diff --git a/README.md b/README.md index 0a6da9c..d39970e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ uvm32 is a minimalist, dependency-free virtual machine sandbox designed for microcontrollers and other resource-constrained devices. Single C file, no dynamic memory allocations, asynchronous design, pure C99. -On an [STM32L0](https://www.st.com/en/microcontrollers-microprocessors/stm32l0-series.html) (ARM Cortex-M0+) the required footprint is under 4KB flash/1KB RAM. +On an [STM32L0](https://www.st.com/en/microcontrollers-microprocessors/stm32l0-series.html) (ARM Cortex-M0+) the required footprint is under 3KB flash/1KB RAM. uvm32 is a RISC-V emulator, wrapped in a management interface and provided with tools to build efficient code to run in it. diff --git a/precompiled/self.bin b/precompiled/self.bin index 40a7b05..9c5e19c 100755 Binary files a/precompiled/self.bin and b/precompiled/self.bin differ diff --git a/uvm32/mini-rv32ima.h b/uvm32/mini-rv32ima.h index f3a3eab..d063c89 100644 --- a/uvm32/mini-rv32ima.h +++ b/uvm32/mini-rv32ima.h @@ -45,6 +45,7 @@ #define MINIRV32_HANDLE_MEM_LOAD_CONTROL(...); #endif +#ifndef MINIRV32_NO_ZICSR #ifndef MINIRV32_OTHERCSR_WRITE #define MINIRV32_OTHERCSR_WRITE(...); #endif @@ -52,6 +53,7 @@ #ifndef MINIRV32_OTHERCSR_READ #define MINIRV32_OTHERCSR_READ(...); #endif +#endif #ifndef MINIRV32_CUSTOM_MEMORY_BUS #define MINIRV32_STORE4( ofs, val ) *(uint32_t*)(image + ofs) = val @@ -82,6 +84,7 @@ struct MiniRV32IMAState uint32_t timermatchl; uint32_t timermatchh; #endif +#ifndef MINIRV32_NO_ZICSR uint32_t mscratch; uint32_t mtvec; uint32_t mie; @@ -90,6 +93,7 @@ struct MiniRV32IMAState uint32_t mepc; uint32_t mtval; uint32_t mcause; +#endif // Note: only a few bits are used. (Machine = 3, User = 0) // Bits 0..1 = privilege. @@ -342,6 +346,7 @@ MINIRV32_STEPPROTO { uint32_t csrno = ir >> 20; uint32_t microop = ( ir >> 12 ) & 0x7; +#ifndef MINIRV32_NO_ZICSR if( (microop & 3) ) // It's a Zicsr function. { int rs1imm = (ir >> 15) & 0x1f; @@ -407,9 +412,12 @@ MINIRV32_STEPPROTO break; } } - else if( microop == 0x0 ) // "SYSTEM" 0b000 + else +#endif + if( microop == 0x0 ) // "SYSTEM" 0b000 { rdid = 0; +#ifndef MINIRV32_NO_ZICSR if( ( ( csrno & 0xff ) == 0x02 ) ) // MRET { //https://raw.githubusercontent.com/riscv/virtual-memory/main/specs/663-Svpbmt.pdf @@ -420,7 +428,10 @@ MINIRV32_STEPPROTO SETCSR( mstatus , (( startmstatus & 0x80) >> 4) | ((startextraflags&3) << 11) | 0x80 ); SETCSR( extraflags, (startextraflags & ~3) | ((startmstatus >> 11) & 3) ); pc = CSR( mepc ) -4; - } else { + } + else +#endif + { switch (csrno) { case 0: trap = ( CSR( extraflags ) & 3) ? (11+1) : (8+1); // ECALL; 8 = "Environment call from U-mode"; 11 = "Environment call from M-mode" @@ -441,6 +452,7 @@ MINIRV32_STEPPROTO trap = (2+1); // Note micrrop 0b100 == undefined. break; } +#ifndef MINIRV32_NO_ATOMICS case 0x2f: // RV32A (0b00101111) { uint32_t rs1 = REG((ir >> 15) & 0x1f); @@ -487,6 +499,7 @@ MINIRV32_STEPPROTO } break; } +#endif default: trap = (2+1); // Fault: Invalid opcode. } diff --git a/uvm32/uvm32.h b/uvm32/uvm32.h index d3d2756..0f8b323 100644 --- a/uvm32/uvm32.h +++ b/uvm32/uvm32.h @@ -42,6 +42,8 @@ SOFTWARE. #define MINIRV32_DECORATE static #define MINIRV32_RETURN_TRAP #define MINIRV32_NO_TIMERS_NO_CYCLES +#define MINIRV32_NO_ZICSR +#define MINIRV32_NO_ATOMICS #define MINI_RV32_RAM_SIZE UVM32_MEMORY_SIZE #define MINIRV32_POSTEXEC(pc, ir, retval) {if (retval > 0) return retval;} uint32_t _uvm32_extramLoad(void *userdata, uint32_t addr, uint32_t accessTyp);