riscv64/smp: Implement multi-processor support
* Working under qemu smp 1,2+ * Working on SiFive Unmatched * x86_64 efi not broken by smp_boot_other_cpus change Change-Id: I32ebc17913e46ed082be9ade8f56448bbf12f16e Reviewed-on: https://review.haiku-os.org/c/haiku/+/4705 Tested-by: Commit checker robot <[email protected]> Reviewed-by: Alex von Gluck IV <[email protected]>
This commit is contained in:
@@ -45,7 +45,7 @@ clear_ac()
|
||||
|
||||
|
||||
typedef struct arch_cpu_info {
|
||||
int null;
|
||||
uint64 hartId;
|
||||
} arch_cpu_info;
|
||||
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
|
||||
struct kernel_args;
|
||||
struct iframe;
|
||||
|
||||
struct arch_debug_registers {
|
||||
};
|
||||
@@ -17,7 +18,7 @@ struct arch_debug_registers {
|
||||
|
||||
void WritePC(addr_t pc);
|
||||
void DoStackTrace(addr_t fp, addr_t pc);
|
||||
void WriteTrapInfo();
|
||||
void WriteTrapInfo(iframe* frame);
|
||||
|
||||
status_t arch_debug_init_early(kernel_args *args);
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#define NUM_IO_VECTORS 256
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
static inline void
|
||||
arch_int_enable_interrupts_inline(void)
|
||||
{
|
||||
@@ -69,5 +71,7 @@ enum {
|
||||
|
||||
extern "C" status_t MSyscall(uint64 op, ...);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _KERNEL_ARCH_RISCV64_INT_H */
|
||||
|
||||
@@ -38,7 +38,6 @@ typedef struct {
|
||||
// MNative hooks, or SBI
|
||||
uint32 machine_platform;
|
||||
|
||||
uint bootHart;
|
||||
uint64 timerFrequency; // in Hz
|
||||
|
||||
// All following address are virtual
|
||||
@@ -50,6 +49,9 @@ typedef struct {
|
||||
addr_range clint;
|
||||
|
||||
uart_info uart;
|
||||
|
||||
uint32 hartIds[SMP_MAX_CPUS];
|
||||
uint32 plicContexts[SMP_MAX_CPUS];
|
||||
} _PACKED arch_kernel_args;
|
||||
|
||||
#endif /* KERNEL_ARCH_RISCV64_KERNEL_ARGS_H */
|
||||
|
||||
@@ -14,6 +14,11 @@ namespace BKernel {
|
||||
|
||||
|
||||
struct iframe {
|
||||
uint64 status;
|
||||
uint64 cause;
|
||||
uint64 tval;
|
||||
uint64 align1; // structure need to be 16 byte aligned
|
||||
|
||||
uint64 ra;
|
||||
uint64 t6;
|
||||
uint64 sp;
|
||||
@@ -48,6 +53,7 @@ struct iframe {
|
||||
uint64 epc;
|
||||
};
|
||||
|
||||
|
||||
struct arch_context {
|
||||
uint64 ra; // 0
|
||||
uint64 s[12]; // 12
|
||||
@@ -60,12 +66,15 @@ struct fpu_context {
|
||||
uint64 fcsr;
|
||||
};
|
||||
|
||||
struct __attribute__((aligned(16))) arch_stack {
|
||||
BKernel::Thread* thread;
|
||||
};
|
||||
|
||||
struct arch_thread {
|
||||
BKernel::Thread* thread;
|
||||
arch_context context;
|
||||
fpu_context fpuContext;
|
||||
iframe* userFrame;
|
||||
uint64 oldA0;
|
||||
};
|
||||
|
||||
struct arch_team {
|
||||
@@ -84,13 +93,12 @@ struct arch_fork_arg {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int arch_setjmp(arch_context* ctx);
|
||||
void arch_longjmp(arch_context* ctx, int val);
|
||||
void arch_context_switch(arch_context* from, arch_context* to);
|
||||
void save_fpu(fpu_context* ctx);
|
||||
void restore_fpu(fpu_context* ctx);
|
||||
void arch_thread_entry();
|
||||
void arch_enter_userspace(void *arg1, void *arg2, addr_t sp);
|
||||
void arch_longjmp_iframe(iframe* frame);
|
||||
void arch_load_user_iframe(arch_stack* stackHeader, iframe* frame)
|
||||
__attribute__ ((noreturn));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -9,79 +9,79 @@
|
||||
|
||||
|
||||
# NOTE: this macro don't save SP, it should be saved manually
|
||||
.macro PushTrapFrame
|
||||
addi sp, sp, -256
|
||||
.macro PushTrapFrame extSize
|
||||
addi sp, sp, -(\extSize + 256)
|
||||
|
||||
sd ra, 0*8(sp)
|
||||
sd t6, 1*8(sp)
|
||||
# sd sp, 2*8(sp) # sp
|
||||
sd gp, 3*8(sp)
|
||||
sd tp, 4*8(sp)
|
||||
sd t0, 5*8(sp)
|
||||
sd t1, 6*8(sp)
|
||||
sd t2, 7*8(sp)
|
||||
sd t5, 8*8(sp)
|
||||
sd s1, 9*8(sp)
|
||||
sd a0, 10*8(sp)
|
||||
sd a1, 11*8(sp)
|
||||
sd a2, 12*8(sp)
|
||||
sd a3, 13*8(sp)
|
||||
sd a4, 14*8(sp)
|
||||
sd a5, 15*8(sp)
|
||||
sd a6, 16*8(sp)
|
||||
sd a7, 17*8(sp)
|
||||
sd s2, 18*8(sp)
|
||||
sd s3, 19*8(sp)
|
||||
sd s4, 20*8(sp)
|
||||
sd s5, 21*8(sp)
|
||||
sd s6, 22*8(sp)
|
||||
sd s7, 23*8(sp)
|
||||
sd s8, 24*8(sp)
|
||||
sd s9, 25*8(sp)
|
||||
sd s10, 26*8(sp)
|
||||
sd s11, 27*8(sp)
|
||||
sd t3, 28*8(sp)
|
||||
sd t4, 29*8(sp)
|
||||
sd fp, 30*8(sp)
|
||||
sd ra, \extSize + 0*8(sp)
|
||||
sd t6, \extSize + 1*8(sp)
|
||||
# sd sp, \extSize + 2*8(sp) # sp
|
||||
sd gp, \extSize + 3*8(sp)
|
||||
sd tp, \extSize + 4*8(sp)
|
||||
sd t0, \extSize + 5*8(sp)
|
||||
sd t1, \extSize + 6*8(sp)
|
||||
sd t2, \extSize + 7*8(sp)
|
||||
sd t5, \extSize + 8*8(sp)
|
||||
sd s1, \extSize + 9*8(sp)
|
||||
sd a0, \extSize + 10*8(sp)
|
||||
sd a1, \extSize + 11*8(sp)
|
||||
sd a2, \extSize + 12*8(sp)
|
||||
sd a3, \extSize + 13*8(sp)
|
||||
sd a4, \extSize + 14*8(sp)
|
||||
sd a5, \extSize + 15*8(sp)
|
||||
sd a6, \extSize + 16*8(sp)
|
||||
sd a7, \extSize + 17*8(sp)
|
||||
sd s2, \extSize + 18*8(sp)
|
||||
sd s3, \extSize + 19*8(sp)
|
||||
sd s4, \extSize + 20*8(sp)
|
||||
sd s5, \extSize + 21*8(sp)
|
||||
sd s6, \extSize + 22*8(sp)
|
||||
sd s7, \extSize + 23*8(sp)
|
||||
sd s8, \extSize + 24*8(sp)
|
||||
sd s9, \extSize + 25*8(sp)
|
||||
sd s10, \extSize + 26*8(sp)
|
||||
sd s11, \extSize + 27*8(sp)
|
||||
sd t3, \extSize + 28*8(sp)
|
||||
sd t4, \extSize + 29*8(sp)
|
||||
sd fp, \extSize + 30*8(sp)
|
||||
|
||||
addi fp, sp, 256
|
||||
addi fp, sp, \extSize + 256
|
||||
.endm
|
||||
|
||||
|
||||
.macro PopTrapFrame
|
||||
ld ra, 0*8(sp)
|
||||
ld t6, 1*8(sp)
|
||||
# ld sp, 2*8(sp) restore later
|
||||
ld gp, 3*8(sp)
|
||||
# ld tp, 4*8(sp)
|
||||
ld t0, 5*8(sp)
|
||||
ld t1, 6*8(sp)
|
||||
ld t2, 7*8(sp)
|
||||
ld t5, 8*8(sp)
|
||||
ld s1, 9*8(sp)
|
||||
ld a0, 10*8(sp)
|
||||
ld a1, 11*8(sp)
|
||||
ld a2, 12*8(sp)
|
||||
ld a3, 13*8(sp)
|
||||
ld a4, 14*8(sp)
|
||||
ld a5, 15*8(sp)
|
||||
ld a6, 16*8(sp)
|
||||
ld a7, 17*8(sp)
|
||||
ld s2, 18*8(sp)
|
||||
ld s3, 19*8(sp)
|
||||
ld s4, 20*8(sp)
|
||||
ld s5, 21*8(sp)
|
||||
ld s6, 22*8(sp)
|
||||
ld s7, 23*8(sp)
|
||||
ld s8, 24*8(sp)
|
||||
ld s9, 25*8(sp)
|
||||
ld s10, 26*8(sp)
|
||||
ld s11, 27*8(sp)
|
||||
ld t3, 28*8(sp)
|
||||
ld t4, 29*8(sp)
|
||||
ld fp, 30*8(sp)
|
||||
.macro PopTrapFrame extSize
|
||||
ld ra, \extSize + 0*8(sp)
|
||||
ld t6, \extSize + 1*8(sp)
|
||||
# ld sp, \extSize + 2*8(sp) restore later
|
||||
ld gp, \extSize + 3*8(sp)
|
||||
# ld tp, \extSize + 4*8(sp)
|
||||
ld t0, \extSize + 5*8(sp)
|
||||
ld t1, \extSize + 6*8(sp)
|
||||
ld t2, \extSize + 7*8(sp)
|
||||
ld t5, \extSize + 8*8(sp)
|
||||
ld s1, \extSize + 9*8(sp)
|
||||
ld a0, \extSize + 10*8(sp)
|
||||
ld a1, \extSize + 11*8(sp)
|
||||
ld a2, \extSize + 12*8(sp)
|
||||
ld a3, \extSize + 13*8(sp)
|
||||
ld a4, \extSize + 14*8(sp)
|
||||
ld a5, \extSize + 15*8(sp)
|
||||
ld a6, \extSize + 16*8(sp)
|
||||
ld a7, \extSize + 17*8(sp)
|
||||
ld s2, \extSize + 18*8(sp)
|
||||
ld s3, \extSize + 19*8(sp)
|
||||
ld s4, \extSize + 20*8(sp)
|
||||
ld s5, \extSize + 21*8(sp)
|
||||
ld s6, \extSize + 22*8(sp)
|
||||
ld s7, \extSize + 23*8(sp)
|
||||
ld s8, \extSize + 24*8(sp)
|
||||
ld s9, \extSize + 25*8(sp)
|
||||
ld s10, \extSize + 26*8(sp)
|
||||
ld s11, \extSize + 27*8(sp)
|
||||
ld t3, \extSize + 28*8(sp)
|
||||
ld t4, \extSize + 29*8(sp)
|
||||
ld fp, \extSize + 30*8(sp)
|
||||
|
||||
ld sp, 2*8(sp)
|
||||
ld sp, \extSize + 2*8(sp)
|
||||
.endm
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2019 Haiku, Inc. All rights reserved.
|
||||
* Copyright 2013-2021 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef KERNEL_BOOT_PLATFORM_EFI_ARCH_SMP_H
|
||||
@@ -13,9 +13,17 @@
|
||||
// These platforms take inventory of cpu cores from fdt
|
||||
|
||||
struct platform_cpu_info {
|
||||
uint32 id;
|
||||
uint32 id; // hart id on riscv
|
||||
#if defined(__riscv)
|
||||
uint32 phandle;
|
||||
uint32 plicContext;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(__riscv)
|
||||
extern uint32 gBootHart;
|
||||
#endif
|
||||
|
||||
void arch_smp_register_cpu(platform_cpu_info** cpu);
|
||||
#endif
|
||||
|
||||
@@ -23,6 +31,7 @@ void arch_smp_register_cpu(platform_cpu_info** cpu);
|
||||
int arch_smp_get_current_cpu(void);
|
||||
void arch_smp_init_other_cpus(void);
|
||||
#ifdef __riscv
|
||||
platform_cpu_info* arch_smp_find_cpu(uint32 phandle);
|
||||
void arch_smp_boot_other_cpus(uint64 satp, uint64 kernel_entry);
|
||||
#else
|
||||
void arch_smp_boot_other_cpus(uint32 pml4, uint64 kernel_entry);
|
||||
|
||||
@@ -376,7 +376,7 @@ vm_page::IncrementWiredCount()
|
||||
inline void
|
||||
vm_page::DecrementWiredCount()
|
||||
{
|
||||
ASSERT(fWiredCount > 0);
|
||||
ASSERT_PRINT(fWiredCount > 0, "page: %#" B_PRIx64, physical_page_number * B_PAGE_SIZE);
|
||||
|
||||
if (--fWiredCount == 0)
|
||||
cache_ref->cache->DecrementWiredPagesCount();
|
||||
|
||||
@@ -230,10 +230,9 @@ vm_page_debug_access_start(vm_page* page)
|
||||
thread_id previousThread = atomic_test_and_set(&page->accessing_thread,
|
||||
threadID, -1);
|
||||
if (previousThread != -1) {
|
||||
panic("Invalid concurrent access to page %p (start), currently "
|
||||
"accessed by: %" B_PRId32
|
||||
"@! page -m %p; sc %" B_PRId32 "; cache _cache", page,
|
||||
previousThread, page, previousThread);
|
||||
panic("Invalid concurrent access to page 0x%" B_PRIXPHYSADDR " (start), currently "
|
||||
"accessed by: %" B_PRId32 "@! page -m %p; sc %" B_PRId32 "; cache _cache",
|
||||
page->physical_page_number * B_PAGE_SIZE, previousThread, page, previousThread);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,9 +244,9 @@ vm_page_debug_access_end(vm_page* page)
|
||||
thread_id previousThread = atomic_test_and_set(&page->accessing_thread, -1,
|
||||
threadID);
|
||||
if (previousThread != threadID) {
|
||||
panic("Invalid concurrent access to page %p (end) by current thread, "
|
||||
"current accessor is: %" B_PRId32
|
||||
"@! page -m %p; sc %" B_PRId32 "; cache _cache", page,
|
||||
panic("Invalid concurrent access to page 0x%" B_PRIXPHYSADDR " (end) by "
|
||||
"current thread, current accessor is: %" B_PRId32 "@! page -m %p; "
|
||||
"sc %" B_PRId32 "; cache _cache", page->physical_page_number * B_PAGE_SIZE,
|
||||
previousThread, page, previousThread);
|
||||
}
|
||||
}
|
||||
@@ -258,10 +257,9 @@ vm_page_debug_access_check(vm_page* page)
|
||||
{
|
||||
thread_id thread = page->accessing_thread;
|
||||
if (thread != thread_get_current_thread_id()) {
|
||||
panic("Invalid concurrent access to page %p (check), currently "
|
||||
"accessed by: %" B_PRId32
|
||||
"@! page -m %p; sc %" B_PRId32 "; cache _cache", page, thread, page,
|
||||
thread);
|
||||
panic("Invalid concurrent access to page 0x%" B_PRIXPHYSADDR " (check), currently "
|
||||
"accessed by: %" B_PRId32 "@! page -m %p; sc %" B_PRId32 "; cache _cache",
|
||||
page->physical_page_number * B_PAGE_SIZE, thread, page, thread);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user