acpi.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. * Copyright (C) 2015, Saket Sinha <saket.sinha89@gmail.com>
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <common.h>
  7. #include <asm/acpi_table.h>
  8. #include <asm/ioapic.h>
  9. #include <asm/tables.h>
  10. void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs,
  11. void *dsdt)
  12. {
  13. acpi_header_t *header = &(fadt->header);
  14. u16 pmbase;
  15. pci_dev_t bdf = PCI_BDF(0, 0x1f, 0);
  16. pci_read_config_word(bdf, 0x40, &pmbase);
  17. /*
  18. * TODO(saket.sinha89@gmail.com): wrong value
  19. * of pmbase by above function. Hard-coding it to
  20. * correct value. Since no PCI register is
  21. * programmed Power Management Interface is
  22. * not working
  23. */
  24. pmbase = 0x0600;
  25. memset((void *)fadt, 0, sizeof(struct acpi_fadt));
  26. memcpy(header->signature, "FACP", 4);
  27. header->length = sizeof(struct acpi_fadt);
  28. header->revision = 3;
  29. memcpy(header->oem_id, OEM_ID, 6);
  30. memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
  31. memcpy(header->asl_compiler_id, ASLC, 4);
  32. header->asl_compiler_revision = 0;
  33. fadt->firmware_ctrl = (unsigned long) facs;
  34. fadt->dsdt = (unsigned long) dsdt;
  35. fadt->model = 0x00;
  36. fadt->preferred_pm_profile = PM_MOBILE;
  37. fadt->sci_int = 0x9;
  38. fadt->smi_cmd = 0;
  39. fadt->acpi_enable = 0;
  40. fadt->acpi_disable = 0;
  41. fadt->s4bios_req = 0x0;
  42. fadt->pstate_cnt = 0;
  43. fadt->pm1a_evt_blk = pmbase;
  44. fadt->pm1b_evt_blk = 0x0;
  45. fadt->pm1a_cnt_blk = pmbase + 0x4;
  46. fadt->pm1b_cnt_blk = 0x0;
  47. fadt->pm2_cnt_blk = pmbase + 0x50;
  48. fadt->pm_tmr_blk = pmbase + 0x8;
  49. fadt->gpe0_blk = pmbase + 0x20;
  50. fadt->gpe1_blk = 0;
  51. fadt->pm1_evt_len = 4;
  52. /*
  53. * Upper word is reserved and
  54. * Linux complains about 32 bit
  55. */
  56. fadt->pm1_cnt_len = 2;
  57. fadt->pm2_cnt_len = 1;
  58. fadt->pm_tmr_len = 4;
  59. fadt->gpe0_blk_len = 16;
  60. fadt->gpe1_blk_len = 0;
  61. fadt->gpe1_base = 0;
  62. fadt->cst_cnt = 0;
  63. fadt->p_lvl2_lat = 1;
  64. fadt->p_lvl3_lat = 0x39;
  65. fadt->flush_size = 0;
  66. fadt->flush_stride = 0;
  67. fadt->duty_offset = 1;
  68. fadt->duty_width = 3;
  69. fadt->day_alrm = 0xd;
  70. fadt->mon_alrm = 0x00;
  71. fadt->century = 0x32;
  72. fadt->iapc_boot_arch = 0x00;
  73. fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED |
  74. ACPI_FADT_SLEEP_BUTTON | ACPI_FADT_S4_RTC_WAKE |
  75. ACPI_FADT_DOCKING_SUPPORTED | ACPI_FADT_RESET_REGISTER |
  76. ACPI_FADT_PLATFORM_CLOCK;
  77. fadt->reset_reg.space_id = ACPI_ADDRESS_SPACE_IO;
  78. fadt->reset_reg.bit_width = 8;
  79. fadt->reset_reg.bit_offset = 0;
  80. fadt->reset_reg.resv = 0;
  81. fadt->reset_reg.addrl = 0xcf9;
  82. fadt->reset_reg.addrh = 0;
  83. fadt->reset_value = 0x06;
  84. /*
  85. * Set X_FIRMWARE_CTRL only if FACS is
  86. * above 4GB. If X_FIRMWARE_CTRL is set,
  87. * then FIRMWARE_CTRL must be zero
  88. */
  89. fadt->x_firmware_ctl_l = 0;
  90. fadt->x_firmware_ctl_h = 0;
  91. fadt->x_dsdt_l = (unsigned long)dsdt;
  92. fadt->x_dsdt_h = 0;
  93. fadt->x_pm1a_evt_blk.space_id = 1;
  94. fadt->x_pm1a_evt_blk.bit_width = 32;
  95. fadt->x_pm1a_evt_blk.bit_offset = 0;
  96. fadt->x_pm1a_evt_blk.resv = 0;
  97. fadt->x_pm1a_evt_blk.addrl = pmbase;
  98. fadt->x_pm1a_evt_blk.addrh = 0x0;
  99. fadt->x_pm1b_evt_blk.space_id = 0;
  100. fadt->x_pm1b_evt_blk.bit_width = 0;
  101. fadt->x_pm1b_evt_blk.bit_offset = 0;
  102. fadt->x_pm1b_evt_blk.resv = 0;
  103. fadt->x_pm1b_evt_blk.addrl = 0x0;
  104. fadt->x_pm1b_evt_blk.addrh = 0x0;
  105. fadt->x_pm1a_cnt_blk.space_id = 1;
  106. /*
  107. * Upper word is reserved and
  108. * Linux complains about 32 bit
  109. */
  110. fadt->x_pm1a_cnt_blk.bit_width = 16;
  111. fadt->x_pm1a_cnt_blk.bit_offset = 0;
  112. fadt->x_pm1a_cnt_blk.resv = 0;
  113. fadt->x_pm1a_cnt_blk.addrl = pmbase + 0x4;
  114. fadt->x_pm1a_cnt_blk.addrh = 0x0;
  115. fadt->x_pm1b_cnt_blk.space_id = 0;
  116. fadt->x_pm1b_cnt_blk.bit_width = 0;
  117. fadt->x_pm1b_cnt_blk.bit_offset = 0;
  118. fadt->x_pm1b_cnt_blk.resv = 0;
  119. fadt->x_pm1b_cnt_blk.addrl = 0x0;
  120. fadt->x_pm1b_cnt_blk.addrh = 0x0;
  121. fadt->x_pm2_cnt_blk.space_id = 1;
  122. fadt->x_pm2_cnt_blk.bit_width = 8;
  123. fadt->x_pm2_cnt_blk.bit_offset = 0;
  124. fadt->x_pm2_cnt_blk.resv = 0;
  125. fadt->x_pm2_cnt_blk.addrl = pmbase + 0x50;
  126. fadt->x_pm2_cnt_blk.addrh = 0x0;
  127. fadt->x_pm_tmr_blk.space_id = 1;
  128. fadt->x_pm_tmr_blk.bit_width = 32;
  129. fadt->x_pm_tmr_blk.bit_offset = 0;
  130. fadt->x_pm_tmr_blk.resv = 0;
  131. fadt->x_pm_tmr_blk.addrl = pmbase + 0x8;
  132. fadt->x_pm_tmr_blk.addrh = 0x0;
  133. fadt->x_gpe0_blk.space_id = 1;
  134. fadt->x_gpe0_blk.bit_width = 128;
  135. fadt->x_gpe0_blk.bit_offset = 0;
  136. fadt->x_gpe0_blk.resv = 0;
  137. fadt->x_gpe0_blk.addrl = pmbase + 0x20;
  138. fadt->x_gpe0_blk.addrh = 0x0;
  139. fadt->x_gpe1_blk.space_id = 0;
  140. fadt->x_gpe1_blk.bit_width = 0;
  141. fadt->x_gpe1_blk.bit_offset = 0;
  142. fadt->x_gpe1_blk.resv = 0;
  143. fadt->x_gpe1_blk.addrl = 0x0;
  144. fadt->x_gpe1_blk.addrh = 0x0;
  145. header->checksum = table_compute_checksum((void *)fadt, header->length);
  146. }
  147. unsigned long acpi_fill_madt(unsigned long current)
  148. {
  149. /* create all subtables for processors */
  150. current = acpi_create_madt_lapics(current);
  151. /*
  152. * TODO(saket.sinha89@gmail.com): get these
  153. * IRQ values from device tree
  154. */
  155. current += acpi_create_madt_ioapic((struct acpi_madt_ioapic *)current,
  156. 2, IO_APIC_ADDR, 0);
  157. current += acpi_create_madt_irqoverride(
  158. (struct acpi_madt_irqoverride *)current, 0, 0, 2, 0);
  159. current += acpi_create_madt_irqoverride(
  160. (struct acpi_madt_irqoverride *)current, 0, 9, 9, 0xd);
  161. current += acpi_create_madt_irqoverride(
  162. (struct acpi_madt_irqoverride *)current, 0, 0xd, 0xd, 0xd);
  163. acpi_create_madt_lapic_nmi(
  164. (struct acpi_madt_lapic_nmi *)current, 0, 0, 0);
  165. return current;
  166. }