#include <sys/param.h>
#include <efi.h>
#include <efiapi.h>
#include "fdt.h"
#include "libsa.h"
#define efi_guidcmp(_a, _b) memcmp((_a), (_b), sizeof(EFI_GUID))
#define fdt_node_add_string_property(n, p, s) \
fdt_node_add_property((n), (p), (s), strlen((s)) + 1)
#define fdt_node_set_string_property(n, p, s) \
fdt_node_set_property((n), (p), (s), strlen((s)) + 1)
extern EFI_SYSTEM_TABLE *ST;
struct acpi_rsdp1 {
uint8_t signature[8];
#define RSDP_SIG "RSD PTR "
#define rsdp_signature rsdp1.signature
uint8_t checksum;
#define rsdp_checksum rsdp1.checksum
uint8_t oemid[6];
#define rsdp_oemid rsdp1.oemid
uint8_t revision;
#define rsdp_revision rsdp1.revision
uint32_t rsdt;
#define rsdp_rsdt rsdp1.rsdt
} __packed;
struct acpi_rsdp {
struct acpi_rsdp1 rsdp1;
uint32_t rsdp_length;
uint64_t rsdp_xsdt;
uint8_t rsdp_extchecksum;
uint8_t rsdp_reserved[3];
} __packed;
struct acpi_table_header {
uint8_t signature[4];
#define hdr_signature hdr.signature
uint32_t length;
#define hdr_length hdr.length
uint8_t revision;
#define hdr_revision hdr.revision
uint8_t checksum;
#define hdr_checksum hdr.checksum
uint8_t oemid[6];
#define hdr_oemid hdr.oemid
uint8_t oemtableid[8];
#define hdr_oemtableid hdr.oemtableid
uint32_t oemrevision;
#define hdr_oemrevision hdr.oemrevision
uint8_t aslcompilerid[4];
#define hdr_aslcompilerid hdr.aslcompilerid
uint32_t aslcompilerrevision;
#define hdr_aslcompilerrevision hdr.aslcompilerrevision
} __packed;
struct acpi_xsdt {
struct acpi_table_header hdr;
#define XSDT_SIG "XSDT"
uint64_t table_offsets[1];
} __packed;
struct acpi_gas {
uint8_t address_space_id;
#define GAS_SYSTEM_MEMORY 0
#define GAS_SYSTEM_IOSPACE 1
#define GAS_PCI_CFG_SPACE 2
#define GAS_EMBEDDED 3
#define GAS_SMBUS 4
#define GAS_FUNCTIONAL_FIXED 127
uint8_t register_bit_width;
uint8_t register_bit_offset;
uint8_t access_size;
#define GAS_ACCESS_UNDEFINED 0
#define GAS_ACCESS_BYTE 1
#define GAS_ACCESS_WORD 2
#define GAS_ACCESS_DWORD 3
#define GAS_ACCESS_QWORD 4
uint64_t address;
} __packed;
struct acpi_fadt {
struct acpi_table_header hdr;
#define FADT_SIG "FACP"
uint32_t firmware_ctl;
uint32_t dsdt;
uint8_t int_model;
#define FADT_INT_DUAL_PIC 0
#define FADT_INT_MULTI_APIC 1
uint8_t pm_profile;
#define FADT_PM_UNSPEC 0
#define FADT_PM_DESKTOP 1
#define FADT_PM_MOBILE 2
#define FADT_PM_WORKSTATION 3
#define FADT_PM_ENT_SERVER 4
#define FADT_PM_SOHO_SERVER 5
#define FADT_PM_APPLIANCE 6
#define FADT_PM_PERF_SERVER 7
uint16_t sci_int;
uint32_t smi_cmd;
uint8_t acpi_enable;
uint8_t acpi_disable;
uint8_t s4bios_req;
uint8_t pstate_cnt;
uint32_t pm1a_evt_blk;
uint32_t pm1b_evt_blk;
uint32_t pm1a_cnt_blk;
uint32_t pm1b_cnt_blk;
uint32_t pm2_cnt_blk;
uint32_t pm_tmr_blk;
uint32_t gpe0_blk;
uint32_t gpe1_blk;
uint8_t pm1_evt_len;
uint8_t pm1_cnt_len;
uint8_t pm2_cnt_len;
uint8_t pm_tmr_len;
uint8_t gpe0_blk_len;
uint8_t gpe1_blk_len;
uint8_t gpe1_base;
uint8_t cst_cnt;
uint16_t p_lvl2_lat;
uint16_t p_lvl3_lat;
uint16_t flush_size;
uint16_t flush_stride;
uint8_t duty_offset;
uint8_t duty_width;
uint8_t day_alrm;
uint8_t mon_alrm;
uint8_t century;
uint16_t iapc_boot_arch;
#define FADT_LEGACY_DEVICES 0x0001
#define FADT_i8042 0x0002
#define FADT_NO_VGA 0x0004
uint8_t reserved1;
uint32_t flags;
#define FADT_WBINVD 0x00000001
#define FADT_WBINVD_FLUSH 0x00000002
#define FADT_PROC_C1 0x00000004
#define FADT_P_LVL2_UP 0x00000008
#define FADT_PWR_BUTTON 0x00000010
#define FADT_SLP_BUTTON 0x00000020
#define FADT_FIX_RTC 0x00000040
#define FADT_RTC_S4 0x00000080
#define FADT_TMR_VAL_EXT 0x00000100
#define FADT_DCK_CAP 0x00000200
#define FADT_RESET_REG_SUP 0x00000400
#define FADT_SEALED_CASE 0x00000800
#define FADT_HEADLESS 0x00001000
#define FADT_CPU_SW_SLP 0x00002000
#define FADT_PCI_EXP_WAK 0x00004000
#define FADT_USE_PLATFORM_CLOCK 0x00008000
#define FADT_S4_RTC_STS_VALID 0x00010000
#define FADT_REMOTE_POWER_ON_CAPABLE 0x00020000
#define FADT_FORCE_APIC_CLUSTER_MODEL 0x00040000
#define FADT_FORCE_APIC_PHYS_DEST_MODE 0x00080000
#define FADT_HW_REDUCED_ACPI 0x00100000
#define FADT_POWER_S0_IDLE_CAPABLE 0x00200000
struct acpi_gas reset_reg;
uint8_t reset_value;
uint16_t arm_boot_arch;
#define FADT_PSCI_COMPLIANT 0x0001
#define FADT_PSCI_USE_HVC 0x0002
uint8_t reserved2;
uint64_t x_firmware_ctl;
uint64_t x_dsdt;
struct acpi_gas x_pm1a_evt_blk;
struct acpi_gas x_pm1b_evt_blk;
struct acpi_gas x_pm1a_cnt_blk;
struct acpi_gas x_pm1b_cnt_blk;
struct acpi_gas x_pm2_cnt_blk;
struct acpi_gas x_pm_tmr_blk;
struct acpi_gas x_gpe0_blk;
struct acpi_gas x_gpe1_blk;
struct acpi_gas sleep_control_reg;
struct acpi_gas sleep_status_reg;
} __packed;
struct acpi_gtdt {
struct acpi_table_header hdr;
#define GTDT_SIG "GTDT"
uint64_t cnt_ctrl_base;
uint32_t reserved;
uint32_t sec_el1_interrupt;
uint32_t sec_el1_flags;
#define ACPI_GTDT_TIMER_TRIGGER_EDGE 0x1
#define ACPI_GTDT_TIMER_POLARITY_LOW 0x2
#define ACPI_GTDT_TIMER_ALWAYS_ON 0x4
uint32_t nonsec_el1_interrupt;
uint32_t nonsec_el1_flags;
uint32_t virt_interrupt;
uint32_t virt_flags;
uint32_t nonsec_el2_interrupt;
uint32_t nonsec_el2_flags;
uint64_t cnt_read_base;
uint32_t platform_timer_count;
uint32_t platform_timer_offset;
} __packed;
struct acpi_madt {
struct acpi_table_header hdr;
#define MADT_SIG "APIC"
uint32_t local_apic_address;
uint32_t flags;
#define ACPI_APIC_PCAT_COMPAT 0x00000001
} __packed;
struct acpi_madt_gicc {
uint8_t apic_type;
#define ACPI_MADT_GICC 11
uint8_t length;
uint16_t reserved1;
uint32_t gic_id;
uint32_t acpi_proc_uid;
uint32_t flags;
#define ACPI_PROC_ENABLE 0x00000001
uint32_t parking_protocol_version;
uint32_t performance_interrupt;
uint64_t parked_address;
uint64_t base_address;
uint64_t gicv_base_address;
uint64_t gich_base_address;
uint32_t maintenance_interrupt;
uint64_t gicr_base_address;
uint64_t mpidr;
uint8_t efficiency_class;
uint8_t reserved2[3];
} __packed;
struct acpi_madt_gicd {
uint8_t apic_type;
#define ACPI_MADT_GICD 12
uint8_t length;
uint16_t reserved1;
uint32_t gic_id;
uint64_t base_address;
uint32_t interrupt_base;
uint8_t version;
uint8_t reserved2[3];
} __packed;
struct acpi_madt_gic_msi {
uint8_t apic_type;
#define ACPI_MADT_GIC_MSI 13
uint8_t length;
uint16_t reserved1;
uint32_t msi_frame_id;
uint64_t base_address;
uint32_t flags;
#define ACPI_MADT_GIC_MSI_SPI_SELECT 0x00000001
uint16_t spi_count;
uint16_t spi_base;
} __packed;
struct acpi_madt_gicr {
uint8_t apic_type;
#define ACPI_MADT_GICR 14
uint8_t length;
uint16_t reserved1;
uint64_t discovery_base_address;
uint32_t discovery_length;
} __packed;
struct acpi_madt_gic_its {
uint8_t apic_type;
#define ACPI_MADT_GIC_ITS 15
uint8_t length;
uint16_t reserved1;
uint32_t gic_its_id;
uint64_t base_address;
uint32_t reserved2;
} __packed;
union acpi_madt_entry {
struct acpi_madt_gicc madt_gicc;
struct acpi_madt_gicd madt_gicd;
struct acpi_madt_gic_msi madt_gic_msi;
struct acpi_madt_gicr madt_gicr;
struct acpi_madt_gic_its madt_gic_its;
} __packed;
struct acpi_spcr {
struct acpi_table_header hdr;
#define SPCR_SIG "SPCR"
uint8_t interface_type;
#define SPCR_16550 0
#define SPCR_16450 1
#define SPCR_ARM_PL011 3
#define SPCR_ARM_SBSA 14
uint8_t reserved1[3];
struct acpi_gas base_address;
uint8_t interrupt_type;
uint8_t irq;
uint32_t gsiv;
uint8_t baud_rate;
uint8_t parity;
uint8_t stop_bits;
uint8_t flow_control;
uint8_t terminal_type;
uint8_t reserved2;
uint16_t pci_device_id;
uint16_t pci_vendor_id;
uint8_t pci_bus;
uint8_t pci_device;
uint8_t pci_function;
uint32_t pci_flags;
uint8_t pci_segment;
uint32_t reserved3;
} __packed;
struct acpi_dbg2 {
struct acpi_table_header hdr;
#define DBG2_SIG "DBG2"
uint32_t info_offset;
uint32_t info_count;
} __packed;
struct acpi_dbg2_info {
uint8_t revision;
uint16_t length;
uint8_t num_address;
uint16_t name_length;
uint16_t name_offset;
uint16_t oem_data_length;
uint16_t oem_data_offset;
uint16_t port_type;
#define DBG2_SERIAL 0x8000
uint16_t port_subtype;
#define DBG2_16550 0x0000
#define DBG2_16450 0x0001
#define DBG2_ARM_PL011 0x0003
#define DBG2_ARM_SBSA 0x000e
uint16_t reserved;
uint16_t base_address_offset;
uint16_t address_size_offset;
} __packed;
static EFI_GUID acpi_guid = ACPI_20_TABLE_GUID;
static int psci = 0;
void
efi_acpi_fadt(struct acpi_table_header *hdr)
{
struct acpi_fadt *fadt = (struct acpi_fadt *)hdr;
void *node;
if (fadt->hdr_revision < 5)
return;
psci = fadt->arm_boot_arch & FADT_PSCI_COMPLIANT;
node = fdt_find_node("/psci");
if (fadt->arm_boot_arch & FADT_PSCI_COMPLIANT)
fdt_node_set_string_property(node, "status", "okay");
if (fadt->arm_boot_arch & FADT_PSCI_USE_HVC)
fdt_node_set_string_property(node, "method", "hvc");
}
void
efi_acpi_gtdt(struct acpi_table_header *hdr)
{
struct acpi_gtdt *gtdt = (struct acpi_gtdt *)hdr;
const uint32_t map[] = { 0x4, 0x1, 0x8, 0x2 };
const uint32_t mask = ACPI_GTDT_TIMER_TRIGGER_EDGE |
ACPI_GTDT_TIMER_POLARITY_LOW;
uint32_t interrupts[12];
void *node;
interrupts[0] = htobe32(1);
interrupts[1] = htobe32(gtdt->sec_el1_interrupt - 16);
interrupts[2] = htobe32(map[gtdt->sec_el1_flags & mask]);
interrupts[3] = htobe32(1);
interrupts[4] = htobe32(gtdt->nonsec_el1_interrupt - 16);
interrupts[5] = htobe32(map[gtdt->nonsec_el1_flags & mask]);
interrupts[6] = htobe32(1);
interrupts[7] = htobe32(gtdt->virt_interrupt - 16);
interrupts[8] = htobe32(map[gtdt->virt_flags & mask]);
interrupts[9] = htobe32(1);
interrupts[10] = htobe32(gtdt->nonsec_el2_interrupt - 16);
interrupts[11] = htobe32(map[gtdt->nonsec_el2_flags & mask]);
node = fdt_find_node("/timer");
fdt_node_set_property(node, "interrupts",
interrupts, sizeof(interrupts));
fdt_node_set_string_property(node, "status", "okay");
}
static int gic_version;
static uint64_t gicc_base;
static uint64_t gicd_base;
static uint64_t gicr_base;
static uint64_t gicr_size;
static uint64_t gicr_stride;
void
efi_acpi_madt_gicc(struct acpi_madt_gicc *gicc)
{
uint64_t mpidr = gicc->mpidr;
void *node, *child;
uint64_t reg;
char name[32];
if ((gicc->flags & ACPI_PROC_ENABLE) == 0)
return;
mpidr = (gicc->length >= 76) ? gicc->mpidr : gicc->acpi_proc_uid;
snprintf(name, sizeof(name), "cpu@%llx", mpidr);
reg = htobe64(mpidr);
node = fdt_find_node("/cpus");
fdt_node_add_node(node, name, &child);
fdt_node_add_string_property(child, "device_type", "cpu");
fdt_node_add_string_property(child, "compatible", "arm,armv8");
fdt_node_add_property(child, "reg", ®, sizeof(reg));
if (gicc->parking_protocol_version == 0 || psci)
fdt_node_add_string_property(child, "enable-method", "psci");
gicc_base = gicc->base_address;
if (gicc->gicr_base_address > 0) {
if (gicr_base > 0) {
uint32_t size;
if (gicc->gicr_base_address < gicr_base)
size = gicr_base - gicc->gicr_base_address;
else
size = gicc->gicr_base_address - gicr_base;
if (gicr_stride == 0 || size < gicr_stride)
gicr_stride = size;
if (gicr_size == 0 || size > gicr_size)
gicr_size = size;
gicr_base = MIN(gicr_base, gicc->gicr_base_address);
} else {
gicr_base = gicc->gicr_base_address;
gicr_size = 0x20000;
}
}
}
void
efi_acpi_madt_gicd(struct acpi_madt_gicd *gicd)
{
gic_version = gicd->version;
gicd_base = gicd->base_address;
}
void
efi_acpi_madt_gic_msi(struct acpi_madt_gic_msi *msi)
{
static uint32_t phandle = 2;
void *node, *child;
uint64_t reg[2];
char name[32];
snprintf(name, sizeof(name), "v2m@%llx", msi->base_address);
reg[0] = htobe64(msi->base_address);
reg[1] = htobe64(0x1000);
node = fdt_find_node("/interrupt-controller");
fdt_node_add_node(node, name, &child);
fdt_node_add_string_property(child, "compatible", "arm,gic-v2m-frame");
fdt_node_add_property(child, "msi-controller", NULL, 0);
fdt_node_add_property(child, "reg", reg, sizeof(reg));
if (msi->flags & ACPI_MADT_GIC_MSI_SPI_SELECT) {
uint32_t spi_base = htobe32(msi->spi_base);
uint32_t spi_count = htobe32(msi->spi_count);
fdt_node_add_property(child, "arm,msi-base-spi",
&spi_base, sizeof(spi_base));
fdt_node_add_property(child, "arm,msi-num-spis",
&spi_count, sizeof(spi_count));
}
fdt_node_add_property(child, "phandle", &phandle, sizeof(phandle));
phandle++;
}
void
efi_acpi_madt_gicr(struct acpi_madt_gicr *gicr)
{
gicr_base = gicr->discovery_base_address;
gicr_size = gicr->discovery_length;
}
void
efi_acpi_madt_gic_its(struct acpi_madt_gic_its *its)
{
static uint32_t phandle = 2;
void *node, *child;
uint64_t reg[2];
uint32_t its_id;
char name[32];
snprintf(name, sizeof(name), "gic-its@%llx", its->base_address);
reg[0] = htobe64(its->base_address);
reg[1] = htobe64(0x20000);
its_id = htobe32(its->gic_its_id);
node = fdt_find_node("/interrupt-controller");
fdt_node_add_node(node, name, &child);
fdt_node_add_string_property(child, "compatible", "arm,gic-v3-its");
fdt_node_add_property(child, "msi-controller", NULL, 0);
fdt_node_add_property(child, "reg", reg, sizeof(reg));
fdt_node_add_property(child, "phandle", &phandle, sizeof(phandle));
fdt_node_add_property(child, "openbsd,gic-its-id", &its_id,
sizeof(its_id));
phandle++;
}
void
efi_acpi_madt(struct acpi_table_header *hdr)
{
struct acpi_madt *madt = (struct acpi_madt *)hdr;
char *compat;
uint64_t reg[4];
char *addr;
void *node;
if (madt->hdr_revision < 3)
return;
addr = (char *)(madt + 1);
while (addr < (char *)madt + madt->hdr.length) {
union acpi_madt_entry *entry = (union acpi_madt_entry *)addr;
uint8_t length = entry->madt_gicc.length;
if (length < 2)
return;
if (addr + length > (char *)madt + madt->hdr_length)
return;
switch (entry->madt_gicc.apic_type) {
case ACPI_MADT_GICC:
efi_acpi_madt_gicc(&entry->madt_gicc);
break;
case ACPI_MADT_GICD:
efi_acpi_madt_gicd(&entry->madt_gicd);
break;
case ACPI_MADT_GIC_MSI:
efi_acpi_madt_gic_msi(&entry->madt_gic_msi);
break;
case ACPI_MADT_GICR:
efi_acpi_madt_gicr(&entry->madt_gicr);
break;
case ACPI_MADT_GIC_ITS:
efi_acpi_madt_gic_its(&entry->madt_gic_its);
break;
}
addr += length;
}
switch (gic_version) {
case 0:
case 2:
compat = "arm,gic-400";
reg[0] = htobe64(gicd_base);
reg[1] = htobe64(0x1000);
reg[2] = htobe64(gicc_base);
reg[3] = htobe64(0x100);
break;
case 3:
case 4:
compat = "arm,gic-v3";
reg[0] = htobe64(gicd_base);
reg[1] = htobe64(0x10000);
reg[2] = htobe64(gicr_base);
reg[3] = htobe64(gicr_size + gicr_stride);
break;
default:
return;
}
node = fdt_find_node("/interrupt-controller");
fdt_node_set_string_property(node, "compatible", compat);
fdt_node_set_property(node, "reg", reg, sizeof(reg));
if (gicr_stride > 0) {
uint64_t stride = htobe64(gicr_stride);
fdt_node_add_property(node, "redistributor-stride",
&stride, sizeof(stride));
}
fdt_node_set_string_property(node, "status", "okay");
}
static int serial = 0;
void
efi_acpi_serial(char *compat, struct acpi_gas *base_address,
uint32_t address_size)
{
uint64_t reg[2], reg_shift, reg_io_width;
void *node;
if (base_address->address_space_id != GAS_SYSTEM_MEMORY)
return;
switch (base_address->access_size) {
case GAS_ACCESS_BYTE:
reg_io_width = 1;
break;
case GAS_ACCESS_WORD:
reg_io_width = 2;
break;
case GAS_ACCESS_DWORD:
reg_io_width = 4;
break;
case GAS_ACCESS_QWORD:
reg_io_width = 8;
break;
default:
return;
}
reg_io_width = htobe32(reg_io_width);
reg_shift = 0;
if (base_address->register_bit_width > 8)
reg_shift = 1;
if (base_address->register_bit_width > 16)
reg_shift = 2;
if (base_address->register_bit_width > 32)
reg_shift = 3;
reg_shift = htobe32(reg_shift);
node = fdt_find_node("/serial");
fdt_node_set_string_property(node, "compatible", compat);
if (strcmp(compat, "snps,dw-apb-uart") == 0) {
fdt_node_add_property(node, "reg-shift",
®_shift, sizeof(reg_shift));
fdt_node_add_property(node, "reg-io-width",
®_io_width, sizeof(reg_io_width));
}
reg[0] = htobe64(base_address->address);
reg[1] = htobe64(address_size);
fdt_node_set_property(node, "reg", reg, sizeof(reg));
}
void
efi_acpi_spcr(struct acpi_table_header *hdr)
{
struct acpi_spcr *spcr = (struct acpi_spcr *)hdr;
if (spcr->hdr_revision < 2)
return;
switch (spcr->interface_type) {
case SPCR_16550:
case SPCR_16450:
efi_acpi_serial("snps,dw-apb-uart", &spcr->base_address, 0x100);
break;
case SPCR_ARM_PL011:
case SPCR_ARM_SBSA:
efi_acpi_serial("arm,pl011", &spcr->base_address, 0x1000);
break;
default:
return;
}
serial = 1;
}
void
efi_acpi_dbg2(struct acpi_table_header *hdr)
{
struct acpi_dbg2 *dbg2 = (struct acpi_dbg2 *)hdr;
struct acpi_dbg2_info *info;
struct acpi_gas *base_address;
uint32_t address_size;
info = (struct acpi_dbg2_info *)((char *)hdr + dbg2->info_offset);
if (info->port_type != DBG2_SERIAL)
return;
base_address = (struct acpi_gas *)
((char *)info + info->base_address_offset);
address_size = *(uint32_t *)
((char *)info + info->address_size_offset);
switch (info->port_subtype) {
case DBG2_16550:
case DBG2_16450:
efi_acpi_serial("snps,dw-apb-uart", base_address, address_size);
break;
case DBG2_ARM_PL011:
case DBG2_ARM_SBSA:
efi_acpi_serial("arm,pl011", base_address, address_size);
break;
default:
return;
}
}
void *
efi_acpi(void)
{
extern uint64_t dma_constraint[2];
extern u_char dt_blob_start[];
void *fdt = dt_blob_start;
struct acpi_table_header *hdr;
struct acpi_rsdp *rsdp = NULL;
struct acpi_xsdt *xsdt;
uint64_t reg[2];
int i, ntables;
size_t len;
void *node;
for (i = 0; i < ST->NumberOfTableEntries; i++) {
if (efi_guidcmp(&acpi_guid,
&ST->ConfigurationTable[i].VendorGuid) == 0)
rsdp = ST->ConfigurationTable[i].VendorTable;
}
if (rsdp == NULL)
return NULL;
if (memcmp(rsdp->rsdp_signature, RSDP_SIG, 8) != 0 ||
rsdp->rsdp_revision < 2)
return NULL;
xsdt = (struct acpi_xsdt *)rsdp->rsdp_xsdt;
len = xsdt->hdr.length;
ntables = (len - sizeof(struct acpi_table_header)) /
sizeof(xsdt->table_offsets[0]);
if (ntables == 0)
return NULL;
if (!fdt_init(fdt))
return NULL;
for (i = 0; i < ntables; i++) {
hdr = (struct acpi_table_header *)xsdt->table_offsets[i];
printf("%c%c%c%c ", hdr->signature[0], hdr->signature[1],
hdr->signature[2], hdr->signature[3]);
if (memcmp(hdr->signature, FADT_SIG, 4) == 0)
efi_acpi_fadt(hdr);
if (memcmp(hdr->signature, GTDT_SIG, 4) == 0)
efi_acpi_gtdt(hdr);
if (memcmp(hdr->signature, MADT_SIG, 4) == 0)
efi_acpi_madt(hdr);
if (memcmp(hdr->signature, SPCR_SIG, 4) == 0)
efi_acpi_spcr(hdr);
}
printf("\n");
for (i = 0; i < ntables; i++) {
hdr = (struct acpi_table_header *)xsdt->table_offsets[i];
if (memcmp(hdr->signature, DBG2_SIG, 4) == 0 && !serial)
efi_acpi_dbg2(hdr);
}
reg[0] = htobe64((uint64_t)rsdp);
reg[1] = htobe64(rsdp->rsdp_length);
node = fdt_find_node("/acpi");
fdt_node_set_property(node, "reg", reg, sizeof(reg));
if (!serial)
cnset(ttydev("fb0"));
if (memcmp(xsdt->hdr_oemid, "RPIFDN", 6) == 0 &&
memcmp(xsdt->hdr_oemtableid, "RPI4", 4) == 0)
dma_constraint[1] = htobe64(0x3bffffff);
fdt_finalize();
return fdt;
}