diff --git a/src/cpu/instruction.h b/src/cpu/instruction.h index ddb8a6c..accadf9 100644 --- a/src/cpu/instruction.h +++ b/src/cpu/instruction.h @@ -96,6 +96,13 @@ #define FUNC3_ECALL_EBREAK 0x0 #define IMM_ECALL 0x0 #define IMM_EBREAK 0x1 +/* RISC-V Privileged Instructions */ +#define FUNC7_SFENCEVMA 0x9 +#define FUNC7_WFI 0x8 +#define FUNC7_SINVALVMA 0x11 +#define FUNC7_SFENCEWINVAL_SFENCEINVALIR 0xC +#define IMM5_SFENCEWINVAL 0x0 +#define IMM5_SFENCEINVALIR 0x1 /* RISC-V RV32 ZICSR Extension */ #define FUNC3_CSRRW 0x1 #define FUNC3_CSRRS 0x2 diff --git a/src/cpu/rv32cpu.c b/src/cpu/rv32cpu.c index 5f1338d..0d4eb2b 100644 --- a/src/cpu/rv32cpu.c +++ b/src/cpu/rv32cpu.c @@ -518,8 +518,19 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction) cpu->pc -= 4; break; default: - fprintf(stderr, "FATAL: Unknown IMM for ECALL/EBREAK instruction while executing (IMM=0x%x)\n", instruction->immediate); - exit(EXIT_FAILURE); + switch(instruction->func7) + { + case FUNC7_SFENCEVMA: + fprintf(stderr, "SFENCE.VMA: Guest kernel must think we have an MMU. We have none.\n"); + break; + case FUNC7_WFI: + fprintf(stderr, "WFI: Guest kernel must think we have interrupts. We have none.\n"); + break; + default: + fprintf(stderr, "FATAL: Unknown IMM for ECALL/EBREAK instruction while executing (IMM=0x%x)\n", instruction->immediate); + exit(EXIT_FAILURE); + break; + } break; } break; @@ -1053,7 +1064,35 @@ static void cpu_print_instruction(instruction_t* instruction) printf("ebreak\n"); break; default: - fprintf(stderr, "Warning: Unknown IMM for ECALL/EBREAK instruction (IMM=0x%x)\n", instruction->immediate); + switch(instruction->func7) + { + case FUNC7_WFI: + printf("wfi\n"); + break; + case FUNC7_SFENCEVMA: + printf("sfence.vma\n"); + break; + case FUNC7_SINVALVMA: + printf("sinval.vma\n"); + break; + case FUNC7_SFENCEWINVAL_SFENCEINVALIR: + switch(instruction->immediate & 0x1F) + { + case IMM5_SFENCEWINVAL: + printf("sfence.w.inval\n"); + break; + case IMM5_SFENCEINVALIR: + printf("sfence.inval.ir\n"); + break; + default: + fprintf(stderr, "Warning: Unknown IMM for SFENCEWINVAL/SFENCEINVALIR instruction (IMM=0x%x)\n", instruction->immediate); + break; + } + break; + default: + fprintf(stderr, "Warning: Unknown IMM for ECALL/EBREAK instruction (IMM=0x%x)\n", instruction->immediate); + break; + } break; } break;