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