aboutsummaryrefslogtreecommitdiff
path: root/i386/i386at/acpi_parse_apic.c
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2024-02-07 05:02:15 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2024-02-08 00:27:18 +0100
commitcaa07fdb903c6d533ce6dad1a66907d862e162ad (patch)
tree923709e5ea823d461f3a53433f0cdd21c9cabf9f /i386/i386at/acpi_parse_apic.c
parent69477710c88420603f32e84511d9adc2923d0503 (diff)
downloadgnumach-caa07fdb903c6d533ce6dad1a66907d862e162ad.tar.gz
gnumach-caa07fdb903c6d533ce6dad1a66907d862e162ad.tar.bz2
gnumach-caa07fdb903c6d533ce6dad1a66907d862e162ad.zip
Add HPET timer for small accurate delays
TESTED: This works in qemu correctly TESTED: This works on an AMD board with ACPI v2.0 correctly Message-ID: <20240207050158.1640853-3-damien@zamaudio.com>
Diffstat (limited to 'i386/i386at/acpi_parse_apic.c')
-rw-r--r--i386/i386at/acpi_parse_apic.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/i386/i386at/acpi_parse_apic.c b/i386/i386at/acpi_parse_apic.c
index dcd5da89..1cfc1791 100644
--- a/i386/i386at/acpi_parse_apic.c
+++ b/i386/i386at/acpi_parse_apic.c
@@ -34,6 +34,7 @@
static struct acpi_apic *apic_madt = NULL;
unsigned lapic_addr;
+uint32_t *hpet_addr;
/*
* acpi_print_info: shows by screen the ACPI's rsdp and rsdt virtual address
@@ -292,28 +293,37 @@ acpi_get_xsdt(phys_addr_t rsdp_phys, int* acpi_xsdt_n)
* and the number of entries of RSDT table.
*
* Returns a reference to APIC/MADT table if success, NULL if failure.
+ * Also sets hpet_addr to base address of HPET.
*/
static struct acpi_apic*
acpi_get_apic(struct acpi_rsdt *rsdt, int acpi_rsdt_n)
{
struct acpi_dhdr *descr_header;
+ struct acpi_apic *madt = NULL;
int check_signature;
+ uint64_t map_addr;
/* Search APIC entries in rsdt table. */
for (int i = 0; i < acpi_rsdt_n; i++) {
descr_header = (struct acpi_dhdr*) kmem_map_aligned_table(rsdt->entry[i], sizeof(struct acpi_dhdr),
VM_PROT_READ);
- /* Check if the entry contains an APIC. */
+ /* Check if the entry is a MADT */
check_signature = acpi_check_signature(descr_header->signature, ACPI_APIC_SIG, 4*sizeof(uint8_t));
+ if (check_signature == ACPI_SUCCESS)
+ madt = (struct acpi_apic*) descr_header;
+ /* Check if the entry is a HPET */
+ check_signature = acpi_check_signature(descr_header->signature, ACPI_HPET_SIG, 4*sizeof(uint8_t));
if (check_signature == ACPI_SUCCESS) {
- /* If yes, return the APIC. */
- return (struct acpi_apic*) descr_header;
+ map_addr = ((struct acpi_hpet *)descr_header)->address.addr64;
+ assert (map_addr != 0);
+ hpet_addr = (uint32_t *)kmem_map_aligned_table(map_addr, 1024, VM_PROT_READ | VM_PROT_WRITE);
+ printf("HPET at physical address 0x%llx\n", map_addr);
}
}
- return NULL;
+ return madt;
}
/*
@@ -323,28 +333,37 @@ acpi_get_apic(struct acpi_rsdt *rsdt, int acpi_rsdt_n)
* and the number of entries of XSDT table.
*
* Returns a reference to APIC/MADT table if success, NULL if failure.
+ * Also sets hpet_addr to base address of HPET.
*/
static struct acpi_apic*
acpi_get_apic2(struct acpi_xsdt *xsdt, int acpi_xsdt_n)
{
struct acpi_dhdr *descr_header;
+ struct acpi_apic *madt = NULL;
int check_signature;
+ uint64_t map_addr;
/* Search APIC entries in rsdt table. */
for (int i = 0; i < acpi_xsdt_n; i++) {
descr_header = (struct acpi_dhdr*) kmem_map_aligned_table(xsdt->entry[i], sizeof(struct acpi_dhdr),
VM_PROT_READ);
- /* Check if the entry contains an APIC. */
+ /* Check if the entry is an APIC. */
check_signature = acpi_check_signature(descr_header->signature, ACPI_APIC_SIG, 4*sizeof(uint8_t));
+ if (check_signature == ACPI_SUCCESS)
+ madt = (struct acpi_apic *)descr_header;
+ /* Check if the entry is a HPET. */
+ check_signature = acpi_check_signature(descr_header->signature, ACPI_HPET_SIG, 4*sizeof(uint8_t));
if (check_signature == ACPI_SUCCESS) {
- /* If yes, return the APIC. */
- return (struct acpi_apic*) descr_header;
+ map_addr = ((struct acpi_hpet *)descr_header)->address.addr64;
+ assert (map_addr != 0);
+ hpet_addr = (uint32_t *)kmem_map_aligned_table(map_addr, 1024, VM_PROT_READ | VM_PROT_WRITE);
+ printf("HPET at physical address 0x%llx\n", map_addr);
}
}
- return NULL;
+ return madt;
}
/*