Skip to content

Commit d27423b

Browse files
committed
Update csr_mip handling to allow atomic modification from controller, move interrupt_flags into mip[31:30]
1 parent 548613c commit d27423b

File tree

2 files changed

+23
-32
lines changed

2 files changed

+23
-32
lines changed

src/cpu/controller.mlog.jinja

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,6 @@ end_slow_init:
175175
# clear pending/enabled interrupts
176176
set csr_mip 0
177177
set csr_mie 0
178-
set interrupt_flags 0b00
179178

180179
# reset mtvec and stvec to implementation-defined value to help catch bugs
181180
write {{SYSCON}} {{CSRS}} "{{ 'mtvec'|csr }}"
@@ -281,7 +280,8 @@ end_breakpoint:
281280
set last_mcycle_update @tick
282281

283282
# tell the next worker to poll and fire interrupts
284-
write 0b11 prev_proc "interrupt_flags"
283+
op or csr_mip csr_mip 0b11000000000000000000000000000000
284+
write csr_mip prev_proc "csr_mip"
285285

286286
# go to next tick
287287

@@ -385,5 +385,4 @@ set _ csr_mstatus
385385
set _ csr_mip
386386
set _ csr_mie
387387
set _ csr_satp
388-
set _ interrupt_flags
389388
# {% endraw %}

src/cpu/worker.mlog.jinja

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
read icache_ram prev_proc "icache_ram"
1919
read icache_var prev_proc "icache_var"
2020
read imm prev_proc "imm"
21-
read interrupt_flags prev_proc "interrupt_flags"
2221
read length prev_proc "length"
2322
read mcause prev_proc "mcause"
2423
read mtval prev_proc "mtval"
@@ -91,7 +90,7 @@
9190

9291
#% set labels.next_tick = 11
9392

94-
#% set labels.end_instruction_with_rd_and_poll_interrupts = 144
93+
#% set labels.end_instruction_with_rd_and_poll_interrupts = 142
9594
#% set labels.end_instruction_with_rd_and_fire_interrupts = _labels_vals|last + 1
9695
#% set labels.end_instruction_with_rd = _labels_vals|last + 1
9796
#% set labels.end_instruction = _labels_vals|last + 2
@@ -154,8 +153,6 @@ reset:
154153
# this runs at the start of the first worker each tick, and at the start of the next worker if certain CSRs/MMRs are modified
155154
poll_interrupts:
156155
#% do reset_locals()
157-
op and interrupt_flags interrupt_flags 0b01 # clear interrupt_flags.poll
158-
159156
# machine timer interrupt
160157
op greaterThan $high_gt csr_mtimeh csr_mtimecmph
161158
op equal $high_eq csr_mtimeh csr_mtimecmph
@@ -165,14 +162,16 @@ poll_interrupts:
165162
op or $mip.mtip $mip.mtip $high_gt
166163
op shl $mip.mtip $mip.mtip 7
167164

168-
op and csr_mip csr_mip 0b11111111111111111111111101111111
165+
# poll -
166+
# mtip -
167+
op and csr_mip csr_mip 0b01111111111111111111111101111111
169168
op or csr_mip csr_mip $mip.mtip
170169

171170
# check if interrupts should fire
172171
# this runs at the start of the first worker each tick, if certain CSRs are modified, and after an xRET instruction
173172
fire_interrupts:
174173
#% do reset_locals()
175-
op and interrupt_flags interrupt_flags 0b10 # clear interrupt_flags.fire
174+
op and csr_mip csr_mip 0b10111111111111111111111111111111 # clear interrupt_flags.fire
176175

177176
# if privilege_mode < M, machine interrupts are globally enabled
178177
jump fire_interrupts__machine lessThan privilege_mode 0b11
@@ -302,13 +301,13 @@ main__no_breakpoint:
302301
# this is a normal length for a label
303302
#directive assert_counter {{ labels.end_instruction_with_rd_and_poll_interrupts }}
304303
end_instruction_with_rd_and_poll_interrupts:
305-
op or interrupt_flags interrupt_flags 0b10 # set interrupt_flags.poll
304+
op or csr_mip csr_mip 0b10000000000000000000000000000000 # set interrupt_flags.poll
306305
# continue into end_instruction_with_rd_and_fire_interrupts
307306

308307
# this is too
309308
#directive assert_counter {{ labels.end_instruction_with_rd_and_fire_interrupts }}
310309
end_instruction_with_rd_and_fire_interrupts:
311-
op or interrupt_flags interrupt_flags 0b01 # set interrupt_flags.fire
310+
op or csr_mip csr_mip 0b01000000000000000000000000000000 # set interrupt_flags.fire
312311
# continue into end_instruction_with_rd
313312

314313
# most instructions with an output register jump here after completing successfully
@@ -337,8 +336,8 @@ end_instruction_trap:
337336
# if next_pc was modified, icache_var should have also been set to null
338337
set pc next_pc
339338

340-
jump main equal interrupt_flags 0b00
341-
jump poll_interrupts greaterThanEq interrupt_flags 0b10
339+
jump main lessThan csr_mip 0b01000000000000000000000000000000
340+
jump poll_interrupts greaterThanEq csr_mip 0b10000000000000000000000000000000
342341
jump fire_interrupts always
343342

344343
# exceptions
@@ -2097,7 +2096,7 @@ WFI:
20972096
# however, it seems like another valid implementation is to just stall for a bounded amount of time
20982097
# since the wait is bounded, we don't need to check mstatus.TW
20992098
# we check interrupt_flags first to avoid unnecessarily stalling if there may be an interrupt ready
2100-
jump end_instruction notEqual interrupt_flags 0b00
2099+
jump end_instruction greaterThanEq csr_mip 0b01000000000000000000000000000000
21012100

21022101
set state "pause"
21032102
wait 1e-5
@@ -2489,11 +2488,11 @@ modify_csr__sip:
24892488
#% do reset_locals(modify_csr_start)
24902489
#% do declare_locals(modify_csr_locals)
24912490
# subset of mip
2492-
# platform ----------------
2491+
# platform --------------
24932492
# SEIP -
24942493
# STIP -
24952494
# SSIP -
2496-
op and rd csr_mip 0b11111111111111110000001000100010
2495+
op and rd csr_mip 0b00111111111111110000001000100010
24972496

24982497
op add $$modify_csr_write @counter 1
24992498
set @counter $$modify_csr_op
@@ -2509,25 +2508,19 @@ modify_csr__sip:
25092508
modify_csr__mip:
25102509
#% do reset_locals(modify_csr_start)
25112510
#% do declare_locals(modify_csr_locals)
2512-
set rd csr_mip
2511+
# hide internal interrupt flags
2512+
op and rd csr_mip 0b00111111111111111111111111111111
25132513

25142514
op add $$modify_csr_write @counter 1
25152515
set @counter $$modify_csr_op
25162516

2517-
# get current read-only non-zero fields
2518-
# MEIP -
2519-
# MTIP -
2520-
op and $tmp csr_mip 0b00000000000000000000100010000000
2521-
2522-
# get new writable fields
2523-
# SEIP -
2524-
# STIP -
2525-
# SSIP -
2526-
op and csr_mip $$new_value 0b00000000000000000000001000100010
2527-
2528-
# merge read-only and writable fields
2529-
# all other fields are read-only zero
2530-
op or csr_mip csr_mip $tmp
2517+
# insert new writable fields
2518+
# SEIP -
2519+
# STIP -
2520+
# SSIP -
2521+
op and csr_mip csr_mip 0b11111111111111111111110111011101
2522+
op and $$new_value $$new_value 0b00000000000000000000001000100010
2523+
op or csr_mip csr_mip $$new_value
25312524

25322525
jump end_instruction_with_rd_and_fire_interrupts always
25332526

@@ -2778,7 +2771,6 @@ jump SRLI always
27782771
jump SRAI always
27792772
jump ILLEGAL_OP always
27802773
jump MLOGSYS always
2781-
jump END_BREAKPOINT always
27822774
jump decode_LOAD always
27832775
jump decode_custom-0 always
27842776
jump decode_MISC-MEM always

0 commit comments

Comments
 (0)