From 7bf965b755b667f7da05e0995c2f09c54a8a2f11 Mon Sep 17 00:00:00 2001 From: Alejandro Soto Date: Thu, 15 Dec 2022 00:41:05 -0600 Subject: Implement swi (system call) --- rtl/core/control/exception.sv | 15 +++++++++++---- rtl/core/decode/decode.sv | 3 ++- rtl/core/decode/mux.sv | 13 ++++++++++--- rtl/core/uarch.sv | 1 + sim/start.S | 17 +++++++---------- tb/sim/syscall.S | 17 +++++++++++++++++ tb/sim/syscall.py | 2 ++ 7 files changed, 50 insertions(+), 18 deletions(-) create mode 100644 tb/sim/syscall.S create mode 100644 tb/sim/syscall.py diff --git a/rtl/core/control/exception.sv b/rtl/core/control/exception.sv index 02560a6..21adb19 100644 --- a/rtl/core/control/exception.sv +++ b/rtl/core/control/exception.sv @@ -6,6 +6,7 @@ module core_control_exception rst_n, input ctrl_cycle next_cycle, + input insn_decode dec, input psr_intmask intmask, input logic issue, irq, @@ -20,23 +21,26 @@ module core_control_exception output word exception_vector ); - logic pending_irq; + logic pending_irq, syscall; logic[2:0] vector_offset; - //TODO: irq, fiq, prefetch abort, swi + //TODO: fiq - assign exception = undefined || prefetch_abort || mem_fault || pending_irq; + assign exception = undefined || syscall || prefetch_abort || mem_fault || pending_irq; assign exception_vector = {{16{high_vectors}}, 11'b0, vector_offset, 2'b00}; always @(posedge clk or negedge rst_n) begin if(!rst_n) begin + syscall <= 0; pending_irq <= 0; vector_offset <= 0; exception_mode <= 0; exception_offset_pc <= 0; end begin - if(next_cycle.issue) + if(next_cycle.issue) begin + syscall <= issue && dec.ctrl.swi; pending_irq <= issue && irq && !intmask.i; + end // A2.6.10 Exception priorities if(mem_fault) begin @@ -51,6 +55,9 @@ module core_control_exception end else if(undefined) begin vector_offset <= 3'b001; exception_mode <= `MODE_UND; + end else if(syscall) begin + vector_offset <= 3'b010; + exception_mode <= `MODE_SVC; end end diff --git a/rtl/core/decode/decode.sv b/rtl/core/decode/decode.sv index c4ffd52..b00e06f 100644 --- a/rtl/core/decode/decode.sv +++ b/rtl/core/decode/decode.sv @@ -28,6 +28,7 @@ module core_decode assign dec_ctrl.nop = 0; assign dec_ctrl.mul = mul; + assign dec_ctrl.swi = swi; assign dec_ctrl.psr = psr; assign dec_ctrl.ldst = ldst; assign dec_ctrl.bkpt = bkpt; @@ -46,7 +47,7 @@ module core_decode assign dec_psr.restore_spsr = restore_spsr; logic execute, undefined, conditional, writeback, update_flags, - restore_spsr, branch, ldst, mul, psr, coproc, bkpt, + restore_spsr, branch, ldst, mul, swi, psr, coproc, bkpt, psr_saved, psr_write, psr_wr_flags, psr_wr_control; core_decode_mux mux diff --git a/rtl/core/decode/mux.sv b/rtl/core/decode/mux.sv index 25e390b..297ad33 100644 --- a/rtl/core/decode/mux.sv +++ b/rtl/core/decode/mux.sv @@ -56,6 +56,7 @@ module core_decode_mux ldst, mul, psr, + swi, coproc, bkpt, psr_saved, @@ -71,6 +72,8 @@ module core_decode_mux always_comb begin mul = 0; + swi = 0; + psr = 0; ldst = 0; bkpt = 0; branch = 0; @@ -81,7 +84,6 @@ module core_decode_mux conditional = 0; restore_spsr = 0; - psr = 0; psr_saved = 0; psr_write = 0; update_flags = 0; @@ -215,8 +217,13 @@ module core_decode_mux psr_wr_control = msr_fields.c; end - /*`GROUP_SWP: ; - `INSN_SWI: ;*/ + // WONTFIX: + //`GROUP_SWP: ; + + `INSN_SWI: begin + swi = 1; + dec_data.uses_rn = 0; + end /* No es parte de ARMv4 pero U-Boot lo necesita. esto se * decodifica igual que `mov pc, lr` ya que no tenemos Thumb. diff --git a/rtl/core/uarch.sv b/rtl/core/uarch.sv index 8ef0ae7..82dc1dc 100644 --- a/rtl/core/uarch.sv +++ b/rtl/core/uarch.sv @@ -88,6 +88,7 @@ typedef struct packed ldst, mul, psr, + swi, nop, bkpt; } ctrl_decode; diff --git a/sim/start.S b/sim/start.S index 65c49c1..28ff728 100644 --- a/sim/start.S +++ b/sim/start.S @@ -7,7 +7,7 @@ __undefined: b undefined __swi: - b . + b swi __prefetch_abort: b prefetch_abort @@ -30,14 +30,11 @@ __fiq: _start: ldr sp, =_stack_end bl reset - -.global halt -halt: -exc_default: b . -.weak undefined, data_abort, prefetch_abort, irq -.set undefined, exc_default -.set data_abort, exc_default -.set prefetch_abort, exc_default -.set irq, exc_default +.weak undefined, swi, data_abort, prefetch_abort, irq +.set swi, __swi +.set undefined, __undefined +.set data_abort, __data_abort +.set prefetch_abort, __prefetch_abort +.set irq, __irq diff --git a/tb/sim/syscall.S b/tb/sim/syscall.S new file mode 100644 index 0000000..a1f7422 --- /dev/null +++ b/tb/sim/syscall.S @@ -0,0 +1,17 @@ +.global reset +reset: + # Switch to user mode + mov r0, lr + mrs r1, cpsr + bic r1, r1, #0b1111 + msr cpsr_fxc, r1 + mov lr, r0 + + mov r0, #123 + swi #0 + mov pc, lr + +.global swi +swi: + add r0, r0, #1 + movs pc, r14 diff --git a/tb/sim/syscall.py b/tb/sim/syscall.py new file mode 100644 index 0000000..cfb9859 --- /dev/null +++ b/tb/sim/syscall.py @@ -0,0 +1,2 @@ +def final(): + assert_reg(r0, 124) -- cgit v1.2.3