diff --git a/.ci/autorun.sh b/.ci/autorun.sh new file mode 100755 index 00000000..d07494bb --- /dev/null +++ b/.ci/autorun.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +function cleanup { + sleep 1 + pkill -9 semu +} + +function ASSERT { + $* + local RES=$? + if [ $RES -ne 0 ]; then + echo 'Assert failed: "' $* '"' + exit $RES + fi +} + +cleanup + +ASSERT expect <priv) + /* Define fetch separately since it is simpler (fixed width, already checked * alignment, only main RAM is executable). */ -static void mem_fetch(vm_t *vm, uint32_t addr, uint32_t *value) +static void mem_fetch(vm_t *vm, uint32_t n_pages, uint32_t **page_addr) { - emu_state_t *data = (emu_state_t *) vm->priv; - if (unlikely(addr >= RAM_SIZE)) { + emu_state_t *data = PRIV(vm); + if (unlikely(n_pages >= RAM_SIZE / RV_PAGE_SIZE)) { /* TODO: check for other regions */ vm_set_exception(vm, RV_EXC_FETCH_FAULT, vm->exc_val); return; } - *value = data->ram[addr >> 2]; + *page_addr = &data->ram[n_pages << (RV_PAGE_SHIFT - 2)]; } /* Similarly, only main memory pages can be used as page tables. */ static uint32_t *mem_page_table(const vm_t *vm, uint32_t ppn) { - emu_state_t *data = (emu_state_t *) vm->priv; + emu_state_t *data = PRIV(vm); if (ppn < (RAM_SIZE / RV_PAGE_SIZE)) return &data->ram[ppn << (RV_PAGE_SHIFT - 2)]; return NULL; @@ -39,7 +41,7 @@ static uint32_t *mem_page_table(const vm_t *vm, uint32_t ppn) static void emu_update_uart_interrupts(vm_t *vm) { - emu_state_t *data = (emu_state_t *) vm->priv; + emu_state_t *data = PRIV(vm); u8250_update_interrupts(&data->uart); if (data->uart.pending_ints) data->plic.active |= IRQ_UART_BIT; @@ -51,7 +53,7 @@ static void emu_update_uart_interrupts(vm_t *vm) #if SEMU_HAS(VIRTIONET) static void emu_update_vnet_interrupts(vm_t *vm) { - emu_state_t *data = (emu_state_t *) vm->priv; + emu_state_t *data = PRIV(vm); if (data->vnet.InterruptStatus) data->plic.active |= IRQ_VNET_BIT; else @@ -63,7 +65,7 @@ static void emu_update_vnet_interrupts(vm_t *vm) #if SEMU_HAS(VIRTIOBLK) static void emu_update_vblk_interrupts(vm_t *vm) { - emu_state_t *data = (emu_state_t *) vm->priv; + emu_state_t *data = PRIV(vm); if (data->vblk.InterruptStatus) data->plic.active |= IRQ_VBLK_BIT; else @@ -86,8 +88,7 @@ static void emu_update_vgpu_interrupts(vm_t *vm) static void mem_load(vm_t *vm, uint32_t addr, uint8_t width, uint32_t *value) { - emu_state_t *data = (emu_state_t *) vm->priv; - + emu_state_t *data = PRIV(vm); /* RAM at 0x00000000 + RAM_SIZE */ if (addr < RAM_SIZE) { ram_read(vm, data->ram, addr, width, value); @@ -131,8 +132,7 @@ static void mem_load(vm_t *vm, uint32_t addr, uint8_t width, uint32_t *value) static void mem_store(vm_t *vm, uint32_t addr, uint8_t width, uint32_t value) { - emu_state_t *data = (emu_state_t *) vm->priv; - + emu_state_t *data = PRIV(vm); /* RAM at 0x00000000 + RAM_SIZE */ if (addr < RAM_SIZE) { ram_write(vm, data->ram, addr, width, value); @@ -185,11 +185,11 @@ typedef struct { static inline sbi_ret_t handle_sbi_ecall_TIMER(vm_t *vm, int32_t fid) { - emu_state_t *data = (emu_state_t *) vm->priv; + emu_state_t *data = PRIV(vm); switch (fid) { case SBI_TIMER__SET_TIMER: - data->timer_lo = vm->x_regs[RV_R_A0]; - data->timer_hi = vm->x_regs[RV_R_A1]; + data->timer = (((uint64_t) vm->x_regs[RV_R_A1]) << 32) | + (uint64_t) (vm->x_regs[RV_R_A0]); return (sbi_ret_t){SBI_SUCCESS, 0}; default: return (sbi_ret_t){SBI_ERR_NOT_SUPPORTED, 0}; @@ -198,7 +198,7 @@ static inline sbi_ret_t handle_sbi_ecall_TIMER(vm_t *vm, int32_t fid) static inline sbi_ret_t handle_sbi_ecall_RST(vm_t *vm, int32_t fid) { - emu_state_t *data = (emu_state_t *) vm->priv; + emu_state_t *data = PRIV(vm); switch (fid) { case SBI_RST__SYSTEM_RESET: fprintf(stderr, "system reset: type=%u, reason=%u\n", @@ -211,7 +211,7 @@ static inline sbi_ret_t handle_sbi_ecall_RST(vm_t *vm, int32_t fid) } #define RV_MVENDORID 0x12345678 -#define RV_MARCHID ((1 << 31) | 1) +#define RV_MARCHID ((1ULL << 31) | 1) #define RV_MIMPID 1 static inline sbi_ret_t handle_sbi_ecall_BASE(vm_t *vm, int32_t fid) @@ -395,6 +395,7 @@ static int semu_start(int argc, char **argv) .mem_store = mem_store, .mem_page_table = mem_page_table, }; + vm_init(&vm); /* Set up RAM */ emu.ram = mmap(NULL, RAM_SIZE, PROT_READ | PROT_WRITE, @@ -431,7 +432,7 @@ static int semu_start(int argc, char **argv) atexit(unmap_files); /* Set up RISC-V hart */ - emu.timer_hi = emu.timer_lo = 0xFFFFFFFF; + emu.timer = 0xFFFFFFFFFFFFFFFF; vm.s_mode = true; vm.x_regs[RV_R_A0] = 0; /* hart ID. i.e., cpuid */ vm.x_regs[RV_R_A1] = dtb_addr; @@ -482,8 +483,7 @@ static int semu_start(int argc, char **argv) #endif } - if (vm.insn_count_hi > emu.timer_hi || - (vm.insn_count_hi == emu.timer_hi && vm.insn_count > emu.timer_lo)) + if (vm.insn_count > emu.timer) vm.sip |= RV_INT_STI_BIT; else vm.sip &= ~RV_INT_STI_BIT; diff --git a/minimal.dts b/minimal.dts index 622e90f2..bedf6569 100644 --- a/minimal.dts +++ b/minimal.dts @@ -6,7 +6,7 @@ model = "semu"; aliases { - serial0 = "/soc/serial@4000000"; + serial0 = "/soc@F0000000/serial@4000000"; }; chosen { @@ -28,6 +28,7 @@ mmu-type = "riscv,rv32"; cpu0_intc: interrupt-controller { #interrupt-cells = <1>; + #address-cells = <0>; interrupt-controller; compatible = "riscv,cpu-intc"; }; @@ -40,7 +41,7 @@ reg-names = "sram0"; }; - soc { + soc: soc@F0000000 { #address-cells = <1>; #size-cells = <1>; compatible = "simple-bus"; diff --git a/mk/external.mk b/mk/external.mk index 84f8e456..17667bc2 100644 --- a/mk/external.mk +++ b/mk/external.mk @@ -8,12 +8,12 @@ COMMON_URL = https://github.com/sysprog21/semu/raw/blob # kernel KERNEL_DATA_URL = $(COMMON_URL)/Image.bz2 KERNEL_DATA = Image -KERNEL_DATA_SHA1 = 36d770efe97beac85204f1f50f8de81e3e529d84 +KERNEL_DATA_SHA1 = b0af9fa4c736dbde5568181c1442182700584495 # initrd INITRD_DATA_URL = $(COMMON_URL)/rootfs.cpio.bz2 INITRD_DATA = rootfs.cpio -INITRD_DATA_SHA1 = fad749d0a9eb33178525f961d6b82e7c0ce917a7 +INITRD_DATA_SHA1 = 4f0c2e646eb99af21ed2c25d48e1c44f6bd58f91 define download $($(T)_DATA): diff --git a/plic.c b/plic.c index 0f72ae4d..08011250 100644 --- a/plic.c +++ b/plic.c @@ -89,7 +89,7 @@ void plic_read(vm_t *vm, vm_set_exception(vm, RV_EXC_LOAD_MISALIGN, vm->exc_val); return; default: - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); return; } } @@ -110,7 +110,7 @@ void plic_write(vm_t *vm, vm_set_exception(vm, RV_EXC_STORE_MISALIGN, vm->exc_val); return; default: - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); return; } } diff --git a/ram.c b/ram.c index d14ffc53..49c7c7d7 100644 --- a/ram.c +++ b/ram.c @@ -38,7 +38,7 @@ void ram_read(vm_t *vm, RAM_FUNC(1, *value = (uint32_t) (int32_t) (int8_t) ((*cell) >> offset)); break; default: - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); return; } } @@ -63,7 +63,7 @@ void ram_write(vm_t *vm, << offset); break; default: - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); return; } } diff --git a/riscv.c b/riscv.c index 36ccfa40..699846fd 100644 --- a/riscv.c +++ b/riscv.c @@ -167,11 +167,17 @@ static inline uint32_t read_rs2(const vm_t *vm, uint32_t insn) /* virtual addressing */ +static void mmu_invalidate(vm_t *vm) +{ + vm->cache_fetch.n_pages = 0xFFFFFFFF; +} + /* Pre-verify the root page table to minimize page table access during * translation time. */ static void mmu_set(vm_t *vm, uint32_t satp) { + mmu_invalidate(vm); if (satp >> 31) { uint32_t *page_table = vm->mem_page_table(vm, satp & MASK(22)); if (!page_table) @@ -267,18 +273,27 @@ static void mmu_translate(vm_t *vm, *addr = ((*addr) & MASK(RV_PAGE_SHIFT)) | (ppn << RV_PAGE_SHIFT); } -static void mmu_fence(vm_t *vm UNUSED, uint32_t insn UNUSED) +static void mmu_fence(vm_t *vm, uint32_t insn UNUSED) { - /* no-op for now */ + mmu_invalidate(vm); } static void mmu_fetch(vm_t *vm, uint32_t addr, uint32_t *value) { - mmu_translate(vm, &addr, (1 << 3), (1 << 6), false, RV_EXC_FETCH_FAULT, - RV_EXC_FETCH_PFAULT); - if (vm->error) - return; - vm->mem_fetch(vm, addr, value); + uint32_t vpn = addr >> RV_PAGE_SHIFT; + if (unlikely(vpn != vm->cache_fetch.n_pages)) { + mmu_translate(vm, &addr, (1 << 3), (1 << 6), false, RV_EXC_FETCH_FAULT, + RV_EXC_FETCH_PFAULT); + if (vm->error) + return; + uint32_t *page_addr; + vm->mem_fetch(vm, addr >> RV_PAGE_SHIFT, &page_addr); + if (vm->error) + return; + vm->cache_fetch.n_pages = vpn; + vm->cache_fetch.page_addr = page_addr; + } + *value = vm->cache_fetch.page_addr[(addr >> 2) & MASK(RV_PAGE_SHIFT - 2)]; } static void mmu_load(vm_t *vm, @@ -347,6 +362,7 @@ void vm_trap(vm_t *vm) /* Set */ vm->sstatus_sie = false; + mmu_invalidate(vm); vm->s_mode = true; vm->pc = vm->stvec_addr; if (vm->stvec_vectored) @@ -359,6 +375,7 @@ static void op_sret(vm_t *vm) { /* Restore from stack */ vm->pc = vm->sepc; + mmu_invalidate(vm); vm->s_mode = vm->sstatus_spp; vm->sstatus_sie = vm->sstatus_spie; @@ -374,7 +391,7 @@ static void op_privileged(vm_t *vm, uint32_t insn) return; } if (insn & ((MASK(5) << 7) | (MASK(5) << 15))) { - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); return; } switch (decode_i_unsigned(insn)) { @@ -391,7 +408,7 @@ static void op_privileged(vm_t *vm, uint32_t insn) /* TODO: Implement this */ break; default: - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); break; } } @@ -415,20 +432,20 @@ static void csr_read(vm_t *vm, uint16_t addr, uint32_t *value) if ((addr >> 8) == 0xC) { uint16_t idx = addr & MASK(7); if (idx >= 0x20 || !(vm->s_mode || ((vm->scounteren >> idx) & 1))) - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); else { /* Use the instruction counter for all of the counters. * Ideally, reads should return the value before the increment, * and writes should set the value after the increment. However, * we do not expose any way to write the counters. */ - *value = (addr & (1 << 7)) ? vm->insn_count_hi : vm->insn_count; + *value = vm->insn_count >> ((addr & (1 << 7)) ? 32 : 0); } return; } if (!vm->s_mode) { - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); return; } @@ -471,14 +488,14 @@ static void csr_read(vm_t *vm, uint16_t addr, uint32_t *value) *value = vm->stval; break; default: - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); } } static void csr_write(vm_t *vm, uint16_t addr, uint32_t value) { if (!vm->s_mode) { - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); return; } @@ -523,7 +540,7 @@ static void csr_write(vm_t *vm, uint16_t addr, uint32_t value) vm->stval = value; break; default: - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); } } @@ -583,7 +600,7 @@ static void op_system(vm_t *vm, uint32_t insn) break; default: - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); return; } } @@ -594,8 +611,11 @@ static uint32_t op_mul(uint32_t insn, uint32_t a, uint32_t b) { /* TODO: Test ifunc7 zeros */ switch (decode_func3(insn)) { - case 0b000: /* MUL */ - return a * b; + case 0b000: { /* MUL */ + const int64_t _a = (int32_t) a; + const int64_t _b = (int32_t) b; + return ((uint64_t) (_a * _b)) & ((1ULL << 32) - 1); + } case 0b001: { /* MULH */ const int64_t _a = (int32_t) a; const int64_t _b = (int32_t) b; @@ -669,7 +689,7 @@ static bool op_jmp(vm_t *vm, uint32_t insn, uint32_t a, uint32_t b) case 0b101: /* BFUNC_BGE */ return ((int32_t) a) >= ((int32_t) b); } - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); return false; } @@ -704,7 +724,7 @@ static void op_jump_link(vm_t *vm, uint32_t insn, uint32_t addr) static void op_amo(vm_t *vm, uint32_t insn) { if (unlikely(decode_func3(insn) != 0b010 /* amo.w */)) - return vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + return vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); uint32_t addr = read_rs1(vm, insn); uint32_t value, value2; switch (decode_func5(insn)) { @@ -712,7 +732,7 @@ static void op_amo(vm_t *vm, uint32_t insn) if (addr & 0b11) return vm_set_exception(vm, RV_EXC_LOAD_MISALIGN, addr); if (decode_rs2(insn)) - return vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + return vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); mmu_load(vm, addr, RV_MEM_LW, &value, true); if (vm->error) return; @@ -755,11 +775,16 @@ static void op_amo(vm_t *vm, uint32_t insn) AMO_OP(value > value2 ? value : value2); break; default: - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); return; } } +void vm_init(vm_t *vm) +{ + mmu_invalidate(vm); +} + void vm_step(vm_t *vm) { if (unlikely(vm->error)) @@ -781,9 +806,8 @@ void vm_step(vm_t *vm) return; vm->pc += 4; + /* Assume no integer overflow */ vm->insn_count++; - if (!vm->insn_count) - vm->insn_count_hi++; uint32_t insn_opcode = insn & MASK(7), value; switch (insn_opcode) { @@ -836,7 +860,7 @@ void vm_step(vm_t *vm) /* TODO: implement for multi-threading */ break; default: - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); break; } break; @@ -847,7 +871,7 @@ void vm_step(vm_t *vm) op_system(vm, insn); break; default: - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); break; } } diff --git a/riscv.h b/riscv.h index c416384e..d318c317 100644 --- a/riscv.h +++ b/riscv.h @@ -29,10 +29,15 @@ typedef enum { ERR_USER, /**< user-specific error */ } vm_error_t; -/* To use the emulator, start by initializing a "vm_t" struct with zero values - * and set the required environment-supplied callbacks. You may also set other - * necessary fields such as argument registers and s_mode, ensuring that all - * field restrictions are met to avoid undefined behavior. +typedef struct { + uint32_t n_pages; + uint32_t *page_addr; +} mmu_cache_t; + +/* To use the emulator, start by initializing a vm_t object with zero values, + * invoke vm_init(), and set the required environment-supplied callbacks. You + * may also set other necessary fields such as argument registers and s_mode, + * ensuring that all field restrictions are met to avoid undefined behavior. * * Once the emulator is set up, execute the emulation loop by calling * "vm_step()" repeatedly. Each call attempts to execute a single instruction. @@ -63,7 +68,7 @@ struct __vm_internal { * utilized in these capacities and should not be modified between logical * resets. */ - uint32_t insn_count, insn_count_hi; + uint64_t insn_count; /* Instruction execution state must be set to "NONE" for instruction * execution to continue. If the state is not "NONE," the vm_step() @@ -77,6 +82,8 @@ struct __vm_internal { */ uint32_t exc_cause, exc_val; + mmu_cache_t cache_fetch; + /* Supervisor state */ bool s_mode; bool sstatus_spp; /**< state saved at trap */ @@ -101,7 +108,7 @@ struct __vm_internal { /* Memory access sets the vm->error to indicate failure. On successful * access, it reads or writes the specified "value". */ - void (*mem_fetch)(vm_t *vm, uint32_t addr, uint32_t *value); + void (*mem_fetch)(vm_t *vm, uint32_t n_pages, uint32_t **page_addr); void (*mem_load)(vm_t *vm, uint32_t addr, uint8_t width, uint32_t *value); void (*mem_store)(vm_t *vm, uint32_t addr, uint8_t width, uint32_t value); @@ -112,6 +119,8 @@ struct __vm_internal { uint32_t *(*mem_page_table)(const vm_t *vm, uint32_t ppn); }; +void vm_init(vm_t *vm); + /* Emulate the next instruction. This is a no-op if the error is already set. */ void vm_step(vm_t *vm); diff --git a/riscv_private.h b/riscv_private.h index c4d5e555..94a3007b 100644 --- a/riscv_private.h +++ b/riscv_private.h @@ -62,7 +62,7 @@ enum { enum { RV_EXC_PC_MISALIGN = 0, /**< Instruction address misaligned */ RV_EXC_FETCH_FAULT = 1, /**< Instruction access fault */ - RV_EXC_ILLEGAL_INSTR = 2, /**< Illegal instruction */ + RV_EXC_ILLEGAL_INSN = 2, /**< Illegal instruction */ RV_EXC_BREAKPOINT = 3, /**< Breakpoint */ RV_EXC_LOAD_MISALIGN = 4, /**< Load address misaligned */ RV_EXC_LOAD_FAULT = 5, /**< Load access fault */ diff --git a/scripts/build-image.sh b/scripts/build-image.sh index 3d0cdd5a..cb8f3c15 100755 --- a/scripts/build-image.sh +++ b/scripts/build-image.sh @@ -21,7 +21,7 @@ PARALLEL="-j$(nproc)" function do_buildroot { - ASSERT git clone https://github.com/buildroot/buildroot -b 2023.05.1 --depth=1 + ASSERT git clone https://github.com/buildroot/buildroot -b 2023.11.x --depth=1 cp -f configs/buildroot.config buildroot/.config cp -f configs/busybox.config buildroot/busybox.config # Otherwise, the error below raises: diff --git a/uart.c b/uart.c index e9f0b443..bb0e0a7f 100644 --- a/uart.c +++ b/uart.c @@ -182,7 +182,7 @@ void u8250_read(vm_t *vm, vm_set_exception(vm, RV_EXC_LOAD_MISALIGN, vm->exc_val); return; default: - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); return; } } @@ -202,7 +202,7 @@ void u8250_write(vm_t *vm, vm_set_exception(vm, RV_EXC_STORE_MISALIGN, vm->exc_val); return; default: - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); return; } } diff --git a/virtio-blk.c b/virtio-blk.c index 0b1988e1..4fb6715f 100644 --- a/virtio-blk.c +++ b/virtio-blk.c @@ -106,7 +106,7 @@ static void virtio_blk_write_handler(virtio_blk_state_t *vblk, uint32_t len) { void *dest = (void *) ((uintptr_t) vblk->disk + sector * DISK_BLK_SIZE); - void *src = (void *) ((uintptr_t) vblk->ram + desc_addr); + const void *src = (void *) ((uintptr_t) vblk->ram + desc_addr); memcpy(dest, src, len); } @@ -116,7 +116,8 @@ static void virtio_blk_read_handler(virtio_blk_state_t *vblk, uint32_t len) { void *dest = (void *) ((uintptr_t) vblk->ram + desc_addr); - void *src = (void *) ((uintptr_t) vblk->disk + sector * DISK_BLK_SIZE); + const void *src = + (void *) ((uintptr_t) vblk->disk + sector * DISK_BLK_SIZE); memcpy(dest, src, len); } @@ -140,7 +141,7 @@ static int virtio_blk_desc_handler(virtio_blk_state_t *vblk, /* Collect the descriptors */ for (int i = 0; i < 3; i++) { /* The size of the `struct virtq_desc` is 4 words */ - uint32_t *desc = &vblk->ram[queue->QueueDesc + desc_idx * 4]; + const uint32_t *desc = &vblk->ram[queue->QueueDesc + desc_idx * 4]; /* Retrieve the fields of current descriptor */ vq_desc[i].addr = desc[0]; @@ -162,7 +163,7 @@ static int virtio_blk_desc_handler(virtio_blk_state_t *vblk, } /* Process the header */ - struct vblk_req_header *header = + const struct vblk_req_header *header = (struct vblk_req_header *) ((uintptr_t) vblk->ram + vq_desc[0].addr); uint32_t type = header->type; uint64_t sector = header->sector; @@ -403,7 +404,7 @@ void virtio_blk_read(vm_t *vm, vm_set_exception(vm, RV_EXC_LOAD_MISALIGN, vm->exc_val); return; default: - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); return; } } @@ -424,7 +425,7 @@ void virtio_blk_write(vm_t *vm, vm_set_exception(vm, RV_EXC_STORE_MISALIGN, vm->exc_val); return; default: - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); return; } } diff --git a/virtio-gpu.c b/virtio-gpu.c index 134cc582..96b1da22 100644 --- a/virtio-gpu.c +++ b/virtio-gpu.c @@ -1026,7 +1026,7 @@ void virtio_gpu_read(vm_t *vm, vm_set_exception(vm, RV_EXC_LOAD_MISALIGN, vm->exc_val); return; default: - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); return; } } @@ -1047,7 +1047,7 @@ void virtio_gpu_write(vm_t *vm, vm_set_exception(vm, RV_EXC_STORE_MISALIGN, vm->exc_val); return; default: - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); return; } } diff --git a/virtio-net.c b/virtio-net.c index ddb7e47b..da1d7df1 100644 --- a/virtio-net.c +++ b/virtio-net.c @@ -116,15 +116,15 @@ static bool vnet_iovec_read(struct iovec **vecs, /* Require existing 'desc_idx' to use as iteration variable, and input * 'buffer_idx'. */ -#define VNET_ITERATE_BUFFER(checked, body) \ - desc_idx = buffer_idx; \ - while (1) { \ - if (checked && desc_idx >= queue->QueueNum) \ - return virtio_net_set_fail(vnet); \ - uint32_t *desc = &ram[queue->QueueDesc + desc_idx * 4]; \ - uint16_t desc_flags = desc[3]; \ - body if (!(desc_flags & VIRTIO_DESC_F_NEXT)) break; \ - desc_idx = desc[3] >> 16; \ +#define VNET_ITERATE_BUFFER(checked, body) \ + desc_idx = buffer_idx; \ + while (1) { \ + if (checked && desc_idx >= queue->QueueNum) \ + return virtio_net_set_fail(vnet); \ + const uint32_t *desc = &ram[queue->QueueDesc + desc_idx * 4]; \ + uint16_t desc_flags = desc[3]; \ + body if (!(desc_flags & VIRTIO_DESC_F_NEXT)) break; \ + desc_idx = desc[3] >> 16; \ } /* Input: 'buffer_idx'. @@ -407,7 +407,7 @@ void virtio_net_read(vm_t *vm, vm_set_exception(vm, RV_EXC_LOAD_MISALIGN, vm->exc_val); return; default: - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); return; } } @@ -428,7 +428,7 @@ void virtio_net_write(vm_t *vm, vm_set_exception(vm, RV_EXC_STORE_MISALIGN, vm->exc_val); return; default: - vm_set_exception(vm, RV_EXC_ILLEGAL_INSTR, 0); + vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0); return; } }