summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2020-09-22 12:45:11 -0600
committerBin Meng <bmeng.cn@gmail.com>2020-09-25 11:27:17 +0800
commit15403289e5ddb0d777f95f5836add1316e2d9ae2 (patch)
tree4a446c005d3ae4f179f1b9a6dbc9b44ade0c74bc /lib
parentf37979e7b75e1290e9756c3e964a85ef8b10c3c7 (diff)
downloadu-boot-15403289e5ddb0d777f95f5836add1316e2d9ae2.tar.gz
acpi: Add support for generating processor tables
ACPI has a number of CPU-related tables. Add utility functions to write out the basic packages. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/acpi/acpigen.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/lib/acpi/acpigen.c b/lib/acpi/acpigen.c
index d859f37841..b9985075cd 100644
--- a/lib/acpi/acpigen.c
+++ b/lib/acpi/acpigen.c
@@ -17,6 +17,9 @@
#include <acpi/acpi_table.h>
#include <dm/acpi.h>
+/* CPU path format */
+#define ACPI_CPU_STRING "\\_PR.CP%02d"
+
u8 *acpigen_get_current(struct acpi_ctx *ctx)
{
return ctx->current;
@@ -340,6 +343,58 @@ void acpigen_write_method_serialized(struct acpi_ctx *ctx, const char *name,
ACPI_METHOD_SERIALIZED_MASK);
}
+void acpigen_write_processor(struct acpi_ctx *ctx, uint cpuindex,
+ u32 pblock_addr, uint pblock_len)
+{
+ /*
+ * Processor (\_PR.CPnn, cpuindex, pblock_addr, pblock_len)
+ * {
+ */
+ char pscope[16];
+
+ acpigen_emit_ext_op(ctx, PROCESSOR_OP);
+ acpigen_write_len_f(ctx);
+
+ snprintf(pscope, sizeof(pscope), ACPI_CPU_STRING, cpuindex);
+ acpigen_emit_namestring(ctx, pscope);
+ acpigen_emit_byte(ctx, cpuindex);
+ acpigen_emit_dword(ctx, pblock_addr);
+ acpigen_emit_byte(ctx, pblock_len);
+}
+
+void acpigen_write_processor_package(struct acpi_ctx *ctx,
+ const char *const name,
+ const uint first_core,
+ const uint core_count)
+{
+ uint i;
+ char pscope[16];
+
+ acpigen_write_name(ctx, name);
+ acpigen_write_package(ctx, core_count);
+ for (i = first_core; i < first_core + core_count; ++i) {
+ snprintf(pscope, sizeof(pscope), ACPI_CPU_STRING, i);
+ acpigen_emit_namestring(ctx, pscope);
+ }
+ acpigen_pop_len(ctx);
+}
+
+void acpigen_write_processor_cnot(struct acpi_ctx *ctx, const uint num_cores)
+{
+ int core_id;
+
+ acpigen_write_method(ctx, "\\_PR.CNOT", 1);
+ for (core_id = 0; core_id < num_cores; core_id++) {
+ char buffer[30];
+
+ snprintf(buffer, sizeof(buffer), ACPI_CPU_STRING, core_id);
+ acpigen_emit_byte(ctx, NOTIFY_OP);
+ acpigen_emit_namestring(ctx, buffer);
+ acpigen_emit_byte(ctx, ARG0_OP);
+ }
+ acpigen_pop_len(ctx);
+}
+
void acpigen_write_device(struct acpi_ctx *ctx, const char *name)
{
acpigen_emit_ext_op(ctx, DEVICE_OP);