bitkeeper revision 1.22.2.20 (3e4bb0deGlYf76D1jtppEmaeeRJyVQ)

Pulled in IO APIC stuff from linux-2.4.21-pre4
This commit is contained in:
iap10@labyrinth.cl.cam.ac.uk committed 2003-02-13 14:51:10 +00:00
1 parent 1381738b9a
commit 4b929a32df
12 files changed
+1124 -477

No files matched your search

+210 -18
View File
@@ -28,11 +28,23 @@
#include <xeno/config.h>
#include <asm/mc146818rtc.h>
#include <asm/io.h>
#include <asm/desc.h>
#include <asm/smp.h>
#include <asm/desc.h>
#include <asm/smpboot.h>
static unsigned int nmi_watchdog; /* XXXX XEN */
#undef APIC_LOCKUP_DEBUG
#define APIC_LOCKUP_DEBUG
static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED;
unsigned int int_dest_addr_mode = APIC_DEST_LOGICAL;
unsigned char int_delivery_mode = dest_LowestPrio;
/*
* # of IRQ routing registers
*/
@@ -47,6 +59,7 @@ int nr_ioapic_registers[MAX_IO_APICS];
/*
* This is performance-critical, we want to do it O(1)
*
* the indexing order of this array favors 1:1 mappings
* between pins and IRQs.
*/
@@ -60,7 +73,7 @@ static struct irq_pin_list {
* shared ISA-space IRQs, so we have to support them. We are super
* fast in the common case, and fast for shared ISA-space IRQs.
*/
static void add_pin_to_irq(unsigned int irq, int apic, int pin)
static void __init add_pin_to_irq(unsigned int irq, int apic, int pin)
{
static int first_free_entry = NR_IRQS;
struct irq_pin_list *entry = irq_2_pin + irq;
@@ -78,6 +91,26 @@ static void add_pin_to_irq(unsigned int irq, int apic, int pin)
entry->pin = pin;
}
/*
* Reroute an IRQ to a different pin.
*/
static void __init replace_pin_at_irq(unsigned int irq,
int oldapic, int oldpin,
int newapic, int newpin)
{
struct irq_pin_list *entry = irq_2_pin + irq;
while (1) {
if (entry->apic == oldapic && entry->pin == oldpin) {
entry->apic = newapic;
entry->pin = newpin;
}
if (!entry->next)
break;
entry = irq_2_pin + entry->next;
}
}
#define __DO_ACTION(R, ACTION, FINAL) \
\
{ \
@@ -156,6 +189,66 @@ static void clear_IO_APIC (void)
clear_IO_APIC_pin(apic, pin);
}
/*
* support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to
* specific CPU-side IRQs.
*/
#define MAX_PIRQS 8
int pirq_entries [MAX_PIRQS];
int pirqs_enabled;
int skip_ioapic_setup;
#if 0
static int __init noioapic_setup(char *str)
{
skip_ioapic_setup = 1;
return 1;
}
__setup("noapic", noioapic_setup);
static int __init ioapic_setup(char *str)
{
skip_ioapic_setup = 0;
return 1;
}
__setup("apic", ioapic_setup);
static int __init ioapic_pirq_setup(char *str)
{
int i, max;
int ints[MAX_PIRQS+1];
get_options(str, ARRAY_SIZE(ints), ints);
for (i = 0; i < MAX_PIRQS; i++)
pirq_entries[i] = -1;
pirqs_enabled = 1;
printk(KERN_INFO "PIRQ redirection, working around broken MP-BIOS.\n");
max = MAX_PIRQS;
if (ints[0] < MAX_PIRQS)
max = ints[0];
for (i = 0; i < max; i++) {
printk(KERN_DEBUG "... PIRQ%d -> IRQ %d\n", i, ints[i+1]);
/*
* PIRQs are mapped upside down, usually.
*/
pirq_entries[MAX_PIRQS-i-1] = ints[i+1];
}
return 1;
}
__setup("pirq=", ioapic_pirq_setup);
#endif
/*
* Find the IRQ entry number of a certain pin.
*/
@@ -206,7 +299,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
Dprintk("querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n",
bus, slot, pin);
if (mp_bus_id_to_pci_bus[bus] == -1) {
if ((mp_bus_id_to_pci_bus==NULL) || (mp_bus_id_to_pci_bus[bus] == -1)) {
printk(KERN_WARNING "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
return -1;
}
@@ -466,6 +559,20 @@ static int pin_2_irq(int idx, int apic, int pin)
}
}
/*
* PCI IRQ command line redirection. Yes, limits are hardcoded.
*/
if ((pin >= 16) && (pin <= 23)) {
if (pirq_entries[pin-16] != -1) {
if (!pirq_entries[pin-16]) {
printk(KERN_DEBUG "disabling PIRQ%d\n", pin-16);
} else {
irq = pirq_entries[pin-16];
printk(KERN_DEBUG "using PIRQ%d -> IRQ %d\n",
pin-16, irq);
}
}
}
return irq;
}
@@ -495,11 +602,17 @@ static int __init assign_irq_vector(int irq)
return IO_APIC_VECTOR(irq);
next:
current_vector += 8;
/* XXX Skip the guestOS -> Xen syscall vector! XXX */
if (current_vector == HYPERVISOR_CALL_VECTOR) goto next;
/* XXX Skip the Linux/BSD fast-trap vector! XXX */
if (current_vector == 0x80) goto next;
#if 0
if (current_vector == SYSCALL_VECTOR)
goto next;
#endif
if (current_vector > FIRST_SYSTEM_VECTOR) {
offset++;
current_vector = FIRST_DEVICE_VECTOR + offset;
@@ -532,10 +645,10 @@ void __init setup_IO_APIC_irqs(void)
*/
memset(&entry,0,sizeof(entry));
entry.delivery_mode = dest_LowestPrio;
entry.dest_mode = INT_DELIVERY_MODE;
entry.delivery_mode = INT_DELIVERY_MODE;
entry.dest_mode = (INT_DEST_ADDR_MODE != 0);
entry.mask = 0; /* enable IRQ */
entry.dest.logical.logical_dest = TARGET_CPUS;
entry.dest.logical.logical_dest = target_cpus();
idx = find_irq_entry(apic,pin,mp_INT);
if (idx == -1) {
@@ -553,11 +666,18 @@ void __init setup_IO_APIC_irqs(void)
if (irq_trigger(idx)) {
entry.trigger = 1;
entry.mask = 1;
entry.dest.logical.logical_dest = TARGET_CPUS;
}
irq = pin_2_irq(idx, apic, pin);
add_pin_to_irq(irq, apic, pin);
/*
* skip adding the timer int on secondary nodes, which causes
* a small but painful rift in the time-space continuum
*/
if ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
&& (apic != 0) && (irq == 0))
continue;
else
add_pin_to_irq(irq, apic, pin);
if (!apic && !IO_APIC_IRQ(irq))
continue;
@@ -607,16 +727,16 @@ void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
* We use logical delivery to get the timer IRQ
* to the first CPU.
*/
entry.dest_mode = INT_DELIVERY_MODE;
entry.dest_mode = (INT_DEST_ADDR_MODE != 0);
entry.mask = 0; /* unmask IRQ now */
entry.dest.logical.logical_dest = TARGET_CPUS;
entry.delivery_mode = dest_LowestPrio;
entry.dest.logical.logical_dest = target_cpus();
entry.delivery_mode = INT_DELIVERY_MODE;
entry.polarity = 0;
entry.trigger = 0;
entry.vector = vector;
/*
* The timer IRQ doesnt have to know that behind the
* The timer IRQ doesn't have to know that behind the
* scene we have a 8259A-master in AEOI mode ...
*/
irq_desc[0].handler = &ioapic_edge_irq_type;
@@ -634,8 +754,9 @@ void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
void __init UNEXPECTED_IO_APIC(void)
{
printk(KERN_WARNING " WARNING: unexpected IO-APIC, please mail\n");
printk(KERN_WARNING " to linux-smp@vger.kernel.org\n");
printk(KERN_WARNING
"An unexpected IO-APIC was found. If this kernel release is less than\n"
"three months old please report this to linux-smp@vger.kernel.org\n");
}
void __init print_IO_APIC(void)
@@ -667,7 +788,7 @@ void __init print_IO_APIC(void)
spin_unlock_irqrestore(&ioapic_lock, flags);
printk("\n");
printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mpc_apicid);
printk(KERN_DEBUG "IO APIC #%d..XXXX....\n", mp_ioapics[apic].mpc_apicid);
printk(KERN_DEBUG ".... register #00: %08X\n", *(int *)&reg_00);
printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.ID);
if (reg_00.__reserved_1 || reg_00.__reserved_2)
@@ -688,6 +809,7 @@ void __init print_IO_APIC(void)
printk(KERN_DEBUG "....... : PRQ implemented: %X\n", reg_01.PRQ);
printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.version);
if ( (reg_01.version != 0x01) && /* 82489DX IO-APICs */
(reg_01.version != 0x02) && /* VIA */
(reg_01.version != 0x10) && /* oldest IO-APICs */
(reg_01.version != 0x11) && /* Pentium/Pro IO-APICs */
(reg_01.version != 0x13) && /* Xeon IO-APICs */
@@ -898,6 +1020,9 @@ static void __init enable_IO_APIC(void)
irq_2_pin[i].pin = -1;
irq_2_pin[i].next = 0;
}
if (!pirqs_enabled)
for (i = 0; i < MAX_PIRQS; i++)
pirq_entries[i] = -1;
/*
* The number of IO-APIC IRQ registers (== #pins):
@@ -944,6 +1069,9 @@ static void __init setup_ioapic_ids_from_mpc (void)
unsigned char old_id;
unsigned long flags;
if (clustered_apic_mode)
/* We don't have a good way to do this yet - hack */
phys_id_present_map = (u_long) 0xf;
/*
* Set the IOAPIC ID to the value stored in the MPC table.
*/
@@ -956,7 +1084,7 @@ static void __init setup_ioapic_ids_from_mpc (void)
old_id = mp_ioapics[apic].mpc_apicid;
if (mp_ioapics[apic].mpc_apicid >= 0xf) {
if (mp_ioapics[apic].mpc_apicid >= apic_broadcast_id) {
printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
apic, mp_ioapics[apic].mpc_apicid);
printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
@@ -968,14 +1096,16 @@ static void __init setup_ioapic_ids_from_mpc (void)
* Sanity check, is the ID really free? Every APIC in a
* system must have a unique ID or we get lots of nice
* 'stuck on smp_invalidate_needed IPI wait' messages.
* I/O APIC IDs no longer have any meaning for xAPICs and SAPICs.
*/
if (phys_id_present_map & (1 << mp_ioapics[apic].mpc_apicid)) {
if ((clustered_apic_mode != CLUSTERED_APIC_XAPIC) &&
(phys_id_present_map & (1 << mp_ioapics[apic].mpc_apicid))) {
printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
apic, mp_ioapics[apic].mpc_apicid);
for (i = 0; i < 0xf; i++)
if (!(phys_id_present_map & (1 << i)))
break;
if (i >= 0xf)
if (i >= apic_broadcast_id)
panic("Max APIC ID exceeded!\n");
printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
i);
@@ -1170,6 +1300,10 @@ static void end_level_ioapic_irq (unsigned int irq)
#ifdef APIC_LOCKUP_DEBUG
struct irq_pin_list *entry;
#endif
#ifdef APIC_MISMATCH_DEBUG
atomic_inc(&irq_mis_count);
#endif
spin_lock(&ioapic_lock);
__mask_and_edge_IO_APIC_irq(irq);
#ifdef APIC_LOCKUP_DEBUG
@@ -1302,6 +1436,36 @@ static struct hw_interrupt_type lapic_irq_type = {
end_lapic_irq
};
static void enable_NMI_through_LVT0 (void * dummy)
{
unsigned int v, ver;
ver = apic_read(APIC_LVR);
ver = GET_APIC_VERSION(ver);
v = APIC_DM_NMI; /* unmask and set to NMI */
if (!APIC_INTEGRATED(ver)) /* 82489DX */
v |= APIC_LVT_LEVEL_TRIGGER;
apic_write_around(APIC_LVT0, v);
}
static void setup_nmi (void)
{
/*
* Dirty trick to enable the NMI watchdog ...
* We put the 8259A master into AEOI mode and
* unmask on all local APICs LVT0 as NMI.
*
* The idea to use the 8259A in AEOI mode ('8259A Virtual Wire')
* is from Maciej W. Rozycki - so we do not have to EOI from
* the NMI handler or the timer interrupt.
*/
printk(KERN_INFO "activating NMI Watchdog ...");
smp_call_function(enable_NMI_through_LVT0, NULL, 1, 1);
enable_NMI_through_LVT0(NULL);
printk(" done.\n");
}
/*
* This looks a bit hackish but it's about the only one way of sending
@@ -1407,6 +1571,12 @@ static inline void check_timer(void)
*/
unmask_IO_APIC_irq(0);
if (timer_irq_works()) {
if (nmi_watchdog == NMI_IO_APIC) {
disable_8259A_irq(0);
setup_nmi();
enable_8259A_irq(0);
// XXX Xen check_nmi_watchdog();
}
return;
}
clear_IO_APIC_pin(0, pin1);
@@ -1422,6 +1592,14 @@ static inline void check_timer(void)
setup_ExtINT_IRQ0_pin(pin2, vector);
if (timer_irq_works()) {
printk("works.\n");
if (pin1 != -1)
replace_pin_at_irq(0, 0, pin1, 0, pin2);
else
add_pin_to_irq(0, 0, pin2);
if (nmi_watchdog == NMI_IO_APIC) {
setup_nmi();
// XXX Xen check_nmi_watchdog();
}
return;
}
/*
@@ -1431,6 +1609,11 @@ static inline void check_timer(void)
}
printk(" failed.\n");
if (nmi_watchdog) {
printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
nmi_watchdog = 0;
}
printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
disable_8259A_irq(0);
@@ -1462,10 +1645,19 @@ static inline void check_timer(void)
}
/*
*
* IRQ's that are handled by the old PIC in all cases:
* - IRQ2 is the cascade IRQ, and cannot be a io-apic IRQ.
* Linux doesn't really care, as it's not actually used
* for any interrupt handling anyway.
* - There used to be IRQ13 here as well, but all
* MPS-compliant must not use it for FPU coupling and we
* want to use exception 16 anyway. And there are
* systems who connect it to an I/O APIC for other uses.
* Thus we don't mark it special any longer.
*
* Additionally, something is definitely wrong with irq9
* on PIIX4 boards.
*/
#define PIC_IRQS (1<<2)
File diff suppressed because it is too large. Load diff
+2 -1
View File
@@ -4,7 +4,8 @@ include $(BASEDIR)/Rules.mk
default: $(OBJS)
$(MAKE) -C ne
$(MAKE) -C tulip
$(LD) -r -o driver.o $(OBJS) tulip/tulip.o ne/ne_drv.o
$(MAKE) -C e1000
$(LD) -r -o driver.o e1000/e1000.o $(OBJS) tulip/tulip.o ne/ne_drv.o
clean:
$(MAKE) -C ne clean
+1 -2
View File
@@ -77,14 +77,13 @@
struct e1000_adapter;
// XEN XXX
#define DBG 1
// #define DBG 1
#include "e1000_hw.h"
#if DBG
#define E1000_DBG(args...) printk(KERN_DEBUG "e1000: " args)
#else
XXX
#define E1000_DBG(args...)
#endif
+1 -1
View File
@@ -1879,7 +1879,7 @@ e1000_read_phy_reg(struct e1000_hw *hw,
uint32_t mdic = 0;
const uint32_t phy_addr = 1;
DEBUGFUNC("e1000_read_phy_reg");
DEBUGFUNC("XXXXe1000_read_phy_reg");
if(reg_addr > MAX_PHY_REG_ADDRESS) {
DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
@@ -301,11 +301,9 @@ e1000_reset(struct e1000_adapter *adapter)
adapter->hw.fc = adapter->hw.original_fc;
e1000_reset_hw(&adapter->hw);
printk("RESET_H/W\n");
if(adapter->hw.mac_type >= e1000_82544)
E1000_WRITE_REG(&adapter->hw, WUC, 0);
e1000_init_hw(&adapter->hw);
printk("INIT H/W\n");
e1000_reset_adaptive(&adapter->hw);
e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
}
@@ -470,14 +468,12 @@ e1000_probe(struct pci_dev *pdev,
printk(KERN_INFO "%s: %s\n", netdev->name, adapter->id_string);
e1000_check_options(adapter);
printk("OPTIONS OVER\n");
/* Initial Wake on LAN setting
* If APM wake is enabled in the EEPROM,
* enable the ACPI Magic Packet filter
*/
e1000_read_eeprom(&adapter->hw, EEPROM_INIT_CONTROL2_REG, &eeprom_data);
printk("EPROM OVER\n");
if((adapter->hw.mac_type >= e1000_82544) &&
(eeprom_data & E1000_EEPROM_APME))
adapter->wol |= E1000_WUFC_MAG;
@@ -485,7 +481,6 @@ printk("EPROM OVER\n");
/* reset the hardware with the new settings */
e1000_reset(adapter);
printk("PROBE OVER\n");
cards_found++;
return 0;
+2 -2
View File
@@ -45,7 +45,7 @@
#define msec_delay(x) {\
int s=jiffies+1+((x*HZ)/1000); \
printk("mdelay(%d) called -- spin\n",x); \
while(jiffies<s); printk("mdelay over\n");}
while(jiffies<s); }
#if 0
/******************** NOT in XEN ! *******/
@@ -73,7 +73,7 @@ typedef enum {
#define ASSERT(x) if(!(x)) BUG()
#define MSGOUT(S, A, B) printk(KERN_DEBUG S "\n", A, B)
#define DBG 1
//#define DBG 1
#if DBG
#define DEBUGOUT(S) printk(KERN_DEBUG S "\n")
+30 -5
View File
@@ -1,9 +1,12 @@
#ifndef __ASM_APIC_H
#define __ASM_APIC_H
#include <asm/system.h>
#include <asm/ptrace.h>
//#include <linux/config.h>
//#include <linux/pm.h>
#include <asm/apicdef.h>
#include <asm/system.h>
#ifdef CONFIG_X86_LOCAL_APIC
#define APIC_DEBUG 0
@@ -37,9 +40,15 @@ static __inline__ void apic_wait_icr_idle(void)
do { } while ( apic_read( APIC_ICR ) & APIC_ICR_BUSY );
}
#define FORCE_READ_AROUND_WRITE 0
#define apic_read_around(x)
#define apic_write_around(x,y) apic_write((x),(y))
#ifdef CONFIG_X86_GOOD_APIC
# define FORCE_READ_AROUND_WRITE 0
# define apic_read_around(x)
# define apic_write_around(x,y) apic_write((x),(y))
#else
# define FORCE_READ_AROUND_WRITE 1
# define apic_read_around(x) apic_read(x)
# define apic_write_around(x,y) apic_write_atomic((x),(y))
#endif
static inline void ack_APIC_irq(void)
{
@@ -67,8 +76,24 @@ extern void setup_local_APIC (void);
extern void init_apic_mappings (void);
extern void smp_local_timer_interrupt (struct pt_regs * regs);
extern void setup_APIC_clocks (void);
extern void setup_apic_nmi_watchdog (void);
extern inline void nmi_watchdog_tick (struct pt_regs * regs);
extern int APIC_init_uniprocessor (void);
extern void disable_APIC_timer(void);
extern void enable_APIC_timer(void);
//extern struct pm_dev *apic_pm_register(pm_dev_t, unsigned long, pm_callback);
//extern void apic_pm_unregister(struct pm_dev*);
extern unsigned int apic_timer_irqs [NR_CPUS];
extern int check_nmi_watchdog (void);
extern unsigned int nmi_watchdog;
#define NMI_NONE 0
#define NMI_IO_APIC 1
#define NMI_LOCAL_APIC 2
#define NMI_INVALID 3
#endif /* CONFIG_X86_LOCAL_APIC */
#endif /* __ASM_APIC_H */
+15
View File
@@ -32,6 +32,8 @@
#define SET_APIC_LOGICAL_ID(x) (((x)<<24))
#define APIC_ALL_CPUS 0xFF
#define APIC_DFR 0xE0
#define APIC_DFR_CLUSTER 0x0FFFFFFFul /* Clustered */
#define APIC_DFR_FLAT 0xFFFFFFFFul /* Flat mode */
#define APIC_SPIV 0xF0
#define APIC_SPIV_FOCUS_DISABLED (1<<9)
#define APIC_SPIV_APIC_ENABLED (1<<8)
@@ -57,6 +59,7 @@
#define APIC_INT_LEVELTRIG 0x08000
#define APIC_INT_ASSERT 0x04000
#define APIC_ICR_BUSY 0x01000
#define APIC_DEST_PHYSICAL 0x00000
#define APIC_DEST_LOGICAL 0x00800
#define APIC_DM_FIXED 0x00000
#define APIC_DM_LOWEST 0x00100
@@ -107,7 +110,19 @@
#define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
#ifdef CONFIG_X86_CLUSTERED_APIC
#define MAX_IO_APICS 32
#else
#define MAX_IO_APICS 8
#endif
/*
* The broadcast ID is 0xF for old APICs and 0xFF for xAPICs. SAPICs
* don't broadcast (yet?), but if they did, they might use 0xFFFF.
*/
#define APIC_BROADCAST_ID_XAPIC (0xFF)
#define APIC_BROADCAST_ID_APIC (0x0F)
/*
* the local APIC register structure, memory mapped. Not terribly well
+4 -4
View File
@@ -15,7 +15,8 @@
#define APIC_MISMATCH_DEBUG
#define IO_APIC_BASE(idx) \
((volatile int *)__fix_to_virt(FIX_IO_APIC_BASE_0 + idx))
((volatile int *)(__fix_to_virt(FIX_IO_APIC_BASE_0 + idx) \
+ (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK)))
/*
* The structure of the IO-APIC:
@@ -96,7 +97,7 @@ extern struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
extern int mp_irq_entries;
/* MP IRQ source entries */
extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
extern struct mpc_config_intsrc *mp_irqs;
/* non-0 if default (table-less) MP configuration */
extern int mpc_default_type;
@@ -132,8 +133,7 @@ static inline void io_apic_sync(unsigned int apic)
}
/* 1 if "noapic" boot option passed */
//extern int skip_ioapic_setup;
#define skip_ioapic_setup 0
extern int skip_ioapic_setup;
/*
* If we use the IO-APIC for IRQ routing, disable automatic
+19 -6
View File
@@ -1,6 +1,7 @@
#ifndef __ASM_MPSPEC_H
#define __ASM_MPSPEC_H
/*
* Structure definitions for SMP machines following the
* Intel Multiprocessing Specification 1.1 and 1.4.
@@ -13,8 +14,15 @@
#define SMP_MAGIC_IDENT (('_'<<24)|('P'<<16)|('M'<<8)|'_')
/* Maximum of 16 APICs with the current APIC ID architecture. */
/*
* a maximum of 16 APICs with the current APIC ID architecture.
* xAPICs can have up to 256. SAPICs have 16 ID bits.
*/
#ifdef CONFIG_X86_CLUSTERED_APIC
#define MAX_APICS 256
#else
#define MAX_APICS 16
#endif
#define MAX_MPC_ENTRY 1024
@@ -178,7 +186,11 @@ struct mpc_config_translation
* 7 2 CPU MCA+PCI
*/
#ifdef CONFIG_MULTIQUAD
#define MAX_IRQ_SOURCES 512
#else /* !CONFIG_MULTIQUAD */
#define MAX_IRQ_SOURCES 256
#endif /* CONFIG_MULTIQUAD */
#define MAX_MP_BUSSES 32
enum mp_bustype {
@@ -187,8 +199,11 @@ enum mp_bustype {
MP_BUS_PCI,
MP_BUS_MCA
};
extern int mp_bus_id_to_type [MAX_MP_BUSSES];
extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
extern int *mp_bus_id_to_type;
extern int *mp_bus_id_to_node;
extern int *mp_bus_id_to_local;
extern int *mp_bus_id_to_pci_bus;
extern int quad_local_to_mp_bus_id [NR_CPUS/4][4];
extern unsigned int boot_cpu_physical_apicid;
extern unsigned long phys_cpu_present_map;
@@ -197,11 +212,9 @@ extern void find_smp_config (void);
extern void get_smp_config (void);
extern int nr_ioapics;
extern int apic_version [MAX_APICS];
extern int mp_bus_id_to_type [MAX_MP_BUSSES];
extern int mp_irq_entries;
extern struct mpc_config_intsrc mp_irqs [MAX_IRQ_SOURCES];
extern struct mpc_config_intsrc *mp_irqs;
extern int mpc_default_type;
extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
extern int mp_current_pci_id;
extern unsigned long mp_lapic_addr;
extern int pic_mode;
+98 -5
View File
@@ -1,13 +1,82 @@
#ifndef __ASM_SMPBOOT_H
#define __ASM_SMPBOOT_H
#define TRAMPOLINE_LOW phys_to_virt(0x467)
#define TRAMPOLINE_HIGH phys_to_virt(0x469)
/*emum for clustered_apic_mode values*/
enum{
CLUSTERED_APIC_NONE = 0,
CLUSTERED_APIC_XAPIC,
CLUSTERED_APIC_NUMAQ
};
#define boot_cpu_apicid boot_cpu_physical_apicid
#ifdef CONFIG_X86_CLUSTERED_APIC
extern unsigned int apic_broadcast_id;
extern unsigned char clustered_apic_mode;
extern unsigned char esr_disable;
extern unsigned char int_delivery_mode;
extern unsigned int int_dest_addr_mode;
extern int cyclone_setup(char*);
/* How to map from the cpu_present_map. */
#define cpu_present_to_apicid(apicid) (apicid)
static inline void detect_clustered_apic(char* oem, char* prod)
{
/*
* Can't recognize Summit xAPICs at present, so use the OEM ID.
*/
if (!strncmp(oem, "IBM ENSW", 8) && !strncmp(prod, "VIGIL SMP", 9)){
clustered_apic_mode = CLUSTERED_APIC_XAPIC;
apic_broadcast_id = APIC_BROADCAST_ID_XAPIC;
int_dest_addr_mode = APIC_DEST_PHYSICAL;
int_delivery_mode = dest_Fixed;
esr_disable = 1;
/*Start cyclone clock*/
cyclone_setup(0);
}
else if (!strncmp(oem, "IBM NUMA", 8)){
clustered_apic_mode = CLUSTERED_APIC_NUMAQ;
apic_broadcast_id = APIC_BROADCAST_ID_APIC;
int_dest_addr_mode = APIC_DEST_LOGICAL;
int_delivery_mode = dest_LowestPrio;
esr_disable = 1;
}
}
#define INT_DEST_ADDR_MODE (int_dest_addr_mode)
#define INT_DELIVERY_MODE (int_delivery_mode)
#else /* CONFIG_X86_CLUSTERED_APIC */
#define apic_broadcast_id (APIC_BROADCAST_ID_APIC)
#define clustered_apic_mode (CLUSTERED_APIC_NONE)
#define esr_disable (0)
#define detect_clustered_apic(x,y)
#define INT_DEST_ADDR_MODE (APIC_DEST_LOGICAL) /* logical delivery */
#define INT_DELIVERY_MODE (dest_LowestPrio)
#endif /* CONFIG_X86_CLUSTERED_APIC */
#define BAD_APICID 0xFFu
#define TRAMPOLINE_LOW phys_to_virt((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?0x8:0x467)
#define TRAMPOLINE_HIGH phys_to_virt((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?0xa:0x469)
#define boot_cpu_apicid ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?boot_cpu_logical_apicid:boot_cpu_physical_apicid)
extern unsigned char raw_phys_apicid[NR_CPUS];
/*
* How to map from the cpu_present_map
*/
static inline int cpu_present_to_apicid(int mps_cpu)
{
if (clustered_apic_mode == CLUSTERED_APIC_XAPIC)
return raw_phys_apicid[mps_cpu];
if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
return (mps_cpu/4)*16 + (1<<(mps_cpu%4));
return mps_cpu;
}
static inline unsigned long apicid_to_phys_cpu_present(int apicid)
{
if(clustered_apic_mode)
return 1UL << (((apicid >> 4) << 2) + (apicid & 0x3));
return 1UL << apicid;
}
#define physical_to_logical_apicid(phys_apic) ( (1ul << (phys_apic & 0x3)) | (phys_apic & 0xF0u) )
/*
* Mappings between logical cpu number and logical / physical apicid
@@ -22,7 +91,31 @@ extern volatile int cpu_2_physical_apicid[];
#define cpu_to_logical_apicid(cpu) cpu_2_logical_apicid[cpu]
#define physical_apicid_to_cpu(apicid) physical_apicid_2_cpu[apicid]
#define cpu_to_physical_apicid(cpu) cpu_2_physical_apicid[cpu]
#ifdef CONFIG_MULTIQUAD /* use logical IDs to bootstrap */
#define boot_apicid_to_cpu(apicid) logical_apicid_2_cpu[apicid]
#define cpu_to_boot_apicid(cpu) cpu_2_logical_apicid[cpu]
#else /* !CONFIG_MULTIQUAD */ /* use physical IDs to bootstrap */
#define boot_apicid_to_cpu(apicid) physical_apicid_2_cpu[apicid]
#define cpu_to_boot_apicid(cpu) cpu_2_physical_apicid[cpu]
#endif /* CONFIG_MULTIQUAD */
#ifdef CONFIG_X86_CLUSTERED_APIC
static inline int target_cpus(void)
{
static int cpu;
switch(clustered_apic_mode){
case CLUSTERED_APIC_NUMAQ:
/* Broadcast intrs to local quad only. */
return APIC_BROADCAST_ID_APIC;
case CLUSTERED_APIC_XAPIC:
/*round robin the interrupts*/
cpu = (cpu+1)%smp_num_cpus;
return cpu_to_physical_apicid(cpu);
default:
}
return cpu_online_map;
}
#else
#define target_cpus() (0x01)
#endif
#endif
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.