mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-24 14:25:56 +00:00
acpi: Add fill_madt to acpi_ops
Add a new method to acpi_ops to let drivers fill out ACPI MADT. The code is unused for now until drivers implement the new ops. TEST: Booted on QEMU sbsa using driver model generated MADT. Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> Reviewed-by: Simon Glass <sjg@chromium.org> Cc: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
f36e29e8da
commit
763bad3e1c
5 changed files with 99 additions and 1 deletions
|
@ -11,6 +11,8 @@
|
|||
#include <acpi/acpigen.h>
|
||||
#include <acpi/acpi_device.h>
|
||||
#include <acpi/acpi_table.h>
|
||||
#include <dm/acpi.h>
|
||||
#include <dm/uclass.h>
|
||||
|
||||
void acpi_write_madt_gicc(struct acpi_madt_gicc *gicc, uint cpu_num,
|
||||
uint perf_gsiv, ulong phys_base, ulong gicv,
|
||||
|
@ -112,3 +114,14 @@ int acpi_pptt_add_cache(struct acpi_ctx *ctx, const u32 flags,
|
|||
|
||||
return offset;
|
||||
}
|
||||
|
||||
void *acpi_fill_madt(struct acpi_madt *madt, struct acpi_ctx *ctx)
|
||||
{
|
||||
uclass_probe_all(UCLASS_CPU);
|
||||
uclass_probe_all(UCLASS_IRQ);
|
||||
|
||||
/* All SoCs must use the driver model */
|
||||
acpi_fill_madt_subtbl(ctx);
|
||||
|
||||
return ctx->current;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ enum method_t {
|
|||
METHOD_FILL_SSDT,
|
||||
METHOD_INJECT_DSDT,
|
||||
METHOD_SETUP_NHLT,
|
||||
METHOD_FILL_MADT,
|
||||
};
|
||||
|
||||
/* Prototype for all methods */
|
||||
|
@ -282,6 +283,8 @@ acpi_method acpi_get_method(struct udevice *dev, enum method_t method)
|
|||
switch (method) {
|
||||
case METHOD_WRITE_TABLES:
|
||||
return aops->write_tables;
|
||||
case METHOD_FILL_MADT:
|
||||
return aops->fill_madt;
|
||||
case METHOD_FILL_SSDT:
|
||||
return aops->fill_ssdt;
|
||||
case METHOD_INJECT_DSDT:
|
||||
|
@ -328,6 +331,19 @@ int acpi_recurse_method(struct acpi_ctx *ctx, struct udevice *parent,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int acpi_fill_madt_subtbl(struct acpi_ctx *ctx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
log_debug("Writing MADT table\n");
|
||||
ret = acpi_recurse_method(ctx, dm_root(), METHOD_FILL_MADT, TYPE_NONE);
|
||||
log_debug("Writing MADT finished, err=%d\n", ret);
|
||||
if (ret)
|
||||
return log_msg_ret("build", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int acpi_fill_ssdt(struct acpi_ctx *ctx)
|
||||
{
|
||||
void *start = ctx->current;
|
||||
|
|
|
@ -146,6 +146,22 @@ struct acpi_ops {
|
|||
*/
|
||||
int (*write_tables)(const struct udevice *dev, struct acpi_ctx *ctx);
|
||||
|
||||
/**
|
||||
* fill_madt() - Generate MADT sub-tables for a device
|
||||
*
|
||||
* This is called to create the MADT table. The method should write out
|
||||
* whatever sub-table is needed by this device. It will end up in the
|
||||
* MADT table.
|
||||
*
|
||||
* Note that this is called 'fill' because the entire contents of the
|
||||
* MADT is build by calling this method on all devices.
|
||||
*
|
||||
* @dev: Device to write
|
||||
* @ctx: ACPI context to use
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int (*fill_madt)(const struct udevice *dev, struct acpi_ctx *ctx);
|
||||
|
||||
/**
|
||||
* fill_ssdt() - Generate SSDT code for a device
|
||||
*
|
||||
|
@ -231,6 +247,16 @@ int acpi_copy_name(char *out_name, const char *name);
|
|||
*/
|
||||
int acpi_write_dev_tables(struct acpi_ctx *ctx);
|
||||
|
||||
/**
|
||||
* acpi_fill_madt_subtbl() - Generate ACPI tables for MADT
|
||||
*
|
||||
* This is called to create the MADT sub-tables for all devices.
|
||||
*
|
||||
* @ctx: ACPI context to use
|
||||
* Return: 0 if OK, -ve on error
|
||||
*/
|
||||
int acpi_fill_madt_subtbl(struct acpi_ctx *ctx);
|
||||
|
||||
/**
|
||||
* acpi_fill_ssdt() - Generate ACPI tables for SSDT
|
||||
*
|
||||
|
|
|
@ -257,11 +257,11 @@ int acpi_write_madt(struct acpi_ctx *ctx, const struct acpi_writer *entry)
|
|||
header->revision = ACPI_MADT_REV_ACPI_3_0;
|
||||
|
||||
acpi_inc(ctx, sizeof(struct acpi_madt));
|
||||
/* TODO: Get rid of acpi_fill_madt and use driver model */
|
||||
current = acpi_fill_madt(madt, ctx);
|
||||
|
||||
/* (Re)calculate length and checksum */
|
||||
header->length = (uintptr_t)current - (uintptr_t)madt;
|
||||
|
||||
header->checksum = table_compute_checksum((void *)madt, header->length);
|
||||
acpi_add_table(ctx, madt);
|
||||
ctx->current = (void *)madt + madt->header.length;
|
||||
|
|
|
@ -95,6 +95,21 @@ static int testacpi_get_name(const struct udevice *dev, char *out_name)
|
|||
return acpi_copy_name(out_name, ACPI_TEST_DEV_NAME);
|
||||
}
|
||||
|
||||
static int testacpi_fill_madt(const struct udevice *dev, struct acpi_ctx *ctx)
|
||||
{
|
||||
u64 *data = ctx->current;
|
||||
|
||||
/* Only fill madt once */
|
||||
if (device_get_uclass_id(dev->parent) != UCLASS_TEST_ACPI)
|
||||
return 0;
|
||||
|
||||
*data = 0xdeadbeef;
|
||||
|
||||
acpi_inc(ctx, sizeof(u64));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int testacpi_fill_ssdt(const struct udevice *dev, struct acpi_ctx *ctx)
|
||||
{
|
||||
const char *data;
|
||||
|
@ -124,6 +139,7 @@ static int testacpi_inject_dsdt(const struct udevice *dev, struct acpi_ctx *ctx)
|
|||
struct acpi_ops testacpi_ops = {
|
||||
.get_name = testacpi_get_name,
|
||||
.write_tables = testacpi_write_tables,
|
||||
.fill_madt = testacpi_fill_madt,
|
||||
.fill_ssdt = testacpi_fill_ssdt,
|
||||
.inject_dsdt = testacpi_inject_dsdt,
|
||||
};
|
||||
|
@ -527,6 +543,33 @@ static int dm_test_acpi_fill_ssdt(struct unit_test_state *uts)
|
|||
}
|
||||
DM_TEST(dm_test_acpi_fill_ssdt, UTF_SCAN_PDATA | UTF_SCAN_FDT);
|
||||
|
||||
/* Test acpi_fill_madt() */
|
||||
static int dm_test_acpi_fill_madt(struct unit_test_state *uts)
|
||||
{
|
||||
struct acpi_ctx ctx;
|
||||
u64 *buf;
|
||||
|
||||
buf = malloc(BUF_SIZE);
|
||||
ut_assertnonnull(buf);
|
||||
|
||||
acpi_reset_items();
|
||||
ctx.current = buf;
|
||||
buf[1] = 'z'; /* sentinel */
|
||||
ut_assertok(acpi_fill_madt_subtbl(&ctx));
|
||||
|
||||
/*
|
||||
* These values come from acpi-test2's acpi-ssdt-test-data property.
|
||||
* This device comes first because of u-boot,acpi-ssdt-order
|
||||
*/
|
||||
ut_asserteq(0xdeadbeef, buf[0]);
|
||||
|
||||
ut_asserteq('z', buf[1]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DM_TEST(dm_test_acpi_fill_madt, UTF_SCAN_PDATA | UTF_SCAN_FDT);
|
||||
|
||||
/* Test acpi_inject_dsdt() */
|
||||
static int dm_test_acpi_inject_dsdt(struct unit_test_state *uts)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue