00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <stdio.h>
00035 #include <avr/boot.h>
00036 #include <avr/pgmspace.h>
00037 #include <avr/interrupt.h>
00038 #include "dev/rs232.h"
00039 #include "elfloader-arch.h"
00040 #include "lib/mmem.h"
00041
00042 #define R_AVR_NONE 0
00043 #define R_AVR_32 1
00044 #define R_AVR_7_PCREL 2
00045 #define R_AVR_13_PCREL 3
00046 #define R_AVR_16 4
00047 #define R_AVR_16_PM 5
00048 #define R_AVR_LO8_LDI 6
00049 #define R_AVR_HI8_LDI 7
00050 #define R_AVR_HH8_LDI 8
00051 #define R_AVR_LO8_LDI_NEG 9
00052 #define R_AVR_HI8_LDI_NEG 10
00053 #define R_AVR_HH8_LDI_NEG 11
00054 #define R_AVR_LO8_LDI_PM 12
00055 #define R_AVR_HI8_LDI_PM 13
00056 #define R_AVR_HH8_LDI_PM 14
00057 #define R_AVR_LO8_LDI_PM_NEG 15
00058 #define R_AVR_HI8_LDI_PM_NEG 16
00059 #define R_AVR_HH8_LDI_PM_NEG 17
00060 #define R_AVR_CALL 18
00061
00062 #define ELF32_R_TYPE(info) ((unsigned char)(info))
00063
00064 #define DEBUG 0
00065 #if DEBUG
00066
00067 #define PRINTF(...) printf(__VA_ARGS__)
00068 #else
00069 #define PRINTF(...)
00070 #endif
00071
00072 static struct mmem module_heap;
00073
00074 void*
00075 elfloader_arch_allocate_ram(int size)
00076 {
00077
00078
00079 if (MMEM_PTR(&module_heap) != 0) {
00080 mmem_free(&module_heap);
00081 }
00082
00083
00084 if (mmem_alloc (&module_heap, size) == 0) {
00085 return NULL;
00086 }
00087
00088 return (char*)MMEM_PTR(&module_heap);
00089 }
00090
00091
00092
00093
00094
00095 void*
00096 elfloader_arch_allocate_rom(int size)
00097 {
00098 return (void *)0x8000;
00099 }
00100
00101
00102
00103 #define INCLUDE_APPLICATE_SOURCE 1
00104 #ifdef __GNUC__
00105 #if (FLASHEND > USHRT_MAX) && (__SIZEOF_POINTER__ <= 2)
00106 #undef INCLUDE_APPLICATE_SOURCE
00107 #define INCLUDE_APPLICATE_SOURCE 0
00108 #endif
00109 #if (__SIZEOF_POINTER__ > 2)
00110 #define INCLUDE_32BIT_CODE 1
00111 #endif
00112 #endif
00113 #if INCLUDE_APPLICATE_SOURCE
00114
00115 BOOTLOADER_SECTION void
00116 elfloader_arch_write_rom(int fd, unsigned short textoff, unsigned int size, char *mem)
00117 {
00118 unsigned char buf[SPM_PAGESIZE];
00119 unsigned short* flashptr = mem;
00120
00121
00122
00123 if (size <= 0)
00124 return;
00125
00126
00127
00128
00129 cfs_seek(fd, textoff, CFS_SEEK_SET);
00130 for (flashptr=mem; flashptr < mem + size; flashptr += SPM_PAGESIZE) {
00131 memset (buf, 0, SPM_PAGESIZE);
00132 cfs_read(fd, buf, SPM_PAGESIZE);
00133
00134
00135 uint8_t sreg;
00136 sreg = SREG;
00137 cli ();
00138
00139
00140 boot_page_erase (flashptr);
00141 boot_spm_busy_wait ();
00142
00143 unsigned short *origptr = flashptr;
00144
00145 int i;
00146
00147 for(i = 0; i < SPM_PAGESIZE; i+=2) {
00148 boot_page_fill (flashptr, (uint16_t)((buf[i+1] << 8) | buf[i]));
00149 PORTB = 0xff - 7;
00150 ++flashptr;
00151 }
00152
00153
00154 boot_page_write (origptr);
00155 boot_spm_busy_wait();
00156
00157
00158 boot_rww_enable ();
00159 boot_spm_busy_wait ();
00160
00161
00162 SREG = sreg;
00163 }
00164 }
00165 #endif
00166
00167
00168 static void
00169 write_ldi(int fd, unsigned char *instr, unsigned char byte)
00170 {
00171 instr[0] = (instr[0] & 0xf0) | (byte & 0x0f);
00172 instr[1] = (instr[1] & 0xf0) | (byte >> 4);
00173 cfs_write (fd, instr, 2);
00174 }
00175
00176 void
00177 elfloader_arch_relocate(int fd, unsigned int sectionoffset,
00178
00179 char *sectionaddr,
00180 struct elf32_rela *rela, char *addr)
00181 {
00182 unsigned int type;
00183 unsigned char instr[4];
00184
00185 cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET);
00186 cfs_read(fd, instr, 4);
00187 cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET);
00188
00189 type = ELF32_R_TYPE(rela->r_info);
00190
00191 addr += rela->r_addend;
00192
00193 switch(type) {
00194 case R_AVR_NONE:
00195 case R_AVR_32:
00196 PRINTF(PSTR ("elfloader-avr.c: unsupported relocation type: "));
00197 PRINTF("%d\n", type);
00198 break;
00199
00200 case R_AVR_7_PCREL: {
00201
00202
00203
00204
00205
00206 int16_t a = (((int)addr - rela->r_offset -2) / 2);
00207 instr[0] |= (a << 3) & 0xf8;
00208 instr[1] |= (a >> 5) & 0x03;
00209 cfs_write(fd, instr, 2);
00210 }
00211 break;
00212 case R_AVR_13_PCREL: {
00213
00214
00215
00216
00217 int16_t a = (int)addr / 2;
00218 a -= rela->r_offset / 2;
00219 a--;
00220 instr[0] |= a & 0xff;
00221 instr[1] |= (a >> 8) & 0x0f;
00222 cfs_write(fd, instr, 2);
00223 }
00224 break;
00225
00226 case R_AVR_16:
00227 instr[0] = (int)addr & 0xff;
00228 instr[1] = ((int)addr >> 8) & 0xff;
00229
00230 cfs_write(fd, instr, 2);
00231 break;
00232
00233 case R_AVR_16_PM:
00234 addr = (char *)((int)addr >> 1);
00235 instr[0] = (int)addr & 0xff;
00236 instr[1] = ((int)addr >> 8) & 0xff;
00237
00238 cfs_write(fd, instr, 2);
00239 break;
00240
00241 case R_AVR_LO8_LDI:
00242 write_ldi(fd, instr, (int)addr);
00243 break;
00244 case R_AVR_HI8_LDI:
00245 write_ldi(fd, instr, (int)addr >> 8);
00246 break;
00247
00248 #if INCLUDE_32BIT_CODE
00249 case R_AVR_HH8_LDI:
00250 write_ldi(fd, instr, (int)addr >> 16);
00251 break;
00252 #endif
00253
00254 case R_AVR_LO8_LDI_NEG:
00255 addr = (char *) (0 - (int)addr);
00256 write_ldi(fd, instr, (int)addr);
00257 break;
00258 case R_AVR_HI8_LDI_NEG:
00259 addr = (char *) (0 - (int)addr);
00260 write_ldi(fd, instr, (int)addr >> 8);
00261 break;
00262
00263 #if INCLUDE_32BIT_CODE
00264 case R_AVR_HH8_LDI_NEG:
00265 addr = (char *)(0 - (int)addr);
00266 write_ldi(fd, instr, (int)addr >> 16);
00267 break;
00268 #endif
00269
00270 case R_AVR_LO8_LDI_PM:
00271 write_ldi(fd, instr, (int)addr >> 1);
00272 break;
00273 case R_AVR_HI8_LDI_PM:
00274 write_ldi(fd, instr, (int)addr >> 9);
00275 break;
00276
00277 #if INCLUDE_32BIT_CODE
00278 case R_AVR_HH8_LDI_PM:
00279 write_ldi(fd, instr, (int)addr >> 17);
00280 break;
00281 #endif
00282
00283 case R_AVR_LO8_LDI_PM_NEG:
00284 addr = (char *) (0 - (int)addr);
00285 write_ldi(fd, instr, (int)addr >> 1);
00286 break;
00287 case R_AVR_HI8_LDI_PM_NEG:
00288 addr = (char *) (0 - (int)addr);
00289 write_ldi(fd, instr, (int)addr >> 9);
00290 break;
00291
00292 #if INCLUDE_32BIT_CODE
00293 case R_AVR_HH8_LDI_PM_NEG:
00294 addr = (char *) (0 - (int)addr);
00295 write_ldi(fd, instr, (int)addr >> 17);
00296 break;
00297 #endif
00298
00299 case R_AVR_CALL:
00300
00301
00302
00303
00304
00305
00306
00307 instr[2] = (u8_t) ((int)addr) & 0xff;
00308 instr[3] = ((int)addr) >> 8;
00309 cfs_write(fd, instr, 4);
00310 break;
00311
00312 default:
00313 PRINTF(PSTR ("Unknown relocation type!\n"));
00314 break;
00315 }
00316 }
00317
00318 void
00319 elfloader_unload(void) {
00320 }