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.
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.
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)
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
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.
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...
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)