From 25727a362ff54dcb05472fbafcdf8ac04702c83b Mon Sep 17 00:00:00 2001 From: cnlohr <lohr85@gmail.com> Date: Tue, 14 Mar 2023 16:40:30 -0400 Subject: [PATCH] Improve demonstration of using self-modifying code. --- examples/self_modify_code/self_modify_code.c | 27 +++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/examples/self_modify_code/self_modify_code.c b/examples/self_modify_code/self_modify_code.c index 5e40b5f..bf33dc5 100644 --- a/examples/self_modify_code/self_modify_code.c +++ b/examples/self_modify_code/self_modify_code.c @@ -8,6 +8,8 @@ uint32_t count; +// This is a complicated way to do it from C land, as a demonstration + // Tell the compiler to put this code in the .data section. That // will cause the startup code to copy it from flash into RAM where // it can be easily modified at runtime. @@ -38,10 +40,14 @@ uint32_t ReadCSRSelfModify( uint16_t whichcsr ) // can know what opcode we want to use, then we can let C tell us // what register it would like the value in. // + // The fence is needed to make sure the CPU knows to not use + // cached instructions. + // // The constraints are "ret" is a "write" register, and register a3 // is going to be clobbered by the assembly code. asm volatile( ".global readCSRLabel \n" + " fence \n" "readCSRLabel: \n" " csrrs a3, 0x000, x0 \n" " addi %[ret], a3, 0 \n" @@ -51,6 +57,25 @@ uint32_t ReadCSRSelfModify( uint16_t whichcsr ) } +uint32_t ReadCSRSelfModifySimple( uint16_t whichcsr ) __attribute__(( section(".data"))) __attribute__((noinline)); +uint32_t ReadCSRSelfModifySimple( uint16_t whichcsr ) +{ + uint32_t ret; + uint32_t csrcmd = 0x000026f3 | ( whichcsr << 20); + asm volatile( + ".global readCSRLabel \n" + " la a3, readCSRLabel \n" + " sw %[csrcmd], 0(a3) \n" + " fence \n" + "readCSRLabel: \n" + " csrrs a3, 0x000, x0 \n" + " addi %[ret], a3, 0 \n" + : [ret]"=r"(ret) : [csrcmd]"r"(csrcmd) : "a3" ); + + return ret; +} + + int main() { SystemInit48HSI(); @@ -64,7 +89,7 @@ int main() int i; for( i = 0x000; i < 0x1000; i++ ) { - uint32_t rv = ReadCSRSelfModify( i ); + uint32_t rv = ReadCSRSelfModifySimple( i ); if( rv ) printf( "%03x = %08x\n", i, rv ); } -- GitLab