summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/x86/boot/mpspec.c112
-rw-r--r--src/arch/x86/include/arch/smp/mpspec.h180
2 files changed, 175 insertions, 117 deletions
diff --git a/src/arch/x86/boot/mpspec.c b/src/arch/x86/boot/mpspec.c
index cd2b142a25..d079d083b9 100644
--- a/src/arch/x86/boot/mpspec.c
+++ b/src/arch/x86/boot/mpspec.c
@@ -73,7 +73,7 @@ static unsigned char smp_compute_checksum(void *v, int len)
return checksum;
}
-static void *smp_write_floating_table_physaddr(unsigned long addr, unsigned long mpf_physptr, unsigned int virtualwire)
+static void *smp_write_floating_table_physaddr(u32 addr, u32 mpf_physptr, unsigned int virtualwire)
{
struct intel_mp_floating *mf;
void *v;
@@ -108,9 +108,10 @@ void *smp_next_mpc_entry(struct mp_config_table *mc)
{
void *v;
v = (void *)(((char *)mc) + mc->mpc_length);
+
return v;
}
-static void smp_add_mpc_entry(struct mp_config_table *mc, unsigned length)
+static void smp_add_mpc_entry(struct mp_config_table *mc, u16 length)
{
mc->mpc_length += length;
mc->mpc_entry_count++;
@@ -120,6 +121,7 @@ void *smp_next_mpe_entry(struct mp_config_table *mc)
{
void *v;
v = (void *)(((char *)mc) + mc->mpc_length + mc->mpe_length);
+
return v;
}
static void smp_add_mpe_entry(struct mp_config_table *mc, mpe_t mpe)
@@ -127,10 +129,14 @@ static void smp_add_mpe_entry(struct mp_config_table *mc, mpe_t mpe)
mc->mpe_length += mpe->mpe_length;
}
+/*
+ * Type 0: Processor Entries:
+ * Entry Type, LAPIC ID, LAPIC Version, CPU Flags EN/BP,
+ * CPU Signature (Stepping, Model, Family), Feature Flags
+ */
void smp_write_processor(struct mp_config_table *mc,
- unsigned char apicid, unsigned char apicver,
- unsigned char cpuflag, unsigned int cpufeature,
- unsigned int featureflag)
+ u8 apicid, u8 apicver, u8 cpuflag,
+ u32 cpufeature, u32 featureflag)
{
struct mpc_config_processor *mpc;
mpc = smp_next_mpc_entry(mc);
@@ -144,7 +150,8 @@ void smp_write_processor(struct mp_config_table *mc,
smp_add_mpc_entry(mc, sizeof(*mpc));
}
-/* If we assume a symmetric processor configuration we can
+/*
+ * If we assume a symmetric processor configuration we can
* get all of the information we need to write the processor
* entry from the bootstrap processor.
* Plus I don't think linux really even cares.
@@ -183,8 +190,9 @@ void smp_write_processors(struct mp_config_table *mc)
cpu_flag = MPC_CPU_ENABLED | MPC_CPU_BOOTPROCESSOR;
if(cpu->path.apic.apic_id == order_id) {
- smp_write_processor(mc, cpu->path.apic.apic_id, apic_version,
- cpu_flag, cpu_features, cpu_feature_flags
+ smp_write_processor(mc,
+ cpu->path.apic.apic_id, apic_version,
+ cpu_flag, cpu_features, cpu_feature_flags
);
break;
}
@@ -192,8 +200,12 @@ void smp_write_processors(struct mp_config_table *mc)
}
}
+/*
+ * Type 1: Bus Entries:
+ * Entry Type, Bus ID, Bus Type
+ */
static void smp_write_bus(struct mp_config_table *mc,
- unsigned char id, const char *bustype)
+ u8 id, const char *bustype)
{
struct mpc_config_bus *mpc;
mpc = smp_next_mpc_entry(mc);
@@ -204,9 +216,13 @@ static void smp_write_bus(struct mp_config_table *mc,
smp_add_mpc_entry(mc, sizeof(*mpc));
}
+/*
+ * Type 2: I/O APIC Entries:
+ * Entry Type, APIC ID, Version,
+ * APIC Flags:EN, Address
+ */
void smp_write_ioapic(struct mp_config_table *mc,
- unsigned char id, unsigned char ver,
- unsigned long apicaddr)
+ u8 id, u8 ver, u32 apicaddr)
{
struct mpc_config_ioapic *mpc;
mpc = smp_next_mpc_entry(mc);
@@ -219,10 +235,15 @@ void smp_write_ioapic(struct mp_config_table *mc,
smp_add_mpc_entry(mc, sizeof(*mpc));
}
+/*
+ * Type 3: I/O Interrupt Table Entries:
+ * Entry Type, Int Type, Int Polarity, Int Level,
+ * Source Bus ID, Source Bus IRQ, Dest APIC ID, Dest PIN#
+ */
void smp_write_intsrc(struct mp_config_table *mc,
- unsigned char irqtype, unsigned short irqflag,
- unsigned char srcbus, unsigned char srcbusirq,
- unsigned char dstapic, unsigned char dstirq)
+ u8 irqtype, u16 irqflag,
+ u8 srcbus, u8 srcbusirq,
+ u8 dstapic, u8 dstirq)
{
struct mpc_config_intsrc *mpc;
mpc = smp_next_mpc_entry(mc);
@@ -242,9 +263,27 @@ void smp_write_intsrc(struct mp_config_table *mc,
#endif
}
+/*
+ * Type 3: I/O Interrupt Table Entries for PCI Devices:
+ * This has the same fields as 'Type 3: I/O Interrupt Table Entries'
+ * but the Source Bus IRQ field has a slightly different
+ * definition:
+ * Bits 1-0: PIRQ pin: INT_A# = 0, INT_B# = 1, INT_C# = 2, INT_D# = 3
+ * Bits 2-6: Originating PCI Device Number (Not its parent bridge device number)
+ * Bit 7: Reserved
+ */
+void smp_write_pci_intsrc(struct mp_config_table *mc,
+ u8 irqtype, u8 srcbus, u8 dev, u8 pirq,
+ u8 dstapic, u8 dstirq)
+{
+ u8 srcbusirq = (dev << 2) | pirq;
+ printk(BIOS_SPEW, "\tPCI srcbusirq = 0x%x from dev = 0x%x and pirq = %x\n", srcbusirq, dev, pirq);
+ smp_write_intsrc(mc, irqtype, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, srcbus,
+ srcbusirq, dstapic, dstirq);
+}
+
void smp_write_intsrc_pci_bridge(struct mp_config_table *mc,
- unsigned char irqtype, unsigned short irqflag,
- struct device *dev,
+ u8 irqtype, u16 irqflag, struct device *dev,
unsigned char dstapic, unsigned char *dstirq)
{
struct device *child;
@@ -293,10 +332,16 @@ next:
}
}
+/*
+ * Type 4: Local Interrupt Assignment Entries:
+ * Entry Type, Int Type, Int Polarity, Int Level,
+ * Source Bus ID, Source Bus IRQ, Dest LAPIC ID,
+ * Dest LAPIC LINTIN#
+ */
void smp_write_lintsrc(struct mp_config_table *mc,
- unsigned char irqtype, unsigned short irqflag,
- unsigned char srcbusid, unsigned char srcbusirq,
- unsigned char destapic, unsigned char destapiclint)
+ u8 irqtype, u16 irqflag,
+ u8 srcbusid, u8 srcbusirq,
+ u8 destapic, u8 destapiclint)
{
struct mpc_config_lintsrc *mpc;
mpc = smp_next_mpc_entry(mc);
@@ -311,10 +356,15 @@ void smp_write_lintsrc(struct mp_config_table *mc,
smp_add_mpc_entry(mc, sizeof(*mpc));
}
+/*
+ * Type 128: System Address Space Mapping Entries
+ * Entry Type, Entry Length, Bus ID, Address Type,
+ * Address Base Lo/Hi, Address Length Lo/Hi
+ */
void smp_write_address_space(struct mp_config_table *mc,
- unsigned char busid, unsigned char address_type,
- unsigned int address_base_low, unsigned int address_base_high,
- unsigned int address_length_low, unsigned int address_length_high)
+ u8 busid, u8 address_type,
+ u32 address_base_low, u32 address_base_high,
+ u32 address_length_low, u32 address_length_high)
{
struct mp_exten_system_address_space *mpe;
mpe = smp_next_mpe_entry(mc);
@@ -330,10 +380,13 @@ void smp_write_address_space(struct mp_config_table *mc,
smp_add_mpe_entry(mc, (mpe_t)mpe);
}
-
+/*
+ * Type 129: Bus Hierarchy Descriptor Entry
+ * Entry Type, Entry Length, Bus ID, Bus Info,
+ * Parent Bus ID
+ */
void smp_write_bus_hierarchy(struct mp_config_table *mc,
- unsigned char busid, unsigned char bus_info,
- unsigned char parent_busid)
+ u8 busid, u8 bus_info, u8 parent_busid)
{
struct mp_exten_bus_hierarchy *mpe;
mpe = smp_next_mpe_entry(mc);
@@ -346,9 +399,14 @@ void smp_write_bus_hierarchy(struct mp_config_table *mc,
smp_add_mpe_entry(mc, (mpe_t)mpe);
}
+/*
+ * Type 130: Compatibility Bus Address Space Modifier Entry
+ * Entry Type, Entry Length, Bus ID, Address Modifier
+ * Predefined Range List
+ */
void smp_write_compatibility_address_space(struct mp_config_table *mc,
- unsigned char busid, unsigned char address_modifier,
- unsigned int range_list)
+ u8 busid, u8 address_modifier,
+ u32 range_list)
{
struct mp_exten_compatibility_address_space *mpe;
mpe = smp_next_mpe_entry(mc);
diff --git a/src/arch/x86/include/arch/smp/mpspec.h b/src/arch/x86/include/arch/smp/mpspec.h
index 725718ac25..61709ff5e0 100644
--- a/src/arch/x86/include/arch/smp/mpspec.h
+++ b/src/arch/x86/include/arch/smp/mpspec.h
@@ -45,36 +45,36 @@
struct intel_mp_floating
{
- char mpf_signature[4]; /* "_MP_" */
- unsigned long mpf_physptr; /* Configuration table address */
- unsigned char mpf_length; /* Our length (paragraphs) */
- unsigned char mpf_specification;/* Specification version */
- unsigned char mpf_checksum; /* Checksum (makes sum 0) */
- unsigned char mpf_feature1; /* Standard or configuration ? */
- unsigned char mpf_feature2; /* Bit7 set for IMCR|PIC */
+ char mpf_signature[4]; /* "_MP_" */
+ u32 mpf_physptr; /* Configuration table address */
+ u8 mpf_length; /* Our length (paragraphs) */
+ u8 mpf_specification;/* Specification version */
+ u8 mpf_checksum; /* Checksum (makes sum 0) */
+ u8 mpf_feature1; /* Predefined or Unique configuration? */
+ u8 mpf_feature2; /* Bit7 set for IMCR/PIC */
#define MP_FEATURE_VIRTUALWIRE (0 << 7)
#define MP_FEATURE_PIC (1 << 7)
- unsigned char mpf_feature3; /* Unused (0) */
- unsigned char mpf_feature4; /* Unused (0) */
- unsigned char mpf_feature5; /* Unused (0) */
+ u8 mpf_feature3; /* Unused (0) */
+ u8 mpf_feature4; /* Unused (0) */
+ u8 mpf_feature5; /* Unused (0) */
} __attribute__((packed));
struct mp_config_table
{
char mpc_signature[4];
#define MPC_SIGNATURE "PCMP"
- unsigned short mpc_length; /* Size of table */
- char mpc_spec; /* 0x01 */
- char mpc_checksum;
+ u16 mpc_length; /* Size of table */
+ u8 mpc_spec; /* 0x01 */
+ u8 mpc_checksum;
char mpc_oem[8];
char mpc_productid[12];
- unsigned long mpc_oemptr; /* 0 if not present */
- unsigned short mpc_oemsize; /* 0 if not present */
- unsigned short mpc_entry_count;
- unsigned long mpc_lapic; /* APIC address */
- unsigned short mpe_length; /* Extended Table size */
- unsigned char mpe_checksum; /* Extended Table checksum */
- unsigned char reserved;
+ u32 mpc_oemptr; /* 0 if not present */
+ u16 mpc_oemsize; /* 0 if not present */
+ u16 mpc_entry_count;
+ u32 mpc_lapic; /* APIC address */
+ u16 mpe_length; /* Extended Table size */
+ u8 mpe_checksum; /* Extended Table checksum */
+ u8 reserved;
} __attribute__((packed));
/* Followed by entries */
@@ -87,25 +87,25 @@ struct mp_config_table
struct mpc_config_processor
{
- unsigned char mpc_type;
- unsigned char mpc_apicid; /* Local APIC number */
- unsigned char mpc_apicver; /* Its versions */
- unsigned char mpc_cpuflag;
+ u8 mpc_type;
+ u8 mpc_apicid; /* Local APIC number */
+ u8 mpc_apicver; /* Its versions */
+ u8 mpc_cpuflag;
#define MPC_CPU_ENABLED 1 /* Processor is available */
#define MPC_CPU_BOOTPROCESSOR 2 /* Processor is the BP */
- unsigned long mpc_cpufeature;
+ u32 mpc_cpufeature;
#define MPC_CPU_STEPPING_MASK 0x0F
#define MPC_CPU_MODEL_MASK 0xF0
#define MPC_CPU_FAMILY_MASK 0xF00
- unsigned long mpc_featureflag; /* CPUID feature value */
- unsigned long mpc_reserved[2];
+ u32 mpc_featureflag; /* CPUID feature value */
+ u32 mpc_reserved[2];
} __attribute__((packed));
struct mpc_config_bus
{
- unsigned char mpc_type;
- unsigned char mpc_busid;
- unsigned char mpc_bustype[6];
+ u8 mpc_type;
+ u8 mpc_busid;
+ u8 mpc_bustype[6];
} __attribute__((packed));
#define BUSTYPE_EISA "EISA"
@@ -118,23 +118,23 @@ struct mpc_config_bus
struct mpc_config_ioapic
{
- unsigned char mpc_type;
- unsigned char mpc_apicid;
- unsigned char mpc_apicver;
- unsigned char mpc_flags;
+ u8 mpc_type;
+ u8 mpc_apicid;
+ u8 mpc_apicver;
+ u8 mpc_flags;
#define MPC_APIC_USABLE 0x01
- unsigned long mpc_apicaddr;
+ u32 mpc_apicaddr;
} __attribute__((packed));
struct mpc_config_intsrc
{
- unsigned char mpc_type;
- unsigned char mpc_irqtype;
- unsigned short mpc_irqflag;
- unsigned char mpc_srcbus;
- unsigned char mpc_srcbusirq;
- unsigned char mpc_dstapic;
- unsigned char mpc_dstirq;
+ u8 mpc_type;
+ u8 mpc_irqtype;
+ u16 mpc_irqflag;
+ u8 mpc_srcbus;
+ u8 mpc_srcbusirq;
+ u8 mpc_dstapic;
+ u8 mpc_dstirq;
} __attribute__((packed));
enum mp_irq_source_types {
@@ -156,14 +156,14 @@ enum mp_irq_source_types {
struct mpc_config_lintsrc
{
- unsigned char mpc_type;
- unsigned char mpc_irqtype;
- unsigned short mpc_irqflag;
- unsigned char mpc_srcbusid;
- unsigned char mpc_srcbusirq;
- unsigned char mpc_destapic;
+ u8 mpc_type;
+ u8 mpc_irqtype;
+ u16 mpc_irqflag;
+ u8 mpc_srcbusid;
+ u8 mpc_srcbusirq;
+ u8 mpc_destapic;
#define MP_APIC_ALL 0xFF
- unsigned char mpc_destapiclint;
+ u8 mpc_destapiclint;
} __attribute__((packed));
/*
@@ -194,44 +194,44 @@ enum mp_bustype {
#define MPE_COMPATIBILITY_ADDRESS_SPACE 0x82
struct mp_exten_config {
- unsigned char mpe_type;
- unsigned char mpe_length;
+ u8 mpe_type;
+ u8 mpe_length;
} __attribute__((packed));
typedef struct mp_exten_config *mpe_t;
struct mp_exten_system_address_space {
- unsigned char mpe_type;
- unsigned char mpe_length;
- unsigned char mpe_busid;
- unsigned char mpe_address_type;
+ u8 mpe_type;
+ u8 mpe_length;
+ u8 mpe_busid;
+ u8 mpe_address_type;
#define ADDRESS_TYPE_IO 0
#define ADDRESS_TYPE_MEM 1
#define ADDRESS_TYPE_PREFETCH 2
- unsigned int mpe_address_base_low;
- unsigned int mpe_address_base_high;
- unsigned int mpe_address_length_low;
- unsigned int mpe_address_length_high;
+ u32 mpe_address_base_low;
+ u32 mpe_address_base_high;
+ u32 mpe_address_length_low;
+ u32 mpe_address_length_high;
} __attribute__((packed));
struct mp_exten_bus_hierarchy {
- unsigned char mpe_type;
- unsigned char mpe_length;
- unsigned char mpe_busid;
- unsigned char mpe_bus_info;
+ u8 mpe_type;
+ u8 mpe_length;
+ u8 mpe_busid;
+ u8 mpe_bus_info;
#define BUS_SUBTRACTIVE_DECODE 1
- unsigned char mpe_parent_busid;
- unsigned char reserved[3];
+ u8 mpe_parent_busid;
+ u8 reserved[3];
} __attribute__((packed));
struct mp_exten_compatibility_address_space {
- unsigned char mpe_type;
- unsigned char mpe_length;
- unsigned char mpe_busid;
- unsigned char mpe_address_modifier;
+ u8 mpe_type;
+ u8 mpe_length;
+ u8 mpe_busid;
+ u8 mpe_address_modifier;
#define ADDRESS_RANGE_SUBTRACT 1
#define ADDRESS_RANGE_ADD 0
- unsigned int mpe_range_list;
+ u32 mpe_range_list;
#define RANGE_LIST_IO_ISA 0
/* X100 - X3FF
* X500 - X7FF
@@ -251,40 +251,40 @@ struct mp_exten_compatibility_address_space {
} __attribute__((packed));
void mptable_init(struct mp_config_table *mc, u32 lapic_addr);
-
void *smp_next_mpc_entry(struct mp_config_table *mc);
void *smp_next_mpe_entry(struct mp_config_table *mc);
void smp_write_processor(struct mp_config_table *mc,
- unsigned char apicid, unsigned char apicver,
- unsigned char cpuflag, unsigned int cpufeature,
- unsigned int featureflag);
+ u8 apicid, u8 apicver,
+ u8 cpuflag, u32 cpufeature,
+ u32 featureflag);
void smp_write_processors(struct mp_config_table *mc);
void smp_write_ioapic(struct mp_config_table *mc,
- unsigned char id, unsigned char ver,
- unsigned long apicaddr);
+ u8 id, u8 ver, u32 apicaddr);
void smp_write_intsrc(struct mp_config_table *mc,
- unsigned char irqtype, unsigned short irqflag,
- unsigned char srcbus, unsigned char srcbusirq,
- unsigned char dstapic, unsigned char dstirq);
+ u8 irqtype, u16 irqflag, u8 srcbus, u8 srcbusirq,
+ u8 dstapic, u8 dstirq);
+void smp_write_pci_intsrc(struct mp_config_table *mc,
+ u8 irqtype, u8 srcbus, u8 dev, u8 pirq,
+ u8 dstapic, u8 dstirq);
void smp_write_intsrc_pci_bridge(struct mp_config_table *mc,
- unsigned char irqtype, unsigned short irqflag,
+ u8 irqtype, u16 irqflag,
struct device *dev,
unsigned char dstapic, unsigned char *dstirq);
void smp_write_lintsrc(struct mp_config_table *mc,
- unsigned char irqtype, unsigned short irqflag,
- unsigned char srcbusid, unsigned char srcbusirq,
- unsigned char destapic, unsigned char destapiclint);
+ u8 irqtype, u16 irqflag,
+ u8 srcbusid, u8 srcbusirq,
+ u8 destapic, u8 destapiclint);
void smp_write_address_space(struct mp_config_table *mc,
- unsigned char busid, unsigned char address_type,
- unsigned int address_base_low, unsigned int address_base_high,
- unsigned int address_length_low, unsigned int address_length_high);
+ u8 busid, u8 address_type,
+ u32 address_base_low, u32 address_base_high,
+ u32 address_length_low, u32 address_length_high);
void smp_write_bus_hierarchy(struct mp_config_table *mc,
- unsigned char busid, unsigned char bus_info,
- unsigned char parent_busid);
+ u8 busid, u8 bus_info,
+ u8 parent_busid);
void smp_write_compatibility_address_space(struct mp_config_table *mc,
- unsigned char busid, unsigned char address_modifier,
- unsigned int range_list);
+ u8 busid, u8 address_modifier,
+ u32 range_list);
void *smp_write_floating_table(unsigned long addr, unsigned int virtualwire);
unsigned long write_smp_table(unsigned long addr);