Esempio n. 1
0
/* 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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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);
}