9os

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 0f0f84d952bb7d41ce9079e5b945a6f41c12e1a6
parent 9ac0b97e7387e98440366b71e0f48fd9b454f7d2
Author: Roberto Vargas <roberto.vargas@arm.com>
Date:   Sun, 14 Oct 2018 18:40:29 +0100

[arm64] Reallocate function pointers

The image must be loaded at any address, but we have
a table with function pointers that are absoulete
values. For this reason, we link the image at 0
and we store in bss the base address where the code
is loaded, and we only have to add this base address
to the value of the pointers (stored as ptrdiff_t
values).

Change-Id: Ic6ff9d2c760b40d8218ee9af898df657745168d4

Diffstat:
March/arm64/arch.s | 12+++++++++---
March/arm64/crt-none.s | 13+++++++------
March/arm64/rom.c | 13+++++++++----
Minclude/rcode.h | 5++++-
Mscripts/gentbl.sh | 5+++--
Msrc/rmc.c | 12+++++++++++-
6 files changed, 43 insertions(+), 17 deletions(-)

diff --git a/arch/arm64/arch.s b/arch/arm64/arch.s @@ -9,7 +9,7 @@ DAIF_DBG = 4 .globl rd_id_aa64rmfr0_r,wr_id_aa64rmfr0_r .globl rd_rcr_r,wr_rcr_r,rd_rdscr_r,wr_rdscr_r .globl rd_sctlr_rwr_sctlr_r,rd_rvbar_el3,wr_sp_r - .globl vectbl,swtch + .globl vectbl,swtch,isb enaabt: msr daifclr,DAIF_ABT @@ -27,10 +27,16 @@ disdbg: msr daifset,DAIF_DBG ret -wfi: wfi +isb: + isb ret -wfe: wfe +wfi: + wfi + ret + +wfe: + wfe ret rd_actlr_r: diff --git a/arch/arm64/crt-none.s b/arch/arm64/crt-none.s @@ -5,6 +5,10 @@ SRAMSIZE = 4096 .text .globl _start _start: + bl getpc +getpc: + sub x30,x30,4 + msr spsel,#0 ldr x0,=SRAMADDR mov x1,#(SRAMSIZE-16) /* Stack grows down towards BSS */ @@ -15,14 +19,11 @@ _start: adr x0,vectbl msr S3_6_C12_C0_6,x0 /* VBAR_R */ isb - bl enaabt - isb - bl _uart_init stp xzr,xzr,[x29] /* zero FP/LR to terminate backtrace */ - - ldr x0,=SRAMADDR - mov x1,#SRAMSIZE + mov x0,x30 + ldr x1,=SRAMADDR + mov x2,#SRAMSIZE bl main adr x0,outsync b panic diff --git a/arch/arm64/rom.c b/arch/arm64/rom.c @@ -40,21 +40,26 @@ badrmc(Rmucmd *cmd, int error) } void -main(void *sram, size_t sramsiz) +main(void *text, void *ram, size_t ramsiz) { struct trapframe *fp; - char *bp = sram; + char *bp = ram; size_t bsssiz; bsssiz = (sizeof(struct bssmap) + 15) & ~15; fp = (struct trapframe *) (bp + bsssiz); fp += NR_NESTED - 1; wr_sp_r(fp); + _uart_init(); + enaabt(); + isb(); - memset(sram, 0, bsssiz); + memset(ram, 0, bsssiz); memset(fp, 0, sizeof(*fp)); - fp->sp = bp + sramsiz - 16; + bss->text = text; + + fp->sp = bp + (ramsiz - 16); fp->elr = rd_rvbar_el3(); fp->spsr = 0xf << 6 | 0xd; diff --git a/include/rcode.h b/include/rcode.h @@ -1,4 +1,5 @@ #include <setjmp.h> +#include <stddef.h> #include <stdint.h> #ifndef NDEBUG @@ -13,6 +14,7 @@ typedef struct rmucmd Rmucmd; struct bssmap { char in_panic; + void *text; }; struct rowidx { @@ -78,7 +80,8 @@ extern unsigned long long rd_sctlr_r(void); extern void wr_sctlr_r(unsigned long long v); extern void *rd_rvbar_el3(void); extern void wr_sp_r(void *); +extern void isb(void); /* global constant variables */ extern const struct rowidx rowidx[]; -extern void (*const handler[])(Rmucmd *cmd); +extern const ptrdiff_t handler[]; diff --git a/scripts/gentbl.sh b/scripts/gentbl.sh @@ -31,6 +31,7 @@ sort -n -k1,2 < $in | awk ' BEGIN { print "#include <rcode.h>\n" + print "#define from0(f) ((char *) (f) - (char *) 0)\n" }; NF == 3 && $1 ~ /[0-9]*/ && $2 ~ /[0-9]*/ { @@ -58,9 +59,9 @@ END { } print "};" - print "void (*const handler[])(Rmucmd *cmd) = {" + print "const ptrdiff_t handler[] = {" for (row in rowcnt) for (col = 0; col < rowcnt[row]; col++) - printf "\t[%d] = hdl_%s,\n", begin[row] + col, cmds[row,col] + printf "\t[%d] = from0(hdl_%s),\n", begin[row] + col, cmds[row,col] print "};" }' > $tmp && mv $tmp rmctbl.c diff --git a/src/rmc.c b/src/rmc.c @@ -24,6 +24,8 @@ void rmc(Rmucmd *cmd) { const struct rowidx *idx; + void (*fp)(Rmucmd *cmd); + char *bp; if (cmd->imm1 > 255 || cmd->imm2 > 255) panic("rmc"); @@ -32,7 +34,15 @@ rmc(Rmucmd *cmd) if (cmd->imm2 >= idx->cnt) badrmc(cmd, 1); /* TODO: put the correct code */ - (*handler[idx->off + cmd->imm2])(cmd); + /* + * and now we have to reallocate the function pointer, + * because we are linked at address 0 but we can be + * loaded at any address + */ + bp = bss->text; + bp += handler[idx->off + cmd->imm2]; + fp = (void (*)(Rmucmd *)) bp; + (*fp)(cmd); cmd->fp->x0 = 0; /* TODO: 0 means success */ }