base.c 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Write base ACPI tables
  4. *
  5. * Copyright 2021 Google LLC
  6. */
  7. #define LOG_CATEGORY LOGC_ACPI
  8. #include <common.h>
  9. #include <acpi/acpi_table.h>
  10. #include <dm/acpi.h>
  11. #include <mapmem.h>
  12. #include <tables_csum.h>
  13. void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt,
  14. struct acpi_xsdt *xsdt)
  15. {
  16. memset(rsdp, 0, sizeof(struct acpi_rsdp));
  17. memcpy(rsdp->signature, RSDP_SIG, 8);
  18. memcpy(rsdp->oem_id, OEM_ID, 6);
  19. rsdp->length = sizeof(struct acpi_rsdp);
  20. rsdp->rsdt_address = map_to_sysmem(rsdt);
  21. rsdp->xsdt_address = map_to_sysmem(xsdt);
  22. rsdp->revision = ACPI_RSDP_REV_ACPI_2_0;
  23. /* Calculate checksums */
  24. rsdp->checksum = table_compute_checksum(rsdp, 20);
  25. rsdp->ext_checksum = table_compute_checksum(rsdp,
  26. sizeof(struct acpi_rsdp));
  27. }
  28. static void acpi_write_rsdt(struct acpi_rsdt *rsdt)
  29. {
  30. struct acpi_table_header *header = &rsdt->header;
  31. /* Fill out header fields */
  32. acpi_fill_header(header, "RSDT");
  33. header->length = sizeof(struct acpi_rsdt);
  34. header->revision = 1;
  35. /* Entries are filled in later, we come with an empty set */
  36. /* Fix checksum */
  37. header->checksum = table_compute_checksum(rsdt,
  38. sizeof(struct acpi_rsdt));
  39. }
  40. static void acpi_write_xsdt(struct acpi_xsdt *xsdt)
  41. {
  42. struct acpi_table_header *header = &xsdt->header;
  43. /* Fill out header fields */
  44. acpi_fill_header(header, "XSDT");
  45. header->length = sizeof(struct acpi_xsdt);
  46. header->revision = 1;
  47. /* Entries are filled in later, we come with an empty set */
  48. /* Fix checksum */
  49. header->checksum = table_compute_checksum(xsdt,
  50. sizeof(struct acpi_xsdt));
  51. }
  52. static int acpi_write_base(struct acpi_ctx *ctx,
  53. const struct acpi_writer *entry)
  54. {
  55. /* We need at least an RSDP and an RSDT Table */
  56. ctx->rsdp = ctx->current;
  57. acpi_inc_align(ctx, sizeof(struct acpi_rsdp));
  58. ctx->rsdt = ctx->current;
  59. acpi_inc_align(ctx, sizeof(struct acpi_rsdt));
  60. ctx->xsdt = ctx->current;
  61. acpi_inc_align(ctx, sizeof(struct acpi_xsdt));
  62. /* clear all table memory */
  63. memset(ctx->base, '\0', ctx->current - ctx->base);
  64. acpi_write_rsdp(ctx->rsdp, ctx->rsdt, ctx->xsdt);
  65. acpi_write_rsdt(ctx->rsdt);
  66. acpi_write_xsdt(ctx->xsdt);
  67. return 0;
  68. }
  69. /*
  70. * Per ACPI spec, the FACS table address must be aligned to a 64-byte boundary
  71. * (Windows checks this, but Linux does not).
  72. *
  73. * Use the '0' prefix to put this one first
  74. */
  75. ACPI_WRITER(0base, NULL, acpi_write_base, ACPIWF_ALIGN64);