Experimental support for storing const strings in SPI flash or IRAM
As discussed in #11 Known limitations: - Only supports l8ui/l16ui - Unoptimised load routine - Not called from DoubleExceptionHandler but should be - Doesn't restore state properly when falling through to fatal exception handler
This commit is contained in:
parent
25e124a612
commit
bfd38cd1e2
3 changed files with 247 additions and 0 deletions
|
@ -173,12 +173,14 @@ CallNMIExceptionHandler:
|
|||
|
||||
/* Some UserException causes, see table Table 4–64 in ISA reference */
|
||||
#define CAUSE_SYSCALL 1
|
||||
#define CAUSE_LOADSTORE 3
|
||||
#define CAUSE_LVL1INT 4
|
||||
|
||||
.type CallUserExceptionHandler, @function
|
||||
CallUserExceptionHandler:
|
||||
rsr.exccause a0
|
||||
beqi a0, CAUSE_SYSCALL, UserSyscallHandler
|
||||
beqi a0, CAUSE_LOADSTORE, UserLoadStoreExceptionHandler
|
||||
mov a0, sp
|
||||
addi sp, sp, -0x50
|
||||
s32i a0, sp, 0x10
|
||||
|
@ -242,6 +244,132 @@ UserSyscallHandler:
|
|||
rsr.excsave1 a0
|
||||
rfe
|
||||
|
||||
|
||||
.section .bss
|
||||
.global LoadStoreErrorFlag
|
||||
.align 4
|
||||
LoadStoreErrorFlag:
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
|
||||
.section .data
|
||||
.align 4
|
||||
PRINT_ADDR:
|
||||
.string "0x%08lx '%c'\r\n"
|
||||
PRINT_MULTI:
|
||||
.string "a3=0x%08lx a4=0x%08lx a5=0x%08lx a6=0x%08lx a7=0x%08lx\r\n"
|
||||
|
||||
.text
|
||||
.section .vecbase.text
|
||||
.literal_position
|
||||
.align 4
|
||||
.global UserLoadStoreExceptionHandler
|
||||
/* "Fix" LoadStoreException exceptions thatare l8/l16 from an Instruction region */
|
||||
UserLoadStoreExceptionHandler:
|
||||
addi sp, sp, -0x40
|
||||
s32i a2, sp, 0x08
|
||||
rsr.excsave1 a2 /* a0 value */
|
||||
s32i a2, sp, 0x00
|
||||
addi a2, sp, 0x40
|
||||
s32i a2, sp, 0x04 /* original sp value */
|
||||
s32i a3, sp, 0x0c
|
||||
s32i a4, sp, 0x10
|
||||
s32i a5, sp, 0x14
|
||||
s32i a6, sp, 0x18
|
||||
s32i a7, sp, 0x1c
|
||||
s32i a8, sp, 0x20
|
||||
s32i a9, sp, 0x24
|
||||
s32i a10, sp, 0x28
|
||||
s32i a11, sp, 0x2c
|
||||
s32i a12, sp, 0x30
|
||||
s32i a13, sp, 0x34
|
||||
s32i a14, sp, 0x38
|
||||
s32i a15, sp, 0x3c
|
||||
|
||||
/* Check the top nibble of the faulting address is 4, otherwise
|
||||
we can't help out here */
|
||||
rsr.excvaddr a2
|
||||
extui a2, a2, 28, 4
|
||||
bnei a2, 0x4, .Lcant_fix
|
||||
|
||||
/* Load the instruction we failed to execute */
|
||||
rsr.epc1 a3
|
||||
movi a4, ~3
|
||||
and a2, a3, a4
|
||||
l32i a4, a2, 0
|
||||
l32i a5, a2, 4
|
||||
ssa8l a3
|
||||
src a4, a5, a4
|
||||
/* a4 is now the instruction that failed */
|
||||
|
||||
/* example l8ui instr 040c72 */
|
||||
movi a2, 0x00F00F /* l8ui/l16ui opcode mask */
|
||||
and a3, a4, a2
|
||||
movi a8, 0xFF
|
||||
movi a5, 0x000002 /* l8ui opcode after masking */
|
||||
beq a3, a5, .Lcan_fix
|
||||
|
||||
movi a8, 0xFFFF
|
||||
movi a5, 0x001002 /* l16ui opcode after masking */
|
||||
beq a3, a5, .Lcan_fix
|
||||
|
||||
.Lcant_fix:
|
||||
/* not an l8ui or an l16ui, or not in the instruction space, so bomb out
|
||||
TODO: the exception dump will have some wrong values in it */
|
||||
movi a2, PRINT_ADDR
|
||||
movi a3, 0xafafafaf
|
||||
call0 printf
|
||||
call0 sdk_user_fatal_exception_handler
|
||||
.Lcan_fix:
|
||||
/* verified an 8- or 16-bit read in an instruction address space.
|
||||
|
||||
a4 holds instruction, a8 holds mask
|
||||
*/
|
||||
extui a2, a4, 4, 4 /* a2 is destination register 0-15 */
|
||||
slli a2, a2, 2 /* a2 is now offset of destination register, relative to stack pointer */
|
||||
|
||||
rsr.sar a6
|
||||
rsr.excvaddr a3
|
||||
ssa8l a3 /* sar is the shift to extract a3's byte */
|
||||
movi a4, ~3
|
||||
and a4, a3, a4 /* a4 is word aligned read address */
|
||||
|
||||
l32i a5, a4, 0 /* perform the actual read */
|
||||
srl a5, a5
|
||||
and a5, a5, a8 /* mask off bits we need for an l8/l16 */
|
||||
|
||||
wsr.sar a6
|
||||
|
||||
add a6, sp, a2
|
||||
s32i a5, a6, 0 /* overwrite correct value on register slot @ stack+a2 */
|
||||
|
||||
/* Footer*/
|
||||
//Increment PC
|
||||
rsr.epc1 a2
|
||||
addi a3, a2, 0x3
|
||||
wsr.epc1 a3
|
||||
|
||||
// Restore registers
|
||||
l32i a0, sp, 0x00
|
||||
l32i a2, sp, 0x08
|
||||
l32i a3, sp, 0x0c
|
||||
l32i a4, sp, 0x10
|
||||
l32i a5, sp, 0x14
|
||||
l32i a6, sp, 0x18
|
||||
l32i a7, sp, 0x1c
|
||||
l32i a8, sp, 0x20
|
||||
l32i a9, sp, 0x24
|
||||
l32i a10, sp, 0x28
|
||||
l32i a11, sp, 0x2c
|
||||
l32i a12, sp, 0x30
|
||||
l32i a13, sp, 0x34
|
||||
l32i a14, sp, 0x38
|
||||
l32i a15, sp, 0x3c
|
||||
l32i sp, sp, 0x04
|
||||
rfe
|
||||
|
||||
.global _xt_user_exit
|
||||
.type _xt_user_exit, @function
|
||||
_xt_user_exit:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue