diff --git a/arch/x86/include/asm/acpigen.h b/arch/x86/include/asm/acpigen.h new file mode 100644 index 0000000000..c531dd61d5 --- /dev/null +++ b/arch/x86/include/asm/acpigen.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Generation of x86-specific ACPI tables + * + * Copyright 2020 Google LLC + */ + +#ifndef __ASM_ACPIGEN_H__ +#define __ASM_ACPIGEN_H__ + +struct acpi_ctx; + +/** + * acpigen_write_empty_pct() - Write an empty PCT + * + * See ACPI v6.3 section 8.4.6.1: _PCT (Performance Control) + * + * This writes an empty table so that CPU performance works as expected + * + * @ctx: ACPI context pointer + */ +void acpigen_write_empty_pct(struct acpi_ctx *ctx); + +/** + * acpigen_write_empty_ptc() - Write an empty PTC + * + * See ACPI v6.3 section 8.4.5.1: _PTC (Processor Throttling Control) + * + * This writes an empty table so that CPU performance works as expected + * + * @ctx: ACPI context pointer + */ +void acpigen_write_empty_ptc(struct acpi_ctx *ctx); + +#endif /* __ASM_ACPI_H__ */ diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 1185a88c27..f04d275dd9 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -38,7 +38,7 @@ obj-y += sfi.o obj-y += acpi.o obj-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.o ifndef CONFIG_QEMU -obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o +obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o acpigen.o endif obj-y += tables.o ifndef CONFIG_SPL_BUILD diff --git a/arch/x86/lib/acpigen.c b/arch/x86/lib/acpigen.c new file mode 100644 index 0000000000..ea2ec2a908 --- /dev/null +++ b/arch/x86/lib/acpigen.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Google LLC + */ + +#include +#include +#include +#include + +void acpigen_write_empty_pct(struct acpi_ctx *ctx) +{ + /* + * Name (_PCT, Package (0x02) + * { + * ResourceTemplate () + * { + * Register (FFixedHW, + * 0x00, // Bit Width + * 0x00, // Bit Offset + * 0x0000000000000000, // Address + * ,) + * }, + * + * ResourceTemplate () + * { + * Register (FFixedHW, + * 0x00, // Bit Width + * 0x00, // Bit Offset + * 0x0000000000000000, // Address + * ,) + * } + * }) + */ + static char stream[] = { + /* 00000030 "0._PCT.," */ + 0x08, 0x5f, 0x50, 0x43, 0x54, 0x12, 0x2c, + /* 00000038 "........" */ + 0x02, 0x11, 0x14, 0x0a, 0x11, 0x82, 0x0c, 0x00, + /* 00000040 "........" */ + 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* 00000048 "....y..." */ + 0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0x11, 0x14, + /* 00000050 "........" */ + 0x0a, 0x11, 0x82, 0x0c, 0x00, 0x7f, 0x00, 0x00, + /* 00000058 "........" */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x79, 0x00 + }; + acpigen_emit_stream(ctx, stream, ARRAY_SIZE(stream)); +} + +void acpigen_write_empty_ptc(struct acpi_ctx *ctx) +{ + /* + * Name (_PTC, Package (0x02) + * { + * ResourceTemplate () + * { + * Register (FFixedHW, + * 0x00, // Bit Width + * 0x00, // Bit Offset + * 0x0000000000000000, // Address + * ,) + * }, + * + * ResourceTemplate () + * { + * Register (FFixedHW, + * 0x00, // Bit Width + * 0x00, // Bit Offset + * 0x0000000000000000, // Address + * ,) + * } + * }) + */ + struct acpi_gen_regaddr addr = { + .space_id = ACPI_ADDRESS_SPACE_FIXED, + .bit_width = 0, + .bit_offset = 0, + .access_size = 0, + .addrl = 0, + .addrh = 0, + }; + + acpigen_write_name(ctx, "_PTC"); + acpigen_write_package(ctx, 2); + + /* ControlRegister */ + acpigen_write_register_resource(ctx, &addr); + + /* StatusRegister */ + acpigen_write_register_resource(ctx, &addr); + + acpigen_pop_len(ctx); +}