From patchwork Mon Jan 27 05:06:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 240235 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 26 Jan 2020 22:06:30 -0700 Subject: [PATCH 083/108] x86: acpi: Support generation of the HPET table In-Reply-To: <20200127050655.170614-1-sjg@chromium.org> References: <20200127050655.170614-1-sjg@chromium.org> Message-ID: <20200126220508.83.If8823c046de531ba72920ef50bbae1dbc77d538b@changeid> Add an implementation of the HPET (High Precision Event Timer) ACPI table. Signed-off-by: Simon Glass --- arch/x86/lib/acpi_table.c | 54 +++++++++++++++++++++++++++++++++++++++ include/acpi_table.h | 32 ++++++++++++++++------- 2 files changed, 77 insertions(+), 9 deletions(-) diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index 4c35111c48..a810b12cfe 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -32,6 +32,26 @@ extern const unsigned char AmlCode[]; /* ACPI RSDP address to be used in boot parameters */ static ulong acpi_rsdp_addr; +int acpi_write_hpet(struct acpi_ctx *ctx, const struct udevice *dev) +{ + struct acpi_hpet *hpet; + int ret; + + /* + * We explicitly add these tables later on: + */ + log_debug("ACPI: * HPET\n"); + + hpet = ctx->current; + acpi_inc_align(ctx, sizeof(struct acpi_hpet)); + acpi_create_hpet(hpet); + ret = acpi_add_table(ctx, hpet); + if (ret) + return log_msg_ret("add", ret); + + return 0; +} + static void acpi_create_facs(struct acpi_facs *facs) { memset((void *)facs, 0, sizeof(struct acpi_facs)); @@ -385,6 +405,40 @@ void acpi_create_ssdt(struct acpi_ctx *ctx, struct acpi_table_header *ssdt, ssdt->checksum = table_compute_checksum((void *)ssdt, ssdt->length); } +/* http://www.intel.com/hardwaredesign/hpetspec_1.pdf */ +int acpi_create_hpet(struct acpi_hpet *hpet) +{ + struct acpi_table_header *header = &hpet->header; + struct acpi_gen_regaddr *addr = &hpet->addr; + + memset((void *)hpet, 0, sizeof(struct acpi_hpet)); + if (!header) + return -EFAULT; + + /* Fill out header fields. */ + acpi_fill_header(header, "HPET"); + + header->aslc_revision = ASL_REVISION; + header->length = sizeof(struct acpi_hpet); + header->revision = acpi_get_table_revision(ACPITAB_HPET); + + /* Fill out HPET address. */ + addr->space_id = 0; /* Memory */ + addr->bit_width = 64; + addr->bit_offset = 0; + addr->addrl = CONFIG_HPET_ADDRESS & 0xffffffff; + addr->addrh = ((unsigned long long)CONFIG_HPET_ADDRESS) >> 32; + + hpet->id = *(unsigned int *)CONFIG_HPET_ADDRESS; + hpet->number = 0; + hpet->min_tick = 0; /* HPET_MIN_TICKS */ + + header->checksum = table_compute_checksum((void *)hpet, + sizeof(struct acpi_hpet)); + + return 0; +} + /* * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c */ diff --git a/include/acpi_table.h b/include/acpi_table.h index e3dedc2496..1d78665abe 100644 --- a/include/acpi_table.h +++ b/include/acpi_table.h @@ -70,6 +70,15 @@ struct __packed acpi_table_header { u32 aslc_revision; /* ASL compiler revision number */ }; +struct acpi_gen_regaddr { + u8 space_id; /* Address space ID */ + u8 bit_width; /* Register size in bits */ + u8 bit_offset; /* Register bit offset */ + u8 access_size; /* Access size */ + u32 addrl; /* Register address, low 32 bits */ + u32 addrh; /* Register address, high 32 bits */ +}; + /* A maximum number of 32 ACPI tables ought to be enough for now */ #define MAX_ACPI_TABLES 32 @@ -85,6 +94,16 @@ struct acpi_xsdt { u64 entry[MAX_ACPI_TABLES]; }; +/* HPET timers */ +struct __packed acpi_hpet { + struct acpi_table_header header; + u32 id; + struct acpi_gen_regaddr addr; + u8 number; + u16 min_tick; + u8 attributes; +}; + /* FADT Preferred Power Management Profile */ enum acpi_pm_profile { ACPI_PM_UNSPECIFIED = 0, @@ -152,15 +171,6 @@ enum acpi_address_space_size { ACPI_ACCESS_SIZE_QWORD_ACCESS }; -struct acpi_gen_regaddr { - u8 space_id; /* Address space ID */ - u8 bit_width; /* Register size in bits */ - u8 bit_offset; /* Register bit offset */ - u8 access_size; /* Access size */ - u32 addrl; /* Register address, low 32 bits */ - u32 addrh; /* Register address, high 32 bits */ -}; - /* FADT (Fixed ACPI Description Table) */ struct __packed acpi_fadt { struct acpi_table_header header; @@ -617,6 +627,10 @@ int acpi_add_table(struct acpi_ctx *ctx, void *table); */ void acpi_setup_base_tables(struct acpi_ctx *ctx, void *start); +int acpi_write_hpet(struct acpi_ctx *ctx, const struct udevice *dev); + +int acpi_create_hpet(struct acpi_hpet *hpet); + #endif /* !__ACPI__*/ #include