Skip to content

Commit c49c32b

Browse files
committed
core: Implement DEXCR and HDEXCR registers
Of the defined aspect bits (which are all read-write), only the NPHIE and PHIE bits have any function at all, since Microwatt is an in-order single-issue machine and never does any branch speculation. Also, since there is no privileged non-hypervisor mode, the high 32 bits of DEXCR do nothing. Signed-off-by: Paul Mackerras <[email protected]>
1 parent bae24b1 commit c49c32b

File tree

4 files changed

+75
-3
lines changed

4 files changed

+75
-3
lines changed

common.vhdl

+23-1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ package common is
7171
constant SPR_DAWRX1 : spr_num_t := 189;
7272
constant SPR_HASHKEYR : spr_num_t := 468;
7373
constant SPR_HASHPKEYR : spr_num_t := 469;
74+
constant SPR_DEXCR : spr_num_t := 828;
75+
constant SPR_DEXCRU : spr_num_t := 812;
76+
constant SPR_HDEXCR : spr_num_t := 471;
77+
constant SPR_HDEXCU : spr_num_t := 455;
7478

7579
-- PMU registers
7680
constant SPR_UPMC1 : spr_num_t := 771;
@@ -184,6 +188,7 @@ package common is
184188
constant SPRSEL_DSCR : spr_selector := 4x"b";
185189
constant SPRSEL_PIR : spr_selector := 4x"c";
186190
constant SPRSEL_CIABR : spr_selector := 4x"d";
191+
constant SPRSEL_DEXCR : spr_selector := 4x"e";
187192
constant SPRSEL_XER : spr_selector := 4x"f";
188193

189194
-- FSCR and HFSCR bit numbers
@@ -266,6 +271,16 @@ package common is
266271
pri : std_ulogic_vector(31 downto 0); -- 8 bits each for 4 cpus
267272
end record;
268273

274+
-- Bits in each half of DEXCR and HDEXCR
275+
subtype aspect_bits_t is std_ulogic_vector(4 downto 0);
276+
constant aspect_bits_init : aspect_bits_t := (others => '1');
277+
-- Bit numbers in aspect_bits_t
278+
constant DEXCR_SBHE : integer := 4; -- speculative branch hint enable
279+
constant DEXCR_IBRTPD : integer := 3; -- indirect branch recurrent target prediction disable
280+
constant DEXCR_SRAPD : integer := 2; -- subroutine return address prediction disable
281+
constant DEXCR_NPHIE : integer := 1; -- non-privileged hash instruction enable
282+
constant DEXCR_PHIE : integer := 0; -- privileged hash instruction enable
283+
269284
-- This needs to die...
270285
type ctrl_t is record
271286
wait_state: std_ulogic;
@@ -287,12 +302,18 @@ package common is
287302
heir: std_ulogic_vector(63 downto 0);
288303
dscr: std_ulogic_vector(24 downto 0);
289304
ciabr: std_ulogic_vector(63 downto 0);
305+
dexcr_pnh: aspect_bits_t;
306+
dexcr_pro: aspect_bits_t;
307+
hdexcr_hyp: aspect_bits_t;
308+
hdexcr_enf: aspect_bits_t;
290309
end record;
291310
constant ctrl_t_init : ctrl_t :=
292311
(wait_state => '0', run => '1', xer_low => 18x"0",
293312
fscr_ic => x"0", fscr_pref => '1', fscr_scv => '1', fscr_tar => '1', fscr_dscr => '1',
294313
hfscr_ic => x"0", hfscr_pref => '1', hfscr_tar => '1', hfscr_dscr => '1', hfscr_fp => '1',
295314
dscr => (others => '0'),
315+
dexcr_pnh => aspect_bits_init, dexcr_pro => aspect_bits_init,
316+
hdexcr_hyp => aspect_bits_init, hdexcr_enf => aspect_bits_init,
296317
others => (others => '0'));
297318

298319
type Fetch1ToIcacheType is record
@@ -604,6 +625,7 @@ package common is
604625
e2stall : std_ulogic;
605626
msr : std_ulogic_vector(63 downto 0);
606627
hashkey : std_ulogic_vector(63 downto 0);
628+
hash_enable : std_ulogic;
607629
end record;
608630
constant Execute1ToLoadstore1Init : Execute1ToLoadstore1Type :=
609631
(valid => '0', op => OP_ILLEGAL, ci => '0', byte_reverse => '0',
@@ -616,7 +638,7 @@ package common is
616638
length => (others => '0'),
617639
mode_32bit => '0', is_32bit => '0', prefixed => '0',
618640
repeat => '0', second => '0', e2stall => '0',
619-
msr => (others => '0'), hashkey => (others => '0'));
641+
msr => (others => '0'), hashkey => (others => '0'), hash_enable => '0');
620642

621643
type Loadstore1ToExecute1Type is record
622644
busy : std_ulogic;

decode1.vhdl

+5
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,11 @@ architecture behaviour of decode1 is
499499
i.sel := SPRSEL_PIR;
500500
when SPR_CIABR =>
501501
i.sel := SPRSEL_CIABR;
502+
when SPR_DEXCR | SPR_HDEXCR =>
503+
i.sel := SPRSEL_DEXCR;
504+
when SPR_DEXCRU | SPR_HDEXCU =>
505+
i.sel := SPRSEL_DEXCR;
506+
i.ronly := '1';
502507
when others =>
503508
i.valid := '0';
504509
end case;

execute1.vhdl

+40
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,32 @@ architecture behaviour of execute1 is
425425
return ret;
426426
end;
427427

428+
-- return contents of DEXCR or HDEXCR
429+
-- top 32 bits are zeroed for access via non-privileged number
430+
function assemble_dexcr(c: ctrl_t; insn: std_ulogic_vector(31 downto 0)) return std_ulogic_vector is
431+
variable ret : std_ulogic_vector(63 downto 0);
432+
variable spr : std_ulogic_vector(9 downto 0);
433+
variable dexh, dexl : aspect_bits_t;
434+
begin
435+
ret := (others => '0');
436+
spr := insn(15 downto 11) & insn(20 downto 16);
437+
if spr(9) = '1' then
438+
dexh := c.dexcr_pnh;
439+
dexl := c.dexcr_pro;
440+
else
441+
dexh := c.hdexcr_hyp;
442+
dexl := c.hdexcr_enf;
443+
end if;
444+
if spr(4) = '0' then
445+
dexl := (others => '0');
446+
end if;
447+
ret := dexh(DEXCR_SBHE) & "00" & dexh(DEXCR_IBRTPD) & dexh(DEXCR_SRAPD) &
448+
dexh(DEXCR_NPHIE) & dexh(DEXCR_PHIE) & 25x"0" &
449+
dexl(DEXCR_SBHE) & "00" & dexl(DEXCR_IBRTPD) & dexl(DEXCR_SRAPD) &
450+
dexl(DEXCR_NPHIE) & dexl(DEXCR_PHIE) & 25x"0";
451+
return ret;
452+
end;
453+
428454
-- Tell vivado to keep the hierarchy for the random module so that the
429455
-- net names in the xdc file match.
430456
attribute keep_hierarchy : string;
@@ -1600,6 +1626,7 @@ begin
16001626
variable go : std_ulogic;
16011627
variable bypass_valid : std_ulogic;
16021628
variable is_scv : std_ulogic;
1629+
variable dex : aspect_bits_t;
16031630
begin
16041631
v := ex1;
16051632
if busy_out = '0' then
@@ -1735,6 +1762,13 @@ begin
17351762
bperm_start <= go and actions.start_bperm;
17361763
pmu_trace <= go and actions.do_trace;
17371764

1765+
-- evaluate DEXCR/HDEXCR bits that apply at present
1766+
if ex1.msr(MSR_PR) = '0' then
1767+
dex := ctrl.hdexcr_hyp;
1768+
else
1769+
dex := ctrl.dexcr_pro or ctrl.hdexcr_enf;
1770+
end if;
1771+
17381772
if not HAS_FPU and ex1.div_in_progress = '1' then
17391773
v.div_in_progress := not divider_to_x.valid;
17401774
v.busy := not divider_to_x.valid;
@@ -1850,6 +1884,11 @@ begin
18501884
lv.second := e_in.second;
18511885
lv.e2stall := fp_in.f2stall;
18521886
lv.hashkey := ramspr_odd;
1887+
if e_in.insn(7) = '0' then
1888+
lv.hash_enable := dex(DEXCR_PHIE);
1889+
else
1890+
lv.hash_enable := dex(DEXCR_NPHIE);
1891+
end if;
18531892

18541893
-- Outputs to FPU
18551894
fv.op := e_in.insn_type;
@@ -1897,6 +1936,7 @@ begin
18971936
39x"0" & ctrl.dscr when SPRSEL_DSCR,
18981937
56x"0" & std_ulogic_vector(to_unsigned(CPU_INDEX, 8)) when SPRSEL_PIR,
18991938
ctrl.ciabr when SPRSEL_CIABR,
1939+
assemble_dexcr(ctrl, ex1.insn) when SPRSEL_DEXCR,
19001940
assemble_xer(ex1.e.xerc, ctrl.xer_low) when others;
19011941

19021942
stage2_stall <= l_in.l2stall or fp_in.f2stall;

loadstore1.vhdl

+7-2
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,7 @@ begin
565565
variable sprn : std_ulogic_vector(9 downto 0);
566566
variable misaligned : std_ulogic;
567567
variable addr_mask : std_ulogic_vector(2 downto 0);
568+
variable hash_nop : std_ulogic;
568569
begin
569570
v := request_init;
570571
sprn := l_in.insn(15 downto 11) & l_in.insn(20 downto 16);
@@ -641,7 +642,7 @@ begin
641642
if l_in.repeat = '1' and l_in.update = '0' and addr(3) /= l_in.second then
642643
misaligned := '1';
643644
end if;
644-
v.align_intr := (l_in.reserve or l_in.hash) and misaligned;
645+
v.align_intr := (l_in.reserve or (l_in.hash and l_in.hash_enable)) and misaligned;
645646

646647
v.atomic_first := not misaligned and not l_in.second;
647648
v.atomic_last := not misaligned and (l_in.second or not l_in.repeat);
@@ -661,6 +662,7 @@ begin
661662
end if;
662663
end if;
663664

665+
hash_nop := '0';
664666
case l_in.op is
665667
when OP_SYNC =>
666668
v.sync := '1';
@@ -671,6 +673,7 @@ begin
671673
v.touch := '1';
672674
end if;
673675
v.hashst := l_in.hash;
676+
hash_nop := not l_in.hash_enable;
674677
when OP_LOAD =>
675678
if l_in.update = '0' or l_in.second = '0' then
676679
v.load := '1';
@@ -686,6 +689,7 @@ begin
686689
v.do_update := '1';
687690
end if;
688691
v.hashcmp := l_in.hash;
692+
hash_nop := not l_in.hash_enable;
689693
when OP_DCBF =>
690694
v.load := '1';
691695
v.flush := '1';
@@ -709,7 +713,8 @@ begin
709713
v.mmu_op := '1';
710714
when others =>
711715
end case;
712-
v.dc_req := l_in.valid and (v.load or v.store or v.sync or v.dcbz) and not v.align_intr;
716+
v.dc_req := l_in.valid and (v.load or v.store or v.sync or v.dcbz) and not v.align_intr and
717+
not hash_nop;
713718
v.incomplete := v.dc_req and v.two_dwords;
714719

715720
-- Work out controls for load and store formatting

0 commit comments

Comments
 (0)