Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/arch/x86/pci/pci_machdep.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/arch/x86/pci/pci_machdep.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.11.2.6 retrieving revision 1.12 diff -u -p -r1.11.2.6 -r1.12 --- src/sys/arch/x86/pci/pci_machdep.c 2008/03/24 09:38:40 1.11.2.6 +++ src/sys/arch/x86/pci/pci_machdep.c 2005/11/16 16:08:36 1.12 @@ -1,4 +1,4 @@ -/* $NetBSD: pci_machdep.c,v 1.11.2.6 2008/03/24 09:38:40 yamt Exp $ */ +/* $NetBSD: pci_machdep.c,v 1.12 2005/11/16 16:08:36 christos Exp $ */ /*- * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. @@ -80,7 +80,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.11.2.6 2008/03/24 09:38:40 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.12 2005/11/16 16:08:36 christos Exp $"); #include #include @@ -88,14 +88,15 @@ __KERNEL_RCSID(0, "$NetBSD: pci_machdep. #include #include #include -#include +#include #include +#include #include #include -#include +#include #include #include @@ -103,29 +104,27 @@ __KERNEL_RCSID(0, "$NetBSD: pci_machdep. #include #include -#include "acpi.h" +#include "ioapic.h" +#include "eisa.h" #include "opt_mpbios.h" -#include "opt_acpi.h" +#include "opt_mpacpi.h" + +#if NIOAPIC > 0 +#include +#include +#include +#endif #ifdef MPBIOS #include #endif -#if NACPI > 0 +#ifdef MPACPI #include #endif -#include - #include "opt_pci_conf_mode.h" -#ifdef __i386__ -#include "opt_xbox.h" -#ifdef XBOX -#include -#endif -#endif - int pci_mode = -1; static void pci_bridge_hook(pci_chipset_tag_t, pcitag_t, void *); @@ -135,17 +134,17 @@ struct pci_bridge_hook_arg { }; -__cpu_simple_lock_t pci_conf_lock = __SIMPLELOCK_UNLOCKED; +struct simplelock pci_conf_slock = SIMPLELOCK_INITIALIZER; #define PCI_CONF_LOCK(s) \ do { \ (s) = splhigh(); \ - __cpu_simple_lock(&pci_conf_lock); \ + simple_lock(&pci_conf_slock); \ } while (0) #define PCI_CONF_UNLOCK(s) \ do { \ - __cpu_simple_unlock(&pci_conf_lock); \ + simple_unlock(&pci_conf_slock); \ splx((s)); \ } while (0) @@ -172,9 +171,6 @@ struct { _qe(0, 0, 0, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82437FX), /* Connectix Virtual PC 5 has a 440BX */ _qe(0, 0, 0, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82443BX_NOAGP), - /* Parallels Desktop for Mac */ - _qe(0, 2, 0, PCI_VENDOR_PARALLELS, PCI_PRODUCT_PARALLELS_VIDEO), - _qe(0, 3, 0, PCI_VENDOR_PARALLELS, PCI_PRODUCT_PARALLELS_TOOLS), /* SIS 741 */ _qe(0, 0, 0, PCI_VENDOR_SIS, PCI_PRODUCT_SIS_741), {0, 0xffffffff} /* patchable */ @@ -188,7 +184,6 @@ struct { * of these functions. */ struct x86_bus_dma_tag pci_bus_dma_tag = { - 0, /* tag_needs_free */ #if defined(_LP64) || defined(PAE) PCI32_DMA_BOUNCE_THRESHOLD, /* bounce_thresh */ ISA_DMA_BOUNCE_THRESHOLD, /* bounce_alloclo */ @@ -206,19 +201,20 @@ struct x86_bus_dma_tag pci_bus_dma_tag = _bus_dmamap_load_uio, _bus_dmamap_load_raw, _bus_dmamap_unload, +#if defined(_LP64) || defined(PAE) _bus_dmamap_sync, +#else + NULL, +#endif _bus_dmamem_alloc, _bus_dmamem_free, _bus_dmamem_map, _bus_dmamem_unmap, _bus_dmamem_mmap, - _bus_dmatag_subregion, - _bus_dmatag_destroy, }; #ifdef _LP64 struct x86_bus_dma_tag pci_bus_dma64_tag = { - 0, /* tag_needs_free */ 0, 0, 0, @@ -236,42 +232,31 @@ struct x86_bus_dma_tag pci_bus_dma64_tag _bus_dmamem_map, _bus_dmamem_unmap, _bus_dmamem_mmap, - _bus_dmatag_subregion, - _bus_dmatag_destroy, }; #endif void -pci_attach_hook(device_t parent, device_t self, struct pcibus_attach_args *pba) +pci_attach_hook(parent, self, pba) + struct device *parent, *self; + struct pcibus_attach_args *pba; { if (pba->pba_bus == 0) - aprint_normal(": configuration mode %d", pci_mode); + printf(": configuration mode %d", pci_mode); #ifdef MPBIOS mpbios_pci_attach_hook(parent, self, pba); #endif -#if NACPI > 0 +#ifdef MPACPI mpacpi_pci_attach_hook(parent, self, pba); #endif } int -pci_bus_maxdevs(pci_chipset_tag_t pc, int busno) +pci_bus_maxdevs(pc, busno) + pci_chipset_tag_t pc; + int busno; { -#if defined(__i386__) && defined(XBOX) - /* - * Scanning above the first device is fatal on the Microsoft Xbox. - * If busno=1, only allow for one device. - */ - if (arch_i386_is_xbox) { - if (busno == 1) - return 1; - else if (busno > 1) - return 0; - } -#endif - /* * Bus number is irrelevant. If Configuration Mechanism 2 is in * use, can only have devices 0-15 on any bus. If Configuration @@ -285,7 +270,9 @@ pci_bus_maxdevs(pci_chipset_tag_t pc, in } pcitag_t -pci_make_tag(pci_chipset_tag_t pc, int bus, int device, int function) +pci_make_tag(pc, bus, device, function) + pci_chipset_tag_t pc; + int bus, device, function; { pcitag_t tag; @@ -327,8 +314,10 @@ mode2: } void -pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag, - int *bp, int *dp, int *fp) +pci_decompose_tag(pc, tag, bp, dp, fp) + pci_chipset_tag_t pc; + pcitag_t tag; + int *bp, *dp, *fp; { #ifndef PCI_CONF_MODE @@ -369,22 +358,14 @@ mode2: } pcireg_t -pci_conf_read( pci_chipset_tag_t pc, pcitag_t tag, - int reg) +pci_conf_read(pc, tag, reg) + pci_chipset_tag_t pc; + pcitag_t tag; + int reg; { pcireg_t data; int s; - KASSERT((reg & 0x3) == 0); -#if defined(__i386__) && defined(XBOX) - if (arch_i386_is_xbox) { - int bus, dev, fn; - pci_decompose_tag(pc, tag, &bus, &dev, &fn); - if (bus == 0 && dev == 0 && (fn == 1 || fn == 2)) - return (pcireg_t)-1; - } -#endif - #ifndef PCI_CONF_MODE switch (pci_mode) { case 1: @@ -423,21 +404,14 @@ mode2: } void -pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, - pcireg_t data) +pci_conf_write(pc, tag, reg, data) + pci_chipset_tag_t pc; + pcitag_t tag; + int reg; + pcireg_t data; { int s; - KASSERT((reg & 0x3) == 0); -#if defined(__i386__) && defined(XBOX) - if (arch_i386_is_xbox) { - int bus, dev, fn; - pci_decompose_tag(pc, tag, &bus, &dev, &fn); - if (bus == 0 && dev == 0 && (fn == 1 || fn == 2)) - return; - } -#endif - #ifndef PCI_CONF_MODE switch (pci_mode) { case 1: @@ -502,7 +476,8 @@ pci_mode_detect() /* * catch some known buggy implementations of mode 1 */ - for (i = 0; i < __arraycount(pcim1_quirk_tbl); i++) { + for (i = 0; i < sizeof(pcim1_quirk_tbl) / sizeof(pcim1_quirk_tbl[0]); + i++) { pcitag_t t; if (!pcim1_quirk_tbl[i].tag) @@ -561,6 +536,156 @@ not2: #endif } +int +pci_intr_map(pa, ihp) + struct pci_attach_args *pa; + pci_intr_handle_t *ihp; +{ + int pin = pa->pa_intrpin; + int line = pa->pa_intrline; +#if NIOAPIC > 0 + int rawpin = pa->pa_rawintrpin; + pci_chipset_tag_t pc = pa->pa_pc; + int bus, dev, func; +#endif + + if (pin == 0) { + /* No IRQ used. */ + goto bad; + } + + if (pin > PCI_INTERRUPT_PIN_MAX) { + printf("pci_intr_map: bad interrupt pin %d\n", pin); + goto bad; + } + +#if NIOAPIC > 0 + pci_decompose_tag(pc, pa->pa_tag, &bus, &dev, &func); + if (mp_busses != NULL) { + if (intr_find_mpmapping(bus, (dev<<2)|(rawpin-1), ihp) == 0) { + *ihp |= line; + return 0; + } + /* + * No explicit PCI mapping found. This is not fatal, + * we'll try the ISA (or possibly EISA) mappings next. + */ + } +#endif + + /* + * Section 6.2.4, `Miscellaneous Functions', says that 255 means + * `unknown' or `no connection' on a PC. We assume that a device with + * `no connection' either doesn't have an interrupt (in which case the + * pin number should be 0, and would have been noticed above), or + * wasn't configured by the BIOS (in which case we punt, since there's + * no real way we can know how the interrupt lines are mapped in the + * hardware). + * + * XXX + * Since IRQ 0 is only used by the clock, and we can't actually be sure + * that the BIOS did its job, we also recognize that as meaning that + * the BIOS has not configured the device. + */ + if (line == 0 || line == X86_PCI_INTERRUPT_LINE_NO_CONNECTION) { + printf("pci_intr_map: no mapping for pin %c (line=%02x)\n", + '@' + pin, line); + goto bad; + } else { + if (line >= NUM_LEGACY_IRQS) { + printf("pci_intr_map: bad interrupt line %d\n", line); + goto bad; + } + if (line == 2) { + printf("pci_intr_map: changed line 2 to line 9\n"); + line = 9; + } + } +#if NIOAPIC > 0 + if (mp_busses != NULL) { + if (intr_find_mpmapping(mp_isa_bus, line, ihp) == 0) { + *ihp |= line; + return 0; + } +#if NEISA > 0 + if (intr_find_mpmapping(mp_eisa_bus, line, ihp) == 0) { + *ihp |= line; + return 0; + } +#endif + printf("pci_intr_map: bus %d dev %d func %d pin %d; line %d\n", + bus, dev, func, pin, line); + printf("pci_intr_map: no MP mapping found\n"); + } +#endif + + *ihp = line; + return 0; + +bad: + *ihp = -1; + return 1; +} + +const char * +pci_intr_string(pc, ih) + pci_chipset_tag_t pc; + pci_intr_handle_t ih; +{ + return intr_string(ih); +} + + +const struct evcnt * +pci_intr_evcnt(pc, ih) + pci_chipset_tag_t pc; + pci_intr_handle_t ih; +{ + + /* XXX for now, no evcnt parent reported */ + return NULL; +} + +void * +pci_intr_establish(pc, ih, level, func, arg) + pci_chipset_tag_t pc; + pci_intr_handle_t ih; + int level, (*func) __P((void *)); + void *arg; +{ + int pin, irq; + struct pic *pic; + + pic = &i8259_pic; + pin = irq = ih; + +#if NIOAPIC > 0 + if (ih & APIC_INT_VIA_APIC) { + pic = (struct pic *)ioapic_find(APIC_IRQ_APIC(ih)); + if (pic == NULL) { + printf("pci_intr_establish: bad ioapic %d\n", + APIC_IRQ_APIC(ih)); + return NULL; + } + pin = APIC_IRQ_PIN(ih); + irq = APIC_IRQ_LEGACY_IRQ(ih); + if (irq < 0 || irq >= NUM_LEGACY_IRQS) + irq = -1; + } +#endif + + return intr_establish(irq, pic, pin, IST_LEVEL, level, func, arg); +} + +void +pci_intr_disestablish(pc, cookie) + pci_chipset_tag_t pc; + void *cookie; +{ + + intr_disestablish(cookie); +} + /* * Determine which flags should be passed to the primary PCI bus's * autoconfiguration node. We use this to detect broken chipsets @@ -693,3 +818,5 @@ pci_bridge_hook(pci_chipset_tag_t pc, pc (*bridge_hook->func)(pc, tag, bridge_hook->arg); } } + +