示例#1
0
void
grub_halt (
#ifdef GRUB_MACHINE_PCBIOS
	   int no_apm __attribute__ ((unused))
#endif
	   )
{
  grub_reboot ();
}
示例#2
0
/*
 * 64-bit boot state initilization. This is really only used for FreeBSD.
 * It is assumed that the repeating 1GB page tables have already been
 * setup. The bhyve library call does almost everything - remaining
 * GP register state is set here
 */
void
grub_emu_bhyve_boot64(struct grub_relocator64_state rs)
{
  uint64_t gdt64[3];
  uint64_t gdt64_addr;
  int error;

  /*
   * Set up the GDT by copying it to just below the top of low memory
   * and point the guest's GDT descriptor at it
   */
  gdt64_addr = bhyve_g2h.lomem - 2 * sizeof(gdt64);
  vm_setup_freebsd_gdt(gdt64);
  memcpy(grub_emu_bhyve_virt(gdt64_addr), gdt64, sizeof(gdt64));

  /*
   * Use the library API to set up a FreeBSD entry reg state
   */
  error = vm_setup_freebsd_registers(bhyve_ctx, 0, rs.rip, rs.cr3, 
				     gdt64_addr, rs.rsp);
  assert(error == 0);

  /* Set up the remaining regs */
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_RAX, rs.rax) == 0);
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_RBX, rs.rbx) == 0);
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_RCX, rs.rcx) == 0);
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_RDX, rs.rdx) == 0);
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_RSI, rs.rsi) == 0);

  /*
   * Exit cleanly, using the conditional test to avoid the noreturn
   * warning.
   */
  if (gdt64_addr)
    grub_reboot();
}
static void
elilo_reboot(void)
{
	grub_reboot();
} /* elilo_reboot */
示例#4
0
/*
 * 32-bit boot state initialization. The Linux sequence appears to
 * work fine for Net/OpenBSD kernel entry. Use the GP register state
 * passed in, and copy other info to the allocated phys address, bt.
 */
void
grub_emu_bhyve_boot32(grub_uint32_t bt, struct grub_relocator32_state rs)
{
  uint64_t cr0, cr4, rflags, desc_base;
  uint32_t desc_access, desc_limit;
  uint16_t gsel;

  /*
   * "At entry, the CPU must be in 32-bit protected mode with paging
   * disabled;"
   */
  cr0 = CR0_PE;
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_CR0, cr0) == 0);

  cr4 = 0;
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_CR4, cr4) == 0);

  /*
   * Reserved bit 1 set to 1. "interrupt must be disabled"
   */
  rflags = 0x2;
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_RFLAGS, rflags) == 0);

  /*
   * "__BOOT_CS(0x10) and __BOOT_DS(0x18); both descriptors must be 4G
   * flat segment; __BOOS_CS must have execute/read permission, and
   * __BOOT_DS must have read/write permission; CS must be __BOOT_CS"
   */
  desc_base = 0;
  desc_limit = 0xffffffff;
  desc_access = 0x0000C09B;
  assert(vm_set_desc(bhyve_ctx, 0, VM_REG_GUEST_CS,
		     desc_base, desc_limit, desc_access) == 0);

  desc_access = 0x0000C093;
  assert(vm_set_desc(bhyve_ctx, 0, VM_REG_GUEST_DS,
		     desc_base, desc_limit, desc_access) == 0);

  /*
   * ... "and DS, ES, SS must be __BOOT_DS;"
   */
  assert(vm_set_desc(bhyve_ctx, 0, VM_REG_GUEST_ES,
		     desc_base, desc_limit, desc_access) == 0);
  assert(vm_set_desc(bhyve_ctx, 0, VM_REG_GUEST_FS,
		     desc_base, desc_limit, desc_access) == 0);
  assert(vm_set_desc(bhyve_ctx, 0, VM_REG_GUEST_GS,
		     desc_base, desc_limit, desc_access) == 0);
  assert(vm_set_desc(bhyve_ctx, 0, VM_REG_GUEST_SS,
		     desc_base, desc_limit, desc_access) == 0);

  /*
   * XXX TR is pointing to null selector even though we set the
   * TSS segment to be usable with a base address and limit of 0.
   * Has to be 8b or vmenter will fail
   */
  desc_access = 0x0000008b;
  assert(vm_set_desc(bhyve_ctx, 0, VM_REG_GUEST_TR, 0x1000, 0x67,
		     desc_access) == 0);

  assert(vm_set_desc(bhyve_ctx, 0, VM_REG_GUEST_LDTR, 0, 0xffff,
		     DESC_UNUSABLE | 0x82) == 0);

  gsel = GSEL(GUEST_CODE_SEL, SEL_KPL);
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_CS, gsel) == 0);

  gsel = GSEL(GUEST_DATA_SEL, SEL_KPL);
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_DS, gsel) == 0);
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_ES, gsel) == 0);
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_FS, gsel) == 0);
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_GS, gsel) == 0);
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_SS, gsel) == 0);

  /* XXX TR is pointing to selector 1 */
  gsel = GSEL(GUEST_TSS_SEL, SEL_KPL);
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_TR, gsel) == 0);

  /* LDTR is pointing to the null selector */
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_LDTR, 0) == 0);

  /*
   * "In 32-bit boot protocol, the kernel is started by jumping to the
   * 32-bit kernel entry point, which is the start address of loaded
   * 32/64-bit kernel."
   */
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_RIP, rs.eip) == 0);

  /*
   * Set up the GDT by copying it into low memory, and then pointing
   * the guest's GDT descriptor at it
   */
  memcpy(grub_emu_bhyve_virt(bt), bhyve_gdt, sizeof(bhyve_gdt));
  desc_base = bt;
  desc_limit = GUEST_GDTR_LIMIT;
  assert(vm_set_desc(bhyve_ctx, 0, VM_REG_GUEST_GDTR, desc_base,
    desc_limit, 0) == 0);;
  
  /*
   * Set the stack to be just below the params real-mode area
   */
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_RSP, rs.esp) == 0);

  /*
   * "%esi must hold the base address of the struct boot_params"
   */
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_RSI, rs.esi) == 0);

  /*
   * "%ebp, %edi and %ebx must be zero."
   * Assume that grub set these up correctly - might be different for
   * *BSD. While at it, init the remaining passed-in register state.
   */
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_RBP, rs.ebp) == 0);
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_RDI, rs.edi) == 0);
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_RBX, rs.ebx) == 0);

  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_RAX, rs.eax) == 0);
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_RCX, rs.ecx) == 0);
  assert(vm_set_register(bhyve_ctx, 0, VM_REG_GUEST_RDX, rs.edx) == 0);

  /*
   * XXX debug: turn on tracing
   */
#if 0
  assert(vm_set_capability(bhyve_ctx, 0, VM_CAP_MTRAP_EXIT, 1) == 0);
#endif

  /*
   * Exit cleanly, using the conditional test to avoid the noreturn
   * warning.
   */
  if (bt)
    grub_reboot();
}