/* bring up an AP */ static void smp_boot(cpu_t *cpu) { /* figure out where the trampoline is */ extern int trampoline_start, trampoline_end, trampoline_stack; size_t trampoline_len = (uintptr_t) &trampoline_end - (uintptr_t) &trampoline_start; /* map the trampoline into low memory */ if (!vmm_map_range(TRAMPOLINE_BASE, TRAMPOLINE_BASE, trampoline_len, VM_R | VM_W | VM_X)) panic("couldn't map SMP trampoline code"); /* allocate a stack for this AP */ void *idle_stack = memalign(IDLE_STACK_ALIGN, IDLE_STACK_SIZE); if (!idle_stack) panic("couldn't allocate AP stack"); /* set up this cpu's bootstrap stack */ uint64_t *rsp = (uint64_t *) &trampoline_stack; *rsp = (uint64_t) idle_stack + IDLE_STACK_SIZE; /* set the pointer to the cpu struct of the cpu we are booting */ booted_cpu = cpu; /* copy the trampoline into low memory */ memcpy((void *) TRAMPOLINE_BASE, &trampoline_start, trampoline_len); /* reset the ack flag */ ack_sipi = false; barrier(); /* send INIT IPI */ apic_ipi_init(cpu->lapic_id); pit_mdelay(10); /* send STARTUP IPI */ uint8_t vector = TRAMPOLINE_BASE / FRAME_SIZE; apic_ipi_startup(cpu->lapic_id, vector); pit_mdelay(1); /* send STARTUP IPI again */ if (!ack_sipi) { apic_ipi_startup(cpu->lapic_id, vector); pit_mdelay(1); } /* wait for the AP to come up */ while (!ack_sipi) pause_once(); /* unmap the trampoline */ vmm_unmap_range(TRAMPOLINE_BASE, trampoline_len); }
void mmio_unmap(void *virt, size_t len) { /* align the address and pad with extra length */ uintptr_t aligned_virt = PAGE_ALIGN_REVERSE((uintptr_t) virt); size_t off = (uintptr_t) virt - aligned_virt; len += off; /* unmap the physical memory */ vmm_unmap_range(aligned_virt, len); /* unreserve the virtual memory in the heap */ heap_free((void *) aligned_virt); }
void shm_detach(vmm_context_t *context, shm_descriptor_t *desc) { uintptr_t start = (uintptr_t)desc->base & PAGE_MASK; size_t num_pages = desc->context->size; vmm_unmap_range(context, start, num_pages); }