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:
parent
7a09488d8e
commit
0c67510ae1
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user