diff options
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/x86/boot/mpspec.c | 112 | ||||
-rw-r--r-- | src/arch/x86/include/arch/smp/mpspec.h | 180 |
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); |