diff options
Diffstat (limited to 'sys')
32 files changed, 1010 insertions, 275 deletions
diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S index 4bd4f77..17f8942 100644 --- a/sys/amd64/amd64/apic_vector.S +++ b/sys/amd64/amd64/apic_vector.S @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: apic_vector.s,v 1.32 1998/08/11 17:01:32 bde Exp $ + * $Id: apic_vector.s,v 1.33 1998/09/04 23:03:04 luoqi Exp $ */ @@ -166,13 +166,17 @@ IDTVEC(vec_name) ; \ popal ; \ addl $4+4,%esp +#define IOAPICADDR(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 8 +#define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12 + #define MASK_IRQ(irq_num) \ IMASK_LOCK ; /* into critical reg */ \ testl $IRQ_BIT(irq_num), _apic_imen ; \ jne 7f ; /* masked, don't mask */ \ orl $IRQ_BIT(irq_num), _apic_imen ; /* set the mask bit */ \ - movl _ioapic, %ecx ; /* ioapic[0] addr */ \ - movl $REDTBL_IDX(irq_num), (%ecx) ; /* write the index */ \ + movl IOAPICADDR(irq_num), %ecx ; /* ioapic addr */ \ + movl REDIRIDX(irq_num), %eax ; /* get the index */ \ + movl %eax, (%ecx) ; /* write the index */ \ movl IOAPIC_WINDOW(%ecx), %eax ; /* current value */ \ orl $IOART_INTMASK, %eax ; /* set the mask */ \ movl %eax, IOAPIC_WINDOW(%ecx) ; /* new value */ \ @@ -218,8 +222,9 @@ IDTVEC(vec_name) ; \ testl $IRQ_BIT(irq_num), _apic_imen ; \ je 7f ; /* bit clear, not masked */ \ andl $~IRQ_BIT(irq_num), _apic_imen ;/* clear mask bit */ \ - movl _ioapic,%ecx ; /* ioapic[0]addr */ \ - movl $REDTBL_IDX(irq_num),(%ecx) ; /* write the index */ \ + movl IOAPICADDR(irq_num),%ecx ; /* ioapic addr */ \ + movl REDIRIDX(irq_num), %eax ; /* get the index */ \ + movl %eax,(%ecx) ; /* write the index */ \ movl IOAPIC_WINDOW(%ecx),%eax ; /* current value */ \ andl $~IOART_INTMASK,%eax ; /* clear the mask */ \ movl %eax,IOAPIC_WINDOW(%ecx) ; /* new value */ \ @@ -990,7 +995,7 @@ CNAME(cpustop_restartfunc): .globl _apic_pin_trigger _apic_pin_trigger: - .space (NAPIC * 4), 0 + .long 0 /* diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 04e3c69..e00c2f4 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.78 1998/08/18 07:46:58 msmith Exp $ + * $Id: mp_machdep.c,v 1.79 1998/08/24 02:28:15 bde Exp $ */ #include "opt_smp.h" @@ -278,6 +278,8 @@ struct { } apic_isrbit_location[32]; #endif +struct apic_intmapinfo int_to_apicintpin[APIC_INTMAPSIZE]; + /* * APIC ID logical/physical mapping structures. * We oversize these to simplify boot-time config. @@ -315,7 +317,7 @@ extern pd_entry_t *my_idlePTD; struct pcb stoppcbs[NCPU]; -static int smp_started; /* has the system started? */ +int smp_started; /* has the system started? */ /* * Local data and functions. @@ -334,6 +336,7 @@ static int mptable_pass1(void); static int mptable_pass2(void); static void default_mp_table(int type); static void fix_mp_table(void); +static void setup_apic_irq_mapping(void); static void init_locks(void); static int start_all_aps(u_int boot_addr); static void install_ap_tramp(u_int boot_addr); @@ -569,6 +572,7 @@ mp_enable(u_int boot_addr) /* post scan cleanup */ fix_mp_table(); + setup_apic_irq_mapping(); #if defined(APIC_IO) @@ -675,6 +679,7 @@ typedef struct INTDATA { u_char src_bus_irq; u_char dst_apic_id; u_char dst_apic_int; + u_char int_vector; } io_int, local_int; typedef struct BUSTYPENAME { @@ -905,8 +910,10 @@ mptable_pass2(void) bus_data[x].bus_id = 0xff; /* clear IO APIC INT table */ - for (x = 0; x < NINTR; ++x) + for (x = 0; x < NINTR; ++x) { io_apic_ints[x].int_type = 0xff; + io_apic_ints[x].int_vector = 0xff; + } /* setup the cpu/apic mapping arrays */ boot_cpu_id = -1; @@ -966,6 +973,29 @@ mptable_pass2(void) } +static void +assign_apic_irq(int apic, int intpin, int irq) +{ + int x; + + if (int_to_apicintpin[irq].ioapic != -1) + panic("assign_apic_irq: inconsistent table"); + + int_to_apicintpin[irq].ioapic = apic; + int_to_apicintpin[irq].int_pin = intpin; + int_to_apicintpin[irq].apic_address = ioapic[apic]; + int_to_apicintpin[irq].redirindex = IOAPIC_REDTBL + 2 * intpin; + + for (x = 0; x < nintrs; x++) { + if ((io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3) && + io_apic_ints[x].int_vector == 0xff && + io_apic_ints[x].dst_apic_id == IO_TO_ID(apic) && + io_apic_ints[x].dst_apic_int == intpin) + io_apic_ints[x].int_vector = irq; + } +} + /* * parse an Intel MP specification table */ @@ -1041,6 +1071,50 @@ fix_mp_table(void) } +static void +setup_apic_irq_mapping(void) +{ + int x; + int int_vector; + + /* Assign low level interrupt handlers */ + for (x = 0; x < APIC_INTMAPSIZE; x++) { + int_to_apicintpin[x].ioapic = -1; + int_to_apicintpin[x].int_pin = 0; + int_to_apicintpin[x].apic_address = NULL; + int_to_apicintpin[x].redirindex = 0; + } + for (x = 0; x < nintrs; x++) { + if (io_apic_ints[x].dst_apic_int <= APIC_INTMAPSIZE && + io_apic_ints[x].dst_apic_id == IO_TO_ID(0) && + io_apic_ints[x].int_vector == 0xff && + (io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3)) { + assign_apic_irq(0, + io_apic_ints[x].dst_apic_int, + io_apic_ints[x].dst_apic_int); + } + } + int_vector = 0; + while (int_vector < APIC_INTMAPSIZE && + int_to_apicintpin[int_vector].ioapic != -1) + int_vector++; + for (x = 0; x < nintrs && int_vector < APIC_INTMAPSIZE; x++) { + if ((io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3) && + io_apic_ints[x].int_vector == 0xff) { + assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id), + io_apic_ints[x].dst_apic_int, + int_vector); + int_vector++; + while (int_vector < APIC_INTMAPSIZE && + int_to_apicintpin[int_vector].ioapic != -1) + int_vector++; + } + } +} + + static int processor_entry(proc_entry_ptr entry, int cpu) { @@ -1164,7 +1238,7 @@ isa_apic_mask(u_int isa_mask) return 0; --isa_irq; /* make it zero based */ - apic_pin = isa_apic_pin(isa_irq); /* look for APIC connection */ + apic_pin = isa_apic_irq(isa_irq); /* look for APIC connection */ if (apic_pin == -1) return 0; @@ -1177,10 +1251,12 @@ isa_apic_mask(u_int isa_mask) */ #define INTTYPE(I) (io_apic_ints[(I)].int_type) #define INTPIN(I) (io_apic_ints[(I)].dst_apic_int) +#define INTIRQ(I) (io_apic_ints[(I)].int_vector) +#define INTAPIC(I) (ID_TO_IO(io_apic_ints[(I)].dst_apic_id)) #define SRCBUSIRQ(I) (io_apic_ints[(I)].src_bus_irq) int -isa_apic_pin(int isa_irq) +isa_apic_irq(int isa_irq) { int intr; @@ -1189,7 +1265,7 @@ isa_apic_pin(int isa_irq) if (SRCBUSIRQ(intr) == isa_irq) { if (apic_int_is_bus_type(intr, ISA) || apic_int_is_bus_type(intr, EISA)) - return INTPIN(intr); /* found */ + return INTIRQ(intr); /* found */ } } } @@ -1204,7 +1280,7 @@ isa_apic_pin(int isa_irq) #define SRCBUSDEVICE(I) ((io_apic_ints[(I)].src_bus_irq >> 2) & 0x1f) #define SRCBUSLINE(I) (io_apic_ints[(I)].src_bus_irq & 0x03) int -pci_apic_pin(int pciBus, int pciDevice, int pciInt) +pci_apic_irq(int pciBus, int pciDevice, int pciInt) { int intr; @@ -1216,13 +1292,13 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt) && (SRCBUSDEVICE(intr) == pciDevice) && (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */ if (apic_int_is_bus_type(intr, PCI)) - return INTPIN(intr); /* exact match */ + return INTIRQ(intr); /* exact match */ return -1; /* NOT found */ } int -next_apic_pin(int pin) +next_apic_irq(int irq) { int intr, ointr; int bus, bustype; @@ -1230,7 +1306,7 @@ next_apic_pin(int pin) bus = 0; bustype = 0; for (intr = 0; intr < nintrs; intr++) { - if (INTPIN(intr) != pin || INTTYPE(intr) != 0) + if (INTIRQ(intr) != irq || INTTYPE(intr) != 0) continue; bus = SRCBUSID(intr); bustype = apic_bus_type(bus); @@ -1265,7 +1341,7 @@ next_apic_pin(int pin) if (ointr >= nintrs) { return -1; } - return INTPIN(ointr); + return INTIRQ(ointr); } #undef SRCBUSLINE #undef SRCBUSDEVICE @@ -1273,6 +1349,8 @@ next_apic_pin(int pin) #undef SRCBUSIRQ #undef INTPIN +#undef INTIRQ +#undef INTAPIC #undef INTTYPE @@ -1397,6 +1475,27 @@ apic_int_type(int apic, int pin) return -1; /* NOT found */ } +int +apic_irq(int apic, int pin) +{ + int x; + int res; + + for (x = 0; x < nintrs; ++x) + if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) && + (pin == io_apic_ints[x].dst_apic_int)) { + res = io_apic_ints[x].int_vector; + if (res == 0xff) + return -1; + if (apic != int_to_apicintpin[res].ioapic) + panic("apic_irq: inconsistent table"); + if (pin != int_to_apicintpin[res].int_pin) + panic("apic_irq inconsistent table (2)"); + return res; + } + return -1; +} + /* * given a LOGICAL APIC# and pin#, return: @@ -2127,9 +2226,11 @@ ap_init() * quite correct yet. We should have a bitfield for cpus willing * to accept TLB flush IPI's or something and sync them. */ - invltlb_ok = 1; - smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ - smp_active = 1; /* historic */ + if (smp_cpus == mp_ncpus) { + invltlb_ok = 1; + smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ + smp_active = 1; /* historic */ + } curproc = NULL; /* make sure */ } diff --git a/sys/amd64/amd64/mpboot.S b/sys/amd64/amd64/mpboot.S index e3661f2..1c311fe 100644 --- a/sys/amd64/amd64/mpboot.S +++ b/sys/amd64/amd64/mpboot.S @@ -31,7 +31,7 @@ * mpboot.s: FreeBSD machine support for the Intel MP Spec * multiprocessor systems. * - * $Id: mpboot.s,v 1.5 1997/09/22 05:03:03 peter Exp $ + * $Id: mpboot.s,v 1.6 1997/10/10 09:44:05 peter Exp $ */ #include "opt_vm86.h" @@ -124,6 +124,12 @@ mp_begin: /* now running relocated at KERNBASE */ /* Now, let's prepare for some REAL WORK :-) */ call _ap_init + call _rel_mplock +2: + cmpl $0, CNAME(smp_started) /* Wait for last AP to be ready */ + jz 2b + call _get_mplock + /* let her rip! (loads new stack) */ jmp _cpu_switch diff --git a/sys/amd64/amd64/mptable.c b/sys/amd64/amd64/mptable.c index 04e3c69..e00c2f4 100644 --- a/sys/amd64/amd64/mptable.c +++ b/sys/amd64/amd64/mptable.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.78 1998/08/18 07:46:58 msmith Exp $ + * $Id: mp_machdep.c,v 1.79 1998/08/24 02:28:15 bde Exp $ */ #include "opt_smp.h" @@ -278,6 +278,8 @@ struct { } apic_isrbit_location[32]; #endif +struct apic_intmapinfo int_to_apicintpin[APIC_INTMAPSIZE]; + /* * APIC ID logical/physical mapping structures. * We oversize these to simplify boot-time config. @@ -315,7 +317,7 @@ extern pd_entry_t *my_idlePTD; struct pcb stoppcbs[NCPU]; -static int smp_started; /* has the system started? */ +int smp_started; /* has the system started? */ /* * Local data and functions. @@ -334,6 +336,7 @@ static int mptable_pass1(void); static int mptable_pass2(void); static void default_mp_table(int type); static void fix_mp_table(void); +static void setup_apic_irq_mapping(void); static void init_locks(void); static int start_all_aps(u_int boot_addr); static void install_ap_tramp(u_int boot_addr); @@ -569,6 +572,7 @@ mp_enable(u_int boot_addr) /* post scan cleanup */ fix_mp_table(); + setup_apic_irq_mapping(); #if defined(APIC_IO) @@ -675,6 +679,7 @@ typedef struct INTDATA { u_char src_bus_irq; u_char dst_apic_id; u_char dst_apic_int; + u_char int_vector; } io_int, local_int; typedef struct BUSTYPENAME { @@ -905,8 +910,10 @@ mptable_pass2(void) bus_data[x].bus_id = 0xff; /* clear IO APIC INT table */ - for (x = 0; x < NINTR; ++x) + for (x = 0; x < NINTR; ++x) { io_apic_ints[x].int_type = 0xff; + io_apic_ints[x].int_vector = 0xff; + } /* setup the cpu/apic mapping arrays */ boot_cpu_id = -1; @@ -966,6 +973,29 @@ mptable_pass2(void) } +static void +assign_apic_irq(int apic, int intpin, int irq) +{ + int x; + + if (int_to_apicintpin[irq].ioapic != -1) + panic("assign_apic_irq: inconsistent table"); + + int_to_apicintpin[irq].ioapic = apic; + int_to_apicintpin[irq].int_pin = intpin; + int_to_apicintpin[irq].apic_address = ioapic[apic]; + int_to_apicintpin[irq].redirindex = IOAPIC_REDTBL + 2 * intpin; + + for (x = 0; x < nintrs; x++) { + if ((io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3) && + io_apic_ints[x].int_vector == 0xff && + io_apic_ints[x].dst_apic_id == IO_TO_ID(apic) && + io_apic_ints[x].dst_apic_int == intpin) + io_apic_ints[x].int_vector = irq; + } +} + /* * parse an Intel MP specification table */ @@ -1041,6 +1071,50 @@ fix_mp_table(void) } +static void +setup_apic_irq_mapping(void) +{ + int x; + int int_vector; + + /* Assign low level interrupt handlers */ + for (x = 0; x < APIC_INTMAPSIZE; x++) { + int_to_apicintpin[x].ioapic = -1; + int_to_apicintpin[x].int_pin = 0; + int_to_apicintpin[x].apic_address = NULL; + int_to_apicintpin[x].redirindex = 0; + } + for (x = 0; x < nintrs; x++) { + if (io_apic_ints[x].dst_apic_int <= APIC_INTMAPSIZE && + io_apic_ints[x].dst_apic_id == IO_TO_ID(0) && + io_apic_ints[x].int_vector == 0xff && + (io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3)) { + assign_apic_irq(0, + io_apic_ints[x].dst_apic_int, + io_apic_ints[x].dst_apic_int); + } + } + int_vector = 0; + while (int_vector < APIC_INTMAPSIZE && + int_to_apicintpin[int_vector].ioapic != -1) + int_vector++; + for (x = 0; x < nintrs && int_vector < APIC_INTMAPSIZE; x++) { + if ((io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3) && + io_apic_ints[x].int_vector == 0xff) { + assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id), + io_apic_ints[x].dst_apic_int, + int_vector); + int_vector++; + while (int_vector < APIC_INTMAPSIZE && + int_to_apicintpin[int_vector].ioapic != -1) + int_vector++; + } + } +} + + static int processor_entry(proc_entry_ptr entry, int cpu) { @@ -1164,7 +1238,7 @@ isa_apic_mask(u_int isa_mask) return 0; --isa_irq; /* make it zero based */ - apic_pin = isa_apic_pin(isa_irq); /* look for APIC connection */ + apic_pin = isa_apic_irq(isa_irq); /* look for APIC connection */ if (apic_pin == -1) return 0; @@ -1177,10 +1251,12 @@ isa_apic_mask(u_int isa_mask) */ #define INTTYPE(I) (io_apic_ints[(I)].int_type) #define INTPIN(I) (io_apic_ints[(I)].dst_apic_int) +#define INTIRQ(I) (io_apic_ints[(I)].int_vector) +#define INTAPIC(I) (ID_TO_IO(io_apic_ints[(I)].dst_apic_id)) #define SRCBUSIRQ(I) (io_apic_ints[(I)].src_bus_irq) int -isa_apic_pin(int isa_irq) +isa_apic_irq(int isa_irq) { int intr; @@ -1189,7 +1265,7 @@ isa_apic_pin(int isa_irq) if (SRCBUSIRQ(intr) == isa_irq) { if (apic_int_is_bus_type(intr, ISA) || apic_int_is_bus_type(intr, EISA)) - return INTPIN(intr); /* found */ + return INTIRQ(intr); /* found */ } } } @@ -1204,7 +1280,7 @@ isa_apic_pin(int isa_irq) #define SRCBUSDEVICE(I) ((io_apic_ints[(I)].src_bus_irq >> 2) & 0x1f) #define SRCBUSLINE(I) (io_apic_ints[(I)].src_bus_irq & 0x03) int -pci_apic_pin(int pciBus, int pciDevice, int pciInt) +pci_apic_irq(int pciBus, int pciDevice, int pciInt) { int intr; @@ -1216,13 +1292,13 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt) && (SRCBUSDEVICE(intr) == pciDevice) && (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */ if (apic_int_is_bus_type(intr, PCI)) - return INTPIN(intr); /* exact match */ + return INTIRQ(intr); /* exact match */ return -1; /* NOT found */ } int -next_apic_pin(int pin) +next_apic_irq(int irq) { int intr, ointr; int bus, bustype; @@ -1230,7 +1306,7 @@ next_apic_pin(int pin) bus = 0; bustype = 0; for (intr = 0; intr < nintrs; intr++) { - if (INTPIN(intr) != pin || INTTYPE(intr) != 0) + if (INTIRQ(intr) != irq || INTTYPE(intr) != 0) continue; bus = SRCBUSID(intr); bustype = apic_bus_type(bus); @@ -1265,7 +1341,7 @@ next_apic_pin(int pin) if (ointr >= nintrs) { return -1; } - return INTPIN(ointr); + return INTIRQ(ointr); } #undef SRCBUSLINE #undef SRCBUSDEVICE @@ -1273,6 +1349,8 @@ next_apic_pin(int pin) #undef SRCBUSIRQ #undef INTPIN +#undef INTIRQ +#undef INTAPIC #undef INTTYPE @@ -1397,6 +1475,27 @@ apic_int_type(int apic, int pin) return -1; /* NOT found */ } +int +apic_irq(int apic, int pin) +{ + int x; + int res; + + for (x = 0; x < nintrs; ++x) + if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) && + (pin == io_apic_ints[x].dst_apic_int)) { + res = io_apic_ints[x].int_vector; + if (res == 0xff) + return -1; + if (apic != int_to_apicintpin[res].ioapic) + panic("apic_irq: inconsistent table"); + if (pin != int_to_apicintpin[res].int_pin) + panic("apic_irq inconsistent table (2)"); + return res; + } + return -1; +} + /* * given a LOGICAL APIC# and pin#, return: @@ -2127,9 +2226,11 @@ ap_init() * quite correct yet. We should have a bitfield for cpus willing * to accept TLB flush IPI's or something and sync them. */ - invltlb_ok = 1; - smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ - smp_active = 1; /* historic */ + if (smp_cpus == mp_ncpus) { + invltlb_ok = 1; + smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ + smp_active = 1; /* historic */ + } curproc = NULL; /* make sure */ } diff --git a/sys/amd64/amd64/tsc.c b/sys/amd64/amd64/tsc.c index 4e14052..3d8f8cd 100644 --- a/sys/amd64/amd64/tsc.c +++ b/sys/amd64/amd64/tsc.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.123 1998/06/07 20:36:39 phk Exp $ + * $Id: clock.c,v 1.124 1998/06/09 13:10:46 phk Exp $ */ /* @@ -953,7 +953,7 @@ cpu_initclocks() /* Finish initializing 8253 timer 0. */ #ifdef APIC_IO - apic_8254_intr = isa_apic_pin(0); + apic_8254_intr = isa_apic_irq(0); apic_8254_trial = 0; if (apic_8254_intr >= 0 ) { if (apic_int_type(0, 0) == 3) @@ -993,7 +993,7 @@ cpu_initclocks() printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); #ifdef APIC_IO - if (isa_apic_pin(8) != 8) + if (isa_apic_irq(8) != 8) panic("APIC RTC != 8"); #endif /* APIC_IO */ diff --git a/sys/amd64/include/apicreg.h b/sys/amd64/include/apicreg.h index 50f8416..55e44e0 100644 --- a/sys/amd64/include/apicreg.h +++ b/sys/amd64/include/apicreg.h @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: apic.h,v 1.7 1997/08/04 17:20:39 smp Exp smp $ + * $Id: apic.h,v 1.11 1997/08/04 17:31:24 fsmp Exp $ */ #ifndef _MACHINE_APIC_H_ @@ -113,12 +113,6 @@ * global defines, etc. */ -/** - * this enables code concerned with handling more than one IO APIC. - * Note: this is NOT READY for use! - * -#define MULTIPLE_IOAPICS - */ /****************************************************************************** * LOCAL APIC structure diff --git a/sys/amd64/include/mptable.h b/sys/amd64/include/mptable.h index 04e3c69..e00c2f4 100644 --- a/sys/amd64/include/mptable.h +++ b/sys/amd64/include/mptable.h @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.78 1998/08/18 07:46:58 msmith Exp $ + * $Id: mp_machdep.c,v 1.79 1998/08/24 02:28:15 bde Exp $ */ #include "opt_smp.h" @@ -278,6 +278,8 @@ struct { } apic_isrbit_location[32]; #endif +struct apic_intmapinfo int_to_apicintpin[APIC_INTMAPSIZE]; + /* * APIC ID logical/physical mapping structures. * We oversize these to simplify boot-time config. @@ -315,7 +317,7 @@ extern pd_entry_t *my_idlePTD; struct pcb stoppcbs[NCPU]; -static int smp_started; /* has the system started? */ +int smp_started; /* has the system started? */ /* * Local data and functions. @@ -334,6 +336,7 @@ static int mptable_pass1(void); static int mptable_pass2(void); static void default_mp_table(int type); static void fix_mp_table(void); +static void setup_apic_irq_mapping(void); static void init_locks(void); static int start_all_aps(u_int boot_addr); static void install_ap_tramp(u_int boot_addr); @@ -569,6 +572,7 @@ mp_enable(u_int boot_addr) /* post scan cleanup */ fix_mp_table(); + setup_apic_irq_mapping(); #if defined(APIC_IO) @@ -675,6 +679,7 @@ typedef struct INTDATA { u_char src_bus_irq; u_char dst_apic_id; u_char dst_apic_int; + u_char int_vector; } io_int, local_int; typedef struct BUSTYPENAME { @@ -905,8 +910,10 @@ mptable_pass2(void) bus_data[x].bus_id = 0xff; /* clear IO APIC INT table */ - for (x = 0; x < NINTR; ++x) + for (x = 0; x < NINTR; ++x) { io_apic_ints[x].int_type = 0xff; + io_apic_ints[x].int_vector = 0xff; + } /* setup the cpu/apic mapping arrays */ boot_cpu_id = -1; @@ -966,6 +973,29 @@ mptable_pass2(void) } +static void +assign_apic_irq(int apic, int intpin, int irq) +{ + int x; + + if (int_to_apicintpin[irq].ioapic != -1) + panic("assign_apic_irq: inconsistent table"); + + int_to_apicintpin[irq].ioapic = apic; + int_to_apicintpin[irq].int_pin = intpin; + int_to_apicintpin[irq].apic_address = ioapic[apic]; + int_to_apicintpin[irq].redirindex = IOAPIC_REDTBL + 2 * intpin; + + for (x = 0; x < nintrs; x++) { + if ((io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3) && + io_apic_ints[x].int_vector == 0xff && + io_apic_ints[x].dst_apic_id == IO_TO_ID(apic) && + io_apic_ints[x].dst_apic_int == intpin) + io_apic_ints[x].int_vector = irq; + } +} + /* * parse an Intel MP specification table */ @@ -1041,6 +1071,50 @@ fix_mp_table(void) } +static void +setup_apic_irq_mapping(void) +{ + int x; + int int_vector; + + /* Assign low level interrupt handlers */ + for (x = 0; x < APIC_INTMAPSIZE; x++) { + int_to_apicintpin[x].ioapic = -1; + int_to_apicintpin[x].int_pin = 0; + int_to_apicintpin[x].apic_address = NULL; + int_to_apicintpin[x].redirindex = 0; + } + for (x = 0; x < nintrs; x++) { + if (io_apic_ints[x].dst_apic_int <= APIC_INTMAPSIZE && + io_apic_ints[x].dst_apic_id == IO_TO_ID(0) && + io_apic_ints[x].int_vector == 0xff && + (io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3)) { + assign_apic_irq(0, + io_apic_ints[x].dst_apic_int, + io_apic_ints[x].dst_apic_int); + } + } + int_vector = 0; + while (int_vector < APIC_INTMAPSIZE && + int_to_apicintpin[int_vector].ioapic != -1) + int_vector++; + for (x = 0; x < nintrs && int_vector < APIC_INTMAPSIZE; x++) { + if ((io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3) && + io_apic_ints[x].int_vector == 0xff) { + assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id), + io_apic_ints[x].dst_apic_int, + int_vector); + int_vector++; + while (int_vector < APIC_INTMAPSIZE && + int_to_apicintpin[int_vector].ioapic != -1) + int_vector++; + } + } +} + + static int processor_entry(proc_entry_ptr entry, int cpu) { @@ -1164,7 +1238,7 @@ isa_apic_mask(u_int isa_mask) return 0; --isa_irq; /* make it zero based */ - apic_pin = isa_apic_pin(isa_irq); /* look for APIC connection */ + apic_pin = isa_apic_irq(isa_irq); /* look for APIC connection */ if (apic_pin == -1) return 0; @@ -1177,10 +1251,12 @@ isa_apic_mask(u_int isa_mask) */ #define INTTYPE(I) (io_apic_ints[(I)].int_type) #define INTPIN(I) (io_apic_ints[(I)].dst_apic_int) +#define INTIRQ(I) (io_apic_ints[(I)].int_vector) +#define INTAPIC(I) (ID_TO_IO(io_apic_ints[(I)].dst_apic_id)) #define SRCBUSIRQ(I) (io_apic_ints[(I)].src_bus_irq) int -isa_apic_pin(int isa_irq) +isa_apic_irq(int isa_irq) { int intr; @@ -1189,7 +1265,7 @@ isa_apic_pin(int isa_irq) if (SRCBUSIRQ(intr) == isa_irq) { if (apic_int_is_bus_type(intr, ISA) || apic_int_is_bus_type(intr, EISA)) - return INTPIN(intr); /* found */ + return INTIRQ(intr); /* found */ } } } @@ -1204,7 +1280,7 @@ isa_apic_pin(int isa_irq) #define SRCBUSDEVICE(I) ((io_apic_ints[(I)].src_bus_irq >> 2) & 0x1f) #define SRCBUSLINE(I) (io_apic_ints[(I)].src_bus_irq & 0x03) int -pci_apic_pin(int pciBus, int pciDevice, int pciInt) +pci_apic_irq(int pciBus, int pciDevice, int pciInt) { int intr; @@ -1216,13 +1292,13 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt) && (SRCBUSDEVICE(intr) == pciDevice) && (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */ if (apic_int_is_bus_type(intr, PCI)) - return INTPIN(intr); /* exact match */ + return INTIRQ(intr); /* exact match */ return -1; /* NOT found */ } int -next_apic_pin(int pin) +next_apic_irq(int irq) { int intr, ointr; int bus, bustype; @@ -1230,7 +1306,7 @@ next_apic_pin(int pin) bus = 0; bustype = 0; for (intr = 0; intr < nintrs; intr++) { - if (INTPIN(intr) != pin || INTTYPE(intr) != 0) + if (INTIRQ(intr) != irq || INTTYPE(intr) != 0) continue; bus = SRCBUSID(intr); bustype = apic_bus_type(bus); @@ -1265,7 +1341,7 @@ next_apic_pin(int pin) if (ointr >= nintrs) { return -1; } - return INTPIN(ointr); + return INTIRQ(ointr); } #undef SRCBUSLINE #undef SRCBUSDEVICE @@ -1273,6 +1349,8 @@ next_apic_pin(int pin) #undef SRCBUSIRQ #undef INTPIN +#undef INTIRQ +#undef INTAPIC #undef INTTYPE @@ -1397,6 +1475,27 @@ apic_int_type(int apic, int pin) return -1; /* NOT found */ } +int +apic_irq(int apic, int pin) +{ + int x; + int res; + + for (x = 0; x < nintrs; ++x) + if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) && + (pin == io_apic_ints[x].dst_apic_int)) { + res = io_apic_ints[x].int_vector; + if (res == 0xff) + return -1; + if (apic != int_to_apicintpin[res].ioapic) + panic("apic_irq: inconsistent table"); + if (pin != int_to_apicintpin[res].int_pin) + panic("apic_irq inconsistent table (2)"); + return res; + } + return -1; +} + /* * given a LOGICAL APIC# and pin#, return: @@ -2127,9 +2226,11 @@ ap_init() * quite correct yet. We should have a bitfield for cpus willing * to accept TLB flush IPI's or something and sync them. */ - invltlb_ok = 1; - smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ - smp_active = 1; /* historic */ + if (smp_cpus == mp_ncpus) { + invltlb_ok = 1; + smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ + smp_active = 1; /* historic */ + } curproc = NULL; /* make sure */ } diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h index f258630..0f4f915 100644 --- a/sys/amd64/include/smp.h +++ b/sys/amd64/include/smp.h @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: smp.h,v 1.42 1998/04/01 21:07:36 tegge Exp $ + * $Id: smp.h,v 1.43 1998/05/17 22:12:05 tegge Exp $ * */ @@ -103,6 +103,14 @@ extern u_int32_t io_apic_versions[]; extern int cpu_num_to_apic_id[]; extern int io_num_to_apic_id[]; extern int apic_id_to_logical[]; +#define APIC_INTMAPSIZE 24 +struct apic_intmapinfo { + int ioapic; + int int_pin; + volatile void *apic_address; + int redirindex; +}; +extern struct apic_intmapinfo int_to_apicintpin[]; extern u_int all_cpus; extern u_char SMP_ioapic[]; extern struct pcb stoppcbs[]; @@ -113,9 +121,10 @@ int mp_probe __P((void)); void mp_start __P((void)); void mp_announce __P((void)); u_int isa_apic_mask __P((u_int)); -int isa_apic_pin __P((int)); -int pci_apic_pin __P((int, int, int)); -int next_apic_pin __P((int)); +int isa_apic_irq __P((int)); +int pci_apic_irq __P((int, int, int)); +int apic_irq __P((int, int)); +int next_apic_irq __P((int)); int undirect_isa_irq __P((int)); int undirect_pci_irq __P((int)); int apic_bus_type __P((int)); @@ -141,12 +150,7 @@ void set_lapic_isrloc __P((int, int)); /* global data in mpapic.c */ extern volatile lapic_t lapic; - -#if defined(MULTIPLE_IOAPICS) -#error MULTIPLE_IOAPICSXXX -#else extern volatile ioapic_t *ioapic[]; -#endif /* MULTIPLE_IOAPICS */ /* functions in mpapic.c */ void apic_dump __P((char*)); diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c index 4e14052..3d8f8cd 100644 --- a/sys/amd64/isa/clock.c +++ b/sys/amd64/isa/clock.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.123 1998/06/07 20:36:39 phk Exp $ + * $Id: clock.c,v 1.124 1998/06/09 13:10:46 phk Exp $ */ /* @@ -953,7 +953,7 @@ cpu_initclocks() /* Finish initializing 8253 timer 0. */ #ifdef APIC_IO - apic_8254_intr = isa_apic_pin(0); + apic_8254_intr = isa_apic_irq(0); apic_8254_trial = 0; if (apic_8254_intr >= 0 ) { if (apic_int_type(0, 0) == 3) @@ -993,7 +993,7 @@ cpu_initclocks() printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); #ifdef APIC_IO - if (isa_apic_pin(8) != 8) + if (isa_apic_irq(8) != 8) panic("APIC RTC != 8"); #endif /* APIC_IO */ diff --git a/sys/amd64/isa/intr_machdep.c b/sys/amd64/isa/intr_machdep.c index 49c7f24..3f891f2 100644 --- a/sys/amd64/isa/intr_machdep.c +++ b/sys/amd64/isa/intr_machdep.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.12 1998/06/18 15:32:06 bde Exp $ + * $Id: intr_machdep.c,v 1.13 1998/06/18 16:08:46 bde Exp $ */ #include "opt_auto_eoi.h" @@ -429,12 +429,15 @@ icu_setup(int intr, inthand2_t *handler, void *arg, u_int *maskptr, int flags) set_lapic_isrloc(intr, vector); #endif /* - * XXX MULTIPLE_IOAPICSXXX * Reprogram the vector in the IO APIC. */ - select = (intr * 2) + IOAPIC_REDTBL0; - value = io_apic_read(0, select) & ~IOART_INTVEC; - io_apic_write(0, select, value | vector); + if (int_to_apicintpin[intr].ioapic >= 0) { + select = int_to_apicintpin[intr].redirindex; + value = io_apic_read(int_to_apicintpin[intr].ioapic, + select) & ~IOART_INTVEC; + io_apic_write(int_to_apicintpin[intr].ioapic, + select, value | vector); + } #else setidt(ICU_OFFSET + intr, flags & INTR_FAST ? fastintr[intr] : slowintr[intr], diff --git a/sys/amd64/isa/nmi.c b/sys/amd64/isa/nmi.c index 49c7f24..3f891f2 100644 --- a/sys/amd64/isa/nmi.c +++ b/sys/amd64/isa/nmi.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.12 1998/06/18 15:32:06 bde Exp $ + * $Id: intr_machdep.c,v 1.13 1998/06/18 16:08:46 bde Exp $ */ #include "opt_auto_eoi.h" @@ -429,12 +429,15 @@ icu_setup(int intr, inthand2_t *handler, void *arg, u_int *maskptr, int flags) set_lapic_isrloc(intr, vector); #endif /* - * XXX MULTIPLE_IOAPICSXXX * Reprogram the vector in the IO APIC. */ - select = (intr * 2) + IOAPIC_REDTBL0; - value = io_apic_read(0, select) & ~IOART_INTVEC; - io_apic_write(0, select, value | vector); + if (int_to_apicintpin[intr].ioapic >= 0) { + select = int_to_apicintpin[intr].redirindex; + value = io_apic_read(int_to_apicintpin[intr].ioapic, + select) & ~IOART_INTVEC; + io_apic_write(int_to_apicintpin[intr].ioapic, + select, value | vector); + } #else setidt(ICU_OFFSET + intr, flags & INTR_FAST ? fastintr[intr] : slowintr[intr], diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 2dac6de..fceb220 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: pci.c,v 1.84 1998/07/22 08:40:46 dfr Exp $ + * $Id: pci.c,v 1.85 1998/08/13 19:12:20 gibbs Exp $ * */ @@ -343,7 +343,7 @@ pci_readcfg(pcicfgregs *probe) if (cfg->intpin != 0) { int airq; - airq = pci_apic_pin(cfg->bus, cfg->slot, cfg->intpin); + airq = pci_apic_irq(cfg->bus, cfg->slot, cfg->intpin); if (airq >= 0) { /* PCI specific entry found in MP table */ if (airq != cfg->intline) { @@ -357,7 +357,7 @@ pci_readcfg(pcicfgregs *probe) * same methods as used by the ISA devices * devices to find the proper IOAPIC int pin. */ - airq = isa_apic_pin(cfg->intline); + airq = isa_apic_irq(cfg->intline); if ((airq >= 0) && (airq != cfg->intline)) { /* XXX: undirect_pci_irq() ? */ undirect_isa_irq(cfg->intline); diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s index 4bd4f77..17f8942 100644 --- a/sys/i386/i386/apic_vector.s +++ b/sys/i386/i386/apic_vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: apic_vector.s,v 1.32 1998/08/11 17:01:32 bde Exp $ + * $Id: apic_vector.s,v 1.33 1998/09/04 23:03:04 luoqi Exp $ */ @@ -166,13 +166,17 @@ IDTVEC(vec_name) ; \ popal ; \ addl $4+4,%esp +#define IOAPICADDR(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 8 +#define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12 + #define MASK_IRQ(irq_num) \ IMASK_LOCK ; /* into critical reg */ \ testl $IRQ_BIT(irq_num), _apic_imen ; \ jne 7f ; /* masked, don't mask */ \ orl $IRQ_BIT(irq_num), _apic_imen ; /* set the mask bit */ \ - movl _ioapic, %ecx ; /* ioapic[0] addr */ \ - movl $REDTBL_IDX(irq_num), (%ecx) ; /* write the index */ \ + movl IOAPICADDR(irq_num), %ecx ; /* ioapic addr */ \ + movl REDIRIDX(irq_num), %eax ; /* get the index */ \ + movl %eax, (%ecx) ; /* write the index */ \ movl IOAPIC_WINDOW(%ecx), %eax ; /* current value */ \ orl $IOART_INTMASK, %eax ; /* set the mask */ \ movl %eax, IOAPIC_WINDOW(%ecx) ; /* new value */ \ @@ -218,8 +222,9 @@ IDTVEC(vec_name) ; \ testl $IRQ_BIT(irq_num), _apic_imen ; \ je 7f ; /* bit clear, not masked */ \ andl $~IRQ_BIT(irq_num), _apic_imen ;/* clear mask bit */ \ - movl _ioapic,%ecx ; /* ioapic[0]addr */ \ - movl $REDTBL_IDX(irq_num),(%ecx) ; /* write the index */ \ + movl IOAPICADDR(irq_num),%ecx ; /* ioapic addr */ \ + movl REDIRIDX(irq_num), %eax ; /* get the index */ \ + movl %eax,(%ecx) ; /* write the index */ \ movl IOAPIC_WINDOW(%ecx),%eax ; /* current value */ \ andl $~IOART_INTMASK,%eax ; /* clear the mask */ \ movl %eax,IOAPIC_WINDOW(%ecx) ; /* new value */ \ @@ -990,7 +995,7 @@ CNAME(cpustop_restartfunc): .globl _apic_pin_trigger _apic_pin_trigger: - .space (NAPIC * 4), 0 + .long 0 /* diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c index 04e3c69..e00c2f4 100644 --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.78 1998/08/18 07:46:58 msmith Exp $ + * $Id: mp_machdep.c,v 1.79 1998/08/24 02:28:15 bde Exp $ */ #include "opt_smp.h" @@ -278,6 +278,8 @@ struct { } apic_isrbit_location[32]; #endif +struct apic_intmapinfo int_to_apicintpin[APIC_INTMAPSIZE]; + /* * APIC ID logical/physical mapping structures. * We oversize these to simplify boot-time config. @@ -315,7 +317,7 @@ extern pd_entry_t *my_idlePTD; struct pcb stoppcbs[NCPU]; -static int smp_started; /* has the system started? */ +int smp_started; /* has the system started? */ /* * Local data and functions. @@ -334,6 +336,7 @@ static int mptable_pass1(void); static int mptable_pass2(void); static void default_mp_table(int type); static void fix_mp_table(void); +static void setup_apic_irq_mapping(void); static void init_locks(void); static int start_all_aps(u_int boot_addr); static void install_ap_tramp(u_int boot_addr); @@ -569,6 +572,7 @@ mp_enable(u_int boot_addr) /* post scan cleanup */ fix_mp_table(); + setup_apic_irq_mapping(); #if defined(APIC_IO) @@ -675,6 +679,7 @@ typedef struct INTDATA { u_char src_bus_irq; u_char dst_apic_id; u_char dst_apic_int; + u_char int_vector; } io_int, local_int; typedef struct BUSTYPENAME { @@ -905,8 +910,10 @@ mptable_pass2(void) bus_data[x].bus_id = 0xff; /* clear IO APIC INT table */ - for (x = 0; x < NINTR; ++x) + for (x = 0; x < NINTR; ++x) { io_apic_ints[x].int_type = 0xff; + io_apic_ints[x].int_vector = 0xff; + } /* setup the cpu/apic mapping arrays */ boot_cpu_id = -1; @@ -966,6 +973,29 @@ mptable_pass2(void) } +static void +assign_apic_irq(int apic, int intpin, int irq) +{ + int x; + + if (int_to_apicintpin[irq].ioapic != -1) + panic("assign_apic_irq: inconsistent table"); + + int_to_apicintpin[irq].ioapic = apic; + int_to_apicintpin[irq].int_pin = intpin; + int_to_apicintpin[irq].apic_address = ioapic[apic]; + int_to_apicintpin[irq].redirindex = IOAPIC_REDTBL + 2 * intpin; + + for (x = 0; x < nintrs; x++) { + if ((io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3) && + io_apic_ints[x].int_vector == 0xff && + io_apic_ints[x].dst_apic_id == IO_TO_ID(apic) && + io_apic_ints[x].dst_apic_int == intpin) + io_apic_ints[x].int_vector = irq; + } +} + /* * parse an Intel MP specification table */ @@ -1041,6 +1071,50 @@ fix_mp_table(void) } +static void +setup_apic_irq_mapping(void) +{ + int x; + int int_vector; + + /* Assign low level interrupt handlers */ + for (x = 0; x < APIC_INTMAPSIZE; x++) { + int_to_apicintpin[x].ioapic = -1; + int_to_apicintpin[x].int_pin = 0; + int_to_apicintpin[x].apic_address = NULL; + int_to_apicintpin[x].redirindex = 0; + } + for (x = 0; x < nintrs; x++) { + if (io_apic_ints[x].dst_apic_int <= APIC_INTMAPSIZE && + io_apic_ints[x].dst_apic_id == IO_TO_ID(0) && + io_apic_ints[x].int_vector == 0xff && + (io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3)) { + assign_apic_irq(0, + io_apic_ints[x].dst_apic_int, + io_apic_ints[x].dst_apic_int); + } + } + int_vector = 0; + while (int_vector < APIC_INTMAPSIZE && + int_to_apicintpin[int_vector].ioapic != -1) + int_vector++; + for (x = 0; x < nintrs && int_vector < APIC_INTMAPSIZE; x++) { + if ((io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3) && + io_apic_ints[x].int_vector == 0xff) { + assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id), + io_apic_ints[x].dst_apic_int, + int_vector); + int_vector++; + while (int_vector < APIC_INTMAPSIZE && + int_to_apicintpin[int_vector].ioapic != -1) + int_vector++; + } + } +} + + static int processor_entry(proc_entry_ptr entry, int cpu) { @@ -1164,7 +1238,7 @@ isa_apic_mask(u_int isa_mask) return 0; --isa_irq; /* make it zero based */ - apic_pin = isa_apic_pin(isa_irq); /* look for APIC connection */ + apic_pin = isa_apic_irq(isa_irq); /* look for APIC connection */ if (apic_pin == -1) return 0; @@ -1177,10 +1251,12 @@ isa_apic_mask(u_int isa_mask) */ #define INTTYPE(I) (io_apic_ints[(I)].int_type) #define INTPIN(I) (io_apic_ints[(I)].dst_apic_int) +#define INTIRQ(I) (io_apic_ints[(I)].int_vector) +#define INTAPIC(I) (ID_TO_IO(io_apic_ints[(I)].dst_apic_id)) #define SRCBUSIRQ(I) (io_apic_ints[(I)].src_bus_irq) int -isa_apic_pin(int isa_irq) +isa_apic_irq(int isa_irq) { int intr; @@ -1189,7 +1265,7 @@ isa_apic_pin(int isa_irq) if (SRCBUSIRQ(intr) == isa_irq) { if (apic_int_is_bus_type(intr, ISA) || apic_int_is_bus_type(intr, EISA)) - return INTPIN(intr); /* found */ + return INTIRQ(intr); /* found */ } } } @@ -1204,7 +1280,7 @@ isa_apic_pin(int isa_irq) #define SRCBUSDEVICE(I) ((io_apic_ints[(I)].src_bus_irq >> 2) & 0x1f) #define SRCBUSLINE(I) (io_apic_ints[(I)].src_bus_irq & 0x03) int -pci_apic_pin(int pciBus, int pciDevice, int pciInt) +pci_apic_irq(int pciBus, int pciDevice, int pciInt) { int intr; @@ -1216,13 +1292,13 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt) && (SRCBUSDEVICE(intr) == pciDevice) && (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */ if (apic_int_is_bus_type(intr, PCI)) - return INTPIN(intr); /* exact match */ + return INTIRQ(intr); /* exact match */ return -1; /* NOT found */ } int -next_apic_pin(int pin) +next_apic_irq(int irq) { int intr, ointr; int bus, bustype; @@ -1230,7 +1306,7 @@ next_apic_pin(int pin) bus = 0; bustype = 0; for (intr = 0; intr < nintrs; intr++) { - if (INTPIN(intr) != pin || INTTYPE(intr) != 0) + if (INTIRQ(intr) != irq || INTTYPE(intr) != 0) continue; bus = SRCBUSID(intr); bustype = apic_bus_type(bus); @@ -1265,7 +1341,7 @@ next_apic_pin(int pin) if (ointr >= nintrs) { return -1; } - return INTPIN(ointr); + return INTIRQ(ointr); } #undef SRCBUSLINE #undef SRCBUSDEVICE @@ -1273,6 +1349,8 @@ next_apic_pin(int pin) #undef SRCBUSIRQ #undef INTPIN +#undef INTIRQ +#undef INTAPIC #undef INTTYPE @@ -1397,6 +1475,27 @@ apic_int_type(int apic, int pin) return -1; /* NOT found */ } +int +apic_irq(int apic, int pin) +{ + int x; + int res; + + for (x = 0; x < nintrs; ++x) + if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) && + (pin == io_apic_ints[x].dst_apic_int)) { + res = io_apic_ints[x].int_vector; + if (res == 0xff) + return -1; + if (apic != int_to_apicintpin[res].ioapic) + panic("apic_irq: inconsistent table"); + if (pin != int_to_apicintpin[res].int_pin) + panic("apic_irq inconsistent table (2)"); + return res; + } + return -1; +} + /* * given a LOGICAL APIC# and pin#, return: @@ -2127,9 +2226,11 @@ ap_init() * quite correct yet. We should have a bitfield for cpus willing * to accept TLB flush IPI's or something and sync them. */ - invltlb_ok = 1; - smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ - smp_active = 1; /* historic */ + if (smp_cpus == mp_ncpus) { + invltlb_ok = 1; + smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ + smp_active = 1; /* historic */ + } curproc = NULL; /* make sure */ } diff --git a/sys/i386/i386/mpapic.c b/sys/i386/i386/mpapic.c index a101a2c..48663a4 100644 --- a/sys/i386/i386/mpapic.c +++ b/sys/i386/i386/mpapic.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mpapic.c,v 1.30 1998/04/19 23:19:20 tegge Exp $ + * $Id: mpapic.c,v 1.31 1998/05/17 17:32:10 tegge Exp $ */ #include "opt_smp.h" @@ -146,7 +146,7 @@ static void polarity __P((int apic, int pin, u_int32_t * flags, int level)); /* * Setup the IO APIC. */ -extern int apic_pin_trigger[]; /* 'opaque' */ +extern int apic_pin_trigger; /* 'opaque' */ int io_apic_setup(int apic) { @@ -159,56 +159,55 @@ io_apic_setup(int apic) target = IOART_DEST; - apic_pin_trigger[apic] = 0; /* default to edge-triggered */ - - if (apic == 0) { - maxpin = REDIRCNT_IOAPIC(apic); /* pins in APIC */ - for (pin = 0; pin < maxpin; ++pin) { - int bus, bustype; - - /* we only deal with vectored INTs here */ - if (apic_int_type(apic, pin) != 0) - continue; - - /* determine the bus type for this pin */ - bus = apic_src_bus_id(apic, pin); - if (bus == -1) - continue; - bustype = apic_bus_type(bus); - - /* the "ISA" type INTerrupts */ - if ((bustype == ISA) && - (pin < IOAPIC_ISA_INTS) && - (isa_apic_pin(pin) == pin) && - (apic_polarity(apic, pin) == 0x1) && - (apic_trigger(apic, pin) == 0x3)) { - flags = DEFAULT_ISA_FLAGS; - } - - /* PCI or other bus */ - else { - flags = DEFAULT_FLAGS; - level = trigger(apic, pin, &flags); - if (level == 1) - apic_pin_trigger[apic] |= (1 << pin); - polarity(apic, pin, &flags, level); - } - - /* program the appropriate registers */ - select = pin * 2 + IOAPIC_REDTBL0; /* register */ - vector = NRSVIDT + pin; /* IDT vec */ - io_apic_write(apic, select, flags | vector); - io_apic_write(apic, select + 1, target); + if (apic == 0) + apic_pin_trigger = 0; /* default to edge-triggered */ + + maxpin = REDIRCNT_IOAPIC(apic); /* pins in APIC */ + printf("Programming %d pins in IOAPIC #%d\n", maxpin, apic); + + for (pin = 0; pin < maxpin; ++pin) { + int bus, bustype, irq; + + /* we only deal with vectored INTs here */ + if (apic_int_type(apic, pin) != 0) + continue; + + irq = apic_irq(apic, pin); + if (irq == 0xff) + continue; + + /* determine the bus type for this pin */ + bus = apic_src_bus_id(apic, pin); + if (bus == -1) + continue; + bustype = apic_bus_type(bus); + + /* the "ISA" type INTerrupts */ + if ((bustype == ISA) && + (pin < IOAPIC_ISA_INTS) && + (irq == pin) && + (apic_polarity(apic, pin) == 0x1) && + (apic_trigger(apic, pin) == 0x3)) { + flags = DEFAULT_ISA_FLAGS; } - } - - /* program entry according to MP table. */ - else { -#if defined(MULTIPLE_IOAPICS) -#error MULTIPLE_IOAPICSXXX -#else - panic("io_apic_setup: apic #%d", apic); -#endif/* MULTIPLE_IOAPICS */ + + /* PCI or other bus */ + else { + flags = DEFAULT_FLAGS; + level = trigger(apic, pin, &flags); + if (level == 1) + apic_pin_trigger |= (1 << irq); + polarity(apic, pin, &flags, level); + } + + /* program the appropriate registers */ + if (apic != 0 || pin != irq) + printf("IOAPIC #%d intpint %d -> irq %d\n", + apic, pin, irq); + select = pin * 2 + IOAPIC_REDTBL0; /* register */ + vector = NRSVIDT + irq; /* IDT vec */ + io_apic_write(apic, select, flags | vector); + io_apic_write(apic, select + 1, target); } /* return GOOD status */ diff --git a/sys/i386/i386/mpboot.s b/sys/i386/i386/mpboot.s index e3661f2..1c311fe 100644 --- a/sys/i386/i386/mpboot.s +++ b/sys/i386/i386/mpboot.s @@ -31,7 +31,7 @@ * mpboot.s: FreeBSD machine support for the Intel MP Spec * multiprocessor systems. * - * $Id: mpboot.s,v 1.5 1997/09/22 05:03:03 peter Exp $ + * $Id: mpboot.s,v 1.6 1997/10/10 09:44:05 peter Exp $ */ #include "opt_vm86.h" @@ -124,6 +124,12 @@ mp_begin: /* now running relocated at KERNBASE */ /* Now, let's prepare for some REAL WORK :-) */ call _ap_init + call _rel_mplock +2: + cmpl $0, CNAME(smp_started) /* Wait for last AP to be ready */ + jz 2b + call _get_mplock + /* let her rip! (loads new stack) */ jmp _cpu_switch diff --git a/sys/i386/i386/mptable.c b/sys/i386/i386/mptable.c index 04e3c69..e00c2f4 100644 --- a/sys/i386/i386/mptable.c +++ b/sys/i386/i386/mptable.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.78 1998/08/18 07:46:58 msmith Exp $ + * $Id: mp_machdep.c,v 1.79 1998/08/24 02:28:15 bde Exp $ */ #include "opt_smp.h" @@ -278,6 +278,8 @@ struct { } apic_isrbit_location[32]; #endif +struct apic_intmapinfo int_to_apicintpin[APIC_INTMAPSIZE]; + /* * APIC ID logical/physical mapping structures. * We oversize these to simplify boot-time config. @@ -315,7 +317,7 @@ extern pd_entry_t *my_idlePTD; struct pcb stoppcbs[NCPU]; -static int smp_started; /* has the system started? */ +int smp_started; /* has the system started? */ /* * Local data and functions. @@ -334,6 +336,7 @@ static int mptable_pass1(void); static int mptable_pass2(void); static void default_mp_table(int type); static void fix_mp_table(void); +static void setup_apic_irq_mapping(void); static void init_locks(void); static int start_all_aps(u_int boot_addr); static void install_ap_tramp(u_int boot_addr); @@ -569,6 +572,7 @@ mp_enable(u_int boot_addr) /* post scan cleanup */ fix_mp_table(); + setup_apic_irq_mapping(); #if defined(APIC_IO) @@ -675,6 +679,7 @@ typedef struct INTDATA { u_char src_bus_irq; u_char dst_apic_id; u_char dst_apic_int; + u_char int_vector; } io_int, local_int; typedef struct BUSTYPENAME { @@ -905,8 +910,10 @@ mptable_pass2(void) bus_data[x].bus_id = 0xff; /* clear IO APIC INT table */ - for (x = 0; x < NINTR; ++x) + for (x = 0; x < NINTR; ++x) { io_apic_ints[x].int_type = 0xff; + io_apic_ints[x].int_vector = 0xff; + } /* setup the cpu/apic mapping arrays */ boot_cpu_id = -1; @@ -966,6 +973,29 @@ mptable_pass2(void) } +static void +assign_apic_irq(int apic, int intpin, int irq) +{ + int x; + + if (int_to_apicintpin[irq].ioapic != -1) + panic("assign_apic_irq: inconsistent table"); + + int_to_apicintpin[irq].ioapic = apic; + int_to_apicintpin[irq].int_pin = intpin; + int_to_apicintpin[irq].apic_address = ioapic[apic]; + int_to_apicintpin[irq].redirindex = IOAPIC_REDTBL + 2 * intpin; + + for (x = 0; x < nintrs; x++) { + if ((io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3) && + io_apic_ints[x].int_vector == 0xff && + io_apic_ints[x].dst_apic_id == IO_TO_ID(apic) && + io_apic_ints[x].dst_apic_int == intpin) + io_apic_ints[x].int_vector = irq; + } +} + /* * parse an Intel MP specification table */ @@ -1041,6 +1071,50 @@ fix_mp_table(void) } +static void +setup_apic_irq_mapping(void) +{ + int x; + int int_vector; + + /* Assign low level interrupt handlers */ + for (x = 0; x < APIC_INTMAPSIZE; x++) { + int_to_apicintpin[x].ioapic = -1; + int_to_apicintpin[x].int_pin = 0; + int_to_apicintpin[x].apic_address = NULL; + int_to_apicintpin[x].redirindex = 0; + } + for (x = 0; x < nintrs; x++) { + if (io_apic_ints[x].dst_apic_int <= APIC_INTMAPSIZE && + io_apic_ints[x].dst_apic_id == IO_TO_ID(0) && + io_apic_ints[x].int_vector == 0xff && + (io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3)) { + assign_apic_irq(0, + io_apic_ints[x].dst_apic_int, + io_apic_ints[x].dst_apic_int); + } + } + int_vector = 0; + while (int_vector < APIC_INTMAPSIZE && + int_to_apicintpin[int_vector].ioapic != -1) + int_vector++; + for (x = 0; x < nintrs && int_vector < APIC_INTMAPSIZE; x++) { + if ((io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3) && + io_apic_ints[x].int_vector == 0xff) { + assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id), + io_apic_ints[x].dst_apic_int, + int_vector); + int_vector++; + while (int_vector < APIC_INTMAPSIZE && + int_to_apicintpin[int_vector].ioapic != -1) + int_vector++; + } + } +} + + static int processor_entry(proc_entry_ptr entry, int cpu) { @@ -1164,7 +1238,7 @@ isa_apic_mask(u_int isa_mask) return 0; --isa_irq; /* make it zero based */ - apic_pin = isa_apic_pin(isa_irq); /* look for APIC connection */ + apic_pin = isa_apic_irq(isa_irq); /* look for APIC connection */ if (apic_pin == -1) return 0; @@ -1177,10 +1251,12 @@ isa_apic_mask(u_int isa_mask) */ #define INTTYPE(I) (io_apic_ints[(I)].int_type) #define INTPIN(I) (io_apic_ints[(I)].dst_apic_int) +#define INTIRQ(I) (io_apic_ints[(I)].int_vector) +#define INTAPIC(I) (ID_TO_IO(io_apic_ints[(I)].dst_apic_id)) #define SRCBUSIRQ(I) (io_apic_ints[(I)].src_bus_irq) int -isa_apic_pin(int isa_irq) +isa_apic_irq(int isa_irq) { int intr; @@ -1189,7 +1265,7 @@ isa_apic_pin(int isa_irq) if (SRCBUSIRQ(intr) == isa_irq) { if (apic_int_is_bus_type(intr, ISA) || apic_int_is_bus_type(intr, EISA)) - return INTPIN(intr); /* found */ + return INTIRQ(intr); /* found */ } } } @@ -1204,7 +1280,7 @@ isa_apic_pin(int isa_irq) #define SRCBUSDEVICE(I) ((io_apic_ints[(I)].src_bus_irq >> 2) & 0x1f) #define SRCBUSLINE(I) (io_apic_ints[(I)].src_bus_irq & 0x03) int -pci_apic_pin(int pciBus, int pciDevice, int pciInt) +pci_apic_irq(int pciBus, int pciDevice, int pciInt) { int intr; @@ -1216,13 +1292,13 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt) && (SRCBUSDEVICE(intr) == pciDevice) && (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */ if (apic_int_is_bus_type(intr, PCI)) - return INTPIN(intr); /* exact match */ + return INTIRQ(intr); /* exact match */ return -1; /* NOT found */ } int -next_apic_pin(int pin) +next_apic_irq(int irq) { int intr, ointr; int bus, bustype; @@ -1230,7 +1306,7 @@ next_apic_pin(int pin) bus = 0; bustype = 0; for (intr = 0; intr < nintrs; intr++) { - if (INTPIN(intr) != pin || INTTYPE(intr) != 0) + if (INTIRQ(intr) != irq || INTTYPE(intr) != 0) continue; bus = SRCBUSID(intr); bustype = apic_bus_type(bus); @@ -1265,7 +1341,7 @@ next_apic_pin(int pin) if (ointr >= nintrs) { return -1; } - return INTPIN(ointr); + return INTIRQ(ointr); } #undef SRCBUSLINE #undef SRCBUSDEVICE @@ -1273,6 +1349,8 @@ next_apic_pin(int pin) #undef SRCBUSIRQ #undef INTPIN +#undef INTIRQ +#undef INTAPIC #undef INTTYPE @@ -1397,6 +1475,27 @@ apic_int_type(int apic, int pin) return -1; /* NOT found */ } +int +apic_irq(int apic, int pin) +{ + int x; + int res; + + for (x = 0; x < nintrs; ++x) + if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) && + (pin == io_apic_ints[x].dst_apic_int)) { + res = io_apic_ints[x].int_vector; + if (res == 0xff) + return -1; + if (apic != int_to_apicintpin[res].ioapic) + panic("apic_irq: inconsistent table"); + if (pin != int_to_apicintpin[res].int_pin) + panic("apic_irq inconsistent table (2)"); + return res; + } + return -1; +} + /* * given a LOGICAL APIC# and pin#, return: @@ -2127,9 +2226,11 @@ ap_init() * quite correct yet. We should have a bitfield for cpus willing * to accept TLB flush IPI's or something and sync them. */ - invltlb_ok = 1; - smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ - smp_active = 1; /* historic */ + if (smp_cpus == mp_ncpus) { + invltlb_ok = 1; + smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ + smp_active = 1; /* historic */ + } curproc = NULL; /* make sure */ } diff --git a/sys/i386/i386/tsc.c b/sys/i386/i386/tsc.c index 4e14052..3d8f8cd 100644 --- a/sys/i386/i386/tsc.c +++ b/sys/i386/i386/tsc.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.123 1998/06/07 20:36:39 phk Exp $ + * $Id: clock.c,v 1.124 1998/06/09 13:10:46 phk Exp $ */ /* @@ -953,7 +953,7 @@ cpu_initclocks() /* Finish initializing 8253 timer 0. */ #ifdef APIC_IO - apic_8254_intr = isa_apic_pin(0); + apic_8254_intr = isa_apic_irq(0); apic_8254_trial = 0; if (apic_8254_intr >= 0 ) { if (apic_int_type(0, 0) == 3) @@ -993,7 +993,7 @@ cpu_initclocks() printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); #ifdef APIC_IO - if (isa_apic_pin(8) != 8) + if (isa_apic_irq(8) != 8) panic("APIC RTC != 8"); #endif /* APIC_IO */ diff --git a/sys/i386/include/apic.h b/sys/i386/include/apic.h index 50f8416..55e44e0 100644 --- a/sys/i386/include/apic.h +++ b/sys/i386/include/apic.h @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: apic.h,v 1.7 1997/08/04 17:20:39 smp Exp smp $ + * $Id: apic.h,v 1.11 1997/08/04 17:31:24 fsmp Exp $ */ #ifndef _MACHINE_APIC_H_ @@ -113,12 +113,6 @@ * global defines, etc. */ -/** - * this enables code concerned with handling more than one IO APIC. - * Note: this is NOT READY for use! - * -#define MULTIPLE_IOAPICS - */ /****************************************************************************** * LOCAL APIC structure diff --git a/sys/i386/include/apicreg.h b/sys/i386/include/apicreg.h index 50f8416..55e44e0 100644 --- a/sys/i386/include/apicreg.h +++ b/sys/i386/include/apicreg.h @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: apic.h,v 1.7 1997/08/04 17:20:39 smp Exp smp $ + * $Id: apic.h,v 1.11 1997/08/04 17:31:24 fsmp Exp $ */ #ifndef _MACHINE_APIC_H_ @@ -113,12 +113,6 @@ * global defines, etc. */ -/** - * this enables code concerned with handling more than one IO APIC. - * Note: this is NOT READY for use! - * -#define MULTIPLE_IOAPICS - */ /****************************************************************************** * LOCAL APIC structure diff --git a/sys/i386/include/mptable.h b/sys/i386/include/mptable.h index 04e3c69..e00c2f4 100644 --- a/sys/i386/include/mptable.h +++ b/sys/i386/include/mptable.h @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.78 1998/08/18 07:46:58 msmith Exp $ + * $Id: mp_machdep.c,v 1.79 1998/08/24 02:28:15 bde Exp $ */ #include "opt_smp.h" @@ -278,6 +278,8 @@ struct { } apic_isrbit_location[32]; #endif +struct apic_intmapinfo int_to_apicintpin[APIC_INTMAPSIZE]; + /* * APIC ID logical/physical mapping structures. * We oversize these to simplify boot-time config. @@ -315,7 +317,7 @@ extern pd_entry_t *my_idlePTD; struct pcb stoppcbs[NCPU]; -static int smp_started; /* has the system started? */ +int smp_started; /* has the system started? */ /* * Local data and functions. @@ -334,6 +336,7 @@ static int mptable_pass1(void); static int mptable_pass2(void); static void default_mp_table(int type); static void fix_mp_table(void); +static void setup_apic_irq_mapping(void); static void init_locks(void); static int start_all_aps(u_int boot_addr); static void install_ap_tramp(u_int boot_addr); @@ -569,6 +572,7 @@ mp_enable(u_int boot_addr) /* post scan cleanup */ fix_mp_table(); + setup_apic_irq_mapping(); #if defined(APIC_IO) @@ -675,6 +679,7 @@ typedef struct INTDATA { u_char src_bus_irq; u_char dst_apic_id; u_char dst_apic_int; + u_char int_vector; } io_int, local_int; typedef struct BUSTYPENAME { @@ -905,8 +910,10 @@ mptable_pass2(void) bus_data[x].bus_id = 0xff; /* clear IO APIC INT table */ - for (x = 0; x < NINTR; ++x) + for (x = 0; x < NINTR; ++x) { io_apic_ints[x].int_type = 0xff; + io_apic_ints[x].int_vector = 0xff; + } /* setup the cpu/apic mapping arrays */ boot_cpu_id = -1; @@ -966,6 +973,29 @@ mptable_pass2(void) } +static void +assign_apic_irq(int apic, int intpin, int irq) +{ + int x; + + if (int_to_apicintpin[irq].ioapic != -1) + panic("assign_apic_irq: inconsistent table"); + + int_to_apicintpin[irq].ioapic = apic; + int_to_apicintpin[irq].int_pin = intpin; + int_to_apicintpin[irq].apic_address = ioapic[apic]; + int_to_apicintpin[irq].redirindex = IOAPIC_REDTBL + 2 * intpin; + + for (x = 0; x < nintrs; x++) { + if ((io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3) && + io_apic_ints[x].int_vector == 0xff && + io_apic_ints[x].dst_apic_id == IO_TO_ID(apic) && + io_apic_ints[x].dst_apic_int == intpin) + io_apic_ints[x].int_vector = irq; + } +} + /* * parse an Intel MP specification table */ @@ -1041,6 +1071,50 @@ fix_mp_table(void) } +static void +setup_apic_irq_mapping(void) +{ + int x; + int int_vector; + + /* Assign low level interrupt handlers */ + for (x = 0; x < APIC_INTMAPSIZE; x++) { + int_to_apicintpin[x].ioapic = -1; + int_to_apicintpin[x].int_pin = 0; + int_to_apicintpin[x].apic_address = NULL; + int_to_apicintpin[x].redirindex = 0; + } + for (x = 0; x < nintrs; x++) { + if (io_apic_ints[x].dst_apic_int <= APIC_INTMAPSIZE && + io_apic_ints[x].dst_apic_id == IO_TO_ID(0) && + io_apic_ints[x].int_vector == 0xff && + (io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3)) { + assign_apic_irq(0, + io_apic_ints[x].dst_apic_int, + io_apic_ints[x].dst_apic_int); + } + } + int_vector = 0; + while (int_vector < APIC_INTMAPSIZE && + int_to_apicintpin[int_vector].ioapic != -1) + int_vector++; + for (x = 0; x < nintrs && int_vector < APIC_INTMAPSIZE; x++) { + if ((io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3) && + io_apic_ints[x].int_vector == 0xff) { + assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id), + io_apic_ints[x].dst_apic_int, + int_vector); + int_vector++; + while (int_vector < APIC_INTMAPSIZE && + int_to_apicintpin[int_vector].ioapic != -1) + int_vector++; + } + } +} + + static int processor_entry(proc_entry_ptr entry, int cpu) { @@ -1164,7 +1238,7 @@ isa_apic_mask(u_int isa_mask) return 0; --isa_irq; /* make it zero based */ - apic_pin = isa_apic_pin(isa_irq); /* look for APIC connection */ + apic_pin = isa_apic_irq(isa_irq); /* look for APIC connection */ if (apic_pin == -1) return 0; @@ -1177,10 +1251,12 @@ isa_apic_mask(u_int isa_mask) */ #define INTTYPE(I) (io_apic_ints[(I)].int_type) #define INTPIN(I) (io_apic_ints[(I)].dst_apic_int) +#define INTIRQ(I) (io_apic_ints[(I)].int_vector) +#define INTAPIC(I) (ID_TO_IO(io_apic_ints[(I)].dst_apic_id)) #define SRCBUSIRQ(I) (io_apic_ints[(I)].src_bus_irq) int -isa_apic_pin(int isa_irq) +isa_apic_irq(int isa_irq) { int intr; @@ -1189,7 +1265,7 @@ isa_apic_pin(int isa_irq) if (SRCBUSIRQ(intr) == isa_irq) { if (apic_int_is_bus_type(intr, ISA) || apic_int_is_bus_type(intr, EISA)) - return INTPIN(intr); /* found */ + return INTIRQ(intr); /* found */ } } } @@ -1204,7 +1280,7 @@ isa_apic_pin(int isa_irq) #define SRCBUSDEVICE(I) ((io_apic_ints[(I)].src_bus_irq >> 2) & 0x1f) #define SRCBUSLINE(I) (io_apic_ints[(I)].src_bus_irq & 0x03) int -pci_apic_pin(int pciBus, int pciDevice, int pciInt) +pci_apic_irq(int pciBus, int pciDevice, int pciInt) { int intr; @@ -1216,13 +1292,13 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt) && (SRCBUSDEVICE(intr) == pciDevice) && (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */ if (apic_int_is_bus_type(intr, PCI)) - return INTPIN(intr); /* exact match */ + return INTIRQ(intr); /* exact match */ return -1; /* NOT found */ } int -next_apic_pin(int pin) +next_apic_irq(int irq) { int intr, ointr; int bus, bustype; @@ -1230,7 +1306,7 @@ next_apic_pin(int pin) bus = 0; bustype = 0; for (intr = 0; intr < nintrs; intr++) { - if (INTPIN(intr) != pin || INTTYPE(intr) != 0) + if (INTIRQ(intr) != irq || INTTYPE(intr) != 0) continue; bus = SRCBUSID(intr); bustype = apic_bus_type(bus); @@ -1265,7 +1341,7 @@ next_apic_pin(int pin) if (ointr >= nintrs) { return -1; } - return INTPIN(ointr); + return INTIRQ(ointr); } #undef SRCBUSLINE #undef SRCBUSDEVICE @@ -1273,6 +1349,8 @@ next_apic_pin(int pin) #undef SRCBUSIRQ #undef INTPIN +#undef INTIRQ +#undef INTAPIC #undef INTTYPE @@ -1397,6 +1475,27 @@ apic_int_type(int apic, int pin) return -1; /* NOT found */ } +int +apic_irq(int apic, int pin) +{ + int x; + int res; + + for (x = 0; x < nintrs; ++x) + if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) && + (pin == io_apic_ints[x].dst_apic_int)) { + res = io_apic_ints[x].int_vector; + if (res == 0xff) + return -1; + if (apic != int_to_apicintpin[res].ioapic) + panic("apic_irq: inconsistent table"); + if (pin != int_to_apicintpin[res].int_pin) + panic("apic_irq inconsistent table (2)"); + return res; + } + return -1; +} + /* * given a LOGICAL APIC# and pin#, return: @@ -2127,9 +2226,11 @@ ap_init() * quite correct yet. We should have a bitfield for cpus willing * to accept TLB flush IPI's or something and sync them. */ - invltlb_ok = 1; - smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ - smp_active = 1; /* historic */ + if (smp_cpus == mp_ncpus) { + invltlb_ok = 1; + smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ + smp_active = 1; /* historic */ + } curproc = NULL; /* make sure */ } diff --git a/sys/i386/include/smp.h b/sys/i386/include/smp.h index f258630..0f4f915 100644 --- a/sys/i386/include/smp.h +++ b/sys/i386/include/smp.h @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: smp.h,v 1.42 1998/04/01 21:07:36 tegge Exp $ + * $Id: smp.h,v 1.43 1998/05/17 22:12:05 tegge Exp $ * */ @@ -103,6 +103,14 @@ extern u_int32_t io_apic_versions[]; extern int cpu_num_to_apic_id[]; extern int io_num_to_apic_id[]; extern int apic_id_to_logical[]; +#define APIC_INTMAPSIZE 24 +struct apic_intmapinfo { + int ioapic; + int int_pin; + volatile void *apic_address; + int redirindex; +}; +extern struct apic_intmapinfo int_to_apicintpin[]; extern u_int all_cpus; extern u_char SMP_ioapic[]; extern struct pcb stoppcbs[]; @@ -113,9 +121,10 @@ int mp_probe __P((void)); void mp_start __P((void)); void mp_announce __P((void)); u_int isa_apic_mask __P((u_int)); -int isa_apic_pin __P((int)); -int pci_apic_pin __P((int, int, int)); -int next_apic_pin __P((int)); +int isa_apic_irq __P((int)); +int pci_apic_irq __P((int, int, int)); +int apic_irq __P((int, int)); +int next_apic_irq __P((int)); int undirect_isa_irq __P((int)); int undirect_pci_irq __P((int)); int apic_bus_type __P((int)); @@ -141,12 +150,7 @@ void set_lapic_isrloc __P((int, int)); /* global data in mpapic.c */ extern volatile lapic_t lapic; - -#if defined(MULTIPLE_IOAPICS) -#error MULTIPLE_IOAPICSXXX -#else extern volatile ioapic_t *ioapic[]; -#endif /* MULTIPLE_IOAPICS */ /* functions in mpapic.c */ void apic_dump __P((char*)); diff --git a/sys/i386/isa/apic_ipl.s b/sys/i386/isa/apic_ipl.s index 5bbdca6..8d9b9d8 100644 --- a/sys/i386/isa/apic_ipl.s +++ b/sys/i386/isa/apic_ipl.s @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: apic_ipl.s,v 1.20 1998/04/22 22:49:29 tegge Exp $ + * $Id: apic_ipl.s,v 1.21 1998/08/11 15:08:12 bde Exp $ */ @@ -227,7 +227,6 @@ bad_mask: .asciz "bad mask" #endif /* - * MULTIPLE_IOAPICSXXX: cannot assume apic #0 in the following function. * (soon to be) MP-safe function to clear ONE INT mask bit. * The passed arg is a 32bit u_int MASK. * It sets the associated bit in _apic_imen. @@ -244,10 +243,9 @@ ENTRY(INTREN) QUALIFY_MASK - leal 16(,%ecx,2), %ecx /* calculate register index */ - - movl $0, %edx /* XXX FIXME: APIC # */ - movl _ioapic(,%edx,4), %edx /* %edx holds APIC base address */ + shll $4, %ecx + movl CNAME(int_to_apicintpin) + 8(%ecx), %edx + movl CNAME(int_to_apicintpin) + 12(%ecx), %ecx movl %ecx, (%edx) /* write the target register index */ movl 16(%edx), %eax /* read the target register data */ @@ -259,7 +257,6 @@ ENTRY(INTREN) ret /* - * MULTIPLE_IOAPICSXXX: cannot assume apic #0 in the following function. * (soon to be) MP-safe function to set ONE INT mask bit. * The passed arg is a 32bit u_int MASK. * It clears the associated bit in _apic_imen. @@ -276,10 +273,9 @@ ENTRY(INTRDIS) QUALIFY_MASK - leal 16(,%ecx,2), %ecx /* calculate register index */ - - movl $0, %edx /* XXX FIXME: APIC # */ - movl _ioapic(,%edx,4), %edx /* %edx holds APIC base address */ + shll $4, %ecx + movl CNAME(int_to_apicintpin) + 8(%ecx), %edx + movl CNAME(int_to_apicintpin) + 12(%ecx), %ecx movl %ecx, (%edx) /* write the target register index */ movl 16(%edx), %eax /* read the target register data */ diff --git a/sys/i386/isa/apic_vector.s b/sys/i386/isa/apic_vector.s index 4bd4f77..17f8942 100644 --- a/sys/i386/isa/apic_vector.s +++ b/sys/i386/isa/apic_vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: apic_vector.s,v 1.32 1998/08/11 17:01:32 bde Exp $ + * $Id: apic_vector.s,v 1.33 1998/09/04 23:03:04 luoqi Exp $ */ @@ -166,13 +166,17 @@ IDTVEC(vec_name) ; \ popal ; \ addl $4+4,%esp +#define IOAPICADDR(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 8 +#define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12 + #define MASK_IRQ(irq_num) \ IMASK_LOCK ; /* into critical reg */ \ testl $IRQ_BIT(irq_num), _apic_imen ; \ jne 7f ; /* masked, don't mask */ \ orl $IRQ_BIT(irq_num), _apic_imen ; /* set the mask bit */ \ - movl _ioapic, %ecx ; /* ioapic[0] addr */ \ - movl $REDTBL_IDX(irq_num), (%ecx) ; /* write the index */ \ + movl IOAPICADDR(irq_num), %ecx ; /* ioapic addr */ \ + movl REDIRIDX(irq_num), %eax ; /* get the index */ \ + movl %eax, (%ecx) ; /* write the index */ \ movl IOAPIC_WINDOW(%ecx), %eax ; /* current value */ \ orl $IOART_INTMASK, %eax ; /* set the mask */ \ movl %eax, IOAPIC_WINDOW(%ecx) ; /* new value */ \ @@ -218,8 +222,9 @@ IDTVEC(vec_name) ; \ testl $IRQ_BIT(irq_num), _apic_imen ; \ je 7f ; /* bit clear, not masked */ \ andl $~IRQ_BIT(irq_num), _apic_imen ;/* clear mask bit */ \ - movl _ioapic,%ecx ; /* ioapic[0]addr */ \ - movl $REDTBL_IDX(irq_num),(%ecx) ; /* write the index */ \ + movl IOAPICADDR(irq_num),%ecx ; /* ioapic addr */ \ + movl REDIRIDX(irq_num), %eax ; /* get the index */ \ + movl %eax,(%ecx) ; /* write the index */ \ movl IOAPIC_WINDOW(%ecx),%eax ; /* current value */ \ andl $~IOART_INTMASK,%eax ; /* clear the mask */ \ movl %eax,IOAPIC_WINDOW(%ecx) ; /* new value */ \ @@ -990,7 +995,7 @@ CNAME(cpustop_restartfunc): .globl _apic_pin_trigger _apic_pin_trigger: - .space (NAPIC * 4), 0 + .long 0 /* diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c index 4e14052..3d8f8cd 100644 --- a/sys/i386/isa/clock.c +++ b/sys/i386/isa/clock.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.123 1998/06/07 20:36:39 phk Exp $ + * $Id: clock.c,v 1.124 1998/06/09 13:10:46 phk Exp $ */ /* @@ -953,7 +953,7 @@ cpu_initclocks() /* Finish initializing 8253 timer 0. */ #ifdef APIC_IO - apic_8254_intr = isa_apic_pin(0); + apic_8254_intr = isa_apic_irq(0); apic_8254_trial = 0; if (apic_8254_intr >= 0 ) { if (apic_int_type(0, 0) == 3) @@ -993,7 +993,7 @@ cpu_initclocks() printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); #ifdef APIC_IO - if (isa_apic_pin(8) != 8) + if (isa_apic_irq(8) != 8) panic("APIC RTC != 8"); #endif /* APIC_IO */ diff --git a/sys/i386/isa/intr_machdep.c b/sys/i386/isa/intr_machdep.c index 49c7f24..3f891f2 100644 --- a/sys/i386/isa/intr_machdep.c +++ b/sys/i386/isa/intr_machdep.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.12 1998/06/18 15:32:06 bde Exp $ + * $Id: intr_machdep.c,v 1.13 1998/06/18 16:08:46 bde Exp $ */ #include "opt_auto_eoi.h" @@ -429,12 +429,15 @@ icu_setup(int intr, inthand2_t *handler, void *arg, u_int *maskptr, int flags) set_lapic_isrloc(intr, vector); #endif /* - * XXX MULTIPLE_IOAPICSXXX * Reprogram the vector in the IO APIC. */ - select = (intr * 2) + IOAPIC_REDTBL0; - value = io_apic_read(0, select) & ~IOART_INTVEC; - io_apic_write(0, select, value | vector); + if (int_to_apicintpin[intr].ioapic >= 0) { + select = int_to_apicintpin[intr].redirindex; + value = io_apic_read(int_to_apicintpin[intr].ioapic, + select) & ~IOART_INTVEC; + io_apic_write(int_to_apicintpin[intr].ioapic, + select, value | vector); + } #else setidt(ICU_OFFSET + intr, flags & INTR_FAST ? fastintr[intr] : slowintr[intr], diff --git a/sys/i386/isa/nmi.c b/sys/i386/isa/nmi.c index 49c7f24..3f891f2 100644 --- a/sys/i386/isa/nmi.c +++ b/sys/i386/isa/nmi.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.12 1998/06/18 15:32:06 bde Exp $ + * $Id: intr_machdep.c,v 1.13 1998/06/18 16:08:46 bde Exp $ */ #include "opt_auto_eoi.h" @@ -429,12 +429,15 @@ icu_setup(int intr, inthand2_t *handler, void *arg, u_int *maskptr, int flags) set_lapic_isrloc(intr, vector); #endif /* - * XXX MULTIPLE_IOAPICSXXX * Reprogram the vector in the IO APIC. */ - select = (intr * 2) + IOAPIC_REDTBL0; - value = io_apic_read(0, select) & ~IOART_INTVEC; - io_apic_write(0, select, value | vector); + if (int_to_apicintpin[intr].ioapic >= 0) { + select = int_to_apicintpin[intr].redirindex; + value = io_apic_read(int_to_apicintpin[intr].ioapic, + select) & ~IOART_INTVEC; + io_apic_write(int_to_apicintpin[intr].ioapic, + select, value | vector); + } #else setidt(ICU_OFFSET + intr, flags & INTR_FAST ? fastintr[intr] : slowintr[intr], diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c index 4e14052..3d8f8cd 100644 --- a/sys/isa/atrtc.c +++ b/sys/isa/atrtc.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 - * $Id: clock.c,v 1.123 1998/06/07 20:36:39 phk Exp $ + * $Id: clock.c,v 1.124 1998/06/09 13:10:46 phk Exp $ */ /* @@ -953,7 +953,7 @@ cpu_initclocks() /* Finish initializing 8253 timer 0. */ #ifdef APIC_IO - apic_8254_intr = isa_apic_pin(0); + apic_8254_intr = isa_apic_irq(0); apic_8254_trial = 0; if (apic_8254_intr >= 0 ) { if (apic_int_type(0, 0) == 3) @@ -993,7 +993,7 @@ cpu_initclocks() printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); #ifdef APIC_IO - if (isa_apic_pin(8) != 8) + if (isa_apic_irq(8) != 8) panic("APIC RTC != 8"); #endif /* APIC_IO */ diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c index 04e3c69..e00c2f4 100644 --- a/sys/kern/subr_smp.c +++ b/sys/kern/subr_smp.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mp_machdep.c,v 1.78 1998/08/18 07:46:58 msmith Exp $ + * $Id: mp_machdep.c,v 1.79 1998/08/24 02:28:15 bde Exp $ */ #include "opt_smp.h" @@ -278,6 +278,8 @@ struct { } apic_isrbit_location[32]; #endif +struct apic_intmapinfo int_to_apicintpin[APIC_INTMAPSIZE]; + /* * APIC ID logical/physical mapping structures. * We oversize these to simplify boot-time config. @@ -315,7 +317,7 @@ extern pd_entry_t *my_idlePTD; struct pcb stoppcbs[NCPU]; -static int smp_started; /* has the system started? */ +int smp_started; /* has the system started? */ /* * Local data and functions. @@ -334,6 +336,7 @@ static int mptable_pass1(void); static int mptable_pass2(void); static void default_mp_table(int type); static void fix_mp_table(void); +static void setup_apic_irq_mapping(void); static void init_locks(void); static int start_all_aps(u_int boot_addr); static void install_ap_tramp(u_int boot_addr); @@ -569,6 +572,7 @@ mp_enable(u_int boot_addr) /* post scan cleanup */ fix_mp_table(); + setup_apic_irq_mapping(); #if defined(APIC_IO) @@ -675,6 +679,7 @@ typedef struct INTDATA { u_char src_bus_irq; u_char dst_apic_id; u_char dst_apic_int; + u_char int_vector; } io_int, local_int; typedef struct BUSTYPENAME { @@ -905,8 +910,10 @@ mptable_pass2(void) bus_data[x].bus_id = 0xff; /* clear IO APIC INT table */ - for (x = 0; x < NINTR; ++x) + for (x = 0; x < NINTR; ++x) { io_apic_ints[x].int_type = 0xff; + io_apic_ints[x].int_vector = 0xff; + } /* setup the cpu/apic mapping arrays */ boot_cpu_id = -1; @@ -966,6 +973,29 @@ mptable_pass2(void) } +static void +assign_apic_irq(int apic, int intpin, int irq) +{ + int x; + + if (int_to_apicintpin[irq].ioapic != -1) + panic("assign_apic_irq: inconsistent table"); + + int_to_apicintpin[irq].ioapic = apic; + int_to_apicintpin[irq].int_pin = intpin; + int_to_apicintpin[irq].apic_address = ioapic[apic]; + int_to_apicintpin[irq].redirindex = IOAPIC_REDTBL + 2 * intpin; + + for (x = 0; x < nintrs; x++) { + if ((io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3) && + io_apic_ints[x].int_vector == 0xff && + io_apic_ints[x].dst_apic_id == IO_TO_ID(apic) && + io_apic_ints[x].dst_apic_int == intpin) + io_apic_ints[x].int_vector = irq; + } +} + /* * parse an Intel MP specification table */ @@ -1041,6 +1071,50 @@ fix_mp_table(void) } +static void +setup_apic_irq_mapping(void) +{ + int x; + int int_vector; + + /* Assign low level interrupt handlers */ + for (x = 0; x < APIC_INTMAPSIZE; x++) { + int_to_apicintpin[x].ioapic = -1; + int_to_apicintpin[x].int_pin = 0; + int_to_apicintpin[x].apic_address = NULL; + int_to_apicintpin[x].redirindex = 0; + } + for (x = 0; x < nintrs; x++) { + if (io_apic_ints[x].dst_apic_int <= APIC_INTMAPSIZE && + io_apic_ints[x].dst_apic_id == IO_TO_ID(0) && + io_apic_ints[x].int_vector == 0xff && + (io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3)) { + assign_apic_irq(0, + io_apic_ints[x].dst_apic_int, + io_apic_ints[x].dst_apic_int); + } + } + int_vector = 0; + while (int_vector < APIC_INTMAPSIZE && + int_to_apicintpin[int_vector].ioapic != -1) + int_vector++; + for (x = 0; x < nintrs && int_vector < APIC_INTMAPSIZE; x++) { + if ((io_apic_ints[x].int_type == 0 || + io_apic_ints[x].int_type == 3) && + io_apic_ints[x].int_vector == 0xff) { + assign_apic_irq(ID_TO_IO(io_apic_ints[x].dst_apic_id), + io_apic_ints[x].dst_apic_int, + int_vector); + int_vector++; + while (int_vector < APIC_INTMAPSIZE && + int_to_apicintpin[int_vector].ioapic != -1) + int_vector++; + } + } +} + + static int processor_entry(proc_entry_ptr entry, int cpu) { @@ -1164,7 +1238,7 @@ isa_apic_mask(u_int isa_mask) return 0; --isa_irq; /* make it zero based */ - apic_pin = isa_apic_pin(isa_irq); /* look for APIC connection */ + apic_pin = isa_apic_irq(isa_irq); /* look for APIC connection */ if (apic_pin == -1) return 0; @@ -1177,10 +1251,12 @@ isa_apic_mask(u_int isa_mask) */ #define INTTYPE(I) (io_apic_ints[(I)].int_type) #define INTPIN(I) (io_apic_ints[(I)].dst_apic_int) +#define INTIRQ(I) (io_apic_ints[(I)].int_vector) +#define INTAPIC(I) (ID_TO_IO(io_apic_ints[(I)].dst_apic_id)) #define SRCBUSIRQ(I) (io_apic_ints[(I)].src_bus_irq) int -isa_apic_pin(int isa_irq) +isa_apic_irq(int isa_irq) { int intr; @@ -1189,7 +1265,7 @@ isa_apic_pin(int isa_irq) if (SRCBUSIRQ(intr) == isa_irq) { if (apic_int_is_bus_type(intr, ISA) || apic_int_is_bus_type(intr, EISA)) - return INTPIN(intr); /* found */ + return INTIRQ(intr); /* found */ } } } @@ -1204,7 +1280,7 @@ isa_apic_pin(int isa_irq) #define SRCBUSDEVICE(I) ((io_apic_ints[(I)].src_bus_irq >> 2) & 0x1f) #define SRCBUSLINE(I) (io_apic_ints[(I)].src_bus_irq & 0x03) int -pci_apic_pin(int pciBus, int pciDevice, int pciInt) +pci_apic_irq(int pciBus, int pciDevice, int pciInt) { int intr; @@ -1216,13 +1292,13 @@ pci_apic_pin(int pciBus, int pciDevice, int pciInt) && (SRCBUSDEVICE(intr) == pciDevice) && (SRCBUSLINE(intr) == pciInt)) /* a candidate IRQ */ if (apic_int_is_bus_type(intr, PCI)) - return INTPIN(intr); /* exact match */ + return INTIRQ(intr); /* exact match */ return -1; /* NOT found */ } int -next_apic_pin(int pin) +next_apic_irq(int irq) { int intr, ointr; int bus, bustype; @@ -1230,7 +1306,7 @@ next_apic_pin(int pin) bus = 0; bustype = 0; for (intr = 0; intr < nintrs; intr++) { - if (INTPIN(intr) != pin || INTTYPE(intr) != 0) + if (INTIRQ(intr) != irq || INTTYPE(intr) != 0) continue; bus = SRCBUSID(intr); bustype = apic_bus_type(bus); @@ -1265,7 +1341,7 @@ next_apic_pin(int pin) if (ointr >= nintrs) { return -1; } - return INTPIN(ointr); + return INTIRQ(ointr); } #undef SRCBUSLINE #undef SRCBUSDEVICE @@ -1273,6 +1349,8 @@ next_apic_pin(int pin) #undef SRCBUSIRQ #undef INTPIN +#undef INTIRQ +#undef INTAPIC #undef INTTYPE @@ -1397,6 +1475,27 @@ apic_int_type(int apic, int pin) return -1; /* NOT found */ } +int +apic_irq(int apic, int pin) +{ + int x; + int res; + + for (x = 0; x < nintrs; ++x) + if ((apic == ID_TO_IO(io_apic_ints[x].dst_apic_id)) && + (pin == io_apic_ints[x].dst_apic_int)) { + res = io_apic_ints[x].int_vector; + if (res == 0xff) + return -1; + if (apic != int_to_apicintpin[res].ioapic) + panic("apic_irq: inconsistent table"); + if (pin != int_to_apicintpin[res].int_pin) + panic("apic_irq inconsistent table (2)"); + return res; + } + return -1; +} + /* * given a LOGICAL APIC# and pin#, return: @@ -2127,9 +2226,11 @@ ap_init() * quite correct yet. We should have a bitfield for cpus willing * to accept TLB flush IPI's or something and sync them. */ - invltlb_ok = 1; - smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ - smp_active = 1; /* historic */ + if (smp_cpus == mp_ncpus) { + invltlb_ok = 1; + smp_started = 1; /* enable IPI's, tlb shootdown, freezes etc */ + smp_active = 1; /* historic */ + } curproc = NULL; /* make sure */ } diff --git a/sys/pci/pci.c b/sys/pci/pci.c index 2dac6de..fceb220 100644 --- a/sys/pci/pci.c +++ b/sys/pci/pci.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: pci.c,v 1.84 1998/07/22 08:40:46 dfr Exp $ + * $Id: pci.c,v 1.85 1998/08/13 19:12:20 gibbs Exp $ * */ @@ -343,7 +343,7 @@ pci_readcfg(pcicfgregs *probe) if (cfg->intpin != 0) { int airq; - airq = pci_apic_pin(cfg->bus, cfg->slot, cfg->intpin); + airq = pci_apic_irq(cfg->bus, cfg->slot, cfg->intpin); if (airq >= 0) { /* PCI specific entry found in MP table */ if (airq != cfg->intline) { @@ -357,7 +357,7 @@ pci_readcfg(pcicfgregs *probe) * same methods as used by the ISA devices * devices to find the proper IOAPIC int pin. */ - airq = isa_apic_pin(cfg->intline); + airq = isa_apic_irq(cfg->intline); if ((airq >= 0) && (airq != cfg->intline)) { /* XXX: undirect_pci_irq() ? */ undirect_isa_irq(cfg->intline); diff --git a/sys/pci/pci_compat.c b/sys/pci/pci_compat.c index 51e450e..4dfe6fd 100644 --- a/sys/pci/pci_compat.c +++ b/sys/pci/pci_compat.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: pci_compat.c,v 1.8 1998/07/22 08:39:08 dfr Exp $ + * $Id: pci_compat.c,v 1.9 1998/08/07 08:20:36 dfr Exp $ * */ @@ -182,7 +182,7 @@ pci_map_int(pcici_t cfg, pci_inthand_t *func, void *arg, unsigned *maskptr) if (error != 0) return 0; #ifdef APIC_IO - nextpin = next_apic_pin(irq); + nextpin = next_apic_irq(irq); if (nextpin < 0) return 1; @@ -196,10 +196,10 @@ pci_map_int(pcici_t cfg, pci_inthand_t *func, void *arg, unsigned *maskptr) */ muxcnt = 2; - nextpin = next_apic_pin(nextpin); + nextpin = next_apic_irq(nextpin); while (muxcnt < 5 && nextpin >= 0) { muxcnt++; - nextpin = next_apic_pin(nextpin); + nextpin = next_apic_irq(nextpin); } if (muxcnt >= 5) { printf("bogus MP table, more than 4 IO APIC pins connected to the same PCI device or ISA/EISA interrupt\n"); @@ -208,7 +208,7 @@ pci_map_int(pcici_t cfg, pci_inthand_t *func, void *arg, unsigned *maskptr) printf("bogus MP table, %d IO APIC pins connected to the same PCI device or ISA/EISA interrupt\n", muxcnt); - nextpin = next_apic_pin(irq); + nextpin = next_apic_irq(irq); while (nextpin >= 0) { idesc = intr_create(dev_instance, nextpin, func, arg, maskptr, 0); @@ -216,7 +216,7 @@ pci_map_int(pcici_t cfg, pci_inthand_t *func, void *arg, unsigned *maskptr) if (error != 0) return 0; printf("Registered extra interrupt handler for int %d (in addition to int %d)\n", nextpin, irq); - nextpin = next_apic_pin(nextpin); + nextpin = next_apic_irq(nextpin); } #endif } diff --git a/sys/sys/smp.h b/sys/sys/smp.h index f258630..0f4f915 100644 --- a/sys/sys/smp.h +++ b/sys/sys/smp.h @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: smp.h,v 1.42 1998/04/01 21:07:36 tegge Exp $ + * $Id: smp.h,v 1.43 1998/05/17 22:12:05 tegge Exp $ * */ @@ -103,6 +103,14 @@ extern u_int32_t io_apic_versions[]; extern int cpu_num_to_apic_id[]; extern int io_num_to_apic_id[]; extern int apic_id_to_logical[]; +#define APIC_INTMAPSIZE 24 +struct apic_intmapinfo { + int ioapic; + int int_pin; + volatile void *apic_address; + int redirindex; +}; +extern struct apic_intmapinfo int_to_apicintpin[]; extern u_int all_cpus; extern u_char SMP_ioapic[]; extern struct pcb stoppcbs[]; @@ -113,9 +121,10 @@ int mp_probe __P((void)); void mp_start __P((void)); void mp_announce __P((void)); u_int isa_apic_mask __P((u_int)); -int isa_apic_pin __P((int)); -int pci_apic_pin __P((int, int, int)); -int next_apic_pin __P((int)); +int isa_apic_irq __P((int)); +int pci_apic_irq __P((int, int, int)); +int apic_irq __P((int, int)); +int next_apic_irq __P((int)); int undirect_isa_irq __P((int)); int undirect_pci_irq __P((int)); int apic_bus_type __P((int)); @@ -141,12 +150,7 @@ void set_lapic_isrloc __P((int, int)); /* global data in mpapic.c */ extern volatile lapic_t lapic; - -#if defined(MULTIPLE_IOAPICS) -#error MULTIPLE_IOAPICSXXX -#else extern volatile ioapic_t *ioapic[]; -#endif /* MULTIPLE_IOAPICS */ /* functions in mpapic.c */ void apic_dump __P((char*)); |