]> Git Repo - J-u-boot.git/blob - lib/acpi/acpi_writer.c
Merge patch series "net: ksz9477: add support for KSZ GbE switches using SPI bus"
[J-u-boot.git] / lib / acpi / acpi_writer.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Handles writing the declared ACPI tables
4  *
5  * Copyright 2021 Google LLC
6  */
7
8 #define LOG_CATEGORY LOGC_ACPI
9
10 #include <log.h>
11 #include <malloc.h>
12 #include <mapmem.h>
13 #include <acpi/acpi_table.h>
14 #include <asm/global_data.h>
15 #include <dm/acpi.h>
16 #include <linux/errno.h>
17
18 DECLARE_GLOBAL_DATA_PTR;
19
20 int acpi_write_one(struct acpi_ctx *ctx, const struct acpi_writer *entry)
21 {
22         int ret;
23
24         log_debug("%s: writing table '%s'\n", entry->name,
25                   entry->table);
26         ctx->tab_start = ctx->current;
27         ret = entry->h_write(ctx, entry);
28         if (ret == -ENOENT) {
29                 log_debug("%s: Omitted due to being empty\n",
30                           entry->name);
31                 ret = 0;
32                 ctx->current = ctx->tab_start;  /* drop the table */
33                 return ret;
34         }
35         if (ret)
36                 return log_msg_ret("write", ret);
37
38         if (entry->flags & ACPIWF_ALIGN64)
39                 acpi_align64(ctx);
40         else
41                 acpi_align(ctx);
42
43         /* Add the item to the internal list */
44         ret = acpi_add_other_item(ctx, entry, ctx->tab_start);
45         if (ret)
46                 return log_msg_ret("add", ret);
47
48         return 0;
49 }
50
51 #ifndef CONFIG_QFW_ACPI
52 static int acpi_write_all(struct acpi_ctx *ctx)
53 {
54         const struct acpi_writer *writer =
55                  ll_entry_start(struct acpi_writer, acpi_writer);
56         const int n_ents = ll_entry_count(struct acpi_writer, acpi_writer);
57         const struct acpi_writer *entry;
58         int ret;
59
60         for (entry = writer; entry != writer + n_ents; entry++) {
61                 ret = acpi_write_one(ctx, entry);
62                 if (ret && ret != -ENOENT)
63                         return log_msg_ret("one", ret);
64         }
65
66         return 0;
67 }
68
69 /*
70  * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c
71  */
72 ulong write_acpi_tables(ulong start_addr)
73 {
74         struct acpi_ctx *ctx;
75         ulong addr;
76         int ret;
77
78         ctx = malloc(sizeof(*ctx));
79         if (!ctx)
80                 return log_msg_ret("mem", -ENOMEM);
81
82         log_debug("ACPI: Writing ACPI tables at %lx\n", start_addr);
83
84         acpi_reset_items();
85         acpi_setup_ctx(ctx, start_addr);
86
87         ret = acpi_write_all(ctx);
88         if (ret) {
89                 log_err("Failed to write ACPI tables (err=%d)\n", ret);
90                 return log_msg_ret("write", -ENOMEM);
91         }
92
93         addr = map_to_sysmem(ctx->current);
94         log_debug("ACPI current = %lx\n", addr);
95
96         return addr;
97 }
98
99 int write_dev_tables(struct acpi_ctx *ctx, const struct acpi_writer *entry)
100 {
101         int ret;
102
103         ret = acpi_write_dev_tables(ctx);
104         if (ret)
105                 return log_msg_ret("write", ret);
106
107         return 0;
108 }
109 ACPI_WRITER(8dev, NULL, write_dev_tables, 0);
110
111 ulong acpi_get_rsdp_addr(void)
112 {
113         if (!gd->acpi_ctx)
114                 return 0;
115
116         return map_to_sysmem(gd->acpi_ctx->rsdp);
117 }
118 #endif /* QFW_ACPI */
119
120 void acpi_setup_ctx(struct acpi_ctx *ctx, ulong start)
121 {
122         gd->acpi_ctx = ctx;
123         memset(ctx, '\0', sizeof(*ctx));
124
125         /* Align ACPI tables to 16-byte boundary */
126         start = ALIGN(start, 16);
127         ctx->base = map_sysmem(start, 0);
128         ctx->current = ctx->base;
129
130         gd_set_acpi_start(start);
131 }
This page took 0.033052 seconds and 4 git commands to generate.