Skip to content

Commit

Permalink
Map Multiprocessor Specification (MP) configuration table (#113)
Browse files Browse the repository at this point in the history
Map the MP table so we can use it as a fallback for the ACPI MADT on
older systems.
  • Loading branch information
phaubertin authored Jan 25, 2025
1 parent cd37398 commit 8fda723
Show file tree
Hide file tree
Showing 14 changed files with 691 additions and 14 deletions.
2 changes: 2 additions & 0 deletions include/kernel/infrastructure/acpi/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
#include <stdbool.h>
#include <stddef.h>

bool verify_acpi_checksum(const void *buffer, size_t buflen);

bool verify_acpi_rsdp(const acpi_rsdp_t *rsdp);

void map_acpi_tables(kern_paddr_t rsdp_paddr, const acpi_table_def_t *table_defs);
Expand Down
2 changes: 1 addition & 1 deletion include/kernel/infrastructure/acpi/tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ typedef PACKED_STRUCT {
acpi_table_header_t header;
uint32_t local_intr_controller_addr;
uint32_t flags;
char entries[];
const char entries[];
} acpi_madt_t;

typedef PACKED_STRUCT {
Expand Down
2 changes: 2 additions & 0 deletions include/kernel/infrastructure/i686/firmware/asm/bios.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,6 @@

#define BIOS_BDA_EBDA_SEGMENT 0x40e

#define BIOS_BDA_MEMORY_SIZE 0x413

#endif
125 changes: 125 additions & 0 deletions include/kernel/infrastructure/i686/firmware/asm/mp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Copyright (C) 2025 Philippe Aubertin.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the author nor the names of other contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_FIRMWARE_ASM_MP_H
#define JINUE_KERNEL_INFRASTRUCTURE_I686_FIRMWARE_ASM_MP_H

/* Multiprocessor Specification 1.4 section 4.1 MP Floating Pointer
* Structure */

#define MP_FLOATING_PTR_SIGNATURE "_MP_"


/* Table 4-1. MP Floating Pointer Structure Fields, flags in the MP Feature
* Information byte 2 field. Bit 6 is defined in Appendix E Errata. */

#define MP_FEATURE2_IMCRP (1 << 7)

#define MP_FEATURE2_MULTIPLE_CLK_SOURCES (1 << 6)

/* Multiprocessor Specification 1.4 section 4.2 MP Configuration Table
* Header */

#define MP_CONF_TABLE_SIGNATURE "PCMP"

#define MP_REVISION_V1_1 1

#define MP_REVISION_V1_4 4

/* Multiprocessor Specification 1.4 Table 4-3 Base MP Configuration Table Entry
* Types */

#define MP_ENTRY_TYPE_PROCESSOR 0

#define MP_ENTRY_TYPE_BUS 1

#define MP_ENTRY_TYPE_IO_APIC 2

#define MP_ENTRY_TYPE_IO_INTR 3

#define MP_ENTRY_TYPE_LOCAL_INTR 4

/* Multiprocessor Specification 1.4 Table 4-8 Bus Type String Values */

#define MP_BUS_TYPE_EISA "EISA"

#define MP_BUS_TYPE_ISA "ISA"

#define MP_BUS_TYPE_PCI "PCI"

/* Multiprocessor Specification 1.4 section 4.3.3 I/O APIC Entries */

#define MP_IO_API_FLAG_EN (1 << 0)

/* Multiprocessor Specification 1.4 Table 4-10 I/O Interrupt Entry Fields */

#define MP_PO_BUS_DEFAULT 0

#define MP_PO_ACTIVE_HIGH 1

#define MP_PO_ACTIVE_LOW 3


#define MP_EL_BUS_DEFAULT (0 << 2)

#define MP_EL_EDGE (1 << 2)

#define MP_EL_LEVEL (2 << 2)

/* Multiprocessor Specification 1.4 Table 4-11 Interrupt Type Values */

#define MP_INTR_TYPE_INT 0

#define MP_INTR_TYPE_NMI 1

#define MP_INTR_TYPE_SMI 2

#define MP_INTR_TYPE_EXTINT 3

/* Multiprocessor Specification 1.4 Table 5-1 Default Configurations */

#define MP_NO_DEFAULT 0

#define MP_DEFAULT_ISA 1

#define MP_DEFAULT_EISA_NO_IRQ0 2

#define MP_DEFAULT_EISA 3

#define MP_DEFAULT_MCA 4

#define MP_DEFAULT_ISA_PCI_APIC 5

#define MP_DEFAULT_EISA_PIC_APIC 6

#define MP_DEFAULT_MCA_PCI_APIC 7

#endif
43 changes: 43 additions & 0 deletions include/kernel/infrastructure/i686/firmware/bios.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2025 Philippe Aubertin.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the author nor the names of other contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_FIRMWARE_BIOS_H
#define JINUE_KERNEL_INFRASTRUCTURE_I686_FIRMWARE_BIOS_H

#include <kernel/infrastructure/i686/firmware/asm/bios.h>
#include <stddef.h>
#include <stdint.h>

uint32_t get_bios_ebda_addr(void);

size_t get_bios_base_memory_size(void);

#endif
120 changes: 120 additions & 0 deletions include/kernel/infrastructure/i686/firmware/mp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Copyright (C) 2025 Philippe Aubertin.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the author nor the names of other contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_FIRMWARE_MP_H
#define JINUE_KERNEL_INFRASTRUCTURE_I686_FIRMWARE_MP_H

#include <kernel/infrastructure/i686/firmware/asm/mp.h>
#include <stdint.h>

/* Multiprocessor Specification 1.4 section 4.1 MP Floating Pointer
* Structure */

typedef struct {
char signature[4];
uint32_t addr;
uint8_t length;
uint8_t revision;
uint8_t checksum;
uint8_t feature1;
uint8_t feature2;
uint8_t feature_reserved[3];
} mp_ptr_struct_t;

/* Multiprocessor Specification 1.4 section 4.2 MP Configuration Table
* Header */

typedef struct {
char signature[4];
uint16_t base_length;
uint8_t revision;
uint8_t checksum;
char oem_id[8];
char product_id[12];
uint32_t oem_table_addr;
uint16_t oem_table_size;
uint16_t entry_count;
uint32_t lapic_addr;
uint16_t ext_table_length;
uint8_t ext_table_checksum;
uint8_t reserved;
const char entries[];
} mp_conf_table_t;

/* Multiprocessor Specification 1.4 section 4.3.1 Processor Entries */

typedef struct {
uint8_t entry_type;
uint8_t apic_id;
uint8_t apic_version;
uint8_t cpu_flags;
uint32_t cpu_signature;
uint32_t feature_flags;
uint32_t reserved1;
uint32_t reserved2;
} mp_entry_processor_t;

/* Multiprocessor Specification 1.4 section 4.3.2 Bus Entries */

typedef struct {
uint8_t entry_type;
uint8_t bus_id;
char bus_type[6];
} mp_entry_bus_t;

/* Multiprocessor Specification 1.4 section 4.3.3 I/O APIC Entries */

typedef struct {
uint8_t entry_type;
uint8_t apic_id;
uint8_t apic_version;
uint8_t flag;
uint32_t addr;
} mp_entry_ioapic_t;

/* Multiprocessor Specification 1.4 section 4.3.4 I/O Interrupt Assignment
* Entries and 4.3.5 Local Interrupt Assignment Entries */

typedef struct {
uint8_t entry_type;
uint8_t intr_type;
uint16_t io_intr_flag;
uint8_t source_bus_id;
uint8_t source_bus_irq;
uint8_t dest_apic_id;
uint8_t dest_apic_intn;
} mp_entry_intr_t;

void find_mp(void);

void init_mp(void);

#endif
2 changes: 2 additions & 0 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ sources.kernel.c = \
infrastructure/i686/drivers/uart16550a.c \
infrastructure/i686/drivers/vga.c \
infrastructure/i686/firmware/acpi.c \
infrastructure/i686/firmware/bios.c \
infrastructure/i686/firmware/mp.c \
infrastructure/i686/pmap/nopae.c \
infrastructure/i686/pmap/pmap.c \
infrastructure/i686/pmap/pae.c \
Expand Down
16 changes: 10 additions & 6 deletions kernel/infrastructure/acpi/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,17 @@
#include <string.h>

/**
* Verify the checksum of an ACPI data structure
* Verify the checksum of an ACPI data structure (RSDP, RSDT, ACPI table)
*
* On x86, this function is also used to verify the checksum of the floating
* pointer structure and MP configuration table header from Intel's
* Multiprocessor Specification since the checksum algorithm is the same.
*
* @param buffer pointer to ACPI data structure
* @param buffer pointer to ACPI (or MP) data structure
* @param buflen size of ACPI data structure
* @return true for correct checksum, false for checksum mismatch
*/
static bool verify_checksum(const void *buffer, size_t buflen) {
bool verify_acpi_checksum(const void *buffer, size_t buflen) {
uint8_t sum = 0;

for(int idx = 0; idx < buflen; ++idx) {
Expand All @@ -64,7 +68,7 @@ bool verify_acpi_rsdp(const acpi_rsdp_t *rsdp) {
return false;
}

if(!verify_checksum(rsdp, ACPI_V1_RSDP_SIZE)) {
if(!verify_acpi_checksum(rsdp, ACPI_V1_RSDP_SIZE)) {
return false;
}

Expand All @@ -76,7 +80,7 @@ bool verify_acpi_rsdp(const acpi_rsdp_t *rsdp) {
return false;
}

return verify_checksum(rsdp, sizeof(acpi_rsdp_t));
return verify_acpi_checksum(rsdp, sizeof(acpi_rsdp_t));
}

/**
Expand Down Expand Up @@ -123,7 +127,7 @@ static const void *map_table(const acpi_table_header_t *header) {

resize_map_in_kernel(header->length);

if(! verify_checksum(header, header->length)) {
if(! verify_acpi_checksum(header, header->length)) {
return NULL;
}

Expand Down
Loading

0 comments on commit 8fda723

Please sign in to comment.