Changeset View
Changeset View
Standalone View
Standalone View
sys/riscv/riscv/mp_machdep.c
Show First 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | |||||
#include <machine/smp.h> | #include <machine/smp.h> | ||||
#include <machine/sbi.h> | #include <machine/sbi.h> | ||||
#ifdef FDT | #ifdef FDT | ||||
#include <dev/ofw/openfirm.h> | #include <dev/ofw/openfirm.h> | ||||
#include <dev/ofw/ofw_cpu.h> | #include <dev/ofw/ofw_cpu.h> | ||||
#endif | #endif | ||||
#define MP_BOOTSTACK_SIZE (kstack_pages * PAGE_SIZE) | |||||
boolean_t ofw_cpu_reg(phandle_t node, u_int, cell_t *); | boolean_t ofw_cpu_reg(phandle_t node, u_int, cell_t *); | ||||
uint32_t __riscv_boot_ap[MAXCPU]; | uint32_t __riscv_boot_ap[MAXCPU]; | ||||
static enum { | static enum { | ||||
CPUS_UNKNOWN, | CPUS_UNKNOWN, | ||||
#ifdef FDT | #ifdef FDT | ||||
CPUS_FDT, | CPUS_FDT, | ||||
▲ Show 20 Lines • Show All 224 Lines • ▼ Show 20 Lines | smp_after_idle_runnable(void *arg __unused) | ||||
* the APs have entered the scheduler at least once, so the boot stacks | * the APs have entered the scheduler at least once, so the boot stacks | ||||
* are safe to free. | * are safe to free. | ||||
*/ | */ | ||||
smp_rendezvous(smp_no_rendezvous_barrier, NULL, | smp_rendezvous(smp_no_rendezvous_barrier, NULL, | ||||
smp_no_rendezvous_barrier, NULL); | smp_no_rendezvous_barrier, NULL); | ||||
for (cpu = 1; cpu <= mp_maxid; cpu++) { | for (cpu = 1; cpu <= mp_maxid; cpu++) { | ||||
if (bootstacks[cpu] != NULL) | if (bootstacks[cpu] != NULL) | ||||
kmem_free((vm_offset_t)bootstacks[cpu], PAGE_SIZE); | kmem_free((vm_offset_t)bootstacks[cpu], | ||||
MP_BOOTSTACK_SIZE); | |||||
} | } | ||||
} | } | ||||
SYSINIT(smp_after_idle_runnable, SI_SUB_SMP, SI_ORDER_ANY, | SYSINIT(smp_after_idle_runnable, SI_SUB_SMP, SI_ORDER_ANY, | ||||
smp_after_idle_runnable, NULL); | smp_after_idle_runnable, NULL); | ||||
static int | static int | ||||
ipi_handler(void *arg) | ipi_handler(void *arg) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 147 Lines • ▼ Show 20 Lines | #endif | ||||
pcpup = &__pcpu[cpuid]; | pcpup = &__pcpu[cpuid]; | ||||
pcpu_init(pcpup, cpuid, sizeof(struct pcpu)); | pcpu_init(pcpup, cpuid, sizeof(struct pcpu)); | ||||
pcpup->pc_hart = hart; | pcpup->pc_hart = hart; | ||||
dpcpu[cpuid - 1] = (void *)kmem_malloc(DPCPU_SIZE, M_WAITOK | M_ZERO); | dpcpu[cpuid - 1] = (void *)kmem_malloc(DPCPU_SIZE, M_WAITOK | M_ZERO); | ||||
dpcpu_init(dpcpu[cpuid - 1], cpuid); | dpcpu_init(dpcpu[cpuid - 1], cpuid); | ||||
bootstacks[cpuid] = (void *)kmem_malloc(PAGE_SIZE, M_WAITOK | M_ZERO); | bootstacks[cpuid] = (void *)kmem_malloc(MP_BOOTSTACK_SIZE, | ||||
M_WAITOK | M_ZERO); | |||||
naps = atomic_load_int(&aps_started); | naps = atomic_load_int(&aps_started); | ||||
bootstack = (char *)bootstacks[cpuid] + PAGE_SIZE; | bootstack = (char *)bootstacks[cpuid] + MP_BOOTSTACK_SIZE; | ||||
printf("Starting CPU %u (hart %lx)\n", cpuid, hart); | printf("Starting CPU %u (hart %lx)\n", cpuid, hart); | ||||
atomic_store_32(&__riscv_boot_ap[hart], 1); | atomic_store_32(&__riscv_boot_ap[hart], 1); | ||||
/* Wait for the AP to switch to its boot stack. */ | /* Wait for the AP to switch to its boot stack. */ | ||||
while (atomic_load_int(&aps_started) < naps + 1) | while (atomic_load_int(&aps_started) < naps + 1) | ||||
cpu_spinwait(); | cpu_spinwait(); | ||||
▲ Show 20 Lines • Show All 75 Lines • Show Last 20 Lines |