Skip to content

Commit

Permalink
riscv: make coreMap generic
Browse files Browse the repository at this point in the history
Signed-off-by: Axel Heider <[email protected]>
  • Loading branch information
Axel Heider committed Mar 25, 2024
1 parent 707962c commit 9223576
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 51 deletions.
18 changes: 7 additions & 11 deletions include/arch/riscv/arch/model/smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,26 @@
#include <config.h>
#include <model/smp.h>
#include <kernel/stack.h>
#include <arch/model/statedata.h>

#ifdef ENABLE_SMP_SUPPORT

typedef struct core_map {
word_t map[CONFIG_MAX_NUM_NODES];
} core_map_t;

extern char kernel_stack_alloc[CONFIG_MAX_NUM_NODES][BIT(CONFIG_KERNEL_STACK_BITS)];
compile_assert(kernel_stack_4k_aligned, KERNEL_STACK_ALIGNMENT == 4096)
extern core_map_t coreMap;

static inline cpu_id_t cpuIndexToID(word_t index)
{
if (index >= ARRAY_SIZE(coreMap.map)) {
if (index >= ARRAY_SIZE(coreMap.cores)) {
printf("ERROR: coreMap index invalid: %"SEL4_PRIu_word"\n", index);
halt();
}
return coreMap.map[index];
return coreMap.cores[index].hart_id;
}

static inline word_t hartIDToCoreID(word_t hart_id)
{
for (word_t i = 0; i < ARRAY_SIZE(coreMap.map); i++) {
if (coreMap.map[i] == hart_id) {
for (word_t i = 0; i < ARRAY_SIZE(coreMap.cores); i++) {
if (coreMap.cores[i].hart_id == hart_id) {
return i;
}
}
Expand All @@ -42,11 +38,11 @@ static inline word_t hartIDToCoreID(word_t hart_id)

static inline void add_hart_to_core_map(word_t hart_id, word_t core_id)
{
if (core_id >= ARRAY_SIZE(coreMap.map)) {
if (core_id >= ARRAY_SIZE(coreMap.cores)) {
printf("ERROR: coreMap too small to add core_id %"SEL4_PRIu_word"\n", core_id);
halt();
}
coreMap.map[core_id] = hart_id;
coreMap.cores[core_id].hart_id = hart_id;
}

static inline bool_t try_arch_atomic_exchange_rlx(void *ptr, void *new_val, void **prev)
Expand Down
11 changes: 11 additions & 0 deletions include/arch/riscv/arch/model/statedata.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ NODE_STATE_BEGIN(archNodeState)
NODE_STATE_DECLARE(word_t, ipiReschedulePending);
NODE_STATE_END(archNodeState);

typedef struct {
word_t hart_id;
} core_context_t;

typedef struct {
core_context_t cores[CONFIG_MAX_NUM_NODES];
} core_map_t;

extern core_map_t coreMap;

extern asid_pool_t *riscvKSASIDTable[BIT(asidHighBits)];

/* Kernel Page Tables */
Expand All @@ -36,3 +46,4 @@ extern pte_t kernel_image_level2_dev_pt[BIT(PT_INDEX_BITS)];
extern pte_t kernel_image_level2_log_buffer_pt[BIT(PT_INDEX_BITS)];
#endif

word_t get_current_hart_id(void);
24 changes: 10 additions & 14 deletions include/drivers/irq/riscv_plic0.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@
#define PLIC_PPTR_BASE PLIC_PPTR


#define PLIC_HART_ID (CONFIG_FIRST_HART_ID)

#define PLIC_PRIO 0x0
#define PLIC_PRIO_PER_ID 0x4

Expand Down Expand Up @@ -117,24 +115,19 @@ static inline bool_t plic_pending_interrupt(word_t interrupt)
* This returns the hart ID used by the PLIC for the hart this code is currently
* executing on.
*/
static inline word_t plic_get_current_hart_id(void)
{
return SMP_TERNARY(
cpuIndexToID(getCurrentCPUIndex()),
CONFIG_FIRST_HART_ID);
}


static inline irq_t plic_get_claim(void)
{
/* Read the claim register for our HART interrupt context */
word_t hart_id = plic_get_current_hart_id();
word_t hart_id = get_current_hart_id();
return readl(PLIC_PPTR_BASE + plic_claim_offset(hart_id, PLIC_SVC_CONTEXT));
}

static inline void plic_complete_claim(irq_t irq)
{
/* Complete the IRQ claim by writing back to the claim register. */
word_t hart_id = plic_get_current_hart_id();
word_t hart_id = get_current_hart_id();
writel(irq, PLIC_PPTR_BASE + plic_claim_offset(hart_id, PLIC_SVC_CONTEXT));
}

Expand All @@ -144,7 +137,7 @@ static inline void plic_mask_irq(bool_t disable, irq_t irq)
uint32_t val = 0;
uint32_t bit = 0;

word_t hart_id = plic_get_current_hart_id();
word_t hart_id = get_current_hart_id();
addr = PLIC_PPTR_BASE + plic_enable_offset(hart_id, PLIC_SVC_CONTEXT) + (irq / 32) * 4;
bit = irq % 32;

Expand All @@ -159,7 +152,7 @@ static inline void plic_mask_irq(bool_t disable, irq_t irq)

static inline void plic_init_hart(void)
{
word_t hart_id = plic_get_current_hart_id();
word_t hart_id = get_current_hart_id();

for (int i = 1; i <= PLIC_NUM_INTERRUPTS; i++) {
/* Disable interrupts */
Expand All @@ -172,11 +165,14 @@ static inline void plic_init_hart(void)

static inline void plic_init_controller(void)
{
/* This is supposed to be called on the primary hart. */
word_t hart_id = get_current_hart_id();

for (int i = 1; i <= PLIC_NUM_INTERRUPTS; i++) {
/* Clear all pending bits */
if (plic_pending_interrupt(i)) {
readl(PLIC_PPTR_BASE + plic_claim_offset(PLIC_HART_ID, PLIC_SVC_CONTEXT));
writel(i, PLIC_PPTR_BASE + plic_claim_offset(PLIC_HART_ID, PLIC_SVC_CONTEXT));
readl(PLIC_PPTR_BASE + plic_claim_offset(hart_id, PLIC_SVC_CONTEXT));
writel(i, PLIC_PPTR_BASE + plic_claim_offset(hart_id, PLIC_SVC_CONTEXT));
}
}

Expand Down
49 changes: 24 additions & 25 deletions src/arch/riscv/kernel/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,12 @@ BOOT_CODE static void init_plat(void)
#ifdef ENABLE_SMP_SUPPORT
BOOT_CODE static bool_t try_init_kernel_secondary_core(word_t hart_id, word_t core_id)
{
if (core_id >= ARRAY_SIZE(coreMap.cores)) {
printf("ERROR: coreMap.map[] too small\n");
return false;
}
coreMap.cores[core_id].hart_id = hart_id;

while (!node_boot_lock);

fence_r_rw();
Expand Down Expand Up @@ -196,8 +202,8 @@ static BOOT_CODE bool_t try_init_kernel(
sword_t pv_offset,
vptr_t v_entry,
paddr_t dtb_phys_addr,
word_t dtb_size
)
word_t dtb_size,
word_t hart_id)
{
cap_t root_cnode_cap;
cap_t it_pd_cap;
Expand All @@ -224,6 +230,8 @@ static BOOT_CODE bool_t try_init_kernel(
bi_frame_vptr = ipcbuf_vptr + BIT(PAGE_BITS);
extra_bi_frame_vptr = bi_frame_vptr + BIT(seL4_BootInfoFrameBits);

coreMap.cores[0].hart_id = hart_id;

map_kernel_window();

/* initialise the CPU */
Expand Down Expand Up @@ -464,34 +472,25 @@ BOOT_CODE VISIBLE void init_kernel(
word_t core_id
)
{
bool_t result;

printf("hart_id %"SEL4_PRIu_word", core_id %"SEL4_PRIu_word", CONFIG_FIRST_HART_ID %d\n",
hart_id, core_id, CONFIG_FIRST_HART_ID);

#ifdef ENABLE_SMP_SUPPORT
add_hart_to_core_map(hart_id, core_id);
if (core_id == 0) {
result = try_init_kernel(ui_p_reg_start,
ui_p_reg_end,
pv_offset,
v_entry,
dtb_addr_p,
dtb_size);
if (0 == core_id) {
if (!try_init_kernel(ui_p_reg_start, ui_p_reg_end, pv_offset, v_entry,
dtb_addr_p, dtb_size, hart_id)) {
fail("ERROR: kernel init on primary hart failed");
UNREACHABLE();
}
} else {
result = try_init_kernel_secondary_core(hart_id, core_id);
}
#else
result = try_init_kernel(ui_p_reg_start,
ui_p_reg_end,
pv_offset,
v_entry,
dtb_addr_p,
dtb_size);
#endif
if (!result) {
fail("ERROR: kernel init failed");
#ifdef CONFIG_ENABLE_SMP_SUPPORT
if (!try_init_kernel_secondary_core(hart_id, core_id)) {
fail("ERROR: kernel init on secondary hart failed");
UNREACHABLE();
}
#else /* not CONFIG_ENABLE_SMP_SUPPORT */
fail("ERROR: secondary cores are not supported on non-SMP configuratons");
UNREACHABLE();
#endif /* [not] CONFIG_ENABLE_SMP_SUPPORT */
}

#ifdef CONFIG_KERNEL_MCS
Expand Down
16 changes: 15 additions & 1 deletion src/arch/riscv/model/statedata.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,18 @@ pte_t kernel_image_level2_dev_pt[BIT(PT_INDEX_BITS)] ALIGN_BSS(BIT(seL4_PageTabl
pte_t kernel_image_level2_log_buffer_pt[BIT(PT_INDEX_BITS)] ALIGN_BSS(BIT(seL4_PageTableBits));
#endif

SMP_STATE_DEFINE(core_map_t, coreMap);
/* Unlike on ARM, there is no register in RISC-V that allows reading the current
* hart ID. It is passed during boot and thus we have to remember it even in
* non-SMP configurations.
*/
core_map_t coreMap;


word_t get_current_hart_id(void)
{
#ifdef CONFIG_ENABLE_SMP_SUPPORT
return cpuIndexToID(getCurrentCPUIndex());
#else
return coreMap.cores[0].hart_id;
#endif
}

0 comments on commit 9223576

Please sign in to comment.