|
45 | 45 | * @{ |
46 | 46 | */ |
47 | 47 |
|
48 | | -/* 32 bits per source */ |
| 48 | +/* |
| 49 | + * PLIC Memory Map (per RISC-V PLIC spec): |
| 50 | + * |
| 51 | + * Interrupt Source Priority (per-source, not per-context): |
| 52 | + * base + 0x000000: Source 0 (reserved, not exist) |
| 53 | + * base + 0x000004: Source 1 priority |
| 54 | + * ... |
| 55 | + * base + 0x000FFC: Source 1023 priority |
| 56 | + * addr = base + source * 4 |
| 57 | + * |
| 58 | + * Interrupt Pending Bits (per-source, not per-context): |
| 59 | + * base + 0x001000: Source 0-31 pending |
| 60 | + * base + 0x001004: Source 32-63 pending |
| 61 | + * ... |
| 62 | + * addr = base + 0x1000 + (source / 32) * 4 |
| 63 | + * |
| 64 | + * Interrupt Enable Bits (per-context, 0x80 bytes each): |
| 65 | + * base + 0x002000: Context 0, Source 0-31 enable |
| 66 | + * base + 0x002080: Context 1, Source 0-31 enable |
| 67 | + * ... |
| 68 | + * addr = base + 0x2000 + ctxid * 0x80 + (source / 32) * 4 |
| 69 | + * |
| 70 | + * Priority Threshold (per-context, 0x1000 bytes each): |
| 71 | + * base + 0x200000: Context 0 threshold |
| 72 | + * base + 0x201000: Context 1 threshold |
| 73 | + * ... |
| 74 | + * addr = base + 0x200000 + ctxid * 0x1000 |
| 75 | + * |
| 76 | + * Claim / Complete (per-context, same 4K block as threshold): |
| 77 | + * base + 0x200004: Context 0 claim/complete |
| 78 | + * base + 0x201004: Context 1 claim/complete |
| 79 | + * ... |
| 80 | + * addr = base + 0x200004 + ctxid * 0x1000 |
| 81 | + * Claim: read returns highest-priority pending interrupt ID |
| 82 | + * Complete: write interrupt ID to signal handler completion |
| 83 | + * |
| 84 | + * Context ID to Hart/Mode mapping (Nuclei RISC-V CPU, not in PLIC spec): |
| 85 | + * M-mode context ID = hartid * 2 (even: 0, 2, 4, 6, 8) |
| 86 | + * S-mode context ID = hartid * 2 + 1 (odd: 1, 3, 5, 7, 9) |
| 87 | + * |
| 88 | + * Hart 0: M=ctxid 0, S=ctxid 1 |
| 89 | + * Hart 1: M=ctxid 2, S=ctxid 3 |
| 90 | + * Hart 2: M=ctxid 4, S=ctxid 5 |
| 91 | + * Hart 3: M=ctxid 6, S=ctxid 7 |
| 92 | + * Hart 4: M=ctxid 8, S=ctxid 9 |
| 93 | + * |
| 94 | + * Reference: https://github.com/riscv/riscv-plic-spec |
| 95 | + */ |
| 96 | + |
| 97 | +/* Priority: 32 bits per source, addr = base + source * 4 */ |
49 | 98 | #define PLIC_PRIORITY_OFFSET _AC(0x0000,UL) /*!< PLIC Priority register offset */ |
50 | | -#define PLIC_PRIORITY_SHIFT_PER_SOURCE 2 /*!< PLIC Priority register offset shift per source */ |
51 | | -/* 1 bit per source (1 address) */ |
| 99 | +#define PLIC_PRIORITY_SHIFT_PER_SOURCE 2 /*!< log2(4), shift per source */ |
| 100 | + |
| 101 | +/* Pending: 1 bit per source, packed 32 per 32-bit register */ |
52 | 102 | #define PLIC_PENDING_OFFSET _AC(0x1000,UL) /*!< PLIC Pending register offset */ |
53 | | -#define PLIC_PENDING_SHIFT_PER_SOURCE 0 /*!< PLIC Pending register offset shift per source */ |
| 103 | +#define PLIC_PENDING_SHIFT_PER_SOURCE 0 /*!< bit index within word */ |
54 | 104 |
|
55 | | -/* 0x80 per context */ |
| 105 | +/* Enable: 0x80 (128) bytes per context, packed 32 sources per 32-bit word */ |
56 | 106 | #define PLIC_ENABLE_OFFSET _AC(0x2000,UL) /*!< PLIC Enable register offset */ |
57 | | -#define PLIC_ENABLE_SHIFT_PER_CONTEXT 7 /*!< PLIC Enable register offset shift per context */ |
| 107 | +#define PLIC_ENABLE_SHIFT_PER_CONTEXT 7 /*!< log2(0x80), shift per context */ |
58 | 108 |
|
| 109 | +/* Threshold: 0x1000 (4096) bytes per context */ |
59 | 110 | #define PLIC_THRESHOLD_OFFSET _AC(0x200000,UL) /*!< PLIC Threshold register offset */ |
60 | | -#define PLIC_CLAIM_OFFSET _AC(0x200004,UL) /*!< PLIC Claim register offset */ |
61 | | -#define PLIC_THRESHOLD_SHIFT_PER_CONTEXT 12 /*!< PLIC Threshold register offset shift per context */ |
62 | | -#define PLIC_CLAIM_SHIFT_PER_CONTEXT 12 /*!< PLIC Claim register offset shift per context */ |
| 111 | +#define PLIC_CLAIM_OFFSET _AC(0x200004,UL) /*!< PLIC Claim/Complete register offset */ |
| 112 | +#define PLIC_THRESHOLD_SHIFT_PER_CONTEXT 12 /*!< log2(0x1000), shift per context */ |
| 113 | +#define PLIC_CLAIM_SHIFT_PER_CONTEXT 12 /*!< log2(0x1000), shift per context */ |
63 | 114 |
|
64 | 115 | #ifndef __PLIC_BASEADDR |
65 | 116 | /* Base address of PLIC(__PLIC_BASEADDR) should be defined in <Device.h> */ |
|
84 | 135 | #define PLIC_GetHartID_S() (__PLIC_HARTID) |
85 | 136 | #endif |
86 | 137 |
|
| 138 | +/* |
| 139 | + * Context ID mapping (Nuclei RISC-V CPU convention): |
| 140 | + * M-mode: ctxid = hartid * 2 (even: 0, 2, 4, 6, 8) |
| 141 | + * S-mode: ctxid = hartid * 2 + 1 (odd: 1, 3, 5, 7, 9) |
| 142 | + * This is NOT part of the RISC-V PLIC spec. |
| 143 | + */ |
87 | 144 | #define PLIC_GetHartMContextID() (PLIC_GetHartID() << 1) |
88 | | -// TODO SMODE HARTID need to handle, maybe use a predefined variable of hartid |
| 145 | +// TODO SMODE HARTID need to handle, maybe use CSR shartid defined by Nuclei RISC-V CPU |
89 | 146 | #define PLIC_GetHartSContextID() ((PLIC_GetHartID_S() << 1) + 1) |
90 | 147 |
|
91 | 148 | #define PLIC_PRIORITY_REGADDR(source) ((PLIC_BASE) + (PLIC_PRIORITY_OFFSET) + ((source) << PLIC_PRIORITY_SHIFT_PER_SOURCE)) |
@@ -317,8 +374,7 @@ __STATIC_FORCEINLINE uint32_t PLIC_ClaimContextInterrupt(uint32_t ctxid) |
317 | 374 | * \details |
318 | 375 | * This function complete interrupt for plic for selected context. |
319 | 376 | * \param [in] ctxid selected context id |
320 | | - * \return the ID of the highest priority pending interrupt or |
321 | | - * zero if there is no pending interrupt |
| 377 | + * \param [in] source interrupt source ID to complete |
322 | 378 | * \remarks |
323 | 379 | * The PLIC signals it has completed executing an interrupt handler by writing |
324 | 380 | * the interrupt ID it received from the claim to the claim/complete register. |
@@ -380,8 +436,8 @@ __STATIC_INLINE void PLIC_Context_Init(uint32_t ctxid, uint32_t num_sources, uin |
380 | 436 | #define PLIC_DisableInterrupt(source) PLIC_DisableContextInterrupt(PLIC_GetHartMContextID(), (source)) |
381 | 437 | #define PLIC_DisableInterrupt_S(source) PLIC_DisableContextInterrupt(PLIC_GetHartSContextID(), (source)) |
382 | 438 |
|
383 | | -#define PLIC_SetThreshold(source, thresh) PLIC_SetContextThreshold(PLIC_GetHartMContextID(), (source), (thresh)) |
384 | | -#define PLIC_SetThreshold_S(source, thresh) PLIC_SetContextThreshold(PLIC_GetHartSContextID(), (source), (thresh)) |
| 439 | +#define PLIC_SetThreshold(thresh) PLIC_SetContextThreshold(PLIC_GetHartMContextID(), (thresh)) |
| 440 | +#define PLIC_SetThreshold_S(thresh) PLIC_SetContextThreshold(PLIC_GetHartSContextID(), (thresh)) |
385 | 441 |
|
386 | 442 | #define PLIC_GetThreshold() PLIC_GetContextThreshold(PLIC_GetHartMContextID()) |
387 | 443 | #define PLIC_GetThreshold_S() PLIC_GetContextThreshold(PLIC_GetHartSContextID()) |
|
0 commit comments