Patch by Dustin Howett (GSOC): Move ACPI probing out of the
bootloader's smp init and into its own unit. ACPI tables can now generally be found with acpi_find_table(signature). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26538 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+17
-16
@@ -1,9 +1,10 @@
|
||||
/*
|
||||
* Copyright 2008, Dustin Howett, dustin.howett@gmail.com. All rights reserved.
|
||||
* Copyright 2007, Michael Lotz, mmlr@mlotz.ch. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _KERNEL_ARCH_x86_SMP_ACPI_H
|
||||
#define _KERNEL_ARCH_x86_SMP_ACPI_H
|
||||
#ifndef _KERNEL_ARCH_x86_ARCH_ACPI_H
|
||||
#define _KERNEL_ARCH_x86_ARCH_ACPI_H
|
||||
|
||||
#define ACPI_RSDP_SIGNATURE "RSD PTR "
|
||||
#define ACPI_RSDT_SIGNATURE "RSDT"
|
||||
@@ -11,7 +12,7 @@
|
||||
|
||||
#define ACPI_LOCAL_APIC_ENABLED 0x01
|
||||
|
||||
struct acpi_rsdp {
|
||||
typedef struct acpi_rsdp {
|
||||
char signature[8]; /* "RSD PTR " including blank */
|
||||
uint8 checksum; /* checksum of bytes 0-19 (per ACPI 1.0) */
|
||||
char oem_id[6]; /* not null terminated */
|
||||
@@ -21,9 +22,9 @@ struct acpi_rsdp {
|
||||
uint64 xsdt_address; /* 64bit physical memory address of XSDT */
|
||||
uint8 extended_checksum; /* including entire table */
|
||||
uint8 reserved[3];
|
||||
} _PACKED;
|
||||
} _PACKED acpi_rsdp;
|
||||
|
||||
struct acpi_descriptor_header {
|
||||
typedef struct acpi_descriptor_header {
|
||||
char signature[4]; /* table identifier as ASCII string */
|
||||
uint32 length; /* length in bytes of the entire table */
|
||||
uint8 revision;
|
||||
@@ -33,39 +34,39 @@ struct acpi_descriptor_header {
|
||||
uint32 oem_revision; /* oem supplied revision number */
|
||||
char creator_id[4]; /* creator / asl compiler id */
|
||||
uint32 creator_revision; /* compiler revision */
|
||||
} _PACKED;
|
||||
} _PACKED acpi_descriptor_header;
|
||||
|
||||
struct acpi_madt {
|
||||
acpi_descriptor_header header; /* "APIC" signature */
|
||||
typedef struct acpi_madt {
|
||||
acpi_descriptor_header header; /* "APIC" signature */
|
||||
uint32 local_apic_address; /* physical address for local CPUs APICs */
|
||||
uint32 flags;
|
||||
} _PACKED;
|
||||
} _PACKED acpi_madt;
|
||||
|
||||
enum {
|
||||
ACPI_MADT_LOCAL_APIC = 0,
|
||||
ACPI_MADT_IO_APIC = 1
|
||||
};
|
||||
|
||||
struct acpi_apic {
|
||||
typedef struct acpi_apic {
|
||||
uint8 type;
|
||||
uint8 length;
|
||||
} _PACKED;
|
||||
} _PACKED acpi_apic;
|
||||
|
||||
struct acpi_local_apic {
|
||||
typedef struct acpi_local_apic {
|
||||
uint8 type; /* 0 = processor local APIC */
|
||||
uint8 length; /* 8 bytes */
|
||||
uint8 acpi_processor_id;
|
||||
uint8 apic_id; /* the id of this APIC */
|
||||
uint32 flags; /* 1 = enabled */
|
||||
} _PACKED;
|
||||
} _PACKED acpi_local_apic;
|
||||
|
||||
struct acpi_io_apic {
|
||||
typedef struct acpi_io_apic {
|
||||
uint8 type; /* 1 = I/O APIC */
|
||||
uint8 length; /* 12 bytes */
|
||||
uint8 io_apic_id; /* the id of this APIC */
|
||||
uint8 reserved;
|
||||
uint32 io_apic_address; /* phyisical address of I/O APIC */
|
||||
uint32 interrupt_base; /* global system interrupt base */
|
||||
} _PACKED;
|
||||
} _PACKED acpi_io_apic;
|
||||
|
||||
#endif /* _KERNEL_ARCH_x86_SMP_ACPI_H */
|
||||
#endif /* _KERNEL_ARCH_x86_ARCH_ACPI_H */
|
||||
+4
-3
@@ -1,12 +1,13 @@
|
||||
/*
|
||||
* Copyright 2008, Dustin Howett, dustin.howett@gmail.com. All rights reserved.
|
||||
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
* Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
#ifndef _KERNEL_ARCH_x86_SMP_APIC_H
|
||||
#define _KERNEL_ARCH_x86_SMP_APIC_H
|
||||
#ifndef _KERNEL_ARCH_x86_ARCH_APIC_H
|
||||
#define _KERNEL_ARCH_x86_ARCH_APIC_H
|
||||
|
||||
#define MP_FLOATING_SIGNATURE '_PM_'
|
||||
#define MP_CONFIG_TABLE_SIGNATURE 'PCMP'
|
||||
@@ -191,4 +192,4 @@ enum {
|
||||
MP_INTR_TYPE_ExtINT,
|
||||
};
|
||||
|
||||
#endif /* _KERNEL_ARCH_x86_SMP_APIC_H */
|
||||
#endif /* _KERNEL_ARCH_x86_ARCH_APIC_H */
|
||||
@@ -29,6 +29,7 @@ KernelMergeObject boot_platform_bios_ia32.o :
|
||||
menu.cpp
|
||||
mmu.cpp
|
||||
cpu.cpp
|
||||
acpi.cpp
|
||||
smp.cpp
|
||||
smp_trampoline.S
|
||||
support.S
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2008, Dustin Howett, [email protected]. All rights reserved.
|
||||
* Copyright 2007, Michael Lotz, [email protected]
|
||||
* Copyright 2004-2005, Axel Dörfler, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||
* Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include "acpi.h"
|
||||
#include "mmu.h"
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <arch/x86/arch_acpi.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
//#define TRACE_ACPI
|
||||
#ifdef TRACE_ACPI
|
||||
# define TRACE(x) dprintf x
|
||||
#else
|
||||
# define TRACE(x) ;
|
||||
#endif
|
||||
|
||||
static struct scan_spots_struct acpi_scan_spots[] = {
|
||||
{ 0x0, 0x400, 0x400 - 0x0 },
|
||||
{ 0xe0000, 0x100000, 0x100000 - 0xe0000 },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
static acpi_descriptor_header *sAcpiRsdt; // System Description Table
|
||||
|
||||
|
||||
static status_t
|
||||
acpi_check_rsdt(acpi_rsdp *rsdp)
|
||||
{
|
||||
TRACE(("acpi: found rsdp at %p oem id: %.6s\n", rsdp, rsdp->oem_id));
|
||||
TRACE(("acpi: rsdp points to rsdt at 0x%lx\n", rsdp->rsdt_address));
|
||||
|
||||
// map and validate the root system description table
|
||||
acpi_descriptor_header *rsdt
|
||||
= (acpi_descriptor_header *)mmu_map_physical_memory(
|
||||
rsdp->rsdt_address, B_PAGE_SIZE, kDefaultPageFlags);
|
||||
if (!rsdt || strncmp(rsdt->signature, ACPI_RSDT_SIGNATURE, 4) != 0) {
|
||||
TRACE(("acpi: invalid root system description table\n"));
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
sAcpiRsdt = rsdt;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
acpi_descriptor_header *
|
||||
acpi_find_table(char *signature)
|
||||
{
|
||||
if (sAcpiRsdt == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Tried to keep numEntries a static variable; kept turning up 0 on table scan
|
||||
// TODO: This calculates numEntries for every acpi probe.
|
||||
int32 numEntries = (sAcpiRsdt->length - sizeof(acpi_descriptor_header)) / 4;
|
||||
if (numEntries <= 0) {
|
||||
TRACE(("acpi: root system description table is empty\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TRACE(("acpi: searching %ld entries for table '%.4s'\n", numEntries, signature));
|
||||
uint32 *pointer = (uint32 *)((uint8 *)sAcpiRsdt + sizeof(acpi_descriptor_header));
|
||||
for (int32 j = 0; j < numEntries; j++, pointer++) {
|
||||
acpi_descriptor_header *header = (acpi_descriptor_header *)
|
||||
mmu_map_physical_memory(*pointer, B_PAGE_SIZE, kDefaultPageFlags);
|
||||
if (!header || strncmp(header->signature, signature, 4) != 0) {
|
||||
// not interesting for us
|
||||
TRACE(("acpi: Looking for '%.4s'. Skipping '%.4s'\n", signature, header->signature));
|
||||
continue;
|
||||
}
|
||||
TRACE(("acpi: Found '%.4s' @ %p\n", signature));
|
||||
return header;
|
||||
}
|
||||
|
||||
// If we didn't find the table, return NULL.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
acpi_init(void)
|
||||
{
|
||||
acpi_rsdp *rsdp = NULL;
|
||||
// Try to find the ACPI RSDP.
|
||||
for (int32 i = 0; acpi_scan_spots[i].length > 0; i++) {
|
||||
char *pointer;
|
||||
TRACE(("acpi_init: entry base 0x%lx, limit 0x%lx\n", acpi_scan_spots[i].start,
|
||||
acpi_scan_spots[i].stop));
|
||||
for (pointer = (char *)acpi_scan_spots[i].start;
|
||||
(uint32)pointer < acpi_scan_spots[i].stop; pointer += 16) {
|
||||
if (strncmp(pointer, ACPI_RSDP_SIGNATURE, 8) == 0) {
|
||||
TRACE(("acpi_init: found ACPI RSDP signature at %p\n", pointer));
|
||||
rsdp = (acpi_rsdp *)pointer;
|
||||
}
|
||||
}
|
||||
if (acpi_check_rsdt(rsdp) == B_OK)
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef ACPI_H
|
||||
#define ACPI_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <arch/x86/arch_acpi.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct scan_spots_struct {
|
||||
uint32 start;
|
||||
uint32 stop;
|
||||
uint32 length;
|
||||
};
|
||||
|
||||
acpi_descriptor_header *acpi_find_table(char *signature);
|
||||
void acpi_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ACPI_H */
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008, Dustin Howett, [email protected]. All rights reserved.
|
||||
* Copyright 2004-2005, Axel Dörfler, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
@@ -9,6 +10,7 @@
|
||||
|
||||
#include "smp.h"
|
||||
#include "mmu.h"
|
||||
#include "acpi.h"
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
@@ -16,8 +18,8 @@
|
||||
#include <safemode.h>
|
||||
#include <boot/stage2.h>
|
||||
#include <boot/menu.h>
|
||||
#include <arch/x86/smp_acpi.h>
|
||||
#include <arch/x86/smp_apic.h>
|
||||
#include <arch/x86/arch_acpi.h>
|
||||
#include <arch/x86/arch_apic.h>
|
||||
#include <arch/x86/arch_system_info.h>
|
||||
|
||||
#include <string.h>
|
||||
@@ -36,24 +38,12 @@ struct gdt_idt_descr {
|
||||
uint32 *b;
|
||||
} _PACKED;
|
||||
|
||||
struct smp_scan_spots_struct {
|
||||
uint32 start;
|
||||
uint32 stop;
|
||||
uint32 length;
|
||||
};
|
||||
|
||||
static struct smp_scan_spots_struct smp_scan_spots[] = {
|
||||
static struct scan_spots_struct smp_scan_spots[] = {
|
||||
{ 0x9fc00, 0xa0000, 0xa0000 - 0x9fc00 },
|
||||
{ 0xf0000, 0x100000, 0x100000 - 0xf0000 },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
static struct smp_scan_spots_struct acpi_scan_spots[] = {
|
||||
{ 0x0, 0x400, 0x400 - 0x0 },
|
||||
{ 0xe0000, 0x100000, 0x100000 - 0xe0000 },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
extern "C" void execute_n_instructions(int count);
|
||||
|
||||
extern "C" void smp_trampoline(void);
|
||||
@@ -103,21 +93,6 @@ smp_mp_probe(uint32 base, uint32 limit)
|
||||
}
|
||||
|
||||
|
||||
static acpi_rsdp *
|
||||
smp_acpi_probe(uint32 base, uint32 limit)
|
||||
{
|
||||
TRACE(("smp_acpi_probe: entry base 0x%lx, limit 0x%lx\n", base, limit));
|
||||
for (char *pointer = (char *)base; (uint32)pointer < limit; pointer += 16) {
|
||||
if (strncmp(pointer, ACPI_RSDP_SIGNATURE, 8) == 0) {
|
||||
TRACE(("smp_acpi_probe: found ACPI RSDP signature at %p\n", pointer));
|
||||
return (acpi_rsdp *)pointer;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
smp_do_mp_config(mp_floating_struct *floatingStruct)
|
||||
{
|
||||
@@ -241,85 +216,59 @@ smp_do_mp_config(mp_floating_struct *floatingStruct)
|
||||
|
||||
|
||||
static status_t
|
||||
smp_do_acpi_config(acpi_rsdp *rsdp)
|
||||
smp_do_acpi_config(void)
|
||||
{
|
||||
TRACE(("smp: using ACPI to detect MP configuration\n"));
|
||||
TRACE(("smp: found rsdp at %p oem id: %.6s\n", rsdp, rsdp->oem_id));
|
||||
TRACE(("smp: rsdp points to rsdt at 0x%lx\n", rsdp->rsdt_address));
|
||||
|
||||
// reset CPU count
|
||||
gKernelArgs.num_cpus = 0;
|
||||
|
||||
// map and validate the root system description table
|
||||
acpi_descriptor_header *rsdt
|
||||
= (acpi_descriptor_header *)mmu_map_physical_memory(
|
||||
rsdp->rsdt_address, B_PAGE_SIZE, kDefaultPageFlags);
|
||||
if (!rsdt || strncmp(rsdt->signature, ACPI_RSDT_SIGNATURE, 4) != 0) {
|
||||
TRACE(("smp: invalid root system description table\n"));
|
||||
acpi_madt *madt = (acpi_madt *)acpi_find_table(ACPI_MADT_SIGNATURE);
|
||||
|
||||
if (madt == NULL) {
|
||||
TRACE(("smp: Failed to find MADT!\n"));
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
int32 numEntries = (rsdt->length - sizeof(acpi_descriptor_header)) / 4;
|
||||
if (numEntries <= 0) {
|
||||
TRACE(("smp: root system description table is empty\n"));
|
||||
return B_ERROR;
|
||||
}
|
||||
gKernelArgs.arch_args.apic_phys = madt->local_apic_address;
|
||||
TRACE(("smp: local apic address is 0x%lx\n", madt->local_apic_address));
|
||||
|
||||
TRACE(("smp: searching %ld entries for APIC information\n", numEntries));
|
||||
uint32 *pointer = (uint32 *)((uint8 *)rsdt + sizeof(acpi_descriptor_header));
|
||||
for (int32 j = 0; j < numEntries; j++, pointer++) {
|
||||
acpi_descriptor_header *header = (acpi_descriptor_header *)
|
||||
mmu_map_physical_memory(*pointer, B_PAGE_SIZE, kDefaultPageFlags);
|
||||
if (!header || strncmp(header->signature, ACPI_MADT_SIGNATURE, 4) != 0) {
|
||||
// not interesting for us
|
||||
TRACE(("smp: skipping uninteresting header '%.4s'\n", header->signature));
|
||||
continue;
|
||||
}
|
||||
|
||||
acpi_madt *madt = (acpi_madt *)header;
|
||||
gKernelArgs.arch_args.apic_phys = madt->local_apic_address;
|
||||
TRACE(("smp: local apic address is 0x%lx\n", madt->local_apic_address));
|
||||
|
||||
acpi_apic *apic = (acpi_apic *)((uint8 *)madt + sizeof(acpi_madt));
|
||||
acpi_apic *end = (acpi_apic *)((uint8 *)madt + header->length);
|
||||
while (apic < end) {
|
||||
switch (apic->type) {
|
||||
case ACPI_MADT_LOCAL_APIC:
|
||||
{
|
||||
if (gKernelArgs.num_cpus == MAX_BOOT_CPUS) {
|
||||
TRACE(("smp: already reached maximum boot CPUs (%d)\n", MAX_BOOT_CPUS));
|
||||
break;
|
||||
}
|
||||
|
||||
acpi_local_apic *localApic = (acpi_local_apic *)apic;
|
||||
TRACE(("smp: found local APIC with id %u\n", localApic->apic_id));
|
||||
if ((localApic->flags & ACPI_LOCAL_APIC_ENABLED) == 0) {
|
||||
TRACE(("smp: APIC is disabled and will not be used\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
gKernelArgs.arch_args.cpu_apic_id[gKernelArgs.num_cpus] = localApic->apic_id;
|
||||
gKernelArgs.arch_args.cpu_os_id[localApic->apic_id] = gKernelArgs.num_cpus;
|
||||
// ToDo: how to find out? putting 0x10 in to indicate a local apic
|
||||
gKernelArgs.arch_args.cpu_apic_version[gKernelArgs.num_cpus] = 0x10;
|
||||
gKernelArgs.num_cpus++;
|
||||
acpi_apic *apic = (acpi_apic *)((uint8 *)madt + sizeof(acpi_madt));
|
||||
acpi_apic *end = (acpi_apic *)((uint8 *)madt + madt->header.length);
|
||||
while (apic < end) {
|
||||
switch (apic->type) {
|
||||
case ACPI_MADT_LOCAL_APIC:
|
||||
{
|
||||
if (gKernelArgs.num_cpus == MAX_BOOT_CPUS) {
|
||||
TRACE(("smp: already reached maximum boot CPUs (%d)\n", MAX_BOOT_CPUS));
|
||||
break;
|
||||
}
|
||||
|
||||
case ACPI_MADT_IO_APIC: {
|
||||
acpi_io_apic *ioApic = (acpi_io_apic *)apic;
|
||||
TRACE(("smp: found io APIC with id %u and address 0x%lx\n",
|
||||
ioApic->io_apic_id, ioApic->io_apic_address));
|
||||
gKernelArgs.arch_args.ioapic_phys = ioApic->io_apic_address;
|
||||
acpi_local_apic *localApic = (acpi_local_apic *)apic;
|
||||
TRACE(("smp: found local APIC with id %u\n", localApic->apic_id));
|
||||
if ((localApic->flags & ACPI_LOCAL_APIC_ENABLED) == 0) {
|
||||
TRACE(("smp: APIC is disabled and will not be used\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
gKernelArgs.arch_args.cpu_apic_id[gKernelArgs.num_cpus] = localApic->apic_id;
|
||||
gKernelArgs.arch_args.cpu_os_id[localApic->apic_id] = gKernelArgs.num_cpus;
|
||||
// ToDo: how to find out? putting 0x10 in to indicate a local apic
|
||||
gKernelArgs.arch_args.cpu_apic_version[gKernelArgs.num_cpus] = 0x10;
|
||||
gKernelArgs.num_cpus++;
|
||||
break;
|
||||
}
|
||||
|
||||
apic = (acpi_apic *)((uint8 *)apic + apic->length);
|
||||
case ACPI_MADT_IO_APIC: {
|
||||
acpi_io_apic *ioApic = (acpi_io_apic *)apic;
|
||||
TRACE(("smp: found io APIC with id %u and address 0x%lx\n",
|
||||
ioApic->io_apic_id, ioApic->io_apic_address));
|
||||
gKernelArgs.arch_args.ioapic_phys = ioApic->io_apic_address;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gKernelArgs.num_cpus > 0)
|
||||
break;
|
||||
apic = (acpi_apic *)((uint8 *)apic + apic->length);
|
||||
}
|
||||
|
||||
return gKernelArgs.num_cpus > 0 ? B_OK : B_ERROR;
|
||||
@@ -609,12 +558,8 @@ smp_init(void)
|
||||
// first try to find ACPI tables to get MP configuration as it handles
|
||||
// physical as well as logical MP configurations as in multiple cpus,
|
||||
// multiple cores or hyper threading.
|
||||
for (int32 i = 0; acpi_scan_spots[i].length > 0; i++) {
|
||||
acpi_rsdp *rsdp = smp_acpi_probe(smp_scan_spots[i].start,
|
||||
smp_scan_spots[i].stop);
|
||||
if (rsdp != NULL && smp_do_acpi_config(rsdp) == B_OK)
|
||||
return;
|
||||
}
|
||||
if (smp_do_acpi_config() == B_OK)
|
||||
return;
|
||||
|
||||
// then try to find MPS tables and do configuration based on them
|
||||
for (int32 i = 0; smp_scan_spots[i].length > 0; i++) {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "cpu.h"
|
||||
#include "mmu.h"
|
||||
#include "smp.h"
|
||||
#include "acpi.h"
|
||||
#include "keyboard.h"
|
||||
#include "bios.h"
|
||||
|
||||
@@ -132,6 +133,7 @@ _start(void)
|
||||
serial_enable();
|
||||
|
||||
apm_init();
|
||||
acpi_init();
|
||||
smp_init();
|
||||
main(&args);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <arch/user_debugger.h>
|
||||
#include <arch/vm.h>
|
||||
|
||||
#include <arch/x86/smp_apic.h>
|
||||
#include <arch/x86/arch_apic.h>
|
||||
#include <arch/x86/descriptors.h>
|
||||
#include <arch/x86/vm86.h>
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <timer.h>
|
||||
|
||||
#include <arch/x86/smp_priv.h>
|
||||
#include <arch/x86/smp_apic.h>
|
||||
#include <arch/x86/arch_apic.h>
|
||||
#include <arch/x86/timer.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <arch/x86/timer.h>
|
||||
|
||||
#include <int.h>
|
||||
#include <arch/x86/smp_apic.h>
|
||||
#include <arch/x86/arch_apic.h>
|
||||
|
||||
#include <arch/cpu.h>
|
||||
#include <arch/smp.h>
|
||||
|
||||
Reference in New Issue
Block a user