Skip to content

Commit

Permalink
Preliminary allow PLIC to support 32 sources to 32 contexts
Browse files Browse the repository at this point in the history
By changing `ie` from `uint32_t` to an array of `uint32_t`, this can
simulate different interrupt enable registers for different contexts.
For example, `ie[0]` simulates the interrupt enable register for the
first context, which is at 0x002000 in the address map, and `ie[1]`
simulates the second context with the address map at 0x002080.
  • Loading branch information
ranvd committed Jun 24, 2024
1 parent 6525dc4 commit 7a91485
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 11 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(vm_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
1 change: 1 addition & 0 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ static int semu_start(int argc, char **argv)
vm.s_mode = true;
vm.x_regs[RV_R_A0] = 0; /* hart ID. i.e., cpuid */
vm.x_regs[RV_R_A1] = dtb_addr;
vm.mhartid = 0;

/* Set up peripherals */
emu.uart.in_fd = 0, emu.uart.out_fd = 1;
Expand Down
26 changes: 17 additions & 9 deletions plic.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ void plic_update_interrupts(vm_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 Expand Up @@ -113,4 +121,4 @@ void plic_write(vm_t *vm,
vm_set_exception(vm, RV_EXC_ILLEGAL_INSN, 0);
return;
}
}
}
3 changes: 3 additions & 0 deletions riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ struct __vm_internal {
uint32_t satp; /**< MMU */
uint32_t *page_table;

/* Machine state */
uint32_t mhartid;

void *priv; /**< environment supplied */

/* Memory access sets the vm->error to indicate failure. On successful
Expand Down

0 comments on commit 7a91485

Please sign in to comment.