Changeset 39


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

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

Location:
trunk/hal/x86_64
Files:
6 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
  • trunk/hal/x86_64/hal_acpi.h

    r35 r39  
    33 *
    44 * Copyright (c) 2017 Maxime Villard
     5 * Inspired by ACPICA.
    56 *
    67 * This file is part of ALMOS-MKH.
     
    2021 */
    2122
     23/*
     24 * Copyright (C) 2000 - 2017, Intel Corp.
     25 * All rights reserved.
     26 *
     27 * Redistribution and use in source and binary forms, with or without
     28 * modification, are permitted provided that the following conditions
     29 * are met:
     30 * 1. Redistributions of source code must retain the above copyright
     31 *    notice, this list of conditions, and the following disclaimer,
     32 *    without modification.
     33 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     34 *    substantially similar to the "NO WARRANTY" disclaimer below
     35 *    ("Disclaimer") and any redistribution must be conditioned upon
     36 *    including a substantially similar Disclaimer requirement for further
     37 *    binary redistribution.
     38 * 3. Neither the names of the above-listed copyright holders nor the names
     39 *    of any contributors may be used to endorse or promote products derived
     40 *    from this software without specific prior written permission.
     41 *
     42 * Alternatively, this software may be distributed under the terms of the
     43 * GNU General Public License ("GPL") version 2 as published by the Free
     44 * Software Foundation.
     45 *
     46 * NO WARRANTY
     47 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     48 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     49 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     50 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     51 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     55 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     56 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     57 * POSSIBILITY OF SUCH DAMAGES.
     58 */
     59
    2260void hal_acpi_init();
    2361
     
    2866#define ACPI_OEM_ID_SIZE        6
    2967
     68#define ACPI_NAME_SIZE  4
     69
     70/* Sizes for ACPI table headers */
     71#define ACPI_OEM_ID_SIZE                6
     72#define ACPI_OEM_TABLE_ID_SIZE  8
     73
     74
     75/*******************************************************************************
     76 * RSDP - Root System Description Pointer (Signature is "RSD PTR ")
     77 *        Version 2
     78 ******************************************************************************/
     79
    3080struct acpi_table_rsdp {
    31         char Signature[8];               /* ACPI signature, contains "RSD PTR " */
    32         uint8_t Checksum;                /* ACPI 1.0 checksum */
    33         char OemId[ACPI_OEM_ID_SIZE];    /* OEM identification */
    34         uint8_t Revision;                /* Must be (0) for ACPI 1.0 or (2) for ACPI 2.0+ */
    35         uint32_t RsdtPhysicalAddress;    /* 32-bit physical address of the RSDT */
    36         uint32_t Length;                 /* Table length in bytes, including header (ACPI 2.0+) */
    37         uint64_t XsdtPhysicalAddress;    /* 64-bit physical address of the XSDT (ACPI 2.0+) */
    38         uint8_t ExtendedChecksum;        /* Checksum of entire table (ACPI 2.0+) */
    39         uint8_t Reserved[3];             /* Reserved, must be zero */
     81        char Signature[8];            /* ACPI signature, contains "RSD PTR " */
     82        uint8_t Checksum;             /* ACPI 1.0 checksum */
     83        char OemId[ACPI_OEM_ID_SIZE]; /* OEM identification */
     84        uint8_t Revision;             /* Must be (0) for ACPI 1.0 or (2) for ACPI 2.0+ */
     85        uint32_t RsdtPhysicalAddress; /* 32-bit physical address of the RSDT */
     86        uint32_t Length;              /* Table length in bytes, including header (ACPI 2.0+) */
     87        uint64_t XsdtPhysicalAddress; /* 64-bit physical address of the XSDT (ACPI 2.0+) */
     88        uint8_t ExtendedChecksum;     /* Checksum of entire table (ACPI 2.0+) */
     89        uint8_t Reserved[3];          /* Reserved, must be zero */
    4090} __packed;
     91typedef struct acpi_table_rsdp  rsdp_t;
    4192
    42 typedef struct acpi_table_rsdp  rsdp_t;
     93/*******************************************************************************
     94 * Master ACPI Table Header. This common header is used by all ACPI tables
     95 * except the RSDP and FACS.
     96 ******************************************************************************/
     97
     98struct acpi_table_header {
     99        char Signature[ACPI_NAME_SIZE];          /* ASCII table signature */
     100        uint32_t Length;                         /* Length of table in bytes, including this header */
     101        uint8_t Revision;                        /* ACPI Specification minor version number */
     102        uint8_t Checksum;                        /* To make sum of entire table == 0 */
     103        char OemId[ACPI_OEM_ID_SIZE];            /* ASCII OEM identification */
     104        char OemTableId[ACPI_OEM_TABLE_ID_SIZE]; /* ASCII OEM table identification */
     105        uint32_t OemRevision;                    /* OEM revision number */
     106        char AslCompilerId[ACPI_NAME_SIZE];      /* ASCII ASL compiler vendor ID */
     107        uint32_t AslCompilerRevision;            /* ASL compiler version */
     108} __packed;
     109typedef struct acpi_table_header        header_t;
     110
     111/*******************************************************************************
     112 * RSDT - Root System Description Tables
     113 *        Version 1
     114 ******************************************************************************/
     115
     116struct acpi_table_rsdt {
     117        header_t Header;              /* Common ACPI table header */
     118    uint32_t TableOffsetEntry[1]; /* Array of pointers to ACPI tables */
     119} __packed;
     120typedef struct acpi_table_rsdt  rsdt_t;
     121
     122/*******************************************************************************
     123 * Common subtable headers
     124 ******************************************************************************/
     125
     126struct acpi_subtable_header {
     127        uint8_t Type;
     128        uint8_t Length;
     129} __packed;
     130typedef struct acpi_subtable_header     subheader_t;
     131
     132/*******************************************************************************
     133 * MADT - Multiple APIC Description Table
     134 *        Version 3
     135 ******************************************************************************/
     136
     137struct acpi_table_madt {
     138        header_t Header;  /* Common ACPI table header */
     139        uint32_t Address; /* Physical address of local APIC */
     140        uint32_t Flags;
     141} __packed;
     142typedef struct acpi_table_madt  madt_t;
     143
     144/*******************************************************************************
     145 * MADT structures
     146 ******************************************************************************/
     147
     148enum AcpiMadtType {
     149        ACPI_MADT_TYPE_LOCAL_APIC            = 0,
     150        ACPI_MADT_TYPE_IO_APIC               = 1,
     151        ACPI_MADT_TYPE_INTERRUPT_OVERRIDE    = 2,
     152        ACPI_MADT_TYPE_NMI_SOURCE            = 3,
     153        ACPI_MADT_TYPE_LOCAL_APIC_NMI        = 4,
     154        ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE   = 5,
     155        ACPI_MADT_TYPE_IO_SAPIC              = 6,
     156        ACPI_MADT_TYPE_LOCAL_SAPIC           = 7,
     157        ACPI_MADT_TYPE_INTERRUPT_SOURCE      = 8,
     158        ACPI_MADT_TYPE_LOCAL_X2APIC          = 9,
     159        ACPI_MADT_TYPE_LOCAL_X2APIC_NMI      = 10,
     160        ACPI_MADT_TYPE_GENERIC_INTERRUPT     = 11,
     161        ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR   = 12,
     162        ACPI_MADT_TYPE_GENERIC_MSI_FRAME     = 13,
     163        ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR = 14,
     164        ACPI_MADT_TYPE_GENERIC_TRANSLATOR    = 15,
     165        ACPI_MADT_TYPE_RESERVED              = 16  /* 16 and greater are reserved */
     166};
     167
     168struct acpi_madt_local_apic {
     169        subheader_t Header;
     170        uint8_t ProcessorId; /* ACPI processor id */
     171        uint8_t Id;          /* Processor's local APIC id */
     172        uint32_t LapicFlags;
     173} __packed;
     174typedef struct acpi_madt_local_apic     madt_lapic_t;
     175
     176struct acpi_madt_local_apic_override {
     177        subheader_t Header;
     178        uint16_t Reserved; /* Reserved, must be zero */
     179        uint64_t Address;  /* APIC physical address */
     180} __packed;
     181typedef struct acpi_madt_local_apic_override madt_lapic_override;
     182
  • trunk/hal/x86_64/hal_gpt.c

    r35 r39  
    6464void hal_gpt_enter(vaddr_t va, paddr_t pa)
    6565{
     66        XASSERT((va % PAGE_SIZE == 0));
     67        XASSERT((pa % PAGE_SIZE == 0));
    6668        PTE_BASE[pl1_i(va)] = (pa & PG_FRAME) | PG_V | PG_KW | PG_NX;
     69}
     70
     71void hal_gpt_enter_range(vaddr_t va, paddr_t pa, size_t n)
     72{
     73        size_t i;
     74        for (i = 0; i < n; i++) {
     75                hal_gpt_enter(va + i * PAGE_SIZE, pa + i * PAGE_SIZE);
     76                invlpg(va + i * PAGE_SIZE);
     77        }
    6778}
    6879
  • trunk/hal/x86_64/hal_init.c

    r35 r39  
    7575{
    7676        x86_printf("[+] init_x86_64 called\n");
    77 
    78         extern uint64_t __kernel_end;
    79         x86_printf("__kernel_end: %Z\n", (uint64_t)&__kernel_end);
    8077
    8178        /* Create the global structures */
  • trunk/hal/x86_64/hal_internal.h

    r35 r39  
    2020 */
    2121
     22#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
     23#define rounddown(x,y) (((x)/(y))*(y))
     24
     25#define XASSERT(a)      \
     26        if (!(a)) { \
     27                x86_panic((char *)__func__); \
     28        }
     29
    2230/* hal_cpu.S */
    2331void invlpg(vaddr_t va);
     
    2735vaddr_t hal_gpt_bootstrap_valloc(size_t npages);
    2836void hal_gpt_enter(vaddr_t va, paddr_t pa);
     37void hal_gpt_enter_range(vaddr_t va, paddr_t pa, size_t n);
    2938void hal_gpt_init(paddr_t firstpa);
    3039
    3140/* x86_printf.c */
     41void x86_panic(char *msg);
    3242void x86_printf(char *s, ...);
    3343
  • trunk/hal/x86_64/x86_printf.c

    r32 r39  
    2323#include <hal_types.h>
    2424#include <hal_boot.h>
     25#include <hal_internal.h>
    2526
    2627#include <memcpy.h>
     
    3940extern intptr_t iom_base;
    4041size_t cons_ptr __in_kdata = 0;
     42
     43void x86_panic(char *msg)
     44{
     45        x86_printf("!!!!! PANIC !!!!!\n");
     46        x86_printf("-> %s\n", msg);
     47        x86_printf("!!!!!!!!!!!!!!!!!\n");
     48        while (1);
     49}
    4150
    4251static void x86_putc(char c)
Note: See TracChangeset for help on using the changeset viewer.