Beispiel #1
0
/*
 * Halt the system, using APM if possible. If NO_APM is true, don't use
 * APM even if it is available.
 */
void 
grub_halt (int no_apm)
{
  struct grub_bios_int_registers regs;

  grub_acpi_halt ();

  if (no_apm)
    stop ();

  /* detect APM */
  regs.eax = 0x5300;
  regs.ebx = 0;
  regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
  grub_bios_interrupt (0x15, &regs);
  
  if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY)
    stop ();

  /* disconnect APM first */
  regs.eax = 0x5304;
  regs.ebx = 0;
  regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
  grub_bios_interrupt (0x15, &regs);

  /* connect APM */
  regs.eax = 0x5301;
  regs.ebx = 0;
  regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
  grub_bios_interrupt (0x15, &regs);
  if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY)
    stop ();

  /* set APM protocol level - 1.1 or bust. (this covers APM 1.2 also) */
  regs.eax = 0x530E;
  regs.ebx = 0;
  regs.ecx = 0x0101;
  regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
  grub_bios_interrupt (0x15, &regs);
  if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY)
    stop ();

  /* set the power state to off */
  regs.eax = 0x5307;
  regs.ebx = 1;
  regs.ecx = 3;
  regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
  grub_bios_interrupt (0x15, &regs);

  /* shouldn't reach here */
  stop ();
}
Beispiel #2
0
/* Get a memory map entry. Return next continuation value. Zero means
   the end.  */
static grub_uint32_t
grub_get_mmap_entry (struct grub_machine_mmap_entry *entry,
		     grub_uint32_t cont)
{
  struct grub_bios_int_registers regs;

  regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;

  /* place address (+4) in ES:DI */
  regs.es = ((grub_addr_t) &entry->addr) >> 4;
  regs.edi = ((grub_addr_t) &entry->addr) & 0xf;
	
  /* set continuation value */
  regs.ebx = cont;

  /* set default maximum buffer size */
  regs.ecx = sizeof (*entry) - sizeof (entry->size);

  /* set EDX to 'SMAP' */
  regs.edx = 0x534d4150;

  regs.eax = 0xe820;
  grub_bios_interrupt (0x15, &regs);

  /* write length of buffer (zero if error) into ADDR */	
  if ((regs.flags & GRUB_CPU_INT_FLAGS_CARRY) || regs.eax != 0x534d4150
      || regs.ecx < 0x14 || regs.ecx > 0x400)
    entry->size = 0;
  else
    entry->size = regs.ecx;

  /* return the continuation value */
  return regs.ebx;
}
Beispiel #3
0
/*
 *
 * grub_get_conv_memsize(i) :  return the conventional memory size in KB.
 *	BIOS call "INT 12H" to get conventional memory size
 *      The return value in AX.
 */
static inline grub_uint16_t
grub_get_conv_memsize (void)
{
  struct grub_bios_int_registers regs;

  regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
  grub_bios_interrupt (0x12, &regs);
  return regs.eax & 0xffff;
}
Beispiel #4
0
static void
int10_9 (grub_uint8_t ch, grub_uint16_t n)
{
  struct grub_bios_int_registers regs;

  regs.eax = ch | 0x0900;
  regs.ebx = grub_console_cur_color & 0xff;
  regs.ecx = n;
  regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;  
  grub_bios_interrupt (0x10, &regs);
}
Beispiel #5
0
int
grub_apm_get_info (struct grub_apm_info *info)
{
  struct grub_bios_int_registers regs;

  /* detect APM */
  regs.eax = 0x5300;
  regs.ebx = 0;
  regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
  grub_bios_interrupt (0x15, &regs);
  
  if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY)
    return 0;
  info->version = regs.eax & 0xffff;
  info->flags = regs.ecx & 0xffff;

  /* disconnect APM first */
  regs.eax = 0x5304;
  regs.ebx = 0;
  regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
  grub_bios_interrupt (0x15, &regs);

  /* connect APM */
  regs.eax = 0x5303;
  regs.ebx = 0;
  regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
  grub_bios_interrupt (0x15, &regs);

  if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY)
    return 0;

  info->cseg = regs.eax & 0xffff;
  info->offset = regs.ebx;
  info->cseg_16 = regs.ecx & 0xffff;
  info->dseg = regs.edx & 0xffff;
  info->cseg_len = regs.esi >> 16;
  info->cseg_16_len = regs.esi & 0xffff;
  info->dseg_len = regs.edi;

  return 1;
}
Beispiel #6
0
static inline grub_uint32_t
grub_get_eisa_mmap (void)
{
  struct grub_bios_int_registers regs;

  regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
  regs.eax = 0xe801;
  grub_bios_interrupt (0x15, &regs);

  if ((regs.eax & 0xff00) == 0x8600)
    return 0;

  return (regs.eax & 0xffff) | (regs.ebx << 16);
}