Bug 491 - MMU Function Unit needed
Summary: MMU Function Unit needed
Status: RESOLVED FIXED
Alias: None
Product: Libre-SOC's first SoC
Classification: Unclassified
Component: Source Code (show other bugs)
Version: unspecified
Hardware: Other Linux
: High enhancement
Deadline: 2022-01-01
Assignee: Luke Kenneth Casson Leighton
URL:
Depends on: 525 636 450 469 485 756
Blocks: 51 262 383 690
  Show dependency treegraph
 
Reported: 2020-09-15 00:36 BST by Luke Kenneth Casson Leighton
Modified: 2022-08-29 23:05 BST (History)
3 users (show)

See Also:
NLnet milestone: NLnet.2019.02.012
total budget (EUR) for completion of task and all subtasks: 1450
budget (EUR) for this task, excluding subtasks' budget: 1450
parent task for budget allocation: 51
child tasks for budget allocation:
The table of payments (in EUR) for this task; TOML format:
[tplaten] amount = 1000 submitted = 2022-06-16 paid = 2022-07-20 [lkcl] amount = 450 submitted = 2022-06-16 paid = 2022-07-21


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Luke Kenneth Casson Leighton 2020-09-15 00:36:17 BST
some opcodes such as tlbie and dcbz as well as those setting pte all really need to be in their own Function Unit.

https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/fu/mmu/fsm.py;hb=HEAD

TODO: move LoadStore1 into fu/ldst (DONE)
Comment 1 Luke Kenneth Casson Leighton 2020-09-15 10:56:28 BST
decision here, anything to do with tlbie, or dcbz and cache or mmu in general goes into this Function Unit.

means creating a new FU in the CSV files (adding to power_enums.py)

it will need to be a FSM not a pipeline because it gets too complex otherwise.

changing tlbie etc not expected to be particularly common so this is ok.
Comment 2 Luke Kenneth Casson Leighton 2020-09-16 01:48:36 BST
 
 -- send MMU-related SPRs to loadstore1
    case sprn is
    when SPR_DAR | SPR_DSISR | SPR_PID | SPR_PRTBL =>
             v.decode.unit := LDST;
                  

in PowerDecoder2 must redirect these SPRs to the MMU FU
Comment 3 Luke Kenneth Casson Leighton 2020-09-16 01:51:20 BST
        majorop := unsigned(f_in.insn(31 downto 26));
        if f_in.fetch_failed = '1' then
            v.valid := '1';
            -- Only send down a single OP_FETCH_FAILED
            if r.decode.insn_type = OP_FETCH_FAILED then
                v.valid := '0';
            end if;
            v.decode := fetch_fail_inst;


also, like interrupts, if a fetch fails run a new op (microcode style)
Comment 4 Luke Kenneth Casson Leighton 2021-05-01 13:37:04 BST
in test_core.py 

def set_mmu_spr(name, i, val, core): #important keep pep8 formatting
        fsm = core.fus.fus["mmu0"].alu
        yield fsm.mmu.l_in.mtspr.eq(1)
        yield fsm.mmu.l_in.sprn.eq(i)
        yield fsm.mmu.l_in.rs.eq(val)
        yield
        yield fsm.mmu.l_in.mtspr.eq(0)
        print("mmu_spr was updated")

this is defeating the object of the exercise of having the unit tests,
because the unit tests are supposed to test the exact path, above.

the correct action is to modify the SPRs *directly* in the fsm.mmu
and *also* to store them in the SPR regfile.

then when the unit test enumerates the SPR regfile after the test has run,
the fsm.mmu will have modified them (in the test), and the unit test can
detect that.
Comment 5 Luke Kenneth Casson Leighton 2021-05-01 22:40:57 BST
dcache, mmu, and the MMU FSM, are all linked up.  currently debugging, the wishbone interface is lacking "stall" signalling which is causing issues.
Comment 6 Luke Kenneth Casson Leighton 2021-05-01 23:44:06 BST
the order in ehich requests are made, when a LDST comes in, is that a dcache request goes out first, and if it fails an MMU request is made instead.


if d_in.error = '1' then
    if d_in.cache_paradox = '1' then
        -- signal an interrupt straight away
        exception := '1';
        dsisr(63 - 38) := not r2.req.load;
        -- XXX there is no architected bit for this
        -- (probably should be a machine check in fact)
        dsisr(63 - 35) := d_in.cache_paradox;
    else
        -- Look up the translation for TLB miss
        -- and also for permission error and RC error
        -- in case the PTE has been updated.
        mmureq := '1';
        v.state := MMU_LOOKUP;
        v.stage1_en := '0';
    end if;
end if
Comment 7 Luke Kenneth Casson Leighton 2021-05-11 12:31:16 BST
http://lists.libre-soc.org/pipermail/libre-soc-dev/2021-May/002623.html
Comment 8 Luke Kenneth Casson Leighton 2021-05-12 19:36:19 BST
commit a9eb2efe76ae1a29db26cbe5f8a3876d458215b5 (HEAD -> master)
Author: Luke Kenneth Casson Leighton <lkcl@lkcl.net>
Date:   Wed May 12 19:35:35 2021 +0100

    experimentation with MMU-enabled LoadStore1 through PortInterface
    added was a way to capture a snapshot of the incoming LD/ST request,
    so that it can be re-presented after an MMU lookup.
Comment 9 Luke Kenneth Casson Leighton 2021-05-13 20:17:21 BST
the LoadStore1 class now has a functional "miss-mmulookup-hit" cycle

https://git.libre-soc.org/?p=soc.git;a=commit;h=9885585d097ca1f26283fa9dc0f22a4fa7bc026c

four VM reads in a row will give the right answer:
https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/experiment/test/test_ldst_pi.py;h=8688bd94d77e954ba1ba907c42c1ce0fe690cc35;hb=9885585d097ca1f26283fa9dc0f22a4fa7bc026c#l136

next phase: VM writes (STOREs), DCBZ.
Comment 10 Luke Kenneth Casson Leighton 2021-05-13 22:06:13 BST
commit 20738782e90bd3fe47c2bb6f887456872c7a3ad3 (HEAD -> master)
Author: Luke Kenneth Casson Leighton <lkcl@lkcl.net>
Date:   Thu May 13 22:02:32 2021 +0100

    added STORE test in test_ldst_pi.py, and it worked straight off

this is a good sign, a preliminary (single) write was successful.
the next (interesting) test would be to set read or write permissions
to false.
Comment 11 Luke Kenneth Casson Leighton 2021-12-08 00:25:41 GMT
(In reply to Luke Kenneth Casson Leighton from comment #3)
>         majorop := unsigned(f_in.insn(31 downto 26));
>         if f_in.fetch_failed = '1' then
>             v.valid := '1';
>             -- Only send down a single OP_FETCH_FAILED
>             if r.decode.insn_type = OP_FETCH_FAILED then
>                 v.valid := '0';
>             end if;
>             v.decode := fetch_fail_inst;
> 
> 
> also, like interrupts, if a fetch fails run a new op (microcode style)

fetch_failed notification is raised HI and left HI by the I-Cache until
the MMU lookup of the required PTE is added. therefore some "blip"
detection is needed.

problem is, PowerDecoder2 is entirely combinatorial so this has to
be done slightly differently in LibreSOC, e.g. by TestIssuer detecting
it and creating the blip (a FSM).  edge-trigger detection, basically.
Comment 12 Luke Kenneth Casson Leighton 2021-12-10 00:53:02 GMT
tobias i am putting you down for EUR 1000 because of all the unit tests
you have done
Comment 13 Tobias Platen 2021-12-10 18:07:59 GMT
I agree with EUR 1000, initially I was expecting even less. I have noticed the deadline and priority change.