Skip to content

Commit

Permalink
Modify PLIC to support SMP system
Browse files Browse the repository at this point in the history
Currently PLIC allow 32 sources send interrupt request
to 32 contexts (harts)
  • Loading branch information
ranvd committed Jun 24, 2024
1 parent 45b6c4d commit a8ab83c
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 12 deletions.
4 changes: 2 additions & 2 deletions device.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ void ram_write(hart_t *core,

typedef struct {
uint32_t masked;
uint32_t ip;
uint32_t ie;
uint32_t ip; /* support 32 interrupt sources only */
uint32_t ie[32]; /* support 32 sources to 32 contexts only */
/* state of input interrupt lines (level-triggered), set by environment */
uint32_t active;
} plic_state_t;
Expand Down
4 changes: 2 additions & 2 deletions minimal.dts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
compatible = "sifive,plic-1.0.0";
reg = <0x0000000 0x4000000>;
interrupt-controller;
interrupts-extended = <&cpu0_intc 9>;
interrupts-extended = <&cpu0_intc 9>, <&cpu1_intc 9>;
riscv,ndev = <31>;
};

Expand Down Expand Up @@ -98,7 +98,7 @@
#endif
clint0: clint@4300000 {
compatible = "riscv,clint0";
interrupt-controller;
interrupt-controller;
interrupts-extended = <&cpu0_intc 5>;
reg = <0x4300000 0x10000>;
};
Expand Down
24 changes: 16 additions & 8 deletions plic.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ void plic_update_interrupts(hart_t *vm, plic_state_t *plic)
plic->ip |= plic->active & ~plic->masked;
plic->masked |= plic->active;
/* Send interrupt to target */
if (plic->ip & plic->ie)
if (plic->ip & plic->ie[vm->mhartid])
vm->sip |= RV_INT_SEI_BIT;
else
vm->sip &= ~RV_INT_SEI_BIT;
Expand All @@ -22,12 +22,17 @@ static bool plic_reg_read(plic_state_t *plic, uint32_t addr, uint32_t *value)
if (1 <= addr && addr <= 31)
return true;

switch (addr) {
case 0x400:
if (addr == 0x400){
*value = plic->ip;
return true;
}

int addr_mask = MASK(ilog2(addr)) ^ (1 & addr);
int context = (addr_mask & addr);
context >>= __builtin_ffs(context) - (__builtin_ffs(context) & 1);
switch (addr & ~addr_mask) {
case 0x800:
*value = plic->ie;
*value = plic->ie[context];
return true;
case 0x80000:
*value = 0;
Expand All @@ -36,7 +41,7 @@ static bool plic_reg_read(plic_state_t *plic, uint32_t addr, uint32_t *value)
case 0x80001:
/* claim */
*value = 0;
uint32_t candidates = plic->ip & plic->ie;
uint32_t candidates = plic->ip & plic->ie[context];
if (candidates) {
*value = ilog2(candidates);
plic->ip &= ~(1 << (*value));
Expand All @@ -53,17 +58,20 @@ static bool plic_reg_write(plic_state_t *plic, uint32_t addr, uint32_t value)
if (1 <= addr && addr <= 31)
return true;

switch (addr) {
int addr_mask = MASK(ilog2(addr)) ^ (1 & addr);
int context = (addr_mask & addr);
context >>= __builtin_ffs(context) - (__builtin_ffs(context) & 1);
switch (addr & ~addr_mask) {
case 0x800:
value &= ~1;
plic->ie = value;
plic->ie[context] = value;
return true;
case 0x80000:
/* no priority support: target priority threshold hardwired to 0 */
return true;
case 0x80001:
/* completion */
if (plic->ie & (1 << value))
if (plic->ie[context] & (1 << value))
plic->masked &= ~(1 << value);
return true;
default:
Expand Down

0 comments on commit a8ab83c

Please sign in to comment.