| 1 |
/* Copyright (c) 2002, Marek Michalkiewicz <marekm@amelek.gda.pl>
|
| 2 |
Copyright (c) 2007, 2008 Eric B. Weddington
|
| 3 |
All rights reserved.
|
| 4 |
|
| 5 |
Redistribution and use in source and binary forms, with or without
|
| 6 |
modification, are permitted provided that the following conditions are met:
|
| 7 |
|
| 8 |
* Redistributions of source code must retain the above copyright
|
| 9 |
notice, this list of conditions and the following disclaimer.
|
| 10 |
|
| 11 |
* Redistributions in binary form must reproduce the above copyright
|
| 12 |
notice, this list of conditions and the following disclaimer in
|
| 13 |
the documentation and/or other materials provided with the
|
| 14 |
distribution.
|
| 15 |
|
| 16 |
* Neither the name of the copyright holders nor the names of
|
| 17 |
contributors may be used to endorse or promote products derived
|
| 18 |
from this software without specific prior written permission.
|
| 19 |
|
| 20 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
| 21 |
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
| 22 |
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
| 23 |
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
| 24 |
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
| 25 |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
| 26 |
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
| 27 |
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
| 28 |
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
| 29 |
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
| 30 |
POSSIBILITY OF SUCH DAMAGE. */
|
| 31 |
|
| 32 |
/* $Id$ */
|
| 33 |
|
| 34 |
#if (__GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
|
| 35 |
#error "GCC version >= 3.3 required"
|
| 36 |
#endif
|
| 37 |
|
| 38 |
#include IOSYMFILE
|
| 39 |
|
| 40 |
#include "macros.inc"
|
| 41 |
|
| 42 |
.macro vector name
|
| 43 |
.if (. - __vectors < _VECTORS_SIZE)
|
| 44 |
.weak \name
|
| 45 |
.set \name, __bad_interrupt
|
| 46 |
XJMP \name
|
| 47 |
.endif
|
| 48 |
.endm
|
| 49 |
|
| 50 |
.section .vectors,"ax",@progbits
|
| 51 |
.global __vectors
|
| 52 |
.func __vectors
|
| 53 |
__vectors:
|
| 54 |
XJMP __init
|
| 55 |
vector __vector_1
|
| 56 |
vector __vector_2
|
| 57 |
vector __vector_3
|
| 58 |
vector __vector_4
|
| 59 |
vector __vector_5
|
| 60 |
vector __vector_6
|
| 61 |
vector __vector_7
|
| 62 |
vector __vector_8
|
| 63 |
vector __vector_9
|
| 64 |
vector __vector_10
|
| 65 |
vector __vector_11
|
| 66 |
vector __vector_12
|
| 67 |
vector __vector_13
|
| 68 |
vector __vector_14
|
| 69 |
vector __vector_15
|
| 70 |
vector __vector_16
|
| 71 |
vector __vector_17
|
| 72 |
vector __vector_18
|
| 73 |
vector __vector_19
|
| 74 |
vector __vector_20
|
| 75 |
vector __vector_21
|
| 76 |
vector __vector_22
|
| 77 |
vector __vector_23
|
| 78 |
vector __vector_24
|
| 79 |
vector __vector_25
|
| 80 |
vector __vector_26
|
| 81 |
vector __vector_27
|
| 82 |
vector __vector_28
|
| 83 |
vector __vector_29
|
| 84 |
vector __vector_30
|
| 85 |
vector __vector_31
|
| 86 |
vector __vector_32
|
| 87 |
vector __vector_33
|
| 88 |
vector __vector_34
|
| 89 |
vector __vector_35
|
| 90 |
vector __vector_36
|
| 91 |
vector __vector_37
|
| 92 |
vector __vector_38
|
| 93 |
vector __vector_39
|
| 94 |
vector __vector_40
|
| 95 |
vector __vector_41
|
| 96 |
vector __vector_42
|
| 97 |
vector __vector_43
|
| 98 |
vector __vector_44
|
| 99 |
vector __vector_45
|
| 100 |
vector __vector_46
|
| 101 |
vector __vector_47
|
| 102 |
vector __vector_48
|
| 103 |
vector __vector_49
|
| 104 |
vector __vector_50
|
| 105 |
vector __vector_51
|
| 106 |
vector __vector_52
|
| 107 |
vector __vector_53
|
| 108 |
vector __vector_54
|
| 109 |
vector __vector_55
|
| 110 |
vector __vector_56
|
| 111 |
vector __vector_57
|
| 112 |
vector __vector_58
|
| 113 |
vector __vector_59
|
| 114 |
vector __vector_60
|
| 115 |
vector __vector_61
|
| 116 |
vector __vector_62
|
| 117 |
vector __vector_63
|
| 118 |
vector __vector_64
|
| 119 |
vector __vector_65
|
| 120 |
vector __vector_66
|
| 121 |
vector __vector_67
|
| 122 |
vector __vector_68
|
| 123 |
vector __vector_69
|
| 124 |
vector __vector_70
|
| 125 |
vector __vector_71
|
| 126 |
vector __vector_72
|
| 127 |
vector __vector_73
|
| 128 |
vector __vector_74
|
| 129 |
vector __vector_75
|
| 130 |
vector __vector_76
|
| 131 |
vector __vector_77
|
| 132 |
vector __vector_78
|
| 133 |
vector __vector_79
|
| 134 |
vector __vector_80
|
| 135 |
vector __vector_81
|
| 136 |
vector __vector_82
|
| 137 |
vector __vector_83
|
| 138 |
vector __vector_84
|
| 139 |
vector __vector_85
|
| 140 |
vector __vector_86
|
| 141 |
vector __vector_87
|
| 142 |
vector __vector_88
|
| 143 |
vector __vector_89
|
| 144 |
vector __vector_90
|
| 145 |
vector __vector_91
|
| 146 |
vector __vector_92
|
| 147 |
vector __vector_93
|
| 148 |
vector __vector_94
|
| 149 |
vector __vector_95
|
| 150 |
vector __vector_96
|
| 151 |
vector __vector_97
|
| 152 |
vector __vector_98
|
| 153 |
vector __vector_99
|
| 154 |
vector __vector_100
|
| 155 |
vector __vector_101
|
| 156 |
vector __vector_102
|
| 157 |
vector __vector_103
|
| 158 |
vector __vector_104
|
| 159 |
vector __vector_105
|
| 160 |
vector __vector_106
|
| 161 |
vector __vector_107
|
| 162 |
vector __vector_108
|
| 163 |
vector __vector_109
|
| 164 |
vector __vector_110
|
| 165 |
vector __vector_111
|
| 166 |
vector __vector_112
|
| 167 |
vector __vector_113
|
| 168 |
vector __vector_114
|
| 169 |
vector __vector_115
|
| 170 |
vector __vector_116
|
| 171 |
vector __vector_117
|
| 172 |
vector __vector_118
|
| 173 |
vector __vector_119
|
| 174 |
vector __vector_120
|
| 175 |
vector __vector_121
|
| 176 |
vector __vector_122
|
| 177 |
vector __vector_123
|
| 178 |
vector __vector_124
|
| 179 |
vector __vector_125
|
| 180 |
vector __vector_126
|
| 181 |
vector __vector_127
|
| 182 |
.endfunc
|
| 183 |
|
| 184 |
/* Handle unexpected interrupts (enabled and no handler), which
|
| 185 |
usually indicate a bug. Jump to the __vector_default function
|
| 186 |
if defined by the user, otherwise jump to the reset address.
|
| 187 |
|
| 188 |
This must be in a different section, otherwise the assembler
|
| 189 |
will resolve "rjmp" offsets and there will be no relocs. */
|
| 190 |
|
| 191 |
.text
|
| 192 |
.global __bad_interrupt
|
| 193 |
.func __bad_interrupt
|
| 194 |
__bad_interrupt:
|
| 195 |
.weak __vector_default
|
| 196 |
.set __vector_default, __vectors
|
| 197 |
XJMP __vector_default
|
| 198 |
.endfunc
|
| 199 |
|
| 200 |
.section .init0,"ax",@progbits
|
| 201 |
.weak __init
|
| 202 |
; .func __init
|
| 203 |
__init:
|
| 204 |
|
| 205 |
#ifndef __AVR_ASM_ONLY__
|
| 206 |
.weak __stack
|
| 207 |
|
| 208 |
/* By default, malloc() uses the current value of the stack pointer
|
| 209 |
minus __malloc_margin as the highest available address.
|
| 210 |
|
| 211 |
In some applications with external SRAM, the stack can be below
|
| 212 |
the data section (in the internal SRAM - faster), and __heap_end
|
| 213 |
should be set to the highest address available for malloc(). */
|
| 214 |
.weak __heap_end
|
| 215 |
.set __heap_end, 0
|
| 216 |
|
| 217 |
.section .init2,"ax",@progbits
|
| 218 |
clr __zero_reg__
|
| 219 |
out AVR_STATUS_ADDR, __zero_reg__
|
| 220 |
ldi r28,lo8(__stack)
|
| 221 |
#ifdef __AVR_XMEGA__
|
| 222 |
out AVR_STACK_POINTER_LO_ADDR, r28
|
| 223 |
#ifdef _HAVE_AVR_STACK_POINTER_HI
|
| 224 |
ldi r29,hi8(__stack)
|
| 225 |
out AVR_STACK_POINTER_HI_ADDR, r29
|
| 226 |
#endif /* _HAVE_AVR_STACK_POINTER_HI */
|
| 227 |
#else
|
| 228 |
#ifdef _HAVE_AVR_STACK_POINTER_HI
|
| 229 |
ldi r29,hi8(__stack)
|
| 230 |
out AVR_STACK_POINTER_HI_ADDR, r29
|
| 231 |
#endif /* _HAVE_AVR_STACK_POINTER_HI */
|
| 232 |
out AVR_STACK_POINTER_LO_ADDR, r28
|
| 233 |
#endif /* __AVR_XMEGA__ */
|
| 234 |
|
| 235 |
#ifdef __AVR_3_BYTE_PC__
|
| 236 |
ldi r16, hh8(pm(__vectors))
|
| 237 |
out _SFR_IO_ADDR(EIND), r16
|
| 238 |
#endif /* __AVR_3_BYTE_PC__ */
|
| 239 |
|
| 240 |
#ifdef __AVR_HAVE_RAMPD__
|
| 241 |
out AVR_RAMPD_ADDR, __zero_reg__
|
| 242 |
out AVR_RAMPX_ADDR, __zero_reg__
|
| 243 |
out AVR_RAMPY_ADDR, __zero_reg__
|
| 244 |
out AVR_RAMPZ_ADDR, __zero_reg__
|
| 245 |
#endif
|
| 246 |
|
| 247 |
#if defined(__GNUC__) && ((__GNUC__ <= 3) || (__GNUC__ == 4 && __GNUC_MINOR__ <= 3))
|
| 248 |
#if BIG_CODE
|
| 249 |
/* Only for >64K devices with RAMPZ, replaces the default code
|
| 250 |
provided by libgcc.S which is only linked in if necessary. */
|
| 251 |
|
| 252 |
.section .init4,"ax",@progbits
|
| 253 |
.global __do_copy_data
|
| 254 |
__do_copy_data:
|
| 255 |
ldi r17, hi8(__data_end)
|
| 256 |
ldi r26, lo8(__data_start)
|
| 257 |
ldi r27, hi8(__data_start)
|
| 258 |
ldi r30, lo8(__data_load_start)
|
| 259 |
ldi r31, hi8(__data_load_start)
|
| 260 |
|
| 261 |
/* On the enhanced core, "elpm" with post-increment updates RAMPZ
|
| 262 |
automatically. Otherwise we have to handle it ourselves. */
|
| 263 |
|
| 264 |
#ifdef __AVR_ENHANCED__
|
| 265 |
ldi r16, hh8(__data_load_start)
|
| 266 |
#else
|
| 267 |
ldi r16, hh8(__data_load_start - 0x10000)
|
| 268 |
.L__do_copy_data_carry:
|
| 269 |
inc r16
|
| 270 |
#endif
|
| 271 |
out AVR_RAMPZ_ADDR, r16
|
| 272 |
rjmp .L__do_copy_data_start
|
| 273 |
.L__do_copy_data_loop:
|
| 274 |
#ifdef __AVR_ENHANCED__
|
| 275 |
elpm r0, Z+
|
| 276 |
#else
|
| 277 |
elpm
|
| 278 |
#endif
|
| 279 |
st X+, r0
|
| 280 |
#ifndef __AVR_ENHANCED__
|
| 281 |
adiw r30, 1
|
| 282 |
brcs .L__do_copy_data_carry
|
| 283 |
#endif
|
| 284 |
.L__do_copy_data_start:
|
| 285 |
cpi r26, lo8(__data_end)
|
| 286 |
cpc r27, r17
|
| 287 |
brne .L__do_copy_data_loop
|
| 288 |
#ifdef __AVR_HAVE_RAMPD__
|
| 289 |
out AVR_RAMPZ_ADDR, __zero_reg__
|
| 290 |
#endif /* __AVR_HAVE_RAMPD__*/
|
| 291 |
|
| 292 |
#endif /* BIG_CODE */
|
| 293 |
#endif /* defined(__GNUC__) && ((__GNUC__ <= 3) || (__GNUC__ == 4 && __GNUC_MINOR__ <= 3)) */
|
| 294 |
|
| 295 |
.set __stack, RAMEND
|
| 296 |
#endif /* !__AVR_ASM_ONLY__ */
|
| 297 |
|
| 298 |
.section .init9,"ax",@progbits
|
| 299 |
#ifdef __AVR_ASM_ONLY__
|
| 300 |
XJMP main
|
| 301 |
#else /* !__AVR_ASM_ONLY__ */
|
| 302 |
XCALL main
|
| 303 |
XJMP exit
|
| 304 |
#endif /* __AVR_ASM_ONLY__ */
|
| 305 |
; .endfunc
|
| 306 |
|
| 307 |
.section .note.gnu.avr.deviceinfo, "", @note
|
| 308 |
#define NOTE_NAME "AVR"
|
| 309 |
#ifdef __AVR_DEVICE_NAME__
|
| 310 |
#define DEVICE_NAME STR(__AVR_DEVICE_NAME__)
|
| 311 |
#else
|
| 312 |
#define DEVICE_NAME ""
|
| 313 |
#endif
|
| 314 |
|
| 315 |
.long .L__note_name_end - .L__note_name_start
|
| 316 |
.long .L__desc_end - .L__desc_start
|
| 317 |
.long 1 ; Type 1 - this is the only known note type for AVR.
|
| 318 |
.L__note_name_start:
|
| 319 |
.asciz NOTE_NAME
|
| 320 |
.balign 4
|
| 321 |
.L__note_name_end:
|
| 322 |
.L__desc_start:
|
| 323 |
#ifdef FLASHSTART
|
| 324 |
.long FLASHSTART
|
| 325 |
#else
|
| 326 |
.long 0
|
| 327 |
#endif
|
| 328 |
#ifdef PROGMEM_SIZE
|
| 329 |
.long PROGMEM_SIZE
|
| 330 |
#elif FLASHEND > 0
|
| 331 |
.long FLASHEND + 1
|
| 332 |
#else
|
| 333 |
.long FLASHEND
|
| 334 |
#endif
|
| 335 |
.long RAMSTART
|
| 336 |
#ifdef RAMSIZE
|
| 337 |
.long RAMSIZE
|
| 338 |
#elif RAMEND > 0
|
| 339 |
.long RAMEND - RAMSTART + 1
|
| 340 |
#else
|
| 341 |
.long RAMEND
|
| 342 |
#endif
|
| 343 |
#ifdef E2START
|
| 344 |
.long E2START
|
| 345 |
#else
|
| 346 |
.long 0
|
| 347 |
#endif
|
| 348 |
#ifdef EEPROM_SIZE
|
| 349 |
.long EEPROM_SIZE
|
| 350 |
#elif E2END > 0
|
| 351 |
.long E2END + 1
|
| 352 |
#else
|
| 353 |
.long E2END
|
| 354 |
#endif
|
| 355 |
/* String offsets table.
|
| 356 |
Index 0 - Size of offset table in bytes
|
| 357 |
Index 1 - Device name byte offset
|
| 358 |
*/
|
| 359 |
.L__stroffsettab_start:
|
| 360 |
.long .L__stroffsettab_end - .L__stroffsettab_start /* Size of index table in bytes */
|
| 361 |
.long .L__device_name_start - .L__strtab_start /* Byte offset of device name */
|
| 362 |
.L__stroffsettab_end:
|
| 363 |
/* String table for storing arbitrary strings.
|
| 364 |
Offsets are stored in the string offset table above */
|
| 365 |
.L__strtab_start:
|
| 366 |
.byte 0
|
| 367 |
.L__device_name_start:
|
| 368 |
.asciz DEVICE_NAME
|
| 369 |
.L__device_name_end:
|
| 370 |
.byte 0
|
| 371 |
.L__strtab_end:
|
| 372 |
.L__desc_end:
|
| 373 |
.balign 4
|
| 374 |
|
| 375 |
/* Set REGION_LENGTH symbol values for well known memory regions.
|
| 376 |
The default linker script uses these symbols to set MEMORY
|
| 377 |
region lengths, and by defining these here, the linker can detect
|
| 378 |
memory overflows accurately on a per device basis, since the
|
| 379 |
values are picked up from the device header file.
|
| 380 |
*/
|
| 381 |
|
| 382 |
.weak __FUSE_REGION_LENGTH__
|
| 383 |
.set __FUSE_REGION_LENGTH__, FUSE_MEMORY_SIZE
|