Use the HSM SBI extension to start APs
The addition of the HSM SBI extension to OpenSBI introduces a new breaking change: secondary harts will remain parked in the firmware, until they are brought up explicitly via sbi_hsm_hart_start(). Add the call to do this, sending the secondary harts to mpentry. If the HSM extension is not present, secondary harts are assumed to be released by the firmware, as is the case for OpenSBI =< v0.6 and BBL. In the case that the HSM call fails we exclude the CPU, notify the user, and allow the system to proceed with booting. Reviewed by: markj (older version) Differential Revision: https://reviews.freebsd.org/D24497
This commit is contained in:
parent
bfe918fa0e
commit
c74959537c
@ -97,6 +97,7 @@ static uint32_t cpu_reg[MAXCPU][2];
|
||||
#endif
|
||||
static device_t cpu_list[MAXCPU];
|
||||
|
||||
void mpentry(u_long hartid);
|
||||
void init_secondary(uint64_t);
|
||||
|
||||
static struct mtx ap_boot_mtx;
|
||||
@ -297,7 +298,7 @@ smp_after_idle_runnable(void *arg __unused)
|
||||
struct pcpu *pc;
|
||||
int cpu;
|
||||
|
||||
for (cpu = 1; cpu < mp_ncpus; cpu++) {
|
||||
for (cpu = 1; cpu <= mp_maxid; cpu++) {
|
||||
if (bootstacks[cpu] != NULL) {
|
||||
pc = pcpu_find(cpu);
|
||||
while (atomic_load_ptr(&pc->pc_curpcb) == NULL)
|
||||
@ -399,9 +400,11 @@ static boolean_t
|
||||
cpu_init_fdt(u_int id, phandle_t node, u_int addr_size, pcell_t *reg)
|
||||
{
|
||||
struct pcpu *pcpup;
|
||||
vm_paddr_t start_addr;
|
||||
uint64_t hart;
|
||||
u_int cpuid;
|
||||
int naps;
|
||||
int error;
|
||||
|
||||
/* Check if this hart supports MMU. */
|
||||
if (OF_getproplen(node, "mmu-type") < 0)
|
||||
@ -441,6 +444,23 @@ cpu_init_fdt(u_int id, phandle_t node, u_int addr_size, pcell_t *reg)
|
||||
if (cpuid > mp_maxid)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Depending on the SBI implementation, APs are waiting either in
|
||||
* locore.S or to be activated explicitly, via SBI call.
|
||||
*/
|
||||
if (sbi_probe_extension(SBI_EXT_ID_HSM) != 0) {
|
||||
start_addr = pmap_kextract((vm_offset_t)mpentry);
|
||||
error = sbi_hsm_hart_start(hart, start_addr, 0);
|
||||
if (error != 0) {
|
||||
mp_ncpus--;
|
||||
|
||||
/* Send a warning to the user and continue. */
|
||||
printf("AP %u (hart %lu) failed to start, error %d\n",
|
||||
cpuid, hart, error);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
pcpup = &__pcpu[cpuid];
|
||||
pcpu_init(pcpup, cpuid, sizeof(struct pcpu));
|
||||
pcpup->pc_hart = hart;
|
||||
|
Loading…
Reference in New Issue
Block a user