ia64/xen-unstable
changeset 4785:39bfbd5ae9b8
bitkeeper revision 1.1398 (427ba39bqKEbkdkvXR-PGTXrS0ed7w)
Merge http://xen.bkbits.net:8080/xeno-unstable.bk
into gandalf.hpl.hp.com:/var/bk/xeno-unstable.bk
Merge http://xen.bkbits.net:8080/xeno-unstable.bk
into gandalf.hpl.hp.com:/var/bk/xeno-unstable.bk
line diff
1.1 --- a/.rootkeys Tue May 03 12:52:47 2005 +0000 1.2 +++ b/.rootkeys Fri May 06 17:04:27 2005 +0000 1.3 @@ -220,6 +220,9 @@ 424f001dsBzCezYZD8vAn-h5D9ZRtQ linux-2.6 1.4 40f56237Mta0yHNaMS_qtM2rge0qYA linux-2.6.11-xen-sparse/arch/xen/i386/Kconfig 1.5 40f56238u2CJdXNpjsZgHBxeVyY-2g linux-2.6.11-xen-sparse/arch/xen/i386/Makefile 1.6 40f56238eczveJ86k_4hNxCLRQIF-g linux-2.6.11-xen-sparse/arch/xen/i386/kernel/Makefile 1.7 +42778a68_kGyflDnRbar9WAmb4CKYw linux-2.6.11-xen-sparse/arch/xen/i386/kernel/acpi/Makefile 1.8 +42778a68_2OruSz7lwFPBiGhl3y-FA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/acpi/boot.c 1.9 +42778a69h76S5SCnDonnxnIt9nDGFQ linux-2.6.11-xen-sparse/arch/xen/i386/kernel/apic.c 1.10 40f56238rXVTJQKbBuXXLH52qEArcg linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/Makefile 1.11 40f562385s4lr6Zg92gExe7UQ4A76Q linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/common.c 1.12 41ab440bnpxZdWShZrGgM9pPaz5rmA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/Makefile 1.13 @@ -227,10 +230,12 @@ 41ab440bBKWz-aEOEojU4PAMXe3Ppg linux-2.6 1.14 40f56238XDtHSijkAFlbv1PT8Bhw_Q linux-2.6.11-xen-sparse/arch/xen/i386/kernel/entry.S 1.15 40f56238bnvciAuyzAiMkdzGErYt1A linux-2.6.11-xen-sparse/arch/xen/i386/kernel/head.S 1.16 40f58a0d31M2EkuPbG94ns_nOi0PVA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c 1.17 +42778a69_lodTzZVlojib1-pZF030g linux-2.6.11-xen-sparse/arch/xen/i386/kernel/io_apic.c 1.18 40faa751_zbZlAmLyQgCXdYekVFdWA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/ioport.c 1.19 41d00d82zN8IfLBRxc7G_i7lbwT3cQ linux-2.6.11-xen-sparse/arch/xen/i386/kernel/irq.c 1.20 40f56238ue3YRsK52HG7iccNzP1AwQ linux-2.6.11-xen-sparse/arch/xen/i386/kernel/ldt.c 1.21 41d54a76YMCA67S8J-TBT3J62Wx6yA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/microcode.c 1.22 +42778a69obEqvR75wSKCWPk9QnHo-w linux-2.6.11-xen-sparse/arch/xen/i386/kernel/mpparse.c 1.23 4107adf1cNtsuOxOB4T6paAoY2R2PA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/pci-dma.c 1.24 40f56238a8iOVDEoostsbun_sy2i4g linux-2.6.11-xen-sparse/arch/xen/i386/kernel/process.c 1.25 40f56238YQIJoYG2ehDGEcdTgLmGbg linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c 1.26 @@ -251,7 +256,6 @@ 40f56239xcNylAxuGsQHwi1AyMLV8w linux-2.6 1.27 41062ab7CjxC1UBaFhOMWWdhHkIUyg linux-2.6.11-xen-sparse/arch/xen/i386/mm/ioremap.c 1.28 40f5623906UYHv1rsVUeRc0tFT0dWw linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c 1.29 4107adf12ndy94MidCaivDibJ3pPAg linux-2.6.11-xen-sparse/arch/xen/i386/pci/Makefile 1.30 -4107adf1WcCgkhsdLTRGX52cOG1vJg linux-2.6.11-xen-sparse/arch/xen/i386/pci/direct.c 1.31 4107adf1s5u6249DNPUViX1YNagbUQ linux-2.6.11-xen-sparse/arch/xen/i386/pci/irq.c 1.32 40f56239zOksGg_H4XD4ye6iZNtoZA linux-2.6.11-xen-sparse/arch/xen/kernel/Makefile 1.33 40f56239bvOjuuuViZ0XMlNiREFC0A linux-2.6.11-xen-sparse/arch/xen/kernel/ctrl_if.c 1.34 @@ -296,6 +300,7 @@ 424efaa6uMX8YJASAVJT8ral74dz9Q linux-2.6 1.35 424efaa629XgfZi3vvTAuQmhCqmvIA linux-2.6.11-xen-sparse/arch/xen/x86_64/pci/Makefile 1.36 424efaa64SRL9FZhtQovFJAVh9sZlQ linux-2.6.11-xen-sparse/arch/xen/x86_64/pci/Makefile-BUS 1.37 41261688yS8eAyy-7kzG4KBs0xbYCA linux-2.6.11-xen-sparse/drivers/Makefile 1.38 +42778a69QJ93x9p93ALrTV5QELHF-Q linux-2.6.11-xen-sparse/drivers/acpi/tables.c 1.39 4108f5c1WfTIrs0HZFeV39sttekCTw linux-2.6.11-xen-sparse/drivers/char/mem.c 1.40 4111308bZAIzwf_Kzu6x1TZYZ3E0_Q linux-2.6.11-xen-sparse/drivers/char/tty_io.c 1.41 40f56239Dp_vMTgz8TEbvo1hjHGc3w linux-2.6.11-xen-sparse/drivers/xen/Makefile 1.42 @@ -1227,10 +1232,7 @@ 41aaf567tqrKGSTDK8OVeAbpeoccPw xen/arch/ 1.43 41aaf567a36esU-rUK7twPiv-yTFyw xen/arch/x86/mtrr/mtrr.h 1.44 41aaf567DcTL6pqVtLZJI5cSryyA1A xen/arch/x86/mtrr/state.c 1.45 3f12cff65EV3qOG2j37Qm0ShgvXGRw xen/arch/x86/nmi.c 1.46 -3ddb79bdHe6_Uij4-glW91vInNtBYQ xen/arch/x86/pci-irq.c 1.47 -3ddb79bcZ_2FxINljqNSkqa17ISyJw xen/arch/x86/pci-pc.c 1.48 -3ddb79bdeJ7_86z03yTAPIeeywOg3Q xen/arch/x86/pci-x86.c 1.49 -3ddb79bdIKgipvGoqExEQ7jawfVowA xen/arch/x86/pci-x86.h 1.50 +4051bcecFeq4DE70p4zGO5setf47CA xen/arch/x86/physdev.c 1.51 3ddb79bc7KxGCEJsgBnkDX7XjD_ZEQ xen/arch/x86/rwlock.c 1.52 3ddb79bcrD6Z_rUvSDgrvjyb4846Eg xen/arch/x86/setup.c 1.53 405b8599xI_PoEr3zZoJ2on-jdn7iw xen/arch/x86/shadow.c 1.54 @@ -1274,7 +1276,6 @@ 3ddb79bduhSEZI8xa7IbGQCpap5y2A xen/commo 1.55 41a61536SZbR6cj1ukWTb0DYU-vz9w xen/common/multicall.c 1.56 3ddb79bdD4SLmmdMD7yLW5HcUWucXw xen/common/page_alloc.c 1.57 3e54c38dkHAev597bPr71-hGzTdocg xen/common/perfc.c 1.58 -4051bcecFeq4DE70p4zGO5setf47CA xen/common/physdev.c 1.59 3ddb79bdHqdQpATqC0rmUZNbsb6L6A xen/common/resource.c 1.60 40589968dD2D1aejwSOvrROg7fOvGQ xen/common/sched_bvt.c 1.61 3e397e6619PgAfBbw2XFbXkewvUWgw xen/common/schedule.c 1.62 @@ -1285,50 +1286,29 @@ 3ddb79bd3zgV33PHdt-cgh3sxcb1hw xen/commo 1.63 4203fb92Qcy7mGpauBdq09J-WAqfoA xen/common/xmalloc.c 1.64 3ddb79c0ppNeJtjC4va8j41ADCnchA xen/drivers/Makefile 1.65 40715b2bi9gU43-cYzlmPDgreYQchw xen/drivers/acpi/Makefile 1.66 -40715b2bDxNCz5LFV8FAXihmYJZFUQ xen/drivers/acpi/acpi_ksyms.c 1.67 40715b2cNVOegtvyft_AHFKJYRprfA xen/drivers/acpi/tables.c 1.68 3e4a8cb7alzQCDKS7MlioPoHBKYkdQ xen/drivers/char/Makefile 1.69 4049e6bfNSIq7s7OV-Bd69QD0RpR2Q xen/drivers/char/console.c 1.70 3e4a8cb7nMChlro4wvOBo76n__iCFA xen/drivers/char/serial.c 1.71 -3ddb79beUWngyIhMHgyPtuTem4o4JA xen/drivers/pci/Makefile 1.72 -3ddb79beU9td0Mnm0VUMklerBa37qQ xen/drivers/pci/compat.c 1.73 -3ddb79beHkGQE58z5t5gyUCYiwOxvw xen/drivers/pci/gen-devlist.c 1.74 -3ddb79bfoQcFKLf5P6wZlDl36alWdQ xen/drivers/pci/names.c 1.75 -3ddb79bfyX7-pD6XdxY_mdNrJR20iw xen/drivers/pci/pci.c 1.76 -3ddb79bf2AS7YBGwooE_Kbv7XgUqNQ xen/drivers/pci/pci.ids 1.77 -3ddb79bf7sTn85WtP_8Nc2YEmmVExQ xen/drivers/pci/quirks.c 1.78 -3ddb79bfJaf0bkE1Y67bnll8-kjEPg xen/drivers/pci/setup-res.c 1.79 40715b2cFpte_UNWnBZW0Du7z9AhTQ xen/include/acpi/acconfig.h 1.80 -40715b2cEQWX-PaxEH30qI48K1krnQ xen/include/acpi/acdebug.h 1.81 -40715b2c_7j-oy3ZNAuqE3IFNPzArg xen/include/acpi/acdisasm.h 1.82 -40715b2cFdcPx-2FHGM1Q-M-592xYQ xen/include/acpi/acdispat.h 1.83 -40715b2cKqD_Lihnlmvnyl4AAl3EFw xen/include/acpi/acevents.h 1.84 40715b2ctNvVZ058w8eM8DR9hOat_A xen/include/acpi/acexcep.h 1.85 40715b2com8I01qcHcAw47e93XsCqQ xen/include/acpi/acglobal.h 1.86 40715b2cS1t4uI3sMsu-c0M4qqAIrw xen/include/acpi/achware.h 1.87 -40715b2chSz545A4Tq-y3WAtanzPMQ xen/include/acpi/acinterp.h 1.88 40715b2cGf23lRI58NphiaDQl698-w xen/include/acpi/aclocal.h 1.89 40715b2cdG7tCF2NMk0j1RCQQPzPXg xen/include/acpi/acmacros.h 1.90 -40715b2ckP2XZZDkSTehu6riuMogDA xen/include/acpi/acnamesp.h 1.91 40715b2c4AvHYn2-2YIyt3mx-Mm5tw xen/include/acpi/acobject.h 1.92 40715b2cPUXsHzmchvXx7QHAfW0nMw xen/include/acpi/acoutput.h 1.93 -40715b2cNbYpt9CHmCHg3RG7fBdACA xen/include/acpi/acparser.h 1.94 40715b2cWM_6zR14U9Tp0s_q8D002A xen/include/acpi/acpi.h 1.95 40715b2dcJDTiROgyMk9swD_veWktA xen/include/acpi/acpi_bus.h 1.96 40715b2dRFlZK6apnH7WkUCBdyFXWA xen/include/acpi/acpi_drivers.h 1.97 40715b2dtgZhNGAzlyBMe3kqve3mqw xen/include/acpi/acpiosxf.h 1.98 40715b2dpW5TY7n5rzCufsDhJVWuMQ xen/include/acpi/acpixf.h 1.99 -40715b2dp9-_D9LTjcvtf-Yopih5mQ xen/include/acpi/acresrc.h 1.100 40715b2djvd97KbIpt4wyJgxwqCqmg xen/include/acpi/acstruct.h 1.101 -40715b2dRIU9cQgmTjtCRNleIJDAYg xen/include/acpi/actables.h 1.102 40715b2dy8ECRkSo9x0tRRueAjPx1g xen/include/acpi/actbl.h 1.103 40715b2ds4J-XWn9Ix-lgBiJffNgxw xen/include/acpi/actbl1.h 1.104 40715b2d_aMKMjKKNImJR4km52KRHA xen/include/acpi/actbl2.h 1.105 -40715b2dxC03aemijgL-iDH_-BkKRw xen/include/acpi/actbl71.h 1.106 40715b2d0oQUijKwEw6SDJ4LhD8c4g xen/include/acpi/actypes.h 1.107 40715b2dBByvcAtRpN5mafyEYLcBWA xen/include/acpi/acutils.h 1.108 -40715b2d_iPcZ0uUVGblPvjsHOwE5Q xen/include/acpi/amlcode.h 1.109 -40715b2d3CdS6dIpZDTiCJRlDG3LCA xen/include/acpi/amlresrc.h 1.110 40715b2dKRW7A71SNaeV6zfrEzYxPw xen/include/acpi/platform/acenv.h 1.111 40715b2d8fYydJMcODFrV1ocLklGDg xen/include/acpi/platform/acgcc.h 1.112 40715b2d1yZkqyAt0kgx2xEwsatuuA xen/include/acpi/platform/aclinux.h 1.113 @@ -1390,6 +1370,7 @@ 41aaf567Mi3OishhvrCtET1y-mxQBg xen/inclu 1.114 41a61536MFhNalgbVmYGXAhQsPTZNw xen/include/asm-x86/multicall.h 1.115 3ddb79c3xjYnrv5t3VqYlR4tNEOl4Q xen/include/asm-x86/page.h 1.116 3ddb79c3ysKUbxZuwKBRK3WXU2TlEg xen/include/asm-x86/pci.h 1.117 +42422fb0FVX-TJkSvAXnbfwMf19XFA xen/include/asm-x86/physdev.h 1.118 3ddb79c2QF5-pZGzuX4QukPCDAl59A xen/include/asm-x86/processor.h 1.119 40cf1596bim9F9DNdV75klgRSZ6Y2A xen/include/asm-x86/regs.h 1.120 3ddb79c2plf7ciNgoNjU-RsbUzawsw xen/include/asm-x86/rwlock.h 1.121 @@ -1472,7 +1453,6 @@ 3ddb79c2Fg44_PBPVxHSC0gTOMq4Ow xen/inclu 1.122 3ddb79c0MOVXq8qZDQRGb6z64_xAwg xen/include/xen/pci_ids.h 1.123 3e54c38dlSCVdyVM4PKcrSfzLLxWUQ xen/include/xen/perfc.h 1.124 3e54c38de9SUSYSAwxDf_DwkpAnQFA xen/include/xen/perfc_defn.h 1.125 -42422fb0FVX-TJkSvAXnbfwMf19XFA xen/include/xen/physdev.h 1.126 3ddb79c04nQVR3EYM5L4zxDV_MCo1g xen/include/xen/prefetch.h 1.127 3e4540ccU1sgCx8seIMGlahmMfv7yQ xen/include/xen/reboot.h 1.128 40589969nPq3DMzv24RDb5LXE9brHw xen/include/xen/sched-if.h
3.1 --- a/BitKeeper/etc/logging_ok Tue May 03 12:52:47 2005 +0000 3.2 +++ b/BitKeeper/etc/logging_ok Fri May 06 17:04:27 2005 +0000 3.3 @@ -99,3 +99,4 @@ vh249@airwolf.cl.cam.ac.uk 3.4 vh249@arcadians.cl.cam.ac.uk 3.5 xen-ia64.adm@bkbits.net 3.6 xenbk@gandalf.hpl.hp.com 3.7 +ydroneaud@mandriva.com
4.1 --- a/linux-2.4.29-xen-sparse/mkbuildtree Tue May 03 12:52:47 2005 +0000 4.2 +++ b/linux-2.4.29-xen-sparse/mkbuildtree Fri May 06 17:04:27 2005 +0000 4.3 @@ -66,7 +66,7 @@ relative_lndir () 4.4 ( 4.5 cd $i 4.6 pref=`echo $i | sed -e 's#/[^/]*#../#g' -e 's#^\.##'` 4.7 - for j in `find . -type f -o -type l -maxdepth 1`; do 4.8 + for j in `find . -maxdepth 1 -type f -o -type l`; do 4.9 ln -sf ${pref}${REAL_DIR}/$i/$j ${SYMLINK_DIR}/$i/$j 4.10 done 4.11 ) 4.12 @@ -232,7 +232,6 @@ ln -sf ../../../${LINUX_26}/arch/xen/ker 4.13 ln -sf ../../../${LINUX_26}/arch/xen/kernel/gnttab.c 4.14 ln -sf ../../../${LINUX_26}/arch/xen/kernel/reboot.c 4.15 ln -sf ../../../${LINUX_26}/arch/xen/kernel/skbuff.c 4.16 -ln -sf ../../../${LINUX_26}/arch/xen/i386/kernel/pci-dma.c 4.17 4.18 cd ${AD}/arch/xen/lib 4.19 ln -sf ../../i386/lib/checksum.S
5.1 --- a/linux-2.6.11-xen-sparse/arch/xen/Kconfig Tue May 03 12:52:47 2005 +0000 5.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/Kconfig Fri May 06 17:04:27 2005 +0000 5.3 @@ -181,6 +181,12 @@ endmenu 5.4 5.5 source "arch/xen/Kconfig.drivers" 5.6 5.7 +if XEN_PRIVILEGED_GUEST 5.8 +menu "Power management options" 5.9 +source "drivers/acpi/Kconfig" 5.10 +endmenu 5.11 +endif 5.12 + 5.13 source "fs/Kconfig" 5.14 5.15 source "security/Kconfig"
6.1 --- a/linux-2.6.11-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 Tue May 03 12:52:47 2005 +0000 6.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 Fri May 06 17:04:27 2005 +0000 6.3 @@ -1,7 +1,7 @@ 6.4 # 6.5 # Automatically generated make config: don't edit 6.6 # Linux kernel version: 2.6.11-xen0 6.7 -# Wed Apr 6 09:19:05 2005 6.8 +# Wed May 4 17:11:56 2005 6.9 # 6.10 CONFIG_XEN=y 6.11 CONFIG_ARCH_XEN=y 6.12 @@ -133,12 +133,23 @@ CONFIG_NOHIGHMEM=y 6.13 CONFIG_MTRR=y 6.14 CONFIG_HAVE_DEC_LOCK=y 6.15 # CONFIG_REGPARM is not set 6.16 +CONFIG_X86_LOCAL_APIC=y 6.17 +CONFIG_X86_IO_APIC=y 6.18 6.19 # 6.20 # Bus options (PCI, PCMCIA, EISA, MCA, ISA) 6.21 # 6.22 +CONFIG_X86_UP_APIC=y 6.23 +CONFIG_X86_UP_IOAPIC=y 6.24 CONFIG_PCI=y 6.25 +# CONFIG_PCI_GOBIOS is not set 6.26 +# CONFIG_PCI_GOMMCONFIG is not set 6.27 +# CONFIG_PCI_GODIRECT is not set 6.28 +CONFIG_PCI_GOANY=y 6.29 +# CONFIG_PCI_BIOS is not set 6.30 CONFIG_PCI_DIRECT=y 6.31 +# CONFIG_PCIEPORTBUS is not set 6.32 +# CONFIG_PCI_MSI is not set 6.33 CONFIG_PCI_LEGACY_PROC=y 6.34 # CONFIG_PCI_NAMES is not set 6.35 CONFIG_ISA=y 6.36 @@ -165,17 +176,25 @@ CONFIG_PCMCIA_PROBE=y 6.37 # Kernel hacking 6.38 # 6.39 CONFIG_DEBUG_KERNEL=y 6.40 +CONFIG_MAGIC_SYSRQ=y 6.41 +# CONFIG_SCHEDSTATS is not set 6.42 +# CONFIG_DEBUG_SLAB is not set 6.43 +# CONFIG_DEBUG_PREEMPT is not set 6.44 +# CONFIG_DEBUG_SPINLOCK is not set 6.45 +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 6.46 +# CONFIG_DEBUG_KOBJECT is not set 6.47 +CONFIG_DEBUG_BUGVERBOSE=y 6.48 +# CONFIG_DEBUG_INFO is not set 6.49 +# CONFIG_DEBUG_FS is not set 6.50 +# CONFIG_FRAME_POINTER is not set 6.51 CONFIG_EARLY_PRINTK=y 6.52 # CONFIG_DEBUG_STACKOVERFLOW is not set 6.53 +# CONFIG_KPROBES is not set 6.54 # CONFIG_DEBUG_STACK_USAGE is not set 6.55 -# CONFIG_DEBUG_SLAB is not set 6.56 -CONFIG_MAGIC_SYSRQ=y 6.57 -# CONFIG_DEBUG_SPINLOCK is not set 6.58 # CONFIG_DEBUG_PAGEALLOC is not set 6.59 -# CONFIG_DEBUG_INFO is not set 6.60 -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 6.61 -# CONFIG_FRAME_POINTER is not set 6.62 # CONFIG_4KSTACKS is not set 6.63 +CONFIG_X86_FIND_SMP_CONFIG=y 6.64 +CONFIG_X86_MPPARSE=y 6.65 CONFIG_GENERIC_HARDIRQS=y 6.66 CONFIG_GENERIC_IRQ_PROBE=y 6.67 CONFIG_X86_BIOS_REBOOT=y 6.68 @@ -230,6 +249,7 @@ CONFIG_BLK_DEV_LOOP=y 6.69 # CONFIG_BLK_DEV_CRYPTOLOOP is not set 6.70 # CONFIG_BLK_DEV_NBD is not set 6.71 # CONFIG_BLK_DEV_SX8 is not set 6.72 +# CONFIG_BLK_DEV_UB is not set 6.73 CONFIG_BLK_DEV_RAM=y 6.74 CONFIG_BLK_DEV_RAM_COUNT=16 6.75 CONFIG_BLK_DEV_RAM_SIZE=4096 6.76 @@ -841,6 +861,7 @@ CONFIG_DRM_MGA=m 6.77 CONFIG_DRM_SIS=m 6.78 # CONFIG_MWAVE is not set 6.79 # CONFIG_RAW_DRIVER is not set 6.80 +# CONFIG_HPET is not set 6.81 # CONFIG_HANGCHECK_TIMER is not set 6.82 6.83 # 6.84 @@ -889,13 +910,107 @@ CONFIG_DUMMY_CONSOLE=y 6.85 # 6.86 # USB support 6.87 # 6.88 -# CONFIG_USB is not set 6.89 +CONFIG_USB=y 6.90 +# CONFIG_USB_DEBUG is not set 6.91 + 6.92 +# 6.93 +# Miscellaneous USB options 6.94 +# 6.95 +# CONFIG_USB_DEVICEFS is not set 6.96 +# CONFIG_USB_BANDWIDTH is not set 6.97 +# CONFIG_USB_DYNAMIC_MINORS is not set 6.98 +# CONFIG_USB_OTG is not set 6.99 CONFIG_USB_ARCH_HAS_HCD=y 6.100 CONFIG_USB_ARCH_HAS_OHCI=y 6.101 6.102 # 6.103 +# USB Host Controller Drivers 6.104 +# 6.105 +# CONFIG_USB_EHCI_HCD is not set 6.106 +CONFIG_USB_OHCI_HCD=y 6.107 +CONFIG_USB_UHCI_HCD=y 6.108 +# CONFIG_USB_SL811_HCD is not set 6.109 + 6.110 +# 6.111 +# USB Device Class drivers 6.112 +# 6.113 +# CONFIG_USB_BLUETOOTH_TTY is not set 6.114 +# CONFIG_USB_ACM is not set 6.115 +# CONFIG_USB_PRINTER is not set 6.116 + 6.117 +# 6.118 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information 6.119 # 6.120 +# CONFIG_USB_STORAGE is not set 6.121 + 6.122 +# 6.123 +# USB Input Devices 6.124 +# 6.125 +CONFIG_USB_HID=y 6.126 +CONFIG_USB_HIDINPUT=y 6.127 +# CONFIG_HID_FF is not set 6.128 +# CONFIG_USB_HIDDEV is not set 6.129 +# CONFIG_USB_AIPTEK is not set 6.130 +# CONFIG_USB_WACOM is not set 6.131 +# CONFIG_USB_KBTAB is not set 6.132 +# CONFIG_USB_POWERMATE is not set 6.133 +# CONFIG_USB_MTOUCH is not set 6.134 +# CONFIG_USB_EGALAX is not set 6.135 +# CONFIG_USB_XPAD is not set 6.136 +# CONFIG_USB_ATI_REMOTE is not set 6.137 + 6.138 +# 6.139 +# USB Imaging devices 6.140 +# 6.141 +# CONFIG_USB_MDC800 is not set 6.142 +# CONFIG_USB_MICROTEK is not set 6.143 +# CONFIG_USB_HPUSBSCSI is not set 6.144 + 6.145 +# 6.146 +# USB Multimedia devices 6.147 +# 6.148 +# CONFIG_USB_DABUSB is not set 6.149 + 6.150 +# 6.151 +# Video4Linux support is needed for USB Multimedia device support 6.152 +# 6.153 + 6.154 +# 6.155 +# USB Network Adapters 6.156 +# 6.157 +# CONFIG_USB_CATC is not set 6.158 +# CONFIG_USB_KAWETH is not set 6.159 +# CONFIG_USB_PEGASUS is not set 6.160 +# CONFIG_USB_RTL8150 is not set 6.161 +# CONFIG_USB_USBNET is not set 6.162 + 6.163 +# 6.164 +# USB port drivers 6.165 +# 6.166 + 6.167 +# 6.168 +# USB Serial Converter support 6.169 +# 6.170 +# CONFIG_USB_SERIAL is not set 6.171 + 6.172 +# 6.173 +# USB Miscellaneous drivers 6.174 +# 6.175 +# CONFIG_USB_EMI62 is not set 6.176 +# CONFIG_USB_EMI26 is not set 6.177 +# CONFIG_USB_AUERSWALD is not set 6.178 +# CONFIG_USB_RIO500 is not set 6.179 +# CONFIG_USB_LEGOTOWER is not set 6.180 +# CONFIG_USB_LCD is not set 6.181 +# CONFIG_USB_LED is not set 6.182 +# CONFIG_USB_CYTHERM is not set 6.183 +# CONFIG_USB_PHIDGETKIT is not set 6.184 +# CONFIG_USB_PHIDGETSERVO is not set 6.185 +# CONFIG_USB_IDMOUSE is not set 6.186 + 6.187 +# 6.188 +# USB ATM/DSL drivers 6.189 +# 6.190 6.191 # 6.192 # USB Gadget Support 6.193 @@ -913,6 +1028,37 @@ CONFIG_USB_ARCH_HAS_OHCI=y 6.194 # CONFIG_INFINIBAND is not set 6.195 6.196 # 6.197 +# Power management options 6.198 +# 6.199 + 6.200 +# 6.201 +# ACPI (Advanced Configuration and Power Interface) Support 6.202 +# 6.203 +CONFIG_ACPI=y 6.204 +CONFIG_ACPI_BOOT=y 6.205 +CONFIG_ACPI_INTERPRETER=y 6.206 +CONFIG_ACPI_AC=m 6.207 +CONFIG_ACPI_BATTERY=m 6.208 +CONFIG_ACPI_BUTTON=m 6.209 +CONFIG_ACPI_VIDEO=m 6.210 +CONFIG_ACPI_FAN=m 6.211 +CONFIG_ACPI_PROCESSOR=m 6.212 +CONFIG_ACPI_THERMAL=m 6.213 +CONFIG_ACPI_ASUS=m 6.214 +CONFIG_ACPI_IBM=m 6.215 +CONFIG_ACPI_TOSHIBA=m 6.216 +# CONFIG_ACPI_CUSTOM_DSDT is not set 6.217 +CONFIG_ACPI_BLACKLIST_YEAR=0 6.218 +# CONFIG_ACPI_DEBUG is not set 6.219 +CONFIG_ACPI_BUS=y 6.220 +CONFIG_ACPI_EC=y 6.221 +CONFIG_ACPI_POWER=y 6.222 +CONFIG_ACPI_PCI=y 6.223 +CONFIG_ACPI_SYSTEM=y 6.224 +# CONFIG_X86_PM_TIMER is not set 6.225 +# CONFIG_ACPI_CONTAINER is not set 6.226 + 6.227 +# 6.228 # File systems 6.229 # 6.230 CONFIG_EXT2_FS=y
7.1 --- a/linux-2.6.11-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 Tue May 03 12:52:47 2005 +0000 7.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 Fri May 06 17:04:27 2005 +0000 7.3 @@ -1,7 +1,7 @@ 7.4 # 7.5 # Automatically generated make config: don't edit 7.6 # Linux kernel version: 2.6.11-xenU 7.7 -# Wed Apr 6 09:20:09 2005 7.8 +# Wed May 4 17:14:10 2005 7.9 # 7.10 CONFIG_XEN=y 7.11 CONFIG_ARCH_XEN=y 7.12 @@ -132,16 +132,22 @@ CONFIG_HAVE_DEC_LOCK=y 7.13 # Kernel hacking 7.14 # 7.15 CONFIG_DEBUG_KERNEL=y 7.16 +CONFIG_MAGIC_SYSRQ=y 7.17 +# CONFIG_SCHEDSTATS is not set 7.18 +# CONFIG_DEBUG_SLAB is not set 7.19 +# CONFIG_DEBUG_PREEMPT is not set 7.20 +# CONFIG_DEBUG_SPINLOCK is not set 7.21 +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 7.22 +# CONFIG_DEBUG_KOBJECT is not set 7.23 +CONFIG_DEBUG_BUGVERBOSE=y 7.24 +# CONFIG_DEBUG_INFO is not set 7.25 +# CONFIG_DEBUG_FS is not set 7.26 +# CONFIG_FRAME_POINTER is not set 7.27 CONFIG_EARLY_PRINTK=y 7.28 # CONFIG_DEBUG_STACKOVERFLOW is not set 7.29 +# CONFIG_KPROBES is not set 7.30 # CONFIG_DEBUG_STACK_USAGE is not set 7.31 -# CONFIG_DEBUG_SLAB is not set 7.32 -CONFIG_MAGIC_SYSRQ=y 7.33 -# CONFIG_DEBUG_SPINLOCK is not set 7.34 # CONFIG_DEBUG_PAGEALLOC is not set 7.35 -# CONFIG_DEBUG_INFO is not set 7.36 -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 7.37 -# CONFIG_FRAME_POINTER is not set 7.38 # CONFIG_4KSTACKS is not set 7.39 CONFIG_GENERIC_HARDIRQS=y 7.40 CONFIG_GENERIC_IRQ_PROBE=y
8.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/Kconfig Tue May 03 12:52:47 2005 +0000 8.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/Kconfig Fri May 06 17:04:27 2005 +0000 8.3 @@ -12,6 +12,11 @@ config XENARCH 8.4 config X86 8.5 bool 8.6 default y 8.7 + help 8.8 + This is Linux's home port. Linux was originally native to the Intel 8.9 + 386, and runs on all the later x86 processors including the Intel 8.10 + 486, 586, Pentiums, and various instruction-set-compatible chips by 8.11 + AMD, Cyrix, and others. 8.12 8.13 config MMU 8.14 bool 8.15 @@ -662,11 +667,15 @@ config REGPARM 8.16 generate incorrect output with certain kernel constructs when 8.17 -mregparm=3 is used. 8.18 8.19 - 8.20 config X86_LOCAL_APIC 8.21 bool 8.22 - depends on (X86_VISWS || SMP) && !X86_VOYAGER 8.23 - default n 8.24 + depends on !SMP && X86_UP_APIC 8.25 + default y 8.26 + 8.27 +config X86_IO_APIC 8.28 + bool 8.29 + depends on !SMP && X86_UP_IOAPIC 8.30 + default y 8.31 8.32 if XEN_PHYSDEV_ACCESS 8.33 8.34 @@ -677,10 +686,45 @@ config X86_VISWS_APIC 8.35 depends on X86_VISWS 8.36 default y 8.37 8.38 -#config X86_IO_APIC 8.39 -# bool 8.40 -# depends on SMP && !(X86_VISWS || X86_VOYAGER) 8.41 -# default y 8.42 +config X86_LOCAL_APIC 8.43 + bool 8.44 + depends on (X86_VISWS || SMP) && !X86_VOYAGER 8.45 + default y 8.46 + 8.47 +config X86_UP_APIC 8.48 + bool "Local APIC support on uniprocessors" if !SMP 8.49 + depends on !(X86_VISWS || X86_VOYAGER) 8.50 + ---help--- 8.51 + A local APIC (Advanced Programmable Interrupt Controller) is an 8.52 + integrated interrupt controller in the CPU. If you have a single-CPU 8.53 + system which has a processor with a local APIC, you can say Y here to 8.54 + enable and use it. If you say Y here even though your machine doesn't 8.55 + have a local APIC, then the kernel will still run with no slowdown at 8.56 + all. The local APIC supports CPU-generated self-interrupts (timer, 8.57 + performance counters), and the NMI watchdog which detects hard 8.58 + lockups. 8.59 + 8.60 + If you have a system with several CPUs, you do not need to say Y 8.61 + here: the local APIC will be used automatically. 8.62 + 8.63 +config X86_UP_IOAPIC 8.64 + bool "IO-APIC support on uniprocessors" 8.65 + depends on !SMP && X86_UP_APIC 8.66 + help 8.67 + An IO-APIC (I/O Advanced Programmable Interrupt Controller) is an 8.68 + SMP-capable replacement for PC-style interrupt controllers. Most 8.69 + SMP systems and a small number of uniprocessor systems have one. 8.70 + If you have a single-CPU system with an IO-APIC, you can say Y here 8.71 + to use it. If you say Y here even though your machine doesn't have 8.72 + an IO-APIC, then the kernel will still run with no slowdown at all. 8.73 + 8.74 + If you have a system with several CPUs, you do not need to say Y 8.75 + here: the IO-APIC will be used automatically. 8.76 + 8.77 +config X86_IO_APIC 8.78 + bool 8.79 + depends on SMP && !(X86_VISWS || X86_VOYAGER) 8.80 + default y 8.81 8.82 config PCI 8.83 bool "PCI support" if !X86_VISWS 8.84 @@ -697,52 +741,53 @@ config PCI 8.85 information about which PCI hardware does work under Linux and which 8.86 doesn't. 8.87 8.88 -#choice 8.89 -# prompt "PCI access mode" 8.90 -# depends on PCI && !X86_VISWS 8.91 -# default PCI_GOANY 8.92 -# ---help--- 8.93 -# On PCI systems, the BIOS can be used to detect the PCI devices and 8.94 -# determine their configuration. However, some old PCI motherboards 8.95 -# have BIOS bugs and may crash if this is done. Also, some embedded 8.96 -# PCI-based systems don't have any BIOS at all. Linux can also try to 8.97 -# detect the PCI hardware directly without using the BIOS. 8.98 -# 8.99 -# With this option, you can specify how Linux should detect the 8.100 -# PCI devices. If you choose "BIOS", the BIOS will be used, 8.101 -# if you choose "Direct", the BIOS won't be used, and if you 8.102 -# choose "MMConfig", then PCI Express MMCONFIG will be used. 8.103 -# If you choose "Any", the kernel will try MMCONFIG, then the 8.104 -# direct access method and falls back to the BIOS if that doesn't 8.105 -# work. If unsure, go with the default, which is "Any". 8.106 -# 8.107 -#config PCI_GOBIOS 8.108 -# bool "BIOS" 8.109 -# 8.110 -#config PCI_GOMMCONFIG 8.111 -# bool "MMConfig" 8.112 -# 8.113 -#config PCI_GODIRECT 8.114 -# bool "Direct" 8.115 -# 8.116 -#config PCI_GOANY 8.117 -# bool "Any" 8.118 -# 8.119 -#endchoice 8.120 -# 8.121 -#config PCI_BIOS 8.122 -# bool 8.123 -# depends on !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY) 8.124 -# default y 8.125 -# 8.126 -#config PCI_DIRECT 8.127 -# bool 8.128 -# depends on PCI && ((PCI_GODIRECT || PCI_GOANY) || X86_VISWS) 8.129 -# default y 8.130 +choice 8.131 + prompt "PCI access mode" 8.132 + depends on PCI && !X86_VISWS 8.133 + default PCI_GOANY 8.134 + ---help--- 8.135 + On PCI systems, the BIOS can be used to detect the PCI devices and 8.136 + determine their configuration. However, some old PCI motherboards 8.137 + have BIOS bugs and may crash if this is done. Also, some embedded 8.138 + PCI-based systems don't have any BIOS at all. Linux can also try to 8.139 + detect the PCI hardware directly without using the BIOS. 8.140 + 8.141 + With this option, you can specify how Linux should detect the 8.142 + PCI devices. If you choose "BIOS", the BIOS will be used, 8.143 + if you choose "Direct", the BIOS won't be used, and if you 8.144 + choose "MMConfig", then PCI Express MMCONFIG will be used. 8.145 + If you choose "Any", the kernel will try MMCONFIG, then the 8.146 + direct access method and falls back to the BIOS if that doesn't 8.147 + work. If unsure, go with the default, which is "Any". 8.148 + 8.149 +config PCI_GOBIOS 8.150 + bool "BIOS" 8.151 + 8.152 +config PCI_GOMMCONFIG 8.153 + bool "MMConfig" 8.154 + 8.155 +config PCI_GODIRECT 8.156 + bool "Direct" 8.157 + 8.158 +config PCI_GOANY 8.159 + bool "Any" 8.160 + 8.161 +endchoice 8.162 + 8.163 +config PCI_BIOS 8.164 + bool 8.165 + depends on !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY) 8.166 + default y 8.167 8.168 config PCI_DIRECT 8.169 bool 8.170 - depends on PCI 8.171 + depends on PCI && ((PCI_GODIRECT || PCI_GOANY) || X86_VISWS) 8.172 + default y 8.173 + 8.174 +config PCI_MMCONFIG 8.175 + bool 8.176 + depends on PCI && (PCI_GOMMCONFIG || (PCI_GOANY && ACPI)) 8.177 + select ACPI_BOOT 8.178 default y 8.179 8.180 source "drivers/pci/pcie/Kconfig" 8.181 @@ -812,129 +857,7 @@ endmenu 8.182 8.183 endif 8.184 8.185 -menu "Kernel hacking" 8.186 - 8.187 -config DEBUG_KERNEL 8.188 - bool "Kernel debugging" 8.189 - help 8.190 - Say Y here if you are developing drivers or trying to debug and 8.191 - identify kernel problems. 8.192 - 8.193 -config EARLY_PRINTK 8.194 - bool "Early printk" if EMBEDDED 8.195 - default y 8.196 - help 8.197 - Write kernel log output directly into the VGA buffer or to a serial 8.198 - port. 8.199 - 8.200 - This is useful for kernel debugging when your machine crashes very 8.201 - early before the console code is initialized. For normal operation 8.202 - it is not recommended because it looks ugly and doesn't cooperate 8.203 - with klogd/syslogd or the X server. You should normally N here, 8.204 - unless you want to debug such a crash. 8.205 - 8.206 -config DEBUG_STACKOVERFLOW 8.207 - bool "Check for stack overflows" 8.208 - depends on DEBUG_KERNEL 8.209 - 8.210 -config DEBUG_STACK_USAGE 8.211 - bool "Stack utilization instrumentation" 8.212 - depends on DEBUG_KERNEL 8.213 - help 8.214 - Enables the display of the minimum amount of free stack which each 8.215 - task has ever had available in the sysrq-T and sysrq-P debug output. 8.216 - 8.217 - This option will slow down process creation somewhat. 8.218 - 8.219 -config DEBUG_SLAB 8.220 - bool "Debug memory allocations" 8.221 - depends on DEBUG_KERNEL 8.222 - help 8.223 - Say Y here to have the kernel do limited verification on memory 8.224 - allocation as well as poisoning memory on free to catch use of freed 8.225 - memory. 8.226 - 8.227 -config MAGIC_SYSRQ 8.228 - bool "Magic SysRq key" 8.229 - depends on DEBUG_KERNEL 8.230 - help 8.231 - If you say Y here, you will have some control over the system even 8.232 - if the system crashes for example during kernel debugging (e.g., you 8.233 - will be able to flush the buffer cache to disk, reboot the system 8.234 - immediately or dump some status information). This is accomplished 8.235 - by pressing various keys while holding SysRq (Alt+PrintScreen). It 8.236 - also works on a serial console (on PC hardware at least), if you 8.237 - send a BREAK and then within 5 seconds a command keypress. The 8.238 - keys are documented in <file:Documentation/sysrq.txt>. Don't say Y 8.239 - unless you really know what this hack does. 8.240 - 8.241 -config DEBUG_SPINLOCK 8.242 - bool "Spinlock debugging" 8.243 - depends on DEBUG_KERNEL 8.244 - help 8.245 - Say Y here and build SMP to catch missing spinlock initialization 8.246 - and certain other kinds of spinlock errors commonly made. This is 8.247 - best used in conjunction with the NMI watchdog so that spinlock 8.248 - deadlocks are also debuggable. 8.249 - 8.250 -config DEBUG_PAGEALLOC 8.251 - bool "Page alloc debugging" 8.252 - depends on DEBUG_KERNEL 8.253 - help 8.254 - Unmap pages from the kernel linear mapping after free_pages(). 8.255 - This results in a large slowdown, but helps to find certain types 8.256 - of memory corruptions. 8.257 - 8.258 -config DEBUG_HIGHMEM 8.259 - bool "Highmem debugging" 8.260 - depends on DEBUG_KERNEL && HIGHMEM 8.261 - help 8.262 - This options enables addition error checking for high memory systems. 8.263 - Disable for production systems. 8.264 - 8.265 -config DEBUG_INFO 8.266 - bool "Compile the kernel with debug info" 8.267 - depends on DEBUG_KERNEL 8.268 - help 8.269 - If you say Y here the resulting kernel image will include 8.270 - debugging info resulting in a larger kernel image. 8.271 - Say Y here only if you plan to use gdb to debug the kernel. 8.272 - If you don't debug the kernel, you can say N. 8.273 - 8.274 -config DEBUG_SPINLOCK_SLEEP 8.275 - bool "Sleep-inside-spinlock checking" 8.276 - help 8.277 - If you say Y here, various routines which may sleep will become very 8.278 - noisy if they are called with a spinlock held. 8.279 - 8.280 -config FRAME_POINTER 8.281 - bool "Compile the kernel with frame pointers" 8.282 - help 8.283 - If you say Y here the resulting kernel image will be slightly larger 8.284 - and slower, but it will give very useful debugging information. 8.285 - If you don't debug the kernel, you can say N, but we may not be able 8.286 - to solve problems without frame pointers. 8.287 - 8.288 -config 4KSTACKS 8.289 - bool "Use 4Kb for kernel stacks instead of 8Kb" 8.290 - help 8.291 - If you say Y here the kernel will use a 4Kb stacksize for the 8.292 - kernel stack attached to each process/thread. This facilitates 8.293 - running more threads on a system and also reduces the pressure 8.294 - on the VM subsystem for higher order allocations. This option 8.295 - will also use IRQ stacks to compensate for the reduced stackspace. 8.296 - 8.297 -config X86_FIND_SMP_CONFIG 8.298 - bool 8.299 - depends on X86_LOCAL_APIC || X86_VOYAGER 8.300 - default y 8.301 - 8.302 -config X86_MPPARSE 8.303 - bool 8.304 - depends on X86_LOCAL_APIC && !X86_VISWS 8.305 - default y 8.306 - 8.307 -endmenu 8.308 +source "arch/i386/Kconfig.debug" 8.309 8.310 # 8.311 # Use the generic interrupt handling code in kernel/irq/:
9.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/Makefile Tue May 03 12:52:47 2005 +0000 9.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/Makefile Fri May 06 17:04:27 2005 +0000 9.3 @@ -20,7 +20,7 @@ s-obj-y := 9.4 9.5 obj-y += cpu/ 9.6 obj-y += timers/ 9.7 -c-obj-$(CONFIG_ACPI_BOOT) += acpi/ 9.8 +obj-$(CONFIG_ACPI_BOOT) += acpi/ 9.9 #c-obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o 9.10 c-obj-$(CONFIG_MCA) += mca.o 9.11 c-obj-$(CONFIG_X86_MSR) += msr.o 9.12 @@ -29,10 +29,10 @@ obj-$(CONFIG_MICROCODE) += microcode.o 9.13 c-obj-$(CONFIG_APM) += apm.o 9.14 obj-$(CONFIG_X86_SMP) += smp.o smpboot.o 9.15 #obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o 9.16 -c-obj-$(CONFIG_X86_MPPARSE) += mpparse.o 9.17 -#obj-$(CONFIG_X86_LOCAL_APIC) += apic.o 9.18 +obj-$(CONFIG_X86_MPPARSE) += mpparse.o 9.19 +obj-$(CONFIG_X86_LOCAL_APIC) += apic.o 9.20 c-obj-$(CONFIG_X86_LOCAL_APIC) += nmi.o 9.21 -c-obj-$(CONFIG_X86_IO_APIC) += io_apic.o 9.22 +obj-$(CONFIG_X86_IO_APIC) += io_apic.o 9.23 c-obj-$(CONFIG_X86_NUMAQ) += numaq.o 9.24 c-obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o 9.25 c-obj-$(CONFIG_MODULES) += module.o
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/acpi/Makefile Fri May 06 17:04:27 2005 +0000 10.3 @@ -0,0 +1,13 @@ 10.4 +obj-$(CONFIG_ACPI_BOOT) := boot.o 10.5 +c-obj-$(CONFIG_X86_IO_APIC) += earlyquirk.o 10.6 +c-obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o 10.7 + 10.8 +c-link := 10.9 + 10.10 +$(patsubst %.o,$(obj)/%.c,$(c-obj-y) $(c-link)): 10.11 + @ln -fsn $(srctree)/arch/i386/kernel/acpi/$(notdir $@) $@ 10.12 + 10.13 +obj-y += $(c-obj-y) $(s-obj-y) 10.14 + 10.15 +clean-files += $(patsubst %.o,%.c,$(c-obj-y) $(c-obj-) $(c-link)) 10.16 +clean-files += $(patsubst %.o,%.S,$(s-obj-y) $(s-obj-) $(s-link))
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/acpi/boot.c Fri May 06 17:04:27 2005 +0000 11.3 @@ -0,0 +1,921 @@ 11.4 +/* 11.5 + * boot.c - Architecture-Specific Low-Level ACPI Boot Support 11.6 + * 11.7 + * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 11.8 + * Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com> 11.9 + * 11.10 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11.11 + * 11.12 + * This program is free software; you can redistribute it and/or modify 11.13 + * it under the terms of the GNU General Public License as published by 11.14 + * the Free Software Foundation; either version 2 of the License, or 11.15 + * (at your option) any later version. 11.16 + * 11.17 + * This program is distributed in the hope that it will be useful, 11.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11.20 + * GNU General Public License for more details. 11.21 + * 11.22 + * You should have received a copy of the GNU General Public License 11.23 + * along with this program; if not, write to the Free Software 11.24 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 11.25 + * 11.26 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11.27 + */ 11.28 + 11.29 +#include <linux/init.h> 11.30 +#include <linux/config.h> 11.31 +#include <linux/acpi.h> 11.32 +#include <linux/efi.h> 11.33 +#include <linux/irq.h> 11.34 +#include <linux/module.h> 11.35 + 11.36 +#include <asm/pgtable.h> 11.37 +#include <asm/io_apic.h> 11.38 +#include <asm/apic.h> 11.39 +#include <asm/io.h> 11.40 +#include <asm/irq.h> 11.41 +#include <asm/mpspec.h> 11.42 +#ifdef CONFIG_XEN 11.43 +#include <asm/fixmap.h> 11.44 +#endif 11.45 + 11.46 +void (*pm_power_off)(void) = NULL; 11.47 + 11.48 +#ifdef CONFIG_X86_64 11.49 + 11.50 +static inline void acpi_madt_oem_check(char *oem_id, char *oem_table_id) { } 11.51 +extern void __init clustered_apic_check(void); 11.52 +static inline int ioapic_setup_disabled(void) { return 0; } 11.53 +#include <asm/proto.h> 11.54 + 11.55 +#else /* X86 */ 11.56 + 11.57 +#ifdef CONFIG_X86_LOCAL_APIC 11.58 +#include <mach_apic.h> 11.59 +#include <mach_mpparse.h> 11.60 +#endif /* CONFIG_X86_LOCAL_APIC */ 11.61 + 11.62 +#endif /* X86 */ 11.63 + 11.64 +#define BAD_MADT_ENTRY(entry, end) ( \ 11.65 + (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ 11.66 + ((acpi_table_entry_header *)entry)->length != sizeof(*entry)) 11.67 + 11.68 +#define PREFIX "ACPI: " 11.69 + 11.70 +#ifdef CONFIG_ACPI_PCI 11.71 +int acpi_noirq __initdata; /* skip ACPI IRQ initialization */ 11.72 +int acpi_pci_disabled __initdata; /* skip ACPI PCI scan and IRQ initialization */ 11.73 +#else 11.74 +int acpi_noirq __initdata = 1; 11.75 +int acpi_pci_disabled __initdata = 1; 11.76 +#endif 11.77 +int acpi_ht __initdata = 1; /* enable HT */ 11.78 + 11.79 +int acpi_lapic; 11.80 +int acpi_ioapic; 11.81 +int acpi_strict; 11.82 +EXPORT_SYMBOL(acpi_strict); 11.83 + 11.84 +acpi_interrupt_flags acpi_sci_flags __initdata; 11.85 +int acpi_sci_override_gsi __initdata; 11.86 +int acpi_skip_timer_override __initdata; 11.87 + 11.88 +#ifdef CONFIG_X86_LOCAL_APIC 11.89 +static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; 11.90 +#endif 11.91 + 11.92 +#ifndef __HAVE_ARCH_CMPXCHG 11.93 +#warning ACPI uses CMPXCHG, i486 and later hardware 11.94 +#endif 11.95 + 11.96 +#define MAX_MADT_ENTRIES 256 11.97 +u8 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] = 11.98 + { [0 ... MAX_MADT_ENTRIES-1] = 0xff }; 11.99 +EXPORT_SYMBOL(x86_acpiid_to_apicid); 11.100 + 11.101 +/* -------------------------------------------------------------------------- 11.102 + Boot-time Configuration 11.103 + -------------------------------------------------------------------------- */ 11.104 + 11.105 +/* 11.106 + * The default interrupt routing model is PIC (8259). This gets 11.107 + * overriden if IOAPICs are enumerated (below). 11.108 + */ 11.109 +enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC; 11.110 + 11.111 +#ifdef CONFIG_XEN 11.112 + 11.113 +char *__acpi_map_table(unsigned long phys_addr, unsigned long size) 11.114 +{ 11.115 + unsigned int i,j; 11.116 + 11.117 + j = PAGE_ALIGN(size) >> PAGE_SHIFT; 11.118 + for (i = 0; (i < FIX_ACPI_PAGES) && j ; i++, j--) { 11.119 + set_fixmap(FIX_ACPI_END - i, 11.120 + (phys_addr & PAGE_MASK) + (i << PAGE_SHIFT)); 11.121 + } 11.122 + 11.123 + return (char *) __fix_to_virt(FIX_ACPI_END) + (phys_addr & ~PAGE_MASK); 11.124 +} 11.125 + 11.126 +#else 11.127 +#ifdef CONFIG_X86_64 11.128 + 11.129 +/* rely on all ACPI tables being in the direct mapping */ 11.130 +char *__acpi_map_table(unsigned long phys_addr, unsigned long size) 11.131 +{ 11.132 + if (!phys_addr || !size) 11.133 + return NULL; 11.134 + 11.135 + if (phys_addr < (end_pfn_map << PAGE_SHIFT)) 11.136 + return __va(phys_addr); 11.137 + 11.138 + return NULL; 11.139 +} 11.140 + 11.141 +#else 11.142 + 11.143 +/* 11.144 + * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END, 11.145 + * to map the target physical address. The problem is that set_fixmap() 11.146 + * provides a single page, and it is possible that the page is not 11.147 + * sufficient. 11.148 + * By using this area, we can map up to MAX_IO_APICS pages temporarily, 11.149 + * i.e. until the next __va_range() call. 11.150 + * 11.151 + * Important Safety Note: The fixed I/O APIC page numbers are *subtracted* 11.152 + * from the fixed base. That's why we start at FIX_IO_APIC_BASE_END and 11.153 + * count idx down while incrementing the phys address. 11.154 + */ 11.155 +char *__acpi_map_table(unsigned long phys, unsigned long size) 11.156 +{ 11.157 + unsigned long base, offset, mapped_size; 11.158 + int idx; 11.159 + 11.160 + if (phys + size < 8*1024*1024) 11.161 + return __va(phys); 11.162 + 11.163 + offset = phys & (PAGE_SIZE - 1); 11.164 + mapped_size = PAGE_SIZE - offset; 11.165 + set_fixmap(FIX_ACPI_END, phys); 11.166 + base = fix_to_virt(FIX_ACPI_END); 11.167 + 11.168 + /* 11.169 + * Most cases can be covered by the below. 11.170 + */ 11.171 + idx = FIX_ACPI_END; 11.172 + while (mapped_size < size) { 11.173 + if (--idx < FIX_ACPI_BEGIN) 11.174 + return NULL; /* cannot handle this */ 11.175 + phys += PAGE_SIZE; 11.176 + set_fixmap(idx, phys); 11.177 + mapped_size += PAGE_SIZE; 11.178 + } 11.179 + 11.180 + return ((unsigned char *) base + offset); 11.181 +} 11.182 +#endif 11.183 +#endif /* CONFIG_XEN */ 11.184 + 11.185 +#ifdef CONFIG_PCI_MMCONFIG 11.186 +static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) 11.187 +{ 11.188 + struct acpi_table_mcfg *mcfg; 11.189 + 11.190 + if (!phys_addr || !size) 11.191 + return -EINVAL; 11.192 + 11.193 + mcfg = (struct acpi_table_mcfg *) __acpi_map_table(phys_addr, size); 11.194 + if (!mcfg) { 11.195 + printk(KERN_WARNING PREFIX "Unable to map MCFG\n"); 11.196 + return -ENODEV; 11.197 + } 11.198 + 11.199 + if (mcfg->base_reserved) { 11.200 + printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); 11.201 + return -ENODEV; 11.202 + } 11.203 + 11.204 + pci_mmcfg_base_addr = mcfg->base_address; 11.205 + 11.206 + return 0; 11.207 +} 11.208 +#else 11.209 +#define acpi_parse_mcfg NULL 11.210 +#endif /* !CONFIG_PCI_MMCONFIG */ 11.211 + 11.212 +#ifdef CONFIG_X86_LOCAL_APIC 11.213 +static int __init 11.214 +acpi_parse_madt ( 11.215 + unsigned long phys_addr, 11.216 + unsigned long size) 11.217 +{ 11.218 + struct acpi_table_madt *madt = NULL; 11.219 + 11.220 + if (!phys_addr || !size) 11.221 + return -EINVAL; 11.222 + 11.223 + madt = (struct acpi_table_madt *) __acpi_map_table(phys_addr, size); 11.224 + if (!madt) { 11.225 + printk(KERN_WARNING PREFIX "Unable to map MADT\n"); 11.226 + return -ENODEV; 11.227 + } 11.228 + 11.229 + if (madt->lapic_address) { 11.230 + acpi_lapic_addr = (u64) madt->lapic_address; 11.231 + 11.232 + printk(KERN_DEBUG PREFIX "Local APIC address 0x%08x\n", 11.233 + madt->lapic_address); 11.234 + } 11.235 + 11.236 + acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id); 11.237 + 11.238 + return 0; 11.239 +} 11.240 + 11.241 + 11.242 +static int __init 11.243 +acpi_parse_lapic ( 11.244 + acpi_table_entry_header *header, const unsigned long end) 11.245 +{ 11.246 + struct acpi_table_lapic *processor = NULL; 11.247 + 11.248 + processor = (struct acpi_table_lapic*) header; 11.249 + 11.250 + if (BAD_MADT_ENTRY(processor, end)) 11.251 + return -EINVAL; 11.252 + 11.253 + acpi_table_print_madt_entry(header); 11.254 + 11.255 + /* no utility in registering a disabled processor */ 11.256 + if (processor->flags.enabled == 0) 11.257 + return 0; 11.258 + 11.259 + x86_acpiid_to_apicid[processor->acpi_id] = processor->id; 11.260 + 11.261 + mp_register_lapic ( 11.262 + processor->id, /* APIC ID */ 11.263 + processor->flags.enabled); /* Enabled? */ 11.264 + 11.265 + return 0; 11.266 +} 11.267 + 11.268 +static int __init 11.269 +acpi_parse_lapic_addr_ovr ( 11.270 + acpi_table_entry_header *header, const unsigned long end) 11.271 +{ 11.272 + struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL; 11.273 + 11.274 + lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr*) header; 11.275 + 11.276 + if (BAD_MADT_ENTRY(lapic_addr_ovr, end)) 11.277 + return -EINVAL; 11.278 + 11.279 + acpi_lapic_addr = lapic_addr_ovr->address; 11.280 + 11.281 + return 0; 11.282 +} 11.283 + 11.284 +static int __init 11.285 +acpi_parse_lapic_nmi ( 11.286 + acpi_table_entry_header *header, const unsigned long end) 11.287 +{ 11.288 + struct acpi_table_lapic_nmi *lapic_nmi = NULL; 11.289 + 11.290 + lapic_nmi = (struct acpi_table_lapic_nmi*) header; 11.291 + 11.292 + if (BAD_MADT_ENTRY(lapic_nmi, end)) 11.293 + return -EINVAL; 11.294 + 11.295 + acpi_table_print_madt_entry(header); 11.296 + 11.297 + if (lapic_nmi->lint != 1) 11.298 + printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n"); 11.299 + 11.300 + return 0; 11.301 +} 11.302 + 11.303 + 11.304 +#endif /*CONFIG_X86_LOCAL_APIC*/ 11.305 + 11.306 +#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER) 11.307 + 11.308 +static int __init 11.309 +acpi_parse_ioapic ( 11.310 + acpi_table_entry_header *header, const unsigned long end) 11.311 +{ 11.312 + struct acpi_table_ioapic *ioapic = NULL; 11.313 + 11.314 + ioapic = (struct acpi_table_ioapic*) header; 11.315 + 11.316 + if (BAD_MADT_ENTRY(ioapic, end)) 11.317 + return -EINVAL; 11.318 + 11.319 + acpi_table_print_madt_entry(header); 11.320 + 11.321 + mp_register_ioapic ( 11.322 + ioapic->id, 11.323 + ioapic->address, 11.324 + ioapic->global_irq_base); 11.325 + 11.326 + return 0; 11.327 +} 11.328 + 11.329 +/* 11.330 + * Parse Interrupt Source Override for the ACPI SCI 11.331 + */ 11.332 +static void 11.333 +acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) 11.334 +{ 11.335 + if (trigger == 0) /* compatible SCI trigger is level */ 11.336 + trigger = 3; 11.337 + 11.338 + if (polarity == 0) /* compatible SCI polarity is low */ 11.339 + polarity = 3; 11.340 + 11.341 + /* Command-line over-ride via acpi_sci= */ 11.342 + if (acpi_sci_flags.trigger) 11.343 + trigger = acpi_sci_flags.trigger; 11.344 + 11.345 + if (acpi_sci_flags.polarity) 11.346 + polarity = acpi_sci_flags.polarity; 11.347 + 11.348 + /* 11.349 + * mp_config_acpi_legacy_irqs() already setup IRQs < 16 11.350 + * If GSI is < 16, this will update its flags, 11.351 + * else it will create a new mp_irqs[] entry. 11.352 + */ 11.353 + mp_override_legacy_irq(gsi, polarity, trigger, gsi); 11.354 + 11.355 + /* 11.356 + * stash over-ride to indicate we've been here 11.357 + * and for later update of acpi_fadt 11.358 + */ 11.359 + acpi_sci_override_gsi = gsi; 11.360 + return; 11.361 +} 11.362 + 11.363 +static int __init 11.364 +acpi_parse_int_src_ovr ( 11.365 + acpi_table_entry_header *header, const unsigned long end) 11.366 +{ 11.367 + struct acpi_table_int_src_ovr *intsrc = NULL; 11.368 + 11.369 + intsrc = (struct acpi_table_int_src_ovr*) header; 11.370 + 11.371 + if (BAD_MADT_ENTRY(intsrc, end)) 11.372 + return -EINVAL; 11.373 + 11.374 + acpi_table_print_madt_entry(header); 11.375 + 11.376 + if (intsrc->bus_irq == acpi_fadt.sci_int) { 11.377 + acpi_sci_ioapic_setup(intsrc->global_irq, 11.378 + intsrc->flags.polarity, intsrc->flags.trigger); 11.379 + return 0; 11.380 + } 11.381 + 11.382 + if (acpi_skip_timer_override && 11.383 + intsrc->bus_irq == 0 && intsrc->global_irq == 2) { 11.384 + printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n"); 11.385 + return 0; 11.386 + } 11.387 + 11.388 + mp_override_legacy_irq ( 11.389 + intsrc->bus_irq, 11.390 + intsrc->flags.polarity, 11.391 + intsrc->flags.trigger, 11.392 + intsrc->global_irq); 11.393 + 11.394 + return 0; 11.395 +} 11.396 + 11.397 + 11.398 +static int __init 11.399 +acpi_parse_nmi_src ( 11.400 + acpi_table_entry_header *header, const unsigned long end) 11.401 +{ 11.402 + struct acpi_table_nmi_src *nmi_src = NULL; 11.403 + 11.404 + nmi_src = (struct acpi_table_nmi_src*) header; 11.405 + 11.406 + if (BAD_MADT_ENTRY(nmi_src, end)) 11.407 + return -EINVAL; 11.408 + 11.409 + acpi_table_print_madt_entry(header); 11.410 + 11.411 + /* TBD: Support nimsrc entries? */ 11.412 + 11.413 + return 0; 11.414 +} 11.415 + 11.416 +#endif /* CONFIG_X86_IO_APIC */ 11.417 + 11.418 +#ifdef CONFIG_ACPI_BUS 11.419 + 11.420 +/* 11.421 + * acpi_pic_sci_set_trigger() 11.422 + * 11.423 + * use ELCR to set PIC-mode trigger type for SCI 11.424 + * 11.425 + * If a PIC-mode SCI is not recognized or gives spurious IRQ7's 11.426 + * it may require Edge Trigger -- use "acpi_sci=edge" 11.427 + * 11.428 + * Port 0x4d0-4d1 are ECLR1 and ECLR2, the Edge/Level Control Registers 11.429 + * for the 8259 PIC. bit[n] = 1 means irq[n] is Level, otherwise Edge. 11.430 + * ECLR1 is IRQ's 0-7 (IRQ 0, 1, 2 must be 0) 11.431 + * ECLR2 is IRQ's 8-15 (IRQ 8, 13 must be 0) 11.432 + */ 11.433 + 11.434 +void __init 11.435 +acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) 11.436 +{ 11.437 + unsigned int mask = 1 << irq; 11.438 + unsigned int old, new; 11.439 + 11.440 + /* Real old ELCR mask */ 11.441 + old = inb(0x4d0) | (inb(0x4d1) << 8); 11.442 + 11.443 + /* 11.444 + * If we use ACPI to set PCI irq's, then we should clear ELCR 11.445 + * since we will set it correctly as we enable the PCI irq 11.446 + * routing. 11.447 + */ 11.448 + new = acpi_noirq ? old : 0; 11.449 + 11.450 + /* 11.451 + * Update SCI information in the ELCR, it isn't in the PCI 11.452 + * routing tables.. 11.453 + */ 11.454 + switch (trigger) { 11.455 + case 1: /* Edge - clear */ 11.456 + new &= ~mask; 11.457 + break; 11.458 + case 3: /* Level - set */ 11.459 + new |= mask; 11.460 + break; 11.461 + } 11.462 + 11.463 + if (old == new) 11.464 + return; 11.465 + 11.466 + printk(PREFIX "setting ELCR to %04x (from %04x)\n", new, old); 11.467 + outb(new, 0x4d0); 11.468 + outb(new >> 8, 0x4d1); 11.469 +} 11.470 + 11.471 + 11.472 +#endif /* CONFIG_ACPI_BUS */ 11.473 + 11.474 +int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) 11.475 +{ 11.476 +#ifdef CONFIG_X86_IO_APIC 11.477 + if (use_pci_vector() && !platform_legacy_irq(gsi)) 11.478 + *irq = IO_APIC_VECTOR(gsi); 11.479 + else 11.480 +#endif 11.481 + *irq = gsi; 11.482 + return 0; 11.483 +} 11.484 + 11.485 +unsigned int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low) 11.486 +{ 11.487 + unsigned int irq; 11.488 + unsigned int plat_gsi = gsi; 11.489 + 11.490 +#ifdef CONFIG_X86_IO_APIC 11.491 + if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) { 11.492 + plat_gsi = mp_register_gsi(gsi, edge_level, active_high_low); 11.493 + } 11.494 +#endif 11.495 + acpi_gsi_to_irq(plat_gsi, &irq); 11.496 + return irq; 11.497 +} 11.498 +EXPORT_SYMBOL(acpi_register_gsi); 11.499 + 11.500 +/* 11.501 + * ACPI based hotplug support for CPU 11.502 + */ 11.503 +#ifdef CONFIG_ACPI_HOTPLUG_CPU 11.504 +int 11.505 +acpi_map_lsapic(acpi_handle handle, int *pcpu) 11.506 +{ 11.507 + /* TBD */ 11.508 + return -EINVAL; 11.509 +} 11.510 +EXPORT_SYMBOL(acpi_map_lsapic); 11.511 + 11.512 + 11.513 +int 11.514 +acpi_unmap_lsapic(int cpu) 11.515 +{ 11.516 + /* TBD */ 11.517 + return -EINVAL; 11.518 +} 11.519 +EXPORT_SYMBOL(acpi_unmap_lsapic); 11.520 +#endif /* CONFIG_ACPI_HOTPLUG_CPU */ 11.521 + 11.522 +static unsigned long __init 11.523 +acpi_scan_rsdp ( 11.524 + unsigned long start, 11.525 + unsigned long length) 11.526 +{ 11.527 + unsigned long offset = 0; 11.528 + unsigned long sig_len = sizeof("RSD PTR ") - 1; 11.529 + unsigned long vstart = (unsigned long)isa_bus_to_virt(start); 11.530 + 11.531 + /* 11.532 + * Scan all 16-byte boundaries of the physical memory region for the 11.533 + * RSDP signature. 11.534 + */ 11.535 + for (offset = 0; offset < length; offset += 16) { 11.536 + if (strncmp((char *) (vstart + offset), "RSD PTR ", sig_len)) 11.537 + continue; 11.538 + return (start + offset); 11.539 + } 11.540 + 11.541 + return 0; 11.542 +} 11.543 + 11.544 +static int __init acpi_parse_sbf(unsigned long phys_addr, unsigned long size) 11.545 +{ 11.546 + struct acpi_table_sbf *sb; 11.547 + 11.548 + if (!phys_addr || !size) 11.549 + return -EINVAL; 11.550 + 11.551 + sb = (struct acpi_table_sbf *) __acpi_map_table(phys_addr, size); 11.552 + if (!sb) { 11.553 + printk(KERN_WARNING PREFIX "Unable to map SBF\n"); 11.554 + return -ENODEV; 11.555 + } 11.556 + 11.557 + sbf_port = sb->sbf_cmos; /* Save CMOS port */ 11.558 + 11.559 + return 0; 11.560 +} 11.561 + 11.562 + 11.563 +#ifdef CONFIG_HPET_TIMER 11.564 + 11.565 +static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) 11.566 +{ 11.567 + struct acpi_table_hpet *hpet_tbl; 11.568 + 11.569 + if (!phys || !size) 11.570 + return -EINVAL; 11.571 + 11.572 + hpet_tbl = (struct acpi_table_hpet *) __acpi_map_table(phys, size); 11.573 + if (!hpet_tbl) { 11.574 + printk(KERN_WARNING PREFIX "Unable to map HPET\n"); 11.575 + return -ENODEV; 11.576 + } 11.577 + 11.578 + if (hpet_tbl->addr.space_id != ACPI_SPACE_MEM) { 11.579 + printk(KERN_WARNING PREFIX "HPET timers must be located in " 11.580 + "memory.\n"); 11.581 + return -1; 11.582 + } 11.583 + 11.584 +#ifdef CONFIG_X86_64 11.585 + vxtime.hpet_address = hpet_tbl->addr.addrl | 11.586 + ((long) hpet_tbl->addr.addrh << 32); 11.587 + 11.588 + printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", 11.589 + hpet_tbl->id, vxtime.hpet_address); 11.590 +#else /* X86 */ 11.591 + { 11.592 + extern unsigned long hpet_address; 11.593 + 11.594 + hpet_address = hpet_tbl->addr.addrl; 11.595 + printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", 11.596 + hpet_tbl->id, hpet_address); 11.597 + } 11.598 +#endif /* X86 */ 11.599 + 11.600 + return 0; 11.601 +} 11.602 +#else 11.603 +#define acpi_parse_hpet NULL 11.604 +#endif 11.605 + 11.606 +#ifdef CONFIG_X86_PM_TIMER 11.607 +extern u32 pmtmr_ioport; 11.608 +#endif 11.609 + 11.610 +static int __init acpi_parse_fadt(unsigned long phys, unsigned long size) 11.611 +{ 11.612 + struct fadt_descriptor_rev2 *fadt = NULL; 11.613 + 11.614 + fadt = (struct fadt_descriptor_rev2*) __acpi_map_table(phys,size); 11.615 + if(!fadt) { 11.616 + printk(KERN_WARNING PREFIX "Unable to map FADT\n"); 11.617 + return 0; 11.618 + } 11.619 + 11.620 +#ifdef CONFIG_ACPI_INTERPRETER 11.621 + /* initialize sci_int early for INT_SRC_OVR MADT parsing */ 11.622 + acpi_fadt.sci_int = fadt->sci_int; 11.623 +#endif 11.624 + 11.625 +#ifdef CONFIG_X86_PM_TIMER 11.626 + /* detect the location of the ACPI PM Timer */ 11.627 + if (fadt->revision >= FADT2_REVISION_ID) { 11.628 + /* FADT rev. 2 */ 11.629 + if (fadt->xpm_tmr_blk.address_space_id != ACPI_ADR_SPACE_SYSTEM_IO) 11.630 + return 0; 11.631 + 11.632 + pmtmr_ioport = fadt->xpm_tmr_blk.address; 11.633 + } else { 11.634 + /* FADT rev. 1 */ 11.635 + pmtmr_ioport = fadt->V1_pm_tmr_blk; 11.636 + } 11.637 + if (pmtmr_ioport) 11.638 + printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n", pmtmr_ioport); 11.639 +#endif 11.640 + return 0; 11.641 +} 11.642 + 11.643 + 11.644 +unsigned long __init 11.645 +acpi_find_rsdp (void) 11.646 +{ 11.647 + unsigned long rsdp_phys = 0; 11.648 + 11.649 + if (efi_enabled) { 11.650 + if (efi.acpi20) 11.651 + return __pa(efi.acpi20); 11.652 + else if (efi.acpi) 11.653 + return __pa(efi.acpi); 11.654 + } 11.655 + /* 11.656 + * Scan memory looking for the RSDP signature. First search EBDA (low 11.657 + * memory) paragraphs and then search upper memory (E0000-FFFFF). 11.658 + */ 11.659 + rsdp_phys = acpi_scan_rsdp (0, 0x400); 11.660 + if (!rsdp_phys) 11.661 + rsdp_phys = acpi_scan_rsdp (0xE0000, 0x20000); 11.662 + 11.663 + set_fixmap(FIX_ACPI_RSDP_PAGE, rsdp_phys); 11.664 + 11.665 + return rsdp_phys; 11.666 +} 11.667 + 11.668 +#ifdef CONFIG_X86_LOCAL_APIC 11.669 +/* 11.670 + * Parse LAPIC entries in MADT 11.671 + * returns 0 on success, < 0 on error 11.672 + */ 11.673 +static int __init 11.674 +acpi_parse_madt_lapic_entries(void) 11.675 +{ 11.676 + int count; 11.677 + 11.678 + /* 11.679 + * Note that the LAPIC address is obtained from the MADT (32-bit value) 11.680 + * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). 11.681 + */ 11.682 + 11.683 + count = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0); 11.684 + if (count < 0) { 11.685 + printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); 11.686 + return count; 11.687 + } 11.688 + 11.689 + mp_register_lapic_address(acpi_lapic_addr); 11.690 + 11.691 + count = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic, 11.692 + MAX_APICS); 11.693 + if (!count) { 11.694 + printk(KERN_ERR PREFIX "No LAPIC entries present\n"); 11.695 + /* TBD: Cleanup to allow fallback to MPS */ 11.696 + return -ENODEV; 11.697 + } 11.698 + else if (count < 0) { 11.699 + printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); 11.700 + /* TBD: Cleanup to allow fallback to MPS */ 11.701 + return count; 11.702 + } 11.703 + 11.704 + count = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0); 11.705 + if (count < 0) { 11.706 + printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); 11.707 + /* TBD: Cleanup to allow fallback to MPS */ 11.708 + return count; 11.709 + } 11.710 + return 0; 11.711 +} 11.712 +#endif /* CONFIG_X86_LOCAL_APIC */ 11.713 + 11.714 +#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER) 11.715 +/* 11.716 + * Parse IOAPIC related entries in MADT 11.717 + * returns 0 on success, < 0 on error 11.718 + */ 11.719 +static int __init 11.720 +acpi_parse_madt_ioapic_entries(void) 11.721 +{ 11.722 + int count; 11.723 + 11.724 + /* 11.725 + * ACPI interpreter is required to complete interrupt setup, 11.726 + * so if it is off, don't enumerate the io-apics with ACPI. 11.727 + * If MPS is present, it will handle them, 11.728 + * otherwise the system will stay in PIC mode 11.729 + */ 11.730 + if (acpi_disabled || acpi_noirq) { 11.731 + return -ENODEV; 11.732 + } 11.733 + 11.734 + /* 11.735 + * if "noapic" boot option, don't look for IO-APICs 11.736 + */ 11.737 + if (skip_ioapic_setup) { 11.738 + printk(KERN_INFO PREFIX "Skipping IOAPIC probe " 11.739 + "due to 'noapic' option.\n"); 11.740 + return -ENODEV; 11.741 + } 11.742 + 11.743 + count = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, MAX_IO_APICS); 11.744 + if (!count) { 11.745 + printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); 11.746 + return -ENODEV; 11.747 + } 11.748 + else if (count < 0) { 11.749 + printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n"); 11.750 + return count; 11.751 + } 11.752 + 11.753 + count = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, NR_IRQ_VECTORS); 11.754 + if (count < 0) { 11.755 + printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); 11.756 + /* TBD: Cleanup to allow fallback to MPS */ 11.757 + return count; 11.758 + } 11.759 + 11.760 + /* 11.761 + * If BIOS did not supply an INT_SRC_OVR for the SCI 11.762 + * pretend we got one so we can set the SCI flags. 11.763 + */ 11.764 + if (!acpi_sci_override_gsi) 11.765 + acpi_sci_ioapic_setup(acpi_fadt.sci_int, 0, 0); 11.766 + 11.767 + /* Fill in identity legacy mapings where no override */ 11.768 + mp_config_acpi_legacy_irqs(); 11.769 + 11.770 + count = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, NR_IRQ_VECTORS); 11.771 + if (count < 0) { 11.772 + printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); 11.773 + /* TBD: Cleanup to allow fallback to MPS */ 11.774 + return count; 11.775 + } 11.776 + 11.777 + return 0; 11.778 +} 11.779 +#else 11.780 +static inline int acpi_parse_madt_ioapic_entries(void) 11.781 +{ 11.782 + return -1; 11.783 +} 11.784 +#endif /* !(CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER) */ 11.785 + 11.786 + 11.787 +static void __init 11.788 +acpi_process_madt(void) 11.789 +{ 11.790 +#ifdef CONFIG_X86_LOCAL_APIC 11.791 + int count, error; 11.792 + 11.793 + count = acpi_table_parse(ACPI_APIC, acpi_parse_madt); 11.794 + if (count >= 1) { 11.795 + 11.796 + /* 11.797 + * Parse MADT LAPIC entries 11.798 + */ 11.799 + error = acpi_parse_madt_lapic_entries(); 11.800 + if (!error) { 11.801 + acpi_lapic = 1; 11.802 + 11.803 + /* 11.804 + * Parse MADT IO-APIC entries 11.805 + */ 11.806 + error = acpi_parse_madt_ioapic_entries(); 11.807 + if (!error) { 11.808 + acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; 11.809 + acpi_irq_balance_set(NULL); 11.810 + acpi_ioapic = 1; 11.811 + 11.812 + smp_found_config = 1; 11.813 + clustered_apic_check(); 11.814 + } 11.815 + } 11.816 + if (error == -EINVAL) { 11.817 + /* 11.818 + * Dell Precision Workstation 410, 610 come here. 11.819 + */ 11.820 + printk(KERN_ERR PREFIX "Invalid BIOS MADT, disabling ACPI\n"); 11.821 + disable_acpi(); 11.822 + } 11.823 + } 11.824 +#endif 11.825 + return; 11.826 +} 11.827 + 11.828 +/* 11.829 + * acpi_boot_table_init() and acpi_boot_init() 11.830 + * called from setup_arch(), always. 11.831 + * 1. checksums all tables 11.832 + * 2. enumerates lapics 11.833 + * 3. enumerates io-apics 11.834 + * 11.835 + * acpi_table_init() is separate to allow reading SRAT without 11.836 + * other side effects. 11.837 + * 11.838 + * side effects of acpi_boot_init: 11.839 + * acpi_lapic = 1 if LAPIC found 11.840 + * acpi_ioapic = 1 if IOAPIC found 11.841 + * if (acpi_lapic && acpi_ioapic) smp_found_config = 1; 11.842 + * if acpi_blacklisted() acpi_disabled = 1; 11.843 + * acpi_irq_model=... 11.844 + * ... 11.845 + * 11.846 + * return value: (currently ignored) 11.847 + * 0: success 11.848 + * !0: failure 11.849 + */ 11.850 + 11.851 +int __init 11.852 +acpi_boot_table_init(void) 11.853 +{ 11.854 + int error; 11.855 + 11.856 + /* 11.857 + * If acpi_disabled, bail out 11.858 + * One exception: acpi=ht continues far enough to enumerate LAPICs 11.859 + */ 11.860 + if (acpi_disabled && !acpi_ht) 11.861 + return 1; 11.862 + 11.863 + /* 11.864 + * Initialize the ACPI boot-time table parser. 11.865 + */ 11.866 + error = acpi_table_init(); 11.867 + if (error) { 11.868 + disable_acpi(); 11.869 + return error; 11.870 + } 11.871 + 11.872 +#ifdef __i386__ 11.873 + check_acpi_pci(); 11.874 +#endif 11.875 + 11.876 + acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); 11.877 + 11.878 + /* 11.879 + * blacklist may disable ACPI entirely 11.880 + */ 11.881 + error = acpi_blacklisted(); 11.882 + if (error) { 11.883 + extern int acpi_force; 11.884 + 11.885 + if (acpi_force) { 11.886 + printk(KERN_WARNING PREFIX "acpi=force override\n"); 11.887 + } else { 11.888 + printk(KERN_WARNING PREFIX "Disabling ACPI support\n"); 11.889 + disable_acpi(); 11.890 + return error; 11.891 + } 11.892 + } 11.893 + 11.894 + return 0; 11.895 +} 11.896 + 11.897 + 11.898 +int __init acpi_boot_init(void) 11.899 +{ 11.900 + /* 11.901 + * If acpi_disabled, bail out 11.902 + * One exception: acpi=ht continues far enough to enumerate LAPICs 11.903 + */ 11.904 + if (acpi_disabled && !acpi_ht) 11.905 + return 1; 11.906 + 11.907 + acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); 11.908 + 11.909 + /* 11.910 + * set sci_int and PM timer address 11.911 + */ 11.912 + acpi_table_parse(ACPI_FADT, acpi_parse_fadt); 11.913 + 11.914 + /* 11.915 + * Process the Multiple APIC Description Table (MADT), if present 11.916 + */ 11.917 + acpi_process_madt(); 11.918 + 11.919 + acpi_table_parse(ACPI_HPET, acpi_parse_hpet); 11.920 + acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); 11.921 + 11.922 + return 0; 11.923 +} 11.924 +
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/apic.c Fri May 06 17:04:27 2005 +0000 12.3 @@ -0,0 +1,83 @@ 12.4 +/* 12.5 + * Local APIC handling, local APIC timers 12.6 + * 12.7 + * (c) 1999, 2000 Ingo Molnar <mingo@redhat.com> 12.8 + * 12.9 + * Fixes 12.10 + * Maciej W. Rozycki : Bits for genuine 82489DX APICs; 12.11 + * thanks to Eric Gilmore 12.12 + * and Rolf G. Tews 12.13 + * for testing these extensively. 12.14 + * Maciej W. Rozycki : Various updates and fixes. 12.15 + * Mikael Pettersson : Power Management for UP-APIC. 12.16 + * Pavel Machek and 12.17 + * Mikael Pettersson : PM converted to driver model. 12.18 + */ 12.19 + 12.20 +#include <linux/config.h> 12.21 +#include <linux/init.h> 12.22 + 12.23 +#include <linux/mm.h> 12.24 +#include <linux/irq.h> 12.25 +#include <linux/delay.h> 12.26 +#include <linux/bootmem.h> 12.27 +#include <linux/smp_lock.h> 12.28 +#include <linux/interrupt.h> 12.29 +#include <linux/mc146818rtc.h> 12.30 +#include <linux/kernel_stat.h> 12.31 +#include <linux/sysdev.h> 12.32 + 12.33 +#include <asm/atomic.h> 12.34 +#include <asm/smp.h> 12.35 +#include <asm/mtrr.h> 12.36 +#include <asm/mpspec.h> 12.37 +#include <asm/desc.h> 12.38 +#include <asm/arch_hooks.h> 12.39 +#include <asm/hpet.h> 12.40 + 12.41 +#include <mach_apic.h> 12.42 + 12.43 +#include "io_ports.h" 12.44 + 12.45 +/* 12.46 + * Debug level 12.47 + */ 12.48 +int apic_verbosity; 12.49 + 12.50 +int get_physical_broadcast(void) 12.51 +{ 12.52 + return 0xff; 12.53 +} 12.54 + 12.55 +/* 12.56 + * 'what should we do if we get a hw irq event on an illegal vector'. 12.57 + * each architecture has to answer this themselves. 12.58 + */ 12.59 +void ack_bad_irq(unsigned int irq) 12.60 +{ 12.61 + printk("unexpected IRQ trap at vector %02x\n", irq); 12.62 + /* 12.63 + * Currently unexpected vectors happen only on SMP and APIC. 12.64 + * We _must_ ack these because every local APIC has only N 12.65 + * irq slots per priority level, and a 'hanging, unacked' IRQ 12.66 + * holds up an irq slot - in excessive cases (when multiple 12.67 + * unexpected vectors occur) that might lock up the APIC 12.68 + * completely. 12.69 + */ 12.70 + ack_APIC_irq(); 12.71 +} 12.72 + 12.73 +/* 12.74 + * This initializes the IO-APIC and APIC hardware if this is 12.75 + * a UP kernel. 12.76 + */ 12.77 +int __init APIC_init_uniprocessor (void) 12.78 +{ 12.79 +#ifdef CONFIG_X86_IO_APIC 12.80 + if (smp_found_config) 12.81 + if (!skip_ioapic_setup && nr_ioapics) 12.82 + setup_IO_APIC(); 12.83 +#endif 12.84 + 12.85 + return 0; 12.86 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/io_apic.c Fri May 06 17:04:27 2005 +0000 13.3 @@ -0,0 +1,2610 @@ 13.4 +/* 13.5 + * Intel IO-APIC support for multi-Pentium hosts. 13.6 + * 13.7 + * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar, Hajnalka Szabo 13.8 + * 13.9 + * Many thanks to Stig Venaas for trying out countless experimental 13.10 + * patches and reporting/debugging problems patiently! 13.11 + * 13.12 + * (c) 1999, Multiple IO-APIC support, developed by 13.13 + * Ken-ichi Yaku <yaku@css1.kbnes.nec.co.jp> and 13.14 + * Hidemi Kishimoto <kisimoto@css1.kbnes.nec.co.jp>, 13.15 + * further tested and cleaned up by Zach Brown <zab@redhat.com> 13.16 + * and Ingo Molnar <mingo@redhat.com> 13.17 + * 13.18 + * Fixes 13.19 + * Maciej W. Rozycki : Bits for genuine 82489DX APICs; 13.20 + * thanks to Eric Gilmore 13.21 + * and Rolf G. Tews 13.22 + * for testing these extensively 13.23 + * Paul Diefenbaugh : Added full ACPI support 13.24 + */ 13.25 + 13.26 +#include <linux/mm.h> 13.27 +#include <linux/irq.h> 13.28 +#include <linux/interrupt.h> 13.29 +#include <linux/init.h> 13.30 +#include <linux/delay.h> 13.31 +#include <linux/sched.h> 13.32 +#include <linux/config.h> 13.33 +#include <linux/smp_lock.h> 13.34 +#include <linux/mc146818rtc.h> 13.35 +#include <linux/compiler.h> 13.36 +#include <linux/acpi.h> 13.37 + 13.38 +#include <linux/sysdev.h> 13.39 +#include <asm/io.h> 13.40 +#include <asm/smp.h> 13.41 +#include <asm/desc.h> 13.42 +#include <asm/timer.h> 13.43 + 13.44 +#include <mach_apic.h> 13.45 + 13.46 +#include "io_ports.h" 13.47 + 13.48 +#ifdef CONFIG_XEN 13.49 + 13.50 +#include <asm-xen/xen-public/xen.h> 13.51 +#include <asm-xen/xen-public/physdev.h> 13.52 + 13.53 +/* Fake i8259 */ 13.54 +#define make_8259A_irq(_irq) (io_apic_irqs &= ~(1UL<<(_irq))) 13.55 +#define disable_8259A_irq(_irq) ((void)0) 13.56 +#define i8259A_irq_pending(_irq) (0) 13.57 + 13.58 +unsigned long io_apic_irqs; 13.59 + 13.60 +static inline unsigned int xen_io_apic_read(unsigned int apic, unsigned int reg) 13.61 +{ 13.62 + physdev_op_t op; 13.63 + int ret; 13.64 + 13.65 + op.cmd = PHYSDEVOP_APIC_READ; 13.66 + op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid; 13.67 + op.u.apic_op.offset = reg; 13.68 + ret = HYPERVISOR_physdev_op(&op); 13.69 + if (ret) 13.70 + return ret; 13.71 + return op.u.apic_op.value; 13.72 +} 13.73 + 13.74 +static inline void xen_io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) 13.75 +{ 13.76 + physdev_op_t op; 13.77 + 13.78 + op.cmd = PHYSDEVOP_APIC_WRITE; 13.79 + op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid; 13.80 + op.u.apic_op.offset = reg; 13.81 + op.u.apic_op.value = value; 13.82 + HYPERVISOR_physdev_op(&op); 13.83 +} 13.84 + 13.85 +#define io_apic_read(a,r) xen_io_apic_read(a,r) 13.86 +#define io_apic_write(a,r,v) xen_io_apic_write(a,r,v) 13.87 + 13.88 +#endif /* CONFIG_XEN */ 13.89 + 13.90 +int (*ioapic_renumber_irq)(int ioapic, int irq); 13.91 +atomic_t irq_mis_count; 13.92 + 13.93 +static DEFINE_SPINLOCK(ioapic_lock); 13.94 + 13.95 +/* 13.96 + * Is the SiS APIC rmw bug present ? 13.97 + * -1 = don't know, 0 = no, 1 = yes 13.98 + */ 13.99 +int sis_apic_bug = -1; 13.100 + 13.101 +/* 13.102 + * # of IRQ routing registers 13.103 + */ 13.104 +int nr_ioapic_registers[MAX_IO_APICS]; 13.105 + 13.106 +/* 13.107 + * Rough estimation of how many shared IRQs there are, can 13.108 + * be changed anytime. 13.109 + */ 13.110 +#define MAX_PLUS_SHARED_IRQS NR_IRQS 13.111 +#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + NR_IRQS) 13.112 + 13.113 +/* 13.114 + * This is performance-critical, we want to do it O(1) 13.115 + * 13.116 + * the indexing order of this array favors 1:1 mappings 13.117 + * between pins and IRQs. 13.118 + */ 13.119 + 13.120 +static struct irq_pin_list { 13.121 + int apic, pin, next; 13.122 +} irq_2_pin[PIN_MAP_SIZE]; 13.123 + 13.124 +int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; 13.125 +#ifdef CONFIG_PCI_MSI 13.126 +#define vector_to_irq(vector) \ 13.127 + (platform_legacy_irq(vector) ? vector : vector_irq[vector]) 13.128 +#else 13.129 +#define vector_to_irq(vector) (vector) 13.130 +#endif 13.131 + 13.132 +/* 13.133 + * The common case is 1:1 IRQ<->pin mappings. Sometimes there are 13.134 + * shared ISA-space IRQs, so we have to support them. We are super 13.135 + * fast in the common case, and fast for shared ISA-space IRQs. 13.136 + */ 13.137 +static void add_pin_to_irq(unsigned int irq, int apic, int pin) 13.138 +{ 13.139 + static int first_free_entry = NR_IRQS; 13.140 + struct irq_pin_list *entry = irq_2_pin + irq; 13.141 + 13.142 + while (entry->next) 13.143 + entry = irq_2_pin + entry->next; 13.144 + 13.145 + if (entry->pin != -1) { 13.146 + entry->next = first_free_entry; 13.147 + entry = irq_2_pin + entry->next; 13.148 + if (++first_free_entry >= PIN_MAP_SIZE) 13.149 + panic("io_apic.c: whoops"); 13.150 + } 13.151 + entry->apic = apic; 13.152 + entry->pin = pin; 13.153 +} 13.154 + 13.155 +#ifndef CONFIG_XEN 13.156 +/* 13.157 + * Reroute an IRQ to a different pin. 13.158 + */ 13.159 +static void __init replace_pin_at_irq(unsigned int irq, 13.160 + int oldapic, int oldpin, 13.161 + int newapic, int newpin) 13.162 +{ 13.163 + struct irq_pin_list *entry = irq_2_pin + irq; 13.164 + 13.165 + while (1) { 13.166 + if (entry->apic == oldapic && entry->pin == oldpin) { 13.167 + entry->apic = newapic; 13.168 + entry->pin = newpin; 13.169 + } 13.170 + if (!entry->next) 13.171 + break; 13.172 + entry = irq_2_pin + entry->next; 13.173 + } 13.174 +} 13.175 + 13.176 +static void __modify_IO_APIC_irq (unsigned int irq, unsigned long enable, unsigned long disable) 13.177 +{ 13.178 + struct irq_pin_list *entry = irq_2_pin + irq; 13.179 + unsigned int pin, reg; 13.180 + 13.181 + for (;;) { 13.182 + pin = entry->pin; 13.183 + if (pin == -1) 13.184 + break; 13.185 + reg = io_apic_read(entry->apic, 0x10 + pin*2); 13.186 + reg &= ~disable; 13.187 + reg |= enable; 13.188 + io_apic_modify(entry->apic, 0x10 + pin*2, reg); 13.189 + if (!entry->next) 13.190 + break; 13.191 + entry = irq_2_pin + entry->next; 13.192 + } 13.193 +} 13.194 + 13.195 +/* mask = 1 */ 13.196 +static void __mask_IO_APIC_irq (unsigned int irq) 13.197 +{ 13.198 + __modify_IO_APIC_irq(irq, 0x00010000, 0); 13.199 +} 13.200 + 13.201 +/* mask = 0 */ 13.202 +static void __unmask_IO_APIC_irq (unsigned int irq) 13.203 +{ 13.204 + __modify_IO_APIC_irq(irq, 0, 0x00010000); 13.205 +} 13.206 + 13.207 +/* mask = 1, trigger = 0 */ 13.208 +static void __mask_and_edge_IO_APIC_irq (unsigned int irq) 13.209 +{ 13.210 + __modify_IO_APIC_irq(irq, 0x00010000, 0x00008000); 13.211 +} 13.212 + 13.213 +/* mask = 0, trigger = 1 */ 13.214 +static void __unmask_and_level_IO_APIC_irq (unsigned int irq) 13.215 +{ 13.216 + __modify_IO_APIC_irq(irq, 0x00008000, 0x00010000); 13.217 +} 13.218 + 13.219 +static void mask_IO_APIC_irq (unsigned int irq) 13.220 +{ 13.221 + unsigned long flags; 13.222 + 13.223 + spin_lock_irqsave(&ioapic_lock, flags); 13.224 + __mask_IO_APIC_irq(irq); 13.225 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.226 +} 13.227 + 13.228 +static void unmask_IO_APIC_irq (unsigned int irq) 13.229 +{ 13.230 + unsigned long flags; 13.231 + 13.232 + spin_lock_irqsave(&ioapic_lock, flags); 13.233 + __unmask_IO_APIC_irq(irq); 13.234 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.235 +} 13.236 + 13.237 +void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) 13.238 +{ 13.239 + struct IO_APIC_route_entry entry; 13.240 + unsigned long flags; 13.241 + 13.242 + /* Check delivery_mode to be sure we're not clearing an SMI pin */ 13.243 + spin_lock_irqsave(&ioapic_lock, flags); 13.244 + *(((int*)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin); 13.245 + *(((int*)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin); 13.246 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.247 + if (entry.delivery_mode == dest_SMI) 13.248 + return; 13.249 + 13.250 + /* 13.251 + * Disable it in the IO-APIC irq-routing table: 13.252 + */ 13.253 + memset(&entry, 0, sizeof(entry)); 13.254 + entry.mask = 1; 13.255 + spin_lock_irqsave(&ioapic_lock, flags); 13.256 + io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry) + 0)); 13.257 + io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry) + 1)); 13.258 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.259 +} 13.260 + 13.261 +static void clear_IO_APIC (void) 13.262 +{ 13.263 + int apic, pin; 13.264 + 13.265 + for (apic = 0; apic < nr_ioapics; apic++) 13.266 + for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) 13.267 + clear_IO_APIC_pin(apic, pin); 13.268 +} 13.269 + 13.270 +static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) 13.271 +{ 13.272 + unsigned long flags; 13.273 + int pin; 13.274 + struct irq_pin_list *entry = irq_2_pin + irq; 13.275 + unsigned int apicid_value; 13.276 + 13.277 + apicid_value = cpu_mask_to_apicid(cpumask); 13.278 + /* Prepare to do the io_apic_write */ 13.279 + apicid_value = apicid_value << 24; 13.280 + spin_lock_irqsave(&ioapic_lock, flags); 13.281 + for (;;) { 13.282 + pin = entry->pin; 13.283 + if (pin == -1) 13.284 + break; 13.285 + io_apic_write(entry->apic, 0x10 + 1 + pin*2, apicid_value); 13.286 + if (!entry->next) 13.287 + break; 13.288 + entry = irq_2_pin + entry->next; 13.289 + } 13.290 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.291 +} 13.292 +#else 13.293 +#define clear_IO_APIC() ((void)0) 13.294 +#endif 13.295 + 13.296 +#if defined(CONFIG_IRQBALANCE) 13.297 +# include <asm/processor.h> /* kernel_thread() */ 13.298 +# include <linux/kernel_stat.h> /* kstat */ 13.299 +# include <linux/slab.h> /* kmalloc() */ 13.300 +# include <linux/timer.h> /* time_after() */ 13.301 + 13.302 +# ifdef CONFIG_BALANCED_IRQ_DEBUG 13.303 +# define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0) 13.304 +# define Dprintk(x...) do { TDprintk(x); } while (0) 13.305 +# else 13.306 +# define TDprintk(x...) 13.307 +# define Dprintk(x...) 13.308 +# endif 13.309 + 13.310 +cpumask_t __cacheline_aligned pending_irq_balance_cpumask[NR_IRQS]; 13.311 + 13.312 +#define IRQBALANCE_CHECK_ARCH -999 13.313 +static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH; 13.314 +static int physical_balance = 0; 13.315 + 13.316 +struct irq_cpu_info { 13.317 + unsigned long * last_irq; 13.318 + unsigned long * irq_delta; 13.319 + unsigned long irq; 13.320 +} irq_cpu_data[NR_CPUS]; 13.321 + 13.322 +#define CPU_IRQ(cpu) (irq_cpu_data[cpu].irq) 13.323 +#define LAST_CPU_IRQ(cpu,irq) (irq_cpu_data[cpu].last_irq[irq]) 13.324 +#define IRQ_DELTA(cpu,irq) (irq_cpu_data[cpu].irq_delta[irq]) 13.325 + 13.326 +#define IDLE_ENOUGH(cpu,now) \ 13.327 + (idle_cpu(cpu) && ((now) - irq_stat[(cpu)].idle_timestamp > 1)) 13.328 + 13.329 +#define IRQ_ALLOWED(cpu, allowed_mask) cpu_isset(cpu, allowed_mask) 13.330 + 13.331 +#define CPU_TO_PACKAGEINDEX(i) (first_cpu(cpu_sibling_map[i])) 13.332 + 13.333 +#define MAX_BALANCED_IRQ_INTERVAL (5*HZ) 13.334 +#define MIN_BALANCED_IRQ_INTERVAL (HZ/2) 13.335 +#define BALANCED_IRQ_MORE_DELTA (HZ/10) 13.336 +#define BALANCED_IRQ_LESS_DELTA (HZ) 13.337 + 13.338 +long balanced_irq_interval = MAX_BALANCED_IRQ_INTERVAL; 13.339 + 13.340 +static unsigned long move(int curr_cpu, cpumask_t allowed_mask, 13.341 + unsigned long now, int direction) 13.342 +{ 13.343 + int search_idle = 1; 13.344 + int cpu = curr_cpu; 13.345 + 13.346 + goto inside; 13.347 + 13.348 + do { 13.349 + if (unlikely(cpu == curr_cpu)) 13.350 + search_idle = 0; 13.351 +inside: 13.352 + if (direction == 1) { 13.353 + cpu++; 13.354 + if (cpu >= NR_CPUS) 13.355 + cpu = 0; 13.356 + } else { 13.357 + cpu--; 13.358 + if (cpu == -1) 13.359 + cpu = NR_CPUS-1; 13.360 + } 13.361 + } while (!cpu_online(cpu) || !IRQ_ALLOWED(cpu,allowed_mask) || 13.362 + (search_idle && !IDLE_ENOUGH(cpu,now))); 13.363 + 13.364 + return cpu; 13.365 +} 13.366 + 13.367 +static inline void balance_irq(int cpu, int irq) 13.368 +{ 13.369 + unsigned long now = jiffies; 13.370 + cpumask_t allowed_mask; 13.371 + unsigned int new_cpu; 13.372 + 13.373 + if (irqbalance_disabled) 13.374 + return; 13.375 + 13.376 + cpus_and(allowed_mask, cpu_online_map, irq_affinity[irq]); 13.377 + new_cpu = move(cpu, allowed_mask, now, 1); 13.378 + if (cpu != new_cpu) { 13.379 + irq_desc_t *desc = irq_desc + irq; 13.380 + unsigned long flags; 13.381 + 13.382 + spin_lock_irqsave(&desc->lock, flags); 13.383 + pending_irq_balance_cpumask[irq] = cpumask_of_cpu(new_cpu); 13.384 + spin_unlock_irqrestore(&desc->lock, flags); 13.385 + } 13.386 +} 13.387 + 13.388 +static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold) 13.389 +{ 13.390 + int i, j; 13.391 + Dprintk("Rotating IRQs among CPUs.\n"); 13.392 + for (i = 0; i < NR_CPUS; i++) { 13.393 + for (j = 0; cpu_online(i) && (j < NR_IRQS); j++) { 13.394 + if (!irq_desc[j].action) 13.395 + continue; 13.396 + /* Is it a significant load ? */ 13.397 + if (IRQ_DELTA(CPU_TO_PACKAGEINDEX(i),j) < 13.398 + useful_load_threshold) 13.399 + continue; 13.400 + balance_irq(i, j); 13.401 + } 13.402 + } 13.403 + balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL, 13.404 + balanced_irq_interval - BALANCED_IRQ_LESS_DELTA); 13.405 + return; 13.406 +} 13.407 + 13.408 +static void do_irq_balance(void) 13.409 +{ 13.410 + int i, j; 13.411 + unsigned long max_cpu_irq = 0, min_cpu_irq = (~0); 13.412 + unsigned long move_this_load = 0; 13.413 + int max_loaded = 0, min_loaded = 0; 13.414 + int load; 13.415 + unsigned long useful_load_threshold = balanced_irq_interval + 10; 13.416 + int selected_irq; 13.417 + int tmp_loaded, first_attempt = 1; 13.418 + unsigned long tmp_cpu_irq; 13.419 + unsigned long imbalance = 0; 13.420 + cpumask_t allowed_mask, target_cpu_mask, tmp; 13.421 + 13.422 + for (i = 0; i < NR_CPUS; i++) { 13.423 + int package_index; 13.424 + CPU_IRQ(i) = 0; 13.425 + if (!cpu_online(i)) 13.426 + continue; 13.427 + package_index = CPU_TO_PACKAGEINDEX(i); 13.428 + for (j = 0; j < NR_IRQS; j++) { 13.429 + unsigned long value_now, delta; 13.430 + /* Is this an active IRQ? */ 13.431 + if (!irq_desc[j].action) 13.432 + continue; 13.433 + if ( package_index == i ) 13.434 + IRQ_DELTA(package_index,j) = 0; 13.435 + /* Determine the total count per processor per IRQ */ 13.436 + value_now = (unsigned long) kstat_cpu(i).irqs[j]; 13.437 + 13.438 + /* Determine the activity per processor per IRQ */ 13.439 + delta = value_now - LAST_CPU_IRQ(i,j); 13.440 + 13.441 + /* Update last_cpu_irq[][] for the next time */ 13.442 + LAST_CPU_IRQ(i,j) = value_now; 13.443 + 13.444 + /* Ignore IRQs whose rate is less than the clock */ 13.445 + if (delta < useful_load_threshold) 13.446 + continue; 13.447 + /* update the load for the processor or package total */ 13.448 + IRQ_DELTA(package_index,j) += delta; 13.449 + 13.450 + /* Keep track of the higher numbered sibling as well */ 13.451 + if (i != package_index) 13.452 + CPU_IRQ(i) += delta; 13.453 + /* 13.454 + * We have sibling A and sibling B in the package 13.455 + * 13.456 + * cpu_irq[A] = load for cpu A + load for cpu B 13.457 + * cpu_irq[B] = load for cpu B 13.458 + */ 13.459 + CPU_IRQ(package_index) += delta; 13.460 + } 13.461 + } 13.462 + /* Find the least loaded processor package */ 13.463 + for (i = 0; i < NR_CPUS; i++) { 13.464 + if (!cpu_online(i)) 13.465 + continue; 13.466 + if (i != CPU_TO_PACKAGEINDEX(i)) 13.467 + continue; 13.468 + if (min_cpu_irq > CPU_IRQ(i)) { 13.469 + min_cpu_irq = CPU_IRQ(i); 13.470 + min_loaded = i; 13.471 + } 13.472 + } 13.473 + max_cpu_irq = ULONG_MAX; 13.474 + 13.475 +tryanothercpu: 13.476 + /* Look for heaviest loaded processor. 13.477 + * We may come back to get the next heaviest loaded processor. 13.478 + * Skip processors with trivial loads. 13.479 + */ 13.480 + tmp_cpu_irq = 0; 13.481 + tmp_loaded = -1; 13.482 + for (i = 0; i < NR_CPUS; i++) { 13.483 + if (!cpu_online(i)) 13.484 + continue; 13.485 + if (i != CPU_TO_PACKAGEINDEX(i)) 13.486 + continue; 13.487 + if (max_cpu_irq <= CPU_IRQ(i)) 13.488 + continue; 13.489 + if (tmp_cpu_irq < CPU_IRQ(i)) { 13.490 + tmp_cpu_irq = CPU_IRQ(i); 13.491 + tmp_loaded = i; 13.492 + } 13.493 + } 13.494 + 13.495 + if (tmp_loaded == -1) { 13.496 + /* In the case of small number of heavy interrupt sources, 13.497 + * loading some of the cpus too much. We use Ingo's original 13.498 + * approach to rotate them around. 13.499 + */ 13.500 + if (!first_attempt && imbalance >= useful_load_threshold) { 13.501 + rotate_irqs_among_cpus(useful_load_threshold); 13.502 + return; 13.503 + } 13.504 + goto not_worth_the_effort; 13.505 + } 13.506 + 13.507 + first_attempt = 0; /* heaviest search */ 13.508 + max_cpu_irq = tmp_cpu_irq; /* load */ 13.509 + max_loaded = tmp_loaded; /* processor */ 13.510 + imbalance = (max_cpu_irq - min_cpu_irq) / 2; 13.511 + 13.512 + Dprintk("max_loaded cpu = %d\n", max_loaded); 13.513 + Dprintk("min_loaded cpu = %d\n", min_loaded); 13.514 + Dprintk("max_cpu_irq load = %ld\n", max_cpu_irq); 13.515 + Dprintk("min_cpu_irq load = %ld\n", min_cpu_irq); 13.516 + Dprintk("load imbalance = %lu\n", imbalance); 13.517 + 13.518 + /* if imbalance is less than approx 10% of max load, then 13.519 + * observe diminishing returns action. - quit 13.520 + */ 13.521 + if (imbalance < (max_cpu_irq >> 3)) { 13.522 + Dprintk("Imbalance too trivial\n"); 13.523 + goto not_worth_the_effort; 13.524 + } 13.525 + 13.526 +tryanotherirq: 13.527 + /* if we select an IRQ to move that can't go where we want, then 13.528 + * see if there is another one to try. 13.529 + */ 13.530 + move_this_load = 0; 13.531 + selected_irq = -1; 13.532 + for (j = 0; j < NR_IRQS; j++) { 13.533 + /* Is this an active IRQ? */ 13.534 + if (!irq_desc[j].action) 13.535 + continue; 13.536 + if (imbalance <= IRQ_DELTA(max_loaded,j)) 13.537 + continue; 13.538 + /* Try to find the IRQ that is closest to the imbalance 13.539 + * without going over. 13.540 + */ 13.541 + if (move_this_load < IRQ_DELTA(max_loaded,j)) { 13.542 + move_this_load = IRQ_DELTA(max_loaded,j); 13.543 + selected_irq = j; 13.544 + } 13.545 + } 13.546 + if (selected_irq == -1) { 13.547 + goto tryanothercpu; 13.548 + } 13.549 + 13.550 + imbalance = move_this_load; 13.551 + 13.552 + /* For physical_balance case, we accumlated both load 13.553 + * values in the one of the siblings cpu_irq[], 13.554 + * to use the same code for physical and logical processors 13.555 + * as much as possible. 13.556 + * 13.557 + * NOTE: the cpu_irq[] array holds the sum of the load for 13.558 + * sibling A and sibling B in the slot for the lowest numbered 13.559 + * sibling (A), _AND_ the load for sibling B in the slot for 13.560 + * the higher numbered sibling. 13.561 + * 13.562 + * We seek the least loaded sibling by making the comparison 13.563 + * (A+B)/2 vs B 13.564 + */ 13.565 + load = CPU_IRQ(min_loaded) >> 1; 13.566 + for_each_cpu_mask(j, cpu_sibling_map[min_loaded]) { 13.567 + if (load > CPU_IRQ(j)) { 13.568 + /* This won't change cpu_sibling_map[min_loaded] */ 13.569 + load = CPU_IRQ(j); 13.570 + min_loaded = j; 13.571 + } 13.572 + } 13.573 + 13.574 + cpus_and(allowed_mask, cpu_online_map, irq_affinity[selected_irq]); 13.575 + target_cpu_mask = cpumask_of_cpu(min_loaded); 13.576 + cpus_and(tmp, target_cpu_mask, allowed_mask); 13.577 + 13.578 + if (!cpus_empty(tmp)) { 13.579 + irq_desc_t *desc = irq_desc + selected_irq; 13.580 + unsigned long flags; 13.581 + 13.582 + Dprintk("irq = %d moved to cpu = %d\n", 13.583 + selected_irq, min_loaded); 13.584 + /* mark for change destination */ 13.585 + spin_lock_irqsave(&desc->lock, flags); 13.586 + pending_irq_balance_cpumask[selected_irq] = 13.587 + cpumask_of_cpu(min_loaded); 13.588 + spin_unlock_irqrestore(&desc->lock, flags); 13.589 + /* Since we made a change, come back sooner to 13.590 + * check for more variation. 13.591 + */ 13.592 + balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL, 13.593 + balanced_irq_interval - BALANCED_IRQ_LESS_DELTA); 13.594 + return; 13.595 + } 13.596 + goto tryanotherirq; 13.597 + 13.598 +not_worth_the_effort: 13.599 + /* 13.600 + * if we did not find an IRQ to move, then adjust the time interval 13.601 + * upward 13.602 + */ 13.603 + balanced_irq_interval = min((long)MAX_BALANCED_IRQ_INTERVAL, 13.604 + balanced_irq_interval + BALANCED_IRQ_MORE_DELTA); 13.605 + Dprintk("IRQ worth rotating not found\n"); 13.606 + return; 13.607 +} 13.608 + 13.609 +static int balanced_irq(void *unused) 13.610 +{ 13.611 + int i; 13.612 + unsigned long prev_balance_time = jiffies; 13.613 + long time_remaining = balanced_irq_interval; 13.614 + 13.615 + daemonize("kirqd"); 13.616 + 13.617 + /* push everything to CPU 0 to give us a starting point. */ 13.618 + for (i = 0 ; i < NR_IRQS ; i++) { 13.619 + pending_irq_balance_cpumask[i] = cpumask_of_cpu(0); 13.620 + } 13.621 + 13.622 + for ( ; ; ) { 13.623 + set_current_state(TASK_INTERRUPTIBLE); 13.624 + time_remaining = schedule_timeout(time_remaining); 13.625 + try_to_freeze(PF_FREEZE); 13.626 + if (time_after(jiffies, 13.627 + prev_balance_time+balanced_irq_interval)) { 13.628 + do_irq_balance(); 13.629 + prev_balance_time = jiffies; 13.630 + time_remaining = balanced_irq_interval; 13.631 + } 13.632 + } 13.633 + return 0; 13.634 +} 13.635 + 13.636 +static int __init balanced_irq_init(void) 13.637 +{ 13.638 + int i; 13.639 + struct cpuinfo_x86 *c; 13.640 + cpumask_t tmp; 13.641 + 13.642 + cpus_shift_right(tmp, cpu_online_map, 2); 13.643 + c = &boot_cpu_data; 13.644 + /* When not overwritten by the command line ask subarchitecture. */ 13.645 + if (irqbalance_disabled == IRQBALANCE_CHECK_ARCH) 13.646 + irqbalance_disabled = NO_BALANCE_IRQ; 13.647 + if (irqbalance_disabled) 13.648 + return 0; 13.649 + 13.650 + /* disable irqbalance completely if there is only one processor online */ 13.651 + if (num_online_cpus() < 2) { 13.652 + irqbalance_disabled = 1; 13.653 + return 0; 13.654 + } 13.655 + /* 13.656 + * Enable physical balance only if more than 1 physical processor 13.657 + * is present 13.658 + */ 13.659 + if (smp_num_siblings > 1 && !cpus_empty(tmp)) 13.660 + physical_balance = 1; 13.661 + 13.662 + for (i = 0; i < NR_CPUS; i++) { 13.663 + if (!cpu_online(i)) 13.664 + continue; 13.665 + irq_cpu_data[i].irq_delta = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); 13.666 + irq_cpu_data[i].last_irq = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); 13.667 + if (irq_cpu_data[i].irq_delta == NULL || irq_cpu_data[i].last_irq == NULL) { 13.668 + printk(KERN_ERR "balanced_irq_init: out of memory"); 13.669 + goto failed; 13.670 + } 13.671 + memset(irq_cpu_data[i].irq_delta,0,sizeof(unsigned long) * NR_IRQS); 13.672 + memset(irq_cpu_data[i].last_irq,0,sizeof(unsigned long) * NR_IRQS); 13.673 + } 13.674 + 13.675 + printk(KERN_INFO "Starting balanced_irq\n"); 13.676 + if (kernel_thread(balanced_irq, NULL, CLONE_KERNEL) >= 0) 13.677 + return 0; 13.678 + else 13.679 + printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq"); 13.680 +failed: 13.681 + for (i = 0; i < NR_CPUS; i++) { 13.682 + if(irq_cpu_data[i].irq_delta) 13.683 + kfree(irq_cpu_data[i].irq_delta); 13.684 + if(irq_cpu_data[i].last_irq) 13.685 + kfree(irq_cpu_data[i].last_irq); 13.686 + } 13.687 + return 0; 13.688 +} 13.689 + 13.690 +int __init irqbalance_disable(char *str) 13.691 +{ 13.692 + irqbalance_disabled = 1; 13.693 + return 0; 13.694 +} 13.695 + 13.696 +__setup("noirqbalance", irqbalance_disable); 13.697 + 13.698 +static inline void move_irq(int irq) 13.699 +{ 13.700 + /* note - we hold the desc->lock */ 13.701 + if (unlikely(!cpus_empty(pending_irq_balance_cpumask[irq]))) { 13.702 + set_ioapic_affinity_irq(irq, pending_irq_balance_cpumask[irq]); 13.703 + cpus_clear(pending_irq_balance_cpumask[irq]); 13.704 + } 13.705 +} 13.706 + 13.707 +late_initcall(balanced_irq_init); 13.708 + 13.709 +#else /* !CONFIG_IRQBALANCE */ 13.710 +static inline void move_irq(int irq) { } 13.711 +#endif /* CONFIG_IRQBALANCE */ 13.712 + 13.713 +#ifndef CONFIG_SMP 13.714 +void fastcall send_IPI_self(int vector) 13.715 +{ 13.716 +#ifndef CONFIG_XEN 13.717 + unsigned int cfg; 13.718 + 13.719 + /* 13.720 + * Wait for idle. 13.721 + */ 13.722 + apic_wait_icr_idle(); 13.723 + cfg = APIC_DM_FIXED | APIC_DEST_SELF | vector | APIC_DEST_LOGICAL; 13.724 + /* 13.725 + * Send the IPI. The write to APIC_ICR fires this off. 13.726 + */ 13.727 + apic_write_around(APIC_ICR, cfg); 13.728 +#endif 13.729 +} 13.730 +#endif /* !CONFIG_SMP */ 13.731 + 13.732 +/* 13.733 + * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to 13.734 + * specific CPU-side IRQs. 13.735 + */ 13.736 + 13.737 +#define MAX_PIRQS 8 13.738 +int pirq_entries [MAX_PIRQS]; 13.739 +int pirqs_enabled; 13.740 +int skip_ioapic_setup; 13.741 + 13.742 +static int __init ioapic_setup(char *str) 13.743 +{ 13.744 + skip_ioapic_setup = 1; 13.745 + return 1; 13.746 +} 13.747 + 13.748 +__setup("noapic", ioapic_setup); 13.749 + 13.750 +static int __init ioapic_pirq_setup(char *str) 13.751 +{ 13.752 + int i, max; 13.753 + int ints[MAX_PIRQS+1]; 13.754 + 13.755 + get_options(str, ARRAY_SIZE(ints), ints); 13.756 + 13.757 + for (i = 0; i < MAX_PIRQS; i++) 13.758 + pirq_entries[i] = -1; 13.759 + 13.760 + pirqs_enabled = 1; 13.761 + apic_printk(APIC_VERBOSE, KERN_INFO 13.762 + "PIRQ redirection, working around broken MP-BIOS.\n"); 13.763 + max = MAX_PIRQS; 13.764 + if (ints[0] < MAX_PIRQS) 13.765 + max = ints[0]; 13.766 + 13.767 + for (i = 0; i < max; i++) { 13.768 + apic_printk(APIC_VERBOSE, KERN_DEBUG 13.769 + "... PIRQ%d -> IRQ %d\n", i, ints[i+1]); 13.770 + /* 13.771 + * PIRQs are mapped upside down, usually. 13.772 + */ 13.773 + pirq_entries[MAX_PIRQS-i-1] = ints[i+1]; 13.774 + } 13.775 + return 1; 13.776 +} 13.777 + 13.778 +__setup("pirq=", ioapic_pirq_setup); 13.779 + 13.780 +/* 13.781 + * Find the IRQ entry number of a certain pin. 13.782 + */ 13.783 +static int find_irq_entry(int apic, int pin, int type) 13.784 +{ 13.785 + int i; 13.786 + 13.787 + for (i = 0; i < mp_irq_entries; i++) 13.788 + if (mp_irqs[i].mpc_irqtype == type && 13.789 + (mp_irqs[i].mpc_dstapic == mp_ioapics[apic].mpc_apicid || 13.790 + mp_irqs[i].mpc_dstapic == MP_APIC_ALL) && 13.791 + mp_irqs[i].mpc_dstirq == pin) 13.792 + return i; 13.793 + 13.794 + return -1; 13.795 +} 13.796 + 13.797 +#ifndef CONFIG_XEN 13.798 +/* 13.799 + * Find the pin to which IRQ[irq] (ISA) is connected 13.800 + */ 13.801 +static int find_isa_irq_pin(int irq, int type) 13.802 +{ 13.803 + int i; 13.804 + 13.805 + for (i = 0; i < mp_irq_entries; i++) { 13.806 + int lbus = mp_irqs[i].mpc_srcbus; 13.807 + 13.808 + if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || 13.809 + mp_bus_id_to_type[lbus] == MP_BUS_EISA || 13.810 + mp_bus_id_to_type[lbus] == MP_BUS_MCA || 13.811 + mp_bus_id_to_type[lbus] == MP_BUS_NEC98 13.812 + ) && 13.813 + (mp_irqs[i].mpc_irqtype == type) && 13.814 + (mp_irqs[i].mpc_srcbusirq == irq)) 13.815 + 13.816 + return mp_irqs[i].mpc_dstirq; 13.817 + } 13.818 + return -1; 13.819 +} 13.820 +#endif 13.821 + 13.822 +/* 13.823 + * Find a specific PCI IRQ entry. 13.824 + * Not an __init, possibly needed by modules 13.825 + */ 13.826 +static int pin_2_irq(int idx, int apic, int pin); 13.827 + 13.828 +int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) 13.829 +{ 13.830 + int apic, i, best_guess = -1; 13.831 + 13.832 + apic_printk(APIC_DEBUG, "querying PCI -> IRQ mapping bus:%d, " 13.833 + "slot:%d, pin:%d.\n", bus, slot, pin); 13.834 + if (mp_bus_id_to_pci_bus[bus] == -1) { 13.835 + printk(KERN_WARNING "PCI BIOS passed nonexistent PCI bus %d!\n", bus); 13.836 + return -1; 13.837 + } 13.838 + for (i = 0; i < mp_irq_entries; i++) { 13.839 + int lbus = mp_irqs[i].mpc_srcbus; 13.840 + 13.841 + for (apic = 0; apic < nr_ioapics; apic++) 13.842 + if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic || 13.843 + mp_irqs[i].mpc_dstapic == MP_APIC_ALL) 13.844 + break; 13.845 + 13.846 + if ((mp_bus_id_to_type[lbus] == MP_BUS_PCI) && 13.847 + !mp_irqs[i].mpc_irqtype && 13.848 + (bus == lbus) && 13.849 + (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f))) { 13.850 + int irq = pin_2_irq(i,apic,mp_irqs[i].mpc_dstirq); 13.851 + 13.852 + if (!(apic || IO_APIC_IRQ(irq))) 13.853 + continue; 13.854 + 13.855 + if (pin == (mp_irqs[i].mpc_srcbusirq & 3)) 13.856 + return irq; 13.857 + /* 13.858 + * Use the first all-but-pin matching entry as a 13.859 + * best-guess fuzzy result for broken mptables. 13.860 + */ 13.861 + if (best_guess < 0) 13.862 + best_guess = irq; 13.863 + } 13.864 + } 13.865 + return best_guess; 13.866 +} 13.867 + 13.868 +#ifndef CONFIG_XEN 13.869 +/* 13.870 + * This function currently is only a helper for the i386 smp boot process where 13.871 + * we need to reprogram the ioredtbls to cater for the cpus which have come online 13.872 + * so mask in all cases should simply be TARGET_CPUS 13.873 + */ 13.874 +void __init setup_ioapic_dest(void) 13.875 +{ 13.876 + int pin, ioapic, irq, irq_entry; 13.877 + 13.878 + if (skip_ioapic_setup == 1) 13.879 + return; 13.880 + 13.881 + for (ioapic = 0; ioapic < nr_ioapics; ioapic++) { 13.882 + for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) { 13.883 + irq_entry = find_irq_entry(ioapic, pin, mp_INT); 13.884 + if (irq_entry == -1) 13.885 + continue; 13.886 + irq = pin_2_irq(irq_entry, ioapic, pin); 13.887 + set_ioapic_affinity_irq(irq, TARGET_CPUS); 13.888 + } 13.889 + 13.890 + } 13.891 +} 13.892 +#endif /* !CONFIG_XEN */ 13.893 + 13.894 +/* 13.895 + * EISA Edge/Level control register, ELCR 13.896 + */ 13.897 +static int EISA_ELCR(unsigned int irq) 13.898 +{ 13.899 + if (irq < 16) { 13.900 + unsigned int port = 0x4d0 + (irq >> 3); 13.901 + return (inb(port) >> (irq & 7)) & 1; 13.902 + } 13.903 + apic_printk(APIC_VERBOSE, KERN_INFO 13.904 + "Broken MPtable reports ISA irq %d\n", irq); 13.905 + return 0; 13.906 +} 13.907 + 13.908 +/* EISA interrupts are always polarity zero and can be edge or level 13.909 + * trigger depending on the ELCR value. If an interrupt is listed as 13.910 + * EISA conforming in the MP table, that means its trigger type must 13.911 + * be read in from the ELCR */ 13.912 + 13.913 +#define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].mpc_srcbusirq)) 13.914 +#define default_EISA_polarity(idx) (0) 13.915 + 13.916 +/* ISA interrupts are always polarity zero edge triggered, 13.917 + * when listed as conforming in the MP table. */ 13.918 + 13.919 +#define default_ISA_trigger(idx) (0) 13.920 +#define default_ISA_polarity(idx) (0) 13.921 + 13.922 +/* PCI interrupts are always polarity one level triggered, 13.923 + * when listed as conforming in the MP table. */ 13.924 + 13.925 +#define default_PCI_trigger(idx) (1) 13.926 +#define default_PCI_polarity(idx) (1) 13.927 + 13.928 +/* MCA interrupts are always polarity zero level triggered, 13.929 + * when listed as conforming in the MP table. */ 13.930 + 13.931 +#define default_MCA_trigger(idx) (1) 13.932 +#define default_MCA_polarity(idx) (0) 13.933 + 13.934 +/* NEC98 interrupts are always polarity zero edge triggered, 13.935 + * when listed as conforming in the MP table. */ 13.936 + 13.937 +#define default_NEC98_trigger(idx) (0) 13.938 +#define default_NEC98_polarity(idx) (0) 13.939 + 13.940 +static int __init MPBIOS_polarity(int idx) 13.941 +{ 13.942 + int bus = mp_irqs[idx].mpc_srcbus; 13.943 + int polarity; 13.944 + 13.945 + /* 13.946 + * Determine IRQ line polarity (high active or low active): 13.947 + */ 13.948 + switch (mp_irqs[idx].mpc_irqflag & 3) 13.949 + { 13.950 + case 0: /* conforms, ie. bus-type dependent polarity */ 13.951 + { 13.952 + switch (mp_bus_id_to_type[bus]) 13.953 + { 13.954 + case MP_BUS_ISA: /* ISA pin */ 13.955 + { 13.956 + polarity = default_ISA_polarity(idx); 13.957 + break; 13.958 + } 13.959 + case MP_BUS_EISA: /* EISA pin */ 13.960 + { 13.961 + polarity = default_EISA_polarity(idx); 13.962 + break; 13.963 + } 13.964 + case MP_BUS_PCI: /* PCI pin */ 13.965 + { 13.966 + polarity = default_PCI_polarity(idx); 13.967 + break; 13.968 + } 13.969 + case MP_BUS_MCA: /* MCA pin */ 13.970 + { 13.971 + polarity = default_MCA_polarity(idx); 13.972 + break; 13.973 + } 13.974 + case MP_BUS_NEC98: /* NEC 98 pin */ 13.975 + { 13.976 + polarity = default_NEC98_polarity(idx); 13.977 + break; 13.978 + } 13.979 + default: 13.980 + { 13.981 + printk(KERN_WARNING "broken BIOS!!\n"); 13.982 + polarity = 1; 13.983 + break; 13.984 + } 13.985 + } 13.986 + break; 13.987 + } 13.988 + case 1: /* high active */ 13.989 + { 13.990 + polarity = 0; 13.991 + break; 13.992 + } 13.993 + case 2: /* reserved */ 13.994 + { 13.995 + printk(KERN_WARNING "broken BIOS!!\n"); 13.996 + polarity = 1; 13.997 + break; 13.998 + } 13.999 + case 3: /* low active */ 13.1000 + { 13.1001 + polarity = 1; 13.1002 + break; 13.1003 + } 13.1004 + default: /* invalid */ 13.1005 + { 13.1006 + printk(KERN_WARNING "broken BIOS!!\n"); 13.1007 + polarity = 1; 13.1008 + break; 13.1009 + } 13.1010 + } 13.1011 + return polarity; 13.1012 +} 13.1013 + 13.1014 +static int MPBIOS_trigger(int idx) 13.1015 +{ 13.1016 + int bus = mp_irqs[idx].mpc_srcbus; 13.1017 + int trigger; 13.1018 + 13.1019 + /* 13.1020 + * Determine IRQ trigger mode (edge or level sensitive): 13.1021 + */ 13.1022 + switch ((mp_irqs[idx].mpc_irqflag>>2) & 3) 13.1023 + { 13.1024 + case 0: /* conforms, ie. bus-type dependent */ 13.1025 + { 13.1026 + switch (mp_bus_id_to_type[bus]) 13.1027 + { 13.1028 + case MP_BUS_ISA: /* ISA pin */ 13.1029 + { 13.1030 + trigger = default_ISA_trigger(idx); 13.1031 + break; 13.1032 + } 13.1033 + case MP_BUS_EISA: /* EISA pin */ 13.1034 + { 13.1035 + trigger = default_EISA_trigger(idx); 13.1036 + break; 13.1037 + } 13.1038 + case MP_BUS_PCI: /* PCI pin */ 13.1039 + { 13.1040 + trigger = default_PCI_trigger(idx); 13.1041 + break; 13.1042 + } 13.1043 + case MP_BUS_MCA: /* MCA pin */ 13.1044 + { 13.1045 + trigger = default_MCA_trigger(idx); 13.1046 + break; 13.1047 + } 13.1048 + case MP_BUS_NEC98: /* NEC 98 pin */ 13.1049 + { 13.1050 + trigger = default_NEC98_trigger(idx); 13.1051 + break; 13.1052 + } 13.1053 + default: 13.1054 + { 13.1055 + printk(KERN_WARNING "broken BIOS!!\n"); 13.1056 + trigger = 1; 13.1057 + break; 13.1058 + } 13.1059 + } 13.1060 + break; 13.1061 + } 13.1062 + case 1: /* edge */ 13.1063 + { 13.1064 + trigger = 0; 13.1065 + break; 13.1066 + } 13.1067 + case 2: /* reserved */ 13.1068 + { 13.1069 + printk(KERN_WARNING "broken BIOS!!\n"); 13.1070 + trigger = 1; 13.1071 + break; 13.1072 + } 13.1073 + case 3: /* level */ 13.1074 + { 13.1075 + trigger = 1; 13.1076 + break; 13.1077 + } 13.1078 + default: /* invalid */ 13.1079 + { 13.1080 + printk(KERN_WARNING "broken BIOS!!\n"); 13.1081 + trigger = 0; 13.1082 + break; 13.1083 + } 13.1084 + } 13.1085 + return trigger; 13.1086 +} 13.1087 + 13.1088 +static inline int irq_polarity(int idx) 13.1089 +{ 13.1090 + return MPBIOS_polarity(idx); 13.1091 +} 13.1092 + 13.1093 +static inline int irq_trigger(int idx) 13.1094 +{ 13.1095 + return MPBIOS_trigger(idx); 13.1096 +} 13.1097 + 13.1098 +static int pin_2_irq(int idx, int apic, int pin) 13.1099 +{ 13.1100 + int irq, i; 13.1101 + int bus = mp_irqs[idx].mpc_srcbus; 13.1102 + 13.1103 + /* 13.1104 + * Debugging check, we are in big trouble if this message pops up! 13.1105 + */ 13.1106 + if (mp_irqs[idx].mpc_dstirq != pin) 13.1107 + printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n"); 13.1108 + 13.1109 + switch (mp_bus_id_to_type[bus]) 13.1110 + { 13.1111 + case MP_BUS_ISA: /* ISA pin */ 13.1112 + case MP_BUS_EISA: 13.1113 + case MP_BUS_MCA: 13.1114 + case MP_BUS_NEC98: 13.1115 + { 13.1116 + irq = mp_irqs[idx].mpc_srcbusirq; 13.1117 + break; 13.1118 + } 13.1119 + case MP_BUS_PCI: /* PCI pin */ 13.1120 + { 13.1121 + /* 13.1122 + * PCI IRQs are mapped in order 13.1123 + */ 13.1124 + i = irq = 0; 13.1125 + while (i < apic) 13.1126 + irq += nr_ioapic_registers[i++]; 13.1127 + irq += pin; 13.1128 + 13.1129 + /* 13.1130 + * For MPS mode, so far only needed by ES7000 platform 13.1131 + */ 13.1132 + if (ioapic_renumber_irq) 13.1133 + irq = ioapic_renumber_irq(apic, irq); 13.1134 + 13.1135 + break; 13.1136 + } 13.1137 + default: 13.1138 + { 13.1139 + printk(KERN_ERR "unknown bus type %d.\n",bus); 13.1140 + irq = 0; 13.1141 + break; 13.1142 + } 13.1143 + } 13.1144 + 13.1145 + /* 13.1146 + * PCI IRQ command line redirection. Yes, limits are hardcoded. 13.1147 + */ 13.1148 + if ((pin >= 16) && (pin <= 23)) { 13.1149 + if (pirq_entries[pin-16] != -1) { 13.1150 + if (!pirq_entries[pin-16]) { 13.1151 + apic_printk(APIC_VERBOSE, KERN_DEBUG 13.1152 + "disabling PIRQ%d\n", pin-16); 13.1153 + } else { 13.1154 + irq = pirq_entries[pin-16]; 13.1155 + apic_printk(APIC_VERBOSE, KERN_DEBUG 13.1156 + "using PIRQ%d -> IRQ %d\n", 13.1157 + pin-16, irq); 13.1158 + } 13.1159 + } 13.1160 + } 13.1161 + return irq; 13.1162 +} 13.1163 + 13.1164 +static inline int IO_APIC_irq_trigger(int irq) 13.1165 +{ 13.1166 + int apic, idx, pin; 13.1167 + 13.1168 + for (apic = 0; apic < nr_ioapics; apic++) { 13.1169 + for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { 13.1170 + idx = find_irq_entry(apic,pin,mp_INT); 13.1171 + if ((idx != -1) && (irq == pin_2_irq(idx,apic,pin))) 13.1172 + return irq_trigger(idx); 13.1173 + } 13.1174 + } 13.1175 + /* 13.1176 + * nonexistent IRQs are edge default 13.1177 + */ 13.1178 + return 0; 13.1179 +} 13.1180 + 13.1181 +/* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ 13.1182 +u8 irq_vector[NR_IRQ_VECTORS]; /* = { FIRST_DEVICE_VECTOR , 0 }; */ 13.1183 + 13.1184 +int assign_irq_vector(int irq) 13.1185 +{ 13.1186 + static int current_vector = FIRST_DEVICE_VECTOR; 13.1187 + physdev_op_t op; 13.1188 + 13.1189 + BUG_ON(irq >= NR_IRQ_VECTORS); 13.1190 + if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) 13.1191 + return IO_APIC_VECTOR(irq); 13.1192 + 13.1193 + op.cmd = PHYSDEVOP_ASSIGN_VECTOR; 13.1194 + op.u.irq_op.irq = irq; 13.1195 + if (HYPERVISOR_physdev_op(&op)) 13.1196 + return -ENOSPC; 13.1197 + current_vector = op.u.irq_op.vector; 13.1198 + 13.1199 + vector_irq[current_vector] = irq; 13.1200 + if (irq != AUTO_ASSIGN) 13.1201 + IO_APIC_VECTOR(irq) = current_vector; 13.1202 + 13.1203 + return current_vector; 13.1204 +} 13.1205 + 13.1206 +#ifndef CONFIG_XEN 13.1207 +static struct hw_interrupt_type ioapic_level_type; 13.1208 +static struct hw_interrupt_type ioapic_edge_type; 13.1209 + 13.1210 +#define IOAPIC_AUTO -1 13.1211 +#define IOAPIC_EDGE 0 13.1212 +#define IOAPIC_LEVEL 1 13.1213 + 13.1214 +static inline void ioapic_register_intr(int irq, int vector, unsigned long trigger) 13.1215 +{ 13.1216 + if (use_pci_vector() && !platform_legacy_irq(irq)) { 13.1217 + if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || 13.1218 + trigger == IOAPIC_LEVEL) 13.1219 + irq_desc[vector].handler = &ioapic_level_type; 13.1220 + else 13.1221 + irq_desc[vector].handler = &ioapic_edge_type; 13.1222 + set_intr_gate(vector, interrupt[vector]); 13.1223 + } else { 13.1224 + if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || 13.1225 + trigger == IOAPIC_LEVEL) 13.1226 + irq_desc[irq].handler = &ioapic_level_type; 13.1227 + else 13.1228 + irq_desc[irq].handler = &ioapic_edge_type; 13.1229 + set_intr_gate(vector, interrupt[irq]); 13.1230 + } 13.1231 +} 13.1232 +#else 13.1233 +#define ioapic_register_intr(_irq,_vector,_trigger) ((void)0) 13.1234 +#endif 13.1235 + 13.1236 +void __init setup_IO_APIC_irqs(void) 13.1237 +{ 13.1238 + struct IO_APIC_route_entry entry; 13.1239 + int apic, pin, idx, irq, first_notcon = 1, vector; 13.1240 + unsigned long flags; 13.1241 + 13.1242 + apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); 13.1243 + 13.1244 + for (apic = 0; apic < nr_ioapics; apic++) { 13.1245 + for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { 13.1246 + 13.1247 + /* 13.1248 + * add it to the IO-APIC irq-routing table: 13.1249 + */ 13.1250 + memset(&entry,0,sizeof(entry)); 13.1251 + 13.1252 + entry.delivery_mode = INT_DELIVERY_MODE; 13.1253 + entry.dest_mode = INT_DEST_MODE; 13.1254 + entry.mask = 0; /* enable IRQ */ 13.1255 + entry.dest.logical.logical_dest = 13.1256 + cpu_mask_to_apicid(TARGET_CPUS); 13.1257 + 13.1258 + idx = find_irq_entry(apic,pin,mp_INT); 13.1259 + if (idx == -1) { 13.1260 + if (first_notcon) { 13.1261 + apic_printk(APIC_VERBOSE, KERN_DEBUG 13.1262 + " IO-APIC (apicid-pin) %d-%d", 13.1263 + mp_ioapics[apic].mpc_apicid, 13.1264 + pin); 13.1265 + first_notcon = 0; 13.1266 + } else 13.1267 + apic_printk(APIC_VERBOSE, ", %d-%d", 13.1268 + mp_ioapics[apic].mpc_apicid, pin); 13.1269 + continue; 13.1270 + } 13.1271 + 13.1272 + entry.trigger = irq_trigger(idx); 13.1273 + entry.polarity = irq_polarity(idx); 13.1274 + 13.1275 + if (irq_trigger(idx)) { 13.1276 + entry.trigger = 1; 13.1277 + entry.mask = 1; 13.1278 + } 13.1279 + 13.1280 + irq = pin_2_irq(idx, apic, pin); 13.1281 + /* 13.1282 + * skip adding the timer int on secondary nodes, which causes 13.1283 + * a small but painful rift in the time-space continuum 13.1284 + */ 13.1285 + if (multi_timer_check(apic, irq)) 13.1286 + continue; 13.1287 + else 13.1288 + add_pin_to_irq(irq, apic, pin); 13.1289 + 13.1290 + if (/*!apic &&*/ !IO_APIC_IRQ(irq)) 13.1291 + continue; 13.1292 + 13.1293 + if (IO_APIC_IRQ(irq)) { 13.1294 + vector = assign_irq_vector(irq); 13.1295 + entry.vector = vector; 13.1296 + ioapic_register_intr(irq, vector, IOAPIC_AUTO); 13.1297 + 13.1298 + if (!apic && (irq < 16)) 13.1299 + disable_8259A_irq(irq); 13.1300 + } 13.1301 + spin_lock_irqsave(&ioapic_lock, flags); 13.1302 + io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1)); 13.1303 + io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0)); 13.1304 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.1305 + } 13.1306 + } 13.1307 + 13.1308 + if (!first_notcon) 13.1309 + apic_printk(APIC_VERBOSE, " not connected.\n"); 13.1310 +} 13.1311 + 13.1312 +/* 13.1313 + * Set up the 8259A-master output pin: 13.1314 + */ 13.1315 +#ifndef CONFIG_XEN 13.1316 +void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector) 13.1317 +{ 13.1318 + struct IO_APIC_route_entry entry; 13.1319 + unsigned long flags; 13.1320 + 13.1321 + memset(&entry,0,sizeof(entry)); 13.1322 + 13.1323 + disable_8259A_irq(0); 13.1324 + 13.1325 + /* mask LVT0 */ 13.1326 + apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); 13.1327 + 13.1328 + /* 13.1329 + * We use logical delivery to get the timer IRQ 13.1330 + * to the first CPU. 13.1331 + */ 13.1332 + entry.dest_mode = INT_DEST_MODE; 13.1333 + entry.mask = 0; /* unmask IRQ now */ 13.1334 + entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); 13.1335 + entry.delivery_mode = INT_DELIVERY_MODE; 13.1336 + entry.polarity = 0; 13.1337 + entry.trigger = 0; 13.1338 + entry.vector = vector; 13.1339 + 13.1340 + /* 13.1341 + * The timer IRQ doesn't have to know that behind the 13.1342 + * scene we have a 8259A-master in AEOI mode ... 13.1343 + */ 13.1344 + irq_desc[0].handler = &ioapic_edge_type; 13.1345 + 13.1346 + /* 13.1347 + * Add it to the IO-APIC irq-routing table: 13.1348 + */ 13.1349 + spin_lock_irqsave(&ioapic_lock, flags); 13.1350 + io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1)); 13.1351 + io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0)); 13.1352 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.1353 + 13.1354 + enable_8259A_irq(0); 13.1355 +} 13.1356 + 13.1357 +static inline void UNEXPECTED_IO_APIC(void) 13.1358 +{ 13.1359 +} 13.1360 + 13.1361 +void __init print_IO_APIC(void) 13.1362 +{ 13.1363 + int apic, i; 13.1364 + union IO_APIC_reg_00 reg_00; 13.1365 + union IO_APIC_reg_01 reg_01; 13.1366 + union IO_APIC_reg_02 reg_02; 13.1367 + union IO_APIC_reg_03 reg_03; 13.1368 + unsigned long flags; 13.1369 + 13.1370 + if (apic_verbosity == APIC_QUIET) 13.1371 + return; 13.1372 + 13.1373 + printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries); 13.1374 + for (i = 0; i < nr_ioapics; i++) 13.1375 + printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n", 13.1376 + mp_ioapics[i].mpc_apicid, nr_ioapic_registers[i]); 13.1377 + 13.1378 + /* 13.1379 + * We are a bit conservative about what we expect. We have to 13.1380 + * know about every hardware change ASAP. 13.1381 + */ 13.1382 + printk(KERN_INFO "testing the IO APIC.......................\n"); 13.1383 + 13.1384 + for (apic = 0; apic < nr_ioapics; apic++) { 13.1385 + 13.1386 + spin_lock_irqsave(&ioapic_lock, flags); 13.1387 + reg_00.raw = io_apic_read(apic, 0); 13.1388 + reg_01.raw = io_apic_read(apic, 1); 13.1389 + if (reg_01.bits.version >= 0x10) 13.1390 + reg_02.raw = io_apic_read(apic, 2); 13.1391 + if (reg_01.bits.version >= 0x20) 13.1392 + reg_03.raw = io_apic_read(apic, 3); 13.1393 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.1394 + 13.1395 + printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mpc_apicid); 13.1396 + printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw); 13.1397 + printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); 13.1398 + printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type); 13.1399 + printk(KERN_DEBUG "....... : LTS : %X\n", reg_00.bits.LTS); 13.1400 + if (reg_00.bits.ID >= get_physical_broadcast()) 13.1401 + UNEXPECTED_IO_APIC(); 13.1402 + if (reg_00.bits.__reserved_1 || reg_00.bits.__reserved_2) 13.1403 + UNEXPECTED_IO_APIC(); 13.1404 + 13.1405 + printk(KERN_DEBUG ".... register #01: %08X\n", reg_01.raw); 13.1406 + printk(KERN_DEBUG "....... : max redirection entries: %04X\n", reg_01.bits.entries); 13.1407 + if ( (reg_01.bits.entries != 0x0f) && /* older (Neptune) boards */ 13.1408 + (reg_01.bits.entries != 0x17) && /* typical ISA+PCI boards */ 13.1409 + (reg_01.bits.entries != 0x1b) && /* Compaq Proliant boards */ 13.1410 + (reg_01.bits.entries != 0x1f) && /* dual Xeon boards */ 13.1411 + (reg_01.bits.entries != 0x22) && /* bigger Xeon boards */ 13.1412 + (reg_01.bits.entries != 0x2E) && 13.1413 + (reg_01.bits.entries != 0x3F) 13.1414 + ) 13.1415 + UNEXPECTED_IO_APIC(); 13.1416 + 13.1417 + printk(KERN_DEBUG "....... : PRQ implemented: %X\n", reg_01.bits.PRQ); 13.1418 + printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.bits.version); 13.1419 + if ( (reg_01.bits.version != 0x01) && /* 82489DX IO-APICs */ 13.1420 + (reg_01.bits.version != 0x10) && /* oldest IO-APICs */ 13.1421 + (reg_01.bits.version != 0x11) && /* Pentium/Pro IO-APICs */ 13.1422 + (reg_01.bits.version != 0x13) && /* Xeon IO-APICs */ 13.1423 + (reg_01.bits.version != 0x20) /* Intel P64H (82806 AA) */ 13.1424 + ) 13.1425 + UNEXPECTED_IO_APIC(); 13.1426 + if (reg_01.bits.__reserved_1 || reg_01.bits.__reserved_2) 13.1427 + UNEXPECTED_IO_APIC(); 13.1428 + 13.1429 + /* 13.1430 + * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02, 13.1431 + * but the value of reg_02 is read as the previous read register 13.1432 + * value, so ignore it if reg_02 == reg_01. 13.1433 + */ 13.1434 + if (reg_01.bits.version >= 0x10 && reg_02.raw != reg_01.raw) { 13.1435 + printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw); 13.1436 + printk(KERN_DEBUG "....... : arbitration: %02X\n", reg_02.bits.arbitration); 13.1437 + if (reg_02.bits.__reserved_1 || reg_02.bits.__reserved_2) 13.1438 + UNEXPECTED_IO_APIC(); 13.1439 + } 13.1440 + 13.1441 + /* 13.1442 + * Some Intel chipsets with IO APIC VERSION of 0x2? don't have reg_02 13.1443 + * or reg_03, but the value of reg_0[23] is read as the previous read 13.1444 + * register value, so ignore it if reg_03 == reg_0[12]. 13.1445 + */ 13.1446 + if (reg_01.bits.version >= 0x20 && reg_03.raw != reg_02.raw && 13.1447 + reg_03.raw != reg_01.raw) { 13.1448 + printk(KERN_DEBUG ".... register #03: %08X\n", reg_03.raw); 13.1449 + printk(KERN_DEBUG "....... : Boot DT : %X\n", reg_03.bits.boot_DT); 13.1450 + if (reg_03.bits.__reserved_1) 13.1451 + UNEXPECTED_IO_APIC(); 13.1452 + } 13.1453 + 13.1454 + printk(KERN_DEBUG ".... IRQ redirection table:\n"); 13.1455 + 13.1456 + printk(KERN_DEBUG " NR Log Phy Mask Trig IRR Pol" 13.1457 + " Stat Dest Deli Vect: \n"); 13.1458 + 13.1459 + for (i = 0; i <= reg_01.bits.entries; i++) { 13.1460 + struct IO_APIC_route_entry entry; 13.1461 + 13.1462 + spin_lock_irqsave(&ioapic_lock, flags); 13.1463 + *(((int *)&entry)+0) = io_apic_read(apic, 0x10+i*2); 13.1464 + *(((int *)&entry)+1) = io_apic_read(apic, 0x11+i*2); 13.1465 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.1466 + 13.1467 + printk(KERN_DEBUG " %02x %03X %02X ", 13.1468 + i, 13.1469 + entry.dest.logical.logical_dest, 13.1470 + entry.dest.physical.physical_dest 13.1471 + ); 13.1472 + 13.1473 + printk("%1d %1d %1d %1d %1d %1d %1d %02X\n", 13.1474 + entry.mask, 13.1475 + entry.trigger, 13.1476 + entry.irr, 13.1477 + entry.polarity, 13.1478 + entry.delivery_status, 13.1479 + entry.dest_mode, 13.1480 + entry.delivery_mode, 13.1481 + entry.vector 13.1482 + ); 13.1483 + } 13.1484 + } 13.1485 + if (use_pci_vector()) 13.1486 + printk(KERN_INFO "Using vector-based indexing\n"); 13.1487 + printk(KERN_DEBUG "IRQ to pin mappings:\n"); 13.1488 + for (i = 0; i < NR_IRQS; i++) { 13.1489 + struct irq_pin_list *entry = irq_2_pin + i; 13.1490 + if (entry->pin < 0) 13.1491 + continue; 13.1492 + if (use_pci_vector() && !platform_legacy_irq(i)) 13.1493 + printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i)); 13.1494 + else 13.1495 + printk(KERN_DEBUG "IRQ%d ", i); 13.1496 + for (;;) { 13.1497 + printk("-> %d:%d", entry->apic, entry->pin); 13.1498 + if (!entry->next) 13.1499 + break; 13.1500 + entry = irq_2_pin + entry->next; 13.1501 + } 13.1502 + printk("\n"); 13.1503 + } 13.1504 + 13.1505 + printk(KERN_INFO ".................................... done.\n"); 13.1506 + 13.1507 + return; 13.1508 +} 13.1509 + 13.1510 +static void print_APIC_bitfield (int base) 13.1511 +{ 13.1512 + unsigned int v; 13.1513 + int i, j; 13.1514 + 13.1515 + if (apic_verbosity == APIC_QUIET) 13.1516 + return; 13.1517 + 13.1518 + printk(KERN_DEBUG "0123456789abcdef0123456789abcdef\n" KERN_DEBUG); 13.1519 + for (i = 0; i < 8; i++) { 13.1520 + v = apic_read(base + i*0x10); 13.1521 + for (j = 0; j < 32; j++) { 13.1522 + if (v & (1<<j)) 13.1523 + printk("1"); 13.1524 + else 13.1525 + printk("0"); 13.1526 + } 13.1527 + printk("\n"); 13.1528 + } 13.1529 +} 13.1530 + 13.1531 +void /*__init*/ print_local_APIC(void * dummy) 13.1532 +{ 13.1533 + unsigned int v, ver, maxlvt; 13.1534 + 13.1535 + if (apic_verbosity == APIC_QUIET) 13.1536 + return; 13.1537 + 13.1538 + printk("\n" KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n", 13.1539 + smp_processor_id(), hard_smp_processor_id()); 13.1540 + v = apic_read(APIC_ID); 13.1541 + printk(KERN_INFO "... APIC ID: %08x (%01x)\n", v, GET_APIC_ID(v)); 13.1542 + v = apic_read(APIC_LVR); 13.1543 + printk(KERN_INFO "... APIC VERSION: %08x\n", v); 13.1544 + ver = GET_APIC_VERSION(v); 13.1545 + maxlvt = get_maxlvt(); 13.1546 + 13.1547 + v = apic_read(APIC_TASKPRI); 13.1548 + printk(KERN_DEBUG "... APIC TASKPRI: %08x (%02x)\n", v, v & APIC_TPRI_MASK); 13.1549 + 13.1550 + if (APIC_INTEGRATED(ver)) { /* !82489DX */ 13.1551 + v = apic_read(APIC_ARBPRI); 13.1552 + printk(KERN_DEBUG "... APIC ARBPRI: %08x (%02x)\n", v, 13.1553 + v & APIC_ARBPRI_MASK); 13.1554 + v = apic_read(APIC_PROCPRI); 13.1555 + printk(KERN_DEBUG "... APIC PROCPRI: %08x\n", v); 13.1556 + } 13.1557 + 13.1558 + v = apic_read(APIC_EOI); 13.1559 + printk(KERN_DEBUG "... APIC EOI: %08x\n", v); 13.1560 + v = apic_read(APIC_RRR); 13.1561 + printk(KERN_DEBUG "... APIC RRR: %08x\n", v); 13.1562 + v = apic_read(APIC_LDR); 13.1563 + printk(KERN_DEBUG "... APIC LDR: %08x\n", v); 13.1564 + v = apic_read(APIC_DFR); 13.1565 + printk(KERN_DEBUG "... APIC DFR: %08x\n", v); 13.1566 + v = apic_read(APIC_SPIV); 13.1567 + printk(KERN_DEBUG "... APIC SPIV: %08x\n", v); 13.1568 + 13.1569 + printk(KERN_DEBUG "... APIC ISR field:\n"); 13.1570 + print_APIC_bitfield(APIC_ISR); 13.1571 + printk(KERN_DEBUG "... APIC TMR field:\n"); 13.1572 + print_APIC_bitfield(APIC_TMR); 13.1573 + printk(KERN_DEBUG "... APIC IRR field:\n"); 13.1574 + print_APIC_bitfield(APIC_IRR); 13.1575 + 13.1576 + if (APIC_INTEGRATED(ver)) { /* !82489DX */ 13.1577 + if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ 13.1578 + apic_write(APIC_ESR, 0); 13.1579 + v = apic_read(APIC_ESR); 13.1580 + printk(KERN_DEBUG "... APIC ESR: %08x\n", v); 13.1581 + } 13.1582 + 13.1583 + v = apic_read(APIC_ICR); 13.1584 + printk(KERN_DEBUG "... APIC ICR: %08x\n", v); 13.1585 + v = apic_read(APIC_ICR2); 13.1586 + printk(KERN_DEBUG "... APIC ICR2: %08x\n", v); 13.1587 + 13.1588 + v = apic_read(APIC_LVTT); 13.1589 + printk(KERN_DEBUG "... APIC LVTT: %08x\n", v); 13.1590 + 13.1591 + if (maxlvt > 3) { /* PC is LVT#4. */ 13.1592 + v = apic_read(APIC_LVTPC); 13.1593 + printk(KERN_DEBUG "... APIC LVTPC: %08x\n", v); 13.1594 + } 13.1595 + v = apic_read(APIC_LVT0); 13.1596 + printk(KERN_DEBUG "... APIC LVT0: %08x\n", v); 13.1597 + v = apic_read(APIC_LVT1); 13.1598 + printk(KERN_DEBUG "... APIC LVT1: %08x\n", v); 13.1599 + 13.1600 + if (maxlvt > 2) { /* ERR is LVT#3. */ 13.1601 + v = apic_read(APIC_LVTERR); 13.1602 + printk(KERN_DEBUG "... APIC LVTERR: %08x\n", v); 13.1603 + } 13.1604 + 13.1605 + v = apic_read(APIC_TMICT); 13.1606 + printk(KERN_DEBUG "... APIC TMICT: %08x\n", v); 13.1607 + v = apic_read(APIC_TMCCT); 13.1608 + printk(KERN_DEBUG "... APIC TMCCT: %08x\n", v); 13.1609 + v = apic_read(APIC_TDCR); 13.1610 + printk(KERN_DEBUG "... APIC TDCR: %08x\n", v); 13.1611 + printk("\n"); 13.1612 +} 13.1613 + 13.1614 +void print_all_local_APICs (void) 13.1615 +{ 13.1616 + on_each_cpu(print_local_APIC, NULL, 1, 1); 13.1617 +} 13.1618 + 13.1619 +void /*__init*/ print_PIC(void) 13.1620 +{ 13.1621 + extern spinlock_t i8259A_lock; 13.1622 + unsigned int v; 13.1623 + unsigned long flags; 13.1624 + 13.1625 + if (apic_verbosity == APIC_QUIET) 13.1626 + return; 13.1627 + 13.1628 + printk(KERN_DEBUG "\nprinting PIC contents\n"); 13.1629 + 13.1630 + spin_lock_irqsave(&i8259A_lock, flags); 13.1631 + 13.1632 + v = inb(0xa1) << 8 | inb(0x21); 13.1633 + printk(KERN_DEBUG "... PIC IMR: %04x\n", v); 13.1634 + 13.1635 + v = inb(0xa0) << 8 | inb(0x20); 13.1636 + printk(KERN_DEBUG "... PIC IRR: %04x\n", v); 13.1637 + 13.1638 + outb(0x0b,0xa0); 13.1639 + outb(0x0b,0x20); 13.1640 + v = inb(0xa0) << 8 | inb(0x20); 13.1641 + outb(0x0a,0xa0); 13.1642 + outb(0x0a,0x20); 13.1643 + 13.1644 + spin_unlock_irqrestore(&i8259A_lock, flags); 13.1645 + 13.1646 + printk(KERN_DEBUG "... PIC ISR: %04x\n", v); 13.1647 + 13.1648 + v = inb(0x4d1) << 8 | inb(0x4d0); 13.1649 + printk(KERN_DEBUG "... PIC ELCR: %04x\n", v); 13.1650 +} 13.1651 +#else 13.1652 +void __init print_IO_APIC(void) { } 13.1653 +#endif /* !CONFIG_XEN */ 13.1654 + 13.1655 +static void __init enable_IO_APIC(void) 13.1656 +{ 13.1657 + union IO_APIC_reg_01 reg_01; 13.1658 + int i; 13.1659 + unsigned long flags; 13.1660 + 13.1661 + for (i = 0; i < PIN_MAP_SIZE; i++) { 13.1662 + irq_2_pin[i].pin = -1; 13.1663 + irq_2_pin[i].next = 0; 13.1664 + } 13.1665 + if (!pirqs_enabled) 13.1666 + for (i = 0; i < MAX_PIRQS; i++) 13.1667 + pirq_entries[i] = -1; 13.1668 + 13.1669 + /* 13.1670 + * The number of IO-APIC IRQ registers (== #pins): 13.1671 + */ 13.1672 + for (i = 0; i < nr_ioapics; i++) { 13.1673 + spin_lock_irqsave(&ioapic_lock, flags); 13.1674 + reg_01.raw = io_apic_read(i, 1); 13.1675 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.1676 + nr_ioapic_registers[i] = reg_01.bits.entries+1; 13.1677 + } 13.1678 + 13.1679 + /* 13.1680 + * Do not trust the IO-APIC being empty at bootup 13.1681 + */ 13.1682 + clear_IO_APIC(); 13.1683 +} 13.1684 + 13.1685 +/* 13.1686 + * Not an __init, needed by the reboot code 13.1687 + */ 13.1688 +void disable_IO_APIC(void) 13.1689 +{ 13.1690 + /* 13.1691 + * Clear the IO-APIC before rebooting: 13.1692 + */ 13.1693 + clear_IO_APIC(); 13.1694 + 13.1695 +#ifndef CONFIG_XEN 13.1696 + disconnect_bsp_APIC(); 13.1697 +#endif 13.1698 +} 13.1699 + 13.1700 +/* 13.1701 + * function to set the IO-APIC physical IDs based on the 13.1702 + * values stored in the MPC table. 13.1703 + * 13.1704 + * by Matt Domsch <Matt_Domsch@dell.com> Tue Dec 21 12:25:05 CST 1999 13.1705 + */ 13.1706 + 13.1707 +#if !defined(CONFIG_XEN) && !defined(CONFIG_X86_NUMAQ) 13.1708 +static void __init setup_ioapic_ids_from_mpc(void) 13.1709 +{ 13.1710 + union IO_APIC_reg_00 reg_00; 13.1711 + physid_mask_t phys_id_present_map; 13.1712 + int apic; 13.1713 + int i; 13.1714 + unsigned char old_id; 13.1715 + unsigned long flags; 13.1716 + 13.1717 + /* 13.1718 + * This is broken; anything with a real cpu count has to 13.1719 + * circumvent this idiocy regardless. 13.1720 + */ 13.1721 + phys_id_present_map = ioapic_phys_id_map(phys_cpu_present_map); 13.1722 + 13.1723 + /* 13.1724 + * Set the IOAPIC ID to the value stored in the MPC table. 13.1725 + */ 13.1726 + for (apic = 0; apic < nr_ioapics; apic++) { 13.1727 + 13.1728 + /* Read the register 0 value */ 13.1729 + spin_lock_irqsave(&ioapic_lock, flags); 13.1730 + reg_00.raw = io_apic_read(apic, 0); 13.1731 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.1732 + 13.1733 + old_id = mp_ioapics[apic].mpc_apicid; 13.1734 + 13.1735 + if (mp_ioapics[apic].mpc_apicid >= get_physical_broadcast()) { 13.1736 + printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n", 13.1737 + apic, mp_ioapics[apic].mpc_apicid); 13.1738 + printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", 13.1739 + reg_00.bits.ID); 13.1740 + mp_ioapics[apic].mpc_apicid = reg_00.bits.ID; 13.1741 + } 13.1742 + 13.1743 + /* Don't check I/O APIC IDs for some xAPIC systems. They have 13.1744 + * no meaning without the serial APIC bus. */ 13.1745 + if (NO_IOAPIC_CHECK) 13.1746 + continue; 13.1747 + /* 13.1748 + * Sanity check, is the ID really free? Every APIC in a 13.1749 + * system must have a unique ID or we get lots of nice 13.1750 + * 'stuck on smp_invalidate_needed IPI wait' messages. 13.1751 + */ 13.1752 + if (check_apicid_used(phys_id_present_map, 13.1753 + mp_ioapics[apic].mpc_apicid)) { 13.1754 + printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n", 13.1755 + apic, mp_ioapics[apic].mpc_apicid); 13.1756 + for (i = 0; i < get_physical_broadcast(); i++) 13.1757 + if (!physid_isset(i, phys_id_present_map)) 13.1758 + break; 13.1759 + if (i >= get_physical_broadcast()) 13.1760 + panic("Max APIC ID exceeded!\n"); 13.1761 + printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", 13.1762 + i); 13.1763 + physid_set(i, phys_id_present_map); 13.1764 + mp_ioapics[apic].mpc_apicid = i; 13.1765 + } else { 13.1766 + physid_mask_t tmp; 13.1767 + tmp = apicid_to_cpu_present(mp_ioapics[apic].mpc_apicid); 13.1768 + apic_printk(APIC_VERBOSE, "Setting %d in the " 13.1769 + "phys_id_present_map\n", 13.1770 + mp_ioapics[apic].mpc_apicid); 13.1771 + physids_or(phys_id_present_map, phys_id_present_map, tmp); 13.1772 + } 13.1773 + 13.1774 + 13.1775 + /* 13.1776 + * We need to adjust the IRQ routing table 13.1777 + * if the ID changed. 13.1778 + */ 13.1779 + if (old_id != mp_ioapics[apic].mpc_apicid) 13.1780 + for (i = 0; i < mp_irq_entries; i++) 13.1781 + if (mp_irqs[i].mpc_dstapic == old_id) 13.1782 + mp_irqs[i].mpc_dstapic 13.1783 + = mp_ioapics[apic].mpc_apicid; 13.1784 + 13.1785 + /* 13.1786 + * Read the right value from the MPC table and 13.1787 + * write it into the ID register. 13.1788 + */ 13.1789 + apic_printk(APIC_VERBOSE, KERN_INFO 13.1790 + "...changing IO-APIC physical APIC ID to %d ...", 13.1791 + mp_ioapics[apic].mpc_apicid); 13.1792 + 13.1793 + reg_00.bits.ID = mp_ioapics[apic].mpc_apicid; 13.1794 + spin_lock_irqsave(&ioapic_lock, flags); 13.1795 + io_apic_write(apic, 0, reg_00.raw); 13.1796 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.1797 + 13.1798 + /* 13.1799 + * Sanity check 13.1800 + */ 13.1801 + spin_lock_irqsave(&ioapic_lock, flags); 13.1802 + reg_00.raw = io_apic_read(apic, 0); 13.1803 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.1804 + if (reg_00.bits.ID != mp_ioapics[apic].mpc_apicid) 13.1805 + printk("could not set ID!\n"); 13.1806 + else 13.1807 + apic_printk(APIC_VERBOSE, " ok.\n"); 13.1808 + } 13.1809 +} 13.1810 +#else 13.1811 +static void __init setup_ioapic_ids_from_mpc(void) { } 13.1812 +#endif 13.1813 + 13.1814 +#ifndef CONFIG_XEN 13.1815 +/* 13.1816 + * There is a nasty bug in some older SMP boards, their mptable lies 13.1817 + * about the timer IRQ. We do the following to work around the situation: 13.1818 + * 13.1819 + * - timer IRQ defaults to IO-APIC IRQ 13.1820 + * - if this function detects that timer IRQs are defunct, then we fall 13.1821 + * back to ISA timer IRQs 13.1822 + */ 13.1823 +static int __init timer_irq_works(void) 13.1824 +{ 13.1825 + unsigned long t1 = jiffies; 13.1826 + 13.1827 + local_irq_enable(); 13.1828 + /* Let ten ticks pass... */ 13.1829 + mdelay((10 * 1000) / HZ); 13.1830 + 13.1831 + /* 13.1832 + * Expect a few ticks at least, to be sure some possible 13.1833 + * glue logic does not lock up after one or two first 13.1834 + * ticks in a non-ExtINT mode. Also the local APIC 13.1835 + * might have cached one ExtINT interrupt. Finally, at 13.1836 + * least one tick may be lost due to delays. 13.1837 + */ 13.1838 + if (jiffies - t1 > 4) 13.1839 + return 1; 13.1840 + 13.1841 + return 0; 13.1842 +} 13.1843 + 13.1844 +/* 13.1845 + * In the SMP+IOAPIC case it might happen that there are an unspecified 13.1846 + * number of pending IRQ events unhandled. These cases are very rare, 13.1847 + * so we 'resend' these IRQs via IPIs, to the same CPU. It's much 13.1848 + * better to do it this way as thus we do not have to be aware of 13.1849 + * 'pending' interrupts in the IRQ path, except at this point. 13.1850 + */ 13.1851 +/* 13.1852 + * Edge triggered needs to resend any interrupt 13.1853 + * that was delayed but this is now handled in the device 13.1854 + * independent code. 13.1855 + */ 13.1856 + 13.1857 +/* 13.1858 + * Starting up a edge-triggered IO-APIC interrupt is 13.1859 + * nasty - we need to make sure that we get the edge. 13.1860 + * If it is already asserted for some reason, we need 13.1861 + * return 1 to indicate that is was pending. 13.1862 + * 13.1863 + * This is not complete - we should be able to fake 13.1864 + * an edge even if it isn't on the 8259A... 13.1865 + */ 13.1866 +static unsigned int startup_edge_ioapic_irq(unsigned int irq) 13.1867 +{ 13.1868 + int was_pending = 0; 13.1869 + unsigned long flags; 13.1870 + 13.1871 + spin_lock_irqsave(&ioapic_lock, flags); 13.1872 + if (irq < 16) { 13.1873 + disable_8259A_irq(irq); 13.1874 + if (i8259A_irq_pending(irq)) 13.1875 + was_pending = 1; 13.1876 + } 13.1877 + __unmask_IO_APIC_irq(irq); 13.1878 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.1879 + 13.1880 + return was_pending; 13.1881 +} 13.1882 + 13.1883 +/* 13.1884 + * Once we have recorded IRQ_PENDING already, we can mask the 13.1885 + * interrupt for real. This prevents IRQ storms from unhandled 13.1886 + * devices. 13.1887 + */ 13.1888 +static void ack_edge_ioapic_irq(unsigned int irq) 13.1889 +{ 13.1890 + move_irq(irq); 13.1891 + if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED)) 13.1892 + == (IRQ_PENDING | IRQ_DISABLED)) 13.1893 + mask_IO_APIC_irq(irq); 13.1894 + ack_APIC_irq(); 13.1895 +} 13.1896 + 13.1897 +/* 13.1898 + * Level triggered interrupts can just be masked, 13.1899 + * and shutting down and starting up the interrupt 13.1900 + * is the same as enabling and disabling them -- except 13.1901 + * with a startup need to return a "was pending" value. 13.1902 + * 13.1903 + * Level triggered interrupts are special because we 13.1904 + * do not touch any IO-APIC register while handling 13.1905 + * them. We ack the APIC in the end-IRQ handler, not 13.1906 + * in the start-IRQ-handler. Protection against reentrance 13.1907 + * from the same interrupt is still provided, both by the 13.1908 + * generic IRQ layer and by the fact that an unacked local 13.1909 + * APIC does not accept IRQs. 13.1910 + */ 13.1911 +static unsigned int startup_level_ioapic_irq (unsigned int irq) 13.1912 +{ 13.1913 + unmask_IO_APIC_irq(irq); 13.1914 + 13.1915 + return 0; /* don't check for pending */ 13.1916 +} 13.1917 + 13.1918 +static void end_level_ioapic_irq (unsigned int irq) 13.1919 +{ 13.1920 + unsigned long v; 13.1921 + int i; 13.1922 + 13.1923 + move_irq(irq); 13.1924 +/* 13.1925 + * It appears there is an erratum which affects at least version 0x11 13.1926 + * of I/O APIC (that's the 82093AA and cores integrated into various 13.1927 + * chipsets). Under certain conditions a level-triggered interrupt is 13.1928 + * erroneously delivered as edge-triggered one but the respective IRR 13.1929 + * bit gets set nevertheless. As a result the I/O unit expects an EOI 13.1930 + * message but it will never arrive and further interrupts are blocked 13.1931 + * from the source. The exact reason is so far unknown, but the 13.1932 + * phenomenon was observed when two consecutive interrupt requests 13.1933 + * from a given source get delivered to the same CPU and the source is 13.1934 + * temporarily disabled in between. 13.1935 + * 13.1936 + * A workaround is to simulate an EOI message manually. We achieve it 13.1937 + * by setting the trigger mode to edge and then to level when the edge 13.1938 + * trigger mode gets detected in the TMR of a local APIC for a 13.1939 + * level-triggered interrupt. We mask the source for the time of the 13.1940 + * operation to prevent an edge-triggered interrupt escaping meanwhile. 13.1941 + * The idea is from Manfred Spraul. --macro 13.1942 + */ 13.1943 + i = IO_APIC_VECTOR(irq); 13.1944 + 13.1945 + v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1)); 13.1946 + 13.1947 + ack_APIC_irq(); 13.1948 + 13.1949 + if (!(v & (1 << (i & 0x1f)))) { 13.1950 + atomic_inc(&irq_mis_count); 13.1951 + spin_lock(&ioapic_lock); 13.1952 + __mask_and_edge_IO_APIC_irq(irq); 13.1953 + __unmask_and_level_IO_APIC_irq(irq); 13.1954 + spin_unlock(&ioapic_lock); 13.1955 + } 13.1956 +} 13.1957 + 13.1958 +#ifdef CONFIG_PCI_MSI 13.1959 +static unsigned int startup_edge_ioapic_vector(unsigned int vector) 13.1960 +{ 13.1961 + int irq = vector_to_irq(vector); 13.1962 + 13.1963 + return startup_edge_ioapic_irq(irq); 13.1964 +} 13.1965 + 13.1966 +static void ack_edge_ioapic_vector(unsigned int vector) 13.1967 +{ 13.1968 + int irq = vector_to_irq(vector); 13.1969 + 13.1970 + ack_edge_ioapic_irq(irq); 13.1971 +} 13.1972 + 13.1973 +static unsigned int startup_level_ioapic_vector (unsigned int vector) 13.1974 +{ 13.1975 + int irq = vector_to_irq(vector); 13.1976 + 13.1977 + return startup_level_ioapic_irq (irq); 13.1978 +} 13.1979 + 13.1980 +static void end_level_ioapic_vector (unsigned int vector) 13.1981 +{ 13.1982 + int irq = vector_to_irq(vector); 13.1983 + 13.1984 + end_level_ioapic_irq(irq); 13.1985 +} 13.1986 + 13.1987 +static void mask_IO_APIC_vector (unsigned int vector) 13.1988 +{ 13.1989 + int irq = vector_to_irq(vector); 13.1990 + 13.1991 + mask_IO_APIC_irq(irq); 13.1992 +} 13.1993 + 13.1994 +static void unmask_IO_APIC_vector (unsigned int vector) 13.1995 +{ 13.1996 + int irq = vector_to_irq(vector); 13.1997 + 13.1998 + unmask_IO_APIC_irq(irq); 13.1999 +} 13.2000 + 13.2001 +static void set_ioapic_affinity_vector (unsigned int vector, 13.2002 + cpumask_t cpu_mask) 13.2003 +{ 13.2004 + int irq = vector_to_irq(vector); 13.2005 + 13.2006 + set_ioapic_affinity_irq(irq, cpu_mask); 13.2007 +} 13.2008 +#endif 13.2009 + 13.2010 +/* 13.2011 + * Level and edge triggered IO-APIC interrupts need different handling, 13.2012 + * so we use two separate IRQ descriptors. Edge triggered IRQs can be 13.2013 + * handled with the level-triggered descriptor, but that one has slightly 13.2014 + * more overhead. Level-triggered interrupts cannot be handled with the 13.2015 + * edge-triggered handler, without risking IRQ storms and other ugly 13.2016 + * races. 13.2017 + */ 13.2018 +static struct hw_interrupt_type ioapic_edge_type = { 13.2019 + .typename = "IO-APIC-edge", 13.2020 + .startup = startup_edge_ioapic, 13.2021 + .shutdown = shutdown_edge_ioapic, 13.2022 + .enable = enable_edge_ioapic, 13.2023 + .disable = disable_edge_ioapic, 13.2024 + .ack = ack_edge_ioapic, 13.2025 + .end = end_edge_ioapic, 13.2026 + .set_affinity = set_ioapic_affinity, 13.2027 +}; 13.2028 + 13.2029 +static struct hw_interrupt_type ioapic_level_type = { 13.2030 + .typename = "IO-APIC-level", 13.2031 + .startup = startup_level_ioapic, 13.2032 + .shutdown = shutdown_level_ioapic, 13.2033 + .enable = enable_level_ioapic, 13.2034 + .disable = disable_level_ioapic, 13.2035 + .ack = mask_and_ack_level_ioapic, 13.2036 + .end = end_level_ioapic, 13.2037 + .set_affinity = set_ioapic_affinity, 13.2038 +}; 13.2039 +#endif /* !CONFIG_XEN */ 13.2040 + 13.2041 +static inline void init_IO_APIC_traps(void) 13.2042 +{ 13.2043 + int irq; 13.2044 + 13.2045 + /* 13.2046 + * NOTE! The local APIC isn't very good at handling 13.2047 + * multiple interrupts at the same interrupt level. 13.2048 + * As the interrupt level is determined by taking the 13.2049 + * vector number and shifting that right by 4, we 13.2050 + * want to spread these out a bit so that they don't 13.2051 + * all fall in the same interrupt level. 13.2052 + * 13.2053 + * Also, we've got to be careful not to trash gate 13.2054 + * 0x80, because int 0x80 is hm, kind of importantish. ;) 13.2055 + */ 13.2056 + for (irq = 0; irq < NR_IRQS ; irq++) { 13.2057 + int tmp = irq; 13.2058 + if (use_pci_vector()) { 13.2059 + if (!platform_legacy_irq(tmp)) 13.2060 + if ((tmp = vector_to_irq(tmp)) == -1) 13.2061 + continue; 13.2062 + } 13.2063 + if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) { 13.2064 + /* 13.2065 + * Hmm.. We don't have an entry for this, 13.2066 + * so default to an old-fashioned 8259 13.2067 + * interrupt if we can.. 13.2068 + */ 13.2069 + if (irq < 16) 13.2070 + make_8259A_irq(irq); 13.2071 +#ifndef CONFIG_XEN 13.2072 + else 13.2073 + /* Strange. Oh, well.. */ 13.2074 + irq_desc[irq].handler = &no_irq_type; 13.2075 +#endif 13.2076 + } 13.2077 + } 13.2078 +} 13.2079 + 13.2080 +#ifndef CONFIG_XEN 13.2081 +static void enable_lapic_irq (unsigned int irq) 13.2082 +{ 13.2083 + unsigned long v; 13.2084 + 13.2085 + v = apic_read(APIC_LVT0); 13.2086 + apic_write_around(APIC_LVT0, v & ~APIC_LVT_MASKED); 13.2087 +} 13.2088 + 13.2089 +static void disable_lapic_irq (unsigned int irq) 13.2090 +{ 13.2091 + unsigned long v; 13.2092 + 13.2093 + v = apic_read(APIC_LVT0); 13.2094 + apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED); 13.2095 +} 13.2096 + 13.2097 +static void ack_lapic_irq (unsigned int irq) 13.2098 +{ 13.2099 + ack_APIC_irq(); 13.2100 +} 13.2101 + 13.2102 +static void end_lapic_irq (unsigned int i) { /* nothing */ } 13.2103 + 13.2104 +static struct hw_interrupt_type lapic_irq_type = { 13.2105 + .typename = "local-APIC-edge", 13.2106 + .startup = NULL, /* startup_irq() not used for IRQ0 */ 13.2107 + .shutdown = NULL, /* shutdown_irq() not used for IRQ0 */ 13.2108 + .enable = enable_lapic_irq, 13.2109 + .disable = disable_lapic_irq, 13.2110 + .ack = ack_lapic_irq, 13.2111 + .end = end_lapic_irq 13.2112 +}; 13.2113 + 13.2114 +static void setup_nmi (void) 13.2115 +{ 13.2116 + /* 13.2117 + * Dirty trick to enable the NMI watchdog ... 13.2118 + * We put the 8259A master into AEOI mode and 13.2119 + * unmask on all local APICs LVT0 as NMI. 13.2120 + * 13.2121 + * The idea to use the 8259A in AEOI mode ('8259A Virtual Wire') 13.2122 + * is from Maciej W. Rozycki - so we do not have to EOI from 13.2123 + * the NMI handler or the timer interrupt. 13.2124 + */ 13.2125 + apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ..."); 13.2126 + 13.2127 + on_each_cpu(enable_NMI_through_LVT0, NULL, 1, 1); 13.2128 + 13.2129 + apic_printk(APIC_VERBOSE, " done.\n"); 13.2130 +} 13.2131 + 13.2132 +/* 13.2133 + * This looks a bit hackish but it's about the only one way of sending 13.2134 + * a few INTA cycles to 8259As and any associated glue logic. ICR does 13.2135 + * not support the ExtINT mode, unfortunately. We need to send these 13.2136 + * cycles as some i82489DX-based boards have glue logic that keeps the 13.2137 + * 8259A interrupt line asserted until INTA. --macro 13.2138 + */ 13.2139 +static inline void unlock_ExtINT_logic(void) 13.2140 +{ 13.2141 + int pin, i; 13.2142 + struct IO_APIC_route_entry entry0, entry1; 13.2143 + unsigned char save_control, save_freq_select; 13.2144 + unsigned long flags; 13.2145 + 13.2146 + pin = find_isa_irq_pin(8, mp_INT); 13.2147 + if (pin == -1) 13.2148 + return; 13.2149 + 13.2150 + spin_lock_irqsave(&ioapic_lock, flags); 13.2151 + *(((int *)&entry0) + 1) = io_apic_read(0, 0x11 + 2 * pin); 13.2152 + *(((int *)&entry0) + 0) = io_apic_read(0, 0x10 + 2 * pin); 13.2153 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.2154 + clear_IO_APIC_pin(0, pin); 13.2155 + 13.2156 + memset(&entry1, 0, sizeof(entry1)); 13.2157 + 13.2158 + entry1.dest_mode = 0; /* physical delivery */ 13.2159 + entry1.mask = 0; /* unmask IRQ now */ 13.2160 + entry1.dest.physical.physical_dest = hard_smp_processor_id(); 13.2161 + entry1.delivery_mode = dest_ExtINT; 13.2162 + entry1.polarity = entry0.polarity; 13.2163 + entry1.trigger = 0; 13.2164 + entry1.vector = 0; 13.2165 + 13.2166 + spin_lock_irqsave(&ioapic_lock, flags); 13.2167 + io_apic_write(0, 0x11 + 2 * pin, *(((int *)&entry1) + 1)); 13.2168 + io_apic_write(0, 0x10 + 2 * pin, *(((int *)&entry1) + 0)); 13.2169 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.2170 + 13.2171 + save_control = CMOS_READ(RTC_CONTROL); 13.2172 + save_freq_select = CMOS_READ(RTC_FREQ_SELECT); 13.2173 + CMOS_WRITE((save_freq_select & ~RTC_RATE_SELECT) | 0x6, 13.2174 + RTC_FREQ_SELECT); 13.2175 + CMOS_WRITE(save_control | RTC_PIE, RTC_CONTROL); 13.2176 + 13.2177 + i = 100; 13.2178 + while (i-- > 0) { 13.2179 + mdelay(10); 13.2180 + if ((CMOS_READ(RTC_INTR_FLAGS) & RTC_PF) == RTC_PF) 13.2181 + i -= 10; 13.2182 + } 13.2183 + 13.2184 + CMOS_WRITE(save_control, RTC_CONTROL); 13.2185 + CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); 13.2186 + clear_IO_APIC_pin(0, pin); 13.2187 + 13.2188 + spin_lock_irqsave(&ioapic_lock, flags); 13.2189 + io_apic_write(0, 0x11 + 2 * pin, *(((int *)&entry0) + 1)); 13.2190 + io_apic_write(0, 0x10 + 2 * pin, *(((int *)&entry0) + 0)); 13.2191 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.2192 +} 13.2193 + 13.2194 +/* 13.2195 + * This code may look a bit paranoid, but it's supposed to cooperate with 13.2196 + * a wide range of boards and BIOS bugs. Fortunately only the timer IRQ 13.2197 + * is so screwy. Thanks to Brian Perkins for testing/hacking this beast 13.2198 + * fanatically on his truly buggy board. 13.2199 + */ 13.2200 +static inline void check_timer(void) 13.2201 +{ 13.2202 + int pin1, pin2; 13.2203 + int vector; 13.2204 + 13.2205 + /* 13.2206 + * get/set the timer IRQ vector: 13.2207 + */ 13.2208 + disable_8259A_irq(0); 13.2209 + vector = assign_irq_vector(0); 13.2210 + set_intr_gate(vector, interrupt[0]); 13.2211 + 13.2212 + /* 13.2213 + * Subtle, code in do_timer_interrupt() expects an AEOI 13.2214 + * mode for the 8259A whenever interrupts are routed 13.2215 + * through I/O APICs. Also IRQ0 has to be enabled in 13.2216 + * the 8259A which implies the virtual wire has to be 13.2217 + * disabled in the local APIC. 13.2218 + */ 13.2219 + apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); 13.2220 + init_8259A(1); 13.2221 + timer_ack = 1; 13.2222 + enable_8259A_irq(0); 13.2223 + 13.2224 + pin1 = find_isa_irq_pin(0, mp_INT); 13.2225 + pin2 = find_isa_irq_pin(0, mp_ExtINT); 13.2226 + 13.2227 + printk(KERN_INFO "..TIMER: vector=0x%02X pin1=%d pin2=%d\n", vector, pin1, pin2); 13.2228 + 13.2229 + if (pin1 != -1) { 13.2230 + /* 13.2231 + * Ok, does IRQ0 through the IOAPIC work? 13.2232 + */ 13.2233 + unmask_IO_APIC_irq(0); 13.2234 + if (timer_irq_works()) { 13.2235 + if (nmi_watchdog == NMI_IO_APIC) { 13.2236 + disable_8259A_irq(0); 13.2237 + setup_nmi(); 13.2238 + enable_8259A_irq(0); 13.2239 + check_nmi_watchdog(); 13.2240 + } 13.2241 + return; 13.2242 + } 13.2243 + clear_IO_APIC_pin(0, pin1); 13.2244 + printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to IO-APIC\n"); 13.2245 + } 13.2246 + 13.2247 + printk(KERN_INFO "...trying to set up timer (IRQ0) through the 8259A ... "); 13.2248 + if (pin2 != -1) { 13.2249 + printk("\n..... (found pin %d) ...", pin2); 13.2250 + /* 13.2251 + * legacy devices should be connected to IO APIC #0 13.2252 + */ 13.2253 + setup_ExtINT_IRQ0_pin(pin2, vector); 13.2254 + if (timer_irq_works()) { 13.2255 + printk("works.\n"); 13.2256 + if (pin1 != -1) 13.2257 + replace_pin_at_irq(0, 0, pin1, 0, pin2); 13.2258 + else 13.2259 + add_pin_to_irq(0, 0, pin2); 13.2260 + if (nmi_watchdog == NMI_IO_APIC) { 13.2261 + setup_nmi(); 13.2262 + check_nmi_watchdog(); 13.2263 + } 13.2264 + return; 13.2265 + } 13.2266 + /* 13.2267 + * Cleanup, just in case ... 13.2268 + */ 13.2269 + clear_IO_APIC_pin(0, pin2); 13.2270 + } 13.2271 + printk(" failed.\n"); 13.2272 + 13.2273 + if (nmi_watchdog == NMI_IO_APIC) { 13.2274 + printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n"); 13.2275 + nmi_watchdog = 0; 13.2276 + } 13.2277 + 13.2278 + printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); 13.2279 + 13.2280 + disable_8259A_irq(0); 13.2281 + irq_desc[0].handler = &lapic_irq_type; 13.2282 + apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ 13.2283 + enable_8259A_irq(0); 13.2284 + 13.2285 + if (timer_irq_works()) { 13.2286 + printk(" works.\n"); 13.2287 + return; 13.2288 + } 13.2289 + apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector); 13.2290 + printk(" failed.\n"); 13.2291 + 13.2292 + printk(KERN_INFO "...trying to set up timer as ExtINT IRQ..."); 13.2293 + 13.2294 + timer_ack = 0; 13.2295 + init_8259A(0); 13.2296 + make_8259A_irq(0); 13.2297 + apic_write_around(APIC_LVT0, APIC_DM_EXTINT); 13.2298 + 13.2299 + unlock_ExtINT_logic(); 13.2300 + 13.2301 + if (timer_irq_works()) { 13.2302 + printk(" works.\n"); 13.2303 + return; 13.2304 + } 13.2305 + printk(" failed :(.\n"); 13.2306 + panic("IO-APIC + timer doesn't work! Boot with apic=debug and send a " 13.2307 + "report. Then try booting with the 'noapic' option"); 13.2308 +} 13.2309 +#else 13.2310 +#define check_timer() ((void)0) 13.2311 +#endif 13.2312 + 13.2313 +/* 13.2314 + * 13.2315 + * IRQ's that are handled by the PIC in the MPS IOAPIC case. 13.2316 + * - IRQ2 is the cascade IRQ, and cannot be a io-apic IRQ. 13.2317 + * Linux doesn't really care, as it's not actually used 13.2318 + * for any interrupt handling anyway. 13.2319 + */ 13.2320 +#define PIC_IRQS (1 << PIC_CASCADE_IR) 13.2321 + 13.2322 +void __init setup_IO_APIC(void) 13.2323 +{ 13.2324 + enable_IO_APIC(); 13.2325 + 13.2326 + if (acpi_ioapic) 13.2327 + io_apic_irqs = ~0; /* all IRQs go through IOAPIC */ 13.2328 + else 13.2329 + io_apic_irqs = ~PIC_IRQS; 13.2330 + 13.2331 + printk("ENABLING IO-APIC IRQs\n"); 13.2332 + 13.2333 + /* 13.2334 + * Set up IO-APIC IRQ routing. 13.2335 + */ 13.2336 + if (!acpi_ioapic) 13.2337 + setup_ioapic_ids_from_mpc(); 13.2338 +#ifndef CONFIG_XEN 13.2339 + sync_Arb_IDs(); 13.2340 +#endif 13.2341 + setup_IO_APIC_irqs(); 13.2342 + init_IO_APIC_traps(); 13.2343 + check_timer(); 13.2344 + if (!acpi_ioapic) 13.2345 + print_IO_APIC(); 13.2346 +} 13.2347 + 13.2348 +/* 13.2349 + * Called after all the initialization is done. If we didnt find any 13.2350 + * APIC bugs then we can allow the modify fast path 13.2351 + */ 13.2352 + 13.2353 +static int __init io_apic_bug_finalize(void) 13.2354 +{ 13.2355 + if(sis_apic_bug == -1) 13.2356 + sis_apic_bug = 0; 13.2357 + return 0; 13.2358 +} 13.2359 + 13.2360 +late_initcall(io_apic_bug_finalize); 13.2361 + 13.2362 +struct sysfs_ioapic_data { 13.2363 + struct sys_device dev; 13.2364 + struct IO_APIC_route_entry entry[0]; 13.2365 +}; 13.2366 +static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS]; 13.2367 + 13.2368 +static int ioapic_suspend(struct sys_device *dev, u32 state) 13.2369 +{ 13.2370 + struct IO_APIC_route_entry *entry; 13.2371 + struct sysfs_ioapic_data *data; 13.2372 + unsigned long flags; 13.2373 + int i; 13.2374 + 13.2375 + data = container_of(dev, struct sysfs_ioapic_data, dev); 13.2376 + entry = data->entry; 13.2377 + spin_lock_irqsave(&ioapic_lock, flags); 13.2378 + for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { 13.2379 + *(((int *)entry) + 1) = io_apic_read(dev->id, 0x11 + 2 * i); 13.2380 + *(((int *)entry) + 0) = io_apic_read(dev->id, 0x10 + 2 * i); 13.2381 + } 13.2382 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.2383 + 13.2384 + return 0; 13.2385 +} 13.2386 + 13.2387 +static int ioapic_resume(struct sys_device *dev) 13.2388 +{ 13.2389 + struct IO_APIC_route_entry *entry; 13.2390 + struct sysfs_ioapic_data *data; 13.2391 + unsigned long flags; 13.2392 + union IO_APIC_reg_00 reg_00; 13.2393 + int i; 13.2394 + 13.2395 + data = container_of(dev, struct sysfs_ioapic_data, dev); 13.2396 + entry = data->entry; 13.2397 + 13.2398 + spin_lock_irqsave(&ioapic_lock, flags); 13.2399 + reg_00.raw = io_apic_read(dev->id, 0); 13.2400 + if (reg_00.bits.ID != mp_ioapics[dev->id].mpc_apicid) { 13.2401 + reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid; 13.2402 + io_apic_write(dev->id, 0, reg_00.raw); 13.2403 + } 13.2404 + for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { 13.2405 + io_apic_write(dev->id, 0x11+2*i, *(((int *)entry)+1)); 13.2406 + io_apic_write(dev->id, 0x10+2*i, *(((int *)entry)+0)); 13.2407 + } 13.2408 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.2409 + 13.2410 + return 0; 13.2411 +} 13.2412 + 13.2413 +static struct sysdev_class ioapic_sysdev_class = { 13.2414 + set_kset_name("ioapic"), 13.2415 + .suspend = ioapic_suspend, 13.2416 + .resume = ioapic_resume, 13.2417 +}; 13.2418 + 13.2419 +static int __init ioapic_init_sysfs(void) 13.2420 +{ 13.2421 + struct sys_device * dev; 13.2422 + int i, size, error = 0; 13.2423 + 13.2424 + error = sysdev_class_register(&ioapic_sysdev_class); 13.2425 + if (error) 13.2426 + return error; 13.2427 + 13.2428 + for (i = 0; i < nr_ioapics; i++ ) { 13.2429 + size = sizeof(struct sys_device) + nr_ioapic_registers[i] 13.2430 + * sizeof(struct IO_APIC_route_entry); 13.2431 + mp_ioapic_data[i] = kmalloc(size, GFP_KERNEL); 13.2432 + if (!mp_ioapic_data[i]) { 13.2433 + printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i); 13.2434 + continue; 13.2435 + } 13.2436 + memset(mp_ioapic_data[i], 0, size); 13.2437 + dev = &mp_ioapic_data[i]->dev; 13.2438 + dev->id = i; 13.2439 + dev->cls = &ioapic_sysdev_class; 13.2440 + error = sysdev_register(dev); 13.2441 + if (error) { 13.2442 + kfree(mp_ioapic_data[i]); 13.2443 + mp_ioapic_data[i] = NULL; 13.2444 + printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i); 13.2445 + continue; 13.2446 + } 13.2447 + } 13.2448 + 13.2449 + return 0; 13.2450 +} 13.2451 + 13.2452 +device_initcall(ioapic_init_sysfs); 13.2453 + 13.2454 +/* -------------------------------------------------------------------------- 13.2455 + ACPI-based IOAPIC Configuration 13.2456 + -------------------------------------------------------------------------- */ 13.2457 + 13.2458 +#ifdef CONFIG_ACPI_BOOT 13.2459 + 13.2460 +int __init io_apic_get_unique_id (int ioapic, int apic_id) 13.2461 +{ 13.2462 +#ifndef CONFIG_XEN 13.2463 + union IO_APIC_reg_00 reg_00; 13.2464 + static physid_mask_t apic_id_map = PHYSID_MASK_NONE; 13.2465 + physid_mask_t tmp; 13.2466 + unsigned long flags; 13.2467 + int i = 0; 13.2468 + 13.2469 + /* 13.2470 + * The P4 platform supports up to 256 APIC IDs on two separate APIC 13.2471 + * buses (one for LAPICs, one for IOAPICs), where predecessors only 13.2472 + * supports up to 16 on one shared APIC bus. 13.2473 + * 13.2474 + * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full 13.2475 + * advantage of new APIC bus architecture. 13.2476 + */ 13.2477 + 13.2478 + if (physids_empty(apic_id_map)) 13.2479 + apic_id_map = ioapic_phys_id_map(phys_cpu_present_map); 13.2480 + 13.2481 + spin_lock_irqsave(&ioapic_lock, flags); 13.2482 + reg_00.raw = io_apic_read(ioapic, 0); 13.2483 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.2484 + 13.2485 + if (apic_id >= get_physical_broadcast()) { 13.2486 + printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying " 13.2487 + "%d\n", ioapic, apic_id, reg_00.bits.ID); 13.2488 + apic_id = reg_00.bits.ID; 13.2489 + } 13.2490 + 13.2491 + /* 13.2492 + * Every APIC in a system must have a unique ID or we get lots of nice 13.2493 + * 'stuck on smp_invalidate_needed IPI wait' messages. 13.2494 + */ 13.2495 + if (check_apicid_used(apic_id_map, apic_id)) { 13.2496 + 13.2497 + for (i = 0; i < get_physical_broadcast(); i++) { 13.2498 + if (!check_apicid_used(apic_id_map, i)) 13.2499 + break; 13.2500 + } 13.2501 + 13.2502 + if (i == get_physical_broadcast()) 13.2503 + panic("Max apic_id exceeded!\n"); 13.2504 + 13.2505 + printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, " 13.2506 + "trying %d\n", ioapic, apic_id, i); 13.2507 + 13.2508 + apic_id = i; 13.2509 + } 13.2510 + 13.2511 + tmp = apicid_to_cpu_present(apic_id); 13.2512 + physids_or(apic_id_map, apic_id_map, tmp); 13.2513 + 13.2514 + if (reg_00.bits.ID != apic_id) { 13.2515 + reg_00.bits.ID = apic_id; 13.2516 + 13.2517 + spin_lock_irqsave(&ioapic_lock, flags); 13.2518 + io_apic_write(ioapic, 0, reg_00.raw); 13.2519 + reg_00.raw = io_apic_read(ioapic, 0); 13.2520 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.2521 + 13.2522 + /* Sanity check */ 13.2523 + if (reg_00.bits.ID != apic_id) 13.2524 + panic("IOAPIC[%d]: Unable change apic_id!\n", ioapic); 13.2525 + } 13.2526 + 13.2527 + apic_printk(APIC_VERBOSE, KERN_INFO 13.2528 + "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id); 13.2529 +#endif /* !CONFIG_XEN */ 13.2530 + 13.2531 + return apic_id; 13.2532 +} 13.2533 + 13.2534 + 13.2535 +int __init io_apic_get_version (int ioapic) 13.2536 +{ 13.2537 + union IO_APIC_reg_01 reg_01; 13.2538 + unsigned long flags; 13.2539 + 13.2540 + spin_lock_irqsave(&ioapic_lock, flags); 13.2541 + reg_01.raw = io_apic_read(ioapic, 1); 13.2542 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.2543 + 13.2544 + return reg_01.bits.version; 13.2545 +} 13.2546 + 13.2547 + 13.2548 +int __init io_apic_get_redir_entries (int ioapic) 13.2549 +{ 13.2550 + union IO_APIC_reg_01 reg_01; 13.2551 + unsigned long flags; 13.2552 + 13.2553 + spin_lock_irqsave(&ioapic_lock, flags); 13.2554 + reg_01.raw = io_apic_read(ioapic, 1); 13.2555 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.2556 + 13.2557 + return reg_01.bits.entries; 13.2558 +} 13.2559 + 13.2560 + 13.2561 +int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low) 13.2562 +{ 13.2563 + struct IO_APIC_route_entry entry; 13.2564 + unsigned long flags; 13.2565 + 13.2566 + if (!IO_APIC_IRQ(irq)) { 13.2567 + printk(KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n", 13.2568 + ioapic); 13.2569 + return -EINVAL; 13.2570 + } 13.2571 + 13.2572 + /* 13.2573 + * Generate a PCI IRQ routing entry and program the IOAPIC accordingly. 13.2574 + * Note that we mask (disable) IRQs now -- these get enabled when the 13.2575 + * corresponding device driver registers for this IRQ. 13.2576 + */ 13.2577 + 13.2578 + memset(&entry,0,sizeof(entry)); 13.2579 + 13.2580 + entry.delivery_mode = INT_DELIVERY_MODE; 13.2581 + entry.dest_mode = INT_DEST_MODE; 13.2582 + entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); 13.2583 + entry.trigger = edge_level; 13.2584 + entry.polarity = active_high_low; 13.2585 + entry.mask = 1; 13.2586 + 13.2587 + /* 13.2588 + * IRQs < 16 are already in the irq_2_pin[] map 13.2589 + */ 13.2590 + if (irq >= 16) 13.2591 + add_pin_to_irq(irq, ioapic, pin); 13.2592 + 13.2593 + entry.vector = assign_irq_vector(irq); 13.2594 + 13.2595 + apic_printk(APIC_DEBUG, KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry " 13.2596 + "(%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i)\n", ioapic, 13.2597 + mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq, 13.2598 + edge_level, active_high_low); 13.2599 + 13.2600 + ioapic_register_intr(irq, entry.vector, edge_level); 13.2601 + 13.2602 + if (!ioapic && (irq < 16)) 13.2603 + disable_8259A_irq(irq); 13.2604 + 13.2605 + spin_lock_irqsave(&ioapic_lock, flags); 13.2606 + io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1)); 13.2607 + io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0)); 13.2608 + spin_unlock_irqrestore(&ioapic_lock, flags); 13.2609 + 13.2610 + return 0; 13.2611 +} 13.2612 + 13.2613 +#endif /*CONFIG_ACPI_BOOT*/
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/mpparse.c Fri May 06 17:04:27 2005 +0000 14.3 @@ -0,0 +1,1115 @@ 14.4 +/* 14.5 + * Intel Multiprocessor Specification 1.1 and 1.4 14.6 + * compliant MP-table parsing routines. 14.7 + * 14.8 + * (c) 1995 Alan Cox, Building #3 <alan@redhat.com> 14.9 + * (c) 1998, 1999, 2000 Ingo Molnar <mingo@redhat.com> 14.10 + * 14.11 + * Fixes 14.12 + * Erich Boleyn : MP v1.4 and additional changes. 14.13 + * Alan Cox : Added EBDA scanning 14.14 + * Ingo Molnar : various cleanups and rewrites 14.15 + * Maciej W. Rozycki: Bits for default MP configurations 14.16 + * Paul Diefenbaugh: Added full ACPI support 14.17 + */ 14.18 + 14.19 +#include <linux/mm.h> 14.20 +#include <linux/irq.h> 14.21 +#include <linux/init.h> 14.22 +#include <linux/acpi.h> 14.23 +#include <linux/delay.h> 14.24 +#include <linux/config.h> 14.25 +#include <linux/bootmem.h> 14.26 +#include <linux/smp_lock.h> 14.27 +#include <linux/kernel_stat.h> 14.28 +#include <linux/mc146818rtc.h> 14.29 +#include <linux/bitops.h> 14.30 + 14.31 +#include <asm/smp.h> 14.32 +#include <asm/acpi.h> 14.33 +#include <asm/mtrr.h> 14.34 +#include <asm/mpspec.h> 14.35 +#include <asm/io_apic.h> 14.36 + 14.37 +#include <mach_apic.h> 14.38 +#include <mach_mpparse.h> 14.39 +#include <bios_ebda.h> 14.40 + 14.41 +/* Have we found an MP table */ 14.42 +int smp_found_config; 14.43 +unsigned int __initdata maxcpus = NR_CPUS; 14.44 + 14.45 +/* 14.46 + * Various Linux-internal data structures created from the 14.47 + * MP-table. 14.48 + */ 14.49 +int apic_version [MAX_APICS]; 14.50 +int mp_bus_id_to_type [MAX_MP_BUSSES]; 14.51 +int mp_bus_id_to_node [MAX_MP_BUSSES]; 14.52 +int mp_bus_id_to_local [MAX_MP_BUSSES]; 14.53 +int quad_local_to_mp_bus_id [NR_CPUS/4][4]; 14.54 +int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; 14.55 +int mp_current_pci_id; 14.56 + 14.57 +/* I/O APIC entries */ 14.58 +struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS]; 14.59 + 14.60 +/* # of MP IRQ source entries */ 14.61 +struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; 14.62 + 14.63 +/* MP IRQ source entries */ 14.64 +int mp_irq_entries; 14.65 + 14.66 +int nr_ioapics; 14.67 + 14.68 +int pic_mode; 14.69 +unsigned long mp_lapic_addr; 14.70 + 14.71 +/* Processor that is doing the boot up */ 14.72 +unsigned int boot_cpu_physical_apicid = -1U; 14.73 +unsigned int boot_cpu_logical_apicid = -1U; 14.74 +/* Internal processor count */ 14.75 +static unsigned int __initdata num_processors; 14.76 + 14.77 +/* Bitmask of physically existing CPUs */ 14.78 +physid_mask_t phys_cpu_present_map; 14.79 + 14.80 +u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; 14.81 + 14.82 +/* 14.83 + * Intel MP BIOS table parsing routines: 14.84 + */ 14.85 + 14.86 + 14.87 +/* 14.88 + * Checksum an MP configuration block. 14.89 + */ 14.90 + 14.91 +static int __init mpf_checksum(unsigned char *mp, int len) 14.92 +{ 14.93 + int sum = 0; 14.94 + 14.95 + while (len--) 14.96 + sum += *mp++; 14.97 + 14.98 + return sum & 0xFF; 14.99 +} 14.100 + 14.101 +/* 14.102 + * Have to match translation table entries to main table entries by counter 14.103 + * hence the mpc_record variable .... can't see a less disgusting way of 14.104 + * doing this .... 14.105 + */ 14.106 + 14.107 +static int mpc_record; 14.108 +static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata; 14.109 + 14.110 +#ifdef CONFIG_X86_NUMAQ 14.111 +static int MP_valid_apicid(int apicid, int version) 14.112 +{ 14.113 + return hweight_long(apicid & 0xf) == 1 && (apicid >> 4) != 0xf; 14.114 +} 14.115 +#elif !defined(CONFIG_XEN) 14.116 +static int MP_valid_apicid(int apicid, int version) 14.117 +{ 14.118 + if (version >= 0x14) 14.119 + return apicid < 0xff; 14.120 + else 14.121 + return apicid < 0xf; 14.122 +} 14.123 +#endif 14.124 + 14.125 +#ifndef CONFIG_XEN 14.126 +void __init MP_processor_info (struct mpc_config_processor *m) 14.127 +{ 14.128 + int ver, apicid; 14.129 + physid_mask_t tmp; 14.130 + 14.131 + if (!(m->mpc_cpuflag & CPU_ENABLED)) 14.132 + return; 14.133 + 14.134 + apicid = mpc_apic_id(m, translation_table[mpc_record]); 14.135 + 14.136 + if (m->mpc_featureflag&(1<<0)) 14.137 + Dprintk(" Floating point unit present.\n"); 14.138 + if (m->mpc_featureflag&(1<<7)) 14.139 + Dprintk(" Machine Exception supported.\n"); 14.140 + if (m->mpc_featureflag&(1<<8)) 14.141 + Dprintk(" 64 bit compare & exchange supported.\n"); 14.142 + if (m->mpc_featureflag&(1<<9)) 14.143 + Dprintk(" Internal APIC present.\n"); 14.144 + if (m->mpc_featureflag&(1<<11)) 14.145 + Dprintk(" SEP present.\n"); 14.146 + if (m->mpc_featureflag&(1<<12)) 14.147 + Dprintk(" MTRR present.\n"); 14.148 + if (m->mpc_featureflag&(1<<13)) 14.149 + Dprintk(" PGE present.\n"); 14.150 + if (m->mpc_featureflag&(1<<14)) 14.151 + Dprintk(" MCA present.\n"); 14.152 + if (m->mpc_featureflag&(1<<15)) 14.153 + Dprintk(" CMOV present.\n"); 14.154 + if (m->mpc_featureflag&(1<<16)) 14.155 + Dprintk(" PAT present.\n"); 14.156 + if (m->mpc_featureflag&(1<<17)) 14.157 + Dprintk(" PSE present.\n"); 14.158 + if (m->mpc_featureflag&(1<<18)) 14.159 + Dprintk(" PSN present.\n"); 14.160 + if (m->mpc_featureflag&(1<<19)) 14.161 + Dprintk(" Cache Line Flush Instruction present.\n"); 14.162 + /* 20 Reserved */ 14.163 + if (m->mpc_featureflag&(1<<21)) 14.164 + Dprintk(" Debug Trace and EMON Store present.\n"); 14.165 + if (m->mpc_featureflag&(1<<22)) 14.166 + Dprintk(" ACPI Thermal Throttle Registers present.\n"); 14.167 + if (m->mpc_featureflag&(1<<23)) 14.168 + Dprintk(" MMX present.\n"); 14.169 + if (m->mpc_featureflag&(1<<24)) 14.170 + Dprintk(" FXSR present.\n"); 14.171 + if (m->mpc_featureflag&(1<<25)) 14.172 + Dprintk(" XMM present.\n"); 14.173 + if (m->mpc_featureflag&(1<<26)) 14.174 + Dprintk(" Willamette New Instructions present.\n"); 14.175 + if (m->mpc_featureflag&(1<<27)) 14.176 + Dprintk(" Self Snoop present.\n"); 14.177 + if (m->mpc_featureflag&(1<<28)) 14.178 + Dprintk(" HT present.\n"); 14.179 + if (m->mpc_featureflag&(1<<29)) 14.180 + Dprintk(" Thermal Monitor present.\n"); 14.181 + /* 30, 31 Reserved */ 14.182 + 14.183 + 14.184 + if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { 14.185 + Dprintk(" Bootup CPU\n"); 14.186 + boot_cpu_physical_apicid = m->mpc_apicid; 14.187 + boot_cpu_logical_apicid = apicid; 14.188 + } 14.189 + 14.190 + if (num_processors >= NR_CPUS) { 14.191 + printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached." 14.192 + " Processor ignored.\n", NR_CPUS); 14.193 + return; 14.194 + } 14.195 + 14.196 + if (num_processors >= maxcpus) { 14.197 + printk(KERN_WARNING "WARNING: maxcpus limit of %i reached." 14.198 + " Processor ignored.\n", maxcpus); 14.199 + return; 14.200 + } 14.201 + num_processors++; 14.202 + ver = m->mpc_apicver; 14.203 + 14.204 + if (!MP_valid_apicid(apicid, ver)) { 14.205 + printk(KERN_WARNING "Processor #%d INVALID. (Max ID: %d).\n", 14.206 + m->mpc_apicid, MAX_APICS); 14.207 + --num_processors; 14.208 + return; 14.209 + } 14.210 + 14.211 + tmp = apicid_to_cpu_present(apicid); 14.212 + physids_or(phys_cpu_present_map, phys_cpu_present_map, tmp); 14.213 + 14.214 + /* 14.215 + * Validate version 14.216 + */ 14.217 + if (ver == 0x0) { 14.218 + printk(KERN_WARNING "BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->mpc_apicid); 14.219 + ver = 0x10; 14.220 + } 14.221 + apic_version[m->mpc_apicid] = ver; 14.222 + bios_cpu_apicid[num_processors - 1] = m->mpc_apicid; 14.223 +} 14.224 +#else 14.225 +void __init MP_processor_info (struct mpc_config_processor *m) 14.226 +{ 14.227 + num_processors++; 14.228 +} 14.229 +#endif /* CONFIG_XEN */ 14.230 + 14.231 +static void __init MP_bus_info (struct mpc_config_bus *m) 14.232 +{ 14.233 + char str[7]; 14.234 + 14.235 + memcpy(str, m->mpc_bustype, 6); 14.236 + str[6] = 0; 14.237 + 14.238 + mpc_oem_bus_info(m, str, translation_table[mpc_record]); 14.239 + 14.240 + if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) { 14.241 + mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; 14.242 + } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) { 14.243 + mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA; 14.244 + } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI)-1) == 0) { 14.245 + mpc_oem_pci_bus(m, translation_table[mpc_record]); 14.246 + mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI; 14.247 + mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id; 14.248 + mp_current_pci_id++; 14.249 + } else if (strncmp(str, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0) { 14.250 + mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA; 14.251 + } else if (strncmp(str, BUSTYPE_NEC98, sizeof(BUSTYPE_NEC98)-1) == 0) { 14.252 + mp_bus_id_to_type[m->mpc_busid] = MP_BUS_NEC98; 14.253 + } else { 14.254 + printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str); 14.255 + } 14.256 +} 14.257 + 14.258 +static void __init MP_ioapic_info (struct mpc_config_ioapic *m) 14.259 +{ 14.260 + if (!(m->mpc_flags & MPC_APIC_USABLE)) 14.261 + return; 14.262 + 14.263 + printk(KERN_INFO "I/O APIC #%d Version %d at 0x%lX.\n", 14.264 + m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr); 14.265 + if (nr_ioapics >= MAX_IO_APICS) { 14.266 + printk(KERN_CRIT "Max # of I/O APICs (%d) exceeded (found %d).\n", 14.267 + MAX_IO_APICS, nr_ioapics); 14.268 + panic("Recompile kernel with bigger MAX_IO_APICS!.\n"); 14.269 + } 14.270 + if (!m->mpc_apicaddr) { 14.271 + printk(KERN_ERR "WARNING: bogus zero I/O APIC address" 14.272 + " found in MP table, skipping!\n"); 14.273 + return; 14.274 + } 14.275 + mp_ioapics[nr_ioapics] = *m; 14.276 + nr_ioapics++; 14.277 +} 14.278 + 14.279 +static void __init MP_intsrc_info (struct mpc_config_intsrc *m) 14.280 +{ 14.281 + mp_irqs [mp_irq_entries] = *m; 14.282 + Dprintk("Int: type %d, pol %d, trig %d, bus %d," 14.283 + " IRQ %02x, APIC ID %x, APIC INT %02x\n", 14.284 + m->mpc_irqtype, m->mpc_irqflag & 3, 14.285 + (m->mpc_irqflag >> 2) & 3, m->mpc_srcbus, 14.286 + m->mpc_srcbusirq, m->mpc_dstapic, m->mpc_dstirq); 14.287 + if (++mp_irq_entries == MAX_IRQ_SOURCES) 14.288 + panic("Max # of irq sources exceeded!!\n"); 14.289 +} 14.290 + 14.291 +static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m) 14.292 +{ 14.293 + Dprintk("Lint: type %d, pol %d, trig %d, bus %d," 14.294 + " IRQ %02x, APIC ID %x, APIC LINT %02x\n", 14.295 + m->mpc_irqtype, m->mpc_irqflag & 3, 14.296 + (m->mpc_irqflag >> 2) &3, m->mpc_srcbusid, 14.297 + m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint); 14.298 + /* 14.299 + * Well it seems all SMP boards in existence 14.300 + * use ExtINT/LVT1 == LINT0 and 14.301 + * NMI/LVT2 == LINT1 - the following check 14.302 + * will show us if this assumptions is false. 14.303 + * Until then we do not have to add baggage. 14.304 + */ 14.305 + if ((m->mpc_irqtype == mp_ExtINT) && 14.306 + (m->mpc_destapiclint != 0)) 14.307 + BUG(); 14.308 + if ((m->mpc_irqtype == mp_NMI) && 14.309 + (m->mpc_destapiclint != 1)) 14.310 + BUG(); 14.311 +} 14.312 + 14.313 +#ifdef CONFIG_X86_NUMAQ 14.314 +static void __init MP_translation_info (struct mpc_config_translation *m) 14.315 +{ 14.316 + printk(KERN_INFO "Translation: record %d, type %d, quad %d, global %d, local %d\n", mpc_record, m->trans_type, m->trans_quad, m->trans_global, m->trans_local); 14.317 + 14.318 + if (mpc_record >= MAX_MPC_ENTRY) 14.319 + printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n"); 14.320 + else 14.321 + translation_table[mpc_record] = m; /* stash this for later */ 14.322 + if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad)) 14.323 + node_set_online(m->trans_quad); 14.324 +} 14.325 + 14.326 +/* 14.327 + * Read/parse the MPC oem tables 14.328 + */ 14.329 + 14.330 +static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable, \ 14.331 + unsigned short oemsize) 14.332 +{ 14.333 + int count = sizeof (*oemtable); /* the header size */ 14.334 + unsigned char *oemptr = ((unsigned char *)oemtable)+count; 14.335 + 14.336 + mpc_record = 0; 14.337 + printk(KERN_INFO "Found an OEM MPC table at %8p - parsing it ... \n", oemtable); 14.338 + if (memcmp(oemtable->oem_signature,MPC_OEM_SIGNATURE,4)) 14.339 + { 14.340 + printk(KERN_WARNING "SMP mpc oemtable: bad signature [%c%c%c%c]!\n", 14.341 + oemtable->oem_signature[0], 14.342 + oemtable->oem_signature[1], 14.343 + oemtable->oem_signature[2], 14.344 + oemtable->oem_signature[3]); 14.345 + return; 14.346 + } 14.347 + if (mpf_checksum((unsigned char *)oemtable,oemtable->oem_length)) 14.348 + { 14.349 + printk(KERN_WARNING "SMP oem mptable: checksum error!\n"); 14.350 + return; 14.351 + } 14.352 + while (count < oemtable->oem_length) { 14.353 + switch (*oemptr) { 14.354 + case MP_TRANSLATION: 14.355 + { 14.356 + struct mpc_config_translation *m= 14.357 + (struct mpc_config_translation *)oemptr; 14.358 + MP_translation_info(m); 14.359 + oemptr += sizeof(*m); 14.360 + count += sizeof(*m); 14.361 + ++mpc_record; 14.362 + break; 14.363 + } 14.364 + default: 14.365 + { 14.366 + printk(KERN_WARNING "Unrecognised OEM table entry type! - %d\n", (int) *oemptr); 14.367 + return; 14.368 + } 14.369 + } 14.370 + } 14.371 +} 14.372 + 14.373 +static inline void mps_oem_check(struct mp_config_table *mpc, char *oem, 14.374 + char *productid) 14.375 +{ 14.376 + if (strncmp(oem, "IBM NUMA", 8)) 14.377 + printk("Warning! May not be a NUMA-Q system!\n"); 14.378 + if (mpc->mpc_oemptr) 14.379 + smp_read_mpc_oem((struct mp_config_oemtable *) mpc->mpc_oemptr, 14.380 + mpc->mpc_oemsize); 14.381 +} 14.382 +#endif /* CONFIG_X86_NUMAQ */ 14.383 + 14.384 +/* 14.385 + * Read/parse the MPC 14.386 + */ 14.387 + 14.388 +static int __init smp_read_mpc(struct mp_config_table *mpc) 14.389 +{ 14.390 + char str[16]; 14.391 + char oem[10]; 14.392 + int count=sizeof(*mpc); 14.393 + unsigned char *mpt=((unsigned char *)mpc)+count; 14.394 + 14.395 + if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) { 14.396 + printk(KERN_ERR "SMP mptable: bad signature [0x%x]!\n", 14.397 + *(u32 *)mpc->mpc_signature); 14.398 + return 0; 14.399 + } 14.400 + if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) { 14.401 + printk(KERN_ERR "SMP mptable: checksum error!\n"); 14.402 + return 0; 14.403 + } 14.404 + if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) { 14.405 + printk(KERN_ERR "SMP mptable: bad table version (%d)!!\n", 14.406 + mpc->mpc_spec); 14.407 + return 0; 14.408 + } 14.409 + if (!mpc->mpc_lapic) { 14.410 + printk(KERN_ERR "SMP mptable: null local APIC address!\n"); 14.411 + return 0; 14.412 + } 14.413 + memcpy(oem,mpc->mpc_oem,8); 14.414 + oem[8]=0; 14.415 + printk(KERN_INFO "OEM ID: %s ",oem); 14.416 + 14.417 + memcpy(str,mpc->mpc_productid,12); 14.418 + str[12]=0; 14.419 + printk("Product ID: %s ",str); 14.420 + 14.421 + mps_oem_check(mpc, oem, str); 14.422 + 14.423 + printk("APIC at: 0x%lX\n",mpc->mpc_lapic); 14.424 + 14.425 + /* 14.426 + * Save the local APIC address (it might be non-default) -- but only 14.427 + * if we're not using ACPI. 14.428 + */ 14.429 + if (!acpi_lapic) 14.430 + mp_lapic_addr = mpc->mpc_lapic; 14.431 + 14.432 + /* 14.433 + * Now process the configuration blocks. 14.434 + */ 14.435 + mpc_record = 0; 14.436 + while (count < mpc->mpc_length) { 14.437 + switch(*mpt) { 14.438 + case MP_PROCESSOR: 14.439 + { 14.440 + struct mpc_config_processor *m= 14.441 + (struct mpc_config_processor *)mpt; 14.442 + /* ACPI may have already provided this data */ 14.443 + if (!acpi_lapic) 14.444 + MP_processor_info(m); 14.445 + mpt += sizeof(*m); 14.446 + count += sizeof(*m); 14.447 + break; 14.448 + } 14.449 + case MP_BUS: 14.450 + { 14.451 + struct mpc_config_bus *m= 14.452 + (struct mpc_config_bus *)mpt; 14.453 + MP_bus_info(m); 14.454 + mpt += sizeof(*m); 14.455 + count += sizeof(*m); 14.456 + break; 14.457 + } 14.458 + case MP_IOAPIC: 14.459 + { 14.460 + struct mpc_config_ioapic *m= 14.461 + (struct mpc_config_ioapic *)mpt; 14.462 + MP_ioapic_info(m); 14.463 + mpt+=sizeof(*m); 14.464 + count+=sizeof(*m); 14.465 + break; 14.466 + } 14.467 + case MP_INTSRC: 14.468 + { 14.469 + struct mpc_config_intsrc *m= 14.470 + (struct mpc_config_intsrc *)mpt; 14.471 + 14.472 + MP_intsrc_info(m); 14.473 + mpt+=sizeof(*m); 14.474 + count+=sizeof(*m); 14.475 + break; 14.476 + } 14.477 + case MP_LINTSRC: 14.478 + { 14.479 + struct mpc_config_lintsrc *m= 14.480 + (struct mpc_config_lintsrc *)mpt; 14.481 + MP_lintsrc_info(m); 14.482 + mpt+=sizeof(*m); 14.483 + count+=sizeof(*m); 14.484 + break; 14.485 + } 14.486 + default: 14.487 + { 14.488 + count = mpc->mpc_length; 14.489 + break; 14.490 + } 14.491 + } 14.492 + ++mpc_record; 14.493 + } 14.494 + clustered_apic_check(); 14.495 + if (!num_processors) 14.496 + printk(KERN_ERR "SMP mptable: no processors registered!\n"); 14.497 + return num_processors; 14.498 +} 14.499 + 14.500 +static int __init ELCR_trigger(unsigned int irq) 14.501 +{ 14.502 + unsigned int port; 14.503 + 14.504 + port = 0x4d0 + (irq >> 3); 14.505 + return (inb(port) >> (irq & 7)) & 1; 14.506 +} 14.507 + 14.508 +static void __init construct_default_ioirq_mptable(int mpc_default_type) 14.509 +{ 14.510 + struct mpc_config_intsrc intsrc; 14.511 + int i; 14.512 + int ELCR_fallback = 0; 14.513 + 14.514 + intsrc.mpc_type = MP_INTSRC; 14.515 + intsrc.mpc_irqflag = 0; /* conforming */ 14.516 + intsrc.mpc_srcbus = 0; 14.517 + intsrc.mpc_dstapic = mp_ioapics[0].mpc_apicid; 14.518 + 14.519 + intsrc.mpc_irqtype = mp_INT; 14.520 + 14.521 + /* 14.522 + * If true, we have an ISA/PCI system with no IRQ entries 14.523 + * in the MP table. To prevent the PCI interrupts from being set up 14.524 + * incorrectly, we try to use the ELCR. The sanity check to see if 14.525 + * there is good ELCR data is very simple - IRQ0, 1, 2 and 13 can 14.526 + * never be level sensitive, so we simply see if the ELCR agrees. 14.527 + * If it does, we assume it's valid. 14.528 + */ 14.529 + if (mpc_default_type == 5) { 14.530 + printk(KERN_INFO "ISA/PCI bus type with no IRQ information... falling back to ELCR\n"); 14.531 + 14.532 + if (ELCR_trigger(0) || ELCR_trigger(1) || ELCR_trigger(2) || ELCR_trigger(13)) 14.533 + printk(KERN_WARNING "ELCR contains invalid data... not using ELCR\n"); 14.534 + else { 14.535 + printk(KERN_INFO "Using ELCR to identify PCI interrupts\n"); 14.536 + ELCR_fallback = 1; 14.537 + } 14.538 + } 14.539 + 14.540 + for (i = 0; i < 16; i++) { 14.541 + switch (mpc_default_type) { 14.542 + case 2: 14.543 + if (i == 0 || i == 13) 14.544 + continue; /* IRQ0 & IRQ13 not connected */ 14.545 + /* fall through */ 14.546 + default: 14.547 + if (i == 2) 14.548 + continue; /* IRQ2 is never connected */ 14.549 + } 14.550 + 14.551 + if (ELCR_fallback) { 14.552 + /* 14.553 + * If the ELCR indicates a level-sensitive interrupt, we 14.554 + * copy that information over to the MP table in the 14.555 + * irqflag field (level sensitive, active high polarity). 14.556 + */ 14.557 + if (ELCR_trigger(i)) 14.558 + intsrc.mpc_irqflag = 13; 14.559 + else 14.560 + intsrc.mpc_irqflag = 0; 14.561 + } 14.562 + 14.563 + intsrc.mpc_srcbusirq = i; 14.564 + intsrc.mpc_dstirq = i ? i : 2; /* IRQ0 to INTIN2 */ 14.565 + MP_intsrc_info(&intsrc); 14.566 + } 14.567 + 14.568 + intsrc.mpc_irqtype = mp_ExtINT; 14.569 + intsrc.mpc_srcbusirq = 0; 14.570 + intsrc.mpc_dstirq = 0; /* 8259A to INTIN0 */ 14.571 + MP_intsrc_info(&intsrc); 14.572 +} 14.573 + 14.574 +static inline void __init construct_default_ISA_mptable(int mpc_default_type) 14.575 +{ 14.576 + struct mpc_config_processor processor; 14.577 + struct mpc_config_bus bus; 14.578 + struct mpc_config_ioapic ioapic; 14.579 + struct mpc_config_lintsrc lintsrc; 14.580 + int linttypes[2] = { mp_ExtINT, mp_NMI }; 14.581 + int i; 14.582 + 14.583 + /* 14.584 + * local APIC has default address 14.585 + */ 14.586 + mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; 14.587 + 14.588 + /* 14.589 + * 2 CPUs, numbered 0 & 1. 14.590 + */ 14.591 + processor.mpc_type = MP_PROCESSOR; 14.592 + /* Either an integrated APIC or a discrete 82489DX. */ 14.593 + processor.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01; 14.594 + processor.mpc_cpuflag = CPU_ENABLED; 14.595 + processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | 14.596 + (boot_cpu_data.x86_model << 4) | 14.597 + boot_cpu_data.x86_mask; 14.598 + processor.mpc_featureflag = boot_cpu_data.x86_capability[0]; 14.599 + processor.mpc_reserved[0] = 0; 14.600 + processor.mpc_reserved[1] = 0; 14.601 + for (i = 0; i < 2; i++) { 14.602 + processor.mpc_apicid = i; 14.603 + MP_processor_info(&processor); 14.604 + } 14.605 + 14.606 + bus.mpc_type = MP_BUS; 14.607 + bus.mpc_busid = 0; 14.608 + switch (mpc_default_type) { 14.609 + default: 14.610 + printk("???\n"); 14.611 + printk(KERN_ERR "Unknown standard configuration %d\n", 14.612 + mpc_default_type); 14.613 + /* fall through */ 14.614 + case 1: 14.615 + case 5: 14.616 + memcpy(bus.mpc_bustype, "ISA ", 6); 14.617 + break; 14.618 + case 2: 14.619 + case 6: 14.620 + case 3: 14.621 + memcpy(bus.mpc_bustype, "EISA ", 6); 14.622 + break; 14.623 + case 4: 14.624 + case 7: 14.625 + memcpy(bus.mpc_bustype, "MCA ", 6); 14.626 + } 14.627 + MP_bus_info(&bus); 14.628 + if (mpc_default_type > 4) { 14.629 + bus.mpc_busid = 1; 14.630 + memcpy(bus.mpc_bustype, "PCI ", 6); 14.631 + MP_bus_info(&bus); 14.632 + } 14.633 + 14.634 + ioapic.mpc_type = MP_IOAPIC; 14.635 + ioapic.mpc_apicid = 2; 14.636 + ioapic.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01; 14.637 + ioapic.mpc_flags = MPC_APIC_USABLE; 14.638 + ioapic.mpc_apicaddr = 0xFEC00000; 14.639 + MP_ioapic_info(&ioapic); 14.640 + 14.641 + /* 14.642 + * We set up most of the low 16 IO-APIC pins according to MPS rules. 14.643 + */ 14.644 + construct_default_ioirq_mptable(mpc_default_type); 14.645 + 14.646 + lintsrc.mpc_type = MP_LINTSRC; 14.647 + lintsrc.mpc_irqflag = 0; /* conforming */ 14.648 + lintsrc.mpc_srcbusid = 0; 14.649 + lintsrc.mpc_srcbusirq = 0; 14.650 + lintsrc.mpc_destapic = MP_APIC_ALL; 14.651 + for (i = 0; i < 2; i++) { 14.652 + lintsrc.mpc_irqtype = linttypes[i]; 14.653 + lintsrc.mpc_destapiclint = i; 14.654 + MP_lintsrc_info(&lintsrc); 14.655 + } 14.656 +} 14.657 + 14.658 +static struct intel_mp_floating *mpf_found; 14.659 + 14.660 +/* 14.661 + * Scan the memory blocks for an SMP configuration block. 14.662 + */ 14.663 +void __init get_smp_config (void) 14.664 +{ 14.665 + struct intel_mp_floating *mpf = mpf_found; 14.666 + 14.667 + /* 14.668 + * ACPI may be used to obtain the entire SMP configuration or just to 14.669 + * enumerate/configure processors (CONFIG_ACPI_BOOT). Note that 14.670 + * ACPI supports both logical (e.g. Hyper-Threading) and physical 14.671 + * processors, where MPS only supports physical. 14.672 + */ 14.673 + if (acpi_lapic && acpi_ioapic) { 14.674 + printk(KERN_INFO "Using ACPI (MADT) for SMP configuration information\n"); 14.675 + return; 14.676 + } 14.677 + else if (acpi_lapic) 14.678 + printk(KERN_INFO "Using ACPI for processor (LAPIC) configuration information\n"); 14.679 + 14.680 + printk(KERN_INFO "Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification); 14.681 + if (mpf->mpf_feature2 & (1<<7)) { 14.682 + printk(KERN_INFO " IMCR and PIC compatibility mode.\n"); 14.683 + pic_mode = 1; 14.684 + } else { 14.685 + printk(KERN_INFO " Virtual Wire compatibility mode.\n"); 14.686 + pic_mode = 0; 14.687 + } 14.688 + 14.689 + /* 14.690 + * Now see if we need to read further. 14.691 + */ 14.692 + if (mpf->mpf_feature1 != 0) { 14.693 + 14.694 + printk(KERN_INFO "Default MP configuration #%d\n", mpf->mpf_feature1); 14.695 + construct_default_ISA_mptable(mpf->mpf_feature1); 14.696 + 14.697 + } else if (mpf->mpf_physptr) { 14.698 + 14.699 + /* 14.700 + * Read the physical hardware table. Anything here will 14.701 + * override the defaults. 14.702 + */ 14.703 + if (!smp_read_mpc(isa_bus_to_virt(mpf->mpf_physptr))) { 14.704 + smp_found_config = 0; 14.705 + printk(KERN_ERR "BIOS bug, MP table errors detected!...\n"); 14.706 + printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n"); 14.707 + return; 14.708 + } 14.709 + /* 14.710 + * If there are no explicit MP IRQ entries, then we are 14.711 + * broken. We set up most of the low 16 IO-APIC pins to 14.712 + * ISA defaults and hope it will work. 14.713 + */ 14.714 + if (!mp_irq_entries) { 14.715 + struct mpc_config_bus bus; 14.716 + 14.717 + printk(KERN_ERR "BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n"); 14.718 + 14.719 + bus.mpc_type = MP_BUS; 14.720 + bus.mpc_busid = 0; 14.721 + memcpy(bus.mpc_bustype, "ISA ", 6); 14.722 + MP_bus_info(&bus); 14.723 + 14.724 + construct_default_ioirq_mptable(0); 14.725 + } 14.726 + 14.727 + } else 14.728 + BUG(); 14.729 + 14.730 + printk(KERN_INFO "Processors: %d\n", num_processors); 14.731 + /* 14.732 + * Only use the first configuration found. 14.733 + */ 14.734 +} 14.735 + 14.736 +static int __init smp_scan_config (unsigned long base, unsigned long length) 14.737 +{ 14.738 + unsigned long *bp = isa_bus_to_virt(base); 14.739 + struct intel_mp_floating *mpf; 14.740 + 14.741 + Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length); 14.742 + if (sizeof(*mpf) != 16) 14.743 + printk("Error: MPF size\n"); 14.744 + 14.745 + while (length > 0) { 14.746 + mpf = (struct intel_mp_floating *)bp; 14.747 + if ((*bp == SMP_MAGIC_IDENT) && 14.748 + (mpf->mpf_length == 1) && 14.749 + !mpf_checksum((unsigned char *)bp, 16) && 14.750 + ((mpf->mpf_specification == 1) 14.751 + || (mpf->mpf_specification == 4)) ) { 14.752 + 14.753 + smp_found_config = 1; 14.754 + printk(KERN_INFO "found SMP MP-table at %08lx\n", 14.755 + virt_to_phys(mpf)); 14.756 + if (mpf->mpf_physptr) { 14.757 + /* 14.758 + * We cannot access to MPC table to compute 14.759 + * table size yet, as only few megabytes from 14.760 + * the bottom is mapped now. 14.761 + * PC-9800's MPC table places on the very last 14.762 + * of physical memory; so that simply reserving 14.763 + * PAGE_SIZE from mpg->mpf_physptr yields BUG() 14.764 + * in reserve_bootmem. 14.765 + */ 14.766 + unsigned long size = PAGE_SIZE; 14.767 + unsigned long end = max_low_pfn * PAGE_SIZE; 14.768 + if (mpf->mpf_physptr + size > end) 14.769 + size = end - mpf->mpf_physptr; 14.770 + reserve_bootmem(mpf->mpf_physptr, size); 14.771 + } 14.772 + 14.773 + mpf_found = mpf; 14.774 + return 1; 14.775 + } 14.776 + bp += 4; 14.777 + length -= 16; 14.778 + } 14.779 + return 0; 14.780 +} 14.781 + 14.782 +void __init find_smp_config (void) 14.783 +{ 14.784 + unsigned int address; 14.785 + 14.786 + /* 14.787 + * FIXME: Linux assumes you have 640K of base ram.. 14.788 + * this continues the error... 14.789 + * 14.790 + * 1) Scan the bottom 1K for a signature 14.791 + * 2) Scan the top 1K of base RAM 14.792 + * 3) Scan the 64K of bios 14.793 + */ 14.794 + if (smp_scan_config(0x0,0x400) || 14.795 + smp_scan_config(639*0x400,0x400) || 14.796 + smp_scan_config(0xF0000,0x10000)) 14.797 + return; 14.798 + /* 14.799 + * If it is an SMP machine we should know now, unless the 14.800 + * configuration is in an EISA/MCA bus machine with an 14.801 + * extended bios data area. 14.802 + * 14.803 + * there is a real-mode segmented pointer pointing to the 14.804 + * 4K EBDA area at 0x40E, calculate and scan it here. 14.805 + * 14.806 + * NOTE! There are Linux loaders that will corrupt the EBDA 14.807 + * area, and as such this kind of SMP config may be less 14.808 + * trustworthy, simply because the SMP table may have been 14.809 + * stomped on during early boot. These loaders are buggy and 14.810 + * should be fixed. 14.811 + * 14.812 + * MP1.4 SPEC states to only scan first 1K of 4K EBDA. 14.813 + */ 14.814 + 14.815 + address = get_bios_ebda(); 14.816 + if (address) 14.817 + smp_scan_config(address, 0x400); 14.818 +} 14.819 + 14.820 +/* -------------------------------------------------------------------------- 14.821 + ACPI-based MP Configuration 14.822 + -------------------------------------------------------------------------- */ 14.823 + 14.824 +#ifdef CONFIG_ACPI_BOOT 14.825 + 14.826 +void __init mp_register_lapic_address ( 14.827 + u64 address) 14.828 +{ 14.829 +#ifndef CONFIG_XEN 14.830 + mp_lapic_addr = (unsigned long) address; 14.831 + 14.832 + if (boot_cpu_physical_apicid == -1U) 14.833 + boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); 14.834 + 14.835 + Dprintk("Boot CPU = %d\n", boot_cpu_physical_apicid); 14.836 +#endif 14.837 +} 14.838 + 14.839 + 14.840 +void __init mp_register_lapic ( 14.841 + u8 id, 14.842 + u8 enabled) 14.843 +{ 14.844 + struct mpc_config_processor processor; 14.845 + int boot_cpu = 0; 14.846 + 14.847 + if (MAX_APICS - id <= 0) { 14.848 + printk(KERN_WARNING "Processor #%d invalid (max %d)\n", 14.849 + id, MAX_APICS); 14.850 + return; 14.851 + } 14.852 + 14.853 + if (id == boot_cpu_physical_apicid) 14.854 + boot_cpu = 1; 14.855 + 14.856 +#ifndef CONFIG_XEN 14.857 + processor.mpc_type = MP_PROCESSOR; 14.858 + processor.mpc_apicid = id; 14.859 + processor.mpc_apicver = GET_APIC_VERSION(apic_read(APIC_LVR)); 14.860 + processor.mpc_cpuflag = (enabled ? CPU_ENABLED : 0); 14.861 + processor.mpc_cpuflag |= (boot_cpu ? CPU_BOOTPROCESSOR : 0); 14.862 + processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | 14.863 + (boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_mask; 14.864 + processor.mpc_featureflag = boot_cpu_data.x86_capability[0]; 14.865 + processor.mpc_reserved[0] = 0; 14.866 + processor.mpc_reserved[1] = 0; 14.867 +#endif 14.868 + 14.869 + MP_processor_info(&processor); 14.870 +} 14.871 + 14.872 +#if defined(CONFIG_X86_IO_APIC) && (defined(CONFIG_ACPI_INTERPRETER) || defined(CONFIG_ACPI_BOOT)) 14.873 + 14.874 +#define MP_ISA_BUS 0 14.875 +#define MP_MAX_IOAPIC_PIN 127 14.876 + 14.877 +struct mp_ioapic_routing { 14.878 + int apic_id; 14.879 + int gsi_base; 14.880 + int gsi_end; 14.881 + u32 pin_programmed[4]; 14.882 +} mp_ioapic_routing[MAX_IO_APICS]; 14.883 + 14.884 + 14.885 +static int mp_find_ioapic ( 14.886 + int gsi) 14.887 +{ 14.888 + int i = 0; 14.889 + 14.890 + /* Find the IOAPIC that manages this GSI. */ 14.891 + for (i = 0; i < nr_ioapics; i++) { 14.892 + if ((gsi >= mp_ioapic_routing[i].gsi_base) 14.893 + && (gsi <= mp_ioapic_routing[i].gsi_end)) 14.894 + return i; 14.895 + } 14.896 + 14.897 + printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi); 14.898 + 14.899 + return -1; 14.900 +} 14.901 + 14.902 + 14.903 +void __init mp_register_ioapic ( 14.904 + u8 id, 14.905 + u32 address, 14.906 + u32 gsi_base) 14.907 +{ 14.908 + int idx = 0; 14.909 + 14.910 + if (nr_ioapics >= MAX_IO_APICS) { 14.911 + printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " 14.912 + "(found %d)\n", MAX_IO_APICS, nr_ioapics); 14.913 + panic("Recompile kernel with bigger MAX_IO_APICS!\n"); 14.914 + } 14.915 + if (!address) { 14.916 + printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address" 14.917 + " found in MADT table, skipping!\n"); 14.918 + return; 14.919 + } 14.920 + 14.921 + idx = nr_ioapics++; 14.922 + 14.923 + mp_ioapics[idx].mpc_type = MP_IOAPIC; 14.924 + mp_ioapics[idx].mpc_flags = MPC_APIC_USABLE; 14.925 + mp_ioapics[idx].mpc_apicaddr = address; 14.926 + 14.927 + mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id); 14.928 + mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); 14.929 + 14.930 + /* 14.931 + * Build basic GSI lookup table to facilitate gsi->io_apic lookups 14.932 + * and to prevent reprogramming of IOAPIC pins (PCI GSIs). 14.933 + */ 14.934 + mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mpc_apicid; 14.935 + mp_ioapic_routing[idx].gsi_base = gsi_base; 14.936 + mp_ioapic_routing[idx].gsi_end = gsi_base + 14.937 + io_apic_get_redir_entries(idx); 14.938 + 14.939 + printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, " 14.940 + "GSI %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, 14.941 + mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr, 14.942 + mp_ioapic_routing[idx].gsi_base, 14.943 + mp_ioapic_routing[idx].gsi_end); 14.944 + 14.945 + return; 14.946 +} 14.947 + 14.948 + 14.949 +void __init mp_override_legacy_irq ( 14.950 + u8 bus_irq, 14.951 + u8 polarity, 14.952 + u8 trigger, 14.953 + u32 gsi) 14.954 +{ 14.955 + struct mpc_config_intsrc intsrc; 14.956 + int ioapic = -1; 14.957 + int pin = -1; 14.958 + 14.959 + /* 14.960 + * Convert 'gsi' to 'ioapic.pin'. 14.961 + */ 14.962 + ioapic = mp_find_ioapic(gsi); 14.963 + if (ioapic < 0) 14.964 + return; 14.965 + pin = gsi - mp_ioapic_routing[ioapic].gsi_base; 14.966 + 14.967 + /* 14.968 + * TBD: This check is for faulty timer entries, where the override 14.969 + * erroneously sets the trigger to level, resulting in a HUGE 14.970 + * increase of timer interrupts! 14.971 + */ 14.972 + if ((bus_irq == 0) && (trigger == 3)) 14.973 + trigger = 1; 14.974 + 14.975 + intsrc.mpc_type = MP_INTSRC; 14.976 + intsrc.mpc_irqtype = mp_INT; 14.977 + intsrc.mpc_irqflag = (trigger << 2) | polarity; 14.978 + intsrc.mpc_srcbus = MP_ISA_BUS; 14.979 + intsrc.mpc_srcbusirq = bus_irq; /* IRQ */ 14.980 + intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid; /* APIC ID */ 14.981 + intsrc.mpc_dstirq = pin; /* INTIN# */ 14.982 + 14.983 + Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, %d-%d\n", 14.984 + intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3, 14.985 + (intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, 14.986 + intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, intsrc.mpc_dstirq); 14.987 + 14.988 + mp_irqs[mp_irq_entries] = intsrc; 14.989 + if (++mp_irq_entries == MAX_IRQ_SOURCES) 14.990 + panic("Max # of irq sources exceeded!\n"); 14.991 + 14.992 + return; 14.993 +} 14.994 + 14.995 + 14.996 +void __init mp_config_acpi_legacy_irqs (void) 14.997 +{ 14.998 + struct mpc_config_intsrc intsrc; 14.999 + int i = 0; 14.1000 + int ioapic = -1; 14.1001 + 14.1002 + /* 14.1003 + * Fabricate the legacy ISA bus (bus #31). 14.1004 + */ 14.1005 + mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA; 14.1006 + Dprintk("Bus #%d is ISA\n", MP_ISA_BUS); 14.1007 + 14.1008 + /* 14.1009 + * ES7000 has no legacy identity mappings 14.1010 + */ 14.1011 + if (es7000_plat) 14.1012 + return; 14.1013 + 14.1014 + /* 14.1015 + * Locate the IOAPIC that manages the ISA IRQs (0-15). 14.1016 + */ 14.1017 + ioapic = mp_find_ioapic(0); 14.1018 + if (ioapic < 0) 14.1019 + return; 14.1020 + 14.1021 + intsrc.mpc_type = MP_INTSRC; 14.1022 + intsrc.mpc_irqflag = 0; /* Conforming */ 14.1023 + intsrc.mpc_srcbus = MP_ISA_BUS; 14.1024 + intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid; 14.1025 + 14.1026 + /* 14.1027 + * Use the default configuration for the IRQs 0-15. Unless 14.1028 + * overriden by (MADT) interrupt source override entries. 14.1029 + */ 14.1030 + for (i = 0; i < 16; i++) { 14.1031 + int idx; 14.1032 + 14.1033 + for (idx = 0; idx < mp_irq_entries; idx++) { 14.1034 + struct mpc_config_intsrc *irq = mp_irqs + idx; 14.1035 + 14.1036 + /* Do we already have a mapping for this ISA IRQ? */ 14.1037 + if (irq->mpc_srcbus == MP_ISA_BUS && irq->mpc_srcbusirq == i) 14.1038 + break; 14.1039 + 14.1040 + /* Do we already have a mapping for this IOAPIC pin */ 14.1041 + if ((irq->mpc_dstapic == intsrc.mpc_dstapic) && 14.1042 + (irq->mpc_dstirq == i)) 14.1043 + break; 14.1044 + } 14.1045 + 14.1046 + if (idx != mp_irq_entries) { 14.1047 + printk(KERN_DEBUG "ACPI: IRQ%d used by override.\n", i); 14.1048 + continue; /* IRQ already used */ 14.1049 + } 14.1050 + 14.1051 + intsrc.mpc_irqtype = mp_INT; 14.1052 + intsrc.mpc_srcbusirq = i; /* Identity mapped */ 14.1053 + intsrc.mpc_dstirq = i; 14.1054 + 14.1055 + Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, " 14.1056 + "%d-%d\n", intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3, 14.1057 + (intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, 14.1058 + intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, 14.1059 + intsrc.mpc_dstirq); 14.1060 + 14.1061 + mp_irqs[mp_irq_entries] = intsrc; 14.1062 + if (++mp_irq_entries == MAX_IRQ_SOURCES) 14.1063 + panic("Max # of irq sources exceeded!\n"); 14.1064 + } 14.1065 +} 14.1066 + 14.1067 +int mp_register_gsi (u32 gsi, int edge_level, int active_high_low) 14.1068 +{ 14.1069 + int ioapic = -1; 14.1070 + int ioapic_pin = 0; 14.1071 + int idx, bit = 0; 14.1072 + 14.1073 +#ifdef CONFIG_ACPI_BUS 14.1074 + /* Don't set up the ACPI SCI because it's already set up */ 14.1075 + if (acpi_fadt.sci_int == gsi) 14.1076 + return gsi; 14.1077 +#endif 14.1078 + 14.1079 + ioapic = mp_find_ioapic(gsi); 14.1080 + if (ioapic < 0) { 14.1081 + printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi); 14.1082 + return gsi; 14.1083 + } 14.1084 + 14.1085 + ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base; 14.1086 + 14.1087 + if (ioapic_renumber_irq) 14.1088 + gsi = ioapic_renumber_irq(ioapic, gsi); 14.1089 + 14.1090 + /* 14.1091 + * Avoid pin reprogramming. PRTs typically include entries 14.1092 + * with redundant pin->gsi mappings (but unique PCI devices); 14.1093 + * we only program the IOAPIC on the first. 14.1094 + */ 14.1095 + bit = ioapic_pin % 32; 14.1096 + idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); 14.1097 + if (idx > 3) { 14.1098 + printk(KERN_ERR "Invalid reference to IOAPIC pin " 14.1099 + "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, 14.1100 + ioapic_pin); 14.1101 + return gsi; 14.1102 + } 14.1103 + if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { 14.1104 + Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", 14.1105 + mp_ioapic_routing[ioapic].apic_id, ioapic_pin); 14.1106 + return gsi; 14.1107 + } 14.1108 + 14.1109 + mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); 14.1110 + 14.1111 + io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, 14.1112 + edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1, 14.1113 + active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1); 14.1114 + return gsi; 14.1115 +} 14.1116 + 14.1117 +#endif /*CONFIG_X86_IO_APIC && (CONFIG_ACPI_INTERPRETER || CONFIG_ACPI_BOOT)*/ 14.1118 +#endif /*CONFIG_ACPI_BOOT*/
15.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c Tue May 03 12:52:47 2005 +0000 15.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c Fri May 06 17:04:27 2005 +0000 15.3 @@ -779,7 +779,7 @@ static void __init parse_cmdline_early ( 15.4 noexec_setup(from + 7); 15.5 15.6 15.7 -#ifdef CONFIG_X86_SMP 15.8 +#ifdef CONFIG_X86_MPPARSE 15.9 /* 15.10 * If the BIOS enumerates physical processors before logical, 15.11 * maxcpus=N at enumeration-time can be used to disable HT. 15.12 @@ -1133,12 +1133,6 @@ static unsigned long __init setup_memory 15.13 */ 15.14 acpi_reserve_bootmem(); 15.15 #endif 15.16 -#ifdef CONFIG_X86_FIND_SMP_CONFIG 15.17 - /* 15.18 - * Find and reserve possible boot-time SMP configuration: 15.19 - */ 15.20 - find_smp_config(); 15.21 -#endif 15.22 15.23 #ifdef CONFIG_BLK_DEV_INITRD 15.24 if (xen_start_info.mod_start) { 15.25 @@ -1503,6 +1497,13 @@ void __init setup_arch(char **cmdline_p) 15.26 #endif 15.27 paging_init(); 15.28 15.29 +#ifdef CONFIG_X86_FIND_SMP_CONFIG 15.30 + /* 15.31 + * Find and reserve possible boot-time SMP configuration: 15.32 + */ 15.33 + find_smp_config(); 15.34 +#endif 15.35 + 15.36 /* Make sure we have a correctly sized P->M table. */ 15.37 if (max_pfn != xen_start_info.nr_pages) { 15.38 phys_to_machine_mapping = alloc_bootmem_low_pages( 15.39 @@ -1566,6 +1567,10 @@ void __init setup_arch(char **cmdline_p) 15.40 if (efi_enabled) 15.41 efi_map_memmap(); 15.42 15.43 + op.cmd = PHYSDEVOP_SET_IOPL; 15.44 + op.u.set_iopl.iopl = current->thread.io_pl = 1; 15.45 + HYPERVISOR_physdev_op(&op); 15.46 + 15.47 /* 15.48 * Parse the ACPI tables for possible boot-time SMP configuration. 15.49 */ 15.50 @@ -1583,10 +1588,6 @@ void __init setup_arch(char **cmdline_p) 15.51 15.52 register_memory(); 15.53 15.54 - op.cmd = PHYSDEVOP_SET_IOPL; 15.55 - op.u.set_iopl.iopl = current->thread.io_pl = 1; 15.56 - HYPERVISOR_physdev_op(&op); 15.57 - 15.58 if (xen_start_info.flags & SIF_INITDOMAIN) { 15.59 if (!(xen_start_info.flags & SIF_PRIVILEGED)) 15.60 panic("Xen granted us console access "
16.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/mm/init.c Tue May 03 12:52:47 2005 +0000 16.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/init.c Fri May 06 17:04:27 2005 +0000 16.3 @@ -562,7 +562,7 @@ void __init paging_init(void) 16.4 zone_sizes_init(); 16.5 16.6 /* Switch to the real shared_info page, and clear the dummy page. */ 16.7 - set_fixmap_ma(FIX_SHARED_INFO, xen_start_info.shared_info); 16.8 + set_fixmap(FIX_SHARED_INFO, xen_start_info.shared_info); 16.9 HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); 16.10 memset(empty_zero_page, 0, sizeof(empty_zero_page)); 16.11 16.12 @@ -570,10 +570,11 @@ void __init paging_init(void) 16.13 /* Setup mapping of lower 1st MB */ 16.14 for (i = 0; i < NR_FIX_ISAMAPS; i++) 16.15 if (xen_start_info.flags & SIF_PRIVILEGED) 16.16 - set_fixmap_ma(FIX_ISAMAP_BEGIN - i, i * PAGE_SIZE); 16.17 + set_fixmap(FIX_ISAMAP_BEGIN - i, i * PAGE_SIZE); 16.18 else 16.19 - set_fixmap_ma_ro(FIX_ISAMAP_BEGIN - i, 16.20 - virt_to_machine(empty_zero_page)); 16.21 + __set_fixmap(FIX_ISAMAP_BEGIN - i, 16.22 + virt_to_machine(empty_zero_page), 16.23 + PAGE_KERNEL_RO); 16.24 #endif 16.25 } 16.26
17.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/mm/ioremap.c Tue May 03 12:52:47 2005 +0000 17.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/ioremap.c Fri May 06 17:04:27 2005 +0000 17.3 @@ -256,7 +256,7 @@ void __init *bt_ioremap(unsigned long ph 17.4 */ 17.5 idx = FIX_BTMAP_BEGIN; 17.6 while (nrpages > 0) { 17.7 - set_fixmap_ma(idx, phys_addr); 17.8 + set_fixmap(idx, phys_addr); 17.9 phys_addr += PAGE_SIZE; 17.10 --idx; 17.11 --nrpages;
18.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c Tue May 03 12:52:47 2005 +0000 18.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c Fri May 06 17:04:27 2005 +0000 18.3 @@ -176,18 +176,18 @@ void __set_fixmap (enum fixed_addresses 18.4 BUG(); 18.5 return; 18.6 } 18.7 - set_pte_pfn(address, phys >> PAGE_SHIFT, flags); 18.8 -} 18.9 - 18.10 -void __set_fixmap_ma (enum fixed_addresses idx, unsigned long phys, pgprot_t flags) 18.11 -{ 18.12 - unsigned long address = __fix_to_virt(idx); 18.13 - 18.14 - if (idx >= __end_of_fixed_addresses) { 18.15 - BUG(); 18.16 - return; 18.17 + switch (idx) { 18.18 + case FIX_WP_TEST: 18.19 + case FIX_VSYSCALL: 18.20 +#ifdef CONFIG_X86_F00F_BUG 18.21 + case FIX_F00F_IDT: 18.22 +#endif 18.23 + set_pte_pfn(address, phys >> PAGE_SHIFT, flags); 18.24 + break; 18.25 + default: 18.26 + set_pte_pfn_ma(address, phys >> PAGE_SHIFT, flags); 18.27 + break; 18.28 } 18.29 - set_pte_pfn_ma(address, phys >> PAGE_SHIFT, flags); 18.30 } 18.31 18.32 pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
19.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/pci/Makefile Tue May 03 12:52:47 2005 +0000 19.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/pci/Makefile Fri May 06 17:04:27 2005 +0000 19.3 @@ -6,12 +6,13 @@ c-obj-y := i386.o 19.4 19.5 c-obj-$(CONFIG_PCI_BIOS) += pcbios.o 19.6 c-obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o 19.7 -obj-$(CONFIG_PCI_DIRECT) += direct.o 19.8 +c-obj-$(CONFIG_PCI_DIRECT) += direct.o 19.9 19.10 c-pci-y := fixup.o 19.11 c-pci-$(CONFIG_ACPI_PCI) += acpi.o 19.12 c-pci-y += legacy.o 19.13 -pci-y += irq.o 19.14 +# Make sure irq.o gets linked in after legacy.o 19.15 +l-pci-y += irq.o 19.16 19.17 c-pci-$(CONFIG_X86_VISWS) := visws.o fixup.o 19.18 pci-$(CONFIG_X86_VISWS) := 19.19 @@ -26,6 +27,6 @@ c-link := 19.20 $(patsubst %.o,$(obj)/%.c,$(c-obj-y) $(c-link)): 19.21 @ln -fsn $(srctree)/arch/i386/pci/$(notdir $@) $@ 19.22 19.23 -obj-y += $(c-obj-y) 19.24 +obj-y += $(c-obj-y) $(l-pci-y) 19.25 19.26 clean-files += $(patsubst %.o,%.c,$(c-obj-y) $(c-obj-) $(c-link))
20.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/pci/direct.c Tue May 03 12:52:47 2005 +0000 20.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 20.3 @@ -1,81 +0,0 @@ 20.4 -/* 20.5 - * direct.c - Low-level direct PCI config space access 20.6 - */ 20.7 - 20.8 -#include <linux/pci.h> 20.9 -#include <linux/init.h> 20.10 -#include "pci.h" 20.11 - 20.12 -#include <asm-xen/xen-public/xen.h> 20.13 -#include <asm-xen/xen-public/physdev.h> 20.14 - 20.15 -/* 20.16 - * Functions for accessing PCI configuration space with type xen accesses 20.17 - */ 20.18 - 20.19 -static int pci_conf_read (int seg, int bus, int devfn, int reg, int len, u32 *value) 20.20 -{ 20.21 - unsigned long flags; 20.22 - physdev_op_t op; 20.23 - int ret; 20.24 - 20.25 - if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) 20.26 - return -EINVAL; 20.27 - 20.28 - spin_lock_irqsave(&pci_config_lock, flags); 20.29 - 20.30 - op.cmd = PHYSDEVOP_PCI_CFGREG_READ; 20.31 - op.u.pci_cfgreg_read.bus = bus; 20.32 - op.u.pci_cfgreg_read.dev = (devfn & ~0x7) >> 3; 20.33 - op.u.pci_cfgreg_read.func = devfn & 0x7; 20.34 - op.u.pci_cfgreg_read.reg = reg; 20.35 - op.u.pci_cfgreg_read.len = len; 20.36 - 20.37 - ret = HYPERVISOR_physdev_op(&op); 20.38 - if (ret == 0) 20.39 - *value = op.u.pci_cfgreg_read.value; 20.40 - 20.41 - spin_unlock_irqrestore(&pci_config_lock, flags); 20.42 - 20.43 - return ret; 20.44 -} 20.45 - 20.46 -static int pci_conf_write (int seg, int bus, int devfn, int reg, int len, u32 value) 20.47 -{ 20.48 - unsigned long flags; 20.49 - physdev_op_t op; 20.50 - int ret; 20.51 - 20.52 - if ((bus > 255) || (devfn > 255) || (reg > 255)) 20.53 - return -EINVAL; 20.54 - 20.55 - spin_lock_irqsave(&pci_config_lock, flags); 20.56 - 20.57 - op.cmd = PHYSDEVOP_PCI_CFGREG_WRITE; 20.58 - op.u.pci_cfgreg_write.bus = bus; 20.59 - op.u.pci_cfgreg_write.dev = (devfn & ~0x7) >> 3; 20.60 - op.u.pci_cfgreg_write.func = devfn & 0x7; 20.61 - op.u.pci_cfgreg_write.reg = reg; 20.62 - op.u.pci_cfgreg_write.len = len; 20.63 - op.u.pci_cfgreg_write.value = value; 20.64 - 20.65 - ret = HYPERVISOR_physdev_op(&op); 20.66 - 20.67 - spin_unlock_irqrestore(&pci_config_lock, flags); 20.68 - 20.69 - return ret; 20.70 -} 20.71 - 20.72 -struct pci_raw_ops pci_direct_xen = { 20.73 - .read = pci_conf_read, 20.74 - .write = pci_conf_write, 20.75 -}; 20.76 - 20.77 -static int __init pci_direct_init(void) 20.78 -{ 20.79 - printk(KERN_INFO "PCI: Using configuration type Xen\n"); 20.80 - raw_pci_ops = &pci_direct_xen; 20.81 - return 0; 20.82 -} 20.83 - 20.84 -arch_initcall(pci_direct_init);
21.1 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/pci/irq.c Tue May 03 12:52:47 2005 +0000 21.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/pci/irq.c Fri May 06 17:04:27 2005 +0000 21.3 @@ -12,6 +12,7 @@ 21.4 #include <linux/slab.h> 21.5 #include <linux/interrupt.h> 21.6 #include <linux/irq.h> 21.7 +#include <linux/dmi.h> 21.8 #include <asm/io.h> 21.9 #include <asm/smp.h> 21.10 #include <asm/io_apic.h> 21.11 @@ -20,8 +21,15 @@ 21.12 21.13 #include "pci.h" 21.14 21.15 -#include <asm-xen/xen-public/xen.h> 21.16 -#include <asm-xen/xen-public/physdev.h> 21.17 +#define DBG printk 21.18 + 21.19 +#define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24)) 21.20 +#define PIRQ_VERSION 0x0100 21.21 + 21.22 +static int broken_hp_bios_irq9; 21.23 +static int acer_tm360_irqrouting; 21.24 + 21.25 +static struct irq_routing_table *pirq_table; 21.26 21.27 static int pirq_enable_irq(struct pci_dev *dev); 21.28 21.29 @@ -37,33 +45,963 @@ static int pirq_penalty[16] = { 21.30 0, 0, 0, 0, 1000, 100000, 100000, 100000 21.31 }; 21.32 21.33 +struct irq_router { 21.34 + char *name; 21.35 + u16 vendor, device; 21.36 + int (*get)(struct pci_dev *router, struct pci_dev *dev, int pirq); 21.37 + int (*set)(struct pci_dev *router, struct pci_dev *dev, int pirq, int new); 21.38 +}; 21.39 + 21.40 +struct irq_router_handler { 21.41 + u16 vendor; 21.42 + int (*probe)(struct irq_router *r, struct pci_dev *router, u16 device); 21.43 +}; 21.44 + 21.45 int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; 21.46 21.47 +/* 21.48 + * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. 21.49 + */ 21.50 + 21.51 +static struct irq_routing_table * __init pirq_find_routing_table(void) 21.52 +{ 21.53 + u8 *addr; 21.54 + struct irq_routing_table *rt; 21.55 + int i; 21.56 + u8 sum; 21.57 + 21.58 +#ifdef CONFIG_XEN_PRIVILEGED_GUEST 21.59 + for(addr = (u8 *) isa_bus_to_virt(0xf0000); addr < (u8 *) isa_bus_to_virt(0x100000); addr += 16) { 21.60 + rt = (struct irq_routing_table *) addr; 21.61 + if (rt->signature != PIRQ_SIGNATURE || 21.62 + rt->version != PIRQ_VERSION || 21.63 + rt->size % 16 || 21.64 + rt->size < sizeof(struct irq_routing_table)) 21.65 + continue; 21.66 + sum = 0; 21.67 + for(i=0; i<rt->size; i++) 21.68 + sum += addr[i]; 21.69 + if (!sum) { 21.70 + DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); 21.71 + return rt; 21.72 + } 21.73 + } 21.74 +#endif 21.75 + 21.76 + return NULL; 21.77 +} 21.78 + 21.79 +/* 21.80 + * If we have a IRQ routing table, use it to search for peer host 21.81 + * bridges. It's a gross hack, but since there are no other known 21.82 + * ways how to get a list of buses, we have to go this way. 21.83 + */ 21.84 + 21.85 +static void __init pirq_peer_trick(void) 21.86 +{ 21.87 + struct irq_routing_table *rt = pirq_table; 21.88 + u8 busmap[256]; 21.89 + int i; 21.90 + struct irq_info *e; 21.91 + 21.92 + memset(busmap, 0, sizeof(busmap)); 21.93 + for(i=0; i < (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); i++) { 21.94 + e = &rt->slots[i]; 21.95 +#ifdef DEBUG 21.96 + { 21.97 + int j; 21.98 + DBG("%02x:%02x slot=%02x", e->bus, e->devfn/8, e->slot); 21.99 + for(j=0; j<4; j++) 21.100 + DBG(" %d:%02x/%04x", j, e->irq[j].link, e->irq[j].bitmap); 21.101 + DBG("\n"); 21.102 + } 21.103 +#endif 21.104 + busmap[e->bus] = 1; 21.105 + } 21.106 + for(i = 1; i < 256; i++) { 21.107 + if (!busmap[i] || pci_find_bus(0, i)) 21.108 + continue; 21.109 + if (pci_scan_bus(i, &pci_root_ops, NULL)) 21.110 + printk(KERN_INFO "PCI: Discovered primary peer bus %02x [IRQ]\n", i); 21.111 + } 21.112 + pcibios_last_bus = -1; 21.113 +} 21.114 + 21.115 +/* 21.116 + * Code for querying and setting of IRQ routes on various interrupt routers. 21.117 + */ 21.118 + 21.119 +void eisa_set_level_irq(unsigned int irq) 21.120 +{ 21.121 + unsigned char mask = 1 << (irq & 7); 21.122 + unsigned int port = 0x4d0 + (irq >> 3); 21.123 + unsigned char val; 21.124 + static u16 eisa_irq_mask; 21.125 + 21.126 + if (irq >= 16 || (1 << irq) & eisa_irq_mask) 21.127 + return; 21.128 + 21.129 + eisa_irq_mask |= (1 << irq); 21.130 + printk("PCI: setting IRQ %u as level-triggered\n", irq); 21.131 + val = inb(port); 21.132 + if (!(val & mask)) { 21.133 + DBG(" -> edge"); 21.134 + outb(val | mask, port); 21.135 + } 21.136 +} 21.137 + 21.138 +/* 21.139 + * Common IRQ routing practice: nybbles in config space, 21.140 + * offset by some magic constant. 21.141 + */ 21.142 +static unsigned int read_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr) 21.143 +{ 21.144 + u8 x; 21.145 + unsigned reg = offset + (nr >> 1); 21.146 + 21.147 + pci_read_config_byte(router, reg, &x); 21.148 + return (nr & 1) ? (x >> 4) : (x & 0xf); 21.149 +} 21.150 + 21.151 +static void write_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr, unsigned int val) 21.152 +{ 21.153 + u8 x; 21.154 + unsigned reg = offset + (nr >> 1); 21.155 + 21.156 + pci_read_config_byte(router, reg, &x); 21.157 + x = (nr & 1) ? ((x & 0x0f) | (val << 4)) : ((x & 0xf0) | val); 21.158 + pci_write_config_byte(router, reg, x); 21.159 +} 21.160 + 21.161 +/* 21.162 + * ALI pirq entries are damn ugly, and completely undocumented. 21.163 + * This has been figured out from pirq tables, and it's not a pretty 21.164 + * picture. 21.165 + */ 21.166 +static int pirq_ali_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 21.167 +{ 21.168 + static unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 }; 21.169 + 21.170 + return irqmap[read_config_nybble(router, 0x48, pirq-1)]; 21.171 +} 21.172 + 21.173 +static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 21.174 +{ 21.175 + static unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 }; 21.176 + unsigned int val = irqmap[irq]; 21.177 + 21.178 + if (val) { 21.179 + write_config_nybble(router, 0x48, pirq-1, val); 21.180 + return 1; 21.181 + } 21.182 + return 0; 21.183 +} 21.184 + 21.185 +/* 21.186 + * The Intel PIIX4 pirq rules are fairly simple: "pirq" is 21.187 + * just a pointer to the config space. 21.188 + */ 21.189 +static int pirq_piix_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 21.190 +{ 21.191 + u8 x; 21.192 + 21.193 + pci_read_config_byte(router, pirq, &x); 21.194 + return (x < 16) ? x : 0; 21.195 +} 21.196 + 21.197 +static int pirq_piix_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 21.198 +{ 21.199 + pci_write_config_byte(router, pirq, irq); 21.200 + return 1; 21.201 +} 21.202 + 21.203 +/* 21.204 + * The VIA pirq rules are nibble-based, like ALI, 21.205 + * but without the ugly irq number munging. 21.206 + * However, PIRQD is in the upper instead of lower 4 bits. 21.207 + */ 21.208 +static int pirq_via_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 21.209 +{ 21.210 + return read_config_nybble(router, 0x55, pirq == 4 ? 5 : pirq); 21.211 +} 21.212 + 21.213 +static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 21.214 +{ 21.215 + write_config_nybble(router, 0x55, pirq == 4 ? 5 : pirq, irq); 21.216 + return 1; 21.217 +} 21.218 + 21.219 +/* 21.220 + * ITE 8330G pirq rules are nibble-based 21.221 + * FIXME: pirqmap may be { 1, 0, 3, 2 }, 21.222 + * 2+3 are both mapped to irq 9 on my system 21.223 + */ 21.224 +static int pirq_ite_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 21.225 +{ 21.226 + static unsigned char pirqmap[4] = { 1, 0, 2, 3 }; 21.227 + return read_config_nybble(router,0x43, pirqmap[pirq-1]); 21.228 +} 21.229 + 21.230 +static int pirq_ite_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 21.231 +{ 21.232 + static unsigned char pirqmap[4] = { 1, 0, 2, 3 }; 21.233 + write_config_nybble(router, 0x43, pirqmap[pirq-1], irq); 21.234 + return 1; 21.235 +} 21.236 + 21.237 +/* 21.238 + * OPTI: high four bits are nibble pointer.. 21.239 + * I wonder what the low bits do? 21.240 + */ 21.241 +static int pirq_opti_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 21.242 +{ 21.243 + return read_config_nybble(router, 0xb8, pirq >> 4); 21.244 +} 21.245 + 21.246 +static int pirq_opti_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 21.247 +{ 21.248 + write_config_nybble(router, 0xb8, pirq >> 4, irq); 21.249 + return 1; 21.250 +} 21.251 + 21.252 +/* 21.253 + * Cyrix: nibble offset 0x5C 21.254 + * 0x5C bits 7:4 is INTB bits 3:0 is INTA 21.255 + * 0x5D bits 7:4 is INTD bits 3:0 is INTC 21.256 + */ 21.257 +static int pirq_cyrix_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 21.258 +{ 21.259 + return read_config_nybble(router, 0x5C, (pirq-1)^1); 21.260 +} 21.261 + 21.262 +static int pirq_cyrix_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 21.263 +{ 21.264 + write_config_nybble(router, 0x5C, (pirq-1)^1, irq); 21.265 + return 1; 21.266 +} 21.267 + 21.268 +/* 21.269 + * PIRQ routing for SiS 85C503 router used in several SiS chipsets. 21.270 + * We have to deal with the following issues here: 21.271 + * - vendors have different ideas about the meaning of link values 21.272 + * - some onboard devices (integrated in the chipset) have special 21.273 + * links and are thus routed differently (i.e. not via PCI INTA-INTD) 21.274 + * - different revision of the router have a different layout for 21.275 + * the routing registers, particularly for the onchip devices 21.276 + * 21.277 + * For all routing registers the common thing is we have one byte 21.278 + * per routeable link which is defined as: 21.279 + * bit 7 IRQ mapping enabled (0) or disabled (1) 21.280 + * bits [6:4] reserved (sometimes used for onchip devices) 21.281 + * bits [3:0] IRQ to map to 21.282 + * allowed: 3-7, 9-12, 14-15 21.283 + * reserved: 0, 1, 2, 8, 13 21.284 + * 21.285 + * The config-space registers located at 0x41/0x42/0x43/0x44 are 21.286 + * always used to route the normal PCI INT A/B/C/D respectively. 21.287 + * Apparently there are systems implementing PCI routing table using 21.288 + * link values 0x01-0x04 and others using 0x41-0x44 for PCI INTA..D. 21.289 + * We try our best to handle both link mappings. 21.290 + * 21.291 + * Currently (2003-05-21) it appears most SiS chipsets follow the 21.292 + * definition of routing registers from the SiS-5595 southbridge. 21.293 + * According to the SiS 5595 datasheets the revision id's of the 21.294 + * router (ISA-bridge) should be 0x01 or 0xb0. 21.295 + * 21.296 + * Furthermore we've also seen lspci dumps with revision 0x00 and 0xb1. 21.297 + * Looks like these are used in a number of SiS 5xx/6xx/7xx chipsets. 21.298 + * They seem to work with the current routing code. However there is 21.299 + * some concern because of the two USB-OHCI HCs (original SiS 5595 21.300 + * had only one). YMMV. 21.301 + * 21.302 + * Onchip routing for router rev-id 0x01/0xb0 and probably 0x00/0xb1: 21.303 + * 21.304 + * 0x61: IDEIRQ: 21.305 + * bits [6:5] must be written 01 21.306 + * bit 4 channel-select primary (0), secondary (1) 21.307 + * 21.308 + * 0x62: USBIRQ: 21.309 + * bit 6 OHCI function disabled (0), enabled (1) 21.310 + * 21.311 + * 0x6a: ACPI/SCI IRQ: bits 4-6 reserved 21.312 + * 21.313 + * 0x7e: Data Acq. Module IRQ - bits 4-6 reserved 21.314 + * 21.315 + * We support USBIRQ (in addition to INTA-INTD) and keep the 21.316 + * IDE, ACPI and DAQ routing untouched as set by the BIOS. 21.317 + * 21.318 + * Currently the only reported exception is the new SiS 65x chipset 21.319 + * which includes the SiS 69x southbridge. Here we have the 85C503 21.320 + * router revision 0x04 and there are changes in the register layout 21.321 + * mostly related to the different USB HCs with USB 2.0 support. 21.322 + * 21.323 + * Onchip routing for router rev-id 0x04 (try-and-error observation) 21.324 + * 21.325 + * 0x60/0x61/0x62/0x63: 1xEHCI and 3xOHCI (companion) USB-HCs 21.326 + * bit 6-4 are probably unused, not like 5595 21.327 + */ 21.328 + 21.329 +#define PIRQ_SIS_IRQ_MASK 0x0f 21.330 +#define PIRQ_SIS_IRQ_DISABLE 0x80 21.331 +#define PIRQ_SIS_USB_ENABLE 0x40 21.332 + 21.333 +static int pirq_sis_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 21.334 +{ 21.335 + u8 x; 21.336 + int reg; 21.337 + 21.338 + reg = pirq; 21.339 + if (reg >= 0x01 && reg <= 0x04) 21.340 + reg += 0x40; 21.341 + pci_read_config_byte(router, reg, &x); 21.342 + return (x & PIRQ_SIS_IRQ_DISABLE) ? 0 : (x & PIRQ_SIS_IRQ_MASK); 21.343 +} 21.344 + 21.345 +static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 21.346 +{ 21.347 + u8 x; 21.348 + int reg; 21.349 + 21.350 + reg = pirq; 21.351 + if (reg >= 0x01 && reg <= 0x04) 21.352 + reg += 0x40; 21.353 + pci_read_config_byte(router, reg, &x); 21.354 + x &= ~(PIRQ_SIS_IRQ_MASK | PIRQ_SIS_IRQ_DISABLE); 21.355 + x |= irq ? irq: PIRQ_SIS_IRQ_DISABLE; 21.356 + pci_write_config_byte(router, reg, x); 21.357 + return 1; 21.358 +} 21.359 + 21.360 + 21.361 +/* 21.362 + * VLSI: nibble offset 0x74 - educated guess due to routing table and 21.363 + * config space of VLSI 82C534 PCI-bridge/router (1004:0102) 21.364 + * Tested on HP OmniBook 800 covering PIRQ 1, 2, 4, 8 for onboard 21.365 + * devices, PIRQ 3 for non-pci(!) soundchip and (untested) PIRQ 6 21.366 + * for the busbridge to the docking station. 21.367 + */ 21.368 + 21.369 +static int pirq_vlsi_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 21.370 +{ 21.371 + if (pirq > 8) { 21.372 + printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq); 21.373 + return 0; 21.374 + } 21.375 + return read_config_nybble(router, 0x74, pirq-1); 21.376 +} 21.377 + 21.378 +static int pirq_vlsi_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 21.379 +{ 21.380 + if (pirq > 8) { 21.381 + printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq); 21.382 + return 0; 21.383 + } 21.384 + write_config_nybble(router, 0x74, pirq-1, irq); 21.385 + return 1; 21.386 +} 21.387 + 21.388 +/* 21.389 + * ServerWorks: PCI interrupts mapped to system IRQ lines through Index 21.390 + * and Redirect I/O registers (0x0c00 and 0x0c01). The Index register 21.391 + * format is (PCIIRQ## | 0x10), e.g.: PCIIRQ10=0x1a. The Redirect 21.392 + * register is a straight binary coding of desired PIC IRQ (low nibble). 21.393 + * 21.394 + * The 'link' value in the PIRQ table is already in the correct format 21.395 + * for the Index register. There are some special index values: 21.396 + * 0x00 for ACPI (SCI), 0x01 for USB, 0x02 for IDE0, 0x04 for IDE1, 21.397 + * and 0x03 for SMBus. 21.398 + */ 21.399 +static int pirq_serverworks_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 21.400 +{ 21.401 + outb_p(pirq, 0xc00); 21.402 + return inb(0xc01) & 0xf; 21.403 +} 21.404 + 21.405 +static int pirq_serverworks_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 21.406 +{ 21.407 + outb_p(pirq, 0xc00); 21.408 + outb_p(irq, 0xc01); 21.409 + return 1; 21.410 +} 21.411 + 21.412 +/* Support for AMD756 PCI IRQ Routing 21.413 + * Jhon H. Caicedo <jhcaiced@osso.org.co> 21.414 + * Jun/21/2001 0.2.0 Release, fixed to use "nybble" functions... (jhcaiced) 21.415 + * Jun/19/2001 Alpha Release 0.1.0 (jhcaiced) 21.416 + * The AMD756 pirq rules are nibble-based 21.417 + * offset 0x56 0-3 PIRQA 4-7 PIRQB 21.418 + * offset 0x57 0-3 PIRQC 4-7 PIRQD 21.419 + */ 21.420 +static int pirq_amd756_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 21.421 +{ 21.422 + u8 irq; 21.423 + irq = 0; 21.424 + if (pirq <= 4) 21.425 + { 21.426 + irq = read_config_nybble(router, 0x56, pirq - 1); 21.427 + } 21.428 + printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d get irq : %2d\n", 21.429 + dev->vendor, dev->device, pirq, irq); 21.430 + return irq; 21.431 +} 21.432 + 21.433 +static int pirq_amd756_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 21.434 +{ 21.435 + printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d SET irq : %2d\n", 21.436 + dev->vendor, dev->device, pirq, irq); 21.437 + if (pirq <= 4) 21.438 + { 21.439 + write_config_nybble(router, 0x56, pirq - 1, irq); 21.440 + } 21.441 + return 1; 21.442 +} 21.443 + 21.444 +#ifdef CONFIG_PCI_BIOS 21.445 + 21.446 +static int pirq_bios_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 21.447 +{ 21.448 + struct pci_dev *bridge; 21.449 + int pin = pci_get_interrupt_pin(dev, &bridge); 21.450 + return pcibios_set_irq_routing(bridge, pin, irq); 21.451 +} 21.452 + 21.453 +#endif 21.454 + 21.455 +static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 21.456 +{ 21.457 + static struct pci_device_id pirq_440gx[] = { 21.458 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) }, 21.459 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) }, 21.460 + { }, 21.461 + }; 21.462 + 21.463 + /* 440GX has a proprietary PIRQ router -- don't use it */ 21.464 + if (pci_dev_present(pirq_440gx)) 21.465 + return 0; 21.466 + 21.467 + switch(device) 21.468 + { 21.469 + case PCI_DEVICE_ID_INTEL_82371FB_0: 21.470 + case PCI_DEVICE_ID_INTEL_82371SB_0: 21.471 + case PCI_DEVICE_ID_INTEL_82371AB_0: 21.472 + case PCI_DEVICE_ID_INTEL_82371MX: 21.473 + case PCI_DEVICE_ID_INTEL_82443MX_0: 21.474 + case PCI_DEVICE_ID_INTEL_82801AA_0: 21.475 + case PCI_DEVICE_ID_INTEL_82801AB_0: 21.476 + case PCI_DEVICE_ID_INTEL_82801BA_0: 21.477 + case PCI_DEVICE_ID_INTEL_82801BA_10: 21.478 + case PCI_DEVICE_ID_INTEL_82801CA_0: 21.479 + case PCI_DEVICE_ID_INTEL_82801CA_12: 21.480 + case PCI_DEVICE_ID_INTEL_82801DB_0: 21.481 + case PCI_DEVICE_ID_INTEL_82801E_0: 21.482 + case PCI_DEVICE_ID_INTEL_82801EB_0: 21.483 + case PCI_DEVICE_ID_INTEL_ESB_1: 21.484 + case PCI_DEVICE_ID_INTEL_ICH6_0: 21.485 + case PCI_DEVICE_ID_INTEL_ICH6_1: 21.486 + case PCI_DEVICE_ID_INTEL_ICH7_0: 21.487 + case PCI_DEVICE_ID_INTEL_ICH7_1: 21.488 + r->name = "PIIX/ICH"; 21.489 + r->get = pirq_piix_get; 21.490 + r->set = pirq_piix_set; 21.491 + return 1; 21.492 + } 21.493 + return 0; 21.494 +} 21.495 + 21.496 +static __init int via_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 21.497 +{ 21.498 + /* FIXME: We should move some of the quirk fixup stuff here */ 21.499 + switch(device) 21.500 + { 21.501 + case PCI_DEVICE_ID_VIA_82C586_0: 21.502 + case PCI_DEVICE_ID_VIA_82C596: 21.503 + case PCI_DEVICE_ID_VIA_82C686: 21.504 + case PCI_DEVICE_ID_VIA_8231: 21.505 + /* FIXME: add new ones for 8233/5 */ 21.506 + r->name = "VIA"; 21.507 + r->get = pirq_via_get; 21.508 + r->set = pirq_via_set; 21.509 + return 1; 21.510 + } 21.511 + return 0; 21.512 +} 21.513 + 21.514 +static __init int vlsi_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 21.515 +{ 21.516 + switch(device) 21.517 + { 21.518 + case PCI_DEVICE_ID_VLSI_82C534: 21.519 + r->name = "VLSI 82C534"; 21.520 + r->get = pirq_vlsi_get; 21.521 + r->set = pirq_vlsi_set; 21.522 + return 1; 21.523 + } 21.524 + return 0; 21.525 +} 21.526 + 21.527 + 21.528 +static __init int serverworks_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 21.529 +{ 21.530 + switch(device) 21.531 + { 21.532 + case PCI_DEVICE_ID_SERVERWORKS_OSB4: 21.533 + case PCI_DEVICE_ID_SERVERWORKS_CSB5: 21.534 + r->name = "ServerWorks"; 21.535 + r->get = pirq_serverworks_get; 21.536 + r->set = pirq_serverworks_set; 21.537 + return 1; 21.538 + } 21.539 + return 0; 21.540 +} 21.541 + 21.542 +static __init int sis_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 21.543 +{ 21.544 + if (device != PCI_DEVICE_ID_SI_503) 21.545 + return 0; 21.546 + 21.547 + r->name = "SIS"; 21.548 + r->get = pirq_sis_get; 21.549 + r->set = pirq_sis_set; 21.550 + return 1; 21.551 +} 21.552 + 21.553 +static __init int cyrix_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 21.554 +{ 21.555 + switch(device) 21.556 + { 21.557 + case PCI_DEVICE_ID_CYRIX_5520: 21.558 + r->name = "NatSemi"; 21.559 + r->get = pirq_cyrix_get; 21.560 + r->set = pirq_cyrix_set; 21.561 + return 1; 21.562 + } 21.563 + return 0; 21.564 +} 21.565 + 21.566 +static __init int opti_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 21.567 +{ 21.568 + switch(device) 21.569 + { 21.570 + case PCI_DEVICE_ID_OPTI_82C700: 21.571 + r->name = "OPTI"; 21.572 + r->get = pirq_opti_get; 21.573 + r->set = pirq_opti_set; 21.574 + return 1; 21.575 + } 21.576 + return 0; 21.577 +} 21.578 + 21.579 +static __init int ite_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 21.580 +{ 21.581 + switch(device) 21.582 + { 21.583 + case PCI_DEVICE_ID_ITE_IT8330G_0: 21.584 + r->name = "ITE"; 21.585 + r->get = pirq_ite_get; 21.586 + r->set = pirq_ite_set; 21.587 + return 1; 21.588 + } 21.589 + return 0; 21.590 +} 21.591 + 21.592 +static __init int ali_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 21.593 +{ 21.594 + switch(device) 21.595 + { 21.596 + case PCI_DEVICE_ID_AL_M1533: 21.597 + case PCI_DEVICE_ID_AL_M1563: 21.598 + printk("PCI: Using ALI IRQ Router\n"); 21.599 + r->name = "ALI"; 21.600 + r->get = pirq_ali_get; 21.601 + r->set = pirq_ali_set; 21.602 + return 1; 21.603 + } 21.604 + return 0; 21.605 +} 21.606 + 21.607 +static __init int amd_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 21.608 +{ 21.609 + switch(device) 21.610 + { 21.611 + case PCI_DEVICE_ID_AMD_VIPER_740B: 21.612 + r->name = "AMD756"; 21.613 + break; 21.614 + case PCI_DEVICE_ID_AMD_VIPER_7413: 21.615 + r->name = "AMD766"; 21.616 + break; 21.617 + case PCI_DEVICE_ID_AMD_VIPER_7443: 21.618 + r->name = "AMD768"; 21.619 + break; 21.620 + default: 21.621 + return 0; 21.622 + } 21.623 + r->get = pirq_amd756_get; 21.624 + r->set = pirq_amd756_set; 21.625 + return 1; 21.626 +} 21.627 + 21.628 +static __initdata struct irq_router_handler pirq_routers[] = { 21.629 + { PCI_VENDOR_ID_INTEL, intel_router_probe }, 21.630 + { PCI_VENDOR_ID_AL, ali_router_probe }, 21.631 + { PCI_VENDOR_ID_ITE, ite_router_probe }, 21.632 + { PCI_VENDOR_ID_VIA, via_router_probe }, 21.633 + { PCI_VENDOR_ID_OPTI, opti_router_probe }, 21.634 + { PCI_VENDOR_ID_SI, sis_router_probe }, 21.635 + { PCI_VENDOR_ID_CYRIX, cyrix_router_probe }, 21.636 + { PCI_VENDOR_ID_VLSI, vlsi_router_probe }, 21.637 + { PCI_VENDOR_ID_SERVERWORKS, serverworks_router_probe }, 21.638 + { PCI_VENDOR_ID_AMD, amd_router_probe }, 21.639 + /* Someone with docs needs to add the ATI Radeon IGP */ 21.640 + { 0, NULL } 21.641 +}; 21.642 +static struct irq_router pirq_router; 21.643 +static struct pci_dev *pirq_router_dev; 21.644 + 21.645 + 21.646 +/* 21.647 + * FIXME: should we have an option to say "generic for 21.648 + * chipset" ? 21.649 + */ 21.650 + 21.651 +static void __init pirq_find_router(struct irq_router *r) 21.652 +{ 21.653 + struct irq_routing_table *rt = pirq_table; 21.654 + struct irq_router_handler *h; 21.655 + 21.656 +#ifdef CONFIG_PCI_BIOS 21.657 + if (!rt->signature) { 21.658 + printk(KERN_INFO "PCI: Using BIOS for IRQ routing\n"); 21.659 + r->set = pirq_bios_set; 21.660 + r->name = "BIOS"; 21.661 + return; 21.662 + } 21.663 +#endif 21.664 + 21.665 + /* Default unless a driver reloads it */ 21.666 + r->name = "default"; 21.667 + r->get = NULL; 21.668 + r->set = NULL; 21.669 + 21.670 + DBG("PCI: Attempting to find IRQ router for %04x:%04x\n", 21.671 + rt->rtr_vendor, rt->rtr_device); 21.672 + 21.673 + pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn); 21.674 + if (!pirq_router_dev) { 21.675 + DBG("PCI: Interrupt router not found at %02x:%02x\n", rt->rtr_bus, rt->rtr_devfn); 21.676 + return; 21.677 + } 21.678 + 21.679 + for( h = pirq_routers; h->vendor; h++) { 21.680 + /* First look for a router match */ 21.681 + if (rt->rtr_vendor == h->vendor && h->probe(r, pirq_router_dev, rt->rtr_device)) 21.682 + break; 21.683 + /* Fall back to a device match */ 21.684 + if (pirq_router_dev->vendor == h->vendor && h->probe(r, pirq_router_dev, pirq_router_dev->device)) 21.685 + break; 21.686 + } 21.687 + printk(KERN_INFO "PCI: Using IRQ router %s [%04x/%04x] at %s\n", 21.688 + pirq_router.name, 21.689 + pirq_router_dev->vendor, 21.690 + pirq_router_dev->device, 21.691 + pci_name(pirq_router_dev)); 21.692 +} 21.693 + 21.694 +static struct irq_info *pirq_get_info(struct pci_dev *dev) 21.695 +{ 21.696 + struct irq_routing_table *rt = pirq_table; 21.697 + int entries = (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); 21.698 + struct irq_info *info; 21.699 + 21.700 + for (info = rt->slots; entries--; info++) 21.701 + if (info->bus == dev->bus->number && PCI_SLOT(info->devfn) == PCI_SLOT(dev->devfn)) 21.702 + return info; 21.703 + return NULL; 21.704 +} 21.705 + 21.706 +static int pcibios_lookup_irq(struct pci_dev *dev, int assign) 21.707 +{ 21.708 + u8 pin; 21.709 + struct irq_info *info; 21.710 + int i, pirq, newirq; 21.711 + int irq = 0; 21.712 + u32 mask; 21.713 + struct irq_router *r = &pirq_router; 21.714 + struct pci_dev *dev2 = NULL; 21.715 + char *msg = NULL; 21.716 + 21.717 + /* Find IRQ pin */ 21.718 + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); 21.719 + if (!pin) { 21.720 + DBG(" -> no interrupt pin\n"); 21.721 + return 0; 21.722 + } 21.723 + pin = pin - 1; 21.724 + 21.725 + /* Find IRQ routing entry */ 21.726 + 21.727 + if (!pirq_table) 21.728 + return 0; 21.729 + 21.730 + DBG("IRQ for %s[%c]", pci_name(dev), 'A' + pin); 21.731 + info = pirq_get_info(dev); 21.732 + if (!info) { 21.733 + DBG(" -> not found in routing table\n"); 21.734 + return 0; 21.735 + } 21.736 + pirq = info->irq[pin].link; 21.737 + mask = info->irq[pin].bitmap; 21.738 + if (!pirq) { 21.739 + DBG(" -> not routed\n"); 21.740 + return 0; 21.741 + } 21.742 + DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, pirq_table->exclusive_irqs); 21.743 + mask &= pcibios_irq_mask; 21.744 + 21.745 + /* Work around broken HP Pavilion Notebooks which assign USB to 21.746 + IRQ 9 even though it is actually wired to IRQ 11 */ 21.747 + 21.748 + if (broken_hp_bios_irq9 && pirq == 0x59 && dev->irq == 9) { 21.749 + dev->irq = 11; 21.750 + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); 21.751 + r->set(pirq_router_dev, dev, pirq, 11); 21.752 + } 21.753 + 21.754 + /* same for Acer Travelmate 360, but with CB and irq 11 -> 10 */ 21.755 + if (acer_tm360_irqrouting && dev->irq == 11 && dev->vendor == PCI_VENDOR_ID_O2) { 21.756 + pirq = 0x68; 21.757 + mask = 0x400; 21.758 + dev->irq = r->get(pirq_router_dev, dev, pirq); 21.759 + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); 21.760 + } 21.761 + 21.762 + /* 21.763 + * Find the best IRQ to assign: use the one 21.764 + * reported by the device if possible. 21.765 + */ 21.766 + newirq = dev->irq; 21.767 + if (!((1 << newirq) & mask)) { 21.768 + if ( pci_probe & PCI_USE_PIRQ_MASK) newirq = 0; 21.769 + else printk(KERN_WARNING "PCI: IRQ %i for device %s doesn't match PIRQ mask - try pci=usepirqmask\n", newirq, pci_name(dev)); 21.770 + } 21.771 + if (!newirq && assign) { 21.772 + for (i = 0; i < 16; i++) { 21.773 + if (!(mask & (1 << i))) 21.774 + continue; 21.775 + if (pirq_penalty[i] < pirq_penalty[newirq] && can_request_irq(i, SA_SHIRQ)) 21.776 + newirq = i; 21.777 + } 21.778 + } 21.779 + DBG(" -> newirq=%d", newirq); 21.780 + 21.781 + /* Check if it is hardcoded */ 21.782 + if ((pirq & 0xf0) == 0xf0) { 21.783 + irq = pirq & 0xf; 21.784 + DBG(" -> hardcoded IRQ %d\n", irq); 21.785 + msg = "Hardcoded"; 21.786 + } else if ( r->get && (irq = r->get(pirq_router_dev, dev, pirq)) && \ 21.787 + ((!(pci_probe & PCI_USE_PIRQ_MASK)) || ((1 << irq) & mask)) ) { 21.788 + DBG(" -> got IRQ %d\n", irq); 21.789 + msg = "Found"; 21.790 + } else if (newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) { 21.791 + DBG(" -> assigning IRQ %d", newirq); 21.792 + if (r->set(pirq_router_dev, dev, pirq, newirq)) { 21.793 + eisa_set_level_irq(newirq); 21.794 + DBG(" ... OK\n"); 21.795 + msg = "Assigned"; 21.796 + irq = newirq; 21.797 + } 21.798 + } 21.799 + 21.800 + if (!irq) { 21.801 + DBG(" ... failed\n"); 21.802 + if (newirq && mask == (1 << newirq)) { 21.803 + msg = "Guessed"; 21.804 + irq = newirq; 21.805 + } else 21.806 + return 0; 21.807 + } 21.808 + printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, pci_name(dev)); 21.809 + 21.810 + /* Update IRQ for all devices with the same pirq value */ 21.811 + while ((dev2 = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) { 21.812 + pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin); 21.813 + if (!pin) 21.814 + continue; 21.815 + pin--; 21.816 + info = pirq_get_info(dev2); 21.817 + if (!info) 21.818 + continue; 21.819 + if (info->irq[pin].link == pirq) { 21.820 + /* We refuse to override the dev->irq information. Give a warning! */ 21.821 + if ( dev2->irq && dev2->irq != irq && \ 21.822 + (!(pci_probe & PCI_USE_PIRQ_MASK) || \ 21.823 + ((1 << dev2->irq) & mask)) ) { 21.824 +#ifndef CONFIG_PCI_MSI 21.825 + printk(KERN_INFO "IRQ routing conflict for %s, have irq %d, want irq %d\n", 21.826 + pci_name(dev2), dev2->irq, irq); 21.827 +#endif 21.828 + continue; 21.829 + } 21.830 + dev2->irq = irq; 21.831 + pirq_penalty[irq]++; 21.832 + if (dev != dev2) 21.833 + printk(KERN_INFO "PCI: Sharing IRQ %d with %s\n", irq, pci_name(dev2)); 21.834 + } 21.835 + } 21.836 + return 1; 21.837 +} 21.838 + 21.839 +static void __init pcibios_fixup_irqs(void) 21.840 +{ 21.841 + struct pci_dev *dev = NULL; 21.842 + u8 pin; 21.843 + 21.844 + DBG("PCI: IRQ fixup\n"); 21.845 + while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { 21.846 + /* 21.847 + * If the BIOS has set an out of range IRQ number, just ignore it. 21.848 + * Also keep track of which IRQ's are already in use. 21.849 + */ 21.850 + if (dev->irq >= 16) { 21.851 + DBG("%s: ignoring bogus IRQ %d\n", pci_name(dev), dev->irq); 21.852 + dev->irq = 0; 21.853 + } 21.854 + /* If the IRQ is already assigned to a PCI device, ignore its ISA use penalty */ 21.855 + if (pirq_penalty[dev->irq] >= 100 && pirq_penalty[dev->irq] < 100000) 21.856 + pirq_penalty[dev->irq] = 0; 21.857 + pirq_penalty[dev->irq]++; 21.858 + } 21.859 + 21.860 + dev = NULL; 21.861 + while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { 21.862 + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); 21.863 +#ifdef CONFIG_X86_IO_APIC 21.864 + /* 21.865 + * Recalculate IRQ numbers if we use the I/O APIC. 21.866 + */ 21.867 + if (io_apic_assign_pci_irqs) 21.868 + { 21.869 + int irq; 21.870 + 21.871 + if (pin) { 21.872 + pin--; /* interrupt pins are numbered starting from 1 */ 21.873 + irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin); 21.874 + /* 21.875 + * Busses behind bridges are typically not listed in the MP-table. 21.876 + * In this case we have to look up the IRQ based on the parent bus, 21.877 + * parent slot, and pin number. The SMP code detects such bridged 21.878 + * busses itself so we should get into this branch reliably. 21.879 + */ 21.880 + if (irq < 0 && dev->bus->parent) { /* go back to the bridge */ 21.881 + struct pci_dev * bridge = dev->bus->self; 21.882 + 21.883 + pin = (pin + PCI_SLOT(dev->devfn)) % 4; 21.884 + irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, 21.885 + PCI_SLOT(bridge->devfn), pin); 21.886 + if (irq >= 0) 21.887 + printk(KERN_WARNING "PCI: using PPB %s[%c] to get irq %d\n", 21.888 + pci_name(bridge), 'A' + pin, irq); 21.889 + } 21.890 + if (irq >= 0) { 21.891 + if (use_pci_vector() && 21.892 + !platform_legacy_irq(irq)) 21.893 + irq = IO_APIC_VECTOR(irq); 21.894 + 21.895 + printk(KERN_INFO "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n", 21.896 + pci_name(dev), 'A' + pin, irq); 21.897 + dev->irq = irq; 21.898 + } 21.899 + } 21.900 + } 21.901 +#endif 21.902 + /* 21.903 + * Still no IRQ? Try to lookup one... 21.904 + */ 21.905 + if (pin && !dev->irq) 21.906 + pcibios_lookup_irq(dev, 0); 21.907 + } 21.908 +} 21.909 + 21.910 +/* 21.911 + * Work around broken HP Pavilion Notebooks which assign USB to 21.912 + * IRQ 9 even though it is actually wired to IRQ 11 21.913 + */ 21.914 +static int __init fix_broken_hp_bios_irq9(struct dmi_system_id *d) 21.915 +{ 21.916 + if (!broken_hp_bios_irq9) { 21.917 + broken_hp_bios_irq9 = 1; 21.918 + printk(KERN_INFO "%s detected - fixing broken IRQ routing\n", d->ident); 21.919 + } 21.920 + return 0; 21.921 +} 21.922 + 21.923 +/* 21.924 + * Work around broken Acer TravelMate 360 Notebooks which assign 21.925 + * Cardbus to IRQ 11 even though it is actually wired to IRQ 10 21.926 + */ 21.927 +static int __init fix_acer_tm360_irqrouting(struct dmi_system_id *d) 21.928 +{ 21.929 + if (!acer_tm360_irqrouting) { 21.930 + acer_tm360_irqrouting = 1; 21.931 + printk(KERN_INFO "%s detected - fixing broken IRQ routing\n", d->ident); 21.932 + } 21.933 + return 0; 21.934 +} 21.935 + 21.936 +static struct dmi_system_id __initdata pciirq_dmi_table[] = { 21.937 + { 21.938 + .callback = fix_broken_hp_bios_irq9, 21.939 + .ident = "HP Pavilion N5400 Series Laptop", 21.940 + .matches = { 21.941 + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 21.942 + DMI_MATCH(DMI_BIOS_VERSION, "GE.M1.03"), 21.943 + DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook Model GE"), 21.944 + DMI_MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736"), 21.945 + }, 21.946 + }, 21.947 + { 21.948 + .callback = fix_acer_tm360_irqrouting, 21.949 + .ident = "Acer TravelMate 36x Laptop", 21.950 + .matches = { 21.951 + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 21.952 + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), 21.953 + }, 21.954 + }, 21.955 + { } 21.956 +}; 21.957 21.958 static int __init pcibios_irq_init(void) 21.959 { 21.960 - int bus; 21.961 - physdev_op_t op; 21.962 - 21.963 DBG("PCI: IRQ init\n"); 21.964 21.965 if (pcibios_enable_irq || raw_pci_ops == NULL) 21.966 return 0; 21.967 21.968 - op.cmd = PHYSDEVOP_PCI_PROBE_ROOT_BUSES; 21.969 - if (HYPERVISOR_physdev_op(&op) != 0) { 21.970 - printk(KERN_WARNING "PCI: System does not support PCI\n"); 21.971 - return 0; 21.972 - } 21.973 + dmi_check_system(pciirq_dmi_table); 21.974 + 21.975 + pirq_table = pirq_find_routing_table(); 21.976 21.977 - printk(KERN_INFO "PCI: Probing PCI hardware\n"); 21.978 - for (bus = 0; bus < 256; bus++) 21.979 - if (test_bit(bus, (unsigned long *) 21.980 - &op.u.pci_probe_root_buses.busmask[0])) 21.981 - (void)pcibios_scan_root(bus); 21.982 +#ifdef CONFIG_PCI_BIOS 21.983 + if (!pirq_table && (pci_probe & PCI_BIOS_IRQ_SCAN)) 21.984 + pirq_table = pcibios_get_irq_routing_table(); 21.985 +#endif 21.986 + if (pirq_table) { 21.987 + pirq_peer_trick(); 21.988 + pirq_find_router(&pirq_router); 21.989 + if (pirq_table->exclusive_irqs) { 21.990 + int i; 21.991 + for (i=0; i<16; i++) 21.992 + if (!(pirq_table->exclusive_irqs & (1 << i))) 21.993 + pirq_penalty[i] += 100; 21.994 + } 21.995 + /* If we're using the I/O APIC, avoid using the PCI IRQ routing table */ 21.996 + if (io_apic_assign_pci_irqs) 21.997 + pirq_table = NULL; 21.998 + } 21.999 21.1000 pcibios_enable_irq = pirq_enable_irq; 21.1001 21.1002 + pcibios_fixup_irqs(); 21.1003 return 0; 21.1004 } 21.1005 21.1006 @@ -92,35 +1030,67 @@ void pcibios_penalize_isa_irq(int irq) 21.1007 21.1008 static int pirq_enable_irq(struct pci_dev *dev) 21.1009 { 21.1010 - int err; 21.1011 u8 pin; 21.1012 - physdev_op_t op; 21.1013 + extern int via_interrupt_line_quirk; 21.1014 + struct pci_dev *temp_dev; 21.1015 + 21.1016 + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); 21.1017 + if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) { 21.1018 + char *msg; 21.1019 + msg = ""; 21.1020 + if (io_apic_assign_pci_irqs) { 21.1021 + int irq; 21.1022 21.1023 - /* Inform Xen that we are going to use this device. */ 21.1024 - op.cmd = PHYSDEVOP_PCI_INITIALISE_DEVICE; 21.1025 - op.u.pci_initialise_device.bus = dev->bus->number; 21.1026 - op.u.pci_initialise_device.dev = PCI_SLOT(dev->devfn); 21.1027 - op.u.pci_initialise_device.func = PCI_FUNC(dev->devfn); 21.1028 - if ( (err = HYPERVISOR_physdev_op(&op)) != 0 ) 21.1029 - return err; 21.1030 + if (pin) { 21.1031 + pin--; /* interrupt pins are numbered starting from 1 */ 21.1032 + irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin); 21.1033 + /* 21.1034 + * Busses behind bridges are typically not listed in the MP-table. 21.1035 + * In this case we have to look up the IRQ based on the parent bus, 21.1036 + * parent slot, and pin number. The SMP code detects such bridged 21.1037 + * busses itself so we should get into this branch reliably. 21.1038 + */ 21.1039 + temp_dev = dev; 21.1040 + while (irq < 0 && dev->bus->parent) { /* go back to the bridge */ 21.1041 + struct pci_dev * bridge = dev->bus->self; 21.1042 21.1043 - /* Now we can bind to the very final IRQ line. */ 21.1044 - pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &pin); 21.1045 - dev->irq = pin; 21.1046 - 21.1047 - /* Sanity-check that an interrupt-producing device is routed 21.1048 - * to an IRQ. */ 21.1049 - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); 21.1050 - if (pin != 0) { 21.1051 - if (dev->irq != 0) 21.1052 - printk(KERN_INFO "PCI: Obtained IRQ %d for device %s\n", 21.1053 - dev->irq, dev->slot_name); 21.1054 + pin = (pin + PCI_SLOT(dev->devfn)) % 4; 21.1055 + irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, 21.1056 + PCI_SLOT(bridge->devfn), pin); 21.1057 + if (irq >= 0) 21.1058 + printk(KERN_WARNING "PCI: using PPB %s[%c] to get irq %d\n", 21.1059 + pci_name(bridge), 'A' + pin, irq); 21.1060 + dev = bridge; 21.1061 + } 21.1062 + dev = temp_dev; 21.1063 + if (irq >= 0) { 21.1064 +#ifdef CONFIG_PCI_MSI 21.1065 + if (!platform_legacy_irq(irq)) 21.1066 + irq = IO_APIC_VECTOR(irq); 21.1067 +#endif 21.1068 + printk(KERN_INFO "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n", 21.1069 + pci_name(dev), 'A' + pin, irq); 21.1070 + dev->irq = irq; 21.1071 + return 0; 21.1072 + } else 21.1073 + msg = " Probably buggy MP table."; 21.1074 + } 21.1075 + } else if (pci_probe & PCI_BIOS_IRQ_SCAN) 21.1076 + msg = ""; 21.1077 else 21.1078 - printk(KERN_WARNING "PCI: No IRQ known for interrupt " 21.1079 - "pin %c of device %s.\n", 'A' + pin - 1, 21.1080 - dev->slot_name); 21.1081 + msg = " Please try using pci=biosirq."; 21.1082 + 21.1083 + /* With IDE legacy devices the IRQ lookup failure is not a problem.. */ 21.1084 + if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE && !(dev->class & 0x5)) 21.1085 + return 0; 21.1086 + 21.1087 + printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n", 21.1088 + 'A' + pin - 1, pci_name(dev), msg); 21.1089 } 21.1090 - 21.1091 + /* VIA bridges use interrupt line for apic/pci steering across 21.1092 + the V-Link */ 21.1093 + else if (via_interrupt_line_quirk) 21.1094 + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq & 15); 21.1095 return 0; 21.1096 } 21.1097
22.1 --- a/linux-2.6.11-xen-sparse/arch/xen/kernel/gnttab.c Tue May 03 12:52:47 2005 +0000 22.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/kernel/gnttab.c Fri May 06 17:04:27 2005 +0000 22.3 @@ -20,10 +20,6 @@ 22.4 #include <asm-xen/linux-public/privcmd.h> 22.5 #include <asm-xen/gnttab.h> 22.6 22.7 -#ifndef set_fixmap_ma 22.8 -#define set_fixmap_ma set_fixmap 22.9 -#endif 22.10 - 22.11 #if 1 22.12 #define ASSERT(_p) \ 22.13 if ( !(_p) ) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n", \ 22.14 @@ -339,7 +335,7 @@ int gnttab_resume(void) 22.15 BUG_ON(setup.status != 0); 22.16 22.17 for ( i = 0; i < NR_GRANT_FRAMES; i++ ) 22.18 - set_fixmap_ma(FIX_GNTTAB_END - i, frames[i] << PAGE_SHIFT); 22.19 + set_fixmap(FIX_GNTTAB_END - i, frames[i] << PAGE_SHIFT); 22.20 22.21 return 0; 22.22 }
23.1 --- a/linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c Tue May 03 12:52:47 2005 +0000 23.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c Fri May 06 17:04:27 2005 +0000 23.3 @@ -129,11 +129,7 @@ static void __do_suspend(void) 23.4 memcpy(&xen_start_info, &suspend_record->resume_info, 23.5 sizeof(xen_start_info)); 23.6 23.7 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 23.8 - set_fixmap_ma(FIX_SHARED_INFO, xen_start_info.shared_info); 23.9 -#else 23.10 set_fixmap(FIX_SHARED_INFO, xen_start_info.shared_info); 23.11 -#endif 23.12 23.13 HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); 23.14
24.1 --- a/linux-2.6.11-xen-sparse/arch/xen/kernel/smp.c Tue May 03 12:52:47 2005 +0000 24.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/kernel/smp.c Fri May 06 17:04:27 2005 +0000 24.3 @@ -4,9 +4,6 @@ 24.4 #include <linux/kernel.h> 24.5 #include <linux/threads.h> 24.6 24.7 -unsigned int __initdata maxcpus = NR_CPUS; 24.8 - 24.9 - 24.10 /* 24.11 * the frequency of the profiling timer can be changed 24.12 * by writing a multiplier value into /proc/profile.
25.1 --- a/linux-2.6.11-xen-sparse/arch/xen/x86_64/Kconfig Tue May 03 12:52:47 2005 +0000 25.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/x86_64/Kconfig Fri May 06 17:04:27 2005 +0000 25.3 @@ -363,8 +363,6 @@ menu "Power management options" 25.4 25.5 source kernel/power/Kconfig 25.6 25.7 -source "drivers/acpi/Kconfig" 25.8 - 25.9 source "arch/x86_64/kernel/cpufreq/Kconfig" 25.10 25.11 endmenu
26.1 --- a/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/init.c Tue May 03 12:52:47 2005 +0000 26.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/init.c Fri May 06 17:04:27 2005 +0000 26.3 @@ -361,7 +361,14 @@ void __set_fixmap (enum fixed_addresses 26.4 printk("Invalid __set_fixmap\n"); 26.5 return; 26.6 } 26.7 - set_pte_phys(address, phys, prot, SET_FIXMAP_KERNEL); 26.8 + switch (idx) { 26.9 + case VSYSCALL_FIRST_PAGE: 26.10 + set_pte_phys(address, phys, prot, SET_FIXMAP_KERNEL); 26.11 + break; 26.12 + default: 26.13 + set_pte_phys_ma(address, phys, prot); 26.14 + break; 26.15 + } 26.16 } 26.17 26.18 26.19 @@ -414,18 +421,6 @@ void __set_fixmap_user (enum fixed_addre 26.20 26.21 } 26.22 26.23 - 26.24 -void __set_fixmap_ma (enum fixed_addresses idx, unsigned long phys, pgprot_t prot) 26.25 -{ 26.26 - unsigned long address = __fix_to_virt(idx); 26.27 - 26.28 - if (idx >= __end_of_fixed_addresses) { 26.29 - printk("Invalid __set_fixmap\n"); 26.30 - return; 26.31 - } 26.32 - set_pte_phys_ma(address, phys, prot); 26.33 -} 26.34 - 26.35 unsigned long __initdata table_start, table_end, tables_reserved; 26.36 26.37 #if 0 26.38 @@ -632,8 +627,7 @@ void __init paging_init(void) 26.39 free_area_init(zones_size); 26.40 } 26.41 26.42 - __set_fixmap_ma(FIX_SHARED_INFO, xen_start_info.shared_info, 26.43 - __pgprot(_KERNPG_TABLE)); 26.44 + set_fixmap(FIX_SHARED_INFO, xen_start_info.shared_info); 26.45 HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); 26.46 26.47 memset(empty_zero_page, 0, sizeof(empty_zero_page)); 26.48 @@ -642,11 +636,11 @@ void __init paging_init(void) 26.49 /* Setup mapping of lower 1st MB */ 26.50 for (i = 0; i < NR_FIX_ISAMAPS; i++) 26.51 if (xen_start_info.flags & SIF_PRIVILEGED) 26.52 - __set_fixmap_ma(FIX_ISAMAP_BEGIN - i, i * PAGE_SIZE, 26.53 - __pgprot(_KERNPG_TABLE)); 26.54 + set_fixmap(FIX_ISAMAP_BEGIN - i, i * PAGE_SIZE); 26.55 else 26.56 - set_fixmap_ma_ro(FIX_ISAMAP_BEGIN - i, 26.57 - virt_to_machine(empty_zero_page)); 26.58 + __set_fixmap(FIX_ISAMAP_BEGIN - i, 26.59 + virt_to_machine(empty_zero_page), 26.60 + PAGE_KERNEL_RO); 26.61 #endif 26.62 26.63 }
27.1 --- a/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/ioremap.c Tue May 03 12:52:47 2005 +0000 27.2 +++ b/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/ioremap.c Fri May 06 17:04:27 2005 +0000 27.3 @@ -273,7 +273,7 @@ void __init *bt_ioremap(unsigned long ph 27.4 */ 27.5 idx = FIX_BTMAP_BEGIN; 27.6 while (nrpages > 0) { 27.7 - set_fixmap_ma(idx, phys_addr); 27.8 + set_fixmap(idx, phys_addr); 27.9 phys_addr += PAGE_SIZE; 27.10 --idx; 27.11 --nrpages;
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/linux-2.6.11-xen-sparse/drivers/acpi/tables.c Fri May 06 17:04:27 2005 +0000 28.3 @@ -0,0 +1,610 @@ 28.4 +/* 28.5 + * acpi_tables.c - ACPI Boot-Time Table Parsing 28.6 + * 28.7 + * Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 28.8 + * 28.9 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 28.10 + * 28.11 + * This program is free software; you can redistribute it and/or modify 28.12 + * it under the terms of the GNU General Public License as published by 28.13 + * the Free Software Foundation; either version 2 of the License, or 28.14 + * (at your option) any later version. 28.15 + * 28.16 + * This program is distributed in the hope that it will be useful, 28.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 28.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28.19 + * GNU General Public License for more details. 28.20 + * 28.21 + * You should have received a copy of the GNU General Public License 28.22 + * along with this program; if not, write to the Free Software 28.23 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 28.24 + * 28.25 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 28.26 + * 28.27 + */ 28.28 + 28.29 +#include <linux/config.h> 28.30 +#include <linux/init.h> 28.31 +#include <linux/kernel.h> 28.32 +#include <linux/sched.h> 28.33 +#include <linux/smp.h> 28.34 +#include <linux/string.h> 28.35 +#include <linux/types.h> 28.36 +#include <linux/irq.h> 28.37 +#include <linux/errno.h> 28.38 +#include <linux/acpi.h> 28.39 +#include <linux/bootmem.h> 28.40 + 28.41 +#define PREFIX "ACPI: " 28.42 + 28.43 +#define ACPI_MAX_TABLES 256 28.44 + 28.45 +static char *acpi_table_signatures[ACPI_TABLE_COUNT] = { 28.46 + [ACPI_TABLE_UNKNOWN] = "????", 28.47 + [ACPI_APIC] = "APIC", 28.48 + [ACPI_BOOT] = "BOOT", 28.49 + [ACPI_DBGP] = "DBGP", 28.50 + [ACPI_DSDT] = "DSDT", 28.51 + [ACPI_ECDT] = "ECDT", 28.52 + [ACPI_ETDT] = "ETDT", 28.53 + [ACPI_FADT] = "FACP", 28.54 + [ACPI_FACS] = "FACS", 28.55 + [ACPI_OEMX] = "OEM", 28.56 + [ACPI_PSDT] = "PSDT", 28.57 + [ACPI_SBST] = "SBST", 28.58 + [ACPI_SLIT] = "SLIT", 28.59 + [ACPI_SPCR] = "SPCR", 28.60 + [ACPI_SRAT] = "SRAT", 28.61 + [ACPI_SSDT] = "SSDT", 28.62 + [ACPI_SPMI] = "SPMI", 28.63 + [ACPI_HPET] = "HPET", 28.64 + [ACPI_MCFG] = "MCFG", 28.65 +}; 28.66 + 28.67 +static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" }; 28.68 +static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" }; 28.69 + 28.70 +/* System Description Table (RSDT/XSDT) */ 28.71 +struct acpi_table_sdt { 28.72 + unsigned long pa; 28.73 + enum acpi_table_id id; 28.74 + unsigned long size; 28.75 +} __attribute__ ((packed)); 28.76 + 28.77 +static unsigned long sdt_pa; /* Physical Address */ 28.78 +static unsigned long sdt_count; /* Table count */ 28.79 + 28.80 +static struct acpi_table_sdt sdt_entry[ACPI_MAX_TABLES]; 28.81 + 28.82 +void 28.83 +acpi_table_print ( 28.84 + struct acpi_table_header *header, 28.85 + unsigned long phys_addr) 28.86 +{ 28.87 + char *name = NULL; 28.88 + 28.89 + if (!header) 28.90 + return; 28.91 + 28.92 + /* Some table signatures aren't good table names */ 28.93 + 28.94 + if (!strncmp((char *) &header->signature, 28.95 + acpi_table_signatures[ACPI_APIC], 28.96 + sizeof(header->signature))) { 28.97 + name = "MADT"; 28.98 + } 28.99 + else if (!strncmp((char *) &header->signature, 28.100 + acpi_table_signatures[ACPI_FADT], 28.101 + sizeof(header->signature))) { 28.102 + name = "FADT"; 28.103 + } 28.104 + else 28.105 + name = header->signature; 28.106 + 28.107 + printk(KERN_DEBUG PREFIX "%.4s (v%3.3d %6.6s %8.8s 0x%08x %.4s 0x%08x) @ 0x%p\n", 28.108 + name, header->revision, header->oem_id, 28.109 + header->oem_table_id, header->oem_revision, 28.110 + header->asl_compiler_id, header->asl_compiler_revision, 28.111 + (void *) phys_addr); 28.112 +} 28.113 + 28.114 + 28.115 +void 28.116 +acpi_table_print_madt_entry ( 28.117 + acpi_table_entry_header *header) 28.118 +{ 28.119 + if (!header) 28.120 + return; 28.121 + 28.122 + switch (header->type) { 28.123 + 28.124 + case ACPI_MADT_LAPIC: 28.125 + { 28.126 + struct acpi_table_lapic *p = 28.127 + (struct acpi_table_lapic*) header; 28.128 + printk(KERN_INFO PREFIX "LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n", 28.129 + p->acpi_id, p->id, p->flags.enabled?"enabled":"disabled"); 28.130 + } 28.131 + break; 28.132 + 28.133 + case ACPI_MADT_IOAPIC: 28.134 + { 28.135 + struct acpi_table_ioapic *p = 28.136 + (struct acpi_table_ioapic*) header; 28.137 + printk(KERN_INFO PREFIX "IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n", 28.138 + p->id, p->address, p->global_irq_base); 28.139 + } 28.140 + break; 28.141 + 28.142 + case ACPI_MADT_INT_SRC_OVR: 28.143 + { 28.144 + struct acpi_table_int_src_ovr *p = 28.145 + (struct acpi_table_int_src_ovr*) header; 28.146 + printk(KERN_INFO PREFIX "INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n", 28.147 + p->bus, p->bus_irq, p->global_irq, 28.148 + mps_inti_flags_polarity[p->flags.polarity], 28.149 + mps_inti_flags_trigger[p->flags.trigger]); 28.150 + if(p->flags.reserved) 28.151 + printk(KERN_INFO PREFIX "INT_SRC_OVR unexpected reserved flags: 0x%x\n", 28.152 + p->flags.reserved); 28.153 + 28.154 + } 28.155 + break; 28.156 + 28.157 + case ACPI_MADT_NMI_SRC: 28.158 + { 28.159 + struct acpi_table_nmi_src *p = 28.160 + (struct acpi_table_nmi_src*) header; 28.161 + printk(KERN_INFO PREFIX "NMI_SRC (%s %s global_irq %d)\n", 28.162 + mps_inti_flags_polarity[p->flags.polarity], 28.163 + mps_inti_flags_trigger[p->flags.trigger], p->global_irq); 28.164 + } 28.165 + break; 28.166 + 28.167 + case ACPI_MADT_LAPIC_NMI: 28.168 + { 28.169 + struct acpi_table_lapic_nmi *p = 28.170 + (struct acpi_table_lapic_nmi*) header; 28.171 + printk(KERN_INFO PREFIX "LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n", 28.172 + p->acpi_id, 28.173 + mps_inti_flags_polarity[p->flags.polarity], 28.174 + mps_inti_flags_trigger[p->flags.trigger], p->lint); 28.175 + } 28.176 + break; 28.177 + 28.178 + case ACPI_MADT_LAPIC_ADDR_OVR: 28.179 + { 28.180 + struct acpi_table_lapic_addr_ovr *p = 28.181 + (struct acpi_table_lapic_addr_ovr*) header; 28.182 + printk(KERN_INFO PREFIX "LAPIC_ADDR_OVR (address[%p])\n", 28.183 + (void *) (unsigned long) p->address); 28.184 + } 28.185 + break; 28.186 + 28.187 + case ACPI_MADT_IOSAPIC: 28.188 + { 28.189 + struct acpi_table_iosapic *p = 28.190 + (struct acpi_table_iosapic*) header; 28.191 + printk(KERN_INFO PREFIX "IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n", 28.192 + p->id, (void *) (unsigned long) p->address, p->global_irq_base); 28.193 + } 28.194 + break; 28.195 + 28.196 + case ACPI_MADT_LSAPIC: 28.197 + { 28.198 + struct acpi_table_lsapic *p = 28.199 + (struct acpi_table_lsapic*) header; 28.200 + printk(KERN_INFO PREFIX "LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n", 28.201 + p->acpi_id, p->id, p->eid, p->flags.enabled?"enabled":"disabled"); 28.202 + } 28.203 + break; 28.204 + 28.205 + case ACPI_MADT_PLAT_INT_SRC: 28.206 + { 28.207 + struct acpi_table_plat_int_src *p = 28.208 + (struct acpi_table_plat_int_src*) header; 28.209 + printk(KERN_INFO PREFIX "PLAT_INT_SRC (%s %s type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n", 28.210 + mps_inti_flags_polarity[p->flags.polarity], 28.211 + mps_inti_flags_trigger[p->flags.trigger], 28.212 + p->type, p->id, p->eid, p->iosapic_vector, p->global_irq); 28.213 + } 28.214 + break; 28.215 + 28.216 + default: 28.217 + printk(KERN_WARNING PREFIX "Found unsupported MADT entry (type = 0x%x)\n", 28.218 + header->type); 28.219 + break; 28.220 + } 28.221 +} 28.222 + 28.223 + 28.224 +static int 28.225 +acpi_table_compute_checksum ( 28.226 + void *table_pointer, 28.227 + unsigned long length) 28.228 +{ 28.229 + u8 *p = (u8 *) table_pointer; 28.230 + unsigned long remains = length; 28.231 + unsigned long sum = 0; 28.232 + 28.233 + if (!p || !length) 28.234 + return -EINVAL; 28.235 + 28.236 + while (remains--) 28.237 + sum += *p++; 28.238 + 28.239 + return (sum & 0xFF); 28.240 +} 28.241 + 28.242 +/* 28.243 + * acpi_get_table_header_early() 28.244 + * for acpi_blacklisted(), acpi_table_get_sdt() 28.245 + */ 28.246 +int __init 28.247 +acpi_get_table_header_early ( 28.248 + enum acpi_table_id id, 28.249 + struct acpi_table_header **header) 28.250 +{ 28.251 + unsigned int i; 28.252 + enum acpi_table_id temp_id; 28.253 + 28.254 + /* DSDT is different from the rest */ 28.255 + if (id == ACPI_DSDT) 28.256 + temp_id = ACPI_FADT; 28.257 + else 28.258 + temp_id = id; 28.259 + 28.260 + /* Locate the table. */ 28.261 + 28.262 + for (i = 0; i < sdt_count; i++) { 28.263 + if (sdt_entry[i].id != temp_id) 28.264 + continue; 28.265 + *header = (void *) 28.266 + __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size); 28.267 + if (!*header) { 28.268 + printk(KERN_WARNING PREFIX "Unable to map %s\n", 28.269 + acpi_table_signatures[temp_id]); 28.270 + return -ENODEV; 28.271 + } 28.272 + break; 28.273 + } 28.274 + 28.275 + if (!*header) { 28.276 + printk(KERN_WARNING PREFIX "%s not present\n", 28.277 + acpi_table_signatures[id]); 28.278 + return -ENODEV; 28.279 + } 28.280 + 28.281 + /* Map the DSDT header via the pointer in the FADT */ 28.282 + if (id == ACPI_DSDT) { 28.283 + struct fadt_descriptor_rev2 *fadt = (struct fadt_descriptor_rev2 *) *header; 28.284 + 28.285 + if (fadt->revision == 3 && fadt->Xdsdt) { 28.286 + *header = (void *) __acpi_map_table(fadt->Xdsdt, 28.287 + sizeof(struct acpi_table_header)); 28.288 + } else if (fadt->V1_dsdt) { 28.289 + *header = (void *) __acpi_map_table(fadt->V1_dsdt, 28.290 + sizeof(struct acpi_table_header)); 28.291 + } else 28.292 + *header = NULL; 28.293 + 28.294 + if (!*header) { 28.295 + printk(KERN_WARNING PREFIX "Unable to map DSDT\n"); 28.296 + return -ENODEV; 28.297 + } 28.298 + } 28.299 + 28.300 + return 0; 28.301 +} 28.302 + 28.303 + 28.304 +int __init 28.305 +acpi_table_parse_madt_family ( 28.306 + enum acpi_table_id id, 28.307 + unsigned long madt_size, 28.308 + int entry_id, 28.309 + acpi_madt_entry_handler handler, 28.310 + unsigned int max_entries) 28.311 +{ 28.312 + void *madt = NULL; 28.313 + acpi_table_entry_header *entry; 28.314 + unsigned int count = 0; 28.315 + unsigned long madt_end; 28.316 + unsigned int i; 28.317 + 28.318 + if (!handler) 28.319 + return -EINVAL; 28.320 + 28.321 + /* Locate the MADT (if exists). There should only be one. */ 28.322 + 28.323 + for (i = 0; i < sdt_count; i++) { 28.324 + if (sdt_entry[i].id != id) 28.325 + continue; 28.326 + madt = (void *) 28.327 + __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size); 28.328 + if (!madt) { 28.329 + printk(KERN_WARNING PREFIX "Unable to map %s\n", 28.330 + acpi_table_signatures[id]); 28.331 + return -ENODEV; 28.332 + } 28.333 + break; 28.334 + } 28.335 + 28.336 + if (!madt) { 28.337 + printk(KERN_WARNING PREFIX "%s not present\n", 28.338 + acpi_table_signatures[id]); 28.339 + return -ENODEV; 28.340 + } 28.341 + 28.342 + madt_end = (unsigned long) madt + sdt_entry[i].size; 28.343 + 28.344 + /* Parse all entries looking for a match. */ 28.345 + 28.346 + entry = (acpi_table_entry_header *) 28.347 + ((unsigned long) madt + madt_size); 28.348 + 28.349 + while (((unsigned long) entry) + sizeof(acpi_table_entry_header) < madt_end) { 28.350 + if (entry->type == entry_id && 28.351 + (!max_entries || count++ < max_entries)) 28.352 + if (handler(entry, madt_end)) 28.353 + return -EINVAL; 28.354 + 28.355 + entry = (acpi_table_entry_header *) 28.356 + ((unsigned long) entry + entry->length); 28.357 + } 28.358 + if (max_entries && count > max_entries) { 28.359 + printk(KERN_WARNING PREFIX "[%s:0x%02x] ignored %i entries of " 28.360 + "%i found\n", acpi_table_signatures[id], entry_id, 28.361 + count - max_entries, count); 28.362 + } 28.363 + 28.364 + return count; 28.365 +} 28.366 + 28.367 + 28.368 +int __init 28.369 +acpi_table_parse_madt ( 28.370 + enum acpi_madt_entry_id id, 28.371 + acpi_madt_entry_handler handler, 28.372 + unsigned int max_entries) 28.373 +{ 28.374 + return acpi_table_parse_madt_family(ACPI_APIC, sizeof(struct acpi_table_madt), 28.375 + id, handler, max_entries); 28.376 +} 28.377 + 28.378 + 28.379 +int __init 28.380 +acpi_table_parse ( 28.381 + enum acpi_table_id id, 28.382 + acpi_table_handler handler) 28.383 +{ 28.384 + int count = 0; 28.385 + unsigned int i = 0; 28.386 + 28.387 + if (!handler) 28.388 + return -EINVAL; 28.389 + 28.390 + for (i = 0; i < sdt_count; i++) { 28.391 + if (sdt_entry[i].id != id) 28.392 + continue; 28.393 + count++; 28.394 + if (count == 1) 28.395 + handler(sdt_entry[i].pa, sdt_entry[i].size); 28.396 + 28.397 + else 28.398 + printk(KERN_WARNING PREFIX "%d duplicate %s table ignored.\n", 28.399 + count, acpi_table_signatures[id]); 28.400 + } 28.401 + 28.402 + return count; 28.403 +} 28.404 + 28.405 + 28.406 +static int __init 28.407 +acpi_table_get_sdt ( 28.408 + struct acpi_table_rsdp *rsdp) 28.409 +{ 28.410 + struct acpi_table_header *header = NULL; 28.411 + unsigned int i, id = 0; 28.412 + 28.413 + if (!rsdp) 28.414 + return -EINVAL; 28.415 + 28.416 + /* First check XSDT (but only on ACPI 2.0-compatible systems) */ 28.417 + 28.418 + if ((rsdp->revision >= 2) && 28.419 + (((struct acpi20_table_rsdp*)rsdp)->xsdt_address)) { 28.420 + 28.421 + struct acpi_table_xsdt *mapped_xsdt = NULL; 28.422 + 28.423 + sdt_pa = ((struct acpi20_table_rsdp*)rsdp)->xsdt_address; 28.424 + 28.425 + /* map in just the header */ 28.426 + header = (struct acpi_table_header *) 28.427 + __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header)); 28.428 + 28.429 + if (!header) { 28.430 + printk(KERN_WARNING PREFIX "Unable to map XSDT header\n"); 28.431 + return -ENODEV; 28.432 + } 28.433 + 28.434 + /* remap in the entire table before processing */ 28.435 + mapped_xsdt = (struct acpi_table_xsdt *) 28.436 + __acpi_map_table(sdt_pa, header->length); 28.437 + if (!mapped_xsdt) { 28.438 + printk(KERN_WARNING PREFIX "Unable to map XSDT\n"); 28.439 + return -ENODEV; 28.440 + } 28.441 + header = &mapped_xsdt->header; 28.442 + 28.443 + if (strncmp(header->signature, "XSDT", 4)) { 28.444 + printk(KERN_WARNING PREFIX "XSDT signature incorrect\n"); 28.445 + return -ENODEV; 28.446 + } 28.447 + 28.448 + if (acpi_table_compute_checksum(header, header->length)) { 28.449 + printk(KERN_WARNING PREFIX "Invalid XSDT checksum\n"); 28.450 + return -ENODEV; 28.451 + } 28.452 + 28.453 + sdt_count = (header->length - sizeof(struct acpi_table_header)) >> 3; 28.454 + if (sdt_count > ACPI_MAX_TABLES) { 28.455 + printk(KERN_WARNING PREFIX "Truncated %lu XSDT entries\n", 28.456 + (sdt_count - ACPI_MAX_TABLES)); 28.457 + sdt_count = ACPI_MAX_TABLES; 28.458 + } 28.459 + 28.460 + for (i = 0; i < sdt_count; i++) 28.461 + sdt_entry[i].pa = (unsigned long) mapped_xsdt->entry[i]; 28.462 + } 28.463 + 28.464 + /* Then check RSDT */ 28.465 + 28.466 + else if (rsdp->rsdt_address) { 28.467 + 28.468 + struct acpi_table_rsdt *mapped_rsdt = NULL; 28.469 + 28.470 + sdt_pa = rsdp->rsdt_address; 28.471 + 28.472 + /* map in just the header */ 28.473 + header = (struct acpi_table_header *) 28.474 + __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header)); 28.475 + if (!header) { 28.476 + printk(KERN_WARNING PREFIX "Unable to map RSDT header\n"); 28.477 + return -ENODEV; 28.478 + } 28.479 + 28.480 + /* remap in the entire table before processing */ 28.481 + mapped_rsdt = (struct acpi_table_rsdt *) 28.482 + __acpi_map_table(sdt_pa, header->length); 28.483 + if (!mapped_rsdt) { 28.484 + printk(KERN_WARNING PREFIX "Unable to map RSDT\n"); 28.485 + return -ENODEV; 28.486 + } 28.487 + header = &mapped_rsdt->header; 28.488 + 28.489 + if (strncmp(header->signature, "RSDT", 4)) { 28.490 + printk(KERN_WARNING PREFIX "RSDT signature incorrect\n"); 28.491 + return -ENODEV; 28.492 + } 28.493 + 28.494 + if (acpi_table_compute_checksum(header, header->length)) { 28.495 + printk(KERN_WARNING PREFIX "Invalid RSDT checksum\n"); 28.496 + return -ENODEV; 28.497 + } 28.498 + 28.499 + sdt_count = (header->length - sizeof(struct acpi_table_header)) >> 2; 28.500 + if (sdt_count > ACPI_MAX_TABLES) { 28.501 + printk(KERN_WARNING PREFIX "Truncated %lu RSDT entries\n", 28.502 + (sdt_count - ACPI_MAX_TABLES)); 28.503 + sdt_count = ACPI_MAX_TABLES; 28.504 + } 28.505 + 28.506 + for (i = 0; i < sdt_count; i++) 28.507 + sdt_entry[i].pa = (unsigned long) mapped_rsdt->entry[i]; 28.508 + } 28.509 + 28.510 + else { 28.511 + printk(KERN_WARNING PREFIX "No System Description Table (RSDT/XSDT) specified in RSDP\n"); 28.512 + return -ENODEV; 28.513 + } 28.514 + 28.515 + acpi_table_print(header, sdt_pa); 28.516 + 28.517 + for (i = 0; i < sdt_count; i++) { 28.518 + 28.519 + /* map in just the header */ 28.520 + header = (struct acpi_table_header *) 28.521 + __acpi_map_table(sdt_entry[i].pa, 28.522 + sizeof(struct acpi_table_header)); 28.523 + if (!header) 28.524 + continue; 28.525 + 28.526 + /* remap in the entire table before processing */ 28.527 + header = (struct acpi_table_header *) 28.528 + __acpi_map_table(sdt_entry[i].pa, 28.529 + header->length); 28.530 + if (!header) 28.531 + continue; 28.532 + 28.533 + acpi_table_print(header, sdt_entry[i].pa); 28.534 + 28.535 + if (acpi_table_compute_checksum(header, header->length)) { 28.536 + printk(KERN_WARNING " >>> ERROR: Invalid checksum\n"); 28.537 + continue; 28.538 + } 28.539 + 28.540 + sdt_entry[i].size = header->length; 28.541 + 28.542 + for (id = 0; id < ACPI_TABLE_COUNT; id++) { 28.543 + if (!strncmp((char *) &header->signature, 28.544 + acpi_table_signatures[id], 28.545 + sizeof(header->signature))) { 28.546 + sdt_entry[i].id = id; 28.547 + } 28.548 + } 28.549 + } 28.550 + 28.551 + /* 28.552 + * The DSDT is *not* in the RSDT (why not? no idea.) but we want 28.553 + * to print its info, because this is what people usually blacklist 28.554 + * against. Unfortunately, we don't know the phys_addr, so just 28.555 + * print 0. Maybe no one will notice. 28.556 + */ 28.557 + if(!acpi_get_table_header_early(ACPI_DSDT, &header)) 28.558 + acpi_table_print(header, 0); 28.559 + 28.560 + return 0; 28.561 +} 28.562 + 28.563 +/* 28.564 + * acpi_table_init() 28.565 + * 28.566 + * find RSDP, find and checksum SDT/XSDT. 28.567 + * checksum all tables, print SDT/XSDT 28.568 + * 28.569 + * result: sdt_entry[] is initialized 28.570 + */ 28.571 + 28.572 +int __init 28.573 +acpi_table_init (void) 28.574 +{ 28.575 + struct acpi_table_rsdp *rsdp = NULL; 28.576 + unsigned long rsdp_phys = 0; 28.577 + int result = 0; 28.578 + 28.579 + /* Locate and map the Root System Description Table (RSDP) */ 28.580 + 28.581 + rsdp_phys = acpi_find_rsdp(); 28.582 + if (!rsdp_phys) { 28.583 + printk(KERN_ERR PREFIX "Unable to locate RSDP\n"); 28.584 + return -ENODEV; 28.585 + } 28.586 + 28.587 + rsdp = (struct acpi_table_rsdp *) (__fix_to_virt(FIX_ACPI_RSDP_PAGE) + 28.588 + (rsdp_phys & ~PAGE_MASK)); 28.589 + if (!rsdp) { 28.590 + printk(KERN_WARNING PREFIX "Unable to map RSDP\n"); 28.591 + return -ENODEV; 28.592 + } 28.593 + 28.594 + printk(KERN_DEBUG PREFIX "RSDP (v%3.3d %6.6s ) @ 0x%p\n", 28.595 + rsdp->revision, rsdp->oem_id, (void *) rsdp_phys); 28.596 + 28.597 + if (rsdp->revision < 2) 28.598 + result = acpi_table_compute_checksum(rsdp, sizeof(struct acpi_table_rsdp)); 28.599 + else 28.600 + result = acpi_table_compute_checksum(rsdp, ((struct acpi20_table_rsdp *)rsdp)->length); 28.601 + 28.602 + if (result) { 28.603 + printk(KERN_WARNING " >>> ERROR: Invalid checksum\n"); 28.604 + return -ENODEV; 28.605 + } 28.606 + 28.607 + /* Locate and map the System Description table (RSDT/XSDT) */ 28.608 + 28.609 + if (acpi_table_get_sdt(rsdp)) 28.610 + return -ENODEV; 28.611 + 28.612 + return 0; 28.613 +}
29.1 --- a/linux-2.6.11-xen-sparse/drivers/xen/Makefile Tue May 03 12:52:47 2005 +0000 29.2 +++ b/linux-2.6.11-xen-sparse/drivers/xen/Makefile Fri May 06 17:04:27 2005 +0000 29.3 @@ -3,8 +3,8 @@ 29.4 obj-y += console/ 29.5 obj-y += evtchn/ 29.6 obj-y += balloon/ 29.7 +obj-y += privcmd/ 29.8 29.9 -obj-$(CONFIG_XEN_PRIVILEGED_GUEST) += privcmd/ 29.10 obj-$(CONFIG_XEN_BLKDEV_BACKEND) += blkback/ 29.11 obj-$(CONFIG_XEN_NETDEV_BACKEND) += netback/ 29.12 obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += blkfront/
30.1 --- a/linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c Tue May 03 12:52:47 2005 +0000 30.2 +++ b/linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c Fri May 06 17:04:27 2005 +0000 30.3 @@ -39,6 +39,7 @@ 30.4 #include <linux/skbuff.h> 30.5 #include <linux/init.h> 30.6 #include <linux/bitops.h> 30.7 +#include <linux/proc_fs.h> 30.8 #include <net/sock.h> 30.9 #include <net/pkt_sched.h> 30.10 #include <net/arp.h> 30.11 @@ -49,6 +50,7 @@ 30.12 #include <asm-xen/xen-public/io/netif.h> 30.13 #include <asm-xen/balloon.h> 30.14 #include <asm/page.h> 30.15 +#include <asm/uaccess.h> 30.16 30.17 #ifndef __GFP_NOWARN 30.18 #define __GFP_NOWARN 0 30.19 @@ -85,6 +87,16 @@ static unsigned long rx_pfn_array[NETIF_ 30.20 static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE+1]; 30.21 static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE]; 30.22 30.23 +#ifdef CONFIG_PROC_FS 30.24 +static int xennet_proc_init(void); 30.25 +static int xennet_proc_addif(struct net_device *dev); 30.26 +static void xennet_proc_delif(struct net_device *dev); 30.27 +#else 30.28 +#define xennet_proc_init() (0) 30.29 +#define xennet_proc_addif(d) (0) 30.30 +#define xennet_proc_delif(d) ((void)0) 30.31 +#endif 30.32 + 30.33 static struct list_head dev_list; 30.34 30.35 struct net_private 30.36 @@ -120,7 +132,7 @@ struct net_private 30.37 /* Receive-ring batched refills. */ 30.38 #define RX_MIN_TARGET 8 30.39 #define RX_MAX_TARGET NETIF_RX_RING_SIZE 30.40 - int rx_target; 30.41 + int rx_min_target, rx_max_target, rx_target; 30.42 struct sk_buff_head rx_batch; 30.43 30.44 /* 30.45 @@ -413,8 +425,8 @@ static void network_alloc_rx_buffers(str 30.46 30.47 /* Adjust our floating fill target if we risked running out of buffers. */ 30.48 if (((req_prod - np->rx->resp_prod) < (np->rx_target / 4)) && 30.49 - ((np->rx_target *= 2) > RX_MAX_TARGET)) 30.50 - np->rx_target = RX_MAX_TARGET; 30.51 + ((np->rx_target *= 2) > np->rx_max_target)) 30.52 + np->rx_target = np->rx_max_target; 30.53 } 30.54 30.55 30.56 @@ -646,8 +658,8 @@ static int netif_poll(struct net_device 30.57 /* If we get a callback with very few responses, reduce fill target. */ 30.58 /* NB. Note exponential increase, linear decrease. */ 30.59 if (((np->rx->req_prod - np->rx->resp_prod) > ((3*np->rx_target) / 4)) && 30.60 - (--np->rx_target < RX_MIN_TARGET)) 30.61 - np->rx_target = RX_MIN_TARGET; 30.62 + (--np->rx_target < np->rx_min_target)) 30.63 + np->rx_target = np->rx_min_target; 30.64 30.65 network_alloc_rx_buffers(dev); 30.66 30.67 @@ -938,7 +950,9 @@ static int create_netdev(int handle, str 30.68 spin_lock_init(&np->rx_lock); 30.69 30.70 skb_queue_head_init(&np->rx_batch); 30.71 - np->rx_target = RX_MIN_TARGET; 30.72 + np->rx_target = RX_MIN_TARGET; 30.73 + np->rx_min_target = RX_MIN_TARGET; 30.74 + np->rx_max_target = RX_MAX_TARGET; 30.75 30.76 /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */ 30.77 for (i = 0; i <= NETIF_TX_RING_SIZE; i++) 30.78 @@ -957,11 +971,17 @@ static int create_netdev(int handle, str 30.79 printk(KERN_WARNING "%s> register_netdev err=%d\n", __FUNCTION__, err); 30.80 goto exit; 30.81 } 30.82 + 30.83 + if ((err = xennet_proc_addif(dev)) != 0) { 30.84 + unregister_netdev(dev); 30.85 + goto exit; 30.86 + } 30.87 + 30.88 np->dev = dev; 30.89 list_add(&np->list, &dev_list); 30.90 30.91 exit: 30.92 - if ((err != 0) && (dev != NULL )) 30.93 + if ((err != 0) && (dev != NULL)) 30.94 kfree(dev); 30.95 else if (val != NULL) 30.96 *val = dev; 30.97 @@ -1238,6 +1258,9 @@ static int __init netif_init(void) 30.98 if (xen_start_info.flags & SIF_INITDOMAIN) 30.99 return 0; 30.100 30.101 + if ((err = xennet_proc_init()) != 0) 30.102 + return err; 30.103 + 30.104 IPRINTK("Initialising virtual ethernet driver.\n"); 30.105 INIT_LIST_HEAD(&dev_list); 30.106 (void)register_inetaddr_notifier(¬ifier_inetdev); 30.107 @@ -1295,6 +1318,153 @@ void netif_resume(void) 30.108 } 30.109 } 30.110 30.111 +#ifdef CONFIG_PROC_FS 30.112 + 30.113 +#define TARGET_MIN 0UL 30.114 +#define TARGET_MAX 1UL 30.115 +#define TARGET_CUR 2UL 30.116 + 30.117 +static int xennet_proc_read( 30.118 + char *page, char **start, off_t off, int count, int *eof, void *data) 30.119 +{ 30.120 + struct net_device *dev = (struct net_device *)((unsigned long)data & ~3UL); 30.121 + struct net_private *np = netdev_priv(dev); 30.122 + int len = 0, which_target = (int)data & 3; 30.123 + 30.124 + switch (which_target) 30.125 + { 30.126 + case TARGET_MIN: 30.127 + len = sprintf(page, "%d\n", np->rx_min_target); 30.128 + break; 30.129 + case TARGET_MAX: 30.130 + len = sprintf(page, "%d\n", np->rx_max_target); 30.131 + break; 30.132 + case TARGET_CUR: 30.133 + len = sprintf(page, "%d\n", np->rx_target); 30.134 + break; 30.135 + } 30.136 + 30.137 + *eof = 1; 30.138 + return len; 30.139 +} 30.140 + 30.141 +static int xennet_proc_write( 30.142 + struct file *file, const char __user *buffer, 30.143 + unsigned long count, void *data) 30.144 +{ 30.145 + struct net_device *dev = (struct net_device *)((unsigned long)data & ~3UL); 30.146 + struct net_private *np = netdev_priv(dev); 30.147 + int which_target = (int)data & 3; 30.148 + char string[64]; 30.149 + long target; 30.150 + 30.151 + if (!capable(CAP_SYS_ADMIN)) 30.152 + return -EPERM; 30.153 + 30.154 + if (count <= 1) 30.155 + return -EBADMSG; /* runt */ 30.156 + if (count > sizeof(string)) 30.157 + return -EFBIG; /* too long */ 30.158 + 30.159 + if (copy_from_user(string, buffer, count)) 30.160 + return -EFAULT; 30.161 + string[sizeof(string)-1] = '\0'; 30.162 + 30.163 + target = simple_strtol(string, NULL, 10); 30.164 + if (target < RX_MIN_TARGET) 30.165 + target = RX_MIN_TARGET; 30.166 + if (target > RX_MAX_TARGET) 30.167 + target = RX_MAX_TARGET; 30.168 + 30.169 + spin_lock(&np->rx_lock); 30.170 + 30.171 + switch (which_target) 30.172 + { 30.173 + case TARGET_MIN: 30.174 + if (target > np->rx_max_target) 30.175 + np->rx_max_target = target; 30.176 + np->rx_min_target = target; 30.177 + if (target > np->rx_target) 30.178 + np->rx_target = target; 30.179 + break; 30.180 + case TARGET_MAX: 30.181 + if (target < np->rx_min_target) 30.182 + np->rx_min_target = target; 30.183 + np->rx_max_target = target; 30.184 + if (target < np->rx_target) 30.185 + np->rx_target = target; 30.186 + break; 30.187 + case TARGET_CUR: 30.188 + break; 30.189 + } 30.190 + 30.191 + network_alloc_rx_buffers(dev); 30.192 + 30.193 + spin_unlock(&np->rx_lock); 30.194 + 30.195 + return count; 30.196 +} 30.197 + 30.198 +static int xennet_proc_init(void) 30.199 +{ 30.200 + if (proc_mkdir("xen/net", NULL) == NULL) 30.201 + return -ENOMEM; 30.202 + return 0; 30.203 +} 30.204 + 30.205 +static int xennet_proc_addif(struct net_device *dev) 30.206 +{ 30.207 + struct proc_dir_entry *dir, *min, *max, *cur; 30.208 + char name[30]; 30.209 + 30.210 + sprintf(name, "xen/net/%s", dev->name); 30.211 + 30.212 + dir = proc_mkdir(name, NULL); 30.213 + if (!dir) 30.214 + goto nomem; 30.215 + 30.216 + min = create_proc_entry("rxbuf_min", 0644, dir); 30.217 + max = create_proc_entry("rxbuf_max", 0644, dir); 30.218 + cur = create_proc_entry("rxbuf_cur", 0444, dir); 30.219 + if (!min || !max || !cur) 30.220 + goto nomem; 30.221 + 30.222 + min->read_proc = xennet_proc_read; 30.223 + min->write_proc = xennet_proc_write; 30.224 + min->data = (void *)((unsigned long)dev | TARGET_MIN); 30.225 + 30.226 + max->read_proc = xennet_proc_read; 30.227 + max->write_proc = xennet_proc_write; 30.228 + max->data = (void *)((unsigned long)dev | TARGET_MAX); 30.229 + 30.230 + cur->read_proc = xennet_proc_read; 30.231 + cur->write_proc = xennet_proc_write; 30.232 + cur->data = (void *)((unsigned long)dev | TARGET_CUR); 30.233 + 30.234 + return 0; 30.235 + 30.236 + nomem: 30.237 + xennet_proc_delif(dev); 30.238 + return -ENOMEM; 30.239 +} 30.240 + 30.241 +static void xennet_proc_delif(struct net_device *dev) 30.242 +{ 30.243 + char name[30]; 30.244 + 30.245 + sprintf(name, "xen/net/%s/rxbuf_min", dev->name); 30.246 + remove_proc_entry(name, NULL); 30.247 + 30.248 + sprintf(name, "xen/net/%s/rxbuf_max", dev->name); 30.249 + remove_proc_entry(name, NULL); 30.250 + 30.251 + sprintf(name, "xen/net/%s/rxbuf_cur", dev->name); 30.252 + remove_proc_entry(name, NULL); 30.253 + 30.254 + sprintf(name, "xen/net/%s", dev->name); 30.255 + remove_proc_entry(name, NULL); 30.256 +} 30.257 + 30.258 +#endif 30.259 30.260 module_init(netif_init); 30.261 -
31.1 --- a/linux-2.6.11-xen-sparse/drivers/xen/privcmd/privcmd.c Tue May 03 12:52:47 2005 +0000 31.2 +++ b/linux-2.6.11-xen-sparse/drivers/xen/privcmd/privcmd.c Fri May 06 17:04:27 2005 +0000 31.3 @@ -219,9 +219,6 @@ static struct file_operations privcmd_fi 31.4 31.5 static int __init privcmd_init(void) 31.6 { 31.7 - if ( !(xen_start_info.flags & SIF_PRIVILEGED) ) 31.8 - return 0; 31.9 - 31.10 privcmd_intf = create_xen_proc_entry("privcmd", 0400); 31.11 if ( privcmd_intf != NULL ) 31.12 privcmd_intf->proc_fops = &privcmd_file_ops;
32.1 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/fixmap.h Tue May 03 12:52:47 2005 +0000 32.2 +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/fixmap.h Fri May 06 17:04:27 2005 +0000 32.3 @@ -80,6 +80,7 @@ enum fixed_addresses { 32.4 #ifdef CONFIG_ACPI_BOOT 32.5 FIX_ACPI_BEGIN, 32.6 FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1, 32.7 + FIX_ACPI_RSDP_PAGE, 32.8 #endif 32.9 #ifdef CONFIG_PCI_MMCONFIG 32.10 FIX_PCIE_MCFG, 32.11 @@ -103,15 +104,9 @@ enum fixed_addresses { 32.12 32.13 extern void __set_fixmap (enum fixed_addresses idx, 32.14 unsigned long phys, pgprot_t flags); 32.15 -extern void __set_fixmap_ma (enum fixed_addresses idx, 32.16 - unsigned long mach, pgprot_t flags); 32.17 32.18 #define set_fixmap(idx, phys) \ 32.19 __set_fixmap(idx, phys, PAGE_KERNEL) 32.20 -#define set_fixmap_ma(idx, phys) \ 32.21 - __set_fixmap_ma(idx, phys, PAGE_KERNEL) 32.22 -#define set_fixmap_ma_ro(idx, phys) \ 32.23 - __set_fixmap_ma(idx, phys, PAGE_KERNEL_RO) 32.24 /* 32.25 * Some hardware wants to get fixmapped without caching. 32.26 */
33.1 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h Tue May 03 12:52:47 2005 +0000 33.2 +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h Fri May 06 17:04:27 2005 +0000 33.3 @@ -59,6 +59,9 @@ 33.4 #define LOCAL_TIMER_VECTOR 0xef 33.5 #endif 33.6 33.7 +#define SPURIOUS_APIC_VECTOR 0xff 33.8 +#define ERROR_APIC_VECTOR 0xfe 33.9 + 33.10 /* 33.11 * First APIC vector available to drivers: (vectors 0x30-0xee) 33.12 * we start at 0x31 to spread out vectors evenly between priority
34.1 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/fixmap.h Tue May 03 12:52:47 2005 +0000 34.2 +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/fixmap.h Fri May 06 17:04:27 2005 +0000 34.3 @@ -60,17 +60,8 @@ enum fixed_addresses { 34.4 extern void __set_fixmap (enum fixed_addresses idx, 34.5 unsigned long phys, pgprot_t flags); 34.6 34.7 -extern void __set_fixmap_ma (enum fixed_addresses idx, 34.8 - unsigned long mach, pgprot_t flags); 34.9 - 34.10 #define set_fixmap(idx, phys) \ 34.11 __set_fixmap(idx, phys, PAGE_KERNEL) 34.12 - 34.13 -#define set_fixmap_ma(idx, phys) \ 34.14 - __set_fixmap_ma(idx, phys, PAGE_KERNEL) 34.15 -#define set_fixmap_ma_ro(idx, phys) \ 34.16 - __set_fixmap_ma(idx, phys, PAGE_KERNEL_RO) 34.17 - 34.18 /* 34.19 * Some hardware wants to get fixmapped without caching. 34.20 */
35.1 --- a/linux-2.6.11-xen-sparse/mkbuildtree Tue May 03 12:52:47 2005 +0000 35.2 +++ b/linux-2.6.11-xen-sparse/mkbuildtree Fri May 06 17:04:27 2005 +0000 35.3 @@ -66,7 +66,7 @@ relative_lndir () 35.4 ( 35.5 cd $i 35.6 pref=`echo $i | sed -e 's#/[^/]*#../#g' -e 's#^\.##'` 35.7 - for j in `find . -type f -o -type l -maxdepth 1`; do 35.8 + for j in `find . -maxdepth 1 -type f -o -type l`; do 35.9 ln -sf ${pref}${REAL_DIR}/$i/$j ${SYMLINK_DIR}/$i/$j 35.10 done 35.11 )
36.1 --- a/tools/libxc/xc_domain.c Tue May 03 12:52:47 2005 +0000 36.2 +++ b/tools/libxc/xc_domain.c Fri May 06 17:04:27 2005 +0000 36.3 @@ -43,7 +43,7 @@ int xc_domain_create(int xc_handle, 36.4 goto fail; 36.5 } 36.6 36.7 - return err; 36.8 + return 0; 36.9 36.10 fail: 36.11 errno_saved = errno; 36.12 @@ -103,6 +103,7 @@ int xc_domain_getinfo(int xc_handle, 36.13 unsigned int nr_doms; 36.14 u32 next_domid = first_domid; 36.15 dom0_op_t op; 36.16 + int rc = 0; 36.17 36.18 for ( nr_doms = 0; nr_doms < max_doms; nr_doms++ ) 36.19 { 36.20 @@ -110,7 +111,7 @@ int xc_domain_getinfo(int xc_handle, 36.21 op.u.getdomaininfo.domain = (domid_t)next_domid; 36.22 op.u.getdomaininfo.exec_domain = 0; // FIX ME?!? 36.23 op.u.getdomaininfo.ctxt = NULL; /* no exec context info, thanks. */ 36.24 - if ( do_dom0_op(xc_handle, &op) < 0 ) 36.25 + if ( (rc = do_dom0_op(xc_handle, &op)) < 0 ) 36.26 break; 36.27 info->domid = (u16)op.u.getdomaininfo.domain; 36.28 36.29 @@ -137,6 +138,8 @@ int xc_domain_getinfo(int xc_handle, 36.30 info++; 36.31 } 36.32 36.33 + if(!nr_doms) return rc; 36.34 + 36.35 return nr_doms; 36.36 } 36.37
37.1 --- a/tools/libxc/xc_physdev.c Tue May 03 12:52:47 2005 +0000 37.2 +++ b/tools/libxc/xc_physdev.c Fri May 06 17:04:27 2005 +0000 37.3 @@ -16,14 +16,6 @@ int xc_physdev_pci_access_modify(int xc_ 37.4 int func, 37.5 int enable) 37.6 { 37.7 - dom0_op_t op; 37.8 - 37.9 - op.cmd = DOM0_PCIDEV_ACCESS; 37.10 - op.u.pcidev_access.domain = (domid_t)domid; 37.11 - op.u.pcidev_access.bus = bus; 37.12 - op.u.pcidev_access.dev = dev; 37.13 - op.u.pcidev_access.func = func; 37.14 - op.u.pcidev_access.enable = enable; 37.15 - 37.16 - return do_dom0_op(xc_handle, &op); 37.17 + errno = ENOSYS; 37.18 + return -1; 37.19 }
38.1 --- a/xen/Rules.mk Tue May 03 12:52:47 2005 +0000 38.2 +++ b/xen/Rules.mk Fri May 06 17:04:27 2005 +0000 38.3 @@ -28,7 +28,6 @@ OBJS += $(patsubst %.c,%.o,$(C_SRCS)) 38.4 ALL_OBJS := $(BASEDIR)/common/common.o 38.5 ALL_OBJS += $(BASEDIR)/drivers/char/driver.o 38.6 ALL_OBJS += $(BASEDIR)/drivers/acpi/driver.o 38.7 -ALL_OBJS += $(BASEDIR)/drivers/pci/driver.o 38.8 ALL_OBJS += $(BASEDIR)/arch/$(TARGET_ARCH)/arch.o 38.9 38.10
39.1 --- a/xen/arch/ia64/domain.c Tue May 03 12:52:47 2005 +0000 39.2 +++ b/xen/arch/ia64/domain.c Fri May 06 17:04:27 2005 +0000 39.3 @@ -621,8 +621,6 @@ int construct_dom0(struct domain *d, 39.4 unsigned long pkern_entry; 39.5 unsigned long pkern_end; 39.6 39.7 - extern void physdev_init_dom0(struct domain *); 39.8 - 39.9 //printf("construct_dom0: starting\n"); 39.10 /* Sanity! */ 39.11 #ifndef CLONE_DOMAIN0 39.12 @@ -755,12 +753,6 @@ int construct_dom0(struct domain *d, 39.13 #endif 39.14 console_endboot(strstr(cmdline, "tty0") != NULL); 39.15 39.16 - /* DOM0 gets access to everything. */ 39.17 -#ifdef CLONE_DOMAIN0 39.18 -if (d == dom0) 39.19 -#endif 39.20 - physdev_init_dom0(d); 39.21 - 39.22 set_bit(DF_CONSTRUCTED, &d->d_flags); 39.23 39.24 new_thread(ed, pkern_entry, 0, 0);
40.1 --- a/xen/arch/ia64/xenmisc.c Tue May 03 12:52:47 2005 +0000 40.2 +++ b/xen/arch/ia64/xenmisc.c Fri May 06 17:04:27 2005 +0000 40.3 @@ -133,73 +133,6 @@ void free_page_type(struct pfn_info *pag 40.4 } 40.5 40.6 /////////////////////////////// 40.7 -// from arch/x86/pci.c 40.8 -/////////////////////////////// 40.9 - 40.10 -int 40.11 -pcibios_prep_mwi (struct pci_dev *dev) 40.12 -{ 40.13 - dummy(); 40.14 -} 40.15 - 40.16 -/////////////////////////////// 40.17 -// from arch/x86/pci-irq.c 40.18 -/////////////////////////////// 40.19 - 40.20 -void pcibios_enable_irq(struct pci_dev *dev) 40.21 -{ 40.22 - dummy(); 40.23 -} 40.24 - 40.25 -/////////////////////////////// 40.26 -// from arch/ia64/pci-pc.c 40.27 -/////////////////////////////// 40.28 - 40.29 -#include <xen/pci.h> 40.30 - 40.31 -int pcibios_enable_device(struct pci_dev *dev, int mask) 40.32 -{ 40.33 - dummy(); 40.34 - return 0; 40.35 -} 40.36 - 40.37 -int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value) = NULL; 40.38 -int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value) = NULL; 40.39 - 40.40 -//struct pci_fixup pcibios_fixups[] = { { 0 } }; 40.41 -struct pci_fixup pcibios_fixups[] = { { 0 } }; 40.42 - 40.43 -void 40.44 -pcibios_align_resource(void *data, struct resource *res, 40.45 - unsigned long size, unsigned long align) 40.46 -{ 40.47 - dummy(); 40.48 -} 40.49 - 40.50 -void 40.51 -pcibios_update_resource(struct pci_dev *dev, struct resource *root, 40.52 - struct resource *res, int resource) 40.53 -{ 40.54 - dummy(); 40.55 -} 40.56 - 40.57 -void __devinit pcibios_fixup_bus(struct pci_bus *b) 40.58 -{ 40.59 - dummy(); 40.60 -} 40.61 - 40.62 -void __init pcibios_init(void) 40.63 -{ 40.64 - dummy(); 40.65 -} 40.66 - 40.67 -char * __devinit pcibios_setup(char *str) 40.68 -{ 40.69 - dummy(); 40.70 - return 0; 40.71 -} 40.72 - 40.73 -/////////////////////////////// 40.74 // from arch/ia64/traps.c 40.75 /////////////////////////////// 40.76 40.77 @@ -217,33 +150,6 @@ void dump_pageframe_info(struct domain * 40.78 } 40.79 40.80 /////////////////////////////// 40.81 -// from common/physdev.c 40.82 -/////////////////////////////// 40.83 -void 40.84 -physdev_init_dom0(struct domain *d) 40.85 -{ 40.86 -} 40.87 - 40.88 -int 40.89 -physdev_pci_access_modify(domid_t id, int bus, int dev, int func, int enable) 40.90 -{ 40.91 - return -EINVAL; 40.92 -} 40.93 - 40.94 -void physdev_modify_ioport_access_range(struct domain *d, int enable, 40.95 - int port, int num) 40.96 -{ 40.97 - printk("physdev_modify_ioport_access_range not implemented\n"); 40.98 - dummy(); 40.99 -} 40.100 - 40.101 -void physdev_destroy_state(struct domain *d) 40.102 -{ 40.103 - printk("physdev_destroy_state not implemented\n"); 40.104 - dummy(); 40.105 -} 40.106 - 40.107 -/////////////////////////////// 40.108 // called from arch/ia64/head.S 40.109 /////////////////////////////// 40.110
41.1 --- a/xen/arch/ia64/xensetup.c Tue May 03 12:52:47 2005 +0000 41.2 +++ b/xen/arch/ia64/xensetup.c Fri May 06 17:04:27 2005 +0000 41.3 @@ -69,9 +69,6 @@ unsigned char opt_pdb[10] = "none"; 41.4 unsigned int opt_tbuf_size = 10; 41.5 /* opt_sched: scheduler - default to Borrowed Virtual Time */ 41.6 char opt_sched[10] = "bvt"; 41.7 -/* opt_physdev_dom0_hide: list of PCI slots to hide from domain 0. */ 41.8 -/* Format is '(%02x:%02x.%1x)(%02x:%02x.%1x)' and so on. */ 41.9 -char opt_physdev_dom0_hide[200] = ""; 41.10 /* opt_leveltrigger, opt_edgetrigger: Force an IO-APIC-routed IRQ to be */ 41.11 /* level- or edge-triggered. */ 41.12 /* Example: 'leveltrigger=4,5,6,20 edgetrigger=21'. */
43.1 --- a/xen/arch/x86/acpi.c Tue May 03 12:52:47 2005 +0000 43.2 +++ b/xen/arch/x86/acpi.c Fri May 06 17:04:27 2005 +0000 43.3 @@ -189,7 +189,7 @@ acpi_parse_lapic_nmi ( 43.4 43.5 #endif /*CONFIG_X86_LOCAL_APIC*/ 43.6 43.7 -#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER) 43.8 +#if defined(CONFIG_X86_IO_APIC) /*&& defined(CONFIG_ACPI_INTERPRETER)*/ 43.9 43.10 static int __init 43.11 acpi_parse_ioapic ( 43.12 @@ -211,6 +211,7 @@ acpi_parse_ioapic ( 43.13 return 0; 43.14 } 43.15 43.16 +#ifdef CONFIG_ACPI_INTERPRETER 43.17 /* 43.18 * Parse Interrupt Source Override for the ACPI SCI 43.19 */ 43.20 @@ -244,6 +245,7 @@ acpi_sci_ioapic_setup(u32 gsi, u16 polar 43.21 acpi_sci_override_gsi = gsi; 43.22 return; 43.23 } 43.24 +#endif 43.25 43.26 static int __init 43.27 acpi_parse_fadt(unsigned long phys, unsigned long size) 43.28 @@ -277,11 +279,13 @@ acpi_parse_int_src_ovr ( 43.29 43.30 acpi_table_print_madt_entry(header); 43.31 43.32 +#ifdef CONFIG_ACPI_INTERPRETER 43.33 if (intsrc->bus_irq == acpi_fadt.sci_int) { 43.34 acpi_sci_ioapic_setup(intsrc->global_irq, 43.35 intsrc->flags.polarity, intsrc->flags.trigger); 43.36 return 0; 43.37 } 43.38 +#endif 43.39 43.40 mp_override_legacy_irq ( 43.41 intsrc->bus_irq, 43.42 @@ -460,13 +464,14 @@ acpi_boot_init (void) 43.43 43.44 #endif /*CONFIG_X86_LOCAL_APIC*/ 43.45 43.46 -#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER) 43.47 +#if defined(CONFIG_X86_IO_APIC) /*&& defined(CONFIG_ACPI_INTERPRETER)*/ 43.48 43.49 /* 43.50 * I/O APIC 43.51 * -------- 43.52 */ 43.53 43.54 +#if 0 43.55 /* 43.56 * ACPI interpreter is required to complete interrupt setup, 43.57 * so if it is off, don't enumerate the io-apics with ACPI. 43.58 @@ -476,6 +481,7 @@ acpi_boot_init (void) 43.59 if (acpi_disabled || acpi_noirq) { 43.60 return 1; 43.61 } 43.62 +#endif 43.63 43.64 /* 43.65 * if "noapic" boot option, don't look for IO-APICs 43.66 @@ -510,12 +516,14 @@ acpi_boot_init (void) 43.67 return result; 43.68 } 43.69 43.70 +#ifdef CONFIG_ACPI_INTERPRETER 43.71 /* 43.72 * If BIOS did not supply an INT_SRC_OVR for the SCI 43.73 * pretend we got one so we can set the SCI flags. 43.74 */ 43.75 if (!acpi_sci_override_gsi) 43.76 acpi_sci_ioapic_setup(acpi_fadt.sci_int, 0, 0); 43.77 +#endif 43.78 43.79 result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src); 43.80 if (result < 0) {
44.1 --- a/xen/arch/x86/domain.c Tue May 03 12:52:47 2005 +0000 44.2 +++ b/xen/arch/x86/domain.c Fri May 06 17:04:27 2005 +0000 44.3 @@ -37,6 +37,7 @@ 44.4 #include <asm/vmx.h> 44.5 #include <asm/vmx_vmcs.h> 44.6 #include <asm/msr.h> 44.7 +#include <asm/physdev.h> 44.8 #include <xen/kernel.h> 44.9 #include <public/io/ioreq.h> 44.10 #include <xen/multicall.h> 44.11 @@ -968,6 +969,8 @@ void domain_relinquish_resources(struct 44.12 44.13 BUG_ON(d->cpuset != 0); 44.14 44.15 + physdev_destroy_state(d); 44.16 + 44.17 ptwr_destroy(d); 44.18 44.19 /* Release device mappings of other domains */
45.1 --- a/xen/arch/x86/io_apic.c Tue May 03 12:52:47 2005 +0000 45.2 +++ b/xen/arch/x86/io_apic.c Fri May 06 17:04:27 2005 +0000 45.3 @@ -313,46 +313,6 @@ static int __init find_isa_irq_pin(int i 45.4 */ 45.5 static int pin_2_irq(int idx, int apic, int pin); 45.6 45.7 -int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) 45.8 -{ 45.9 - int apic, i, best_guess = -1; 45.10 - 45.11 - Dprintk("querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n", 45.12 - bus, slot, pin); 45.13 - if ((mp_bus_id_to_pci_bus==NULL) || (mp_bus_id_to_pci_bus[bus] == -1)) { 45.14 - printk(KERN_WARNING "PCI BIOS passed nonexistent PCI bus %d!\n", bus); 45.15 - return -1; 45.16 - } 45.17 - for (i = 0; i < mp_irq_entries; i++) { 45.18 - int lbus = mp_irqs[i].mpc_srcbus; 45.19 - 45.20 - for (apic = 0; apic < nr_ioapics; apic++) 45.21 - if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic || 45.22 - mp_irqs[i].mpc_dstapic == MP_APIC_ALL) 45.23 - break; 45.24 - 45.25 - if ((mp_bus_id_to_type[lbus] == MP_BUS_PCI) && 45.26 - !mp_irqs[i].mpc_irqtype && 45.27 - (bus == lbus) && 45.28 - (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f))) { 45.29 - int irq = pin_2_irq(i,apic,mp_irqs[i].mpc_dstirq); 45.30 - 45.31 - if (!(apic || IO_APIC_IRQ(irq))) 45.32 - continue; 45.33 - 45.34 - if (pin == (mp_irqs[i].mpc_srcbusirq & 3)) 45.35 - return irq; 45.36 - /* 45.37 - * Use the first all-but-pin matching entry as a 45.38 - * best-guess fuzzy result for broken mptables. 45.39 - */ 45.40 - if (best_guess < 0) 45.41 - best_guess = irq; 45.42 - } 45.43 - } 45.44 - return best_guess; 45.45 -} 45.46 - 45.47 /* 45.48 * EISA Edge/Level control register, ELCR 45.49 */ 45.50 @@ -615,11 +575,9 @@ static inline int IO_APIC_irq_trigger(in 45.51 45.52 int irq_vector[NR_IRQS] = { FIRST_DEVICE_VECTOR , 0 }; 45.53 45.54 -#ifdef CONFIG_VMX 45.55 int vector_irq[256]; 45.56 -#endif 45.57 45.58 -static int __init assign_irq_vector(int irq) 45.59 +int assign_irq_vector(int irq) 45.60 { 45.61 static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; 45.62 if (IO_APIC_VECTOR(irq) > 0) 45.63 @@ -641,10 +599,9 @@ next: 45.64 panic("ran out of interrupt sources!"); 45.65 45.66 IO_APIC_VECTOR(irq) = current_vector; 45.67 -#ifdef CONFIG_VMX 45.68 + 45.69 vector_irq[current_vector] = irq; 45.70 - printk("vector_irq[%x] = %d\n", current_vector, irq); 45.71 -#endif 45.72 + 45.73 return current_vector; 45.74 } 45.75 45.76 @@ -1627,6 +1584,16 @@ static inline void check_timer(void) 45.77 panic("IO-APIC + timer doesn't work! pester mingo@redhat.com"); 45.78 } 45.79 45.80 +#define NR_IOAPIC_BIOSIDS 256 45.81 +static u8 ioapic_biosid_to_apic_enum[NR_IOAPIC_BIOSIDS]; 45.82 +static void store_ioapic_biosid_mapping(void) 45.83 +{ 45.84 + u8 apic; 45.85 + memset(ioapic_biosid_to_apic_enum, ~0, NR_IOAPIC_BIOSIDS); 45.86 + for ( apic = 0; apic < nr_ioapics; apic++ ) 45.87 + ioapic_biosid_to_apic_enum[mp_ioapics[apic].mpc_apicid] = apic; 45.88 +} 45.89 + 45.90 /* 45.91 * 45.92 * IRQ's that are handled by the old PIC in all cases: 45.93 @@ -1646,6 +1613,8 @@ static inline void check_timer(void) 45.94 45.95 void __init setup_IO_APIC(void) 45.96 { 45.97 + store_ioapic_biosid_mapping(); 45.98 + 45.99 enable_IO_APIC(); 45.100 45.101 io_apic_irqs = ~PIC_IRQS; 45.102 @@ -1660,8 +1629,7 @@ void __init setup_IO_APIC(void) 45.103 setup_IO_APIC_irqs(); 45.104 init_IO_APIC_traps(); 45.105 check_timer(); 45.106 - if (!acpi_ioapic) 45.107 - print_IO_APIC(); 45.108 + print_IO_APIC(); 45.109 } 45.110 45.111 #endif /* CONFIG_X86_IO_APIC */ 45.112 @@ -1949,3 +1917,82 @@ static int __init ioapic_trigger_setup(v 45.113 } 45.114 45.115 __initcall(ioapic_trigger_setup); 45.116 + 45.117 +int ioapic_guest_read(int apicid, int address, u32 *pval) 45.118 +{ 45.119 + u32 val; 45.120 + int apicenum; 45.121 + struct IO_APIC_reg_00 reg_00; 45.122 + unsigned long flags; 45.123 + 45.124 + if ( (apicid >= NR_IOAPIC_BIOSIDS) || 45.125 + ((apicenum = ioapic_biosid_to_apic_enum[apicid]) >= nr_ioapics) ) 45.126 + return -EINVAL; 45.127 + 45.128 + spin_lock_irqsave(&ioapic_lock, flags); 45.129 + val = io_apic_read(apicenum, address); 45.130 + spin_unlock_irqrestore(&ioapic_lock, flags); 45.131 + 45.132 + /* Rewrite APIC ID to what the BIOS originally specified. */ 45.133 + if ( address == 0 ) 45.134 + { 45.135 + *(int *)®_00 = val; 45.136 + reg_00.ID = apicid; 45.137 + val = *(u32 *)®_00; 45.138 + } 45.139 + 45.140 + *pval = val; 45.141 + return 0; 45.142 +} 45.143 + 45.144 +int ioapic_guest_write(int apicid, int address, u32 val) 45.145 +{ 45.146 + int apicenum, pin, irq; 45.147 + struct IO_APIC_route_entry rte = { 0 }; 45.148 + struct irq_pin_list *entry; 45.149 + unsigned long flags; 45.150 + 45.151 + if ( (apicid >= NR_IOAPIC_BIOSIDS) || 45.152 + ((apicenum = ioapic_biosid_to_apic_enum[apicid]) >= nr_ioapics) ) 45.153 + return -EINVAL; 45.154 + 45.155 + /* Only write to the first half of a route entry. */ 45.156 + if ( (address < 0x10) || (address & 1) ) 45.157 + return 0; 45.158 + 45.159 + pin = (address - 0x10) >> 1; 45.160 + 45.161 + rte.dest.logical.logical_dest = target_cpus(); 45.162 + *(int *)&rte = val; 45.163 + 45.164 + if ( rte.vector >= FIRST_DEVICE_VECTOR ) 45.165 + { 45.166 + /* Is there a valid irq mapped to this vector? */ 45.167 + irq = vector_irq[rte.vector]; 45.168 + if ( !IO_APIC_IRQ(irq) ) 45.169 + return 0; 45.170 + 45.171 + /* Set the correct irq-handling type. */ 45.172 + irq_desc[irq].handler = rte.trigger ? 45.173 + &ioapic_level_irq_type: &ioapic_edge_irq_type; 45.174 + 45.175 + /* Record the pin<->irq mapping. */ 45.176 + for ( entry = &irq_2_pin[irq]; ; entry = &irq_2_pin[entry->next] ) 45.177 + { 45.178 + if ( (entry->apic == apicenum) && (entry->pin == pin) ) 45.179 + break; 45.180 + if ( !entry->next ) 45.181 + { 45.182 + add_pin_to_irq(irq, apicenum, pin); 45.183 + break; 45.184 + } 45.185 + } 45.186 + } 45.187 + 45.188 + spin_lock_irqsave(&ioapic_lock, flags); 45.189 + io_apic_write(apicenum, 0x10 + 2 * pin, *(((int *)&rte) + 0)); 45.190 + io_apic_write(apicenum, 0x11 + 2 * pin, *(((int *)&rte) + 1)); 45.191 + spin_unlock_irqrestore(&ioapic_lock, flags); 45.192 + 45.193 + return 0; 45.194 +}
46.1 --- a/xen/arch/x86/mpparse.c Tue May 03 12:52:47 2005 +0000 46.2 +++ b/xen/arch/x86/mpparse.c Fri May 06 17:04:27 2005 +0000 46.3 @@ -1017,7 +1017,7 @@ void __init mp_register_lapic ( 46.4 MP_processor_info(&processor); 46.5 } 46.6 46.7 -#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER) 46.8 +#if defined(CONFIG_X86_IO_APIC) /*&& defined(CONFIG_ACPI_INTERPRETER)*/ 46.9 46.10 #define MP_ISA_BUS 0 46.11 #define MP_MAX_IOAPIC_PIN 127 46.12 @@ -1085,7 +1085,7 @@ void __init mp_register_ioapic ( 46.13 mp_ioapic_routing[idx].irq_end = irq_base + 46.14 io_apic_get_redir_entries(idx); 46.15 46.16 - printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, " 46.17 + printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " 46.18 "IRQ %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, 46.19 mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr, 46.20 mp_ioapic_routing[idx].irq_start,
47.1 --- a/xen/arch/x86/mtrr/generic.c Tue May 03 12:52:47 2005 +0000 47.2 +++ b/xen/arch/x86/mtrr/generic.c Fri May 06 17:04:27 2005 +0000 47.3 @@ -1,8 +1,8 @@ 47.4 /* This only handles 32bit MTRR on 32bit hosts. This is strictly wrong 47.5 because MTRRs can span upto 40 bits (36bits on most modern x86) */ 47.6 #include <xen/init.h> 47.7 +#include <xen/mm.h> 47.8 #include <xen/slab.h> 47.9 -#include <xen/mm.h> 47.10 #include <asm/io.h> 47.11 #include <asm/mtrr.h> 47.12 #include <asm/msr.h>
48.1 --- a/xen/arch/x86/pci-irq.c Tue May 03 12:52:47 2005 +0000 48.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 48.3 @@ -1,1084 +0,0 @@ 48.4 -/* 48.5 - * Low-Level PCI Support for PC -- Routing of Interrupts 48.6 - * 48.7 - * (c) 1999--2000 Martin Mares <mj@ucw.cz> 48.8 - */ 48.9 - 48.10 -#include <xen/config.h> 48.11 -#include <xen/types.h> 48.12 -#include <xen/kernel.h> 48.13 -#include <xen/pci.h> 48.14 -#include <xen/init.h> 48.15 -#include <xen/slab.h> 48.16 -#include <xen/irq.h> 48.17 -#include <asm/io.h> 48.18 -#include <asm/smp.h> 48.19 -#include <asm/io_apic.h> 48.20 -#include "pci-x86.h" 48.21 - 48.22 -#define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24)) 48.23 -#define PIRQ_VERSION 0x0100 48.24 - 48.25 -int broken_hp_bios_irq9; 48.26 - 48.27 -static struct irq_routing_table *pirq_table; 48.28 - 48.29 -/* 48.30 - * Never use: 0, 1, 2 (timer, keyboard, and cascade) 48.31 - * Avoid using: 13, 14 and 15 (FP error and IDE). 48.32 - * Penalize: 3, 4, 6, 7, 12 (known ISA uses: serial, floppy, parallel and mouse) 48.33 - */ 48.34 -unsigned int pcibios_irq_mask = 0xfff8; 48.35 - 48.36 -static int pirq_penalty[16] = { 48.37 - 1000000, 1000000, 1000000, 1000, 1000, 0, 1000, 1000, 48.38 - 0, 0, 0, 0, 1000, 100000, 100000, 100000 48.39 -}; 48.40 - 48.41 -struct irq_router { 48.42 - char *name; 48.43 - u16 vendor, device; 48.44 - int (*get)(struct pci_dev *router, struct pci_dev *dev, int pirq); 48.45 - int (*set)(struct pci_dev *router, struct pci_dev *dev, int pirq, int new); 48.46 -}; 48.47 - 48.48 -struct irq_router_handler { 48.49 - u16 vendor; 48.50 - int (*probe)(struct irq_router *r, struct pci_dev *router, u16 device); 48.51 -}; 48.52 - 48.53 -/* 48.54 - * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. 48.55 - */ 48.56 - 48.57 -static struct irq_routing_table * __init pirq_find_routing_table(void) 48.58 -{ 48.59 - u8 *addr; 48.60 - struct irq_routing_table *rt; 48.61 - int i; 48.62 - u8 sum; 48.63 - 48.64 - for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) { 48.65 - rt = (struct irq_routing_table *) addr; 48.66 - if (rt->signature != PIRQ_SIGNATURE || 48.67 - rt->version != PIRQ_VERSION || 48.68 - rt->size % 16 || 48.69 - rt->size < sizeof(struct irq_routing_table)) 48.70 - continue; 48.71 - sum = 0; 48.72 - for(i=0; i<rt->size; i++) 48.73 - sum += addr[i]; 48.74 - if (!sum) { 48.75 - DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); 48.76 - return rt; 48.77 - } 48.78 - } 48.79 - return NULL; 48.80 -} 48.81 - 48.82 -/* 48.83 - * If we have a IRQ routing table, use it to search for peer host 48.84 - * bridges. It's a gross hack, but since there are no other known 48.85 - * ways how to get a list of buses, we have to go this way. 48.86 - */ 48.87 - 48.88 -static void __init pirq_peer_trick(void) 48.89 -{ 48.90 - struct irq_routing_table *rt = pirq_table; 48.91 - u8 busmap[256]; 48.92 - int i; 48.93 - struct irq_info *e; 48.94 - 48.95 - memset(busmap, 0, sizeof(busmap)); 48.96 - for(i=0; i < (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); i++) { 48.97 - e = &rt->slots[i]; 48.98 -#ifdef DEBUG 48.99 - { 48.100 - int j; 48.101 - DBG("%02x:%02x slot=%02x", e->bus, e->devfn/8, e->slot); 48.102 - for(j=0; j<4; j++) 48.103 - DBG(" %d:%02x/%04x", j, e->irq[j].link, e->irq[j].bitmap); 48.104 - DBG("\n"); 48.105 - } 48.106 -#endif 48.107 - busmap[e->bus] = 1; 48.108 - } 48.109 - for(i=1; i<256; i++) 48.110 - /* 48.111 - * It might be a secondary bus, but in this case its parent is already 48.112 - * known (ascending bus order) and therefore pci_scan_bus returns immediately. 48.113 - */ 48.114 - if (busmap[i] && pci_scan_bus(i, pci_root_bus->ops, NULL)) 48.115 - printk(KERN_INFO "PCI: Discovered primary peer bus %02x [IRQ]\n", i); 48.116 - pcibios_last_bus = -1; 48.117 -} 48.118 - 48.119 -/* 48.120 - * Code for querying and setting of IRQ routes on various interrupt routers. 48.121 - */ 48.122 - 48.123 -void eisa_set_level_irq(unsigned int irq) 48.124 -{ 48.125 - unsigned char mask = 1 << (irq & 7); 48.126 - unsigned int port = 0x4d0 + (irq >> 3); 48.127 - unsigned char val = inb(port); 48.128 - 48.129 - if (!(val & mask)) { 48.130 - DBG(" -> edge"); 48.131 - outb(val | mask, port); 48.132 - } 48.133 -} 48.134 - 48.135 -/* 48.136 - * Common IRQ routing practice: nybbles in config space, 48.137 - * offset by some magic constant. 48.138 - */ 48.139 -static unsigned int read_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr) 48.140 -{ 48.141 - u8 x; 48.142 - unsigned reg = offset + (nr >> 1); 48.143 - 48.144 - pci_read_config_byte(router, reg, &x); 48.145 - return (nr & 1) ? (x >> 4) : (x & 0xf); 48.146 -} 48.147 - 48.148 -static void write_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr, unsigned int val) 48.149 -{ 48.150 - u8 x; 48.151 - unsigned reg = offset + (nr >> 1); 48.152 - 48.153 - pci_read_config_byte(router, reg, &x); 48.154 - x = (nr & 1) ? ((x & 0x0f) | (val << 4)) : ((x & 0xf0) | val); 48.155 - pci_write_config_byte(router, reg, x); 48.156 -} 48.157 - 48.158 -/* 48.159 - * ALI pirq entries are damn ugly, and completely undocumented. 48.160 - * This has been figured out from pirq tables, and it's not a pretty 48.161 - * picture. 48.162 - */ 48.163 -static int pirq_ali_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 48.164 -{ 48.165 - static unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 }; 48.166 - 48.167 - return irqmap[read_config_nybble(router, 0x48, pirq-1)]; 48.168 -} 48.169 - 48.170 -static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 48.171 -{ 48.172 - static unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 }; 48.173 - unsigned int val = irqmap[irq]; 48.174 - 48.175 - if (val) { 48.176 - write_config_nybble(router, 0x48, pirq-1, val); 48.177 - return 1; 48.178 - } 48.179 - return 0; 48.180 -} 48.181 - 48.182 -/* 48.183 - * The Intel PIIX4 pirq rules are fairly simple: "pirq" is 48.184 - * just a pointer to the config space. 48.185 - */ 48.186 -static int pirq_piix_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 48.187 -{ 48.188 - u8 x; 48.189 - 48.190 - pci_read_config_byte(router, pirq, &x); 48.191 - return (x < 16) ? x : 0; 48.192 -} 48.193 - 48.194 -static int pirq_piix_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 48.195 -{ 48.196 - pci_write_config_byte(router, pirq, irq); 48.197 - return 1; 48.198 -} 48.199 - 48.200 -/* 48.201 - * The VIA pirq rules are nibble-based, like ALI, 48.202 - * but without the ugly irq number munging. 48.203 - * However, PIRQD is in the upper instead of lower nibble. 48.204 - */ 48.205 -static int pirq_via_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 48.206 -{ 48.207 - return read_config_nybble(router, 0x55, pirq == 4 ? 5 : pirq); 48.208 -} 48.209 - 48.210 -static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 48.211 -{ 48.212 - write_config_nybble(router, 0x55, pirq == 4 ? 5 : pirq, irq); 48.213 - return 1; 48.214 -} 48.215 - 48.216 -/* 48.217 - * ITE 8330G pirq rules are nibble-based 48.218 - * FIXME: pirqmap may be { 1, 0, 3, 2 }, 48.219 - * 2+3 are both mapped to irq 9 on my system 48.220 - */ 48.221 -static int pirq_ite_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 48.222 -{ 48.223 - static unsigned char pirqmap[4] = { 1, 0, 2, 3 }; 48.224 - return read_config_nybble(router,0x43, pirqmap[pirq-1]); 48.225 -} 48.226 - 48.227 -static int pirq_ite_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 48.228 -{ 48.229 - static unsigned char pirqmap[4] = { 1, 0, 2, 3 }; 48.230 - write_config_nybble(router, 0x43, pirqmap[pirq-1], irq); 48.231 - return 1; 48.232 -} 48.233 - 48.234 -/* 48.235 - * OPTI: high four bits are nibble pointer.. 48.236 - * I wonder what the low bits do? 48.237 - */ 48.238 -static int pirq_opti_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 48.239 -{ 48.240 - return read_config_nybble(router, 0xb8, pirq >> 4); 48.241 -} 48.242 - 48.243 -static int pirq_opti_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 48.244 -{ 48.245 - write_config_nybble(router, 0xb8, pirq >> 4, irq); 48.246 - return 1; 48.247 -} 48.248 - 48.249 -/* 48.250 - * Cyrix: nibble offset 0x5C 48.251 - */ 48.252 -static int pirq_cyrix_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 48.253 -{ 48.254 - return read_config_nybble(router, 0x5C, (pirq-1)^1); 48.255 -} 48.256 - 48.257 -static int pirq_cyrix_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 48.258 -{ 48.259 - write_config_nybble(router, 0x5C, (pirq-1)^1, irq); 48.260 - return 1; 48.261 -} 48.262 - 48.263 -/* 48.264 - * PIRQ routing for SiS 85C503 router used in several SiS chipsets. 48.265 - * We have to deal with the following issues here: 48.266 - * - vendors have different ideas about the meaning of link values 48.267 - * - some onboard devices (integrated in the chipset) have special 48.268 - * links and are thus routed differently (i.e. not via PCI INTA-INTD) 48.269 - * - different revision of the router have a different layout for 48.270 - * the routing registers, particularly for the onchip devices 48.271 - * 48.272 - * For all routing registers the common thing is we have one byte 48.273 - * per routeable link which is defined as: 48.274 - * bit 7 IRQ mapping enabled (0) or disabled (1) 48.275 - * bits [6:4] reserved (sometimes used for onchip devices) 48.276 - * bits [3:0] IRQ to map to 48.277 - * allowed: 3-7, 9-12, 14-15 48.278 - * reserved: 0, 1, 2, 8, 13 48.279 - * 48.280 - * The config-space registers located at 0x41/0x42/0x43/0x44 are 48.281 - * always used to route the normal PCI INT A/B/C/D respectively. 48.282 - * Apparently there are systems implementing PCI routing table using 48.283 - * link values 0x01-0x04 and others using 0x41-0x44 for PCI INTA..D. 48.284 - * We try our best to handle both link mappings. 48.285 - * 48.286 - * Currently (2003-05-21) it appears most SiS chipsets follow the 48.287 - * definition of routing registers from the SiS-5595 southbridge. 48.288 - * According to the SiS 5595 datasheets the revision id's of the 48.289 - * router (ISA-bridge) should be 0x01 or 0xb0. 48.290 - * 48.291 - * Furthermore we've also seen lspci dumps with revision 0x00 and 0xb1. 48.292 - * Looks like these are used in a number of SiS 5xx/6xx/7xx chipsets. 48.293 - * They seem to work with the current routing code. However there is 48.294 - * some concern because of the two USB-OHCI HCs (original SiS 5595 48.295 - * had only one). YMMV. 48.296 - * 48.297 - * Onchip routing for router rev-id 0x01/0xb0 and probably 0x00/0xb1: 48.298 - * 48.299 - * 0x61: IDEIRQ: 48.300 - * bits [6:5] must be written 01 48.301 - * bit 4 channel-select primary (0), secondary (1) 48.302 - * 48.303 - * 0x62: USBIRQ: 48.304 - * bit 6 OHCI function disabled (0), enabled (1) 48.305 - * 48.306 - * 0x6a: ACPI/SCI IRQ: bits 4-6 reserved 48.307 - * 48.308 - * 0x7e: Data Acq. Module IRQ - bits 4-6 reserved 48.309 - * 48.310 - * We support USBIRQ (in addition to INTA-INTD) and keep the 48.311 - * IDE, ACPI and DAQ routing untouched as set by the BIOS. 48.312 - * 48.313 - * Currently the only reported exception is the new SiS 65x chipset 48.314 - * which includes the SiS 69x southbridge. Here we have the 85C503 48.315 - * router revision 0x04 and there are changes in the register layout 48.316 - * mostly related to the different USB HCs with USB 2.0 support. 48.317 - * 48.318 - * Onchip routing for router rev-id 0x04 (try-and-error observation) 48.319 - * 48.320 - * 0x60/0x61/0x62/0x63: 1xEHCI and 3xOHCI (companion) USB-HCs 48.321 - * bit 6-4 are probably unused, not like 5595 48.322 - */ 48.323 - 48.324 -#define PIRQ_SIS_IRQ_MASK 0x0f 48.325 -#define PIRQ_SIS_IRQ_DISABLE 0x80 48.326 -#define PIRQ_SIS_USB_ENABLE 0x40 48.327 -#define PIRQ_SIS_DETECT_REGISTER 0x40 48.328 - 48.329 -/* return value: 48.330 - * -1 on error 48.331 - * 0 for PCI INTA-INTD 48.332 - * 0 or enable bit mask to check or set for onchip functions 48.333 - */ 48.334 -static inline int pirq_sis5595_onchip(int pirq, int *reg) 48.335 -{ 48.336 - int ret = -1; 48.337 - 48.338 - *reg = pirq; 48.339 - switch(pirq) { 48.340 - case 0x01: 48.341 - case 0x02: 48.342 - case 0x03: 48.343 - case 0x04: 48.344 - *reg += 0x40; 48.345 - case 0x41: 48.346 - case 0x42: 48.347 - case 0x43: 48.348 - case 0x44: 48.349 - ret = 0; 48.350 - break; 48.351 - 48.352 - case 0x62: 48.353 - ret = PIRQ_SIS_USB_ENABLE; /* documented for 5595 */ 48.354 - break; 48.355 - 48.356 - case 0x61: 48.357 - case 0x6a: 48.358 - case 0x7e: 48.359 - printk(KERN_INFO "SiS pirq: IDE/ACPI/DAQ mapping not implemented: (%u)\n", 48.360 - (unsigned) pirq); 48.361 - /* fall thru */ 48.362 - default: 48.363 - printk(KERN_INFO "SiS router unknown request: (%u)\n", 48.364 - (unsigned) pirq); 48.365 - break; 48.366 - } 48.367 - return ret; 48.368 -} 48.369 - 48.370 -/* return value: 48.371 - * -1 on error 48.372 - * 0 for PCI INTA-INTD 48.373 - * 0 or enable bit mask to check or set for onchip functions 48.374 - */ 48.375 -static inline int pirq_sis96x_onchip(int pirq, int *reg) 48.376 -{ 48.377 - int ret = -1; 48.378 - 48.379 - *reg = pirq; 48.380 - switch(pirq) { 48.381 - case 0x01: 48.382 - case 0x02: 48.383 - case 0x03: 48.384 - case 0x04: 48.385 - *reg += 0x40; 48.386 - case 0x41: 48.387 - case 0x42: 48.388 - case 0x43: 48.389 - case 0x44: 48.390 - case 0x60: 48.391 - case 0x61: 48.392 - case 0x62: 48.393 - case 0x63: 48.394 - ret = 0; 48.395 - break; 48.396 - 48.397 - default: 48.398 - printk(KERN_INFO "SiS router unknown request: (%u)\n", 48.399 - (unsigned) pirq); 48.400 - break; 48.401 - } 48.402 - return ret; 48.403 -} 48.404 - 48.405 - 48.406 -static int pirq_sis5595_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 48.407 -{ 48.408 - u8 x; 48.409 - int reg, check; 48.410 - 48.411 - check = pirq_sis5595_onchip(pirq, ®); 48.412 - if (check < 0) 48.413 - return 0; 48.414 - 48.415 - pci_read_config_byte(router, reg, &x); 48.416 - if (check != 0 && !(x & check)) 48.417 - return 0; 48.418 - 48.419 - return (x & PIRQ_SIS_IRQ_DISABLE) ? 0 : (x & PIRQ_SIS_IRQ_MASK); 48.420 -} 48.421 - 48.422 -static int pirq_sis96x_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 48.423 -{ 48.424 - u8 x; 48.425 - int reg, check; 48.426 - 48.427 - check = pirq_sis96x_onchip(pirq, ®); 48.428 - if (check < 0) 48.429 - return 0; 48.430 - 48.431 - pci_read_config_byte(router, reg, &x); 48.432 - if (check != 0 && !(x & check)) 48.433 - return 0; 48.434 - 48.435 - return (x & PIRQ_SIS_IRQ_DISABLE) ? 0 : (x & PIRQ_SIS_IRQ_MASK); 48.436 -} 48.437 - 48.438 -static int pirq_sis5595_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 48.439 -{ 48.440 - u8 x; 48.441 - int reg, set; 48.442 - 48.443 - set = pirq_sis5595_onchip(pirq, ®); 48.444 - if (set < 0) 48.445 - return 0; 48.446 - 48.447 - x = (irq & PIRQ_SIS_IRQ_MASK); 48.448 - if (x == 0) 48.449 - x = PIRQ_SIS_IRQ_DISABLE; 48.450 - else 48.451 - x |= set; 48.452 - 48.453 - pci_write_config_byte(router, reg, x); 48.454 - 48.455 - return 1; 48.456 -} 48.457 - 48.458 -static int pirq_sis96x_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 48.459 -{ 48.460 - u8 x; 48.461 - int reg, set; 48.462 - 48.463 - set = pirq_sis96x_onchip(pirq, ®); 48.464 - if (set < 0) 48.465 - return 0; 48.466 - 48.467 - x = (irq & PIRQ_SIS_IRQ_MASK); 48.468 - if (x == 0) 48.469 - x = PIRQ_SIS_IRQ_DISABLE; 48.470 - else 48.471 - x |= set; 48.472 - 48.473 - pci_write_config_byte(router, reg, x); 48.474 - 48.475 - return 1; 48.476 -} 48.477 - 48.478 - 48.479 -/* 48.480 - * VLSI: nibble offset 0x74 - educated guess due to routing table and 48.481 - * config space of VLSI 82C534 PCI-bridge/router (1004:0102) 48.482 - * Tested on HP OmniBook 800 covering PIRQ 1, 2, 4, 8 for onboard 48.483 - * devices, PIRQ 3 for non-pci(!) soundchip and (untested) PIRQ 6 48.484 - * for the busbridge to the docking station. 48.485 - */ 48.486 - 48.487 -static int pirq_vlsi_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 48.488 -{ 48.489 - if (pirq > 8) { 48.490 - printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq); 48.491 - return 0; 48.492 - } 48.493 - return read_config_nybble(router, 0x74, pirq-1); 48.494 -} 48.495 - 48.496 -static int pirq_vlsi_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 48.497 -{ 48.498 - if (pirq > 8) { 48.499 - printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq); 48.500 - return 0; 48.501 - } 48.502 - write_config_nybble(router, 0x74, pirq-1, irq); 48.503 - return 1; 48.504 -} 48.505 - 48.506 -/* 48.507 - * ServerWorks: PCI interrupts mapped to system IRQ lines through Index 48.508 - * and Redirect I/O registers (0x0c00 and 0x0c01). The Index register 48.509 - * format is (PCIIRQ## | 0x10), e.g.: PCIIRQ10=0x1a. The Redirect 48.510 - * register is a straight binary coding of desired PIC IRQ (low nibble). 48.511 - * 48.512 - * The 'link' value in the PIRQ table is already in the correct format 48.513 - * for the Index register. There are some special index values: 48.514 - * 0x00 for ACPI (SCI), 0x01 for USB, 0x02 for IDE0, 0x04 for IDE1, 48.515 - * and 0x03 for SMBus. 48.516 - */ 48.517 -static int pirq_serverworks_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 48.518 -{ 48.519 - outb_p(pirq, 0xc00); 48.520 - return inb(0xc01) & 0xf; 48.521 -} 48.522 - 48.523 -static int pirq_serverworks_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 48.524 -{ 48.525 - outb_p(pirq, 0xc00); 48.526 - outb_p(irq, 0xc01); 48.527 - return 1; 48.528 -} 48.529 - 48.530 -/* Support for AMD756 PCI IRQ Routing 48.531 - * Jhon H. Caicedo <jhcaiced@osso.org.co> 48.532 - * Jun/21/2001 0.2.0 Release, fixed to use "nybble" functions... (jhcaiced) 48.533 - * Jun/19/2001 Alpha Release 0.1.0 (jhcaiced) 48.534 - * The AMD756 pirq rules are nibble-based 48.535 - * offset 0x56 0-3 PIRQA 4-7 PIRQB 48.536 - * offset 0x57 0-3 PIRQC 4-7 PIRQD 48.537 - */ 48.538 -static int pirq_amd756_get(struct pci_dev *router, struct pci_dev *dev, int pirq) 48.539 -{ 48.540 - u8 irq; 48.541 - irq = 0; 48.542 - if (pirq <= 4) 48.543 - { 48.544 - irq = read_config_nybble(router, 0x56, pirq - 1); 48.545 - } 48.546 - printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d get irq : %2d\n", 48.547 - dev->vendor, dev->device, pirq, irq); 48.548 - return irq; 48.549 -} 48.550 - 48.551 -static int pirq_amd756_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 48.552 -{ 48.553 - printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d SET irq : %2d\n", 48.554 - dev->vendor, dev->device, pirq, irq); 48.555 - if (pirq <= 4) 48.556 - { 48.557 - write_config_nybble(router, 0x56, pirq - 1, irq); 48.558 - } 48.559 - return 1; 48.560 -} 48.561 - 48.562 -#ifdef CONFIG_PCI_BIOS 48.563 - 48.564 -static int pirq_bios_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 48.565 -{ 48.566 - struct pci_dev *bridge; 48.567 - int pin = pci_get_interrupt_pin(dev, &bridge); 48.568 - return pcibios_set_irq_routing(bridge, pin, irq); 48.569 -} 48.570 - 48.571 -#endif 48.572 - 48.573 - 48.574 -static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 48.575 -{ 48.576 - /* We must not touch 440GX even if we have tables. 440GX has 48.577 - different IRQ routing weirdness */ 48.578 - if(pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0, NULL) || 48.579 - pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2, NULL)) 48.580 - return 0; 48.581 - switch(device) 48.582 - { 48.583 - case PCI_DEVICE_ID_INTEL_82371FB_0: 48.584 - case PCI_DEVICE_ID_INTEL_82371SB_0: 48.585 - case PCI_DEVICE_ID_INTEL_82371AB_0: 48.586 - case PCI_DEVICE_ID_INTEL_82371MX: 48.587 - case PCI_DEVICE_ID_INTEL_82443MX_0: 48.588 - case PCI_DEVICE_ID_INTEL_82801AA_0: 48.589 - case PCI_DEVICE_ID_INTEL_82801AB_0: 48.590 - case PCI_DEVICE_ID_INTEL_82801BA_0: 48.591 - case PCI_DEVICE_ID_INTEL_82801BA_10: 48.592 - case PCI_DEVICE_ID_INTEL_82801CA_0: 48.593 - case PCI_DEVICE_ID_INTEL_82801CA_12: 48.594 - case PCI_DEVICE_ID_INTEL_82801DB_0: 48.595 - case PCI_DEVICE_ID_INTEL_82801E_0: 48.596 - case PCI_DEVICE_ID_INTEL_82801EB_0: 48.597 - case PCI_DEVICE_ID_INTEL_ESB_0: 48.598 - case PCI_DEVICE_ID_INTEL_ICH6_0: 48.599 - r->name = "PIIX/ICH"; 48.600 - r->get = pirq_piix_get; 48.601 - r->set = pirq_piix_set; 48.602 - return 1; 48.603 - } 48.604 - return 0; 48.605 -} 48.606 - 48.607 -static __init int via_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 48.608 -{ 48.609 - /* FIXME: We should move some of the quirk fixup stuff here */ 48.610 - switch(device) 48.611 - { 48.612 - case PCI_DEVICE_ID_VIA_82C586_0: 48.613 - case PCI_DEVICE_ID_VIA_82C596: 48.614 - case PCI_DEVICE_ID_VIA_82C686: 48.615 - case PCI_DEVICE_ID_VIA_8231: 48.616 - /* FIXME: add new ones for 8233/5 */ 48.617 - r->name = "VIA"; 48.618 - r->get = pirq_via_get; 48.619 - r->set = pirq_via_set; 48.620 - return 1; 48.621 - } 48.622 - return 0; 48.623 -} 48.624 - 48.625 -static __init int vlsi_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 48.626 -{ 48.627 - switch(device) 48.628 - { 48.629 - case PCI_DEVICE_ID_VLSI_82C534: 48.630 - r->name = "VLSI 82C534"; 48.631 - r->get = pirq_vlsi_get; 48.632 - r->set = pirq_vlsi_set; 48.633 - return 1; 48.634 - } 48.635 - return 0; 48.636 -} 48.637 - 48.638 - 48.639 -static __init int serverworks_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 48.640 -{ 48.641 - switch(device) 48.642 - { 48.643 - case PCI_DEVICE_ID_SERVERWORKS_OSB4: 48.644 - case PCI_DEVICE_ID_SERVERWORKS_CSB5: 48.645 - r->name = "ServerWorks"; 48.646 - r->get = pirq_serverworks_get; 48.647 - r->set = pirq_serverworks_set; 48.648 - return 1; 48.649 - } 48.650 - return 0; 48.651 -} 48.652 - 48.653 -static __init int sis_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 48.654 -{ 48.655 - u8 reg; 48.656 - u16 devid; 48.657 - 48.658 - if (device != PCI_DEVICE_ID_SI_503) 48.659 - return 0; 48.660 - 48.661 - /* 48.662 - * In case of SiS south bridge, we need to detect the two 48.663 - * kinds of routing tables we have seen so far (5595 and 96x). 48.664 - * Since the maintain the same device ID, we need to do poke 48.665 - * the PCI configuration space to find the router type we are 48.666 - * dealing with. 48.667 - */ 48.668 - 48.669 - /* 48.670 - * Factoid: writing bit6 of register 0x40 of the router config space 48.671 - * will make the SB to show up 0x096x inside the device id. Note, 48.672 - * we need to restore register 0x40 after the device id poke. 48.673 - */ 48.674 - 48.675 - pci_read_config_byte(router, PIRQ_SIS_DETECT_REGISTER, ®); 48.676 - pci_write_config_byte(router, PIRQ_SIS_DETECT_REGISTER, reg | (1 << 6)); 48.677 - pci_read_config_word(router, PCI_DEVICE_ID, &devid); 48.678 - pci_write_config_byte(router, PIRQ_SIS_DETECT_REGISTER, reg); 48.679 - 48.680 - if ((devid & 0xfff0) == 0x0960) { 48.681 - r->name = "SIS96x"; 48.682 - r->get = pirq_sis96x_get; 48.683 - r->set = pirq_sis96x_set; 48.684 - DBG("PCI: Detecting SiS router at %02x:%02x : SiS096x detected\n", 48.685 - rt->rtr_bus, rt->rtr_devfn); 48.686 - } else { 48.687 - r->name = "SIS5595"; 48.688 - r->get = pirq_sis5595_get; 48.689 - r->set = pirq_sis5595_set; 48.690 - DBG("PCI: Detecting SiS router at %02x:%02x : SiS5595 detected\n", 48.691 - rt->rtr_bus, rt->rtr_devfn); 48.692 - } 48.693 - return 1; 48.694 -} 48.695 - 48.696 -static __init int cyrix_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 48.697 -{ 48.698 - switch(device) 48.699 - { 48.700 - case PCI_DEVICE_ID_CYRIX_5520: 48.701 - r->name = "NatSemi"; 48.702 - r->get = pirq_cyrix_get; 48.703 - r->set = pirq_cyrix_set; 48.704 - return 1; 48.705 - } 48.706 - return 0; 48.707 -} 48.708 - 48.709 -static __init int opti_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 48.710 -{ 48.711 - switch(device) 48.712 - { 48.713 - case PCI_DEVICE_ID_OPTI_82C700: 48.714 - r->name = "OPTI"; 48.715 - r->get = pirq_opti_get; 48.716 - r->set = pirq_opti_set; 48.717 - return 1; 48.718 - } 48.719 - return 0; 48.720 -} 48.721 - 48.722 -static __init int ite_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 48.723 -{ 48.724 - switch(device) 48.725 - { 48.726 - case PCI_DEVICE_ID_ITE_IT8330G_0: 48.727 - r->name = "ITE"; 48.728 - r->get = pirq_ite_get; 48.729 - r->set = pirq_ite_set; 48.730 - return 1; 48.731 - } 48.732 - return 0; 48.733 -} 48.734 - 48.735 -static __init int ali_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 48.736 -{ 48.737 - switch(device) 48.738 - { 48.739 - case PCI_DEVICE_ID_AL_M1533: 48.740 - r->name = "ALI"; 48.741 - r->get = pirq_ali_get; 48.742 - r->set = pirq_ali_set; 48.743 - return 1; 48.744 - /* Should add 156x some day */ 48.745 - } 48.746 - return 0; 48.747 -} 48.748 - 48.749 -static __init int amd_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) 48.750 -{ 48.751 - switch(device) 48.752 - { 48.753 - case PCI_DEVICE_ID_AMD_VIPER_740B: 48.754 - r->name = "AMD756"; 48.755 - break; 48.756 - case PCI_DEVICE_ID_AMD_VIPER_7413: 48.757 - r->name = "AMD766"; 48.758 - break; 48.759 - case PCI_DEVICE_ID_AMD_VIPER_7443: 48.760 - r->name = "AMD768"; 48.761 - break; 48.762 - default: 48.763 - return 0; 48.764 - } 48.765 - r->get = pirq_amd756_get; 48.766 - r->set = pirq_amd756_set; 48.767 - return 1; 48.768 -} 48.769 - 48.770 -static __initdata struct irq_router_handler pirq_routers[] = { 48.771 - { PCI_VENDOR_ID_INTEL, intel_router_probe }, 48.772 - { PCI_VENDOR_ID_AL, ali_router_probe }, 48.773 - { PCI_VENDOR_ID_ITE, ite_router_probe }, 48.774 - { PCI_VENDOR_ID_VIA, via_router_probe }, 48.775 - { PCI_VENDOR_ID_OPTI, opti_router_probe }, 48.776 - { PCI_VENDOR_ID_SI, sis_router_probe }, 48.777 - { PCI_VENDOR_ID_CYRIX, cyrix_router_probe }, 48.778 - { PCI_VENDOR_ID_VLSI, vlsi_router_probe }, 48.779 - { PCI_VENDOR_ID_SERVERWORKS, serverworks_router_probe }, 48.780 - { PCI_VENDOR_ID_AMD, amd_router_probe }, 48.781 - /* Someone with docs needs to add the ATI Radeon IGP */ 48.782 - { 0, NULL } 48.783 -}; 48.784 -static struct irq_router pirq_router; 48.785 -static struct pci_dev *pirq_router_dev; 48.786 - 48.787 -/* 48.788 - * FIXME: should we have an option to say "generic for 48.789 - * chipset" ? 48.790 - */ 48.791 - 48.792 -static void __init pirq_find_router(struct irq_router *r) 48.793 -{ 48.794 - struct irq_routing_table *rt = pirq_table; 48.795 - struct irq_router_handler *h; 48.796 - 48.797 -#ifdef CONFIG_PCI_BIOS 48.798 - if (!rt->signature) { 48.799 - printk(KERN_INFO "PCI: Using BIOS for IRQ routing\n"); 48.800 - r->set = pirq_bios_set; 48.801 - r->name = "BIOS"; 48.802 - return; 48.803 - } 48.804 -#endif 48.805 - 48.806 - /* Default unless a driver reloads it */ 48.807 - r->name = "default"; 48.808 - r->get = NULL; 48.809 - r->set = NULL; 48.810 - 48.811 - DBG("PCI: Attempting to find IRQ router for %04x:%04x\n", 48.812 - rt->rtr_vendor, rt->rtr_device); 48.813 - 48.814 - pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn); 48.815 - if (!pirq_router_dev) { 48.816 - DBG("PCI: Interrupt router not found at %02x:%02x\n", rt->rtr_bus, rt->rtr_devfn); 48.817 - return; 48.818 - } 48.819 - 48.820 - for( h = pirq_routers; h->vendor; h++) { 48.821 - /* First look for a router match */ 48.822 - if (rt->rtr_vendor == h->vendor && h->probe(r, pirq_router_dev, rt->rtr_device)) 48.823 - break; 48.824 - /* Fall back to a device match */ 48.825 - if (pirq_router_dev->vendor == h->vendor && h->probe(r, pirq_router_dev, pirq_router_dev->device)) 48.826 - break; 48.827 - } 48.828 - printk(KERN_INFO "PCI: Using IRQ router %s [%04x/%04x] at %s\n", 48.829 - pirq_router.name, 48.830 - pirq_router_dev->vendor, 48.831 - pirq_router_dev->device, 48.832 - pirq_router_dev->slot_name); 48.833 -} 48.834 - 48.835 -static struct irq_info *pirq_get_info(struct pci_dev *dev) 48.836 -{ 48.837 - struct irq_routing_table *rt = pirq_table; 48.838 - int entries = (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); 48.839 - struct irq_info *info; 48.840 - 48.841 - for (info = rt->slots; entries--; info++) 48.842 - if (info->bus == dev->bus->number && PCI_SLOT(info->devfn) == PCI_SLOT(dev->devfn)) 48.843 - return info; 48.844 - return NULL; 48.845 -} 48.846 - 48.847 -static int pcibios_lookup_irq(struct pci_dev *dev, int assign) 48.848 -{ 48.849 - u8 pin; 48.850 - struct irq_info *info; 48.851 - int i, pirq, newirq; 48.852 - int irq = 0; 48.853 - u32 mask; 48.854 - struct irq_router *r = &pirq_router; 48.855 - struct pci_dev *dev2; 48.856 - char *msg = NULL; 48.857 - 48.858 - if (!pirq_table) 48.859 - return 0; 48.860 - 48.861 - /* Find IRQ routing entry */ 48.862 - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); 48.863 - if (!pin) { 48.864 - DBG(" -> no interrupt pin\n"); 48.865 - return 0; 48.866 - } 48.867 - pin = pin - 1; 48.868 - 48.869 - DBG("IRQ for %s:%d", dev->slot_name, pin); 48.870 - info = pirq_get_info(dev); 48.871 - if (!info) { 48.872 - DBG(" -> not found in routing table\n"); 48.873 - return 0; 48.874 - } 48.875 - pirq = info->irq[pin].link; 48.876 - mask = info->irq[pin].bitmap; 48.877 - if (!pirq) { 48.878 - DBG(" -> not routed\n"); 48.879 - return 0; 48.880 - } 48.881 - DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, pirq_table->exclusive_irqs); 48.882 - mask &= pcibios_irq_mask; 48.883 - 48.884 - /* Work around broken HP Pavilion Notebooks which assign USB to 48.885 - IRQ 9 even though it is actually wired to IRQ 11 */ 48.886 - 48.887 - if (broken_hp_bios_irq9 && pirq == 0x59 && dev->irq == 9) { 48.888 - dev->irq = 11; 48.889 - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); 48.890 - r->set(pirq_router_dev, dev, pirq, 11); 48.891 - } 48.892 - 48.893 - /* 48.894 - * Find the best IRQ to assign: use the one 48.895 - * reported by the device if possible. 48.896 - */ 48.897 - newirq = dev->irq; 48.898 - if (!newirq && assign) { 48.899 - for (i = 0; i < 16; i++) { 48.900 - if (!(mask & (1 << i))) 48.901 - continue; 48.902 - if (pirq_penalty[i] < pirq_penalty[newirq] && 48.903 - pirq_guest_bindable(i,1)) 48.904 - newirq = i; 48.905 - } 48.906 - } 48.907 - DBG(" -> newirq=%d", newirq); 48.908 - 48.909 - /* Check if it is hardcoded */ 48.910 - if ((pirq & 0xf0) == 0xf0) { 48.911 - irq = pirq & 0xf; 48.912 - DBG(" -> hardcoded IRQ %d\n", irq); 48.913 - msg = "Hardcoded"; 48.914 - } else if (r->get && (irq = r->get(pirq_router_dev, dev, pirq))) { 48.915 - DBG(" -> got IRQ %d\n", irq); 48.916 - msg = "Found"; 48.917 - } else if (newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) { 48.918 - DBG(" -> assigning IRQ %d", newirq); 48.919 - if (r->set(pirq_router_dev, dev, pirq, newirq)) { 48.920 - eisa_set_level_irq(newirq); 48.921 - DBG(" ... OK\n"); 48.922 - msg = "Assigned"; 48.923 - irq = newirq; 48.924 - } 48.925 - } 48.926 - 48.927 - if (!irq) { 48.928 - DBG(" ... failed\n"); 48.929 - if (newirq && mask == (1 << newirq)) { 48.930 - msg = "Guessed"; 48.931 - irq = newirq; 48.932 - } else 48.933 - return 0; 48.934 - } 48.935 - printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, dev->slot_name); 48.936 - 48.937 - /* Update IRQ for all devices with the same pirq value */ 48.938 - pci_for_each_dev(dev2) { 48.939 - pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin); 48.940 - if (!pin) 48.941 - continue; 48.942 - pin--; 48.943 - info = pirq_get_info(dev2); 48.944 - if (!info) 48.945 - continue; 48.946 - if (info->irq[pin].link == pirq) { 48.947 - /* We refuse to override the dev->irq information. Give a warning! */ 48.948 - if (dev2->irq && dev2->irq != irq) { 48.949 - printk(KERN_INFO "IRQ routing conflict for %s, have irq %d, want irq %d\n", 48.950 - dev2->slot_name, dev2->irq, irq); 48.951 - continue; 48.952 - } 48.953 - dev2->irq = irq; 48.954 - pirq_penalty[irq]++; 48.955 - if (dev != dev2) 48.956 - printk(KERN_INFO "PCI: Sharing IRQ %d with %s\n", irq, dev2->slot_name); 48.957 - } 48.958 - } 48.959 - return 1; 48.960 -} 48.961 - 48.962 -void __init pcibios_irq_init(void) 48.963 -{ 48.964 - DBG("PCI: IRQ init\n"); 48.965 - pirq_table = pirq_find_routing_table(); 48.966 -#ifdef CONFIG_PCI_BIOS 48.967 - if (!pirq_table && (pci_probe & PCI_BIOS_IRQ_SCAN)) 48.968 - pirq_table = pcibios_get_irq_routing_table(); 48.969 -#endif 48.970 - if (pirq_table) { 48.971 - pirq_peer_trick(); 48.972 - pirq_find_router(&pirq_router); 48.973 - if (pirq_table->exclusive_irqs) { 48.974 - int i; 48.975 - for (i=0; i<16; i++) 48.976 - if (!(pirq_table->exclusive_irqs & (1 << i))) 48.977 - pirq_penalty[i] += 100; 48.978 - } 48.979 - /* If we're using the I/O APIC, avoid using the PCI IRQ routing table */ 48.980 - if (io_apic_assign_pci_irqs) 48.981 - pirq_table = NULL; 48.982 - } 48.983 -} 48.984 - 48.985 -void __init pcibios_fixup_irqs(void) 48.986 -{ 48.987 - struct pci_dev *dev; 48.988 - u8 pin; 48.989 - 48.990 - DBG("PCI: IRQ fixup\n"); 48.991 - pci_for_each_dev(dev) { 48.992 - /* 48.993 - * If the BIOS has set an out of range IRQ number, just ignore it. 48.994 - * Also keep track of which IRQ's are already in use. 48.995 - */ 48.996 - if (dev->irq >= 16) { 48.997 - DBG("%s: ignoring bogus IRQ %d\n", dev->slot_name, dev->irq); 48.998 - dev->irq = 0; 48.999 - } 48.1000 - /* If the IRQ is already assigned to a PCI device, ignore its ISA use penalty */ 48.1001 - if (pirq_penalty[dev->irq] >= 100 && pirq_penalty[dev->irq] < 100000) 48.1002 - pirq_penalty[dev->irq] = 0; 48.1003 - pirq_penalty[dev->irq]++; 48.1004 - } 48.1005 - 48.1006 - pci_for_each_dev(dev) { 48.1007 - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); 48.1008 -#ifdef CONFIG_X86_IO_APIC 48.1009 - /* 48.1010 - * Recalculate IRQ numbers if we use the I/O APIC. 48.1011 - */ 48.1012 - if (io_apic_assign_pci_irqs) 48.1013 - { 48.1014 - int irq; 48.1015 - 48.1016 - if (pin) { 48.1017 - pin--; /* interrupt pins are numbered starting from 1 */ 48.1018 - irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin); 48.1019 - /* 48.1020 - * Busses behind bridges are typically not listed in the MP-table. 48.1021 - * In this case we have to look up the IRQ based on the parent bus, 48.1022 - * parent slot, and pin number. The SMP code detects such bridged 48.1023 - * busses itself so we should get into this branch reliably. 48.1024 - */ 48.1025 - if (irq < 0 && dev->bus->parent) { /* go back to the bridge */ 48.1026 - struct pci_dev * bridge = dev->bus->self; 48.1027 - 48.1028 - pin = (pin + PCI_SLOT(dev->devfn)) % 4; 48.1029 - irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, 48.1030 - PCI_SLOT(bridge->devfn), pin); 48.1031 - if (irq >= 0) 48.1032 - printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n", 48.1033 - bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq); 48.1034 - } 48.1035 - if (irq >= 0) { 48.1036 - printk(KERN_INFO "PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n", 48.1037 - dev->bus->number, PCI_SLOT(dev->devfn), pin, irq); 48.1038 - dev->irq = irq; 48.1039 - } 48.1040 - } 48.1041 - } 48.1042 -#endif 48.1043 - /* 48.1044 - * Still no IRQ? Try to lookup one... 48.1045 - */ 48.1046 - if (pin && !dev->irq) 48.1047 - pcibios_lookup_irq(dev, 0); 48.1048 - } 48.1049 -} 48.1050 - 48.1051 -void pcibios_penalize_isa_irq(int irq) 48.1052 -{ 48.1053 - /* 48.1054 - * If any ISAPnP device reports an IRQ in its list of possible 48.1055 - * IRQ's, we try to avoid assigning it to PCI devices. 48.1056 - */ 48.1057 - pirq_penalty[irq] += 100; 48.1058 -} 48.1059 - 48.1060 -void pcibios_enable_irq(struct pci_dev *dev) 48.1061 -{ 48.1062 - u8 pin; 48.1063 - extern int interrupt_line_quirk; 48.1064 - 48.1065 - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); 48.1066 - if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) { 48.1067 - char *msg; 48.1068 - 48.1069 - /* With IDE legacy devices the IRQ lookup failure is not a problem.. */ 48.1070 - if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE && !(dev->class & 0x5)) 48.1071 - return; 48.1072 - 48.1073 - if (io_apic_assign_pci_irqs) 48.1074 - msg = " Probably buggy MP table."; 48.1075 - else if (pci_probe & PCI_BIOS_IRQ_SCAN) 48.1076 - msg = ""; 48.1077 - else 48.1078 - msg = " Please try using pci=biosirq."; 48.1079 - printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n", 48.1080 - 'A' + pin - 1, dev->slot_name, msg); 48.1081 - } 48.1082 - /* VIA bridges use interrupt line for apic/pci steering across 48.1083 - the V-Link */ 48.1084 - else if (interrupt_line_quirk) 48.1085 - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); 48.1086 - 48.1087 -}
49.1 --- a/xen/arch/x86/pci-pc.c Tue May 03 12:52:47 2005 +0000 49.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 49.3 @@ -1,1557 +0,0 @@ 49.4 -/* 49.5 - * Low-Level PCI Support for PC 49.6 - * 49.7 - * (c) 1999--2000 Martin Mares <mj@ucw.cz> 49.8 - */ 49.9 - 49.10 -#include <xen/config.h> 49.11 -#include <xen/types.h> 49.12 -#include <xen/kernel.h> 49.13 -#include <xen/sched.h> 49.14 -#include <xen/pci.h> 49.15 -#include <xen/init.h> 49.16 -#include <xen/ioport.h> 49.17 -#include <xen/acpi.h> 49.18 - 49.19 -/*#include <asm/segment.h>*/ 49.20 -#include <asm/io.h> 49.21 -#include <asm/smp.h> 49.22 -#include <asm/smpboot.h> 49.23 - 49.24 -#include "pci-x86.h" 49.25 - 49.26 -extern int numnodes; 49.27 -#define __KERNEL_CS __HYPERVISOR_CS 49.28 -#define __KERNEL_DS __HYPERVISOR_DS 49.29 - 49.30 -unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2; 49.31 - 49.32 -int pcibios_last_bus = -1; 49.33 -struct pci_bus *pci_root_bus = NULL; 49.34 -struct pci_ops *pci_root_ops = NULL; 49.35 - 49.36 -int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value) = NULL; 49.37 -int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value) = NULL; 49.38 - 49.39 -static int pci_using_acpi_prt = 0; 49.40 - 49.41 -#ifdef CONFIG_MULTIQUAD 49.42 -#define BUS2QUAD(global) (mp_bus_id_to_node[global]) 49.43 -#define BUS2LOCAL(global) (mp_bus_id_to_local[global]) 49.44 -#define QUADLOCAL2BUS(quad,local) (quad_local_to_mp_bus_id[quad][local]) 49.45 -#else 49.46 -#define BUS2QUAD(global) (0) 49.47 -#define BUS2LOCAL(global) (global) 49.48 -#define QUADLOCAL2BUS(quad,local) (local) 49.49 -#endif 49.50 - 49.51 -/* 49.52 - * This interrupt-safe spinlock protects all accesses to PCI 49.53 - * configuration space. 49.54 - */ 49.55 -static spinlock_t pci_config_lock = SPIN_LOCK_UNLOCKED; 49.56 - 49.57 - 49.58 -/* 49.59 - * Functions for accessing PCI configuration space with type 1 accesses 49.60 - */ 49.61 - 49.62 -#ifdef CONFIG_PCI_DIRECT 49.63 - 49.64 -#ifdef CONFIG_MULTIQUAD 49.65 -#define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \ 49.66 - (0x80000000 | (BUS2LOCAL(bus) << 16) | (dev << 11) | (fn << 8) | (reg & ~3)) 49.67 - 49.68 -static int pci_conf1_mq_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value) /* CONFIG_MULTIQUAD */ 49.69 -{ 49.70 - unsigned long flags; 49.71 - 49.72 - if (bus > 255 || dev > 31 || fn > 7 || reg > 255) 49.73 - return -EINVAL; 49.74 - 49.75 - spin_lock_irqsave(&pci_config_lock, flags); 49.76 - 49.77 - outl_quad(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8, BUS2QUAD(bus)); 49.78 - 49.79 - switch (len) { 49.80 - case 1: 49.81 - *value = inb_quad(0xCFC + (reg & 3), BUS2QUAD(bus)); 49.82 - break; 49.83 - case 2: 49.84 - *value = inw_quad(0xCFC + (reg & 2), BUS2QUAD(bus)); 49.85 - break; 49.86 - case 4: 49.87 - *value = inl_quad(0xCFC, BUS2QUAD(bus)); 49.88 - break; 49.89 - } 49.90 - 49.91 - spin_unlock_irqrestore(&pci_config_lock, flags); 49.92 - 49.93 - return 0; 49.94 -} 49.95 - 49.96 -static int pci_conf1_mq_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value) /* CONFIG_MULTIQUAD */ 49.97 -{ 49.98 - unsigned long flags; 49.99 - 49.100 - if (bus > 255 || dev > 31 || fn > 7 || reg > 255) 49.101 - return -EINVAL; 49.102 - 49.103 - spin_lock_irqsave(&pci_config_lock, flags); 49.104 - 49.105 - outl_quad(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8, BUS2QUAD(bus)); 49.106 - 49.107 - switch (len) { 49.108 - case 1: 49.109 - outb_quad((u8)value, 0xCFC + (reg & 3), BUS2QUAD(bus)); 49.110 - break; 49.111 - case 2: 49.112 - outw_quad((u16)value, 0xCFC + (reg & 2), BUS2QUAD(bus)); 49.113 - break; 49.114 - case 4: 49.115 - outl_quad((u32)value, 0xCFC, BUS2QUAD(bus)); 49.116 - break; 49.117 - } 49.118 - 49.119 - spin_unlock_irqrestore(&pci_config_lock, flags); 49.120 - 49.121 - return 0; 49.122 -} 49.123 - 49.124 -static int pci_conf1_read_mq_config_byte(struct pci_dev *dev, int where, u8 *value) 49.125 -{ 49.126 - int result; 49.127 - u32 data; 49.128 - 49.129 - result = pci_conf1_mq_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 49.130 - PCI_FUNC(dev->devfn), where, 1, &data); 49.131 - 49.132 - *value = (u8)data; 49.133 - 49.134 - return result; 49.135 -} 49.136 - 49.137 -static int pci_conf1_read_mq_config_word(struct pci_dev *dev, int where, u16 *value) 49.138 -{ 49.139 - int result; 49.140 - u32 data; 49.141 - 49.142 - result = pci_conf1_mq_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 49.143 - PCI_FUNC(dev->devfn), where, 2, &data); 49.144 - 49.145 - *value = (u16)data; 49.146 - 49.147 - return result; 49.148 -} 49.149 - 49.150 -static int pci_conf1_read_mq_config_dword(struct pci_dev *dev, int where, u32 *value) 49.151 -{ 49.152 - if (!value) 49.153 - return -EINVAL; 49.154 - 49.155 - return pci_conf1_mq_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 49.156 - PCI_FUNC(dev->devfn), where, 4, value); 49.157 -} 49.158 - 49.159 -static int pci_conf1_write_mq_config_byte(struct pci_dev *dev, int where, u8 value) 49.160 -{ 49.161 - return pci_conf1_mq_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 49.162 - PCI_FUNC(dev->devfn), where, 1, value); 49.163 -} 49.164 - 49.165 -static int pci_conf1_write_mq_config_word(struct pci_dev *dev, int where, u16 value) 49.166 -{ 49.167 - return pci_conf1_mq_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 49.168 - PCI_FUNC(dev->devfn), where, 2, value); 49.169 -} 49.170 - 49.171 -static int pci_conf1_write_mq_config_dword(struct pci_dev *dev, int where, u32 value) 49.172 -{ 49.173 - return pci_conf1_mq_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 49.174 - PCI_FUNC(dev->devfn), where, 4, value); 49.175 -} 49.176 - 49.177 -static struct pci_ops pci_direct_mq_conf1 = { 49.178 - pci_conf1_read_mq_config_byte, 49.179 - pci_conf1_read_mq_config_word, 49.180 - pci_conf1_read_mq_config_dword, 49.181 - pci_conf1_write_mq_config_byte, 49.182 - pci_conf1_write_mq_config_word, 49.183 - pci_conf1_write_mq_config_dword 49.184 -}; 49.185 - 49.186 -#endif /* !CONFIG_MULTIQUAD */ 49.187 -#define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \ 49.188 - (0x80000000 | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3)) 49.189 - 49.190 -static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value) /* !CONFIG_MULTIQUAD */ 49.191 -{ 49.192 - unsigned long flags; 49.193 - 49.194 - if (bus > 255 || dev > 31 || fn > 7 || reg > 255) 49.195 - return -EINVAL; 49.196 - 49.197 - spin_lock_irqsave(&pci_config_lock, flags); 49.198 - 49.199 - outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8); 49.200 - 49.201 - switch (len) { 49.202 - case 1: 49.203 - *value = inb(0xCFC + (reg & 3)); 49.204 - break; 49.205 - case 2: 49.206 - *value = inw(0xCFC + (reg & 2)); 49.207 - break; 49.208 - case 4: 49.209 - *value = inl(0xCFC); 49.210 - break; 49.211 - } 49.212 - 49.213 - spin_unlock_irqrestore(&pci_config_lock, flags); 49.214 - 49.215 - return 0; 49.216 -} 49.217 - 49.218 -static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value) /* !CONFIG_MULTIQUAD */ 49.219 -{ 49.220 - unsigned long flags; 49.221 - 49.222 - if ((bus > 255 || dev > 31 || fn > 7 || reg > 255)) 49.223 - return -EINVAL; 49.224 - 49.225 - spin_lock_irqsave(&pci_config_lock, flags); 49.226 - 49.227 - outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8); 49.228 - 49.229 - switch (len) { 49.230 - case 1: 49.231 - outb((u8)value, 0xCFC + (reg & 3)); 49.232 - break; 49.233 - case 2: 49.234 - outw((u16)value, 0xCFC + (reg & 2)); 49.235 - break; 49.236 - case 4: 49.237 - outl((u32)value, 0xCFC); 49.238 - break; 49.239 - } 49.240 - 49.241 - spin_unlock_irqrestore(&pci_config_lock, flags); 49.242 - 49.243 - return 0; 49.244 -} 49.245 - 49.246 -#undef PCI_CONF1_ADDRESS 49.247 - 49.248 -static int pci_conf1_read_config_byte(struct pci_dev *dev, int where, u8 *value) 49.249 -{ 49.250 - int result; 49.251 - u32 data; 49.252 - 49.253 - result = pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 49.254 - PCI_FUNC(dev->devfn), where, 1, &data); 49.255 - 49.256 - *value = (u8)data; 49.257 - 49.258 - return result; 49.259 -} 49.260 - 49.261 -static int pci_conf1_read_config_word(struct pci_dev *dev, int where, u16 *value) 49.262 -{ 49.263 - int result; 49.264 - u32 data; 49.265 - 49.266 - result = pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 49.267 - PCI_FUNC(dev->devfn), where, 2, &data); 49.268 - 49.269 - *value = (u16)data; 49.270 - 49.271 - return result; 49.272 -} 49.273 - 49.274 -static int pci_conf1_read_config_dword(struct pci_dev *dev, int where, u32 *value) 49.275 -{ 49.276 - return pci_conf1_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 49.277 - PCI_FUNC(dev->devfn), where, 4, value); 49.278 -} 49.279 - 49.280 -static int pci_conf1_write_config_byte(struct pci_dev *dev, int where, u8 value) 49.281 -{ 49.282 - return pci_conf1_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 49.283 - PCI_FUNC(dev->devfn), where, 1, value); 49.284 -} 49.285 - 49.286 -static int pci_conf1_write_config_word(struct pci_dev *dev, int where, u16 value) 49.287 -{ 49.288 - return pci_conf1_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 49.289 - PCI_FUNC(dev->devfn), where, 2, value); 49.290 -} 49.291 - 49.292 -static int pci_conf1_write_config_dword(struct pci_dev *dev, int where, u32 value) 49.293 -{ 49.294 - return pci_conf1_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 49.295 - PCI_FUNC(dev->devfn), where, 4, value); 49.296 -} 49.297 - 49.298 -static struct pci_ops pci_direct_conf1 = { 49.299 - pci_conf1_read_config_byte, 49.300 - pci_conf1_read_config_word, 49.301 - pci_conf1_read_config_dword, 49.302 - pci_conf1_write_config_byte, 49.303 - pci_conf1_write_config_word, 49.304 - pci_conf1_write_config_dword 49.305 -}; 49.306 - 49.307 - 49.308 -/* 49.309 - * Functions for accessing PCI configuration space with type 2 accesses 49.310 - */ 49.311 - 49.312 -#define PCI_CONF2_ADDRESS(dev, reg) (u16)(0xC000 | (dev << 8) | reg) 49.313 - 49.314 -static int pci_conf2_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value) 49.315 -{ 49.316 - unsigned long flags; 49.317 - 49.318 - if (bus > 255 || dev > 31 || fn > 7 || reg > 255) 49.319 - return -EINVAL; 49.320 - 49.321 - if (dev & 0x10) 49.322 - return PCIBIOS_DEVICE_NOT_FOUND; 49.323 - 49.324 - spin_lock_irqsave(&pci_config_lock, flags); 49.325 - 49.326 - outb((u8)(0xF0 | (fn << 1)), 0xCF8); 49.327 - outb((u8)bus, 0xCFA); 49.328 - 49.329 - switch (len) { 49.330 - case 1: 49.331 - *value = inb(PCI_CONF2_ADDRESS(dev, reg)); 49.332 - break; 49.333 - case 2: 49.334 - *value = inw(PCI_CONF2_ADDRESS(dev, reg)); 49.335 - break; 49.336 - case 4: 49.337 - *value = inl(PCI_CONF2_ADDRESS(dev, reg)); 49.338 - break; 49.339 - } 49.340 - 49.341 - outb (0, 0xCF8); 49.342 - 49.343 - spin_unlock_irqrestore(&pci_config_lock, flags); 49.344 - 49.345 - return 0; 49.346 -} 49.347 - 49.348 -static int pci_conf2_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value) 49.349 -{ 49.350 - unsigned long flags; 49.351 - 49.352 - if ((bus > 255 || dev > 31 || fn > 7 || reg > 255)) 49.353 - return -EINVAL; 49.354 - 49.355 - if (dev & 0x10) 49.356 - return PCIBIOS_DEVICE_NOT_FOUND; 49.357 - 49.358 - spin_lock_irqsave(&pci_config_lock, flags); 49.359 - 49.360 - outb((u8)(0xF0 | (fn << 1)), 0xCF8); 49.361 - outb((u8)bus, 0xCFA); 49.362 - 49.363 - switch (len) { 49.364 - case 1: 49.365 - outb ((u8)value, PCI_CONF2_ADDRESS(dev, reg)); 49.366 - break; 49.367 - case 2: 49.368 - outw ((u16)value, PCI_CONF2_ADDRESS(dev, reg)); 49.369 - break; 49.370 - case 4: 49.371 - outl ((u32)value, PCI_CONF2_ADDRESS(dev, reg)); 49.372 - break; 49.373 - } 49.374 - 49.375 - outb (0, 0xCF8); 49.376 - 49.377 - spin_unlock_irqrestore(&pci_config_lock, flags); 49.378 - 49.379 - return 0; 49.380 -} 49.381 - 49.382 -#undef PCI_CONF2_ADDRESS 49.383 - 49.384 -static int pci_conf2_read_config_byte(struct pci_dev *dev, int where, u8 *value) 49.385 -{ 49.386 - int result; 49.387 - u32 data; 49.388 - result = pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 49.389 - PCI_FUNC(dev->devfn), where, 1, &data); 49.390 - *value = (u8)data; 49.391 - return result; 49.392 -} 49.393 - 49.394 -static int pci_conf2_read_config_word(struct pci_dev *dev, int where, u16 *value) 49.395 -{ 49.396 - int result; 49.397 - u32 data; 49.398 - result = pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 49.399 - PCI_FUNC(dev->devfn), where, 2, &data); 49.400 - *value = (u16)data; 49.401 - return result; 49.402 -} 49.403 - 49.404 -static int pci_conf2_read_config_dword(struct pci_dev *dev, int where, u32 *value) 49.405 -{ 49.406 - return pci_conf2_read(0, dev->bus->number, PCI_SLOT(dev->devfn), 49.407 - PCI_FUNC(dev->devfn), where, 4, value); 49.408 -} 49.409 - 49.410 -static int pci_conf2_write_config_byte(struct pci_dev *dev, int where, u8 value) 49.411 -{ 49.412 - return pci_conf2_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 49.413 - PCI_FUNC(dev->devfn), where, 1, value); 49.414 -} 49.415 - 49.416 -static int pci_conf2_write_config_word(struct pci_dev *dev, int where, u16 value) 49.417 -{ 49.418 - return pci_conf2_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 49.419 - PCI_FUNC(dev->devfn), where, 2, value); 49.420 -} 49.421 - 49.422 -static int pci_conf2_write_config_dword(struct pci_dev *dev, int where, u32 value) 49.423 -{ 49.424 - return pci_conf2_write(0, dev->bus->number, PCI_SLOT(dev->devfn), 49.425 - PCI_FUNC(dev->devfn), where, 4, value); 49.426 -} 49.427 - 49.428 -static struct pci_ops pci_direct_conf2 = { 49.429 - pci_conf2_read_config_byte, 49.430 - pci_conf2_read_config_word, 49.431 - pci_conf2_read_config_dword, 49.432 - pci_conf2_write_config_byte, 49.433 - pci_conf2_write_config_word, 49.434 - pci_conf2_write_config_dword 49.435 -}; 49.436 - 49.437 - 49.438 -/* 49.439 - * Before we decide to use direct hardware access mechanisms, we try to do some 49.440 - * trivial checks to ensure it at least _seems_ to be working -- we just test 49.441 - * whether bus 00 contains a host bridge (this is similar to checking 49.442 - * techniques used in XFree86, but ours should be more reliable since we 49.443 - * attempt to make use of direct access hints provided by the PCI BIOS). 49.444 - * 49.445 - * This should be close to trivial, but it isn't, because there are buggy 49.446 - * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID. 49.447 - */ 49.448 -static int __devinit pci_sanity_check(struct pci_ops *o) 49.449 -{ 49.450 - u16 x; 49.451 - /* XEN: static is important to prevent stack overflow! */ 49.452 - static struct pci_bus bus; /* Fake bus and device */ 49.453 - static struct pci_dev dev; 49.454 - 49.455 - if (pci_probe & PCI_NO_CHECKS) 49.456 - return 1; 49.457 - bus.number = 0; 49.458 - dev.bus = &bus; 49.459 - for(dev.devfn=0; dev.devfn < 0x100; dev.devfn++) 49.460 - if ((!o->read_word(&dev, PCI_CLASS_DEVICE, &x) && 49.461 - (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)) || 49.462 - (!o->read_word(&dev, PCI_VENDOR_ID, &x) && 49.463 - (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ))) 49.464 - return 1; 49.465 - DBG("PCI: Sanity check failed\n"); 49.466 - return 0; 49.467 -} 49.468 - 49.469 -static struct pci_ops * __devinit pci_check_direct(void) 49.470 -{ 49.471 - unsigned int tmp; 49.472 - unsigned long flags; 49.473 - 49.474 - __save_flags(flags); __cli(); 49.475 - 49.476 - /* 49.477 - * Check if configuration type 1 works. 49.478 - */ 49.479 - if (pci_probe & PCI_PROBE_CONF1) { 49.480 - outb (0x01, 0xCFB); 49.481 - tmp = inl (0xCF8); 49.482 - outl (0x80000000, 0xCF8); 49.483 - if (inl (0xCF8) == 0x80000000 && 49.484 - pci_sanity_check(&pci_direct_conf1)) { 49.485 - outl (tmp, 0xCF8); 49.486 - __restore_flags(flags); 49.487 - printk(KERN_INFO "PCI: Using configuration type 1\n"); 49.488 - request_region(0xCF8, 8, "PCI conf1"); 49.489 - 49.490 -#ifdef CONFIG_MULTIQUAD 49.491 - /* Multi-Quad has an extended PCI Conf1 */ 49.492 - if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ) 49.493 - return &pci_direct_mq_conf1; 49.494 -#endif 49.495 - return &pci_direct_conf1; 49.496 - } 49.497 - outl (tmp, 0xCF8); 49.498 - } 49.499 - 49.500 - /* 49.501 - * Check if configuration type 2 works. 49.502 - */ 49.503 - if (pci_probe & PCI_PROBE_CONF2) { 49.504 - outb (0x00, 0xCFB); 49.505 - outb (0x00, 0xCF8); 49.506 - outb (0x00, 0xCFA); 49.507 - if (inb (0xCF8) == 0x00 && inb (0xCFA) == 0x00 && 49.508 - pci_sanity_check(&pci_direct_conf2)) { 49.509 - __restore_flags(flags); 49.510 - printk(KERN_INFO "PCI: Using configuration type 2\n"); 49.511 - request_region(0xCF8, 4, "PCI conf2"); 49.512 - return &pci_direct_conf2; 49.513 - } 49.514 - } 49.515 - 49.516 - __restore_flags(flags); 49.517 - return NULL; 49.518 -} 49.519 - 49.520 -#endif 49.521 - 49.522 -/* 49.523 - * BIOS32 and PCI BIOS handling. 49.524 - */ 49.525 - 49.526 -#ifdef CONFIG_PCI_BIOS 49.527 - 49.528 -#define PCIBIOS_PCI_FUNCTION_ID 0xb1XX 49.529 -#define PCIBIOS_PCI_BIOS_PRESENT 0xb101 49.530 -#define PCIBIOS_FIND_PCI_DEVICE 0xb102 49.531 -#define PCIBIOS_FIND_PCI_CLASS_CODE 0xb103 49.532 -#define PCIBIOS_GENERATE_SPECIAL_CYCLE 0xb106 49.533 -#define PCIBIOS_READ_CONFIG_BYTE 0xb108 49.534 -#define PCIBIOS_READ_CONFIG_WORD 0xb109 49.535 -#define PCIBIOS_READ_CONFIG_DWORD 0xb10a 49.536 -#define PCIBIOS_WRITE_CONFIG_BYTE 0xb10b 49.537 -#define PCIBIOS_WRITE_CONFIG_WORD 0xb10c 49.538 -#define PCIBIOS_WRITE_CONFIG_DWORD 0xb10d 49.539 -#define PCIBIOS_GET_ROUTING_OPTIONS 0xb10e 49.540 -#define PCIBIOS_SET_PCI_HW_INT 0xb10f 49.541 - 49.542 -/* BIOS32 signature: "_32_" */ 49.543 -#define BIOS32_SIGNATURE (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24)) 49.544 - 49.545 -/* PCI signature: "PCI " */