Ignore:
Timestamp:
Jun 22, 2017, 3:13:14 PM (5 years ago)
Author:
max@…
Message:

Parse RSDP->RSDT->MADT, and get the LAPIC PA.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/hal/x86_64/hal_acpi.c

    r35 r39  
    3434#include <cluster.h>
    3535
    36 
    3736/* XXX XXX libk XXX XXX */
    3837int memcmp(char *s1, char *s2, size_t n)
     
    4645}
    4746
     47/* -------------------------------------------------------------------------- */
     48
     49#define RSDT_NENTRIES(rsdt) \
     50        ( (rsdt->Header.Length - sizeof(rsdt_t) + sizeof(uint32_t)) / sizeof(uint32_t) )
     51#define RSDT_ENTRIES(rsdt) \
     52        ((uint32_t *)&rsdt->TableOffsetEntry[0])
     53
     54static bool_t hal_acpi_table_correct(header_t *header)
     55{
     56        uint8_t *ptr, sum = 0;
     57        size_t i, n;
     58
     59        ptr = (uint8_t *)header;
     60        n = header->Length;
     61
     62        /* Verify checksum */
     63        for (i = 0; i < n; i++) {
     64                sum += ptr[i];
     65        }
     66
     67        return (sum == 0);
     68}
     69
     70static vaddr_t hal_acpi_map_table(paddr_t headerpa, const char *sig)
     71{
     72        paddr_t basepa, pa;
     73        vaddr_t baseva, retva, va;
     74        size_t i, off, size;
     75        size_t npages, ngrow, n;
     76        header_t *header;
     77
     78        /* Allocate the VA for the header */
     79        basepa = rounddown(headerpa, PAGE_SIZE);
     80        npages = roundup(headerpa + sizeof(header_t), PAGE_SIZE) - basepa;
     81        baseva = hal_gpt_bootstrap_valloc(npages);
     82        off = headerpa - basepa;
     83
     84        /* Enter the VA, and get the total size of the structure */
     85        hal_gpt_enter_range(baseva, basepa, npages);
     86        retva = (vaddr_t)(baseva + off);
     87        header = (header_t *)retva;
     88        size = header->Length;
     89        XASSERT(size >= sizeof(header_t));
     90
     91        /* Check the signature */
     92        if (memcmp((void *)&header->Signature, sig, ACPI_NAME_SIZE))
     93                return 0;
     94
     95        /* Grow the VA to map the rest */
     96        ngrow = roundup(headerpa + size, PAGE_SIZE) - basepa;
     97        n = ngrow - npages;
     98        va = hal_gpt_bootstrap_valloc(n);
     99        pa = basepa + npages * PAGE_SIZE;
     100        hal_gpt_enter_range(va, pa, n);
     101
     102        /* Verify the checksum */
     103        if (!hal_acpi_table_correct(header))
     104                x86_panic("Wrong checksum for table");
     105
     106        return retva;
     107}
     108
     109/* -------------------------------------------------------------------------- */
     110
     111static void hal_acpi_parse_madt(madt_t *madt)
     112{
     113        paddr_t lapic_pa = (paddr_t)madt->Address;
     114        x86_printf("-> LAPIC address: %Z\n", lapic_pa);
     115}
     116
     117static madt_t *hal_acpi_map_madt(rsdt_t *rsdt)
     118{
     119        vaddr_t va;
     120        paddr_t basepa, pa;
     121        uint32_t *ent;
     122        size_t i, n;
     123
     124        n = RSDT_NENTRIES(rsdt);
     125        ent = RSDT_ENTRIES(rsdt);
     126
     127        for (i = 0; i < n; i++) {
     128                pa = (paddr_t)ent[i];
     129                va = hal_acpi_map_table(pa, "APIC");
     130                if (va == 0)
     131                        continue;
     132                return (madt_t *)va;
     133        }
     134
     135        return NULL;
     136}
     137
     138/* -------------------------------------------------------------------------- */
     139
     140static rsdt_t *hal_acpi_map_rsdt(rsdp_t *rsdp)
     141{
     142        paddr_t rsdt_pa;
     143        rsdt_t *rsdt;
     144
     145        rsdt_pa = (paddr_t)rsdp->RsdtPhysicalAddress;
     146        rsdt = (rsdt_t *)hal_acpi_map_table(rsdt_pa, "RSDT");
     147        if (rsdt == 0)
     148                x86_panic("RSDT invalid");
     149
     150        return rsdt;
     151}
     152
     153/* -------------------------------------------------------------------------- */
     154
    48155static bool_t hal_acpi_rsdp_correct(uint8_t *ptr)
    49156{
     
    59166}
    60167
    61 static void *hal_acpi_find_rsdp(vaddr_t va_start, vaddr_t va_end)
     168static rsdp_t *hal_acpi_find_rsdp(vaddr_t va_start, vaddr_t va_end)
    62169{
    63170        rsdp_t *rsdp;
     
    84191        rsdp = (rsdp_t *)ptr;
    85192
    86         x86_printf("-> rsdp = %Z\n", rsdp);
    87193        memcpy(&oem, rsdp->OemId, ACPI_OEM_ID_SIZE);
    88194        oem[ACPI_OEM_ID_SIZE] = '\0';
    89195        x86_printf("-> OEM: %s\n", oem);
     196        if (rsdp->Revision != 0)
     197                x86_printf("[!] Using ACPI 1.0\n");
    90198
    91199        return rsdp;
    92200}
    93201
     202/* -------------------------------------------------------------------------- */
     203
    94204void hal_acpi_init()
    95205{
    96206        rsdp_t *rsdp;
     207        rsdt_t *rsdt;
     208        madt_t *madt;
    97209        paddr_t bios_min = 0x0E0000;
    98210        paddr_t bios_max = 0x100000;
     
    114226        /* First, find RSDP */
    115227        rsdp = hal_acpi_find_rsdp(vabase, vabase + npages * PAGE_SIZE);
    116         if (rsdp == NULL) {
    117                 x86_printf("[!] RSDP not found\n");
    118         }
    119 }
    120 
     228        if (rsdp == NULL)
     229                x86_panic("RSDP not found");
     230
     231        /* Then, map RSDT */
     232        rsdt = hal_acpi_map_rsdt(rsdp);
     233        if (rsdt == NULL)
     234                x86_panic("RSDT not found");
     235
     236        /* Now, map MADT */
     237        madt = hal_acpi_map_madt(rsdt);
     238        if (madt == NULL)
     239                x86_panic("MADT not found");
     240
     241        /* Parse it */
     242        hal_acpi_parse_madt(madt);
     243}
     244
Note: See TracChangeset for help on using the changeset viewer.