acpi.c: Add functions to create GTDT
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Change-Id: Ica6b2d79d61558706998edbbaee185125ff5b36c Reviewed-on: https://review.coreboot.org/c/coreboot/+/76296 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
This commit is contained in:
parent
c202be793f
commit
2e3cb63925
|
@ -68,3 +68,9 @@ config ACPI_LPIT
|
||||||
depends on HAVE_ACPI_TABLES
|
depends on HAVE_ACPI_TABLES
|
||||||
help
|
help
|
||||||
Selected by platforms that support and fill Intel Low Power Idle Table.
|
Selected by platforms that support and fill Intel Low Power Idle Table.
|
||||||
|
|
||||||
|
config ACPI_GTDT
|
||||||
|
bool
|
||||||
|
depends on HAVE_ACPI_TABLES
|
||||||
|
help
|
||||||
|
Selected by platforms that implement ARM generic timers
|
||||||
|
|
|
@ -1134,6 +1134,64 @@ static void acpi_create_lpit(acpi_header_t *header, void *unused)
|
||||||
header->length = current - (unsigned long)lpit;
|
header->length = current - (unsigned long)lpit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void acpi_create_gtdt(acpi_header_t *header, void *unused)
|
||||||
|
{
|
||||||
|
if (!CONFIG(ACPI_GTDT))
|
||||||
|
return;
|
||||||
|
|
||||||
|
acpi_gtdt_t *gtdt = (acpi_gtdt_t *)header;
|
||||||
|
unsigned long current = (unsigned long)gtdt + sizeof(acpi_gtdt_t);
|
||||||
|
|
||||||
|
if (acpi_fill_header(header, "GTDT", GTDT, sizeof(acpi_gtdt_t)) != CB_SUCCESS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Fill out header fields. */
|
||||||
|
gtdt->platform_timer_offset = sizeof(acpi_gtdt_t);
|
||||||
|
|
||||||
|
acpi_soc_fill_gtdt(gtdt);
|
||||||
|
current = acpi_soc_gtdt_add_timers(>dt->platform_timer_count, current);
|
||||||
|
|
||||||
|
/* (Re)calculate length. */
|
||||||
|
header->length = current - (unsigned long)gtdt;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long acpi_gtdt_add_timer_block(unsigned long current, const uint64_t address,
|
||||||
|
struct acpi_gtdt_timer_entry *timers, size_t number)
|
||||||
|
{
|
||||||
|
struct acpi_gtdt_timer_block *block = (struct acpi_gtdt_timer_block *)current;
|
||||||
|
memset(block, 0, sizeof(struct acpi_gtdt_timer_block));
|
||||||
|
|
||||||
|
assert(number < 8 && number != 0);
|
||||||
|
const size_t entries_size = number * sizeof(struct acpi_gtdt_timer_entry);
|
||||||
|
|
||||||
|
block->header.type = ACPI_GTDT_TYPE_TIMER_BLOCK;
|
||||||
|
block->header.length = sizeof(struct acpi_gtdt_timer_block)
|
||||||
|
+ entries_size;
|
||||||
|
block->block_address = address;
|
||||||
|
block->timer_count = number;
|
||||||
|
block->timer_offset = sizeof(struct acpi_gtdt_timer_block);
|
||||||
|
current += sizeof(struct acpi_gtdt_timer_block);
|
||||||
|
memcpy((void *)current, timers, entries_size);
|
||||||
|
current += entries_size;
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long acpi_gtdt_add_watchdog(unsigned long current, uint64_t refresh_frame,
|
||||||
|
uint64_t control_frame, uint32_t gsiv, uint32_t flags)
|
||||||
|
{
|
||||||
|
struct acpi_gtdt_watchdog *wd = (struct acpi_gtdt_watchdog *)current;
|
||||||
|
memset(wd, 0, sizeof(struct acpi_gtdt_watchdog));
|
||||||
|
|
||||||
|
wd->header.type = ACPI_GTDT_TYPE_WATCHDOG;
|
||||||
|
wd->header.length = sizeof(struct acpi_gtdt_watchdog);
|
||||||
|
wd->refresh_frame_address = refresh_frame;
|
||||||
|
wd->control_frame_address = control_frame;
|
||||||
|
wd->timer_interrupt = gsiv;
|
||||||
|
wd->timer_flags = flags;
|
||||||
|
|
||||||
|
return current + sizeof(struct acpi_gtdt_watchdog);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long acpi_create_lpi_desc_ncst(acpi_lpi_desc_ncst_t *lpi_desc, uint16_t uid)
|
unsigned long acpi_create_lpi_desc_ncst(acpi_lpi_desc_ncst_t *lpi_desc, uint16_t uid)
|
||||||
{
|
{
|
||||||
memset(lpi_desc, 0, sizeof(acpi_lpi_desc_ncst_t));
|
memset(lpi_desc, 0, sizeof(acpi_lpi_desc_ncst_t));
|
||||||
|
@ -1333,6 +1391,7 @@ unsigned long write_acpi_tables(const unsigned long start)
|
||||||
{ acpi_create_madt, NULL, sizeof(acpi_header_t) },
|
{ acpi_create_madt, NULL, sizeof(acpi_header_t) },
|
||||||
{ acpi_create_bert, NULL, sizeof(acpi_bert_t) },
|
{ acpi_create_bert, NULL, sizeof(acpi_bert_t) },
|
||||||
{ acpi_create_spcr, NULL, sizeof(acpi_spcr_t) },
|
{ acpi_create_spcr, NULL, sizeof(acpi_spcr_t) },
|
||||||
|
{ acpi_create_gtdt, NULL, sizeof(acpi_gtdt_t) },
|
||||||
};
|
};
|
||||||
|
|
||||||
current = start;
|
current = start;
|
||||||
|
@ -1647,6 +1706,8 @@ int get_acpi_table_revision(enum acpi_tables table)
|
||||||
return 0;
|
return 0;
|
||||||
case SPCR:
|
case SPCR:
|
||||||
return 4;
|
return 4;
|
||||||
|
case GTDT:
|
||||||
|
return 3;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ enum acpi_tables {
|
||||||
/* Tables defined by ACPI and used by coreboot */
|
/* Tables defined by ACPI and used by coreboot */
|
||||||
BERT, CEDT, DBG2, DMAR, DSDT, EINJ, FACS, FADT, HEST, HMAT, HPET, IVRS,
|
BERT, CEDT, DBG2, DMAR, DSDT, EINJ, FACS, FADT, HEST, HMAT, HPET, IVRS,
|
||||||
MADT, MCFG, RSDP, RSDT, SLIT, SRAT, SSDT, TCPA, TPM2, XSDT, ECDT, LPIT,
|
MADT, MCFG, RSDP, RSDT, SLIT, SRAT, SSDT, TCPA, TPM2, XSDT, ECDT, LPIT,
|
||||||
SPCR,
|
SPCR, GTDT,
|
||||||
/* Additional proprietary tables used by coreboot */
|
/* Additional proprietary tables used by coreboot */
|
||||||
VFCT, NHLT, SPMI, CRAT
|
VFCT, NHLT, SPMI, CRAT
|
||||||
};
|
};
|
||||||
|
@ -1576,6 +1576,13 @@ unsigned long acpi_create_lpi_desc_ncst(acpi_lpi_desc_ncst_t *lpi_desc, uint16_t
|
||||||
/* chipsets that select ACPI_BERT must implement this function */
|
/* chipsets that select ACPI_BERT must implement this function */
|
||||||
enum cb_err acpi_soc_get_bert_region(void **region, size_t *length);
|
enum cb_err acpi_soc_get_bert_region(void **region, size_t *length);
|
||||||
|
|
||||||
|
void acpi_soc_fill_gtdt(acpi_gtdt_t *gtdt);
|
||||||
|
unsigned long acpi_soc_gtdt_add_timers(uint32_t *count, unsigned long current);
|
||||||
|
unsigned long acpi_gtdt_add_timer_block(unsigned long current, const uint64_t address,
|
||||||
|
struct acpi_gtdt_timer_entry *timers, size_t number);
|
||||||
|
unsigned long acpi_gtdt_add_watchdog(unsigned long current, uint64_t refresh_frame,
|
||||||
|
uint64_t control_frame, uint32_t gsiv, uint32_t flags);
|
||||||
|
|
||||||
/* For ACPI S3 support. */
|
/* For ACPI S3 support. */
|
||||||
void __noreturn acpi_resume(void *wake_vec);
|
void __noreturn acpi_resume(void *wake_vec);
|
||||||
void mainboard_suspend_resume(void);
|
void mainboard_suspend_resume(void);
|
||||||
|
|
Loading…
Reference in New Issue