Skip to content

Commit 98f2d2b

Browse files
committed
Implement mcounteren and scounteren
1 parent 86bc52e commit 98f2d2b

File tree

2 files changed

+36
-10
lines changed

2 files changed

+36
-10
lines changed

src/cpu/cpu.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ csrs:
133133
read: minstret
134134
hpmcounter{}:
135135
args: !py!range [3, 32]
136-
read: zero
136+
read: hpmcounter
137137
cycleh:
138138
read: LABEL
139139
timeh:
@@ -142,7 +142,7 @@ csrs:
142142
read: minstreth
143143
hpmcounter{}h:
144144
args: !py!range [3, 32]
145-
read: zero
145+
read: hpmcounter
146146

147147
# -- supervisor --
148148

src/cpu/worker.mlog.jinja

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2489,32 +2489,30 @@ csr_write_satp:
24892489
# TODO: this may not be strictly required by the spec
24902490
jump end_instruction_with_rd_and_invalidate_icache always
24912491

2492-
# FIXME: add support for mcounteren/scounteren
2493-
24942492
csr_read_cycle:
24952493
#% do declare_locals(modify_csr_locals)
24962494
read rd {{CSRS}} "{{ 'mcycle'|csr }}"
2497-
set @counter $$modify_csr_op
2495+
jump check_xcounteren always
24982496

24992497
csr_read_cycleh:
25002498
#% do declare_locals(modify_csr_locals)
25012499
read rd {{CSRS}} "{{ 'mcycleh'|csr }}"
2502-
set @counter $$modify_csr_op
2500+
jump check_xcounteren always
25032501

25042502
csr_read_time:
25052503
#% do declare_locals(modify_csr_locals)
25062504
set rd csr_mtime
2507-
set @counter $$modify_csr_op
2505+
jump check_xcounteren always
25082506

25092507
csr_read_timeh:
25102508
#% do declare_locals(modify_csr_locals)
25112509
set rd csr_mtimeh
2512-
set @counter $$modify_csr_op
2510+
jump check_xcounteren always
25132511

25142512
csr_read_minstret:
25152513
#% do declare_locals(modify_csr_locals)
25162514
set rd csr_minstret
2517-
set @counter $$modify_csr_op
2515+
jump check_xcounteren always
25182516

25192517
csr_write_minstret:
25202518
# a value written to instret by one instruction should be the value read by the following instruction
@@ -2524,14 +2522,41 @@ csr_write_minstret:
25242522
csr_read_minstreth:
25252523
#% do declare_locals(modify_csr_locals)
25262524
set rd csr_minstreth
2527-
set @counter $$modify_csr_op
2525+
jump check_xcounteren always
25282526

25292527
csr_write_minstreth:
25302528
# a value written to instret by one instruction should be the value read by the following instruction
25312529
op sub csr_minstret csr_minstret 1
25322530
set csr_minstreth result
25332531
jump end_instruction_with_rd always
25342532

2533+
csr_read_hpmcounter:
2534+
#% do declare_locals(modify_csr_locals)
2535+
set rd 0
2536+
# continue into check_xcounteren
2537+
2538+
check_xcounteren:
2539+
# if in M-mode, always allow counter accesses
2540+
jump check_xcounteren__m_mode equal privilege_mode 0b11
2541+
2542+
# if in S-mode, only require the bit to be set in mcounteren
2543+
read $xcounteren {{CSRS}} "{{ 'mcounteren'|csr }}"
2544+
jump check_xcounteren__s_mode equal privilege_mode 0b01
2545+
2546+
# if in U-mode, also require the bit to be set in scounteren
2547+
read $scounteren {{CSRS}} "{{ 'scounteren'|csr }}"
2548+
op and $xcounteren $xcounteren $scounteren
2549+
check_xcounteren__s_mode:
2550+
2551+
# trap if the bit in xcounteren corresponding to the CSR being read is clear
2552+
op and $bit imm 31
2553+
op shr $bit $xcounteren $bit
2554+
op and $bit $bit 0b1
2555+
jump ILLEGAL_OP equal $bit 0
2556+
2557+
check_xcounteren__m_mode:
2558+
set @counter $$modify_csr_op
2559+
25352560
MLOGSYS:
25362561
# I-type: rs1, imm=funct12, rd_id
25372562

@@ -2684,6 +2709,7 @@ jump decode_SYSTEM always
26842709
jump csr_read_cycle always
26852710
jump csr_read_time always
26862711
jump csr_read_minstret always
2712+
jump csr_read_hpmcounter always
26872713
jump csr_read_zero always
26882714
jump csr_read_cycleh always
26892715
jump csr_read_timeh always

0 commit comments

Comments
 (0)