Some cleanup: renamed the mp_ext_* structures to mp_base_* as they are
part of the base table, not the extended table. Renamed some structure fields, variables to be clearer and nicer to read. Removed some unused stuff. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14502 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
41ab7dff11
commit
fde12d6407
@ -108,39 +108,33 @@
|
||||
#define MP_EXT_IO_INT 3
|
||||
#define MP_EXT_LOCAL_INT 4
|
||||
|
||||
#define MP_EXT_PE_LEN 20
|
||||
#define MP_EXT_BUS_LEN 8
|
||||
#define MP_EXT_IO_APIC_LEN 8
|
||||
#define MP_EXT_IO_INT_LEN 8
|
||||
#define MP_EXT_LOCAL_INT_LEN 8
|
||||
|
||||
struct mp_config_table {
|
||||
uint32 signature; /* "PCMP" */
|
||||
uint16 table_len; /* length of this structure */
|
||||
uint8 mp_rev; /* spec supported, 1 for 1.1 or 4 for 1.4 */
|
||||
uint16 base_table_length; /* length of the base table entries and this structure */
|
||||
uint8 spec_revision; /* spec supported, 1 for 1.1 or 4 for 1.4 */
|
||||
uint8 checksum; /* checksum, all bytes add up to zero */
|
||||
char oem[8]; /* oem identification, not null-terminated */
|
||||
char product[12]; /* product name, not null-terminated */
|
||||
void *oem_table_ptr; /* addr of oem-defined table, zero if none */
|
||||
uint16 oem_len; /* length of oem table */
|
||||
uint16 num_entries; /* number of entries in base table */
|
||||
void *oem_table; /* addr of oem-defined table, zero if none */
|
||||
uint16 oem_length; /* length of oem table */
|
||||
uint16 num_base_entries; /* number of entries in base table */
|
||||
uint32 apic; /* address of apic */
|
||||
uint16 ext_len; /* length of extended section */
|
||||
uint16 ext_length; /* length of extended section */
|
||||
uint8 ext_checksum; /* checksum of extended table entries */
|
||||
};
|
||||
|
||||
struct mp_flt_struct {
|
||||
struct mp_floating_struct {
|
||||
uint32 signature; /* "_MP_" */
|
||||
struct mp_config_table *mpc; /* address of mp configuration table */
|
||||
uint8 mpc_len; /* length of this structure in 16-byte units */
|
||||
uint8 mp_rev; /* spec supported, 1 for 1.1 or 4 for 1.4 */
|
||||
struct mp_config_table *config_table; /* address of mp configuration table */
|
||||
uint8 config_length; /* length of the table in 16-byte units */
|
||||
uint8 spec_revision; /* spec supported, 1 for 1.1 or 4 for 1.4 */
|
||||
uint8 checksum; /* checksum, all bytes add up to zero */
|
||||
uint8 mp_feature_1; /* mp system configuration type if no mpc */
|
||||
uint8 mp_feature_2; /* imcrp */
|
||||
uint8 mp_feature_3, mp_feature_4, mp_feature_5; /* reserved */
|
||||
};
|
||||
|
||||
struct mp_ext_pe {
|
||||
struct mp_base_processor {
|
||||
uint8 type;
|
||||
uint8 apic_id;
|
||||
uint8 apic_version;
|
||||
@ -150,7 +144,7 @@ struct mp_ext_pe {
|
||||
uint32 res1, res2;
|
||||
};
|
||||
|
||||
struct mp_ext_ioapic {
|
||||
struct mp_base_ioapic {
|
||||
uint8 type;
|
||||
uint8 ioapic_id;
|
||||
uint8 ioapic_version;
|
||||
@ -158,13 +152,13 @@ struct mp_ext_ioapic {
|
||||
uint32 *addr;
|
||||
};
|
||||
|
||||
struct mp_ext_bus {
|
||||
struct mp_base_bus {
|
||||
uint8 type;
|
||||
uint8 bus_id;
|
||||
char name[6];
|
||||
};
|
||||
|
||||
struct mp_ext_interrupt {
|
||||
struct mp_base_interrupt {
|
||||
uint8 type;
|
||||
uint8 interrupt_type;
|
||||
uint16 polarity : 2;
|
||||
@ -176,4 +170,11 @@ struct mp_ext_interrupt {
|
||||
uint8 dest_apic_int;
|
||||
};
|
||||
|
||||
enum {
|
||||
MP_INT_TYPE_INT = 0,
|
||||
MP_INT_TYPE_NMI,
|
||||
MP_INT_TYPE_SMI,
|
||||
MP_INT_TYPE_ExtINT,
|
||||
};
|
||||
|
||||
#endif /* _KERNEL_ARCH_x86_SMP_APIC_H */
|
||||
|
@ -33,6 +33,18 @@ 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[] = {
|
||||
{ 0x9fc00, 0xa0000, 0xa0000 - 0x9fc00 },
|
||||
{ 0xf0000, 0x100000, 0x100000 - 0xf0000 },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
extern void execute_n_instructions(int count);
|
||||
|
||||
@ -40,9 +52,7 @@ extern void smp_trampoline(void);
|
||||
extern void smp_trampoline_end(void);
|
||||
|
||||
|
||||
static uint32 mp_mem_phys = 0;
|
||||
static uint32 mp_mem_virt = 0;
|
||||
static struct mp_flt_struct *mp_flt_ptr = NULL;
|
||||
static struct mp_floating_struct *sFloatingStruct = NULL;
|
||||
|
||||
static int smp_get_current_cpu(void);
|
||||
|
||||
@ -61,20 +71,6 @@ apic_write(uint32 offset, uint32 data)
|
||||
*addr = data;
|
||||
}
|
||||
|
||||
/*
|
||||
static void *
|
||||
mp_virt_to_phys(void *ptr)
|
||||
{
|
||||
return ((void *)(((unsigned int)ptr - mp_mem_virt) + mp_mem_phys));
|
||||
}
|
||||
*/
|
||||
|
||||
static void *
|
||||
mp_phys_to_virt(void *ptr)
|
||||
{
|
||||
return ((void *)(((uint32)ptr - mp_mem_phys) + mp_mem_virt));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
smp_get_current_cpu(void)
|
||||
@ -106,9 +102,9 @@ smp_probe(uint32 base, uint32 limit)
|
||||
static void
|
||||
smp_do_config(void)
|
||||
{
|
||||
struct mp_config_table *config;
|
||||
char *ptr;
|
||||
int i;
|
||||
struct mp_config_table *mpc;
|
||||
#ifdef TRACE_SMP
|
||||
const char *cpu_family[] = { "", "", "", "", "Intel 486",
|
||||
"Intel Pentium", "Intel Pentium Pro", "Intel Pentium II" };
|
||||
@ -121,86 +117,83 @@ smp_do_config(void)
|
||||
*/
|
||||
gKernelArgs.num_cpus = 0;
|
||||
|
||||
mpc = mp_phys_to_virt(mp_flt_ptr->mpc);
|
||||
config = sFloatingStruct->config_table;
|
||||
|
||||
/* print out our new found configuration. */
|
||||
ptr = (char *) &(mpc->oem[0]);
|
||||
|
||||
ptr = (char *)&(config->oem[0]);
|
||||
TRACE(("smp: oem id: %c%c%c%c%c%c%c%c product id: "
|
||||
"%c%c%c%c%c%c%c%c%c%c%c%c\n", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4],
|
||||
ptr[5], ptr[6], ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12],
|
||||
ptr[13], ptr[14], ptr[15], ptr[16], ptr[17], ptr[18], ptr[19]));
|
||||
TRACE(("smp: base table has %d entries, extended section %d bytes\n",
|
||||
mpc->num_entries, mpc->ext_len));
|
||||
config->num_base_entries, config->ext_length));
|
||||
|
||||
gKernelArgs.arch_args.apic_phys = (uint32)mpc->apic;
|
||||
gKernelArgs.arch_args.apic_phys = (uint32)config->apic;
|
||||
|
||||
ptr = (char *)((uint32)mpc + sizeof(struct mp_config_table));
|
||||
for (i = 0; i < mpc->num_entries; i++) {
|
||||
ptr = (char *)((uint32)config + sizeof(struct mp_config_table));
|
||||
for (i = 0; i < config->num_base_entries; i++) {
|
||||
switch (*ptr) {
|
||||
case MP_EXT_PE:
|
||||
{
|
||||
struct mp_ext_pe *pe = (struct mp_ext_pe *)ptr;
|
||||
struct mp_base_processor *processor = (struct mp_base_processor *)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;
|
||||
gKernelArgs.arch_args.cpu_apic_id[gKernelArgs.num_cpus] = processor->apic_id;
|
||||
gKernelArgs.arch_args.cpu_os_id[processor->apic_id] = gKernelArgs.num_cpus;
|
||||
gKernelArgs.arch_args.cpu_apic_version[gKernelArgs.num_cpus] = processor->apic_version;
|
||||
|
||||
TRACE(("smp: cpu#%ld: %s, apic id %d, version %d%s\n",
|
||||
gKernelArgs.num_cpus, cpu_family[(pe->signature & 0xf00) >> 8],
|
||||
pe->apic_id, pe->apic_version, (pe->cpu_flags & 0x2) ?
|
||||
gKernelArgs.num_cpus, cpu_family[(processor->signature & 0xf00) >> 8],
|
||||
processor->apic_id, processor->apic_version, (processor->cpu_flags & 0x2) ?
|
||||
", BSP" : ""));
|
||||
|
||||
gKernelArgs.num_cpus++;
|
||||
ptr += sizeof(struct mp_ext_pe);
|
||||
ptr += sizeof(struct mp_base_processor);
|
||||
break;
|
||||
}
|
||||
case MP_EXT_BUS:
|
||||
{
|
||||
struct mp_ext_bus *bus = (struct mp_ext_bus *)ptr;
|
||||
struct mp_base_bus *bus = (struct mp_base_bus *)ptr;
|
||||
|
||||
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 += sizeof(struct mp_ext_bus);
|
||||
ptr += sizeof(struct mp_base_bus);
|
||||
break;
|
||||
}
|
||||
case MP_EXT_IO_APIC:
|
||||
{
|
||||
struct mp_ext_ioapic *io = (struct mp_ext_ioapic *) ptr;
|
||||
struct mp_base_ioapic *io = (struct mp_base_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 += sizeof(struct mp_ext_ioapic);
|
||||
ptr += sizeof(struct mp_base_ioapic);
|
||||
break;
|
||||
}
|
||||
case MP_EXT_IO_INT:
|
||||
{
|
||||
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:
|
||||
{
|
||||
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);
|
||||
struct mp_base_interrupt *interrupt = (struct mp_base_interrupt *)ptr;
|
||||
|
||||
dprintf("smp: %s int: type %d, source bus %d, irq %d, dest apic %d, int %d, polarity %d, trigger mode %d\n",
|
||||
interrupt->type == MP_EXT_IO_INT ? "I/O" : "local",
|
||||
interrupt->interrupt_type, 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_base_interrupt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dprintf("smp: apic @ %p, i/o apic @ %p, total %ld processors detected\n",
|
||||
(void *)gKernelArgs.arch_args.apic_phys, (void *)gKernelArgs.arch_args.ioapic_phys, gKernelArgs.num_cpus);
|
||||
(void *)gKernelArgs.arch_args.apic_phys,
|
||||
(void *)gKernelArgs.arch_args.ioapic_phys,
|
||||
gKernelArgs.num_cpus);
|
||||
|
||||
// this BIOS looks broken, because it didn't report any cpus (VMWare)
|
||||
if (gKernelArgs.num_cpus == 0)
|
||||
@ -208,19 +201,6 @@ smp_do_config(void)
|
||||
}
|
||||
|
||||
|
||||
struct smp_scan_spots_struct {
|
||||
uint32 start;
|
||||
uint32 stop;
|
||||
uint32 len;
|
||||
};
|
||||
|
||||
static struct smp_scan_spots_struct smp_scan_spots[] = {
|
||||
{ 0x9fc00, 0xa0000, 0xa0000 - 0x9fc00 },
|
||||
{ 0xf0000, 0x100000, 0x100000 - 0xf0000 },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
smp_find_mp_config(void)
|
||||
{
|
||||
@ -232,30 +212,29 @@ smp_find_mp_config(void)
|
||||
#endif
|
||||
|
||||
// XXX for now, assume the memory is identity mapped by the 1st stage
|
||||
for (i = 0; smp_scan_spots[i].len > 0; i++) {
|
||||
mp_flt_ptr = (struct mp_flt_struct *)smp_probe(smp_scan_spots[i].start,
|
||||
for (i = 0; smp_scan_spots[i].length > 0; i++) {
|
||||
sFloatingStruct = (struct mp_floating_struct *)smp_probe(smp_scan_spots[i].start,
|
||||
smp_scan_spots[i].stop);
|
||||
if (mp_flt_ptr != NULL)
|
||||
if (sFloatingStruct != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
if (mp_flt_ptr != NULL) {
|
||||
mp_mem_phys = smp_scan_spots[i].start;
|
||||
mp_mem_virt = smp_scan_spots[i].start;
|
||||
if (sFloatingStruct != NULL) {
|
||||
TRACE(("smp_boot: intel mp version %s, %s",
|
||||
(sFloatingStruct->spec_revision == 1) ? "1.1" : "1.4",
|
||||
(sFloatingStruct->mp_feature_2 & 0x80)
|
||||
? "imcr and pic compatibility mode.\n"
|
||||
: "virtual wire compatibility mode.\n"));
|
||||
|
||||
TRACE(("smp_boot: intel mp version %s, %s", (mp_flt_ptr->mp_rev == 1) ? "1.1" :
|
||||
"1.4", (mp_flt_ptr->mp_feature_2 & 0x80) ?
|
||||
"imcr and pic compatibility mode.\n" : "virtual wire compatibility mode.\n"));
|
||||
|
||||
if (mp_flt_ptr->mpc == 0) {
|
||||
if (sFloatingStruct->config_table == NULL) {
|
||||
// XXX need to implement
|
||||
#if 1
|
||||
gKernelArgs.num_cpus = 1;
|
||||
return 1;
|
||||
#else
|
||||
/* this system conforms to one of the default configurations */
|
||||
// mp_num_def_config = mp_flt_ptr->mp_feature_1;
|
||||
TRACE(("smp: standard configuration %d\n", mp_flt_ptr->mp_feature_1));
|
||||
// mp_num_def_config = sFloatingStruct->mp_feature_1;
|
||||
TRACE(("smp: standard configuration %d\n", sFloatingStruct->mp_feature_1));
|
||||
/* num_cpus = 2;
|
||||
gKernelArgs.cpu_apic_id[0] = 0;
|
||||
gKernelArgs.cpu_apic_id[1] = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user