acpi.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /* acpi.c - get acpi tables. */
  2. /*
  3. * GRUB -- GRand Unified Bootloader
  4. * Copyright (C) 2009 Free Software Foundation, Inc.
  5. *
  6. * GRUB is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * GRUB is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <grub/acpi.h>
  20. #include <grub/misc.h>
  21. struct grub_acpi_rsdp_v10 *
  22. grub_machine_acpi_get_rsdpv1 (void)
  23. {
  24. int ebda_len;
  25. grub_uint8_t *ebda, *ptr;
  26. grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
  27. ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) grub_absolute_pointer (0x40e))) << 4);
  28. ebda_len = * (grub_uint16_t *) ebda;
  29. if (! ebda_len) /* FIXME do we really need this check? */
  30. goto scan_bios;
  31. for (ptr = ebda; ptr < ebda + 0x400; ptr += 16)
  32. if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0
  33. && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
  34. && ((struct grub_acpi_rsdp_v10 *) ptr)->revision == 0)
  35. return (struct grub_acpi_rsdp_v10 *) ptr;
  36. scan_bios:
  37. grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
  38. for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000;
  39. ptr += 16)
  40. if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0
  41. && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
  42. && ((struct grub_acpi_rsdp_v10 *) ptr)->revision == 0)
  43. return (struct grub_acpi_rsdp_v10 *) ptr;
  44. return 0;
  45. }
  46. struct grub_acpi_rsdp_v20 *
  47. grub_machine_acpi_get_rsdpv2 (void)
  48. {
  49. int ebda_len;
  50. grub_uint8_t *ebda, *ptr;
  51. grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
  52. ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) grub_absolute_pointer (0x40e))) << 4);
  53. ebda_len = * (grub_uint16_t *) ebda;
  54. if (! ebda_len) /* FIXME do we really need this check? */
  55. goto scan_bios;
  56. for (ptr = ebda; ptr < ebda + 0x400; ptr += 16)
  57. if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0
  58. && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
  59. && ((struct grub_acpi_rsdp_v10 *) ptr)->revision != 0
  60. && ((struct grub_acpi_rsdp_v20 *) ptr)->length < 1024
  61. && grub_byte_checksum (ptr, ((struct grub_acpi_rsdp_v20 *) ptr)->length)
  62. == 0)
  63. return (struct grub_acpi_rsdp_v20 *) ptr;
  64. scan_bios:
  65. grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
  66. for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000;
  67. ptr += 16)
  68. if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0
  69. && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
  70. && ((struct grub_acpi_rsdp_v10 *) ptr)->revision != 0
  71. && ((struct grub_acpi_rsdp_v20 *) ptr)->length < 1024
  72. && grub_byte_checksum (ptr, ((struct grub_acpi_rsdp_v20 *) ptr)->length)
  73. == 0)
  74. return (struct grub_acpi_rsdp_v20 *) ptr;
  75. return 0;
  76. }