void grub_acpi_halt (void) { struct grub_acpi_rsdp_v20 *rsdp2; struct grub_acpi_rsdp_v10 *rsdp1; struct grub_acpi_table_header *rsdt; grub_uint32_t *entry_ptr; rsdp2 = grub_acpi_get_rsdpv2 (); if (rsdp2) rsdp1 = &(rsdp2->rsdpv1); else rsdp1 = grub_acpi_get_rsdpv1 (); grub_dprintf ("acpi", "rsdp1=%p\n", rsdp1); if (!rsdp1) return; rsdt = (struct grub_acpi_table_header *) (grub_addr_t) rsdp1->rsdt_addr; for (entry_ptr = (grub_uint32_t *) (rsdt + 1); entry_ptr < (grub_uint32_t *) (((grub_uint8_t *) rsdt) + rsdt->length); entry_ptr++) { if (grub_memcmp ((void *) (grub_addr_t) *entry_ptr, "FACP", 4) == 0) { grub_uint32_t port; struct grub_acpi_fadt *fadt = ((struct grub_acpi_fadt *) (grub_addr_t) *entry_ptr); struct grub_acpi_table_header *dsdt = (struct grub_acpi_table_header *) (grub_addr_t) fadt->dsdt_addr; int sleep_type = -1; port = fadt->pm1a; grub_dprintf ("acpi", "PM1a port=%x\n", port); if (grub_memcmp (dsdt->signature, "DSDT", sizeof (dsdt->signature)) != 0) break; sleep_type = get_sleep_type ((grub_uint8_t *) dsdt, (grub_uint8_t *) dsdt + dsdt->length); if (sleep_type < 0 || sleep_type >= 8) break; grub_dprintf ("acpi", "SLP_TYP = %d, port = 0x%x\n", sleep_type, port); grub_outw (GRUB_ACPI_SLP_EN | (sleep_type << GRUB_ACPI_SLP_TYP_OFFSET), port & 0xffff); } } grub_millisleep (1500); /* TRANSLATORS: It's computer shutdown using ACPI, not disabling ACPI. */ grub_puts_ (N_("ACPI shutdown failed")); }
static grub_err_t grub_cmd_write (grub_command_t cmd, int argc, char **argv) { grub_target_addr_t addr; grub_uint32_t value; grub_uint32_t mask = 0xffffffff; if (argc != 2 && argc != 3) return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments"); addr = grub_strtoul (argv[0], 0, 0); value = grub_strtoul (argv[1], 0, 0); if (argc == 3) mask = grub_strtoul (argv[2], 0, 0); value &= mask; switch (cmd->name[sizeof ("out") - 1]) { case 'l': if (mask != 0xffffffff) grub_outl ((grub_inl (addr) & ~mask) | value, addr); else grub_outl (value, addr); break; case 'w': if ((mask & 0xffff) != 0xffff) grub_outw ((grub_inw (addr) & ~mask) | value, addr); else grub_outw (value, addr); break; case 'b': if ((mask & 0xff) != 0xff) grub_outb ((grub_inb (addr) & ~mask) | value, addr); else grub_outb (value, addr); break; } return 0; }
void grub_acpi_halt (void) { struct grub_acpi_rsdp_v20 *rsdp2; struct grub_acpi_rsdp_v10 *rsdp1; struct grub_acpi_table_header *rsdt; grub_uint32_t *entry_ptr; grub_uint32_t port = 0; int sleep_type = -1; rsdp2 = grub_acpi_get_rsdpv2 (); if (rsdp2) rsdp1 = &(rsdp2->rsdpv1); else rsdp1 = grub_acpi_get_rsdpv1 (); grub_dprintf ("acpi", "rsdp1=%p\n", rsdp1); if (!rsdp1) return; rsdt = (struct grub_acpi_table_header *) io_map_cached (rsdp1->rsdt_addr, sizeof *rsdt); rsdt = (struct grub_acpi_table_header *) io_map_cached (rsdp1->rsdt_addr, rsdt->length); for (entry_ptr = (grub_uint32_t *) (rsdt + 1); entry_ptr < (grub_uint32_t *) (((grub_uint8_t *) rsdt) + rsdt->length); entry_ptr++) { if (grub_memcmp ((void *) io_map_cached (*entry_ptr, 4), "FACP", 4) == 0) { struct grub_acpi_fadt *fadt = (struct grub_acpi_fadt *) io_map_cached (*entry_ptr, sizeof *fadt); struct grub_acpi_table_header *dsdt = (struct grub_acpi_table_header *) io_map_cached (fadt->dsdt_addr, sizeof *dsdt); grub_uint8_t *buf = (grub_uint8_t *) io_map_cached (fadt->dsdt_addr, dsdt->length); port = fadt->pm1a; grub_dprintf ("acpi", "PM1a port=%x\n", port); if (grub_memcmp (dsdt->signature, "DSDT", sizeof (dsdt->signature)) == 0 && sleep_type < 0) sleep_type = get_sleep_type (buf, NULL, buf + dsdt->length, NULL, 0); } else if (grub_memcmp ((void *) io_map_cached (*entry_ptr, 4), "SSDT", 4) == 0 && sleep_type < 0) { struct grub_acpi_table_header *ssdt = (struct grub_acpi_table_header *) (grub_addr_t) io_map_cached (*entry_ptr, sizeof *ssdt); grub_uint8_t *buf = (grub_uint8_t *) io_map_cached (*entry_ptr, ssdt->length); grub_dprintf ("acpi", "SSDT = %p\n", ssdt); sleep_type = get_sleep_type (buf, NULL, buf + ssdt->length, NULL, 0); } } grub_dprintf ("acpi", "SLP_TYP = %d, port = 0x%x\n", sleep_type, port); if (port && sleep_type >= 0 && sleep_type < 8) grub_outw (GRUB_ACPI_SLP_EN | (sleep_type << GRUB_ACPI_SLP_TYP_OFFSET), port & 0xffff); grub_millisleep (1500); /* TRANSLATORS: It's computer shutdown using ACPI, not disabling ACPI. */ grub_puts_ (N_("ACPI shutdown failed")); }