summaryrefslogtreecommitdiff
path: root/src/arch/x86/boot
diff options
context:
space:
mode:
authorMike Loptien <mike.loptien@se-eng.com>2014-06-16 10:46:56 -0600
committerMike Loptien <mike.loptien@se-eng.com>2014-06-24 00:30:12 +0200
commitbd4553bb4c594ff5098fc7c4c85133aab163705e (patch)
treefdad03b9672e7dd0c0cefc8fab6ba513e8c2a3df /src/arch/x86/boot
parente96f4b1122fea74b8f9933fcefa1a2d5a616b39f (diff)
MP Table: Change types to be consistent with the spec
Update the elements in the MP Spec structures with appropriate types to more accurately reflect the real sizes of the bit fields in the MP Tables. Also add a function for PCI I/O interrupts since these are handled slightly differently than the other I/O interrupt entries. The src_bus_irq field is defined where Bits 1-0: PIRQ pin: INT_A# = 0, INT_B# = 1, INT_C# = 2, INT_D# = 3 Bits 2-6: Originating PCI Device Number Bit 7: Reserved Change-Id: I693407beaa0ee454f49464e43ed45d8cba3b18fc Signed-off-by: Mike Loptien <mike.loptien@se-eng.com> Reviewed-on: http://review.coreboot.org/6050 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
Diffstat (limited to 'src/arch/x86/boot')
-rw-r--r--src/arch/x86/boot/mpspec.c112
1 files changed, 85 insertions, 27 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);