void cpu_up(int id) { extern char _bootother_start[]; extern uint64_t _bootother_size; extern void (*apstart)(void); char *stack; unsigned char *code = (unsigned char*)VADDR_DIRECT(0x7000); struct cpu *c = per_cpu_ptr(cpus, id); assert(c->id != myid()); assert(c->id == id); memcpy(code, _bootother_start, _bootother_size); stack = (char*)page2kva(alloc_pages_cpu(c, KSTACKPAGE)); assert(stack != NULL); kprintf("LAPIC %d, CODE %p PA: %p, STACK: %p\n", c->hwid, code, PADDR_DIRECT(code), stack); warmreset(PADDR_DIRECT(code)); *(uint32_t*)(code-4) = (uint32_t)PADDR_DIRECT(&apstart); *(uint64_t*)(code-12) = (uint64_t)stack + KSTACKSIZE; *(uint64_t*)(code-20) = (uint64_t)boot_cr3; // bootother.S sets this to 0x0a55face early on *(uint32_t*)(code-64) = 0; bcpuid = c->id; atomic_set(&bsync, 0); lapic_start_ap(c, PADDR_DIRECT(code)); while(atomic_read(&bsync) == 0) nop_pause(); rstrreset(); }
static int lapic_icr_wait() { uint32_t i = 100000; while ((lapic_read(ICRLO) & DLSTAT_BUSY) != 0) { nop_pause(); i--; if (i == 0) { cprintf("apic_icr_wait: wedged?\n"); return -E_INVAL; } } return 0; }