avr: fix .data initialization for binaries over 64kB
I found that .data is not correctly initialized with firmware images that use over 64kB of flash. The problem is that the data in .data (which is stored in flash, and copied to RAM at reset) is beyond the 64kB limit and must therefore be loaded using the elpm instruction instead of the lpm instruction. I encountered this issue while getting testdata/math.go to work for AVR. The following command mostly works with this patch, while it prints garbage withtout it: tinygo run -target=simavr -size=short -scheduler=none ./testdata/math.go (This also requires a patch to picolibc to work, see https://github.com/picolibc/picolibc/pull/371) It still doesn't work entirely with this patch: some of the math operations have an incorrect result. But at least it's an improvement as it won't print garbage anymore.
Этот коммит содержится в:
родитель
73b368270c
коммит
bb5050a50d
1 изменённых файлов: 13 добавлений и 0 удалений
|
@ -11,6 +11,11 @@
|
|||
#define zl r30
|
||||
#define zh r31
|
||||
|
||||
; Ugly hack until https://reviews.llvm.org/D137572 is merged.
|
||||
#if !defined(__AVR_HAVE_ELPM__) && defined(__flash1)
|
||||
#define __AVR_HAVE_ELPM__
|
||||
#endif
|
||||
|
||||
; Startup code
|
||||
.section .text.__vector_RESET
|
||||
.global __vector_RESET
|
||||
|
@ -34,11 +39,19 @@ init_data:
|
|||
ldi yh, hi8(_edata)
|
||||
ldi zl, lo8(_sidata)
|
||||
ldi zh, hi8(_sidata)
|
||||
#ifdef __AVR_HAVE_ELPM__
|
||||
ldi r16, hh8(_sidata) ; RAMPZ = hh8(_sidata)
|
||||
out 0x3b, r16
|
||||
#endif
|
||||
init_data_loop:
|
||||
cp xl, yl ; if x == y
|
||||
cpc xh, yh
|
||||
breq init_data_end ; goto main
|
||||
#ifdef __AVR_HAVE_ELPM__
|
||||
elpm r0, Z+ ; r0 = *(z++)
|
||||
#else
|
||||
lpm r0, Z+ ; r0 = *(z++)
|
||||
#endif
|
||||
st X+, r0 ; *(x++) = r0
|
||||
rjmp init_data_loop ; goto init_data_loop
|
||||
init_data_end:
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче