| // SPDX-License-Identifier: GPL-2.0+ |
| /* |
| * Write the ACPI Differentiated System Description Table (DSDT) |
| * |
| * Copyright 2021 Google LLC |
| */ |
| |
| #define LOG_CATEGORY LOGC_ACPI |
| |
| #include <acpi/acpi_table.h> |
| #include <dm/acpi.h> |
| #include <tables_csum.h> |
| #include <linux/string.h> |
| |
| /* |
| * IASL compiles the dsdt entries and writes the hex values |
| * to a C array AmlCode[] (see dsdt.c). |
| */ |
| extern const unsigned char AmlCode[]; |
| |
| int acpi_write_dsdt(struct acpi_ctx *ctx, const struct acpi_writer *entry) |
| { |
| const int thl = sizeof(struct acpi_table_header); |
| struct acpi_table_header *dsdt = ctx->current; |
| int aml_len; |
| |
| /* Put the table header first */ |
| memcpy(dsdt, &AmlCode, thl); |
| acpi_inc(ctx, thl); |
| log_debug("DSDT starts at %p, hdr ends at %p\n", dsdt, ctx->current); |
| |
| /* If the table is not empty, allow devices to inject things */ |
| aml_len = dsdt->length - thl; |
| if (aml_len) { |
| void *base = ctx->current; |
| int ret; |
| |
| ret = acpi_inject_dsdt(ctx); |
| if (ret) |
| return log_msg_ret("inject", ret); |
| log_debug("Added %lx bytes from inject_dsdt, now at %p\n", |
| (ulong)(ctx->current - base), ctx->current); |
| log_debug("Copy AML code size %x to %p\n", aml_len, |
| ctx->current); |
| memcpy(ctx->current, AmlCode + thl, aml_len); |
| acpi_inc(ctx, aml_len); |
| } |
| |
| ctx->dsdt = dsdt; |
| dsdt->length = ctx->current - (void *)dsdt; |
| log_debug("Updated DSDT length to %x\n", dsdt->length); |
| |
| return 0; |
| } |
| ACPI_WRITER(3dsdt, "DSDT", acpi_write_dsdt, 0); |