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
author xenbk@gandalf.hpl.hp.com
date Fri May 06 17:04:27 2005 +0000 (2005-05-06)
parents 356fb3de6e7b f1d19fea460b
children ddd290cc8f0d
files .rootkeys BitKeeper/etc/ignore BitKeeper/etc/logging_ok linux-2.4.29-xen-sparse/mkbuildtree linux-2.6.11-xen-sparse/arch/xen/Kconfig linux-2.6.11-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 linux-2.6.11-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 linux-2.6.11-xen-sparse/arch/xen/i386/Kconfig linux-2.6.11-xen-sparse/arch/xen/i386/kernel/Makefile linux-2.6.11-xen-sparse/arch/xen/i386/kernel/acpi/Makefile linux-2.6.11-xen-sparse/arch/xen/i386/kernel/acpi/boot.c linux-2.6.11-xen-sparse/arch/xen/i386/kernel/apic.c linux-2.6.11-xen-sparse/arch/xen/i386/kernel/io_apic.c linux-2.6.11-xen-sparse/arch/xen/i386/kernel/mpparse.c linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c linux-2.6.11-xen-sparse/arch/xen/i386/mm/init.c linux-2.6.11-xen-sparse/arch/xen/i386/mm/ioremap.c linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c linux-2.6.11-xen-sparse/arch/xen/i386/pci/Makefile linux-2.6.11-xen-sparse/arch/xen/i386/pci/direct.c linux-2.6.11-xen-sparse/arch/xen/i386/pci/irq.c linux-2.6.11-xen-sparse/arch/xen/kernel/gnttab.c linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c linux-2.6.11-xen-sparse/arch/xen/kernel/smp.c linux-2.6.11-xen-sparse/arch/xen/x86_64/Kconfig linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/init.c linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/ioremap.c linux-2.6.11-xen-sparse/drivers/acpi/tables.c linux-2.6.11-xen-sparse/drivers/xen/Makefile linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c linux-2.6.11-xen-sparse/drivers/xen/privcmd/privcmd.c linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/fixmap.h linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/fixmap.h linux-2.6.11-xen-sparse/mkbuildtree tools/libxc/xc_domain.c tools/libxc/xc_physdev.c xen/Rules.mk xen/arch/ia64/domain.c xen/arch/ia64/xenmisc.c xen/arch/ia64/xensetup.c xen/arch/x86/Makefile xen/arch/x86/acpi.c xen/arch/x86/domain.c xen/arch/x86/io_apic.c xen/arch/x86/mpparse.c xen/arch/x86/mtrr/generic.c xen/arch/x86/pci-irq.c xen/arch/x86/pci-pc.c xen/arch/x86/pci-x86.c xen/arch/x86/pci-x86.h xen/arch/x86/physdev.c xen/common/Makefile xen/common/dom0_ops.c xen/common/domain.c xen/common/physdev.c xen/drivers/Makefile xen/drivers/acpi/Makefile xen/drivers/acpi/acpi_ksyms.c xen/drivers/char/console.c xen/drivers/char/serial.c xen/drivers/pci/Makefile xen/drivers/pci/compat.c xen/drivers/pci/gen-devlist.c xen/drivers/pci/names.c xen/drivers/pci/pci.c xen/drivers/pci/pci.ids xen/drivers/pci/quirks.c xen/drivers/pci/setup-res.c xen/include/acpi/acdebug.h xen/include/acpi/acdisasm.h xen/include/acpi/acdispat.h xen/include/acpi/acevents.h xen/include/acpi/acinterp.h xen/include/acpi/acnamesp.h xen/include/acpi/acparser.h xen/include/acpi/acresrc.h xen/include/acpi/actables.h xen/include/acpi/actbl71.h xen/include/acpi/amlcode.h xen/include/acpi/amlresrc.h xen/include/asm-x86/config.h xen/include/asm-x86/debugger.h xen/include/asm-x86/io_apic.h xen/include/asm-x86/physdev.h xen/include/public/dom0_ops.h xen/include/public/physdev.h xen/include/xen/physdev.h xen/include/xen/sched.h xen/include/xen/slab.h
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(&notifier_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 *)&reg_00 = val;
  45.136 +        reg_00.ID = apicid;
  45.137 +        val = *(u32 *)&reg_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, &reg);
  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, &reg);
  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, &reg);
  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, &reg);
  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, &reg);
  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 " */