static void init_primary_cpu_post(void) { /* Perform any necessary BSP initialization */ init_bsp(); init_debug_pre(); init_cpu_post(BOOT_CPU_ID); init_debug_post(BOOT_CPU_ID); init_passthru(); enter_guest_mode(BOOT_CPU_ID); }
int mp_init(struct mp_params *p) { int num_aps; atomic_t *ap_count; struct udevice *cpu; int ret; /* This will cause the CPUs devices to be bound */ struct uclass *uc; ret = uclass_get(UCLASS_CPU, &uc); if (ret) return ret; ret = init_bsp(&cpu); if (ret) { debug("Cannot init boot CPU: err=%d\n", ret); return ret; } if (p == NULL || p->flight_plan == NULL || p->num_records < 1) { printf("Invalid MP parameters\n"); return -1; } num_cpus = cpu_get_count(cpu); if (num_cpus < 0) { debug("Cannot get number of CPUs: err=%d\n", num_cpus); return num_cpus; } if (num_cpus < 2) debug("Warning: Only 1 CPU is detected\n"); ret = check_cpu_devices(num_cpus); if (ret) debug("Warning: Device tree does not describe all CPUs. Extra ones will not be started correctly\n"); /* Copy needed parameters so that APs have a reference to the plan */ mp_info.num_records = p->num_records; mp_info.records = p->flight_plan; /* Load the SIPI vector */ ret = load_sipi_vector(&ap_count); if (ap_count == NULL) return -1; /* * Make sure SIPI data hits RAM so the APs that come up will see * the startup code even if the caches are disabled */ wbinvd(); /* Start the APs providing number of APs and the cpus_entered field */ num_aps = num_cpus - 1; ret = start_aps(num_aps, ap_count); if (ret) { mdelay(1000); debug("%d/%d eventually checked in?\n", atomic_read(ap_count), num_aps); return ret; } /* Walk the flight plan for the BSP */ ret = bsp_do_flight_plan(cpu, p); if (ret) { debug("CPU init failed: err=%d\n", ret); return ret; } return 0; }