Enabled SMP detection again - since it's very likely that it doesn't work on

your system, I've also added a "Disable SMP" safemode option. The NO_SMP
define is still there, and will be removed once SMP works flawlessly.
Prints out infos about the interrupt entries in the MP config.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14499 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2005-10-24 19:43:50 +00:00
parent 7a09488d8e
commit 0c67510ae1
4 changed files with 71 additions and 25 deletions

View File

@ -1,7 +1,10 @@
/*
** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
/*
* 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
@ -161,4 +164,16 @@ struct mp_ext_bus {
char name[6];
};
struct mp_ext_interrupt {
uint8 type;
uint8 interrupt_type;
uint16 polarity : 2;
uint16 trigger_mode : 2;
uint16 _reserved : 12;
uint8 source_bus_id;
uint8 source_bus_irq;
uint8 dest_apic_id;
uint8 dest_apic_int;
};
#endif /* _KERNEL_ARCH_x86_SMP_APIC_H */

View File

@ -1,5 +1,5 @@
/*
* Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_SAFEMODE_H
@ -14,6 +14,7 @@
#define B_SAFEMODE_DISABLE_USER_ADD_ONS "disableuseraddons"
#define B_SAFEMODE_DISABLE_IDE_DMA "disableidedma"
#define B_SAFEMODE_DISABLE_SMP "disablesmp"
#ifdef __cplusplus

View File

@ -11,6 +11,7 @@
#include <boot/platform.h>
#include <boot/menu.h>
#include <safemode.h>
#include <string.h>
@ -463,6 +464,9 @@ platform_add_menus(Menu *menu)
item->SetTarget(video_mode_hook);
break;
case SAFE_MODE_MENU:
menu->AddItem(item = new MenuItem("Disable SMP"));
item->SetData(B_SAFEMODE_DISABLE_SMP);
item->SetType(MENU_ITEM_MARKABLE);
menu->AddItem(item = new MenuItem("Don't call the BIOS"));
item->SetType(MENU_ITEM_MARKABLE);
break;

View File

@ -14,12 +14,12 @@
#include <boot/stage2.h>
#include <arch/x86/smp_apic.h>
#include <safemode.h>
#include <kernel.h>
#include <string.h>
// ToDo: SMP is temporarily disabled!
#define NO_SMP 1
#define NO_SMP 0
#define TRACE_SMP
#ifdef TRACE_SMP
@ -109,9 +109,6 @@ smp_do_config(void)
char *ptr;
int i;
struct mp_config_table *mpc;
struct mp_ext_pe *pe;
struct mp_ext_ioapic *io;
struct mp_ext_bus *bus;
#ifdef TRACE_SMP
const char *cpu_family[] = { "", "", "", "", "Intel 486",
"Intel Pentium", "Intel Pentium Pro", "Intel Pentium II" };
@ -142,7 +139,9 @@ smp_do_config(void)
for (i = 0; i < mpc->num_entries; i++) {
switch (*ptr) {
case MP_EXT_PE:
pe = (struct mp_ext_pe *) ptr;
{
struct mp_ext_pe *pe = (struct mp_ext_pe *)ptr;
gKernelArgs.arch_args.cpu_apic_id[gKernelArgs.num_cpus] = pe->apic_id;
gKernelArgs.arch_args.cpu_os_id[pe->apic_id] = gKernelArgs.num_cpus;
gKernelArgs.arch_args.cpu_apic_version[gKernelArgs.num_cpus] = pe->apic_version;
@ -152,33 +151,52 @@ smp_do_config(void)
pe->apic_id, pe->apic_version, (pe->cpu_flags & 0x2) ?
", BSP" : ""));
ptr += 20;
gKernelArgs.num_cpus++;
ptr += sizeof(struct mp_ext_pe);
break;
}
case MP_EXT_BUS:
bus = (struct mp_ext_bus *)ptr;
{
struct mp_ext_bus *bus = (struct mp_ext_bus *)ptr;
TRACE(("smp: bus%d: %c%c%c%c%c%c\n", bus->bus_id,
TRACE(("smp: bus %d: %c%c%c%c%c%c\n", bus->bus_id,
bus->name[0], bus->name[1], bus->name[2], bus->name[3],
bus->name[4], bus->name[5]));
ptr += 8;
ptr += sizeof(struct mp_ext_bus);
break;
}
case MP_EXT_IO_APIC:
io = (struct mp_ext_ioapic *) ptr;
{
struct mp_ext_ioapic *io = (struct mp_ext_ioapic *) ptr;
gKernelArgs.arch_args.ioapic_phys = (uint32)io->addr;
TRACE(("smp: found io apic with apic id %d, version %d\n",
io->ioapic_id, io->ioapic_version));
ptr += 8;
ptr += sizeof(struct mp_ext_ioapic);
break;
}
case MP_EXT_IO_INT:
ptr += 8;
{
struct mp_ext_interrupt *interrupt = (struct mp_ext_interrupt *)ptr;
dprintf("smp: I/O int: source bus %d, irq %d, dest apic %d, int %d, polarity %d, trigger mode %d\n",
interrupt->source_bus_id, interrupt->source_bus_irq,
interrupt->dest_apic_id, interrupt->dest_apic_int,
interrupt->polarity, interrupt->trigger_mode);
ptr += sizeof(struct mp_ext_interrupt);
break;
}
case MP_EXT_LOCAL_INT:
ptr += 8;
{
struct mp_ext_interrupt *interrupt = (struct mp_ext_interrupt *)ptr;
dprintf("smp: local int: source bus %d, irq %d, dest apic %d, int %d, polarity %d, trigger mode %d\n",
interrupt->source_bus_id, interrupt->source_bus_irq,
interrupt->dest_apic_id, interrupt->dest_apic_int,
interrupt->polarity, interrupt->trigger_mode);
ptr += sizeof(struct mp_ext_interrupt);
break;
}
}
}
dprintf("smp: apic @ %p, i/o apic @ %p, total %ld processors detected\n",
@ -296,7 +314,7 @@ smp_cpu_ready(void)
"pushl $0x0;" // dummy retval for call to main
"pushl %2; " // this is the start address
"ret; " // jump.
: : "r" (curr_cpu), "m" (&gKernelArgs), "g" (gKernelArgs.kernel_image.elf_header.e_entry));
: : "g" (curr_cpu), "g" (&gKernelArgs), "g" (gKernelArgs.kernel_image.elf_header.e_entry));
// no where to return to
return 0;
@ -344,18 +362,26 @@ smp_boot_other_cpus(void)
uint32 trampolineStack;
uint32 i;
void *handle = load_driver_settings(B_SAFEMODE_DRIVER_SETTINGS);
if (handle != NULL) {
if (get_driver_boolean_parameter(handle, B_SAFEMODE_DISABLE_SMP, false, false)) {
// SMP has been disabled!
gKernelArgs.num_cpus = 1;
}
unload_driver_settings(handle);
}
if (gKernelArgs.num_cpus < 2)
return;
TRACE(("trampolining other cpus\n"));
// XXX assume low 1 meg is identity mapped by the 1st stage bootloader
// and nothing important is in 0x9e000 & 0x9f000
// The first 8 MB are identity mapped, 0x9e000-0x9ffff is reserved for this
// allocate a stack and a code area for the smp trampoline
// (these have to be < 1M physical)
trampolineCode = 0x9f000; // 640kB - 4096 == 0x9f000
trampolineStack = 0x9e000; // 640kB - 8192 == 0x9e000
// (these have to be < 1M physical, 0xa0000-0xfffff is reserved by the BIOS)
trampolineCode = 0x9f000;
trampolineStack = 0x9e000;
// copy the trampoline code over
memcpy((char *)trampolineCode, &smp_trampoline,