]> Git Repo - u-boot.git/blobdiff - lib/acpi/acpi_table.c
Merge tag 'v2023.07-rc6' into next
[u-boot.git] / lib / acpi / acpi_table.c
index 1c253af3bfd122ac448bc0daacb18701140db5e8..a8d4b470001d16f3811a42d001184118104087b0 100644 (file)
@@ -8,12 +8,30 @@
 #include <common.h>
 #include <dm.h>
 #include <cpu.h>
+#include <log.h>
 #include <mapmem.h>
 #include <tables_csum.h>
-#include <version.h>
+#include <version_string.h>
 #include <acpi/acpi_table.h>
+#include <asm/global_data.h>
 #include <dm/acpi.h>
 
+/*
+ * OEM_REVISION is 32-bit unsigned number. It should be increased only when
+ * changing software version. Therefore it should not depend on build time.
+ * U-Boot calculates it from U-Boot version and represent it in hexadecimal
+ * notation. As U-Boot version is in form year.month set low 8 bits to 0x01
+ * to have valid date. So for U-Boot version 2021.04 OEM_REVISION is set to
+ * value 0x20210401.
+ */
+#define OEM_REVISION ((((version_num / 1000) % 10) << 28) | \
+                     (((version_num / 100) % 10) << 24) | \
+                     (((version_num / 10) % 10) << 20) | \
+                     ((version_num % 10) << 16) | \
+                     (((version_num_patch / 10) % 10) << 12) | \
+                     ((version_num_patch % 10) << 8) | \
+                     0x01)
+
 int acpi_create_dmar(struct acpi_dmar *dmar, enum dmar_flags flags)
 {
        struct acpi_table_header *header = &dmar->header;
@@ -21,7 +39,7 @@ int acpi_create_dmar(struct acpi_dmar *dmar, enum dmar_flags flags)
        struct udevice *cpu;
        int ret;
 
-       ret = uclass_first_device(UCLASS_CPU, &cpu);
+       ret = uclass_first_device_err(UCLASS_CPU, &cpu);
        if (ret)
                return log_msg_ret("cpu", ret);
        ret = cpu_get_info(cpu, &info);
@@ -98,7 +116,7 @@ void acpi_fill_header(struct acpi_table_header *header, char *signature)
        memcpy(header->signature, signature, 4);
        memcpy(header->oem_id, OEM_ID, 6);
        memcpy(header->oem_table_id, OEM_TABLE_ID, 8);
-       header->oem_revision = U_BOOT_BUILD_DATE;
+       header->oem_revision = OEM_REVISION;
        memcpy(header->aslc_id, ASLC_ID, 4);
 }
 
@@ -182,83 +200,66 @@ int acpi_add_table(struct acpi_ctx *ctx, void *table)
        return 0;
 }
 
-static void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt,
-                           struct acpi_xsdt *xsdt)
-{
-       memset(rsdp, 0, sizeof(struct acpi_rsdp));
-
-       memcpy(rsdp->signature, RSDP_SIG, 8);
-       memcpy(rsdp->oem_id, OEM_ID, 6);
-
-       rsdp->length = sizeof(struct acpi_rsdp);
-       rsdp->rsdt_address = map_to_sysmem(rsdt);
-
-       rsdp->xsdt_address = map_to_sysmem(xsdt);
-       rsdp->revision = ACPI_RSDP_REV_ACPI_2_0;
-
-       /* Calculate checksums */
-       rsdp->checksum = table_compute_checksum(rsdp, 20);
-       rsdp->ext_checksum = table_compute_checksum(rsdp,
-                                                   sizeof(struct acpi_rsdp));
-}
-
-static void acpi_write_rsdt(struct acpi_rsdt *rsdt)
-{
-       struct acpi_table_header *header = &rsdt->header;
-
-       /* Fill out header fields */
-       acpi_fill_header(header, "RSDT");
-       header->length = sizeof(struct acpi_rsdt);
-       header->revision = 1;
-
-       /* Entries are filled in later, we come with an empty set */
-
-       /* Fix checksum */
-       header->checksum = table_compute_checksum(rsdt,
-                                                 sizeof(struct acpi_rsdt));
-}
-
-static void acpi_write_xsdt(struct acpi_xsdt *xsdt)
+void acpi_create_dbg2(struct acpi_dbg2_header *dbg2,
+                     int port_type, int port_subtype,
+                     struct acpi_gen_regaddr *address, u32 address_size,
+                     const char *device_path)
 {
-       struct acpi_table_header *header = &xsdt->header;
-
-       /* Fill out header fields */
-       acpi_fill_header(header, "XSDT");
-       header->length = sizeof(struct acpi_xsdt);
-       header->revision = 1;
-
-       /* Entries are filled in later, we come with an empty set */
-
-       /* Fix checksum */
-       header->checksum = table_compute_checksum(xsdt,
-                                                 sizeof(struct acpi_xsdt));
-}
+       uintptr_t current;
+       struct acpi_dbg2_device *device;
+       u32 *dbg2_addr_size;
+       struct acpi_table_header *header;
+       size_t path_len;
+       const char *path;
+       char *namespace;
 
-void acpi_setup_base_tables(struct acpi_ctx *ctx, void *start)
-{
-       ctx->current = start;
-
-       /* Align ACPI tables to 16 byte */
-       acpi_align(ctx);
-       gd->arch.acpi_start = map_to_sysmem(ctx->current);
-
-       /* We need at least an RSDP and an RSDT Table */
-       ctx->rsdp = ctx->current;
-       acpi_inc_align(ctx, sizeof(struct acpi_rsdp));
-       ctx->rsdt = ctx->current;
-       acpi_inc_align(ctx, sizeof(struct acpi_rsdt));
-       ctx->xsdt = ctx->current;
-       acpi_inc_align(ctx, sizeof(struct acpi_xsdt));
-
-       /* clear all table memory */
-       memset((void *)start, '\0', ctx->current - start);
-
-       acpi_write_rsdp(ctx->rsdp, ctx->rsdt, ctx->xsdt);
-       acpi_write_rsdt(ctx->rsdt);
-       acpi_write_xsdt(ctx->xsdt);
-       /*
-        * Per ACPI spec, the FACS table address must be aligned to a 64 byte
-        * boundary (Windows checks this, but Linux does not).
-        */
-       acpi_align64(ctx);
+       /* Fill out header fields. */
+       current = (uintptr_t)dbg2;
+       memset(dbg2, '\0', sizeof(struct acpi_dbg2_header));
+       header = &dbg2->header;
+
+       header->revision = acpi_get_table_revision(ACPITAB_DBG2);
+       acpi_fill_header(header, "DBG2");
+       header->aslc_revision = ASL_REVISION;
+
+       /* One debug device defined */
+       dbg2->devices_offset = sizeof(struct acpi_dbg2_header);
+       dbg2->devices_count = 1;
+       current += sizeof(struct acpi_dbg2_header);
+
+       /* Device comes after the header */
+       device = (struct acpi_dbg2_device *)current;
+       memset(device, 0, sizeof(struct acpi_dbg2_device));
+       current += sizeof(struct acpi_dbg2_device);
+
+       device->revision = 0;
+       device->address_count = 1;
+       device->port_type = port_type;
+       device->port_subtype = port_subtype;
+
+       /* Base Address comes after device structure */
+       memcpy((void *)current, address, sizeof(struct acpi_gen_regaddr));
+       device->base_address_offset = current - (uintptr_t)device;
+       current += sizeof(struct acpi_gen_regaddr);
+
+       /* Address Size comes after address structure */
+       dbg2_addr_size = (uint32_t *)current;
+       device->address_size_offset = current - (uintptr_t)device;
+       *dbg2_addr_size = address_size;
+       current += sizeof(uint32_t);
+
+       /* Namespace string comes last, use '.' if not provided */
+       path = device_path ? : ".";
+       /* Namespace string length includes NULL terminator */
+       path_len = strlen(path) + 1;
+       namespace = (char *)current;
+       device->namespace_string_length = path_len;
+       device->namespace_string_offset = current - (uintptr_t)device;
+       strncpy(namespace, path, path_len);
+       current += path_len;
+
+       /* Update structure lengths and checksum */
+       device->length = current - (uintptr_t)device;
+       header->length = current - (uintptr_t)dbg2;
+       header->checksum = table_compute_checksum(dbg2, header->length);
 }
This page took 0.043014 seconds and 4 git commands to generate.