Bug 859 - Implement SPR_KAIVB
Summary: Implement SPR_KAIVB
Status: CONFIRMED
Alias: None
Product: Libre-SOC's second ASIC
Classification: Unclassified
Component: source code (show other bugs)
Version: unspecified
Hardware: PC Linux
: --- enhancement
Assignee: Luke Kenneth Casson Leighton
URL:
Depends on:
Blocks: 855
  Show dependency treegraph
 
Reported: 2022-06-16 19:40 BST by tpearson
Modified: 2023-10-20 03:39 BST (History)
1 user (show)

See Also:
NLnet milestone: NGI.POINTER.Gigabit.ASIC
total budget (EUR) for completion of task and all subtasks: 0
budget (EUR) for this task, excluding subtasks' budget: 0
parent task for budget allocation:
child tasks for budget allocation:
The table of payments (in EUR) for this task; TOML format:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description tpearson 2022-06-16 19:40:16 BST
Kestrel currently uses a custom SPR (SPR_KAIVB: SPR 850) to allow the interrupt table to be relocated at runtime out of ROM into RAM.  Similar functionality is provided in POWER8+ in terms of the hypervisor instruction set, but since those optional instructions are not available in LibreSoC we need a different access mechanism for the same functionalty.

Without the ability to relocate the interrupt table, we cannot use ISRs in the ROM bootloader, significantly slowing down the early boot process for many real-world use cases.  Several attempts have been made to develop a solution that would stub all interrupt calls out in ROM, but they have proven fragile and difficult to work with in practice.
Comment 1 tpearson 2022-06-16 19:41:58 BST
Here is the implementation in Microwatt:

https://gitlab.raptorengineering.com/kestrel-collaboration/kestrel-litex/pythondata-cpu-microwatt/-/commit/df85156a603149c8393d28075f7c12f19dca5c8f

All of the existing Kestrel firmware uses this SPR at some point, as the base bootloader expects to see it.
Comment 2 Luke Kenneth Casson Leighton 2022-06-16 19:42:15 BST
adding this new SPR is tricky, there are two techniques:

1) add to CoreState as a peer of DEC and TB. this requires hooking
   into how DEC and TB read from a State regfile port.

   complicated.

2) have the cached copy in the Trap pipeline which handles
   *all* exceptions/interrupts.

   in PowerDecode2 spot the read/write to the SPR, manually
   redirect the pipeline unit, and then add OP_MTSPR
   and OP_MFSPR to the trap pipeline

   this is already done for LDST (loadstore1.py)



also needs adding to sprs.csv

also needs qualifying as a "fast" spr in decoder/enums.py
(decoder/sprs.py i think)
Comment 3 Luke Kenneth Casson Leighton 2022-06-17 13:55:47 BST
adding the SPR to power_enums.py and the sprs.csv file:

https://git.libre-soc.org/?p=openpower-isa.git;a=tree;h=eb3cdd7a3ef76c0975ca9a958131b9776702c44e;hb=eb3cdd7a3ef76c0975ca9a958131b9776702c44e
Comment 4 Luke Kenneth Casson Leighton 2022-06-17 14:15:51 BST
https://git.libre-soc.org/?p=openpower-isa.git;a=commitdiff;h=10ecc13c335716813ff3dc01f1f7fe18c17cb615

adds a "redirector" in the PowerDecoder for KAIVB so that MFSPR and MTSPR
are handled directly by the Trap pipeline.
Comment 5 Luke Kenneth Casson Leighton 2022-06-26 12:41:59 BST
storing KAIVB SPR 850 in the Trap Pipeline by *redirecting*
PowerDecoder2 to send OP_MTSPR and OP_MFSPR to that pipeline,
but *only* for SPR=850 (see comment #4)

https://git.libre-soc.org/?p=openpower-isa.git;a=commitdiff;h=06e56ef855c57bb7a8ffa5f4b03ba34bf43c1010
https://git.libre-soc.org/?p=soc.git;a=commitdiff;h=44f8a121d68fed0889d49823936371e6c3d15425

now that KAIVB is actually in the pipeline responsible for doing
all exceptions (TRAP), the next thing is to actually use it...
Comment 6 Luke Kenneth Casson Leighton 2022-06-26 13:00:13 BST
all good, unit test created and passes

https://git.libre-soc.org/?p=soc.git;a=commitdiff;h=10f4200e58562d6070203afdddea1dc0c0eb5f88
https://git.libre-soc.org/?p=openpower-isa.git;a=commitdiff;h=58a7e851cc2b288fe99a125f6d929e3402328e06

-        # trap address
+        # trap address, including KAIVB override
         comb += nia_o.data.eq(trap_addr)
+        comb += nia_o.data[13:].eq(self.kaivb[13:])

sc *also* is redirected as well because it uses the exact same TRAP
system

            #################
            # SC.  v3.0B p952

            with m.Case(MicrOp.OP_SC):
                # jump to the trap address, return at cia+4
                self.trap(m, 0xc00, cia_i+4)
                self.msr_exception(m, 0xc00)