]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.116pre1 2.1.116pre1
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:16:18 +0000 (15:16 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:16:18 +0000 (15:16 -0500)
148 files changed:
CREDITS
Documentation/magic-number.txt
Documentation/radiotrack.txt [new file with mode: 0644]
Documentation/sound/ChangeLog.multisound [new file with mode: 0644]
Documentation/sound/MultiSound
Documentation/sound/OPL3-SA
Documentation/sound/Wavefront
MAINTAINERS
Makefile
arch/alpha/Makefile
arch/alpha/config.in
arch/alpha/defconfig
arch/alpha/kernel/Makefile
arch/alpha/kernel/alpha_ksyms.c
arch/alpha/kernel/apecs.c [deleted file]
arch/alpha/kernel/bios32.c
arch/alpha/kernel/bios32.h [new file with mode: 0644]
arch/alpha/kernel/cia.c [deleted file]
arch/alpha/kernel/core_apecs.c [new file with mode: 0644]
arch/alpha/kernel/core_cia.c [new file with mode: 0644]
arch/alpha/kernel/core_lca.c [new file with mode: 0644]
arch/alpha/kernel/core_mcpcia.c [new file with mode: 0644]
arch/alpha/kernel/core_pyxis.c [new file with mode: 0644]
arch/alpha/kernel/core_t2.c [new file with mode: 0644]
arch/alpha/kernel/core_tsunami.c [new file with mode: 0644]
arch/alpha/kernel/entry.S
arch/alpha/kernel/es1888.c [new file with mode: 0644]
arch/alpha/kernel/fpreg.c
arch/alpha/kernel/head.S
arch/alpha/kernel/irq.c
arch/alpha/kernel/irq.h [new file with mode: 0644]
arch/alpha/kernel/lca.c [deleted file]
arch/alpha/kernel/machvec.h [new file with mode: 0644]
arch/alpha/kernel/mcpcia.c [deleted file]
arch/alpha/kernel/osf_sys.c
arch/alpha/kernel/process.c
arch/alpha/kernel/proto.h [new file with mode: 0644]
arch/alpha/kernel/ptrace.c
arch/alpha/kernel/pyxis.c [deleted file]
arch/alpha/kernel/setup.c
arch/alpha/kernel/smp.c
arch/alpha/kernel/sys_alcor.c [new file with mode: 0644]
arch/alpha/kernel/sys_cabriolet.c [new file with mode: 0644]
arch/alpha/kernel/sys_dp264.c [new file with mode: 0644]
arch/alpha/kernel/sys_eb64p.c [new file with mode: 0644]
arch/alpha/kernel/sys_jensen.c [new file with mode: 0644]
arch/alpha/kernel/sys_miata.c [new file with mode: 0644]
arch/alpha/kernel/sys_mikasa.c [new file with mode: 0644]
arch/alpha/kernel/sys_noritake.c [new file with mode: 0644]
arch/alpha/kernel/sys_rawhide.c [new file with mode: 0644]
arch/alpha/kernel/sys_ruffian.c [new file with mode: 0644]
arch/alpha/kernel/sys_sable.c [new file with mode: 0644]
arch/alpha/kernel/sys_sio.c [new file with mode: 0644]
arch/alpha/kernel/sys_sx164.c [new file with mode: 0644]
arch/alpha/kernel/sys_takara.c [new file with mode: 0644]
arch/alpha/kernel/t2.c [deleted file]
arch/alpha/kernel/traps.c
arch/alpha/kernel/tsunami.c [deleted file]
arch/alpha/lib/Makefile
arch/alpha/lib/io.c
arch/alpha/lib/strcasecmp.c [new file with mode: 0644]
arch/alpha/math-emu/fp-emul.c
arch/alpha/mm/fault.c
arch/alpha/mm/init.c
arch/i386/kernel/entry.S
arch/i386/kernel/head.S
arch/i386/kernel/setup.c
drivers/block/genhd.c
drivers/block/loop.c
drivers/block/trm290.c
drivers/char/apm_bios.c
drivers/char/bttv.c
drivers/char/bw-qcam.c
drivers/char/c-qcam.c
drivers/char/cyclades.c
drivers/char/keyboard.c
drivers/char/lp.c
drivers/char/msp3400.c
drivers/char/pc_keyb.c
drivers/char/pms.c
drivers/char/pty.c
drivers/char/radio-aimslab.c
drivers/char/radio-aztech.c
drivers/char/radio-rtrack2.c [new file with mode: 0644]
drivers/char/radio-sf16fmi.c
drivers/char/radio-zoltrix.c
drivers/char/videodev.c
drivers/net/3c509.c
drivers/net/plip.c
drivers/net/shaper.c
drivers/net/tlan.c
drivers/net/tlan.h
drivers/video/tgafb.c
drivers/video/vgacon.c
fs/exec.c
fs/nfsd/vfs.c
fs/proc/array.c
fs/proc/generic.c
fs/proc/root.c
fs/super.c
fs/vfat/namei.c
include/asm-alpha/apecs.h [deleted file]
include/asm-alpha/bitops.h
include/asm-alpha/cia.h [deleted file]
include/asm-alpha/compiler.h [new file with mode: 0644]
include/asm-alpha/core_apecs.h [new file with mode: 0644]
include/asm-alpha/core_cia.h [new file with mode: 0644]
include/asm-alpha/core_lca.h [new file with mode: 0644]
include/asm-alpha/core_mcpcia.h [new file with mode: 0644]
include/asm-alpha/core_pyxis.h [new file with mode: 0644]
include/asm-alpha/core_t2.h [new file with mode: 0644]
include/asm-alpha/core_tsunami.h [new file with mode: 0644]
include/asm-alpha/dma.h
include/asm-alpha/floppy.h
include/asm-alpha/hwrpb.h
include/asm-alpha/init.h
include/asm-alpha/io.h
include/asm-alpha/irq.h
include/asm-alpha/jensen.h
include/asm-alpha/lca.h [deleted file]
include/asm-alpha/machvec.h [new file with mode: 0644]
include/asm-alpha/mcpcia.h [deleted file]
include/asm-alpha/mmu_context.h
include/asm-alpha/pci.h [new file with mode: 0644]
include/asm-alpha/pgtable.h
include/asm-alpha/posix_types.h
include/asm-alpha/processor.h
include/asm-alpha/pyxis.h [deleted file]
include/asm-alpha/string.h
include/asm-alpha/system.h
include/asm-alpha/t2.h [deleted file]
include/asm-alpha/tsunami.h [deleted file]
include/asm-i386/processor.h
include/asm-i386/unistd.h
include/linux/genhd.h
include/linux/if_shaper.h
include/linux/if_wic.h [deleted file]
include/linux/mount.h
include/linux/proc_fs.h
include/linux/videodev.h
ipc/msg.c
kernel/ksyms.c
mm/swap.c
net/ax25/af_ax25.c
net/core/dev.c
net/econet/econet.c
net/ipv4/arp.c
net/packet/af_packet.c

diff --git a/CREDITS b/CREDITS
index 7180abd9196ad399e3068875741d15f36e04ad6b..2035ac51a84dfb296474dc935f8637133dd1a36d 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -706,8 +706,8 @@ N: Richard Henderson
 E: rth@cygnus.com
 E: richard@gnu.org
 D: Alpha/ELF, gcc, binutils, and glibc
-S: 5450 Mayme #25
-S: San Jose, California 95129
+S: 50 E. Middlefield #10
+S: Mountain View, California 94043-3822
 S: USA
 
 N: Sebastian Hetze
index ca5c3e20c62ede38b494bc6b7d15c1b6d0b2b033..4449732ab81afa33fec393090638d17d1feaf737 100644 (file)
@@ -26,7 +26,7 @@ structures following the array have been overwritten.  Using this
 discipline, these cases get detected quickly and safely.
 
                                        Theodore Ts'o
-                                       31-Mar-94
+                                       31 Mar 94
 
 The magic table is current to Linux 2.1.55.
 
@@ -34,42 +34,65 @@ The magic table is current to Linux 2.1.55.
                                        <mailto:mec@shout.net>
                                        22 Sep 1997
 
+Now it should be up to date with Linux 2.1.112. Because
+we are in feature freeze time it is very unlikely that
+something will change before 2.2.x. The entries are
+sorted by number field.
 
+                                       Krzysztof G. Baranowski
+                                       <mailto: kgb@knm.org.pl>
+                                       29 Jul 1998
 
-Magic Name          Number      Structure            File
+Magic Name            Number      Structure            File
 ===========================================================================
-
+PG_MAGIC             'P'         pg_{read,write}_hdr include/linux/pg.h
 MKISS_DRIVER_MAGIC    0x04bf      mkiss_channel     drivers/net/mkiss.h
 RISCOM8_MAGIC         0x0907      riscom_port       drivers/char/riscom8.h
 APM_BIOS_MAGIC        0x4101      apm_bios_struct   include/linux/apm_bios.h
 CYCLADES_MAGIC        0x4359      cyclades_port     include/linux/cyclades.h
 FASYNC_MAGIC          0x4601      fasync_struct     include/linux/fs.h
+PTY_MAGIC            0x5001      (none at the moment)
+                                                   drivers/char/pty.c
 PPP_MAGIC             0x5002      ppp               include/linux/if_ppp.h
 SERIAL_MAGIC          0x5301      async_struct      include/linux/serial.h
 SSTATE_MAGIC          0x5302      serial_state      include/linux/serial.h
 SLIP_MAGIC            0x5302      slip              drivers/net/slip.h
 STRIP_MAGIC           0x5303      strip             drivers/net/strip.c
 X25_ASY_MAGIC         0x5303      x25_asy           drivers/net/x25_asy.h
+SIXPACK_MAGIC        0x5304      sixpack           drivers/net/hamradio/6pack.h
 AX25_MAGIC            0x5316      ax_disp           drivers/net/mkiss.h
 ESP_MAGIC             0x53ee      esp_struct        drivers/char/esp.h
 TTY_MAGIC             0x5401      tty_struct        include/linux/tty.h
 TTY_DRIVER_MAGIC      0x5402      tty_driver        include/linux/tty_driver.h
 TTY_LDISC_MAGIC       0x5403      tty_ldisc         include/linux/tty_ldisc.h
 SCC_MAGIC             0x8530      scc_channel       include/linux/scc.h
+SPECIALIX_MAGIC       0x0907      specialix_port    drivers/char/specialix_io8.h
+CG_MAGIC             0x090255    ufs_cylinder_group include/linux/ufs_fs.h
 RPORT_MAGIC           0x525001    r_port            drivers/char/rocket_int.h
-SLAB_C_MAGIC          0x4f17a36d  kmem_cache_s      mm/slab.c
+GDTIOCTL_MAGIC       0x06030f07  gdth_iowr_str     drivers/scsi/gdth_ioctl.h
+NBD_REQUEST_MAGIC     0x12560953  nbd_request       include/linux/nbd.h
 SLAB_RED_MAGIC2       0x170fc2a5  (any)             mm/slab.c
+BAYCOM_MAGIC          0x19730510  baycom_state      drivers/net/baycom_epp.c
+ISDN_X25IFACE_MAGIC   0x1e75a2b9  isdn_x25iface_proto_data
+                                                    drivers/isdn/isdn_x25iface.h
 ECP_MAGIC             0x21504345  cdkecpsig         include/linux/cdk.h
+LSMAGIC               0x2a3b4d2a  ls                drivers/fc4/fc.c
+LSOMAGIC              0x2a3c4e3c  lso               drivers/fc4/fc.c
+WANPIPE_MAGIC         0x414C4453  sdla_{dump,exec}  include/linux/wanpipe.h
+CODA_CNODE_MAGIC      0x47114711  coda_inode_info   include/linux/coda_fs_i.h
 ISDN_ASYNC_MAGIC      0x49344C01  modem_info        include/linux/isdn.h
 ISDN_NET_MAGIC        0x49344C02  isdn_net_local_s  include/linux/isdn.h
 STLI_BOARDMAGIC       0x4bc6c825  stlibrd           include/linux/istallion.h
+SLAB_C_MAGIC          0x4f17a36d  kmem_cache_s      mm/slab.c
 ROUTER_MAGIC          0x524d4157  wan_device        include/linux/wanrouter.h
 SLAB_RED_MAGIC1       0x5a2cf071  (any)             mm/slab.c
 STL_PORTMAGIC         0x5a7182c9  stlport           include/linux/stallion.h
 HDLCDRV_MAGIC         0x5ac6e778  hdlcdrv_state     include/linux/hdlcdrv.h
-EPCA_MAGIC            0x5c6df104  channel           include/linux/epca.h
+EPCA_MAGIC                   0x5c6df104  channel           include/linux/epca.h
 PCXX_MAGIC            0x5c6df104  channel           drivers/char/pcxx.h
+LO_MAGIC              0x68797548  nbd_device        include/linux/nbd.h
 STL_PANELMAGIC        0x7ef621a1  stlpanel          include/linux/stallion.h
+NBD_REPLY_MAGIC       0x96744668  nbd_reply         include/linux/nbd.h
 STL_BOARDMAGIC        0xa2267f52  stlbrd            include/linux/stallion.h
 SLAB_MAGIC_ALLOC      0xa5c32f2b  kmem_slab_s       mm/slab.c
 SLAB_MAGIC_DESTROYED  0xb2f23c5a  kmem_slab_s       mm/slab.c
diff --git a/Documentation/radiotrack.txt b/Documentation/radiotrack.txt
new file mode 100644 (file)
index 0000000..fe942e8
--- /dev/null
@@ -0,0 +1,147 @@
+NOTES ON RADIOTRACK CARD CONTROL
+by Stephen M. Benoit (benoits@servicepro.com)  Dec 14, 1996
+----------------------------------------------------------------------------
+
+Document version 1.0
+
+ACKNOWLEDGMENTS
+----------------
+This document was made based on 'C' code for Linux from Gideon le Grange
+(legrang@active.co.za or legrang@cs.sun.ac.za) in 1994, and elaborations from
+Frans Brinkman (brinkman@esd.nl) in 1996.  The results reported here are from
+experiments that the author performed on his own setup, so your mileage may
+vary... I make no guarantees, claims or warrantees to the suitability or
+validity of this information.  No other documentation on the AIMS
+Lab (http://www.aimslab.com/) RadioTrack card was made available to the
+author.  This document is offered in the hopes that it might help users who
+want to use the RadioTrack card in an environment other than MS Windows.
+
+WHY THIS DOCUMENT?
+------------------
+I have a RadioTrack card from back when I ran an MS-Windows platform.  After
+converting to Linux, I found Gideon le Grange's command-line software for
+running the card, and found that it was good!  Frans Brinkman made a
+comfortable X-windows interface, and added a scanning feature.  For hack
+value, I wanted to see if the tuner could be tuned beyond the usual FM radio
+broadcast band, so I could pick up the audio carriers from North American
+broadcast TV channels, situated just below and above the 87.0-109.0 MHz range.
+I did not get much success, but I learned about programming ioports under
+Linux and gained some insights about the hardware design used for the card.
+
+So, without further delay, here are the details.
+
+
+PHYSICAL DESCRIPTION
+--------------------
+The RadioTrack card is an ISA 8-bit FM radio card.  The radio frequency (RF)
+input is simply an antenna lead, and the output is a power audio signal
+available through a miniature phono plug.  Its RF frequencies of operation are
+more or less limited from 87.0 to 109.0 MHz (the commercial FM broadcast
+band).  Although the registers can be programmed to request frequencies beyond
+these limits, experiments did not give promising results.  The variable
+frequency oscillator (VFO) that demodulates the intermediate frequency (IF)
+signal probably has a small range of useful frequencies, and wraps around or
+gets clipped beyond the limits mentioned above.
+
+
+CONTROLLING THE CARD WITH IOPORT
+--------------------------------
+The RadioTrack (base) ioport is configurable for 0x30c or 0x20c.  Only one
+ioport seems to be involved.  The ioport decoding circuitry must be pretty
+simple, as individual ioport bits are directly matched to specific functions
+(or blocks) of the radio card.  This way, many functions can be changed in
+parallel with one write to the ioport.  The only feedback available through
+the ioports appears to be the "Stereo Detect" bit.
+
+The bits of the ioport are arranged as follows:
+
+  MSb                                                         LSb
++------+------+------+--------+--------+-------+---------+--------+
+| VolA | VolB | ???? | Stereo | Radio  | TuneA | TuneB   | Tune   |
+|  (+) |  (-) |      | Detect | Audio  | (bit) | (latch) | Update |
+|      |      |      | Enable | Enable |       |         | Enable |
++------+------+------+--------+--------+-------+---------+--------+
+
+
+VolA . VolB  [AB......]
+-----------
+0 0 : audio mute
+0 1 : volume +    (some delay required)
+1 0 : volume -    (some delay required)
+1 1 : stay at present volume
+
+Stereo Detect Enable [...S....]
+--------------------
+0 : No Detect
+1 : Detect
+
+  Results available by reading ioport >60 msec after last port write.
+  0xff ==> no stereo detected,  0xfd ==> stereo detected.
+
+Radio to Audio (path) Enable [....R...]
+----------------------------
+0 : Disable path (silence)
+1 : Enable path  (audio produced)
+
+TuneA . TuneB [.....AB.]
+-------------
+0 0 : "zero" bit phase 1
+0 1 : "zero" bit phase 2
+
+1 0 : "one" bit phase 1
+1 1 : "one" bit phase 2
+
+  24-bit code, where bits = (freq*40) + 10486188.
+  The Most Significant 11 bits must be 1010 xxxx 0x0 to be valid.
+  The bits are shifted in LSb first.
+
+Tune Update Enable [.......T]
+------------------
+0 : Tuner held constant
+1 : Tuner updating in progress
+
+
+PROGRAMMING EXAMPLES
+--------------------
+Default:        BASE <-- 0xc8  (current volume, no stereo detect,
+                               radio enable, tuner adjust disable)
+
+Card Off:      BASE <-- 0x00  (audio mute, no stereo detect,
+                               radio disable, tuner adjust disable)
+
+Card On:       BASE <-- 0x00  (see "Card Off", clears any unfinished business)
+               BASE <-- 0xc8  (see "Default")
+
+Volume Down:    BASE <-- 0x48  (volume down, no stereo detect,
+                               radio enable, tuner adjust disable)
+               * wait 10 msec *
+               BASE <-- 0xc8  (see "Default")
+
+Volume Up:      BASE <-- 0x88  (volume up, no stereo detect,
+                               radio enable, tuner adjust disable)
+               * wait 10 msec *
+               BASE <-- 0xc8  (see "Default")
+
+Check Stereo:   BASE <-- 0xd8  (current volume, stereo detect,
+                               radio enable, tuner adjust disable)
+               * wait 100 msec *
+               x <-- BASE     (read ioport)
+               BASE <-- 0xc8  (see "Default")
+
+               x=0xff ==> "not stereo", x=0xfd ==> "stereo detected"
+
+Set Frequency:  code = (freq*40) + 10486188
+                foreach of the 24 bits in code,
+                (from Least to Most Significant):
+                  to write a "zero" bit,
+                    BASE <-- 0x01  (audio mute, no stereo detect, radio
+                                   disable, "zero" bit phase 1, tuner adjust)
+                    BASE <-- 0x03  (audio mute, no stereo detect, radio
+                                   disable, "zero" bit phase 2, tuner adjust)
+                  to write a "one" bit,
+                    BASE <-- 0x05  (audio mute, no stereo detect, radio
+                                   disable, "one" bit phase 1, tuner adjust)
+                    BASE <-- 0x07  (audio mute, no stereo detect, radio
+                                   disable, "one" bit phase 2, tuner adjust)
+
+----------------------------------------------------------------------------
diff --git a/Documentation/sound/ChangeLog.multisound b/Documentation/sound/ChangeLog.multisound
new file mode 100644 (file)
index 0000000..a25f465
--- /dev/null
@@ -0,0 +1,137 @@
+1998-08-06  Andrew Veliath  <andrewtv@usa.net>
+
+       * Update version to 0.7.2
+       
+       * After A/D calibration, do an explicit set to the line input,
+         rather than using set_recsrc
+
+1998-07-20  Andrew Veliath  <andrewtv@usa.net>
+
+       * Update version to 0.7.1
+
+       * Add more OSS ioctls
+       
+1998-07-19  Andrew Veliath  <andrewtv@usa.net>
+
+       * Update doc file
+       
+       * Bring back DIGITAL1 with digital parameter to msnd_pinnacle.c
+         and CONFIG_MSNDPIN_DIGITAL.  I'm not sure this actually works,
+         since I find audio playback goes into a very speeded mode of
+         operation, however it might be due to a lack of a digital
+         source, which I don't have to test.
+
+1998-07-18  Andrew Veliath  <andrewtv@usa.net>
+
+       * Update version to 0.7.0
+
+       * Can now compile with Alan Cox' 2.0.34-modular-sound patch (so
+         now it requires >= 2.1.106 or 2.0.34-ms) (note for 2.0.34-ms it
+         is in the Experimental section)
+
+       * More modularization, consolidation, also some MIDI hooks
+         installed for future MIDI modules
+
+       * Write flush
+
+       * Change default speed, channels, bit size to OSS/Free defaults
+
+1998-06-02  Andrew Veliath  <andrewtv@usa.net>
+
+       * Update version to 0.5b
+
+       * Fix version detection
+       
+       * Remove underflow and overflow resets (delay was too long)
+
+       * Replace spinlocked bitops with atomic bit ops
+
+1998-05-27  Andrew Veliath  <andrewtv@usa.net>
+
+       * Update version to 0.5a
+       
+       * Better recovery from underflow or overflow conditions
+       
+       * Fix a deadlock condition with one thread reading and the other
+         writing
+
+1998-05-26  Andrew Veliath  <andrewtv@usa.net>
+
+       * Update version to 0.5
+       
+       * Separate reset queue functions for play and record
+
+       * Add delays in dsp_halt
+
+1998-05-24  Andrew Veliath  <andrewtv@usa.net>
+
+       * Add a check for Linux >= 2.1.95
+       
+       * Remove DIGITAL1 input until I figure out how to make it work
+       
+       * Add HAVE_DSPCODEH which when not defined will load firmware from
+         files using mod_firmware_load, then release memory after they
+         are uploaded (requires reorganized OSS).
+
+1998-05-22  Andrew Veliath  <andrewtv@usa.net>
+
+       * Update version to 0.4c
+
+       * Hopefully fix the mixer volume problem
+
+1998-05-19  Andrew Veliath  <andrewtv@usa.net>
+
+       * Add __initfuncs and __initdatas to reduce resident code size
+
+       * Move bunch of code around, remove some protos
+
+       * Integrate preliminary changes for Alan Cox's OSS reorganization
+         for non-OSS drivers to coexist with OSS devices on the same
+         major.  To compile standalone, must now define STANDALONE.
+
+1998-05-16  Andrew Veliath  <andrewtv@usa.net>
+
+       * Update version to 0.4b
+       
+       * Integrated older card support into a unified driver, tested on a
+         MultiSound Classic c/o Kendrick Vargas.
+
+1998-05-15  Andrew Veliath  <andrewtv@usa.net>
+
+       * Update version to 0.4
+       
+       * Fix read/write return values
+
+1998-05-13  Andrew Veliath  <andrewtv@usa.net>
+
+       * Update version to 0.3
+
+       * Stop play gracefully
+
+       * Add busy flag
+       
+       * Add major and calibrate_signal module parameters
+       
+       * Add ADC calibration
+
+       * Add some OSS compatibility ioctls
+
+       * Add mixer record selection
+       
+       * Add O_NONBLOCK support, separate read/write wait queues
+
+       * Add sample bit size ioctl, expanded sample rate ioctl
+
+       * Playback suspension now resumes
+
+       * Use signal_pending after interruptible_sleep_on
+       
+       * Add recording, change ints to bit flags
+
+1998-05-11  Andrew Veliath  <andrewtv@usa.net>
+
+       * Update version to 0.2
+
+       * Add preliminary playback support
+
+       * Use new Turtle Beach DSP code
\ No newline at end of file
index de85125f40cc799691b820fbbd3fcb3e66f9000f..4d4313134b5a9a733e4adbd1e5eef96372c101eb 100644 (file)
@@ -9,8 +9,8 @@ Supported Features
 ~~~~~~~~~~~~~~~~~~
 
 Currently digital audio and mixer functionality is supported.  (memory
-mapped digital audio is not yet supported).  MultiSound support is
-fully modularized, and can only be used as modules:
+mapped digital audio is not yet supported).  Modular MultiSound
+support is composed of the following modules:
 
 msnd           - MultiSound base (requires soundcore)
 msnd_classic   - Base audio/mixer support for Classic, Monetery and
@@ -80,14 +80,28 @@ mem                 Shared memory area, e.g. mem=0xd8000
 msnd_classic, msnd_pinnacle Additional Options
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-fifosize               The digital audio FIFOs, in kilobytes.  The default is
-                       64kB (two FIFOs are allocated, so this uses up 128kB).
+fifosize               The digital audio FIFOs, in kilobytes.  The
+                       default is 64kB (two FIFOs are allocated, so
+                       this uses up 128kB).
 
 calibrate_signal       Setting this to one calibrates the ADCs to the
                        signal, zero calibrates to the card (defaults
                        to zero).
 
 
+msnd_pinnacle Additional Options
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+digital                        Specify digital=1 to enable the S/PDIF input
+                       if you have the digital daughterboard
+                       adapter. This will enable access to the
+                       DIGITAL1 input for the soundcard in the mixer.
+                       Some mixer programs might have trouble setting
+                       the DIGITAL1 source as an input.  If you have
+                       trouble, you can try the setdigital.c program
+                       at the bottom of this document.
+
+
 Obtaining and Creating Firmware Files
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -105,7 +119,9 @@ following firmware files to /etc/sound (note the file renaming):
   cp DSPCODE/MSNDPERM.REB /etc/sound/msndperm.bin
 
 When configuring the Linux kernel, specify /etc/sound/msndinit.bin and
-/etc/sound/msndperm.bin for the two firmware files.
+/etc/sound/msndperm.bin for the two firmware files (Linux kernel
+versions older than 2.2 do not ask for firmware paths, and are
+hardcoded to /etc/sound).
 
 
        For the Pinnacle/Fiji
@@ -122,9 +138,9 @@ and end lines):
 
 -- conv.l start --
 %%
-[ \n\t,\r]     ;
-\;.*           ;
-DB             ;
+[ \n\t,\r]
+\;.*
+DB
 [0-9A-Fa-f]+H  { int n; sscanf(yytext, "%xH", &n); printf("%c", n); }
 -- conv.l end --
 
@@ -143,4 +159,76 @@ archive unpacked into a directory named PINNDDK):
 The conv (and conv.l) program is not needed after conversion and can
 be safely deleted.  Then, when configuring the Linux kernel, specify
 /etc/sound/pndspini.bin and /etc/sound/pndsperm.bin for the two
-firmware files.
+firmware files (Linux kernel versions older than 2.2 do not ask for
+firmware paths, and are hardcoded to /etc/sound).
+
+
+Recording from the S/PDIF Input
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you have a Pinnacle or Fiji with S/PDIF input and want to set it as
+the input source, you can use this program if you have trouble trying
+to do it with a mixer program (be sure to insert the module with the
+digital=1 option).
+
+Compile with:
+cc -O setdigital.c -o setdigital
+
+-- start setdigital.c --
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/soundcard.h>
+
+int main(int argc, char *argv[])
+{
+       int fd;
+       unsigned long recmask, recsrc;
+
+       if (argc != 2) {
+               fprintf(stderr, "usage: setdigital <mixer device>\n");
+               exit(1);
+       } else
+
+       if ((fd = open(argv[1], O_RDWR)) < 0) {
+               perror(argv[1]);
+               exit(1);
+       }
+
+       if (ioctl(fd, SOUND_MIXER_READ_RECMASK, &recmask) < 0) {
+               fprintf(stderr, "error: ioctl read recmask failed\n");
+               perror("ioctl");
+               close(fd);
+               exit(1);
+       }
+
+       if (!(recmask & SOUND_MASK_DIGITAL1)) {
+               fprintf(stderr, "error: cannot find DIGITAL1 device in mixer\n");
+               close(fd);
+               exit(1);
+       }
+
+       if (ioctl(fd, SOUND_MIXER_READ_RECSRC, &recsrc) < 0) {
+               fprintf(stderr, "error: ioctl read recsrc failed\n");
+               perror("ioctl");
+               close(fd);
+               exit(1);
+       }
+
+       recsrc |= SOUND_MASK_DIGITAL1;
+       
+       if (ioctl(fd, SOUND_MIXER_WRITE_RECSRC, &recsrc) < 0) {
+               fprintf(stderr, "error: ioctl write recsrc failed\n");
+               perror("ioctl");
+               close(fd);
+               exit(1);
+       }
+
+       close(fd);
+       
+       return 0;
+}
+-- end setdigital.c --
index 62f7989309205ddf2dc9edccfcd2e94ca5882f69..153082c463de6fd36bfab589c47b41179c9eec7f 100644 (file)
@@ -1,6 +1,12 @@
-OPL3-SA sound driver (opl3sa.o)
+OPL3-SA1 sound driver (opl3sa.o)
 
-The Yamaha OPL3-SAx sound chip is usually found built into motherboards, and
+---
+Note: This howto only describes how to setup the OPL3-SA1 chip; this info
+does not apply to the SA2, SA3, or SA4. Contact hannu@opensound.com for
+the support details of these other SAx chips.
+---
+
+The Yamaha OPL3-SA1 sound chip is usually found built into motherboards, and
 it's a decent little chip offering a WSS mode, a SB Pro emulation mode, MPU401
 and OPL3 FM Synth capabilities.
 
@@ -73,4 +79,3 @@ A 'cat /dev/sndstat' with all the above options should look similar to this:
 
 Questions? Comments?
 <stiker@northlink.com>
-
index 4a2ad4b9eced0f15feed951c6a62e04ad3f781d6..aadbfd23ff434eac1568316d96c00d6371f492d6 100644 (file)
@@ -1,14 +1,17 @@
-             An OSS/Free Driver for WaveFront soundcards
-               (Turtle Beach Maui, Tropez, Tropez Plus)
+            An OSS/Free Driver for WaveFront soundcards
+              (Turtle Beach Maui, Tropez, Tropez Plus)
 
-                     Paul Barton-Davis, July 1998
+                    Paul Barton-Davis, July 1998
+
+                         VERSION 0.2.4
 
 Driver Status
 -------------
 
-Requires: Kernel 2.1.106 or later
-        
-As of 7/3/1998, this driver is currently in *BETA* state. This means
+Requires: Kernel 2.1.106 or later (a version of the driver is included
+with kernels 2.1.109 and above)
+         
+As of 7/20/1998, this driver is currently in *BETA* state. This means
 that it compiles and runs, and that I use it on my system (Linux
 2.1.106) with some reasonably demanding applications and uses.  I
 believe the code is approaching an initial "finished" state that
@@ -17,11 +20,11 @@ provides bug-free support for the Tropez Plus.
 Please note that to date, the driver has ONLY been tested on a Tropez
 Plus. I would very much like to hear (and help out) people with Tropez
 and Maui cards, since I think the driver can support those cards as
-well.
+well. 
 
-Finally, the driver has not been tested as a static (non-modular) part
-of the kernel. Alan Cox's good work in modularizing OSS/Free for Linux
-makes this rather unnecessary.
+Finally, the driver has not been tested (or even compiled) as a static
+(non-modular) part of the kernel. Alan Cox's good work in modularizing
+OSS/Free for Linux makes this rather unnecessary.
 
 Some Questions
 --------------
@@ -30,7 +33,7 @@ Some Questions
 0) What does this driver do that the maui driver did not ?
 **********************************************************************
 
-* can fully initialize a WaveFront card from cold boot - no DOS
+* can fully initialize a WaveFront card from cold boot - no DOS 
           utilities needed
 * working patch/sample/program loading and unloading (the maui
       driver didn't document how to make this work, and assumed
@@ -40,14 +43,13 @@ Some Questions
 * for the Tropez Plus, (primitive) control of the YSS225 FX processor
 * Virtual MIDI mode supported - 2 MIDI devices accessible via the
           WaveFront's MPU401/UART emulation. One
-          accesses the WaveFront synth, the other accesses the
-          external MIDI connector. Full MIDI read/write semantics
-          for both devices.
+         accesses the WaveFront synth, the other accesses the
+         external MIDI connector. Full MIDI read/write semantics
+         for both devices.
 * OSS-compliant /dev/sequencer interface for the WaveFront synth,
-          including native and GUS-format patch downloading.
+         including native and GUS-format patch downloading.
 * semi-intelligent patch management (prototypical at this point)
 
-
 **********************************************************************
 1) What to do about MIDI interfaces ?
 **********************************************************************
@@ -81,24 +83,27 @@ out. Reports welcome.
 
 Either because its not finished yet, or because you're a better coder
 than I am, or because you don't understand some aspect of how the card
-or the code works.
+or the code works. 
 
 I absolutely welcome comments, criticisms and suggestions about the
-design and implementation of the driver.
+design and implementation of the driver. 
 
 **********************************************************************
 3) What files are included ?
 **********************************************************************
 
    drivers/sound/README.wavefront       -- this file
-   drivers/sound/wavefront.patch        -- patches for the 2.1.106 sound driver
-s
-                                           needed to make the rest of this work
+
+   drivers/sound/wavefront.patch       -- patches for the 2.1.106 sound drivers
+                                          needed to make the rest of this work
+                                          DO NOT USE IF YOU'VE APPLIED THEM 
+                                          BEFORE, OR HAVE 2.1.109 OR ABOVE
+
    drivers/sound/wavfront.c             -- the driver
    drivers/sound/ys225.h                -- data declarations for FX config
    drivers/sound/ys225.c                -- data definitions for FX config
-   drivers/sound/wf_midi.c              -- the "uart401" driver
-                                              to support virtual MIDI mode.
+   drivers/sound/wf_midi.c              -- the "uart401" driver 
+                                             to support virtual MIDI mode.
    include/wavefront.h                  -- the header file
    Documentation/sound/Tropez+          -- short docs on configuration
 
@@ -113,6 +118,9 @@ PART ONE: install the source code into your sound driver directory
 
 PART TWO: apply the patches
 
+     DO THIS ONLY IF YOU HAVE A KERNEL VERSION BELOW 2.1.109
+     AND HAVE NOT ALREADY INSTALLED THE PATCH(ES).
+
   cd drivers/sound
   patch < wavefront.patch
 
@@ -121,15 +129,14 @@ PART THREE: configure your kernel
   cd <top of your kernel tree>
   make xconfig (or whichever config option you use)
 
-         - choose YES for Sound Support
+         - choose YES for Sound Support              
          - choose MODULE (M) for OSS Sound Modules
-         - choose MODULE(M) to Generic OPL2/OPL3 support
          - choose MODULE(M) to YM3812/OPL3 support
-         - choose MODULE(M) for WaveFront support
-         - choose MODULE(M) for CS4232 support
+        - choose MODULE(M) for WaveFront support
+        - choose MODULE(M) for CS4232 support
 
-         - choose "N" for everything else (unless you have other
-              soundcards you want support for)
+        - choose "N" for everything else (unless you have other
+             soundcards you want support for)
 
 
    make dep
@@ -155,7 +162,6 @@ Here's my autoconf.h SOUND section:
 #undef  CONFIG_SOUND_PAS
 #undef  CONFIG_SOUND_SB
 #undef  CONFIG_SOUND_ADLIB
-#define CONFIG_SOUND_ADLIB_MODULE 1
 #undef  CONFIG_SOUND_GUS
 #undef  CONFIG_SOUND_MPU401
 #undef  CONFIG_SOUND_PSS
@@ -191,21 +197,22 @@ relevant details):
   alias char-major-14 wavefront
   alias synth0 wavefront
   alias mixer0 cs4232
+  alias audio0 cs4232
   pre-install wavefront modprobe "-k" "cs4232"
-  post-install wavefront modprobe "-k" "adlib_card"
+  post-install wavefront modprobe "-k" "opl3"
   options wavefront io=0x200 irq=9
   options cs4232 synthirq=9 synthio=0x200 io=0x530 irq=5 dma=1 dma2=0
-  options adlib_card io=0x388
+  options opl3 io=0x388
 
-Things to note:
+Things to note: 
 
        the wavefront options "io" and "irq" ***MUST*** match the "synthio"
        and "synthirq" cs4232 options.
 
-       you can do without the adlib_card module if you don't
-       want to use the OPL/[34] synth on the soundcard
+       you can do without the opl3 module if you don't
+       want to use the OPL/[34] FM synth on the soundcard
 
-       the adlib_card io parameter is conventionally not adjustable.
+       the opl3 io parameter is conventionally not adjustable.
        In theory, any not-in-use IO port address would work, but
        just use 0x388 and stick with the crowd.
 
@@ -218,7 +225,7 @@ for the ICS2115. However, if you have a WaveFront card, then you
 almost certainly have the firmware, and if not, its freely available
 on their website, at:
 
-   http://www.tbeach.com/tbs/downloads/scardsdown.htm#tropezplus
+   http://www.tbeach.com/tbs/downloads/scardsdown.htm#tropezplus 
 
 The file is called WFOS2001.MOT (for the Tropez+).
 
@@ -233,7 +240,7 @@ processed version:
 %%
 ^S[28].*\r$ printf ("%c%.*s", yyleng-1,yyleng-1,yytext);
 <<EOF>> { fputc ('\0', stdout); return; }
-\n {}
+\n {} 
 .  {}
 ---- cut here -------------------------
 
@@ -241,7 +248,7 @@ To use it, put the above in file (say, ws.l) compile it like this:
 
       shell> flex -ows.c ws.l
       shell> cc -o ws ws.c
-
+      
 and then use it like this:
 
     ws < my-copy-of-the-oswf.mot-file > /etc/sound/wavefront.os
@@ -260,12 +267,11 @@ Then, as root do:
 
      modprobe wavefront
 
-You should get something like this, directly if you're on a console, and in
-/var/log/messages:
+You should get something like this in /var/log/messages:
 
     WaveFront: firmware 1.20 already loaded.
 
-or
+or 
 
     WaveFront: no response to firmware probe, assume raw.
 
@@ -294,9 +300,9 @@ Load type: Driver loaded as a module
 Kernel: Linux bd 2.1.106 #12 SMP Fri Jul 3 00:37:34 EDT 1998 i486
 Config options: 0
 
-Installed drivers:
+Installed drivers: 
 
-Card config:
+Card config: 
 
 Audio devices:
 0: Crystal audio controller (CS4232) (DUPLEX)
@@ -325,7 +331,7 @@ which is the default (I think ...). If you have an external synth(s)
 hooked to the soundcard, you can use "-e" to route to the
 external synth(s) (in theory, -D 1 should work as well, but I think
 there is a bug in playmidi which prevents this from doing what it
-should).
+should). 
 
 **********************************************************************
 8) What are the module parameters ?
@@ -333,39 +339,28 @@ should).
 
 Its best to read wavefront.c for this, but here is a summary:
 
-integers:
-          wf_raw  - if set, ignore apparent presence of firmware
-                    loaded onto the ICS2115, reset the whole
-                    board, and initialize it from scratch. (default = 0)
+integers: 
+         wf_raw  - if set, ignore apparent presence of firmware
+                   loaded onto the ICS2115, reset the whole
+                   board, and initialize it from scratch. (default = 0)
 
           fx_raw  - if set, always initialize the YSS225 processor
-                    on the Tropez plus. (default = 1)
+                   on the Tropez plus. (default = 1)
 
           < The next 4 are basically for kernel hackers to allow
-            tweaking the driver for testing purposes. >
-
-          wf_short_wait_count - loop counter used when waiting for
-                                status conditions on the board. This
-                                is CPU-specific. After this many
-                                loops, the driver will sleep.
-                                The default is 5000. I have a 66Mhz 486.
-
-          wf_sleep_interval  - the driver sleeps for
-                               HZ/wf_sleep_interval seconds per sleep.
-                               The default is 50.
-
-          wf_sleep_tries  - the number of times the driver will sleep
-                            when waiting for a status condition on the
-                            board. The default is 100 (2 secs, if
-                            wf_sleep_interval is 50).
-
-          wf_debug_default - debugging flags. See sound/wavefront.h
-                             for WF_DEBUG_* values. Default is zero.
-                             Setting this allows you to debug the
-                             driver during module installation.
+           tweaking the driver for testing purposes. >             
+
+          wait_usecs        -  loop timer used when waiting for
+                              status conditions on the board. 
+                              The default is 150.
+
+          debug_default    - debugging flags. See sound/wavefront.h
+                            for WF_DEBUG_* values. Default is zero.
+                            Setting this allows you to debug the
+                            driver during module installation.
 strings:
-          wf_ospath - path to get to the pre-processed OS firmware.
-                    (default: /etc/sound/wavefront.os)
+         ospath - path to get to the pre-processed OS firmware.
+                   (default: /etc/sound/wavefront.os)
 
 **********************************************************************
 9) Who should I contact if I have problems?
@@ -374,4 +369,3 @@ strings:
 Just me: Paul Barton-Davis <pbd@op.net>
 
 
-
index 8d565e586d498a21068fcae61d1dfde0bda466c6..9fbebebbd1c1eeda716df3184ddcf9a4199e36d8 100644 (file)
@@ -330,9 +330,9 @@ S:  Maintained
 
 JOYSTICK DRIVER
 P:     Vojtech Pavlik
-M:     vojtech@atrey.karlin.mff.cuni.cz
-W:     http://atrey.karlin.mff.cuni.cz/~vojtech/joystick/
+M:     vojtech@ucw.cz
 L:     linux-joystick@atrey.karlin.mff.cuni.cz
+W:     http://atrey.karlin.mff.cuni.cz/~vojtech/joystick/
 S:     Maintained
 
 KERNEL AUTOMOUNTER (AUTOFS)
index 079e835c915cfa1cdb7b714a40eec3709479d093..62981e9d300e6532bf35208c45f8cb7e9ef2c1f2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 115
+SUBLEVEL = 116
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
index 77dde66141f310b9fbd2404a328bd719bf642885..d497ec3c80be2660968b7cf36de565f7ff04ba9c 100644 (file)
 
 NM := nm -B
 
-ifdef CONFIG_CROSSCOMPILE
-# enable this for linking under OSF/1:
-LINKFLAGS = -non_shared -T 0xfffffc0000310000 -N
-else
- elf=$(shell if $(LD) --help | grep elf64alpha >/dev/null; then echo yes; fi)
- ifeq ($(elf),yes)
-   LINKFLAGS = -static -T arch/alpha/vmlinux.lds
- else
-   LINKFLAGS = -static -T arch/alpha/vmlinux.lds -N
- endif
-# GNU gcc/cc1/as can use pipes instead of temporary files
-CFLAGS := $(CFLAGS) -pipe
-endif
+LINKFLAGS = -static -T arch/alpha/vmlinux.lds -N
+CFLAGS := $(CFLAGS) -pipe -mno-fp-regs -ffixed-8
 
-CFLAGS := $(CFLAGS) -mno-fp-regs -ffixed-8
+# Determine if we can use the BWX instructions with GAS.
+old_gas := $(shell if $(AS) --version 2>&1 | grep 'version 2.7' > /dev/null; then echo y; else echo n; fi)
 
-# determine if we can use the BWX instructions with GAS
-OLD_GAS := $(shell if $(AS) --version 2>&1 | grep 'version 2.7' > /dev/null; then echo y; else echo n; fi)
+# Determine if GCC understands the -mcpu= option.
+have_mcpu := $(shell if $(CC) -mcpu=ev5 -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi)
 
-# If PYXIS, then enable use of BWIO space
-ifneq ($(OLD_GAS),y)
- ifeq ($(CONFIG_ALPHA_PYXIS),y)
-  CFLAGS := $(CFLAGS) -Wa,-m21164a -DBWX_USABLE -DBWIO_ENABLED
- endif
+# If GENERIC, make sure to turn off any instruction set extensions that
+# the host compiler might have on by default.  Given that EV4 and EV5
+# have the same instruction set, prefer EV5 because an EV5 schedule is
+# more likely to keep an EV4 processor busy than vice-versa.
+ifeq ($(CONFIG_ALPHA_GENERIC)$(have_mcpu),yy)
+ CFLAGS := $(CFLAGS) -mcpu=ev5
 endif
 
 # If EV6, turn on the proper optimizations.
-ifeq ($(CONFIG_ALPHA_EV6),y)
- CFLAGS := -mcpu=ev6 $(CFLAGS)
+ifeq ($(CONFIG_ALPHA_EV6)$(have_mcpu),yy)
+ CFLAGS := $(CFLAGS) -mcpu=ev6
+endif
+
+# For TSUNAMI, we must have the assembler not emulate our instructions.
+# BWX is most important, but we don't really want any emulation ever.
+ifeq ($(old_gas),y)
+ ifneq ($(CONFIG_ALPHA_GENERIC)$(CONFIG_ALPHA_TSUNAMI),)
+   # How do we do #error in make?
+   CFLAGS := --error-please-upgrade-your-assembler
+ endif
+else
+ ifeq ($(CONFIG_ALPHA_GENERIC),y)
+   CFLAGS := $(CFLAGS) -Wa,-mev6
+ endif
+ ifeq ($(CONFIG_ALPHA_PYXIS),y)
+   CFLAGS := $(CFLAGS) -Wa,-m21164a -DBWIO_ENABLED
+ endif
 endif
 
 HEAD := arch/alpha/kernel/head.o
@@ -59,7 +66,7 @@ rawboot:
        @$(MAKEBOOT) rawboot
 
 #
-# my boot writes directly to a specific disk partition, I doubt most
+# My boot writes directly to a specific disk partition, I doubt most
 # people will want to do that without changes..
 #
 msb my-special-boot:
index 7eda886d91ce145699856cb9dddd7583bc42669c..9d0f5769ec50bf0863db2f01b95aba9b2ac54355 100644 (file)
@@ -31,30 +31,30 @@ else
 fi
 
 choice 'Alpha system type' \
-       "Avanti         CONFIG_ALPHA_AVANTI             \
-        Alpha-XL       CONFIG_ALPHA_XL                 \
-        Alpha-XLT      CONFIG_ALPHA_XLT                \
-        Cabriolet      CONFIG_ALPHA_CABRIOLET          \
-        EB66           CONFIG_ALPHA_EB66               \
-        EB66+          CONFIG_ALPHA_EB66P              \
-        EB64+          CONFIG_ALPHA_EB64P              \
-        EB164          CONFIG_ALPHA_EB164              \
-        PC164          CONFIG_ALPHA_PC164              \
-        LX164          CONFIG_ALPHA_LX164              \
-        SX164          CONFIG_ALPHA_SX164              \
-        DP264          CONFIG_ALPHA_DP264              \
-        Jensen         CONFIG_ALPHA_JENSEN             \
-        Noname         CONFIG_ALPHA_NONAME             \
-        Takara         CONFIG_ALPHA_TAKARA             \
-        Mikasa         CONFIG_ALPHA_MIKASA             \
-        Noritake       CONFIG_ALPHA_NORITAKE           \
-        Alcor          CONFIG_ALPHA_ALCOR              \
-        Miata          CONFIG_ALPHA_MIATA              \
-        Sable          CONFIG_ALPHA_SABLE              \
-        Rawhide        CONFIG_ALPHA_RAWHIDE            \
-        AlphaBook1     CONFIG_ALPHA_BOOK1              \
-        Ruffian        CONFIG_ALPHA_RUFFIAN            \
-        Platform2000   CONFIG_ALPHA_P2K" Cabriolet
+       "Generic                CONFIG_ALPHA_GENERIC            \
+        Alcor/Alpha-XLT        CONFIG_ALPHA_ALCOR              \
+        Alpha-XL               CONFIG_ALPHA_XL                 \
+        AlphaBook1             CONFIG_ALPHA_BOOK1              \
+        Avanti                 CONFIG_ALPHA_AVANTI             \
+        Cabriolet              CONFIG_ALPHA_CABRIOLET          \
+        DP264                  CONFIG_ALPHA_DP264              \
+        EB164                  CONFIG_ALPHA_EB164              \
+        EB64+                  CONFIG_ALPHA_EB64P              \
+        EB66                   CONFIG_ALPHA_EB66               \
+        EB66+                  CONFIG_ALPHA_EB66P              \
+        Jensen                 CONFIG_ALPHA_JENSEN             \
+        LX164                  CONFIG_ALPHA_LX164              \
+        Miata                  CONFIG_ALPHA_MIATA              \
+        Mikasa                 CONFIG_ALPHA_MIKASA             \
+        Noname                 CONFIG_ALPHA_NONAME             \
+        Noritake               CONFIG_ALPHA_NORITAKE           \
+        PC164                  CONFIG_ALPHA_PC164              \
+        Platform2000           CONFIG_ALPHA_P2K                \
+        Rawhide                CONFIG_ALPHA_RAWHIDE            \
+        Ruffian                CONFIG_ALPHA_RUFFIAN            \
+        SX164                  CONFIG_ALPHA_SX164              \
+        Sable                  CONFIG_ALPHA_SABLE              \
+        Takara                 CONFIG_ALPHA_TAKARA" Generic
 
 # clear all implied options (don't want default values for those):
 unset CONFIG_ALPHA_EV4 CONFIG_ALPHA_EV5 CONFIG_ALPHA_EV6
@@ -64,6 +64,11 @@ unset CONFIG_ALPHA_T2 CONFIG_ALPHA_PYXIS
 unset CONFIG_ALPHA_TSUNAMI CONFIG_ALPHA_MCPCIA
 unset CONFIG_ALPHA_NEED_ROUNDING_EMULATION
 
+if [ "$CONFIG_ALPHA_GENERIC" = "y" ]
+then
+       define_bool CONFIG_PCI y
+       define_bool CONFIG_ALPHA_NEED_ROUNDING_EMULATION y
+fi
 if [ "$CONFIG_ALPHA_BOOK1" = "y" ]
 then
        define_bool CONFIG_ALPHA_NONAME y
index 7f0ffbf2069a2012af0d9246bd3f0c33a4731c82..64a051c16590530cb7917fd477e2f45333a5e25f 100644 (file)
@@ -18,35 +18,32 @@ CONFIG_MODULES=y
 # General setup
 #
 CONFIG_NATIVE=y
-# CONFIG_ALPHA_AVANTI is not set
+CONFIG_ALPHA_GENERIC=y
+# CONFIG_ALPHA_ALCOR is not set
 # CONFIG_ALPHA_XL is not set
-# CONFIG_ALPHA_XLT is not set
+# CONFIG_ALPHA_BOOK1 is not set
+# CONFIG_ALPHA_AVANTI is not set
 # CONFIG_ALPHA_CABRIOLET is not set
+# CONFIG_ALPHA_DP264 is not set
+# CONFIG_ALPHA_EB164 is not set
+# CONFIG_ALPHA_EB64P is not set
 # CONFIG_ALPHA_EB66 is not set
 # CONFIG_ALPHA_EB66P is not set
-# CONFIG_ALPHA_EB64P is not set
-# CONFIG_ALPHA_EB164 is not set
-# CONFIG_ALPHA_PC164 is not set
-# CONFIG_ALPHA_LX164 is not set
-# CONFIG_ALPHA_SX164 is not set
-# CONFIG_ALPHA_DP264 is not set
 # CONFIG_ALPHA_JENSEN is not set
-# CONFIG_ALPHA_NONAME is not set
-# CONFIG_ALPHA_TAKARA is not set
+# CONFIG_ALPHA_LX164 is not set
+# CONFIG_ALPHA_MIATA is not set
 # CONFIG_ALPHA_MIKASA is not set
+# CONFIG_ALPHA_NONAME is not set
 # CONFIG_ALPHA_NORITAKE is not set
-CONFIG_ALPHA_ALCOR=y
-# CONFIG_ALPHA_MIATA is not set
-# CONFIG_ALPHA_SABLE is not set
+# CONFIG_ALPHA_PC164 is not set
+# CONFIG_ALPHA_P2K is not set
 # CONFIG_ALPHA_RAWHIDE is not set
-# CONFIG_ALPHA_BOOK1 is not set
 # CONFIG_ALPHA_RUFFIAN is not set
-# CONFIG_ALPHA_P2K is not set
+# CONFIG_ALPHA_SX164 is not set
+# CONFIG_ALPHA_SABLE is not set
+# CONFIG_ALPHA_TAKARA is not set
 CONFIG_PCI=y
-CONFIG_ALPHA_EV5=y
-CONFIG_ALPHA_CIA=y
-CONFIG_ALPHA_SRM=y
-CONFIG_ALPHA_EISA=y
+CONFIG_ALPHA_NEED_ROUNDING_EMULATION=y
 # CONFIG_PCI_QUIRKS is not set
 CONFIG_PCI_OLD_PROC=y
 CONFIG_NET=y
index 8d09ea8c438b638211d069873f3ec0d248aafd52..fcbb37615fade5ef6891b8a2a8378c2b1d00136b 100644 (file)
@@ -20,34 +20,96 @@ O_OBJS   := entry.o traps.o process.o osf_sys.o irq.o signal.o setup.o \
 OX_OBJS  := alpha_ksyms.o
 
 
+ifdef CONFIG_ALPHA_GENERIC
+
+O_OBJS  += core_apecs.o core_cia.o core_lca.o core_mcpcia.o core_pyxis.o \
+           core_t2.o core_tsunami.o \
+           sys_alcor.o sys_cabriolet.o sys_dp264.o sys_eb64p.o \
+           sys_jensen.o sys_miata.o sys_mikasa.o sys_noritake.o \
+           sys_rawhide.o sys_ruffian.o sys_sable.o sys_sio.o \
+           sys_sx164.o sys_takara.o \
+           es1888.o smc37c669.o smc37c93x.o
+else
+
+# Core logic support
 ifdef CONFIG_ALPHA_APECS
-O_OBJS   += apecs.o
+O_OBJS   += core_apecs.o
 endif
 ifdef CONFIG_ALPHA_CIA
-O_OBJS   += cia.o
+O_OBJS   += core_cia.o
 endif
 ifdef CONFIG_ALPHA_LCA
-O_OBJS   += lca.o
+O_OBJS   += core_lca.o
+endif
+ifdef CONFIG_ALPHA_MCPCIA
+O_OBJS   += core_mcpcia.o
 endif
 ifdef CONFIG_ALPHA_PYXIS
-O_OBJS   += pyxis.o
+O_OBJS   += core_pyxis.o
 endif
 ifdef CONFIG_ALPHA_T2
-O_OBJS   += t2.o
+O_OBJS   += core_t2.o
 endif
 ifdef CONFIG_ALPHA_TSUNAMI
-O_OBJS   += tsunami.o
+O_OBJS   += core_tsunami.o
 endif
-ifdef CONFIG_ALPHA_MCPCIA
-O_OBJS   += mcpcia.o
+
+# Board support
+ifneq ($(CONFIG_ALPHA_ALCOR)$(CONFIG_ALPHA_XLT),)
+O_OBJS   += sys_alcor.o
+endif
+ifneq ($(CONFIG_ALPHA_CABRIOLET)$(CONFIG_ALPHA_EB164)$(CONFIG_ALPHA_EB66P)$(CONFIG_ALPHA_LX164)$(CONFIG_ALPHA_PC164),)
+O_OBJS   += sys_cabriolet.o
+endif
+ifdef CONFIG_ALPHA_DP264
+O_OBJS   += sys_dp264.o
+endif
+ifneq ($(CONFIG_ALPHA_EB64P)$(CONFIG_ALPHA_EB66),)
+O_OBJS   += sys_eb64p.o
+endif
+ifdef CONFIG_ALPHA_JENSEN
+O_OBJS   += sys_jensen.o
+endif
+ifdef CONFIG_ALPHA_MIATA
+O_OBJS   += sys_miata.o
+endif
+ifdef CONFIG_ALPHA_MIKASA
+O_OBJS   += sys_mikasa.o
+endif
+ifdef CONFIG_ALPHA_NORITAKE
+O_OBJS   += sys_noritake.o
+endif
+ifdef CONFIG_ALPHA_RAWHIDE
+O_OBJS   += sys_rawhide.o
+endif
+ifdef CONFIG_ALPHA_RUFFIAN
+O_OBJS   += sys_ruffian.o
+endif
+ifdef CONFIG_ALPHA_SABLE
+O_OBJS   += sys_sable.o
+endif
+ifneq ($(CONFIG_ALPHA_BOOK1)$(CONFIG_ALPHA_AVANTI)$(CONFIG_ALPHA_NONAME)$(CONFIG_ALPHA_P2K)$(CONFIG_ALPHA_XL),)
+O_OBJS   += sys_sio.o
+endif
+ifdef CONFIG_ALPHA_SX164
+O_OBJS   += sys_sx164.o
+endif
+ifdef CONFIG_ALPHA_TAKARA
+O_OBJS   += sys_takara.o
 endif
 
-ifneq ($(CONFIG_ALPHA_PC164)$(CONFIG_ALPHA_LX164),nn)
-O_OBJS   += smc37c93x.o
+# Device support
+ifdef CONFIG_ALPHA_MIATA
+O_OBJS   += es1888.o
 endif
-ifneq ($(CONFIG_ALPHA_SX164)$(CONFIG_ALPHA_MIATA)$(CONFIG_ALPHA_DP264),nnn)
+ifneq ($(CONFIG_ALPHA_SX164)$(CONFIG_ALPHA_MIATA)$(CONFIG_ALPHA_DP264),)
 O_OBJS   += smc37c669.o
 endif
+ifneq ($(CONFIG_ALPHA_PC164)$(CONFIG_ALPHA_LX164),)
+O_OBJS   += smc37c93x.o
+endif
+
+endif # GENERIC
 
 ifdef SMP
 O_OBJS   += smp.o
@@ -55,9 +117,4 @@ endif
 
 all: kernel.o head.o
 
-head.o: head.s
-
-head.s: head.S $(TOPDIR)/include/asm-alpha/system.h
-       $(CPP) -traditional $(AFLAGS) -o $*.s $<
-
 include $(TOPDIR)/Rules.make
index f66ace9a0be55d60cc8e47d4339dee8b849a69bc..a7047dd1f4f4fa96d4d69ca43ec450ccc4ba1d4a 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/softirq.h>
 #include <asm/fpu.h>
 #include <asm/irq.h>
+#include <asm/machvec.h>
 
 #define __KERNEL_SYSCALLS__
 #include <asm/unistd.h>
@@ -43,6 +44,7 @@ extern void __remlu (void);
 extern void __divqu (void);
 extern void __remqu (void);
 
+EXPORT_SYMBOL(alpha_mv);
 EXPORT_SYMBOL(local_bh_count);
 EXPORT_SYMBOL(local_irq_count);
 EXPORT_SYMBOL(enable_irq);
@@ -121,7 +123,9 @@ EXPORT_SYMBOL(csum_ipv6_magic);
 
 #ifdef CONFIG_MATHEMU_MODULE
 extern long (*alpha_fp_emul_imprecise)(struct pt_regs *, unsigned long);
+extern long (*alpha_fp_emul) (unsigned long pc);
 EXPORT_SYMBOL(alpha_fp_emul_imprecise);
+EXPORT_SYMBOL(alpha_fp_emul);
 #endif
 
 /*
diff --git a/arch/alpha/kernel/apecs.c b/arch/alpha/kernel/apecs.c
deleted file mode 100644 (file)
index cc8912a..0000000
+++ /dev/null
@@ -1,622 +0,0 @@
-/*
- * Code common to all APECS chips.
- *
- * Rewritten for Apecs from the lca.c from:
- *
- * Written by David Mosberger (davidm@cs.arizona.edu) with some code
- * taken from Dave Rusling's (david.rusling@reo.mts.dec.com) 32-bit
- * bios code.
- */
-#include <linux/kernel.h>
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/hwrpb.h>
-#include <asm/ptrace.h>
-
-/*
- * NOTE: Herein lie back-to-back mb instructions.  They are magic. 
- * One plausible explanation is that the i/o controller does not properly
- * handle the system transaction.  Another involves timing.  Ho hum.
- */
-
-extern struct hwrpb_struct *hwrpb;
-extern asmlinkage void wrmces(unsigned long mces);
-
-/*
- * BIOS32-style PCI interface:
- */
-
-#ifdef DEBUG
-# define DBG(args)     printk args
-#else
-# define DBG(args)
-#endif
-
-#define vuip   volatile unsigned int  *
-
-static volatile unsigned int apecs_mcheck_expected = 0;
-static volatile unsigned int apecs_mcheck_taken = 0;
-static unsigned int apecs_jd, apecs_jd1, apecs_jd2;
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-unsigned int APECS_DMA_WIN_BASE = APECS_DMA_WIN_BASE_DEFAULT;
-unsigned int APECS_DMA_WIN_SIZE = APECS_DMA_WIN_SIZE_DEFAULT;
-#endif /* SRM_SETUP */
-
-/*
- * Given a bus, device, and function number, compute resulting
- * configuration space address and setup the APECS_HAXR2 register
- * accordingly.  It is therefore not safe to have concurrent
- * invocations to configuration space access routines, but there
- * really shouldn't be any need for this.
- *
- * Type 0:
- *
- *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | | | | | | | | | | | | | | | | | | |F|F|F|R|R|R|R|R|R|0|0|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *     31:11   Device select bit.
- *     10:8    Function number
- *      7:2    Register number
- *
- * Type 1:
- *
- *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *     31:24   reserved
- *     23:16   bus number (8 bits = 128 possible buses)
- *     15:11   Device number (5 bits)
- *     10:8    function number
- *      7:2    register number
- *  
- * Notes:
- *     The function number selects which function of a multi-function device 
- *     (e.g., SCSI and Ethernet).
- * 
- *     The register selects a DWORD (32 bit) register offset.  Hence it
- *     doesn't get shifted by 2 bits as we want to "drop" the bottom two
- *     bits.
- */
-static int mk_conf_addr(unsigned char bus, unsigned char device_fn,
-                       unsigned char where, unsigned long *pci_addr,
-                       unsigned char *type1)
-{
-       unsigned long addr;
-
-       DBG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
-            " pci_addr=0x%p, type1=0x%p)\n",
-            bus, device_fn, where, pci_addr, type1));
-
-       if (bus == 0) {
-               int device = device_fn >> 3;
-
-               /* type 0 configuration cycle: */
-
-               if (device > 20) {
-                       DBG(("mk_conf_addr: device (%d) > 20, returning -1\n",
-                            device));
-                       return -1;
-               }
-
-               *type1 = 0;
-               addr = (device_fn << 8) | (where);
-       } else {
-               /* type 1 configuration cycle: */
-               *type1 = 1;
-               addr = (bus << 16) | (device_fn << 8) | (where);
-       }
-       *pci_addr = addr;
-       DBG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
-       return 0;
-}
-
-
-static unsigned int conf_read(unsigned long addr, unsigned char type1)
-{
-       unsigned long flags;
-       unsigned int stat0, value;
-       unsigned int haxr2 = 0; /* to keep gcc quiet */
-
-#ifdef CONFIG_ALPHA_SRM
-       /* some SRMs step on these registers during a machine check: */
-       register long s0 asm ("9");
-       register long s1 asm ("10");
-       register long s2 asm ("11");
-       register long s3 asm ("12");
-       register long s4 asm ("13");
-       register long s5 asm ("14");
-       asm volatile ("# %0" : "r="(s0));
-       asm volatile ("# %0" : "r="(s1));
-       asm volatile ("# %0" : "r="(s2));
-       asm volatile ("# %0" : "r="(s3));
-       asm volatile ("# %0" : "r="(s4));
-       asm volatile ("# %0" : "r="(s5));
-#endif
-
-       save_flags(flags);      /* avoid getting hit by machine check */
-       cli();
-
-       DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
-
-       /* reset status register to avoid losing errors: */
-       stat0 = *(vuip)APECS_IOC_DCSR;
-       *(vuip)APECS_IOC_DCSR = stat0;
-       mb();
-       DBG(("conf_read: APECS DCSR was 0x%x\n", stat0));
-       /* if Type1 access, must set HAE #2 */
-       if (type1) {
-               haxr2 = *(vuip)APECS_IOC_HAXR2;
-               mb();
-               *(vuip)APECS_IOC_HAXR2 = haxr2 | 1;
-               DBG(("conf_read: TYPE1 access\n"));
-       }
-
-       draina();
-       apecs_mcheck_expected = 1;
-       apecs_mcheck_taken = 0;
-       mb();
-       /* access configuration space: */
-       value = *(vuip)addr;
-       mb();
-       mb();  /* magic */
-       if (apecs_mcheck_taken) {
-               apecs_mcheck_taken = 0;
-               value = 0xffffffffU;
-               mb();
-       }
-       apecs_mcheck_expected = 0;
-       mb();
-
-#if 1
-       /*
-        * david.rusling@reo.mts.dec.com.  This code is needed for the
-        * EB64+ as it does not generate a machine check (why I don't
-        * know).  When we build kernels for one particular platform
-        * then we can make this conditional on the type.
-        */
-       draina();
-
-       /* now look for any errors */
-       stat0 = *(vuip)APECS_IOC_DCSR;
-       DBG(("conf_read: APECS DCSR after read 0x%x\n", stat0));
-       if (stat0 & 0xffe0U) { /* is any error bit set? */
-               /* if not NDEV, print status */
-               if (!(stat0 & 0x0800)) {
-                       printk("apecs.c:conf_read: got stat0=%x\n", stat0);
-               }
-
-               /* reset error status: */
-               *(vuip)APECS_IOC_DCSR = stat0;
-               mb();
-               wrmces(0x7);                    /* reset machine check */
-               value = 0xffffffff;
-       }
-#endif
-
-       /* if Type1 access, must reset HAE #2 so normal IO space ops work */
-       if (type1) {
-               *(vuip)APECS_IOC_HAXR2 = haxr2 & ~1;
-               mb();
-       }
-       restore_flags(flags);
-#ifdef CONFIG_ALPHA_SRM
-       /* some SRMs step on these registers during a machine check: */
-       asm volatile ("# %0" :: "r"(s0));
-       asm volatile ("# %0" :: "r"(s1));
-       asm volatile ("# %0" :: "r"(s2));
-       asm volatile ("# %0" :: "r"(s3));
-       asm volatile ("# %0" :: "r"(s4));
-       asm volatile ("# %0" :: "r"(s5));
-#endif
-       return value;
-}
-
-
-static void conf_write(unsigned long addr, unsigned int value, unsigned char type1)
-{
-       unsigned long flags;
-       unsigned int stat0;
-       unsigned int haxr2 = 0; /* to keep gcc quiet */
-
-       save_flags(flags);      /* avoid getting hit by machine check */
-       cli();
-
-       /* reset status register to avoid losing errors: */
-       stat0 = *(vuip)APECS_IOC_DCSR;
-       *(vuip)APECS_IOC_DCSR = stat0;
-       mb();
-
-       /* if Type1 access, must set HAE #2 */
-       if (type1) {
-               haxr2 = *(vuip)APECS_IOC_HAXR2;
-               mb();
-               *(vuip)APECS_IOC_HAXR2 = haxr2 | 1;
-       }
-
-       draina();
-       apecs_mcheck_expected = 1;
-       mb();
-       /* access configuration space: */
-       *(vuip)addr = value;
-       mb();
-       mb();  /* magic */
-       apecs_mcheck_expected = 0;
-       mb();
-
-#if 1
-       /*
-        * david.rusling@reo.mts.dec.com.  This code is needed for the
-        * EB64+ as it does not generate a machine check (why I don't
-        * know).  When we build kernels for one particular platform
-        * then we can make this conditional on the type.
-        */
-       draina();
-
-       /* now look for any errors */
-       stat0 = *(vuip)APECS_IOC_DCSR;
-       if (stat0 & 0xffe0U) { /* is any error bit set? */
-               /* if not NDEV, print status */
-               if (!(stat0 & 0x0800)) {
-                       printk("apecs.c:conf_write: got stat0=%x\n", stat0);
-               }
-
-               /* reset error status: */
-               *(vuip)APECS_IOC_DCSR = stat0;
-               mb();
-               wrmces(0x7);                    /* reset machine check */
-       }
-#endif
-
-       /* if Type1 access, must reset HAE #2 so normal IO space ops work */
-       if (type1) {
-               *(vuip)APECS_IOC_HAXR2 = haxr2 & ~1;
-               mb();
-       }
-       restore_flags(flags);
-}
-
-
-int pcibios_read_config_byte (unsigned char bus, unsigned char device_fn,
-                             unsigned char where, unsigned char *value)
-{
-       unsigned long addr = APECS_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       *value = 0xff;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       addr |= (pci_addr << 5) + 0x00;
-
-       *value = conf_read(addr, type1) >> ((where & 3) * 8);
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_read_config_word (unsigned char bus, unsigned char device_fn,
-                             unsigned char where, unsigned short *value)
-{
-       unsigned long addr = APECS_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       *value = 0xffff;
-
-       if (where & 0x1) {
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-       }
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       addr |= (pci_addr << 5) + 0x08;
-
-       *value = conf_read(addr, type1) >> ((where & 3) * 8);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_read_config_dword (unsigned char bus, unsigned char device_fn,
-                              unsigned char where, unsigned int *value)
-{
-       unsigned long addr = APECS_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       *value = 0xffffffff;
-       if (where & 0x3) {
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-       }
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x18;
-       *value = conf_read(addr, type1);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_write_config_byte (unsigned char bus, unsigned char device_fn,
-                              unsigned char where, unsigned char value)
-{
-       unsigned long addr = APECS_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x00;
-       conf_write(addr, value << ((where & 3) * 8), type1);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_write_config_word (unsigned char bus, unsigned char device_fn,
-                              unsigned char where, unsigned short value)
-{
-       unsigned long addr = APECS_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x08;
-       conf_write(addr, value << ((where & 3) * 8), type1);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_write_config_dword (unsigned char bus, unsigned char device_fn,
-                               unsigned char where, unsigned int value)
-{
-       unsigned long addr = APECS_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x18;
-       conf_write(addr, value << ((where & 3) * 8), type1);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-unsigned long apecs_init(unsigned long mem_start, unsigned long mem_end)
-{
-
-#ifdef CONFIG_ALPHA_XL
-       /*
-        * Set up the PCI->physical memory translation windows.
-        * For the XL we *must* use both windows, in order to
-        * maximize the amount of physical memory that can be used
-        * to DMA from the ISA bus, and still allow PCI bus devices
-        * access to all of host memory.
-        *
-        * see <asm/apecs.h> for window bases and sizes.
-        *
-        * this restriction due to the true XL motherboards' 82379AB SIO
-        * PCI<->ISA bridge chip which passes only 27 bits of address...
-        */
-
-       *(vuip)APECS_IOC_PB1R = 1U<<19 | (APECS_XL_DMA_WIN1_BASE & 0xfff00000U);
-       *(vuip)APECS_IOC_PM1R = (APECS_XL_DMA_WIN1_SIZE - 1) & 0xfff00000U;
-       *(vuip)APECS_IOC_TB1R = 0;
-
-       *(vuip)APECS_IOC_PB2R = 1U<<19 | (APECS_XL_DMA_WIN2_BASE & 0xfff00000U);
-       *(vuip)APECS_IOC_PM2R = (APECS_XL_DMA_WIN2_SIZE - 1) & 0xfff00000U;
-       *(vuip)APECS_IOC_TB2R = 0;
-
-#else  /* CONFIG_ALPHA_XL */
-#ifdef CONFIG_ALPHA_SRM_SETUP
-       /* check window 1 for enabled and mapped to 0 */
-       if ((*(vuip)APECS_IOC_PB1R & (1U<<19)) && (*(vuip)APECS_IOC_TB1R == 0))
-       {
-         APECS_DMA_WIN_BASE = *(vuip)APECS_IOC_PB1R & 0xfff00000U;
-         APECS_DMA_WIN_SIZE = *(vuip)APECS_IOC_PM1R & 0xfff00000U;
-         APECS_DMA_WIN_SIZE += 0x00100000U;
-#if 0
-         printk("apecs_init: using Window 1 settings\n");
-         printk("apecs_init: PB1R 0x%x PM1R 0x%x TB1R 0x%x\n",
-                *(vuip)APECS_IOC_PB1R,
-                *(vuip)APECS_IOC_PM1R,
-                *(vuip)APECS_IOC_TB1R);
-#endif
-       }
-       else    /* check window 2 for enabled and mapped to 0 */
-       if ((*(vuip)APECS_IOC_PB2R & (1U<<19)) && (*(vuip)APECS_IOC_TB2R == 0))
-       {
-         APECS_DMA_WIN_BASE = *(vuip)APECS_IOC_PB2R & 0xfff00000U;
-         APECS_DMA_WIN_SIZE = *(vuip)APECS_IOC_PM2R & 0xfff00000U;
-         APECS_DMA_WIN_SIZE += 0x00100000U;
-#if 0
-         printk("apecs_init: using Window 2 settings\n");
-         printk("apecs_init: PB2R 0x%x PM2R 0x%x TB2R 0x%x\n",
-                *(vuip)APECS_IOC_PB2R,
-                *(vuip)APECS_IOC_PM2R,
-                *(vuip)APECS_IOC_TB2R);
-#endif
-       }
-       else /* we must use our defaults... */
-#endif /* SRM_SETUP */
-       {
-       /*
-        * Set up the PCI->physical memory translation windows.
-        * For now, window 2 is disabled.  In the future, we may
-        * want to use it to do scatter/gather DMA.  Window 1
-        * goes at 1 GB and is 1 GB large.
-        */
-       *(vuip)APECS_IOC_PB2R  = 0U; /* disable window 2 */
-
-       *(vuip)APECS_IOC_PB1R  = 1U<<19 | (APECS_DMA_WIN_BASE & 0xfff00000U);
-       *(vuip)APECS_IOC_PM1R  = (APECS_DMA_WIN_SIZE - 1) & 0xfff00000U;
-       *(vuip)APECS_IOC_TB1R  = 0;
-       }
-#endif /* CONFIG_ALPHA_XL */
-
-#ifdef CONFIG_ALPHA_CABRIOLET
-#ifdef NO_LONGER_NEEDED_I_HOPE
-       /*
-        * JAE: HACK!!! for now, hardwire if configured...
-        * davidm: Older miniloader versions don't set the clock frequency
-        * right, so hardcode it for now.
-        */
-       if (hwrpb->sys_type == ST_DEC_EB64P) {
-               hwrpb->sys_type = ST_DEC_EBPC64;
-       }
-       if (hwrpb->cycle_freq == 0) {
-           hwrpb->cycle_freq = 275000000;
-       }
-
-       /* update checksum: */
-       {
-           unsigned long *l, sum;
-
-           sum = 0;
-           for (l = (unsigned long *) hwrpb;
-                l < (unsigned long *) &hwrpb->chksum;
-                ++l)
-             sum += *l;
-           hwrpb->chksum = sum;
-       }
-#endif /* NO_LONGER_NEEDED_I_HOPE */
-#endif /* CONFIG_ALPHA_CABRIOLET */
-
-       /*
-        * Finally, clear the HAXR2 register, which gets used
-        *  for PCI Config Space accesses. That is the way
-        *  we want to use it, and we do not want to depend on
-        *  what ARC or SRM might have left behind...
-        */
-       {
-#if 0
-         unsigned int haxr2 = *(vuip)APECS_IOC_HAXR2; mb();
-         if (haxr2) printk("apecs_init: HAXR2 was 0x%x\n", haxr2);
-#endif
-         *(vuip)APECS_IOC_HAXR2 = 0; mb();
-       }
-
-
-       return mem_start;
-}
-
-int apecs_pci_clr_err(void)
-{
-       apecs_jd = *(vuip)APECS_IOC_DCSR;
-       if (apecs_jd & 0xffe0L) {
-               apecs_jd1 = *(vuip)APECS_IOC_SEAR;
-               *(vuip)APECS_IOC_DCSR = apecs_jd | 0xffe1L;
-               apecs_jd = *(vuip)APECS_IOC_DCSR;
-               mb();
-       }
-       *(vuip)APECS_IOC_TBIA = (unsigned int)APECS_IOC_TBIA;
-       apecs_jd2 = *(vuip)APECS_IOC_TBIA;
-       mb();
-       return 0;
-}
-
-void apecs_machine_check(unsigned long vector, unsigned long la_ptr,
-                        struct pt_regs * regs)
-{
-       struct el_common *mchk_header;
-       struct el_procdata *mchk_procdata;
-       struct el_apecs_sysdata_mcheck *mchk_sysdata;
-       unsigned long *ptr;
-       int i;
-
-
-       mchk_header = (struct el_common *)la_ptr;
-       mchk_procdata = (struct el_procdata *)
-         (la_ptr + mchk_header->proc_offset - sizeof(mchk_procdata->paltemp));
-       mchk_sysdata = 
-         (struct el_apecs_sysdata_mcheck *)(la_ptr + mchk_header->sys_offset);
-
-#ifdef DEBUG
-       printk("apecs_machine_check: vector=0x%lx la_ptr=0x%lx\n",
-              vector, la_ptr);
-       printk("        pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
-              regs->pc, mchk_header->size, mchk_header->proc_offset,
-              mchk_header->sys_offset);
-       printk("apecs_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
-              apecs_mcheck_expected, mchk_sysdata->epic_dcsr,
-              mchk_sysdata->epic_pear);
-       ptr = (unsigned long *)la_ptr;
-       for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
-               printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
-       }
-#endif /* DEBUG */
-
-       /*
-        * Check if machine check is due to a badaddr() and if so,
-        * ignore the machine check.
-        */
-#ifdef CONFIG_ALPHA_MIKASA
-#define MCHK_NO_DEVSEL 0x205L
-#define MCHK_NO_TABT 0x204L
-       if (apecs_mcheck_expected &&
-           (((unsigned int)mchk_header->code == MCHK_NO_DEVSEL) ||
-            ((unsigned int)mchk_header->code == MCHK_NO_TABT))
-           )
-       {
-#else
-       if (apecs_mcheck_expected && (mchk_sysdata->epic_dcsr && 0x0c00UL)) {
-#endif
-               apecs_mcheck_expected = 0;
-               apecs_mcheck_taken = 1;
-               mb();
-               mb(); /* magic */
-               apecs_pci_clr_err();
-               wrmces(0x7);
-               mb();
-               draina();
-               DBG(("apecs_machine_check: EXPECTED\n"));
-       }
-       else if (vector == 0x620 || vector == 0x630) {
-               wrmces(0x1f); /* disable correctable from now on */
-               mb();
-               draina();
-               printk("apecs_machine_check: HW correctable (0x%lx)\n",
-                      vector);
-       }
-       else {
-               printk(KERN_CRIT "APECS machine check:\n");
-               printk(KERN_CRIT "  vector=0x%lx la_ptr=0x%lx\n",
-                      vector, la_ptr);
-               printk(KERN_CRIT
-                      "  pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
-                      regs->pc, mchk_header->size, mchk_header->proc_offset,
-                      mchk_header->sys_offset);
-               printk(KERN_CRIT "  expected %d DCSR 0x%lx PEAR 0x%lx\n",
-                      apecs_mcheck_expected, mchk_sysdata->epic_dcsr,
-                      mchk_sysdata->epic_pear);
-
-               ptr = (unsigned long *)la_ptr;
-               for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
-                   printk(KERN_CRIT " +%lx %lx %lx\n",
-                          i*sizeof(long), ptr[i], ptr[i+1]);
-               }
-#if 0
-               /* doesn't work with MILO */
-               show_regs(regs);
-#endif
-       }
-}
index e2a04324b5c843027edc8d7947121896d773ecc6..633273954f30c8c428e61598d85445172e164b07 100644 (file)
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/pci.h>
+#include <asm/pci.h>
 #include <asm/dma.h>
 
-#if 0
+#include "proto.h"
+#include "bios32.h"
+
+#define DEBUG_DEVS 0
+
+#if DEBUG_DEVS
 # define DBG_DEVS(args)                printk args
 #else
 # define DBG_DEVS(args)
 
 asmlinkage int sys_pciconfig_read() { return -ENOSYS; }
 asmlinkage int sys_pciconfig_write() { return -ENOSYS; }
+void reset_for_srm(void) { }
 
 #else /* CONFIG_PCI */
 
 #include <linux/malloc.h>
 #include <linux/mm.h>
 
-#include <asm/hwrpb.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/segment.h>
 #include <asm/system.h>
 
-
-#define KB             1024
-#define MB             (1024*KB)
-#define GB             (1024*MB)
+/*
+ * PCI public interfaces.
+ */
 
 #define MAJOR_REV      0
+#define MINOR_REV      4       /* minor revision 4, add multi-PCI handling */
 
-/* minor revision 4, add multi-PCI handling */
-#define MINOR_REV      4
 
-/*
- * Align VAL to ALIGN, which must be a power of two.
- */
-#define ALIGN(val,align)       (((val) + ((align) - 1)) & ~((align) - 1))
+int
+pcibios_present(void)
+{
+       return alpha_mv.pci_read_config_byte != NULL;
+}
 
+void __init
+pcibios_init(void)
+{
+       printk("Alpha PCI BIOS32 revision %x.%02x\n", MAJOR_REV, MINOR_REV);
+       if (alpha_use_srm_setup)
+               printk("   NOT modifying existing (SRM) PCI configuration\n");
 
-/*
- * On multiple PCI bus machines, create a handle from the bus number.
- */
-#if defined(CONFIG_ALPHA_MCPCIA) /* || defined(CONFIG_ALPHA_TSUNAMI) */
-extern struct linux_hose_info *bus2hose[256];
-#define HANDLE(b) (((unsigned long)(bus2hose[(b)]->pci_hose_index)&3)<<32)
-#define DEV_IS_ON_PRIMARY(dev) \
-       (bus2hose[(dev)->bus->number]->pci_first_busno == (dev)->bus->number)
-#else
-#define HANDLE(b) (0)
-#define DEV_IS_ON_PRIMARY(dev) ((dev)->bus->number == 0)
-#endif
+       /* FIXME: Scan for multiple PCI busses here.  */
+}
 
-/*
- * PCI_MODIFY
- *
- * Temporary internal macro.  If this 0, then do not write to any of
- * the PCI registers, merely read them (i.e., use configuration as
- * determined by SRM).  The SRM seem do be doing a less than perfect
- * job in configuring PCI devices, so for now we do it ourselves.
- * Reconfiguring PCI devices breaks console (RPB) callbacks, but
- * those don't work properly with 64 bit addresses anyways.
- *
- * The accepted convention seems to be that the console (POST
- * software) should fully configure boot devices and configure the
- * interrupt routing of *all* devices.  In particular, the base
- * addresses of non-boot devices need not be initialized.  For
- * example, on the AXPpci33 board, the base address a #9 GXE PCI
- * graphics card reads as zero (this may, however, be due to a bug in
- * the graphics card---there have been some rumor that the #9 BIOS
- * incorrectly resets that address to 0...).
- */
-#ifdef CONFIG_ALPHA_SRM_SETUP
-#define PCI_MODIFY             0
-static struct pci_dev *irq_dev_to_reset[16];
-static unsigned char irq_to_reset[16];
-static int irq_reset_count = 0;
-static struct pci_dev *io_dev_to_reset[16];
-static unsigned char io_reg_to_reset[16];
-static unsigned int io_to_reset[16];
-static int io_reset_count = 0;
-#else /* SRM_SETUP */
-#define PCI_MODIFY             1
-#endif /* SRM_SETUP */
-
-extern struct hwrpb_struct *hwrpb;
-
-/* Forward declarations for some extra fixup routines for specific hardware. */
-#if defined(CONFIG_ALPHA_PC164) || defined(CONFIG_ALPHA_LX164)
-extern int SMC93x_Init(void);
-#endif
-extern int SMC669_Init(void);
-#ifdef CONFIG_ALPHA_MIATA
-static int es1888_init(void);
-#endif
+char * __init
+pcibios_setup(char *str)
+{
+       return str;
+}
+
+void __init
+pcibios_fixup(void)
+{
+       alpha_mv.pci_fixup();
+}
 
-#if PCI_MODIFY
+void __init
+pcibios_fixup_bus(struct pci_bus *bus)
+{
+}
+
+int
+pcibios_read_config_byte (u8 bus, u8 dev, u8 where, u8 *value)
+{
+       int r = PCIBIOS_FUNC_NOT_SUPPORTED;
+       if (alpha_mv.pci_read_config_byte)
+               r = alpha_mv.pci_read_config_byte(bus, dev, where, value);
+       return r;
+}
+
+int
+pcibios_read_config_word (u8 bus, u8 dev, u8 where, u16 *value)
+{
+       int r = PCIBIOS_FUNC_NOT_SUPPORTED;
+       if (alpha_mv.pci_read_config_word)
+               r = alpha_mv.pci_read_config_word(bus, dev, where, value);
+       return r;
+}
+
+int
+pcibios_read_config_dword (u8 bus, u8 dev, u8 where, u32 *value)
+{
+       int r = PCIBIOS_FUNC_NOT_SUPPORTED;
+       if (alpha_mv.pci_read_config_dword)
+               r = alpha_mv.pci_read_config_dword(bus, dev, where, value);
+       return r;
+}
+
+int
+pcibios_write_config_byte (u8 bus, u8 dev, u8 where, u8 value)
+{
+       int r = PCIBIOS_FUNC_NOT_SUPPORTED;
+       if (alpha_mv.pci_write_config_byte)
+               r = alpha_mv.pci_write_config_byte(bus, dev, where, value);
+       return r;
+}
+
+int
+pcibios_write_config_word (u8 bus, u8 dev, u8 where, u16 value)
+{
+       int r = PCIBIOS_FUNC_NOT_SUPPORTED;
+       if (alpha_mv.pci_write_config_word)
+               r = alpha_mv.pci_write_config_word(bus, dev, where, value);
+       return r;
+}
+
+int
+pcibios_write_config_dword (u8 bus, u8 dev, u8 where, u32 value)
+{
+       int r = PCIBIOS_FUNC_NOT_SUPPORTED;
+       if (alpha_mv.pci_write_config_dword)
+               r = alpha_mv.pci_write_config_dword(bus, dev, where, value);
+       return r;
+}
+
+asmlinkage int
+sys_pciconfig_read(unsigned long bus, unsigned long dfn,
+                  unsigned long off, unsigned long len,
+                  unsigned char *buf)
+{
+       unsigned char ubyte;
+       unsigned short ushort;
+       unsigned int uint;
+       long err = 0;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+       if (!pcibios_present())
+               return -ENOSYS;
+       
+       lock_kernel();
+       switch (len) {
+       case 1:
+               err = pcibios_read_config_byte(bus, dfn, off, &ubyte);
+               if (err != PCIBIOS_SUCCESSFUL)
+                       ubyte = 0xff;
+               put_user(ubyte, buf);
+               break;
+       case 2:
+               err = pcibios_read_config_word(bus, dfn, off, &ushort);
+               if (err != PCIBIOS_SUCCESSFUL)
+                       ushort = 0xffff;
+               put_user(ushort, (unsigned short *)buf);
+               break;
+       case 4:
+               err = pcibios_read_config_dword(bus, dfn, off, &uint);
+               if (err != PCIBIOS_SUCCESSFUL)
+                       uint = 0xffffffff;
+               put_user(uint, (unsigned int *)buf);
+               break;
+       default:
+               err = -EINVAL;
+               break;
+       }
+       unlock_kernel();
+       return err;
+}
+
+asmlinkage int
+sys_pciconfig_write(unsigned long bus, unsigned long dfn,
+                   unsigned long off, unsigned long len,
+                   unsigned char *buf)
+{
+       unsigned char ubyte;
+       unsigned short ushort;
+       unsigned int uint;
+       long err = 0;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+       if (!pcibios_present())
+               return -ENOSYS;
+
+       lock_kernel();
+       switch (len) {
+       case 1:
+               err = get_user(ubyte, buf);
+               if (err)
+                       break;
+               err = pcibios_write_config_byte(bus, dfn, off, ubyte);
+               if (err != PCIBIOS_SUCCESSFUL) {
+                       err = -EFAULT;
+               }
+               break;
+       case 2:
+               err = get_user(ushort, (unsigned short *)buf);
+               if (err)
+                       break;
+               err = pcibios_write_config_word(bus, dfn, off, ushort);
+               if (err != PCIBIOS_SUCCESSFUL) {
+                       err = -EFAULT;
+               }
+               break;
+       case 4:
+               err = get_user(uint, (unsigned int *)buf);
+               if (err)
+                       break;
+               err = pcibios_write_config_dword(bus, dfn, off, uint);
+               if (err != PCIBIOS_SUCCESSFUL) {
+                       err = -EFAULT;
+               }
+               break;
+       default:
+               err = -EINVAL;
+               break;
+       }
+       unlock_kernel();
+       return err;
+}
 
-/*
- * NOTE: we can't just blindly use 64K for machines with EISA busses; they
- * may also have PCI-PCI bridges present, and then we'd configure the bridge
- * incorrectly.
- *
- * Also, we start at 0x8000 or 0x9000, in hopes to get all devices'
- * IO space areas allocated *before* 0xC000; this is because certain
- * BIOSes (Millennium for one) use PCI Config space "mechanism #2"
- * accesses to probe the bus. If a device's registers appear at 0xC000,
- * it may see an INx/OUTx at that address during BIOS emulation of the
- * VGA BIOS, and some cards, notably Adaptec 2940UW, take mortal offense.
- *
- * Note that we may need this stuff for SRM_SETUP also, since certain
- * SRM consoles screw up and allocate I/O space addresses > 64K behind
- * PCI-to_PCI bridges, which can't pass I/O addresses larger than 64K, AFAIK.
- */
-#if defined(CONFIG_ALPHA_EISA)
-#define DEFAULT_IO_BASE 0x9000 /* start above 8th slot */
-#else
-#define DEFAULT_IO_BASE 0x8000 /* start at 8th slot */
-#endif
-static unsigned int    io_base;
 
-#if defined(CONFIG_ALPHA_XL)
 /*
- * An XL is AVANTI (APECS) family, *but* it has only 27 bits of ISA address
- * that get passed through the PCI<->ISA bridge chip. Although this causes
- * us to set the PCI->Mem window bases lower than normal, we still allocate
- * PCI bus devices' memory addresses *below* the low DMA mapping window,
- * and hope they fit below 64Mb (to avoid conflicts), and so that they can
- * be accessed via SPARSE space.
- *
- * We accept the risk that a broken Myrinet card will be put into a true XL
- * and thus can more easily run into the problem described below.
+ * Gory details start here...
  */
-#define DEFAULT_MEM_BASE (16*MB + 2*MB) /* 16M to 64M-1 is avail */
 
-#elif defined(CONFIG_ALPHA_LCA) || defined(CONFIG_ALPHA_APECS)
+struct linux_hose_info *bus2hose[256];
+
 /*
- * We try to make this address *always* have more than 1 bit set.
- * this is so that devices like the broken Myrinet card will always have
- * a PCI memory address that will never match a IDSEL address in
- * PCI Config space, which can cause problems with early rev cards.
- *
- * However, APECS and LCA have only 34 bits for physical addresses, thus
- * limiting PCI bus memory addresses for SPARSE access to be less than 128Mb.
+ * Align VAL to ALIGN, which must be a power of two.
  */
-#define DEFAULT_MEM_BASE (64*MB + 2*MB)
+#define ALIGN(val,align)       (((val) + ((align) - 1)) & ~((align) - 1))
 
-#else
-/*
- * We try to make this address *always* have more than 1 bit set.
- * this is so that devices like the broken Myrinet card will always have
- * a PCI memory address that will never match a IDSEL address in
- * PCI Config space, which can cause problems with early rev cards.
- *
- * Because CIA and PYXIS and T2 have more bits for physical addresses,
- * they support an expanded range of SPARSE memory addresses.
+
+/* 
+ * The following structure records initial configuration of devices
+ * so that we can reset them on shutdown and so enable clean reboots
+ * on SRM.  It is more trouble than it iw worth to conditionalize this.
  */
-#define DEFAULT_MEM_BASE (128*MB + 16*MB)
 
+static struct {
+       struct reset_irq {
+               struct pci_dev *dev;
+               u8 irq;
+       } irq[16];
+       int irq_count;
+
+       struct reset_io {
+               struct pci_dev *dev;
+               u8 reg;
+               u32 io;
+       } io[16];
+       int io_count;
+} srm_resets;
+
+/* Apply the collected reset modifications.  */
+
+void
+reset_for_srm(void)
+{
+       struct pci_dev *dev;
+       int i;
+
+       /* Reset any IRQs that we changed.  */
+       for (i = 0; i < srm_resets.irq_count; i++) {
+               dev = srm_resets.irq[i].dev;
+
+               pcibios_write_config_byte(dev->bus->number, dev->devfn,
+                                         PCI_INTERRUPT_LINE,
+                                         srm_resets.irq[i].irq);
+#if 1
+               printk("reset_for_srm: bus %d slot 0x%x "
+                      "SRM IRQ 0x%x changed back from 0x%x\n",
+                      dev->bus->number, PCI_SLOT(dev->devfn),
+                      srm_resets.irq[i].irq, dev->irq);
 #endif
-static unsigned int mem_base; 
+       }
+
+       /* Reset any IO addresses that we changed.  */
+       for (i = 0; i < srm_resets.io_count; i++) {
+               dev = srm_resets.io[i].dev;
+
+               pcibios_write_config_byte(dev->bus->number, dev->devfn,
+                                         srm_resets.io[i].reg,
+                                         srm_resets.io[i].io);
+#if 1
+               printk("reset_for_srm: bus %d slot 0x%x "
+                      "SRM IO restored to 0x%x\n",
+                      dev->bus->number, PCI_SLOT(dev->devfn),
+                      srm_resets.io[i].io);
+#endif
+       }
+}
+
 
 /*
  * Disable PCI device DEV so that it does not respond to I/O or memory
  * accesses.
  */
-static void disable_dev(struct pci_dev *dev)
+static void __init
+disable_dev(struct pci_dev *dev)
 {
        struct pci_bus *bus;
        unsigned short cmd;
@@ -208,12 +341,20 @@ static void disable_dev(struct pci_dev *dev)
         */
        if (dev->vendor == PCI_VENDOR_ID_INTEL &&
            dev->device == PCI_DEVICE_ID_INTEL_82375) {
+               dev->class = PCI_CLASS_BRIDGE_EISA;
                DBG_DEVS(("disable_dev: ignoring PCEB...\n"));
                return;
        }
 
+       if (dev->vendor == PCI_VENDOR_ID_INTEL &&
+           dev->device == PCI_DEVICE_ID_INTEL_82378) {
+               dev->class = PCI_CLASS_BRIDGE_ISA;
+               DBG_DEVS(("disable_dev: ignoring SIO...\n"));
+               return;
+       }
+
        /*
-        * we don't have code that will init the CYPRESS bridge correctly
+        * We don't have code that will init the CYPRESS bridge correctly
         * so we do the next best thing, and depend on the previous
         * console code to do the right thing, and ignore it here... :-\
         */
@@ -223,6 +364,19 @@ static void disable_dev(struct pci_dev *dev)
                return;
        }
 
+#if DEBUG_DEVS && 0
+       /* Worse HACK: Don't disable the video card, so I can see where
+          it is *really* falling over.  */
+       if (dev->class >> 16 == PCI_BASE_CLASS_DISPLAY) {
+               DBG_DEVS(("disable_dev: ignoring video card %04x:%04x\n",
+                         dev->vendor, dev->device));
+               return;
+       }
+#endif
+
+       DBG_DEVS(("disable_dev: disabling %04x:%04x\n",
+                 dev->vendor, dev->device));
+
        bus = dev->bus;
        pcibios_read_config_word(bus->number, dev->devfn, PCI_COMMAND, &cmd);
 
@@ -237,7 +391,11 @@ static void disable_dev(struct pci_dev *dev)
  */
 #define MAX(val1, val2) ((val1) > (val2) ? (val1) : (val2))
 
-static void layout_dev(struct pci_dev *dev)
+static unsigned int io_base;
+static unsigned int mem_base; 
+
+static void __init
+layout_dev(struct pci_dev *dev)
 {
        struct pci_bus *bus;
        unsigned short cmd;
@@ -251,12 +409,20 @@ static void layout_dev(struct pci_dev *dev)
         */
        if (dev->vendor == PCI_VENDOR_ID_INTEL &&
            dev->device == PCI_DEVICE_ID_INTEL_82375) {
+               dev->class = PCI_CLASS_BRIDGE_EISA;
                DBG_DEVS(("layout_dev: ignoring PCEB...\n"));
                return;
        }
 
+       if (dev->vendor == PCI_VENDOR_ID_INTEL &&
+           dev->device == PCI_DEVICE_ID_INTEL_82378) {
+               dev->class = PCI_CLASS_BRIDGE_ISA;
+               DBG_DEVS(("layout_dev: ignoring SIO...\n"));
+               return;
+       }
+
        /*
-        * we don't have code that will init the CYPRESS bridge correctly
+        * We don't have code that will init the CYPRESS bridge correctly
         * so we do the next best thing, and depend on the previous
         * console code to do the right thing, and ignore it here... :-\
         */
@@ -315,7 +481,7 @@ static void layout_dev(struct pci_dev *dev)
                        pcibios_write_config_dword(bus->number, dev->devfn, 
                                                   off, base | 0x1);
 
-                       handle = HANDLE(bus->number) | base | 1;
+                       handle = PCI_HANDLE(bus->number) | base | 1;
                        dev->base_address[idx] = handle;
 
                        DBG_DEVS(("layout_dev: dev 0x%x IO @ 0x%lx (0x%x)\n",
@@ -400,7 +566,7 @@ static void layout_dev(struct pci_dev *dev)
                        mem_base = base + size;
                        pcibios_write_config_dword(bus->number, dev->devfn,
                                                   off, base);
-                       handle = HANDLE(bus->number) | base;
+                       handle = PCI_HANDLE(bus->number) | base;
                        dev->base_address[idx] = handle;
                        DBG_DEVS(("layout_dev: dev 0x%x MEM @ 0x%lx (0x%x)\n",
                                  dev->device, handle, size));
@@ -431,8 +597,8 @@ static void layout_dev(struct pci_dev *dev)
                  dev->device, dev->class, cmd|PCI_COMMAND_MASTER));
 }
 
-
-static int layout_bus(struct pci_bus *bus)
+static int __init
+layout_bus(struct pci_bus *bus)
 {
        unsigned int l, tio, bio, tmem, bmem;
        struct pci_bus *child;
@@ -543,24 +709,44 @@ static int layout_bus(struct pci_bus *bus)
        return found_vga;
 }
 
-#endif /* !PCI_MODIFY */
-
-
-int pcibios_present(void)
+void __init
+layout_all_busses(unsigned long default_io_base,
+                 unsigned long default_mem_base)
 {
-       return 1;
-}
+       struct pci_bus *cur;
 
+#if defined(CONFIG_ALPHA_GENERIC)
+       static struct linux_hose_info dummy_hose;
+       int i;
 
-void __init
-pcibios_init(void)
-{
-       printk("Alpha PCI BIOS32 revision %x.%02x\n", MAJOR_REV, MINOR_REV);
-#if !PCI_MODIFY
-       printk("...NOT modifying existing (SRM) PCI configuration\n");
+       /*
+        * HACK: Emulate a multi-bus machine to a limited extent
+        * by initializing bus2hose to point to something that
+        * has pci_hose_index & pci_first_busno zero.
+        */
+       for (i = 0; i <= 0xff; i++)
+               bus2hose[i] = &dummy_hose;
 #endif
+
+       /*
+        * Scan the tree, allocating PCI memory and I/O space.
+        */
+       /*
+        * Sigh; check_region() will need changing to accept a PCI_HANDLE,
+        * if we allocate I/O space addresses on a per-bus basis.
+        * For now, make the I/O bases unique across all busses, so
+        * that check_region() will not get confused... ;-}
+        */
+       io_base = default_io_base;
+       for (cur = &pci_root; cur; cur = cur->next) {
+               mem_base = default_mem_base;
+               DBG_DEVS(("layout_all_busses: calling layout_bus()\n"));
+               layout_bus(cur);
+       }
+       DBG_DEVS(("layout_all_busses: done.\n"));
 }
 
+
 /*
  * The SRM console *disables* the IDE interface, this code ensures it's
  * enabled.
@@ -575,7 +761,9 @@ pcibios_init(void)
  * written twice (I believe this is a safety feature to prevent
  * accidental modification---fun, isn't it?).
  */
-static inline void enable_ide(long ide_base)
+
+void __init
+enable_ide(long ide_base)
 {
        int data;
 
@@ -586,68 +774,29 @@ static inline void enable_ide(long ide_base)
        outb(data | 0x40, ide_base+1);  /* turn on IDE, really! */
 }
 
-/* 
- * A small note about bridges and interrupts.    The DECchip 21050 (and later)
- * adheres to the PCI-PCI bridge specification.   This says that the
- * interrupts on the other side of a bridge are swizzled in the following
- * manner:
- *
- * Dev    Interrupt   Interrupt 
- *        Pin on      Pin on 
- *        Device      Connector
- *
- *   4    A           A
- *        B           B
- *        C           C
- *        D           D
- * 
- *   5    A           B
- *        B           C
- *        C           D
- *        D           A
- *
- *   6    A           C
- *        B           D
- *        C           A
- *        D           B
- *
- *   7    A           D
- *        B           A
- *        C           B
- *        D           C
- *
- *   Where A = pin 1, B = pin 2 and so on and pin=0 = default = A.
- *   Thus, each swizzle is ((pin-1) + (device#-4)) % 4
- *
- *   The following code is somewhat simplistic as it assumes only one bridge.
- *   I will fix it later (david.rusling@reo.mts.dec.com).
- */
-static inline unsigned char
-bridge_swizzle(unsigned char pin, unsigned int slot) 
-{
-       /* swizzle */
-       return (((pin-1) + slot) % 4) + 1;
-}
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-/* look for mis-configured devices' I/O space addresses behind bridges */
-static void check_behind_io(struct pci_dev *dev)
+/* Look for mis-configured devices' I/O space addresses behind bridges.  */
+static void
+check_behind_io(struct pci_dev *dev)
 {
        struct pci_bus *bus = dev->bus;
        unsigned int reg, orig_base, new_base, found_one = 0;
+       struct reset_io *ior;
 
        for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) {
-               /* read the current setting, check for I/O space and >= 64K */
-               pcibios_read_config_dword(bus->number, dev->devfn, reg, &orig_base);
+               /* Read the current setting, check for I/O space and >= 64K */
+               pcibios_read_config_dword(bus->number, dev->devfn,
+                                         reg, &orig_base);
+
                if (!orig_base || !(orig_base & PCI_BASE_ADDRESS_SPACE_IO))
                        continue; /* unused or non-IO */
+
                if (orig_base < 64*1024) {
 #if 1
 printk("check_behind_io: ALREADY OK! bus %d slot %d base 0x%x\n",
        bus->number, PCI_SLOT(dev->devfn), orig_base);
 #endif
                        if (orig_base & ~1)
-                         continue; /* OK! */
+                               continue; /* OK! */
                        orig_base = 0x12001; /* HACK! FIXME!! */
                }
 
@@ -662,1160 +811,148 @@ printk("check_behind_io: ALERT! bus %d slot %d old 0x%x new 0x%x\n",
                pcibios_write_config_dword(bus->number, dev->devfn,
                                           reg, new_base);
 
-               io_dev_to_reset[io_reset_count] = dev;
-               io_reg_to_reset[io_reset_count] = reg;
-               io_to_reset[io_reset_count] = orig_base;
-               io_reset_count++;
+               ior = &srm_resets.io[srm_resets.io_count++];
+               ior->dev = dev;
+               ior->reg = reg;
+               ior->io = orig_base;
                found_one++;
-       } /* end for-loop */
+       }
 
-       /* if any were modified, gotta hack the bridge IO limits too... */
+       /* If any were modified, gotta hack the bridge IO limits too. */
        if (found_one) {
-           if (bus->self) {
-               struct pci_dev *bridge = bus->self;
-               unsigned int l;
-               /*
-                * Set up the top and bottom of the PCI I/O segment
-                * for this bus.
-                */
-               pcibios_read_config_dword(bridge->bus->number,
-                                         bridge->devfn, 0x1c, &l);
+               if (bus->self) {
+                       struct pci_dev *bridge = bus->self;
+                       unsigned int l;
+                       /*
+                        * Set up the top and bottom of the PCI I/O segment
+                        * for this bus.
+                        */
+                       pcibios_read_config_dword(bridge->bus->number,
+                                                 bridge->devfn, 0x1c, &l);
 #if 1
 printk("check_behind_io: ALERT! bus %d slot %d oldLIM 0x%x\n",
        bus->number, PCI_SLOT(bridge->devfn), l);
 #endif
-               l = (l & 0xffff0000U) | 0xf080U; /* give it ALL */
-               pcibios_write_config_dword(bridge->bus->number,
-                                          bridge->devfn, 0x1c, l);
-               pcibios_write_config_dword(bridge->bus->number,
-                                          bridge->devfn,
-                                          0x3c, 0x00040000);
-               pcibios_write_config_dword(bridge->bus->number,
-                                          bridge->devfn,
-                                          0x4, 0xffff0007);
-           } else
-               printk("check_behind_io: WARNING! bus->self NULL\n");
+                       l = (l & 0xffff0000U) | 0xf080U; /* give it ALL */
+                       pcibios_write_config_dword(bridge->bus->number,
+                                                  bridge->devfn, 0x1c, l);
+                       pcibios_write_config_dword(bridge->bus->number,
+                                                  bridge->devfn,
+                                                  0x3c, 0x00040000);
+                       pcibios_write_config_dword(bridge->bus->number,
+                                                  bridge->devfn,
+                                                  0x4, 0xffff0007);
+               } else
+                       printk("check_behind_io: WARNING! bus->self NULL\n");
        }
 }
-#endif /* CONFIG_ALPHA_SRM_SETUP */
+
 
 /*
- * Most evaluation boards share most of the fixup code, which is isolated
- * here.  This function is declared "inline" as only one platform will ever
- * be selected in any given kernel.  If that platform doesn't need this code,
- * we don't want it around as dead code.
+ * Most boards share most of the fixup code, which is isolated here.
  */
-static inline void
-common_fixup(long min_idsel, long max_idsel, long irqs_per_slot,
-            char irq_tab[max_idsel - min_idsel + 1][irqs_per_slot],
-            long ide_base)
+
+void __init
+common_pci_fixup(int (*map_irq)(struct pci_dev *dev, int slot, int pin),
+                int (*swizzle)(struct pci_dev *dev, int *pin))
 {
-       struct pci_dev *dev, *curr;
-       unsigned char pin;
-       unsigned char slot;
+       struct pci_dev *dev;
+       u8 pin, slot, irq_orig;
+       int irq;
 
        /*
-        * Go through all devices, fixing up irqs as we see fit:
+        * Go through all devices, fixing up irqs as we see fit.
         */
        for (dev = pci_devices; dev; dev = dev->next) {
-               if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE ||
-                   dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA) {
-                       /*
-                        * HACK: the PCI-to-EISA bridge appears not to identify
-                        *       itself as a bridge... :-(
-                        */
-                       if (dev->vendor == PCI_VENDOR_ID_INTEL &&
-                           dev->device == PCI_DEVICE_ID_INTEL_82375) {
-                               DBG_DEVS(("common_fixup: ignoring PCEB...\n"));
-                               continue;
-                       }
+               if ((dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) &&
+                   (dev->class >> 8 != PCI_CLASS_BRIDGE_PCMCIA))
+                       continue;
 
-                       /*
-                        * This device is not on the primary bus, we need
-                        * to figure out which interrupt pin it will come
-                        * in on.   We know which slot it will come in on
-                        * 'cos that slot is where the bridge is.   Each
-                        * time the interrupt line passes through a PCI-PCI
-                        * bridge we must apply the swizzle function (see
-                        * the inline static routine above).
-                        */
-                       dev->irq = 0;
-                       if (!DEV_IS_ON_PRIMARY(dev)) {
-                               /* read the pin and do the PCI-PCI bridge
-                                  interrupt pin swizzle */
-                               pcibios_read_config_byte(dev->bus->number,
-                                                        dev->devfn,
-                                                        PCI_INTERRUPT_PIN,
-                                                        &pin);
-                               /* cope with 0 and illegal */
-                               if (pin == 0 || pin > 4)
-                                       pin = 1;
-                               /* follow the chain of bridges, swizzling
-                                  as we go */
-                               curr = dev;
-#if defined(CONFIG_ALPHA_MIATA)
-                               /* check first for the built-in bridge */
-                               if ((PCI_SLOT(dev->bus->self->devfn) == 8) ||
-                                   (PCI_SLOT(dev->bus->self->devfn) == 20)) {
-                               slot = PCI_SLOT(dev->devfn) + 5;
-                               DBG_DEVS(("MIATA: bus 1 slot %d pin %d"
-                                         " irq %d min_idsel %d\n",
-                                         PCI_SLOT(dev->devfn), pin,
-                                         irq_tab[slot - min_idsel][pin],
-                                         min_idsel));
-                               }
-                               else /* must be a card-based bridge */
-                               {
-                               do {
-                                 if ((PCI_SLOT(curr->bus->self->devfn) == 8) ||
-                                     (PCI_SLOT(curr->bus->self->devfn) == 20))
-                                   {
-                                     slot = PCI_SLOT(curr->devfn) + 5;
-                                     break;
-                                   }
-                                       /* swizzle */
-                                   pin = bridge_swizzle(
-                                                 pin, PCI_SLOT(curr->devfn)) ;
-                                   /* move up the chain of bridges */
-                                   curr = curr->bus->self ;
-                                   /* slot of the next bridge. */
-                                   slot = PCI_SLOT(curr->devfn);
-                                 } while (curr->bus->self) ;
-                               }
-#elif defined(CONFIG_ALPHA_NORITAKE)
-                               /* check first for the built-in bridge */
-                               if (PCI_SLOT(dev->bus->self->devfn) == 8) {
-                                 slot = PCI_SLOT(dev->devfn) + 15; /* WAG! */
-                               DBG_DEVS(("NORITAKE: bus 1 slot %d pin %d"
-                                           "irq %d min_idsel %ld\n",
-                                         PCI_SLOT(dev->devfn), pin,
-                                         irq_tab[slot - min_idsel][pin],
-                                         min_idsel));
-                               }
-                               else /* must be a card-based bridge */
-                               {
-                               do {
-                                   if (PCI_SLOT(curr->bus->self->devfn) == 8) {
-                                     slot = PCI_SLOT(curr->devfn) + 15;
-                                     break;
-                                   }
-                                       /* swizzle */
-                                   pin = bridge_swizzle(
-                                               pin, PCI_SLOT(curr->devfn)) ;
-                                   /* move up the chain of bridges */
-                                   curr = curr->bus->self ;
-                                   /* slot of the next bridge. */
-                                   slot = PCI_SLOT(curr->devfn);
-                                 } while (curr->bus->self) ;
-                               }
-#else /* everyone but MIATA and NORITAKE */
-                               DBG_DEVS(("common_fixup: bus %d slot %d pin %d "
-                                         "irq %d min_idsel %ld\n",
-                                         curr->bus->number,
-                                         PCI_SLOT(dev->devfn), pin,
-                                         irq_tab[slot - min_idsel][pin],
-                                         min_idsel));
-                               do {
-                                 /* swizzle */
-                                 pin =
-                                   bridge_swizzle(pin, PCI_SLOT(curr->devfn));
-                                       /* move up the chain of bridges */
-                                       curr = curr->bus->self;
-                               } while (curr->bus->self);
-                               /* The slot is the slot of the last bridge. */
-                               slot = PCI_SLOT(curr->devfn);
-#endif
-#ifdef CONFIG_ALPHA_SRM_SETUP
-                               /*
-                                * must make sure that SRM didn't screw up
-                                * and allocate an address > 64K for I/O
-                                * space behind a PCI-PCI bridge
-                               */
-                               check_behind_io(dev);
-#endif /* CONFIG_ALPHA_SRM_SETUP */
-                       } else { /* just a device on a primary bus */
-                               /* work out the slot */
-                               slot = PCI_SLOT(dev->devfn);
-                               /* read the pin */
-                               pcibios_read_config_byte(dev->bus->number,
-                                                        dev->devfn,
-                                                        PCI_INTERRUPT_PIN,
-                                                        &pin);
-                               DBG_DEVS(("common_fixup: bus %d slot %d"
-                                         " pin %d irq %d min_idsel %ld\n",
-                                         dev->bus->number, slot, pin,
-                                         irq_tab[slot - min_idsel][pin],
-                                         min_idsel));
-                               /* cope with 0 and illegal */
-                               if (pin == 0 || pin > 4)
-                                       pin = 1;
-                       }
-                       if (irq_tab[slot - min_idsel][pin] != -1)
-                               dev->irq = irq_tab[slot - min_idsel][pin];
-#ifdef CONFIG_ALPHA_RAWHIDE
-                       dev->irq +=
-                           24 * bus2hose[dev->bus->number]->pci_hose_index;
-#endif /* RAWHIDE */
-#ifdef CONFIG_ALPHA_SRM
-                       {
-                         unsigned char irq_orig;
-                         /* read the original SRM-set IRQ and tell */
-                         pcibios_read_config_byte(dev->bus->number,
-                                                 dev->devfn,
-                                                 PCI_INTERRUPT_LINE,
-                                                   &irq_orig);
-                         if (irq_orig != dev->irq) {
-                           DBG_DEVS(("common_fixup: bus %d slot 0x%x "
-                                     "SRM IRQ 0x%x changed to 0x%x\n",
-                                     dev->bus->number,PCI_SLOT(dev->devfn),
-                                     irq_orig, dev->irq));
-#ifdef CONFIG_ALPHA_SRM_SETUP
-                           irq_dev_to_reset[irq_reset_count] = dev;
-                           irq_to_reset[irq_reset_count] = irq_orig;
-                           irq_reset_count++;
-#endif /* CONFIG_ALPHA_SRM_SETUP */
-                         }
-                       }
-#endif /* SRM */
-
-                       /* always tell the device, so the driver knows what is
-                        * the real IRQ to use; the device does not use it.
-                        */
-                       pcibios_write_config_byte(dev->bus->number, dev->devfn,
-                                                 PCI_INTERRUPT_LINE, dev->irq);
-
-                       DBG_DEVS(("common_fixup: bus %d slot 0x%x"
-                                 " VID 0x%x DID 0x%x\n"
-                                 "              int_slot 0x%x pin 0x%x"
-                                 " pirq 0x%x\n",
-                                 dev->bus->number, PCI_SLOT(dev->devfn),
-                                 dev->vendor, dev->device,
-                                 slot, pin, dev->irq));
-
-                       /*
-                        * if it's a VGA, enable its BIOS ROM at C0000
-                        */
-                       if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
-                         /* but if its a Cirrus 543x/544x DISABLE it, */
-                         /* since enabling ROM disables the memory... */
-                         if ((dev->vendor == PCI_VENDOR_ID_CIRRUS) &&
-                             (dev->device >= 0x00a0) &&
-                             (dev->device <= 0x00ac)) {
-                                 pcibios_write_config_dword(
-                                       dev->bus->number,
-                                       dev->devfn,
-                                       PCI_ROM_ADDRESS,
-                                       0x00000000);
-                         } else {
-                                 pcibios_write_config_dword(
-                                       dev->bus->number,
-                                                          dev->devfn,
-                                                          PCI_ROM_ADDRESS,
-                                                          0x000c0000 | PCI_ROM_ADDRESS_ENABLE);
-                       }
-                       }
-                       /*
-                        * if it's a SCSI, disable its BIOS ROM
-                        */
-                       if ((dev->class >> 8) == PCI_CLASS_STORAGE_SCSI) {
-                               pcibios_write_config_dword(dev->bus->number,
-                                                          dev->devfn,
-                                                          PCI_ROM_ADDRESS,
-                                                          0x0000000);
-                       }
-               }
-       }
-       if (ide_base) {
-               enable_ide(ide_base);
-       }
-}
-
-/*
- * The EB66+ is very similar to the EB66 except that it does not have
- * the on-board NCR and Tulip chips.  In the code below, I have used
- * slot number to refer to the id select line and *not* the slot
- * number used in the EB66+ documentation.  However, in the table,
- * I've given the slot number, the id select line and the Jxx number
- * that's printed on the board.  The interrupt pins from the PCI slots
- * are wired into 3 interrupt summary registers at 0x804, 0x805 and
- * 0x806 ISA.
- *
- * In the table, -1 means don't assign an IRQ number.  This is usually
- * because it is the Saturn IO (SIO) PCI/ISA Bridge Chip.
- */
-static inline void eb66p_fixup(void)
-{
-       static char irq_tab[5][5] __initlocaldata = {
-               /*INT  INTA  INTB  INTC   INTD */
-               {16+0, 16+0, 16+5,  16+9, 16+13},  /* IdSel 6,  slot 0, J25 */
-               {16+1, 16+1, 16+6, 16+10, 16+14},  /* IdSel 7,  slot 1, J26 */
-               {  -1,   -1,   -1,    -1,    -1},  /* IdSel 8,  SIO         */
-               {16+2, 16+2, 16+7, 16+11, 16+15},  /* IdSel 9,  slot 2, J27 */
-               {16+3, 16+3, 16+8, 16+12,  16+6}   /* IdSel 10, slot 3, J28 */
-       };
-       common_fixup(6, 10, 5, irq_tab, 0x398);
-}
-
-
-/*
- * The PC164 and LX164 have 19 PCI interrupts, four from each of the four
- * PCI slots, the SIO, PCI/IDE, and USB.
- * 
- * Each of the interrupts can be individually masked. This is
- * accomplished by setting the appropriate bit in the mask register.
- * A bit is set by writing a "1" to the desired position in the mask
- * register and cleared by writing a "0". There are 3 mask registers
- * located at ISA address 804h, 805h and 806h.
- * 
- * An I/O read at ISA address 804h, 805h, 806h will return the
- * state of the 11 PCI interrupts and not the state of the MASKED
- * interrupts.
- * 
- * Note: A write to I/O 804h, 805h, and 806h the mask register will be
- * updated.
- * 
- * 
- *                             ISA DATA<7:0>
- * ISA     +--------------------------------------------------------------+
- * ADDRESS |   7   |   6   |   5   |   4   |   3   |   2  |   1   |   0   |
- *         +==============================================================+
- * 0x804   | INTB0 |  USB  |  IDE  |  SIO  | INTA3 |INTA2 | INTA1 | INTA0 |
- *         +--------------------------------------------------------------+
- * 0x805   | INTD0 | INTC3 | INTC2 | INTC1 | INTC0 |INTB3 | INTB2 | INTB1 |
- *         +--------------------------------------------------------------+
- * 0x806   | Rsrv  | Rsrv  | Rsrv  | Rsrv  | Rsrv  |INTD3 | INTD2 | INTD1 |
- *         +--------------------------------------------------------------+
- *         * Rsrv = reserved bits
- *         Note: The mask register is write-only.
- * 
- * IdSel       
- *   5  32 bit PCI option slot 2
- *   6  64 bit PCI option slot 0
- *   7  64 bit PCI option slot 1
- *   8  Saturn I/O
- *   9  32 bit PCI option slot 3
- *  10  USB
- *  11  IDE
- * 
- */
-
-#if defined(CONFIG_ALPHA_PC164) || defined(CONFIG_ALPHA_LX164)
-static inline void alphapc164_fixup(void)
-{
-       static char irq_tab[7][5] __initlocaldata = {
-               /*INT   INTA  INTB   INTC   INTD */
-               { 16+2, 16+2, 16+9,  16+13, 16+17}, /* IdSel  5, slot 2, J20 */
-               { 16+0, 16+0, 16+7,  16+11, 16+15}, /* IdSel  6, slot 0, J29 */
-               { 16+1, 16+1, 16+8,  16+12, 16+16}, /* IdSel  7, slot 1, J26 */
-               {   -1,   -1,   -1,    -1,    -1},  /* IdSel  8, SIO */
-               { 16+3, 16+3, 16+10, 16+14, 16+18}, /* IdSel  9, slot 3, J19 */
-               { 16+6, 16+6, 16+6,  16+6,  16+6},  /* IdSel 10, USB */
-               { 16+5, 16+5, 16+5,  16+5,  16+5}   /* IdSel 11, IDE */
-       };
-
-       common_fixup(5, 11, 5, irq_tab, 0);
-       SMC93x_Init();
-}
-#endif
-
-/*
- * The AlphaPC64 is very similar to the EB66+ except that its slots
- * are numbered differently.  In the code below, I have used slot
- * number to refer to the id select line and *not* the slot number
- * used in the AlphaPC64 documentation.  However, in the table, I've
- * given the slot number, the id select line and the Jxx number that's
- * printed on the board.  The interrupt pins from the PCI slots are
- * wired into 3 interrupt summary registers at 0x804, 0x805 and 0x806
- * ISA.
- *
- * In the table, -1 means don't assign an IRQ number.  This is usually
- * because it is the Saturn IO (SIO) PCI/ISA Bridge Chip.
- */
-static inline void cabriolet_fixup(void)
-{
-       static char irq_tab[5][5] __initlocaldata = {
-               /*INT   INTA  INTB  INTC   INTD */
-               { 16+2, 16+2, 16+7, 16+11, 16+15}, /* IdSel 5,  slot 2, J21 */
-               { 16+0, 16+0, 16+5,  16+9, 16+13}, /* IdSel 6,  slot 0, J19 */
-               { 16+1, 16+1, 16+6, 16+10, 16+14}, /* IdSel 7,  slot 1, J20 */
-               {   -1,   -1,   -1,    -1,    -1}, /* IdSel 8,  SIO         */
-               { 16+3, 16+3, 16+8, 16+12, 16+16}  /* IdSel 9,  slot 3, J22 */
-       };
-
-       common_fixup(5, 9, 5, irq_tab, 0x398);
-}
-
-
-/*
- * Fixup configuration for EB66/EB64+ boards.
- *
- * Both these boards use the same interrupt summary scheme.  There are
- * two 8 bit external summary registers as follows:
- *
- * Summary @ 0x26:
- * Bit      Meaning
- * 0        Interrupt Line A from slot 0
- * 1        Interrupt Line A from slot 1
- * 2        Interrupt Line B from slot 0
- * 3        Interrupt Line B from slot 1
- * 4        Interrupt Line C from slot 0
- * 5        Interrupt line from the two ISA PICs
- * 6        Tulip (slot 
- * 7        NCR SCSI
- *
- * Summary @ 0x27
- * Bit      Meaning
- * 0        Interrupt Line C from slot 1
- * 1        Interrupt Line D from slot 0
- * 2        Interrupt Line D from slot 1
- * 3        RAZ
- * 4        RAZ
- * 5        RAZ
- * 6        RAZ
- * 7        RAZ
- *
- * The device to slot mapping looks like:
- *
- * Slot     Device
- *  5       NCR SCSI controller
- *  6       PCI on board slot 0
- *  7       PCI on board slot 1
- *  8       Intel SIO PCI-ISA bridge chip
- *  9       Tulip - DECchip 21040 Ethernet controller
- *   
- *
- * This two layered interrupt approach means that we allocate IRQ 16 and 
- * above for PCI interrupts.  The IRQ relates to which bit the interrupt
- * comes in on.  This makes interrupt processing much easier.
- */
-static inline void eb66_and_eb64p_fixup(void)
-{
-       static char irq_tab[5][5] __initlocaldata = {
-               /*INT  INTA  INTB  INTC   INTD */
-               {16+7, 16+7, 16+7, 16+7,  16+7},  /* IdSel 5,  slot ?, ?? */
-               {16+0, 16+0, 16+2, 16+4,  16+9},  /* IdSel 6,  slot ?, ?? */
-               {16+1, 16+1, 16+3, 16+8, 16+10},  /* IdSel 7,  slot ?, ?? */
-               {  -1,   -1,   -1,   -1,    -1},  /* IdSel 8,  SIO */
-               {16+6, 16+6, 16+6, 16+6,  16+6},  /* IdSel 9,  TULIP */
-       };
-       common_fixup(5, 9, 5, irq_tab, 0);
-}
-
-
-/*
- * Fixup configuration for MIKASA (AlphaServer 1000)
- *
- * Summary @ 0x536:
- * Bit      Meaning
- * 0        Interrupt Line A from slot 0
- * 1        Interrupt Line B from slot 0
- * 2        Interrupt Line C from slot 0
- * 3        Interrupt Line D from slot 0
- * 4        Interrupt Line A from slot 1
- * 5        Interrupt line B from slot 1
- * 6        Interrupt Line C from slot 1
- * 7        Interrupt Line D from slot 1
- * 8        Interrupt Line A from slot 2
- * 9        Interrupt Line B from slot 2
- *10        Interrupt Line C from slot 2
- *11        Interrupt Line D from slot 2
- *12        NCR 810 SCSI
- *13        Power Supply Fail
- *14        Temperature Warn
- *15        Reserved
- *
- * The device to slot mapping looks like:
- *
- * Slot     Device
- *  6       NCR SCSI controller
- *  7       Intel PCI-EISA bridge chip
- * 11       PCI on board slot 0
- * 12       PCI on board slot 1
- * 13       PCI on board slot 2
- *   
- *
- * This two layered interrupt approach means that we allocate IRQ 16 and 
- * above for PCI interrupts.  The IRQ relates to which bit the interrupt
- * comes in on.  This makes interrupt processing much easier.
- */
-static inline void mikasa_fixup(void)
-{
-       static char irq_tab[8][5] __initlocaldata = {
-               /*INT    INTA   INTB   INTC   INTD */
-               {16+12, 16+12, 16+12, 16+12, 16+12},    /* IdSel 17,  SCSI */
-               {   -1,    -1,    -1,    -1,    -1},    /* IdSel 18,  PCEB */
-               {   -1,    -1,    -1,    -1,    -1},    /* IdSel 19,  ???? */
-               {   -1,    -1,    -1,    -1,    -1},    /* IdSel 20,  ???? */
-               {   -1,    -1,    -1,    -1,    -1},    /* IdSel 21,  ???? */
-               { 16+0,  16+0,  16+1,  16+2,  16+3},    /* IdSel 22,  slot 0 */
-               { 16+4,  16+4,  16+5,  16+6,  16+7},    /* IdSel 23,  slot 1 */
-               { 16+8,  16+8,  16+9, 16+10, 16+11},    /* IdSel 24,  slot 2 */
-       };
-       common_fixup(6, 13, 5, irq_tab, 0);
-}
-
-/*
- * Fixup configuration for NORITAKE (AlphaServer 1000A)
- *
- * This is also used for CORELLE (AlphaServer 800)
- * and ALCOR Primo (AlphaStation 600A).
- *
- * Summary @ 0x542, summary register #1:
- * Bit      Meaning
- * 0        All valid ints from summary regs 2 & 3
- * 1        QLOGIC ISP1020A SCSI
- * 2        Interrupt Line A from slot 0
- * 3        Interrupt Line B from slot 0
- * 4        Interrupt Line A from slot 1
- * 5        Interrupt line B from slot 1
- * 6        Interrupt Line A from slot 2
- * 7        Interrupt Line B from slot 2
- * 8        Interrupt Line A from slot 3
- * 9        Interrupt Line B from slot 3
- *10        Interrupt Line A from slot 4
- *11        Interrupt Line B from slot 4
- *12        Interrupt Line A from slot 5
- *13        Interrupt Line B from slot 5
- *14        Interrupt Line A from slot 6
- *15        Interrupt Line B from slot 6
- *
- * Summary @ 0x544, summary register #2:
- * Bit      Meaning
- * 0        OR of all unmasked ints in SR #2
- * 1        OR of secondary bus ints
- * 2        Interrupt Line C from slot 0
- * 3        Interrupt Line D from slot 0
- * 4        Interrupt Line C from slot 1
- * 5        Interrupt line D from slot 1
- * 6        Interrupt Line C from slot 2
- * 7        Interrupt Line D from slot 2
- * 8        Interrupt Line C from slot 3
- * 9        Interrupt Line D from slot 3
- *10        Interrupt Line C from slot 4
- *11        Interrupt Line D from slot 4
- *12        Interrupt Line C from slot 5
- *13        Interrupt Line D from slot 5
- *14        Interrupt Line C from slot 6
- *15        Interrupt Line D from slot 6
- *
- * The device to slot mapping looks like:
- *
- * Slot     Device
- *  7       Intel PCI-EISA bridge chip
- *  8       DEC PCI-PCI bridge chip
- * 11       PCI on board slot 0
- * 12       PCI on board slot 1
- * 13       PCI on board slot 2
- *   
- *
- * This two layered interrupt approach means that we allocate IRQ 16 and 
- * above for PCI interrupts.  The IRQ relates to which bit the interrupt
- * comes in on.  This makes interrupt processing much easier.
- */
-static inline void noritake_fixup(void)
-{
-       static char irq_tab[15][5] __initlocaldata = {
-               /*INT    INTA   INTB   INTC   INTD */
-         /* note: IDSELs 16, 17, and 25 are CORELLE only */
-          { 16+1,  16+1,  16+1,  16+1,  16+1},  /* IdSel 16,  QLOGIC */
-         {   -1,    -1,    -1,    -1,    -1},  /* IdSel 17,  S3 Trio64 */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 18,  PCEB */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 19,  PPB  */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 20,  ???? */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 21,  ???? */
-               { 16+2,  16+2,  16+3,  32+2,  32+3},  /* IdSel 22,  slot 0 */
-               { 16+4,  16+4,  16+5,  32+4,  32+5},  /* IdSel 23,  slot 1 */
-               { 16+6,  16+6,  16+7,  32+6,  32+7},  /* IdSel 24,  slot 2 */
-         { 16+8,  16+8,  16+9,  32+8,  32+9},  /* IdSel 25,  slot 3 */
-         /* the following 5 are actually on PCI bus 1, which is */
-         /* across the built-in bridge of the NORITAKE only */
-               { 16+1,  16+1,  16+1,  16+1,  16+1},  /* IdSel 16,  QLOGIC */
-               { 16+8,  16+8,  16+9,  32+8,  32+9},  /* IdSel 17,  slot 3 */
-               {16+10, 16+10, 16+11, 32+10, 32+11},  /* IdSel 18,  slot 4 */
-               {16+12, 16+12, 16+13, 32+12, 32+13},  /* IdSel 19,  slot 5 */
-               {16+14, 16+14, 16+15, 32+14, 32+15},  /* IdSel 20,  slot 6 */
-       };
-       common_fixup(5, 19, 5, irq_tab, 0);
-}
-
-/*
- * Fixup configuration for ALCOR and XLT (XL-300/366/433)
- *
- * Summary @ GRU_INT_REQ:
- * Bit      Meaning
- * 0        Interrupt Line A from slot 2
- * 1        Interrupt Line B from slot 2
- * 2        Interrupt Line C from slot 2
- * 3        Interrupt Line D from slot 2
- * 4        Interrupt Line A from slot 1
- * 5        Interrupt line B from slot 1
- * 6        Interrupt Line C from slot 1
- * 7        Interrupt Line D from slot 1
- * 8        Interrupt Line A from slot 0
- * 9        Interrupt Line B from slot 0
- *10        Interrupt Line C from slot 0
- *11        Interrupt Line D from slot 0
- *12        Interrupt Line A from slot 4
- *13        Interrupt Line B from slot 4
- *14        Interrupt Line C from slot 4
- *15        Interrupt Line D from slot 4
- *16        Interrupt Line D from slot 3
- *17        Interrupt Line D from slot 3
- *18        Interrupt Line D from slot 3
- *19        Interrupt Line D from slot 3
- *20-30     Reserved
- *31        EISA interrupt
- *
- * The device to slot mapping looks like:
- *
- * Slot     Device
- *  6       built-in TULIP (XLT only)
- *  7       PCI on board slot 0
- *  8       PCI on board slot 3
- *  9       PCI on board slot 4
- * 10       PCEB (PCI-EISA bridge)
- * 11       PCI on board slot 2
- * 12       PCI on board slot 1
- *   
- *
- * This two layered interrupt approach means that we allocate IRQ 16 and 
- * above for PCI interrupts.  The IRQ relates to which bit the interrupt
- * comes in on.  This makes interrupt processing much easier.
- */
-static inline void alcor_fixup(void)
-{
-       static char irq_tab[7][5] __initlocaldata = {
-               /*INT    INTA   INTB   INTC   INTD */
-         /* note: IDSEL 17 is XLT only */
-         {16+13, 16+13, 16+13, 16+13, 16+13},  /* IdSel 17,  TULIP  */
-               { 16+8,  16+8,  16+9, 16+10, 16+11},    /* IdSel 18,  slot 0 */
-               {16+16, 16+16, 16+17, 16+18, 16+19},    /* IdSel 19,  slot 3 */
-               {16+12, 16+12, 16+13, 16+14, 16+15},    /* IdSel 20,  slot 4 */
-               {   -1,    -1,    -1,    -1,    -1},    /* IdSel 21,  PCEB   */
-               { 16+0,  16+0,  16+1,  16+2,  16+3},    /* IdSel 22,  slot 2 */
-               { 16+4,  16+4,  16+5,  16+6,  16+7},    /* IdSel 23,  slot 1 */
-       };
-       common_fixup(6, 12, 5, irq_tab, 0);
-}
-
-/*
- * Fixup configuration for ALPHA SABLE (2100) - 2100A is different ??
- *
- * Summary Registers (536/53a/53c):
- * Bit      Meaning
- *-----------------
- * 0        PCI slot 0
- * 1        NCR810 (builtin)
- * 2        TULIP (builtin)
- * 3        mouse
- * 4        PCI slot 1
- * 5        PCI slot 2
- * 6        keyboard
- * 7        floppy
- * 8        COM2
- * 9        parallel port
- *10        EISA irq 3
- *11        EISA irq 4
- *12        EISA irq 5
- *13        EISA irq 6
- *14        EISA irq 7
- *15        COM1
- *16        EISA irq 9
- *17        EISA irq 10
- *18        EISA irq 11
- *19        EISA irq 12
- *20        EISA irq 13
- *21        EISA irq 14
- *22        NC
- *23        IIC
- *
- * The device to slot mapping looks like:
- *
- * Slot     Device
- *  0       TULIP
- *  1       SCSI
- *  2       PCI-EISA bridge
- *  3       none
- *  4       none
- *  5       none
- *  6       PCI on board slot 0
- *  7       PCI on board slot 1
- *  8       PCI on board slot 2
- *   
- *
- * This two layered interrupt approach means that we allocate IRQ 16 and 
- * above for PCI interrupts.  The IRQ relates to which bit the interrupt
- * comes in on.  This makes interrupt processing much easier.
- */
-/*
- * NOTE: the IRQ assignments below are arbitrary, but need to be consistent
- * with the values in the sable_irq_to_mask[] and sable_mask_to_irq[] tables
- * in irq.c
- */
-static inline void sable_fixup(void)
-{
-        static char irq_tab[9][5] __initlocaldata = {
-               /*INT    INTA   INTB   INTC   INTD */
-               { 32+0,  32+0,  32+0,  32+0,  32+0},  /* IdSel 0,  TULIP  */
-               { 32+1,  32+1,  32+1,  32+1,  32+1},  /* IdSel 1,  SCSI   */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 2,  SIO   */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 3,  none   */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 4,  none   */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 5,  none   */
-               { 32+2,  32+2,  32+2,  32+2,  32+2},  /* IdSel 6,  slot 0 */
-               { 32+3,  32+3,  32+3,  32+3,  32+3},  /* IdSel 7,  slot 1 */
-               { 32+4,  32+4,  32+4,  32+4,  32+4},  /* IdSel 8,  slot 2 */
-        };
-        common_fixup(0, 8, 5, irq_tab, 0);
-}
-
-/*
- * Fixup configuration for MIATA (EV56+PYXIS)
- *
- * Summary @ PYXIS_INT_REQ:
- * Bit      Meaning
- * 0        Fan Fault
- * 1        NMI
- * 2        Halt/Reset switch
- * 3        none
- * 4        CID0 (Riser ID)
- * 5        CID1 (Riser ID)
- * 6        Interval timer
- * 7        PCI-ISA Bridge
- * 8        Ethernet
- * 9        EIDE (deprecated, ISA 14/15 used)
- *10        none
- *11        USB
- *12        Interrupt Line A from slot 4
- *13        Interrupt Line B from slot 4
- *14        Interrupt Line C from slot 4
- *15        Interrupt Line D from slot 4
- *16        Interrupt Line A from slot 5
- *17        Interrupt line B from slot 5
- *18        Interrupt Line C from slot 5
- *19        Interrupt Line D from slot 5
- *20        Interrupt Line A from slot 1
- *21        Interrupt Line B from slot 1
- *22        Interrupt Line C from slot 1
- *23        Interrupt Line D from slot 1
- *24        Interrupt Line A from slot 2
- *25        Interrupt Line B from slot 2
- *26        Interrupt Line C from slot 2
- *27        Interrupt Line D from slot 2
- *27        Interrupt Line A from slot 3
- *29        Interrupt Line B from slot 3
- *30        Interrupt Line C from slot 3
- *31        Interrupt Line D from slot 3
- *
- * The device to slot mapping looks like:
- *
- * Slot     Device
- *  3       DC21142 Ethernet
- *  4       EIDE CMD646
- *  5       none
- *  6       USB
- *  7       PCI-ISA bridge
- *  8       PCI-PCI Bridge      (SBU Riser)
- *  9       none
- * 10       none
- * 11       PCI on board slot 4 (SBU Riser)
- * 12       PCI on board slot 5 (SBU Riser)
- *
- *  These are behind the bridge, so I'm not sure what to do...
- *
- * 13       PCI on board slot 1 (SBU Riser)
- * 14       PCI on board slot 2 (SBU Riser)
- * 15       PCI on board slot 3 (SBU Riser)
- *   
- *
- * This two layered interrupt approach means that we allocate IRQ 16 and 
- * above for PCI interrupts.  The IRQ relates to which bit the interrupt
- * comes in on.  This makes interrupt processing much easier.
- */
-
-#ifdef CONFIG_ALPHA_MIATA
-static inline void miata_fixup(void)
-{
-        static char irq_tab[18][5] __initlocaldata = {
-               /*INT    INTA   INTB   INTC   INTD */
-               {16+ 8, 16+ 8, 16+ 8, 16+ 8, 16+ 8},  /* IdSel 14,  DC21142  */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 15,  EIDE   */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 16,  none   */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 17,  none   */
-/*             {16+11, 16+11, 16+11, 16+11, 16+11},*//* IdSel 17,  USB ??  */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 18,  PCI-ISA */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 19,  PCI-PCI */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 20,  none    */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 21,  none    */
-               {16+12, 16+12, 16+13, 16+14, 16+15},  /* IdSel 22,  slot 4 */
-               {16+16, 16+16, 16+17, 16+18, 16+19},  /* IdSel 23,  slot 5 */
-               /* The following are actually on bus 1, which is */
-               /* across the builtin PCI-PCI bridge */
-               {16+20, 16+20, 16+21, 16+22, 16+23},  /* IdSel 24,  slot 1 */
-               {16+24, 16+24, 16+25, 16+26, 16+27},  /* IdSel 25,  slot 2 */
-               {16+28, 16+28, 16+29, 16+30, 16+31},  /* IdSel 26,  slot 3 */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 27,  none    */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 28,  none    */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 29,  none    */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 30,  none    */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 31,  PCI-PCI */
-        };
-       common_fixup(3, 20, 5, irq_tab, 0);
-       SMC669_Init(); /* it might be a GL (fails harmlessly if not) */
-       es1888_init();
-}
-#endif
+               /*
+                * This device is not on the primary bus, we need
+                * to figure out which interrupt pin it will come
+                * in on.   We know which slot it will come in on
+                * 'cos that slot is where the bridge is.   Each
+                * time the interrupt line passes through a PCI-PCI
+                * bridge we must apply the swizzle function (see
+                * the inline static routine above).
+                */
+               dev->irq = 0;
 
-/*
- * Fixup configuration for SX164 (PCA56+PYXIS)
- *
- * Summary @ PYXIS_INT_REQ:
- * Bit      Meaning
- * 0        RSVD
- * 1        NMI
- * 2        Halt/Reset switch
- * 3        MBZ
- * 4        RAZ
- * 5        RAZ
- * 6        Interval timer (RTC)
- * 7        PCI-ISA Bridge
- * 8        Interrupt Line A from slot 3
- * 9        Interrupt Line A from slot 2
- *10        Interrupt Line A from slot 1
- *11        Interrupt Line A from slot 0
- *12        Interrupt Line B from slot 3
- *13        Interrupt Line B from slot 2
- *14        Interrupt Line B from slot 1
- *15        Interrupt line B from slot 0
- *16        Interrupt Line C from slot 3
- *17        Interrupt Line C from slot 2
- *18        Interrupt Line C from slot 1
- *19        Interrupt Line C from slot 0
- *20        Interrupt Line D from slot 3
- *21        Interrupt Line D from slot 2
- *22        Interrupt Line D from slot 1
- *23        Interrupt Line D from slot 0
- *
- * IdSel       
- *   5  32 bit PCI option slot 2
- *   6  64 bit PCI option slot 0
- *   7  64 bit PCI option slot 1
- *   8  Cypress I/O
- *   9  32 bit PCI option slot 3
- * 
- */
+               pcibios_read_config_byte(dev->bus->number, dev->devfn,
+                                        PCI_INTERRUPT_PIN, &pin);
+               /* Cope with 0 and illegal. */
+               if (pin == 0 || pin > 4)
+                       pin = 1;
 
-static inline void sx164_fixup(void)
-{
-       static char irq_tab[5][5] __initlocaldata = {
-               /*INT    INTA   INTB   INTC   INTD */
-               { 16+ 9, 16+ 9, 16+13, 16+17, 16+21}, /* IdSel 5 slot 2 J17 */
-               { 16+11, 16+11, 16+15, 16+19, 16+23}, /* IdSel 6 slot 0 J19 */
-               { 16+10, 16+10, 16+14, 16+18, 16+22}, /* IdSel 7 slot 1 J18 */
-               {    -1,    -1,    -1,    -1,    -1}, /* IdSel 8 SIO        */
-               { 16+ 8, 16+ 8, 16+12, 16+16, 16+20}  /* IdSel 9 slot 3 J15 */
-       };
-       common_fixup(5, 9, 5, irq_tab, 0);
-       SMC669_Init();
-}
-
-/*
- * Fixup configuration for DP264 (EV6+TSUNAMI)
- *
- * Summary @ TSUNAMI_CSR_DIM0:
- * Bit      Meaning
- * 0-17     Unused
- *18        Interrupt SCSI B (Adaptec 7895 builtin)
- *19        Interrupt SCSI A (Adaptec 7895 builtin)
- *20        Interrupt Line D from slot 2 PCI0
- *21        Interrupt Line C from slot 2 PCI0
- *22        Interrupt Line B from slot 2 PCI0
- *23        Interrupt Line A from slot 2 PCI0
- *24        Interrupt Line D from slot 1 PCI0
- *25        Interrupt Line C from slot 1 PCI0
- *26        Interrupt Line B from slot 1 PCI0
- *27        Interrupt Line A from slot 1 PCI0
- *28        Interrupt Line D from slot 0 PCI0
- *29        Interrupt Line C from slot 0 PCI0
- *30        Interrupt Line B from slot 0 PCI0
- *31        Interrupt Line A from slot 0 PCI0
- *
- *32        Interrupt Line D from slot 3 PCI1
- *33        Interrupt Line C from slot 3 PCI1
- *34        Interrupt Line B from slot 3 PCI1
- *35        Interrupt Line A from slot 3 PCI1
- *36        Interrupt Line D from slot 2 PCI1
- *37        Interrupt Line C from slot 2 PCI1
- *38        Interrupt Line B from slot 2 PCI1
- *39        Interrupt Line A from slot 2 PCI1
- *40        Interrupt Line D from slot 1 PCI1
- *41        Interrupt Line C from slot 1 PCI1
- *42        Interrupt Line B from slot 1 PCI1
- *43        Interrupt Line A from slot 1 PCI1
- *44        Interrupt Line D from slot 0 PCI1
- *45        Interrupt Line C from slot 0 PCI1
- *46        Interrupt Line B from slot 0 PCI1
- *47        Interrupt Line A from slot 0 PCI1
- *48-52     Unused
- *53        PCI0 NMI (from Cypress)
- *54        PCI0 SMI INT (from Cypress)
- *55        PCI0 ISA Interrupt (from Cypress)
- *56-60     Unused
- *61        PCI1 Bus Error
- *62        PCI0 Bus Error
- *63        Reserved
- *
- * IdSel       
- *   5  Cypress Bridge I/O
- *   6  SCSI Adaptec builtin
- *   7  64 bit PCI option slot 0
- *   8  64 bit PCI option slot 1
- *   9  64 bit PCI option slot 2
- * 
- */
+               if (!DEV_IS_ON_PRIMARY(dev)) {
+                       /* Follow the chain of bridges, swizzling as we go.  */
 
-static inline void dp264_fixup(void)
-{
-       static char irq_tab[5][5] __initlocaldata = {
-          /*INT    INTA   INTB   INTC   INTD */
-         {    -1,    -1,    -1,    -1,    -1}, /* IdSel 5 ISA Bridge */
-         { 16+ 2, 16+ 2, 16+ 2, 16+ 2, 16+ 2}, /* IdSel 6 SCSI builtin */
-         { 16+15, 16+15, 16+14, 16+13, 16+12}, /* IdSel 7 slot 0 */
-         { 16+11, 16+11, 16+10, 16+ 9, 16+ 8}, /* IdSel 8 slot 1 */
-         { 16+ 7, 16+ 7, 16+ 6, 16+ 5, 16+ 4}  /* IdSel 9 slot 2 */
-       };
-       common_fixup(5, 9, 5, irq_tab, 0);
-       SMC669_Init();
-}
+                       int spill = pin;
+                       slot = (*swizzle)(dev, &spill);
+                       pin = spill;
 
-/*
- * Fixup configuration for RAWHIDE
- *
- * Summary @ MCPCIA_PCI0_INT_REQ:
- * Bit      Meaning
- *0         Interrupt Line A from slot 2 PCI0
- *1         Interrupt Line B from slot 2 PCI0
- *2         Interrupt Line C from slot 2 PCI0
- *3         Interrupt Line D from slot 2 PCI0
- *4         Interrupt Line A from slot 3 PCI0
- *5         Interrupt Line B from slot 3 PCI0
- *6         Interrupt Line C from slot 3 PCI0
- *7         Interrupt Line D from slot 3 PCI0
- *8         Interrupt Line A from slot 4 PCI0
- *9         Interrupt Line B from slot 4 PCI0
- *10        Interrupt Line C from slot 4 PCI0
- *11        Interrupt Line D from slot 4 PCI0
- *12        Interrupt Line A from slot 5 PCI0
- *13        Interrupt Line B from slot 5 PCI0
- *14        Interrupt Line C from slot 5 PCI0
- *15        Interrupt Line D from slot 5 PCI0
- *16        EISA interrupt (PCI 0) or SCSI interrupt (PCI 1)
- *17-23     NA
- *
- * IdSel       
- *   1  EISA bridge (PCI bus 0 only)
- *   2          PCI option slot 2
- *   3  PCI option slot 3
- *   4   PCI option slot 4
- *   5   PCI option slot 5
- * 
- */
+                       /* Must make sure that SRM didn't screw up
+                          and allocate an address > 64K for I/O
+                          space behind a PCI-PCI bridge. */
+                       if (alpha_use_srm_setup)
+                               check_behind_io(dev);
+               } else {
+                       /* Just a device on a primary bus.  */
+                       slot = PCI_SLOT(dev->devfn);
+               }
 
-static inline void rawhide_fixup(void)
-{
-       static char irq_tab[5][5] __initlocaldata = {
-          /*INT    INTA   INTB   INTC   INTD */
-         { 16+16, 16+16, 16+16, 16+16, 16+16}, /* IdSel 1 SCSI PCI 1 only */
-         { 16+ 0, 16+ 0, 16+ 1, 16+ 2, 16+ 3}, /* IdSel 2 slot 2 */
-         { 16+ 4, 16+ 4, 16+ 5, 16+ 6, 16+ 7}, /* IdSel 3 slot 3 */
-         { 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11}, /* IdSel 4 slot 4 */
-         { 16+12, 16+12, 16+13, 16+14, 16+15}  /* IdSel 5 slot 5 */
-       };
-       common_fixup(1, 5, 5, irq_tab, 0);
-}
+               irq = (*map_irq)(dev, slot, pin);
 
-/*
- * The Takara has PCI devices 1, 2, and 3 configured to slots 20,
- * 19, and 18 respectively, in the default configuration. They can
- * also be jumpered to slots 8, 7, and 6 respectively, which is fun
- * because the SIO ISA bridge can also be slot 7. However, the SIO
- * doesn't explicitly generate PCI-type interrupts, so we can
- * assign it whatever the hell IRQ we like and it doesn't matter.
- */
-static inline void takara_fixup(void)
-{
-       static char irq_tab[15][5] __initlocaldata = {
-           { 16+3, 16+3, 16+3, 16+3, 16+3},   /* slot  6 == device 3 */
-           { 16+2, 16+2, 16+2, 16+2, 16+2},   /* slot  7 == device 2 */
-           { 16+1, 16+1, 16+1, 16+1, 16+1},   /* slot  8 == device 1 */
-           {   -1,   -1,   -1,   -1,   -1},   /* slot  9 == nothing */
-           {   -1,   -1,   -1,   -1,   -1},   /* slot 10 == nothing */
-           {   -1,   -1,   -1,   -1,   -1},   /* slot 11 == nothing */
-           {   -1,   -1,   -1,   -1,   -1},   /* slot 12 == nothing */
-           {   -1,   -1,   -1,   -1,   -1},   /* slot 13 == nothing */
-           {   -1,   -1,   -1,   -1,   -1},   /* slot 14 == nothing */
-           {   -1,   -1,   -1,   -1,   -1},   /* slot 15 == nothing */
-           {   -1,   -1,   -1,   -1,   -1},   /* slot 16 == nothing */
-           {   -1,   -1,   -1,   -1,   -1},   /* slot 17 == nothing */
-           { 16+3, 16+3, 16+3, 16+3, 16+3},   /* slot 18 == device 3 */
-           { 16+2, 16+2, 16+2, 16+2, 16+2},   /* slot 19 == device 2 */
-           { 16+1, 16+1, 16+1, 16+1, 16+1},   /* slot 20 == device 1 */
-       };
-       common_fixup(6, 20, 5, irq_tab, 0x26e);
-}
-
-/*
- * Fixup configuration for all boards that route the PCI interrupts
- * through the SIO PCI/ISA bridge.  This includes Noname (AXPpci33),
- * Avanti (AlphaStation) and Kenetics's Platform 2000.
- */
-static inline void sio_fixup(void)
-{
-       struct pci_dev *dev;
-       /*
-        * The Noname board has 5 PCI slots with each of the 4
-        * interrupt pins routed to different pins on the PCI/ISA
-        * bridge (PIRQ0-PIRQ3).  The table below is based on
-        * information available at:
-        *
-        *   http://ftp.digital.com/pub/DEC/axppci/ref_interrupts.txt
-        *
-        * I have no information on the Avanti interrupt routing, but
-        * the routing seems to be identical to the Noname except
-        * that the Avanti has an additional slot whose routing I'm
-        * unsure of.
-        *
-        * pirq_tab[0] is a fake entry to deal with old PCI boards
-        * that have the interrupt pin number hardwired to 0 (meaning
-        * that they use the default INTA line, if they are interrupt
-        * driven at all).
-        */
-       static const char pirq_tab[][5] __initlocaldata = {
-             /*INT   A   B   C   D */
-#ifdef CONFIG_ALPHA_P2K
-               { 0,  0, -1, -1, -1}, /* idsel  6 (53c810) */
-               {-1, -1, -1, -1, -1}, /* idsel  7 (SIO: PCI/ISA bridge) */
-               { 1,  1,  2,  3,  0}, /* idsel  8 (slot A) */
-               { 2,  2,  3,  0,  1}, /* idsel  9 (slot B) */
-               {-1, -1, -1, -1, -1}, /* idsel 10 (unused) */
-               {-1, -1, -1, -1, -1}, /* idsel 11 (unused) */
-               { 3,  3, -1, -1, -1}, /* idsel 12 (CMD0646) */
-#else
-               { 3,  3,  3,  3,  3}, /* idsel  6 (53c810) */ 
-               {-1, -1, -1, -1, -1}, /* idsel  7 (SIO: PCI/ISA bridge) */
-               { 2,  2, -1, -1, -1}, /* idsel  8 (Noname hack: slot closest to ISA) */
-               {-1, -1, -1, -1, -1}, /* idsel  9 (unused) */
-               {-1, -1, -1, -1, -1}, /* idsel 10 (unused) */
-               { 0,  0,  2,  1,  0}, /* idsel 11 KN25_PCI_SLOT0 */
-               { 1,  1,  0,  2,  1}, /* idsel 12 KN25_PCI_SLOT1 */
-               { 2,  2,  1,  0,  2}, /* idsel 13 KN25_PCI_SLOT2 */
-               { 0,  0,  0,  0,  0}, /* idsel 14 AS255 TULIP */
-#endif
-       };
-       const size_t pirq_tab_len = sizeof(pirq_tab)/sizeof(pirq_tab[0]);
+               DBG_DEVS(("common_pci_fixup: bus %d slot %d "
+                         "pin %d irq %d\n",
+                         dev->bus->number, slot, pin, irq));
 
-       /*
-        * route_tab selects irq routing in PCI/ISA bridge so that:
-        *              PIRQ0 -> irq 15
-        *              PIRQ1 -> irq  9
-        *              PIRQ2 -> irq 10
-        *              PIRQ3 -> irq 11
-        *
-        * This probably ought to be configurable via MILO.  For
-        * example, sound boards seem to like using IRQ 9.
-        */
+               if (irq != -1)
+                       dev->irq = irq;
 
-#if defined(CONFIG_ALPHA_BOOK1)
-        /* for the AlphaBook1, NCR810 SCSI is 14, PCMCIA controller is 15 */
-        const unsigned int new_route_tab = 0x0e0f0a0a;
+               if (alpha_using_srm) {
+                       /* Read the original SRM-set IRQ and tell. */
+                       pcibios_read_config_byte(dev->bus->number,
+                                                dev->devfn,
+                                                PCI_INTERRUPT_LINE,
+                                                &irq_orig);
 
-#elif defined(CONFIG_ALPHA_NONAME)
-       /*
-        * For UDB, the only available PCI slot must not map to IRQ 9,
-        *  since that's the builtin MSS sound chip. That PCI slot
-        *  will map to PIRQ1 (for INTA at least), so we give it IRQ 15
-        *  instead.
-        *
-        * Unfortunately we have to do this for NONAME as well, since
-        *  they are co-indicated when the platform type "Noname" is
-        *  selected... :-(
-        */
-       const unsigned int new_route_tab = 0x0b0a0f09;
-#else
-       const unsigned int new_route_tab = 0x0b0a090f;
-#endif
-        unsigned int route_tab, old_route_tab;
-       unsigned int level_bits, old_level_bits;
-       unsigned char pin, slot;
-       int pirq;
-
-        pcibios_read_config_dword(0, PCI_DEVFN(7, 0), 0x60, &old_route_tab);
-       DBG_DEVS(("sio_fixup: old pirq route table: 0x%08x\n",
-                  old_route_tab));
-#if PCI_MODIFY
-       route_tab = new_route_tab;
-       pcibios_write_config_dword(0, PCI_DEVFN(7, 0), 0x60, route_tab);
-#else
-       route_tab = old_route_tab;
-#endif
+                       if (irq_orig != dev->irq) {
+                               struct reset_irq *r;
 
-       /*
-        * Go through all devices, fixing up irqs as we see fit:
-        */
-       level_bits = 0;
-       for (dev = pci_devices; dev; dev = dev->next) {
-               if ((dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) &&
-                   (dev->class >> 8 != PCI_CLASS_BRIDGE_PCMCIA))
-                       continue;
+                               DBG_DEVS(("common_pci_fixup: bus %d "
+                                         "slot 0x%x SRM IRQ 0x%x "
+                                         "changed to 0x%x\n",
+                                         dev->bus->number,
+                                         PCI_SLOT(dev->devfn),
+                                         irq_orig, dev->irq));
 
-               dev->irq = 0;
-               if (dev->bus->number != 0) {
-                       struct pci_dev *curr = dev;
-                       /*
-                        * read the pin and do the PCI-PCI bridge
-                        * interrupt pin swizzle
-                        */
-                       pcibios_read_config_byte(dev->bus->number, dev->devfn,
-                                                PCI_INTERRUPT_PIN, &pin);
-                       /* cope with 0 */
-                       if (pin == 0)
-                               pin = 1;
-                       /* follow the chain of bridges, swizzling as we go */
-                       do {
-                               /* swizzle */
-                               pin = bridge_swizzle(pin, PCI_SLOT(curr->devfn));
-                               /* move up the chain of bridges */
-                               curr = curr->bus->self;
-                       } while (curr->bus->self);
-                       /* The slot is the slot of the last bridge. */
-                       slot = PCI_SLOT(curr->devfn);
-               } else {
-                       /* work out the slot */
-                       slot = PCI_SLOT(dev->devfn);
-                       /* read the pin */
-                       pcibios_read_config_byte(dev->bus->number, dev->devfn,
-                                                PCI_INTERRUPT_PIN, &pin);
+                               r = &srm_resets.irq[srm_resets.irq_count++];
+                               r->dev = dev;
+                               r->irq = irq_orig;
+                       }
                }
 
-               if (slot < 6 || slot >= 6 + pirq_tab_len) {
-                       printk("bios32.sio_fixup: "
-                              "weird, found device %04x:%04x in"
-                              " non-existent slot %d!!\n",
-                              dev->vendor, dev->device, slot);
-                       continue;
-               }
-               pirq = pirq_tab[slot - 6][pin];
+               /* Always tell the device, so the driver knows what is
+                  the real IRQ to use; the device does not use it. */
+               pcibios_write_config_byte(dev->bus->number, dev->devfn,
+                                         PCI_INTERRUPT_LINE, dev->irq);
+
+               DBG_DEVS(("common_pci_fixup: bus %d slot 0x%x"
+                         " VID 0x%x DID 0x%x\n"
+                         "              int_slot 0x%x pin 0x%x"
+                         " pirq 0x%x\n",
+                         dev->bus->number, PCI_SLOT(dev->devfn),
+                         dev->vendor, dev->device,
+                         slot, pin, dev->irq));
 
-               DBG_DEVS(("sio_fixup: bus %d  slot 0x%x  VID 0x%x  DID 0x%x\n"
-                         "           int_slot 0x%x  pin 0x%x  pirq 0x%x\n",
-                         dev->bus->number, PCI_SLOT(dev->devfn), dev->vendor,
-                         dev->device, slot, pin, pirq));
                /*
-                * if it's a VGA, enable its BIOS ROM at C0000
+                * If it's a VGA, enable its BIOS ROM at C0000.
                 */
                if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
-                       /* but if its a Cirrus 543x/544x DISABLE it, */
-                       /* since enabling ROM disables the memory... */
+                       /* But if its a Cirrus 543x/544x DISABLE it,
+                          since enabling ROM disables the memory... */
                        if ((dev->vendor == PCI_VENDOR_ID_CIRRUS) &&
                            (dev->device >= 0x00a0) &&
                            (dev->device <= 0x00ac)) {
@@ -1827,401 +964,37 @@ static inline void sio_fixup(void)
                        } else {
                                pcibios_write_config_dword(
                                        dev->bus->number,
-                                                  dev->devfn,
-                                                  PCI_ROM_ADDRESS,
-                                                  0x000c0000 | PCI_ROM_ADDRESS_ENABLE);
-               }
-               }
-               if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
-                       continue; /* for now, displays get no IRQ */
-               }
-
-               if (pirq < 0) {
-                       DBG_DEVS(("bios32.sio_fixup: "
-                              "weird, device %04x:%04x coming in on"
-                              " slot %d has no irq line!!\n",
-                              dev->vendor, dev->device, slot));
-                       continue;
-               }
-
-               dev->irq = (route_tab >> (8 * pirq)) & 0xff;
-
-#ifndef CONFIG_ALPHA_BOOK1
-                /* do not set *ANY* level triggers for AlphaBook1 */
-                /* must set the PCI IRQs to level triggered */
-                level_bits |= (1 << dev->irq);
-#endif /* !CONFIG_ALPHA_BOOK1 */
-
-#if PCI_MODIFY
-               /* tell the device: */
-               pcibios_write_config_byte(dev->bus->number, dev->devfn,
-                                         PCI_INTERRUPT_LINE, dev->irq);
-#endif
-
-#ifdef CONFIG_ALPHA_BOOK1
-                /*
-                 * On the AlphaBook1, the PCMCIA chip (Cirrus 6729)
-                 * is sensitive to PCI bus bursts, so we must DISABLE
-                 * burst mode for the NCR 8xx SCSI... :-(
-                *
-                * Note that the NCR810 SCSI driver must preserve the
-                * setting of the bit in order for this to work.  At the
-                * moment (2.0.29), ncr53c8xx.c does NOT do this, but
-                * 53c7,8xx.c DOES.
-                 */
-                if (dev->vendor == PCI_VENDOR_ID_NCR &&
-                    (dev->device == PCI_DEVICE_ID_NCR_53C810 ||
-                     dev->device == PCI_DEVICE_ID_NCR_53C815 ||
-                     dev->device == PCI_DEVICE_ID_NCR_53C820 ||
-                     dev->device == PCI_DEVICE_ID_NCR_53C825)) {
-                       unsigned int io_port;
-                       unsigned char ctest4;
-
-                       pcibios_read_config_dword(dev->bus->number,
-                                                 dev->devfn,
-                                                 PCI_BASE_ADDRESS_0,
-                                                 &io_port);
-                       io_port &= PCI_BASE_ADDRESS_IO_MASK;
-                       ctest4 = inb(io_port+0x21);
-                       if (!(ctest4 & 0x80)) {
-                               printk("AlphaBook1 NCR init: setting"
-                                      " burst disable\n");
-                               outb(ctest4 | 0x80, io_port+0x21);
+                                       dev->devfn,
+                                       PCI_ROM_ADDRESS,
+                                       0x000c0000 | PCI_ROM_ADDRESS_ENABLE);
                        }
-                }
-#endif /* CONFIG_ALPHA_BOOK1 */
-       } /* end for-devs */
-
-       /*
-        * Now, make all PCI interrupts level sensitive.  Notice:
-        * these registers must be accessed byte-wise.  inw()/outw()
-        * don't work.
-        *
-        * Make sure to turn off any level bits set for IRQs 9,10,11,15,
-        *  so that the only bits getting set are for devices actually found.
-        * Note that we do preserve the remainder of the bits, which we hope
-        *  will be set correctly by ARC/SRM.
-        *
-        * Note: we at least preserve any level-set bits on AlphaBook1
-        */
-       old_level_bits = inb(0x4d0) | (inb(0x4d1) << 8);
-       DBG_DEVS(("sio_fixup: old irq level bits: 0x%04x\n",
-                  old_level_bits));
-       level_bits |= (old_level_bits & 0x71ff);
-       DBG_DEVS(("sio_fixup: new irq level bits: 0x%04x\n",
-                  level_bits));
-       outb((level_bits >> 0) & 0xff, 0x4d0);
-       outb((level_bits >> 8) & 0xff, 0x4d1);
-
-#ifdef CONFIG_ALPHA_BOOK1
-        {
-               unsigned char orig, config;
-               /* On the AlphaBook1, make sure that register PR1
-                  indicates 1Mb mem */
-               outb(0x0f, 0x3ce); orig = inb(0x3cf);   /* read PR5  */
-               outb(0x0f, 0x3ce); outb(0x05, 0x3cf);   /* unlock PR0-4 */
-               outb(0x0b, 0x3ce); config = inb(0x3cf); /* read PR1 */
-               if ((config & 0xc0) != 0xc0) {
-                       printk("AlphaBook1 VGA init: setting 1Mb memory\n");
-                       config |= 0xc0;
-                       outb(0x0b, 0x3ce); outb(config, 0x3cf); /* write PR1 */
-               }
-               outb(0x0f, 0x3ce); outb(orig, 0x3cf); /* (re)lock PR0-4 */
-        }
-#endif /* CONFIG_ALPHA_BOOK1 */
-
-#ifndef CONFIG_ALPHA_BOOK1
-        /* Do not do IDE init for AlphaBook1 */
-        enable_ide(0x26e);
-#endif
-}
-
-
-__initfunc(void
-pcibios_fixup(void))
-{
-         struct pci_bus *cur;
-
-#ifdef CONFIG_ALPHA_MCPCIA
-       /* must do massive setup for multiple PCI busses here... */
-       DBG_DEVS(("pcibios_fixup: calling mcpcia_fixup()...\n"));
-       mcpcia_fixup();
-#endif /* MCPCIA */
-
-#ifdef CONFIG_ALPHA_TSUNAMI
-       /* must do massive setup for multiple PCI busses here... */
-       /* tsunami_fixup(); */
-#endif /* TSUNAMI */
-
-#if PCI_MODIFY && !defined(CONFIG_ALPHA_RUFFIAN)
-       /*
-        * Scan the tree, allocating PCI memory and I/O space.
-        */
-       /*
-        * Sigh; check_region() will need changing to accept a HANDLE,
-        * if we allocate I/O space addresses on a per-bus basis.
-        * For now, make the I/O bases unique across all busses, so
-        * that check_region() will not get confused... ;-}
-        */
-       io_base = DEFAULT_IO_BASE;
-       for (cur = &pci_root; cur; cur = cur->next) {
-               mem_base = DEFAULT_MEM_BASE;
-               DBG_DEVS(("pcibios_fixup: calling layout_bus()\n"));
-               layout_bus(cur);
-       }
-#endif
-       
-       /*
-        * Now is the time to do all those dirty little deeds...
-        */
-#if defined(CONFIG_ALPHA_NONAME) || defined(CONFIG_ALPHA_AVANTI) || \
-    defined(CONFIG_ALPHA_P2K)
-       sio_fixup();
-#elif defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB164)
-       cabriolet_fixup();
-#elif defined(CONFIG_ALPHA_PC164) || defined(CONFIG_ALPHA_LX164)
-       alphapc164_fixup();
-#elif defined(CONFIG_ALPHA_EB66P)
-       eb66p_fixup();
-#elif defined(CONFIG_ALPHA_EB66)
-       eb66_and_eb64p_fixup();
-#elif defined(CONFIG_ALPHA_EB64P)
-       eb66_and_eb64p_fixup();
-#elif defined(CONFIG_ALPHA_MIKASA)
-       mikasa_fixup();
-#elif defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
-       alcor_fixup();
-#elif defined(CONFIG_ALPHA_SABLE)
-       sable_fixup();
-#elif defined(CONFIG_ALPHA_MIATA)
-       miata_fixup();
-#elif defined(CONFIG_ALPHA_NORITAKE)
-       noritake_fixup();
-#elif defined(CONFIG_ALPHA_SX164)
-       sx164_fixup();
-#elif defined(CONFIG_ALPHA_DP264)
-       dp264_fixup();
-#elif defined(CONFIG_ALPHA_RAWHIDE)
-       rawhide_fixup();
-#elif defined(CONFIG_ALPHA_TAKARA)
-       takara_fixup();
-#elif defined(CONFIG_ALPHA_RUFFIAN)
-       /* no fixup needed */
-#else
-# error "You must tell me what kind of platform you want."
-#endif
-}
-
-
-__initfunc(void
-pcibios_fixup_bus(struct pci_bus *bus))
-{
-}
-
-
-asmlinkage int sys_pciconfig_read(unsigned long bus, unsigned long dfn,
-                                 unsigned long off, unsigned long len,
-                                 unsigned char *buf)
-{
-       unsigned char ubyte;
-       unsigned short ushort;
-       unsigned int uint;
-       long err = 0;
-
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
-
-       lock_kernel();
-       switch (len) {
-       case 1:
-               err = pcibios_read_config_byte(bus, dfn, off, &ubyte);
-               if (err != PCIBIOS_SUCCESSFUL)
-                       ubyte = 0xff;
-               put_user(ubyte, buf);
-               break;
-       case 2:
-               err = pcibios_read_config_word(bus, dfn, off, &ushort);
-               if (err != PCIBIOS_SUCCESSFUL)
-                       ushort = 0xffff;
-               put_user(ushort, (unsigned short *)buf);
-               break;
-       case 4:
-               err = pcibios_read_config_dword(bus, dfn, off, &uint);
-               if (err != PCIBIOS_SUCCESSFUL)
-                       uint = 0xffffffff;
-               put_user(uint, (unsigned int *)buf);
-               break;
-       default:
-               err = -EINVAL;
-               break;
-       }
-       unlock_kernel();
-       return err;
-}
-
-
-asmlinkage int sys_pciconfig_write(unsigned long bus, unsigned long dfn,
-                                  unsigned long off, unsigned long len,
-                                  unsigned char *buf)
-{
-       unsigned char ubyte;
-       unsigned short ushort;
-       unsigned int uint;
-       long err = 0;
-
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
-
-       lock_kernel();
-       switch (len) {
-       case 1:
-               err = get_user(ubyte, buf);
-               if (err)
-                       break;
-               err = pcibios_write_config_byte(bus, dfn, off, ubyte);
-               if (err != PCIBIOS_SUCCESSFUL) {
-                       err = -EFAULT;
                }
-               break;
-       case 2:
-               err = get_user(ushort, (unsigned short *)buf);
-               if (err)
-                       break;
-               err = pcibios_write_config_word(bus, dfn, off, ushort);
-               if (err != PCIBIOS_SUCCESSFUL) {
-                       err = -EFAULT;
-               }
-               break;
-       case 4:
-               err = get_user(uint, (unsigned int *)buf);
-               if (err)
-                       break;
-               err = pcibios_write_config_dword(bus, dfn, off, uint);
-               if (err != PCIBIOS_SUCCESSFUL) {
-                       err = -EFAULT;
+               /*
+                * If it's a SCSI, disable its BIOS ROM.
+                */
+               if ((dev->class >> 8) == PCI_CLASS_STORAGE_SCSI) {
+                       pcibios_write_config_dword(dev->bus->number,
+                                                  dev->devfn,
+                                                  PCI_ROM_ADDRESS,
+                                                  0x0000000);
                }
-               break;
-       default:
-               err = -EINVAL;
-               break;
        }
-       unlock_kernel();
-       return err;
-}
-
-#if (defined(CONFIG_ALPHA_PC164) || \
-     defined(CONFIG_ALPHA_LX164) || \
-     defined(CONFIG_ALPHA_SX164) || \
-     defined(CONFIG_ALPHA_EB164) || \
-     defined(CONFIG_ALPHA_EB66P) || \
-     defined(CONFIG_ALPHA_CABRIOLET)) && defined(CONFIG_ALPHA_SRM)
-
-/*
-  on the above machines, under SRM console, we must use the CSERVE PALcode
-  routine to manage the interrupt mask for us, otherwise, the kernel/HW get
-  out of sync with what the PALcode thinks it needs to deliver/ignore
- */
-void
-cserve_update_hw(unsigned long irq, unsigned long mask)
-{
-    extern void cserve_ena(unsigned long);
-    extern void cserve_dis(unsigned long);
-
-    if (mask & (1UL << irq))
-       /* disable */
-       cserve_dis(irq - 16);
-    else
-      /* enable */
-       cserve_ena(irq - 16);
-    return;
 }
-#endif /* (PC164 || LX164 || SX164 || EB164 || CABRIO) && SRM */
 
-#ifdef CONFIG_ALPHA_MIATA
-/*
- * Init the built-in ES1888 sound chip (SB16 compatible)
- */
-static int __init
-es1888_init(void)
-{
-       /* Sequence of IO reads to init the audio controller */
-       inb(0x0229);
-       inb(0x0229);
-       inb(0x0229);
-       inb(0x022b);
-       inb(0x0229);
-       inb(0x022b);
-       inb(0x0229);
-       inb(0x0229);
-       inb(0x022b);
-       inb(0x0229);
-       inb(0x0220); /* This sets the base address to 0x220 */
-
-       /* Sequence to set DMA channels */
-       outb(0x01, 0x0226);             /* reset */
-       inb(0x0226);                    /* pause */
-       outb(0x00, 0x0226);             /* release reset */
-       while (!(inb(0x022e) & 0x80))   /* wait for bit 7 to assert*/
-               continue;
-       inb(0x022a);                    /* pause */
-       outb(0xc6, 0x022c);             /* enable extended mode */
-       while (inb(0x022c) & 0x80)      /* wait for bit 7 to deassert */
-               continue;
-       outb(0xb1, 0x022c);             /* setup for write to Interrupt CR */
-       while (inb(0x022c) & 0x80)      /* wait for bit 7 to deassert */
-               continue;
-       outb(0x14, 0x022c);             /* set IRQ 5 */
-       while (inb(0x022c) & 0x80)      /* wait for bit 7 to deassert */
-               continue;
-       outb(0xb2, 0x022c);             /* setup for write to DMA CR */
-       while (inb(0x022c) & 0x80)      /* wait for bit 7 to deassert */
-               continue;
-       outb(0x18, 0x022c);             /* set DMA channel 1 */
-    
-       return 0;
-}
-#endif /* CONFIG_ALPHA_MIATA */
+/* Most Alphas have straight-forward swizzling needs.  */
 
-__initfunc(char *pcibios_setup(char *str))
+int __init
+common_swizzle(struct pci_dev *dev, int *pinp)
 {
-       return str;
-}
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-void reset_for_srm(void)
-{
-       struct pci_dev *dev;
-       int i;
+       int pin = *pinp;
+       do {
+               pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+               /* Move up the chain of bridges. */
+               dev = dev->bus->self;
+       } while (dev->bus->self);
+       *pinp = pin;
 
-       /* reset any IRQs that we changed */
-       for (i = 0; i < irq_reset_count; i++) {
-           dev = irq_dev_to_reset[i];
-
-           pcibios_write_config_byte(dev->bus->number, dev->devfn,
-                                     PCI_INTERRUPT_LINE, irq_to_reset[i]);
-#if 1
-           printk("reset_for_srm: bus %d slot 0x%x "
-                  "SRM IRQ 0x%x changed back from 0x%x\n",
-                  dev->bus->number, PCI_SLOT(dev->devfn),
-                  irq_to_reset[i], dev->irq);
-#endif
-       }
-
-       /* reset any IO addresses that we changed */
-       for (i = 0; i < io_reset_count; i++) {
-           dev = io_dev_to_reset[i];
-
-           pcibios_write_config_byte(dev->bus->number, dev->devfn,
-                                     io_reg_to_reset[i], io_to_reset[i]);
-#if 1
-           printk("reset_for_srm: bus %d slot 0x%x "
-                  "SRM IO restored to 0x%x\n",
-                  dev->bus->number, PCI_SLOT(dev->devfn),
-                  io_to_reset[i]);
-#endif
+       /* The slot is the slot of the last bridge. */
+       return PCI_SLOT(dev->devfn);
 }
-       /* FIXME: reset the video origin.  */
-}
-#endif /* CONFIG_ALPHA_SRM_SETUP */
-
 #endif /* CONFIG_PCI */
diff --git a/arch/alpha/kernel/bios32.h b/arch/alpha/kernel/bios32.h
new file mode 100644 (file)
index 0000000..9a3184f
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ *     linux/arch/alpha/kernel/bios32.h
+ *
+ * This file contains declarations and inline functions for interfacing
+ * with the PCI initialization routines in bios32.c.
+ */
+
+
+#define KB             1024
+#define MB             (1024*KB)
+#define GB             (1024*MB)
+
+/*
+ * We can't just blindly use 64K for machines with EISA busses; they
+ * may also have PCI-PCI bridges present, and then we'd configure the
+ * bridge incorrectly.
+ *
+ * Also, we start at 0x8000 or 0x9000, in hopes to get all devices'
+ * IO space areas allocated *before* 0xC000; this is because certain
+ * BIOSes (Millennium for one) use PCI Config space "mechanism #2"
+ * accesses to probe the bus. If a device's registers appear at 0xC000,
+ * it may see an INx/OUTx at that address during BIOS emulation of the
+ * VGA BIOS, and some cards, notably Adaptec 2940UW, take mortal offense.
+ *
+ * Note that we may need this stuff for SRM_SETUP also, since certain
+ * SRM consoles screw up and allocate I/O space addresses > 64K behind
+ * PCI-to_PCI bridges, which can't pass I/O addresses larger than 64K,
+ * AFAIK.
+ */
+
+#define EISA_DEFAULT_IO_BASE 0x9000    /* start above 8th slot */
+#define DEFAULT_IO_BASE 0x8000         /* start at 8th slot */
+
+/*
+ * An XL is AVANTI (APECS) family, *but* it has only 27 bits of ISA address
+ * that get passed through the PCI<->ISA bridge chip. Although this causes
+ * us to set the PCI->Mem window bases lower than normal, we still allocate
+ * PCI bus devices' memory addresses *below* the low DMA mapping window,
+ * and hope they fit below 64Mb (to avoid conflicts), and so that they can
+ * be accessed via SPARSE space.
+ *
+ * We accept the risk that a broken Myrinet card will be put into a true XL
+ * and thus can more easily run into the problem described below.
+ */
+#define XL_DEFAULT_MEM_BASE (16*MB + 2*MB) /* 16M to 64M-1 is avail */
+
+/*
+ * We try to make this address *always* have more than 1 bit set.
+ * this is so that devices like the broken Myrinet card will always have
+ * a PCI memory address that will never match a IDSEL address in
+ * PCI Config space, which can cause problems with early rev cards.
+ *
+ * However, APECS and LCA have only 34 bits for physical addresses, thus
+ * limiting PCI bus memory addresses for SPARSE access to be less than 128Mb.
+ */
+#define APECS_AND_LCA_DEFAULT_MEM_BASE (64*MB + 2*MB)
+
+/*
+ * We try to make this address *always* have more than 1 bit set.
+ * this is so that devices like the broken Myrinet card will always have
+ * a PCI memory address that will never match a IDSEL address in
+ * PCI Config space, which can cause problems with early rev cards.
+ *
+ * Because CIA and PYXIS and T2 have more bits for physical addresses,
+ * they support an expanded range of SPARSE memory addresses.
+ */
+#define DEFAULT_MEM_BASE (128*MB + 16*MB)
+
+
+/*
+ * PCI_MODIFY
+ *
+ * If this 0, then do not write to any of the PCI registers, merely
+ * read them (i.e., use configuration as determined by SRM).  The SRM
+ * seem do be doing a less than perfect job in configuring PCI
+ * devices, so for now we do it ourselves.  Reconfiguring PCI devices
+ * breaks console (RPB) callbacks, but those don't work properly with
+ * 64 bit addresses anyways.
+ *
+ * The accepted convention seems to be that the console (POST
+ * software) should fully configure boot devices and configure the
+ * interrupt routing of *all* devices.  In particular, the base
+ * addresses of non-boot devices need not be initialized.  For
+ * example, on the AXPpci33 board, the base address a #9 GXE PCI
+ * graphics card reads as zero (this may, however, be due to a bug in
+ * the graphics card---there have been some rumor that the #9 BIOS
+ * incorrectly resets that address to 0...).
+ */
+
+#define PCI_MODIFY     (!alpha_use_srm_setup)
+     
+
+/* 
+ * A small note about bridges and interrupts.  The DECchip 21050 (and
+ * later) adheres to the PCI-PCI bridge specification.  This says that
+ * the interrupts on the other side of a bridge are swizzled in the
+ * following manner:
+ *
+ * Dev    Interrupt   Interrupt 
+ *        Pin on      Pin on 
+ *        Device      Connector
+ *
+ *   4    A           A
+ *        B           B
+ *        C           C
+ *        D           D
+ * 
+ *   5    A           B
+ *        B           C
+ *        C           D
+ *        D           A
+ *
+ *   6    A           C
+ *        B           D
+ *        C           A
+ *        D           B
+ *
+ *   7    A           D
+ *        B           A
+ *        C           B
+ *        D           C
+ *
+ *   Where A = pin 1, B = pin 2 and so on and pin=0 = default = A.
+ *   Thus, each swizzle is ((pin-1) + (device#-4)) % 4
+ *
+ *   The following code swizzles for exactly one bridge.  The routine
+ *   common_swizzle below handles multiple bridges.  But there are a
+ *   couple boards that do strange things, so we define this here.
+ */
+
+static inline unsigned char
+bridge_swizzle(unsigned char pin, unsigned int slot) 
+{
+       return (((pin-1) + slot) % 4) + 1;
+}
+
+extern void layout_all_busses(unsigned long io_base, unsigned long mem_base);
+extern void enable_ide(long ide_base);
+
+struct pci_dev;
+
+extern void
+common_pci_fixup(int (*map_irq)(struct pci_dev *dev, int slot, int pin),
+                int (*swizzle)(struct pci_dev *dev, int *pin));
+
+extern int common_swizzle(struct pci_dev *dev, int *pinp);
+
+/* The following macro is used to implement the table-based irq mapping
+   function for all single-bus Alphas.  */
+
+#define COMMON_TABLE_LOOKUP                                            \
+({ long _ctl_ = -1;                                                    \
+   if (slot >= min_idsel && slot <= max_idsel && pin < irqs_per_slot)  \
+     _ctl_ = irq_tab[slot - min_idsel][pin];                           \
+   _ctl_; })
diff --git a/arch/alpha/kernel/cia.c b/arch/alpha/kernel/cia.c
deleted file mode 100644 (file)
index 079b4c2..0000000
+++ /dev/null
@@ -1,735 +0,0 @@
-/*
- * Code common to all CIA chips.
- *
- * Written by David A Rusling (david.rusling@reo.mts.dec.com).
- * December 1995.
- *
- */
-#include <linux/kernel.h>
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/sched.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/hwrpb.h>
-#include <asm/ptrace.h>
-#include <asm/mmu_context.h>
-
-/*
- * NOTE: Herein lie back-to-back mb instructions.  They are magic. 
- * One plausible explanation is that the i/o controller does not properly
- * handle the system transaction.  Another involves timing.  Ho hum.
- */
-
-extern struct hwrpb_struct *hwrpb;
-extern asmlinkage void wrmces(unsigned long mces);
-
-/*
- * Machine check reasons.  Defined according to PALcode sources
- * (osf.h and platform.h).
- */
-#define MCHK_K_TPERR           0x0080
-#define MCHK_K_TCPERR          0x0082
-#define MCHK_K_HERR            0x0084
-#define MCHK_K_ECC_C           0x0086
-#define MCHK_K_ECC_NC          0x0088
-#define MCHK_K_OS_BUGCHECK     0x008A
-#define MCHK_K_PAL_BUGCHECK    0x0090
-
-/*
- * BIOS32-style PCI interface:
- */
-
-/* #define DEBUG_MCHECK */
-/* #define DEBUG_CONFIG */
-/* #define DEBUG_DUMP_REGS */
-
-#ifdef DEBUG_MCHECK
-# define DBGM(args)    printk args
-#else
-# define DBGM(args)
-#endif
-#ifdef DEBUG_CONFIG
-# define DBGC(args)    printk args
-#else
-# define DBGC(args)
-#endif
-
-#define vuip   volatile unsigned int  *
-
-static volatile unsigned int CIA_mcheck_expected = 0;
-static volatile unsigned int CIA_mcheck_taken = 0;
-static unsigned int CIA_jd;
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-unsigned int CIA_DMA_WIN_BASE = CIA_DMA_WIN_BASE_DEFAULT;
-unsigned int CIA_DMA_WIN_SIZE = CIA_DMA_WIN_SIZE_DEFAULT;
-unsigned long cia_sm_base_r1, cia_sm_base_r2, cia_sm_base_r3;
-#endif /* SRM_SETUP */
-
-/*
- * Given a bus, device, and function number, compute resulting
- * configuration space address and setup the CIA_HAXR2 register
- * accordingly.  It is therefore not safe to have concurrent
- * invocations to configuration space access routines, but there
- * really shouldn't be any need for this.
- *
- * Type 0:
- *
- *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *     31:11   Device select bit.
- *     10:8    Function number
- *      7:2    Register number
- *
- * Type 1:
- *
- *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *     31:24   reserved
- *     23:16   bus number (8 bits = 128 possible buses)
- *     15:11   Device number (5 bits)
- *     10:8    function number
- *      7:2    register number
- *  
- * Notes:
- *     The function number selects which function of a multi-function device 
- *     (e.g., SCSI and Ethernet).
- * 
- *     The register selects a DWORD (32 bit) register offset.  Hence it
- *     doesn't get shifted by 2 bits as we want to "drop" the bottom two
- *     bits.
- */
-static int mk_conf_addr(unsigned char bus, unsigned char device_fn,
-                       unsigned char where, unsigned long *pci_addr,
-                       unsigned char *type1)
-{
-       unsigned long addr;
-
-       DBGC(("mk_conf_addr(bus=%d, device_fn=0x%x, where=0x%x, "
-             "pci_addr=0x%p, type1=0x%p)\n",
-             bus, device_fn, where, pci_addr, type1));
-
-       if (bus == 0) {
-               int device = device_fn >> 3;
-
-               /* type 0 configuration cycle: */
-
-               if (device > 20) {
-                       DBGC(("mk_conf_addr: device (%d) > 20, returning -1\n",
-                             device));
-                       return -1;
-               }
-
-               *type1 = 0;
-               addr = (device_fn << 8) | (where);
-       } else {
-               /* type 1 configuration cycle: */
-               *type1 = 1;
-               addr = (bus << 16) | (device_fn << 8) | (where);
-       }
-       *pci_addr = addr;
-       DBGC(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
-       return 0;
-}
-
-
-static unsigned int conf_read(unsigned long addr, unsigned char type1)
-{
-       unsigned long flags;
-       unsigned int stat0, value;
-       unsigned int cia_cfg = 0; /* to keep gcc quiet */
-
-       value = 0xffffffffU;
-       mb();
-
-       save_flags(flags);      /* avoid getting hit by machine check */
-       cli();
-
-       DBGC(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
-
-       /* reset status register to avoid losing errors: */
-       stat0 = *(vuip)CIA_IOC_CIA_ERR;
-       *(vuip)CIA_IOC_CIA_ERR = stat0;
-       mb();
-       DBGC(("conf_read: CIA ERR was 0x%x\n", stat0));
-       /* if Type1 access, must set CIA CFG */
-       if (type1) {
-               cia_cfg = *(vuip)CIA_IOC_CFG;
-               *(vuip)CIA_IOC_CFG = cia_cfg | 1;
-               mb();
-               DBGC(("conf_read: TYPE1 access\n"));
-       }
-
-       mb();
-       draina();
-       CIA_mcheck_expected = 1;
-       CIA_mcheck_taken = 0;
-       mb();
-       /* access configuration space: */
-       value = *(vuip)addr;
-       mb();
-       mb();  /* magic */
-       if (CIA_mcheck_taken) {
-               CIA_mcheck_taken = 0;
-               value = 0xffffffffU;
-               mb();
-       }
-       CIA_mcheck_expected = 0;
-       mb();
-
-#if 0
-       /*
-         this code might be necessary if machine checks aren't taken,
-         but I can't get it to work on CIA-2, so its disabled.
-         */
-       draina();
-
-       /* now look for any errors */
-       stat0 = *(vuip)CIA_IOC_CIA_ERR;
-       DBGC(("conf_read: CIA ERR after read 0x%x\n", stat0));
-       if (stat0 & 0x8FEF0FFFU) { /* is any error bit set? */
-               /* if not MAS_ABT, print status */
-               if (!(stat0 & 0x0080)) {
-                       printk("CIA.c:conf_read: got stat0=%x\n", stat0);
-               }
-
-               /* reset error status: */
-               *(vuip)CIA_IOC_CIA_ERR = stat0;
-               mb();
-               wrmces(0x7);                    /* reset machine check */
-               value = 0xffffffff;
-       }
-#endif
-
-       /* if Type1 access, must reset IOC CFG so normal IO space ops work */
-       if (type1) {
-               *(vuip)CIA_IOC_CFG = cia_cfg & ~1;
-               mb();
-       }
-
-       DBGC(("conf_read(): finished\n"));
-
-       restore_flags(flags);
-       return value;
-}
-
-
-static void conf_write(unsigned long addr, unsigned int value,
-                      unsigned char type1)
-{
-       unsigned long flags;
-       unsigned int stat0;
-       unsigned int cia_cfg = 0; /* to keep gcc quiet */
-
-       save_flags(flags);      /* avoid getting hit by machine check */
-       cli();
-
-       /* reset status register to avoid losing errors: */
-       stat0 = *(vuip)CIA_IOC_CIA_ERR;
-       *(vuip)CIA_IOC_CIA_ERR = stat0;
-       mb();
-       DBGC(("conf_write: CIA ERR was 0x%x\n", stat0));
-       /* if Type1 access, must set CIA CFG */
-       if (type1) {
-               cia_cfg = *(vuip)CIA_IOC_CFG;
-               *(vuip)CIA_IOC_CFG = cia_cfg | 1;
-               mb();
-               DBGC(("conf_write: TYPE1 access\n"));
-       }
-
-       draina();
-       CIA_mcheck_expected = 1;
-       mb();
-       /* access configuration space: */
-       *(vuip)addr = value;
-       mb();
-       mb();  /* magic */
-
-       CIA_mcheck_expected = 0;
-       mb();
-
-#if 0
-       /*
-        * This code might be necessary if machine checks aren't taken,
-        * but I can't get it to work on CIA-2, so its disabled.
-        */
-       draina();
-
-       /* Now look for any errors */
-       stat0 = *(vuip)CIA_IOC_CIA_ERR;
-       DBGC(("conf_write: CIA ERR after write 0x%x\n", stat0));
-       if (stat0 & 0x8FEF0FFFU) { /* is any error bit set? */
-               /* If not MAS_ABT, print status */
-               if (!(stat0 & 0x0080)) {
-                       printk("CIA.c:conf_read: got stat0=%x\n", stat0);
-               }
-
-               /* reset error status: */
-               *(vuip)CIA_IOC_CIA_ERR = stat0;
-               mb();
-               wrmces(0x7);                    /* reset machine check */
-               value = 0xffffffff;
-       }
-#endif
-
-       /* if Type1 access, must reset IOC CFG so normal IO space ops work */
-       if (type1) {
-               *(vuip)CIA_IOC_CFG = cia_cfg & ~1;
-               mb();
-       }
-
-       DBGC(("conf_write(): finished\n"));
-       restore_flags(flags);
-}
-
-
-int pcibios_read_config_byte (unsigned char bus, unsigned char device_fn,
-                             unsigned char where, unsigned char *value)
-{
-       unsigned long addr = CIA_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       *value = 0xff;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       addr |= (pci_addr << 5) + 0x00;
-
-       *value = conf_read(addr, type1) >> ((where & 3) * 8);
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_read_config_word (unsigned char bus, unsigned char device_fn,
-                             unsigned char where, unsigned short *value)
-{
-       unsigned long addr = CIA_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       *value = 0xffff;
-
-       if (where & 0x1) {
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-       }
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       addr |= (pci_addr << 5) + 0x08;
-
-       *value = conf_read(addr, type1) >> ((where & 3) * 8);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_read_config_dword (unsigned char bus, unsigned char device_fn,
-                              unsigned char where, unsigned int *value)
-{
-       unsigned long addr = CIA_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       *value = 0xffffffff;
-       if (where & 0x3) {
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-       }
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x18;
-       *value = conf_read(addr, type1);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_write_config_byte (unsigned char bus, unsigned char device_fn,
-                              unsigned char where, unsigned char value)
-{
-       unsigned long addr = CIA_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x00;
-       conf_write(addr, value << ((where & 3) * 8), type1);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_write_config_word (unsigned char bus, unsigned char device_fn,
-                              unsigned char where, unsigned short value)
-{
-       unsigned long addr = CIA_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x08;
-       conf_write(addr, value << ((where & 3) * 8), type1);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_write_config_dword (unsigned char bus, unsigned char device_fn,
-                               unsigned char where, unsigned int value)
-{
-       unsigned long addr = CIA_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x18;
-       conf_write(addr, value << ((where & 3) * 8), type1);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-unsigned long cia_init(unsigned long mem_start, unsigned long mem_end)
-{
-        unsigned int cia_tmp;
-
-#ifdef DEBUG_DUMP_REGS
-       {
-               unsigned int temp;
-               temp = *(vuip)CIA_IOC_CIA_REV; mb();
-               printk("CIA_init: CIA_REV was 0x%x\n", temp);
-               temp = *(vuip)CIA_IOC_PCI_LAT; mb();
-               printk("CIA_init: CIA_PCI_LAT was 0x%x\n", temp);
-               temp = *(vuip)CIA_IOC_CIA_CTRL; mb();
-               printk("CIA_init: CIA_CTRL was 0x%x\n", temp);
-               temp = *(vuip)0xfffffc8740000140UL; mb();
-               printk("CIA_init: CIA_CTRL1 was 0x%x\n", temp);
-               temp = *(vuip)CIA_IOC_HAE_MEM; mb();
-               printk("CIA_init: CIA_HAE_MEM was 0x%x\n", temp);
-               temp = *(vuip)CIA_IOC_HAE_IO; mb();
-               printk("CIA_init: CIA_HAE_IO was 0x%x\n", temp);
-               temp = *(vuip)CIA_IOC_CFG; mb();
-               printk("CIA_init: CIA_CFG was 0x%x\n", temp);
-               temp = *(vuip)CIA_IOC_CACK_EN; mb();
-               printk("CIA_init: CIA_CACK_EN was 0x%x\n", temp);
-               temp = *(vuip)CIA_IOC_CFG; mb();
-               printk("CIA_init: CIA_CFG was 0x%x\n", temp);
-               temp = *(vuip)CIA_IOC_CIA_DIAG; mb();
-               printk("CIA_init: CIA_DIAG was 0x%x\n", temp);
-               temp = *(vuip)CIA_IOC_DIAG_CHECK; mb();
-               printk("CIA_init: CIA_DIAG_CHECK was 0x%x\n", temp);
-               temp = *(vuip)CIA_IOC_PERF_MONITOR; mb();
-               printk("CIA_init: CIA_PERF_MONITOR was 0x%x\n", temp);
-               temp = *(vuip)CIA_IOC_PERF_CONTROL; mb();
-               printk("CIA_init: CIA_PERF_CONTROL was 0x%x\n", temp);
-               temp = *(vuip)CIA_IOC_CIA_ERR; mb();
-               printk("CIA_init: CIA_ERR was 0x%x\n", temp);
-               temp = *(vuip)CIA_IOC_CIA_STAT; mb();
-               printk("CIA_init: CIA_STAT was 0x%x\n", temp);
-               temp = *(vuip)CIA_IOC_MCR; mb();
-               printk("CIA_init: CIA_MCR was 0x%x\n", temp);
-               temp = *(vuip)CIA_IOC_CIA_CTRL; mb();
-               printk("CIA_init: CIA_CTRL was 0x%x\n", temp);
-               temp = *(vuip)CIA_IOC_ERR_MASK; mb();
-               printk("CIA_init: CIA_ERR_MASK was 0x%x\n", temp);
-               temp = *((vuip)CIA_IOC_PCI_W0_BASE); mb();
-               printk("CIA_init: W0_BASE was 0x%x\n", temp);
-               temp = *((vuip)CIA_IOC_PCI_W1_BASE); mb();
-               printk("CIA_init: W1_BASE was 0x%x\n", temp);
-               temp = *((vuip)CIA_IOC_PCI_W2_BASE); mb();
-               printk("CIA_init: W2_BASE was 0x%x\n", temp);
-               temp = *((vuip)CIA_IOC_PCI_W3_BASE); mb();
-               printk("CIA_init: W3_BASE was 0x%x\n", temp);
-       }
-#endif /* DEBUG_DUMP_REGS */
-
-        /* 
-        * Set up error reporting.
-        */
-       cia_tmp = *(vuip)CIA_IOC_CIA_ERR;
-       cia_tmp |= 0x180;   /* master, target abort */
-       *(vuip)CIA_IOC_CIA_ERR = cia_tmp;
-       mb();
-
-       cia_tmp = *(vuip)CIA_IOC_CIA_CTRL;
-       cia_tmp |= 0x400;   /* turn on FILL_ERR to get mchecks */
-       *(vuip)CIA_IOC_CIA_CTRL = cia_tmp;
-       mb();
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-       /* check window 0 for enabled and mapped to 0 */
-       if (((*(vuip)CIA_IOC_PCI_W0_BASE & 3) == 1) &&
-           (*(vuip)CIA_IOC_PCI_T0_BASE == 0))
-       {
-         CIA_DMA_WIN_BASE = *(vuip)CIA_IOC_PCI_W0_BASE & 0xfff00000U;
-         CIA_DMA_WIN_SIZE = *(vuip)CIA_IOC_PCI_W0_MASK & 0xfff00000U;
-         CIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-         printk("cia_init: using Window 0 settings\n");
-         printk("cia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-                *(vuip)CIA_IOC_PCI_W0_BASE,
-                *(vuip)CIA_IOC_PCI_W0_MASK,
-                *(vuip)CIA_IOC_PCI_T0_BASE);
-#endif
-       }
-       else  /* check window 1 for enabled and mapped to 0 */
-       if (((*(vuip)CIA_IOC_PCI_W1_BASE & 3) == 1) &&
-           (*(vuip)CIA_IOC_PCI_T1_BASE == 0))
-       {
-         CIA_DMA_WIN_BASE = *(vuip)CIA_IOC_PCI_W1_BASE & 0xfff00000U;
-         CIA_DMA_WIN_SIZE = *(vuip)CIA_IOC_PCI_W1_MASK & 0xfff00000U;
-         CIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-         printk("cia_init: using Window 1 settings\n");
-         printk("cia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-                *(vuip)CIA_IOC_PCI_W1_BASE,
-                *(vuip)CIA_IOC_PCI_W1_MASK,
-                *(vuip)CIA_IOC_PCI_T1_BASE);
-#endif
-       }
-       else  /* check window 2 for enabled and mapped to 0 */
-       if (((*(vuip)CIA_IOC_PCI_W2_BASE & 3) == 1) &&
-           (*(vuip)CIA_IOC_PCI_T2_BASE == 0))
-       {
-         CIA_DMA_WIN_BASE = *(vuip)CIA_IOC_PCI_W2_BASE & 0xfff00000U;
-         CIA_DMA_WIN_SIZE = *(vuip)CIA_IOC_PCI_W2_MASK & 0xfff00000U;
-         CIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-         printk("cia_init: using Window 2 settings\n");
-         printk("cia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-                *(vuip)CIA_IOC_PCI_W2_BASE,
-                *(vuip)CIA_IOC_PCI_W2_MASK,
-                *(vuip)CIA_IOC_PCI_T2_BASE);
-#endif
-       }
-       else  /* check window 3 for enabled and mapped to 0 */
-       if (((*(vuip)CIA_IOC_PCI_W3_BASE & 3) == 1) &&
-           (*(vuip)CIA_IOC_PCI_T3_BASE == 0))
-       {
-         CIA_DMA_WIN_BASE = *(vuip)CIA_IOC_PCI_W3_BASE & 0xfff00000U;
-         CIA_DMA_WIN_SIZE = *(vuip)CIA_IOC_PCI_W3_MASK & 0xfff00000U;
-         CIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-         printk("cia_init: using Window 3 settings\n");
-         printk("cia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-                *(vuip)CIA_IOC_PCI_W3_BASE,
-                *(vuip)CIA_IOC_PCI_W3_MASK,
-                *(vuip)CIA_IOC_PCI_T3_BASE);
-#endif
-       }
-       else  /* we must use our defaults which were pre-initialized... */
-#endif /* SRM_SETUP */
-       {
-       /*
-        * Set up the PCI->physical memory translation windows.
-        * For now, windows 1,2 and 3 are disabled.  In the future, we may
-        * want to use them to do scatter/gather DMA.  Window 0
-        * goes at 1 GB and is 1 GB large.
-        */
-
-       *(vuip)CIA_IOC_PCI_W0_BASE = 1U | (CIA_DMA_WIN_BASE & 0xfff00000U);
-       *(vuip)CIA_IOC_PCI_W0_MASK = (CIA_DMA_WIN_SIZE - 1) & 0xfff00000U;
-       *(vuip)CIA_IOC_PCI_T0_BASE = 0;
-
-       *(vuip)CIA_IOC_PCI_W1_BASE = 0x0;
-       *(vuip)CIA_IOC_PCI_W2_BASE = 0x0;
-       *(vuip)CIA_IOC_PCI_W3_BASE = 0x0;
-       }
-
-       /*
-        * check ASN in HWRPB for validity, report if bad
-        */
-       if (hwrpb->max_asn != MAX_ASN) {
-               printk("CIA_init: max ASN from HWRPB is bad (0x%lx)\n",
-                      hwrpb->max_asn);
-               hwrpb->max_asn = MAX_ASN;
-       }
-
-        /*
-         * Next, clear the CIA_CFG register, which gets used
-         *  for PCI Config Space accesses. That is the way
-         *  we want to use it, and we do not want to depend on
-         *  what ARC or SRM might have left behind...
-         */
-        {
-          unsigned int cia_cfg = *((vuip)CIA_IOC_CFG); mb();
-          if (cia_cfg) {
-             printk("CIA_init: CFG was 0x%x\n", cia_cfg);
-             *((vuip)CIA_IOC_CFG) = 0; mb();
-         }
-        }
-       {
-          unsigned int cia_hae_mem = *((vuip)CIA_IOC_HAE_MEM);
-          unsigned int cia_hae_io = *((vuip)CIA_IOC_HAE_IO);
-#if 0
-         printk("CIA_init: HAE_MEM was 0x%x\n", cia_hae_mem);
-         printk("CIA_init: HAE_IO was 0x%x\n", cia_hae_io);
-#endif
-#ifdef CONFIG_ALPHA_SRM_SETUP
-         /*
-           sigh... For the SRM setup, unless we know apriori what the HAE
-           contents will be, we need to setup the arbitrary region bases
-           so we can test against the range of addresses and tailor the
-           region chosen for the SPARSE memory access.
-
-           see include/asm-alpha/cia.h for the SPARSE mem read/write
-         */
-         cia_sm_base_r1 = (cia_hae_mem      ) & 0xe0000000UL; /* region 1 */
-         cia_sm_base_r2 = (cia_hae_mem << 16) & 0xf8000000UL; /* region 2 */
-         cia_sm_base_r3 = (cia_hae_mem << 24) & 0xfc000000UL; /* region 3 */
-
-         /*
-           Set the HAE cache, so that setup_arch() code
-           will use the SRM setting always. Our readb/writeb
-           code in cia.h expects never to have to change
-           the contents of the HAE.
-          */
-         hae.cache = cia_hae_mem;
-#else /* SRM_SETUP */
-         *((vuip)CIA_IOC_HAE_MEM) = 0; mb();
-         cia_hae_mem = *((vuip)CIA_IOC_HAE_MEM);
-         *((vuip)CIA_IOC_HAE_IO) = 0; mb();
-         cia_hae_io = *((vuip)CIA_IOC_HAE_IO);
-#endif /* SRM_SETUP */
-        }
-       return mem_start;
-}
-
-int cia_pci_clr_err(void)
-{
-       CIA_jd = *(vuip)CIA_IOC_CIA_ERR;
-       DBGM(("CIA_pci_clr_err: CIA ERR after read 0x%x\n", CIA_jd));
-       *(vuip)CIA_IOC_CIA_ERR = 0x0180;
-       mb();
-       return 0;
-}
-
-void cia_machine_check(unsigned long vector, unsigned long la_ptr,
-                      struct pt_regs * regs)
-{
-       struct el_common *mchk_header;
-       struct el_procdata *mchk_procdata;
-       struct el_CIA_sysdata_mcheck *mchk_sysdata;
-       unsigned long * ptr;
-       const char * reason;
-       char buf[128];
-       long i;
-
-       mchk_header = (struct el_common *)la_ptr;
-       mchk_procdata = (struct el_procdata *)
-               (la_ptr + mchk_header->proc_offset);
-       mchk_sysdata = (struct el_CIA_sysdata_mcheck *)
-               (la_ptr + mchk_header->sys_offset);
-
-       DBGM(("cia_machine_check: vector=0x%lx la_ptr=0x%lx\n",
-             vector, la_ptr));
-       DBGM(("                     pc=0x%lx size=0x%x procoffset=0x%x "
-             "sysoffset 0x%x\n", regs->pc, mchk_header->size,
-             mchk_header->proc_offset, mchk_header->sys_offset));
-       DBGM(("cia_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
-             CIA_mcheck_expected, mchk_sysdata->epic_dcsr,
-             mchk_sysdata->epic_pear));
-
-#ifdef DEBUG_MCHECK
-       {
-               unsigned long *ptr;
-               int i;
-
-               ptr = (unsigned long *)la_ptr;
-               for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
-                       printk(" +%lx %lx %lx\n", i*sizeof(long),
-                              ptr[i], ptr[i+1]);
-               }
-       }
-#endif
-
-       /*
-        * Check if machine check is due to a badaddr() and if so,
-        * ignore the machine check.
-        */
-       mb();
-       mb();  /* magic */
-       if (CIA_mcheck_expected) {
-               DBGM(("CIA machine check expected\n"));
-               CIA_mcheck_expected = 0;
-               CIA_mcheck_taken = 1;
-               mb();
-               mb();  /* magic */
-               draina();
-               cia_pci_clr_err();
-               wrmces(0x7);
-               mb();
-               return;
-       }
-
-       switch ((unsigned int) mchk_header->code) {
-       case MCHK_K_TPERR:      reason = "tag parity error"; break;
-       case MCHK_K_TCPERR:     reason = "tag control parity error"; break;
-       case MCHK_K_HERR:               reason = "generic hard error"; break;
-       case MCHK_K_ECC_C:      reason = "correctable ECC error"; break;
-       case MCHK_K_ECC_NC:     reason = "uncorrectable ECC error"; break;
-       case MCHK_K_OS_BUGCHECK:        reason = "OS-specific PAL bugcheck"; break;
-       case MCHK_K_PAL_BUGCHECK:       reason = "callsys in kernel mode"; break;
-       case 0x96: reason = "i-cache read retryable error"; break;
-       case 0x98: reason = "processor detected hard error"; break;
-
-               /* system specific (these are for Alcor, at least): */
-       case 0x203: reason = "system detected uncorrectable ECC error"; break;
-       case 0x205: reason = "parity error detected by CIA"; break;
-       case 0x207: reason = "non-existent memory error"; break;
-       case 0x209: reason = "PCI SERR detected"; break;
-       case 0x20b: reason = "PCI data parity error detected"; break;
-       case 0x20d: reason = "PCI address parity error detected"; break;
-       case 0x20f: reason = "PCI master abort error"; break;
-       case 0x211: reason = "PCI target abort error"; break;
-       case 0x213: reason = "scatter/gather PTE invalid error"; break;
-       case 0x215: reason = "flash ROM write error"; break;
-       case 0x217: reason = "IOA timeout detected"; break;
-       case 0x219: reason = "IOCHK#, EISA add-in board parity or other catastrophic error"; break;
-       case 0x21b: reason = "EISA fail-safe timer timeout"; break;
-       case 0x21d: reason = "EISA bus time-out"; break;
-       case 0x21f: reason = "EISA software generated NMI"; break;
-       case 0x221: reason = "unexpected ev5 IRQ[3] interrupt"; break;
-       default:
-               sprintf(buf, "reason for machine-check unknown (0x%x)",
-                       (unsigned int) mchk_header->code);
-               reason = buf;
-               break;
-       }
-       wrmces(rdmces());       /* reset machine check pending flag */
-       mb();
-
-       printk(KERN_CRIT "  CIA machine check: %s%s\n",
-              reason, mchk_header->retry ? " (retryable)" : "");
-       printk(KERN_CRIT "   vector=0x%lx la_ptr=0x%lx pc=0x%lx\n",
-              vector, la_ptr, regs->pc);
-
-       /* dump the logout area to give all info: */
-
-       ptr = (unsigned long *)la_ptr;
-       for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
-               printk(KERN_CRIT " +%8lx %016lx %016lx\n",
-                      i*sizeof(long), ptr[i], ptr[i+1]);
-       }
-}
diff --git a/arch/alpha/kernel/core_apecs.c b/arch/alpha/kernel/core_apecs.c
new file mode 100644 (file)
index 0000000..d2633be
--- /dev/null
@@ -0,0 +1,542 @@
+/*
+ *     linux/arch/alpha/kernel/core_apecs.c
+ *
+ * Code common to all APECS core logic chips.
+ *
+ * Rewritten for Apecs from the lca.c from:
+ *
+ * Written by David Mosberger (davidm@cs.arizona.edu) with some code
+ * taken from Dave Rusling's (david.rusling@reo.mts.dec.com) 32-bit
+ * bios code.
+ */
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/ptrace.h>
+
+#define __EXTERN_INLINE inline
+#include <asm/io.h>
+#include <asm/core_apecs.h>
+#undef __EXTERN_INLINE
+
+#include "proto.h"
+
+/*
+ * NOTE: Herein lie back-to-back mb instructions.  They are magic. 
+ * One plausible explanation is that the i/o controller does not properly
+ * handle the system transaction.  Another involves timing.  Ho hum.
+ */
+
+/*
+ * BIOS32-style PCI interface:
+ */
+
+#ifdef DEBUG
+# define DBG(args)     printk args
+#else
+# define DBG(args)
+#endif
+
+#define vuip   volatile unsigned int  *
+
+volatile unsigned int apecs_mcheck_expected = 0;
+volatile unsigned int apecs_mcheck_taken = 0;
+static unsigned int apecs_jd, apecs_jd1, apecs_jd2;
+
+
+/*
+ * Given a bus, device, and function number, compute resulting
+ * configuration space address and setup the APECS_HAXR2 register
+ * accordingly.  It is therefore not safe to have concurrent
+ * invocations to configuration space access routines, but there
+ * really shouldn't be any need for this.
+ *
+ * Type 0:
+ *
+ *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | | | | | | | | | | | | | | | | | | | | | | |F|F|F|R|R|R|R|R|R|0|0|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *     31:11   Device select bit.
+ *     10:8    Function number
+ *      7:2    Register number
+ *
+ * Type 1:
+ *
+ *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *     31:24   reserved
+ *     23:16   bus number (8 bits = 128 possible buses)
+ *     15:11   Device number (5 bits)
+ *     10:8    function number
+ *      7:2    register number
+ *  
+ * Notes:
+ *     The function number selects which function of a multi-function device 
+ *     (e.g., SCSI and Ethernet).
+ * 
+ *     The register selects a DWORD (32 bit) register offset.  Hence it
+ *     doesn't get shifted by 2 bits as we want to "drop" the bottom two
+ *     bits.
+ */
+
+static int
+mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr,
+            unsigned char *type1)
+{
+       unsigned long addr;
+
+       DBG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
+            " pci_addr=0x%p, type1=0x%p)\n",
+            bus, device_fn, where, pci_addr, type1));
+
+       if (bus == 0) {
+               int device = device_fn >> 3;
+
+               /* type 0 configuration cycle: */
+
+               if (device > 20) {
+                       DBG(("mk_conf_addr: device (%d) > 20, returning -1\n",
+                            device));
+                       return -1;
+               }
+
+               *type1 = 0;
+               addr = (device_fn << 8) | (where);
+       } else {
+               /* type 1 configuration cycle: */
+               *type1 = 1;
+               addr = (bus << 16) | (device_fn << 8) | (where);
+       }
+       *pci_addr = addr;
+       DBG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
+       return 0;
+}
+
+static unsigned int
+conf_read(unsigned long addr, unsigned char type1)
+{
+       unsigned long flags;
+       unsigned int stat0, value;
+       unsigned int haxr2 = 0;
+
+       save_flags(flags);      /* avoid getting hit by machine check */
+       cli();
+
+       DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
+
+       /* Reset status register to avoid losing errors.  */
+       stat0 = *(vuip)APECS_IOC_DCSR;
+       *(vuip)APECS_IOC_DCSR = stat0;
+       mb();
+       DBG(("conf_read: APECS DCSR was 0x%x\n", stat0));
+
+       /* If Type1 access, must set HAE #2. */
+       if (type1) {
+               haxr2 = *(vuip)APECS_IOC_HAXR2;
+               mb();
+               *(vuip)APECS_IOC_HAXR2 = haxr2 | 1;
+               DBG(("conf_read: TYPE1 access\n"));
+       }
+
+       draina();
+       apecs_mcheck_expected = 1;
+       apecs_mcheck_taken = 0;
+       mb();
+
+       /* Access configuration space.  */
+
+       /* Some SRMs step on these registers during a machine check.  */
+       asm volatile("ldl %0,%1; mb; mb" : "=r"(value) : "m"(*(vuip)addr)
+                    : "$9", "$10", "$11", "$12", "$13", "$14", "memory");
+
+       if (apecs_mcheck_taken) {
+               apecs_mcheck_taken = 0;
+               value = 0xffffffffU;
+               mb();
+       }
+       apecs_mcheck_expected = 0;
+       mb();
+
+#if 1
+       /*
+        * david.rusling@reo.mts.dec.com.  This code is needed for the
+        * EB64+ as it does not generate a machine check (why I don't
+        * know).  When we build kernels for one particular platform
+        * then we can make this conditional on the type.
+        */
+       draina();
+
+       /* Now look for any errors.  */
+       stat0 = *(vuip)APECS_IOC_DCSR;
+       DBG(("conf_read: APECS DCSR after read 0x%x\n", stat0));
+
+       /* Is any error bit set? */
+       if (stat0 & 0xffe0U) {
+               /* If not NDEV, print status.  */
+               if (!(stat0 & 0x0800)) {
+                       printk("apecs.c:conf_read: got stat0=%x\n", stat0);
+               }
+
+               /* Reset error status.  */
+               *(vuip)APECS_IOC_DCSR = stat0;
+               mb();
+               wrmces(0x7);                    /* reset machine check */
+               value = 0xffffffff;
+       }
+#endif
+
+       /* If Type1 access, must reset HAE #2 so normal IO space ops work.  */
+       if (type1) {
+               *(vuip)APECS_IOC_HAXR2 = haxr2 & ~1;
+               mb();
+       }
+       restore_flags(flags);
+
+       return value;
+}
+
+static void
+conf_write(unsigned long addr, unsigned int value, unsigned char type1)
+{
+       unsigned long flags;
+       unsigned int stat0;
+       unsigned int haxr2 = 0;
+
+       save_flags(flags);      /* avoid getting hit by machine check */
+       cli();
+
+       /* Reset status register to avoid losing errors.  */
+       stat0 = *(vuip)APECS_IOC_DCSR;
+       *(vuip)APECS_IOC_DCSR = stat0;
+       mb();
+
+       /* If Type1 access, must set HAE #2. */
+       if (type1) {
+               haxr2 = *(vuip)APECS_IOC_HAXR2;
+               mb();
+               *(vuip)APECS_IOC_HAXR2 = haxr2 | 1;
+       }
+
+       draina();
+       apecs_mcheck_expected = 1;
+       mb();
+
+       /* Access configuration space.  */
+       *(vuip)addr = value;
+       mb();
+       mb();  /* magic */
+       apecs_mcheck_expected = 0;
+       mb();
+
+#if 1
+       /*
+        * david.rusling@reo.mts.dec.com.  This code is needed for the
+        * EB64+ as it does not generate a machine check (why I don't
+        * know).  When we build kernels for one particular platform
+        * then we can make this conditional on the type.
+        */
+       draina();
+
+       /* Now look for any errors.  */
+       stat0 = *(vuip)APECS_IOC_DCSR;
+
+       /* Is any error bit set? */
+       if (stat0 & 0xffe0U) {
+               /* If not NDEV, print status.  */
+               if (!(stat0 & 0x0800)) {
+                       printk("apecs.c:conf_write: got stat0=%x\n", stat0);
+               }
+
+               /* Reset error status.  */
+               *(vuip)APECS_IOC_DCSR = stat0;
+               mb();
+               wrmces(0x7);                    /* reset machine check */
+       }
+#endif
+
+       /* If Type1 access, must reset HAE #2 so normal IO space ops work.  */
+       if (type1) {
+               *(vuip)APECS_IOC_HAXR2 = haxr2 & ~1;
+               mb();
+       }
+       restore_flags(flags);
+}
+
+int
+apecs_pcibios_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value)
+{
+       unsigned long addr = APECS_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       *value = 0xff;
+
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x00;
+
+       *value = conf_read(addr, type1) >> ((where & 3) * 8);
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+apecs_pcibios_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value)
+{
+       unsigned long addr = APECS_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       *value = 0xffff;
+
+       if (where & 0x1)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x08;
+
+       *value = conf_read(addr, type1) >> ((where & 3) * 8);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int
+apecs_pcibios_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value)
+{
+       unsigned long addr = APECS_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       *value = 0xffffffff;
+       if (where & 0x3)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x18;
+       *value = conf_read(addr, type1);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int
+apecs_pcibios_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value)
+{
+       unsigned long addr = APECS_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x00;
+       conf_write(addr, value << ((where & 3) * 8), type1);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+apecs_pcibios_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value)
+{
+       unsigned long addr = APECS_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x08;
+       conf_write(addr, value << ((where & 3) * 8), type1);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+apecs_pcibios_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value)
+{
+       unsigned long addr = APECS_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x18;
+       conf_write(addr, value << ((where & 3) * 8), type1);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+void __init
+apecs_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+{
+       switch (alpha_use_srm_setup)
+       {
+       default:
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
+               /* Check window 1 for enabled and mapped to 0. */
+               if ((*(vuip)APECS_IOC_PB1R & (1U<<19))
+                   && (*(vuip)APECS_IOC_TB1R == 0)) {
+                       APECS_DMA_WIN_BASE = *(vuip)APECS_IOC_PB1R & 0xfff00000U;
+                       APECS_DMA_WIN_SIZE = *(vuip)APECS_IOC_PM1R & 0xfff00000U;
+                       APECS_DMA_WIN_SIZE += 0x00100000U;
+#if 1
+                       printk("apecs_init: using Window 1 settings\n");
+                       printk("apecs_init: PB1R 0x%x PM1R 0x%x TB1R 0x%x\n",
+                              *(vuip)APECS_IOC_PB1R,
+                              *(vuip)APECS_IOC_PM1R,
+                              *(vuip)APECS_IOC_TB1R);
+#endif
+                       break;
+               }
+
+               /* Check window 2 for enabled and mapped to 0.  */
+               if ((*(vuip)APECS_IOC_PB2R & (1U<<19))
+                   && (*(vuip)APECS_IOC_TB2R == 0)) {
+                       APECS_DMA_WIN_BASE = *(vuip)APECS_IOC_PB2R & 0xfff00000U;
+                       APECS_DMA_WIN_SIZE = *(vuip)APECS_IOC_PM2R & 0xfff00000U;
+                       APECS_DMA_WIN_SIZE += 0x00100000U;
+#if 1
+                       printk("apecs_init: using Window 2 settings\n");
+                       printk("apecs_init: PB2R 0x%x PM2R 0x%x TB2R 0x%x\n",
+                              *(vuip)APECS_IOC_PB2R,
+                              *(vuip)APECS_IOC_PM2R,
+                              *(vuip)APECS_IOC_TB2R);
+#endif
+                       break;
+               }
+               
+               /* Otherwise, we must use our defaults.  */
+               APECS_DMA_WIN_BASE = APECS_DMA_WIN_BASE_DEFAULT;
+               APECS_DMA_WIN_SIZE = APECS_DMA_WIN_SIZE_DEFAULT;
+#endif
+       case 0:
+               /*
+                * Set up the PCI->physical memory translation windows.
+                * For now, window 2 is disabled.  In the future, we may
+                * want to use it to do scatter/gather DMA.  Window 1
+                * goes at 1 GB and is 1 GB large.
+                */
+               *(vuip)APECS_IOC_PB2R  = 0U; /* disable window 2 */
+
+               *(vuip)APECS_IOC_PB1R  = 1U<<19 | (APECS_DMA_WIN_BASE_DEFAULT & 0xfff00000U);
+               *(vuip)APECS_IOC_PM1R  = (APECS_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000U;
+               *(vuip)APECS_IOC_TB1R  = 0;
+               break;
+       }
+
+       /*
+        * Finally, clear the HAXR2 register, which gets used
+        * for PCI Config Space accesses. That is the way
+        * we want to use it, and we do not want to depend on
+        * what ARC or SRM might have left behind...
+        */
+       *(vuip)APECS_IOC_HAXR2 = 0; mb();
+}
+
+int
+apecs_pci_clr_err(void)
+{
+       apecs_jd = *(vuip)APECS_IOC_DCSR;
+       if (apecs_jd & 0xffe0L) {
+               apecs_jd1 = *(vuip)APECS_IOC_SEAR;
+               *(vuip)APECS_IOC_DCSR = apecs_jd | 0xffe1L;
+               apecs_jd = *(vuip)APECS_IOC_DCSR;
+               mb();
+       }
+       *(vuip)APECS_IOC_TBIA = (unsigned int)APECS_IOC_TBIA;
+       apecs_jd2 = *(vuip)APECS_IOC_TBIA;
+       mb();
+       return 0;
+}
+
+void
+apecs_machine_check(unsigned long vector, unsigned long la_ptr,
+                   struct pt_regs * regs)
+{
+       struct el_common *mchk_header;
+       struct el_apecs_procdata *mchk_procdata;
+       struct el_apecs_sysdata_mcheck *mchk_sysdata;
+       unsigned long *ptr;
+       int i;
+
+       mchk_header = (struct el_common *)la_ptr;
+
+       mchk_procdata = (struct el_apecs_procdata *)
+               (la_ptr + mchk_header->proc_offset
+                - sizeof(mchk_procdata->paltemp));
+
+       mchk_sysdata = (struct el_apecs_sysdata_mcheck *)
+               (la_ptr + mchk_header->sys_offset);
+
+#ifdef DEBUG
+       printk("apecs_machine_check: vector=0x%lx la_ptr=0x%lx\n",
+              vector, la_ptr);
+       printk("        pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
+              regs->pc, mchk_header->size, mchk_header->proc_offset,
+              mchk_header->sys_offset);
+       printk("apecs_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
+              apecs_mcheck_expected, mchk_sysdata->epic_dcsr,
+              mchk_sysdata->epic_pear);
+       ptr = (unsigned long *)la_ptr;
+       for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
+               printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
+       }
+#endif
+
+       /*
+        * Check if machine check is due to a badaddr() and if so,
+        * ignore the machine check.
+        */
+
+       if (apecs_mcheck_expected
+           && (mchk_sysdata->epic_dcsr & 0x0c00UL)) {
+               apecs_mcheck_expected = 0;
+               apecs_mcheck_taken = 1;
+               mb();
+               mb(); /* magic */
+               apecs_pci_clr_err();
+               wrmces(0x7);
+               mb();
+               draina();
+               DBG(("apecs_machine_check: EXPECTED\n"));
+       }
+       else if (vector == 0x620 || vector == 0x630) {
+               /* Disable correctable from now on.  */
+               wrmces(0x1f);
+               mb();
+               draina();
+               printk("apecs_machine_check: HW correctable (0x%lx)\n",
+                      vector);
+       }
+       else {
+               printk(KERN_CRIT "APECS machine check:\n");
+               printk(KERN_CRIT "  vector=0x%lx la_ptr=0x%lx\n",
+                      vector, la_ptr);
+               printk(KERN_CRIT
+                      "  pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
+                      regs->pc, mchk_header->size, mchk_header->proc_offset,
+                      mchk_header->sys_offset);
+               printk(KERN_CRIT "  expected %d DCSR 0x%lx PEAR 0x%lx\n",
+                      apecs_mcheck_expected, mchk_sysdata->epic_dcsr,
+                      mchk_sysdata->epic_pear);
+
+               ptr = (unsigned long *)la_ptr;
+               for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
+                       printk(KERN_CRIT " +%lx %lx %lx\n",
+                              i*sizeof(long), ptr[i], ptr[i+1]);
+               }
+#if 0
+               /* doesn't work with MILO */
+               show_regs(regs);
+#endif
+       }
+}
diff --git a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c
new file mode 100644 (file)
index 0000000..9f290bf
--- /dev/null
@@ -0,0 +1,727 @@
+/*
+ *     linux/arch/alpha/kernel/core_cia.c
+ *
+ * Code common to all CIA core logic chips.
+ *
+ * Written by David A Rusling (david.rusling@reo.mts.dec.com).
+ * December 1995.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/ptrace.h>
+
+#define __EXTERN_INLINE inline
+#include <asm/io.h>
+#include <asm/core_cia.h>
+#undef __EXTERN_INLINE
+
+#include "proto.h"
+
+/*
+ * NOTE: Herein lie back-to-back mb instructions.  They are magic. 
+ * One plausible explanation is that the i/o controller does not properly
+ * handle the system transaction.  Another involves timing.  Ho hum.
+ */
+
+extern asmlinkage void wrmces(unsigned long mces);
+
+/*
+ * Machine check reasons.  Defined according to PALcode sources
+ * (osf.h and platform.h).
+ */
+#define MCHK_K_TPERR           0x0080
+#define MCHK_K_TCPERR          0x0082
+#define MCHK_K_HERR            0x0084
+#define MCHK_K_ECC_C           0x0086
+#define MCHK_K_ECC_NC          0x0088
+#define MCHK_K_OS_BUGCHECK     0x008A
+#define MCHK_K_PAL_BUGCHECK    0x0090
+
+/*
+ * BIOS32-style PCI interface:
+ */
+
+#define DEBUG_MCHECK 0
+#define DEBUG_CONFIG 0
+/* #define DEBUG_DUMP_REGS */
+
+#if DEBUG_MCHECK
+# define DBGM(args)    printk args
+#else
+# define DBGM(args)
+#endif
+#if DEBUG_CONFIG
+# define DBGC(args)    printk args
+#else
+# define DBGC(args)
+#endif
+
+#define vuip   volatile unsigned int  *
+
+static volatile unsigned int CIA_mcheck_expected = 0;
+static volatile unsigned int CIA_mcheck_taken = 0;
+static unsigned int CIA_jd;
+
+
+/*
+ * Given a bus, device, and function number, compute resulting
+ * configuration space address and setup the CIA_HAXR2 register
+ * accordingly.  It is therefore not safe to have concurrent
+ * invocations to configuration space access routines, but there
+ * really shouldn't be any need for this.
+ *
+ * Type 0:
+ *
+ *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *     31:11   Device select bit.
+ *     10:8    Function number
+ *      7:2    Register number
+ *
+ * Type 1:
+ *
+ *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *     31:24   reserved
+ *     23:16   bus number (8 bits = 128 possible buses)
+ *     15:11   Device number (5 bits)
+ *     10:8    function number
+ *      7:2    register number
+ *  
+ * Notes:
+ *     The function number selects which function of a multi-function device 
+ *     (e.g., SCSI and Ethernet).
+ * 
+ *     The register selects a DWORD (32 bit) register offset.  Hence it
+ *     doesn't get shifted by 2 bits as we want to "drop" the bottom two
+ *     bits.
+ */
+
+static int
+mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr,
+            unsigned char *type1)
+{
+       unsigned long addr;
+
+       DBGC(("mk_conf_addr(bus=%d, device_fn=0x%x, where=0x%x, "
+             "pci_addr=0x%p, type1=0x%p)\n",
+             bus, device_fn, where, pci_addr, type1));
+
+       if (bus == 0) {
+               int device = device_fn >> 3;
+
+               /* Type 0 configuration cycle.  */
+
+               if (device > 20) {
+                       DBGC(("mk_conf_addr: device (%d) > 20, returning -1\n",
+                             device));
+                       return -1;
+               }
+
+               *type1 = 0;
+               addr = (device_fn << 8) | (where);
+       } else {
+               /* Type 1 configuration cycle.  */
+               *type1 = 1;
+               addr = (bus << 16) | (device_fn << 8) | (where);
+       }
+       *pci_addr = addr;
+       DBGC(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
+       return 0;
+}
+
+static unsigned int
+conf_read(unsigned long addr, unsigned char type1)
+{
+       unsigned long flags;
+       unsigned int stat0, value;
+       unsigned int cia_cfg = 0;
+
+       value = 0xffffffffU;
+       mb();
+
+       save_flags(flags);      /* avoid getting hit by machine check */
+       cli();
+
+       DBGC(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
+
+       /* Reset status register to avoid losing errors.  */
+       stat0 = *(vuip)CIA_IOC_CIA_ERR;
+       *(vuip)CIA_IOC_CIA_ERR = stat0;
+       mb();
+       DBGC(("conf_read: CIA ERR was 0x%x\n", stat0));
+
+       /* If Type1 access, must set CIA CFG. */
+       if (type1) {
+               cia_cfg = *(vuip)CIA_IOC_CFG;
+               *(vuip)CIA_IOC_CFG = cia_cfg | 1;
+               mb();
+               DBGC(("conf_read: TYPE1 access\n"));
+       }
+
+       mb();
+       draina();
+       CIA_mcheck_expected = 1;
+       CIA_mcheck_taken = 0;
+       mb();
+
+       /* Access configuration space.  */
+       value = *(vuip)addr;
+       mb();
+       mb();  /* magic */
+       if (CIA_mcheck_taken) {
+               CIA_mcheck_taken = 0;
+               value = 0xffffffffU;
+               mb();
+       }
+       CIA_mcheck_expected = 0;
+       mb();
+
+#if 0
+       /* This code might be necessary if machine checks aren't taken,
+          but I can't get it to work on CIA-2, so its disabled. */
+       draina();
+
+       /* Now look for any errors.  */
+       stat0 = *(vuip)CIA_IOC_CIA_ERR;
+       DBGC(("conf_read: CIA ERR after read 0x%x\n", stat0));
+
+       /* Is any error bit set? */
+       if (stat0 & 0x8FEF0FFFU) {
+               /* If not MAS_ABT, print status. */
+               if (!(stat0 & 0x0080)) {
+                       printk("CIA.c:conf_read: got stat0=%x\n", stat0);
+               }
+
+               /* reset error status: */
+               *(vuip)CIA_IOC_CIA_ERR = stat0;
+               mb();
+               wrmces(0x7);                    /* reset machine check */
+               value = 0xffffffff;
+       }
+#endif
+
+       /* If Type1 access, must reset IOC CFG so normal IO space ops work.  */
+       if (type1) {
+               *(vuip)CIA_IOC_CFG = cia_cfg & ~1;
+               mb();
+       }
+
+       DBGC(("conf_read(): finished\n"));
+
+       restore_flags(flags);
+       return value;
+}
+
+static void
+conf_write(unsigned long addr, unsigned int value, unsigned char type1)
+{
+       unsigned long flags;
+       unsigned int stat0;
+       unsigned int cia_cfg = 0;
+
+       save_flags(flags);      /* avoid getting hit by machine check */
+       cli();
+
+       /* Reset status register to avoid losing errors.  */
+       stat0 = *(vuip)CIA_IOC_CIA_ERR;
+       *(vuip)CIA_IOC_CIA_ERR = stat0;
+       mb();
+       DBGC(("conf_write: CIA ERR was 0x%x\n", stat0));
+
+       /* If Type1 access, must set CIA CFG.  */
+       if (type1) {
+               cia_cfg = *(vuip)CIA_IOC_CFG;
+               *(vuip)CIA_IOC_CFG = cia_cfg | 1;
+               mb();
+               DBGC(("conf_write: TYPE1 access\n"));
+       }
+
+       draina();
+       CIA_mcheck_expected = 1;
+       mb();
+
+       /* Access configuration space.  */
+       *(vuip)addr = value;
+       mb();
+       mb();  /* magic */
+
+       CIA_mcheck_expected = 0;
+       mb();
+
+#if 0
+       /* This code might be necessary if machine checks aren't taken,
+          but I can't get it to work on CIA-2, so its disabled. */
+       draina();
+
+       /* Now look for any errors */
+       stat0 = *(vuip)CIA_IOC_CIA_ERR;
+       DBGC(("conf_write: CIA ERR after write 0x%x\n", stat0));
+
+       /* Is any error bit set? */
+       if (stat0 & 0x8FEF0FFFU) {
+               /* If not MAS_ABT, print status */
+               if (!(stat0 & 0x0080)) {
+                       printk("CIA.c:conf_read: got stat0=%x\n", stat0);
+               }
+
+               /* Reset error status.  */
+               *(vuip)CIA_IOC_CIA_ERR = stat0;
+               mb();
+               wrmces(0x7);                    /* reset machine check */
+               value = 0xffffffff;
+       }
+#endif
+
+       /* If Type1 access, must reset IOC CFG so normal IO space ops work.  */
+       if (type1) {
+               *(vuip)CIA_IOC_CFG = cia_cfg & ~1;
+               mb();
+       }
+
+       DBGC(("conf_write(): finished\n"));
+       restore_flags(flags);
+}
+
+int
+cia_pcibios_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value)
+{
+       unsigned long addr = CIA_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       *value = 0xff;
+
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x00;
+       *value = conf_read(addr, type1) >> ((where & 3) * 8);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+cia_pcibios_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value)
+{
+       unsigned long addr = CIA_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       *value = 0xffff;
+
+       if (where & 0x1)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x08;
+       *value = conf_read(addr, type1) >> ((where & 3) * 8);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+cia_pcibios_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value)
+{
+       unsigned long addr = CIA_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       *value = 0xffffffff;
+       if (where & 0x3)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x18;
+       *value = conf_read(addr, type1);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+cia_pcibios_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value)
+{
+       unsigned long addr = CIA_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x00;
+       conf_write(addr, value << ((where & 3) * 8), type1);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+cia_pcibios_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value)
+{
+       unsigned long addr = CIA_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       if (where & 0x1)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x08;
+       conf_write(addr, value << ((where & 3) * 8), type1);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+cia_pcibios_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value)
+{
+       unsigned long addr = CIA_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       if (where & 0x3)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x18;
+       conf_write(addr, value << ((where & 3) * 8), type1);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+void __init
+cia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+{
+        unsigned int cia_tmp;
+
+#ifdef DEBUG_DUMP_REGS
+       {
+               unsigned int temp;
+               temp = *(vuip)CIA_IOC_CIA_REV; mb();
+               printk("cia_init: CIA_REV was 0x%x\n", temp);
+               temp = *(vuip)CIA_IOC_PCI_LAT; mb();
+               printk("cia_init: CIA_PCI_LAT was 0x%x\n", temp);
+               temp = *(vuip)CIA_IOC_CIA_CTRL; mb();
+               printk("cia_init: CIA_CTRL was 0x%x\n", temp);
+               temp = *(vuip)0xfffffc8740000140UL; mb();
+               printk("cia_init: CIA_CTRL1 was 0x%x\n", temp);
+               temp = *(vuip)CIA_IOC_HAE_MEM; mb();
+               printk("cia_init: CIA_HAE_MEM was 0x%x\n", temp);
+               temp = *(vuip)CIA_IOC_HAE_IO; mb();
+               printk("cia_init: CIA_HAE_IO was 0x%x\n", temp);
+               temp = *(vuip)CIA_IOC_CFG; mb();
+               printk("cia_init: CIA_CFG was 0x%x\n", temp);
+               temp = *(vuip)CIA_IOC_CACK_EN; mb();
+               printk("cia_init: CIA_CACK_EN was 0x%x\n", temp);
+               temp = *(vuip)CIA_IOC_CFG; mb();
+               printk("cia_init: CIA_CFG was 0x%x\n", temp);
+               temp = *(vuip)CIA_IOC_CIA_DIAG; mb();
+               printk("cia_init: CIA_DIAG was 0x%x\n", temp);
+               temp = *(vuip)CIA_IOC_DIAG_CHECK; mb();
+               printk("cia_init: CIA_DIAG_CHECK was 0x%x\n", temp);
+               temp = *(vuip)CIA_IOC_PERF_MONITOR; mb();
+               printk("cia_init: CIA_PERF_MONITOR was 0x%x\n", temp);
+               temp = *(vuip)CIA_IOC_PERF_CONTROL; mb();
+               printk("cia_init: CIA_PERF_CONTROL was 0x%x\n", temp);
+               temp = *(vuip)CIA_IOC_CIA_ERR; mb();
+               printk("cia_init: CIA_ERR was 0x%x\n", temp);
+               temp = *(vuip)CIA_IOC_CIA_STAT; mb();
+               printk("cia_init: CIA_STAT was 0x%x\n", temp);
+               temp = *(vuip)CIA_IOC_MCR; mb();
+               printk("cia_init: CIA_MCR was 0x%x\n", temp);
+               temp = *(vuip)CIA_IOC_CIA_CTRL; mb();
+               printk("cia_init: CIA_CTRL was 0x%x\n", temp);
+               temp = *(vuip)CIA_IOC_ERR_MASK; mb();
+               printk("cia_init: CIA_ERR_MASK was 0x%x\n", temp);
+               temp = *((vuip)CIA_IOC_PCI_W0_BASE); mb();
+               printk("cia_init: W0_BASE was 0x%x\n", temp);
+               temp = *((vuip)CIA_IOC_PCI_W1_BASE); mb();
+               printk("cia_init: W1_BASE was 0x%x\n", temp);
+               temp = *((vuip)CIA_IOC_PCI_W2_BASE); mb();
+               printk("cia_init: W2_BASE was 0x%x\n", temp);
+               temp = *((vuip)CIA_IOC_PCI_W3_BASE); mb();
+               printk("cia_init: W3_BASE was 0x%x\n", temp);
+       }
+#endif /* DEBUG_DUMP_REGS */
+
+        /* 
+        * Set up error reporting.
+        */
+       cia_tmp = *(vuip)CIA_IOC_CIA_ERR;
+       cia_tmp |= 0x180;   /* master, target abort */
+       *(vuip)CIA_IOC_CIA_ERR = cia_tmp;
+       mb();
+
+       cia_tmp = *(vuip)CIA_IOC_CIA_CTRL;
+       cia_tmp |= 0x400;       /* turn on FILL_ERR to get mchecks */
+       *(vuip)CIA_IOC_CIA_CTRL = cia_tmp;
+       mb();
+
+       switch (alpha_use_srm_setup)
+       {
+       default:
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
+               /* Check window 0 for enabled and mapped to 0 */
+               if (((*(vuip)CIA_IOC_PCI_W0_BASE & 3) == 1)
+                   && (*(vuip)CIA_IOC_PCI_T0_BASE == 0)) {
+                       CIA_DMA_WIN_BASE = *(vuip)CIA_IOC_PCI_W0_BASE & 0xfff00000U;
+                       CIA_DMA_WIN_SIZE = *(vuip)CIA_IOC_PCI_W0_MASK & 0xfff00000U;
+                       CIA_DMA_WIN_SIZE += 0x00100000U;
+#if 1
+                       printk("cia_init: using Window 0 settings\n");
+                       printk("cia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
+                              *(vuip)CIA_IOC_PCI_W0_BASE,
+                              *(vuip)CIA_IOC_PCI_W0_MASK,
+                              *(vuip)CIA_IOC_PCI_T0_BASE);
+#endif
+                       break;
+               }
+
+               /* Check window 1 for enabled and mapped to 0.  */
+               if (((*(vuip)CIA_IOC_PCI_W1_BASE & 3) == 1)
+                   && (*(vuip)CIA_IOC_PCI_T1_BASE == 0)) {
+                       CIA_DMA_WIN_BASE = *(vuip)CIA_IOC_PCI_W1_BASE & 0xfff00000U;
+                       CIA_DMA_WIN_SIZE = *(vuip)CIA_IOC_PCI_W1_MASK & 0xfff00000U;
+                       CIA_DMA_WIN_SIZE += 0x00100000U;
+#if 1
+                       printk("cia_init: using Window 1 settings\n");
+                       printk("cia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
+                              *(vuip)CIA_IOC_PCI_W1_BASE,
+                              *(vuip)CIA_IOC_PCI_W1_MASK,
+                              *(vuip)CIA_IOC_PCI_T1_BASE);
+#endif
+                       break;
+               }
+
+               /* Check window 2 for enabled and mapped to 0.  */
+               if (((*(vuip)CIA_IOC_PCI_W2_BASE & 3) == 1)
+                   && (*(vuip)CIA_IOC_PCI_T2_BASE == 0)) {
+                       CIA_DMA_WIN_BASE = *(vuip)CIA_IOC_PCI_W2_BASE & 0xfff00000U;
+                       CIA_DMA_WIN_SIZE = *(vuip)CIA_IOC_PCI_W2_MASK & 0xfff00000U;
+                       CIA_DMA_WIN_SIZE += 0x00100000U;
+#if 1
+                       printk("cia_init: using Window 2 settings\n");
+                       printk("cia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
+                              *(vuip)CIA_IOC_PCI_W2_BASE,
+                              *(vuip)CIA_IOC_PCI_W2_MASK,
+                              *(vuip)CIA_IOC_PCI_T2_BASE);
+#endif
+                       break;
+               }
+
+               /* Check window 3 for enabled and mapped to 0.  */
+               if (((*(vuip)CIA_IOC_PCI_W3_BASE & 3) == 1)
+                   && (*(vuip)CIA_IOC_PCI_T3_BASE == 0)) {
+                       CIA_DMA_WIN_BASE = *(vuip)CIA_IOC_PCI_W3_BASE & 0xfff00000U;
+                       CIA_DMA_WIN_SIZE = *(vuip)CIA_IOC_PCI_W3_MASK & 0xfff00000U;
+                       CIA_DMA_WIN_SIZE += 0x00100000U;
+#if 1
+                       printk("cia_init: using Window 3 settings\n");
+                       printk("cia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
+                              *(vuip)CIA_IOC_PCI_W3_BASE,
+                              *(vuip)CIA_IOC_PCI_W3_MASK,
+                              *(vuip)CIA_IOC_PCI_T3_BASE);
+#endif
+                       break;
+               }
+
+               /* Otherwise, we must use our defaults.  */
+               CIA_DMA_WIN_BASE = CIA_DMA_WIN_BASE_DEFAULT;
+               CIA_DMA_WIN_SIZE = CIA_DMA_WIN_SIZE_DEFAULT;
+#endif
+       case 0:
+               /*
+                * Set up the PCI->physical memory translation windows.
+                * For now, windows 1,2 and 3 are disabled.  In the future,
+                * we may want to use them to do scatter/gather DMA. 
+                *
+                * Window 0 goes at 1 GB and is 1 GB large.
+                */
+
+               *(vuip)CIA_IOC_PCI_W0_BASE = 1U | (CIA_DMA_WIN_BASE_DEFAULT & 0xfff00000U);
+               *(vuip)CIA_IOC_PCI_W0_MASK = (CIA_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000U;
+               *(vuip)CIA_IOC_PCI_T0_BASE = 0;
+
+               *(vuip)CIA_IOC_PCI_W1_BASE = 0x0;
+               *(vuip)CIA_IOC_PCI_W2_BASE = 0x0;
+               *(vuip)CIA_IOC_PCI_W3_BASE = 0x0;
+               break;
+       }
+
+        /*
+         * Next, clear the CIA_CFG register, which gets used
+         * for PCI Config Space accesses. That is the way
+         * we want to use it, and we do not want to depend on
+         * what ARC or SRM might have left behind...
+         */
+       *((vuip)CIA_IOC_CFG) = 0; mb();
+
+       /*
+        * Sigh... For the SRM setup, unless we know apriori what the HAE
+        * contents will be, we need to setup the arbitrary region bases
+        * so we can test against the range of addresses and tailor the
+        * region chosen for the SPARSE memory access.
+        *
+        * See include/asm-alpha/cia.h for the SPARSE mem read/write.
+        */
+       if (alpha_use_srm_setup) {
+               unsigned int cia_hae_mem = *((vuip)CIA_IOC_HAE_MEM);
+
+               alpha_mv.sm_base_r1 = (cia_hae_mem      ) & 0xe0000000UL;
+               alpha_mv.sm_base_r2 = (cia_hae_mem << 16) & 0xf8000000UL;
+               alpha_mv.sm_base_r3 = (cia_hae_mem << 24) & 0xfc000000UL;
+
+               /*
+                * Set the HAE cache, so that setup_arch() code
+                * will use the SRM setting always. Our readb/writeb
+                * code in cia.h expects never to have to change
+                * the contents of the HAE.
+                */
+               alpha_mv.hae_cache = cia_hae_mem;
+
+               alpha_mv.mv_readb = cia_srm_readb;
+               alpha_mv.mv_readw = cia_srm_readw;
+               alpha_mv.mv_writeb = cia_srm_writeb;
+               alpha_mv.mv_writew = cia_srm_writew;
+       } else {
+               *((vuip)CIA_IOC_HAE_MEM) = 0; mb();
+               *((vuip)CIA_IOC_HAE_MEM); /* read it back. */
+               *((vuip)CIA_IOC_HAE_IO) = 0; mb();
+               *((vuip)CIA_IOC_HAE_IO);  /* read it back. */
+        }
+}
+
+static int
+cia_pci_clr_err(void)
+{
+       CIA_jd = *(vuip)CIA_IOC_CIA_ERR;
+       DBGM(("CIA_pci_clr_err: CIA ERR after read 0x%x\n", CIA_jd));
+       *(vuip)CIA_IOC_CIA_ERR = 0x0180;
+       mb();
+       return 0;
+}
+
+void
+cia_machine_check(unsigned long vector, unsigned long la_ptr,
+                 struct pt_regs * regs)
+{
+       struct el_common *mchk_header;
+       struct el_CIA_procdata *mchk_procdata;
+       struct el_CIA_sysdata_mcheck *mchk_sysdata;
+       unsigned long * ptr;
+       const char * reason;
+       char buf[128];
+       long i;
+
+       mchk_header = (struct el_common *)la_ptr;
+
+       mchk_procdata = (struct el_CIA_procdata *)
+               (la_ptr + mchk_header->proc_offset);
+
+       mchk_sysdata = (struct el_CIA_sysdata_mcheck *)
+               (la_ptr + mchk_header->sys_offset);
+
+       DBGM(("cia_machine_check: vector=0x%lx la_ptr=0x%lx\n",
+             vector, la_ptr));
+       DBGM(("                     pc=0x%lx size=0x%x procoffset=0x%x "
+             "sysoffset 0x%x\n", regs->pc, mchk_header->size,
+             mchk_header->proc_offset, mchk_header->sys_offset));
+       DBGM(("cia_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
+             CIA_mcheck_expected, mchk_sysdata->epic_dcsr,
+             mchk_sysdata->epic_pear));
+
+#if DEBUG_MCHECK
+       {
+               unsigned long *ptr;
+               int i;
+
+               ptr = (unsigned long *)la_ptr;
+               for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
+                       printk(" +%lx %lx %lx\n", i*sizeof(long),
+                              ptr[i], ptr[i+1]);
+               }
+       }
+#endif
+
+       /*
+        * Check if machine check is due to a badaddr() and if so,
+        * ignore the machine check.
+        */
+       mb();
+       mb();  /* magic */
+       if (CIA_mcheck_expected) {
+               DBGM(("CIA machine check expected\n"));
+               CIA_mcheck_expected = 0;
+               CIA_mcheck_taken = 1;
+               mb();
+               mb();  /* magic */
+               draina();
+               cia_pci_clr_err();
+               wrmces(0x7);
+               mb();
+               return;
+       }
+
+       switch ((unsigned int) mchk_header->code) {
+       case MCHK_K_TPERR:      reason = "tag parity error"; break;
+       case MCHK_K_TCPERR:     reason = "tag control parity error"; break;
+       case MCHK_K_HERR:       reason = "generic hard error"; break;
+       case MCHK_K_ECC_C:      reason = "correctable ECC error"; break;
+       case MCHK_K_ECC_NC:     reason = "uncorrectable ECC error"; break;
+       case MCHK_K_OS_BUGCHECK:        reason = "OS-specific PAL bugcheck"; break;
+       case MCHK_K_PAL_BUGCHECK:       reason = "callsys in kernel mode"; break;
+       case 0x96: reason = "i-cache read retryable error"; break;
+       case 0x98: reason = "processor detected hard error"; break;
+
+               /* System specific (these are for Alcor, at least): */
+       case 0x203: reason = "system detected uncorrectable ECC error"; break;
+       case 0x205: reason = "parity error detected by CIA"; break;
+       case 0x207: reason = "non-existent memory error"; break;
+       case 0x209: reason = "PCI SERR detected"; break;
+       case 0x20b: reason = "PCI data parity error detected"; break;
+       case 0x20d: reason = "PCI address parity error detected"; break;
+       case 0x20f: reason = "PCI master abort error"; break;
+       case 0x211: reason = "PCI target abort error"; break;
+       case 0x213: reason = "scatter/gather PTE invalid error"; break;
+       case 0x215: reason = "flash ROM write error"; break;
+       case 0x217: reason = "IOA timeout detected"; break;
+       case 0x219: reason = "IOCHK#, EISA add-in board parity or other catastrophic error"; break;
+       case 0x21b: reason = "EISA fail-safe timer timeout"; break;
+       case 0x21d: reason = "EISA bus time-out"; break;
+       case 0x21f: reason = "EISA software generated NMI"; break;
+       case 0x221: reason = "unexpected ev5 IRQ[3] interrupt"; break;
+       default:
+               sprintf(buf, "reason for machine-check unknown (0x%x)",
+                       (unsigned int) mchk_header->code);
+               reason = buf;
+               break;
+       }
+       wrmces(rdmces());       /* reset machine check pending flag */
+       mb();
+
+       printk(KERN_CRIT "CIA machine check: %s%s\n",
+              reason, mchk_header->retry ? " (retryable)" : "");
+       printk(KERN_CRIT "   vector=0x%lx la_ptr=0x%lx pc=0x%lx\n",
+              vector, la_ptr, regs->pc);
+
+       /* Dump the logout area to give all info.  */
+
+       ptr = (unsigned long *)la_ptr;
+       for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
+               printk(KERN_CRIT "   +%8lx %016lx %016lx\n",
+                      i*sizeof(long), ptr[i], ptr[i+1]);
+       }
+}
diff --git a/arch/alpha/kernel/core_lca.c b/arch/alpha/kernel/core_lca.c
new file mode 100644 (file)
index 0000000..fe1e779
--- /dev/null
@@ -0,0 +1,570 @@
+/*
+ *     linux/arch/alpha/kernel/core_lca.c
+ *
+ * Code common to all LCA core logic chips.
+ *
+ * Written by David Mosberger (davidm@cs.arizona.edu) with some code
+ * taken from Dave Rusling's (david.rusling@reo.mts.dec.com) 32-bit
+ * bios code.
+ */
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/smp.h>
+
+#define __EXTERN_INLINE inline
+#include <asm/io.h>
+#include <asm/core_lca.h>
+#undef __EXTERN_INLINE
+
+#include "proto.h"
+
+/*
+ * BIOS32-style PCI interface:
+ */
+
+/*
+ * Machine check reasons.  Defined according to PALcode sources
+ * (osf.h and platform.h).
+ */
+#define MCHK_K_TPERR           0x0080
+#define MCHK_K_TCPERR          0x0082
+#define MCHK_K_HERR            0x0084
+#define MCHK_K_ECC_C           0x0086
+#define MCHK_K_ECC_NC          0x0088
+#define MCHK_K_UNKNOWN         0x008A
+#define MCHK_K_CACKSOFT                0x008C
+#define MCHK_K_BUGCHECK                0x008E
+#define MCHK_K_OS_BUGCHECK     0x0090
+#define MCHK_K_DCPERR          0x0092
+#define MCHK_K_ICPERR          0x0094
+
+
+/*
+ * Platform-specific machine-check reasons:
+ */
+#define MCHK_K_SIO_SERR                0x204   /* all platforms so far */
+#define MCHK_K_SIO_IOCHK       0x206   /* all platforms so far */
+#define MCHK_K_DCSR            0x208   /* all but Noname */
+
+
+/*
+ * Given a bus, device, and function number, compute resulting
+ * configuration space address and setup the LCA_IOC_CONF register
+ * accordingly.  It is therefore not safe to have concurrent
+ * invocations to configuration space access routines, but there
+ * really shouldn't be any need for this.
+ *
+ * Type 0:
+ *
+ *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | | | | | | | | | | | | | | | | | | | | | | |F|F|F|R|R|R|R|R|R|0|0|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *     31:11   Device select bit.
+ *     10:8    Function number
+ *      7:2    Register number
+ *
+ * Type 1:
+ *
+ *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *     31:24   reserved
+ *     23:16   bus number (8 bits = 128 possible buses)
+ *     15:11   Device number (5 bits)
+ *     10:8    function number
+ *      7:2    register number
+ *  
+ * Notes:
+ *     The function number selects which function of a multi-function device 
+ *     (e.g., SCSI and Ethernet).
+ * 
+ *     The register selects a DWORD (32 bit) register offset.  Hence it
+ *     doesn't get shifted by 2 bits as we want to "drop" the bottom two
+ *     bits.
+ */
+
+static int
+mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr)
+{
+       unsigned long addr;
+
+       if (bus == 0) {
+               int device = device_fn >> 3;
+               int func = device_fn & 0x7;
+
+               /* Type 0 configuration cycle.  */
+
+               if (device > 12) {
+                       return -1;
+               }
+
+               *(vulp)LCA_IOC_CONF = 0;
+               addr = (1 << (11 + device)) | (func << 8) | where;
+       } else {
+               /* Type 1 configuration cycle.  */
+               *(vulp)LCA_IOC_CONF = 1;
+               addr = (bus << 16) | (device_fn << 8) | where;
+       }
+       *pci_addr = addr;
+       return 0;
+}
+
+static unsigned int
+conf_read(unsigned long addr)
+{
+       unsigned long flags, code, stat0;
+       unsigned int value;
+
+       save_flags(flags);
+       cli();
+
+       /* Reset status register to avoid loosing errors.  */
+       stat0 = *(vulp)LCA_IOC_STAT0;
+       *(vulp)LCA_IOC_STAT0 = stat0;
+       mb();
+
+       /* Access configuration space.  */
+       value = *(vuip)addr;
+       draina();
+
+       stat0 = *(vulp)LCA_IOC_STAT0;
+       if (stat0 & LCA_IOC_STAT0_ERR) {
+               code = ((stat0 >> LCA_IOC_STAT0_CODE_SHIFT)
+                       & LCA_IOC_STAT0_CODE_MASK);
+               if (code != 1) {
+                       printk("lca.c:conf_read: got stat0=%lx\n", stat0);
+               }
+
+               /* Reset error status.  */
+               *(vulp)LCA_IOC_STAT0 = stat0;
+               mb();
+
+               /* Reset machine check.  */
+               wrmces(0x7);
+
+               value = 0xffffffff;
+       }
+       restore_flags(flags);
+       return value;
+}
+
+static void
+conf_write(unsigned long addr, unsigned int value)
+{
+       unsigned long flags, code, stat0;
+
+       save_flags(flags);      /* avoid getting hit by machine check */
+       cli();
+
+       /* Reset status register to avoid loosing errors.  */
+       stat0 = *(vulp)LCA_IOC_STAT0;
+       *(vulp)LCA_IOC_STAT0 = stat0;
+       mb();
+
+       /* Access configuration space.  */
+       *(vuip)addr = value;
+       draina();
+
+       stat0 = *(vulp)LCA_IOC_STAT0;
+       if (stat0 & LCA_IOC_STAT0_ERR) {
+               code = ((stat0 >> LCA_IOC_STAT0_CODE_SHIFT)
+                       & LCA_IOC_STAT0_CODE_MASK);
+               if (code != 1) {
+                       printk("lca.c:conf_write: got stat0=%lx\n", stat0);
+               }
+
+               /* Reset error status.  */
+               *(vulp)LCA_IOC_STAT0 = stat0;
+               mb();
+
+               /* Reset machine check. */
+               wrmces(0x7);
+       }
+       restore_flags(flags);
+}
+
+int
+lca_pcibios_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value)
+{
+       unsigned long addr = LCA_CONF;
+       unsigned long pci_addr;
+
+       *value = 0xff;
+
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x00;
+       *value = conf_read(addr) >> ((where & 3) * 8);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+lca_pcibios_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value)
+{
+       unsigned long addr = LCA_CONF;
+       unsigned long pci_addr;
+
+       *value = 0xffff;
+
+       if (where & 0x1)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x08;
+       *value = conf_read(addr) >> ((where & 3) * 8);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int
+lca_pcibios_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value)
+{
+       unsigned long addr = LCA_CONF;
+       unsigned long pci_addr;
+
+       *value = 0xffffffff;
+       if (where & 0x3)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x18;
+       *value = conf_read(addr);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+lca_pcibios_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value)
+{
+       unsigned long addr = LCA_CONF;
+       unsigned long pci_addr;
+
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x00;
+       conf_write(addr, value << ((where & 3) * 8));
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int
+lca_pcibios_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value)
+{
+       unsigned long addr = LCA_CONF;
+       unsigned long pci_addr;
+
+       if (where & 0x1)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x08;
+       conf_write(addr, value << ((where & 3) * 8));
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+lca_pcibios_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value)
+{
+       unsigned long addr = LCA_CONF;
+       unsigned long pci_addr;
+
+       if (where & 0x3)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x18;
+       conf_write(addr, value << ((where & 3) * 8));
+       return PCIBIOS_SUCCESSFUL;
+}
+
+void __init
+lca_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+{
+       switch (alpha_use_srm_setup)
+       {
+       default:
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
+               /* Check window 0 for enabled and mapped to 0.  */
+               if ((*(vulp)LCA_IOC_W_BASE0 & (1UL<<33))
+                   && (*(vulp)LCA_IOC_T_BASE0 == 0)) {
+                       LCA_DMA_WIN_BASE = *(vulp)LCA_IOC_W_BASE0 & 0xffffffffUL;
+                       LCA_DMA_WIN_SIZE = *(vulp)LCA_IOC_W_MASK0 & 0xffffffffUL;
+                       LCA_DMA_WIN_SIZE += 1;
+#if 0
+                       printk("lca_init: using Window 0 settings\n");
+                       printk("lca_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
+                              *(vulp)LCA_IOC_W_BASE0,
+                              *(vulp)LCA_IOC_W_MASK0,
+                              *(vulp)LCA_IOC_T_BASE0);
+#endif
+                       break;
+               }
+
+               /* Check window 2 for enabled and mapped to 0.  */
+               if ((*(vulp)LCA_IOC_W_BASE1 & (1UL<<33))
+                   && (*(vulp)LCA_IOC_T_BASE1 == 0)) {
+                       LCA_DMA_WIN_BASE = *(vulp)LCA_IOC_W_BASE1 & 0xffffffffUL;
+                       LCA_DMA_WIN_SIZE = *(vulp)LCA_IOC_W_MASK1 & 0xffffffffUL;
+                       LCA_DMA_WIN_SIZE += 1;
+#if 1
+                       printk("lca_init: using Window 1 settings\n");
+                       printk("lca_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
+                              *(vulp)LCA_IOC_W_BASE1,
+                              *(vulp)LCA_IOC_W_MASK1,
+                              *(vulp)LCA_IOC_T_BASE1);
+#endif
+                       break;
+               }
+
+               /* Otherwise, we must use our defaults.  */
+               LCA_DMA_WIN_BASE = LCA_DMA_WIN_BASE_DEFAULT;
+               LCA_DMA_WIN_SIZE = LCA_DMA_WIN_SIZE_DEFAULT;
+#endif
+       case 0:
+               /*
+                * Set up the PCI->physical memory translation windows.
+                * For now, window 1 is disabled.  In the future, we may
+                * want to use it to do scatter/gather DMA. 
+                *
+                * Window 0 goes at 1 GB and is 1 GB large.
+                */
+               *(vulp)LCA_IOC_W_BASE1 = 0UL<<33;
+
+               *(vulp)LCA_IOC_W_BASE0 = 1UL<<33 | LCA_DMA_WIN_BASE_DEFAULT;
+               *(vulp)LCA_IOC_W_MASK0 = LCA_DMA_WIN_SIZE_DEFAULT - 1;
+               *(vulp)LCA_IOC_T_BASE0 = 0;
+               break;
+       }
+
+       /*
+        * Disable PCI parity for now.  The NCR53c810 chip has
+        * troubles meeting the PCI spec which results in
+        * data parity errors.
+        */
+       *(vulp)LCA_IOC_PAR_DIS = 1UL<<5;
+}
+
+/*
+ * Constants used during machine-check handling.  I suppose these
+ * could be moved into lca.h but I don't see much reason why anybody
+ * else would want to use them.
+ */
+
+#define ESR_EAV                (1UL<< 0)       /* error address valid */
+#define ESR_CEE                (1UL<< 1)       /* correctable error */
+#define ESR_UEE                (1UL<< 2)       /* uncorrectable error */
+#define ESR_WRE                (1UL<< 3)       /* write-error */
+#define ESR_SOR                (1UL<< 4)       /* error source */
+#define ESR_CTE                (1UL<< 7)       /* cache-tag error */
+#define ESR_MSE                (1UL<< 9)       /* multiple soft errors */
+#define ESR_MHE                (1UL<<10)       /* multiple hard errors */
+#define ESR_NXM                (1UL<<12)       /* non-existent memory */
+
+#define IOC_ERR                (  1<<4)        /* ioc logs an error */
+#define IOC_CMD_SHIFT  0
+#define IOC_CMD                (0xf<<IOC_CMD_SHIFT)
+#define IOC_CODE_SHIFT 8
+#define IOC_CODE       (0xf<<IOC_CODE_SHIFT)
+#define IOC_LOST       (  1<<5)
+#define IOC_P_NBR      ((__u32) ~((1<<13) - 1))
+
+static void
+mem_error (unsigned long esr, unsigned long ear)
+{
+       printk("    %s %s error to %s occurred at address %x\n",
+              ((esr & ESR_CEE) ? "Correctable" :
+               (esr & ESR_UEE) ? "Uncorrectable" : "A"),
+              (esr & ESR_WRE) ? "write" : "read",
+              (esr & ESR_SOR) ? "memory" : "b-cache",
+              (unsigned) (ear & 0x1ffffff8));
+       if (esr & ESR_CTE) {
+               printk("    A b-cache tag parity error was detected.\n");
+       }
+       if (esr & ESR_MSE) {
+               printk("    Several other correctable errors occurred.\n");
+       }
+       if (esr & ESR_MHE) {
+               printk("    Several other uncorrectable errors occurred.\n");
+       }
+       if (esr & ESR_NXM) {
+               printk("    Attempted to access non-existent memory.\n");
+       }
+}
+
+static void
+ioc_error (__u32 stat0, __u32 stat1)
+{
+       static const char * const pci_cmd[] = {
+               "Interrupt Acknowledge", "Special", "I/O Read", "I/O Write",
+               "Rsvd 1", "Rsvd 2", "Memory Read", "Memory Write", "Rsvd3",
+               "Rsvd4", "Configuration Read", "Configuration Write",
+               "Memory Read Multiple", "Dual Address", "Memory Read Line",
+               "Memory Write and Invalidate"
+       };
+       static const char * const err_name[] = {
+               "exceeded retry limit", "no device", "bad data parity",
+               "target abort", "bad address parity", "page table read error",
+               "invalid page", "data error"
+       };
+       unsigned code = (stat0 & IOC_CODE) >> IOC_CODE_SHIFT;
+       unsigned cmd  = (stat0 & IOC_CMD)  >> IOC_CMD_SHIFT;
+
+       printk("    %s initiated PCI %s cycle to address %x"
+              " failed due to %s.\n",
+              code > 3 ? "PCI" : "CPU", pci_cmd[cmd], stat1, err_name[code]);
+
+       if (code == 5 || code == 6) {
+               printk("    (Error occurred at PCI memory address %x.)\n",
+                      (stat0 & ~IOC_P_NBR));
+       }
+       if (stat0 & IOC_LOST) {
+               printk("    Other PCI errors occurred simultaneously.\n");
+       }
+}
+
+void
+lca_machine_check (unsigned long vector, unsigned long la,
+                  struct pt_regs *regs)
+{
+       unsigned long * ptr;
+       const char * reason;
+       union el_lca el;
+       char buf[128];
+       long i;
+
+       printk(KERN_CRIT "lca: machine check (la=0x%lx,pc=0x%lx)\n",
+              la, regs->pc);
+       el.c = (struct el_common *) la;
+
+       /*
+        * The first quadword after the common header always seems to
+        * be the machine check reason---don't know why this isn't
+        * part of the common header instead.  In the case of a long
+        * logout frame, the upper 32 bits is the machine check
+        * revision level, which we ignore for now.
+        */
+       switch (el.c->code & 0xffffffff) {
+       case MCHK_K_TPERR:      reason = "tag parity error"; break;
+       case MCHK_K_TCPERR:     reason = "tag control parity error"; break;
+       case MCHK_K_HERR:       reason = "access to non-existent memory"; break;
+       case MCHK_K_ECC_C:      reason = "correctable ECC error"; break;
+       case MCHK_K_ECC_NC:     reason = "non-correctable ECC error"; break;
+       case MCHK_K_CACKSOFT:   reason = "MCHK_K_CACKSOFT"; break; /* what's this? */
+       case MCHK_K_BUGCHECK:   reason = "illegal exception in PAL mode"; break;
+       case MCHK_K_OS_BUGCHECK: reason = "callsys in kernel mode"; break;
+       case MCHK_K_DCPERR:     reason = "d-cache parity error"; break;
+       case MCHK_K_ICPERR:     reason = "i-cache parity error"; break;
+       case MCHK_K_SIO_SERR:   reason = "SIO SERR occurred on on PCI bus"; break;
+       case MCHK_K_SIO_IOCHK:  reason = "SIO IOCHK occurred on ISA bus"; break;
+       case MCHK_K_DCSR:       reason = "MCHK_K_DCSR"; break;
+       case MCHK_K_UNKNOWN:
+       default:
+               sprintf(buf, "reason for machine-check unknown (0x%lx)",
+                       el.c->code & 0xffffffff);
+               reason = buf;
+               break;
+       }
+
+       wrmces(rdmces());       /* reset machine check pending flag */
+
+       switch (el.c->size) {
+       case sizeof(struct el_lca_mcheck_short):
+               printk(KERN_CRIT
+                      "  Reason: %s (short frame%s, dc_stat=%lx):\n",
+                      reason, el.c->retry ? ", retryable" : "",
+                      el.s->dc_stat);
+               if (el.s->esr & ESR_EAV) {
+                       mem_error(el.s->esr, el.s->ear);
+               }
+               if (el.s->ioc_stat0 & IOC_ERR) {
+                       ioc_error(el.s->ioc_stat0, el.s->ioc_stat1);
+               }
+               break;
+
+       case sizeof(struct el_lca_mcheck_long):
+               printk(KERN_CRIT "  Reason: %s (long frame%s):\n",
+                      reason, el.c->retry ? ", retryable" : "");
+               printk(KERN_CRIT
+                      "    reason: %lx  exc_addr: %lx  dc_stat: %lx\n", 
+                      el.l->pt[0], el.l->exc_addr, el.l->dc_stat);
+               printk(KERN_CRIT "    car: %lx\n", el.l->car);
+               if (el.l->esr & ESR_EAV) {
+                       mem_error(el.l->esr, el.l->ear);
+               }
+               if (el.l->ioc_stat0 & IOC_ERR) {
+                       ioc_error(el.l->ioc_stat0, el.l->ioc_stat1);
+               }
+               break;
+
+       default:
+               printk(KERN_CRIT "  Unknown errorlog size %d\n", el.c->size);
+       }
+
+       /* Dump the logout area to give all info.  */
+
+       ptr = (unsigned long *) la;
+       for (i = 0; i < el.c->size / sizeof(long); i += 2) {
+               printk(KERN_CRIT " +%8lx %016lx %016lx\n",
+                      i*sizeof(long), ptr[i], ptr[i+1]);
+       }
+}
+
+/*
+ * The following routines are needed to support the SPEED changing
+ * necessary to successfully manage the thermal problem on the AlphaBook1.
+ */
+
+void
+lca_clock_print(void)
+{
+        long    pmr_reg;
+
+        pmr_reg = LCA_READ_PMR;
+
+        printk("Status of clock control:\n");
+        printk("\tPrimary clock divisor\t0x%lx\n", LCA_GET_PRIMARY(pmr_reg));
+        printk("\tOverride clock divisor\t0x%lx\n", LCA_GET_OVERRIDE(pmr_reg));
+        printk("\tInterrupt override is %s\n",
+              (pmr_reg & LCA_PMR_INTO) ? "on" : "off"); 
+        printk("\tDMA override is %s\n",
+              (pmr_reg & LCA_PMR_DMAO) ? "on" : "off"); 
+
+}
+
+int
+lca_get_clock(void)
+{
+        long    pmr_reg;
+
+        pmr_reg = LCA_READ_PMR;
+        return(LCA_GET_PRIMARY(pmr_reg));
+
+}
+
+void
+lca_clock_fiddle(int divisor)
+{
+        long    pmr_reg;
+
+        pmr_reg = LCA_READ_PMR;
+        LCA_SET_PRIMARY_CLOCK(pmr_reg, divisor);
+       /* lca_norm_clock = divisor; */
+        LCA_WRITE_PMR(pmr_reg);
+        mb();
+}
diff --git a/arch/alpha/kernel/core_mcpcia.c b/arch/alpha/kernel/core_mcpcia.c
new file mode 100644 (file)
index 0000000..b194861
--- /dev/null
@@ -0,0 +1,969 @@
+/*
+ *     linux/arch/alpha/kernel/core_mcpcia.c
+ *
+ * Code common to all MCbus-PCI Adaptor core logic chipsets
+ *
+ * Based on code written by David A Rusling (david.rusling@reo.mts.dec.com).
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/pci.h>
+
+#define __EXTERN_INLINE inline
+#include <asm/io.h>
+#include <asm/core_mcpcia.h>
+#undef __EXTERN_INLINE
+
+#include "proto.h"
+
+/*
+ * NOTE: Herein lie back-to-back mb instructions.  They are magic. 
+ * One plausible explanation is that the i/o controller does not properly
+ * handle the system transaction.  Another involves timing.  Ho hum.
+ */
+
+extern asmlinkage void wrmces(unsigned long mces);
+
+/*
+ * BIOS32-style PCI interface:
+ */
+
+#undef DEBUG_CFG
+
+#ifdef DEBUG_CFG
+# define DBG_CFG(args) printk args
+#else
+# define DBG_CFG(args)
+#endif
+
+#undef DEBUG_PCI
+
+#ifdef DEBUG_PCI
+# define DBG_PCI(args) printk args
+#else
+# define DBG_PCI(args)
+#endif
+
+#define DEBUG_MCHECK
+
+#ifdef DEBUG_MCHECK
+# define DBG_MCK(args) printk args
+# define DEBUG_MCHECK_DUMP
+#else
+# define DBG_MCK(args)
+#endif
+
+#define vuip   volatile unsigned int  *
+#define vulp   volatile unsigned long  *
+
+static volatile unsigned int MCPCIA_mcheck_expected[NR_CPUS];
+static volatile unsigned int MCPCIA_mcheck_taken[NR_CPUS];
+static unsigned int MCPCIA_jd[NR_CPUS];
+
+#define MCPCIA_MAX_HOSES 2
+static int mcpcia_num_hoses = 0;
+
+static int pci_probe_enabled = 0; /* disable to start */
+
+static struct linux_hose_info *mcpcia_root = NULL, *mcpcia_last_hose;
+
+static inline unsigned long long_align(unsigned long addr)
+{
+       return ((addr + (sizeof(unsigned long) - 1)) &
+               ~(sizeof(unsigned long) - 1));
+}
+
+
+/*
+ * Given a bus, device, and function number, compute resulting
+ * configuration space address and setup the MCPCIA_HAXR2 register
+ * accordingly.  It is therefore not safe to have concurrent
+ * invocations to configuration space access routines, but there
+ * really shouldn't be any need for this.
+ *
+ * Type 0:
+ *
+ *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *     31:11   Device select bit.
+ *     10:8    Function number
+ *      7:2    Register number
+ *
+ * Type 1:
+ *
+ *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *     31:24   reserved
+ *     23:16   bus number (8 bits = 128 possible buses)
+ *     15:11   Device number (5 bits)
+ *     10:8    function number
+ *      7:2    register number
+ *  
+ * Notes:
+ *     The function number selects which function of a multi-function device 
+ *     (e.g., SCSI and Ethernet).
+ * 
+ *     The register selects a DWORD (32 bit) register offset.  Hence it
+ *     doesn't get shifted by 2 bits as we want to "drop" the bottom two
+ *     bits.
+ */
+
+static unsigned int
+conf_read(unsigned long addr, unsigned char type1,
+         struct linux_hose_info *hose)
+{
+       unsigned long flags;
+       unsigned long hoseno = hose->pci_hose_index;
+       unsigned int stat0, value, temp, cpu;
+
+       cpu = smp_processor_id();
+
+       save_and_cli(flags);
+
+       DBG_CFG(("conf_read(addr=0x%lx, type1=%d, hose=%d)\n",
+                addr, type1, hoseno));
+
+       /* Reset status register to avoid losing errors.  */
+       stat0 = *(vuip)MCPCIA_CAP_ERR(hoseno);
+       *(vuip)MCPCIA_CAP_ERR(hoseno) = stat0; mb();
+       temp = *(vuip)MCPCIA_CAP_ERR(hoseno);
+       DBG_CFG(("conf_read: MCPCIA CAP_ERR(%d) was 0x%x\n", hoseno, stat0));
+
+       mb();
+       draina();
+       MCPCIA_mcheck_expected[cpu] = 1;
+       MCPCIA_mcheck_taken[cpu] = 0;
+       mb();
+
+       /* Access configuration space.  */
+       value = *((vuip)addr);
+       mb();
+       mb();  /* magic */
+
+       if (MCPCIA_mcheck_taken[cpu]) {
+               MCPCIA_mcheck_taken[cpu] = 0;
+               value = 0xffffffffU;
+               mb();
+       }
+       MCPCIA_mcheck_expected[cpu] = 0;
+       mb();
+
+       DBG_CFG(("conf_read(): finished\n"));
+
+       restore_flags(flags);
+       return value;
+}
+
+static void
+conf_write(unsigned long addr, unsigned int value, unsigned char type1,
+          struct linux_hose_info *hose)
+{
+       unsigned long flags;
+       unsigned long hoseno = hose->pci_hose_index;
+       unsigned int stat0, temp, cpu;
+
+       cpu = smp_processor_id();
+
+       save_and_cli(flags);    /* avoid getting hit by machine check */
+
+       /* Reset status register to avoid losing errors.  */
+       stat0 = *(vuip)MCPCIA_CAP_ERR(hoseno);
+       *(vuip)MCPCIA_CAP_ERR(hoseno) = stat0; mb();
+       temp = *(vuip)MCPCIA_CAP_ERR(hoseno);
+       DBG_CFG(("conf_write: MCPCIA CAP_ERR(%d) was 0x%x\n", hoseno, stat0));
+
+       draina();
+       MCPCIA_mcheck_expected[cpu] = 1;
+       mb();
+
+       /* Access configuration space.  */
+       *((vuip)addr) = value;
+       mb();
+       mb();  /* magic */
+       temp = *(vuip)MCPCIA_CAP_ERR(hoseno); /* read to force the write */
+       MCPCIA_mcheck_expected[cpu] = 0;
+       mb();
+
+       DBG_CFG(("conf_write(): finished\n"));
+       restore_flags(flags);
+}
+
+static int
+mk_conf_addr(struct linux_hose_info *hose,
+            u8 bus, u8 device_fn, u8 where,
+            unsigned long *pci_addr, unsigned char *type1)
+{
+       unsigned long addr;
+
+       if (!pci_probe_enabled) /* if doing standard pci_init(), ignore */
+               return -1;
+
+       DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
+                " pci_addr=0x%p, type1=0x%p)\n",
+                bus, device_fn, where, pci_addr, type1));
+
+       /* Type 1 configuration cycle for *ALL* busses.  */
+       *type1 = 1;
+
+       if (hose->pci_first_busno == bus)
+               bus = 0;
+       addr = (bus << 16) | (device_fn << 8) | (where);
+       addr <<= 5; /* swizzle for SPARSE */
+       addr |= hose->pci_config_space;
+
+       *pci_addr = addr;
+       DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
+       return 0;
+}
+
+/* FIXME: At some point we should update these routines to use the new
+   PCI interface, which can jump through these hoops for us.  */
+
+static inline int
+hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value,
+                      struct linux_hose_info *hose)
+{
+       unsigned long addr;
+       unsigned char type1;
+
+       *value = 0xff;
+
+       if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= 0x00;
+       *value = conf_read(addr, type1, hose) >> ((where & 3) * 8);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static inline int
+hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value,
+                      struct linux_hose_info *hose)
+{
+       unsigned long addr;
+       unsigned char type1;
+
+       *value = 0xffff;
+
+       if (where & 0x1)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= 0x08;
+       *value = conf_read(addr, type1, hose) >> ((where & 3) * 8);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static inline int
+hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value,
+                       struct linux_hose_info *hose)
+{
+       unsigned long addr;
+       unsigned char type1;
+
+       *value = 0xffffffff;
+
+       if (where & 0x3)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= 0x18;
+       *value = conf_read(addr, type1, hose);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static inline int
+hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value,
+                       struct linux_hose_info *hose)
+{
+       unsigned long addr;
+       unsigned char type1;
+
+       if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= 0x00;
+       conf_write(addr, value << ((where & 3) * 8), type1, hose);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static inline int
+hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value,
+                       struct linux_hose_info *hose)
+{
+       unsigned long addr;
+       unsigned char type1;
+
+       if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= 0x08;
+       conf_write(addr, value << ((where & 3) * 8), type1, hose);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static inline int
+hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value,
+                        struct linux_hose_info *hose)
+{
+       unsigned long addr;
+       unsigned char type1;
+
+       if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= 0x18;
+       conf_write(addr, value << ((where & 3) * 8), type1, hose);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int
+mcpcia_pcibios_read_config_byte (u8 bus, u8 devfn, u8 where, u8 *value)
+{
+       return hose_read_config_byte(bus, devfn, where, value, bus2hose[bus]);
+}
+
+int
+mcpcia_pcibios_read_config_word (u8 bus, u8 devfn, u8 where, u16 *value)
+{
+       return hose_read_config_word(bus, devfn, where, value, bus2hose[bus]);
+}
+
+int 
+mcpcia_pcibios_read_config_dword (u8 bus, u8 devfn, u8 where, u32 *value)
+{
+       return hose_read_config_dword(bus, devfn, where, value, bus2hose[bus]);
+}
+
+int 
+mcpcia_pcibios_write_config_byte (u8 bus, u8 devfn, u8 where, u8 value)
+{
+       return hose_write_config_byte(bus, devfn, where, value, bus2hose[bus]);
+}
+
+int 
+mcpcia_pcibios_write_config_word (u8 bus, u8 devfn, u8 where, u16 value)
+{
+       return hose_write_config_word(bus, devfn, where, value, bus2hose[bus]);
+}
+
+int 
+mcpcia_pcibios_write_config_dword (u8 bus, u8 devfn, u8 where, u32 val)
+{
+       return hose_write_config_dword(bus, devfn, where, val, bus2hose[bus]);
+}
+
+void __init
+mcpcia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+{
+       struct linux_hose_info *hose;
+       unsigned int mcpcia_err;
+       unsigned int pci_rev;
+       int h;
+
+       *mem_start = long_align(*mem_start);
+
+       for (h = 0; h < NR_CPUS; h++) {
+               MCPCIA_mcheck_expected[h] = 0;
+               MCPCIA_mcheck_taken[h] = 0;
+       }
+
+       /* First, find how many hoses we have.  */
+       for (h = 0; h < MCPCIA_MAX_HOSES; h++) {
+               pci_rev = *(vuip)MCPCIA_REV(h);
+#if 0
+               printk("mcpcia_init: got 0x%x for PCI_REV for hose %d\n",
+                      pci_rev, h);
+#endif
+               if ((pci_rev >> 16) == PCI_CLASS_BRIDGE_HOST) {
+                       mcpcia_num_hoses++;
+
+                       hose = (struct linux_hose_info *)*mem_start;
+                       *mem_start = long_align(*mem_start + sizeof(*hose));
+
+                       memset(hose, 0, sizeof(*hose));
+
+                       if (mcpcia_root)
+                               mcpcia_last_hose->next = hose;
+                       else
+                               mcpcia_root = hose;
+                       mcpcia_last_hose = hose;
+
+                       hose->pci_io_space = MCPCIA_IO(h);
+                       hose->pci_mem_space = MCPCIA_DENSE(h);
+                       hose->pci_config_space = MCPCIA_CONF(h);
+                       hose->pci_sparse_space = MCPCIA_SPARSE(h);
+                       hose->pci_hose_index = h;
+                       hose->pci_first_busno = 255;
+                       hose->pci_last_busno = 0;
+               }
+       }
+
+#if 1
+       printk("mcpcia_init: found %d hoses\n", mcpcia_num_hoses);
+#endif
+
+       /* Now do init for each hose.  */
+       for (hose = mcpcia_root; hose; hose = hose->next) {
+               h = hose->pci_hose_index;
+#if 0
+               printk("mcpcia_init: -------- hose %d --------\n",h);
+               printk("MCPCIA_REV 0x%x\n", *(vuip)MCPCIA_REV(h));
+               printk("MCPCIA_WHOAMI 0x%x\n", *(vuip)MCPCIA_WHOAMI(h));
+               printk("MCPCIA_HAE_MEM 0x%x\n", *(vuip)MCPCIA_HAE_MEM(h));
+               printk("MCPCIA_HAE_IO 0x%x\n", *(vuip)MCPCIA_HAE_IO(h));
+               printk("MCPCIA_HAE_DENSE 0x%x\n", *(vuip)MCPCIA_HAE_DENSE(h));
+               printk("MCPCIA_INT_CTL 0x%x\n", *(vuip)MCPCIA_INT_CTL(h));
+               printk("MCPCIA_INT_REQ 0x%x\n", *(vuip)MCPCIA_INT_REQ(h));
+               printk("MCPCIA_INT_TARG 0x%x\n", *(vuip)MCPCIA_INT_TARG(h));
+               printk("MCPCIA_INT_ADR 0x%x\n", *(vuip)MCPCIA_INT_ADR(h));
+               printk("MCPCIA_INT_ADR_EXT 0x%x\n", *(vuip)MCPCIA_INT_ADR_EXT(h));
+               printk("MCPCIA_INT_MASK0 0x%x\n", *(vuip)MCPCIA_INT_MASK0(h));
+               printk("MCPCIA_INT_MASK1 0x%x\n", *(vuip)MCPCIA_INT_MASK1(h));
+               printk("MCPCIA_HBASE 0x%x\n", *(vuip)MCPCIA_HBASE(h));
+#endif
+
+               /* 
+                * Set up error reporting. Make sure CPU_PE is OFF in the mask.
+                */
+#if 0
+               mcpcia_err = *(vuip)MCPCIA_ERR_MASK(h);
+               mcpcia_err &= ~4;   
+               *(vuip)MCPCIA_ERR_MASK(h) = mcpcia_err;
+               mb();
+               mcpcia_err = *(vuip)MCPCIA_ERR_MASK;
+#endif
+
+               mcpcia_err = *(vuip)MCPCIA_CAP_ERR(h);
+               mcpcia_err |= 0x0006;   /* master/target abort */
+               *(vuip)MCPCIA_CAP_ERR(h) = mcpcia_err;
+               mb() ;
+               mcpcia_err = *(vuip)MCPCIA_CAP_ERR(h);
+
+               switch (alpha_use_srm_setup)
+               {
+               default:
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
+                       /* Check window 0 for enabled and mapped to 0. */
+                       if (((*(vuip)MCPCIA_W0_BASE(h) & 3) == 1)
+                           && (*(vuip)MCPCIA_T0_BASE(h) == 0)
+                           && ((*(vuip)MCPCIA_W0_MASK(h) & 0xfff00000U) > 0x0ff00000U)) {
+                               MCPCIA_DMA_WIN_BASE = *(vuip)MCPCIA_W0_BASE(h) & 0xfff00000U;
+                               MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W0_MASK(h) & 0xfff00000U;
+                               MCPCIA_DMA_WIN_SIZE += 0x00100000U;
+#if 1
+                               printk("mcpcia_init: using Window 0 settings\n");
+                               printk("mcpcia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
+                                      *(vuip)MCPCIA_W0_BASE(h),
+                                      *(vuip)MCPCIA_W0_MASK(h),
+                                      *(vuip)MCPCIA_T0_BASE(h));
+#endif
+                               break;
+                       }
+
+                       /* Check window 1 for enabled and mapped to 0.  */
+                       if (((*(vuip)MCPCIA_W1_BASE(h) & 3) == 1)
+                           && (*(vuip)MCPCIA_T1_BASE(h) == 0)
+                           && ((*(vuip)MCPCIA_W1_MASK(h) & 0xfff00000U) > 0x0ff00000U)) {
+                               MCPCIA_DMA_WIN_BASE = *(vuip)MCPCIA_W1_BASE(h) & 0xfff00000U;
+                               MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W1_MASK(h) & 0xfff00000U;
+                               MCPCIA_DMA_WIN_SIZE += 0x00100000U;
+#if 1
+                               printk("mcpcia_init: using Window 1 settings\n");
+                               printk("mcpcia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
+                                      *(vuip)MCPCIA_W1_BASE(h),
+                                      *(vuip)MCPCIA_W1_MASK(h),
+                                      *(vuip)MCPCIA_T1_BASE(h));
+#endif
+                               break;
+                       }
+
+                       /* Check window 2 for enabled and mapped to 0.  */
+                       if (((*(vuip)MCPCIA_W2_BASE(h) & 3) == 1)
+                           && (*(vuip)MCPCIA_T2_BASE(h) == 0)
+                           && ((*(vuip)MCPCIA_W2_MASK(h) & 0xfff00000U) > 0x0ff00000U)) {
+                               MCPCIA_DMA_WIN_BASE = *(vuip)MCPCIA_W2_BASE(h) & 0xfff00000U;
+                               MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W2_MASK(h) & 0xfff00000U;
+                               MCPCIA_DMA_WIN_SIZE += 0x00100000U;
+#if 1
+                               printk("mcpcia_init: using Window 2 settings\n");
+                               printk("mcpcia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
+                                      *(vuip)MCPCIA_W2_BASE(h),
+                                      *(vuip)MCPCIA_W2_MASK(h),
+                                      *(vuip)MCPCIA_T2_BASE(h));
+#endif
+                               break;
+                       }
+
+                       /* Check window 3 for enabled and mapped to 0.  */
+                       if (((*(vuip)MCPCIA_W3_BASE(h) & 3) == 1)
+                           && (*(vuip)MCPCIA_T3_BASE(h) == 0)
+                           && ((*(vuip)MCPCIA_W3_MASK(h) & 0xfff00000U) > 0x0ff00000U)) {
+                               MCPCIA_DMA_WIN_BASE = *(vuip)MCPCIA_W3_BASE(h) & 0xfff00000U;
+                               MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W3_MASK(h) & 0xfff00000U;
+                               MCPCIA_DMA_WIN_SIZE += 0x00100000U;
+#if 1
+                               printk("mcpcia_init: using Window 3 settings\n");
+                               printk("mcpcia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
+                                      *(vuip)MCPCIA_W3_BASE(h),
+                                      *(vuip)MCPCIA_W3_MASK(h),
+                                      *(vuip)MCPCIA_T3_BASE(h));
+#endif
+                               break;
+                       }
+
+                       /* Otherwise, we must use our defaults.  */
+                       MCPCIA_DMA_WIN_BASE = MCPCIA_DMA_WIN_BASE_DEFAULT;
+                       MCPCIA_DMA_WIN_SIZE = MCPCIA_DMA_WIN_SIZE_DEFAULT;
+#endif
+               case 0:
+                       /*
+                        * Set up the PCI->physical memory translation windows.
+                        * For now, windows 1,2 and 3 are disabled.  In the
+                        * future, we may want to use them to do scatter/
+                        * gather DMA.
+                        *
+                        * Window 0 goes at 1 GB and is 1 GB large.
+                        */
+
+                       *(vuip)MCPCIA_W0_BASE(h) = 1U | (MCPCIA_DMA_WIN_BASE_DEFAULT & 0xfff00000U);
+                       *(vuip)MCPCIA_W0_MASK(h) = (MCPCIA_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000U;
+                       *(vuip)MCPCIA_T0_BASE(h) = 0;
+
+                       *(vuip)MCPCIA_W1_BASE(h) = 0x0 ;
+                       *(vuip)MCPCIA_W2_BASE(h) = 0x0 ;
+                       *(vuip)MCPCIA_W3_BASE(h) = 0x0 ;
+
+                       *(vuip)MCPCIA_HBASE(h) = 0x0 ;
+                       mb();
+                       break;
+               }
+#if 0
+               {
+                       unsigned int mcpcia_int_ctl = *((vuip)MCPCIA_INT_CTL(h));
+                       printk("mcpcia_init: INT_CTL was 0x%x\n", mcpcia_int_ctl);
+                       *(vuip)MCPCIA_INT_CTL(h) = 1U; mb();
+                       mcpcia_int_ctl = *(vuip)MCPCIA_INT_CTL(h);
+               }
+#endif
+
+               /*
+                * Sigh... For the SRM setup, unless we know apriori what the HAE
+                * contents will be, we need to setup the arbitrary region bases
+                * so we can test against the range of addresses and tailor the
+                * region chosen for the SPARSE memory access.
+                *
+                * See include/asm-alpha/mcpcia.h for the SPARSE mem read/write.
+                */
+               if (alpha_use_srm_setup) {
+                       unsigned int mcpcia_hae_mem = *(vuip)MCPCIA_HAE_MEM(h);
+
+                       alpha_mv.sm_base_r1 = (mcpcia_hae_mem      ) & 0xe0000000UL;
+                       alpha_mv.sm_base_r2 = (mcpcia_hae_mem << 16) & 0xf8000000UL;
+                       alpha_mv.sm_base_r3 = (mcpcia_hae_mem << 24) & 0xfc000000UL;
+
+                       /*
+                        * Set the HAE cache, so that setup_arch() code
+                        * will use the SRM setting always. Our readb/writeb
+                        * code in mcpcia.h expects never to have to change
+                        * the contents of the HAE.
+                        */
+                       alpha_mv.hae_cache = mcpcia_hae_mem;
+
+                       alpha_mv.mv_readb = mcpcia_srm_readb;
+                       alpha_mv.mv_readw = mcpcia_srm_readw;
+                       alpha_mv.mv_writeb = mcpcia_srm_writeb;
+                       alpha_mv.mv_writew = mcpcia_srm_writew;
+               } else {
+                       *(vuip)MCPCIA_HAE_MEM(h) = 0U; mb();
+                       *(vuip)MCPCIA_HAE_MEM(h); /* read it back. */
+                       *(vuip)MCPCIA_HAE_IO(h) = 0; mb();
+                       *(vuip)MCPCIA_HAE_IO(h);  /* read it back. */
+               }
+       }
+}
+
+static int
+mcpcia_pci_clr_err(int h)
+{
+       unsigned int cpu = smp_processor_id();
+
+       MCPCIA_jd[cpu] = *(vuip)MCPCIA_CAP_ERR(h);
+#if 0
+       DBG_MCK(("MCPCIA_pci_clr_err: MCPCIA CAP_ERR(%d) after read 0x%x\n",
+                h, MCPCIA_jd[cpu]));
+#endif
+       *(vuip)MCPCIA_CAP_ERR(h) = 0xffffffff; mb(); /* clear them all */
+       MCPCIA_jd[cpu] = *(vuip)MCPCIA_CAP_ERR(h);
+       return 0;
+}
+
+static void
+mcpcia_print_uncorrectable(struct el_MCPCIA_uncorrected_frame_mcheck *logout)
+{
+       struct el_common_EV5_uncorrectable_mcheck *frame;
+       int i;
+
+       frame = &logout->procdata;
+
+       /* Print PAL fields */
+       for (i = 0; i < 24; i += 2) {
+               printk("\tpal temp[%d-%d]\t\t= %16lx %16lx\n\r",
+                      i, i+1, frame->paltemp[i], frame->paltemp[i+1]);
+       }
+       for (i = 0; i < 8; i += 2) {
+               printk("\tshadow[%d-%d]\t\t= %16lx %16lx\n\r",
+                      i, i+1, frame->shadow[i], 
+                      frame->shadow[i+1]);
+       }
+       printk("\tAddr of excepting instruction\t= %16lx\n\r",
+              frame->exc_addr);
+       printk("\tSummary of arithmetic traps\t= %16lx\n\r",
+              frame->exc_sum);
+       printk("\tException mask\t\t\t= %16lx\n\r",
+              frame->exc_mask);
+       printk("\tBase address for PALcode\t= %16lx\n\r",
+              frame->pal_base);
+       printk("\tInterrupt Status Reg\t\t= %16lx\n\r",
+              frame->isr);
+       printk("\tCURRENT SETUP OF EV5 IBOX\t= %16lx\n\r",
+              frame->icsr);
+       printk("\tI-CACHE Reg %s parity error\t= %16lx\n\r",
+              (frame->ic_perr_stat & 0x800L) ? 
+              "Data" : "Tag", 
+              frame->ic_perr_stat); 
+       printk("\tD-CACHE error Reg\t\t= %16lx\n\r",
+              frame->dc_perr_stat);
+       if (frame->dc_perr_stat & 0x2) {
+               switch (frame->dc_perr_stat & 0x03c) {
+               case 8:
+                       printk("\t\tData error in bank 1\n\r");
+                       break;
+               case 4:
+                       printk("\t\tData error in bank 0\n\r");
+                       break;
+               case 20:
+                       printk("\t\tTag error in bank 1\n\r");
+                       break;
+               case 10:
+                       printk("\t\tTag error in bank 0\n\r");
+                       break;
+               }
+       }
+       printk("\tEffective VA\t\t\t= %16lx\n\r",
+              frame->va);
+       printk("\tReason for D-stream\t\t= %16lx\n\r",
+              frame->mm_stat);
+       printk("\tEV5 SCache address\t\t= %16lx\n\r",
+              frame->sc_addr);
+       printk("\tEV5 SCache TAG/Data parity\t= %16lx\n\r",
+              frame->sc_stat);
+       printk("\tEV5 BC_TAG_ADDR\t\t\t= %16lx\n\r",
+              frame->bc_tag_addr);
+       printk("\tEV5 EI_ADDR: Phys addr of Xfer\t= %16lx\n\r",
+              frame->ei_addr);
+       printk("\tFill Syndrome\t\t\t= %16lx\n\r",
+              frame->fill_syndrome);
+       printk("\tEI_STAT reg\t\t\t= %16lx\n\r",
+              frame->ei_stat);
+       printk("\tLD_LOCK\t\t\t\t= %16lx\n\r",
+              frame->ld_lock);
+}
+
+void
+mcpcia_machine_check(unsigned long type, unsigned long la_ptr,
+                    struct pt_regs * regs)
+{
+#if 0
+        printk("mcpcia machine check ignored\n") ;
+#else
+       struct el_common *mchk_header;
+       struct el_MCPCIA_uncorrected_frame_mcheck *mchk_logout;
+       unsigned int cpu = smp_processor_id();
+       int h = 0;
+
+       mchk_header = (struct el_common *)la_ptr;
+       mchk_logout = (struct el_MCPCIA_uncorrected_frame_mcheck *)la_ptr;
+
+#if 0
+       DBG_MCK(("mcpcia_machine_check: type=0x%lx la_ptr=0x%lx\n",
+                type, la_ptr));
+       DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
+                regs->pc, mchk_header->size, mchk_header->proc_offset,
+                mchk_header->sys_offset));
+#endif
+       /*
+        * Check if machine check is due to a badaddr() and if so,
+        * ignore the machine check.
+        */
+       mb();
+       mb();  /* magic */
+       if (MCPCIA_mcheck_expected[cpu]) {
+#if 0
+               DBG_MCK(("MCPCIA machine check expected\n"));
+#endif
+               MCPCIA_mcheck_expected[cpu] = 0;
+               MCPCIA_mcheck_taken[cpu] = 1;
+               mb();
+               mb();  /* magic */
+               draina();
+               mcpcia_pci_clr_err(h);
+               wrmces(0x7);
+               mb();
+       }
+#if 1
+       else {
+               printk("MCPCIA machine check NOT expected on CPU %d\n", cpu);
+               DBG_MCK(("mcpcia_machine_check: type=0x%lx pc=0x%lx"
+                        " code=0x%lx\n",
+                        type, regs->pc, mchk_header->code));
+
+               MCPCIA_mcheck_expected[cpu] = 0;
+               MCPCIA_mcheck_taken[cpu] = 1;
+               mb();
+               mb();  /* magic */
+               draina();
+               mcpcia_pci_clr_err(h);
+               wrmces(0x7);
+               mb();
+#ifdef DEBUG_MCHECK_DUMP
+               if (type == 0x620)
+                       printk("MCPCIA machine check: system CORRECTABLE!\n");
+               else if (type == 0x630)
+                       printk("MCPCIA machine check: processor CORRECTABLE!\n");
+               else
+                       mcpcia_print_uncorrectable(mchk_logout);
+#endif /* DEBUG_MCHECK_DUMP */
+       }
+#endif
+#endif
+}
+
+/*==========================================================================*/
+
+#define PRIMARY(b) ((b)&0xff)
+#define SECONDARY(b) (((b)>>8)&0xff)
+#define SUBORDINATE(b) (((b)>>16)&0xff)
+
+static int __init
+hose_scan_bridges(struct linux_hose_info *hose, unsigned char bus)
+{
+       unsigned int devfn, l, class;
+       unsigned char hdr_type = 0;
+       unsigned int found = 0;
+
+       for (devfn = 0; devfn < 0xff; ++devfn) {
+               if (PCI_FUNC(devfn) == 0) {
+                       hose_read_config_byte(bus, devfn, PCI_HEADER_TYPE,
+                                             &hdr_type, hose);
+               } else if (!(hdr_type & 0x80)) {
+                       /* not a multi-function device */
+                       continue;
+               }
+
+               /* Check if there is anything here. */
+               hose_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l, hose);
+               if (l == 0xffffffff || l == 0x00000000) {
+                       hdr_type = 0;
+                       continue;
+               }
+
+               /* See if this is a bridge device. */
+               hose_read_config_dword(bus, devfn, PCI_CLASS_REVISION,
+                                      &class, hose);
+
+               if ((class >> 16) == PCI_CLASS_BRIDGE_PCI) {
+                       unsigned int busses;
+
+                       found++;
+
+                       hose_read_config_dword(bus, devfn, PCI_PRIMARY_BUS,
+                                              &busses, hose);
+
+                       DBG_PCI(("hose_scan_bridges: hose %d bus %d "
+                                "slot %d busses 0x%x\n",
+                                hose->pci_hose_index, bus, PCI_SLOT(devfn),
+                                busses));
+
+                       /*
+                        * Do something with first_busno and last_busno
+                        */
+                       if (hose->pci_first_busno > PRIMARY(busses)) {
+                               hose->pci_first_busno = PRIMARY(busses);
+                               DBG_PCI(("hose_scan_bridges: hose %d bus %d "
+                                        "slot %d change first to %d\n",
+                                        hose->pci_hose_index, bus,
+                                        PCI_SLOT(devfn), PRIMARY(busses)));
+                       }
+                       if (hose->pci_last_busno < SUBORDINATE(busses)) {
+                               hose->pci_last_busno = SUBORDINATE(busses);
+                               DBG_PCI(("hose_scan_bridges: hose %d bus %d "
+                                        "slot %d change last to %d\n",
+                                        hose->pci_hose_index, bus,
+                                        PCI_SLOT(devfn),
+                                        SUBORDINATE(busses)));
+                       }
+                       /*
+                        * Now scan everything underneath the bridge.
+                        */
+                       hose_scan_bridges(hose, SECONDARY(busses));
+               }
+       }
+       return found;
+}
+
+static void __init
+hose_reconfigure_bridges(struct linux_hose_info *hose, unsigned char bus)
+{
+       unsigned int devfn, l, class;
+       unsigned char hdr_type = 0;
+
+       for (devfn = 0; devfn < 0xff; ++devfn) {
+               if (PCI_FUNC(devfn) == 0) {
+                       hose_read_config_byte(bus, devfn, PCI_HEADER_TYPE,
+                                             &hdr_type, hose);
+               } else if (!(hdr_type & 0x80)) {
+                       /* not a multi-function device */
+                       continue;
+               }
+
+               /* Check if there is anything here. */
+               hose_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l, hose);
+               if (l == 0xffffffff || l == 0x00000000) {
+                       hdr_type = 0;
+                       continue;
+               }
+
+               /* See if this is a bridge device. */
+               hose_read_config_dword(bus, devfn, PCI_CLASS_REVISION,
+                                      &class, hose);
+
+               if ((class >> 16) == PCI_CLASS_BRIDGE_PCI) {
+                       unsigned int busses;
+
+                       hose_read_config_dword(bus, devfn, PCI_PRIMARY_BUS,
+                                              &busses, hose);
+
+                       /*
+                        * First reconfigure everything underneath the bridge.
+                        */
+                       hose_reconfigure_bridges(hose, (busses >> 8) & 0xff);
+
+                       /*
+                        * Unconfigure this bridges bus numbers,
+                        * pci_scan_bus() will fix this up properly.
+                        */
+                       busses &= 0xff000000;
+                       hose_write_config_dword(bus, devfn, PCI_PRIMARY_BUS,
+                                               busses, hose);
+               }
+       }
+}
+
+static void __init
+mcpcia_fixup_busno(struct linux_hose_info *hose, unsigned char bus)
+{
+       unsigned int nbus;
+
+       /*
+        * First, scan for all bridge devices underneath this hose,
+        * to determine the first and last busnos.
+        */
+       if (!hose_scan_bridges(hose, 0)) {
+               /* none found, exit */
+               hose->pci_first_busno = bus;
+               hose->pci_last_busno = bus;
+       } else {
+               /*
+                * Reconfigure all bridge devices underneath this hose.
+                */
+               hose_reconfigure_bridges(hose, hose->pci_first_busno);
+       }
+
+       /*
+        * Now reconfigure the hose to it's new bus number and set up
+        * our bus2hose mapping for this hose.
+        */
+       nbus = hose->pci_last_busno - hose->pci_first_busno;
+
+       hose->pci_first_busno = bus;
+
+       DBG_PCI(("mcpcia_fixup_busno: hose %d startbus %d nbus %d\n",
+                hose->pci_hose_index, bus, nbus));
+
+       do {
+               bus2hose[bus++] = hose;
+       } while (nbus-- > 0);
+}
+
+static void __init
+mcpcia_probe(struct linux_hose_info *hose)
+{
+       static struct pci_bus *pchain = NULL;
+       struct pci_bus *pbus = &hose->pci_bus;
+       static unsigned char busno = 0;
+
+       /*
+        * Hoses include child PCI bridges in bus-range property,
+        * but we don't scan each of those ourselves, Linux generic PCI
+        * probing code will find child bridges and link them into this
+        * hose's root PCI device hierarchy.
+        */
+
+       pbus->number = pbus->secondary = busno;
+       pbus->sysdata = hose;
+
+       mcpcia_fixup_busno(hose, busno);
+
+       pbus->subordinate = pci_scan_bus(pbus); /* the original! */
+
+       /*
+        * Set the maximum subordinate bus of this hose.
+        */
+       hose->pci_last_busno = pbus->subordinate;
+#if 0
+       hose_write_config_byte(busno, 0, 0x41, hose->pci_last_busno, hose);
+#endif
+       busno = pbus->subordinate + 1;
+
+       /*
+        * Fixup the chain of primary PCI busses.
+        */
+       if (pchain) {
+               pchain->next = &hose->pci_bus;
+               pchain = pchain->next;
+       } else {
+               pchain = &pci_root;
+               memcpy(pchain, &hose->pci_bus, sizeof(pci_root));
+       }
+}
+
+void __init
+mcpcia_pci_fixup(void)
+{
+       struct linux_hose_info *hose;
+
+       /* Turn on Config space access finally! */
+       pci_probe_enabled = 1;
+
+       /* For each hose, probe and setup the devices on the hose.  */
+       for (hose = mcpcia_root; hose; hose = hose->next)
+               mcpcia_probe(hose);
+}
diff --git a/arch/alpha/kernel/core_pyxis.c b/arch/alpha/kernel/core_pyxis.c
new file mode 100644 (file)
index 0000000..ab49de0
--- /dev/null
@@ -0,0 +1,634 @@
+/*
+ *     linux/arch/alpha/kernel/core_pyxis.c
+ *
+ * Code common to all PYXIS core logic chips.
+ *
+ * Based on code written by David A Rusling (david.rusling@reo.mts.dec.com).
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+
+#define __EXTERN_INLINE inline
+#include <asm/io.h>
+#include <asm/core_pyxis.h>
+#undef __EXTERN_INLINE
+
+#include "proto.h"
+
+/* NOTE: Herein are back-to-back mb instructions.  They are magic.
+   One plausible explanation is that the I/O controller does not properly
+   handle the system transaction.  Another involves timing.  Ho hum.  */
+
+extern asmlinkage void wrmces(unsigned long mces);
+
+/*
+ * BIOS32-style PCI interface:
+ */
+
+#ifdef DEBUG 
+# define DBG(args)     printk args
+#else
+# define DBG(args)
+#endif
+
+#define DEBUG_MCHECK
+#ifdef DEBUG_MCHECK
+# define DBG_MCK(args) printk args
+#define DEBUG_MCHECK_DUMP
+#else
+# define DBG_MCK(args)
+#endif
+
+
+static volatile unsigned int PYXIS_mcheck_expected = 0;
+static volatile unsigned int PYXIS_mcheck_taken = 0;
+static unsigned int PYXIS_jd;
+
+
+/*
+ * Given a bus, device, and function number, compute resulting
+ * configuration space address and setup the PYXIS_HAXR2 register
+ * accordingly.  It is therefore not safe to have concurrent
+ * invocations to configuration space access routines, but there
+ * really shouldn't be any need for this.
+ *
+ * Type 0:
+ *
+ *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *     31:11   Device select bit.
+ *     10:8    Function number
+ *      7:2    Register number
+ *
+ * Type 1:
+ *
+ *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *     31:24   reserved
+ *     23:16   bus number (8 bits = 128 possible buses)
+ *     15:11   Device number (5 bits)
+ *     10:8    function number
+ *      7:2    register number
+ *  
+ * Notes:
+ *     The function number selects which function of a multi-function device 
+ *     (e.g., SCSI and Ethernet).
+ * 
+ *     The register selects a DWORD (32 bit) register offset.  Hence it
+ *     doesn't get shifted by 2 bits as we want to "drop" the bottom two
+ *     bits.
+ */
+
+static int
+mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr,
+            unsigned char *type1)
+{
+       unsigned long addr;
+
+       DBG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
+            " pci_addr=0x%p, type1=0x%p)\n",
+            bus, device_fn, where, pci_addr, type1));
+
+       if (bus == 0) {
+               int device;
+
+               device = device_fn >> 3;
+               /* Type 0 configuration cycle. */
+#if NOT_NOW
+               if (device > 20) {
+                       DBG(("mk_conf_addr: device (%d) > 20, returning -1\n",
+                            device));
+                       return -1;
+               }
+#endif
+               *type1 = 0;
+               addr = (device_fn << 8) | (where);
+       } else {
+               /* Type 1 configuration cycle.  */
+               *type1 = 1;
+               addr = (bus << 16) | (device_fn << 8) | (where);
+       }
+       *pci_addr = addr;
+       DBG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
+       return 0;
+}
+
+static unsigned int
+conf_read(unsigned long addr, unsigned char type1)
+{
+       unsigned long flags;
+       unsigned int stat0, value, temp;
+       unsigned int pyxis_cfg = 0;
+
+       save_and_cli(flags);    /* avoid getting hit by machine check */
+
+       DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
+
+       /* Reset status register to avoid losing errors.  */
+       stat0 = *(vuip)PYXIS_ERR;
+       *(vuip)PYXIS_ERR = stat0; mb();
+       temp = *(vuip)PYXIS_ERR;  /* re-read to force write */
+       DBG(("conf_read: PYXIS ERR was 0x%x\n", stat0));
+
+       /* If Type1 access, must set PYXIS CFG.  */
+       if (type1) {
+               pyxis_cfg = *(vuip)PYXIS_CFG;
+               *(vuip)PYXIS_CFG = pyxis_cfg | 1; mb();
+               temp = *(vuip)PYXIS_CFG;  /* re-read to force write */
+               DBG(("conf_read: TYPE1 access\n"));
+       }
+
+       mb();
+       draina();
+       PYXIS_mcheck_expected = 1;
+       PYXIS_mcheck_taken = 0;
+       mb();
+
+       /* Access configuration space.  */
+       value = *(vuip)addr;
+       mb();
+       mb();  /* magic */
+
+       if (PYXIS_mcheck_taken) {
+               PYXIS_mcheck_taken = 0;
+               value = 0xffffffffU;
+               mb();
+       }
+       PYXIS_mcheck_expected = 0;
+       mb();
+
+       /* If Type1 access, must reset IOC CFG so normal IO space ops work.  */
+       if (type1) {
+               *(vuip)PYXIS_CFG = pyxis_cfg & ~1; mb();
+               temp = *(vuip)PYXIS_CFG;  /* re-read to force write */
+       }
+
+       DBG(("conf_read(): finished\n"));
+
+       restore_flags(flags);
+       return value;
+}
+
+static void
+conf_write(unsigned long addr, unsigned int value, unsigned char type1)
+{
+       unsigned long flags;
+       unsigned int stat0, temp;
+       unsigned int pyxis_cfg = 0;
+
+       save_and_cli(flags);    /* avoid getting hit by machine check */
+
+       /* Reset status register to avoid losing errors.  */
+       stat0 = *(vuip)PYXIS_ERR;
+       *(vuip)PYXIS_ERR = stat0; mb();
+       temp = *(vuip)PYXIS_ERR;  /* re-read to force write */
+       DBG(("conf_write: PYXIS ERR was 0x%x\n", stat0));
+
+       /* If Type1 access, must set PYXIS CFG.  */
+       if (type1) {
+               pyxis_cfg = *(vuip)PYXIS_CFG;
+               *(vuip)PYXIS_CFG = pyxis_cfg | 1; mb();
+               temp = *(vuip)PYXIS_CFG;  /* re-read to force write */
+               DBG(("conf_read: TYPE1 access\n"));
+       }
+
+       draina();
+       PYXIS_mcheck_expected = 1;
+       mb();
+
+       /* Access configuration space.  */
+       *(vuip)addr = value;
+       mb();
+       mb();  /* magic */
+       temp = *(vuip)PYXIS_ERR; /* do a PYXIS read to force the write */
+       PYXIS_mcheck_expected = 0;
+       mb();
+
+       /* If Type1 access, must reset IOC CFG so normal IO space ops work.  */
+       if (type1) {
+               *(vuip)PYXIS_CFG = pyxis_cfg & ~1; mb();
+               temp = *(vuip)PYXIS_CFG;  /* re-read to force write */
+       }
+
+       DBG(("conf_write(): finished\n"));
+       restore_flags(flags);
+}
+
+int
+pyxis_pcibios_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value)
+{
+       unsigned long addr = PYXIS_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       *value = 0xff;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x00;
+       *value = conf_read(addr, type1) >> ((where & 3) * 8);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int
+pyxis_pcibios_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value)
+{
+       unsigned long addr = PYXIS_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       *value = 0xffff;
+       if (where & 0x1)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x08;
+       *value = conf_read(addr, type1) >> ((where & 3) * 8);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int
+pyxis_pcibios_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value)
+{
+       unsigned long addr = PYXIS_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       *value = 0xffffffff;
+       if (where & 0x3)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x18;
+       *value = conf_read(addr, type1);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+pyxis_pcibios_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value)
+{
+       unsigned long addr = PYXIS_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x00;
+       conf_write(addr, value << ((where & 3) * 8), type1);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+pyxis_pcibios_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value)
+{
+       unsigned long addr = PYXIS_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       if (where & 0x1)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x08;
+       conf_write(addr, value << ((where & 3) * 8), type1);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+pyxis_pcibios_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value)
+{
+       unsigned long addr = PYXIS_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       if (where & 0x3)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x18;
+       conf_write(addr, value << ((where & 3) * 8), type1);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+void __init
+pyxis_enable_errors (void)
+{
+       unsigned int pyxis_err;
+
+#if 0
+       printk("pyxis_init: PYXIS_ERR_MASK 0x%x\n", *(vuip)PYXIS_ERR_MASK);
+       printk("pyxis_init: PYXIS_ERR 0x%x\n", *(vuip)PYXIS_ERR);
+       printk("pyxis_init: PYXIS_INT_REQ 0x%lx\n", *(vulp)PYXIS_INT_REQ);
+       printk("pyxis_init: PYXIS_INT_MASK 0x%lx\n", *(vulp)PYXIS_INT_MASK);
+       printk("pyxis_init: PYXIS_INT_ROUTE 0x%lx\n", *(vulp)PYXIS_INT_ROUTE);
+       printk("pyxis_init: PYXIS_INT_HILO 0x%lx\n", *(vulp)PYXIS_INT_HILO);
+       printk("pyxis_init: PYXIS_INT_CNFG 0x%x\n", *(vuip)PYXIS_INT_CNFG);
+       printk("pyxis_init: PYXIS_RT_COUNT 0x%lx\n", *(vulp)PYXIS_RT_COUNT);
+#endif
+
+       /* 
+        * Set up error reporting. Make sure CPU_PE is OFF in the mask.
+        */
+       pyxis_err = *(vuip)PYXIS_ERR_MASK;
+       pyxis_err &= ~4;   
+       *(vuip)PYXIS_ERR_MASK = pyxis_err; mb();
+       pyxis_err = *(vuip)PYXIS_ERR_MASK; /* re-read to force write */
+
+       pyxis_err = *(vuip)PYXIS_ERR ;
+       pyxis_err |= 0x180;   /* master/target abort */
+       *(vuip)PYXIS_ERR = pyxis_err; mb();
+       pyxis_err = *(vuip)PYXIS_ERR; /* re-read to force write */
+}
+
+int __init
+pyxis_srm_window_setup (void)
+{
+       switch (alpha_use_srm_setup)
+       {
+       default:
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
+               /* Check window 0 for enabled and mapped to 0.  */
+               if (((*(vuip)PYXIS_W0_BASE & 3) == 1)
+                   && (*(vuip)PYXIS_T0_BASE == 0)
+                   && ((*(vuip)PYXIS_W0_MASK & 0xfff00000U) > 0x0ff00000U)) {
+                       PYXIS_DMA_WIN_BASE = *(vuip)PYXIS_W0_BASE & 0xfff00000U;
+                       PYXIS_DMA_WIN_SIZE = *(vuip)PYXIS_W0_MASK & 0xfff00000U;
+                       PYXIS_DMA_WIN_SIZE += 0x00100000U;
+#if 1
+                       printk("pyxis_init: using Window 0 settings\n");
+                       printk("pyxis_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
+                              *(vuip)PYXIS_W0_BASE,
+                              *(vuip)PYXIS_W0_MASK,
+                              *(vuip)PYXIS_T0_BASE);
+#endif
+                       break;
+               }
+
+               /* Check window 1 for enabled and mapped to 0.  */
+               if (((*(vuip)PYXIS_W1_BASE & 3) == 1)
+                   && (*(vuip)PYXIS_T1_BASE == 0)
+                   && ((*(vuip)PYXIS_W1_MASK & 0xfff00000U) > 0x0ff00000U)) {
+                       PYXIS_DMA_WIN_BASE = *(vuip)PYXIS_W1_BASE & 0xfff00000U;
+                       PYXIS_DMA_WIN_SIZE = *(vuip)PYXIS_W1_MASK & 0xfff00000U;
+                       PYXIS_DMA_WIN_SIZE += 0x00100000U;
+#if 1
+                       printk("pyxis_init: using Window 1 settings\n");
+                       printk("pyxis_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
+                              *(vuip)PYXIS_W1_BASE,
+                              *(vuip)PYXIS_W1_MASK,
+                              *(vuip)PYXIS_T1_BASE);
+#endif
+                       break;
+               }
+
+               /* Check window 2 for enabled and mapped to 0.  */
+               if (((*(vuip)PYXIS_W2_BASE & 3) == 1)
+                   && (*(vuip)PYXIS_T2_BASE == 0)
+                   && ((*(vuip)PYXIS_W2_MASK & 0xfff00000U) > 0x0ff00000U)) {
+                       PYXIS_DMA_WIN_BASE = *(vuip)PYXIS_W2_BASE & 0xfff00000U;
+                       PYXIS_DMA_WIN_SIZE = *(vuip)PYXIS_W2_MASK & 0xfff00000U;
+                       PYXIS_DMA_WIN_SIZE += 0x00100000U;
+#if 1
+                       printk("pyxis_init: using Window 2 settings\n");
+                       printk("pyxis_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
+                              *(vuip)PYXIS_W2_BASE,
+                              *(vuip)PYXIS_W2_MASK,
+                              *(vuip)PYXIS_T2_BASE);
+#endif
+                       break;
+               }
+
+               /* Check window 3 for enabled and mapped to 0.  */
+               if (((*(vuip)PYXIS_W3_BASE & 3) == 1)
+                   && (*(vuip)PYXIS_T3_BASE == 0)
+                   && ((*(vuip)PYXIS_W3_MASK & 0xfff00000U) > 0x0ff00000U)) {
+                       PYXIS_DMA_WIN_BASE = *(vuip)PYXIS_W3_BASE & 0xfff00000U;
+                       PYXIS_DMA_WIN_SIZE = *(vuip)PYXIS_W3_MASK & 0xfff00000U;
+                       PYXIS_DMA_WIN_SIZE += 0x00100000U;
+#if 1
+                       printk("pyxis_init: using Window 3 settings\n");
+                       printk("pyxis_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
+                              *(vuip)PYXIS_W3_BASE,
+                              *(vuip)PYXIS_W3_MASK,
+                              *(vuip)PYXIS_T3_BASE);
+#endif
+                       break;
+               }
+
+               /* Otherwise, we must use our defaults.  */
+               PYXIS_DMA_WIN_BASE = PYXIS_DMA_WIN_BASE_DEFAULT;
+               PYXIS_DMA_WIN_SIZE = PYXIS_DMA_WIN_SIZE_DEFAULT;
+#endif
+       case 0:
+               return 0;
+       }
+       return 1;
+}
+
+void __init
+pyxis_native_window_setup(void)
+{
+       /*
+        * Set up the PCI->physical memory translation windows.
+        * For now, windows 1,2 and 3 are disabled.  In the future, we may
+        * want to use them to do scatter/gather DMA. 
+        *
+        * Window 0 goes at 1 GB and is 1 GB large.
+        */
+
+       *(vuip)PYXIS_W0_BASE = 1U | (PYXIS_DMA_WIN_BASE_DEFAULT & 0xfff00000U);
+       *(vuip)PYXIS_W0_MASK = (PYXIS_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000U;
+       *(vuip)PYXIS_T0_BASE = 0;
+
+       *(vuip)PYXIS_W1_BASE = 0x0 ;
+       *(vuip)PYXIS_W2_BASE = 0x0 ;
+       *(vuip)PYXIS_W3_BASE = 0x0 ;
+       mb();
+}
+
+void __init
+pyxis_finish_init_arch(void)
+{
+       /*
+         * Next, clear the PYXIS_CFG register, which gets used
+        *  for PCI Config Space accesses. That is the way
+        *  we want to use it, and we do not want to depend on
+        *  what ARC or SRM might have left behind...
+        */
+       {
+               unsigned int pyxis_cfg, temp;
+               pyxis_cfg = *(vuip)PYXIS_CFG; mb();
+               if (pyxis_cfg != 0) {
+#if 1
+                       printk("PYXIS_init: CFG was 0x%x\n", pyxis_cfg);
+#endif
+                       *(vuip)PYXIS_CFG = 0; mb();
+                       temp = *(vuip)PYXIS_CFG;  /* re-read to force write */
+               }
+       }
+       /*
+        * Sigh... For the SRM setup, unless we know apriori what the HAE
+        * contents will be, we need to setup the arbitrary region bases
+        * so we can test against the range of addresses and tailor the
+        * region chosen for the SPARSE memory access.
+        *
+        * See include/asm-alpha/pyxis.h for the SPARSE mem read/write.
+        */
+       if (alpha_use_srm_setup) {
+               unsigned int pyxis_hae_mem = *(vuip)PYXIS_HAE_MEM;
+
+               alpha_mv.sm_base_r1 = (pyxis_hae_mem      ) & 0xe0000000UL;
+               alpha_mv.sm_base_r2 = (pyxis_hae_mem << 16) & 0xf8000000UL;
+               alpha_mv.sm_base_r3 = (pyxis_hae_mem << 24) & 0xfc000000UL;
+
+               /*
+                * Set the HAE cache, so that setup_arch() code
+                * will use the SRM setting always. Our readb/writeb
+                * code in pyxis.h expects never to have to change
+                * the contents of the HAE.
+                */
+               alpha_mv.hae_cache = pyxis_hae_mem;
+
+#ifndef CONFIG_ALPHA_GENERIC
+               /* In a generic kernel, we can always use BWIO.  */
+               alpha_mv.mv_readb = pyxis_srm_readb;
+               alpha_mv.mv_readw = pyxis_srm_readw;
+               alpha_mv.mv_writeb = pyxis_srm_writeb;
+               alpha_mv.mv_writew = pyxis_srm_writew;
+#endif
+       } else {
+               *(vuip)PYXIS_HAE_MEM = 0U; mb();
+               *(vuip)PYXIS_HAE_MEM; /* re-read to force write */
+               *(vuip)PYXIS_HAE_IO = 0; mb();
+               *(vuip)PYXIS_HAE_IO;  /* re-read to force write */
+        }
+
+       /*
+        * Finally, check that the PYXIS_CTRL1 has IOA_BEN set for
+        * enabling byte/word PCI bus space(s) access.
+        */
+       {
+               unsigned int ctrl1;
+               ctrl1 = *(vuip) PYXIS_CTRL1;
+               if (!(ctrl1 & 1)) {
+#if 1
+                       printk("PYXIS_init: enabling byte/word PCI space\n");
+#endif
+                       *(vuip) PYXIS_CTRL1 = ctrl1 | 1; mb();
+                       ctrl1 = *(vuip)PYXIS_CTRL1;  /* re-read */
+               }
+       }
+}
+
+void __init
+pyxis_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+{
+       pyxis_enable_errors();
+       if (!pyxis_srm_window_setup())
+               pyxis_native_window_setup();
+       pyxis_finish_init_arch();
+}
+
+static int
+pyxis_pci_clr_err(void)
+{
+       PYXIS_jd = *(vuip)PYXIS_ERR;
+       DBG(("PYXIS_pci_clr_err: PYXIS ERR after read 0x%x\n", PYXIS_jd));
+       *(vuip)PYXIS_ERR = 0x0180; mb();
+       PYXIS_jd = *(vuip)PYXIS_ERR;  /* re-read to force write */
+       return 0;
+}
+
+void
+pyxis_machine_check(unsigned long vector, unsigned long la_ptr,
+                   struct pt_regs * regs)
+{
+       struct el_common *mchk_header;
+       struct el_PYXIS_sysdata_mcheck *mchk_sysdata;
+
+       mchk_header = (struct el_common *)la_ptr;
+
+       mchk_sysdata = (struct el_PYXIS_sysdata_mcheck *)
+               (la_ptr + mchk_header->sys_offset);
+
+#if 0
+       DBG_MCK(("pyxis_machine_check: vector=0x%lx la_ptr=0x%lx\n",
+                vector, la_ptr));
+       DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
+                regs->pc, mchk_header->size, mchk_header->proc_offset,
+                mchk_header->sys_offset));
+       DBG_MCK(("pyxis_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
+                PYXIS_mcheck_expected, mchk_sysdata->epic_dcsr,
+                mchk_sysdata->epic_pear));
+#endif
+#ifdef DEBUG_MCHECK_DUMP
+       {
+               unsigned long *ptr;
+               int i;
+
+               ptr = (unsigned long *)la_ptr;
+               for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
+                       printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
+               }
+       }
+#endif /* DEBUG_MCHECK_DUMP */
+
+       /*
+        * Check if machine check is due to a badaddr() and if so,
+        * ignore the machine check.
+        */
+       mb();
+       mb();  /* magic */
+       if (PYXIS_mcheck_expected) {
+               DBG(("PYXIS machine check expected\n"));
+               PYXIS_mcheck_expected = 0;
+               PYXIS_mcheck_taken = 1;
+               mb();
+               mb();  /* magic */
+               draina();
+               pyxis_pci_clr_err();
+               wrmces(0x7);
+               mb();
+       }
+#if 1
+       else {
+               printk("PYXIS machine check NOT expected\n") ;
+               DBG_MCK(("pyxis_machine_check: vector=0x%lx la_ptr=0x%lx\n",
+                        vector, la_ptr));
+               DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x"
+                        " sysoffset 0x%x\n",
+                        regs->pc, mchk_header->size, mchk_header->proc_offset,
+                        mchk_header->sys_offset));
+               PYXIS_mcheck_expected = 0;
+               PYXIS_mcheck_taken = 1;
+               mb();
+               mb();  /* magic */
+               draina();
+               pyxis_pci_clr_err();
+               wrmces(0x7);
+               mb();
+       }
+#endif
+}
diff --git a/arch/alpha/kernel/core_t2.c b/arch/alpha/kernel/core_t2.c
new file mode 100644 (file)
index 0000000..13adb7b
--- /dev/null
@@ -0,0 +1,628 @@
+/*
+ *     linux/arch/alpha/kernel/core_t2.c
+ *
+ * Code common to all T2 core logic chips.
+ *
+ * Written by Jay A Estabrook (jestabro@amt.tay1.dec.com).
+ * December 1996.
+ *
+ * based on CIA code by David A Rusling (david.rusling@reo.mts.dec.com)
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+
+#define __EXTERN_INLINE
+#include <asm/io.h>
+#include <asm/core_t2.h>
+#undef __EXTERN_INLINE
+
+#include "proto.h"
+
+/*
+ * NOTE: Herein lie back-to-back mb instructions.  They are magic. 
+ * One plausible explanation is that the i/o controller does not properly
+ * handle the system transaction.  Another involves timing.  Ho hum.
+ */
+
+/*
+ * Machine check reasons.  Defined according to PALcode sources
+ * (osf.h and platform.h).
+ */
+#define MCHK_K_TPERR           0x0080
+#define MCHK_K_TCPERR          0x0082
+#define MCHK_K_HERR            0x0084
+#define MCHK_K_ECC_C           0x0086
+#define MCHK_K_ECC_NC          0x0088
+#define MCHK_K_OS_BUGCHECK     0x008A
+#define MCHK_K_PAL_BUGCHECK    0x0090
+
+/*
+ * BIOS32-style PCI interface:
+ */
+
+#ifdef DEBUG_CONF
+# define DBG(args)     printk args
+#else
+# define DBG(args)
+#endif
+
+#ifdef DEBUG_MCHECK
+# define DBGMC(args)   printk args
+#else
+# define DBGMC(args)
+#endif
+
+static volatile unsigned int T2_mcheck_expected[NR_CPUS];
+static volatile unsigned int T2_mcheck_taken[NR_CPUS];
+
+
+/*
+ * Given a bus, device, and function number, compute resulting
+ * configuration space address and setup the T2_HAXR2 register
+ * accordingly.  It is therefore not safe to have concurrent
+ * invocations to configuration space access routines, but there
+ * really shouldn't be any need for this.
+ *
+ * Type 0:
+ *
+ *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *     31:11   Device select bit.
+ *     10:8    Function number
+ *      7:2    Register number
+ *
+ * Type 1:
+ *
+ *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *     31:24   reserved
+ *     23:16   bus number (8 bits = 128 possible buses)
+ *     15:11   Device number (5 bits)
+ *     10:8    function number
+ *      7:2    register number
+ *  
+ * Notes:
+ *     The function number selects which function of a multi-function device 
+ *     (e.g., SCSI and Ethernet).
+ * 
+ *     The register selects a DWORD (32 bit) register offset.  Hence it
+ *     doesn't get shifted by 2 bits as we want to "drop" the bottom two
+ *     bits.
+ */
+
+static int
+mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr,
+            unsigned char *type1)
+{
+       unsigned long addr;
+
+       DBG(("mk_conf_addr(bus=%d, dfn=0x%x, where=0x%x,"
+            " addr=0x%lx, type1=0x%x)\n",
+            bus, device_fn, where, pci_addr, type1));
+
+       if (bus == 0) {
+               int device = device_fn >> 3;
+
+               /* Type 0 configuration cycle.  */
+
+               if (device > 8) {
+                       DBG(("mk_conf_addr: device (%d)>20, returning -1\n",
+                            device));
+                       return -1;
+               }
+
+               *type1 = 0;
+               addr = (0x0800L << device) | ((device_fn & 7) << 8) | (where);
+       } else {
+               /* Type 1 configuration cycle.  */
+               *type1 = 1;
+               addr = (bus << 16) | (device_fn << 8) | (where);
+       }
+       *pci_addr = addr;
+       DBG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
+       return 0;
+}
+
+static unsigned int
+conf_read(unsigned long addr, unsigned char type1)
+{
+       unsigned long flags;
+       unsigned int stat0, value, cpu;
+       unsigned long t2_cfg = 0;
+
+       cpu = smp_processor_id();
+
+       save_flags(flags);      /* avoid getting hit by machine check */
+       cli();
+
+       DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
+
+#if 0
+       /* Reset status register to avoid losing errors.  */
+       stat0 = *(vulp)T2_IOCSR;
+       *(vulp)T2_IOCSR = stat0;
+       mb();
+       DBG(("conf_read: T2 IOCSR was 0x%x\n", stat0));
+#endif
+
+       /* If Type1 access, must set T2 CFG.  */
+       if (type1) {
+               t2_cfg = *(vulp)T2_HAE_3 & ~0xc0000000UL;
+               *(vulp)T2_HAE_3 = 0x40000000UL | t2_cfg;
+               mb();
+               DBG(("conf_read: TYPE1 access\n"));
+       }
+       mb();
+       draina();
+
+       T2_mcheck_expected[cpu] = 1;
+       T2_mcheck_taken[cpu] = 0;
+       mb();
+
+       /* Access configuration space. */
+       value = *(vuip)addr;
+       mb();
+       mb();  /* magic */
+
+       if (T2_mcheck_taken[cpu]) {
+               T2_mcheck_taken[cpu] = 0;
+               value = 0xffffffffU;
+               mb();
+       }
+       T2_mcheck_expected[cpu] = 0;
+       mb();
+
+       /* If Type1 access, must reset T2 CFG so normal IO space ops work.  */
+       if (type1) {
+               *(vulp)T2_HAE_3 = t2_cfg;
+               mb();
+       }
+       DBG(("conf_read(): finished\n"));
+
+       restore_flags(flags);
+       return value;
+}
+
+static void
+conf_write(unsigned long addr, unsigned int value, unsigned char type1)
+{
+       unsigned long flags;
+       unsigned int stat0, cpu;
+       unsigned long t2_cfg = 0;
+
+       cpu = smp_processor_id();
+
+       save_flags(flags);      /* avoid getting hit by machine check */
+       cli();
+
+#if 0
+       /* Reset status register to avoid losing errors.  */
+       stat0 = *(vulp)T2_IOCSR;
+       *(vulp)T2_IOCSR = stat0;
+       mb();
+       DBG(("conf_write: T2 ERR was 0x%x\n", stat0));
+#endif
+
+       /* If Type1 access, must set T2 CFG.  */
+       if (type1) {
+               t2_cfg = *(vulp)T2_HAE_3 & ~0xc0000000UL;
+               *(vulp)T2_HAE_3 = t2_cfg | 0x40000000UL;
+               mb();
+               DBG(("conf_write: TYPE1 access\n"));
+       }
+       mb();
+       draina();
+
+       T2_mcheck_expected[cpu] = 1;
+       mb();
+
+       /* Access configuration space.  */
+       *(vuip)addr = value;
+       mb();
+       mb();  /* magic */
+
+       T2_mcheck_expected[cpu] = 0;
+       mb();
+
+       /* If Type1 access, must reset T2 CFG so normal IO space ops work.  */
+       if (type1) {
+               *(vulp)T2_HAE_3 = t2_cfg;
+               mb();
+       }
+       DBG(("conf_write(): finished\n"));
+       restore_flags(flags);
+}
+
+
+int
+t2_pcibios_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value)
+{
+       unsigned long addr = T2_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       *value = 0xff;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x00;
+       *value = conf_read(addr, type1) >> ((where & 3) * 8);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+t2_pcibios_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value)
+{
+       unsigned long addr = T2_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       *value = 0xffff;
+       if (where & 0x1)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x08;
+       *value = conf_read(addr, type1) >> ((where & 3) * 8);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+t2_pcibios_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value)
+{
+       unsigned long addr = T2_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       *value = 0xffffffff;
+       if (where & 0x3)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x18;
+       *value = conf_read(addr, type1);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+t2_pcibios_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value)
+{
+       unsigned long addr = T2_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x00;
+       conf_write(addr, value << ((where & 3) * 8), type1);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int
+t2_pcibios_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value)
+{
+       unsigned long addr = T2_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       if (where & 0x1)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x08;
+       conf_write(addr, value << ((where & 3) * 8), type1);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+t2_pcibios_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value)
+{
+       unsigned long addr = T2_CONF;
+       unsigned long pci_addr;
+       unsigned char type1;
+
+       if (where & 0x3)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr |= (pci_addr << 5) + 0x18;
+       conf_write(addr, value << ((where & 3) * 8), type1);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+void __init
+t2_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+{
+       unsigned long t2_err;
+       unsigned int i;
+
+       for (i = 0; i < NR_CPUS; i++) {
+               T2_mcheck_expected[i] = 0;
+               T2_mcheck_taken[i] = 0;
+       }
+
+#if 0
+       /* 
+        * Set up error reporting.
+        */
+       t2_err = *(vulp)T2_IOCSR ;
+       t2_err |= (0x1 << 7) ;   /* master abort */
+       *(vulp)T2_IOCSR = t2_err ;
+       mb() ;
+#endif
+
+       printk("t2_init: HBASE was 0x%lx\n", *(vulp)T2_HBASE);
+#if 0
+       printk("t2_init: WBASE1=0x%lx WMASK1=0x%lx TBASE1=0x%lx\n",
+              *(vulp)T2_WBASE1,
+              *(vulp)T2_WMASK1,
+              *(vulp)T2_TBASE1);
+       printk("t2_init: WBASE2=0x%lx WMASK2=0x%lx TBASE2=0x%lx\n",
+              *(vulp)T2_WBASE2,
+              *(vulp)T2_WMASK2,
+              *(vulp)T2_TBASE2);
+#endif
+
+       switch (alpha_use_srm_setup) 
+       {
+       default:
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
+               /* Check window 1 for enabled and mapped to 0.  */
+               if (((*(vulp)T2_WBASE1 & (3UL<<18)) == (2UL<<18))
+                   && (*(vulp)T2_TBASE1 == 0)) {
+                       T2_DMA_WIN_BASE = *(vulp)T2_WBASE1 & 0xfff00000UL;
+                       T2_DMA_WIN_SIZE = *(vulp)T2_WMASK1 & 0xfff00000UL;
+                       T2_DMA_WIN_SIZE += 0x00100000UL;
+                       /* DISABLE window 2!! ?? */
+#if 1
+                       printk("t2_init: using Window 1 settings\n");
+                       printk("t2_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
+                              *(vulp)T2_WBASE1,
+                              *(vulp)T2_WMASK1,
+                              *(vulp)T2_TBASE1);
+#endif
+                       break;
+               }
+
+               /* Check window 2 for enabled and mapped to 0.  */
+               if (((*(vulp)T2_WBASE2 & (3UL<<18)) == (2UL<<18))
+                   && (*(vulp)T2_TBASE2 == 0)) {
+                       T2_DMA_WIN_BASE = *(vulp)T2_WBASE2 & 0xfff00000UL;
+                       T2_DMA_WIN_SIZE = *(vulp)T2_WMASK2 & 0xfff00000UL;
+                       T2_DMA_WIN_SIZE += 0x00100000UL;
+                       /* DISABLE window 1!! ?? */
+#if 1
+                       printk("t2_init: using Window 2 settings\n");
+                       printk("t2_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
+                              *(vulp)T2_WBASE2,
+                              *(vulp)T2_WMASK2,
+                              *(vulp)T2_TBASE2);
+#endif
+                       break;
+               }
+
+               /* Otherwise, we must use our defaults.  */
+               T2_DMA_WIN_BASE = T2_DMA_WIN_BASE_DEFAULT;
+               T2_DMA_WIN_SIZE = T2_DMA_WIN_SIZE_DEFAULT;
+#endif
+       case 0:
+               /*
+                * Set up the PCI->physical memory translation windows.
+                * For now, window 2 is  disabled.  In the future, we may
+                * want to use it to do scatter/gather DMA. 
+                *
+                * Window 1 goes at 1 GB and is 1 GB large.
+                */
+
+               /* WARNING!! must correspond to the DMA_WIN params!!! */
+               *(vulp)T2_WBASE1 = 0x400807ffU;
+               *(vulp)T2_WMASK1 = 0x3ff00000U;
+               *(vulp)T2_TBASE1 = 0;
+
+               *(vulp)T2_WBASE2 = 0x0;
+               *(vulp)T2_HBASE = 0x0;
+               break;
+       }
+
+       /*
+        * Sigh... For the SRM setup, unless we know apriori what the HAE
+        * contents will be, we need to setup the arbitrary region bases
+        * so we can test against the range of addresses and tailor the
+        * region chosen for the SPARSE memory access.
+        *
+        * See include/asm-alpha/t2.h for the SPARSE mem read/write.
+        */
+       if (alpha_use_srm_setup) {
+               unsigned long t2_hae_1 = *(vulp)T2_HAE_1;
+
+               alpha_mv.sm_base_r1 = (t2_hae_1 << 27) & 0xf8000000UL;
+
+               /*
+                * Set the HAE cache, so that setup_arch() code
+                * will use the SRM setting always. Our readb/writeb
+                * code in .h expects never to have to change
+                * the contents of the HAE.
+                */
+               alpha_mv.hae_cache = t2_hae_1;
+
+               alpha_mv.mv_readb = t2_srm_readb;
+               alpha_mv.mv_readw = t2_srm_readw;
+               alpha_mv.mv_writeb = t2_srm_writeb;
+               alpha_mv.mv_writew = t2_srm_writew;
+       } else {
+               *(vulp)T2_HAE_1 = 0; mb();
+               *(vulp)T2_HAE_2 = 0; mb();
+               *(vulp)T2_HAE_3 = 0; mb();
+#if 0
+               *(vulp)T2_HAE_4 = 0; mb(); /* do not touch this */
+#endif
+       }
+}
+
+#define SIC_SEIC (1UL << 33)    /* System Event Clear */
+
+static int
+t2_clear_errors(void)
+{
+       unsigned int cpu = smp_processor_id();
+       static struct sable_cpu_csr *cpu_regs = NULL;
+
+       switch (cpu)
+       {
+       case 0: cpu_regs = (struct sable_cpu_csr *)T2_CPU0_BASE; break;
+       case 1: cpu_regs = (struct sable_cpu_csr *)T2_CPU1_BASE; break;
+       case 2: cpu_regs = (struct sable_cpu_csr *)T2_CPU2_BASE; break;
+       case 3: cpu_regs = (struct sable_cpu_csr *)T2_CPU3_BASE; break;
+       }
+
+       DBGMC(("???????? t2_clear_errors\n"));
+
+       cpu_regs->sic &= ~SIC_SEIC;
+
+       /* 
+        * clear CPU errors
+        */
+       cpu_regs->bcce |= cpu_regs->bcce;
+       cpu_regs->cbe  |= cpu_regs->cbe;
+       cpu_regs->bcue |= cpu_regs->bcue;
+       cpu_regs->dter |= cpu_regs->dter;
+
+       *(vulp)T2_CERR1 |= *(vulp)T2_CERR1;
+       *(vulp)T2_PERR1 |= *(vulp)T2_PERR1;
+
+       mb();
+       mb();  /* magic */
+       return 0;
+}
+
+void
+t2_machine_check(unsigned long vector, unsigned long la_ptr,
+                struct pt_regs * regs)
+{
+       struct el_t2_logout_header *mchk_header;
+       struct el_t2_procdata_mcheck *mchk_procdata;
+       struct el_t2_sysdata_mcheck *mchk_sysdata;
+       unsigned long * ptr;
+       const char * reason;
+       char buf[128];
+       long i;
+       unsigned int cpu = smp_processor_id();
+
+       DBGMC(("t2_machine_check: vector=0x%lx la_ptr=0x%lx\n",
+              vector, la_ptr));
+
+       mchk_header = (struct el_t2_logout_header *)la_ptr;
+
+       DBGMC(("t2_machine_check: susoffset=0x%lx procoffset=0x%lx\n",
+              mchk_header->elfl_sysoffset, mchk_header->elfl_procoffset));
+
+       mchk_sysdata = (struct el_t2_sysdata_mcheck *)
+               (la_ptr + mchk_header->elfl_sysoffset);
+       mchk_procdata = (struct el_t2_procdata_mcheck *)
+               (la_ptr + mchk_header->elfl_procoffset - sizeof(unsigned long)*32);
+
+       DBGMC(("         pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
+              regs->pc, mchk_header->elfl_size, mchk_header->elfl_procoffset,
+              mchk_header->elfl_sysoffset));
+       DBGMC(("t2_machine_check: expected %d\n", T2_mcheck_expected[cpu]));
+
+#ifdef DEBUG_DUMP
+       {
+               unsigned long *ptr;
+               int i;
+
+               ptr = (unsigned long *)la_ptr;
+               for (i = 0; i < mchk_header->elfl_size/sizeof(long); i += 2) {
+                       printk(" +%lx %lx %lx\n", i*sizeof(long),
+                              ptr[i], ptr[i+1]);
+               }
+       }
+#endif /* DEBUG_DUMP */
+
+       /*
+        * Check if machine check is due to a badaddr() and if so,
+        * ignore the machine check.
+        */
+       mb();
+       mb();  /* magic */
+       if (T2_mcheck_expected[cpu]) {
+               DBGMC(("T2 machine check expected\n"));
+               T2_mcheck_taken[cpu] = 1;
+               t2_clear_errors();
+               T2_mcheck_expected[cpu] = 0;
+               mb();
+               mb();  /* magic */
+               wrmces(rdmces()|1);/* ??? */
+               draina();
+               return;
+       }
+
+       switch ((unsigned int) mchk_header->elfl_error_type) {
+       case MCHK_K_TPERR:      reason = "tag parity error"; break;
+       case MCHK_K_TCPERR:     reason = "tag control parity error"; break;
+       case MCHK_K_HERR:       reason = "generic hard error"; break;
+       case MCHK_K_ECC_C:      reason = "correctable ECC error"; break;
+       case MCHK_K_ECC_NC:     reason = "uncorrectable ECC error"; break;
+       case MCHK_K_OS_BUGCHECK: reason = "OS-specific PAL bugcheck"; break;
+       case MCHK_K_PAL_BUGCHECK: reason = "callsys in kernel mode"; break;
+       case 0x96: reason = "i-cache read retryable error"; break;
+       case 0x98: reason = "processor detected hard error"; break;
+
+               /* System specific (these are for Alcor, at least): */
+       case 0x203: reason = "system detected uncorrectable ECC error"; break;
+       case 0x205: reason = "parity error detected by T2"; break;
+       case 0x207: reason = "non-existent memory error"; break;
+       case 0x209: reason = "PCI SERR detected"; break;
+       case 0x20b: reason = "PCI data parity error detected"; break;
+       case 0x20d: reason = "PCI address parity error detected"; break;
+       case 0x20f: reason = "PCI master abort error"; break;
+       case 0x211: reason = "PCI target abort error"; break;
+       case 0x213: reason = "scatter/gather PTE invalid error"; break;
+       case 0x215: reason = "flash ROM write error"; break;
+       case 0x217: reason = "IOA timeout detected"; break;
+       case 0x219: reason = "IOCHK#, EISA add-in board parity or other catastrophic error"; break;
+       case 0x21b: reason = "EISA fail-safe timer timeout"; break;
+       case 0x21d: reason = "EISA bus time-out"; break;
+       case 0x21f: reason = "EISA software generated NMI"; break;
+       case 0x221: reason = "unexpected ev5 IRQ[3] interrupt"; break;
+       default:
+               sprintf(buf, "reason for machine-check unknown (0x%x)",
+                       (unsigned int) mchk_header->elfl_error_type);
+               reason = buf;
+               break;
+       }
+       wrmces(rdmces()|1);     /* reset machine check pending flag */
+       mb();
+
+       printk(KERN_CRIT "  T2 machine check: %s%s\n",
+              reason, mchk_header->elfl_retry ? " (retryable)" : "");
+
+       /* Dump the logout area to give all info.  */
+
+       ptr = (unsigned long *)la_ptr;
+       for (i = 0; i < mchk_header->elfl_size / sizeof(long); i += 2) {
+               printk(KERN_CRIT " +%8lx %016lx %016lx\n",
+                      i*sizeof(long), ptr[i], ptr[i+1]);
+       }
+}
diff --git a/arch/alpha/kernel/core_tsunami.c b/arch/alpha/kernel/core_tsunami.c
new file mode 100644 (file)
index 0000000..382a976
--- /dev/null
@@ -0,0 +1,446 @@
+/*
+ *     linux/arch/alpha/kernel/core_tsunami.c
+ *
+ * Code common to all TSUNAMI core logic chips.
+ *
+ * Based on code written by David A. Rusling (david.rusling@reo.mts.dec.com).
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+
+#define __EXTERN_INLINE inline
+#include <asm/io.h>
+#include <asm/core_tsunami.h>
+#undef __EXTERN_INLINE
+
+#include "proto.h"
+
+/*
+ * NOTE: Herein lie back-to-back mb instructions.  They are magic. 
+ * One plausible explanation is that the I/O controller does not properly
+ * handle the system transaction.  Another involves timing.  Ho hum.
+ */
+
+/*
+ * BIOS32-style PCI interface:
+ */
+
+#ifdef DEBUG 
+# define DBG(args)     printk args
+#else
+# define DBG(args)
+#endif
+
+#define DEBUG_MCHECK
+#ifdef DEBUG_MCHECK
+# define DBG_MCK(args) printk args
+#define DEBUG_MCHECK_DUMP
+#else
+# define DBG_MCK(args)
+#endif
+
+static volatile unsigned int TSUNAMI_mcheck_expected[NR_CPUS];
+static volatile unsigned int TSUNAMI_mcheck_taken[NR_CPUS];
+static unsigned int TSUNAMI_jd[NR_CPUS];
+
+
+/*
+ * Given a bus, device, and function number, compute resulting
+ * configuration space address
+ * accordingly.  It is therefore not safe to have concurrent
+ * invocations to configuration space access routines, but there
+ * really shouldn't be any need for this.
+ *
+ * Note that all config space accesses use Type 1 address format.
+ *
+ * Note also that type 1 is determined by non-zero bus number.
+ *
+ * Type 1:
+ *
+ *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *     31:24   reserved
+ *     23:16   bus number (8 bits = 128 possible buses)
+ *     15:11   Device number (5 bits)
+ *     10:8    function number
+ *      7:2    register number
+ *  
+ * Notes:
+ *     The function number selects which function of a multi-function device 
+ *     (e.g., SCSI and Ethernet).
+ * 
+ *     The register selects a DWORD (32 bit) register offset.  Hence it
+ *     doesn't get shifted by 2 bits as we want to "drop" the bottom two
+ *     bits.
+ */
+
+static int
+mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr,
+            unsigned char *type1)
+{
+       unsigned long addr;
+
+       DBG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
+            "pci_addr=0x%p, type1=0x%p)\n",
+            bus, device_fn, where, pci_addr, type1));
+
+       if (bus == 0) {
+               *type1 = 0;
+       } else {
+               /* Type 1 configuration cycle.  */
+               *type1 = 1;
+       }
+       addr = (bus << 16) | (device_fn << 8) | (where);
+       *pci_addr = addr;
+       DBG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
+       return 0;
+}
+
+int 
+tsunami_pcibios_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value)
+{
+       unsigned long addr;
+       unsigned char type1;
+
+       *value = 0xff;
+       if (mk_conf_addr(bus, device_fn, where, &addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       *value = __kernel_ldbu(*(vucp)(addr+TSUNAMI_PCI0_CONF));
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int
+tsunami_pcibios_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value)
+{
+       unsigned long addr;
+       unsigned char type1;
+
+       *value = 0xffff;
+       if (where & 0x1)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       *value = __kernel_ldwu(*(vusp)(addr+TSUNAMI_PCI0_CONF));
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int
+tsunami_pcibios_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value)
+{
+       unsigned long addr;
+       unsigned char type1;
+
+       *value = 0xffffffff;
+       if (where & 0x3)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       *value = *(vuip)(addr+TSUNAMI_PCI0_CONF);
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+tsunami_pcibios_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value)
+{
+       unsigned long addr;
+       unsigned char type1;
+
+       if (mk_conf_addr(bus, device_fn, where, &addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       __kernel_stb(value, *(vucp)(addr+TSUNAMI_PCI0_CONF));
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int 
+tsunami_pcibios_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value)
+{
+       unsigned long addr;
+       unsigned char type1;
+
+       if (where & 0x1)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       __kernel_stw(value, *(vusp)(addr+TSUNAMI_PCI0_CONF));
+       return PCIBIOS_SUCCESSFUL;
+}
+
+int
+tsunami_pcibios_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value)
+{
+       unsigned long addr;
+       unsigned char type1;
+
+       if (where & 0x3)
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       if (mk_conf_addr(bus, device_fn, where, &addr, &type1))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       *(vuip)(addr+TSUNAMI_PCI0_CONF) = value;
+       return PCIBIOS_SUCCESSFUL;
+}
+
+void __init
+tsunami_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+{
+        unsigned long tsunami_err;
+       unsigned int i;
+
+#if 0
+       printk("tsunami_init: CChip registers:\n");
+       printk("CSR_CSC 0x%lx\n", *(vulp)TSUNAMI_CSR_CSC);
+       printk("CSR_MTR 0x%lx\n", *(vulp)TSUNAMI_CSR_MTR);
+       printk("CSR_MISC 0x%lx\n", *(vulp)TSUNAMI_CSR_MISC);
+       printk("CSR_DIM0 0x%lx\n", *(vulp)TSUNAMI_CSR_DIM0);
+       printk("CSR_DIM1 0x%lx\n", *(vulp)TSUNAMI_CSR_DIM1);
+       printk("CSR_DIR0 0x%lx\n", *(vulp)TSUNAMI_CSR_DIR0);
+       printk("CSR_DIR1 0x%lx\n", *(vulp)TSUNAMI_CSR_DIR1);
+       printk("CSR_DRIR 0x%lx\n", *(vulp)TSUNAMI_CSR_DRIR);
+
+       printk("tsunami_init: DChip registers:\n");
+       printk("CSR_DSC 0x%lx\n", *(vulp)TSUNAMI_CSR_DSC);
+       printk("CSR_STR 0x%lx\n", *(vulp)TSUNAMI_CSR_STR);
+       printk("CSR_DREV 0x%lx\n", *(vulp)TSUNAMI_CSR_DREV);
+
+       printk("tsunami_init: PChip registers:\n");
+       printk("PCHIP0_WSBA0 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSBA0);
+       printk("PCHIP0_WSBA1 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSBA1);
+       printk("PCHIP0_WSBA2 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSBA2);
+       printk("PCHIP0_WSBA3 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSBA3);
+       printk("PCHIP0_WSM0 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSM0);
+       printk("PCHIP0_WSM1 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSM1);
+       printk("PCHIP0_WSM2 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSM2);
+       printk("PCHIP0_WSM3 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSM3);
+       printk("PCHIP0_TBA0 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_TBA0);
+       printk("PCHIP0_TBA1 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_TBA1);
+       printk("PCHIP0_TBA2 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_TBA2);
+       printk("PCHIP0_TBA3 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_TBA3);
+       printk("PCHIP0_PCTL 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_PCTL);
+       printk("PCHIP0_PLAT 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_PLAT);
+       printk("PCHIP0_PERROR 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_PERROR);
+       printk("PCHIP0_PERRMASK 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_PERRMASK);
+#endif
+
+       for (i = 0; i < NR_CPUS; i++) {
+               TSUNAMI_mcheck_expected[i] = 0;
+               TSUNAMI_mcheck_taken[i] = 0;
+       }
+
+#ifdef NOT_YET
+        /* 
+        * Set up error reporting. Make sure CPU_PE is OFF in the mask.
+        */
+       tsunami_err = *(vulp)TSUNAMI_PCHIP0_PERRMASK;
+       tsunami_err &= ~20;   
+       *(vulp)TSUNAMI_PCHIP0_PERRMASK = tsunami_err;
+       mb();
+       tsunami_err = *(vulp)TSUNAMI_PCHIP0_PERRMASK;
+
+       tsunami_err = *(vulp)TSUNAMI_PCHIP0_PERROR ;
+       tsunami_err |= 0x40;   /* master/target abort */
+       *(vulp)TSUNAMI_PCHIP0_PERROR = tsunami_err ;
+       mb() ;
+       tsunami_err = *(vulp)TSUNAMI_PCHIP0_PERROR ;
+#endif /* NOT_YET */
+
+       switch (alpha_use_srm_setup)
+       {
+       default:
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
+               /* Check window 0 for enabled and mapped to 0.  */
+               if (((*(vulp)TSUNAMI_PCHIP0_WSBA0 & 3) == 1)
+                   && (*(vulp)TSUNAMI_PCHIP0_TBA0 == 0)
+                   && ((*(vulp)TSUNAMI_PCHIP0_WSM0 & 0xfff00000U) > 0x0ff00000U)) {
+                       TSUNAMI_DMA_WIN_BASE = *(vulp)TSUNAMI_PCHIP0_WSBA0 & 0xfff00000U;
+                       TSUNAMI_DMA_WIN_SIZE = *(vulp)TSUNAMI_PCHIP0_WSM0 & 0xfff00000U;
+                       TSUNAMI_DMA_WIN_SIZE += 0x00100000U;
+#if 1
+                       printk("tsunami_init: using Window 0 settings\n");
+                       printk("tsunami_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
+                              *(vulp)TSUNAMI_PCHIP0_WSBA0,
+                              *(vulp)TSUNAMI_PCHIP0_WSM0,
+                              *(vulp)TSUNAMI_PCHIP0_TBA0);
+#endif
+                       break;
+               }
+
+               /* Check window 1 for enabled and mapped to 0.  */
+               if (((*(vulp)TSUNAMI_PCHIP0_WSBA1 & 3) == 1)
+                   && (*(vulp)TSUNAMI_PCHIP0_TBA1 == 0)
+                   && ((*(vulp)TSUNAMI_PCHIP0_WSM1 & 0xfff00000U) > 0x0ff00000U)) {
+                       TSUNAMI_DMA_WIN_BASE = *(vulp)TSUNAMI_PCHIP0_WSBA1 & 0xfff00000U;
+                       TSUNAMI_DMA_WIN_SIZE = *(vulp)TSUNAMI_PCHIP0_WSM1 & 0xfff00000U;
+                       TSUNAMI_DMA_WIN_SIZE += 0x00100000U;
+#if 1
+                       printk("tsunami_init: using Window 1 settings\n");
+                       printk("tsunami_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
+                              *(vulp)TSUNAMI_PCHIP0_WSBA1,
+                              *(vulp)TSUNAMI_PCHIP0_WSM1,
+                              *(vulp)TSUNAMI_PCHIP0_TBA1);
+#endif
+                       break;
+               }
+
+               /* Check window 2 for enabled and mapped to 0.  */
+               if (((*(vulp)TSUNAMI_PCHIP0_WSBA2 & 3) == 1)
+                   && (*(vulp)TSUNAMI_PCHIP0_TBA2 == 0)
+                   && ((*(vulp)TSUNAMI_PCHIP0_WSM2 & 0xfff00000U) > 0x0ff00000U)) {
+                       TSUNAMI_DMA_WIN_BASE = *(vulp)TSUNAMI_PCHIP0_WSBA2 & 0xfff00000U;
+                       TSUNAMI_DMA_WIN_SIZE = *(vulp)TSUNAMI_PCHIP0_WSM2 & 0xfff00000U;
+                       TSUNAMI_DMA_WIN_SIZE += 0x00100000U;
+#if 1
+                       printk("tsunami_init: using Window 2 settings\n");
+                       printk("tsunami_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
+                              *(vulp)TSUNAMI_PCHIP0_WSBA2,
+                              *(vulp)TSUNAMI_PCHIP0_WSM2,
+                              *(vulp)TSUNAMI_PCHIP0_TBA2);
+#endif
+                       break;
+               }
+
+               /* Check window 3 for enabled and mapped to 0.  */
+               if (((*(vulp)TSUNAMI_PCHIP0_WSBA3 & 3) == 1)
+                   && (*(vulp)TSUNAMI_PCHIP0_TBA3 == 0)
+                   && ((*(vulp)TSUNAMI_PCHIP0_WSM3 & 0xfff00000U) > 0x0ff00000U)) {
+                       TSUNAMI_DMA_WIN_BASE = *(vulp)TSUNAMI_PCHIP0_WSBA3 & 0xfff00000U;
+                       TSUNAMI_DMA_WIN_SIZE = *(vulp)TSUNAMI_PCHIP0_WSM3 & 0xfff00000U;
+                       TSUNAMI_DMA_WIN_SIZE += 0x00100000U;
+#if 1
+                       printk("tsunami_init: using Window 3 settings\n");
+                       printk("tsunami_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
+                              *(vulp)TSUNAMI_PCHIP0_WSBA3,
+                              *(vulp)TSUNAMI_PCHIP0_WSM3,
+                              *(vulp)TSUNAMI_PCHIP0_TBA3);
+#endif
+                       break;
+               }
+
+               /* Otherwise, we must use our defaults.  */
+               TSUNAMI_DMA_WIN_BASE = TSUNAMI_DMA_WIN_BASE_DEFAULT;
+               TSUNAMI_DMA_WIN_SIZE = TSUNAMI_DMA_WIN_SIZE_DEFAULT;
+#endif
+       case 0:
+               /*
+                * Set up the PCI->physical memory translation windows.
+                * For now, windows 1,2 and 3 are disabled.  In the future,
+                * we may want to use them to do scatter/gather DMA. 
+                *
+                * Window 0 goes at 1 GB and is 1 GB large.
+                */
+
+               *(vulp)TSUNAMI_PCHIP0_WSBA0
+                       = 1L | (TSUNAMI_DMA_WIN_BASE_DEFAULT & 0xfff00000U);
+               *(vulp)TSUNAMI_PCHIP0_WSM0
+                       = (TSUNAMI_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000UL;
+               *(vulp)TSUNAMI_PCHIP0_TBA0 = 0UL;
+
+               *(vulp)TSUNAMI_PCHIP0_WSBA1 = 0UL;
+               *(vulp)TSUNAMI_PCHIP0_WSBA2 = 0UL;
+               *(vulp)TSUNAMI_PCHIP0_WSBA3 = 0UL;
+               mb();
+       }
+}
+
+static int
+tsunami_pci_clr_err(void)
+{
+       unsigned int cpu = smp_processor_id();
+
+       TSUNAMI_jd[cpu] = *((vulp)TSUNAMI_PCHIP0_PERROR);
+       DBG(("TSUNAMI_pci_clr_err: PERROR after read 0x%x\n",TSUNAMI_jd[cpu]));
+       *((vulp)TSUNAMI_PCHIP0_PERROR) = 0x040; mb();
+       TSUNAMI_jd[cpu] = *((vulp)TSUNAMI_PCHIP0_PERROR);
+       return 0;
+}
+
+void
+tsunami_machine_check(unsigned long vector, unsigned long la_ptr,
+                     struct pt_regs * regs)
+{
+#if 1
+        printk("TSUNAMI machine check ignored\n") ;
+#else
+       struct el_common *mchk_header;
+       struct el_TSUNAMI_sysdata_mcheck *mchk_sysdata;
+       unsigned int cpu = smp_processor_id();
+
+       mchk_header = (struct el_common *)la_ptr;
+
+       mchk_sysdata = (struct el_TSUNAMI_sysdata_mcheck *)
+               (la_ptr + mchk_header->sys_offset);
+
+#if 0
+       DBG_MCK(("tsunami_machine_check: vector=0x%lx la_ptr=0x%lx\n",
+                vector, la_ptr));
+       DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
+                regs->pc, mchk_header->size, mchk_header->proc_offset,
+                mchk_header->sys_offset));
+       DBG_MCK(("tsunami_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
+                TSUNAMI_mcheck_expected[cpu], mchk_sysdata->epic_dcsr,
+                mchk_sysdata->epic_pear));
+#endif
+#ifdef DEBUG_MCHECK_DUMP
+       {
+               unsigned long *ptr;
+               int i;
+
+               ptr = (unsigned long *)la_ptr;
+               for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
+                       printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
+               }
+       }
+#endif /* DEBUG_MCHECK_DUMP */
+       /*
+        * Check if machine check is due to a badaddr() and if so,
+        * ignore the machine check.
+        */
+       mb();
+       mb();  /* magic */
+       if (TSUNAMI_mcheck_expected[cpu]) {
+               DBG(("TSUNAMI machine check expected\n"));
+               TSUNAMI_mcheck_expected[cpu] = 0;
+               TSUNAMI_mcheck_taken[cpu] = 1;
+               mb();
+               mb();  /* magic */
+               draina();
+               tsunami_pci_clr_err();
+               wrmces(0x7);
+               mb();
+       }
+#if 1
+       else {
+               printk("TSUNAMI machine check NOT expected\n") ;
+               DBG_MCK(("tsunami_machine_check: vector=0x%lx la_ptr=0x%lx\n",
+                        vector, la_ptr));
+               DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
+                        regs->pc, mchk_header->size, mchk_header->proc_offset,
+                        mchk_header->sys_offset));
+               TSUNAMI_mcheck_expected[cpu] = 0;
+               TSUNAMI_mcheck_taken[cpu] = 1;
+               mb();
+               mb();  /* magic */
+               draina();
+               tsunami_pci_clr_err();
+               wrmces(0x7);
+               mb();
+       }
+#endif
+#endif
+}
index eb13590fc22a81a15e7d16bd17a6b542c6349c16..79b0d818cd6012961affd3e45c64ce8af2b4c417 100644 (file)
@@ -15,7 +15,7 @@
 #define osf_vfork sys_fork
 
 /*
- * These offsets must match with "struct hae" in io.h:
+ * These offsets must match with alpha_mv in <asm/machvec.h>.
  */
 #define HAE_CACHE      0
 #define HAE_REG                8
        stq     $3,24($30);             \
        stq     $4,32($30);             \
        stq     $28,144($30);           \
-       lda     $2,hae;                 \
+       lda     $2,alpha_mv;            \
        stq     $5,40($30);             \
        stq     $6,48($30);             \
        stq     $7,56($30);             \
        stq     $18,176($30)
 
 #define RESTORE_ALL                    \
-       lda     $19,hae;                \
+       lda     $19,alpha_mv;           \
        ldq     $0,0($30);              \
        ldq     $1,8($30);              \
        ldq     $2,16($30);             \
@@ -1135,7 +1135,7 @@ sys_call_table:
        .quad sys_sysinfo
        .quad sys_sysctl
        .quad sys_idle                          /* 320 */
-       .quad sys_umount
+       .quad sys_oldumount
        .quad sys_swapon
        .quad sys_times
        .quad sys_personality
diff --git a/arch/alpha/kernel/es1888.c b/arch/alpha/kernel/es1888.c
new file mode 100644 (file)
index 0000000..10115ac
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *     linux/arch/alpha/kernel/es1888.c
+ *
+ * Init the built-in ES1888 sound chip (SB16 compatible)
+ */
+
+#include <linux/init.h>
+#include <asm/io.h>
+#include "proto.h"
+
+void __init
+es1888_init(void)
+{
+       /* Sequence of IO reads to init the audio controller */
+       inb(0x0229);
+       inb(0x0229);
+       inb(0x0229);
+       inb(0x022b);
+       inb(0x0229);
+       inb(0x022b);
+       inb(0x0229);
+       inb(0x0229);
+       inb(0x022b);
+       inb(0x0229);
+       inb(0x0220); /* This sets the base address to 0x220 */
+
+       /* Sequence to set DMA channels */
+       outb(0x01, 0x0226);             /* reset */
+       inb(0x0226);                    /* pause */
+       outb(0x00, 0x0226);             /* release reset */
+       while (!(inb(0x022e) & 0x80))   /* wait for bit 7 to assert*/
+               continue;
+       inb(0x022a);                    /* pause */
+       outb(0xc6, 0x022c);             /* enable extended mode */
+       while (inb(0x022c) & 0x80)      /* wait for bit 7 to deassert */
+               continue;
+       outb(0xb1, 0x022c);             /* setup for write to Interrupt CR */
+       while (inb(0x022c) & 0x80)      /* wait for bit 7 to deassert */
+               continue;
+       outb(0x14, 0x022c);             /* set IRQ 5 */
+       while (inb(0x022c) & 0x80)      /* wait for bit 7 to deassert */
+               continue;
+       outb(0xb2, 0x022c);             /* setup for write to DMA CR */
+       while (inb(0x022c) & 0x80)      /* wait for bit 7 to deassert */
+               continue;
+       outb(0x18, 0x022c);             /* set DMA channel 1 */
+}
index 502144058d1c081e50f91844cb4c35640feb1b8b..6da94c0cbb6145e2b0e8f9e48e91e468caffbb38 100644 (file)
@@ -4,62 +4,58 @@
  * (C) Copyright 1998 Linus Torvalds
  */
 
+#ifdef __alpha_cix__
+#define STT(reg,val)  asm volatile ("ftoit $f"#reg",%0" : "=r"(val));
+#else
+#define STT(reg,val)  asm volatile ("stt $f"#reg",%0" : "=m"(val));
+#endif
+
 unsigned long
 alpha_read_fp_reg (unsigned long reg)
 {
-       unsigned long r;
+       unsigned long val;
 
        switch (reg) {
-             case  0: asm ("stt  $f0,%0" : "m="(r)); break;
-             case  1: asm ("stt  $f1,%0" : "m="(r)); break;
-             case  2: asm ("stt  $f2,%0" : "m="(r)); break;
-             case  3: asm ("stt  $f3,%0" : "m="(r)); break;
-             case  4: asm ("stt  $f4,%0" : "m="(r)); break;
-             case  5: asm ("stt  $f5,%0" : "m="(r)); break;
-             case  6: asm ("stt  $f6,%0" : "m="(r)); break;
-             case  7: asm ("stt  $f7,%0" : "m="(r)); break;
-             case  8: asm ("stt  $f8,%0" : "m="(r)); break;
-             case  9: asm ("stt  $f9,%0" : "m="(r)); break;
-             case 10: asm ("stt $f10,%0" : "m="(r)); break;
-             case 11: asm ("stt $f11,%0" : "m="(r)); break;
-             case 12: asm ("stt $f12,%0" : "m="(r)); break;
-             case 13: asm ("stt $f13,%0" : "m="(r)); break;
-             case 14: asm ("stt $f14,%0" : "m="(r)); break;
-             case 15: asm ("stt $f15,%0" : "m="(r)); break;
-             case 16: asm ("stt $f16,%0" : "m="(r)); break;
-             case 17: asm ("stt $f17,%0" : "m="(r)); break;
-             case 18: asm ("stt $f18,%0" : "m="(r)); break;
-             case 19: asm ("stt $f19,%0" : "m="(r)); break;
-             case 20: asm ("stt $f20,%0" : "m="(r)); break;
-             case 21: asm ("stt $f21,%0" : "m="(r)); break;
-             case 22: asm ("stt $f22,%0" : "m="(r)); break;
-             case 23: asm ("stt $f23,%0" : "m="(r)); break;
-             case 24: asm ("stt $f24,%0" : "m="(r)); break;
-             case 25: asm ("stt $f25,%0" : "m="(r)); break;
-             case 26: asm ("stt $f26,%0" : "m="(r)); break;
-             case 27: asm ("stt $f27,%0" : "m="(r)); break;
-             case 28: asm ("stt $f28,%0" : "m="(r)); break;
-             case 29: asm ("stt $f29,%0" : "m="(r)); break;
-             case 30: asm ("stt $f30,%0" : "m="(r)); break;
-             case 31: asm ("stt $f31,%0" : "m="(r)); break;
-             default:
-               break;
+             case  0: STT( 0, val); break;
+             case  1: STT( 1, val); break;
+             case  2: STT( 2, val); break;
+             case  3: STT( 3, val); break;
+             case  4: STT( 4, val); break;
+             case  5: STT( 5, val); break;
+             case  6: STT( 6, val); break;
+             case  7: STT( 7, val); break;
+             case  8: STT( 8, val); break;
+             case  9: STT( 9, val); break;
+             case 10: STT(10, val); break;
+             case 11: STT(11, val); break;
+             case 12: STT(12, val); break;
+             case 13: STT(13, val); break;
+             case 14: STT(14, val); break;
+             case 15: STT(15, val); break;
+             case 16: STT(16, val); break;
+             case 17: STT(17, val); break;
+             case 18: STT(18, val); break;
+             case 19: STT(19, val); break;
+             case 20: STT(20, val); break;
+             case 21: STT(21, val); break;
+             case 22: STT(22, val); break;
+             case 23: STT(23, val); break;
+             case 24: STT(24, val); break;
+             case 25: STT(25, val); break;
+             case 26: STT(26, val); break;
+             case 27: STT(27, val); break;
+             case 28: STT(28, val); break;
+             case 29: STT(29, val); break;
+             case 30: STT(30, val); break;
+             case 31: STT(31, val); break;
        }
-       return r;
+       return val;
 }
 
-#if 1
-/*
- * This is IMHO the better way of implementing LDT().  But it
- * has the disadvantage that gcc 2.7.0 refuses to compile it
- * (invalid operand constraints), so instead, we use the uglier
- * macro below.
- */
-# define LDT(reg,val)  \
-  asm volatile ("ldt $f"#reg",%0" : : "m"(val));
+#ifdef __alpha_cix__
+#define LDT(reg,val)  asm volatile ("itoft %0,$f"#reg : : "r"(val));
 #else
-# define LDT(reg,val)  \
-  asm volatile ("ldt $f"#reg",0(%0)" : : "r"(&val));
+#define LDT(reg,val)  asm volatile ("ldt $f"#reg",%0" : : "m"(val));
 #endif
 
 void
@@ -98,7 +94,5 @@ alpha_write_fp_reg (unsigned long reg, unsigned long val)
              case 29: LDT(29, val); break;
              case 30: LDT(30, val); break;
              case 31: LDT(31, val); break;
-             default:
-               break;
        }
 }
index 48ad8ff82efdc5f19343b34f723cad4b9ce53214..92e11a82ec0b8d0e5fe94d32eeccf1164e4b44ec 100644 (file)
@@ -7,7 +7,6 @@
  * the kernel global pointer and jump to the kernel entry-point.
  */
 
-#define __ASSEMBLY__
 #include <asm/system.h>
 
 #define halt call_pal PAL_halt
index 9470ee69a90ffc0fb9064b187dc84cf9da90d75d..0fee440e1eee30e04ca94e36be1eb454b695a4db 100644 (file)
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/bitops.h>
-#include <asm/dma.h>
+#include <asm/machvec.h>
+
+#include "proto.h"
+#include "irq.h"
 
 #define vulp   volatile unsigned long *
 #define vuip   volatile unsigned int *
 
-extern void timer_interrupt(struct pt_regs * regs);
-extern void cserve_update_hw(unsigned long, unsigned long);
-extern void handle_ipi(struct pt_regs *);
+unsigned int local_irq_count[NR_CPUS];
+unsigned int local_bh_count[NR_CPUS];
+
 
 #define RTC_IRQ    8
 #ifdef CONFIG_RTC
@@ -45,497 +48,169 @@ extern void handle_ipi(struct pt_regs *);
 #  error Unable to handle more than 64 irq levels.
 #endif
 
-/* PROBE_MASK is the bitset of irqs that we consider for autoprobing: */
-#if defined(CONFIG_ALPHA_P2K)
-  /* always mask out unused timer irq 0 and RTC irq 8 */
-# define PROBE_MASK (((1UL << NR_IRQS) - 1) & ~0x101UL)
-#elif defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
-  /* always mask out unused timer irq 0, "irqs" 20-30, and the EISA cascade: */
-# define PROBE_MASK (((1UL << NR_IRQS) - 1) & ~0xfff000000001UL)
-#elif defined(CONFIG_ALPHA_RUFFIAN)
-  /* must leave timer irq 0 in the mask */
-# define PROBE_MASK ((1UL << NR_IRQS) - 1)
-#elif NR_IRQS == 64
-  /* always mask out unused timer irq 0: */
-# define PROBE_MASK (~1UL)
+#ifdef CONFIG_ALPHA_GENERIC
+#define ACTUAL_NR_IRQS alpha_mv.nr_irqs
 #else
-  /* always mask out unused timer irq 0: */
-# define PROBE_MASK (((1UL << NR_IRQS) - 1) & ~1UL)
+#define ACTUAL_NR_IRQS NR_IRQS
 #endif
 
 /* Reserved interrupts.  These must NEVER be requested by any driver!
- */
-#define        IS_RESERVED_IRQ(irq)    ((irq)==2)      /* IRQ 2 used by hw cascade */
  IRQ 2 used by hw cascade */
+#define        IS_RESERVED_IRQ(irq)    ((irq)==2)
 
-/*
- * Shadow-copy of masked interrupts.
- *  The bits are used as follows:
- *      0.. 7  first (E)ISA PIC (irq level 0..7)
- *      8..15  second (E)ISA PIC (irq level 8..15)
- *   Systems with PCI interrupt lines managed by GRU (e.g., Alcor, XLT)
- *    or PYXIS (e.g. Miata, PC164-LX):
- *     16..47  PCI interrupts 0..31 (int at xxx_INT_MASK)
- *   Mikasa:
- *     16..31  PCI interrupts 0..15 (short at I/O port 536)
- *   Other systems (not Mikasa) with 16 PCI interrupt lines:
- *     16..23  PCI interrupts 0.. 7 (char at I/O port 26)
- *     24..31  PCI interrupts 8..15 (char at I/O port 27)
- *   Systems with 17 PCI interrupt lines (e.g., Cabriolet and eb164):
- *     16..32  PCI interrupts 0..31 (int at I/O port 804)
- *   For SABLE, which is really baroque, we manage 40 IRQ's, but the
- *   hardware really only supports 24, not via normal ISA PIC,
- *   but cascaded custom 8259's, etc.
- *      0-7  (char at 536)
- *      8-15 (char at 53a)
- *     16-23 (char at 53c)
- */
-static unsigned long irq_mask = ~0UL;
 
-#ifdef CONFIG_ALPHA_SABLE
 /*
- * Note that the vector reported by the SRM PALcode corresponds to the
- * interrupt mask bits, but we have to manage via more normal IRQs.
- *
- * We have to be able to go back and forth between MASK bits and IRQ:
- * these tables help us do so.
+ * Shadow-copy of masked interrupts.
  */
-static char sable_irq_to_mask[NR_IRQS] = {
-       -1,  6, -1,  8, 15, 12,  7,  9, /* pseudo PIC  0-7  */
-       -1, 16, 17, 18,  3, -1, 21, 22, /* pseudo PIC  8-15 */
-       -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo EISA 0-7  */
-       -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo EISA 8-15 */
-       2,  1,  0,  4,  5, -1, -1, -1, /* pseudo PCI */
-};
-#define IRQ_TO_MASK(irq) (sable_irq_to_mask[(irq)])
-static char sable_mask_to_irq[NR_IRQS] = {
-       34, 33, 32, 12, 35, 36,  1,  6, /* mask 0-7  */
-       3,  7, -1, -1,  5, -1, -1,  4, /* mask 8-15  */
-       9, 10, 11, -1, -1, 14, 15, -1, /* mask 16-23  */
-};
-#else /* CONFIG_ALPHA_SABLE */
-#define IRQ_TO_MASK(irq) (irq)
-#endif /* CONFIG_ALPHA_SABLE */
+unsigned long alpha_irq_mask = ~0UL;
 
 /*
- * Update the hardware with the irq mask passed in MASK.  The function
- * exploits the fact that it is known that only bit IRQ has changed.
+ * The ack_irq routine used by 80% of the systems.
  */
 
-static inline void 
-sable_update_hw(unsigned long irq, unsigned long mask)
+void
+generic_ack_irq(unsigned long irq)
 {
-       /* The "irq" argument is really the mask bit number */
-       switch (irq) {
-       case 16 ... 23:
-               outb(mask >> 16, 0x53d);
-               break;
-       case 8 ... 15:
-               outb(mask >> 8, 0x53b);
-               break;
-       case 0 ... 7:
-               outb(mask, 0x537);
-               break;
+       if (irq < 16) {
+               /* Ack the interrupt making it the lowest priority */
+               /*  First the slave .. */
+               if (irq > 7) {
+                       outb(0xE0 | (irq - 8), 0xa0);
+                       irq = 2;
+               }
+               /* .. then the master */
+               outb(0xE0 | irq, 0x20);
        }
 }
 
-static inline void 
-noritake_update_hw(unsigned long irq, unsigned long mask)
-{
-       switch (irq) {
-       case 32 ... 47:
-               outw(~(mask >> 32), 0x54c);
-               break;
-       case 16 ... 31:
-               outw(~(mask >> 16), 0x54a);
-               break;
-       case  8 ... 15: /* ISA PIC2 */
-               outb(mask >> 8, 0xA1);
-               break;
-       case  0 ... 7:  /* ISA PIC1 */
-               outb(mask, 0x21);
-               break;
-       }
-}
+/*
+ * Dispatch device interrupts.
+ */
 
-#ifdef CONFIG_ALPHA_MIATA
-static inline void 
-miata_update_hw(unsigned long irq, unsigned long mask)
-{
-       switch (irq) {
-       case 16 ... 47:
-               /* Make CERTAIN none of the bogus ints get enabled... */
-               *(vulp)PYXIS_INT_MASK =
-                       ~((long)mask >> 16) & ~0x4000000000000e3bUL;
-               mb();
-               /* ... and read it back to make sure it got written.  */
-               *(vulp)PYXIS_INT_MASK;
-               break;
-       case  8 ... 15: /* ISA PIC2 */
-               outb(mask >> 8, 0xA1);
-               break;
-       case  0 ... 7:  /* ISA PIC1 */
-               outb(mask, 0x21);
-               break;
-       }
-}
-#endif
+/* Handle ISA interrupt via the PICs. */
 
-#if defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
-static inline void 
-alcor_and_xlt_update_hw(unsigned long irq, unsigned long mask)
-{
-       switch (irq) {
-       case 16 ... 47:
-               /* On Alcor, at least, lines 20..30 are not connected and can
-                  generate spurrious interrupts if we turn them on while IRQ
-                  probing.  So explicitly mask them out. */
-               mask |= 0x7ff000000000UL;
-
-               /* Note inverted sense of mask bits: */
-               *(vuip)GRU_INT_MASK = ~(mask >> 16);
-               mb();
-               break;
-       case  8 ... 15: /* ISA PIC2 */
-               outb(mask >> 8, 0xA1);
-               break;
-       case  0 ... 7:  /* ISA PIC1 */
-               outb(mask, 0x21);
-               break;
-       }
-}
+#if defined(CONFIG_ALPHA_GENERIC)
+# define IACK_SC       alpha_mv.iack_sc
+#elif defined(CONFIG_ALPHA_APECS)
+# define IACK_SC       APECS_IACK_SC
+#elif defined(CONFIG_ALPHA_LCA)
+# define IACK_SC       LCA_IACK_SC
+#elif defined(CONFIG_ALPHA_CIA)
+# define IACK_SC       CIA_IACK_SC
+#elif defined(CONFIG_ALPHA_PYXIS)
+# define IACK_SC       PYXIS_IACK_SC
+#elif defined(CONFIG_ALPHA_TSUNAMI)
+# define IACK_SC       TSUNAMI_PCI0_IACK_SC
+#else
+  /* This is bogus but necessary to get it to compile on all platforms. */
+# define IACK_SC       1L
 #endif
 
-static inline void
-mikasa_update_hw(unsigned long irq, unsigned long mask)
-{
-       switch (irq) {
-       case 16 ... 31:
-               outw(~(mask >> 16), 0x536); /* note invert */
-               break;
-       case  8 ... 15: /* ISA PIC2 */
-               outb(mask >> 8, 0xA1);
-               break;
-       case  0 ... 7:  /* ISA PIC1 */
-               outb(mask, 0x21);
-               break;
-       }
-}
-
-#if defined(CONFIG_ALPHA_RUFFIAN)
-static inline void
-ruffian_update_hw(unsigned long irq, unsigned long mask)
+void
+isa_device_interrupt(unsigned long vector, struct pt_regs * regs)
 {
-       switch (irq) {
-       case 16 ... 47:
-               /* Note inverted sense of mask bits: */
-               /* Make CERTAIN none of the bogus ints get enabled... */
-               *(vulp)PYXIS_INT_MASK =
-                     ~((long)mask >> 16) & 0x00000000ffffffbfUL; mb();
-               /* ... and read it back to make sure it got written.  */
-               *(vulp)PYXIS_INT_MASK;
-               break;
-       case  8 ... 15: /* ISA PIC2 */
-               outb(mask >> 8, 0xA1);
-               break;
-       case  0 ... 7: /* ISA PIC1 */
-               outb(mask, 0x21);
-               break;
+#if 1
+       /*
+        * Generate a PCI interrupt acknowledge cycle.  The PIC will
+        * respond with the interrupt vector of the highest priority
+        * interrupt that is pending.  The PALcode sets up the
+        * interrupts vectors such that irq level L generates vector L.
+        */
+       int j = *(vuip) IACK_SC;
+       j &= 0xff;
+       if (j == 7) {
+               if (!(inb(0x20) & 0x80)) {
+                       /* It's only a passive release... */
+                       return;
+               }
        }
-}
-#endif /* RUFFIAN */
-
-#if defined(CONFIG_ALPHA_SX164)
-static inline void
-sx164_update_hw(unsigned long irq, unsigned long mask)
-{
-       switch (irq) {
-       case 16 ... 39:
-#if defined(CONFIG_ALPHA_SRM)
-               cserve_update_hw(irq, mask);
+       handle_irq(j, j, regs);
 #else
-               /* make CERTAIN none of the bogus ints get enabled */
-               *(vulp)PYXIS_INT_MASK =
-                   ~((long)mask >> 16) & ~0x000000000000003bUL; mb();
-               /* ... and read it back to make sure it got written.  */
-               *(vulp)PYXIS_INT_MASK;
-#endif /* SRM */
-               break;
-       case  8 ... 15: /* ISA PIC2 */
-               outb(mask >> 8, 0xA1);
-               break;
-       case  0 ... 7: /* ISA PIC1 */
-               outb(mask, 0x21);
-               break;
-       }
+       unsigned long pic;
 
-}
-#endif /* SX164 */
+       /*
+        * It seems to me that the probability of two or more *device*
+        * interrupts occurring at almost exactly the same time is
+        * pretty low.  So why pay the price of checking for
+        * additional interrupts here if the common case can be
+        * handled so much easier?
+        */
+       /* 
+        *  The first read of gives you *all* interrupting lines.
+        *  Therefore, read the mask register and and out those lines
+        *  not enabled.  Note that some documentation has 21 and a1 
+        *  write only.  This is not true.
+        */
+       pic = inb(0x20) | (inb(0xA0) << 8);     /* read isr */
+       pic &= ~alpha_irq_mask;                 /* apply mask */
+       pic &= 0xFFFB;                          /* mask out cascade & hibits */
 
-#if defined(CONFIG_ALPHA_DP264)
-static inline void
-dp264_update_hw(unsigned long irq, unsigned long mask)
-{
-       switch (irq) {
-       case 16 ... 63:
-               /* make CERTAIN none of the bogus ints get enabled */
-               /* HACK ALERT! only CPU#0 is used currently */
-               *(vulp)TSUNAMI_CSR_DIM0 =
-                   ~(mask) & ~0x0000000000000000UL; mb();
-               /* ... and read it back to make sure it got written.  */
-               *(vulp)TSUNAMI_CSR_DIM0;
-               break;
-       case  8 ... 15: /* ISA PIC2 */
-               outb(mask >> 8, 0xA1);
-               break;
-       case  0 ... 7:  /* ISA PIC1 */
-               outb(mask, 0x21);
-               break;
+       while (pic) {
+               int j = ffz(~pic);
+               pic &= pic - 1;
+               handle_irq(j, j, regs);
        }
+#endif
 }
-#endif /* DP264 */
 
-#if defined(CONFIG_ALPHA_RAWHIDE)
-static inline void
-rawhide_update_hw(unsigned long irq, unsigned long mask)
-{
-       switch (irq) {
-       case 16 ... 39: /* PCI bus 0 with EISA bridge */
-               *(vuip)MCPCIA_INT_MASK0(0) =
-                   (~((mask) >> 16) & 0x00ffffffU) | 0x00ff0000U; mb();
-               /* ... and read it back to make sure it got written.  */
-               *(vuip)MCPCIA_INT_MASK0(0);
-               break;
-       case 40 ... 63: /* PCI bus 1 with builtin NCR810 SCSI */
-               *(vuip)MCPCIA_INT_MASK0(1) =
-                   (~((mask) >> 40) & 0x00ffffffU) | 0x00fe0000U; mb();
-               /* ... and read it back to make sure it got written.  */
-               *(vuip)MCPCIA_INT_MASK0(1);
-               break;
-       case  8 ... 15: /* ISA PIC2 */
-               outb(mask >> 8, 0xA1);
-               break;
-       case  0 ... 7:  /* ISA PIC1 */
-               outb(mask, 0x21);
-               break;
-       }
-}
-#endif /* RAWHIDE */
+/* Handle interrupts from the SRM, assuming no additional weirdness.  */
 
-/*
- * HW update code for the following platforms:
- *
- *     CABRIOLET (AlphaPC64)
- *     EB66P
- *     EB164
- *     PC164
- *     LX164
- */
-static inline void
-update_hw_35(unsigned long irq, unsigned long mask)
+void 
+srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
 {
-       switch (irq) {
-       case 16 ... 34:
-#if defined(CONFIG_ALPHA_SRM)
-               cserve_update_hw(irq, mask);
-#else /* SRM */
-               outl(irq_mask >> 16, 0x804);
-#endif /* SRM */
-               break;
-       case  8 ... 15: /* ISA PIC2 */
-               outb(mask >> 8, 0xA1);
-               break;
-       case  0 ... 7: /* ISA PIC1 */
-               outb(mask, 0x21);
-               break;
-       }
-}
+       int irq, ack;
+       unsigned long flags;
 
-static inline void
-update_hw_32(unsigned long irq, unsigned long mask)
-{
-       switch (irq) {
-       case 24 ... 31:
-               outb(mask >> 24, 0x27);
-               break;
-       case 16 ... 23:
-               outb(mask >> 16, 0x26);
-               break;
-       case  8 ... 15: /* ISA PIC2 */
-               outb(mask >> 8, 0xA1);
-               break;
-       case  0 ... 7:  /* ISA PIC1 */
-               outb(mask, 0x21);
-               break;
-}
-}
+       __save_and_cli(flags);
+       ack = irq = (vector - 0x800) >> 4;
 
-static inline void
-update_hw_16(unsigned long irq, unsigned long mask)
-{
-       switch (irq) {
-       case 8 ... 15: /* ISA PIC2 */
-               outb(mask >> 8, 0xA1);
-               break;
-       case  0 ... 7: /* ISA PIC1 */
-               outb(mask, 0x21);
-               break;
-}
+       handle_irq(irq, ack, regs);
+       __restore_flags(flags);
 }
 
+
 /*
- * We manipulate the hardware ourselves.
+ * Initial irq handlers.
  */
 
-static void update_hw(unsigned long irq, unsigned long mask)
-{
-#if defined(CONFIG_ALPHA_SABLE)
-       sable_update_hw(irq, mask);
-#elif defined(CONFIG_ALPHA_MIATA)
-       miata_update_hw(irq, mask);
-#elif defined(CONFIG_ALPHA_NORITAKE)
-       noritake_update_hw(irq, mask);
-#elif defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
-       alcor_and_xlt_update_hw(irq, mask);
-#elif defined(CONFIG_ALPHA_MIKASA)
-       mikasa_update_hw(irq, mask);
-#elif defined(CONFIG_ALPHA_SX164)
-       sx164_update_hw(irq, mask);
-#elif defined(CONFIG_ALPHA_RUFFIAN)
-       ruffian_update_hw(irq, mask);
-#elif defined(CONFIG_ALPHA_DP264)
-       dp264_update_hw(irq, mask);
-#elif defined(CONFIG_ALPHA_RAWHIDE)
-       rawhide_update_hw(irq, mask);
-#elif defined(CONFIG_ALPHA_CABRIOLET) || \
-      defined(CONFIG_ALPHA_EB66P)     || \
-      defined(CONFIG_ALPHA_EB164)     || \
-      defined(CONFIG_ALPHA_PC164)     || \
-      defined(CONFIG_ALPHA_LX164)
-       update_hw_35(irq, mask);
-#elif defined(CONFIG_ALPHA_EB66) || \
-      defined(CONFIG_ALPHA_EB64P)
-       update_hw_32(irq, mask);
-#elif NR_IRQS == 16
-       update_hw_16(irq, mask);
-#else
-#error "How do I update the IRQ hardware?"
-#endif
-}
+static struct irqaction timer_irq = { NULL, 0, 0, NULL, NULL, NULL};
+static struct irqaction *irq_action[NR_IRQS];
 
-static inline void mask_irq(unsigned long irq)
+
+static inline void
+mask_irq(unsigned long irq)
 {
-       irq_mask |= (1UL << irq);
-       update_hw(irq, irq_mask);
+       alpha_mv.update_irq_hw(irq, alpha_irq_mask |= 1UL << irq, 0);
 }
 
-static inline void unmask_irq(unsigned long irq)
+static inline void
+unmask_irq(unsigned long irq)
 {
-       irq_mask &= ~(1UL << irq);
-       update_hw(irq, irq_mask);
+       alpha_mv.update_irq_hw(irq, alpha_irq_mask &= ~(1UL << irq), 1);
 }
 
-void disable_irq(unsigned int irq_nr)
+void
+disable_irq(unsigned int irq_nr)
 {
        unsigned long flags;
 
        save_and_cli(flags);
-       mask_irq(IRQ_TO_MASK(irq_nr));
+       mask_irq(irq_nr);
        restore_flags(flags);
 }
 
-void enable_irq(unsigned int irq_nr)
+void
+enable_irq(unsigned int irq_nr)
 {
        unsigned long flags;
 
        save_and_cli(flags);
-       unmask_irq(IRQ_TO_MASK(irq_nr));
+       unmask_irq(irq_nr);
        restore_flags(flags);
 }
 
-/*
- * Initial irq handlers.
- */
-static struct irqaction timer_irq = { NULL, 0, 0, NULL, NULL, NULL};
-static struct irqaction *irq_action[NR_IRQS];
-
-int get_irq_list(char *buf)
-{
-       int i, len = 0;
-       struct irqaction * action;
-       int cpu = smp_processor_id();
-
-       for (i = 0; i < NR_IRQS; i++) {
-               action = irq_action[i];
-               if (!action) 
-                       continue;
-               len += sprintf(buf+len, "%2d: %10u %c %s",
-                              i, kstat.irqs[cpu][i],
-                              (action->flags & SA_INTERRUPT) ? '+' : ' ',
-                              action->name);
-               for (action=action->next; action; action = action->next) {
-                       len += sprintf(buf+len, ",%s %s",
-                                      (action->flags & SA_INTERRUPT) ? " +" : "",
-                                      action->name);
-               }
-               len += sprintf(buf+len, "\n");
-       }
-       return len;
-}
-
-static inline void ack_irq(int irq)
-{
-#ifdef CONFIG_ALPHA_SABLE
-       /* Note that the "irq" here is really the mask bit number */
-       switch (irq) {
-       case 0 ... 7:
-               outb(0xE0 | (irq - 0), 0x536);
-               outb(0xE0 | 1, 0x534); /* slave 0 */
-               break;
-       case 8 ... 15:
-               outb(0xE0 | (irq - 8), 0x53a);
-               outb(0xE0 | 3, 0x534); /* slave 1 */
-               break;
-       case 16 ... 24:
-               outb(0xE0 | (irq - 16), 0x53c);
-               outb(0xE0 | 4, 0x534); /* slave 2 */
-               break;
-       }
-#elif defined(CONFIG_ALPHA_RUFFIAN)
-       if (irq < 16) {
-               /* Ack PYXIS ISA interrupt.  */
-               *(vulp)PYXIS_INT_REQ = 1L << 7; mb();
-               /* ... and read it back to make sure it got written.  */
-               *(vulp)PYXIS_INT_REQ;
-               if (irq > 7) {
-                       outb(0x20, 0xa0);
-               }
-               outb(0x20, 0x20);
-       } else {
-               /* Ack PYXIS PCI interrupt.  */
-               *(vulp)PYXIS_INT_REQ = (1UL << (irq - 16));
-               /* ... and read it back to make sure it got written.  */
-               *(vulp)PYXIS_INT_REQ;
-       }
-#else
-       if (irq < 16) {
-               /* Ack the interrupt making it the lowest priority */
-               /*  First the slave .. */
-               if (irq > 7) {
-                       outb(0xE0 | (irq - 8), 0xa0);
-                       irq = 2;
-               }
-               /* .. then the master */
-               outb(0xE0 | irq, 0x20);
-#if defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
-               /* on ALCOR/XLT, need to dismiss interrupt via GRU */
-               *(vuip)GRU_INT_CLEAR = 0x80000000; mb();
-               *(vuip)GRU_INT_CLEAR = 0x00000000; mb();
-#endif /* ALCOR || XLT */
-       }
-#endif
-}
-
-int check_irq(unsigned int irq)
+int
+check_irq(unsigned int irq)
 {
        struct irqaction **p;
 
@@ -545,22 +220,21 @@ int check_irq(unsigned int irq)
        return -EBUSY;
 }
 
-int request_irq(unsigned int irq, 
-               void (*handler)(int, void *, struct pt_regs *),
-               unsigned long irqflags, 
-               const char * devname,
-               void *dev_id)
+int
+request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+           unsigned long irqflags, const char * devname, void *dev_id)
 {
        int shared = 0;
        struct irqaction * action, **p;
        unsigned long flags;
 
-       if (irq >= NR_IRQS)
+       if (irq >= ACTUAL_NR_IRQS)
                return -EINVAL;
        if (IS_RESERVED_IRQ(irq))
                return -EINVAL;
        if (!handler)
                return -EINVAL;
+
        p = irq_action + irq;
        action = *p;
        if (action) {
@@ -580,11 +254,11 @@ int request_irq(unsigned int irq,
                shared = 1;
        }
 
-       if (irq == TIMER_IRQ)
-               action = &timer_irq;
-       else
-               action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
-                                                    GFP_KERNEL);
+       action = &timer_irq;
+       if (irq != TIMER_IRQ) {
+               action = (struct irqaction *)
+                       kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+       }
        if (!action)
                return -ENOMEM;
 
@@ -602,18 +276,19 @@ int request_irq(unsigned int irq,
        *p = action;
 
        if (!shared)
-               unmask_irq(IRQ_TO_MASK(irq));
+               unmask_irq(irq);
 
        restore_flags(flags);
        return 0;
 }
                
-void free_irq(unsigned int irq, void *dev_id)
+void
+free_irq(unsigned int irq, void *dev_id)
 {
        struct irqaction * action, **p;
        unsigned long flags;
 
-       if (irq >= NR_IRQS) {
+       if (irq >= ACTUAL_NR_IRQS) {
                printk("Trying to free IRQ%d\n",irq);
                return;
        }
@@ -629,7 +304,7 @@ void free_irq(unsigned int irq, void *dev_id)
                save_and_cli(flags);
                *p = action->next;
                if (!irq[irq_action])
-                       mask_irq(IRQ_TO_MASK(irq));
+                       mask_irq(irq);
                restore_flags(flags);
                kfree(action);
                return;
@@ -637,14 +312,29 @@ void free_irq(unsigned int irq, void *dev_id)
        printk("Trying to free free IRQ%d\n",irq);
 }
 
-static inline void handle_nmi(struct pt_regs * regs)
+int get_irq_list(char *buf)
 {
-       printk("Whee.. NMI received. Probable hardware error\n");
-       printk("61=%02x, 461=%02x\n", inb(0x61), inb(0x461));
-}
+       int i, len = 0;
+       struct irqaction * action;
+       int cpu = smp_processor_id();
 
-unsigned int local_irq_count[NR_CPUS];
-unsigned int local_bh_count[NR_CPUS];
+       for (i = 0; i < NR_IRQS; i++) {
+               action = irq_action[i];
+               if (!action) 
+                       continue;
+               len += sprintf(buf+len, "%2d: %10u %c %s",
+                              i, kstat.irqs[cpu][i],
+                              (action->flags & SA_INTERRUPT) ? '+' : ' ',
+                              action->name);
+               for (action=action->next; action; action = action->next) {
+                       len += sprintf(buf+len, ", %s%s",
+                                      (action->flags & SA_INTERRUPT) ? "+":"",
+                                      action->name);
+               }
+               len += sprintf(buf+len, "\n");
+       }
+       return len;
+}
 
 #ifdef __SMP__
 /* Who has global_irq_lock. */
@@ -666,10 +356,17 @@ static unsigned long previous_irqholder = NO_PROC_ID;
 #define INIT_STUCK 100000000
 
 #undef STUCK
-#define STUCK \
-if (!--stuck) {printk("wait_on_irq CPU#%d stuck at %08lx, waiting for %08lx (local=%d, global=%d)\n", cpu, where, previous_irqholder, local_count, atomic_read(&global_irq_count)); stuck = INIT_STUCK; }
+#define STUCK                                          \
+  if (!--stuck) {                                      \
+    printk("wait_on_irq CPU#%d stuck at %08lx, "       \
+          "waiting for %08lx (local=%d, global=%d)\n", \
+          cpu, where, previous_irqholder, local_count, \
+          atomic_read(&global_irq_count));             \
+    stuck = INIT_STUCK;                                        \
+  }
 
-static inline void wait_on_irq(int cpu, unsigned long where)
+static inline void
+wait_on_irq(int cpu, unsigned long where)
 {
        int stuck = INIT_STUCK;
        int local_count = local_irq_count[cpu];
@@ -706,10 +403,15 @@ static inline void wait_on_irq(int cpu, unsigned long where)
 #define INIT_STUCK 10000000
 
 #undef STUCK
-#define STUCK \
-if (!--stuck) {printk("get_irqlock stuck at %08lx, waiting for %08lx\n", where, previous_irqholder); stuck = INIT_STUCK;}
+#define STUCK                                                  \
+  if (!--stuck) {                                              \
+    printk("get_irqlock stuck at %08lx, waiting for %08lx\n",  \
+          where, previous_irqholder);                          \
+    stuck = INIT_STUCK;                                                \
+  }
 
-static inline void get_irqlock(int cpu, unsigned long where)
+static inline void
+get_irqlock(int cpu, unsigned long where)
 {
        int stuck = INIT_STUCK;
 
@@ -745,7 +447,8 @@ static inline void get_irqlock(int cpu, unsigned long where)
        previous_irqholder = where;
 }
 
-void __global_cli(void)
+void
+__global_cli(void)
 {
        int cpu = smp_processor_id();
        unsigned long where;
@@ -754,27 +457,30 @@ void __global_cli(void)
        __cli();
 
        if (!local_irq_count[cpu])
-         get_irqlock(smp_processor_id(), where);
+               get_irqlock(smp_processor_id(), where);
 }
 
-void __global_sti(void)
+void
+__global_sti(void)
 {
         int cpu = smp_processor_id();
 
         if (!local_irq_count[cpu])
-         release_irqlock(smp_processor_id());
+               release_irqlock(smp_processor_id());
 
        __sti();
 }
 
 #if 0
-unsigned long __global_save_flags(void)
+unsigned long
+__global_save_flags(void)
 {
        return global_irq_holder == (unsigned char) smp_processor_id();
 }
 #endif
 
-void __global_restore_flags(unsigned long flags)
+void
+__global_restore_flags(unsigned long flags)
 {
        if (flags & 1) {
                __global_cli();
@@ -793,12 +499,17 @@ void __global_restore_flags(unsigned long flags)
 #define INIT_STUCK 200000000
 
 #undef STUCK
-#define STUCK \
-if (!--stuck) {printk("irq_enter stuck (irq=%d, cpu=%d, global=%d)\n",irq,cpu,global_irq_holder); stuck = INIT_STUCK;}
+#define STUCK                                                  \
+  if (!--stuck) {                                              \
+    printk("irq_enter stuck (irq=%d, cpu=%d, global=%d)\n",    \
+          irq, cpu,global_irq_holder);                         \
+    stuck = INIT_STUCK;                                                \
+  }
 
 #undef VERBOSE_IRQLOCK_DEBUGGING
 
-void irq_enter(int cpu, int irq)
+void
+irq_enter(int cpu, int irq)
 {
 #ifdef VERBOSE_IRQLOCK_DEBUGGING
        extern void smp_show_backtrace_all_cpus(void);
@@ -813,10 +524,10 @@ void irq_enter(int cpu, int irq)
                        int globl_icount = atomic_read(&global_irq_count);
                        int local_count = local_irq_count[cpu];
 
-                       /* It is very important that we load the state variables
-                        * before we do the first call to printk() as printk()
-                        * could end up changing them...
-                        */
+                       /* It is very important that we load the state
+                          variables before we do the first call to
+                          printk() as printk() could end up changing
+                          them...  */
 
 #if 0
                        printk("CPU[%d]: BAD! Local IRQ's enabled,"
@@ -838,13 +549,15 @@ void irq_enter(int cpu, int irq)
        }
 }
 
-void irq_exit(int cpu, int irq)
+void
+irq_exit(int cpu, int irq)
 {
        hardirq_exit(cpu);
        release_irqlock(cpu);
 }
 
-static void show(char * str)
+static void
+show(char * str)
 {
 #if 0
        int i;
@@ -873,7 +586,8 @@ static void show(char * str)
         
 #define MAXCOUNT 100000000
 
-static inline void wait_on_bh(void)
+static inline void
+wait_on_bh(void)
 {
        int count = MAXCOUNT;
         do {
@@ -893,7 +607,8 @@ static inline void wait_on_bh(void)
  * Don't wait if we're already running in an interrupt
  * context or are inside a bh handler.
  */
-void synchronize_bh(void)
+void
+synchronize_bh(void)
 {
        if (atomic_read(&global_bh_count)) {
                int cpu = smp_processor_id();
@@ -904,7 +619,8 @@ void synchronize_bh(void)
 }
 
 /* There has to be a better way. */
-void synchronize_irq(void)
+void
+synchronize_irq(void)
 {
        int cpu = smp_processor_id();
        int local_count = local_irq_count[cpu];
@@ -918,26 +634,35 @@ void synchronize_irq(void)
        }
 }
 
-#else
+#else /* !__SMP__ */
+
 #define irq_enter(cpu, irq)    (++local_irq_count[cpu])
 #define irq_exit(cpu, irq)     (--local_irq_count[cpu])
-#endif
 
-static void unexpected_irq(int irq, struct pt_regs * regs)
+#endif /* __SMP__ */
+
+static void
+unexpected_irq(int irq, struct pt_regs * regs)
 {
+#if 0
+#if 1
+       printk("device_interrupt: unexpected interrupt %d\n", irq);
+#else
        struct irqaction *action;
        int i;
 
        printk("IO device interrupt, irq = %d\n", irq);
        printk("PC = %016lx PS=%04lx\n", regs->pc, regs->ps);
        printk("Expecting: ");
-       for (i = 0; i < 16; i++)
+       for (i = 0; i < ACTUAL_NR_IRQS; i++)
                if ((action = irq_action[i]))
                        while (action->handler) {
                                printk("[%s:%d] ", action->name, i);
                                action = action->next;
                        }
        printk("\n");
+#endif
+#endif
 
 #if defined(CONFIG_ALPHA_JENSEN)
        /* ??? Is all this just debugging, or are the inb's and outb's
@@ -951,33 +676,16 @@ static void unexpected_irq(int irq, struct pt_regs * regs)
 #endif
 }
 
-static inline void handle_irq(int irq, struct pt_regs * regs)
+void
+handle_irq(int irq, int ack, struct pt_regs * regs)
 {
-       struct irqaction * action = irq_action[irq];
+       struct irqaction * action;
        int cpu = smp_processor_id();
-
-       irq_enter(cpu, irq);
-       kstat.irqs[cpu][irq] += 1;
-       if (!action) {
-               unexpected_irq(irq, regs);
-       } else {
-               do {
-                       action->handler(irq, action->dev_id, regs);
-                       action = action->next;
-               } while (action);
-       }
-       irq_exit(cpu, irq);
-}
-
-static inline void device_interrupt(int irq, int ack, struct pt_regs * regs)
-{
-       struct irqaction * action;
-       int cpu = smp_processor_id();
-
-       if ((unsigned) irq > NR_IRQS) {
-               printk("device_interrupt: illegal interrupt %d\n", irq);
-               return;
-       }
+
+       if ((unsigned) irq > ACTUAL_NR_IRQS) {
+               printk("device_interrupt: illegal interrupt %d\n", irq);
+               return;
+       }
 
        irq_enter(cpu, irq);
        kstat.irqs[cpu][irq] += 1;
@@ -992,8 +700,10 @@ static inline void device_interrupt(int irq, int ack, struct pt_regs * regs)
         * never unmasked. The autoirq stuff depends on this (it looks
         * at the masks before and after doing the probing).
         */
-       mask_irq(ack);
-       ack_irq(ack);
+       if (ack >= 0) {
+               mask_irq(ack);
+               alpha_mv.ack_irq(ack);
+       }
        if (action) {
                if (action->flags & SA_SAMPLE_RANDOM)
                        add_interrupt_randomness(irq);
@@ -1001,622 +711,28 @@ static inline void device_interrupt(int irq, int ack, struct pt_regs * regs)
                        action->handler(irq, action->dev_id, regs);
                        action = action->next;
                } while (action);
-               unmask_irq(ack);
+               if (ack >= 0)
+                       unmask_irq(ack);
        } else {
-#if 1
-               printk("device_interrupt: unexpected interrupt %d\n", irq);
-#endif
+               unexpected_irq(irq, regs);
        }
        irq_exit(cpu, irq);
 }
 
-#ifdef CONFIG_PCI
-
-/*
- * Handle ISA interrupt via the PICs.
- */
-static inline void isa_device_interrupt(unsigned long vector,
-                                       struct pt_regs * regs)
-{
-#if defined(CONFIG_ALPHA_APECS)
-#      define IACK_SC  APECS_IACK_SC
-#elif defined(CONFIG_ALPHA_LCA)
-#      define IACK_SC  LCA_IACK_SC
-#elif defined(CONFIG_ALPHA_CIA)
-#      define IACK_SC  CIA_IACK_SC
-#elif defined(CONFIG_ALPHA_PYXIS)
-#      define IACK_SC  PYXIS_IACK_SC
-#elif defined(CONFIG_ALPHA_TSUNAMI)
-#      define IACK_SC  TSUNAMI_PCI0_IACK_SC
-#else
-       /*
-        * This is bogus but necessary to get it to compile
-        * on all platforms.  If you try to use this on any
-        * other than the intended platforms, you'll notice
-        * real fast...
-        */
-#      define IACK_SC  1L
-#endif
-       int j;
-
-#if 1
-       /*
-        * Generate a PCI interrupt acknowledge cycle.  The PIC will
-        * respond with the interrupt vector of the highest priority
-        * interrupt that is pending.  The PALcode sets up the
-        * interrupts vectors such that irq level L generates vector L.
-        */
-       j = *(vuip) IACK_SC;
-       j &= 0xff;
-       if (j == 7) {
-               if (!(inb(0x20) & 0x80)) {
-                       /* It's only a passive release... */
-                       return;
-               }
-       }
-       device_interrupt(j, j, regs);
-#else
-       unsigned long pic;
-
-       /*
-        * It seems to me that the probability of two or more *device*
-        * interrupts occurring at almost exactly the same time is
-        * pretty low.  So why pay the price of checking for
-        * additional interrupts here if the common case can be
-        * handled so much easier?
-        */
-       /* 
-        *  The first read of gives you *all* interrupting lines.
-        *  Therefore, read the mask register and and out those lines
-        *  not enabled.  Note that some documentation has 21 and a1 
-        *  write only.  This is not true.
-        */
-       pic = inb(0x20) | (inb(0xA0) << 8);     /* read isr */
-       pic &= ~irq_mask;                       /* apply mask */
-       pic &= 0xFFFB;                          /* mask out cascade & hibits */
-
-       while (pic) {
-               j = ffz(~pic);
-               pic &= pic - 1;
-               device_interrupt(j, j, regs);
-       }
-#endif
-}
-
-#if defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
-/* We have to conditionally compile this because of GRU_xxx symbols */
-static inline void
-alcor_and_xlt_device_interrupt(unsigned long vector, struct pt_regs *regs)
-{
-       unsigned long pld;
-       unsigned int i;
-       unsigned long flags;
-
-       save_and_cli(flags);
-
-       /* Read the interrupt summary register of the GRU */
-       pld = (*(vuip)GRU_INT_REQ) & GRU_INT_REQ_BITS;
-
-#if 0
-       printk("[0x%08lx/0x%04x]", pld, inb(0x20) | (inb(0xA0) << 8));
-#endif
-
-       /*
-        * Now for every possible bit set, work through them and call
-        * the appropriate interrupt handler.
-        */
-       while (pld) {
-               i = ffz(~pld);
-               pld &= pld - 1; /* clear least bit set */
-               if (i == 31) {
-                       isa_device_interrupt(vector, regs);
-               } else {
-                       device_interrupt(16 + i, 16 + i, regs);
-               }
-       }
-       restore_flags(flags);
-}
-#endif /* ALCOR || XLT */
-
-static inline void 
-cabriolet_and_eb66p_device_interrupt(unsigned long vector,
-                                    struct pt_regs *regs)
-{
-       unsigned long pld;
-       unsigned int i;
-       unsigned long flags;
-
-       save_and_cli(flags);
-
-       /* Read the interrupt summary registers */
-       pld = inb(0x804) | (inb(0x805) << 8) | (inb(0x806) << 16);
-
-#if 0
-       printk("[0x%04X/0x%04X]", pld, inb(0x20) | (inb(0xA0) << 8));
-#endif
-
-       /*
-        * Now for every possible bit set, work through them and call
-        * the appropriate interrupt handler.
-        */
-       while (pld) {
-               i = ffz(~pld);
-               pld &= pld - 1; /* clear least bit set */
-               if (i == 4) {
-                       isa_device_interrupt(vector, regs);
-               } else {
-                       device_interrupt(16 + i, 16 + i, regs);
-               }
-       }
-       restore_flags(flags);
-}
-
-static inline void 
-mikasa_device_interrupt(unsigned long vector, struct pt_regs *regs)
-{
-       unsigned long pld;
-       unsigned int i;
-       unsigned long flags;
-
-       save_and_cli(flags);
-
-       /* Read the interrupt summary registers */
-       pld = (((unsigned long) (~inw(0x534)) & 0x0000ffffUL) << 16) |
-               (((unsigned long) inb(0xa0))  <<  8) |
-               ((unsigned long) inb(0x20));
-
-#if 0
-       printk("[0x%08lx]", pld);
-#endif
-
-       /*
-        * Now for every possible bit set, work through them and call
-        * the appropriate interrupt handler.
-        */
-       while (pld) {
-               i = ffz(~pld);
-               pld &= pld - 1; /* clear least bit set */
-               if (i < 16) {
-                       isa_device_interrupt(vector, regs);
-               } else {
-                       device_interrupt(i, i, regs);
-               }
-       }
-       restore_flags(flags);
-}
-
-static inline void 
-eb66_and_eb64p_device_interrupt(unsigned long vector, struct pt_regs *regs)
-{
-       unsigned long pld;
-       unsigned int i;
-       unsigned long flags;
-
-       save_and_cli(flags);
-
-       /* Read the interrupt summary registers */
-       pld = inb(0x26) | (inb(0x27) << 8);
-       /*
-        * Now, for every possible bit set, work through
-        * them and call the appropriate interrupt handler.
-        */
-       while (pld) {
-               i = ffz(~pld);
-               pld &= pld - 1; /* clear least bit set */
-
-               if (i == 5) {
-                       isa_device_interrupt(vector, regs);
-               } else {
-                       device_interrupt(16 + i, 16 + i, regs);
-               }
-       }
-       restore_flags(flags);
-}
-
-#if defined(CONFIG_ALPHA_MIATA) || defined(CONFIG_ALPHA_SX164)
-/* We have to conditionally compile this because of PYXIS_xxx symbols */
-static inline void 
-miata_device_interrupt(unsigned long vector, struct pt_regs *regs)
-{
-       unsigned long pld, tmp;
-       unsigned int i;
-       unsigned long flags;
-
-       save_and_cli(flags);
-
-       /* Read the interrupt summary register of PYXIS */
-       pld = *(vulp)PYXIS_INT_REQ;
-
-#if 0
-       printk("[0x%08lx/0x%08lx/0x%04x]", pld,
-              *(vulp)PYXIS_INT_MASK, inb(0x20) | (inb(0xA0) << 8));
-#endif
-
-#ifdef CONFIG_ALPHA_MIATA
-       /*
-        * For now, AND off any bits we are not interested in:
-        *   HALT (2), timer (6), ISA Bridge (7), 21142/3 (8)
-        * then all the PCI slots/INTXs (12-31).
-        */
-       /* Maybe HALT should only be used for SRM console boots? */
-       pld &= 0x00000000fffff1c4UL;
-#endif
-#ifdef CONFIG_ALPHA_SX164
-       /*
-        * For now, AND off any bits we are not interested in:
-        *  HALT (2), timer (6), ISA Bridge (7)
-        * then all the PCI slots/INTXs (8-23)
-        */
-       /* Maybe HALT should only be used for SRM console boots? */
-       pld &= 0x0000000000ffffc0UL;
-#endif /* SX164 */
-
-       /*
-        * Now for every possible bit set, work through them and call
-        * the appropriate interrupt handler.
-        */
-       while (pld) {
-               i = ffz(~pld);
-               pld &= pld - 1; /* clear least bit set */
-               if (i == 7) {
-                       isa_device_interrupt(vector, regs);
-               } else if (i == 6)
-                       continue;
-               else { /* if not timer int */
-                       device_interrupt(16 + i, 16 + i, regs);
-               }
-               *(vulp)PYXIS_INT_REQ = 1UL << i; mb();
-               tmp = *(vulp)PYXIS_INT_REQ;
-       }
-       restore_flags(flags);
-}
-#endif /* MIATA || SX164 */
-
-static inline void 
-noritake_device_interrupt(unsigned long vector, struct pt_regs *regs)
-{
-       unsigned long pld;
-       unsigned int i;
-       unsigned long flags;
-
-       save_and_cli(flags);
-
-       /* Read the interrupt summary registers of NORITAKE */
-       pld = ((unsigned long) inw(0x54c) << 32) |
-               ((unsigned long) inw(0x54a) << 16) |
-               ((unsigned long) inb(0xa0)  <<  8) |
-               ((unsigned long) inb(0x20));
-
-#if 0
-       printk("[0x%08lx]", pld);
-#endif
-
-       /*
-        * Now for every possible bit set, work through them and call
-        * the appropriate interrupt handler.
-        */
-       while (pld) {
-               i = ffz(~pld);
-               pld &= pld - 1; /* clear least bit set */
-               if (i < 16) {
-                       isa_device_interrupt(vector, regs);
-               } else {
-                       device_interrupt(i, i, regs);
-               }
-       }
-       restore_flags(flags);
-}
-
-#if defined(CONFIG_ALPHA_DP264)
-/* we have to conditionally compile this because of TSUNAMI_xxx symbols */
-static inline void dp264_device_interrupt(unsigned long vector,
-                                                  struct pt_regs * regs)
-{
-        unsigned long pld, tmp;
-        unsigned int i;
-        unsigned long flags;
-
-       __save_and_cli(flags);
-
-        /* Read the interrupt summary register of TSUNAMI */
-        pld = (*(vulp)TSUNAMI_CSR_DIR0);
-
-#if 0
-        printk("[0x%08lx/0x%08lx/0x%04x]", pld,
-              *(vulp)TSUNAMI_CSR_DIM0,
-              inb(0x20) | (inb(0xA0) << 8));
-#endif
-
-        /*
-         * Now for every possible bit set, work through them and call
-         * the appropriate interrupt handler.
-         */
-        while (pld) {
-                i = ffz(~pld);
-                pld &= pld - 1; /* clear least bit set */
-                if (i == 55) {
-                        isa_device_interrupt(vector, regs);
-               } else { /* if not timer int */
-                        device_interrupt(16 + i, 16 + i, regs);
-                }
-#if 0
-               *(vulp)TSUNAMI_CSR_DIR0 = 1UL << i; mb();
-               tmp = *(vulp)TSUNAMI_CSR_DIR0;
-#endif
-        }
-       __restore_flags(flags);
-}
-#endif /* DP264 */
-
-#if defined(CONFIG_ALPHA_RAWHIDE)
-/* we have to conditionally compile this because of MCPCIA_xxx symbols */
-static inline void rawhide_device_interrupt(unsigned long vector,
-                                                  struct pt_regs * regs)
-{
-#if 0
-        unsigned long pld;
-        unsigned int i;
-        unsigned long flags;
-
-       __save_and_cli(flags);
-
-       /* PLACEHOLDER, perhaps never used if we always do SRM */
-
-       __restore_flags(flags);
-#endif
-}
-#endif /* RAWHIDE */
-
-#if defined(CONFIG_ALPHA_RUFFIAN)
-static inline void
-ruffian_device_interrupt(unsigned long vector, struct pt_regs *regs)
-
-{
-       unsigned long pld;
-       unsigned int i;
-       unsigned long flags;
-
-        save_and_cli(flags);
-
-       /* Read the interrupt summary register of PYXIS */
-       pld = *(vulp)PYXIS_INT_REQ;
-
-       /* For now, AND off any bits we are not interested in:
-        * HALT (2), timer (6), ISA Bridge (7), 21142 (8)
-        * then all the PCI slots/INTXs (12-31) 
-        * flash(5) :DWH:
-        */
-        pld &= 0x00000000ffffff9fUL;/* was ffff7f */
-
-       /*
-        * Now for every possible bit set, work through them and call
-        * the appropriate interrupt handler.
-        */
-
-       while (pld) {
-               i = ffz(~pld);
-               pld &= pld - 1; /* clear least bit set */
-               if (i == 7) {
-                       /* Copy this bit from isa_device_interrupt cause
-                          we need to hook into int 0 for the timer.  I
-                          refuse to soil device_interrupt with ifdefs.  */
-
-                       /* Generate a PCI interrupt acknowledge cycle.
-                          The PIC will respond with the interrupt
-                          vector of the highest priority interrupt
-                          that is pending.  The PALcode sets up the
-                          interrupts vectors such that irq level L
-                          generates vector L.  */
-
-                       unsigned int j = *(vuip)PYXIS_IACK_SC & 0xff;
-                       if (j == 7 && !(inb(0x20) & 0x80)) {
-                               /* It's only a passive release... */
-                       } else if (j == 0) {
-                               timer_interrupt(regs);
-                               ack_irq(0);
-                       } else {
-                               device_interrupt(j, j, regs);
-                       }
-                } else { /* if not timer int */
-                       device_interrupt(16 + i, 16 + i, regs);
-               }
-
-                *(vulp)PYXIS_INT_REQ = 1UL << i; mb();
-                *(vulp)PYXIS_INT_REQ; /* read to force the write */
-       }
-       restore_flags(flags);
-}
-#endif /* RUFFIAN */
-
-static inline void takara_device_interrupt(unsigned long vector,
-                                          struct pt_regs * regs)
-{
-       unsigned long flags;
-       unsigned intstatus;
-
-       save_and_cli(flags);
-
-       /*
-        * The PALcode will have passed us vectors 0x800 or 0x810,
-        * which are fairly arbitrary values and serve only to tell
-        * us whether an interrupt has come in on IRQ0 or IRQ1. If
-        * it's IRQ1 it's a PCI interrupt; if it's IRQ0, it's
-        * probably ISA, but PCI interrupts can come through IRQ0
-        * as well if the interrupt controller isn't in accelerated
-        * mode.
-        *
-        * OTOH, the accelerator thing doesn't seem to be working
-        * overly well, so what we'll do instead is try directly
-        * examining the Master Interrupt Register to see if it's a
-        * PCI interrupt, and if _not_ then we'll pass it on to the
-        * ISA handler.
-        */
-
-       intstatus = inw(0x500) & 15;
-       if (intstatus) {
-               /*
-                * This is a PCI interrupt. Check each bit and
-                * despatch an interrupt if it's set.
-                */
-               if (intstatus & 8) device_interrupt(16+3, 16+3, regs);
-               if (intstatus & 4) device_interrupt(16+2, 16+2, regs);
-               if (intstatus & 2) device_interrupt(16+1, 16+1, regs);
-               if (intstatus & 1) device_interrupt(16+0, 16+0, regs);
-       } else
-               isa_device_interrupt (vector, regs);
-
-       restore_flags(flags);
-}
-
-#endif /* CONFIG_PCI */
-
-/*
- * Jensen is special: the vector is 0x8X0 for EISA interrupt X, and
- * 0x9X0 for the local motherboard interrupts..
- *
- *     0x660 - NMI
- *
- *     0x800 - IRQ0  interval timer (not used, as we use the RTC timer)
- *     0x810 - IRQ1  line printer (duh..)
- *     0x860 - IRQ6  floppy disk
- *     0x8E0 - IRQ14 SCSI controller
- *
- *     0x900 - COM1
- *     0x920 - COM2
- *     0x980 - keyboard
- *     0x990 - mouse
- *
- * PCI-based systems are more sane: they don't have the local
- * interrupts at all, and have only normal PCI interrupts from
- * devices.  Happily it's easy enough to do a sane mapping from the
- * Jensen..  Note that this means that we may have to do a hardware
- * "ack" to a different interrupt than we report to the rest of the
- * world.
- */
-static inline void 
-srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
-{
-       int irq, ack;
-       unsigned long flags;
-
-       __save_and_cli(flags);
-
-#ifdef __SMP__
-if (smp_processor_id()) printk("srm_device_interrupt on other CPU\n");
-#endif
-
-       ack = irq = (vector - 0x800) >> 4;
-
-#ifdef CONFIG_ALPHA_JENSEN
-       switch (vector) {
-       case 0x660: handle_nmi(regs); return;
-               /* local device interrupts: */
-       case 0x900: handle_irq(4, regs); return;        /* com1 -> irq 4 */
-       case 0x920: handle_irq(3, regs); return;        /* com2 -> irq 3 */
-       case 0x980: handle_irq(1, regs); return;        /* kbd -> irq 1 */
-       case 0x990: handle_irq(9, regs); return;        /* mouse -> irq 9 */
-       default:
-               if (vector > 0x900) {
-                       printk("Unknown local interrupt %lx\n", vector);
-               }
-       }
-       /* irq1 is supposed to be the keyboard, silly Jensen
-          (is this really needed??) */
-       if (irq == 1)
-               irq = 7;
-#endif /* CONFIG_ALPHA_JENSEN */
-
-#ifdef CONFIG_ALPHA_MIATA
-       /*
-        * I really hate to do this, but the MIATA SRM console ignores the
-        *  low 8 bits in the interrupt summary register, and reports the
-        *  vector 0x80 *lower* than I expected from the bit numbering in
-        *  the documentation.
-        * This was done because the low 8 summary bits really aren't used
-        *  for reporting any interrupts (the PCI-ISA bridge, bit 7, isn't
-        *  used for this purpose, as PIC interrupts are delivered as the
-        *  vectors 0x800-0x8f0).
-        * But I really don't want to change the fixup code for allocation
-        *  of IRQs, nor the irq_mask maintenance stuff, both of which look
-        *  nice and clean now.
-        * So, here's this grotty hack... :-(
-        */
-       if (irq >= 16)
-               ack = irq = irq + 8;
-#endif /* CONFIG_ALPHA_MIATA */
-
-#ifdef CONFIG_ALPHA_NORITAKE
-       /*
-        * I really hate to do this, too, but the NORITAKE SRM console also
-        *  reports PCI vectors *lower* than I expected from the bit numbers
-        *  in the documentation.
-        * But I really don't want to change the fixup code for allocation
-        *  of IRQs, nor the irq_mask maintenance stuff, both of which look
-        *  nice and clean now.
-        * So, here's this additional grotty hack... :-(
-        */
-       if (irq >= 16)
-               ack = irq = irq + 1;
-#endif /* CONFIG_ALPHA_NORITAKE */
-
-#ifdef CONFIG_ALPHA_SABLE
-       irq = sable_mask_to_irq[(ack)];
-#if 0
-       if (irq == 5 || irq == 9 || irq == 10 || irq == 11 ||
-           irq == 14 || irq == 15)
-               printk("srm_device_interrupt: vector=0x%lx  ack=0x%x"
-                      "  irq=0x%x\n", vector, ack, irq);
-#endif
-#endif /* CONFIG_ALPHA_SABLE */
-
-#ifdef CONFIG_ALPHA_DP264
-        /*
-         * the DP264 SRM console reports PCI interrupts with a vector
-        * 0x100 *higher* than one might expect, as PCI IRQ 0 (ie bit 0)
-        * shows up as IRQ 16, etc, etc. We adjust it down by 16 to have
-        * it line up with the actual bit numbers from the DIM registers,
-        * which is how we manage the interrupts/mask. Sigh...
-         */
-        if (irq >= 32)
-                ack = irq = irq - 16;
-#endif /* DP264 */
-
-#ifdef CONFIG_ALPHA_RAWHIDE
-        /*
-         * the RAWHIDE SRM console reports PCI interrupts with a vector
-        * 0x80 *higher* than one might expect, as PCI IRQ 0 (ie bit 0)
-        * shows up as IRQ 24, etc, etc. We adjust it down by 8 to have
-        * it line up with the actual bit numbers from the REQ registers,
-        * which is how we manage the interrupts/mask. Sigh...
-        *
-        * also, PCI #1 interrupts are offset some more... :-(
-         */
-       if (irq == 52)
-         ack = irq = 56; /* SCSI on PCI 1 is special */
-       else {
-         if (irq >= 24) /* adjust all PCI interrupts down 8 */
-           ack = irq = irq - 8;
-         if (irq >= 48) /* adjust PCI bus 1 interrupts down another 8 */
-           ack = irq = irq - 8;
-       }
-#endif /* RAWHIDE */
-
-       device_interrupt(irq, ack, regs);
-
-       __restore_flags(flags);
-}
 
 /*
  * Start listening for interrupts..
  */
-unsigned long probe_irq_on(void)
+
+unsigned long
+probe_irq_on(void)
 {
        struct irqaction * action;
        unsigned long irqs = 0;
        unsigned long delay;
        unsigned int i;
 
-       for (i = NR_IRQS - 1; i > 0; i--) {
+       for (i = ACTUAL_NR_IRQS - 1; i > 0; i--) {
                if (!(PROBE_MASK & (1UL << i))) {
                        continue;
                }
@@ -1634,8 +750,8 @@ unsigned long probe_irq_on(void)
        for (delay = jiffies + HZ/10; delay > jiffies; )
                barrier();
 
-       /* now filter out any obviously spurious interrupts */
-       return irqs & ~irq_mask;
+       /* Now filter out any obviously spurious interrupts.  */
+       return irqs & ~alpha_irq_mask;
 }
 
 /*
@@ -1643,11 +759,13 @@ unsigned long probe_irq_on(void)
  * we have several candidates (but we return the lowest-numbered
  * one).
  */
-int probe_irq_off(unsigned long irqs)
+
+int
+probe_irq_off(unsigned long irqs)
 {
        int i;
        
-        irqs &= irq_mask;
+        irqs &= alpha_irq_mask;
        if (!irqs)
                return 0;
        i = ffz(~irqs);
@@ -1656,42 +774,10 @@ int probe_irq_off(unsigned long irqs)
        return i;
 }
 
-extern void lca_machine_check (unsigned long vector, unsigned long la,
-                              struct pt_regs *regs);
-extern void apecs_machine_check(unsigned long vector, unsigned long la,
-                               struct pt_regs * regs);
-extern void cia_machine_check(unsigned long vector, unsigned long la,
-                             struct pt_regs * regs);
-extern void pyxis_machine_check(unsigned long vector, unsigned long la,
-                               struct pt_regs * regs);
-extern void t2_machine_check(unsigned long vector, unsigned long la,
-                            struct pt_regs * regs);
-extern void tsunami_machine_check(unsigned long vector, unsigned long la,
-                                 struct pt_regs * regs);
-extern void mcpcia_machine_check(unsigned long vector, unsigned long la,
-                                struct pt_regs * regs);
-
-static void 
-machine_check(unsigned long vector, unsigned long la, struct pt_regs *regs)
-{
-#if defined(CONFIG_ALPHA_LCA)
-       lca_machine_check(vector, la, regs);
-#elif defined(CONFIG_ALPHA_APECS)
-       apecs_machine_check(vector, la, regs);
-#elif defined(CONFIG_ALPHA_CIA)
-       cia_machine_check(vector, la, regs);
-#elif defined(CONFIG_ALPHA_PYXIS)
-       pyxis_machine_check(vector, la, regs);
-#elif defined(CONFIG_ALPHA_T2)
-       t2_machine_check(vector, la, regs);
-#elif defined(CONFIG_ALPHA_TSUNAMI)
-       tsunami_machine_check(vector, la, regs);
-#elif defined(CONFIG_ALPHA_MCPCIA)
-       mcpcia_machine_check(vector, la, regs);
-#else
-       printk("Machine check\n");
-#endif
-}
+
+/*
+ * The main interrupt entry point.
+ */
 
 asmlinkage void 
 do_entInt(unsigned long type, unsigned long vector, unsigned long la_ptr,
@@ -1701,56 +787,20 @@ do_entInt(unsigned long type, unsigned long vector, unsigned long la_ptr,
        switch (type) {
        case 0:
 #ifdef __SMP__
-/*             irq_enter(smp_processor_id(), 0); ??????? */
                handle_ipi(&regs);
-/*             irq_exit(smp_processor_id(), 0);  ??????? */
                return;
-#else /* __SMP__ */
+#else
                printk("Interprocessor interrupt? You must be kidding\n");
-#endif /* __SMP__ */
+#endif
                break;
        case 1:
-               handle_irq(RTC_IRQ, &regs);
+               handle_irq(RTC_IRQ, -1, &regs);
                return;
        case 2:
-               machine_check(vector, la_ptr, &regs);
+               alpha_mv.machine_check(vector, la_ptr, &regs);
                return;
        case 3:
-#if defined(CONFIG_ALPHA_JENSEN) || \
-    defined(CONFIG_ALPHA_NONAME) || \
-    defined(CONFIG_ALPHA_P2K)    || \
-    defined(CONFIG_ALPHA_SRM)
-               srm_device_interrupt(vector, &regs);
-#elif defined(CONFIG_ALPHA_MIATA) || \
-    defined(CONFIG_ALPHA_SX164)
-               miata_device_interrupt(vector, &regs);
-#elif defined(CONFIG_ALPHA_NORITAKE)
-               noritake_device_interrupt(vector, &regs);
-#elif defined(CONFIG_ALPHA_ALCOR) || \
-      defined(CONFIG_ALPHA_XLT)
-               alcor_and_xlt_device_interrupt(vector, &regs);
-#elif defined(CONFIG_ALPHA_CABRIOLET) || \
-      defined(CONFIG_ALPHA_EB66P)     || \
-      defined(CONFIG_ALPHA_EB164)     || \
-      defined(CONFIG_ALPHA_PC164)     || \
-      defined(CONFIG_ALPHA_LX164)
-               cabriolet_and_eb66p_device_interrupt(vector, &regs);
-#elif defined(CONFIG_ALPHA_MIKASA)
-               mikasa_device_interrupt(vector, &regs);
-#elif defined(CONFIG_ALPHA_EB66) || \
-      defined(CONFIG_ALPHA_EB64P)
-               eb66_and_eb64p_device_interrupt(vector, &regs);
-#elif defined(CONFIG_ALPHA_RUFFIAN)
-               ruffian_device_interrupt(vector, &regs);
-#elif defined(CONFIG_ALPHA_DP264)
-               dp264_device_interrupt(vector, &regs);
-#elif defined(CONFIG_ALPHA_RAWHIDE)
-               rawhide_device_interrupt(vector, &regs);
-#elif defined(CONFIG_ALPHA_TAKARA)
-               takara_device_interrupt(vector, &regs);
-#elif NR_IRQS == 16
-               isa_device_interrupt(vector, &regs);
-#endif
+               alpha_mv.device_interrupt(vector, &regs);
                return;
        case 4:
                printk("Performance counter interrupt\n");
@@ -1761,226 +811,9 @@ do_entInt(unsigned long type, unsigned long vector, unsigned long la_ptr,
        printk("PC = %016lx PS=%04lx\n", regs.pc, regs.ps);
 }
 
-extern asmlinkage void entInt(void);
-
-static inline void sable_init_IRQ(void)
-{
-       outb(irq_mask      , 0x537);    /* slave 0 */
-       outb(irq_mask >>  8, 0x53b);    /* slave 1 */
-       outb(irq_mask >> 16, 0x53d);    /* slave 2 */
-       outb(0x44, 0x535);              /* enable cascades in master */
-}
-
-#if defined(CONFIG_ALPHA_SX164)
-static inline void sx164_init_IRQ(void)
-{
-#if !defined(CONFIG_ALPHA_SRM)
-       /* note invert on MASK bits */
-       *(vulp)PYXIS_INT_MASK  = ~((long)irq_mask >> 16); mb();
-        *(vulp)PYXIS_INT_MASK;
-#endif /* !SRM */
-       enable_irq(16 + 6);     /* enable timer */
-       enable_irq(16 + 7);     /* enable ISA PIC cascade */
-       enable_irq(2);          /* enable cascade */
-}
-#endif /* SX164 */
-
-#if defined(CONFIG_ALPHA_RUFFIAN)
-static inline void ruffian_init_IRQ(void)
-{
-       /* invert 6&7 for i82371 */
-       *(vulp)PYXIS_INT_HILO  = 0x000000c0UL; mb();
-       *(vulp)PYXIS_INT_CNFG  = 0x00002064UL; mb();     /* all clear */
-       *(vulp)PYXIS_INT_MASK  = 0x00000000UL; mb();
-       *(vulp)PYXIS_INT_REQ   = 0xffffffffUL; mb();
-
-       outb(0x11,0xA0);
-       outb(0x08,0xA1);
-       outb(0x02,0xA1);
-       outb(0x01,0xA1);
-       outb(0xFF,0xA1);
-       
-       outb(0x11,0x20);
-       outb(0x00,0x21);
-       outb(0x04,0x21);
-       outb(0x01,0x21);
-       outb(0xFF,0x21);
-       
-       /* Send -INTA pulses to clear any pending interrupts ...*/
-       *(vuip) IACK_SC;
-
-       /* Finish writing the 82C59A PIC Operation Control Words */
-       outb(0x20,0xA0);
-       outb(0x20,0x20);
-       
-       /* Turn on the interrupt controller, the timer interrupt  */
-       enable_irq(16 + 7);     /* enable ISA PIC cascade */
-       enable_irq(0);          /* enable timer */
-       enable_irq(2);          /* enable 2nd PIC cascade */
-}
-#endif /* RUFFIAN */
-
-#ifdef CONFIG_ALPHA_MIATA
-static inline void miata_init_IRQ(void)
-{
-       /* note invert on MASK bits */
-       *(vulp)PYXIS_INT_MASK = ~((long)irq_mask >> 16); mb(); /* invert */
-#if 0
-       /* these break on MiataGL so we'll try not to do it at all */
-       *(vulp)PYXIS_INT_HILO = 0x000000B2UL; mb();     /* ISA/NMI HI */
-       *(vulp)PYXIS_RT_COUNT = 0UL; mb();              /* clear count */
-#endif
-       /* clear upper timer */
-       *(vulp)PYXIS_INT_REQ  = 0x4000000000000000UL; mb();
-
-       enable_irq(16 + 2);     /* enable HALT switch - SRM only? */
-       enable_irq(16 + 6);     /* enable timer */
-       enable_irq(16 + 7);     /* enable ISA PIC cascade */
-       enable_irq(2);          /* enable cascade */
-}
-#endif
-
-static inline void noritake_init_IRQ(void)
-{
-       outw(~(irq_mask >> 16), 0x54a); /* note invert */
-       outw(~(irq_mask >> 32), 0x54c); /* note invert */
-       enable_irq(2);                  /* enable cascade */
-}
-
-#if defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
-static inline void alcor_and_xlt_init_IRQ(void)
-{
-       *(vuip)GRU_INT_MASK  = ~(irq_mask >> 16); mb(); /* note invert */
-       *(vuip)GRU_INT_EDGE  = 0U; mb();                /* all are level */
-       *(vuip)GRU_INT_HILO  = 0x80000000U; mb();       /* ISA only HI */
-       *(vuip)GRU_INT_CLEAR = 0UL; mb();               /* all clear */
-
-       enable_irq(16 + 31);            /* enable (E)ISA PIC cascade */
-       enable_irq(2);                  /* enable cascade */
-}
-#endif /* ALCOR || XLT */
-
-static inline void mikasa_init_IRQ(void)
-{
-       outw(~(irq_mask >> 16), 0x536); /* note invert */
-       enable_irq(2);                  /* enable cascade */
-}
-
-#if defined(CONFIG_ALPHA_DP264)
-static inline void dp264_init_IRQ(void)
-{
-       /* note invert on MASK bits */
-        *(vulp)TSUNAMI_CSR_DIM0 =
-             ~(irq_mask) & ~0x0000000000000000UL; mb();
-        *(vulp)TSUNAMI_CSR_DIM0;
-        enable_irq(55);     /* enable CYPRESS interrupt controller (ISA) */
-       enable_irq(2);
-}
-#endif /* DP264 */
-
-#if defined(CONFIG_ALPHA_RAWHIDE)
-static inline void rawhide_init_IRQ(void)
-{
-       /* HACK ALERT! only PCI busses 0 and 1 are used currently,
-          and routing is only to CPU #1*/
-
-       *(vuip)MCPCIA_INT_MASK0(0) =
-           (~((irq_mask) >> 16) & 0x00ffffffU) | 0x00ff0000U; mb();
-       /* ... and read it back to make sure it got written.  */
-       *(vuip)MCPCIA_INT_MASK0(0);
-
-       *(vuip)MCPCIA_INT_MASK0(1) =
-           (~((irq_mask) >> 40) & 0x00ffffffU) | 0x00fe0000U; mb();
-       /* ... and read it back to make sure it got written.  */
-       *(vuip)MCPCIA_INT_MASK0(1);
-       enable_irq(2);
-}
-#endif /* RAWHIDE */
-
-static inline void takara_init_IRQ(void)
-{
-       unsigned int ctlreg = inl(0x500);
-
-       ctlreg &= ~0x8000;     /* return to non-accelerated mode */
-       outw(ctlreg >> 16, 0x502);
-       outw(ctlreg & 0xFFFF, 0x500);
-       ctlreg = 0x05107c00;   /* enable the PCI interrupt register */
-       printk("Setting to 0x%08x\n", ctlreg);
-       outw(ctlreg >> 16, 0x502);
-       outw(ctlreg & 0xFFFF, 0x500);
-       enable_irq(2);
-}
-
-static inline void init_IRQ_35(void)
-{
-#if !defined(CONFIG_ALPHA_SRM)
-       outl(irq_mask >> 16, 0x804);
-#endif /* !SRM */
-       enable_irq(16 + 4);             /* enable SIO cascade */
-       enable_irq(2);                  /* enable cascade */
-}
-
-static inline void init_IRQ_32(void)
-{
-       outb(irq_mask >> 16, 0x26);
-       outb(irq_mask >> 24, 0x27);
-       enable_irq(16 + 5);             /* enable SIO cascade */
-       enable_irq(2);                  /* enable cascade */
-}
-
-static inline void init_IRQ_16(void)
-{
-       enable_irq(2);                  /* enable cascade */
-}
-
 void __init
 init_IRQ(void)
 {
        wrent(entInt, 0);
-
-/* FIXME FIXME FIXME FIXME FIXME */
-#if !defined(CONFIG_ALPHA_DP264)
-       /* we need to figure out why these fail on the DP264 */
-       outb(0, DMA1_RESET_REG);
-       outb(0, DMA2_RESET_REG);
-#endif /* !DP264 */
-/* FIXME FIXME FIXME FIXME FIXME */
-#if !defined(CONFIG_ALPHA_SX164) && !defined(CONFIG_ALPHA_DP264)
-       outb(0, DMA1_CLR_MASK_REG);
-       /* we need to figure out why this fails on the SX164 */
-       outb(0, DMA2_CLR_MASK_REG);
-#endif /* !SX164 && !DP264 */
-/* end FIXMEs */
-
-#if defined(CONFIG_ALPHA_SABLE)
-       sable_init_IRQ();
-#elif defined(CONFIG_ALPHA_MIATA)
-       miata_init_IRQ();
-#elif defined(CONFIG_ALPHA_SX164)
-       sx164_init_IRQ();
-#elif defined(CONFIG_ALPHA_NORITAKE)
-       noritake_init_IRQ();
-#elif defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
-       alcor_and_xlt_init_IRQ();
-#elif defined(CONFIG_ALPHA_MIKASA)
-       mikasa_init_IRQ();
-#elif defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P) || \
-      defined(CONFIG_ALPHA_PC164)     || defined(CONFIG_ALPHA_LX164) || \
-      defined(CONFIG_ALPHA_EB164)
-       init_IRQ_35();
-#elif defined(CONFIG_ALPHA_RUFFIAN)
-       ruffian_init_IRQ();
-#elif defined(CONFIG_ALPHA_DP264)
-        dp264_init_IRQ();
-#elif defined(CONFIG_ALPHA_RAWHIDE)
-        rawhide_init_IRQ();
-#elif defined(CONFIG_ALPHA_TAKARA)
-        takara_init_IRQ();
-#elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P)
-       init_IRQ_32();
-#elif NR_IRQS == 16
-       init_IRQ_16();
-#else
-#error "How do I initialize the interrupt hardware?"
-#endif
+       alpha_mv.init_irq();
 }
diff --git a/arch/alpha/kernel/irq.h b/arch/alpha/kernel/irq.h
new file mode 100644 (file)
index 0000000..08db28e
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *     linux/arch/alpha/kernel/irq.h
+ *
+ *     Copyright (C) 1995 Linus Torvalds
+ *     Copyright (C) 1998 Richard Henderson
+ *
+ * This file contains declarations and inline functions for interfacing
+ * with the IRQ handling routines in irq.c.
+ */
+
+
+/* FIXME FIXME FIXME FIXME FIXME */
+/* We need to figure out why these fail on the DP264 & SX164.  Otherwise
+   we'd just do this in init_IRQ().  */
+#define STANDARD_INIT_IRQ_PROLOG       \
+       outb(0, DMA1_RESET_REG);        \
+       outb(0, DMA2_RESET_REG);        \
+       outb(0, DMA1_CLR_MASK_REG);     \
+       outb(0, DMA2_CLR_MASK_REG)
+
+extern unsigned long alpha_irq_mask;
+
+extern void generic_ack_irq(unsigned long irq);
+extern void isa_device_interrupt(unsigned long vector, struct pt_regs * regs);
+extern void srm_device_interrupt(unsigned long vector, struct pt_regs * regs);
+
+extern void handle_irq(int irq, int ack, struct pt_regs * regs);
diff --git a/arch/alpha/kernel/lca.c b/arch/alpha/kernel/lca.c
deleted file mode 100644 (file)
index 7e9b03c..0000000
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * Code common to all LCA chips.
- *
- * Written by David Mosberger (davidm@cs.arizona.edu) with some code
- * taken from Dave Rusling's (david.rusling@reo.mts.dec.com) 32-bit
- * bios code.
- */
-#include <linux/kernel.h>
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-
-#include <asm/ptrace.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-
-/*
- * BIOS32-style PCI interface:
- */
-
-#define vulp   volatile unsigned long *
-#define vuip   volatile unsigned int *
-
-/*
- * Machine check reasons.  Defined according to PALcode sources
- * (osf.h and platform.h).
- */
-#define MCHK_K_TPERR           0x0080
-#define MCHK_K_TCPERR          0x0082
-#define MCHK_K_HERR            0x0084
-#define MCHK_K_ECC_C           0x0086
-#define MCHK_K_ECC_NC          0x0088
-#define MCHK_K_UNKNOWN         0x008A
-#define MCHK_K_CACKSOFT                0x008C
-#define MCHK_K_BUGCHECK                0x008E
-#define MCHK_K_OS_BUGCHECK     0x0090
-#define MCHK_K_DCPERR          0x0092
-#define MCHK_K_ICPERR          0x0094
-
-/*
- * Platform-specific machine-check reasons:
- */
-#define MCHK_K_SIO_SERR                0x204   /* all platforms so far */
-#define MCHK_K_SIO_IOCHK       0x206   /* all platforms so far */
-#define MCHK_K_DCSR            0x208   /* all but Noname */
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-unsigned int LCA_DMA_WIN_BASE = LCA_DMA_WIN_BASE_DEFAULT;
-unsigned int LCA_DMA_WIN_SIZE = LCA_DMA_WIN_SIZE_DEFAULT;
-#endif /* SRM_SETUP */
-
-/*
- * Given a bus, device, and function number, compute resulting
- * configuration space address and setup the LCA_IOC_CONF register
- * accordingly.  It is therefore not safe to have concurrent
- * invocations to configuration space access routines, but there
- * really shouldn't be any need for this.
- *
- * Type 0:
- *
- *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | | | | | | | | | | | | | | | | | | |F|F|F|R|R|R|R|R|R|0|0|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *     31:11   Device select bit.
- *     10:8    Function number
- *      7:2    Register number
- *
- * Type 1:
- *
- *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *     31:24   reserved
- *     23:16   bus number (8 bits = 128 possible buses)
- *     15:11   Device number (5 bits)
- *     10:8    function number
- *      7:2    register number
- *  
- * Notes:
- *     The function number selects which function of a multi-function device 
- *     (e.g., SCSI and Ethernet).
- * 
- *     The register selects a DWORD (32 bit) register offset.  Hence it
- *     doesn't get shifted by 2 bits as we want to "drop" the bottom two
- *     bits.
- */
-static int mk_conf_addr(unsigned char bus, unsigned char device_fn,
-                       unsigned char where, unsigned long *pci_addr)
-{
-       unsigned long addr;
-
-       if (bus == 0) {
-               int device = device_fn >> 3;
-               int func = device_fn & 0x7;
-
-               /* type 0 configuration cycle: */
-
-               if (device > 12) {
-                       return -1;
-               }
-
-               *(vulp)LCA_IOC_CONF = 0;
-               addr = (1 << (11 + device)) | (func << 8) | where;
-       } else {
-               /* type 1 configuration cycle: */
-               *(vulp)LCA_IOC_CONF = 1;
-               addr = (bus << 16) | (device_fn << 8) | where;
-       }
-       *pci_addr = addr;
-       return 0;
-}
-
-
-static unsigned int conf_read(unsigned long addr)
-{
-       unsigned long flags, code, stat0;
-       unsigned int value;
-
-       save_flags(flags);
-       cli();
-
-       /* reset status register to avoid loosing errors: */
-       stat0 = *(vulp)LCA_IOC_STAT0;
-       *(vulp)LCA_IOC_STAT0 = stat0;
-       mb();
-
-       /* access configuration space: */
-
-       value = *(vuip)addr;
-       draina();
-
-       stat0 = *(vulp)LCA_IOC_STAT0;
-       if (stat0 & LCA_IOC_STAT0_ERR) {
-               code = ((stat0 >> LCA_IOC_STAT0_CODE_SHIFT)
-                       & LCA_IOC_STAT0_CODE_MASK);
-               if (code != 1) {
-                       printk("lca.c:conf_read: got stat0=%lx\n", stat0);
-               }
-
-               /* reset error status: */
-               *(vulp)LCA_IOC_STAT0 = stat0;
-               mb();
-               wrmces(0x7);                    /* reset machine check */
-
-               value = 0xffffffff;
-       }
-       restore_flags(flags);
-       return value;
-}
-
-
-static void conf_write(unsigned long addr, unsigned int value)
-{
-       unsigned long flags, code, stat0;
-
-       save_flags(flags);      /* avoid getting hit by machine check */
-       cli();
-
-       /* reset status register to avoid loosing errors: */
-       stat0 = *(vulp)LCA_IOC_STAT0;
-       *(vulp)LCA_IOC_STAT0 = stat0;
-       mb();
-
-       /* access configuration space: */
-
-       *(vuip)addr = value;
-       draina();
-
-       stat0 = *(vulp)LCA_IOC_STAT0;
-       if (stat0 & LCA_IOC_STAT0_ERR) {
-               code = ((stat0 >> LCA_IOC_STAT0_CODE_SHIFT)
-                       & LCA_IOC_STAT0_CODE_MASK);
-               if (code != 1) {
-                       printk("lca.c:conf_write: got stat0=%lx\n", stat0);
-               }
-
-               /* reset error status: */
-               *(vulp)LCA_IOC_STAT0 = stat0;
-               mb();
-               wrmces(0x7);                    /* reset machine check */
-       }
-       restore_flags(flags);
-}
-
-
-int pcibios_read_config_byte (unsigned char bus, unsigned char device_fn,
-                             unsigned char where, unsigned char *value)
-{
-       unsigned long addr = LCA_CONF;
-       unsigned long pci_addr;
-
-       *value = 0xff;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x00;
-       *value = conf_read(addr) >> ((where & 3) * 8);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_read_config_word (unsigned char bus, unsigned char device_fn,
-                             unsigned char where, unsigned short *value)
-{
-       unsigned long addr = LCA_CONF;
-       unsigned long pci_addr;
-
-       *value = 0xffff;
-
-       if (where & 0x1) {
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-       }
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr)) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x08;
-       *value = conf_read(addr) >> ((where & 3) * 8);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_read_config_dword (unsigned char bus, unsigned char device_fn,
-                              unsigned char where, unsigned int *value)
-{
-       unsigned long addr = LCA_CONF;
-       unsigned long pci_addr;
-
-       *value = 0xffffffff;
-       if (where & 0x3) {
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-       }
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr)) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x18;
-       *value = conf_read(addr);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_write_config_byte (unsigned char bus, unsigned char device_fn,
-                              unsigned char where, unsigned char value)
-{
-       unsigned long addr = LCA_CONF;
-       unsigned long pci_addr;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x00;
-       conf_write(addr, value << ((where & 3) * 8));
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_write_config_word (unsigned char bus, unsigned char device_fn,
-                              unsigned char where, unsigned short value)
-{
-       unsigned long addr = LCA_CONF;
-       unsigned long pci_addr;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x08;
-       conf_write(addr, value << ((where & 3) * 8));
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_write_config_dword (unsigned char bus, unsigned char device_fn,
-                               unsigned char where, unsigned int value)
-{
-       unsigned long addr = LCA_CONF;
-       unsigned long pci_addr;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x18;
-       conf_write(addr, value << ((where & 3) * 8));
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-unsigned long lca_init(unsigned long mem_start, unsigned long mem_end)
-{
-#ifdef CONFIG_ALPHA_SRM_SETUP
-       /* check window 0 for enabled and mapped to 0 */
-       if ((*(vulp)LCA_IOC_W_BASE0 & (1UL<<33)) &&
-           (*(vulp)LCA_IOC_T_BASE0 == 0))
-       {
-         LCA_DMA_WIN_BASE = *(vulp)LCA_IOC_W_BASE0 & 0xffffffffUL;
-         LCA_DMA_WIN_SIZE = *(vulp)LCA_IOC_W_MASK0 & 0xffffffffUL;
-         LCA_DMA_WIN_SIZE += 1;
-#if 1
-         printk("lca_init: using Window 0 settings\n");
-         printk("lca_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
-                *(vulp)LCA_IOC_W_BASE0,
-                *(vulp)LCA_IOC_W_MASK0,
-                *(vulp)LCA_IOC_T_BASE0);
-#endif
-       }
-       else    /* check window 2 for enabled and mapped to 0 */
-       if ((*(vulp)LCA_IOC_W_BASE1 & (1UL<<33)) &&
-           (*(vulp)LCA_IOC_T_BASE1 == 0))
-       {
-         LCA_DMA_WIN_BASE = *(vulp)LCA_IOC_W_BASE1 & 0xffffffffUL;
-         LCA_DMA_WIN_SIZE = *(vulp)LCA_IOC_W_MASK1 & 0xffffffffUL;
-         LCA_DMA_WIN_SIZE += 1;
-#if 1
-         printk("lca_init: using Window 1 settings\n");
-         printk("lca_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
-                *(vulp)LCA_IOC_W_BASE1,
-                *(vulp)LCA_IOC_W_MASK1,
-                *(vulp)LCA_IOC_T_BASE1);
-#endif
-       }
-       else /* we must use our defaults... */
-#endif /* SRM_SETUP */
-       {
-       /*
-        * Set up the PCI->physical memory translation windows.
-        * For now, window 1 is disabled.  In the future, we may
-        * want to use it to do scatter/gather DMA.  Window 0
-        * goes at 1 GB and is 1 GB large.
-        */
-       *(vulp)LCA_IOC_W_BASE1 = 0UL<<33;
-
-       *(vulp)LCA_IOC_W_BASE0 = 1UL<<33 | LCA_DMA_WIN_BASE;
-       *(vulp)LCA_IOC_W_MASK0 = LCA_DMA_WIN_SIZE - 1;
-       *(vulp)LCA_IOC_T_BASE0 = 0;
-       }
-
-       /*
-        * Disable PCI parity for now.  The NCR53c810 chip has
-        * troubles meeting the PCI spec which results in
-        * data parity errors.
-        */
-       *(vulp)LCA_IOC_PAR_DIS = 1UL<<5;
-       return mem_start;
-}
-
-
-/*
- * Constants used during machine-check handling.  I suppose these
- * could be moved into lca.h but I don't see much reason why anybody
- * else would want to use them.
- */
-
-#define ESR_EAV                (1UL<< 0)       /* error address valid */
-#define ESR_CEE                (1UL<< 1)       /* correctable error */
-#define ESR_UEE                (1UL<< 2)       /* uncorrectable error */
-#define ESR_WRE                (1UL<< 3)       /* write-error */
-#define ESR_SOR                (1UL<< 4)       /* error source */
-#define ESR_CTE                (1UL<< 7)       /* cache-tag error */
-#define ESR_MSE                (1UL<< 9)       /* multiple soft errors */
-#define ESR_MHE                (1UL<<10)       /* multiple hard errors */
-#define ESR_NXM                (1UL<<12)       /* non-existent memory */
-
-#define IOC_ERR                (  1<<4)        /* ioc logs an error */
-#define IOC_CMD_SHIFT  0
-#define IOC_CMD                (0xf<<IOC_CMD_SHIFT)
-#define IOC_CODE_SHIFT 8
-#define IOC_CODE       (0xf<<IOC_CODE_SHIFT)
-#define IOC_LOST       (  1<<5)
-#define IOC_P_NBR      ((__u32) ~((1<<13) - 1))
-
-
-void mem_error (unsigned long esr, unsigned long ear)
-{
-       printk("    %s %s error to %s occurred at address %x\n",
-              *((esr & ESR_CEE) ? "Correctable" :
-                (esr & ESR_UEE) ? "Uncorrectable" : "A"),
-              (esr & ESR_WRE) ? "write" : "read",
-              (esr & ESR_SOR) ? "memory" : "b-cache",
-              (unsigned) (ear & 0x1ffffff8));
-       if (esr & ESR_CTE) {
-               printk("    A b-cache tag parity error was detected.\n");
-       }
-       if (esr & ESR_MSE) {
-               printk("    Several other correctable errors occurred.\n");
-       }
-       if (esr & ESR_MHE) {
-               printk("    Several other uncorrectable errors occurred.\n");
-       }
-       if (esr & ESR_NXM) {
-               printk("    Attempted to access non-existent memory.\n");
-       }
-}
-
-
-void ioc_error (__u32 stat0, __u32 stat1)
-{
-       static const char * const pci_cmd[] = {
-               "Interrupt Acknowledge", "Special", "I/O Read", "I/O Write",
-               "Rsvd 1", "Rsvd 2", "Memory Read", "Memory Write", "Rsvd3",
-               "Rsvd4", "Configuration Read", "Configuration Write",
-               "Memory Read Multiple", "Dual Address", "Memory Read Line",
-               "Memory Write and Invalidate"
-       };
-       static const char * const err_name[] = {
-               "exceeded retry limit", "no device", "bad data parity",
-               "target abort", "bad address parity", "page table read error",
-               "invalid page", "data error"
-       };
-       unsigned code = (stat0 & IOC_CODE) >> IOC_CODE_SHIFT;
-       unsigned cmd  = (stat0 & IOC_CMD)  >> IOC_CMD_SHIFT;
-
-       printk("    %s initiated PCI %s cycle to address %x"
-              " failed due to %s.\n",
-              code > 3 ? "PCI" : "CPU", pci_cmd[cmd], stat1, err_name[code]);
-
-       if (code == 5 || code == 6) {
-               printk("    (Error occurred at PCI memory address %x.)\n",
-                      (stat0 & ~IOC_P_NBR));
-       }
-       if (stat0 & IOC_LOST) {
-               printk("    Other PCI errors occurred simultaneously.\n");
-       }
-}
-
-
-void lca_machine_check (unsigned long vector, unsigned long la,
-                       struct pt_regs *regs)
-{
-       unsigned long * ptr;
-       const char * reason;
-       union el_lca el;
-       char buf[128];
-       long i;
-
-       printk(KERN_CRIT "lca: machine check (la=0x%lx,pc=0x%lx)\n",
-              la, regs->pc);
-       el.c = (struct el_common *) la;
-       /*
-        * The first quadword after the common header always seems to
-        * be the machine check reason---don't know why this isn't
-        * part of the common header instead.  In the case of a long
-        * logout frame, the upper 32 bits is the machine check
-        * revision level, which we ignore for now.
-        */
-       switch (el.c->code & 0xffffffff) {
-       case MCHK_K_TPERR:      reason = "tag parity error"; break;
-       case MCHK_K_TCPERR:     reason = "tag control parity error"; break;
-       case MCHK_K_HERR:       reason = "access to non-existent memory"; break;
-       case MCHK_K_ECC_C:      reason = "correctable ECC error"; break;
-       case MCHK_K_ECC_NC:     reason = "non-correctable ECC error"; break;
-       case MCHK_K_CACKSOFT:   reason = "MCHK_K_CACKSOFT"; break; /* what's this? */
-       case MCHK_K_BUGCHECK:   reason = "illegal exception in PAL mode"; break;
-       case MCHK_K_OS_BUGCHECK: reason = "callsys in kernel mode"; break;
-       case MCHK_K_DCPERR:     reason = "d-cache parity error"; break;
-       case MCHK_K_ICPERR:     reason = "i-cache parity error"; break;
-       case MCHK_K_SIO_SERR:   reason = "SIO SERR occurred on on PCI bus"; break;
-       case MCHK_K_SIO_IOCHK:  reason = "SIO IOCHK occurred on ISA bus"; break;
-       case MCHK_K_DCSR:       reason = "MCHK_K_DCSR"; break;
-       case MCHK_K_UNKNOWN:
-       default:
-               sprintf(buf, "reason for machine-check unknown (0x%lx)",
-                       el.c->code & 0xffffffff);
-               reason = buf;
-               break;
-       }
-
-       wrmces(rdmces());       /* reset machine check pending flag */
-
-       switch (el.c->size) {
-       case sizeof(struct el_lca_mcheck_short):
-               printk(KERN_CRIT
-                      "  Reason: %s (short frame%s, dc_stat=%lx):\n",
-                      reason, el.c->retry ? ", retryable" : "",
-                      el.s->dc_stat);
-               if (el.s->esr & ESR_EAV) {
-                       mem_error(el.s->esr, el.s->ear);
-               }
-               if (el.s->ioc_stat0 & IOC_ERR) {
-                       ioc_error(el.s->ioc_stat0, el.s->ioc_stat1);
-               }
-               break;
-
-       case sizeof(struct el_lca_mcheck_long):
-               printk(KERN_CRIT "  Reason: %s (long frame%s):\n",
-                      reason, el.c->retry ? ", retryable" : "");
-               printk(KERN_CRIT
-                      "    reason: %lx  exc_addr: %lx  dc_stat: %lx\n", 
-                      el.l->pt[0], el.l->exc_addr, el.l->dc_stat);
-               printk(KERN_CRIT "    car: %lx\n", el.l->car);
-               if (el.l->esr & ESR_EAV) {
-                       mem_error(el.l->esr, el.l->ear);
-               }
-               if (el.l->ioc_stat0 & IOC_ERR) {
-                       ioc_error(el.l->ioc_stat0, el.l->ioc_stat1);
-               }
-               break;
-
-       default:
-               printk(KERN_CRIT "  Unknown errorlog size %d\n", el.c->size);
-       }
-
-       /* dump the logout area to give all info: */
-
-       ptr = (unsigned long *) la;
-       for (i = 0; i < el.c->size / sizeof(long); i += 2) {
-               printk(KERN_CRIT " +%8lx %016lx %016lx\n",
-                      i*sizeof(long), ptr[i], ptr[i+1]);
-       }
-}
-
-/*
- * The following routines are needed to support the SPEED changing
- * necessary to successfully manage the thermal problem on the AlphaBook1.
- */
-
-void
-lca_clock_print(void)
-{
-        long    pmr_reg;
-
-        pmr_reg = READ_PMR;
-
-        printk("Status of clock control:\n");
-        printk("\tPrimary clock divisor\t0x%x\n", GET_PRIMARY(pmr_reg));
-        printk("\tOverride clock divisor\t0x%x\n", GET_OVERRIDE(pmr_reg));
-        printk("\tInterrupt override is %s\n",
-              (pmr_reg & LCA_PMR_INTO) ? "on" : "off"); 
-        printk("\tDMA override is %s\n",
-              (pmr_reg & LCA_PMR_DMAO) ? "on" : "off"); 
-
-}
-
-int
-lca_get_clock(void)
-{
-        long    pmr_reg;
-
-        pmr_reg = READ_PMR;
-        return(GET_PRIMARY(pmr_reg));
-
-}
-
-void
-lca_clock_fiddle(int divisor)
-{
-        long    pmr_reg;
-
-        pmr_reg = READ_PMR;
-        SET_PRIMARY_CLOCK(pmr_reg, divisor);
-       /* lca_norm_clock = divisor; */
-        WRITE_PMR(pmr_reg);
-        mb();
-}
diff --git a/arch/alpha/kernel/machvec.h b/arch/alpha/kernel/machvec.h
new file mode 100644 (file)
index 0000000..5aa2ead
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ *     linux/arch/alpha/kernel/machvec.h
+ *
+ *     Copyright (C) 1997, 1998  Richard Henderson
+ *
+ * This file has goodies to help simplify instantiation of machine vectors.
+ */
+
+
+/* Whee.  TSUNAMI doesn't have an HAE.  Fix things up for the GENERIC
+   kernel by defining the HAE address to be that of the cache.  Now
+   we can read and write it as we like.  ;-)  */
+#define TSUNAMI_HAE_ADDRESS    (&alpha_mv.hae_cache)
+
+/* Only a few systems don't define IACK_SC, handling all interrupts through
+   the SRM console.  But splitting out that one case from IO() below
+   seems like such a pain.  Define this to get things to compile.  */
+#define JENSEN_IACK_SC         1
+#define T2_IACK_SC             1
+
+
+/*
+ * Some helpful macros for filling in the blanks.
+ */
+
+#define CAT1(x,y)  x##y
+#define CAT(x,y)   CAT1(x,y)
+
+#define DO_DEFAULT_RTC                         \
+       rtc_port: 0x70, rtc_addr: 0x80
+
+#define DO_EV4_MMU                                                     \
+       max_asn:                        EV4_MAX_ASN,                    \
+       mmu_context_mask:               ~0UL,                           \
+       mv_get_mmu_context:             ev4_get_mmu_context,            \
+       mv_flush_tlb_current:           ev4_flush_tlb_current,          \
+       mv_flush_tlb_other:             ev4_flush_tlb_other,            \
+       mv_flush_tlb_current_page:      ev4_flush_tlb_current_page
+
+#define DO_EV5_MMU                                                     \
+       max_asn:                        EV5_MAX_ASN,                    \
+       mmu_context_mask:               ~0UL,                           \
+       mv_get_mmu_context:             ev5_get_mmu_context,            \
+       mv_flush_tlb_current:           ev5_flush_tlb_current,          \
+       mv_flush_tlb_other:             ev5_flush_tlb_other,            \
+       mv_flush_tlb_current_page:      ev5_flush_tlb_current_page
+
+#define DO_EV6_MMU                                                     \
+       max_asn:                        EV5_MAX_ASN,                    \
+       mmu_context_mask:               0xfffffffffful,                 \
+       mv_get_mmu_context:             ev5_get_mmu_context,            \
+       mv_flush_tlb_current:           ev5_flush_tlb_current,          \
+       mv_flush_tlb_other:             ev5_flush_tlb_other,            \
+       mv_flush_tlb_current_page:      ev5_flush_tlb_current_page
+
+#define IO_LITE(UP,low1,low2)                                          \
+       hae_register:           (unsigned long *) CAT(UP,_HAE_ADDRESS), \
+       iack_sc:                CAT(UP,_IACK_SC),                       \
+       mv_inb:                 CAT(low1,_inb),                         \
+       mv_inw:                 CAT(low1,_inw),                         \
+       mv_inl:                 CAT(low1,_inl),                         \
+       mv_outb:                CAT(low1,_outb),                        \
+       mv_outw:                CAT(low1,_outw),                        \
+       mv_outl:                CAT(low1,_outl),                        \
+       mv_readb:               CAT(low1,_readb),                       \
+       mv_readw:               CAT(low1,_readw),                       \
+       mv_readl:               CAT(low1,_readl),                       \
+       mv_readq:               CAT(low1,_readq),                       \
+       mv_writeb:              CAT(low1,_writeb),                      \
+       mv_writew:              CAT(low1,_writew),                      \
+       mv_writel:              CAT(low1,_writel),                      \
+       mv_writeq:              CAT(low1,_writeq),                      \
+       mv_dense_mem:           CAT(low2,_dense_mem)
+
+#define IO(UP,low1,low2)                                               \
+       IO_LITE(UP,low1,low2),                                          \
+       pci_read_config_byte:   CAT(low2,_pcibios_read_config_byte),    \
+       pci_read_config_word:   CAT(low2,_pcibios_read_config_word),    \
+       pci_read_config_dword:  CAT(low2,_pcibios_read_config_dword),   \
+       pci_write_config_byte:  CAT(low2,_pcibios_write_config_byte),   \
+       pci_write_config_word:  CAT(low2,_pcibios_write_config_word),   \
+       pci_write_config_dword: CAT(low2,_pcibios_write_config_dword),  \
+       dma_win_base:           CAT(UP,_DMA_WIN_BASE_DEFAULT),          \
+        dma_win_size:          CAT(UP,_DMA_WIN_SIZE_DEFAULT)
+
+/* Any assembler that can generate a GENERIC kernel can generate BWX
+   instructions.  So always use them for PYXIS I/O.  */
+
+#define DO_APECS_IO    IO(APECS,apecs,apecs)
+#define DO_CIA_IO      IO(CIA,cia,cia)
+#define DO_LCA_IO      IO(LCA,lca,lca)
+#define DO_MCPCIA_IO   IO(MCPCIA,mcpcia,mcpcia)
+#define DO_PYXIS_IO    IO(PYXIS,pyxis_bw,pyxis)
+#define DO_T2_IO       IO(T2,t2,t2)
+#define DO_TSUNAMI_IO  IO(TSUNAMI,tsunami,tsunami)
+
+#define BUS(which)                                     \
+       mv_virt_to_bus: CAT(which,_virt_to_bus),        \
+       mv_bus_to_virt: CAT(which,_bus_to_virt)
+
+#define DO_APECS_BUS   BUS(apecs)
+#define DO_CIA_BUS     BUS(cia)
+#define DO_LCA_BUS     BUS(lca)
+#define DO_MCPCIA_BUS  BUS(mcpcia)
+#define DO_PYXIS_BUS   BUS(pyxis)
+#define DO_T2_BUS      BUS(t2)
+#define DO_TSUNAMI_BUS BUS(tsunami)
+
+
+/*
+ * In a GENERIC kernel, we have lots of these vectors floating about,
+ * all but one of which we want to go away.  In a non-GENERIC kernel,
+ * we want only one, ever.
+ *
+ * Accomplish this in the GENERIC kernel by puting all of the vectors
+ * in the .init.data section where they'll go away.  We'll copy the
+ * one we want to the real alpha_mv vector in setup_arch.
+ *
+ * Accomplish this in a non-GENERIC kernel by ifdef'ing out all but
+ * one of the vectors, which will not reside in .init.data.  We then
+ * alias this one vector to alpha_mv, so no copy is needed.
+ *
+ * Upshot: set __initdata to nothing for non-GENERIC kernels.
+ */
+
+#ifdef CONFIG_ALPHA_GENERIC
+#define __initmv __initdata
+#define ALIAS_MV(x)
+#else
+#define __initmv
+
+/* GCC actually has a syntax for defining aliases, but is under some
+   delusion that you shouldn't be able to declare it extern somewhere
+   else beforehand.  Fine.  We'll do it ourselves.  */
+#define ALIAS_MV(system) asm(".global alpha_mv\nalpha_mv = " #system "_mv");
+#endif
diff --git a/arch/alpha/kernel/mcpcia.c b/arch/alpha/kernel/mcpcia.c
deleted file mode 100644 (file)
index e88526f..0000000
+++ /dev/null
@@ -1,975 +0,0 @@
-/*
- * Code common to all MCbus-PCI adaptor chipsets
- *
- * Based on code written by David A Rusling (david.rusling@reo.mts.dec.com).
- *
- */
-#include <linux/kernel.h>
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/hwrpb.h>
-#include <asm/ptrace.h>
-#include <asm/mmu_context.h>
-
-/*
- * NOTE: Herein lie back-to-back mb instructions.  They are magic. 
- * One plausible explanation is that the i/o controller does not properly
- * handle the system transaction.  Another involves timing.  Ho hum.
- */
-
-extern struct hwrpb_struct *hwrpb;
-extern asmlinkage void wrmces(unsigned long mces);
-
-/*
- * BIOS32-style PCI interface:
- */
-
-#ifdef CONFIG_ALPHA_MCPCIA
-
-#undef DEBUG_CFG
-
-#ifdef DEBUG_CFG
-# define DBG_CFG(args) printk args
-#else
-# define DBG_CFG(args)
-#endif
-
-#undef DEBUG_PCI
-
-#ifdef DEBUG_PCI
-# define DBG_PCI(args) printk args
-#else
-# define DBG_PCI(args)
-#endif
-
-#define DEBUG_MCHECK
-
-#ifdef DEBUG_MCHECK
-# define DBG_MCK(args) printk args
-# define DEBUG_MCHECK_DUMP
-#else
-# define DBG_MCK(args)
-#endif
-
-#define vuip   volatile unsigned int  *
-#define vulp   volatile unsigned long  *
-
-static volatile unsigned int MCPCIA_mcheck_expected[NR_CPUS];
-static volatile unsigned int MCPCIA_mcheck_taken[NR_CPUS];
-static unsigned int MCPCIA_jd[NR_CPUS];
-
-#define MCPCIA_MAX_HOSES 2
-static int mcpcia_num_hoses = 0;
-
-static int pci_probe_enabled = 0; /* disable to start */
-
-static struct linux_hose_info *mcpcia_root = NULL, *mcpcia_last_hose;
-
-struct linux_hose_info *bus2hose[256];
-
-static inline unsigned long long_align(unsigned long addr)
-{
-       return ((addr + (sizeof(unsigned long) - 1)) &
-               ~(sizeof(unsigned long) - 1));
-}
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-unsigned int MCPCIA_DMA_WIN_BASE = MCPCIA_DMA_WIN_BASE_DEFAULT;
-unsigned int MCPCIA_DMA_WIN_SIZE = MCPCIA_DMA_WIN_SIZE_DEFAULT;
-unsigned long mcpcia_sm_base_r1, mcpcia_sm_base_r2, mcpcia_sm_base_r3;
-#endif /* SRM_SETUP */
-
-/*
- * Given a bus, device, and function number, compute resulting
- * configuration space address and setup the MCPCIA_HAXR2 register
- * accordingly.  It is therefore not safe to have concurrent
- * invocations to configuration space access routines, but there
- * really shouldn't be any need for this.
- *
- * Type 0:
- *
- *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *     31:11   Device select bit.
- *     10:8    Function number
- *      7:2    Register number
- *
- * Type 1:
- *
- *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *     31:24   reserved
- *     23:16   bus number (8 bits = 128 possible buses)
- *     15:11   Device number (5 bits)
- *     10:8    function number
- *      7:2    register number
- *  
- * Notes:
- *     The function number selects which function of a multi-function device 
- *     (e.g., SCSI and Ethernet).
- * 
- *     The register selects a DWORD (32 bit) register offset.  Hence it
- *     doesn't get shifted by 2 bits as we want to "drop" the bottom two
- *     bits.
- */
-
-static unsigned int
-conf_read(unsigned long addr, unsigned char type1,
-         struct linux_hose_info *hose)
-{
-       unsigned long flags;
-       unsigned long hoseno = hose->pci_hose_index;
-       unsigned int stat0, value, temp, cpu;
-
-       cpu = smp_processor_id();
-
-       save_and_cli(flags);
-
-       DBG_CFG(("conf_read(addr=0x%lx, type1=%d, hose=%d)\n",
-            addr, type1, hoseno));
-
-       /* reset status register to avoid losing errors: */
-       stat0 = *(vuip)MCPCIA_CAP_ERR(hoseno);
-       *(vuip)MCPCIA_CAP_ERR(hoseno) = stat0; mb();
-       temp = *(vuip)MCPCIA_CAP_ERR(hoseno);
-       DBG_CFG(("conf_read: MCPCIA CAP_ERR(%d) was 0x%x\n", hoseno, stat0));
-
-       mb();
-       draina();
-       MCPCIA_mcheck_expected[cpu] = 1;
-       MCPCIA_mcheck_taken[cpu] = 0;
-       mb();
-       /* access configuration space: */
-       value = *((vuip)addr);
-       mb();
-       mb();  /* magic */
-       if (MCPCIA_mcheck_taken[cpu]) {
-               MCPCIA_mcheck_taken[cpu] = 0;
-               value = 0xffffffffU;
-               mb();
-       }
-       MCPCIA_mcheck_expected[cpu] = 0;
-       mb();
-
-       DBG_CFG(("conf_read(): finished\n"));
-
-       restore_flags(flags);
-       return value;
-}
-
-
-static void
-conf_write(unsigned long addr, unsigned int value, unsigned char type1,
-          struct linux_hose_info *hose)
-{
-       unsigned long flags;
-       unsigned long hoseno = hose->pci_hose_index;
-       unsigned int stat0, temp, cpu;
-
-       cpu = smp_processor_id();
-
-       save_and_cli(flags);    /* avoid getting hit by machine check */
-
-       /* reset status register to avoid losing errors: */
-       stat0 = *(vuip)MCPCIA_CAP_ERR(hoseno);
-       *(vuip)MCPCIA_CAP_ERR(hoseno) = stat0; mb();
-       temp = *(vuip)MCPCIA_CAP_ERR(hoseno);
-       DBG_CFG(("conf_write: MCPCIA CAP_ERR(%d) was 0x%x\n", hoseno, stat0));
-
-       draina();
-       MCPCIA_mcheck_expected[cpu] = 1;
-       mb();
-       /* access configuration space: */
-       *((vuip)addr) = value;
-       mb();
-       mb();  /* magic */
-       temp = *(vuip)MCPCIA_CAP_ERR(hoseno); /* read to force the write */
-       MCPCIA_mcheck_expected[cpu] = 0;
-       mb();
-
-       DBG_CFG(("conf_write(): finished\n"));
-       restore_flags(flags);
-}
-
-static int mk_conf_addr(struct linux_hose_info *hose,
-                       unsigned char bus, unsigned char device_fn,
-                       unsigned char where, unsigned long *pci_addr,
-                       unsigned char *type1)
-{
-       unsigned long addr;
-
-       if (!pci_probe_enabled) /* if doing standard pci_init(), ignore */
-           return -1;
-
-       DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
-            " pci_addr=0x%p, type1=0x%p)\n",
-            bus, device_fn, where, pci_addr, type1));
-
-       /* type 1 configuration cycle for *ALL* busses */
-       *type1 = 1;
-
-       if (hose->pci_first_busno == bus)
-           bus = 0;
-       addr = (bus << 16) | (device_fn << 8) | (where);
-       addr <<= 5; /* swizzle for SPARSE */
-       addr |= hose->pci_config_space;
-
-       *pci_addr = addr;
-       DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
-       return 0;
-}
-
-
-int hose_read_config_byte (struct linux_hose_info *hose,
-                          unsigned char bus, unsigned char device_fn,
-                          unsigned char where, unsigned char *value)
-{
-       unsigned long addr;
-       unsigned char type1;
-
-       *value = 0xff;
-
-       if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       addr |= 0x00; /* or in length */
-
-       *value = conf_read(addr, type1, hose) >> ((where & 3) * 8);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int hose_read_config_word (struct linux_hose_info *hose,
-                          unsigned char bus, unsigned char device_fn,
-                          unsigned char where, unsigned short *value)
-{
-       unsigned long addr;
-       unsigned char type1;
-
-       *value = 0xffff;
-
-       if (where & 0x1) {
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-       }
-
-       if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1)) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       addr |= 0x08; /* or in length */
-
-       *value = conf_read(addr, type1, hose) >> ((where & 3) * 8);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int hose_read_config_dword (struct linux_hose_info *hose,
-                           unsigned char bus, unsigned char device_fn,
-                           unsigned char where, unsigned int *value)
-{
-       unsigned long addr;
-       unsigned char type1;
-
-       *value = 0xffffffff;
-
-       if (where & 0x3) {
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-       }
-
-       if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1)) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= 0x18; /* or in length */
-
-       *value = conf_read(addr, type1, hose);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int hose_write_config_byte (struct linux_hose_info *hose,
-                           unsigned char bus, unsigned char device_fn,
-                           unsigned char where, unsigned char value)
-{
-       unsigned long addr;
-       unsigned char type1;
-
-       if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       addr |= 0x00; /* or in length */
-
-       conf_write(addr, value << ((where & 3) * 8), type1, hose);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int hose_write_config_word (struct linux_hose_info *hose,
-                           unsigned char bus, unsigned char device_fn,
-                           unsigned char where, unsigned short value)
-{
-       unsigned long addr;
-       unsigned char type1;
-
-       if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       addr |= 0x08; /* or in length */
-
-       conf_write(addr, value << ((where & 3) * 8), type1, hose);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int hose_write_config_dword (struct linux_hose_info *hose,
-                            unsigned char bus, unsigned char device_fn,
-                            unsigned char where, unsigned int value)
-{
-       unsigned long addr;
-       unsigned char type1;
-
-       if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       addr |= 0x18; /* or in length */
-
-       conf_write(addr, value << ((where & 3) * 8), type1, hose);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-int pcibios_read_config_byte (unsigned char bus, unsigned char devfn,
-                             unsigned char where, unsigned char *value)
-{
-       return hose_read_config_byte(bus2hose[bus], bus, devfn, where, value);
-}
-
-int pcibios_read_config_word (unsigned char bus, unsigned char devfn,
-                             unsigned char where, unsigned short *value)
-{
-       return hose_read_config_word(bus2hose[bus], bus, devfn, where, value);
-}
-
-int pcibios_read_config_dword (unsigned char bus, unsigned char devfn,
-                              unsigned char where, unsigned int *value)
-{
-       return hose_read_config_dword(bus2hose[bus], bus, devfn, where, value);
-}
-
-int pcibios_write_config_byte (unsigned char bus, unsigned char devfn,
-                              unsigned char where, unsigned char value)
-{
-       return hose_write_config_byte(bus2hose[bus], bus, devfn, where, value);
-}
-
-int pcibios_write_config_word (unsigned char bus, unsigned char devfn,
-                              unsigned char where, unsigned short value)
-{
-       return hose_write_config_word(bus2hose[bus], bus, devfn, where, value);
-}
-
-int pcibios_write_config_dword (unsigned char bus, unsigned char devfn,
-                               unsigned char where, unsigned int value)
-{
-       return hose_write_config_dword(bus2hose[bus], bus, devfn, where, value);
-}
-
-unsigned long mcpcia_init(unsigned long mem_start, unsigned long mem_end)
-{
-    struct linux_hose_info *hose;
-    unsigned int mcpcia_err;
-    unsigned int pci_rev;
-    int h;
-
-    mem_start = long_align(mem_start);
-
-    for (h = 0; h < NR_CPUS; h++) {
-       MCPCIA_mcheck_expected[h] = 0;
-       MCPCIA_mcheck_taken[h] = 0;
-    }
-
-    /* first, find how many hoses we have */
-    for (h = 0; h < MCPCIA_MAX_HOSES; h++) {
-       pci_rev = *(vuip)MCPCIA_REV(h);
-#if 0
-       printk("mcpcia_init: got 0x%x for PCI_REV for hose %d\n",
-              pci_rev, h);
-#endif
-       if ((pci_rev >> 16) == PCI_CLASS_BRIDGE_HOST) {
-           mcpcia_num_hoses++;
-
-           hose = (struct linux_hose_info *)mem_start;
-           mem_start = long_align(mem_start + sizeof(*hose));
-
-           memset(hose, 0, sizeof(*hose));
-
-           if (mcpcia_root)
-               mcpcia_last_hose->next = hose;
-           else
-               mcpcia_root = hose;
-           mcpcia_last_hose = hose;
-
-           hose->pci_io_space = MCPCIA_IO(h);
-           hose->pci_mem_space = MCPCIA_DENSE(h);
-           hose->pci_config_space = MCPCIA_CONF(h);
-           hose->pci_sparse_space = MCPCIA_SPARSE(h);
-           hose->pci_hose_index = h;
-           hose->pci_first_busno = 255;
-           hose->pci_last_busno = 0;
-       }
-    }
-
-#if 1
-    printk("mcpcia_init: found %d hoses\n", mcpcia_num_hoses);
-#endif
-
-    /* now do init for each hose */
-    for (hose = mcpcia_root; hose; hose = hose->next) {
-      h = hose->pci_hose_index;
-#if 0
-#define PRINTK printk
-PRINTK("mcpcia_init: -------- hose %d --------\n",h);
-PRINTK("mcpcia_init: MCPCIA_REV 0x%x\n", *(vuip)MCPCIA_REV(h));
-PRINTK("mcpcia_init: MCPCIA_WHOAMI 0x%x\n", *(vuip)MCPCIA_WHOAMI(h));
-PRINTK("mcpcia_init: MCPCIA_HAE_MEM 0x%x\n", *(vuip)MCPCIA_HAE_MEM(h));
-PRINTK("mcpcia_init: MCPCIA_HAE_IO 0x%x\n", *(vuip)MCPCIA_HAE_IO(h));
-PRINTK("mcpcia_init: MCPCIA_HAE_DENSE 0x%x\n", *(vuip)MCPCIA_HAE_DENSE(h));
-PRINTK("mcpcia_init: MCPCIA_INT_CTL 0x%x\n", *(vuip)MCPCIA_INT_CTL(h));
-PRINTK("mcpcia_init: MCPCIA_INT_REQ 0x%x\n", *(vuip)MCPCIA_INT_REQ(h));
-PRINTK("mcpcia_init: MCPCIA_INT_TARG 0x%x\n", *(vuip)MCPCIA_INT_TARG(h));
-PRINTK("mcpcia_init: MCPCIA_INT_ADR 0x%x\n", *(vuip)MCPCIA_INT_ADR(h));
-PRINTK("mcpcia_init: MCPCIA_INT_ADR_EXT 0x%x\n", *(vuip)MCPCIA_INT_ADR_EXT(h));
-PRINTK("mcpcia_init: MCPCIA_INT_MASK0 0x%x\n", *(vuip)MCPCIA_INT_MASK0(h));
-PRINTK("mcpcia_init: MCPCIA_INT_MASK1 0x%x\n", *(vuip)MCPCIA_INT_MASK1(h));
-PRINTK("mcpcia_init: MCPCIA_HBASE 0x%x\n", *(vuip)MCPCIA_HBASE(h));
-#endif
-
-        /* 
-        * Set up error reporting. Make sure CPU_PE is OFF in the mask.
-        */
-#if 0
-       mcpcia_err = *(vuip)MCPCIA_ERR_MASK(h);
-       mcpcia_err &= ~4;   
-       *(vuip)MCPCIA_ERR_MASK(h) = mcpcia_err;
-       mb();
-       mcpcia_err = *(vuip)MCPCIA_ERR_MASK;
-#endif
-
-       mcpcia_err = *(vuip)MCPCIA_CAP_ERR(h);
-       mcpcia_err |= 0x0006;   /* master/target abort */
-       *(vuip)MCPCIA_CAP_ERR(h) = mcpcia_err;
-       mb() ;
-       mcpcia_err = *(vuip)MCPCIA_CAP_ERR(h);
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-       /* check window 0 for enabled and mapped to 0 */
-       if (((*(vuip)MCPCIA_W0_BASE(h) & 3) == 1) &&
-           (*(vuip)MCPCIA_T0_BASE(h) == 0) &&
-           ((*(vuip)MCPCIA_W0_MASK(h) & 0xfff00000U) > 0x0ff00000U))
-       {
-         MCPCIA_DMA_WIN_BASE = *(vuip)MCPCIA_W0_BASE(h) & 0xfff00000U;
-         MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W0_MASK(h) & 0xfff00000U;
-         MCPCIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-         printk("mcpcia_init: using Window 0 settings\n");
-         printk("mcpcia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-                *(vuip)MCPCIA_W0_BASE(h),
-                *(vuip)MCPCIA_W0_MASK(h),
-                *(vuip)MCPCIA_T0_BASE(h));
-#endif
-       }
-       else  /* check window 1 for enabled and mapped to 0 */
-       if (((*(vuip)MCPCIA_W1_BASE(h) & 3) == 1) &&
-           (*(vuip)MCPCIA_T1_BASE(h) == 0) &&
-           ((*(vuip)MCPCIA_W1_MASK(h) & 0xfff00000U) > 0x0ff00000U))
-{
-         MCPCIA_DMA_WIN_BASE = *(vuip)MCPCIA_W1_BASE(h) & 0xfff00000U;
-         MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W1_MASK(h) & 0xfff00000U;
-         MCPCIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-         printk("mcpcia_init: using Window 1 settings\n");
-         printk("mcpcia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-                *(vuip)MCPCIA_W1_BASE(h),
-                *(vuip)MCPCIA_W1_MASK(h),
-                *(vuip)MCPCIA_T1_BASE(h));
-#endif
-       }
-       else  /* check window 2 for enabled and mapped to 0 */
-       if (((*(vuip)MCPCIA_W2_BASE(h) & 3) == 1) &&
-           (*(vuip)MCPCIA_T2_BASE(h) == 0) &&
-           ((*(vuip)MCPCIA_W2_MASK(h) & 0xfff00000U) > 0x0ff00000U))
-       {
-         MCPCIA_DMA_WIN_BASE = *(vuip)MCPCIA_W2_BASE(h) & 0xfff00000U;
-         MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W2_MASK(h) & 0xfff00000U;
-         MCPCIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-         printk("mcpcia_init: using Window 2 settings\n");
-         printk("mcpcia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-                *(vuip)MCPCIA_W2_BASE(h),
-                *(vuip)MCPCIA_W2_MASK(h),
-                *(vuip)MCPCIA_T2_BASE(h));
-#endif
-       }
-       else  /* check window 3 for enabled and mapped to 0 */
-       if (((*(vuip)MCPCIA_W3_BASE(h) & 3) == 1) &&
-           (*(vuip)MCPCIA_T3_BASE(h) == 0) &&
-           ((*(vuip)MCPCIA_W3_MASK(h) & 0xfff00000U) > 0x0ff00000U))
-       {
-         MCPCIA_DMA_WIN_BASE = *(vuip)MCPCIA_W3_BASE(h) & 0xfff00000U;
-         MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W3_MASK(h) & 0xfff00000U;
-         MCPCIA_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-         printk("mcpcia_init: using Window 3 settings\n");
-         printk("mcpcia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-                *(vuip)MCPCIA_W3_BASE(h),
-                *(vuip)MCPCIA_W3_MASK(h),
-                *(vuip)MCPCIA_T3_BASE(h));
-#endif
-       }
-       else  /* we must use our defaults which were pre-initialized... */
-#endif /* SRM_SETUP */
-       {
-       /*
-        * Set up the PCI->physical memory translation windows.
-        * For now, windows 1,2 and 3 are disabled.  In the future, we may
-        * want to use them to do scatter/gather DMA.  Window 0
-        * goes at 1 GB and is 1 GB large.
-        */
-
-       *(vuip)MCPCIA_W0_BASE(h) = 1U | (MCPCIA_DMA_WIN_BASE & 0xfff00000U);
-       *(vuip)MCPCIA_W0_MASK(h) = (MCPCIA_DMA_WIN_SIZE - 1) & 0xfff00000U;
-       *(vuip)MCPCIA_T0_BASE(h) = 0;
-
-       *(vuip)MCPCIA_W1_BASE(h) = 0x0 ;
-       *(vuip)MCPCIA_W2_BASE(h) = 0x0 ;
-       *(vuip)MCPCIA_W3_BASE(h) = 0x0 ;
-
-       *(vuip)MCPCIA_HBASE(h) = 0x0 ;
-       mb();
-       }
-
-       /*
-        * check ASN in HWRPB for validity, report if bad
-        */
-       if (hwrpb->max_asn != MAX_ASN) {
-               printk("mcpcia_init: max ASN from HWRPB is bad (0x%lx)\n",
-                       hwrpb->max_asn);
-               hwrpb->max_asn = MAX_ASN;
-       }
-
-#if 0
-        {
-          unsigned int mcpcia_int_ctl = *((vuip)MCPCIA_INT_CTL(h));
-         printk("mcpcia_init: INT_CTL was 0x%x\n", mcpcia_int_ctl);
-          *(vuip)MCPCIA_INT_CTL(h) = 1U; mb();
-         mcpcia_int_ctl = *(vuip)MCPCIA_INT_CTL(h);
-        }
-#endif
-
-        {
-          unsigned int mcpcia_hae_mem = *(vuip)MCPCIA_HAE_MEM(h);
-          unsigned int mcpcia_hae_io = *(vuip)MCPCIA_HAE_IO(h);
-#if 0
-         printk("mcpcia_init: HAE_MEM was 0x%x\n", mcpcia_hae_mem);
-         printk("mcpcia_init: HAE_IO was 0x%x\n", mcpcia_hae_io);
-#endif
-#ifdef CONFIG_ALPHA_SRM_SETUP
-         /*
-           sigh... For the SRM setup, unless we know apriori what the HAE
-           contents will be, we need to setup the arbitrary region bases
-           so we can test against the range of addresses and tailor the
-           region chosen for the SPARSE memory access.
-
-           see include/asm-alpha/mcpcia.h for the SPARSE mem read/write
-         */
-         mcpcia_sm_base_r1 = (mcpcia_hae_mem      ) & 0xe0000000UL;/* reg 1 */
-         mcpcia_sm_base_r2 = (mcpcia_hae_mem << 16) & 0xf8000000UL;/* reg 2 */
-         mcpcia_sm_base_r3 = (mcpcia_hae_mem << 24) & 0xfc000000UL;/* reg 3 */
-         /*
-           Set the HAE cache, so that setup_arch() code
-           will use the SRM setting always. Our readb/writeb
-           code in mcpcia.h expects never to have to change
-           the contents of the HAE.
-          */
-         hae.cache = mcpcia_hae_mem;
-#else /* SRM_SETUP */
-          *(vuip)MCPCIA_HAE_MEM(h) = 0U; mb();
-         mcpcia_hae_mem = *(vuip)MCPCIA_HAE_MEM(h);
-          *(vuip)MCPCIA_HAE_IO(h) = 0; mb();
-         mcpcia_hae_io = *(vuip)MCPCIA_HAE_IO(h);
-#endif /* SRM_SETUP */
-        }
-    } /* end for-loop on hoses */
-    return mem_start;
-}
-
-int mcpcia_pci_clr_err(int h)
-{
-       unsigned int cpu = smp_processor_id();
-
-       MCPCIA_jd[cpu] = *(vuip)MCPCIA_CAP_ERR(h);
-#if 0
-       DBG_MCK(("MCPCIA_pci_clr_err: MCPCIA CAP_ERR(%d) after read 0x%x\n",
-            h, MCPCIA_jd[cpu]));
-#endif
-       *(vuip)MCPCIA_CAP_ERR(h) = 0xffffffff; mb(); /* clear them all */
-       MCPCIA_jd[cpu] = *(vuip)MCPCIA_CAP_ERR(h);
-       return 0;
-}
-
-static void
-mcpcia_print_uncorrectable(struct el_MCPCIA_uncorrected_frame_mcheck *logout)
-{
-  struct el_common_EV5_uncorrectable_mcheck *frame;
-  int i;
-
-  frame = &logout->procdata;
-
-  /* Print PAL fields */
-  for (i = 0; i < 24; i += 2) {
-    printk("\tpal temp[%d-%d]\t\t= %16lx %16lx\n\r",
-          i, i+1, frame->paltemp[i], frame->paltemp[i+1]);
-  }
-  for (i = 0; i < 8; i += 2) {
-    printk("\tshadow[%d-%d]\t\t= %16lx %16lx\n\r",
-          i, i+1, frame->shadow[i], 
-          frame->shadow[i+1]);
-  }
-  printk("\tAddr of excepting instruction\t= %16lx\n\r",
-        frame->exc_addr);
-  printk("\tSummary of arithmetic traps\t= %16lx\n\r",
-        frame->exc_sum);
-  printk("\tException mask\t\t\t= %16lx\n\r",
-        frame->exc_mask);
-  printk("\tBase address for PALcode\t= %16lx\n\r",
-        frame->pal_base);
-  printk("\tInterrupt Status Reg\t\t= %16lx\n\r",
-        frame->isr);
-  printk("\tCURRENT SETUP OF EV5 IBOX\t= %16lx\n\r",
-        frame->icsr);
-  printk("\tI-CACHE Reg %s parity error\t= %16lx\n\r",
-        (frame->ic_perr_stat & 0x800L) ? 
-        "Data" : "Tag", 
-        frame->ic_perr_stat); 
-  printk("\tD-CACHE error Reg\t\t= %16lx\n\r",
-        frame->dc_perr_stat);
-  if (frame->dc_perr_stat & 0x2) {
-    switch (frame->dc_perr_stat & 0x03c) {
-    case 8:
-      printk("\t\tData error in bank 1\n\r");
-      break;
-    case 4:
-      printk("\t\tData error in bank 0\n\r");
-      break;
-    case 20:
-      printk("\t\tTag error in bank 1\n\r");
-      break;
-    case 10:
-      printk("\t\tTag error in bank 0\n\r");
-      break;
-    }
-  }
-  printk("\tEffective VA\t\t\t= %16lx\n\r",
-        frame->va);
-  printk("\tReason for D-stream\t\t= %16lx\n\r",
-        frame->mm_stat);
-  printk("\tEV5 SCache address\t\t= %16lx\n\r",
-        frame->sc_addr);
-  printk("\tEV5 SCache TAG/Data parity\t= %16lx\n\r",
-        frame->sc_stat);
-  printk("\tEV5 BC_TAG_ADDR\t\t\t= %16lx\n\r",
-        frame->bc_tag_addr);
-  printk("\tEV5 EI_ADDR: Phys addr of Xfer\t= %16lx\n\r",
-        frame->ei_addr);
-  printk("\tFill Syndrome\t\t\t= %16lx\n\r",
-        frame->fill_syndrome);
-  printk("\tEI_STAT reg\t\t\t= %16lx\n\r",
-        frame->ei_stat);
-  printk("\tLD_LOCK\t\t\t\t= %16lx\n\r",
-        frame->ld_lock);
-}
-
-void mcpcia_machine_check(unsigned long type, unsigned long la_ptr,
-                        struct pt_regs * regs)
-{
-#if 0
-        printk("mcpcia machine check ignored\n") ;
-#else
-       struct el_common *mchk_header;
-       struct el_MCPCIA_uncorrected_frame_mcheck *mchk_logout;
-       unsigned int cpu = smp_processor_id();
-       int h = 0;
-
-       mchk_header = (struct el_common *)la_ptr;
-       mchk_logout = (struct el_MCPCIA_uncorrected_frame_mcheck *)la_ptr;
-
-#if 0
-       DBG_MCK(("mcpcia_machine_check: type=0x%lx la_ptr=0x%lx\n",
-            type, la_ptr));
-       DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
-            regs->pc, mchk_header->size, mchk_header->proc_offset,
-            mchk_header->sys_offset));
-#endif
-       /*
-        * Check if machine check is due to a badaddr() and if so,
-        * ignore the machine check.
-        */
-       mb();
-       mb();  /* magic */
-       if (MCPCIA_mcheck_expected[cpu]) {
-#if 0
-               DBG_MCK(("MCPCIA machine check expected\n"));
-#endif
-               MCPCIA_mcheck_expected[cpu] = 0;
-               MCPCIA_mcheck_taken[cpu] = 1;
-               mb();
-               mb();  /* magic */
-               draina();
-               mcpcia_pci_clr_err(h);
-               wrmces(0x7);
-               mb();
-       }
-#if 1
-       else {
-               printk("MCPCIA machine check NOT expected on CPU %d\n", cpu);
-               DBG_MCK(("mcpcia_machine_check: type=0x%lx pc=0x%lx"
-                        " code=0x%lx\n",
-                        type, regs->pc, mchk_header->code));
-
-               MCPCIA_mcheck_expected[cpu] = 0;
-               MCPCIA_mcheck_taken[cpu] = 1;
-               mb();
-               mb();  /* magic */
-               draina();
-               mcpcia_pci_clr_err(h);
-               wrmces(0x7);
-               mb();
-#ifdef DEBUG_MCHECK_DUMP
-               if (type == 0x620)
-                 printk("MCPCIA machine check: system CORRECTABLE!\n");
-               else if (type == 0x630)
-                 printk("MCPCIA machine check: processor CORRECTABLE!\n");
-               else
-                 mcpcia_print_uncorrectable(mchk_logout);
-#endif /* DEBUG_MCHECK_DUMP */
-       }
-#endif
-#endif
-}
-
-/*==========================================================================*/
-
-#define PRIMARY(b) ((b)&0xff)
-#define SECONDARY(b) (((b)>>8)&0xff)
-#define SUBORDINATE(b) (((b)>>16)&0xff)
-
-static int
-hose_scan_bridges(struct linux_hose_info *hose, unsigned char bus)
-{
-       unsigned int devfn, l, class;
-       unsigned char hdr_type = 0;
-       unsigned int found = 0;
-
-       for (devfn = 0; devfn < 0xff; ++devfn) {
-               if (PCI_FUNC(devfn) == 0) {
-                       hose_read_config_byte(hose, bus, devfn,
-                                             PCI_HEADER_TYPE, &hdr_type);
-               } else if (!(hdr_type & 0x80)) {
-                       /* not a multi-function device */
-                       continue;
-               }
-
-               /* Check if there is anything here. */
-               hose_read_config_dword(hose, bus, devfn, PCI_VENDOR_ID, &l);
-               if (l == 0xffffffff || l == 0x00000000) {
-                       hdr_type = 0;
-                       continue;
-               }
-
-               /* See if this is a bridge device. */
-               hose_read_config_dword(hose, bus, devfn,
-                                      PCI_CLASS_REVISION, &class);
-
-               if ((class >> 16) == PCI_CLASS_BRIDGE_PCI) {
-                       unsigned int busses;
-
-                       found++;
-
-                       hose_read_config_dword(hose, bus, devfn,
-                                              PCI_PRIMARY_BUS, &busses);
-
-DBG_PCI(("hose_scan_bridges: hose %d bus %d slot %d busses 0x%x\n",
-       hose->pci_hose_index, bus, PCI_SLOT(devfn), busses));
-                       /*
-                        * do something with first_busno and last_busno
-                        */
-                       if (hose->pci_first_busno > PRIMARY(busses)) {
-                               hose->pci_first_busno = PRIMARY(busses);
-DBG_PCI(("hose_scan_bridges: hose %d bus %d slot %d change first to %d\n",
-       hose->pci_hose_index, bus, PCI_SLOT(devfn), PRIMARY(busses)));
-                       }
-                       if (hose->pci_last_busno < SUBORDINATE(busses)) {
-                               hose->pci_last_busno = SUBORDINATE(busses);
-DBG_PCI(("hose_scan_bridges: hose %d bus %d slot %d change last to %d\n",
-       hose->pci_hose_index, bus, PCI_SLOT(devfn), SUBORDINATE(busses)));
-                       }
-                       /*
-                        * Now scan everything underneath the bridge.
-                        */
-                       hose_scan_bridges(hose, SECONDARY(busses));
-               }
-       }
-       return found;
-}
-
-static void
-hose_reconfigure_bridges(struct linux_hose_info *hose, unsigned char bus)
-{
-       unsigned int devfn, l, class;
-       unsigned char hdr_type = 0;
-
-       for (devfn = 0; devfn < 0xff; ++devfn) {
-               if (PCI_FUNC(devfn) == 0) {
-                       hose_read_config_byte(hose, bus, devfn,
-                                             PCI_HEADER_TYPE, &hdr_type);
-               } else if (!(hdr_type & 0x80)) {
-                       /* not a multi-function device */
-                       continue;
-               }
-
-               /* Check if there is anything here. */
-               hose_read_config_dword(hose, bus, devfn, PCI_VENDOR_ID, &l);
-               if (l == 0xffffffff || l == 0x00000000) {
-                       hdr_type = 0;
-                       continue;
-               }
-
-               /* See if this is a bridge device. */
-               hose_read_config_dword(hose, bus, devfn,
-                                      PCI_CLASS_REVISION, &class);
-
-               if ((class >> 16) == PCI_CLASS_BRIDGE_PCI) {
-                       unsigned int busses;
-
-                       hose_read_config_dword(hose, bus, devfn,
-                                              PCI_PRIMARY_BUS, &busses);
-
-                       /*
-                        * First reconfigure everything underneath the bridge.
-                        */
-                       hose_reconfigure_bridges(hose, (busses >> 8) & 0xff);
-
-                       /*
-                        * Unconfigure this bridges bus numbers,
-                        * pci_scan_bus() will fix this up properly.
-                        */
-                       busses &= 0xff000000;
-                       hose_write_config_dword(hose, bus, devfn,
-                                               PCI_PRIMARY_BUS, busses);
-               }
-       }
-}
-
-static void mcpcia_fixup_busno(struct linux_hose_info *hose, unsigned char bus)
-{
-       unsigned int nbus;
-
-       /*
-        * First, scan for all bridge devices underneath this hose,
-        * to determine the first and last busnos.
-        */
-       if (!hose_scan_bridges(hose, 0)) {
-               /* none found, exit */
-               hose->pci_first_busno = bus;
-               hose->pci_last_busno = bus;
-       } else {
-               /*
-                * Reconfigure all bridge devices underneath this hose.
-                */
-               hose_reconfigure_bridges(hose, hose->pci_first_busno);
-       }
-
-       /*
-        * Now reconfigure the hose to it's new bus number and set up
-        * our bus2hose mapping for this hose.
-        */
-       nbus = hose->pci_last_busno - hose->pci_first_busno;
-
-       hose->pci_first_busno = bus;
-
-DBG_PCI(("mcpcia_fixup_busno: hose %d startbus %d nbus %d\n",
-       hose->pci_hose_index, bus, nbus));
-
-       do {
-               bus2hose[bus++] = hose;
-       } while (nbus-- > 0);
-}
-
-static void mcpcia_probe(struct linux_hose_info *hose)
-{
-       static struct pci_bus *pchain = NULL;
-       struct pci_bus *pbus = &hose->pci_bus;
-       static unsigned char busno = 0;
-
-       /* Hoses include child PCI bridges in bus-range property,
-        * but we don't scan each of those ourselves, Linux generic PCI
-        * probing code will find child bridges and link them into this
-        * hose's root PCI device hierarchy.
-        */
-
-       pbus->number = pbus->secondary = busno;
-       pbus->sysdata = hose;
-
-       mcpcia_fixup_busno(hose, busno);
-
-       pbus->subordinate = pci_scan_bus(pbus); /* the original! */
-
-       /*
-        * Set the maximum subordinate bus of this hose.
-        */
-       hose->pci_last_busno = pbus->subordinate;
-#if 0
-       hose_write_config_byte(hose, busno, 0, 0x41, hose->pci_last_busno);
-#endif
-       busno = pbus->subordinate + 1;
-
-       /*
-        * Fixup the chain of primary PCI busses.
-        */
-       if (pchain) {
-               pchain->next = &hose->pci_bus;
-               pchain = pchain->next;
-       } else {
-               pchain = &pci_root;
-               memcpy(pchain, &hose->pci_bus, sizeof(pci_root));
-       }
-}
-
-void mcpcia_fixup(void)
-{
-       struct linux_hose_info *hose;
-
-       /* turn on Config space access finally! */
-       pci_probe_enabled = 1;
-
-       /* for each hose, probe and setup the devices on the hose */
-       for (hose = mcpcia_root; hose; hose = hose->next)
-               mcpcia_probe(hose);
-}
-#endif /* CONFIG_ALPHA_MCPCIA */
index efeafe411ed97ab639dc625b383807036992e83e..b3e919500a769fc2ed964ac1353f5d11d37ea4f5 100644 (file)
@@ -47,7 +47,7 @@ extern struct file_operations *get_chrfops(unsigned int);
 extern kdev_t get_unnamed_dev(void);
 extern void put_unnamed_dev(kdev_t);
 
-extern asmlinkage int sys_umount(char *);
+extern asmlinkage int sys_umount(char *, int);
 extern asmlinkage int sys_swapon(const char *specialfile, int swap_flags);
 extern asmlinkage unsigned long sys_brk(unsigned long);
 
@@ -542,7 +542,7 @@ asmlinkage int osf_umount(char *path, int flag)
        int ret;
 
        lock_kernel();
-       ret = sys_umount(path);
+       ret = sys_umount(path,flag);
        unlock_kernel();
        return ret;
 }
index ba3c41563c2eca34bc79368ec69161c4964da6d9..697572e7ae6706b72d2505f87ce6bc5d1e6a99ae 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/mman.h>
 #include <linux/elfcore.h>
 #include <linux/reboot.h>
+#include <linux/console.h>
 
 #ifdef CONFIG_RTC
 #include <linux/mc146818rtc.h>
@@ -41,6 +42,9 @@
 #include <asm/hwrpb.h>
 #include <asm/fpu.h>
 
+#include "proto.h"
+#include "bios32.h"
+
 /*
  * Initial task structure. Make this a per-architecture thing,
  * because different architectures tend to have different
@@ -62,20 +66,20 @@ union task_union init_task_union __attribute__((section("init_task")))
 /*
  * No need to acquire the kernel lock, we're entirely local..
  */
-asmlinkage int sys_sethae(unsigned long hae, unsigned long a1, unsigned long a2,
-       unsigned long a3, unsigned long a4, unsigned long a5,
-       struct pt_regs regs)
+asmlinkage int
+sys_sethae(unsigned long hae, unsigned long a1, unsigned long a2,
+          unsigned long a3, unsigned long a4, unsigned long a5,
+          struct pt_regs regs)
 {
-#if !defined(CONFIG_ALPHA_TSUNAMI)
        (&regs)->hae = hae;
-#endif
        return 0;
 }
 
 #ifdef __SMP__
 /* This is being executed in task 0 'user space'. */
 #define resched_needed() 1
-int cpu_idle(void *unused)
+int
+cpu_idle(void *unused)
 {
        extern volatile int smp_commenced;
 
@@ -90,7 +94,8 @@ int cpu_idle(void *unused)
        }
 }
 
-asmlinkage int sys_idle(void)
+asmlinkage int
+sys_idle(void)
 {
         if(current->pid != 0)
                 return -EPERM;
@@ -101,7 +106,8 @@ asmlinkage int sys_idle(void)
 
 #else /* __SMP__ */
 
-asmlinkage int sys_idle(void)
+asmlinkage int
+sys_idle(void)
 {
        int ret = -EPERM;
 
@@ -122,90 +128,101 @@ out:
 }
 #endif /* __SMP__ */
 
-#if defined(CONFIG_ALPHA_SRM_SETUP)
-extern void reset_for_srm(void);       
-extern unsigned long srm_hae;
-#endif
-
-static void finish_shutdown(void)
+void
+generic_kill_arch (int mode, char *restart_cmd)
 {
-#ifdef CONFIG_RTC  /* reset rtc to defaults */
-       unsigned char control;
-       unsigned long flags;
-
-       /* i'm not sure if i really need to disable interrupts here */
-       save_and_cli(flags);
-
-       /* reset periodic interrupt frequency */
-        CMOS_WRITE(0x26, RTC_FREQ_SELECT);
-
-       /* turn on periodic interrupts */
-       control = CMOS_READ(RTC_CONTROL);
-       control |= RTC_PIE;
-       CMOS_WRITE(control, RTC_CONTROL);       
-        CMOS_READ(RTC_INTR_FLAGS);
-       restore_flags(flags);
+       /* The following currently only has any effect on SRM.  We should
+          fix MILO to understand it.  Should be pretty easy.  Also we can
+          support RESTART2 via the ipc_buffer machinations pictured below,
+          which SRM ignores.  */
+
+       if (alpha_using_srm) {
+               struct percpu_struct *cpup;
+               unsigned long flags;
+       
+               cpup = (struct percpu_struct *)
+                 ((unsigned long)hwrpb + hwrpb->processor_offset);
+
+               flags = cpup->flags;
+
+               /* Clear reason to "default"; clear "bootstrap in progress". */
+               flags &= ~0x00ff0001UL;
+
+               if (mode == LINUX_REBOOT_CMD_RESTART) {
+                       if (!restart_cmd) {
+                               flags |= 0x00020000UL; /* "cold bootstrap" */
+                               cpup->ipc_buffer[0] = 0;
+                       } else {
+                               flags |=  0x00030000UL; /* "warm bootstrap" */
+                               strncpy(cpup->ipc_buffer, restart_cmd,
+                                       sizeof(cpup->ipc_buffer));
+                       }
+               }
+               else {
+                       flags |=  0x00040000UL; /* "remain halted" */
+               }
+                       
+               cpup->flags = flags;                                           
+               mb();                                           
+
+               if (alpha_use_srm_setup) {
+                       reset_for_srm();
+                       set_hae(srm_hae);
+               }
+
+#ifdef CONFIG_DUMMY_CONSOLE
+               /* This has the effect of reseting the VGA video origin.  */
+               take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1);
 #endif
-#if defined(CONFIG_ALPHA_SRM) && defined(CONFIG_ALPHA_ALCOR)
-       /* who said DEC engineer's have no sense of humor? ;-)) */
-       *(int *) GRU_RESET = 0x0000dead;
-       mb();
+       }
+
+#ifdef CONFIG_RTC
+       /* Reset rtc to defaults.  */
+       {
+               unsigned char control;
+               unsigned long flags;
+
+               /* I'm not sure if i really need to disable interrupts here. */
+               save_and_cli(flags);
+
+               /* Reset periodic interrupt frequency.  */
+               CMOS_WRITE(0x26, RTC_FREQ_SELECT);
+
+               /* Turn on periodic interrupts.  */
+               control = CMOS_READ(RTC_CONTROL);
+               control |= RTC_PIE;
+               CMOS_WRITE(control, RTC_CONTROL);       
+               CMOS_READ(RTC_INTR_FLAGS);
+
+               restore_flags(flags);
+       }
 #endif
+
+       if (!alpha_using_srm && mode != LINUX_REBOOT_CMD_RESTART) {
+               /* Unfortunately, since MILO doesn't currently understand
+                  the hwrpb bits above, we can't reliably halt the 
+                  processor and keep it halted.  So just loop.  */
+               return;
+       }
+
        halt();
 }
 
-void machine_restart(char * __unused)
+void
+machine_restart(char *restart_cmd)
 {
-#if defined(CONFIG_ALPHA_SRM)
-       extern struct hwrpb_struct *hwrpb;
-       struct percpu_struct *cpup;
-       unsigned long flags;
-       
-       cpup = (struct percpu_struct *)
-         ((unsigned long)hwrpb + hwrpb->processor_offset);
-       flags = cpup->flags;
-       flags &= ~0x0000000000ff0001UL; /* clear reason to "default" */
-       flags |=  0x0000000000020000UL; /* this is "cold bootstrap" */
-/*     flags |=  0x0000000000030000UL; *//* this is "warm bootstrap" */
-       cpup->flags = flags;                                           
-       mb();                                           
-#if defined(CONFIG_ALPHA_SRM_SETUP)
-       reset_for_srm();
-       set_hae(srm_hae);
-#endif
-#endif /* SRM */                                        
-
-       finish_shutdown();
+       alpha_mv.kill_arch(LINUX_REBOOT_CMD_RESTART, restart_cmd);
 }
 
-void machine_halt(void)
+void
+machine_halt(void)
 {
-#if defined(CONFIG_ALPHA_SRM)
-       extern struct hwrpb_struct *hwrpb;
-       struct percpu_struct *cpup;
-       unsigned long flags;
-       
-       cpup = (struct percpu_struct *)
-         ((unsigned long)hwrpb + hwrpb->processor_offset);
-       flags = cpup->flags;
-       flags &= ~0x0000000000ff0001UL; /* clear reason to "default" */
-       flags |=  0x0000000000040000UL; /* this is "remain halted" */
-       cpup->flags = flags;                                           
-       mb();                                           
-#if defined(CONFIG_ALPHA_SRM_SETUP)
-       reset_for_srm();
-       set_hae(srm_hae);
-#endif
-
-       finish_shutdown();
-#endif /* SRM */                                        
+       alpha_mv.kill_arch(LINUX_REBOOT_CMD_HALT, NULL);
 }
 
 void machine_power_off(void)
 {
-       /* None of the machines we support, at least, has switchable 
-          power supplies.  */
-       machine_halt();
+       alpha_mv.kill_arch(LINUX_REBOOT_CMD_POWER_OFF, NULL);
 }
 
 void show_regs(struct pt_regs * regs)
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
new file mode 100644 (file)
index 0000000..f55a0ed
--- /dev/null
@@ -0,0 +1,131 @@
+/* Prototypes of functions used across modules here in this directory.  */
+
+#define vucp   volatile unsigned char  *
+#define vusp   volatile unsigned short *
+#define vip    volatile int *
+#define vuip   volatile unsigned int   *
+#define vulp   volatile unsigned long  *
+
+/* core_apecs.c */
+extern int apecs_pcibios_read_config_byte (u8, u8, u8, u8 *value);
+extern int apecs_pcibios_read_config_word (u8, u8, u8, u16 *value);
+extern int apecs_pcibios_read_config_dword (u8, u8, u8, u32 *value);
+extern int apecs_pcibios_write_config_byte (u8, u8, u8, u8 value);
+extern int apecs_pcibios_write_config_word (u8, u8, u8, u16 value);
+extern int apecs_pcibios_write_config_dword (u8, u8, u8, u32 value);
+extern void apecs_init_arch(unsigned long *, unsigned long *);
+
+extern volatile unsigned int apecs_mcheck_expected;
+extern volatile unsigned int apecs_mcheck_taken;
+extern int apecs_pci_clr_err(void);
+extern void apecs_machine_check(u64, u64, struct pt_regs *);
+
+/* core_cia.c */
+extern int cia_pcibios_read_config_byte (u8, u8, u8, u8 *value);
+extern int cia_pcibios_read_config_word (u8, u8, u8, u16 *value);
+extern int cia_pcibios_read_config_dword (u8, u8, u8, u32 *value);
+extern int cia_pcibios_write_config_byte (u8, u8, u8, u8 value);
+extern int cia_pcibios_write_config_word (u8, u8, u8, u16 value);
+extern int cia_pcibios_write_config_dword (u8, u8, u8, u32 value);
+extern void cia_init_arch(unsigned long *, unsigned long *);
+extern void cia_machine_check(u64, u64, struct pt_regs *);
+
+/* core_lca.c */
+extern int lca_pcibios_read_config_byte (u8, u8, u8, u8 *value);
+extern int lca_pcibios_read_config_word (u8, u8, u8, u16 *value);
+extern int lca_pcibios_read_config_dword (u8, u8, u8, u32 *value);
+extern int lca_pcibios_write_config_byte (u8, u8, u8, u8 value);
+extern int lca_pcibios_write_config_word (u8, u8, u8, u16 value);
+extern int lca_pcibios_write_config_dword (u8, u8, u8, u32 value);
+extern void lca_init_arch(unsigned long *, unsigned long *);
+extern void lca_machine_check(u64, u64, struct pt_regs *);
+
+/* core_mcpcia.c */
+extern int mcpcia_pcibios_read_config_byte (u8, u8, u8, u8 *value);
+extern int mcpcia_pcibios_read_config_word (u8, u8, u8, u16 *value);
+extern int mcpcia_pcibios_read_config_dword (u8, u8, u8, u32 *value);
+extern int mcpcia_pcibios_write_config_byte (u8, u8, u8, u8 value);
+extern int mcpcia_pcibios_write_config_word (u8, u8, u8, u16 value);
+extern int mcpcia_pcibios_write_config_dword (u8, u8, u8, u32 value);
+extern void mcpcia_init_arch(unsigned long *, unsigned long *);
+extern void mcpcia_machine_check(u64, u64, struct pt_regs *);
+extern void mcpcia_pci_fixup(void);
+
+/* core_pyxis.c */
+extern int pyxis_pcibios_read_config_byte (u8, u8, u8, u8 *value);
+extern int pyxis_pcibios_read_config_word (u8, u8, u8, u16 *value);
+extern int pyxis_pcibios_read_config_dword (u8, u8, u8, u32 *value);
+extern int pyxis_pcibios_write_config_byte (u8, u8, u8, u8 value);
+extern int pyxis_pcibios_write_config_word (u8, u8, u8, u16 value);
+extern int pyxis_pcibios_write_config_dword (u8, u8, u8, u32 value);
+extern void pyxis_enable_errors (void);
+extern int pyxis_srm_window_setup (void);
+extern void pyxis_native_window_setup(void);
+extern void pyxis_finish_init_arch(void);
+extern void pyxis_init_arch(unsigned long *, unsigned long *);
+extern void pyxis_machine_check(u64, u64, struct pt_regs *);
+
+/* core_t2.c */
+extern int t2_pcibios_read_config_byte (u8, u8, u8, u8 *value);
+extern int t2_pcibios_read_config_word (u8, u8, u8, u16 *value);
+extern int t2_pcibios_read_config_dword (u8, u8, u8, u32 *value);
+extern int t2_pcibios_write_config_byte (u8, u8, u8, u8 value);
+extern int t2_pcibios_write_config_word (u8, u8, u8, u16 value);
+extern int t2_pcibios_write_config_dword (u8, u8, u8, u32 value);
+extern void t2_init_arch(unsigned long *, unsigned long *);
+extern void t2_machine_check(u64, u64, struct pt_regs *);
+
+/* core_tsunami.c */
+extern int tsunami_pcibios_read_config_byte (u8, u8, u8, u8 *value);
+extern int tsunami_pcibios_read_config_word (u8, u8, u8, u16 *value);
+extern int tsunami_pcibios_read_config_dword (u8, u8, u8, u32 *value);
+extern int tsunami_pcibios_write_config_byte (u8, u8, u8, u8 value);
+extern int tsunami_pcibios_write_config_word (u8, u8, u8, u16 value);
+extern int tsunami_pcibios_write_config_dword (u8, u8, u8, u32 value);
+extern void tsunami_init_arch(unsigned long *, unsigned long *);
+extern void tsunami_machine_check(u64, u64, struct pt_regs *);
+
+/* setup.c */
+extern void init_pit_rest(void);
+extern void generic_init_pit (void);
+extern unsigned long srm_hae;
+
+/* smp.c */
+extern void setup_smp(void);
+extern char *smp_info(void);
+extern void handle_ipi(struct pt_regs *);
+
+/* bios32.c */
+extern void reset_for_srm(void);
+
+/* time.c */
+extern void timer_interrupt(struct pt_regs * regs);
+
+/* smc37c93x.c */
+extern void SMC93x_Init(void);
+
+/* smc37c669.c */
+extern void SMC669_Init(void);
+
+/* es1888.c */
+extern void es1888_init(void);
+
+/* fpregs.c */
+extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
+extern unsigned long alpha_read_fp_reg (unsigned long reg);
+
+/* head.S */
+extern void wrmces(unsigned long mces);
+extern void cserve_ena(unsigned long);
+extern void cserve_dis(unsigned long);
+
+/* entry.S */
+extern void entArith(void);
+extern void entIF(void);
+extern void entInt(void);
+extern void entMM(void);
+extern void entSys(void);
+extern void entUna(void);
+
+/* process.c */
+void generic_kill_arch (int mode, char *reboot_cmd);
index d91ede2995a85a93173db152739cb7b91e1d8cb9..384f534af60707c87194cbadbd375eb826568c84 100644 (file)
@@ -281,10 +281,8 @@ static int read_long(struct task_struct * tsk, unsigned long addr,
        struct vm_area_struct * vma = find_extend_vma(tsk, addr);
 
        DBG(DBG_MEM_ALL, ("in read_long\n"));
-       if (!vma) {
-               printk("Unable to find vma for addr 0x%lx\n",addr);
+       if (!vma)
                return -EIO;
-       }
        if ((addr & ~PAGE_MASK) > (PAGE_SIZE - sizeof(long))) {
                struct vm_area_struct * vma_high = vma;
                unsigned long low, align;
diff --git a/arch/alpha/kernel/pyxis.c b/arch/alpha/kernel/pyxis.c
deleted file mode 100644 (file)
index 9db4fe4..0000000
+++ /dev/null
@@ -1,663 +0,0 @@
-/*
- * Code common to all PYXIS chips.
- *
- * Based on code written by David A Rusling (david.rusling@reo.mts.dec.com).
- *
- */
-#include <linux/config.h> /* CONFIG_ALPHA_RUFFIAN. */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/sched.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/hwrpb.h>
-#include <asm/ptrace.h>
-#include <asm/mmu_context.h>
-
-/* NOTE: Herein are back-to-back mb instructions.  They are magic.
-   One plausible explanation is that the I/O controller does not properly
-   handle the system transaction.  Another involves timing.  Ho hum.  */
-
-extern struct hwrpb_struct *hwrpb;
-extern asmlinkage void wrmces(unsigned long mces);
-
-/*
- * BIOS32-style PCI interface:
- */
-
-#ifdef DEBUG 
-# define DBG(args)     printk args
-#else
-# define DBG(args)
-#endif
-
-#define DEBUG_MCHECK
-#ifdef DEBUG_MCHECK
-# define DBG_MCK(args) printk args
-#define DEBUG_MCHECK_DUMP
-#else
-# define DBG_MCK(args)
-#endif
-
-#define vulp   volatile unsigned long *
-#define vuip   volatile unsigned int  *
-
-static volatile unsigned int PYXIS_mcheck_expected = 0;
-static volatile unsigned int PYXIS_mcheck_taken = 0;
-static unsigned int PYXIS_jd;
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-unsigned int PYXIS_DMA_WIN_BASE = PYXIS_DMA_WIN_BASE_DEFAULT;
-unsigned int PYXIS_DMA_WIN_SIZE = PYXIS_DMA_WIN_SIZE_DEFAULT;
-unsigned long pyxis_sm_base_r1, pyxis_sm_base_r2, pyxis_sm_base_r3;
-#endif /* SRM_SETUP */
-
-/*
- * Given a bus, device, and function number, compute resulting
- * configuration space address and setup the PYXIS_HAXR2 register
- * accordingly.  It is therefore not safe to have concurrent
- * invocations to configuration space access routines, but there
- * really shouldn't be any need for this.
- *
- * Type 0:
- *
- *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *     31:11   Device select bit.
- *     10:8    Function number
- *      7:2    Register number
- *
- * Type 1:
- *
- *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *     31:24   reserved
- *     23:16   bus number (8 bits = 128 possible buses)
- *     15:11   Device number (5 bits)
- *     10:8    function number
- *      7:2    register number
- *  
- * Notes:
- *     The function number selects which function of a multi-function device 
- *     (e.g., SCSI and Ethernet).
- * 
- *     The register selects a DWORD (32 bit) register offset.  Hence it
- *     doesn't get shifted by 2 bits as we want to "drop" the bottom two
- *     bits.
- */
-static int mk_conf_addr(unsigned char bus, unsigned char device_fn,
-                       unsigned char where, unsigned long *pci_addr,
-                       unsigned char *type1)
-{
-       unsigned long addr;
-
-       DBG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
-            " pci_addr=0x%p, type1=0x%p)\n",
-            bus, device_fn, where, pci_addr, type1));
-
-       if (bus == 0) {
-               int device;
-
-               device = device_fn >> 3;
-               /* type 0 configuration cycle: */
-#if NOT_NOW
-               if (device > 20) {
-                       DBG(("mk_conf_addr: device (%d) > 20, returning -1\n",
-                            device));
-                       return -1;
-               }
-#endif
-               *type1 = 0;
-               addr = (device_fn << 8) | (where);
-       } else {
-               /* type 1 configuration cycle: */
-               *type1 = 1;
-               addr = (bus << 16) | (device_fn << 8) | (where);
-       }
-       *pci_addr = addr;
-       DBG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
-       return 0;
-}
-
-
-static unsigned int conf_read(unsigned long addr, unsigned char type1)
-{
-       unsigned long flags;
-       unsigned int stat0, value, temp;
-       unsigned int pyxis_cfg = 0; /* to keep gcc quiet */
-
-       save_and_cli(flags);    /* avoid getting hit by machine check */
-
-       DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
-
-       /* reset status register to avoid losing errors: */
-       stat0 = *(vuip)PYXIS_ERR;
-       *(vuip)PYXIS_ERR = stat0; mb();
-       temp = *(vuip)PYXIS_ERR;  /* re-read to force write */
-       DBG(("conf_read: PYXIS ERR was 0x%x\n", stat0));
-       /* if Type1 access, must set PYXIS CFG */
-       if (type1) {
-               pyxis_cfg = *(vuip)PYXIS_CFG;
-               *(vuip)PYXIS_CFG = pyxis_cfg | 1; mb();
-               temp = *(vuip)PYXIS_CFG;  /* re-read to force write */
-               DBG(("conf_read: TYPE1 access\n"));
-       }
-
-       mb();
-       draina();
-       PYXIS_mcheck_expected = 1;
-       PYXIS_mcheck_taken = 0;
-       mb();
-       /* access configuration space: */
-       value = *(vuip)addr;
-       mb();
-       mb();  /* magic */
-       if (PYXIS_mcheck_taken) {
-               PYXIS_mcheck_taken = 0;
-               value = 0xffffffffU;
-               mb();
-       }
-       PYXIS_mcheck_expected = 0;
-       mb();
-
-       /* if Type1 access, must reset IOC CFG so normal IO space ops work */
-       if (type1) {
-               *(vuip)PYXIS_CFG = pyxis_cfg & ~1; mb();
-               temp = *(vuip)PYXIS_CFG;  /* re-read to force write */
-       }
-
-       DBG(("conf_read(): finished\n"));
-
-       restore_flags(flags);
-       return value;
-}
-
-
-static void conf_write(unsigned long addr, unsigned int value,
-                      unsigned char type1)
-{
-       unsigned long flags;
-       unsigned int stat0, temp;
-       unsigned int pyxis_cfg = 0; /* to keep gcc quiet */
-
-       save_and_cli(flags);    /* avoid getting hit by machine check */
-
-       /* reset status register to avoid losing errors: */
-       stat0 = *(vuip)PYXIS_ERR;
-       *(vuip)PYXIS_ERR = stat0; mb();
-       temp = *(vuip)PYXIS_ERR;  /* re-read to force write */
-       DBG(("conf_write: PYXIS ERR was 0x%x\n", stat0));
-       /* if Type1 access, must set PYXIS CFG */
-       if (type1) {
-               pyxis_cfg = *(vuip)PYXIS_CFG;
-               *(vuip)PYXIS_CFG = pyxis_cfg | 1; mb();
-               temp = *(vuip)PYXIS_CFG;  /* re-read to force write */
-               DBG(("conf_read: TYPE1 access\n"));
-       }
-
-       draina();
-       PYXIS_mcheck_expected = 1;
-       mb();
-       /* access configuration space: */
-       *(vuip)addr = value;
-       mb();
-       mb();  /* magic */
-       temp = *(vuip)PYXIS_ERR; /* do a PYXIS read to force the write */
-       PYXIS_mcheck_expected = 0;
-       mb();
-
-       /* if Type1 access, must reset IOC CFG so normal IO space ops work */
-       if (type1) {
-               *(vuip)PYXIS_CFG = pyxis_cfg & ~1; mb();
-               temp = *(vuip)PYXIS_CFG;  /* re-read to force write */
-       }
-
-       DBG(("conf_write(): finished\n"));
-       restore_flags(flags);
-}
-
-
-int pcibios_read_config_byte (unsigned char bus, unsigned char device_fn,
-                             unsigned char where, unsigned char *value)
-{
-       unsigned long addr = PYXIS_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       *value = 0xff;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       addr |= (pci_addr << 5) + 0x00;
-
-       *value = conf_read(addr, type1) >> ((where & 3) * 8);
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_read_config_word (unsigned char bus, unsigned char device_fn,
-                             unsigned char where, unsigned short *value)
-{
-       unsigned long addr = PYXIS_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       *value = 0xffff;
-
-       if (where & 0x1) {
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-       }
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       addr |= (pci_addr << 5) + 0x08;
-
-       *value = conf_read(addr, type1) >> ((where & 3) * 8);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_read_config_dword (unsigned char bus, unsigned char device_fn,
-                              unsigned char where, unsigned int *value)
-{
-       unsigned long addr = PYXIS_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       *value = 0xffffffff;
-       if (where & 0x3) {
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-       }
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x18;
-       *value = conf_read(addr, type1);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_write_config_byte (unsigned char bus, unsigned char device_fn,
-                              unsigned char where, unsigned char value)
-{
-       unsigned long addr = PYXIS_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x00;
-       conf_write(addr, value << ((where & 3) * 8), type1);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_write_config_word (unsigned char bus, unsigned char device_fn,
-                              unsigned char where, unsigned short value)
-{
-       unsigned long addr = PYXIS_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x08;
-       conf_write(addr, value << ((where & 3) * 8), type1);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_write_config_dword (unsigned char bus, unsigned char device_fn,
-                               unsigned char where, unsigned int value)
-{
-       unsigned long addr = PYXIS_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x18;
-       conf_write(addr, value << ((where & 3) * 8), type1);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-unsigned long pyxis_init(unsigned long mem_start, unsigned long mem_end)
-{
-       unsigned int pyxis_err ;
-
-#if 0
-printk("pyxis_init: PYXIS_ERR_MASK 0x%x\n", *(vuip)PYXIS_ERR_MASK);
-printk("pyxis_init: PYXIS_ERR 0x%x\n", *(vuip)PYXIS_ERR);
-
-printk("pyxis_init: PYXIS_INT_REQ 0x%lx\n", *(vulp)PYXIS_INT_REQ);
-printk("pyxis_init: PYXIS_INT_MASK 0x%lx\n", *(vulp)PYXIS_INT_MASK);
-printk("pyxis_init: PYXIS_INT_ROUTE 0x%lx\n", *(vulp)PYXIS_INT_ROUTE);
-printk("pyxis_init: PYXIS_INT_HILO 0x%lx\n", *(vulp)PYXIS_INT_HILO);
-printk("pyxis_init: PYXIS_INT_CNFG 0x%x\n", *(vuip)PYXIS_INT_CNFG);
-printk("pyxis_init: PYXIS_RT_COUNT 0x%lx\n", *(vulp)PYXIS_RT_COUNT);
-#endif
-
-       /* 
-        * Set up error reporting. Make sure CPU_PE is OFF in the mask.
-        */
-       pyxis_err = *(vuip)PYXIS_ERR_MASK;
-       pyxis_err &= ~4;   
-       *(vuip)PYXIS_ERR_MASK = pyxis_err; mb();
-       pyxis_err = *(vuip)PYXIS_ERR_MASK;  /* re-read to force write */
-
-       pyxis_err = *(vuip)PYXIS_ERR ;
-       pyxis_err |= 0x180;   /* master/target abort */
-       *(vuip)PYXIS_ERR = pyxis_err; mb();
-       pyxis_err = *(vuip)PYXIS_ERR;  /* re-read to force write */
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-       /* check window 0 for enabled and mapped to 0 */
-       if (((*(vuip)PYXIS_W0_BASE & 3) == 1) &&
-           (*(vuip)PYXIS_T0_BASE == 0) &&
-           ((*(vuip)PYXIS_W0_MASK & 0xfff00000U) > 0x0ff00000U))
-       {
-         PYXIS_DMA_WIN_BASE = *(vuip)PYXIS_W0_BASE & 0xfff00000U;
-         PYXIS_DMA_WIN_SIZE = *(vuip)PYXIS_W0_MASK & 0xfff00000U;
-         PYXIS_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-         printk("pyxis_init: using Window 0 settings\n");
-         printk("pyxis_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-                *(vuip)PYXIS_W0_BASE,
-                *(vuip)PYXIS_W0_MASK,
-                *(vuip)PYXIS_T0_BASE);
-#endif
-       }
-       else  /* check window 1 for enabled and mapped to 0 */
-       if (((*(vuip)PYXIS_W1_BASE & 3) == 1) &&
-           (*(vuip)PYXIS_T1_BASE == 0) &&
-           ((*(vuip)PYXIS_W1_MASK & 0xfff00000U) > 0x0ff00000U))
-{
-         PYXIS_DMA_WIN_BASE = *(vuip)PYXIS_W1_BASE & 0xfff00000U;
-         PYXIS_DMA_WIN_SIZE = *(vuip)PYXIS_W1_MASK & 0xfff00000U;
-         PYXIS_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-         printk("pyxis_init: using Window 1 settings\n");
-         printk("pyxis_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-                *(vuip)PYXIS_W1_BASE,
-                *(vuip)PYXIS_W1_MASK,
-                *(vuip)PYXIS_T1_BASE);
-#endif
-       }
-       else  /* check window 2 for enabled and mapped to 0 */
-       if (((*(vuip)PYXIS_W2_BASE & 3) == 1) &&
-           (*(vuip)PYXIS_T2_BASE == 0) &&
-           ((*(vuip)PYXIS_W2_MASK & 0xfff00000U) > 0x0ff00000U))
-       {
-         PYXIS_DMA_WIN_BASE = *(vuip)PYXIS_W2_BASE & 0xfff00000U;
-         PYXIS_DMA_WIN_SIZE = *(vuip)PYXIS_W2_MASK & 0xfff00000U;
-         PYXIS_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-         printk("pyxis_init: using Window 2 settings\n");
-         printk("pyxis_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-                *(vuip)PYXIS_W2_BASE,
-                *(vuip)PYXIS_W2_MASK,
-                *(vuip)PYXIS_T2_BASE);
-#endif
-       }
-       else  /* check window 3 for enabled and mapped to 0 */
-       if (((*(vuip)PYXIS_W3_BASE & 3) == 1) &&
-           (*(vuip)PYXIS_T3_BASE == 0) &&
-           ((*(vuip)PYXIS_W3_MASK & 0xfff00000U) > 0x0ff00000U))
-       {
-         PYXIS_DMA_WIN_BASE = *(vuip)PYXIS_W3_BASE & 0xfff00000U;
-         PYXIS_DMA_WIN_SIZE = *(vuip)PYXIS_W3_MASK & 0xfff00000U;
-         PYXIS_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-         printk("pyxis_init: using Window 3 settings\n");
-         printk("pyxis_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-                *(vuip)PYXIS_W3_BASE,
-                *(vuip)PYXIS_W3_MASK,
-                *(vuip)PYXIS_T3_BASE);
-#endif
-       }
-       else  /* we must use our defaults which were pre-initialized... */
-#endif /* SRM_SETUP */
-       {
-#if defined(CONFIG_ALPHA_RUFFIAN)
-#if 1
-       printk("pyxis_init: skipping window register rewrites... "
-              " trust DeskStation firmware!\n");
-#endif
-#else /* RUFFIAN */
-       /*
-        * Set up the PCI->physical memory translation windows.
-        * For now, windows 1,2 and 3 are disabled.  In the future, we may
-        * want to use them to do scatter/gather DMA.  Window 0
-        * goes at 1 GB and is 1 GB large.
-        */
-
-       *(vuip)PYXIS_W0_BASE = 1U | (PYXIS_DMA_WIN_BASE & 0xfff00000U);
-       *(vuip)PYXIS_W0_MASK = (PYXIS_DMA_WIN_SIZE - 1) & 0xfff00000U;
-       *(vuip)PYXIS_T0_BASE = 0;
-
-       *(vuip)PYXIS_W1_BASE = 0x0 ;
-       *(vuip)PYXIS_W2_BASE = 0x0 ;
-       *(vuip)PYXIS_W3_BASE = 0x0 ;
-       mb();
-#endif /* RUFFIAN */
-       }
-
-       /*
-        * check ASN in HWRPB for validity, report if bad
-        */
-       if (hwrpb->max_asn != MAX_ASN) {
-               printk("PYXIS_init: max ASN from HWRPB is bad (0x%lx)\n",
-                      hwrpb->max_asn);
-               hwrpb->max_asn = MAX_ASN;
-       }
-
-       /*
-         * Next, clear the PYXIS_CFG register, which gets used
-        *  for PCI Config Space accesses. That is the way
-        *  we want to use it, and we do not want to depend on
-        *  what ARC or SRM might have left behind...
-        */
-       {
-          unsigned int pyxis_cfg, temp;
-               pyxis_cfg = *(vuip)PYXIS_CFG; mb();
-         if (pyxis_cfg != 0) {
-#if 1
-               printk("PYXIS_init: CFG was 0x%x\n", pyxis_cfg);
-#endif
-               *(vuip)PYXIS_CFG = 0; mb();
-           temp = *(vuip)PYXIS_CFG;  /* re-read to force write */
-         }
-       }
-       {
-               unsigned int pyxis_hae_mem = *(vuip)PYXIS_HAE_MEM;
-               unsigned int pyxis_hae_io = *(vuip)PYXIS_HAE_IO;
-#if 0
-               printk("PYXIS_init: HAE_MEM was 0x%x\n", pyxis_hae_mem);
-               printk("PYXIS_init: HAE_IO was 0x%x\n", pyxis_hae_io);
-#endif
-#ifdef CONFIG_ALPHA_SRM_SETUP
-         /*
-          * sigh... For the SRM setup, unless we know apriori what the HAE
-          * contents will be, we need to setup the arbitrary region bases
-          * so we can test against the range of addresses and tailor the
-          * region chosen for the SPARSE memory access.
-          * 
-          * see include/asm-alpha/pyxis.h for the SPARSE mem read/write
-         */
-         pyxis_sm_base_r1 = (pyxis_hae_mem      ) & 0xe0000000UL;/* region 1 */
-         pyxis_sm_base_r2 = (pyxis_hae_mem << 16) & 0xf8000000UL;/* region 2 */
-         pyxis_sm_base_r3 = (pyxis_hae_mem << 24) & 0xfc000000UL;/* region 3 */
-
-         /*
-           Set the HAE cache, so that setup_arch() code
-           will use the SRM setting always. Our readb/writeb
-           code in pyxis.h expects never to have to change
-           the contents of the HAE.
-          */
-         hae.cache = pyxis_hae_mem;
-#else /* SRM_SETUP */
-          *(vuip)PYXIS_HAE_MEM = 0U; mb();
-         pyxis_hae_mem = *(vuip)PYXIS_HAE_MEM;  /* re-read to force write */
-               *(vuip)PYXIS_HAE_IO = 0; mb();
-         pyxis_hae_io = *(vuip)PYXIS_HAE_IO;  /* re-read to force write */
-#endif /* SRM_SETUP */
-        }
-
-       /*
-        * Finally, check that the PYXIS_CTRL1 has IOA_BEN set for
-        * enabling byte/word PCI bus space(s) access.
-        */
-       {
-         unsigned int ctrl1;
-         ctrl1 = *(vuip) PYXIS_CTRL1;
-         if (!(ctrl1 & 1)) {
-#if 1
-           printk("PYXIS_init: enabling byte/word PCI space\n");
-#endif
-           *(vuip) PYXIS_CTRL1 = ctrl1 | 1; mb();
-           ctrl1 = *(vuip)PYXIS_CTRL1;  /* re-read to force write */
-         }
-       }
-
-       return mem_start;
-}
-
-int pyxis_pci_clr_err(void)
-{
-       PYXIS_jd = *(vuip)PYXIS_ERR;
-       DBG(("PYXIS_pci_clr_err: PYXIS ERR after read 0x%x\n", PYXIS_jd));
-       *(vuip)PYXIS_ERR = 0x0180; mb();
-       PYXIS_jd = *(vuip)PYXIS_ERR;  /* re-read to force write */
-       return 0;
-}
-
-void pyxis_machine_check(unsigned long vector, unsigned long la_ptr,
-                        struct pt_regs * regs)
-{
-       struct el_common *mchk_header;
-       struct el_PYXIS_sysdata_mcheck *mchk_sysdata;
-
-       mchk_header = (struct el_common *)la_ptr;
-
-       mchk_sysdata = (struct el_PYXIS_sysdata_mcheck *)
-               (la_ptr + mchk_header->sys_offset);
-
-#if 0
-       DBG_MCK(("pyxis_machine_check: vector=0x%lx la_ptr=0x%lx\n",
-                vector, la_ptr));
-       DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
-                regs->pc, mchk_header->size, mchk_header->proc_offset,
-                mchk_header->sys_offset));
-       DBG_MCK(("pyxis_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
-                PYXIS_mcheck_expected, mchk_sysdata->epic_dcsr,
-                mchk_sysdata->epic_pear));
-#endif
-#ifdef DEBUG_MCHECK_DUMP
-       {
-               unsigned long *ptr;
-               int i;
-
-               ptr = (unsigned long *)la_ptr;
-               for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
-                       printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
-               }
-       }
-#endif /* DEBUG_MCHECK_DUMP */
-
-       /*
-        * Check if machine check is due to a badaddr() and if so,
-        * ignore the machine check.
-        */
-       mb();
-       mb();  /* magic */
-       if (PYXIS_mcheck_expected) {
-               DBG(("PYXIS machine check expected\n"));
-               PYXIS_mcheck_expected = 0;
-               PYXIS_mcheck_taken = 1;
-               mb();
-               mb();  /* magic */
-               draina();
-               pyxis_pci_clr_err();
-               wrmces(0x7);
-               mb();
-       }
-#if 1
-       else {
-               printk("PYXIS machine check NOT expected\n") ;
-               DBG_MCK(("pyxis_machine_check: vector=0x%lx la_ptr=0x%lx\n",
-                        vector, la_ptr));
-               DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x"
-                        " sysoffset 0x%x\n",
-                        regs->pc, mchk_header->size, mchk_header->proc_offset,
-                        mchk_header->sys_offset));
-               PYXIS_mcheck_expected = 0;
-               PYXIS_mcheck_taken = 1;
-               mb();
-               mb();  /* magic */
-               draina();
-               pyxis_pci_clr_err();
-               wrmces(0x7);
-               mb();
-       }
-#endif
-}
-
-#if defined(CONFIG_ALPHA_RUFFIAN)
-/* Note: This is only used by MILO, AFAIK... */
-/*
- * The DeskStation Ruffian motherboard firmware does not place
- * the memory size in the PALimpure area.  Therefore, we use
- * the Bank Configuration Registers in PYXIS to obtain the size.
- */
-unsigned long pyxis_get_bank_size(unsigned long offset)
-{
-       unsigned long bank_addr, bank, ret = 0;
-  
-       /* Valid offsets are: 0x800, 0x840 and 0x880
-          since Ruffian only uses three banks.  */
-       bank_addr = (unsigned long)PYXIS_MCR + offset;
-       bank = *(vulp)bank_addr;
-    
-       /* Check BANK_ENABLE */
-       if (bank & 0x01) {
-               static unsigned long size[] = {
-                       0x40000000UL, /* 0x00,   1G */ 
-                       0x20000000UL, /* 0x02, 512M */
-                       0x10000000UL, /* 0x04, 256M */
-                       0x08000000UL, /* 0x06, 128M */
-                       0x04000000UL, /* 0x08,  64M */
-                       0x02000000UL, /* 0x0a,  32M */
-                       0x01000000UL, /* 0x0c,  16M */
-                       0x00800000UL, /* 0x0e,   8M */
-                       0x80000000UL, /* 0x10,   2G */
-               };
-
-               bank = (bank & 0x1e) >> 1;
-               if (bank < sizeof(size)/sizeof(*size))
-                       ret = size[bank];
-       }
-
-       return ret;
-}
-#endif /* CONFIG_ALPHA_RUFFIAN */
index f0683b1c10bf463920a57521bfd82260a5801517..419fb47de0be3434a721ff2864df9bab9a5a9c66 100644 (file)
@@ -5,10 +5,9 @@
  */
 
 /*
- * bootup setup stuff..
+ * Bootup setup stuff.
  */
 
-#include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
@@ -24,6 +23,9 @@
 #include <linux/ioport.h>
 #include <linux/mc146818rtc.h>
 #include <linux/console.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/string.h>
 
 #ifdef CONFIG_RTC
 #include <linux/timex.h>
@@ -36,8 +38,8 @@
 #include <asm/dma.h>
 #include <asm/io.h>
 
-extern void setup_smp(void);
-extern char *smp_info(void);
+
+#include "proto.h"
 
 #if 1
 # define DBG_SRM(args)         printk args
@@ -45,19 +47,23 @@ extern char *smp_info(void);
 # define DBG_SRM(args)
 #endif
 
-struct hae hae = {
-       0,
-       (unsigned long*) HAE_ADDRESS
-};
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
+struct hwrpb_struct *hwrpb;
 unsigned long srm_hae;
-#endif
 
-struct hwrpb_struct *hwrpb;
+#ifdef CONFIG_ALPHA_GENERIC
+struct alpha_machine_vector alpha_mv;
+int alpha_using_srm, alpha_use_srm_setup;
+#endif
 
 unsigned char aux_device_present = 0xaa;
 
+#define N(a) (sizeof(a)/sizeof(a[0]))
+
+static unsigned long find_end_memory(void);
+static struct alpha_machine_vector *get_sysvec(long, long, long);
+static struct alpha_machine_vector *get_sysvec_byname(const char *);
+static void get_sysnames(long, long, char **, char **);
+
 /*
  * This is setup by the secondary bootstrap loader.  Because
  * the zero page is zeroed out as soon as the vm system is
@@ -68,161 +74,241 @@ unsigned char aux_device_present = 0xaa;
 #define COMMAND_LINE           ((char*)(PARAM + 0x0000))
 #define COMMAND_LINE_SIZE      256
 
-static char command_line[COMMAND_LINE_SIZE] = { 0, };
-       char saved_command_line[COMMAND_LINE_SIZE];
+static char command_line[COMMAND_LINE_SIZE];
+char saved_command_line[COMMAND_LINE_SIZE];
+
 
 /*
  * The format of "screen_info" is strange, and due to early
  * i386-setup code. This is just enough to make the console
  * code think we're on a VGA color display.
  */
+
 struct screen_info screen_info = {
-#if defined(CONFIG_ALPHA_BOOK1)
-  /* the AlphaBook1 has LCD video fixed at 800x600, 37 rows and 100 cols */
-       0, 37,                  /* orig-x, orig-y */
-       { 0, 0 },               /* unused */
-       0,                      /* orig-video-page */
-       0,                      /* orig-video-mode */
-        100,                   /* orig-video-cols */
-       0,0,0,                  /* ega_ax, ega_bx, ega_cx */
-        37,                    /* orig-video-lines */
-       1,                      /* orig-video-isVGA */
-       16                      /* orig-video-points */
-#else
-       0, 25,                  /* orig-x, orig-y */
-       0,                      /* unused */
-       0,                      /* orig-video-page */
-       0,                      /* orig-video-mode */
-       80,                     /* orig-video-cols */
-       0,0,0,                  /* ega_ax, ega_bx, ega_cx */
-       25,                     /* orig-video-lines */
-       1,                      /* orig-video-isVGA */
-       16                      /* orig-video-points */
-#endif
+       orig_x: 0,
+       orig_y: 25,
+       orig_video_cols: 80,
+       orig_video_lines: 25,
+       orig_video_isVGA: 1,
+       orig_video_points: 16
 };
 
+
 /*
  * Initialize Programmable Interval Timers with standard values.  Some
  * drivers depend on them being initialized (e.g., joystick driver).
  */
-static void init_pit (void)
+
+/* It is (normally) only counter 1 that presents config problems, so
+   provide this support function to do the rest of the job.  */
+
+void inline
+init_pit_rest(void)
 {
 #if 0
-    /*
-     * Leave refresh timer alone---nobody should depend on
-     * a particular value anyway.
-     */
-    outb(0x54, 0x43);  /* counter 1: refresh timer */
-    outb(0x18, 0x41);
+       /* Leave refresh timer alone---nobody should depend on a
+          particular value anyway. */
+       outb(0x54, 0x43);       /* counter 1: refresh timer */
+       outb(0x18, 0x41);
 #endif
 
-#ifdef CONFIG_RTC /* setup interval timer if /dev/rtc is being used */
-    outb(0x34, 0x43);  /* binary, mode 2, LSB/MSB, ch 0 */
-    outb(LATCH & 0xff, 0x40); /* LSB */
-    outb(LATCH >> 8, 0x40); /* MSB */
-    request_region(0x40, 0x20, "timer"); /* reserve pit */
-#else /* RTC */
-#if !defined(CONFIG_ALPHA_RUFFIAN)
-    /* Ruffian depends on the system timer established in MILO!! */
-    outb(0x36, 0x43);  /* counter 0: system timer */
-    outb(0x00, 0x40);
-    outb(0x00, 0x40);
-#endif /* RUFFIAN */
-    request_region(0x70, 0x10, "timer"); /* reserve rtc */
-#endif /* RTC */
-
-    outb(0xb6, 0x43);  /* counter 2: speaker */
-    outb(0x31, 0x42);
-    outb(0x13, 0x42);
+       outb(0xb6, 0x43);       /* counter 2: speaker */
+       outb(0x31, 0x42);
+       outb(0x13, 0x42);
+
+       if ((CMOS_READ(RTC_FREQ_SELECT) & 0x3f) != 0x26) {
+               printk("Setting RTC_FREQ to 1024 Hz\n");
+               CMOS_WRITE(0x26, RTC_FREQ_SELECT);
+       }
 }
 
-static unsigned long find_end_memory(void)
+#ifdef CONFIG_RTC
+static inline void
+rtc_init_pit (void)
 {
-       int i;
-       unsigned long high = 0;
-       struct memclust_struct * cluster;
-       struct memdesc_struct * memdesc;
+       /* Setup interval timer if /dev/rtc is being used */
+       outb(0x34, 0x43);               /* binary, mode 2, LSB/MSB, ch 0 */
+       outb(LATCH & 0xff, 0x40);       /* LSB */
+       outb(LATCH >> 8, 0x40);         /* MSB */
+       request_region(0x40, 0x20, "timer"); /* reserve pit */
 
-       memdesc = (struct memdesc_struct *)
-         (INIT_HWRPB->mddt_offset + (unsigned long) INIT_HWRPB);
-       cluster = memdesc->cluster;
-       for (i = memdesc->numclusters ; i > 0; i--, cluster++) {
-               unsigned long tmp;
-               tmp = (cluster->start_pfn + cluster->numpages) << PAGE_SHIFT;
-               if (tmp > high)
-                       high = tmp;
-       }
-       /* round it up to an even number of pages.. */
-       high = (high + PAGE_SIZE) & (PAGE_MASK*2);
-       return PAGE_OFFSET + high;
+       init_pit_rest();
 }
+#endif
 
-void setup_arch(char **cmdline_p,
-       unsigned long * memory_start_p, unsigned long * memory_end_p)
+void
+generic_init_pit (void)
 {
-       extern int _end;
+       outb(0x36, 0x43);       /* counter 0: system timer */
+       outb(0x00, 0x40);
+       outb(0x00, 0x40);
+       request_region(RTC_PORT(0), 0x10, "timer"); /* reserve rtc */
 
-       init_pit();
+       init_pit_rest();
+}
 
-       if ((CMOS_READ(RTC_FREQ_SELECT) & 0x3f) != 0x26) {
-         printk("setup_arch: setting RTC_FREQ to 1024/sec\n");
-         CMOS_WRITE(0x26, RTC_FREQ_SELECT);
-       }
+/* This probably isn't Right, but it is what the old code did.  */
+#if defined(CONFIG_RTC)
+# define init_pit      rtc_init_pit
+#else
+# define init_pit      alpha_mv.init_pit
+#endif
 
-       hwrpb = (struct hwrpb_struct*)(IDENT_ADDR + INIT_HWRPB->phys_addr);
 
-#if !defined(CONFIG_ALPHA_TSUNAMI)
-#ifdef CONFIG_ALPHA_SRM_SETUP
-       srm_hae = *hae.reg; /* save SRM setting for restoration */
-       DBG_SRM(("setup_arch: old HAE base: 0x%016lx\n", srm_hae));
-#endif /* SRM_SETUP */
-       set_hae(hae.cache);     /* sync HAE register w/hae_cache */
-#endif /* !TSUNAMI */
+/*
+ * Declare all of the machine vectors.
+ */
 
-       wrmces(0x7);            /* reset enable correctable error reports */
+extern struct alpha_machine_vector alcor_mv;
+extern struct alpha_machine_vector alphabook1_mv;
+extern struct alpha_machine_vector avanti_mv;
+extern struct alpha_machine_vector cabriolet_mv;
+extern struct alpha_machine_vector dp264_mv;
+extern struct alpha_machine_vector eb164_mv;
+extern struct alpha_machine_vector eb64p_mv;
+extern struct alpha_machine_vector eb66_mv;
+extern struct alpha_machine_vector eb66p_mv;
+extern struct alpha_machine_vector jensen_mv;
+extern struct alpha_machine_vector lx164_mv;
+extern struct alpha_machine_vector miata_mv;
+extern struct alpha_machine_vector mikasa_mv;
+extern struct alpha_machine_vector mikasa_primo_mv;
+extern struct alpha_machine_vector noname_mv;
+extern struct alpha_machine_vector noritake_mv;
+extern struct alpha_machine_vector noritake_primo_mv;
+extern struct alpha_machine_vector p2k_mv;
+extern struct alpha_machine_vector pc164_mv;
+extern struct alpha_machine_vector rawhide_mv;
+extern struct alpha_machine_vector ruffian_mv;
+extern struct alpha_machine_vector sable_mv;
+extern struct alpha_machine_vector sable_gamma_mv;
+extern struct alpha_machine_vector sx164_mv;
+extern struct alpha_machine_vector takara_mv;
+extern struct alpha_machine_vector xl_mv;
+extern struct alpha_machine_vector xlt_mv;
+
+
+void __init
+setup_arch(char **cmdline_p, unsigned long * memory_start_p,
+          unsigned long * memory_end_p)
+{
+       extern char _end[];
+
+       struct alpha_machine_vector *vec = NULL;
+       struct percpu_struct *cpu;
+       char *type_name, *var_name, *p;
 
-       ROOT_DEV = to_kdev_t(0x0802);           /* sda2 */
-       command_line[COMMAND_LINE_SIZE - 1] = '\0';
+       hwrpb = (struct hwrpb_struct*)(IDENT_ADDR + INIT_HWRPB->phys_addr);
 
-       /* Hack for Jensen... since we're restricted to 8 or 16 
-        * chars for boot flags depending on the boot mode,
-        * we need some shorthand.  This should do for 
-        * installation.  Later we'll add other abbreviations
-        * as well...
+       /* 
+        * Locate the command line.
         */
+
+       /* Hack for Jensen... since we're restricted to 8 or 16 chars for
+          boot flags depending on the boot mode, we need some shorthand.
+          This should do for installation.  Later we'll add other
+          abbreviations as well... */
        if (strcmp(COMMAND_LINE, "INSTALL") == 0) {
                strcpy(command_line, "root=/dev/fd0 load_ramdisk=1");
-               strcpy(saved_command_line, command_line);
        } else {
-               strcpy(command_line, COMMAND_LINE);
-               strcpy(saved_command_line, COMMAND_LINE);
+               strncpy(command_line, COMMAND_LINE, sizeof command_line);
+               command_line[sizeof(command_line)-1] = 0;
        }
-       printk("Command line: %s\n", command_line);
-
+       strcpy(saved_command_line, command_line);
        *cmdline_p = command_line;
-       *memory_start_p = (unsigned long) &_end;
-       *memory_end_p = find_end_memory();
 
-#if defined(CONFIG_ALPHA_LCA)
-       *memory_start_p = lca_init(*memory_start_p, *memory_end_p);
-#elif defined(CONFIG_ALPHA_APECS)
-       *memory_start_p = apecs_init(*memory_start_p, *memory_end_p);
-#elif defined(CONFIG_ALPHA_CIA)
-       *memory_start_p = cia_init(*memory_start_p, *memory_end_p);
-#elif defined(CONFIG_ALPHA_PYXIS)
-       *memory_start_p = pyxis_init(*memory_start_p, *memory_end_p);
-#elif defined(CONFIG_ALPHA_T2)
-       *memory_start_p = t2_init(*memory_start_p, *memory_end_p);
-#elif defined(CONFIG_ALPHA_TSUNAMI)
-       *memory_start_p = tsunami_init(*memory_start_p, *memory_end_p);
-#elif defined(CONFIG_ALPHA_MCPCIA)
-       *memory_start_p = mcpcia_init(*memory_start_p, *memory_end_p);
+       /* 
+        * Process command-line arguments.
+        */
+
+       for (p = strtok(command_line, " \t"); p ; p = strtok(NULL, " \t")) {
+#ifndef alpha_use_srm_setup
+               /* Allow a command-line option to respect the
+                  SRM's configuration.  */
+               if (strncmp(p, "srm_setup=", 10) == 0) {
+                       alpha_use_srm_setup = (p[10] != '0');
+                       continue;
+               }
 #endif
 
-#ifdef __SMP__
-       setup_smp();
+               if (strncmp(p, "alpha_mv=", 9) == 0) {
+                       vec = get_sysvec_byname(p+9);
+                       continue;
+               }
+       }
+
+       /* Replace the command line, not that we've killed it with strtok.  */
+       strcpy(command_line, saved_command_line);
+
+       /*
+        * Indentify and reconfigure for the current system.
+        */
+
+       get_sysnames(hwrpb->sys_type, hwrpb->sys_variation,
+                    &type_name, &var_name);
+       if (*var_name == '0')
+               var_name = "";
+
+       if (!vec) {
+               cpu = (struct percpu_struct*)
+                       ((char*)hwrpb + hwrpb->processor_offset);
+               vec = get_sysvec(hwrpb->sys_type, hwrpb->sys_variation,
+                                cpu->type);
+       }
+
+#ifdef CONFIG_ALPHA_GENERIC
+       if (!vec) {
+               panic("Unsupported system type: %s%s%s (%ld %ld)\n",
+                     type_name, (*var_name ? " variation " : ""), var_name,
+                     hwrpb->sys_type, hwrpb->sys_variation);
+       }
+       alpha_mv = *vec;
+
+       /* Assume that we've booted from SRM if we havn't booted from MILO.
+          Detect the later by looking for "MILO" in the system serial nr.  */
+       alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0;
+#else
+       /* Once we're sure we can reliably identify systems, we should
+          simply panic as we do above.  */
+       if (vec != &alpha_mv) {
+               printk("WARNING: Not configured for system type: %s%s%s "
+                      "(%ld %ld)\nContinuing with trepidation...\n",
+                      type_name, (*var_name ? " variation " : ""), var_name,
+                      hwrpb->sys_type, hwrpb->sys_variation);
+       }
 #endif
 
+       /* 
+        * Sync with the HAE
+        */
+
+       /* Save the SRM's current value for restoration.  */
+       srm_hae = *alpha_mv.hae_register;
+       __set_hae(alpha_mv.hae_cache);
+
+       /* Reset enable correctable error reports.  */
+       wrmces(0x7);
+
+       /* Find our memory.  */
+       *memory_end_p = find_end_memory();
+       *memory_start_p = (unsigned long) _end;
+
+       /* Initialize the machine.  Usually has to do with setting up
+          DMA windows and the like.  */
+       if (alpha_mv.init_arch)
+               alpha_mv.init_arch(memory_start_p, memory_end_p);
+
+       /* Initialize the timers.  */
+       init_pit();
+
+       /* Default root filesystem to sda2.  */
+       ROOT_DEV = to_kdev_t(0x0802);
+
+       /* 
+        * Give us a default console.  TGA users will see nothing until
+        * chr_dev_init is called, rather late in the boot sequence.
+        */
+
 #ifdef CONFIG_VT
 #if defined(CONFIG_VGA_CONSOLE)
        conswitchp = &vga_con;
@@ -230,81 +316,284 @@ void setup_arch(char **cmdline_p,
        conswitchp = &dummy_con;
 #endif
 #endif
-}
 
+       /* Delayed so that we've initialized the machine first.  */
+       printk("Booting on %s%s%s using machine vector %s\n",
+              type_name, (*var_name ? " variation " : ""),
+              var_name, alpha_mv.vector_name);
+       printk("Command line: %s\n", command_line);
 
-#define N(a) (sizeof(a)/sizeof(a[0]))
+       /*
+        * Check ASN in HWRPB for validity, report if bad.
+        * FIXME: how was this failing?  Should we trust it instead,
+        * and copy the value into alpha_mv.max_asn?
+        */
 
-/* A change was made to the HWRPB via an ECO and the following code tracks
- * a part of the ECO.  In HWRPB versions less than 5, the ECO was not
- * implemented in the console firmware.  If it's revision 5 or greater we can
- * get the name of the platform as an ASCII string from the HWRPB.  That's what
- * this function does.  It checks the revision level and if the string is in
- * the HWRPB it returns the address of the string--a pointer to the name of the
- * platform.
- *
- * Returns:
- *      - Pointer to a ASCII string if it's in the HWRPB
- *      - Pointer to a blank string if the data is not in the HWRPB.
- */
-static char *
-platform_string(void)
-{
-       struct dsr_struct *dsr;
-       static char unk_system_string[] = "N/A";
+       if (hwrpb->max_asn != MAX_ASN) {
+               printk("Max ASN from HWRPB is bad (0x%lx)\n", hwrpb->max_asn);
+       }
 
-        /* Go to the console for the string pointer.
-         * If the rpb_vers is not 5 or greater the rpb
-        * is old and does not have this data in it.
+       /*
+        * Identify the flock of penguins.
         */
-        if (hwrpb->revision < 5)
-               return (unk_system_string);
-       else {
-               /* The Dynamic System Recognition struct
-                * has the system platform name starting
-                * after the character count of the string.
-                */
-               dsr =  ((struct dsr_struct *)
-                         ((char *)hwrpb + hwrpb->dsr_offset));
-               return ((char *)dsr + (dsr->sysname_off +
-                                                sizeof(long)));
-        }
+
+#ifdef __SMP__
+       setup_smp();
+#endif
 }
 
-static void
-get_sysnames(long type, long variation,
-            char **type_name, char **variation_name)
+static unsigned long __init
+find_end_memory(void)
 {
-       static char *sys_unknown = "Unknown";
-       static char *systype_names[] = {
-               "0",
-               "ADU", "Cobra", "Ruby", "Flamingo", "Mannequin", "Jensen",
-               "Pelican", "Morgan", "Sable", "Medulla", "Noname",
-               "Turbolaser", "Avanti", "Mustang", "Alcor", "Tradewind",
-               "Mikasa", "EB64", "EB66", "EB64+", "AlphaBook1",
-               "Rawhide", "K2", "Lynx", "XL", "EB164", "Noritake",
-               "Cortex", "29", "Miata", "XXM", "Takara", "Yukon",
-               "Tsunami", "Wildfire", "CUSCO"
+       int i;
+       unsigned long high = 0;
+       struct memclust_struct * cluster;
+       struct memdesc_struct * memdesc;
+
+       memdesc = (struct memdesc_struct *)
+               (INIT_HWRPB->mddt_offset + (unsigned long) INIT_HWRPB);
+       cluster = memdesc->cluster;
+
+       for (i = memdesc->numclusters ; i > 0; i--, cluster++) {
+               unsigned long tmp;
+               tmp = (cluster->start_pfn + cluster->numpages) << PAGE_SHIFT;
+               if (tmp > high)
+                       high = tmp;
+       }
+
+       /* Round it up to an even number of pages. */
+       high = (high + PAGE_SIZE) & (PAGE_MASK*2);
+       return PAGE_OFFSET + high;
+}
+
+
+static char sys_unknown[] = "Unknown";
+static char systype_names[][16] = {
+       "0",
+       "ADU", "Cobra", "Ruby", "Flamingo", "Mannequin", "Jensen",
+       "Pelican", "Morgan", "Sable", "Medulla", "Noname",
+       "Turbolaser", "Avanti", "Mustang", "Alcor", "Tradewind",
+       "Mikasa", "EB64", "EB66", "EB64+", "AlphaBook1",
+       "Rawhide", "K2", "Lynx", "XL", "EB164", "Noritake",
+       "Cortex", "29", "Miata", "XXM", "Takara", "Yukon",
+       "Tsunami", "Wildfire", "CUSCO"
+};
+
+static char unofficial_names[][8] = {"100", "Ruffian"};
+
+static char eb164_names[][8] = {"EB164", "PC164", "LX164", "SX164"};
+static int eb164_indices[] = {0,0,0,1,1,1,1,1,2,2,2,2,3,3,3,3};
+
+static char alcor_names[][16] = {"Alcor", "Maverick", "Bret"};
+static int alcor_indices[] = {0,0,0,1,1,1,0,0,0,0,0,0,2,2,2,2,2,2};
+
+static char eb64p_names[][16] = {"EB64+", "Cabriolet", "AlphaPCI64"};
+static int eb64p_indices[] = {0,0,1,2};
+
+static char eb66_names[][8] = {"EB66", "EB66+"};
+static int eb66_indices[] = {0,0,1};
+
+static char rawhide_names[][16] = {
+       "Dodge", "Wrangler", "Durango", "Tincup", "DaVinci"
+};
+static int rawhide_indices[] = {0,0,0,1,1,2,2,3,3,4,4};
+
+
+static struct alpha_machine_vector * __init
+get_sysvec(long type, long variation, long cpu)
+{
+#ifdef CONFIG_ALPHA_GENERIC
+       static struct alpha_machine_vector *systype_vecs[] __initlocaldata =
+       {
+               NULL,           /* 0 */
+               NULL,           /* ADU */
+               NULL,           /* Cobra */
+               NULL,           /* Ruby */
+               NULL,           /* Flamingo */
+               NULL,           /* Mannequin */
+               &jensen_mv,
+               NULL,           /* Pelican */
+               NULL,           /* Morgan */
+               NULL,           /* Sable -- see below.  */
+               NULL,           /* Medulla */
+               &noname_mv,
+               NULL,           /* Turbolaser */
+               &avanti_mv,
+               NULL,           /* Mustang */
+               &alcor_mv,      /* Alcor, Bret, Maverick.  */
+               NULL,           /* Tradewind */
+               NULL,           /* Mikasa -- see below.  */
+               NULL,           /* EB64 */
+               NULL,           /* EB66 -- see variation.  */
+               NULL,           /* EB64+ -- see variation.  */
+               &alphabook1_mv,
+               &rawhide_mv,
+               NULL,           /* K2 */
+               NULL,           /* Lynx */
+               &xl_mv,
+               NULL,           /* EB164 -- see variation.  */
+               NULL,           /* Noritake -- see below.  */
+               NULL,           /* Cortex */
+               NULL,           /* 29 */
+               &miata_mv,
+               NULL,           /* XXM */
+               &takara_mv,
+               NULL,           /* Yukon */
+               &dp264_mv,
+               NULL,           /* Wildfire */
+               NULL,           /* CUSCO */
+       };
+
+       static struct alpha_machine_vector *unofficial_vecs[] __initlocaldata =
+       {
+               NULL,           /* 100 */
+               &ruffian_mv,
+       };
+
+       static struct alpha_machine_vector *alcor_vecs[] __initlocaldata = 
+       {
+               &alcor_mv, &xlt_mv, &xlt_mv
+       };
+
+       static struct alpha_machine_vector *eb164_vecs[] __initlocaldata =
+       {
+               &eb164_mv, &pc164_mv, &lx164_mv, &sx164_mv
+       };
+
+       static struct alpha_machine_vector *eb64p_vecs[] __initlocaldata =
+       {
+               &eb64p_mv,
+               &cabriolet_mv,
+               NULL            /* AlphaPCI64 */
+       };
+
+       static struct alpha_machine_vector *eb66_vecs[] __initlocaldata =
+       {
+               &eb66_mv,
+               &eb66p_mv
        };
 
-       static char *unofficial_names[] = {"100", "Ruffian"};
+       /* ??? Do we need to distinguish between Rawhides?  */
 
-       static char * eb164_names[] = {"EB164", "PC164", "LX164", "SX164"};
-       static int eb164_indices[] = {0,0,0,1,1,1,1,1,2,2,2,2,3,3,3,3};
+       struct alpha_machine_vector *vec;
 
-       static char * alcor_names[] = {"Alcor", "Maverick", "Bret"};
-       static int alcor_indices[] = {0,0,0,1,1,1,0,0,0,0,0,0,2,2,2,2,2,2};
+       /* Restore real CABRIO and EB66+ family names, ie EB64+ and EB66 */
+       if (type < 0)
+               type = -type;
+
+       /* Search the system tables first... */
+       vec = NULL;
+       if (type < N(systype_vecs)) {
+               vec = systype_vecs[type];
+       } else if ((type > ST_UNOFFICIAL_BIAS) &&
+                  (type - ST_UNOFFICIAL_BIAS) < N(unofficial_vecs)) {
+               vec = unofficial_vecs[type - ST_UNOFFICIAL_BIAS];
+       }
 
-       static char * eb64p_names[] = {"EB64+", "Cabriolet", "AlphaPCI64"};
-       static int eb64p_indices[] = {0,0,1,2};
+       /* If we've not found one, try for a variation.  */
+
+       if (!vec) {
+               /* Member ID is a bit-field. */
+               long member = (variation >> 10) & 0x3f;
+
+               switch (type) {
+               case ST_DEC_ALCOR:
+                       if (member < N(alcor_indices))
+                               vec = alcor_vecs[alcor_indices[member]];
+                       break;
+               case ST_DEC_EB164:
+                       if (member < N(eb164_indices))
+                               vec = eb164_vecs[eb164_indices[member]];
+                       break;
+               case ST_DEC_EB64P:
+                       if (member < N(eb64p_indices))
+                               vec = eb64p_vecs[eb64p_indices[member]];
+                       break;
+               case ST_DEC_EB66:
+                       if (member < N(eb66_indices))
+                               vec = eb66_vecs[eb66_indices[member]];
+                       break;
+               case ST_DEC_1000:
+                       if (cpu == EV5_CPU)
+                               vec = &mikasa_primo_mv;
+                       else
+                               vec = &mikasa_mv;
+                       break;
+               case ST_DEC_NORITAKE:
+                       if (cpu == EV5_CPU)
+                               vec = &noritake_primo_mv;
+                       else
+                               vec = &noritake_mv;
+                       break;
+               case ST_DEC_2100_A500:
+                       if (cpu == EV5_CPU)
+                               vec = &sable_gamma_mv;
+                       else
+                               vec = &sable_mv;
+                       break;
+               }
+       }
+       return vec;
+#else
+       /* TODO: verify that the system is of the type for which we
+          were configured.  For now, cop out and return success.  */
+       return &alpha_mv;
+#endif /* GENERIC */
+}
 
-       static char * eb66_names[] = {"EB66", "EB66+"};
-       static int eb66_indices[] = {0,0,1};
+static struct alpha_machine_vector * __init
+get_sysvec_byname(const char *name)
+{
+#ifdef CONFIG_ALPHA_GENERIC
+       static struct alpha_machine_vector *all_vecs[] __initlocaldata =
+       {
+               &alcor_mv,
+               &alphabook1_mv,
+               &avanti_mv,
+               &cabriolet_mv,
+               &dp264_mv,
+               &eb164_mv,
+               &eb64p_mv,
+               &eb66_mv,
+               &eb66p_mv,
+               &jensen_mv,
+               &lx164_mv,
+               &miata_mv,
+               &mikasa_mv,
+               &mikasa_primo_mv,
+               &noname_mv,
+               &noritake_mv,
+               &noritake_primo_mv,
+               &p2k_mv,
+               &pc164_mv,
+               &rawhide_mv,
+               &ruffian_mv,
+               &sable_mv,
+               &sable_gamma_mv,
+               &sx164_mv,
+               &takara_mv,
+               &xl_mv,
+               &xlt_mv
+       };
 
-       static char * rawhide_names[] = {"Dodge", "Wrangler", "Durango",
-                                        "Tincup", "DaVinci"};
-       static int rawhide_indices[] = {0,0,0,1,1,2,2,3,3,4,4};
+       int i, n = sizeof(all_vecs)/sizeof(*all_vecs);
+       for (i = 0; i < n; ++i) {
+               struct alpha_machine_vector *mv = all_vecs[i];
+               if (strcasecmp(mv->vector_name, name) == 0)
+                       return mv;
+       }
+       return NULL;
+#else
+       if (strcasecmp(alpha_mv.vector_name, name) == 0)
+               return &alpha_mv;
+       return NULL;
+#endif
+}
 
+static void
+get_sysnames(long type, long variation,
+            char **type_name, char **variation_name)
+{
        long member;
 
        /* Restore real CABRIO and EB66+ family names, ie EB64+ and EB66 */
@@ -353,9 +642,47 @@ get_sysnames(long type, long variation,
                break;
        case ST_DEC_RAWHIDE:
                if (member < N(rawhide_indices))
-                 *variation_name = rawhide_names[rawhide_indices[member]];
+                       *variation_name = rawhide_names[rawhide_indices[member]];
                break;
-       } /* end family switch */
+       }
+}
+
+/*
+ * A change was made to the HWRPB via an ECO and the following code
+ * tracks a part of the ECO.  In HWRPB versions less than 5, the ECO
+ * was not implemented in the console firmware.  If it's revision 5 or
+ * greater we can get the name of the platform as an ASCII string from
+ * the HWRPB.  That's what this function does.  It checks the revision
+ * level and if the string is in the HWRPB it returns the address of
+ * the string--a pointer to the name of the platform.
+ *
+ * Returns:
+ *      - Pointer to a ASCII string if it's in the HWRPB
+ *      - Pointer to a blank string if the data is not in the HWRPB.
+ */
+
+static char *
+platform_string(void)
+{
+       struct dsr_struct *dsr;
+       static char unk_system_string[] = "N/A";
+
+       /* Go to the console for the string pointer.
+        * If the rpb_vers is not 5 or greater the rpb
+        * is old and does not have this data in it.
+        */
+       if (hwrpb->revision < 5)
+               return (unk_system_string);
+       else {
+               /* The Dynamic System Recognition struct
+                * has the system platform name starting
+                * after the character count of the string.
+                */
+               dsr =  ((struct dsr_struct *)
+                       ((char *)hwrpb + hwrpb->dsr_offset));
+               return ((char *)dsr + (dsr->sysname_off +
+                                      sizeof(long)));
+       }
 }
 
 /*
@@ -363,20 +690,21 @@ get_sysnames(long type, long variation,
  */
 int get_cpuinfo(char *buffer)
 {
-       static char *cpu_names[] = {
-               "EV3", "EV4", "Unknown", "LCA4", "EV5", "EV45", "EV56",
-               "EV6", "PCA56", "PCA57"
-       };
-
        extern struct unaligned_stat {
                unsigned long count, va, pc;
        } unaligned[2];
 
+       static char cpu_names[][8] = {
+               "EV3", "EV4", "Unknown", "LCA4", "EV5", "EV45", "EV56",
+               "EV6", "PCA56", "PCA57"
+       };
+
        struct percpu_struct *cpu;
        unsigned int cpu_index;
        char *cpu_name;
        char *systype_name;
        char *sysvariation_name;
+       int len;
 
        cpu = (struct percpu_struct*)((char*)hwrpb + hwrpb->processor_offset);
        cpu_index = (unsigned) (cpu->type - 1);
@@ -387,30 +715,25 @@ int get_cpuinfo(char *buffer)
        get_sysnames(hwrpb->sys_type, hwrpb->sys_variation,
                     &systype_name, &sysvariation_name);
 
-       return sprintf(buffer,
-                      "cpu\t\t\t: Alpha\n"
-                      "cpu model\t\t: %s\n"
-                      "cpu variation\t\t: %ld\n"
-                      "cpu revision\t\t: %ld\n"
-                      "cpu serial number\t: %s\n"
-                      "system type\t\t: %s\n"
-                      "system variation\t: %s\n"
-                      "system revision\t\t: %ld\n"
-                      "system serial number\t: %s\n"
-                      "cycle frequency [Hz]\t: %lu\n"
-                      "timer frequency [Hz]\t: %lu.%02lu\n"
-                      "page size [bytes]\t: %ld\n"
-                      "phys. address bits\t: %ld\n"
-                      "max. addr. space #\t: %ld\n"
-                      "BogoMIPS\t\t: %lu.%02lu\n"
-                      "kernel unaligned acc\t: %ld (pc=%lx,va=%lx)\n"
-                      "user unaligned acc\t: %ld (pc=%lx,va=%lx)\n"
-                      "platform string\t\t: %s\n"
-#ifdef __SMP__
-                      "%s"
-#endif
-                      ,
-
+       len = sprintf(buffer,
+                     "cpu\t\t\t: Alpha\n"
+                     "cpu model\t\t: %s\n"
+                     "cpu variation\t\t: %ld\n"
+                     "cpu revision\t\t: %ld\n"
+                     "cpu serial number\t: %s\n"
+                     "system type\t\t: %s\n"
+                     "system variation\t: %s\n"
+                     "system revision\t\t: %ld\n"
+                     "system serial number\t: %s\n"
+                     "cycle frequency [Hz]\t: %lu\n"
+                     "timer frequency [Hz]\t: %lu.%02lu\n"
+                     "page size [bytes]\t: %ld\n"
+                     "phys. address bits\t: %ld\n"
+                     "max. addr. space #\t: %ld\n"
+                     "BogoMIPS\t\t: %lu.%02lu\n"
+                     "kernel unaligned acc\t: %ld (pc=%lx,va=%lx)\n"
+                     "user unaligned acc\t: %ld (pc=%lx,va=%lx)\n"
+                     "platform string\t\t: %s\n",
                       cpu_name, cpu->variation, cpu->revision,
                       (char*)cpu->serial_no,
                       systype_name, sysvariation_name, hwrpb->sys_revision,
@@ -424,9 +747,11 @@ int get_cpuinfo(char *buffer)
                       loops_per_sec / 500000, (loops_per_sec / 5000) % 100,
                       unaligned[0].count, unaligned[0].pc, unaligned[0].va,
                       unaligned[1].count, unaligned[1].pc, unaligned[1].va,
-                      platform_string()
+                      platform_string());
+
 #ifdef __SMP__
-                      , smp_info()
+       return len + smp_info(buffer+len);
+#else
+       return len;
 #endif
-                      );
 }
index 7226ed83c769c55477f18231000f791857a4b549..53175a0f11f940724d59afcf3dab1b36798e7dc3 100644 (file)
@@ -24,6 +24,8 @@
 #define __KERNEL_SYSCALLS__
 #include <asm/unistd.h>
 
+#include "proto.h"
+
 struct ipi_msg_flush_tb_struct ipi_msg_flush_tb;
 
 struct cpuinfo_alpha cpu_data[NR_CPUS];
@@ -735,15 +737,11 @@ send_ipi_message(long to_whom, enum ipi_message_type operation)
        }
 }
 
-static char smp_buf[256];
-
-char *smp_info(void)
+int smp_info(char *buffer)
 {
-        sprintf(smp_buf, "CPUs probed %d active %d map 0x%x AKP %d\n",
-               smp_num_probed, smp_num_cpus, cpu_present_map,
-               klock_info.akp);
-
-        return smp_buf;
+        return sprintf(buffer, "CPUs probed %d active %d map 0x%x AKP %d\n",
+                      smp_num_probed, smp_num_cpus, cpu_present_map,
+                      klock_info.akp);
 }
 
 /* wrapper for call from panic() */
diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c
new file mode 100644 (file)
index 0000000..9b9dd34
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ *     linux/arch/alpha/kernel/sys_alcor.c
+ *
+ *     Copyright (C) 1995 David A Rusling
+ *     Copyright (C) 1996 Jay A Estabrook
+ *     Copyright (C) 1998 Richard Henderson
+ *
+ * Code supporting the ALCOR and XLT (XL-300/366/433).
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/bitops.h>
+#include <asm/mmu_context.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/core_cia.h>
+
+#include "proto.h"
+#include "irq.h"
+#include "bios32.h"
+#include "machvec.h"
+
+
+static void 
+alcor_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+       if (irq >= 16) {
+               /* On Alcor, at least, lines 20..30 are not connected and can
+                  generate spurrious interrupts if we turn them on while IRQ
+                  probing.  So explicitly mask them out. */
+               mask |= 0x7ff000000000UL;
+
+               /* Note inverted sense of mask bits: */
+               *(vuip)GRU_INT_MASK = ~(mask >> 16);
+               mb();
+       }
+       else if (irq >= 8)
+               outb(mask >> 8, 0xA1);  /* ISA PIC2 */
+       else
+               outb(mask, 0x21);       /* ISA PIC1 */
+}
+
+static void
+alcor_ack_irq(unsigned long irq)
+{
+       if (irq < 16) {
+               /* Ack the interrupt making it the lowest priority */
+               /*  First the slave .. */
+               if (irq > 7) {
+                       outb(0xE0 | (irq - 8), 0xa0);
+                       irq = 2;
+               }
+               /* .. then the master */
+               outb(0xE0 | irq, 0x20);
+
+               /* On ALCOR/XLT, need to dismiss interrupt via GRU. */
+               *(vuip)GRU_INT_CLEAR = 0x80000000; mb();
+               *(vuip)GRU_INT_CLEAR = 0x00000000; mb();
+       }
+}
+
+static void
+alcor_device_interrupt(unsigned long vector, struct pt_regs *regs)
+{
+       unsigned long pld;
+       unsigned int i;
+       unsigned long flags;
+
+       save_and_cli(flags);
+
+       /* Read the interrupt summary register of the GRU */
+       pld = (*(vuip)GRU_INT_REQ) & GRU_INT_REQ_BITS;
+
+       /*
+        * Now for every possible bit set, work through them and call
+        * the appropriate interrupt handler.
+        */
+       while (pld) {
+               i = ffz(~pld);
+               pld &= pld - 1; /* clear least bit set */
+               if (i == 31) {
+                       isa_device_interrupt(vector, regs);
+               } else {
+                       handle_irq(16 + i, 16 + i, regs);
+               }
+       }
+       restore_flags(flags);
+}
+
+static void
+alcor_init_irq(void)
+{
+       STANDARD_INIT_IRQ_PROLOG;
+
+       if (alpha_using_srm)
+               alpha_mv.device_interrupt = srm_device_interrupt;
+
+       *(vuip)GRU_INT_MASK  = ~(alpha_irq_mask >> 16); mb(); /* invert */
+       *(vuip)GRU_INT_EDGE  = 0U; mb();                /* all are level */
+       *(vuip)GRU_INT_HILO  = 0x80000000U; mb();       /* ISA only HI */
+       *(vuip)GRU_INT_CLEAR = 0UL; mb();               /* all clear */
+
+       enable_irq(16 + 31);            /* enable (E)ISA PIC cascade */
+       enable_irq(2);                  /* enable cascade */
+}
+
+
+/*
+ * PCI Fixup configuration.
+ *
+ * Summary @ GRU_INT_REQ:
+ * Bit      Meaning
+ * 0        Interrupt Line A from slot 2
+ * 1        Interrupt Line B from slot 2
+ * 2        Interrupt Line C from slot 2
+ * 3        Interrupt Line D from slot 2
+ * 4        Interrupt Line A from slot 1
+ * 5        Interrupt line B from slot 1
+ * 6        Interrupt Line C from slot 1
+ * 7        Interrupt Line D from slot 1
+ * 8        Interrupt Line A from slot 0
+ * 9        Interrupt Line B from slot 0
+ *10        Interrupt Line C from slot 0
+ *11        Interrupt Line D from slot 0
+ *12        Interrupt Line A from slot 4
+ *13        Interrupt Line B from slot 4
+ *14        Interrupt Line C from slot 4
+ *15        Interrupt Line D from slot 4
+ *16        Interrupt Line D from slot 3
+ *17        Interrupt Line D from slot 3
+ *18        Interrupt Line D from slot 3
+ *19        Interrupt Line D from slot 3
+ *20-30     Reserved
+ *31        EISA interrupt
+ *
+ * The device to slot mapping looks like:
+ *
+ * Slot     Device
+ *  6       built-in TULIP (XLT only)
+ *  7       PCI on board slot 0
+ *  8       PCI on board slot 3
+ *  9       PCI on board slot 4
+ * 10       PCEB (PCI-EISA bridge)
+ * 11       PCI on board slot 2
+ * 12       PCI on board slot 1
+ *   
+ *
+ * This two layered interrupt approach means that we allocate IRQ 16 and 
+ * above for PCI interrupts.  The IRQ relates to which bit the interrupt
+ * comes in on.  This makes interrupt processing much easier.
+ */
+
+static int __init
+alcor_map_irq(struct pci_dev *dev, int slot, int pin)
+{
+       static char irq_tab[7][5] __initlocaldata = {
+               /*INT    INTA   INTB   INTC   INTD */
+               /* note: IDSEL 17 is XLT only */
+               {16+13, 16+13, 16+13, 16+13, 16+13},    /* IdSel 17,  TULIP  */
+               { 16+8,  16+8,  16+9, 16+10, 16+11},    /* IdSel 18,  slot 0 */
+               {16+16, 16+16, 16+17, 16+18, 16+19},    /* IdSel 19,  slot 3 */
+               {16+12, 16+12, 16+13, 16+14, 16+15},    /* IdSel 20,  slot 4 */
+               {   -1,    -1,    -1,    -1,    -1},    /* IdSel 21,  PCEB   */
+               { 16+0,  16+0,  16+1,  16+2,  16+3},    /* IdSel 22,  slot 2 */
+               { 16+4,  16+4,  16+5,  16+6,  16+7},    /* IdSel 23,  slot 1 */
+       };
+       const long min_idsel = 6, max_idsel = 12, irqs_per_slot = 5;
+       return COMMON_TABLE_LOOKUP;
+}
+
+static void __init
+alcor_pci_fixup(void)
+{
+       layout_all_busses(EISA_DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
+       common_pci_fixup(alcor_map_irq, common_swizzle);
+}
+
+
+static void
+alcor_kill_arch (int mode, char *reboot_cmd)
+{
+       /* Who said DEC engineer's have no sense of humor? ;-)  */
+       if (alpha_using_srm) {
+               *(vuip) GRU_RESET = 0x0000dead;
+               mb();
+       }
+
+       generic_kill_arch(mode, reboot_cmd);
+}
+
+
+/*
+ * The System Vectors
+ */
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_ALCOR)
+struct alpha_machine_vector alcor_mv __initmv = {
+       vector_name:            "Alcor",
+       DO_EV5_MMU,
+       DO_DEFAULT_RTC,
+       DO_CIA_IO,
+       DO_CIA_BUS,
+       machine_check:          cia_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                48,
+       irq_probe_mask:         ALCOR_PROBE_MASK,
+       update_irq_hw:          alcor_update_irq_hw,
+       ack_irq:                alcor_ack_irq,
+       device_interrupt:       alcor_device_interrupt,
+
+       init_arch:              cia_init_arch,
+       init_irq:               alcor_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              alcor_pci_fixup,
+       kill_arch:              alcor_kill_arch,
+
+       sys: { cia: {
+           gru_int_req_bits:   ALCOR_GRU_INT_REQ_BITS
+       }}
+};
+ALIAS_MV(alcor)
+#endif
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_XLT)
+struct alpha_machine_vector xlt_mv __initmv = {
+       vector_name:            "XLT",
+       DO_EV5_MMU,
+       DO_DEFAULT_RTC,
+       DO_CIA_IO,
+       DO_CIA_BUS,
+       machine_check:          cia_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                48,
+       irq_probe_mask:         ALCOR_PROBE_MASK,
+       update_irq_hw:          alcor_update_irq_hw,
+       ack_irq:                alcor_ack_irq,
+       device_interrupt:       alcor_device_interrupt,
+
+       init_arch:              cia_init_arch,
+       init_irq:               alcor_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              alcor_pci_fixup,
+       kill_arch:              alcor_kill_arch,
+
+       sys: { cia: {
+           gru_int_req_bits:   XLT_GRU_INT_REQ_BITS
+       }}
+};
+ALIAS_MV(xlt)
+#endif
diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c
new file mode 100644 (file)
index 0000000..273d53c
--- /dev/null
@@ -0,0 +1,395 @@
+/*
+ *     linux/arch/alpha/kernel/sys_cabriolet.c
+ *
+ *     Copyright (C) 1995 David A Rusling
+ *     Copyright (C) 1996 Jay A Estabrook
+ *     Copyright (C) 1998 Richard Henderson
+ *
+ * Code supporting the Cabriolet (AlphaPC64), EB66+, and EB164,
+ * PC164 and LX164.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/core_apecs.h>
+#include <asm/core_cia.h>
+#include <asm/core_lca.h>
+#include <asm/core_pyxis.h>
+
+#include "proto.h"
+#include "irq.h"
+#include "bios32.h"
+#include "machvec.h"
+
+
+static void
+cabriolet_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+       if (irq >= 16)
+               outl(alpha_irq_mask >> 16, 0x804);
+       else if (irq >= 8)
+               outb(mask >> 8, 0xA1);
+       else
+               outb(mask, 0x21);
+}
+
+
+/* Under SRM console, we must use the CSERVE PALcode routine to manage
+   the interrupt mask for us.  Otherwise, the kernel/HW get out of
+   sync with what the PALcode thinks it needs to deliver/ignore.  */
+
+static void
+cabriolet_srm_update_irq_hw(unsigned long irq, unsigned long mask, int unmaskp)
+{
+       if (irq >= 16) {
+               if (unmaskp)
+                       cserve_ena(irq - 16);
+               else
+                       cserve_dis(irq - 16);
+       }
+       else if (irq >= 8)
+               outb(mask >> 8, 0xA1);
+       else
+               outb(mask, 0x21);
+}
+
+static void 
+cabriolet_device_interrupt(unsigned long v, struct pt_regs *r)
+{
+       unsigned long pld;
+       unsigned int i;
+       unsigned long flags;
+
+       save_and_cli(flags);
+
+       /* Read the interrupt summary registers */
+       pld = inb(0x804) | (inb(0x805) << 8) | (inb(0x806) << 16);
+
+       /*
+        * Now for every possible bit set, work through them and call
+        * the appropriate interrupt handler.
+        */
+       while (pld) {
+               i = ffz(~pld);
+               pld &= pld - 1; /* clear least bit set */
+               if (i == 4) {
+                       isa_device_interrupt(v, r);
+               } else {
+                       handle_irq(16 + i, 16 + i, r);
+               }
+       }
+       restore_flags(flags);
+}
+
+static void
+cabriolet_init_irq(void)
+{
+       STANDARD_INIT_IRQ_PROLOG;
+
+       if (alpha_using_srm) {
+               alpha_mv.update_irq_hw = cabriolet_srm_update_irq_hw;
+               alpha_mv.device_interrupt = srm_device_interrupt;
+       }
+       else {
+               outl(alpha_irq_mask >> 16, 0x804);
+       }
+
+       enable_irq(16 + 4);             /* enable SIO cascade */
+       enable_irq(2);                  /* enable cascade */
+}
+
+
+/*
+ * The EB66+ is very similar to the EB66 except that it does not have
+ * the on-board NCR and Tulip chips.  In the code below, I have used
+ * slot number to refer to the id select line and *not* the slot
+ * number used in the EB66+ documentation.  However, in the table,
+ * I've given the slot number, the id select line and the Jxx number
+ * that's printed on the board.  The interrupt pins from the PCI slots
+ * are wired into 3 interrupt summary registers at 0x804, 0x805 and
+ * 0x806 ISA.
+ *
+ * In the table, -1 means don't assign an IRQ number.  This is usually
+ * because it is the Saturn IO (SIO) PCI/ISA Bridge Chip.
+ */
+
+static inline int __init
+eb66p_map_irq(struct pci_dev *dev, int slot, int pin)
+{
+       static char irq_tab[5][5] __initlocaldata = {
+               /*INT  INTA  INTB  INTC   INTD */
+               {16+0, 16+0, 16+5,  16+9, 16+13},  /* IdSel 6,  slot 0, J25 */
+               {16+1, 16+1, 16+6, 16+10, 16+14},  /* IdSel 7,  slot 1, J26 */
+               {  -1,   -1,   -1,    -1,    -1},  /* IdSel 8,  SIO         */
+               {16+2, 16+2, 16+7, 16+11, 16+15},  /* IdSel 9,  slot 2, J27 */
+               {16+3, 16+3, 16+8, 16+12,  16+6}   /* IdSel 10, slot 3, J28 */
+       };
+       const long min_idsel = 6, max_idsel = 10, irqs_per_slot = 5;
+       return COMMON_TABLE_LOOKUP;
+}
+
+static inline void __init
+eb66p_pci_fixup(void)
+{
+       layout_all_busses(DEFAULT_IO_BASE, APECS_AND_LCA_DEFAULT_MEM_BASE);
+       common_pci_fixup(eb66p_map_irq, common_swizzle);
+       enable_ide(0x398);
+}
+
+
+/*
+ * The AlphaPC64 is very similar to the EB66+ except that its slots
+ * are numbered differently.  In the code below, I have used slot
+ * number to refer to the id select line and *not* the slot number
+ * used in the AlphaPC64 documentation.  However, in the table, I've
+ * given the slot number, the id select line and the Jxx number that's
+ * printed on the board.  The interrupt pins from the PCI slots are
+ * wired into 3 interrupt summary registers at 0x804, 0x805 and 0x806
+ * ISA.
+ *
+ * In the table, -1 means don't assign an IRQ number.  This is usually
+ * because it is the Saturn IO (SIO) PCI/ISA Bridge Chip.
+ */
+
+static inline int __init
+cabriolet_map_irq(struct pci_dev *dev, int slot, int pin)
+{
+       static char irq_tab[5][5] __initlocaldata = {
+               /*INT   INTA  INTB  INTC   INTD */
+               { 16+2, 16+2, 16+7, 16+11, 16+15}, /* IdSel 5,  slot 2, J21 */
+               { 16+0, 16+0, 16+5,  16+9, 16+13}, /* IdSel 6,  slot 0, J19 */
+               { 16+1, 16+1, 16+6, 16+10, 16+14}, /* IdSel 7,  slot 1, J20 */
+               {   -1,   -1,   -1,    -1,    -1}, /* IdSel 8,  SIO         */
+               { 16+3, 16+3, 16+8, 16+12, 16+16}  /* IdSel 9,  slot 3, J22 */
+       };
+       const long min_idsel = 5, max_idsel = 9, irqs_per_slot = 5;
+       return COMMON_TABLE_LOOKUP;
+}
+
+static inline void __init
+cabriolet_pci_fixup(void)
+{
+       layout_all_busses(DEFAULT_IO_BASE, APECS_AND_LCA_DEFAULT_MEM_BASE);
+       common_pci_fixup(cabriolet_map_irq, common_swizzle);
+       enable_ide(0x398);
+}
+
+static inline void __init
+eb164_pci_fixup(void)
+{
+       layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
+       common_pci_fixup(cabriolet_map_irq, common_swizzle);
+       enable_ide(0x398);
+}
+
+
+/*
+ * The PC164 and LX164 have 19 PCI interrupts, four from each of the four
+ * PCI slots, the SIO, PCI/IDE, and USB.
+ * 
+ * Each of the interrupts can be individually masked. This is
+ * accomplished by setting the appropriate bit in the mask register.
+ * A bit is set by writing a "1" to the desired position in the mask
+ * register and cleared by writing a "0". There are 3 mask registers
+ * located at ISA address 804h, 805h and 806h.
+ * 
+ * An I/O read at ISA address 804h, 805h, 806h will return the
+ * state of the 11 PCI interrupts and not the state of the MASKED
+ * interrupts.
+ * 
+ * Note: A write to I/O 804h, 805h, and 806h the mask register will be
+ * updated.
+ * 
+ * 
+ *                             ISA DATA<7:0>
+ * ISA     +--------------------------------------------------------------+
+ * ADDRESS |   7   |   6   |   5   |   4   |   3   |   2  |   1   |   0   |
+ *         +==============================================================+
+ * 0x804   | INTB0 |  USB  |  IDE  |  SIO  | INTA3 |INTA2 | INTA1 | INTA0 |
+ *         +--------------------------------------------------------------+
+ * 0x805   | INTD0 | INTC3 | INTC2 | INTC1 | INTC0 |INTB3 | INTB2 | INTB1 |
+ *         +--------------------------------------------------------------+
+ * 0x806   | Rsrv  | Rsrv  | Rsrv  | Rsrv  | Rsrv  |INTD3 | INTD2 | INTD1 |
+ *         +--------------------------------------------------------------+
+ *         * Rsrv = reserved bits
+ *         Note: The mask register is write-only.
+ * 
+ * IdSel       
+ *   5  32 bit PCI option slot 2
+ *   6  64 bit PCI option slot 0
+ *   7  64 bit PCI option slot 1
+ *   8  Saturn I/O
+ *   9  32 bit PCI option slot 3
+ *  10  USB
+ *  11  IDE
+ * 
+ */
+
+static inline int __init
+alphapc164_map_irq(struct pci_dev *dev, int slot, int pin)
+{
+       static char irq_tab[7][5] __initlocaldata = {
+               /*INT   INTA  INTB   INTC   INTD */
+               { 16+2, 16+2, 16+9,  16+13, 16+17}, /* IdSel  5, slot 2, J20 */
+               { 16+0, 16+0, 16+7,  16+11, 16+15}, /* IdSel  6, slot 0, J29 */
+               { 16+1, 16+1, 16+8,  16+12, 16+16}, /* IdSel  7, slot 1, J26 */
+               {   -1,   -1,   -1,    -1,    -1},  /* IdSel  8, SIO */
+               { 16+3, 16+3, 16+10, 16+14, 16+18}, /* IdSel  9, slot 3, J19 */
+               { 16+6, 16+6, 16+6,  16+6,  16+6},  /* IdSel 10, USB */
+               { 16+5, 16+5, 16+5,  16+5,  16+5}   /* IdSel 11, IDE */
+       };
+       const long min_idsel = 5, max_idsel = 11, irqs_per_slot = 5;
+       return COMMON_TABLE_LOOKUP;
+}
+
+static inline void __init
+alphapc164_pci_fixup(void)
+{
+       layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
+       common_pci_fixup(alphapc164_map_irq, common_swizzle);
+       SMC93x_Init();
+}
+
+/*
+ * The System Vector
+ */
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_CABRIOLET)
+struct alpha_machine_vector cabriolet_mv __initmv = {
+       vector_name:            "Cabriolet",
+       DO_EV4_MMU,
+       DO_DEFAULT_RTC,
+       DO_APECS_IO,
+       DO_APECS_BUS,
+       machine_check:          apecs_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                35,
+       irq_probe_mask:         _PROBE_MASK(35),
+       update_irq_hw:          cabriolet_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       cabriolet_device_interrupt,
+
+       init_arch:              apecs_init_arch,
+       init_irq:               cabriolet_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              cabriolet_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(cabriolet)
+#endif
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EB164)
+struct alpha_machine_vector eb164_mv __initmv = {
+       vector_name:            "EB164",
+       DO_EV5_MMU,
+       DO_DEFAULT_RTC,
+       DO_CIA_IO,
+       DO_CIA_BUS,
+       machine_check:          cia_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                35,
+       irq_probe_mask:         _PROBE_MASK(35),
+       update_irq_hw:          cabriolet_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       cabriolet_device_interrupt,
+
+       init_arch:              cia_init_arch,
+       init_irq:               cabriolet_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              eb164_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(eb164)
+#endif
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EB66P)
+struct alpha_machine_vector eb66p_mv __initmv = {
+       vector_name:            "EB66+",
+       DO_EV4_MMU,
+       DO_DEFAULT_RTC,
+       DO_LCA_IO,
+       DO_LCA_BUS,
+       machine_check:          lca_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                35,
+       irq_probe_mask:         _PROBE_MASK(35),
+       update_irq_hw:          cabriolet_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       cabriolet_device_interrupt,
+
+       init_arch:              lca_init_arch,
+       init_irq:               cabriolet_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              eb66p_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(eb66p)
+#endif
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LX164)
+struct alpha_machine_vector lx164_mv __initmv = {
+       vector_name:            "LX164",
+       DO_EV5_MMU,
+       DO_DEFAULT_RTC,
+       DO_PYXIS_IO,
+       DO_PYXIS_BUS,
+       machine_check:          pyxis_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                35,
+       irq_probe_mask:         _PROBE_MASK(35),
+       update_irq_hw:          cabriolet_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       cabriolet_device_interrupt,
+
+       init_arch:              pyxis_init_arch,
+       init_irq:               cabriolet_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              alphapc164_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(lx164)
+#endif
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_PC164)
+struct alpha_machine_vector pc164_mv __initmv = {
+       vector_name:            "PC164",
+       DO_EV5_MMU,
+       DO_DEFAULT_RTC,
+       DO_CIA_IO,
+       DO_CIA_BUS,
+       machine_check:          cia_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                35,
+       irq_probe_mask:         _PROBE_MASK(35),
+       update_irq_hw:          cabriolet_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       cabriolet_device_interrupt,
+
+       init_arch:              cia_init_arch,
+       init_irq:               cabriolet_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              alphapc164_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(pc164)
+#endif
+
diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c
new file mode 100644 (file)
index 0000000..e110891
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ *     linux/arch/alpha/kernel/sys_dp264.c
+ *
+ *     Copyright (C) 1995 David A Rusling
+ *     Copyright (C) 1996 Jay A Estabrook
+ *     Copyright (C) 1998 Richard Henderson
+ *
+ * Code supporting the DP264 (EV6+TSUNAMI).
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/core_tsunami.h>
+
+#include "proto.h"
+#include "irq.h"
+#include "bios32.h"
+#include "machvec.h"
+
+
+/*
+ * HACK ALERT! only CPU#0 is used currently
+ */
+
+static void
+dp264_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+       if (irq >= 16) {
+               /* Make CERTAIN none of the bogus ints get enabled */
+               *(vulp)TSUNAMI_CSR_DIM0 =
+                       ~(mask) & ~0x0000000000000000UL;
+               mb();
+               /* ... and read it back to make sure it got written.  */
+               *(vulp)TSUNAMI_CSR_DIM0;
+       }
+       else if (irq >= 8)
+               outb(mask >> 8, 0xA1);  /* ISA PIC2 */
+       else
+               outb(mask, 0x21);       /* ISA PIC1 */
+}
+
+static void
+dp264_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+        unsigned long pld;
+        unsigned int i;
+        unsigned long flags;
+
+       __save_and_cli(flags);
+
+        /* Read the interrupt summary register of TSUNAMI */
+        pld = (*(vulp)TSUNAMI_CSR_DIR0);
+
+        /*
+         * Now for every possible bit set, work through them and call
+         * the appropriate interrupt handler.
+         */
+        while (pld) {
+                i = ffz(~pld);
+                pld &= pld - 1; /* clear least bit set */
+                if (i == 55) {
+                        isa_device_interrupt(vector, regs);
+               } else { /* if not timer int */
+                        handle_irq(16 + i, 16 + i, regs);
+                }
+#if 0
+               *(vulp)TSUNAMI_CSR_DIR0 = 1UL << i; mb();
+               tmp = *(vulp)TSUNAMI_CSR_DIR0;
+#endif
+        }
+       __restore_flags(flags);
+}
+
+static void 
+dp264_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+       int irq, ack;
+       unsigned long flags;
+
+       __save_and_cli(flags);
+       ack = irq = (vector - 0x800) >> 4;
+
+        /*
+         * The DP264 SRM console reports PCI interrupts with a vector
+        * 0x100 *higher* than one might expect, as PCI IRQ 0 (ie bit 0)
+        * shows up as IRQ 16, etc, etc. We adjust it down by 16 to have
+        * it line up with the actual bit numbers from the DIM registers,
+        * which is how we manage the interrupts/mask. Sigh...
+         */
+        if (irq >= 32)
+                ack = irq = irq - 16;
+
+       handle_irq(irq, ack, regs);
+       __restore_flags(flags);
+}
+
+static void __init
+dp264_init_irq(void)
+{
+       STANDARD_INIT_IRQ_PROLOG;
+
+       if (alpha_using_srm)
+               alpha_mv.device_interrupt = dp264_srm_device_interrupt;
+
+       /* Note invert on MASK bits.  */
+        *(vulp)TSUNAMI_CSR_DIM0 = ~(alpha_irq_mask) & ~0UL; mb();
+        *(vulp)TSUNAMI_CSR_DIM0;
+
+        enable_irq(55);     /* Enable CYPRESS interrupt controller (ISA).  */
+       enable_irq(2);
+}
+
+
+/*
+ * PCI Fixup configuration.
+ *
+ * Summary @ TSUNAMI_CSR_DIM0:
+ * Bit      Meaning
+ * 0-17     Unused
+ *18        Interrupt SCSI B (Adaptec 7895 builtin)
+ *19        Interrupt SCSI A (Adaptec 7895 builtin)
+ *20        Interrupt Line D from slot 2 PCI0
+ *21        Interrupt Line C from slot 2 PCI0
+ *22        Interrupt Line B from slot 2 PCI0
+ *23        Interrupt Line A from slot 2 PCI0
+ *24        Interrupt Line D from slot 1 PCI0
+ *25        Interrupt Line C from slot 1 PCI0
+ *26        Interrupt Line B from slot 1 PCI0
+ *27        Interrupt Line A from slot 1 PCI0
+ *28        Interrupt Line D from slot 0 PCI0
+ *29        Interrupt Line C from slot 0 PCI0
+ *30        Interrupt Line B from slot 0 PCI0
+ *31        Interrupt Line A from slot 0 PCI0
+ *
+ *32        Interrupt Line D from slot 3 PCI1
+ *33        Interrupt Line C from slot 3 PCI1
+ *34        Interrupt Line B from slot 3 PCI1
+ *35        Interrupt Line A from slot 3 PCI1
+ *36        Interrupt Line D from slot 2 PCI1
+ *37        Interrupt Line C from slot 2 PCI1
+ *38        Interrupt Line B from slot 2 PCI1
+ *39        Interrupt Line A from slot 2 PCI1
+ *40        Interrupt Line D from slot 1 PCI1
+ *41        Interrupt Line C from slot 1 PCI1
+ *42        Interrupt Line B from slot 1 PCI1
+ *43        Interrupt Line A from slot 1 PCI1
+ *44        Interrupt Line D from slot 0 PCI1
+ *45        Interrupt Line C from slot 0 PCI1
+ *46        Interrupt Line B from slot 0 PCI1
+ *47        Interrupt Line A from slot 0 PCI1
+ *48-52     Unused
+ *53        PCI0 NMI (from Cypress)
+ *54        PCI0 SMI INT (from Cypress)
+ *55        PCI0 ISA Interrupt (from Cypress)
+ *56-60     Unused
+ *61        PCI1 Bus Error
+ *62        PCI0 Bus Error
+ *63        Reserved
+ *
+ * IdSel       
+ *   5  Cypress Bridge I/O
+ *   6  SCSI Adaptec builtin
+ *   7  64 bit PCI option slot 0
+ *   8  64 bit PCI option slot 1
+ *   9  64 bit PCI option slot 2
+ * 
+ */
+
+static int __init
+dp264_map_irq(struct pci_dev *dev, int slot, int pin)
+{
+       static char irq_tab[5][5] __initlocaldata = {
+               /*INT    INTA   INTB   INTC   INTD */
+               {    -1,    -1,    -1,    -1,    -1}, /* IdSel 5 ISA Bridge */
+               { 16+ 2, 16+ 2, 16+ 2, 16+ 2, 16+ 2}, /* IdSel 6 SCSI builtin*/
+               { 16+15, 16+15, 16+14, 16+13, 16+12}, /* IdSel 7 slot 0 */
+               { 16+11, 16+11, 16+10, 16+ 9, 16+ 8}, /* IdSel 8 slot 1 */
+               { 16+ 7, 16+ 7, 16+ 6, 16+ 5, 16+ 4}  /* IdSel 9 slot 2 */
+       };
+       const long min_idsel = 5, max_idsel = 9, irqs_per_slot = 5;
+       return COMMON_TABLE_LOOKUP;
+}
+
+static void __init
+dp264_pci_fixup(void)
+{
+       layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
+       common_pci_fixup(dp264_map_irq, common_swizzle);
+       SMC669_Init();
+}
+
+
+/*
+ * The System Vector
+ */
+
+struct alpha_machine_vector dp264_mv __initmv = {
+       vector_name:            "DP264",
+       DO_EV6_MMU,
+       DO_DEFAULT_RTC,
+       DO_TSUNAMI_IO,
+       DO_TSUNAMI_BUS,
+       machine_check:          tsunami_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                64,
+       irq_probe_mask:         _PROBE_MASK(64),
+       update_irq_hw:          dp264_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       dp264_device_interrupt,
+
+       init_arch:              tsunami_init_arch,
+       init_irq:               dp264_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              dp264_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(dp264)
diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c
new file mode 100644 (file)
index 0000000..bffd119
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ *     linux/arch/alpha/kernel/sys_eb64p.c
+ *
+ *     Copyright (C) 1995 David A Rusling
+ *     Copyright (C) 1996 Jay A Estabrook
+ *     Copyright (C) 1998 Richard Henderson
+ *
+ * Code supporting the EB64+ and EB66.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/core_apecs.h>
+#include <asm/core_lca.h>
+
+#include "proto.h"
+#include "irq.h"
+#include "bios32.h"
+#include "machvec.h"
+
+
+static void
+eb64p_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+       if (irq >= 16)
+               if (irq >= 24)
+                       outb(mask >> 24, 0x27);
+               else
+                       outb(mask >> 16, 0x26);
+       else if (irq >= 8)
+               outb(mask >> 8, 0xA1);
+       else
+               outb(mask, 0x21);
+}
+
+static void 
+eb64p_device_interrupt(unsigned long vector, struct pt_regs *regs)
+{
+       unsigned long pld;
+       unsigned int i;
+       unsigned long flags;
+
+       save_and_cli(flags);
+
+       /* Read the interrupt summary registers */
+       pld = inb(0x26) | (inb(0x27) << 8);
+       /*
+        * Now, for every possible bit set, work through
+        * them and call the appropriate interrupt handler.
+        */
+       while (pld) {
+               i = ffz(~pld);
+               pld &= pld - 1; /* clear least bit set */
+
+               if (i == 5) {
+                       isa_device_interrupt(vector, regs);
+               } else {
+                       handle_irq(16 + i, 16 + i, regs);
+               }
+       }
+       restore_flags(flags);
+}
+
+static void __init
+eb64p_init_irq(void)
+{
+       STANDARD_INIT_IRQ_PROLOG;
+
+       outb(alpha_irq_mask >> 16, 0x26);
+       outb(alpha_irq_mask >> 24, 0x27);
+       enable_irq(16 + 5);             /* enable SIO cascade */
+       enable_irq(2);                  /* enable cascade */
+}
+
+/*
+ * PCI Fixup configuration.
+ *
+ * There are two 8 bit external summary registers as follows:
+ *
+ * Summary @ 0x26:
+ * Bit      Meaning
+ * 0        Interrupt Line A from slot 0
+ * 1        Interrupt Line A from slot 1
+ * 2        Interrupt Line B from slot 0
+ * 3        Interrupt Line B from slot 1
+ * 4        Interrupt Line C from slot 0
+ * 5        Interrupt line from the two ISA PICs
+ * 6        Tulip (slot 
+ * 7        NCR SCSI
+ *
+ * Summary @ 0x27
+ * Bit      Meaning
+ * 0        Interrupt Line C from slot 1
+ * 1        Interrupt Line D from slot 0
+ * 2        Interrupt Line D from slot 1
+ * 3        RAZ
+ * 4        RAZ
+ * 5        RAZ
+ * 6        RAZ
+ * 7        RAZ
+ *
+ * The device to slot mapping looks like:
+ *
+ * Slot     Device
+ *  5       NCR SCSI controller
+ *  6       PCI on board slot 0
+ *  7       PCI on board slot 1
+ *  8       Intel SIO PCI-ISA bridge chip
+ *  9       Tulip - DECchip 21040 Ethernet controller
+ *   
+ *
+ * This two layered interrupt approach means that we allocate IRQ 16 and 
+ * above for PCI interrupts.  The IRQ relates to which bit the interrupt
+ * comes in on.  This makes interrupt processing much easier.
+ */
+
+static int __init
+eb64p_map_irq(struct pci_dev *dev, int slot, int pin)
+{
+       static char irq_tab[5][5] __initlocaldata = {
+               /*INT  INTA  INTB  INTC   INTD */
+               {16+7, 16+7, 16+7, 16+7,  16+7},  /* IdSel 5,  slot ?, ?? */
+               {16+0, 16+0, 16+2, 16+4,  16+9},  /* IdSel 6,  slot ?, ?? */
+               {16+1, 16+1, 16+3, 16+8, 16+10},  /* IdSel 7,  slot ?, ?? */
+               {  -1,   -1,   -1,   -1,    -1},  /* IdSel 8,  SIO */
+               {16+6, 16+6, 16+6, 16+6,  16+6},  /* IdSel 9,  TULIP */
+       };
+       const long min_idsel = 5, max_idsel = 9, irqs_per_slot = 5;
+       return COMMON_TABLE_LOOKUP;
+}
+
+static void __init
+eb64p_pci_fixup(void)
+{
+       layout_all_busses(DEFAULT_IO_BASE, APECS_AND_LCA_DEFAULT_MEM_BASE);
+       common_pci_fixup(eb64p_map_irq, common_swizzle);
+}
+
+
+/*
+ * The System Vector
+ */
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EB64P)
+struct alpha_machine_vector eb64p_mv __initmv = {
+       vector_name:            "EB64+",
+       DO_EV4_MMU,
+       DO_DEFAULT_RTC,
+       DO_APECS_IO,
+       DO_APECS_BUS,
+       machine_check:          apecs_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                32,
+       irq_probe_mask:         _PROBE_MASK(32),
+       update_irq_hw:          eb64p_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       eb64p_device_interrupt,
+
+       init_arch:              apecs_init_arch,
+       init_irq:               eb64p_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              eb64p_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(eb64p)
+#endif
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EB66)
+struct alpha_machine_vector eb66_mv __initmv = {
+       vector_name:            "EB66",
+       DO_EV4_MMU,
+       DO_DEFAULT_RTC,
+       DO_LCA_IO,
+       DO_LCA_BUS,
+       machine_check:          lca_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                32,
+       irq_probe_mask:         _PROBE_MASK(32),
+       update_irq_hw:          eb64p_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       eb64p_device_interrupt,
+
+       init_arch:              lca_init_arch,
+       init_irq:               eb64p_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              eb64p_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(eb66)
+#endif
diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c
new file mode 100644 (file)
index 0000000..8406661
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ *     linux/arch/alpha/kernel/sys_jensen.c
+ *
+ *     Copyright (C) 1995 Linus Torvalds
+ *     Copyright (C) 1998 Richard Henderson
+ *
+ * Code supporting the Jensen.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+
+#define __EXTERN_INLINE inline
+#include <asm/io.h>
+#include <asm/jensen.h>
+#undef  __EXTERN_INLINE
+
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+
+#include "proto.h"
+#include "irq.h"
+#include "machvec.h"
+
+
+static void
+jensen_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+       if (irq >= 8)
+               outb(mask >> 8, 0xA1);
+       else
+               outb(mask, 0x21);
+}
+
+/*
+ * Jensen is special: the vector is 0x8X0 for EISA interrupt X, and
+ * 0x9X0 for the local motherboard interrupts..
+ *
+ *     0x660 - NMI
+ *
+ *     0x800 - IRQ0  interval timer (not used, as we use the RTC timer)
+ *     0x810 - IRQ1  line printer (duh..)
+ *     0x860 - IRQ6  floppy disk
+ *     0x8E0 - IRQ14 SCSI controller
+ *
+ *     0x900 - COM1
+ *     0x920 - COM2
+ *     0x980 - keyboard
+ *     0x990 - mouse
+ *
+ * PCI-based systems are more sane: they don't have the local
+ * interrupts at all, and have only normal PCI interrupts from
+ * devices.  Happily it's easy enough to do a sane mapping from the
+ * Jensen..  Note that this means that we may have to do a hardware
+ * "ack" to a different interrupt than we report to the rest of the
+ * world.
+ */
+
+static void
+handle_nmi(struct pt_regs * regs)
+{
+       printk("Whee.. NMI received. Probable hardware error\n");
+       printk("61=%02x, 461=%02x\n", inb(0x61), inb(0x461));
+}
+
+static void 
+jensen_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+       int irq, ack;
+       unsigned long flags;
+
+       __save_and_cli(flags);
+       ack = irq = (vector - 0x800) >> 4;
+
+       switch (vector) {
+       case 0x660: handle_nmi(regs); return;
+
+       /* local device interrupts: */
+       case 0x900: irq = 4, ack = -1; break;           /* com1 -> irq 4 */
+       case 0x920: irq = 3, ack = -1; break;           /* com2 -> irq 3 */
+       case 0x980: irq = 1, ack = -1; break;           /* kbd -> irq 1 */
+       case 0x990: irq = 9, ack = -1; break;           /* mouse -> irq 9 */
+       default:
+               if (vector > 0x900) {
+                       printk("Unknown local interrupt %lx\n", vector);
+               }
+
+               /* irq1 is supposed to be the keyboard, silly Jensen
+                  (is this really needed??) */
+               if (irq == 1)
+                       irq = 7;
+               break;
+       }
+
+       handle_irq(irq, ack, regs);
+       __restore_flags(flags);
+}
+
+static void
+jensen_init_irq(void)
+{
+       STANDARD_INIT_IRQ_PROLOG;
+
+       enable_irq(2);                  /* enable cascade */
+}
+
+static void
+jensen_machine_check (u64 vector, u64 la, struct pt_regs *regs)
+{
+       printk(KERN_CRIT "Machine check\n");
+}
+
+
+/*
+ * The System Vector
+ */
+
+struct alpha_machine_vector jensen_mv __initmv = {
+       vector_name:            "Jensen",
+       DO_EV4_MMU,
+       IO_LITE(JENSEN,jensen,jensen),
+       BUS(jensen),
+       machine_check:          jensen_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                16,
+       irq_probe_mask:         _PROBE_MASK(16),
+       update_irq_hw:          jensen_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       jensen_device_interrupt,
+
+       init_arch:              NULL,
+       init_irq:               jensen_init_irq,
+       init_pit:               generic_init_pit,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(jensen)
diff --git a/arch/alpha/kernel/sys_miata.c b/arch/alpha/kernel/sys_miata.c
new file mode 100644 (file)
index 0000000..71ec1b2
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ *     linux/arch/alpha/kernel/sys_miata.c
+ *
+ *     Copyright (C) 1995 David A Rusling
+ *     Copyright (C) 1996 Jay A Estabrook
+ *     Copyright (C) 1998 Richard Henderson
+ *
+ * Code supporting the MIATA (EV56+PYXIS).
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/core_pyxis.h>
+
+#include "proto.h"
+#include "irq.h"
+#include "bios32.h"
+#include "machvec.h"
+
+
+static void 
+miata_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+       if (irq >= 16) {
+               /* Make CERTAIN none of the bogus ints get enabled... */
+               *(vulp)PYXIS_INT_MASK =
+                       ~((long)mask >> 16) & ~0x4000000000000e3bUL;
+               mb();
+               /* ... and read it back to make sure it got written.  */
+               *(vulp)PYXIS_INT_MASK;
+       }
+       else if (irq >= 8)
+               outb(mask >> 8, 0xA1);  /* ISA PIC2 */
+       else
+               outb(mask, 0x21);       /* ISA PIC1 */
+}
+
+static void 
+miata_device_interrupt(unsigned long vector, struct pt_regs *regs)
+{
+       unsigned long pld, tmp;
+       unsigned int i;
+       unsigned long flags;
+
+       save_and_cli(flags);
+
+       /* Read the interrupt summary register of PYXIS */
+       pld = *(vulp)PYXIS_INT_REQ;
+
+       /*
+        * For now, AND off any bits we are not interested in:
+        *   HALT (2), timer (6), ISA Bridge (7), 21142/3 (8)
+        * then all the PCI slots/INTXs (12-31).
+        */
+       /* Maybe HALT should only be used for SRM console boots? */
+       pld &= 0x00000000fffff1c4UL;
+
+       /*
+        * Now for every possible bit set, work through them and call
+        * the appropriate interrupt handler.
+        */
+       while (pld) {
+               i = ffz(~pld);
+               pld &= pld - 1; /* clear least bit set */
+               if (i == 7) {
+                       isa_device_interrupt(vector, regs);
+               } else if (i == 6) {
+                       continue;
+               } else {
+                       /* if not timer int */
+                       handle_irq(16 + i, 16 + i, regs);
+               }
+               *(vulp)PYXIS_INT_REQ = 1UL << i; mb();
+               tmp = *(vulp)PYXIS_INT_REQ;
+       }
+       restore_flags(flags);
+}
+
+static void 
+miata_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+       int irq, ack;
+       unsigned long flags;
+
+       __save_and_cli(flags);
+       ack = irq = (vector - 0x800) >> 4;
+
+       /*
+        * I really hate to do this, but the MIATA SRM console ignores the
+        *  low 8 bits in the interrupt summary register, and reports the
+        *  vector 0x80 *lower* than I expected from the bit numbering in
+        *  the documentation.
+        * This was done because the low 8 summary bits really aren't used
+        *  for reporting any interrupts (the PCI-ISA bridge, bit 7, isn't
+        *  used for this purpose, as PIC interrupts are delivered as the
+        *  vectors 0x800-0x8f0).
+        * But I really don't want to change the fixup code for allocation
+        *  of IRQs, nor the alpha_irq_mask maintenance stuff, both of which look
+        *  nice and clean now.
+        * So, here's this grotty hack... :-(
+        */
+       if (irq >= 16)
+               ack = irq = irq + 8;
+
+       handle_irq(irq, ack, regs);
+       __restore_flags(flags);
+}
+
+static void __init
+miata_init_irq(void)
+{
+       STANDARD_INIT_IRQ_PROLOG;
+
+       if (alpha_using_srm)
+               alpha_mv.device_interrupt = miata_srm_device_interrupt;
+
+       /* Note invert on MASK bits.  */
+       *(vulp)PYXIS_INT_MASK = ~((long)alpha_irq_mask >> 16); mb();
+#if 0
+       /* These break on MiataGL so we'll try not to do it at all.  */
+       *(vulp)PYXIS_INT_HILO = 0x000000B2UL; mb();     /* ISA/NMI HI */
+       *(vulp)PYXIS_RT_COUNT = 0UL; mb();              /* clear count */
+#endif
+       /* Clear upper timer.  */
+       *(vulp)PYXIS_INT_REQ  = 0x4000000000000000UL; mb();
+
+       enable_irq(16 + 2);     /* enable HALT switch - SRM only? */
+       enable_irq(16 + 6);     /* enable timer */
+       enable_irq(16 + 7);     /* enable ISA PIC cascade */
+       enable_irq(2);          /* enable cascade */
+}
+
+
+/*
+ * PCI Fixup configuration.
+ *
+ * Summary @ PYXIS_INT_REQ:
+ * Bit      Meaning
+ * 0        Fan Fault
+ * 1        NMI
+ * 2        Halt/Reset switch
+ * 3        none
+ * 4        CID0 (Riser ID)
+ * 5        CID1 (Riser ID)
+ * 6        Interval timer
+ * 7        PCI-ISA Bridge
+ * 8        Ethernet
+ * 9        EIDE (deprecated, ISA 14/15 used)
+ *10        none
+ *11        USB
+ *12        Interrupt Line A from slot 4
+ *13        Interrupt Line B from slot 4
+ *14        Interrupt Line C from slot 4
+ *15        Interrupt Line D from slot 4
+ *16        Interrupt Line A from slot 5
+ *17        Interrupt line B from slot 5
+ *18        Interrupt Line C from slot 5
+ *19        Interrupt Line D from slot 5
+ *20        Interrupt Line A from slot 1
+ *21        Interrupt Line B from slot 1
+ *22        Interrupt Line C from slot 1
+ *23        Interrupt Line D from slot 1
+ *24        Interrupt Line A from slot 2
+ *25        Interrupt Line B from slot 2
+ *26        Interrupt Line C from slot 2
+ *27        Interrupt Line D from slot 2
+ *27        Interrupt Line A from slot 3
+ *29        Interrupt Line B from slot 3
+ *30        Interrupt Line C from slot 3
+ *31        Interrupt Line D from slot 3
+ *
+ * The device to slot mapping looks like:
+ *
+ * Slot     Device
+ *  3       DC21142 Ethernet
+ *  4       EIDE CMD646
+ *  5       none
+ *  6       USB
+ *  7       PCI-ISA bridge
+ *  8       PCI-PCI Bridge      (SBU Riser)
+ *  9       none
+ * 10       none
+ * 11       PCI on board slot 4 (SBU Riser)
+ * 12       PCI on board slot 5 (SBU Riser)
+ *
+ *  These are behind the bridge, so I'm not sure what to do...
+ *
+ * 13       PCI on board slot 1 (SBU Riser)
+ * 14       PCI on board slot 2 (SBU Riser)
+ * 15       PCI on board slot 3 (SBU Riser)
+ *   
+ *
+ * This two layered interrupt approach means that we allocate IRQ 16 and 
+ * above for PCI interrupts.  The IRQ relates to which bit the interrupt
+ * comes in on.  This makes interrupt processing much easier.
+ */
+
+static int __init
+miata_map_irq(struct pci_dev *dev, int slot, int pin)
+{
+        static char irq_tab[18][5] __initlocaldata = {
+               /*INT    INTA   INTB   INTC   INTD */
+               {16+ 8, 16+ 8, 16+ 8, 16+ 8, 16+ 8},  /* IdSel 14,  DC21142 */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 15,  EIDE    */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 16,  none    */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 17,  none    */
+       /*      {16+11, 16+11, 16+11, 16+11, 16+11},*//* IdSel 17,  USB ??  */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 18,  PCI-ISA */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 19,  PCI-PCI */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 20,  none    */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 21,  none    */
+               {16+12, 16+12, 16+13, 16+14, 16+15},  /* IdSel 22,  slot 4  */
+               {16+16, 16+16, 16+17, 16+18, 16+19},  /* IdSel 23,  slot 5  */
+               /* The following are actually on bus 1, which is
+                  across the builtin PCI-PCI bridge.  */
+               {16+20, 16+20, 16+21, 16+22, 16+23},  /* IdSel 24,  slot 1  */
+               {16+24, 16+24, 16+25, 16+26, 16+27},  /* IdSel 25,  slot 2  */
+               {16+28, 16+28, 16+29, 16+30, 16+31},  /* IdSel 26,  slot 3  */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 27,  none    */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 28,  none    */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 29,  none    */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 30,  none    */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 31,  PCI-PCI */
+        };
+       const long min_idsel = 3, max_idsel = 20, irqs_per_slot = 5;
+       return COMMON_TABLE_LOOKUP;
+}
+
+static int __init
+miata_swizzle(struct pci_dev *dev, int *pinp)
+{
+       int slot, pin = *pinp;
+
+       /* Check first for the built-in bridge.  */
+       if ((PCI_SLOT(dev->bus->self->devfn) == 8) ||
+           (PCI_SLOT(dev->bus->self->devfn) == 20)) {
+               slot = PCI_SLOT(dev->devfn) + 5;
+       }
+       else 
+       {
+               /* Must be a card-based bridge.  */
+               do {
+                       if ((PCI_SLOT(dev->bus->self->devfn) == 8) ||
+                           (PCI_SLOT(dev->bus->self->devfn) == 20)) {
+                               slot = PCI_SLOT(dev->devfn) + 5;
+                               break;
+                       }
+                       pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+
+                       /* Move up the chain of bridges.  */
+                       dev = dev->bus->self;
+                       /* Slot of the next bridge.  */
+                       slot = PCI_SLOT(dev->devfn);
+               } while (dev->bus->self);
+       }
+       *pinp = pin;
+       return slot;
+}
+
+static void __init
+miata_pci_fixup(void)
+{
+       layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
+       common_pci_fixup(miata_map_irq, miata_swizzle);
+       SMC669_Init(); /* it might be a GL (fails harmlessly if not) */
+       es1888_init();
+}
+
+
+/*
+ * The System Vector
+ */
+
+struct alpha_machine_vector miata_mv __initmv = {
+       vector_name:            "Miata",
+       DO_EV5_MMU,
+       DO_DEFAULT_RTC,
+       DO_PYXIS_IO,
+       DO_PYXIS_BUS,
+       machine_check:          pyxis_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                48,
+       irq_probe_mask:         _PROBE_MASK(48),
+       update_irq_hw:          miata_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       miata_device_interrupt,
+
+       init_arch:              pyxis_init_arch,
+       init_irq:               miata_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              miata_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(miata)
diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c
new file mode 100644 (file)
index 0000000..92af5d3
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+ *     linux/arch/alpha/kernel/sys_mikasa.c
+ *
+ *     Copyright (C) 1995 David A Rusling
+ *     Copyright (C) 1996 Jay A Estabrook
+ *     Copyright (C) 1998 Richard Henderson
+ *
+ * Code supporting the MIKASA (AlphaServer 1000).
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/core_apecs.h>
+#include <asm/core_cia.h>
+
+#include "proto.h"
+#include "irq.h"
+#include "bios32.h"
+#include "machvec.h"
+
+static void
+mikasa_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+       if (irq >= 16)
+               outw(~(mask >> 16), 0x536); /* note invert */
+       else if (irq >= 8)
+               outb(mask >> 8, 0xA1);
+       else
+               outb(mask, 0x21);
+}
+
+static void 
+mikasa_device_interrupt(unsigned long vector, struct pt_regs *regs)
+{
+       unsigned long pld;
+       unsigned int i;
+       unsigned long flags;
+
+       save_and_cli(flags);
+
+       /* Read the interrupt summary registers */
+       pld = (((unsigned long) (~inw(0x534)) & 0x0000ffffUL) << 16) |
+               (((unsigned long) inb(0xa0))  <<  8) |
+               ((unsigned long) inb(0x20));
+
+       /*
+        * Now for every possible bit set, work through them and call
+        * the appropriate interrupt handler.
+        */
+       while (pld) {
+               i = ffz(~pld);
+               pld &= pld - 1; /* clear least bit set */
+               if (i < 16) {
+                       isa_device_interrupt(vector, regs);
+               } else {
+                       handle_irq(i, i, regs);
+               }
+       }
+       restore_flags(flags);
+}
+
+static void __init
+mikasa_init_irq(void)
+{
+       STANDARD_INIT_IRQ_PROLOG;
+
+       if (alpha_using_srm)
+               alpha_mv.device_interrupt = srm_device_interrupt;
+
+       outw(~(alpha_irq_mask >> 16), 0x536);   /* note invert */
+       enable_irq(2);                          /* enable cascade */
+}
+
+
+/*
+ * PCI Fixup configuration.
+ *
+ * Summary @ 0x536:
+ * Bit      Meaning
+ * 0        Interrupt Line A from slot 0
+ * 1        Interrupt Line B from slot 0
+ * 2        Interrupt Line C from slot 0
+ * 3        Interrupt Line D from slot 0
+ * 4        Interrupt Line A from slot 1
+ * 5        Interrupt line B from slot 1
+ * 6        Interrupt Line C from slot 1
+ * 7        Interrupt Line D from slot 1
+ * 8        Interrupt Line A from slot 2
+ * 9        Interrupt Line B from slot 2
+ *10        Interrupt Line C from slot 2
+ *11        Interrupt Line D from slot 2
+ *12        NCR 810 SCSI
+ *13        Power Supply Fail
+ *14        Temperature Warn
+ *15        Reserved
+ *
+ * The device to slot mapping looks like:
+ *
+ * Slot     Device
+ *  6       NCR SCSI controller
+ *  7       Intel PCI-EISA bridge chip
+ * 11       PCI on board slot 0
+ * 12       PCI on board slot 1
+ * 13       PCI on board slot 2
+ *   
+ *
+ * This two layered interrupt approach means that we allocate IRQ 16 and 
+ * above for PCI interrupts.  The IRQ relates to which bit the interrupt
+ * comes in on.  This makes interrupt processing much easier.
+ */
+
+static int __init
+mikasa_map_irq(struct pci_dev *dev, int slot, int pin)
+{
+       static char irq_tab[8][5] __initlocaldata = {
+               /*INT    INTA   INTB   INTC   INTD */
+               {16+12, 16+12, 16+12, 16+12, 16+12},    /* IdSel 17,  SCSI */
+               {   -1,    -1,    -1,    -1,    -1},    /* IdSel 18,  PCEB */
+               {   -1,    -1,    -1,    -1,    -1},    /* IdSel 19,  ???? */
+               {   -1,    -1,    -1,    -1,    -1},    /* IdSel 20,  ???? */
+               {   -1,    -1,    -1,    -1,    -1},    /* IdSel 21,  ???? */
+               { 16+0,  16+0,  16+1,  16+2,  16+3},    /* IdSel 22,  slot 0 */
+               { 16+4,  16+4,  16+5,  16+6,  16+7},    /* IdSel 23,  slot 1 */
+               { 16+8,  16+8,  16+9, 16+10, 16+11},    /* IdSel 24,  slot 2 */
+       };
+       const long min_idsel = 6, max_idsel = 13, irqs_per_slot = 5;
+       return COMMON_TABLE_LOOKUP;
+}
+
+static void __init
+mikasa_pci_fixup(void)
+{
+       layout_all_busses(EISA_DEFAULT_IO_BASE,APECS_AND_LCA_DEFAULT_MEM_BASE);
+       common_pci_fixup(mikasa_map_irq, common_swizzle);
+}
+
+static void __init
+mikasa_primo_pci_fixup(void)
+{
+       layout_all_busses(EISA_DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
+       common_pci_fixup(mikasa_map_irq, common_swizzle);
+}
+
+static void
+mikasa_machine_check(unsigned long vector, unsigned long la_ptr,
+                    struct pt_regs * regs)
+{
+#define MCHK_NO_DEVSEL 0x205L
+#define MCHK_NO_TABT 0x204L
+
+       struct el_common *mchk_header;
+       struct el_apecs_procdata *mchk_procdata;
+       struct el_apecs_mikasa_sysdata_mcheck *mchk_sysdata;
+       unsigned long *ptr;
+       int i;
+
+       mchk_header = (struct el_common *)la_ptr;
+
+       mchk_procdata = (struct el_apecs_procdata *)
+               (la_ptr + mchk_header->proc_offset
+                - sizeof(mchk_procdata->paltemp));
+
+       mchk_sysdata = (struct el_apecs_mikasa_sysdata_mcheck *)
+               (la_ptr + mchk_header->sys_offset);
+
+#ifdef DEBUG
+       printk("mikasa_machine_check: vector=0x%lx la_ptr=0x%lx\n",
+              vector, la_ptr);
+       printk("        pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
+              regs->pc, mchk_header->size, mchk_header->proc_offset,
+              mchk_header->sys_offset);
+       printk("mikasa_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
+              apecs_mcheck_expected, mchk_sysdata->epic_dcsr,
+              mchk_sysdata->epic_pear);
+       ptr = (unsigned long *)la_ptr;
+       for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
+               printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
+       }
+#endif
+
+       /*
+        * Check if machine check is due to a badaddr() and if so,
+        * ignore the machine check.
+        */
+
+       if (apecs_mcheck_expected
+           && ((unsigned int)mchk_header->code == MCHK_NO_DEVSEL
+               || (unsigned int)mchk_header->code == MCHK_NO_TABT)) {
+               apecs_mcheck_expected = 0;
+               apecs_mcheck_taken = 1;
+               mb();
+               mb(); /* magic */
+               apecs_pci_clr_err();
+               wrmces(0x7);
+               mb();
+               draina();
+       }
+       else if (vector == 0x620 || vector == 0x630) {
+               /* Disable correctable from now on.  */
+               wrmces(0x1f);
+               mb();
+               draina();
+               printk("mikasa_machine_check: HW correctable (0x%lx)\n",
+                      vector);
+       }
+       else {
+               printk(KERN_CRIT "APECS machine check:\n");
+               printk(KERN_CRIT "  vector=0x%lx la_ptr=0x%lx\n",
+                      vector, la_ptr);
+               printk(KERN_CRIT
+                      "  pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
+                      regs->pc, mchk_header->size, mchk_header->proc_offset,
+                      mchk_header->sys_offset);
+               printk(KERN_CRIT "  expected %d DCSR 0x%lx PEAR 0x%lx\n",
+                      apecs_mcheck_expected, mchk_sysdata->epic_dcsr,
+                      mchk_sysdata->epic_pear);
+
+               ptr = (unsigned long *)la_ptr;
+               for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
+                       printk(KERN_CRIT " +%lx %lx %lx\n",
+                              i*sizeof(long), ptr[i], ptr[i+1]);
+               }
+#if 0
+               /* doesn't work with MILO */
+               show_regs(regs);
+#endif
+       }
+}
+
+
+/*
+ * The System Vector
+ */
+
+#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
+struct alpha_machine_vector mikasa_mv __initmv = {
+       vector_name:            "Mikasa",
+       DO_EV4_MMU,
+       DO_DEFAULT_RTC,
+       DO_APECS_IO,
+       DO_APECS_BUS,
+       machine_check:          mikasa_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                32,
+       irq_probe_mask:         _PROBE_MASK(32),
+       update_irq_hw:          mikasa_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       mikasa_device_interrupt,
+
+       init_arch:              apecs_init_arch,
+       init_irq:               mikasa_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              mikasa_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(mikasa)
+#endif
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_PRIMO)
+struct alpha_machine_vector mikasa_primo_mv __initmv = {
+       vector_name:            "Mikasa-Primo",
+       DO_EV5_MMU,
+       DO_DEFAULT_RTC,
+       DO_CIA_IO,
+       DO_CIA_BUS,
+       machine_check:          mikasa_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                32,
+       irq_probe_mask:         _PROBE_MASK(32),
+       update_irq_hw:          mikasa_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       mikasa_device_interrupt,
+
+       init_arch:              cia_init_arch,
+       init_irq:               mikasa_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              mikasa_primo_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(mikasa_primo)
+#endif
diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c
new file mode 100644 (file)
index 0000000..c8901ae
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ *     linux/arch/alpha/kernel/sys_noritake.c
+ *
+ *     Copyright (C) 1995 David A Rusling
+ *     Copyright (C) 1996 Jay A Estabrook
+ *     Copyright (C) 1998 Richard Henderson
+ *
+ * Code supporting the NORITAKE (AlphaServer 1000A), 
+ * CORELLE (AlphaServer 800), and ALCOR Primo (AlphaStation 600A).
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/core_apecs.h>
+#include <asm/core_cia.h>
+
+#include "proto.h"
+#include "irq.h"
+#include "bios32.h"
+#include "machvec.h"
+
+
+static void 
+noritake_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+       if (irq <= 15)
+               if (irq <= 7)
+                       outb(mask, 0x21);       /* ISA PIC1 */
+               else
+                       outb(mask >> 8, 0xA1);  /* ISA PIC2 */
+       else if (irq <= 31)
+               outw(~(mask >> 16), 0x54a);
+       else
+               outw(~(mask >> 32), 0x54c);
+}
+
+static void 
+noritake_device_interrupt(unsigned long vector, struct pt_regs *regs)
+{
+       unsigned long pld;
+       unsigned int i;
+       unsigned long flags;
+
+       save_and_cli(flags);
+
+       /* Read the interrupt summary registers of NORITAKE */
+       pld = ((unsigned long) inw(0x54c) << 32) |
+               ((unsigned long) inw(0x54a) << 16) |
+               ((unsigned long) inb(0xa0)  <<  8) |
+               ((unsigned long) inb(0x20));
+
+       /*
+        * Now for every possible bit set, work through them and call
+        * the appropriate interrupt handler.
+        */
+       while (pld) {
+               i = ffz(~pld);
+               pld &= pld - 1; /* clear least bit set */
+               if (i < 16) {
+                       isa_device_interrupt(vector, regs);
+               } else {
+                       handle_irq(i, i, regs);
+               }
+       }
+       restore_flags(flags);
+}
+
+static void 
+noritake_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+       int irq, ack;
+       unsigned long flags;
+
+       __save_and_cli(flags);
+       ack = irq = (vector - 0x800) >> 4;
+
+       /*
+        * I really hate to do this, too, but the NORITAKE SRM console also
+        *  reports PCI vectors *lower* than I expected from the bit numbers
+        *  in the documentation.
+        * But I really don't want to change the fixup code for allocation
+        *  of IRQs, nor the alpha_irq_mask maintenance stuff, both of which
+        *  look nice and clean now.
+        * So, here's this additional grotty hack... :-(
+        */
+       if (irq >= 16)
+               ack = irq = irq + 1;
+
+       handle_irq(irq, ack, regs);
+       __restore_flags(flags);
+}
+
+static void __init
+noritake_init_irq(void)
+{
+       STANDARD_INIT_IRQ_PROLOG;
+
+       if (alpha_using_srm)
+               alpha_mv.device_interrupt = noritake_srm_device_interrupt;
+
+       outw(~(alpha_irq_mask >> 16), 0x54a); /* note invert */
+       outw(~(alpha_irq_mask >> 32), 0x54c); /* note invert */
+       enable_irq(2);                  /* enable cascade */
+}
+
+
+/*
+ * PCI Fixup configuration.
+ *
+ * Summary @ 0x542, summary register #1:
+ * Bit      Meaning
+ * 0        All valid ints from summary regs 2 & 3
+ * 1        QLOGIC ISP1020A SCSI
+ * 2        Interrupt Line A from slot 0
+ * 3        Interrupt Line B from slot 0
+ * 4        Interrupt Line A from slot 1
+ * 5        Interrupt line B from slot 1
+ * 6        Interrupt Line A from slot 2
+ * 7        Interrupt Line B from slot 2
+ * 8        Interrupt Line A from slot 3
+ * 9        Interrupt Line B from slot 3
+ *10        Interrupt Line A from slot 4
+ *11        Interrupt Line B from slot 4
+ *12        Interrupt Line A from slot 5
+ *13        Interrupt Line B from slot 5
+ *14        Interrupt Line A from slot 6
+ *15        Interrupt Line B from slot 6
+ *
+ * Summary @ 0x544, summary register #2:
+ * Bit      Meaning
+ * 0        OR of all unmasked ints in SR #2
+ * 1        OR of secondary bus ints
+ * 2        Interrupt Line C from slot 0
+ * 3        Interrupt Line D from slot 0
+ * 4        Interrupt Line C from slot 1
+ * 5        Interrupt line D from slot 1
+ * 6        Interrupt Line C from slot 2
+ * 7        Interrupt Line D from slot 2
+ * 8        Interrupt Line C from slot 3
+ * 9        Interrupt Line D from slot 3
+ *10        Interrupt Line C from slot 4
+ *11        Interrupt Line D from slot 4
+ *12        Interrupt Line C from slot 5
+ *13        Interrupt Line D from slot 5
+ *14        Interrupt Line C from slot 6
+ *15        Interrupt Line D from slot 6
+ *
+ * The device to slot mapping looks like:
+ *
+ * Slot     Device
+ *  7       Intel PCI-EISA bridge chip
+ *  8       DEC PCI-PCI bridge chip
+ * 11       PCI on board slot 0
+ * 12       PCI on board slot 1
+ * 13       PCI on board slot 2
+ *   
+ *
+ * This two layered interrupt approach means that we allocate IRQ 16 and 
+ * above for PCI interrupts.  The IRQ relates to which bit the interrupt
+ * comes in on.  This makes interrupt processing much easier.
+ */
+
+static int __init
+noritake_map_irq(struct pci_dev *dev, int slot, int pin)
+{
+       static char irq_tab[15][5] __initlocaldata = {
+               /*INT    INTA   INTB   INTC   INTD */
+               /* note: IDSELs 16, 17, and 25 are CORELLE only */
+               { 16+1,  16+1,  16+1,  16+1,  16+1},  /* IdSel 16,  QLOGIC */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 17, S3 Trio64 */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 18,  PCEB */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 19,  PPB  */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 20,  ???? */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 21,  ???? */
+               { 16+2,  16+2,  16+3,  32+2,  32+3},  /* IdSel 22,  slot 0 */
+               { 16+4,  16+4,  16+5,  32+4,  32+5},  /* IdSel 23,  slot 1 */
+               { 16+6,  16+6,  16+7,  32+6,  32+7},  /* IdSel 24,  slot 2 */
+               { 16+8,  16+8,  16+9,  32+8,  32+9},    /* IdSel 25,  slot 3 */
+               /* The following 5 are actually on PCI bus 1, which is 
+                  across the built-in bridge of the NORITAKE only.  */
+               { 16+1,  16+1,  16+1,  16+1,  16+1},  /* IdSel 16,  QLOGIC */
+               { 16+8,  16+8,  16+9,  32+8,  32+9},  /* IdSel 17,  slot 3 */
+               {16+10, 16+10, 16+11, 32+10, 32+11},  /* IdSel 18,  slot 4 */
+               {16+12, 16+12, 16+13, 32+12, 32+13},  /* IdSel 19,  slot 5 */
+               {16+14, 16+14, 16+15, 32+14, 32+15},  /* IdSel 20,  slot 6 */
+       };
+       const long min_idsel = 5, max_idsel = 19, irqs_per_slot = 5;
+       return COMMON_TABLE_LOOKUP;
+}
+
+static int __init
+noritake_swizzle(struct pci_dev *dev, int *pinp)
+{
+       int slot, pin = *pinp;
+
+       /* Check first for the built-in bridge */
+       if (PCI_SLOT(dev->bus->self->devfn) == 8) {
+               slot = PCI_SLOT(dev->devfn) + 15; /* WAG! */
+       }
+       else
+       {
+               /* Must be a card-based bridge.  */
+               do {
+                       if (PCI_SLOT(dev->bus->self->devfn) == 8) {
+                               slot = PCI_SLOT(dev->devfn) + 15;
+                               break;
+                       }
+                       pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)) ;
+
+                       /* Move up the chain of bridges.  */
+                       dev = dev->bus->self;
+                       /* Slot of the next bridge.  */
+                       slot = PCI_SLOT(dev->devfn);
+               } while (dev->bus->self);
+       }
+       *pinp = pin;
+       return slot;
+}
+
+static void __init
+noritake_pci_fixup(void)
+{
+       layout_all_busses(EISA_DEFAULT_IO_BASE,APECS_AND_LCA_DEFAULT_MEM_BASE);
+       common_pci_fixup(noritake_map_irq, noritake_swizzle);
+}
+
+static void __init
+noritake_primo_pci_fixup(void)
+{
+       layout_all_busses(EISA_DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
+       common_pci_fixup(noritake_map_irq, noritake_swizzle);
+}
+
+
+/*
+ * The System Vectors
+ */
+
+#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
+struct alpha_machine_vector noritake_mv __initmv = {
+       vector_name:            "Noritake",
+       DO_EV4_MMU,
+       DO_DEFAULT_RTC,
+       DO_APECS_IO,
+       DO_APECS_BUS,
+       machine_check:          apecs_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                48,
+       irq_probe_mask:         _PROBE_MASK(48),
+       update_irq_hw:          noritake_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       noritake_device_interrupt,
+
+       init_arch:              apecs_init_arch,
+       init_irq:               noritake_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              noritake_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(noritake)
+#endif
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_PRIMO)
+struct alpha_machine_vector noritake_primo_mv __initmv = {
+       vector_name:            "Noritake-Primo",
+       DO_EV5_MMU,
+       DO_DEFAULT_RTC,
+       DO_CIA_IO,
+       DO_CIA_BUS,
+       machine_check:          cia_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                48,
+       irq_probe_mask:         _PROBE_MASK(48),
+       update_irq_hw:          noritake_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       noritake_device_interrupt,
+
+       init_arch:              cia_init_arch,
+       init_irq:               noritake_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              noritake_primo_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(noritake_primo)
+#endif
diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c
new file mode 100644 (file)
index 0000000..0885a23
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ *     linux/arch/alpha/kernel/sys_rawhide.c
+ *
+ *     Copyright (C) 1995 David A Rusling
+ *     Copyright (C) 1996 Jay A Estabrook
+ *     Copyright (C) 1998 Richard Henderson
+ *
+ * Code supporting the RAWHIDE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/pci.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/core_mcpcia.h>
+
+#include "proto.h"
+#include "irq.h"
+#include "bios32.h"
+#include "machvec.h"
+
+
+static void
+rawhide_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+       if (irq >= 40) {
+               /* PCI bus 1 with builtin NCR810 SCSI */
+               *(vuip)MCPCIA_INT_MASK0(1) =
+                       (~((mask) >> 40) & 0x00ffffffU) | 0x00fe0000U;
+               mb();
+               /* ... and read it back to make sure it got written.  */
+               *(vuip)MCPCIA_INT_MASK0(1);
+       }
+       else if (irq >= 16) {
+               /* PCI bus 0 with EISA bridge */
+               *(vuip)MCPCIA_INT_MASK0(0) =
+                       (~((mask) >> 16) & 0x00ffffffU) | 0x00ff0000U;
+               mb();
+               /* ... and read it back to make sure it got written.  */
+               *(vuip)MCPCIA_INT_MASK0(0);
+       }
+       else if (irq >= 8)
+               outb(mask >> 8, 0xA1);  /* ISA PIC2 */
+       else
+               outb(mask, 0x21);       /* ISA PIC1 */
+}
+
+static void 
+rawhide_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+       int irq, ack;
+       unsigned long flags;
+
+       __save_and_cli(flags);
+       ack = irq = (vector - 0x800) >> 4;
+
+        /*
+         * The RAWHIDE SRM console reports PCI interrupts with a vector
+        * 0x80 *higher* than one might expect, as PCI IRQ 0 (ie bit 0)
+        * shows up as IRQ 24, etc, etc. We adjust it down by 8 to have
+        * it line up with the actual bit numbers from the REQ registers,
+        * which is how we manage the interrupts/mask. Sigh...
+        *
+        * also, PCI #1 interrupts are offset some more... :-(
+         */
+       if (irq == 52)
+               ack = irq = 56; /* SCSI on PCI 1 is special */
+       else {
+               if (irq >= 24) /* adjust all PCI interrupts down 8 */
+                       ack = irq = irq - 8;
+               if (irq >= 48) /* adjust PCI bus 1 interrupts down another 8 */
+                       ack = irq = irq - 8;
+       }
+
+       handle_irq(irq, ack, regs);
+       __restore_flags(flags);
+}
+
+static void __init
+rawhide_init_irq(void)
+{
+       STANDARD_INIT_IRQ_PROLOG;
+
+       /* HACK ALERT! only PCI busses 0 and 1 are used currently,
+          and routing is only to CPU #1*/
+
+       *(vuip)MCPCIA_INT_MASK0(0) =
+               (~((alpha_irq_mask) >> 16) & 0x00ffffffU) | 0x00ff0000U; mb();
+       /* ... and read it back to make sure it got written.  */
+       *(vuip)MCPCIA_INT_MASK0(0);
+
+       *(vuip)MCPCIA_INT_MASK0(1) =
+               (~((alpha_irq_mask) >> 40) & 0x00ffffffU) | 0x00fe0000U; mb();
+       /* ... and read it back to make sure it got written.  */
+       *(vuip)MCPCIA_INT_MASK0(1);
+
+       enable_irq(2);
+}
+
+/*
+ * PCI Fixup configuration.
+ *
+ * Summary @ MCPCIA_PCI0_INT_REQ:
+ * Bit      Meaning
+ * 0        Interrupt Line A from slot 2 PCI0
+ * 1        Interrupt Line B from slot 2 PCI0
+ * 2        Interrupt Line C from slot 2 PCI0
+ * 3        Interrupt Line D from slot 2 PCI0
+ * 4        Interrupt Line A from slot 3 PCI0
+ * 5        Interrupt Line B from slot 3 PCI0
+ * 6        Interrupt Line C from slot 3 PCI0
+ * 7        Interrupt Line D from slot 3 PCI0
+ * 8        Interrupt Line A from slot 4 PCI0
+ * 9        Interrupt Line B from slot 4 PCI0
+ * 10       Interrupt Line C from slot 4 PCI0
+ * 11       Interrupt Line D from slot 4 PCI0
+ * 12       Interrupt Line A from slot 5 PCI0
+ * 13       Interrupt Line B from slot 5 PCI0
+ * 14       Interrupt Line C from slot 5 PCI0
+ * 15       Interrupt Line D from slot 5 PCI0
+ * 16       EISA interrupt (PCI 0) or SCSI interrupt (PCI 1)
+ * 17-23    NA
+ *
+ * IdSel       
+ *   1  EISA bridge (PCI bus 0 only)
+ *   2          PCI option slot 2
+ *   3  PCI option slot 3
+ *   4   PCI option slot 4
+ *   5   PCI option slot 5
+ * 
+ */
+
+static int __init
+rawhide_map_irq(struct pci_dev *dev, int slot, int pin)
+{
+       static char irq_tab[5][5] __initlocaldata = {
+               /*INT    INTA   INTB   INTC   INTD */
+               { 16+16, 16+16, 16+16, 16+16, 16+16}, /* IdSel 1 SCSI PCI 1 */
+               { 16+ 0, 16+ 0, 16+ 1, 16+ 2, 16+ 3}, /* IdSel 2 slot 2 */
+               { 16+ 4, 16+ 4, 16+ 5, 16+ 6, 16+ 7}, /* IdSel 3 slot 3 */
+               { 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11}, /* IdSel 4 slot 4 */
+               { 16+12, 16+12, 16+13, 16+14, 16+15}  /* IdSel 5 slot 5 */
+       };
+       const long min_idsel = 1, max_idsel = 5, irqs_per_slot = 5;
+       int irq = COMMON_TABLE_LOOKUP;
+       if (irq >= 0)
+               irq += 24 * bus2hose[dev->bus->number]->pci_hose_index;
+       return irq;
+}
+
+static void __init
+rawhide_pci_fixup(void)
+{
+       mcpcia_pci_fixup();
+       common_pci_fixup(rawhide_map_irq, common_swizzle);
+}
+
+
+/*
+ * The System Vector
+ */
+
+struct alpha_machine_vector rawhide_mv __initmv = {
+       vector_name:            "Rawhide",
+       DO_EV5_MMU,
+       DO_DEFAULT_RTC,
+       DO_MCPCIA_IO,
+       DO_MCPCIA_BUS,
+       machine_check:          mcpcia_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                64,
+       irq_probe_mask:         _PROBE_MASK(64),
+       update_irq_hw:          rawhide_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       rawhide_srm_device_interrupt,
+
+       init_arch:              mcpcia_init_arch,
+       init_irq:               rawhide_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              rawhide_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(rawhide)
diff --git a/arch/alpha/kernel/sys_ruffian.c b/arch/alpha/kernel/sys_ruffian.c
new file mode 100644 (file)
index 0000000..9d32bcb
--- /dev/null
@@ -0,0 +1,267 @@
+/*
+ *     linux/arch/alpha/kernel/sys_ruffian.c
+ *
+ *     Copyright (C) 1995 David A Rusling
+ *     Copyright (C) 1996 Jay A Estabrook
+ *     Copyright (C) 1998 Richard Henderson
+ *
+ * Code supporting the RUFFIAN.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/core_pyxis.h>
+
+#include "proto.h"
+#include "irq.h"
+#include "bios32.h"
+#include "machvec.h"
+
+
+static void
+ruffian_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+       if (irq >= 16) {
+               /* Note inverted sense of mask bits: */
+               /* Make CERTAIN none of the bogus ints get enabled... */
+               *(vulp)PYXIS_INT_MASK =
+                       ~((long)mask >> 16) & 0x00000000ffffffbfUL;
+               mb();
+               /* ... and read it back to make sure it got written.  */
+               *(vulp)PYXIS_INT_MASK;
+       }
+       else if (irq >= 8)
+               outb(mask >> 8, 0xA1);  /* ISA PIC2 */
+       else
+               outb(mask, 0x21);       /* ISA PIC1 */
+}
+
+static void
+ruffian_ack_irq(unsigned long irq)
+{
+       if (irq < 16) {
+               /* Ack PYXIS ISA interrupt.  */
+               *(vulp)PYXIS_INT_REQ = 1L << 7; mb();
+               /* ... and read it back to make sure it got written.  */
+               *(vulp)PYXIS_INT_REQ;
+               if (irq > 7) {
+                       outb(0x20, 0xa0);
+               }
+               outb(0x20, 0x20);
+       } else {
+               /* Ack PYXIS PCI interrupt.  */
+               *(vulp)PYXIS_INT_REQ = (1UL << (irq - 16));
+               /* ... and read it back to make sure it got written.  */
+               *(vulp)PYXIS_INT_REQ;
+       }
+}
+
+static void
+ruffian_device_interrupt(unsigned long vector, struct pt_regs *regs)
+{
+       unsigned long pld;
+       unsigned int i;
+       unsigned long flags;
+
+        save_and_cli(flags);
+
+       /* Read the interrupt summary register of PYXIS */
+       pld = *(vulp)PYXIS_INT_REQ;
+
+       /* For now, AND off any bits we are not interested in:
+        * HALT (2), timer (6), ISA Bridge (7), 21142 (8)
+        * then all the PCI slots/INTXs (12-31) 
+        * flash(5) :DWH:
+        */
+        pld &= 0x00000000ffffff9fUL; /* was ffff7f */
+
+       /*
+        * Now for every possible bit set, work through them and call
+        * the appropriate interrupt handler.
+        */
+       while (pld) {
+               i = ffz(~pld);
+               pld &= pld - 1; /* clear least bit set */
+               if (i == 7) {
+                       /* Copy this bit from isa_device_interrupt cause
+                          we need to hook into int 0 for the timer.  I
+                          refuse to soil device_interrupt with ifdefs.  */
+
+                       /* Generate a PCI interrupt acknowledge cycle.
+                          The PIC will respond with the interrupt
+                          vector of the highest priority interrupt
+                          that is pending.  The PALcode sets up the
+                          interrupts vectors such that irq level L
+                          generates vector L.  */
+
+                       unsigned int j = *(vuip)PYXIS_IACK_SC & 0xff;
+                       if (j == 7 && !(inb(0x20) & 0x80)) {
+                               /* It's only a passive release... */
+                       } else if (j == 0) {
+                               timer_interrupt(regs);
+                               ruffian_ack_irq(0);
+                       } else {
+                               handle_irq(j, j, regs);
+                       }
+                } else {
+                       /* if not timer int */
+                       handle_irq(16 + i, 16 + i, regs);
+               }
+
+                *(vulp)PYXIS_INT_REQ = 1UL << i; mb();
+                *(vulp)PYXIS_INT_REQ; /* read to force the write */
+       }
+       restore_flags(flags);
+}
+
+static void __init
+ruffian_init_irq(void)
+{
+       STANDARD_INIT_IRQ_PROLOG;
+
+       /* Invert 6&7 for i82371 */
+       *(vulp)PYXIS_INT_HILO  = 0x000000c0UL; mb();
+       *(vulp)PYXIS_INT_CNFG  = 0x00002064UL; mb();     /* all clear */
+       *(vulp)PYXIS_INT_MASK  = 0x00000000UL; mb();
+       *(vulp)PYXIS_INT_REQ   = 0xffffffffUL; mb();
+
+       outb(0x11,0xA0);
+       outb(0x08,0xA1);
+       outb(0x02,0xA1);
+       outb(0x01,0xA1);
+       outb(0xFF,0xA1);
+       
+       outb(0x11,0x20);
+       outb(0x00,0x21);
+       outb(0x04,0x21);
+       outb(0x01,0x21);
+       outb(0xFF,0x21);
+       
+       /* Send -INTA pulses to clear any pending interrupts ...*/
+       *(vuip) PYXIS_IACK_SC;
+
+       /* Finish writing the 82C59A PIC Operation Control Words */
+       outb(0x20,0xA0);
+       outb(0x20,0x20);
+       
+       /* Turn on the interrupt controller, the timer interrupt  */
+       enable_irq(16 + 7);     /* enable ISA PIC cascade */
+       enable_irq(0);          /* enable timer */
+       enable_irq(2);          /* enable 2nd PIC cascade */
+}
+
+
+/*
+ * For RUFFIAN, we do not want to make any modifications to the PCI
+ * setup.  So just scan the busses.
+ */
+
+static void __init
+ruffian_pci_fixup(void)
+{
+       layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
+}
+
+
+/*
+ * The DeskStation Ruffian motherboard firmware does not place
+ * the memory size in the PALimpure area.  Therefore, we use
+ * the Bank Configuration Registers in PYXIS to obtain the size.
+ */
+static unsigned long __init
+ruffian_get_bank_size(unsigned long offset)
+{
+       unsigned long bank_addr, bank, ret = 0;
+  
+       /* Valid offsets are: 0x800, 0x840 and 0x880
+          since Ruffian only uses three banks.  */
+       bank_addr = (unsigned long)PYXIS_MCR + offset;
+       bank = *(vulp)bank_addr;
+    
+       /* Check BANK_ENABLE */
+       if (bank & 0x01) {
+               static unsigned long size[] __initdata = {
+                       0x40000000UL, /* 0x00,   1G */ 
+                       0x20000000UL, /* 0x02, 512M */
+                       0x10000000UL, /* 0x04, 256M */
+                       0x08000000UL, /* 0x06, 128M */
+                       0x04000000UL, /* 0x08,  64M */
+                       0x02000000UL, /* 0x0a,  32M */
+                       0x01000000UL, /* 0x0c,  16M */
+                       0x00800000UL, /* 0x0e,   8M */
+                       0x80000000UL, /* 0x10,   2G */
+               };
+
+               bank = (bank & 0x1e) >> 1;
+               if (bank < sizeof(size)/sizeof(*size))
+                       ret = size[bank];
+       }
+
+       return ret;
+}
+
+static void __init
+ruffian_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+{
+       /* FIXME: What do we do with ruffian_get_bank_size above?  */
+
+       pyxis_enable_errors();
+       if (!pyxis_srm_window_setup()) {
+               printk("ruffian_init_arch: Skipping window register rewrites."
+                      "\n... Trust DeskStation firmware!\n");
+       }
+       pyxis_finish_init_arch();
+}
+
+
+static void
+ruffian_init_pit (void)
+{
+       /* Ruffian depends on the system timer established in MILO! */
+       request_region(0x70, 0x10, "timer");
+       init_pit_rest();
+}
+
+
+/*
+ * The System Vector
+ */
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_RUFFIAN)
+struct alpha_machine_vector ruffian_mv __initmv = {
+       vector_name:            "Ruffian",
+       DO_EV5_MMU,
+       DO_DEFAULT_RTC,
+       DO_PYXIS_IO,
+       DO_PYXIS_BUS,
+       machine_check:          pyxis_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                48,
+       irq_probe_mask:         RUFFIAN_PROBE_MASK,
+       update_irq_hw:          ruffian_update_irq_hw,
+       ack_irq:                ruffian_ack_irq,
+       device_interrupt:       ruffian_device_interrupt,
+
+       init_arch:              ruffian_init_arch,
+       init_irq:               ruffian_init_irq,
+       init_pit:               ruffian_init_pit,
+       pci_fixup:              ruffian_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(ruffian)
+#endif
diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c
new file mode 100644 (file)
index 0000000..42a1f9c
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+ *     linux/arch/alpha/kernel/sys_sable.c
+ *
+ *     Copyright (C) 1995 David A Rusling
+ *     Copyright (C) 1996 Jay A Estabrook
+ *     Copyright (C) 1998 Richard Henderson
+ *
+ * Code supporting the Sable and Sable-Gamma systems.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/core_t2.h>
+
+#include "proto.h"
+#include "irq.h"
+#include "bios32.h"
+#include "machvec.h"
+
+
+/*
+ *   For SABLE, which is really baroque, we manage 40 IRQ's, but the
+ *   hardware really only supports 24, not via normal ISA PIC,
+ *   but cascaded custom 8259's, etc.
+ *      0-7  (char at 536)
+ *      8-15 (char at 53a)
+ *     16-23 (char at 53c)
+ */
+
+/* Note that the vector reported by the SRM PALcode corresponds to the
+   interrupt mask bits, but we have to manage via more normal IRQs.  */
+
+static struct 
+{
+       char irq_to_mask[40];
+       char mask_to_irq[40];
+       unsigned long shadow_mask;
+} sable_irq_swizzle = {
+       {
+               -1,  6, -1,  8, 15, 12,  7,  9, /* pseudo PIC  0-7  */
+               -1, 16, 17, 18,  3, -1, 21, 22, /* pseudo PIC  8-15 */
+               -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo EISA 0-7  */
+               -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo EISA 8-15 */
+               2,  1,  0,  4,  5, -1, -1, -1,  /* pseudo PCI */
+       },
+       {
+               34, 33, 32, 12, 35, 36,  1,  6, /* mask 0-7  */
+               3,  7, -1, -1,  5, -1, -1,  4,  /* mask 8-15  */
+               9, 10, 11, -1, -1, 14, 15, -1,  /* mask 16-23  */
+       },
+       0
+};
+
+
+static void 
+sable_update_irq_hw(unsigned long irq, unsigned long unused_mask, int unmask_p)
+{
+       unsigned long bit, mask;
+
+       /* The "irq" argument is really the irq, but we need it to
+          be the mask bit number.  Convert it now.  */
+
+       irq = sable_irq_swizzle.irq_to_mask[irq];
+       bit = 1UL << irq;
+       mask = sable_irq_swizzle.shadow_mask | bit;
+       if (unmask_p)
+               mask &= ~bit;
+       sable_irq_swizzle.shadow_mask = mask;
+
+       /* The "irq" argument is now really the mask bit number.  */
+       if (irq <= 7)
+               outb(mask, 0x537);
+       else if (irq <= 15)
+               outb(mask >> 8, 0x53b);
+       else
+               outb(mask >> 16, 0x53d);
+}
+
+static void
+sable_ack_irq(unsigned long irq)
+{
+       /* Note that the "irq" here is really the mask bit number */
+       switch (irq) {
+       case 0 ... 7:
+               outb(0xE0 | (irq - 0), 0x536);
+               outb(0xE0 | 1, 0x534); /* slave 0 */
+               break;
+       case 8 ... 15:
+               outb(0xE0 | (irq - 8), 0x53a);
+               outb(0xE0 | 3, 0x534); /* slave 1 */
+               break;
+       case 16 ... 24:
+               outb(0xE0 | (irq - 16), 0x53c);
+               outb(0xE0 | 4, 0x534); /* slave 2 */
+               break;
+       }
+}
+
+static void 
+sable_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+       /* Note that the vector reported by the SRM PALcode corresponds
+          to the interrupt mask bits, but we have to manage via more
+          normal IRQs.  */
+
+       int irq, ack;
+       unsigned long flags;
+
+       __save_and_cli(flags);
+       ack = irq = (vector - 0x800) >> 4;
+
+       irq = sable_irq_swizzle.mask_to_irq[(ack)];
+#if 0
+       if (irq == 5 || irq == 9 || irq == 10 || irq == 11 ||
+           irq == 14 || irq == 15)
+               printk("srm_device_interrupt: vector=0x%lx  ack=0x%x"
+                      "  irq=0x%x\n", vector, ack, irq);
+#endif
+
+       handle_irq(irq, ack, regs);
+       __restore_flags(flags);
+}
+
+static void __init
+sable_init_irq(void)
+{
+       STANDARD_INIT_IRQ_PROLOG;
+
+       outb(alpha_irq_mask      , 0x537);      /* slave 0 */
+       outb(alpha_irq_mask >>  8, 0x53b);      /* slave 1 */
+       outb(alpha_irq_mask >> 16, 0x53d);      /* slave 2 */
+       outb(0x44, 0x535);              /* enable cascades in master */
+}
+
+
+/*
+ * PCI Fixup configuration for ALPHA SABLE (2100) - 2100A is different ??
+ *
+ * Summary Registers (536/53a/53c):
+ * Bit      Meaning
+ *-----------------
+ * 0        PCI slot 0
+ * 1        NCR810 (builtin)
+ * 2        TULIP (builtin)
+ * 3        mouse
+ * 4        PCI slot 1
+ * 5        PCI slot 2
+ * 6        keyboard
+ * 7        floppy
+ * 8        COM2
+ * 9        parallel port
+ *10        EISA irq 3
+ *11        EISA irq 4
+ *12        EISA irq 5
+ *13        EISA irq 6
+ *14        EISA irq 7
+ *15        COM1
+ *16        EISA irq 9
+ *17        EISA irq 10
+ *18        EISA irq 11
+ *19        EISA irq 12
+ *20        EISA irq 13
+ *21        EISA irq 14
+ *22        NC
+ *23        IIC
+ *
+ * The device to slot mapping looks like:
+ *
+ * Slot     Device
+ *  0       TULIP
+ *  1       SCSI
+ *  2       PCI-EISA bridge
+ *  3       none
+ *  4       none
+ *  5       none
+ *  6       PCI on board slot 0
+ *  7       PCI on board slot 1
+ *  8       PCI on board slot 2
+ *   
+ *
+ * This two layered interrupt approach means that we allocate IRQ 16 and 
+ * above for PCI interrupts.  The IRQ relates to which bit the interrupt
+ * comes in on.  This makes interrupt processing much easier.
+ */
+/*
+ * NOTE: the IRQ assignments below are arbitrary, but need to be consistent
+ * with the values in the irq swizzling tables above.
+ */
+
+static int __init
+sable_map_irq(struct pci_dev *dev, int slot, int pin)
+{
+        static char irq_tab[9][5] __initlocaldata = {
+               /*INT    INTA   INTB   INTC   INTD */
+               { 32+0,  32+0,  32+0,  32+0,  32+0},  /* IdSel 0,  TULIP  */
+               { 32+1,  32+1,  32+1,  32+1,  32+1},  /* IdSel 1,  SCSI   */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 2,  SIO   */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 3,  none   */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 4,  none   */
+               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 5,  none   */
+               { 32+2,  32+2,  32+2,  32+2,  32+2},  /* IdSel 6,  slot 0 */
+               { 32+3,  32+3,  32+3,  32+3,  32+3},  /* IdSel 7,  slot 1 */
+               { 32+4,  32+4,  32+4,  32+4,  32+4},  /* IdSel 8,  slot 2 */
+        };
+       const long min_idsel = 0, max_idsel = 8, irqs_per_slot = 5;
+       return COMMON_TABLE_LOOKUP;
+}
+
+void __init
+sable_pci_fixup(void)
+{
+       layout_all_busses(EISA_DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
+        common_pci_fixup(sable_map_irq, common_swizzle);
+}
+
+
+/*
+ * The System Vectors
+ *
+ * In order that T2_HAE_ADDRESS should be a constant, we play
+ * these games with GAMMA_BIAS.
+ */
+
+#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_GAMMA)
+#undef GAMMA_BIAS
+#define GAMMA_BIAS 0
+struct alpha_machine_vector sable_mv __initmv = {
+       vector_name:            "Sable",
+       DO_EV4_MMU,
+       DO_DEFAULT_RTC,
+       DO_T2_IO,
+       DO_T2_BUS,
+       machine_check:          t2_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                40,
+       irq_probe_mask:         _PROBE_MASK(40),
+       update_irq_hw:          sable_update_irq_hw,
+       ack_irq:                sable_ack_irq,
+       device_interrupt:       sable_srm_device_interrupt,
+
+       init_arch:              t2_init_arch,
+       init_irq:               sable_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              sable_pci_fixup,
+       kill_arch:              generic_kill_arch,
+
+       sys: { t2: {
+           gamma_bias:         0
+       } }
+};
+ALIAS_MV(sable)
+#endif
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_GAMMA)
+#undef GAMMA_BIAS
+#define GAMMA_BIAS _GAMMA_BIAS
+struct alpha_machine_vector sable_gamma_mv __initmv = {
+       vector_name:            "Sable-Gamma",
+       DO_EV5_MMU,
+       DO_DEFAULT_RTC,
+       DO_T2_IO,
+       DO_T2_BUS,
+       machine_check:          t2_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                40,
+       irq_probe_mask:         _PROBE_MASK(40),
+       update_irq_hw:          sable_update_irq_hw,
+       ack_irq:                sable_ack_irq,
+       device_interrupt:       sable_srm_device_interrupt,
+
+       init_arch:              t2_init_arch,
+       init_irq:               sable_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              sable_pci_fixup,
+       kill_arch:              generic_kill_arch,
+
+       sys: { t2: {
+           gamma_bias:         _GAMMA_BIAS
+       } }
+};
+ALIAS_MV(sable_gamma)
+#endif
diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c
new file mode 100644 (file)
index 0000000..dfd6ada
--- /dev/null
@@ -0,0 +1,470 @@
+/*
+ *     linux/arch/alpha/kernel/sys_sio.c
+ *
+ *     Copyright (C) 1995 David A Rusling
+ *     Copyright (C) 1996 Jay A Estabrook
+ *     Copyright (C) 1998 Richard Henderson
+ *
+ * Code for all boards that route the PCI interrupts through the SIO
+ * PCI/ISA bridge.  This includes Noname (AXPpci33), Multia (UDB),
+ * Kenetics's Platform 2000, Avanti (AlphaStation), XL, and AlphaBook1.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/compiler.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/core_apecs.h>
+#include <asm/core_lca.h>
+
+#include "proto.h"
+#include "irq.h"
+#include "bios32.h"
+#include "machvec.h"
+
+static void
+sio_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+       if (irq >= 8)
+               outb(mask >> 8, 0xA1);
+       else
+               outb(mask, 0x21);
+}
+
+static void __init
+sio_init_irq(void)
+{
+       STANDARD_INIT_IRQ_PROLOG;
+
+       if (alpha_using_srm)
+               alpha_mv.device_interrupt = srm_device_interrupt;
+               
+       enable_irq(2);                  /* enable cascade */
+}
+
+static inline void __init
+xl_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+{
+       /*
+        * Set up the PCI->physical memory translation windows.  For
+        * the XL we *must* use both windows, in order to maximize the
+        * amount of physical memory that can be used to DMA from the
+        * ISA bus, and still allow PCI bus devices access to all of
+        * host memory.
+        *
+        * See <asm/apecs.h> for window bases and sizes.
+        *
+        * This restriction due to the true XL motherboards' 82379AB SIO
+        * PCI<->ISA bridge chip which passes only 27 bits of address...
+        */
+
+       *(vuip)APECS_IOC_PB1R = 1<<19 | (APECS_XL_DMA_WIN1_BASE & 0xfff00000U);
+       *(vuip)APECS_IOC_PM1R = (APECS_XL_DMA_WIN1_SIZE - 1) & 0xfff00000U;
+       *(vuip)APECS_IOC_TB1R = 0;
+
+       *(vuip)APECS_IOC_PB2R = 1<<19 | (APECS_XL_DMA_WIN2_BASE & 0xfff00000U);
+       *(vuip)APECS_IOC_PM2R = (APECS_XL_DMA_WIN2_SIZE - 1) & 0xfff00000U;
+       *(vuip)APECS_IOC_TB2R = 0;
+
+       /*
+        * Finally, clear the HAXR2 register, which gets used for PCI
+        * Config Space accesses. That is the way we want to use it,
+        * and we do not want to depend on what ARC or SRM might have
+        * left behind...
+        */
+
+       *(vuip)APECS_IOC_HAXR2 = 0; mb();
+}
+
+static inline void __init
+alphabook1_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+{
+       /* The AlphaBook1 has LCD video fixed at 800x600,
+          37 rows and 100 cols. */
+       screen_info.orig_y = 37;
+       screen_info.orig_video_cols = 100;
+       screen_info.orig_video_lines = 37;
+
+       lca_init_arch(mem_start, mem_end);
+}
+
+
+/*
+ * sio_route_tab selects irq routing in PCI/ISA bridge so that:
+ *             PIRQ0 -> irq 15
+ *             PIRQ1 -> irq  9
+ *             PIRQ2 -> irq 10
+ *             PIRQ3 -> irq 11
+ *
+ * This probably ought to be configurable via MILO.  For
+ * example, sound boards seem to like using IRQ 9.
+ */
+static unsigned long sio_route_tab __initdata = 0;
+
+static void __init
+sio_pci_fixup(int (*map_irq)(struct pci_dev *dev, int sel, int pin),
+             unsigned long new_route_tab)
+{
+       unsigned int route_tab;
+
+       /* Examine or update the PCI routing table.  */
+        pcibios_read_config_dword(0, PCI_DEVFN(7, 0), 0x60, &route_tab);
+
+       sio_route_tab = route_tab; 
+       if (PCI_MODIFY) {
+               sio_route_tab = new_route_tab;
+               pcibios_write_config_dword(0, PCI_DEVFN(7, 0), 0x60,
+                                          new_route_tab);
+       }
+
+       /* Update all the IRQs.  */
+       common_pci_fixup(map_irq, common_swizzle);
+}
+
+static unsigned int __init
+sio_collect_irq_levels(void)
+{
+       unsigned int level_bits = 0;
+       struct pci_dev *dev;
+
+       /* Iterate through the devices, collecting IRQ levels.  */
+       for (dev = pci_devices; dev; dev = dev->next) {
+               if ((dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) &&
+                   (dev->class >> 8 != PCI_CLASS_BRIDGE_PCMCIA))
+                       continue;
+
+               if (dev->irq)
+                       level_bits |= (1 << dev->irq);
+       }
+       return level_bits;
+}
+
+static void __init
+sio_fixup_irq_levels(unsigned int level_bits)
+{
+       unsigned int old_level_bits;
+
+       /*
+        * Now, make all PCI interrupts level sensitive.  Notice:
+        * these registers must be accessed byte-wise.  inw()/outw()
+        * don't work.
+        *
+        * Make sure to turn off any level bits set for IRQs 9,10,11,15,
+        *  so that the only bits getting set are for devices actually found.
+        * Note that we do preserve the remainder of the bits, which we hope
+        *  will be set correctly by ARC/SRM.
+        *
+        * Note: we at least preserve any level-set bits on AlphaBook1
+        */
+       old_level_bits = inb(0x4d0) | (inb(0x4d1) << 8);
+
+       level_bits |= (old_level_bits & 0x71ff);
+
+       outb((level_bits >> 0) & 0xff, 0x4d0);
+       outb((level_bits >> 8) & 0xff, 0x4d1);
+}
+
+static inline int __init
+noname_map_irq(struct pci_dev *dev, int slot, int pin)
+{
+       /*
+        * The Noname board has 5 PCI slots with each of the 4
+        * interrupt pins routed to different pins on the PCI/ISA
+        * bridge (PIRQ0-PIRQ3).  The table below is based on
+        * information available at:
+        *
+        *   http://ftp.digital.com/pub/DEC/axppci/ref_interrupts.txt
+        *
+        * I have no information on the Avanti interrupt routing, but
+        * the routing seems to be identical to the Noname except
+        * that the Avanti has an additional slot whose routing I'm
+        * unsure of.
+        *
+        * pirq_tab[0] is a fake entry to deal with old PCI boards
+        * that have the interrupt pin number hardwired to 0 (meaning
+        * that they use the default INTA line, if they are interrupt
+        * driven at all).
+        */
+       static char irq_tab[][5] __initlocaldata = {
+               /*INT A   B   C   D */
+               { 3,  3,  3,  3,  3}, /* idsel  6 (53c810) */ 
+               {-1, -1, -1, -1, -1}, /* idsel  7 (SIO: PCI/ISA bridge) */
+               { 2,  2, -1, -1, -1}, /* idsel  8 (Hack: slot closest ISA) */
+               {-1, -1, -1, -1, -1}, /* idsel  9 (unused) */
+               {-1, -1, -1, -1, -1}, /* idsel 10 (unused) */
+               { 0,  0,  2,  1,  0}, /* idsel 11 KN25_PCI_SLOT0 */
+               { 1,  1,  0,  2,  1}, /* idsel 12 KN25_PCI_SLOT1 */
+               { 2,  2,  1,  0,  2}, /* idsel 13 KN25_PCI_SLOT2 */
+               { 0,  0,  0,  0,  0}, /* idsel 14 AS255 TULIP */
+       };
+       const long min_idsel = 6, max_idsel = 14, irqs_per_slot = 5;
+       int irq = COMMON_TABLE_LOOKUP, tmp;
+       tmp = __kernel_extbl(sio_route_tab, irq);
+       return irq >= 0 ? tmp : -1;
+}
+
+static inline void __init
+noname_pci_fixup(void)
+{
+       /*
+        * For UDB, the only available PCI slot must not map to IRQ 9,
+        * since that's the builtin MSS sound chip. That PCI slot
+        * will map to PIRQ1 (for INTA at least), so we give it IRQ 15
+        * instead.
+        *
+        * Unfortunately we have to do this for NONAME as well, since
+        * they are co-indicated when the platform type "Noname" is
+        * selected... :-(
+        */
+       layout_all_busses(DEFAULT_IO_BASE, APECS_AND_LCA_DEFAULT_MEM_BASE);
+       sio_pci_fixup(noname_map_irq, 0x0b0a0f09);
+       sio_fixup_irq_levels(sio_collect_irq_levels());
+        enable_ide(0x26e);
+}
+
+static inline void __init
+avanti_pci_fixup(void)
+{
+       layout_all_busses(DEFAULT_IO_BASE, APECS_AND_LCA_DEFAULT_MEM_BASE);
+       sio_pci_fixup(noname_map_irq, 0x0b0a090f);
+       sio_fixup_irq_levels(sio_collect_irq_levels());
+        enable_ide(0x26e);
+}
+
+static inline void __init
+xl_pci_fixup(void)
+{
+       layout_all_busses(DEFAULT_IO_BASE, XL_DEFAULT_MEM_BASE);
+       sio_pci_fixup(noname_map_irq, 0x0b0a090f);
+       sio_fixup_irq_levels(sio_collect_irq_levels());
+        enable_ide(0x26e);
+}
+
+static inline int __init
+p2k_map_irq(struct pci_dev *dev, int slot, int pin)
+{
+       static char irq_tab[][5] __initlocaldata = {
+               /*INT A   B   C   D */
+               { 0,  0, -1, -1, -1}, /* idsel  6 (53c810) */
+               {-1, -1, -1, -1, -1}, /* idsel  7 (SIO: PCI/ISA bridge) */
+               { 1,  1,  2,  3,  0}, /* idsel  8 (slot A) */
+               { 2,  2,  3,  0,  1}, /* idsel  9 (slot B) */
+               {-1, -1, -1, -1, -1}, /* idsel 10 (unused) */
+               {-1, -1, -1, -1, -1}, /* idsel 11 (unused) */
+               { 3,  3, -1, -1, -1}, /* idsel 12 (CMD0646) */
+       };
+       const long min_idsel = 6, max_idsel = 12, irqs_per_slot = 5;
+       int irq = COMMON_TABLE_LOOKUP, tmp;
+       tmp = __kernel_extbl(sio_route_tab, irq);
+       return irq >= 0 ? tmp : -1;
+}
+
+static inline void __init
+p2k_pci_fixup(void)
+{
+       layout_all_busses(DEFAULT_IO_BASE, APECS_AND_LCA_DEFAULT_MEM_BASE);
+       sio_pci_fixup(p2k_map_irq, 0x0b0a090f);
+       sio_fixup_irq_levels(sio_collect_irq_levels());
+        enable_ide(0x26e);
+}
+
+static inline void __init
+alphabook1_pci_fixup(void)
+{
+       struct pci_dev *dev;
+       unsigned char orig, config;
+
+       layout_all_busses(DEFAULT_IO_BASE, APECS_AND_LCA_DEFAULT_MEM_BASE);
+
+        /* For the AlphaBook1, NCR810 SCSI is 14, PCMCIA controller is 15. */
+       sio_pci_fixup(noname_map_irq, 0x0e0f0a0a);
+
+       /*
+        * On the AlphaBook1, the PCMCIA chip (Cirrus 6729)
+        * is sensitive to PCI bus bursts, so we must DISABLE
+        * burst mode for the NCR 8xx SCSI... :-(
+        *
+        * Note that the NCR810 SCSI driver must preserve the
+        * setting of the bit in order for this to work.  At the
+        * moment (2.0.29), ncr53c8xx.c does NOT do this, but
+        * 53c7,8xx.c DOES.
+        */
+       for (dev = pci_devices; dev; dev = dev->next) {
+                if (dev->vendor == PCI_VENDOR_ID_NCR &&
+                    (dev->device == PCI_DEVICE_ID_NCR_53C810 ||
+                     dev->device == PCI_DEVICE_ID_NCR_53C815 ||
+                     dev->device == PCI_DEVICE_ID_NCR_53C820 ||
+                     dev->device == PCI_DEVICE_ID_NCR_53C825)) {
+                       unsigned int io_port;
+                       unsigned char ctest4;
+
+                       pcibios_read_config_dword(dev->bus->number,
+                                                 dev->devfn,
+                                                 PCI_BASE_ADDRESS_0,
+                                                 &io_port);
+                       io_port &= PCI_BASE_ADDRESS_IO_MASK;
+                       ctest4 = inb(io_port+0x21);
+                       if (!(ctest4 & 0x80)) {
+                               printk("AlphaBook1 NCR init: setting"
+                                      " burst disable\n");
+                               outb(ctest4 | 0x80, io_port+0x21);
+                       }
+                }
+       }
+
+       /* Do not set *ANY* level triggers for AlphaBook1. */
+       sio_fixup_irq_levels(0);
+
+       /* Make sure that register PR1 indicates 1Mb mem */
+       outb(0x0f, 0x3ce); orig = inb(0x3cf);   /* read PR5  */
+       outb(0x0f, 0x3ce); outb(0x05, 0x3cf);   /* unlock PR0-4 */
+       outb(0x0b, 0x3ce); config = inb(0x3cf); /* read PR1 */
+       if ((config & 0xc0) != 0xc0) {
+               printk("AlphaBook1 VGA init: setting 1Mb memory\n");
+               config |= 0xc0;
+               outb(0x0b, 0x3ce); outb(config, 0x3cf); /* write PR1 */
+       }
+       outb(0x0f, 0x3ce); outb(orig, 0x3cf); /* (re)lock PR0-4 */
+}
+
+
+/*
+ * The System Vectors
+ */
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_BOOK1)
+struct alpha_machine_vector alphabook1_mv __initmv = {
+       vector_name:            "AlphaBook1",
+       DO_EV4_MMU,
+       DO_DEFAULT_RTC,
+       DO_LCA_IO,
+       DO_LCA_BUS,
+       machine_check:          lca_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                16,
+       irq_probe_mask:         _PROBE_MASK(16),
+       update_irq_hw:          sio_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       isa_device_interrupt,
+
+       init_arch:              alphabook1_init_arch,
+       init_irq:               sio_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              alphabook1_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(alphabook1)
+#endif
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_AVANTI)
+struct alpha_machine_vector avanti_mv __initmv = {
+       vector_name:            "Avanti",
+       DO_EV4_MMU,
+       DO_DEFAULT_RTC,
+       DO_APECS_IO,
+       DO_APECS_BUS,
+       machine_check:          apecs_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                16,
+       irq_probe_mask:         _PROBE_MASK(16),
+       update_irq_hw:          sio_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       isa_device_interrupt,
+
+       init_arch:              apecs_init_arch,
+       init_irq:               sio_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              avanti_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(avanti)
+#endif
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_NONAME)
+struct alpha_machine_vector noname_mv __initmv = {
+       vector_name:            "Noname",
+       DO_EV4_MMU,
+       DO_DEFAULT_RTC,
+       DO_LCA_IO,
+       DO_LCA_BUS,
+       machine_check:          lca_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                16,
+       irq_probe_mask:         _PROBE_MASK(16),
+       update_irq_hw:          sio_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       srm_device_interrupt,
+
+       init_arch:              lca_init_arch,
+       init_irq:               sio_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              noname_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(noname)
+#endif
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_P2K)
+struct alpha_machine_vector p2k_mv __initmv = {
+       vector_name:            "Platform2000",
+       DO_EV4_MMU,
+       DO_DEFAULT_RTC,
+       DO_LCA_IO,
+       DO_LCA_BUS,
+       machine_check:          lca_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                16,
+       irq_probe_mask:         P2K_PROBE_MASK,
+       update_irq_hw:          sio_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       srm_device_interrupt,
+
+       init_arch:              lca_init_arch,
+       init_irq:               sio_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              p2k_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(p2k)
+#endif
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_XL)
+struct alpha_machine_vector xl_mv __initmv = {
+       vector_name:            "XL",
+       DO_EV4_MMU,
+       DO_DEFAULT_RTC,
+       DO_APECS_IO,
+       BUS(apecs_xl),
+       machine_check:          apecs_machine_check,
+       max_dma_address:        ALPHA_XL_MAX_DMA_ADDRESS,
+
+       nr_irqs:                16,
+       irq_probe_mask:         _PROBE_MASK(16),
+       update_irq_hw:          sio_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       isa_device_interrupt,
+
+       init_arch:              xl_init_arch,
+       init_irq:               sio_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              xl_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(xl)
+#endif
diff --git a/arch/alpha/kernel/sys_sx164.c b/arch/alpha/kernel/sys_sx164.c
new file mode 100644 (file)
index 0000000..1219b96
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ *     linux/arch/alpha/kernel/sys_sx164.c
+ *
+ *     Copyright (C) 1995 David A Rusling
+ *     Copyright (C) 1996 Jay A Estabrook
+ *     Copyright (C) 1998 Richard Henderson
+ *
+ * Code supporting the SX164 (PCA56+PYXIS).
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/core_pyxis.h>
+
+#include "proto.h"
+#include "irq.h"
+#include "bios32.h"
+#include "machvec.h"
+
+
+static void
+sx164_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+       if (irq >= 16) {
+               /* Make CERTAIN none of the bogus ints get enabled */
+               *(vulp)PYXIS_INT_MASK =
+                       ~((long)mask >> 16) & ~0x000000000000003bUL;
+               mb();
+               /* ... and read it back to make sure it got written.  */
+               *(vulp)PYXIS_INT_MASK;
+       }
+       else if (irq >= 8)
+               outb(mask >> 8, 0xA1);  /* ISA PIC2 */
+       else
+               outb(mask, 0x21);       /* ISA PIC1 */
+}
+
+static void
+sx164_srm_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+       if (irq >= 16) {
+               if (unmask_p)
+                       cserve_ena(irq - 16);
+               else
+                       cserve_dis(irq - 16);
+       }
+       else if (irq >= 8)
+               outb(mask >> 8, 0xA1);  /* ISA PIC2 */
+       else
+               outb(mask, 0x21);       /* ISA PIC1 */
+}
+
+static void 
+sx164_device_interrupt(unsigned long vector, struct pt_regs *regs)
+{
+       unsigned long pld, tmp;
+       unsigned int i;
+       unsigned long flags;
+
+       save_and_cli(flags);
+
+       /* Read the interrupt summary register of PYXIS */
+       pld = *(vulp)PYXIS_INT_REQ;
+
+       /*
+        * For now, AND off any bits we are not interested in:
+        *  HALT (2), timer (6), ISA Bridge (7)
+        * then all the PCI slots/INTXs (8-23)
+        */
+       /* Maybe HALT should only be used for SRM console boots? */
+       pld &= 0x0000000000ffffc0UL;
+
+       /*
+        * Now for every possible bit set, work through them and call
+        * the appropriate interrupt handler.
+        */
+       while (pld) {
+               i = ffz(~pld);
+               pld &= pld - 1; /* clear least bit set */
+               if (i == 7) {
+                       isa_device_interrupt(vector, regs);
+               } else if (i == 6) {
+                       continue;
+               } else {
+                       /* if not timer int */
+                       handle_irq(16 + i, 16 + i, regs);
+               }
+               *(vulp)PYXIS_INT_REQ = 1UL << i; mb();
+               tmp = *(vulp)PYXIS_INT_REQ;
+       }
+       restore_flags(flags);
+}
+
+static void
+sx164_init_irq(void)
+{
+       outb(0, DMA1_RESET_REG);
+       outb(0, DMA2_RESET_REG);
+
+       if (alpha_using_srm) {
+               alpha_mv.update_irq_hw = sx164_srm_update_irq_hw;
+               alpha_mv.device_interrupt = srm_device_interrupt;
+       }
+       else {
+               /* Note invert on MASK bits. */
+               *(vulp)PYXIS_INT_MASK  = ~((long)alpha_irq_mask >> 16);
+               mb();
+               *(vulp)PYXIS_INT_MASK;
+       }
+
+       enable_irq(16 + 6);     /* enable timer */
+       enable_irq(16 + 7);     /* enable ISA PIC cascade */
+       enable_irq(2);          /* enable cascade */
+}
+
+/*
+ * PCI Fixup configuration.
+ *
+ * Summary @ PYXIS_INT_REQ:
+ * Bit      Meaning
+ * 0        RSVD
+ * 1        NMI
+ * 2        Halt/Reset switch
+ * 3        MBZ
+ * 4        RAZ
+ * 5        RAZ
+ * 6        Interval timer (RTC)
+ * 7        PCI-ISA Bridge
+ * 8        Interrupt Line A from slot 3
+ * 9        Interrupt Line A from slot 2
+ *10        Interrupt Line A from slot 1
+ *11        Interrupt Line A from slot 0
+ *12        Interrupt Line B from slot 3
+ *13        Interrupt Line B from slot 2
+ *14        Interrupt Line B from slot 1
+ *15        Interrupt line B from slot 0
+ *16        Interrupt Line C from slot 3
+ *17        Interrupt Line C from slot 2
+ *18        Interrupt Line C from slot 1
+ *19        Interrupt Line C from slot 0
+ *20        Interrupt Line D from slot 3
+ *21        Interrupt Line D from slot 2
+ *22        Interrupt Line D from slot 1
+ *23        Interrupt Line D from slot 0
+ *
+ * IdSel       
+ *   5  32 bit PCI option slot 2
+ *   6  64 bit PCI option slot 0
+ *   7  64 bit PCI option slot 1
+ *   8  Cypress I/O
+ *   9  32 bit PCI option slot 3
+ * 
+ */
+
+static int __init
+sx164_map_irq(struct pci_dev *dev, int slot, int pin)
+{
+       static char irq_tab[5][5] __initlocaldata = {
+               /*INT    INTA   INTB   INTC   INTD */
+               { 16+ 9, 16+ 9, 16+13, 16+17, 16+21}, /* IdSel 5 slot 2 J17 */
+               { 16+11, 16+11, 16+15, 16+19, 16+23}, /* IdSel 6 slot 0 J19 */
+               { 16+10, 16+10, 16+14, 16+18, 16+22}, /* IdSel 7 slot 1 J18 */
+               {    -1,    -1,    -1,    -1,    -1}, /* IdSel 8 SIO        */
+               { 16+ 8, 16+ 8, 16+12, 16+16, 16+20}  /* IdSel 9 slot 3 J15 */
+       };
+       const long min_idsel = 5, max_idsel = 9, irqs_per_slot = 5;
+       return COMMON_TABLE_LOOKUP;
+}
+
+void __init
+sx164_pci_fixup(void)
+{
+       layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
+       common_pci_fixup(sx164_map_irq, common_swizzle);
+       SMC669_Init();
+}
+
+
+/*
+ * The System Vector
+ */
+
+struct alpha_machine_vector sx164_mv __initmv = {
+       vector_name:            "SX164",
+       DO_EV5_MMU,
+       DO_DEFAULT_RTC,
+       DO_PYXIS_IO,
+       DO_PYXIS_BUS,
+       machine_check:          pyxis_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                40,
+       irq_probe_mask:         _PROBE_MASK(40),
+       update_irq_hw:          sx164_update_irq_hw,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       sx164_device_interrupt,
+
+       init_arch:              pyxis_init_arch,
+       init_irq:               sx164_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              sx164_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(sx164)
diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c
new file mode 100644 (file)
index 0000000..326fd64
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ *     linux/arch/alpha/kernel/sys_takara.c
+ *
+ *     Copyright (C) 1995 David A Rusling
+ *     Copyright (C) 1996 Jay A Estabrook
+ *     Copyright (C) 1998 Richard Henderson
+ *
+ * Code supporting the TAKARA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/core_cia.h>
+
+#include "proto.h"
+#include "irq.h"
+#include "bios32.h"
+#include "machvec.h"
+
+
+/*
+ * WARNING WARNING WARNING
+ *
+ * This port is missing an update_irq_hw implementation.
+ */
+
+static void
+takara_device_interrupt(unsigned long vector, struct pt_regs *regs)
+{
+       unsigned long flags;
+       unsigned intstatus;
+
+       save_and_cli(flags);
+
+       /*
+        * The PALcode will have passed us vectors 0x800 or 0x810,
+        * which are fairly arbitrary values and serve only to tell
+        * us whether an interrupt has come in on IRQ0 or IRQ1. If
+        * it's IRQ1 it's a PCI interrupt; if it's IRQ0, it's
+        * probably ISA, but PCI interrupts can come through IRQ0
+        * as well if the interrupt controller isn't in accelerated
+        * mode.
+        *
+        * OTOH, the accelerator thing doesn't seem to be working
+        * overly well, so what we'll do instead is try directly
+        * examining the Master Interrupt Register to see if it's a
+        * PCI interrupt, and if _not_ then we'll pass it on to the
+        * ISA handler.
+        */
+
+       intstatus = inw(0x500) & 15;
+       if (intstatus) {
+               /*
+                * This is a PCI interrupt. Check each bit and
+                * despatch an interrupt if it's set.
+                */
+
+               if (intstatus & 8) handle_irq(16+3, 16+3, regs);
+               if (intstatus & 4) handle_irq(16+2, 16+2, regs);
+               if (intstatus & 2) handle_irq(16+1, 16+1, regs);
+               if (intstatus & 1) handle_irq(16+0, 16+0, regs);
+       } else
+               isa_device_interrupt (vector, regs);
+
+       restore_flags(flags);
+}
+
+static void __init
+takara_init_irq(void)
+{
+       unsigned int ctlreg;
+
+       STANDARD_INIT_IRQ_PROLOG;
+
+       ctlreg = inl(0x500);
+       ctlreg &= ~0x8000;     /* return to non-accelerated mode */
+       outw(ctlreg >> 16, 0x502);
+       outw(ctlreg & 0xFFFF, 0x500);
+       ctlreg = 0x05107c00;   /* enable the PCI interrupt register */
+       outw(ctlreg >> 16, 0x502);
+       outw(ctlreg & 0xFFFF, 0x500);
+       enable_irq(2);
+}
+
+
+/*
+ * The Takara has PCI devices 1, 2, and 3 configured to slots 20,
+ * 19, and 18 respectively, in the default configuration. They can
+ * also be jumpered to slots 8, 7, and 6 respectively, which is fun
+ * because the SIO ISA bridge can also be slot 7. However, the SIO
+ * doesn't explicitly generate PCI-type interrupts, so we can
+ * assign it whatever the hell IRQ we like and it doesn't matter.
+ */
+
+static int __init
+takara_map_irq(struct pci_dev *dev, int slot, int pin)
+{
+       static char irq_tab[15][5] __initlocaldata = {
+               { 16+3, 16+3, 16+3, 16+3, 16+3},   /* slot  6 == device 3 */
+               { 16+2, 16+2, 16+2, 16+2, 16+2},   /* slot  7 == device 2 */
+               { 16+1, 16+1, 16+1, 16+1, 16+1},   /* slot  8 == device 1 */
+               {   -1,   -1,   -1,   -1,   -1},   /* slot  9 == nothing */
+               {   -1,   -1,   -1,   -1,   -1},   /* slot 10 == nothing */
+               {   -1,   -1,   -1,   -1,   -1},   /* slot 11 == nothing */
+               {   -1,   -1,   -1,   -1,   -1},   /* slot 12 == nothing */
+               {   -1,   -1,   -1,   -1,   -1},   /* slot 13 == nothing */
+               {   -1,   -1,   -1,   -1,   -1},   /* slot 14 == nothing */
+               {   -1,   -1,   -1,   -1,   -1},   /* slot 15 == nothing */
+               {   -1,   -1,   -1,   -1,   -1},   /* slot 16 == nothing */
+               {   -1,   -1,   -1,   -1,   -1},   /* slot 17 == nothing */
+               { 16+3, 16+3, 16+3, 16+3, 16+3},   /* slot 18 == device 3 */
+               { 16+2, 16+2, 16+2, 16+2, 16+2},   /* slot 19 == device 2 */
+               { 16+1, 16+1, 16+1, 16+1, 16+1},   /* slot 20 == device 1 */
+       };
+       const long min_idsel = 6, max_idsel = 20, irqs_per_slot = 5;
+       return COMMON_TABLE_LOOKUP;
+}
+
+static void __init
+takara_pci_fixup(void)
+{
+       layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
+       common_pci_fixup(takara_map_irq, common_swizzle);
+       enable_ide(0x26e);
+}
+
+
+/*
+ * The System Vector
+ */
+
+struct alpha_machine_vector takara_mv __initmv = {
+       vector_name:            "Takara",
+       DO_EV5_MMU,
+       DO_DEFAULT_RTC,
+       DO_CIA_IO,
+       DO_CIA_BUS,
+       machine_check:          cia_machine_check,
+       max_dma_address:        ALPHA_MAX_DMA_ADDRESS,
+
+       nr_irqs:                20,
+       irq_probe_mask:         _PROBE_MASK(20),
+       update_irq_hw:          NULL,
+       ack_irq:                generic_ack_irq,
+       device_interrupt:       takara_device_interrupt,
+
+       init_arch:              cia_init_arch,
+       init_irq:               takara_init_irq,
+       init_pit:               generic_init_pit,
+       pci_fixup:              takara_pci_fixup,
+       kill_arch:              generic_kill_arch,
+};
+ALIAS_MV(takara)
diff --git a/arch/alpha/kernel/t2.c b/arch/alpha/kernel/t2.c
deleted file mode 100644 (file)
index 2430aae..0000000
+++ /dev/null
@@ -1,646 +0,0 @@
-/*
- * Code common to all T2 chips.
- *
- * Written by Jay A Estabrook (jestabro@amt.tay1.dec.com).
- * December 1996.
- *
- * based on CIA code by David A Rusling (david.rusling@reo.mts.dec.com)
- *
- */
-#include <linux/kernel.h>
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/sched.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/hwrpb.h>
-#include <asm/ptrace.h>
-#include <asm/mmu_context.h>
-
-/*
- * NOTE: Herein lie back-to-back mb instructions.  They are magic. 
- * One plausible explanation is that the i/o controller does not properly
- * handle the system transaction.  Another involves timing.  Ho hum.
- */
-
-extern struct hwrpb_struct *hwrpb;
-extern asmlinkage void wrmces(unsigned long mces);
-
-/*
- * Machine check reasons.  Defined according to PALcode sources
- * (osf.h and platform.h).
- */
-#define MCHK_K_TPERR           0x0080
-#define MCHK_K_TCPERR          0x0082
-#define MCHK_K_HERR            0x0084
-#define MCHK_K_ECC_C           0x0086
-#define MCHK_K_ECC_NC          0x0088
-#define MCHK_K_OS_BUGCHECK     0x008A
-#define MCHK_K_PAL_BUGCHECK    0x0090
-
-/*
- * BIOS32-style PCI interface:
- */
-
-#ifdef DEBUG_CONF
-# define DBG(args)     printk args
-#else
-# define DBG(args)
-#endif
-
-#ifdef DEBUG_MCHECK
-# define DBGMC(args)   printk args
-#else
-# define DBGMC(args)
-#endif
-
-#define vulp   volatile unsigned long *
-#define vuip   volatile unsigned int  *
-
-static volatile unsigned int T2_mcheck_expected[NR_CPUS];
-static volatile unsigned int T2_mcheck_taken[NR_CPUS];
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-unsigned int T2_DMA_WIN_BASE = T2_DMA_WIN_BASE_DEFAULT;
-unsigned int T2_DMA_WIN_SIZE = T2_DMA_WIN_SIZE_DEFAULT;
-unsigned long t2_sm_base;
-#endif /* SRM_SETUP */
-
-/*
- * Given a bus, device, and function number, compute resulting
- * configuration space address and setup the T2_HAXR2 register
- * accordingly.  It is therefore not safe to have concurrent
- * invocations to configuration space access routines, but there
- * really shouldn't be any need for this.
- *
- * Type 0:
- *
- *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *     31:11   Device select bit.
- *     10:8    Function number
- *      7:2    Register number
- *
- * Type 1:
- *
- *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *     31:24   reserved
- *     23:16   bus number (8 bits = 128 possible buses)
- *     15:11   Device number (5 bits)
- *     10:8    function number
- *      7:2    register number
- *  
- * Notes:
- *     The function number selects which function of a multi-function device 
- *     (e.g., SCSI and Ethernet).
- * 
- *     The register selects a DWORD (32 bit) register offset.  Hence it
- *     doesn't get shifted by 2 bits as we want to "drop" the bottom two
- *     bits.
- */
-static int mk_conf_addr(unsigned char bus, unsigned char device_fn,
-                       unsigned char where, unsigned long *pci_addr,
-                       unsigned char *type1)
-{
-       unsigned long addr;
-
-       DBG(("mk_conf_addr(bus=%d, dfn=0x%x, where=0x%x,"
-            " addr=0x%lx, type1=0x%x)\n",
-            bus, device_fn, where, pci_addr, type1));
-
-       if (bus == 0) {
-               int device = device_fn >> 3;
-
-               /* type 0 configuration cycle: */
-
-               if (device > 8) {
-                       DBG(("mk_conf_addr: device (%d)>20, returning -1\n",
-                            device));
-                       return -1;
-               }
-
-               *type1 = 0;
-               addr = (0x0800L << device) | ((device_fn & 7) << 8) | (where);
-       } else {
-               /* type 1 configuration cycle: */
-               *type1 = 1;
-               addr = (bus << 16) | (device_fn << 8) | (where);
-       }
-       *pci_addr = addr;
-       DBG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
-       return 0;
-}
-
-
-static unsigned int conf_read(unsigned long addr, unsigned char type1)
-{
-       unsigned long flags;
-       unsigned int stat0, value, cpu;
-       unsigned long t2_cfg = 0; /* to keep gcc quiet */
-
-       cpu = smp_processor_id();
-
-       save_flags(flags);      /* avoid getting hit by machine check */
-       cli();
-
-       DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
-
-#if 0
-       /* reset status register to avoid losing errors: */
-       stat0 = *(vulp)T2_IOCSR;
-       *(vulp)T2_IOCSR = stat0;
-       mb();
-       DBG(("conf_read: T2 IOCSR was 0x%x\n", stat0));
-#endif
-       /* if Type1 access, must set T2 CFG */
-       if (type1) {
-               t2_cfg = *(vulp)T2_HAE_3 & ~0xc0000000UL;
-               *(vulp)T2_HAE_3 = 0x40000000UL | t2_cfg;
-               mb();
-               DBG(("conf_read: TYPE1 access\n"));
-       }
-       mb();
-       draina();
-
-       T2_mcheck_expected[cpu] = 1;
-       T2_mcheck_taken[cpu] = 0;
-       mb();
-       /* access configuration space: */
-       value = *(vuip)addr;
-       mb();
-       mb();  /* magic */
-       if (T2_mcheck_taken[cpu]) {
-               T2_mcheck_taken[cpu] = 0;
-               value = 0xffffffffU;
-               mb();
-       }
-       T2_mcheck_expected[cpu] = 0;
-       mb();
-
-       /* if Type1 access, must reset T2 CFG so normal IO space ops work */
-       if (type1) {
-               *(vulp)T2_HAE_3 = t2_cfg;
-               mb();
-       }
-       DBG(("conf_read(): finished\n"));
-
-       restore_flags(flags);
-       return value;
-}
-
-
-static void conf_write(unsigned long addr, unsigned int value,
-                      unsigned char type1)
-{
-       unsigned long flags;
-       unsigned int stat0, cpu;
-       unsigned long t2_cfg = 0; /* to keep gcc quiet */
-
-       cpu = smp_processor_id();
-
-       save_flags(flags);      /* avoid getting hit by machine check */
-       cli();
-
-#if 0
-       /* reset status register to avoid losing errors: */
-       stat0 = *(vulp)T2_IOCSR;
-       *(vulp)T2_IOCSR = stat0;
-       mb();
-       DBG(("conf_write: T2 ERR was 0x%x\n", stat0));
-#endif
-       /* if Type1 access, must set T2 CFG */
-       if (type1) {
-               t2_cfg = *(vulp)T2_HAE_3 & ~0xc0000000UL;
-               *(vulp)T2_HAE_3 = t2_cfg | 0x40000000UL;
-               mb();
-               DBG(("conf_write: TYPE1 access\n"));
-       }
-       mb();
-       draina();
-
-       T2_mcheck_expected[cpu] = 1;
-       mb();
-       /* access configuration space: */
-       *(vuip)addr = value;
-       mb();
-       mb();  /* magic */
-       T2_mcheck_expected[cpu] = 0;
-       mb();
-
-       /* if Type1 access, must reset T2 CFG so normal IO space ops work */
-       if (type1) {
-               *(vulp)T2_HAE_3 = t2_cfg;
-               mb();
-       }
-       DBG(("conf_write(): finished\n"));
-       restore_flags(flags);
-}
-
-
-int pcibios_read_config_byte (unsigned char bus, unsigned char device_fn,
-                             unsigned char where, unsigned char *value)
-{
-       unsigned long addr = T2_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       *value = 0xff;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       addr |= (pci_addr << 5) + 0x00;
-
-       *value = conf_read(addr, type1) >> ((where & 3) * 8);
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_read_config_word (unsigned char bus, unsigned char device_fn,
-                             unsigned char where, unsigned short *value)
-{
-       unsigned long addr = T2_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       *value = 0xffff;
-
-       if (where & 0x1) {
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-       }
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       addr |= (pci_addr << 5) + 0x08;
-
-       *value = conf_read(addr, type1) >> ((where & 3) * 8);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_read_config_dword (unsigned char bus, unsigned char device_fn,
-                              unsigned char where, unsigned int *value)
-{
-       unsigned long addr = T2_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       *value = 0xffffffff;
-       if (where & 0x3) {
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-       }
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x18;
-       *value = conf_read(addr, type1);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_write_config_byte (unsigned char bus, unsigned char device_fn,
-                              unsigned char where, unsigned char value)
-{
-       unsigned long addr = T2_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x00;
-       conf_write(addr, value << ((where & 3) * 8), type1);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_write_config_word (unsigned char bus, unsigned char device_fn,
-                              unsigned char where, unsigned short value)
-{
-       unsigned long addr = T2_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x08;
-       conf_write(addr, value << ((where & 3) * 8), type1);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_write_config_dword (unsigned char bus, unsigned char device_fn,
-                               unsigned char where, unsigned int value)
-{
-       unsigned long addr = T2_CONF;
-       unsigned long pci_addr;
-       unsigned char type1;
-
-       if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-       addr |= (pci_addr << 5) + 0x18;
-       conf_write(addr, value << ((where & 3) * 8), type1);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-unsigned long t2_init(unsigned long mem_start, unsigned long mem_end)
-{
-       unsigned long t2_err;
-       unsigned int i;
-
-       for (i = 0; i < NR_CPUS; i++) {
-               T2_mcheck_expected[i] = 0;
-               T2_mcheck_taken[i] = 0;
-       }
-
-#if 0
-       /* 
-        * Set up error reporting.
-        */
-       t2_err = *(vulp)T2_IOCSR ;
-       t2_err |= (0x1 << 7) ;   /* master abort */
-       *(vulp)T2_IOCSR = t2_err ;
-       mb() ;
-#endif
-
-       printk("t2_init: HBASE was 0x%lx\n", *(vulp)T2_HBASE);
-#if 0
-       printk("t2_init: WBASE1=0x%lx WMASK1=0x%lx TBASE1=0x%lx\n",
-              *(vulp)T2_WBASE1,
-              *(vulp)T2_WMASK1,
-              *(vulp)T2_TBASE1);
-       printk("t2_init: WBASE2=0x%lx WMASK2=0x%lx TBASE2=0x%lx\n",
-              *(vulp)T2_WBASE2,
-              *(vulp)T2_WMASK2,
-              *(vulp)T2_TBASE2);
-#endif
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-       /* check window 1 for enabled and mapped to 0 */
-       if (((*(vulp)T2_WBASE1 & (3UL<<18)) == (2UL<<18)) &&
-            (*(vulp)T2_TBASE1 == 0))
-       {
-         T2_DMA_WIN_BASE = *(vulp)T2_WBASE1 & 0xfff00000UL;
-         T2_DMA_WIN_SIZE = *(vulp)T2_WMASK1 & 0xfff00000UL;
-         T2_DMA_WIN_SIZE += 0x00100000UL;
-/* DISABLE window 2!! ?? */
-#if 1
-         printk("t2_init: using Window 1 settings\n");
-         printk("t2_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
-                *(vulp)T2_WBASE1,
-                *(vulp)T2_WMASK1,
-                *(vulp)T2_TBASE1);
-#endif
-       }
-       else    /* check window 2 for enabled and mapped to 0 */
-       if (((*(vulp)T2_WBASE2 & (3UL<<18)) == (2UL<<18)) &&
-            (*(vulp)T2_TBASE2 == 0))
-       {
-         T2_DMA_WIN_BASE = *(vulp)T2_WBASE2 & 0xfff00000UL;
-         T2_DMA_WIN_SIZE = *(vulp)T2_WMASK2 & 0xfff00000UL;
-         T2_DMA_WIN_SIZE += 0x00100000UL;
-/* DISABLE window 1!! ?? */
-#if 1
-         printk("t2_init: using Window 2 settings\n");
-         printk("t2_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
-                *(vulp)T2_WBASE2,
-                *(vulp)T2_WMASK2,
-                *(vulp)T2_TBASE2);
-#endif
-       }
-       else /* we must use our defaults... */
-#endif /* SRM_SETUP */
-       {
-       /*
-        * Set up the PCI->physical memory translation windows.
-        * For now, window 2 is  disabled.  In the future, we may
-        * want to use it to do scatter/gather DMA.  Window 1
-        * goes at 1 GB and is 1 GB large.
-        */
-
-       /* WARNING!! must correspond to the DMA_WIN params!!! */
-       *(vulp)T2_WBASE1 = 0x400807ffU;
-       *(vulp)T2_WMASK1 = 0x3ff00000U;
-       *(vulp)T2_TBASE1 = 0;
-
-       *(vulp)T2_WBASE2 = 0x0;
-       *(vulp)T2_HBASE = 0x0;
-       }
-
-       /*
-        * check ASN in HWRPB for validity, report if bad
-        */
-       if (hwrpb->max_asn != MAX_ASN) {
-               printk("T2_init: max ASN from HWRPB is bad (0x%lx)\n",
-                      hwrpb->max_asn);
-               hwrpb->max_asn = MAX_ASN;
-       }
-
-       /*
-        * Finally, clear the T2_HAE_3 register, which gets used
-        *  for PCI Config Space accesses. That is the way
-        *  we want to use it, and we do not want to depend on
-        *  what ARC or SRM might have left behind...
-        */
-       {
-         unsigned long t2_hae_1 = *(vulp)T2_HAE_1;
-         unsigned long t2_hae_2 = *(vulp)T2_HAE_2;
-         unsigned long t2_hae_3 = *(vulp)T2_HAE_3;
-         unsigned long t2_hae_4 = *(vulp)T2_HAE_4;
-#if 1
-          printk("T2_init: HAE1 was 0x%lx\n", t2_hae_1);
-          printk("T2_init: HAE2 was 0x%lx\n", t2_hae_2);
-          printk("T2_init: HAE3 was 0x%lx\n", t2_hae_3);
-          printk("T2_init: HAE4 was 0x%lx\n", t2_hae_4);
-#endif
-#ifdef CONFIG_ALPHA_SRM_SETUP
-         /*
-          * sigh... For the SRM setup, unless we know apriori what the HAE
-          * contents will be, we need to setup the arbitrary region bases
-          * so we can test against the range of addresses and tailor the
-          *        region chosen for the SPARSE memory access.
-          *
-          * see include/asm-alpha/t2.h for the SPARSE mem read/write
-         */
-         t2_sm_base = (t2_hae_1 << 27) & 0xf8000000UL;
-         /*
-           Set the HAE cache, so that setup_arch() code
-           will use the SRM setting always. Our readb/writeb
-           code in .h expects never to have to change
-           the contents of the HAE.
-          */
-         hae.cache = t2_hae_1;
-#else /* SRM_SETUP */
-         *(vulp)T2_HAE_1 = 0; mb();
-         *(vulp)T2_HAE_2 = 0; mb();
-         *(vulp)T2_HAE_3 = 0; mb();
-#if 0
-         *(vulp)T2_HAE_4 = 0; mb(); /* do not touch this */
-#endif
-#endif /* SRM_SETUP */
-       }
-       return mem_start;
-}
-
-#define SIC_SEIC (1UL << 33)    /* System Event Clear */
-
-static struct sable_cpu_csr *sable_cpu_regs[4] = {
-       (struct sable_cpu_csr *)CPU0_BASE,
-       (struct sable_cpu_csr *)CPU1_BASE,
-       (struct sable_cpu_csr *)CPU2_BASE,
-       (struct sable_cpu_csr *)CPU3_BASE,
-};
-
-int t2_clear_errors(void)
-{
-       unsigned int cpu = smp_processor_id();
-
-       DBGMC(("???????? t2_clear_errors\n"));
-
-       sable_cpu_regs[cpu]->sic &= ~SIC_SEIC;
-
-       /* 
-        * clear CPU errors
-        */
-       sable_cpu_regs[cpu]->bcce |= sable_cpu_regs[cpu]->bcce;
-       sable_cpu_regs[cpu]->cbe  |= sable_cpu_regs[cpu]->cbe;
-       sable_cpu_regs[cpu]->bcue |= sable_cpu_regs[cpu]->bcue;
-       sable_cpu_regs[cpu]->dter |= sable_cpu_regs[cpu]->dter;
-
-       *(vulp)T2_CERR1 |= *(vulp)T2_CERR1;
-       *(vulp)T2_PERR1 |= *(vulp)T2_PERR1;
-
-       mb();
-       mb();  /* magic */
-       return 0;
-}
-
-void t2_machine_check(unsigned long vector, unsigned long la_ptr,
-                     struct pt_regs * regs)
-{
-       struct el_t2_logout_header *mchk_header;
-       struct el_t2_procdata_mcheck *mchk_procdata;
-       struct el_t2_sysdata_mcheck *mchk_sysdata;
-       unsigned long * ptr;
-       const char * reason;
-       char buf[128];
-       long i;
-       unsigned int cpu = smp_processor_id();
-
-       DBGMC(("t2_machine_check: vector=0x%lx la_ptr=0x%lx\n",
-              vector, la_ptr));
-
-       mchk_header = (struct el_t2_logout_header *)la_ptr;
-
-       DBGMC(("t2_machine_check: susoffset=0x%lx procoffset=0x%lx\n",
-              mchk_header->elfl_sysoffset, mchk_header->elfl_procoffset));
-
-       mchk_sysdata = (struct el_t2_sysdata_mcheck *)
-         (la_ptr + mchk_header->elfl_sysoffset);
-       mchk_procdata = (struct el_t2_procdata_mcheck *)
-         (la_ptr + mchk_header->elfl_procoffset - sizeof(unsigned long)*32);
-
-       DBGMC(("         pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
-              regs->pc, mchk_header->elfl_size, mchk_header->elfl_procoffset,
-              mchk_header->elfl_sysoffset));
-       DBGMC(("t2_machine_check: expected %d\n", T2_mcheck_expected[cpu]));
-
-#ifdef DEBUG_DUMP
-       {
-               unsigned long *ptr;
-               int i;
-
-               ptr = (unsigned long *)la_ptr;
-               for (i = 0; i < mchk_header->elfl_size/sizeof(long); i += 2) {
-                       printk(" +%lx %lx %lx\n", i*sizeof(long),
-                              ptr[i], ptr[i+1]);
-               }
-       }
-#endif /* DEBUG_DUMP */
-
-       /*
-        * Check if machine check is due to a badaddr() and if so,
-        * ignore the machine check.
-        */
-       mb();
-       mb();  /* magic */
-       if (T2_mcheck_expected[cpu]) {
-               DBGMC(("T2 machine check expected\n"));
-               T2_mcheck_taken[cpu] = 1;
-               t2_clear_errors();
-               T2_mcheck_expected[cpu] = 0;
-               mb();
-               mb();  /* magic */
-               wrmces(rdmces()|1);/* ??? */
-               draina();
-               return;
-       }
-
-       switch ((unsigned int) mchk_header->elfl_error_type) {
-       case MCHK_K_TPERR:      reason = "tag parity error"; break;
-       case MCHK_K_TCPERR:     reason = "tag control parity error"; break;
-       case MCHK_K_HERR:       reason = "generic hard error"; break;
-       case MCHK_K_ECC_C:      reason = "correctable ECC error"; break;
-       case MCHK_K_ECC_NC:     reason = "uncorrectable ECC error"; break;
-       case MCHK_K_OS_BUGCHECK: reason = "OS-specific PAL bugcheck"; break;
-       case MCHK_K_PAL_BUGCHECK: reason = "callsys in kernel mode"; break;
-       case 0x96: reason = "i-cache read retryable error"; break;
-       case 0x98: reason = "processor detected hard error"; break;
-
-       /* System specific (these are for Alcor, at least): */
-       case 0x203: reason = "system detected uncorrectable ECC error"; break;
-       case 0x205: reason = "parity error detected by T2"; break;
-       case 0x207: reason = "non-existent memory error"; break;
-       case 0x209: reason = "PCI SERR detected"; break;
-       case 0x20b: reason = "PCI data parity error detected"; break;
-       case 0x20d: reason = "PCI address parity error detected"; break;
-       case 0x20f: reason = "PCI master abort error"; break;
-       case 0x211: reason = "PCI target abort error"; break;
-       case 0x213: reason = "scatter/gather PTE invalid error"; break;
-       case 0x215: reason = "flash ROM write error"; break;
-       case 0x217: reason = "IOA timeout detected"; break;
-       case 0x219: reason = "IOCHK#, EISA add-in board parity or other catastrophic error"; break;
-       case 0x21b: reason = "EISA fail-safe timer timeout"; break;
-       case 0x21d: reason = "EISA bus time-out"; break;
-       case 0x21f: reason = "EISA software generated NMI"; break;
-       case 0x221: reason = "unexpected ev5 IRQ[3] interrupt"; break;
-       default:
-               sprintf(buf, "reason for machine-check unknown (0x%x)",
-                       (unsigned int) mchk_header->elfl_error_type);
-               reason = buf;
-               break;
-       }
-       wrmces(rdmces()|1);     /* reset machine check pending flag */
-       mb();
-
-       printk(KERN_CRIT "  T2 machine check: %s%s\n",
-              reason, mchk_header->elfl_retry ? " (retryable)" : "");
-
-       /* dump the logout area to give all info: */
-
-       ptr = (unsigned long *)la_ptr;
-       for (i = 0; i < mchk_header->elfl_size / sizeof(long); i += 2) {
-               printk(KERN_CRIT " +%8lx %016lx %016lx\n",
-                      i*sizeof(long), ptr[i], ptr[i+1]);
-       }
-}
index d6c1a7e4549de023178e1ad33fab3bd8d0decb53..c2fc4c8e692728155c1e6a819e0b488e31ec80a2 100644 (file)
 #include <asm/unaligned.h>
 #include <asm/sysinfo.h>
 
+#include "proto.h"
 
-static void dik_show_regs(struct pt_regs *regs, unsigned long *r9_15)
+static void
+dik_show_regs(struct pt_regs *regs, unsigned long *r9_15)
 {
        printk("pc = [<%016lx>]  ra = [<%016lx>]  ps = %04lx\n",
               regs->pc, regs->r26, regs->ps);
@@ -51,7 +53,8 @@ static void dik_show_regs(struct pt_regs *regs, unsigned long *r9_15)
        printk("gp = %016lx  sp = %p\n", regs->gp, regs+1);
 }
 
-static void dik_show_code(unsigned int *pc)
+static void
+dik_show_code(unsigned int *pc)
 {
        long i;
 
@@ -65,7 +68,8 @@ static void dik_show_code(unsigned int *pc)
        printk("\n");
 }
 
-static void dik_show_trace(unsigned long *sp)
+static void
+dik_show_trace(unsigned long *sp)
 {
        long i = 0;
        printk("Trace:");
@@ -86,8 +90,8 @@ static void dik_show_trace(unsigned long *sp)
        printk("\n");
 }
 
-void die_if_kernel(char * str, struct pt_regs *regs, long err,
-                  unsigned long *r9_15)
+void
+die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
 {
        if (regs->ps & 8)
                return;
@@ -106,21 +110,20 @@ void die_if_kernel(char * str, struct pt_regs *regs, long err,
 }
 
 #ifndef CONFIG_MATHEMU
-static long dummy_alpha_fp_emul_imprecise(struct pt_regs *r, unsigned long wm)
-{
-  return 0;
-}
-
+static long dummy_emul() { return 0; }
 long (*alpha_fp_emul_imprecise)(struct pt_regs *regs, unsigned long writemask)
-  = dummy_alpha_fp_emul_imprecise;
+  = (void *)dummy_emul;
+long (*alpha_fp_emul) (unsigned long pc)
+  = (void *)dummy_emul;
 #else
 long alpha_fp_emul_imprecise(struct pt_regs *regs, unsigned long writemask);
+long alpha_fp_emul (unsigned long pc);
 #endif
 
-asmlinkage void do_entArith(unsigned long summary, unsigned long write_mask,
-                           unsigned long a2, unsigned long a3,
-                           unsigned long a4, unsigned long a5,
-                           struct pt_regs regs)
+asmlinkage void
+do_entArith(unsigned long summary, unsigned long write_mask, unsigned long a2,
+           unsigned long a3, unsigned long a4, unsigned long a5,
+           struct pt_regs regs)
 {
        if ((summary & 1)) {
                /*
@@ -133,8 +136,10 @@ asmlinkage void do_entArith(unsigned long summary, unsigned long write_mask,
        }
 
        lock_kernel();
+#if 0
        printk("%s: arithmetic trap at %016lx: %02lx %016lx\n",
                current->comm, regs.pc, summary, write_mask);
+#endif
        die_if_kernel("Arithmetic fault", &regs, 0, 0);
        force_sig(SIGFPE, current);
        unlock_kernel();
@@ -202,7 +207,6 @@ asmlinkage void do_entIF(unsigned long type, unsigned long a1,
              case 4: /* opDEC */
 #ifdef CONFIG_ALPHA_NEED_ROUNDING_EMULATION
                {
-                       extern long alpha_fp_emul (unsigned long pc);
                        unsigned int opcode;
 
                        /* get opcode of faulting instruction: */
@@ -255,9 +259,10 @@ struct unaligned_stat {
 #define una_reg(r)  (regs.regs[(r) >= 16 && (r) <= 18 ? (r)+19 : (r)])
 
 
-asmlinkage void do_entUna(void * va, unsigned long opcode, unsigned long reg,
-       unsigned long a3, unsigned long a4, unsigned long a5,
-       struct allregs regs)
+asmlinkage void
+do_entUna(void * va, unsigned long opcode, unsigned long reg,
+         unsigned long a3, unsigned long a4, unsigned long a5,
+         struct allregs regs)
 {
        long error, tmp1, tmp2, tmp3, tmp4;
        unsigned long pc = regs.pc - 4;
@@ -497,7 +502,8 @@ got_exception:
  * needs to be remapped to preserve non-finite values
  * (infinities, not-a-numbers, denormals).
  */
-static inline unsigned long s_mem_to_reg (unsigned long s_mem)
+static inline unsigned long
+s_mem_to_reg (unsigned long s_mem)
 {
        unsigned long frac    = (s_mem >>  0) & 0x7fffff;
        unsigned long sign    = (s_mem >> 31) & 0x1;
@@ -524,7 +530,8 @@ static inline unsigned long s_mem_to_reg (unsigned long s_mem)
  * Convert an s-floating point value in register format to the
  * corresponding value in memory format.
  */
-static inline unsigned long s_reg_to_mem (unsigned long s_reg)
+static inline unsigned long
+s_reg_to_mem (unsigned long s_reg)
 {
        return ((s_reg >> 62) << 30) | ((s_reg << 5) >> 34);
 }
@@ -571,12 +578,10 @@ static int unauser_reg_offsets[32] = {
 
 #undef R
 
-asmlinkage void do_entUnaUser(void * va, unsigned long opcode,
-                             unsigned long reg, struct pt_regs *regs)
+asmlinkage void
+do_entUnaUser(void * va, unsigned long opcode,
+             unsigned long reg, struct pt_regs *regs)
 {
-       extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
-       extern unsigned long alpha_read_fp_reg (unsigned long reg);
-
        static int cnt = 0;
        static long last_time = 0;
 
@@ -868,10 +873,10 @@ give_sigbus:
 /*
  * Unimplemented system calls.
  */
-asmlinkage long alpha_ni_syscall(unsigned long a0, unsigned long a1,
-                                unsigned long a2, unsigned long a3,
-                                unsigned long a4, unsigned long a5,
-                                struct pt_regs regs)
+asmlinkage long
+alpha_ni_syscall(unsigned long a0, unsigned long a1, unsigned long a2,
+                unsigned long a3, unsigned long a4, unsigned long a5,
+                struct pt_regs regs)
 {
        /* We only get here for OSF system calls, minus #112;
           the rest go to sys_ni_syscall.  */
@@ -879,17 +884,11 @@ asmlinkage long alpha_ni_syscall(unsigned long a0, unsigned long a1,
        return -ENOSYS;
 }
 
-extern asmlinkage void entMM(void);
-extern asmlinkage void entIF(void);
-extern asmlinkage void entArith(void);
-extern asmlinkage void entUna(void);
-extern asmlinkage void entSys(void);
-
-register unsigned long gptr __asm__("$29");
-
-void trap_init(void)
+void
+trap_init(void)
 {
        /* Tell PAL-code what global pointer we want in the kernel.  */
+       register unsigned long gptr __asm__("$29");
        wrkgp(gptr);
 
        wrent(entArith, 1);
diff --git a/arch/alpha/kernel/tsunami.c b/arch/alpha/kernel/tsunami.c
deleted file mode 100644 (file)
index f351632..0000000
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
- * Code common to all TSUNAMI chips.
- *
- * Based on code written by David A. Rusling (david.rusling@reo.mts.dec.com).
- *
- */
-#include <linux/kernel.h>
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/sched.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/hwrpb.h>
-#include <asm/ptrace.h>
-#include <asm/mmu_context.h>
-
-/*
- * NOTE: Herein lie back-to-back mb instructions.  They are magic. 
- * One plausible explanation is that the I/O controller does not properly
- * handle the system transaction.  Another involves timing.  Ho hum.
- */
-
-extern struct hwrpb_struct *hwrpb;
-extern asmlinkage void wrmces(unsigned long mces);
-
-/*
- * BIOS32-style PCI interface:
- */
-
-#ifdef CONFIG_ALPHA_TSUNAMI
-
-#ifdef DEBUG 
-# define DBG(args)     printk args
-#else
-# define DBG(args)
-#endif
-
-#define DEBUG_MCHECK
-#ifdef DEBUG_MCHECK
-# define DBG_MCK(args) printk args
-#define DEBUG_MCHECK_DUMP
-#else
-# define DBG_MCK(args)
-#endif
-
-#define vuip   volatile unsigned int  *
-#define vulp   volatile unsigned long  *
-
-static volatile unsigned int TSUNAMI_mcheck_expected[NR_CPUS];
-static volatile unsigned int TSUNAMI_mcheck_taken[NR_CPUS];
-static unsigned int TSUNAMI_jd[NR_CPUS];
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-unsigned int TSUNAMI_DMA_WIN_BASE = TSUNAMI_DMA_WIN_BASE_DEFAULT;
-unsigned int TSUNAMI_DMA_WIN_SIZE = TSUNAMI_DMA_WIN_SIZE_DEFAULT;
-#endif /* SRM_SETUP */
-
-/*
- * Given a bus, device, and function number, compute resulting
- * configuration space address
- * accordingly.  It is therefore not safe to have concurrent
- * invocations to configuration space access routines, but there
- * really shouldn't be any need for this.
- *
- * Note that all config space accesses use Type 1 address format.
- *
- * Note also that type 1 is determined by non-zero bus number.
- *
- * Type 1:
- *
- *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *     31:24   reserved
- *     23:16   bus number (8 bits = 128 possible buses)
- *     15:11   Device number (5 bits)
- *     10:8    function number
- *      7:2    register number
- *  
- * Notes:
- *     The function number selects which function of a multi-function device 
- *     (e.g., SCSI and Ethernet).
- * 
- *     The register selects a DWORD (32 bit) register offset.  Hence it
- *     doesn't get shifted by 2 bits as we want to "drop" the bottom two
- *     bits.
- */
-static int mk_conf_addr(unsigned char bus, unsigned char device_fn,
-                       unsigned char where, unsigned long *pci_addr,
-                       unsigned char *type1)
-{
-       unsigned long addr;
-
-       DBG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, pci_addr=0x%p, type1=0x%p)\n",
-            bus, device_fn, where, pci_addr, type1));
-
-       if (bus == 0) {
-               *type1 = 0;
-       } else {
-               /* type 1 configuration cycle: */
-               *type1 = 1;
-       }
-       addr = (bus << 16) | (device_fn << 8) | (where);
-       *pci_addr = addr;
-       DBG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
-       return 0;
-}
-
-int pcibios_read_config_byte (unsigned char bus, unsigned char device_fn,
-                             unsigned char where, unsigned char *value)
-{
-       unsigned long addr;
-       unsigned char type1;
-       unsigned char result;
-
-       *value = 0xff;
-
-       if (mk_conf_addr(bus, device_fn, where, &addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       __asm__ __volatile__ (
-                "ldbu %0,%1"
-                : "=r" (result)
-                : "m"  (*(unsigned char *)(addr+TSUNAMI_PCI0_CONF)));
-
-       *value = result;
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_read_config_word (unsigned char bus, unsigned char device_fn,
-                             unsigned char where, unsigned short *value)
-{
-       unsigned long addr;
-       unsigned char type1;
-       unsigned short result;
-
-       *value = 0xffff;
-
-       if (where & 0x1) {
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-       }
-
-       if (mk_conf_addr(bus, device_fn, where, &addr, &type1)) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       __asm__ __volatile__ (
-                "ldwu %0,%1"
-                : "=r" (result)
-                : "m"  (*(unsigned short *)(addr+TSUNAMI_PCI0_CONF)));
-
-       *value = result;
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_read_config_dword (unsigned char bus, unsigned char device_fn,
-                              unsigned char where, unsigned int *value)
-{
-       unsigned long addr;
-       unsigned char type1;
-       unsigned int result;
-
-       *value = 0xffffffff;
-       if (where & 0x3) {
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-       }
-
-       if (mk_conf_addr(bus, device_fn, where, &addr, &type1)) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       __asm__ __volatile__ (
-                "ldl %0,%1"
-                : "=r" (result)
-                : "m"  (*(unsigned int *)(addr+TSUNAMI_PCI0_CONF)));
-
-       *value = result;
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_write_config_byte (unsigned char bus, unsigned char device_fn,
-                              unsigned char where, unsigned char value)
-{
-       unsigned long addr;
-       unsigned char type1;
-
-       if (mk_conf_addr(bus, device_fn, where, &addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       __asm__ __volatile__ (
-                "stb %1,%0\n\t"
-                "mb"
-                : : "m" (*(unsigned char *)(addr+TSUNAMI_PCI0_CONF)),
-                    "r" (value));
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_write_config_word (unsigned char bus, unsigned char device_fn,
-                              unsigned char where, unsigned short value)
-{
-       unsigned long addr;
-       unsigned char type1;
-
-       if (where & 0x1) {
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-       }
-
-       if (mk_conf_addr(bus, device_fn, where, &addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       __asm__ __volatile__ (
-                "stw %1,%0\n\t"
-                "mb"
-                : : "m" (*(unsigned short *)(addr+TSUNAMI_PCI0_CONF)),
-                    "r" (value));
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-int pcibios_write_config_dword (unsigned char bus, unsigned char device_fn,
-                               unsigned char where, unsigned int value)
-{
-       unsigned long addr;
-       unsigned char type1;
-
-       if (where & 0x3) {
-               return PCIBIOS_BAD_REGISTER_NUMBER;
-       }
-
-       if (mk_conf_addr(bus, device_fn, where, &addr, &type1) < 0) {
-               return PCIBIOS_SUCCESSFUL;
-       }
-
-       __asm__ __volatile__ (
-                "stl %1,%0\n\t"
-                "mb"
-                : : "m" (*(unsigned int *)(addr+TSUNAMI_PCI0_CONF)),
-                    "r" (value));
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-
-unsigned long tsunami_init(unsigned long mem_start, unsigned long mem_end)
-{
-        unsigned long tsunami_err;
-       unsigned int i;
-
-#if 0
-printk("tsunami_init: CChip registers:\n");
-printk("tsunami_init: CSR_CSC 0x%lx\n", *(vulp)TSUNAMI_CSR_CSC);
-printk("tsunami_init: CSR_MTR 0x%lx\n", *(vulp)TSUNAMI_CSR_MTR);
-printk("tsunami_init: CSR_MISC 0x%lx\n", *(vulp)TSUNAMI_CSR_MISC);
-printk("tsunami_init: CSR_DIM0 0x%lx\n", *(vulp)TSUNAMI_CSR_DIM0);
-printk("tsunami_init: CSR_DIM1 0x%lx\n", *(vulp)TSUNAMI_CSR_DIM1);
-printk("tsunami_init: CSR_DIR0 0x%lx\n", *(vulp)TSUNAMI_CSR_DIR0);
-printk("tsunami_init: CSR_DIR1 0x%lx\n", *(vulp)TSUNAMI_CSR_DIR1);
-printk("tsunami_init: CSR_DRIR 0x%lx\n", *(vulp)TSUNAMI_CSR_DRIR);
-
-printk("tsunami_init: DChip registers:\n");
-printk("tsunami_init: CSR_DSC 0x%lx\n", *(vulp)TSUNAMI_CSR_DSC);
-printk("tsunami_init: CSR_STR 0x%lx\n", *(vulp)TSUNAMI_CSR_STR);
-printk("tsunami_init: CSR_DREV 0x%lx\n", *(vulp)TSUNAMI_CSR_DREV);
-
-printk("tsunami_init: PChip registers:\n");
-printk("tsunami_init: PCHIP0_WSBA0 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSBA0);
-printk("tsunami_init: PCHIP0_WSBA1 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSBA1);
-printk("tsunami_init: PCHIP0_WSBA2 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSBA2);
-printk("tsunami_init: PCHIP0_WSBA3 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSBA3);
-printk("tsunami_init: PCHIP0_WSM0 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSM0);
-printk("tsunami_init: PCHIP0_WSM1 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSM1);
-printk("tsunami_init: PCHIP0_WSM2 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSM2);
-printk("tsunami_init: PCHIP0_WSM3 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSM3);
-printk("tsunami_init: PCHIP0_TBA0 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_TBA0);
-printk("tsunami_init: PCHIP0_TBA1 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_TBA1);
-printk("tsunami_init: PCHIP0_TBA2 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_TBA2);
-printk("tsunami_init: PCHIP0_TBA3 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_TBA3);
-
-printk("tsunami_init: PCHIP0_PCTL 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_PCTL);
-printk("tsunami_init: PCHIP0_PLAT 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_PLAT);
-printk("tsunami_init: PCHIP0_PERROR 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_PERROR);
-printk("tsunami_init: PCHIP0_PERRMASK 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_PERRMASK);
-
-#endif
-
-       for (i = 0; i < NR_CPUS; i++) {
-               TSUNAMI_mcheck_expected[i] = 0;
-               TSUNAMI_mcheck_taken[i] = 0;
-       }
-#ifdef NOT_YET
-        /* 
-        * Set up error reporting. Make sure CPU_PE is OFF in the mask.
-        */
-       tsunami_err = *(vulp)TSUNAMI_PCHIP0_PERRMASK;
-       tsunami_err &= ~20;   
-       *(vulp)TSUNAMI_PCHIP0_PERRMASK = tsunami_err;
-       mb();
-       tsunami_err = *(vulp)TSUNAMI_PCHIP0_PERRMASK;
-
-       tsunami_err = *(vulp)TSUNAMI_PCHIP0_PERROR ;
-       tsunami_err |= 0x40;   /* master/target abort */
-       *(vulp)TSUNAMI_PCHIP0_PERROR = tsunami_err ;
-       mb() ;
-       tsunami_err = *(vulp)TSUNAMI_PCHIP0_PERROR ;
-#endif /* NOT_YET */
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-       /* check window 0 for enabled and mapped to 0 */
-       if (((*(vulp)TSUNAMI_PCHIP0_WSBA0 & 3) == 1) &&
-           (*(vulp)TSUNAMI_PCHIP0_TBA0 == 0) &&
-           ((*(vulp)TSUNAMI_PCHIP0_WSM0 & 0xfff00000U) > 0x0ff00000U))
-       {
-         TSUNAMI_DMA_WIN_BASE = *(vulp)TSUNAMI_PCHIP0_WSBA0 & 0xfff00000U;
-         TSUNAMI_DMA_WIN_SIZE = *(vulp)TSUNAMI_PCHIP0_WSM0 & 0xfff00000U;
-         TSUNAMI_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-         printk("tsunami_init: using Window 0 settings\n");
-         printk("tsunami_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-                *(vulp)TSUNAMI_PCHIP0_WSBA0,
-                *(vulp)TSUNAMI_PCHIP0_WSM0,
-                *(vulp)TSUNAMI_PCHIP0_TBA0);
-#endif
-       }
-       else  /* check window 1 for enabled and mapped to 0 */
-       if (((*(vulp)TSUNAMI_PCHIP0_WSBA1 & 3) == 1) &&
-           (*(vulp)TSUNAMI_PCHIP0_TBA1 == 0) &&
-           ((*(vulp)TSUNAMI_PCHIP0_WSM1 & 0xfff00000U) > 0x0ff00000U))
-{
-         TSUNAMI_DMA_WIN_BASE = *(vulp)TSUNAMI_PCHIP0_WSBA1 & 0xfff00000U;
-         TSUNAMI_DMA_WIN_SIZE = *(vulp)TSUNAMI_PCHIP0_WSM1 & 0xfff00000U;
-         TSUNAMI_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-         printk("tsunami_init: using Window 1 settings\n");
-         printk("tsunami_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-                *(vulp)TSUNAMI_PCHIP0_WSBA1,
-                *(vulp)TSUNAMI_PCHIP0_WSM1,
-                *(vulp)TSUNAMI_PCHIP0_TBA1);
-#endif
-       }
-       else  /* check window 2 for enabled and mapped to 0 */
-       if (((*(vulp)TSUNAMI_PCHIP0_WSBA2 & 3) == 1) &&
-           (*(vulp)TSUNAMI_PCHIP0_TSB2 == 0) &&
-           ((*(vulp)TSUNAMI_PCHIP0_WSM2 & 0xfff00000U) > 0x0ff00000U))
-       {
-         TSUNAMI_DMA_WIN_BASE = *(vulp)TSUNAMI_PCHIP0_WSBA2 & 0xfff00000U;
-         TSUNAMI_DMA_WIN_SIZE = *(vulp)TSUNAMI_PCHIP0_WSM2 & 0xfff00000U;
-         TSUNAMI_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-         printk("tsunami_init: using Window 2 settings\n");
-         printk("tsunami_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-                *(vulp)TSUNAMI_PCHIP0_WSBA2,
-                *(vulp)TSUNAMI_PCHIP0_WSM2,
-                *(vulp)TSUNAMI_PCHIP0_TSB2);
-#endif
-       }
-       else  /* check window 3 for enabled and mapped to 0 */
-       if (((*(vulp)TSUNAMI_PCHIP0_WSBA3 & 3) == 1) &&
-           (*(vulp)TSUNAMI_PCHIP0_TBA3 == 0) &&
-           ((*(vulp)TSUNAMI_PCHIP0_WSM3 & 0xfff00000U) > 0x0ff00000U))
-       {
-         TSUNAMI_DMA_WIN_BASE = *(vulp)TSUNAMI_PCHIP0_WSBA3 & 0xfff00000U;
-         TSUNAMI_DMA_WIN_SIZE = *(vulp)TSUNAMI_PCHIP0_WSM3 & 0xfff00000U;
-         TSUNAMI_DMA_WIN_SIZE += 0x00100000U;
-#if 1
-         printk("tsunami_init: using Window 3 settings\n");
-         printk("tsunami_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n",
-                *(vulp)TSUNAMI_PCHIP0_WSBA3,
-                *(vulp)TSUNAMI_PCHIP0_WSM3,
-                *(vulp)TSUNAMI_PCHIP0_TBA3);
-#endif
-       }
-       else  /* we must use our defaults which were pre-initialized... */
-#endif /* SRM_SETUP */
-       {
-       /*
-        * Set up the PCI->physical memory translation windows.
-        * For now, windows 1,2 and 3 are disabled.  In the future, we may
-        * want to use them to do scatter/gather DMA.  Window 0
-        * goes at 1 GB and is 1 GB large.
-        */
-
-        *(vulp)TSUNAMI_PCHIP0_WSBA0 = 1L | (TSUNAMI_DMA_WIN_BASE & 0xfff00000U);
-        *(vulp)TSUNAMI_PCHIP0_WSM0 = (TSUNAMI_DMA_WIN_SIZE - 1) & 0xfff00000UL;
-        *(vulp)TSUNAMI_PCHIP0_TBA0 = 0UL;
-
-        *(vulp)TSUNAMI_PCHIP0_WSBA1 = 0UL;
-        *(vulp)TSUNAMI_PCHIP0_WSBA2 = 0UL;
-        *(vulp)TSUNAMI_PCHIP0_WSBA3 = 0UL;
-       mb();
-       }
-
-       /*
-        * check ASN in HWRPB for validity, report if bad
-        */
-       if (hwrpb->max_asn != MAX_ASN) {
-               printk("TSUNAMI_init: max ASN from HWRPB is bad (0x%lx)\n",
-                       hwrpb->max_asn);
-               hwrpb->max_asn = MAX_ASN;
-       }
-
-       return mem_start;
-}
-
-int tsunami_pci_clr_err(void)
-{
-       unsigned int cpu = smp_processor_id();
-
-       TSUNAMI_jd[cpu] = *((vulp)TSUNAMI_PCHIP0_PERROR);
-       DBG(("TSUNAMI_pci_clr_err: PERROR after read 0x%x\n", TSUNAMI_jd[cpu]));
-       *((vulp)TSUNAMI_PCHIP0_PERROR) = 0x040; mb();
-       TSUNAMI_jd[cpu] = *((vulp)TSUNAMI_PCHIP0_PERROR);
-       return 0;
-}
-
-void tsunami_machine_check(unsigned long vector, unsigned long la_ptr,
-                        struct pt_regs * regs)
-{
-#if 1
-        printk("TSUNAMI machine check ignored\n") ;
-#else
-       struct el_common *mchk_header;
-       struct el_TSUNAMI_sysdata_mcheck *mchk_sysdata;
-       unsigned int cpu = smp_processor_id();
-
-       mchk_header = (struct el_common *)la_ptr;
-
-       mchk_sysdata = 
-         (struct el_TSUNAMI_sysdata_mcheck *)(la_ptr + mchk_header->sys_offset);
-
-#if 0
-       DBG_MCK(("tsunami_machine_check: vector=0x%lx la_ptr=0x%lx\n",
-            vector, la_ptr));
-       DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
-            regs->pc, mchk_header->size, mchk_header->proc_offset,
-            mchk_header->sys_offset));
-       DBG_MCK(("tsunami_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
-            TSUNAMI_mcheck_expected[cpu], mchk_sysdata->epic_dcsr,
-            mchk_sysdata->epic_pear));
-#endif
-#ifdef DEBUG_MCHECK_DUMP
-       {
-           unsigned long *ptr;
-           int i;
-
-           ptr = (unsigned long *)la_ptr;
-           for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
-               printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
-           }
-       }
-#endif /* DEBUG_MCHECK_DUMP */
-       /*
-        * Check if machine check is due to a badaddr() and if so,
-        * ignore the machine check.
-        */
-       mb();
-       mb();  /* magic */
-       if (TSUNAMI_mcheck_expected[cpu]) {
-               DBG(("TSUNAMI machine check expected\n"));
-               TSUNAMI_mcheck_expected[cpu] = 0;
-               TSUNAMI_mcheck_taken[cpu] = 1;
-               mb();
-               mb();  /* magic */
-               draina();
-               tsunami_pci_clr_err();
-               wrmces(0x7);
-               mb();
-       }
-#if 1
-       else {
-               printk("TSUNAMI machine check NOT expected\n") ;
-       DBG_MCK(("tsunami_machine_check: vector=0x%lx la_ptr=0x%lx\n",
-            vector, la_ptr));
-       DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
-            regs->pc, mchk_header->size, mchk_header->proc_offset,
-            mchk_header->sys_offset));
-               TSUNAMI_mcheck_expected[cpu] = 0;
-               TSUNAMI_mcheck_taken[cpu] = 1;
-               mb();
-               mb();  /* magic */
-               draina();
-               tsunami_pci_clr_err();
-               wrmces(0x7);
-               mb();
-       }
-#endif
-#endif
-}
-
-#endif /* CONFIG_ALPHA_TSUNAMI */
index 7c1e37bac683c48cd87cb6b94630422b40db165d..4dd7d591d770a209ad757492aabb46402e42267f 100644 (file)
@@ -7,7 +7,7 @@ OBJS  = __divqu.o __remqu.o __divlu.o __remlu.o memset.o memcpy.o io.o \
        strcat.o strcpy.o strncat.o strncpy.o stxcpy.o stxncpy.o \
        strchr.o strrchr.o \
        copy_user.o clear_user.o strncpy_from_user.o strlen_user.o \
-       csum_ipv6_magic.o
+       csum_ipv6_magic.o strcasecmp.o
 
 lib.a: $(OBJS)
        $(AR) rcs lib.a $(OBJS)
index 7c99fe5aea181327c51be834edb7b7d74b8d4879..50cc1fe05ceeac03aba2b34486cae53a4f3f5794 100644 (file)
@@ -6,23 +6,6 @@
 #include <linux/types.h>
 #include <asm/io.h>
 
-/* 
- * Jensen has a separate "local" and "bus" IO space for
- * byte-wide IO.
- */
-#ifdef __is_local
-
-unsigned int _bus_inb(unsigned long addr)
-{
-       return __bus_inb(addr);
-}
-
-void _bus_outb(unsigned char b, unsigned long addr)
-{
-       __bus_outb(b, addr);
-}
-#endif
-
 unsigned int _inb(unsigned long addr)
 {
        return __inb(addr);
@@ -470,47 +453,57 @@ void _memcpy_toio(unsigned long to, void * from, long count)
 
 /*
  * "memset" on IO memory space.
- * This needs to be optimized.
  */
 void _memset_c_io(unsigned long to, unsigned long c, long count)
 {
+       /* Handle any initial odd byte */
        if (count > 0 && (to & 1)) {
                writeb(c, to);
                to++;
                count--;
        }
+
+       /* Handle any initial odd halfword */
        if (count >= 2 && (to & 2)) {
                writew(c, to);
                to += 2;
                count -= 2;
        }
+
+       /* Handle any initial odd word */
        if (count >= 4 && (to & 4)) {
                writel(c, to);
                to += 4;
                count -= 4;
        }
-       if ((to & 7) == 0) {
-               count -= 8;
-               while (count >= 0) {
+
+       /* Handle all full-sized quadwords: we're aligned (or have a small count) */
+       count -= 8;
+       if (count >= 0) {
+               do {
                        writeq(c, to);
                        to += 8;
                        count -= 8;
-               }
-               count += 8;
+               } while (count >= 0);
        }
-       if (count >= 4 && (to & 4)) {
+       count += 8;
+
+       /* The tail is word-aligned if we still have count >= 4 */
+       if (count >= 4) {
                writel(c, to);
                to += 4;
                count -= 4;
        }
-       if (count >= 2 && (to & 2)) {
+
+       /* The tail is half-word aligned if we have count >= 2 */
+       if (count >= 2) {
                writew(c, to);
                to += 2;
                count -= 2;
        }
-       while (count > 0) {
+
+       /* And finally, one last byte.. */
+       if (count) {
                writeb(c, to);
-               count--;
-               to++;
        }
 }
diff --git a/arch/alpha/lib/strcasecmp.c b/arch/alpha/lib/strcasecmp.c
new file mode 100644 (file)
index 0000000..4e57a21
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ *  linux/arch/alpha/lib/strcasecmp.c
+ */
+
+#include <linux/string.h>
+
+
+/* We handle nothing here except the C locale.  Since this is used in
+   only one place, on strings known to contain only 7 bit ASCII, this
+   is ok.  */
+
+int strcasecmp(const char *a, const char *b)
+{
+       int ca, cb;
+
+       do {
+               ca = *a++ & 0xff;
+               cb = *b++ & 0xff;
+               if (ca >= 'A' && ca <= 'Z')
+                       ca += 'a' - 'A';
+               if (cb >= 'A' && cb <= 'Z')
+                       cb += 'a' - 'A';
+       } while (ca == cb && ca != '\0');
+
+       return ca - cb;
+}
index b3c10887b4ca1e530cb975d2998158e0c16183d8..97f4bc3267f2b7ae10d802fc5bc78caeabce1ef3 100644 (file)
@@ -61,23 +61,33 @@ extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
 MODULE_DESCRIPTION("FP Software completion module");
 
 extern long (*alpha_fp_emul_imprecise)(struct pt_regs *, unsigned long);
-static long (*save_emul)(struct pt_regs *, unsigned long);
+extern long (*alpha_fp_emul) (unsigned long pc);
+
+static long (*save_emul_imprecise)(struct pt_regs *, unsigned long);
+static long (*save_emul) (unsigned long pc);
+
 long do_alpha_fp_emul_imprecise(struct pt_regs *, unsigned long);
+long do_alpha_fp_emul(unsigned long);
 
 int init_module(void)
 {
-       save_emul = alpha_fp_emul_imprecise;
+       save_emul_imprecise = alpha_fp_emul_imprecise;
+       save_emul = alpha_fp_emul;
        alpha_fp_emul_imprecise = do_alpha_fp_emul_imprecise;
+       alpha_fp_emul = do_alpha_fp_emul;
        return 0;
 }
 
 void cleanup_module(void)
 {
-       alpha_fp_emul_imprecise = save_emul;
+       alpha_fp_emul_imprecise = save_emul_imprecise;
+       alpha_fp_emul = save_emul;
 }
 
-#undef alpha_fp_emul_imprecise
-#define alpha_fp_emul_imprecise  do_alpha_fp_emul_imprecise
+#undef  alpha_fp_emul_imprecise
+#define alpha_fp_emul_imprecise                do_alpha_fp_emul_imprecise
+#undef  alpha_fp_emul
+#define alpha_fp_emul                  do_alpha_fp_emul
 
 #endif /* MODULE */
 
@@ -96,6 +106,8 @@ alpha_fp_emul (unsigned long pc)
        unsigned long va, vb, vc, res, fpcr;
        __u32 insn;
 
+       MOD_INC_USE_COUNT;
+
        get_user(insn, (__u32*)pc);
        fc     = (insn >>  0) &  0x1f;  /* destination register */
        func   = (insn >>  5) & 0x7ff;
@@ -105,8 +117,8 @@ alpha_fp_emul (unsigned long pc)
        
        va = alpha_read_fp_reg(fa);
        vb = alpha_read_fp_reg(fb);
-
        fpcr = rdfpcr();
+
        /*
         * Try the operation in software.  First, obtain the rounding
         * mode...
@@ -213,8 +225,10 @@ alpha_fp_emul (unsigned long pc)
              default:
                printk("alpha_fp_emul: unexpected function code %#lx at %#lx\n",
                       func & 0x3f, pc);
+               MOD_DEC_USE_COUNT;
                return 0;
        }
+
        /*
         * Take the appropriate action for each possible
         * floating-point result:
@@ -237,8 +251,10 @@ alpha_fp_emul (unsigned long pc)
                wrfpcr(fpcr);
 
                /* Do we generate a signal?  */
-               if (res >> 51 & fpcw & IEEE_TRAP_ENABLE_MASK)
+               if (res >> 51 & fpcw & IEEE_TRAP_ENABLE_MASK) {
+                       MOD_DEC_USE_COUNT;
                        return 0;
+               }
        }
 
        /*
@@ -247,6 +263,8 @@ alpha_fp_emul (unsigned long pc)
         * result:
         */
        alpha_write_fp_reg(fc, vc);
+
+       MOD_DEC_USE_COUNT;
        return 1;
 }
 
index 647456833aa90936c847940712479f13fb04021d..f2d5cc763534f3f236327afd2832e1cb737c4bc1 100644 (file)
@@ -4,23 +4,31 @@
  *  Copyright (C) 1995  Linus Torvalds
  */
 
-#include <linux/signal.h>
 #include <linux/sched.h>
-#include <linux/head.h>
 #include <linux/kernel.h>
+#include <linux/mm.h>
+
+#define __EXTERN_INLINE inline
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#undef  __EXTERN_INLINE
+
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/head.h>
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/ptrace.h>
 #include <linux/mman.h>
-#include <linux/mm.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/mmu_context.h>
+
+extern void die_if_kernel(char *,struct pt_regs *,long, unsigned long *);
+
 
 #ifdef __SMP__
 unsigned long last_asn[NR_CPUS] = { /* gag */
@@ -61,21 +69,26 @@ unsigned long last_asn[NR_CPUS] = { /* gag */
 unsigned long asn_cache = ASN_FIRST_VERSION;
 #endif /* __SMP__ */
 
-#ifndef BROKEN_ASN
 /*
- * Select a new ASN and reload the context. This is
- * not inlined as this expands to a pretty large
- * function.
+ * Select a new ASN for a task.
  */
-void get_new_asn_and_reload(struct task_struct *tsk, struct mm_struct *mm)
+
+void
+get_new_mmu_context(struct task_struct *p, struct mm_struct *mm)
 {
-       mm->context = 0;
-       get_new_mmu_context(tsk, mm);
-       reload_context(tsk);
-}
-#endif
+       unsigned long asn = asn_cache;
 
-extern void die_if_kernel(char *,struct pt_regs *,long, unsigned long *);
+       if ((asn & HARDWARE_ASN_MASK) < MAX_ASN)
+               ++asn;
+       else {
+               tbiap();
+               imb();
+               asn = (asn & ~HARDWARE_ASN_MASK) + ASN_FIRST_VERSION;
+       }
+       asn_cache = asn;
+       mm->context = asn;                      /* full version + asn */
+       p->tss.asn = asn & HARDWARE_ASN_MASK;   /* just asn */
+}
 
 /*
  * This routine handles page faults.  It determines the address,
@@ -99,12 +112,13 @@ extern void die_if_kernel(char *,struct pt_regs *,long, unsigned long *);
  */
 
 /* Macro for exception fixup code to access integer registers.  */
-#define dpf_reg(r) \
-       (((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-16 : \
+#define dpf_reg(r)                                                     \
+       (((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-16 :  \
                                 (r) <= 18 ? (r)+8 : (r)-10])
 
-asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr,
-                             long cause, struct pt_regs *regs)
+asmlinkage void
+do_page_fault(unsigned long address, unsigned long mmcsr,
+             long cause, struct pt_regs *regs)
 {
        struct vm_area_struct * vma;
        struct mm_struct *mm = current->mm;
index 3e1437cc12dcd6c22e00dd36a3626423e4d82716..85b1e3e07d203018dca08b270776fe9e05d5d7c1 100644 (file)
@@ -32,19 +32,22 @@ struct thread_struct * original_pcb_ptr;
 struct pgtable_cache_struct quicklists;
 #endif
 
-void __bad_pmd(pgd_t *pgd)
+void
+__bad_pmd(pgd_t *pgd)
 {
        printk("Bad pgd in pmd_alloc: %08lx\n", pgd_val(*pgd));
        pgd_set(pgd, BAD_PAGETABLE);
 }
 
-void __bad_pte(pmd_t *pmd)
+void
+__bad_pte(pmd_t *pmd)
 {
        printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
        pmd_set(pmd, (pte_t *) BAD_PAGETABLE);
 }
 
-pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset)
+pmd_t *
+get_pmd_slow(pgd_t *pgd, unsigned long offset)
 {
        pmd_t *pmd;
 
@@ -66,7 +69,8 @@ pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset)
        return (pmd_t *) pgd_page(*pgd) + offset;
 }
 
-pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
+pte_t *
+get_pte_slow(pmd_t *pmd, unsigned long offset)
 {
        pte_t *pte;
 
@@ -117,22 +121,25 @@ int do_check_pgt_cache(int low, int high)
  * ZERO_PAGE is a special page that is used for zero-initialized
  * data and COW.
  */
-pmd_t * __bad_pagetable(void)
+pmd_t *
+__bad_pagetable(void)
 {
        memset((void *) EMPTY_PGT, 0, PAGE_SIZE);
        return (pmd_t *) EMPTY_PGT;
 }
 
-pte_t __bad_page(void)
+pte_t
+__bad_page(void)
 {
        memset((void *) EMPTY_PGE, 0, PAGE_SIZE);
        return pte_mkdirty(mk_pte((unsigned long) EMPTY_PGE, PAGE_SHARED));
 }
 
-void show_mem(void)
+void
+show_mem(void)
 {
-       int i,free = 0,total = 0,reserved = 0;
-       int shared = 0, cached = 0;
+       long i,free = 0,total = 0,reserved = 0;
+       long shared = 0, cached = 0;
 
        printk("\nMem-info:\n");
        show_free_areas();
@@ -149,12 +156,12 @@ void show_mem(void)
                else
                        shared += atomic_read(&mem_map[i].count) - 1;
        }
-       printk("%d pages of RAM\n",total);
-       printk("%d free pages\n",free);
-       printk("%d reserved pages\n",reserved);
-       printk("%d pages shared\n",shared);
-       printk("%d pages swap cached\n",cached);
-       printk("%d pages in page table cache\n",pgtable_cache_size);
+       printk("%ld pages of RAM\n",total);
+       printk("%ld free pages\n",free);
+       printk("%ld reserved pages\n",reserved);
+       printk("%ld pages shared\n",shared);
+       printk("%ld pages swap cached\n",cached);
+       printk("%ld pages in page table cache\n",pgtable_cache_size);
        show_buffers();
 #ifdef CONFIG_NET
        show_net_buffers();
@@ -163,29 +170,20 @@ void show_mem(void)
 
 extern unsigned long free_area_init(unsigned long, unsigned long);
 
-static struct thread_struct * load_PCB(struct thread_struct * pcb)
+static struct thread_struct *
+load_PCB(struct thread_struct * pcb)
 {
-       struct thread_struct *old_pcb;
-
-       __asm__ __volatile__(
-               "stq $30,0(%1)\n\t"
-               "bis %1,%1,$16\n\t"
-#ifdef CONFIG_ALPHA_DP264
-               "zap $16,0xe0,$16\n\t"
-#endif /* DP264 */
-               "call_pal %2\n\t"
-               "bis $0,$0,%0"
-               : "=r" (old_pcb)
-               : "r" (pcb), "i" (PAL_swpctx)
-               : "$0", "$1", "$16", "$22", "$23", "$24", "$25");
-       return old_pcb;
+       register unsigned long sp __asm__("$30");
+       pcb->ksp = sp;
+       return __reload_tss(pcb);
 }
 
 /*
  * paging_init() sets up the page tables: in the alpha version this actually
  * unmaps the bootup page table (as we're now in KSEG, so we don't need it).
  */
-unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
+unsigned long
+paging_init(unsigned long start_mem, unsigned long end_mem)
 {
        int i;
        unsigned long newptbr;
@@ -242,7 +240,8 @@ printk("OKSP 0x%lx OPTBR 0x%lx\n",
  * note that current should be pointing at the idle thread task struct
  * for this CPU.
  */
-void paging_init_secondary(void)
+void
+paging_init_secondary(void)
 {
        current->tss.ptbr = init_task.tss.ptbr;
        current->tss.pal_flags = 1;
@@ -260,7 +259,8 @@ printk("paging_init_secondary: KSP 0x%lx PTBR 0x%lx\n",
 }
 #endif /* __SMP__ */
 
-void mem_init(unsigned long start_mem, unsigned long end_mem)
+void
+mem_init(unsigned long start_mem, unsigned long end_mem)
 {
        unsigned long tmp;
 
@@ -291,7 +291,8 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
        return;
 }
 
-void free_initmem (void)
+void
+free_initmem (void)
 {
        extern char __init_begin, __init_end;
        unsigned long addr;
@@ -306,7 +307,8 @@ void free_initmem (void)
                (&__init_end - &__init_begin) >> 10);
 }
 
-void si_meminfo(struct sysinfo *val)
+void
+si_meminfo(struct sysinfo *val)
 {
        int i;
 
index 58cc0d38b52867e1b6603d993d0f3dabcbe9d6d9..b67cd20d68a95153eb16a8ccd4da9513f2400b30 100644 (file)
@@ -396,7 +396,7 @@ ENTRY(sys_call_table)
        .long SYMBOL_NAME(sys_lseek)
        .long SYMBOL_NAME(sys_getpid)           /* 20 */
        .long SYMBOL_NAME(sys_mount)
-       .long SYMBOL_NAME(sys_umount)
+       .long SYMBOL_NAME(sys_oldumount)
        .long SYMBOL_NAME(sys_setuid)
        .long SYMBOL_NAME(sys_getuid)
        .long SYMBOL_NAME(sys_stime)            /* 25 */
@@ -426,7 +426,7 @@ ENTRY(sys_call_table)
        .long SYMBOL_NAME(sys_geteuid)
        .long SYMBOL_NAME(sys_getegid)          /* 50 */
        .long SYMBOL_NAME(sys_acct)
-       .long SYMBOL_NAME(sys_ni_syscall)                               /* old phys syscall holder */
+       .long SYMBOL_NAME(sys_umount)                                   /* recycled never used phys() */
        .long SYMBOL_NAME(sys_ni_syscall)                               /* old lock syscall holder */
        .long SYMBOL_NAME(sys_ioctl)
        .long SYMBOL_NAME(sys_fcntl)            /* 55 */
index 46fa4ad701c15a8dda5db63d288dbed3097890e8..0697306a70d2aa8ee426f9e1dbdcf236f7ab788c 100644 (file)
@@ -241,9 +241,6 @@ is386:      pushl %ecx              # restore original EFLAGS
 #endif
        xorl %eax,%eax
        lldt %ax
-       pushl %eax              # These are the parameters to main :-)
-       pushl %eax
-       pushl %eax
        cld                     # gcc2 wants the direction flag cleared at all times
        call SYMBOL_NAME(start_kernel)
 L6:
index 330a15982920233a596e3ef5d0cb6c4169338d0b..84eaf4962d7e0165d1529b088f40ab04d0cb7137 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/console.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
+#include <asm/io.h>
 #include <asm/smp.h>
 
 /*
@@ -81,12 +82,10 @@ extern int rd_image_start;  /* starting block # of image */
 extern int root_mountflags;
 extern int _etext, _edata, _end;
 
-extern char empty_zero_page[PAGE_SIZE];
-
 /*
  * This is set up by the setup-routine at boot-time
  */
-#define PARAM  empty_zero_page
+#define PARAM  ((unsigned char *)empty_zero_page)
 #define EXT_MEM_K (*(unsigned short *) (PARAM+2))
 #define ALT_MEM_K (*(unsigned long *) (PARAM+0x1e0))
 #ifdef CONFIG_APM
@@ -255,6 +254,27 @@ __initfunc(static int amd_model(struct cpuinfo_x86 *c))
        return 1;
 }
 
+/*
+ *      Cyrix CPU configuration register indexes
+ */
+#define CX86_CCR2 0xc2
+#define CX86_CCR3 0xc3
+#define CX86_CCR4 0xe8
+#define CX86_CCR5 0xe9
+#define CX86_DIR0 0xfe
+#define CX86_DIR1 0xff
+
+/*
+ *      Cyrix CPU indexed register access macros
+ */
+
+#define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); })
+
+#define setCx86(reg, data) do { \
+       outb((reg), 0x22); \
+       outb((data), 0x23); \
+} while (0)
+
 /*
  * Use the Cyrix DEVID CPU registers if avail. to get more detailed info.
  */
index b45bf2ec90d258d0121a2ff64986f88e1165ab7f..8116648a3c5e8e140ed683e5d359028eb47a73fa 100644 (file)
@@ -1101,7 +1101,6 @@ __initfunc(void device_setup(void))
        extern int soc_probe(void);
 #endif
        struct gendisk *p;
-       int nr=0;
 
 #ifdef CONFIG_PARPORT
        parport_init();
@@ -1123,10 +1122,9 @@ __initfunc(void device_setup(void))
        console_map_init();
 #endif
 
-       for (p = gendisk_head ; p ; p=p->next) {
+       for (p = gendisk_head ; p ; p=p->next)
                setup_dev(p);
-               nr += p->nr_real;
-       }
+
 #ifdef CONFIG_BLK_DEV_RAM
 #ifdef CONFIG_BLK_DEV_INITRD
        if (initrd_start && mount_initrd) initrd_load();
@@ -1138,3 +1136,25 @@ __initfunc(void device_setup(void))
         md_setup_drive();
 #endif
 }
+
+#ifdef CONFIG_PROC_FS
+int get_partition_list(char * page)
+{
+       struct gendisk *p;
+       char buf[8];
+       int n, len;
+
+       len = sprintf(page, "major minor  #blocks  name\n\n");
+       for (p = gendisk_head; p; p = p->next) {
+               for (n=0; n < (p->nr_real << p->minor_shift); n++) {
+                       if (p->part[n].nr_sects && len < PAGE_SIZE - 80) {
+                               len += sprintf(page+len,
+                                              "%4d  %4d %10d %s\n",
+                                              p->major, n, p->sizes[n],
+                                              disk_name(p, n, buf));
+                       }
+               }
+       }
+       return len;
+}
+#endif
index af64cb00873acdea7aa62ac7c81e68f8003879ec..268c9187aa3e23365569092383f1ef053a3dded4 100644 (file)
@@ -6,14 +6,13 @@
  * Copyright 1993 by Theodore Ts'o.  Redistribution of this file is
  * permitted under the GNU Public License.
  *
- * more DES encryption plus IDEA encryption by Nicholas J. Leon, June 20, 1996
  * DES encryption plus some minor changes by Werner Almesberger, 30-MAY-1993
+ * more DES encryption plus IDEA encryption by Nicholas J. Leon, June 20, 1996
  *
  * Modularized and updated for 1.1.16 kernel - Mitch Dsouza 28th May 1994
- *
  * Adapted for 1.3.59 kernel - Andries Brouwer, 1 Feb 1996
  *
- * Fixed do_loop_request() re-entrancy - <Vincent.Renardias@waw.com> Mar 20, 1997
+ * Fixed do_loop_request() re-entrancy - Vincent.Renardias@waw.com Mar 20, 1997
  *
  * Handle sparse backing files correctly - Kenn Humborg, Jun 28, 1998
  */
@@ -427,7 +426,11 @@ static int loop_set_fd(struct loop_device *lo, kdev_t dev, unsigned int arg)
                        lo->lo_backing_file->f_op = file->f_op;
                        lo->lo_backing_file->private_data = file->private_data;
 
-                       error = 0;
+                       error = get_write_access(inode); /* cannot fail */
+                       if (error) {
+                               fput(lo->lo_backing_file);
+                               lo->lo_backing_file = NULL;
+                       }
                }
        }
        if (error)
index 2b067884967957746809970250008c3fee11ffb6..a502fedf679886602299af17b0514f54a1265ad9 100644 (file)
@@ -249,7 +249,7 @@ __initfunc(void ide_init_trm290 (ide_hwif_t *hwif))
        ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3);
        hwif->dmaproc = &trm290_dmaproc;
        hwif->selectproc = &trm290_selectproc;
-       hwif->no_autodma = 1;                           /* play it safe for now */
+       hwif->autodma = 0;                              /* play it safe for now */
 #if 1
        {
                /*
index 8ed9e9643043d9d1e8633793067f4e48949c31be..e9e964c4308d1e887e580b0dbc501321c824e417 100644 (file)
@@ -515,6 +515,8 @@ static int apm_get_power_status(u_short *status, u_short *bat, u_short *life)
        return APM_SUCCESS;
 }
 
+#if 0
+/* not used anywhere */
 static int apm_get_battery_status(u_short which, 
                                  u_short *bat, u_short *life, u_short *nbat)
 {
@@ -532,6 +534,7 @@ static int apm_get_battery_status(u_short which,
                return (error >> 8);
        return APM_SUCCESS;
 }
+#endif
 
 static inline int apm_engage_power_management(u_short device)
 {
index c7bae0b443f2de437dc1b65620476e2429700b7c..8bb3f203efd2df90a01f84b3f894eed369e8395d 100644 (file)
@@ -156,6 +156,7 @@ static void * rvmalloc(unsigned long size)
        mem=vmalloc(size);
        if (mem) 
        {
+               memset(mem, 0, size); /* Clear the ram out, no junk to the user */
                adr=(unsigned long) mem;
                while (size > 0) 
                 {
@@ -642,7 +643,16 @@ int palette2fmt[] = {
        BT848_COLOR_FMT_RGB24,
        BT848_COLOR_FMT_RGB32,
        BT848_COLOR_FMT_RGB15,
+       BT848_COLOR_FMT_YUY2,
+       BT848_COLOR_FMT_BtYUV,
+       -1,
+       -1,
+       -1,
+       BT848_COLOR_FMT_RAW,
+       BT848_COLOR_FMT_YCrCb422,
+       BT848_COLOR_FMT_YCrCb411,
 };
+#define PALETTEFMT_MAX 11
 
 static int  make_rawrisctab(struct bttv *btv, unsigned int *ro,
                             unsigned int *re, unsigned int *vbuf)
@@ -1044,13 +1054,18 @@ static int vgrab(struct bttv *btv, struct video_mmap *mp)
         */
         
        vbuf=(unsigned int *)(btv->fbuffer+BTTV_MAX_FBUF*mp->frame);
-       if (!(btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC))
-                return -EAGAIN;
+/*     if (!(btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC))
+                return -EAGAIN; */
        ro=btv->grisc+(((btv->grabcount++)&1) ? 4096 :0);
        re=ro+2048;
        btv->gwidth=mp->width;
        btv->gheight=mp->height;
-       btv->gfmt=mp->format;
+       if (mp->format > PALETTEFMT_MAX)
+               return -EINVAL;
+       btv->gfmt=palette2fmt[mp->format];
+       if(btv->gfmt==-1)
+               return -EINVAL;
+               
        make_vrisctab(btv, ro, re, vbuf, btv->gwidth, btv->gheight, btv->gfmt);
        /* bt848_set_risc_jmps(btv); */
        btor(3, BT848_CAP_CTL);
@@ -1561,6 +1576,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        v.rangehigh=0xFFFFFFFF;
                        v.flags=VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
                        v.mode = btv->win.norm;
+                       v.signal = (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) ? 0xFFFF : 0;
                        if(copy_to_user(arg,&v,sizeof(v)))
                                return -EFAULT;
                        return 0;
@@ -1927,6 +1943,7 @@ static struct video_device bttv_template=
        bttv_close,
        bttv_read,
        bttv_write,
+       NULL,                   /* poll */
        bttv_ioctl,
        bttv_mmap,
        bttv_init_done,
@@ -1980,6 +1997,20 @@ static long vbi_read(struct video_device *v, char *buf, unsigned long count,
        return count;
 }
 
+static unsigned int vbi_poll(struct video_device *dev, struct file *file,
+       poll_table *wait)
+{
+       struct bttv *btv=(struct bttv *)(dev-2);
+       unsigned int mask = 0;
+
+       poll_wait(file, &btv->vbiq, wait);
+
+       if (btv->vbip < VBIBUF_SIZE)
+               mask |= (POLLIN | POLLRDNORM);
+
+       return mask;
+}
+
 static int vbi_open(struct video_device *dev, int flags)
 {
        struct bttv *btv=(struct bttv *)(dev-2);
@@ -2017,6 +2048,7 @@ static struct video_device vbi_template=
        vbi_close,
        vbi_read,
        bttv_write,
+       vbi_poll,
        vbi_ioctl,
        NULL,   /* no mmap yet */
        bttv_init_done,
@@ -2113,6 +2145,7 @@ static struct video_device radio_template=
        radio_close,
        radio_read,          /* just returns -EINVAL */
        bttv_write,          /* just returns -EINVAL */
+       NULL,                /* no poll */
        radio_ioctl,
        NULL,                /* no mmap */
        bttv_init_done,      /* just returns 0 */
@@ -2176,7 +2209,7 @@ static int find_vga(void)
        for (dev = pci_devices; dev != NULL; dev = dev->next) 
        {
                if (dev->class != PCI_CLASS_NOT_DEFINED_VGA &&
-                       (dev->class) >> 8 != PCI_BASE_CLASS_DISPLAY) 
+                       ((dev->class) >> 16 != PCI_BASE_CLASS_DISPLAY))
                {
                        continue;
                }
@@ -2196,40 +2229,40 @@ static int find_vga(void)
                                badr=vbs[i].badr;
                                break;
                        }
-                       if (!badr) 
-                       {
-                               printk(KERN_ERR "bttv: Unknown video memory base address.\n");
-                               continue;
-                       }
-                       pci_read_config_dword(dev, badr, &vidadr);
-                       if (vidadr & PCI_BASE_ADDRESS_SPACE_IO) 
-                       {
-                               printk(KERN_ERR "bttv: Memory seems to be I/O memory.\n");
-                               printk(KERN_ERR "bttv: Check entry for your card type in bttv.c vidbases struct.\n");
-                               continue;
-                       }
-                       vidadr &= PCI_BASE_ADDRESS_MEM_MASK;
-                       if (!vidadr) 
-                       {
-                               printk(KERN_ERR "bttv: Memory @ 0, must be something wrong!");
-                               continue;
-                       }
-      
-                       if (dev->vendor == PCI_VENDOR_ID_DEC &&
-                               dev->device == PCI_DEVICE_ID_DEC_TGA) 
+               }
+               if (!badr) 
+               {
+                       printk(KERN_ERR "bttv: Unknown video memory base address.\n");
+                       continue;
+               }
+               pci_read_config_dword(dev, badr, &vidadr);
+               if (vidadr & PCI_BASE_ADDRESS_SPACE_IO) 
+               {
+                       printk(KERN_ERR "bttv: Memory seems to be I/O memory.\n");
+                       printk(KERN_ERR "bttv: Check entry for your card type in bttv.c vidbases struct.\n");
+                       continue;
+               }
+               vidadr &= PCI_BASE_ADDRESS_MEM_MASK;
+               if (!vidadr) 
+               {
+                       printk(KERN_ERR "bttv: Memory @ 0, must be something wrong!");
+                       continue;
+               }
+     
+               if (dev->vendor == PCI_VENDOR_ID_DEC &&
+                       dev->device == PCI_DEVICE_ID_DEC_TGA) 
+               {
+                       tga_type = (readl((unsigned long)vidadr) >> 12) & 0x0f;
+                       if (tga_type != 0 && tga_type != 1 && tga_type != 3) 
                        {
-                               tga_type = (readl((unsigned long)vidadr) >> 12) & 0x0f;
-                               if (tga_type != 0 && tga_type != 1 && tga_type != 3) 
-                               {
-                                       printk(KERN_ERR "bttv: TGA type (0x%x) unrecognized!\n", tga_type);
-                                       found--;
-                               }
-                               vidadr+=dec_offsets[tga_type];
+                               printk(KERN_ERR "bttv: TGA type (0x%x) unrecognized!\n", tga_type);
+                               found--;
                        }
-                       DEBUG(printk(KERN_DEBUG "bttv: memory @ 0x%08x, ", vidadr));
-                       DEBUG(printk(KERN_DEBUG "devfn: 0x%04x.\n", dev->devfn));
-                       found++;
+                       vidadr+=dec_offsets[tga_type];
                }
+               DEBUG(printk(KERN_DEBUG "bttv: memory @ 0x%08x, ", vidadr));
+               DEBUG(printk(KERN_DEBUG "devfn: 0x%04x.\n", dev->devfn));
+               found++;
        }
   
        if (vidmem)
@@ -2548,6 +2581,8 @@ static int init_bt848(int i)
        if (!(btv->grisc=(unsigned int *) kmalloc(32768, GFP_KERNEL)))
                return -1;
 
+       memset(btv->vbibuf, 0, VBIBUF_SIZE); /* We don't want to return random
+                                               memory to the user */
        btv->fbuffer=NULL;
 
        bt848_muxsel(btv, 1);
index 160c9945b560e9ff381402aec013e189a535984f..48de68db349411e421c85a7e223bf064d3f3fba1 100644 (file)
@@ -842,6 +842,7 @@ static struct video_device qcam_template=
        qcam_close,
        qcam_read,
        qcam_write,
+       NULL,
        qcam_ioctl,
        NULL,
        qcam_init_done,
index 46e2b88bab9cc76c49df15e482f8f0cc8e34b825..e6d4c16b5efe2222f920ffc71114800b7a21fb7e 100644 (file)
@@ -646,6 +646,7 @@ static struct video_device qcam_template=
        qcam_close,
        qcam_read,
        qcam_write,
+       NULL,
        qcam_ioctl,
        NULL,
        qcam_init_done,
index 81833b821224b297f9ed14bb308326c17b9eb52e..c05659fd2f96855df12bb4ecef69d50f68edffdf 100644 (file)
@@ -4949,7 +4949,7 @@ cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
                        info->idle_stats.recv_bytes,
                        JIFFIES_DIFF(info->idle_stats.recv_idle, cur_jifs) / HZ,
                        info->idle_stats.overruns,
-                       info->tty->ldisc.num);
+                       (long) info->tty->ldisc.num);
        else
            size = sprintf(buf+len,
                        "%3d %8lu %10lu %8lu %10lu %8lu %9lu %6ld\n",
index cf16d9cf3e3e921a84903db76e1e3d858bf03968..65d2f77477f7845e3887e7c1693200fab3de4a5d 100644 (file)
@@ -11,8 +11,8 @@
  * Diacriticals redone & other small changes, aeb@cwi.nl, June 1993
  * Added decr/incr_console, dynamic keymaps, Unicode support,
  * dynamic function/string keys, led setting,  Sept 1994
- *
  * `Sticky' modifier keys, 951006.
+ *
  * 11-11-96: SAK should now work in the raw mode (Martin Mares)
  * 
  * Modified to provide 'generic' keyboard support by Hamish Macdonald
@@ -590,6 +590,7 @@ unsigned char handle_diacr(unsigned char ch)
        if (ch == ' ' || ch == d)
                return d;
 
+       put_queue(d);
        return ch;
 }
 
index 4e49b9f052132e6726869c383221d87ef02fa4e8..1036f104629b2dac89e47b9baf863560bff239b1 100644 (file)
@@ -564,7 +564,7 @@ static int lp_open(struct inode * inode, struct file * file)
                return -ENXIO;
        if ((LP_F(minor) & LP_EXIST) == 0)
                return -ENXIO;
-       if (test_and_set_bit(LP_BUSY_BIT_POS, &LP_F(minor)) & LP_BUSY)
+       if (test_and_set_bit(LP_BUSY_BIT_POS, &LP_F(minor)))
                return -EBUSY;
 
        MOD_INC_USE_COUNT;
index 73c20a16b42e565f285738baea7f863a0be53922..18cce49dd474f50438b9c0a2aef609fdd60b8217 100644 (file)
@@ -58,7 +58,7 @@
 #endif
 
 
-int debug = 0; /* insmod parameter */
+static int debug = 0; /* insmod parameter */
 
 struct msp3400c {
        struct i2c_bus     *bus;
@@ -542,7 +542,8 @@ static int msp3400c_thread(void *data)
                LOCK_I2C_BUS(msp->bus);
                msp3400c_setvolume(msp->bus, 0, 0);
                msp3400c_setmode(msp, MSP_MODE_AM_DETECT);
-               val1 = val2 = max1 = max2 = 0;
+               val1 = val2 = 0;
+               max1 = max2 = -1;
                del_timer(&msp->wake_stereo);
                msp->watch_stereo = 0;
 
index 5910de6b41144209af490fdf87b5a319d0599caa..ad84a09d34a64b3c98457df31afa56caf11ebbff 100644 (file)
@@ -50,7 +50,7 @@ unsigned char pckbd_sysrq_xlate[128] =
  */
 
 /*
- * Some x86 BIOSes do not correctly initializes the keyboard, so the
+ * Some x86 BIOSes do not correctly initialize the keyboard, so the
  * "kbd-reset" command line options can be given to force a reset.
  * [Ranger]
  */
index 5c4f3de48348179b1ac199e333702b8065b293f9..81c8fbb79ed9955602265d3569fd70aa3c530ecd 100644 (file)
@@ -893,6 +893,7 @@ struct video_device pms_template=
        pms_close,
        pms_read,
        pms_write,
+       NULL,           /* FIXME - we can use POLL on this board with the irq */
        pms_ioctl,
        NULL,
        pms_init_done,
index 3c49647de4380a1114347b0cd3575aca2c22b78a..4aaa67579cb41d81b6eac9fc9b337c047e77e596 100644 (file)
@@ -7,6 +7,7 @@
  *    -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998
  */
 
+#include <linux/config.h>
 #include <linux/module.h>      /* For EXPORT_SYMBOL */
 
 #include <linux/errno.h>
index ed1cced0236a7f994343757a326cb02db7004417..014def0c49cccb9ea105d003c43871a3c6bfb7e5 100644 (file)
@@ -155,7 +155,11 @@ static int rt_setfreq(struct rt_device *dev, unsigned long freq)
 
        /* adapted from radio-aztech.c */
 
-       freq = (freq * 100) / 16;       /* massage the data a little    */
+       /* We want to compute x * 100 / 16 without overflow 
+        * So we compute x*6 + (x/100)*25 to give x*6.25
+        */
+        
+       freq = freq * 6 + freq/4;       /* massage the data a little    */
        freq += 1070;                   /* IF = 10.7 MHz                */
        freq /= 5;                      /* ref = 25 kHz                 */
 
@@ -308,6 +312,7 @@ static struct video_device rtrack_radio=
        rt_close,
        NULL,   /* Can't read  (no capture ability) */
        NULL,   /* Can't write */
+       NULL,   /* No poll */
        rt_ioctl,
        NULL,
        NULL
index e883c712a7b97f1ad9cddfc87b9e32c79068ec51..aaeaa726558c271c94381fb51e4dce48ae770476 100644 (file)
@@ -113,7 +113,8 @@ static int az_setfreq(struct az_device *dev, unsigned long frequency)
 {
        int  i;
 
-       frequency = (frequency * 100) / 16;     /* massage data a bit */
+       /*  6.25 *  */
+       frequency = frequency*6 + frequency/4;  /* massage data a bit */
   
        frequency += 1070;              /* tuning needs 24 data bits  */
        frequency /= 5;
@@ -269,6 +270,7 @@ static struct video_device aztech_radio=
        az_close,
        NULL,   /* Can't read  (no capture ability) */
        NULL,   /* Can't write */
+       NULL,   /* No poll */
        az_ioctl,
        NULL,
        NULL
diff --git a/drivers/char/radio-rtrack2.c b/drivers/char/radio-rtrack2.c
new file mode 100644 (file)
index 0000000..7daeb4e
--- /dev/null
@@ -0,0 +1,272 @@
+/* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
+ * 
+ * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
+ * Coverted to new API by Alan Cox <Alan.Cox@linux.org>
+ * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
+ *
+ * TODO: Allow for more than one of these foolish entities :-)
+ *
+ */
+
+#include <linux/module.h>      /* Modules                      */
+#include <linux/init.h>                /* Initdata                     */
+#include <linux/ioport.h>      /* check_region, request_region */
+#include <linux/delay.h>       /* udelay                       */
+#include <asm/io.h>            /* outb, outb_p                 */
+#include <asm/uaccess.h>       /* copy to/from user            */
+#include <linux/videodev.h>    /* kernel radio structs         */
+#include <linux/config.h>      /* CONFIG_RADIO_RTRACK2_PORT    */
+
+#ifndef CONFIG_RADIO_RTRACK2_PORT
+#define CONFIG_RADIO_RTRACK2_PORT -1
+#endif
+
+static int io = CONFIG_RADIO_RTRACK2_PORT; 
+static int users = 0;
+
+struct rt_device
+{
+       int port;
+       unsigned long curfreq;
+       int muted;
+};
+
+
+/* local things */
+
+static void rt_mute(struct rt_device *dev)
+{
+        if(dev->muted)
+               return;
+       outb(1, io);
+       dev->muted = 1;
+}
+
+static void rt_unmute(struct rt_device *dev)
+{
+       if(dev->muted == 0)
+               return;
+       outb(0, io);
+       dev->muted = 0;
+}
+
+static void zero(void)
+{
+        outb_p(1, io);
+       outb_p(3, io);
+       outb_p(1, io);
+}
+
+static void one(void)
+{
+        outb_p(5, io);
+       outb_p(7, io);
+       outb_p(5, io);
+}
+
+static int rt_setfreq(struct rt_device *dev, unsigned long freq)
+{
+       int i;
+
+       freq = freq / 200 + 856;
+
+       outb_p(0xc8, io);
+       outb_p(0xc9, io);
+       outb_p(0xc9, io);
+
+       for (i = 0; i < 10; i++)
+               zero ();
+
+       for (i = 14; i >= 0; i--)
+               if (freq & (1 << i))
+                       one ();
+               else
+                       zero ();
+
+       outb_p(0xc8, io);
+       if (!dev->muted)
+         outb_p(0, io);
+       return 0;
+}
+
+int rt_getsigstr(struct rt_device *dev)
+{
+       if (inb(io) & 2)        /* bit set = no signal present  */
+               return 0;
+       return 1;               /* signal present               */
+}
+
+static int rt_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+{
+       struct rt_device *rt=dev->priv;
+
+       switch(cmd)
+       {
+               case VIDIOCGCAP:
+               {
+                       struct video_capability v;
+                       v.type=VID_TYPE_TUNER;
+                       v.channels=1;
+                       v.audios=1;
+                       /* No we don't do pictures */
+                       v.maxwidth=0;
+                       v.maxheight=0;
+                       v.minwidth=0;
+                       v.minheight=0;
+                       if(copy_to_user(arg,&v,sizeof(v)))
+                               return -EFAULT;
+                       return 0;
+               }
+               case VIDIOCGTUNER:
+               {
+                       struct video_tuner v;
+                       if(copy_from_user(&v, arg,sizeof(v))!=0) 
+                               return -EFAULT;
+                       if(v.tuner)     /* Only 1 tuner */ 
+                               return -EINVAL;
+                       v.rangelow=88*16000;
+                       v.rangehigh=108*16000;
+                       v.flags=VIDEO_TUNER_LOW;
+                       v.mode=VIDEO_MODE_AUTO;
+                       v.signal=0xFFFF*rt_getsigstr(rt);
+                       if(copy_to_user(arg,&v, sizeof(v)))
+                               return -EFAULT;
+                       return 0;
+               }
+               case VIDIOCSTUNER:
+               {
+                       struct video_tuner v;
+                       if(copy_from_user(&v, arg, sizeof(v)))
+                               return -EFAULT;
+                       if(v.tuner!=0)
+                               return -EINVAL;
+                       /* Only 1 tuner so no setting needed ! */
+                       return 0;
+               }
+               case VIDIOCGFREQ:
+                       if(copy_to_user(arg, &rt->curfreq, sizeof(rt->curfreq)))
+                               return -EFAULT;
+                       return 0;
+               case VIDIOCSFREQ:
+                       if(copy_from_user(&rt->curfreq, arg,sizeof(rt->curfreq)))
+                               return -EFAULT;
+                       rt_setfreq(rt, rt->curfreq);
+                       return 0;
+               case VIDIOCGAUDIO:
+               {       
+                       struct video_audio v;
+                       memset(&v,0, sizeof(v));
+                       v.flags|=VIDEO_AUDIO_MUTABLE;
+                       v.volume=1;
+                       strcpy(v.name, "Radio");
+                       if(copy_to_user(arg,&v, sizeof(v)))
+                               return -EFAULT;
+                       return 0;                       
+               }
+               case VIDIOCSAUDIO:
+               {
+                       struct video_audio v;
+                       if(copy_from_user(&v, arg, sizeof(v))) 
+                               return -EFAULT; 
+                       if(v.audio) 
+                               return -EINVAL;
+
+                       if(v.flags&VIDEO_AUDIO_MUTE) 
+                               rt_mute(rt);
+                       else
+                               rt_unmute(rt);
+
+                       return 0;
+               }
+               default:
+                       return -ENOIOCTLCMD;
+       }
+}
+
+static int rt_open(struct video_device *dev, int flags)
+{
+       if(users)
+               return -EBUSY;
+       users++;
+       MOD_INC_USE_COUNT;
+       return 0;
+}
+
+static void rt_close(struct video_device *dev)
+{
+       users--;
+       MOD_DEC_USE_COUNT;
+}
+
+static struct rt_device rtrack2_unit;
+
+static struct video_device rtrack2_radio=
+{
+       "RadioTrack II radio",
+       VID_TYPE_TUNER,
+       VID_HARDWARE_RTRACK2,
+       rt_open,
+       rt_close,
+       NULL,   /* Can't read  (no capture ability) */
+       NULL,   /* Can't write */
+       NULL,   /* Can't poll */
+       rt_ioctl,
+       NULL,
+       NULL
+};
+
+__initfunc(int rtrack2_init(struct video_init *v))
+{
+       if (check_region(io, 4)) 
+       {
+               printk(KERN_ERR "rtrack2: port 0x%x already in use\n", io);
+               return -EBUSY;
+       }
+
+       rtrack2_radio.priv=&rtrack2_unit;
+       
+       if(video_register_device(&rtrack2_radio, VFL_TYPE_RADIO)==-1)
+               return -EINVAL;
+               
+       request_region(io, 4, "rtrack2");
+       printk(KERN_INFO "AIMSlab Radiotrack II card driver.\n");
+
+       /* mute card - prevents noisy bootups */
+       outb(1, io);
+       rtrack2_unit.muted = 1;
+
+       return 0;
+}
+
+#ifdef MODULE
+
+MODULE_AUTHOR("Ben Pfaff");
+MODULE_DESCRIPTION("A driver for the RadioTrack II radio card.");
+MODULE_PARM(io, "i");
+MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)");
+
+EXPORT_NO_SYMBOLS;
+
+int init_module(void)
+{
+       if(io==-1)
+       {
+               printk(KERN_ERR "You must set an I/O address with io=0x20c or io=0x30c\n");
+               return -EINVAL;
+       }
+       return rtrack2_init(NULL);
+}
+
+void cleanup_module(void)
+{
+       video_unregister_device(&rtrack2_radio);
+       release_region(io,4);
+}
+
+#endif
+
+/*
+  Local variables:
+  compile-command: "gcc -c -DMODVERSIONS -D__KERNEL__ -DMODULE -O6 -Wall -Wstrict-prototypes -I /home/blp/tmp/linux-2.1.111-rtrack/include radio-rtrack2.c"
+  End:
+*/
index ae975288123d0dc07f8862e4d55664d98bcb5307..13659fd85eb6101007bf789ec8e966c65df55805 100644 (file)
@@ -29,6 +29,7 @@ struct fmi_device
        int port;
        int curvol;
        unsigned long curfreq;
+       int flags;
 };
 
 #ifndef CONFIG_RADIO_SF16FMI_PORT
@@ -39,7 +40,8 @@ static int io = CONFIG_RADIO_SF16FMI_PORT;
 static int users = 0;
 
 /* local things */
-#define RSF16_ENCODE(x)        ((x*(1000/4)+10700)/50)
+/* freq in 1/16kHz to internal number */
+#define RSF16_ENCODE(x)        ((x/16+10700)/50)
 
 static void outbits(int bits, int data, int port)
 {
@@ -69,8 +71,6 @@ static void fmi_unmute(int port)
        outb(0x08, port);
 }
 
-/* FREQ is in 1/16ths of a MHz so this is probably wrong atm */
-
 static int fmi_setfreq(struct fmi_device *dev, unsigned long freq)
 {
        int myport = dev->port;
@@ -124,9 +124,14 @@ static int fmi_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                                return -EFAULT;
                        if(v.tuner)     /* Only 1 tuner */
                                return -EINVAL;
-                       v.rangelow=(int)(87.5*16);
-                       v.rangehigh=(int)(108.0*16);
-                       v.flags=0;
+                       if (fmi->flags & VIDEO_TUNER_LOW) {
+                               v.rangelow = 87500 * 16;
+                               v.rangehigh = 108000 * 16;
+                       } else {
+                               v.rangelow=(int)(175*8 /* 87.5 *16 */);
+                               v.rangehigh=(int)(108*16);
+                       }
+                       v.flags=fmi->flags;
                        v.mode=VIDEO_MODE_AUTO;
                        v.signal=0xFFFF*fmi_getsigstr(fmi);
                        if(copy_to_user(arg,&v, sizeof(v)))
@@ -140,18 +145,30 @@ static int fmi_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                                return -EFAULT;
                        if(v.tuner!=0)
                                return -EINVAL;
+                       fmi->flags = v.flags & VIDEO_TUNER_LOW;
                        /* Only 1 tuner so no setting needed ! */
                        return 0;
                }
                case VIDIOCGFREQ:
-                       if(copy_to_user(arg, &fmi->curfreq, sizeof(fmi->curfreq)))
+               {
+                       unsigned long tmp = fmi->curfreq;
+                       if (!(fmi->flags & VIDEO_TUNER_LOW))
+                               tmp /= 1000;
+                       if(copy_to_user(arg, &tmp, sizeof(tmp)))
                                return -EFAULT;
                        return 0;
+               }
                case VIDIOCSFREQ:
-                       if(copy_from_user(&fmi->curfreq, arg,sizeof(fmi->curfreq)))
+               {
+                       unsigned long tmp;
+                       if(copy_from_user(&tmp, arg, sizeof(tmp)))
                                return -EFAULT;
+                       if (!(fmi->flags & VIDEO_TUNER_LOW))
+                               tmp *= 1000;
+                       fmi->curfreq = tmp;
                        fmi_setfreq(fmi, fmi->curfreq);
                        return 0;
+               }
                case VIDIOCGAUDIO:
                {       
                        struct video_audio v;
@@ -211,6 +228,7 @@ static struct video_device fmi_radio=
        fmi_close,
        NULL,   /* Can't read  (no capture ability) */
        NULL,   /* Can't write */
+       NULL,   /* Can't poll */
        fmi_ioctl,
        NULL,
        NULL
@@ -225,6 +243,7 @@ __initfunc(int fmi_init(struct video_init *v))
        }
 
        fmi_unit.port=io;
+       fmi_unit.flags = VIDEO_TUNER_LOW;
        fmi_radio.priv=&fmi_unit;
        
        if(video_register_device(&fmi_radio, VFL_TYPE_RADIO)==-1)
index b07f4cea1fcabf8fe1dc7265129b0a1a32275e92..c820c8a36e1ad85c561a0081f36174a1c106c1a8 100644 (file)
@@ -2,14 +2,14 @@
  * (c) 1998 C. van Schaik <carl@leg.uct.ac.za>
  *
  * BUGS  
- *  The signal strength query is unsurprisingly inaccurate.  And it seems
- *  to indicate that (on my card, at least) the frequency setting isn't
- *  too great.  It seems to work in a similar way to a car stereo which
- *  flickers when it is near or on a station...
+ *  Due to the inconsistancy in reading from the signal flags
+ *  it is difficult to get an accurate tuned signal.
  *
  *  There seems to be a problem with the volume setting that I must still
- *  figure out. This is a minor problem... It still works but you may
- *  have to set the card lounder to get the same volume.
+ *  figure out. 
+ *  It seems that the card has is not linear to 0 volume. It cuts off
+ *  at a low frequency, and it is not possible (at least I have not found)
+ *  to get fine volume control over the low volume range.
  *
  *  Some code derived from code by Frans Brinkman
  */
@@ -62,31 +62,31 @@ static void zol_mute(struct zol_device *dev)
        inb(io + 3);            /* Zoltrix needs to be read to confirm */
 }
 
-static int zol_setvol(struct zol_device *dev, int vol)
+static void zol_on(int vol)
 {
-       int l;
+        int l;
+        outb(vol, io);
+        sleep_delay(10000);
+        l = inb(io + 2);
+}
 
+static int zol_setvol(struct zol_device *dev, int vol)
+{
        if (vol == dev->curvol) {       /* requested volume = current */
                if (dev->muted) {       /* user is unmuting the card  */
                        dev->muted = 0;
-                       outb(vol, io);
-                       sleep_delay(20000);
-                       l = inb(io + 2);
+                        zol_on(vol);
                }
                return 0;
        }
        if (vol == 0) {         /* volume = 0 means mute the card */
-               outb(0, io);
-               outb(0, io);
-               l = inb(io + 3);
+                zol_mute(dev);
                return 0;
        }
        dev->muted = 0;
        dev->curvol = vol;
 
-       outb(vol, io);
-       sleep_delay(20000);
-       l = inb(io + 2);
+       zol_on(vol);
 
        return 0;
 }
@@ -95,7 +95,7 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq)
 {
        /* tunes the radio to the desired frequency */
        unsigned long long bitmask, f, m;
-       int i, l;
+       int i;
 
        m = (freq * 25 / 4 - 8800) * 2;
        f = (unsigned long long) m + 0x4d1c;
@@ -103,10 +103,8 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq)
        bitmask = 0xc480402c10080000ull;
        i = 45;
 
-       outb(0x00, io);
-       outb(0x00, io);
-       sleep_delay(10000);
-       inb(io + 3);
+       zol_mute(dev);
+
        outb(0x40, io);
        outb(0xc0, io);
 
@@ -133,29 +131,26 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq)
        outb(0x80, io);
        outb(0xc0, io);
        outb(0x40, io);
-       outb(0x00, io);
-       sleep_delay(10000);
-       l = inb(io + 2);
-       sleep_delay(10000);
-       l = inb(io + 1);
-       outb(dev->curvol, io);
-       sleep_delay(10000);
-       l = inb(io + 2);
+        zol_on(dev->curvol);
        return 0;
 }
 
-/* Get signal strenght */
+/* Get signal strength */
+
 int zol_getsigstr(struct zol_device *dev)
 {
        int a, b;
-       outb(0x00, io);
-       sleep_delay(10000);
-       a = inb(io + 2);
+
+       outb(0x00, io);         /* This stuff I found to do nothing */
+       outb(dev->curvol, io);
        sleep_delay(20000);
-       b = inb(io + 1);
-       outb(0x00, io);
 
-       if (((a | b) & 255) != 0x0ff)
+       a = inb(io);
+       sleep_delay(1000);
+       b = inb(io);
+
+        if ((a == b) && (a == 0xdf))  /* I found this out by playing */
+                                      /* with a binary scanner on the card io */
                return (1);
        else
                return (0);
@@ -225,7 +220,7 @@ static int zol_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        struct video_audio v;
                        memset(&v, 0, sizeof(v));
                        v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
-                       v.volume = rt->curvol * 6554;
+                       v.volume = rt->curvol * 4095;
                        strcpy(v.name, "Radio");
                        if (copy_to_user(arg, &v, sizeof(v)))
                                return -EFAULT;
@@ -242,7 +237,7 @@ static int zol_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        if (v.flags & VIDEO_AUDIO_MUTE)
                                zol_mute(rt);
                        else
-                               zol_setvol(rt, v.volume / 6554);
+                               zol_setvol(rt, v.volume / 4096);
 
                        return 0;
                }
@@ -277,6 +272,7 @@ static struct video_device zoltrix_radio =
        zol_close,
        NULL,                   /* Can't read  (no capture ability) */
        NULL,                   /* Can't write */
+       NULL,
        zol_ioctl,
        NULL,
        NULL
index 174c3cc0dd38164d9432389ef6af5b1cd4938953..868ba4eb958f982b6b09ab2bb6d36661aa80419c 100644 (file)
@@ -108,7 +108,6 @@ static ssize_t video_read(struct file *file,
 }
 
 
-
 /*
  *     Write for now does nothing. No reason it shouldnt do overlay setting
  *     for some boards I guess..
@@ -124,6 +123,21 @@ static ssize_t video_write(struct file *file, const char *buf,
                return 0;
 }
 
+
+/*
+ *     Poll to see if we're readable, can probably be used for timing on incoming
+ *  frames, etc..
+ */
+
+static unsigned int video_poll(struct file *file, poll_table * wait)
+{
+       struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
+       if(vfl->poll)
+               return vfl->poll(vfl, file, wait);
+       else
+               return 0;
+}
+
 /*
  *     Open a video device.
  */
@@ -297,7 +311,7 @@ static struct file_operations video_fops=
        video_read,
        video_write,
        NULL,   /* readdir */
-       NULL,   /* poll */
+       video_poll,     /* poll */
        video_ioctl,
        video_mmap,
        video_open,
index bbeab290c9f9c32f38f374c465fec6be054205e2..ca8e80f8e3556665ed0596b5db6475277eef390f 100644 (file)
@@ -178,6 +178,9 @@ int el3_probe(struct device *dev)
        }
 
 #ifdef CONFIG_MCA
+#warning "The MCA code in drivers/net/3c509.c does not compile"
+#warning "See http://glycerine.itsmm.uni.edu/mca/ for patches."
+#if 0   
        if (MCA_bus) {
                mca_adaptor_select_mode(1);
                for (i = 0; i < 8; i++)
@@ -194,6 +197,7 @@ int el3_probe(struct device *dev)
                mca_adaptor_select_mode(0);
 
        }
+#endif
 #endif
 
        /* Reset the ISA PnP mechanism on 3c509b. */
@@ -208,7 +212,7 @@ int el3_probe(struct device *dev)
                if (inb(id_port) & 0x01)
                        break;
        }
-       if (id_port >= 0x200) {             /* GCC optimizes this test out. */
+       if (id_port >= 0x200) {
                /* Rare -- do we really need a warning? */
                printk(" WARNING: No I/O port available for 3c509 activation.\n");
                return -ENODEV;
index bcadd467fd5b193c1b3c94cac521b46108a38d39..6aea631f03c94a906cca37b6326f5af86a335d33 100644 (file)
@@ -382,7 +382,7 @@ plip_bh_timeout_error(struct device *dev, struct net_local *nl,
                                return TIMEOUT;
                        }
                        c0 = inb(PAR_STATUS(dev));
-                       printk("%s: transmit timeout(%d,%02x)\n",
+                       printk(KERN_WARNING "%s: transmit timeout(%d,%02x)\n",
                               dev->name, snd->state, c0);
                }
                nl->enet_stats.tx_errors++;
@@ -400,7 +400,7 @@ plip_bh_timeout_error(struct device *dev, struct net_local *nl,
                                return TIMEOUT;
                        }
                        c0 = inb(PAR_STATUS(dev));
-                       printk("%s: receive timeout(%d,%02x)\n",
+                       printk(KERN_WARNING "%s: receive timeout(%d,%02x)\n",
                               dev->name, rcv->state, c0);
                }
                nl->enet_stats.rx_dropped++;
@@ -501,7 +501,7 @@ plip_receive_packet(struct device *dev, struct net_local *nl,
                dev->interrupt = 0;
                outb(0x01, PAR_DATA(dev)); /* send ACK */
                if (net_debug > 2)
-                       printk("%s: receive start\n", dev->name);
+                       printk(KERN_DEBUG "%s: receive start\n", dev->name);
                rcv->state = PLIP_PK_LENGTH_LSB;
                rcv->nibble = PLIP_NB_BEGIN;
 
@@ -531,13 +531,13 @@ plip_receive_packet(struct device *dev, struct net_local *nl,
                        return TIMEOUT;
                if (rcv->length.h > dev->mtu + dev->hard_header_len
                    || rcv->length.h < 8) {
-                       printk("%s: bogus packet size %d.\n", dev->name, rcv->length.h);
+                       printk(KERN_WARNING "%s: bogus packet size %d.\n", dev->name, rcv->length.h);
                        return ERROR;
                }
                /* Malloc up new buffer. */
                rcv->skb = dev_alloc_skb(rcv->length.h);
                if (rcv->skb == NULL) {
-                       printk("%s: Memory squeeze.\n", dev->name);
+                       printk(KERN_WARNING "%s: Memory squeeze.\n", dev->name);
                        return ERROR;
                }
                skb_put(rcv->skb,rcv->length.h);
@@ -565,7 +565,7 @@ plip_receive_packet(struct device *dev, struct net_local *nl,
                if (rcv->data != rcv->checksum) {
                        nl->enet_stats.rx_crc_errors++;
                        if (net_debug)
-                               printk("%s: checksum error\n", dev->name);
+                               printk(KERN_DEBUG "%s: checksum error\n", dev->name);
                        return ERROR;
                }
                rcv->state = PLIP_PK_DONE;
@@ -578,7 +578,7 @@ plip_receive_packet(struct device *dev, struct net_local *nl,
                nl->enet_stats.rx_packets++;
                rcv->skb = NULL;
                if (net_debug > 2)
-                       printk("%s: receive end\n", dev->name);
+                       printk(KERN_DEBUG "%s: receive end\n", dev->name);
 
                /* Close the connection. */
                outb (0x00, PAR_DATA(dev));
@@ -662,7 +662,7 @@ plip_send_packet(struct device *dev, struct net_local *nl,
        unsigned int cx;
 
        if (snd->skb == NULL || (lbuf = snd->skb->data) == NULL) {
-               printk("%s: send skb lost\n", dev->name);
+               printk(KERN_ERR "%s: send skb lost\n", dev->name);
                snd->state = PLIP_PK_DONE;
                snd->skb = NULL;
                return ERROR;
@@ -699,7 +699,7 @@ plip_send_packet(struct device *dev, struct net_local *nl,
                                }
                                outb(PAR_INTR_OFF, PAR_CONTROL(dev));
                                if (net_debug > 2)
-                                       printk("%s: send start\n", dev->name);
+                                       printk(KERN_DEBUG "%s: send start\n", dev->name);
                                snd->state = PLIP_PK_LENGTH_LSB;
                                snd->nibble = PLIP_NB_BEGIN;
                                nl->timeout_count = 0;
@@ -752,7 +752,7 @@ plip_send_packet(struct device *dev, struct net_local *nl,
                outb (0x00, data_addr);
                snd->skb = NULL;
                if (net_debug > 2)
-                       printk("%s: send end\n", dev->name);
+                       printk(KERN_DEBUG "%s: send end\n", dev->name);
                nl->connection = PLIP_CN_CLOSING;
                nl->is_deferred = 1;
                queue_task(&nl->deferred, &tq_timer);
@@ -791,7 +791,7 @@ plip_error(struct device *dev, struct net_local *nl,
        status = inb(PAR_STATUS(dev));
        if ((status & 0xf8) == 0x80) {
                if (net_debug > 2)
-                       printk("%s: reset interface.\n", dev->name);
+                       printk(KERN_DEBUG "%s: reset interface.\n", dev->name);
                nl->connection = PLIP_CN_NONE;
                nl->should_relinquish = 0;
                dev->tbusy = 0;
@@ -817,7 +817,7 @@ plip_interrupt(int irq, void *dev_id, struct pt_regs * regs)
        unsigned char c0;
 
        if (dev == NULL) {
-               printk("plip_interrupt: irq %d for unknown device.\n", irq);
+               printk(KERN_ERR "plip_interrupt: irq %d for unknown device.\n", irq);
                return;
        }
 
@@ -830,12 +830,12 @@ plip_interrupt(int irq, void *dev_id, struct pt_regs * regs)
        c0 = inb(PAR_STATUS(dev));
        if ((c0 & 0xf8) != 0xc0) {
                if (net_debug > 1)
-                       printk("%s: spurious interrupt\n", dev->name);
+                       printk(KERN_DEBUG "%s: spurious interrupt\n", dev->name);
                return;
        }
        dev->interrupt = 1;
        if (net_debug > 3)
-               printk("%s: interrupt.\n", dev->name);
+               printk(KERN_DEBUG "%s: interrupt.\n", dev->name);
 
        spin_lock_irq(&nl->lock);
        switch (nl->connection) {
@@ -861,7 +861,7 @@ plip_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 
        case PLIP_CN_ERROR:
                spin_unlock_irq(&nl->lock);
-               printk("%s: receive interrupt in error state\n", dev->name);
+               printk(KERN_WARNING "%s: receive interrupt in error state\n", dev->name);
                break;
        }
 }
@@ -899,18 +899,18 @@ plip_tx_packet(struct sk_buff *skb, struct device *dev)
        }
 
        if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
-               printk("%s: Transmitter access conflict.\n", dev->name);
+               printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
                return 1;
        }
 
        if (skb->len > dev->mtu + dev->hard_header_len) {
-               printk("%s: packet too big, %d.\n", dev->name, (int)skb->len);
+               printk(KERN_WARNING "%s: packet too big, %d.\n", dev->name, (int)skb->len);
                dev->tbusy = 0;
                return 0;
        }
 
        if (net_debug > 2)
-               printk("%s: send request\n", dev->name);
+               printk(KERN_DEBUG "%s: send request\n", dev->name);
 
        spin_lock_irq(&nl->lock);
        dev->trans_start = jiffies;
@@ -1083,8 +1083,7 @@ plip_get_stats(struct device *dev)
        return r;
 }
 
-static int
-plip_config(struct device *dev, struct ifmap *map)
+static int plip_config(struct device *dev, struct ifmap *map)
 {
        struct net_local *nl = (struct net_local *) dev->priv;
        struct pardevice *pardev = nl->pardev;
@@ -1092,8 +1091,8 @@ plip_config(struct device *dev, struct ifmap *map)
        if (dev->flags & IFF_UP)
                return -EBUSY;
 
-       printk(KERN_WARNING "plip: Warning, changing irq with ifconfig will be obsoleted.\n");
-       printk("plip: Next time, please set with /proc/parport/*/irq instead.\n");
+       printk(KERN_INFO "plip: Warning, changing irq with ifconfig will be obsoleted.\n");
+       printk(KERN_INFO "plip: Next time, please set with /proc/parport/*/irq instead.\n");
 
        if (map->irq != (unsigned char)-1) {
                pardev->port->irq = dev->irq = map->irq;
index 5340ceddf010c5e3e3dc244c3842675c87a0608f..9879f3de06789f8e7ca1be498c73135628456e72 100644 (file)
@@ -128,6 +128,7 @@ static int shaper_clocks(struct shaper *shaper, struct sk_buff *skb)
   
 static void shaper_setspeed(struct shaper *shaper, int bitspersec)
 {
+       shaper->bitspersec=bitspersec;
        shaper->bytespertick=(bitspersec/HZ)/8;
        if(!shaper->bytespertick)
                shaper->bytespertick++;
@@ -549,18 +550,28 @@ static int shaper_ioctl(struct device *dev,  struct ifreq *ifr, int cmd)
 {
        struct shaperconf *ss= (struct shaperconf *)&ifr->ifr_data;
        struct shaper *sh=dev->priv;
-       struct device *them=dev_get(ss->ss_name);
        switch(ss->ss_cmd)
        {
                case SHAPER_SET_DEV:
+               {
+                       struct device *them=dev_get(ss->ss_name);
                        if(them==NULL)
                                return -ENODEV;
                        if(sh->dev)
                                return -EBUSY;
                        return shaper_attach(dev,dev->priv, them);
+               }
+               case SHAPER_GET_DEV:
+                       if(sh->dev==NULL)
+                               return -ENODEV;
+                       memcpy(ss->ss_name, sh->dev->name, sizeof(ss->ss_name));
+                       return 0;
                case SHAPER_SET_SPEED:
                        shaper_setspeed(sh,ss->ss_speed);
                        return 0;
+               case SHAPER_GET_SPEED:
+                       ss->ss_speed=sh->bitspersec;
+                       return 0;
                default:
                        return -EINVAL;
        }
index d8b37d37756a187c1f333e0eed99791834e96430..7d4eaa225b8d959aeb8a3e4cfe5adc3bada5ef3b 100644 (file)
@@ -48,15 +48,16 @@ typedef u32 (TLanIntVectorFunc)( struct device *, u16 );
 static struct device   *TLanDevices = NULL;
 static int             TLanDevicesInstalled = 0;
 
+static int             aui = 0;
+static int             sa_int = 0;
+static int             duplex = 0;
+static int             speed = 0;
+
 #endif
 
 
 static  int            debug = 0;
-static int             aui = 0;
-static int             sa_int = 0;
 static int             bbuf = 0;
-static int             duplex = 0;
-static int             speed = 0;
 static u8              *TLanPadBuffer;
 static char            TLanSignature[] = "TLAN";
 static int             TLanVersionMajor = 1;
index a66e26c2873cdb7f627cf3b1040c6712b085be0b..fa1f91bbee143a71957214190421273157cc9b16 100644 (file)
@@ -496,6 +496,24 @@ inline void TLan_SetBit(u8 bit, u16 port)
 #define TLan_GetBit( bit, port )       ((int) (inb_p(port) & bit))
 #define TLan_SetBit( bit, port )       outb_p(inb_p(port) | bit, port)
 
+#ifdef I_LIKE_A_FAST_HASH_FUNCTION
+/* given 6 bytes, view them as 8 6-bit numbers and return the XOR of those */
+/* the code below is about seven times as fast as the original code */
+inline u32 TLan_HashFunc( u8 *a )
+{
+        u8     hash;
+
+        hash = (a[0]^a[3]);             /* & 077 */
+        hash ^= ((a[0]^a[3])>>6);       /* & 003 */
+        hash ^= ((a[1]^a[4])<<2);       /* & 074 */
+        hash ^= ((a[1]^a[4])>>4);       /* & 017 */
+        hash ^= ((a[2]^a[5])<<4);       /* & 060 */
+        hash ^= ((a[2]^a[5])>>2);       /* & 077 */
+
+        return (hash & 077);
+}
+
+#else /* original code */
 
 inline u32     xor( u32 a, u32 b )
 {
@@ -519,7 +537,5 @@ inline u32 TLan_HashFunc( u8 *a )
 
 } 
 
-
-
-
+#endif /* I_LIKE_A_FAST_HASH_FUNCTION */
 #endif
index 015aef38c3792004dac3dacbebcb5a091e1dcb2e..d15d87a6b88d93aec3666c25d656f42652345101 100644 (file)
@@ -688,7 +688,7 @@ __initfunc(void tgafb_init(void))
     fb_var.xres = fb_var.xres_virtual = 640;
     fb_var.yres = fb_var.yres_virtual = 480;
     fb_fix.line_length = 80*fb_var.bits_per_pixel;
-    fb_fix.smem_start = (char *)__pa(tga_fb_base + DENSE_MEM(tga_fb_base));
+    fb_fix.smem_start = (char *)__pa(tga_fb_base + dense_mem(tga_fb_base));
     fb_fix.smem_len = fb_fix.line_length*fb_var.yres;
     fb_fix.type = FB_TYPE_PACKED_PIXELS;
     fb_fix.type_aux = 0;
@@ -729,7 +729,7 @@ __initfunc(void tgafb_init(void))
     disp.cmap.start = 0;
     disp.cmap.len = 0;
     disp.cmap.red = disp.cmap.green = disp.cmap.blue = disp.cmap.transp = NULL;
-    disp.screen_base = (char *)tga_fb_base + DENSE_MEM(tga_fb_base);
+    disp.screen_base = (char *)tga_fb_base + dense_mem(tga_fb_base);
     disp.visual = fb_fix.visual;
     disp.type = fb_fix.type;
     disp.type_aux = fb_fix.type_aux;
index d4fd45d4b8ba7e28c0cd2dccb0b175eaa336ea84..a464d389ace63800594d916814e4361a001f5724 100644 (file)
@@ -453,6 +453,8 @@ static int vgacon_switch(struct vc_data *c)
         */
        vga_video_num_columns = c->vc_cols;
        vga_video_num_lines = c->vc_rows;
+       if (vga_is_gfx)
+               return 1;
        scr_memcpyw_to((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size);
        return 0;       /* Redrawing not needed */
 }
@@ -933,6 +935,8 @@ static void vgacon_save_screen(struct vc_data *c)
                c->vc_x = ORIG_X;
                c->vc_y = ORIG_Y;
        }
+       if (vga_is_gfx)
+               return;
        scr_memcpyw_from((u16 *) c->vc_screenbuf, (u16 *) c->vc_origin, c->vc_screenbuf_size);
 }
 
index 41ca7c2832d6729c093923ca5472e6cfe26851c0..81de324686e24f41354c5d9826742d9abcc571ec 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -392,7 +392,7 @@ end_readexec:
 static int exec_mmap(void)
 {
        struct mm_struct * mm, * old_mm;
-       int retval;
+       int retval, nr;
 
        if (current->mm->count == 1) {
                flush_cache_mm(current->mm);
@@ -411,9 +411,16 @@ static int exec_mmap(void)
        mm = mm_alloc();
        if (!mm)
                goto fail_nomem;
+
        mm->cpu_vm_mask = (1UL << smp_processor_id());
        mm->total_vm = 0;
        mm->rss = 0;
+       /*
+        * Make sure we have a private ldt if needed ...
+        */
+       nr = current->tarray_ptr - &task[0]; 
+       copy_segments(nr, current, mm);
+
        old_mm = current->mm;
        current->mm = mm;
        retval = new_page_tables(current);
@@ -431,6 +438,8 @@ fail_restore:
        /* The pgd belongs to the parent ... don't free it! */
        mm->pgd = NULL;
        current->mm = old_mm;
+       /* restore the ldt for this task */
+       copy_segments(nr, current, NULL);
        mmput(mm);
 
 fail_nomem:
index 4c3d876c1ddb28fcd669418c4acdae8740f5e085..8b398112db52100e3f1305cba24fdd97cb2c1f8e 100644 (file)
@@ -1157,10 +1157,7 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
        /* If we didn't fill the buffer completely, we're at EOF */
        eof = !cd.eob;
 
-       /* Hewlett Packard ignores the eof flag on READDIR. Some
-        * fs-specific readdir implementations seem to reset f_pos to 0
-        * at EOF however, causing an endless loop. */
-       if (cd.offset && !eof)
+       if (cd.offset)
                *cd.offset = htonl(file.f_pos);
 
        p = cd.buffer;
index 631665f04d4de77af8c8d9f52a48f03ac82cacbc..113647683c2c93c3ae6c3ee5995cd373f985237a 100644 (file)
@@ -35,6 +35,8 @@
  *                     - Incorporation and non-SMP safe operation
  *                     of forissier patch in 2.1.78 by 
  *                     Hans Marcus <crowbar@concepts.nl>
+ *
+ * aeb@cwi.nl        :  /proc/partitions
  */
 
 #include <linux/types.h>
@@ -1191,6 +1193,7 @@ extern int get_module_list(char *);
 extern int get_ksyms_list(char *, char **, off_t, int);
 #endif
 extern int get_device_list(char *);
+extern int get_partition_list(char *);
 extern int get_filesystem_list(char *);
 extern int get_filesystem_info( char * );
 extern int get_irq_list(char *);
@@ -1250,6 +1253,9 @@ static long get_root_array(char * page, int type, char **start,
                case PROC_DEVICES:
                        return get_device_list(page);
 
+               case PROC_PARTITIONS:
+                       return get_partition_list(page);
+
                case PROC_INTERRUPTS:
                        return get_irq_list(page);
 
index b161ceb86c5f541e1d4cc4e53a2f8a9bf631fc41..a9b00f1f50a316009878ea716482c10d1d5e0093 100644 (file)
@@ -283,7 +283,11 @@ out:
 extern void free_proc_entry(struct proc_dir_entry *);
 void free_proc_entry(struct proc_dir_entry *de)
 {
-       kfree(de);
+       int ino = de->low_ino;
+
+       if (ino >= PROC_DYNAMIC_FIRST &&
+           ino < PROC_DYNAMIC_FIRST+PROC_NDYNAMIC)
+               kfree(de);
 }
 
 /*
index 77e7b1585f99abc4f45b05a7790959a318680ef7..1f5a1ea5d1740d919209528bea74a947faa1c9c8 100644 (file)
@@ -560,6 +560,11 @@ static struct proc_dir_entry proc_root_devices = {
        S_IFREG | S_IRUGO, 1, 0, 0,
        0, &proc_array_inode_operations
 };
+static struct proc_dir_entry proc_root_partitions = {
+       PROC_PARTITIONS, 10, "partitions",
+       S_IFREG | S_IRUGO, 1, 0, 0,
+       0, &proc_array_inode_operations
+};
 static struct proc_dir_entry proc_root_interrupts = {
        PROC_INTERRUPTS, 10,"interrupts",
        S_IFREG | S_IRUGO, 1, 0, 0,
@@ -667,6 +672,7 @@ __initfunc(void proc_root_init(void))
 #endif
        proc_register(&proc_root, &proc_root_stat);
        proc_register(&proc_root, &proc_root_devices);
+       proc_register(&proc_root, &proc_root_partitions);
        proc_register(&proc_root, &proc_root_interrupts);
        proc_register(&proc_root, &proc_root_filesystems);
        proc_register(&proc_root, &proc_root_fs);
index 2842f62787e63d1a438bcd6ce94a9734587f107b..07aa03a63c98c707dd5f4ee187122591f55a4e68 100644 (file)
@@ -633,7 +633,7 @@ static void d_mount(struct dentry *covered, struct dentry *dentry)
        dentry->d_covers = covered;
 }
 
-static int do_umount(kdev_t dev, int unmount_root)
+static int do_umount(kdev_t dev, int unmount_root, int flags)
 {
        struct super_block * sb;
        int retval;
@@ -665,7 +665,7 @@ static int do_umount(kdev_t dev, int unmount_root)
         * about for the moment.
         */
         
-       if(sb->s_op->umount_begin)
+       if( (flags&MNT_FORCE) && sb->s_op->umount_begin)
                sb->s_op->umount_begin(sb);
 
        /*
@@ -717,7 +717,7 @@ out:
        return retval;
 }
 
-static int umount_dev(kdev_t dev)
+static int umount_dev(kdev_t dev, int flags)
 {
        int retval;
        struct inode * inode = get_empty_inode();
@@ -735,7 +735,7 @@ static int umount_dev(kdev_t dev)
 
        down(&mount_sem);
 
-       retval = do_umount(dev,0);
+       retval = do_umount(dev, 0, flags);
        if (!retval) {
                fsync_dev(dev);
                if (dev != ROOT_DEV) {
@@ -761,10 +761,11 @@ out:
  * If any other fields are ever needed by any block device release
  * functions, they should be faked here.  -- jrs
  *
- * For 2.3.x we want a new sys_umount syscall with flags (ie 'force')
+ * We now support a flag for forced unmount like the other 'big iron'
+ * unixes. Our API is identical to OSF/1 to avoid making a mess of AMD
  */
 
-asmlinkage int sys_umount(char * name)
+asmlinkage int sys_umount(char * name, int flags)
 {
        struct dentry * dentry;
        int retval;
@@ -794,12 +795,21 @@ asmlinkage int sys_umount(char * name)
                dput(dentry);
 
                if (!retval)
-                       retval = umount_dev(dev);
+                       retval = umount_dev(dev, flags);
        }
        unlock_kernel();
        return retval;
 }
 
+/*
+ *     The 2.0 compatible umount. No flags. 
+ */
+asmlinkage int sys_oldumount(char * name)
+{
+       return sys_umount(name,0);
+}
+
 /*
  * Check whether we can mount the specified device.
  */
@@ -1263,7 +1273,7 @@ __initfunc(static int do_change_root(kdev_t new_root_dev,const char *put_old))
                int umount_error;
 
                printk(KERN_NOTICE "Trying to unmount old root ... ");
-               umount_error = do_umount(old_root_dev,1);
+               umount_error = do_umount(old_root_dev,1, 0);
                if (!umount_error) {
                        printk("okay\n");
                        invalidate_buffers(old_root_dev);
index 8277ab6b240cb616d6b3a3d1d7348e649a823fd3..9e7184213a169d2212442e691323fe8c7da89011 100644 (file)
@@ -1822,6 +1822,8 @@ int vfat_rename(struct inode *old_dir,struct dentry *old_dentry,
                put_new_inode = 0;
        }
 
+       clear_inode(old_inode);
+
 rename_done:
        if (locked)
                fat_unlock_creation();
diff --git a/include/asm-alpha/apecs.h b/include/asm-alpha/apecs.h
deleted file mode 100644 (file)
index 3c7b9e0..0000000
+++ /dev/null
@@ -1,588 +0,0 @@
-#ifndef __ALPHA_APECS__H__
-#define __ALPHA_APECS__H__
-
-#include <linux/types.h>
-
-/*
- * APECS is the internal name for the 2107x chipset which provides
- * memory controller and PCI access for the 21064 chip based systems.
- *
- * This file is based on:
- *
- * DECchip 21071-AA and DECchip 21072-AA Core Logic Chipsets
- * Data Sheet
- *
- * EC-N0648-72
- *
- *
- * david.rusling@reo.mts.dec.com Initial Version.
- *
- */
-#include <linux/config.h>
-
-#ifdef CONFIG_ALPHA_XL
-/*
-   An AVANTI *might* be an XL, and an XL has only 27 bits of ISA address
-   that get passed through the PCI<->ISA bridge chip. So we've gotta use
-   both windows to max out the physical memory we can DMA to. Sigh...
-
-   If we try a window at 0 for 1GB as a work-around, we run into conflicts
-   with ISA/PCI bus memory which can't be relocated, like VGA aperture and
-   BIOS ROMs. So we must put the windows high enough to avoid these areas.
-
-   We put window 1 at BUS 64Mb for 64Mb, mapping physical 0 to 64Mb-1,
-   and window 2 at BUS 1Gb for 1Gb, mapping physical 0 to 1Gb-1.
-   Yes, this does map 0 to 64Mb-1 twice, but only window 1 will actually
-   be used for that range (via virt_to_bus()).
-
-   Note that we actually fudge the window 1 maximum as 48Mb instead of 64Mb,
-   to keep virt_to_bus() from returning an address in the first window, for
-   a data area that goes beyond the 64Mb first DMA window.  Sigh...
-   The fudge factor MUST match with <asm/dma.h> MAX_DMA_ADDRESS, but
-   we can't just use that here, because of header file looping... :-(
-
-   Window 1 will be used for all DMA from the ISA bus; yes, that does
-   limit what memory an ISA floppy or sound card or Ethernet can touch, but
-   it's also a known limitation on other platforms as well. We use the
-   same technique that is used on INTEL platforms with similar limitation:
-   set MAX_DMA_ADDRESS and clear some pages' DMAable flags during mem_init().
-   We trust that any ISA bus device drivers will *always* ask for DMAable
-   memory explicitly via kmalloc()/get_free_pages() flags arguments.
-
-   Note that most PCI bus devices' drivers do *not* explicitly ask for
-   DMAable memory; they count on being able to DMA to any memory they
-   get from kmalloc()/get_free_pages(). They will also use window 1 for
-   any physical memory accesses below 64Mb; the rest will be handled by
-   window 2, maxing out at 1Gb of memory. I trust this is enough... :-)
-
-   We hope that the area before the first window is large enough so that
-   there will be no overlap at the top end (64Mb). We *must* locate the
-   PCI cards' memory just below window 1, so that there's still the
-   possibility of being able to access it via SPARSE space. This is
-   important for cards such as the Matrox Millennium, whose Xserver
-   wants to access memory-mapped registers in byte and short lengths.
-
-   Note that the XL is treated differently from the AVANTI, even though
-   for most other things they are identical. It didn't seem reasonable to
-   make the AVANTI support pay for the limitations of the XL. It is true,
-   however, that an XL kernel will run on an AVANTI without problems.
-
-*/
-#define APECS_XL_DMA_WIN1_BASE         (64*1024*1024)
-#define APECS_XL_DMA_WIN1_SIZE         (64*1024*1024)
-#define APECS_XL_DMA_WIN1_SIZE_PARANOID        (48*1024*1024)
-#define APECS_XL_DMA_WIN2_BASE         (1024*1024*1024)
-#define APECS_XL_DMA_WIN2_SIZE         (1024*1024*1024)
-
-#else /* CONFIG_ALPHA_XL */
-
-/* these are for normal APECS family machines, AVANTI/MUSTANG/EB64/PC64 */
-#ifdef CONFIG_ALPHA_SRM_SETUP
-/* if we are using the SRM PCI setup, we'll need to use variables instead */
-#define APECS_DMA_WIN_BASE_DEFAULT     (1024*1024*1024)
-#define APECS_DMA_WIN_SIZE_DEFAULT     (1024*1024*1024)
-
-extern unsigned int APECS_DMA_WIN_BASE;
-extern unsigned int APECS_DMA_WIN_SIZE;
-
-#else /* SRM_SETUP */
-#define APECS_DMA_WIN_BASE     (1024*1024*1024)
-#define APECS_DMA_WIN_SIZE     (1024*1024*1024)
-#endif /* SRM_SETUP */
-
-#endif /* CONFIG_ALPHA_XL */
-
-/*
- * 21071-DA Control and Status registers.
- * These are used for PCI memory access.
- */
-#define APECS_IOC_DCSR                  (IDENT_ADDR + 0x1A0000000UL)
-#define APECS_IOC_PEAR                  (IDENT_ADDR + 0x1A0000020UL)
-#define APECS_IOC_SEAR                  (IDENT_ADDR + 0x1A0000040UL)
-#define APECS_IOC_DR1                   (IDENT_ADDR + 0x1A0000060UL)
-#define APECS_IOC_DR2                   (IDENT_ADDR + 0x1A0000080UL)
-#define APECS_IOC_DR3                   (IDENT_ADDR + 0x1A00000A0UL)
-
-#define APECS_IOC_TB1R                  (IDENT_ADDR + 0x1A00000C0UL)
-#define APECS_IOC_TB2R                  (IDENT_ADDR + 0x1A00000E0UL)
-
-#define APECS_IOC_PB1R                  (IDENT_ADDR + 0x1A0000100UL)
-#define APECS_IOC_PB2R                  (IDENT_ADDR + 0x1A0000120UL)
-
-#define APECS_IOC_PM1R                  (IDENT_ADDR + 0x1A0000140UL)
-#define APECS_IOC_PM2R                  (IDENT_ADDR + 0x1A0000160UL)
-
-#define APECS_IOC_HAXR0                 (IDENT_ADDR + 0x1A0000180UL)
-#define APECS_IOC_HAXR1                 (IDENT_ADDR + 0x1A00001A0UL)
-#define APECS_IOC_HAXR2                 (IDENT_ADDR + 0x1A00001C0UL)
-
-#define APECS_IOC_PMLT                  (IDENT_ADDR + 0x1A00001E0UL)
-
-#define APECS_IOC_TLBTAG0               (IDENT_ADDR + 0x1A0000200UL)
-#define APECS_IOC_TLBTAG1               (IDENT_ADDR + 0x1A0000220UL)
-#define APECS_IOC_TLBTAG2               (IDENT_ADDR + 0x1A0000240UL)
-#define APECS_IOC_TLBTAG3               (IDENT_ADDR + 0x1A0000260UL)
-#define APECS_IOC_TLBTAG4               (IDENT_ADDR + 0x1A0000280UL)
-#define APECS_IOC_TLBTAG5               (IDENT_ADDR + 0x1A00002A0UL)
-#define APECS_IOC_TLBTAG6               (IDENT_ADDR + 0x1A00002C0UL)
-#define APECS_IOC_TLBTAG7               (IDENT_ADDR + 0x1A00002E0UL)
-
-#define APECS_IOC_TLBDATA0              (IDENT_ADDR + 0x1A0000300UL)
-#define APECS_IOC_TLBDATA1              (IDENT_ADDR + 0x1A0000320UL)
-#define APECS_IOC_TLBDATA2              (IDENT_ADDR + 0x1A0000340UL)
-#define APECS_IOC_TLBDATA3              (IDENT_ADDR + 0x1A0000360UL)
-#define APECS_IOC_TLBDATA4              (IDENT_ADDR + 0x1A0000380UL)
-#define APECS_IOC_TLBDATA5              (IDENT_ADDR + 0x1A00003A0UL)
-#define APECS_IOC_TLBDATA6              (IDENT_ADDR + 0x1A00003C0UL)
-#define APECS_IOC_TLBDATA7              (IDENT_ADDR + 0x1A00003E0UL)
-
-#define APECS_IOC_TBIA                  (IDENT_ADDR + 0x1A0000400UL)
-
-
-/*
- * 21071-CA Control and Status registers.
- * These are used to program memory timing,
- *  configure memory and initialise the B-Cache.
- */
-#define APECS_MEM_GCR                  (IDENT_ADDR + 0x180000000UL)
-#define APECS_MEM_EDSR                 (IDENT_ADDR + 0x180000040UL)
-#define APECS_MEM_TAR                          (IDENT_ADDR + 0x180000060UL)
-#define APECS_MEM_ELAR                 (IDENT_ADDR + 0x180000080UL)
-#define APECS_MEM_EHAR                 (IDENT_ADDR + 0x1800000a0UL)
-#define APECS_MEM_SFT_RST              (IDENT_ADDR + 0x1800000c0UL)
-#define APECS_MEM_LDxLAR               (IDENT_ADDR + 0x1800000e0UL)
-#define APECS_MEM_LDxHAR               (IDENT_ADDR + 0x180000100UL)
-#define APECS_MEM_GTR                  (IDENT_ADDR + 0x180000200UL)
-#define APECS_MEM_RTR                  (IDENT_ADDR + 0x180000220UL)
-#define APECS_MEM_VFPR                 (IDENT_ADDR + 0x180000240UL)
-#define APECS_MEM_PDLDR                (IDENT_ADDR + 0x180000260UL)
-#define APECS_MEM_PDhDR                (IDENT_ADDR + 0x180000280UL)
-
-/* Bank x Base Address Register */
-#define APECS_MEM_B0BAR                (IDENT_ADDR + 0x180000800UL)
-#define APECS_MEM_B1BAR                (IDENT_ADDR + 0x180000820UL)
-#define APECS_MEM_B2BAR                (IDENT_ADDR + 0x180000840UL)
-#define APECS_MEM_B3BAR                (IDENT_ADDR + 0x180000860UL)
-#define APECS_MEM_B4BAR                (IDENT_ADDR + 0x180000880UL)
-#define APECS_MEM_B5BAR                (IDENT_ADDR + 0x1800008A0UL)
-#define APECS_MEM_B6BAR                (IDENT_ADDR + 0x1800008C0UL)
-#define APECS_MEM_B7BAR                (IDENT_ADDR + 0x1800008E0UL)
-#define APECS_MEM_B8BAR                (IDENT_ADDR + 0x180000900UL)
-
-/* Bank x Configuration Register */
-#define APECS_MEM_B0BCR                (IDENT_ADDR + 0x180000A00UL)
-#define APECS_MEM_B1BCR                (IDENT_ADDR + 0x180000A20UL)
-#define APECS_MEM_B2BCR                (IDENT_ADDR + 0x180000A40UL)
-#define APECS_MEM_B3BCR                (IDENT_ADDR + 0x180000A60UL)
-#define APECS_MEM_B4BCR                (IDENT_ADDR + 0x180000A80UL)
-#define APECS_MEM_B5BCR                (IDENT_ADDR + 0x180000AA0UL)
-#define APECS_MEM_B6BCR                (IDENT_ADDR + 0x180000AC0UL)
-#define APECS_MEM_B7BCR                (IDENT_ADDR + 0x180000AE0UL)
-#define APECS_MEM_B8BCR                (IDENT_ADDR + 0x180000B00UL)
-
-/* Bank x Timing Register A */
-#define APECS_MEM_B0TRA                (IDENT_ADDR + 0x180000C00UL)
-#define APECS_MEM_B1TRA                (IDENT_ADDR + 0x180000C20UL)
-#define APECS_MEM_B2TRA                (IDENT_ADDR + 0x180000C40UL)
-#define APECS_MEM_B3TRA                (IDENT_ADDR + 0x180000C60UL)
-#define APECS_MEM_B4TRA                (IDENT_ADDR + 0x180000C80UL)
-#define APECS_MEM_B5TRA                (IDENT_ADDR + 0x180000CA0UL)
-#define APECS_MEM_B6TRA                (IDENT_ADDR + 0x180000CC0UL)
-#define APECS_MEM_B7TRA                (IDENT_ADDR + 0x180000CE0UL)
-#define APECS_MEM_B8TRA                (IDENT_ADDR + 0x180000D00UL)
-
-/* Bank x Timing Register B */
-#define APECS_MEM_B0TRB                 (IDENT_ADDR + 0x180000E00UL)
-#define APECS_MEM_B1TRB                (IDENT_ADDR + 0x180000E20UL)
-#define APECS_MEM_B2TRB                (IDENT_ADDR + 0x180000E40UL)
-#define APECS_MEM_B3TRB                (IDENT_ADDR + 0x180000E60UL)
-#define APECS_MEM_B4TRB                (IDENT_ADDR + 0x180000E80UL)
-#define APECS_MEM_B5TRB                (IDENT_ADDR + 0x180000EA0UL)
-#define APECS_MEM_B6TRB                (IDENT_ADDR + 0x180000EC0UL)
-#define APECS_MEM_B7TRB                (IDENT_ADDR + 0x180000EE0UL)
-#define APECS_MEM_B8TRB                (IDENT_ADDR + 0x180000F00UL)
-
-
-/*
- * Memory spaces:
- */
-#define APECS_IACK_SC                  (IDENT_ADDR + 0x1b0000000UL)
-#define APECS_CONF                     (IDENT_ADDR + 0x1e0000000UL)
-#define APECS_IO                       (IDENT_ADDR + 0x1c0000000UL)
-#define APECS_SPARSE_MEM               (IDENT_ADDR + 0x200000000UL)
-#define APECS_DENSE_MEM                        (IDENT_ADDR + 0x300000000UL)
-#define DENSE_MEM(addr)                        APECS_DENSE_MEM
-
-/*
- * Bit definitions for I/O Controller status register 0:
- */
-#define APECS_IOC_STAT0_CMD            0xf
-#define APECS_IOC_STAT0_ERR            (1<<4)
-#define APECS_IOC_STAT0_LOST           (1<<5)
-#define APECS_IOC_STAT0_THIT           (1<<6)
-#define APECS_IOC_STAT0_TREF           (1<<7)
-#define APECS_IOC_STAT0_CODE_SHIFT     8
-#define APECS_IOC_STAT0_CODE_MASK      0x7
-#define APECS_IOC_STAT0_P_NBR_SHIFT    13
-#define APECS_IOC_STAT0_P_NBR_MASK     0x7ffff
-
-#define HAE_ADDRESS    APECS_IOC_HAXR1
-
-#ifdef __KERNEL__
-
-/*
- * Translate physical memory address as seen on (PCI) bus into
- * a kernel virtual address and vv.
- */
-/* NOTE: we fudge the window 1 maximum as 48Mb instead of 64Mb, to prevent 
-   virt_to_bus() from returning an address in the first window, for a
-   data area that goes beyond the 64Mb first DMA window. Sigh...
-   This MUST match with <asm/dma.h> MAX_DMA_ADDRESS for consistency, but
-   we can't just use that here, because of header file looping... :-(
-*/
-extern inline unsigned long virt_to_bus(void * address)
-{
-       unsigned long paddr = virt_to_phys(address);
-#ifdef CONFIG_ALPHA_XL
-       if (paddr < APECS_XL_DMA_WIN1_SIZE_PARANOID)
-         return paddr + APECS_XL_DMA_WIN1_BASE;
-       else
-         return paddr + APECS_XL_DMA_WIN2_BASE; /* win 2 xlates to 0 also */
-#else /* CONFIG_ALPHA_XL */
-       return paddr + APECS_DMA_WIN_BASE;
-#endif /* CONFIG_ALPHA_XL */
-}
-
-extern inline void * bus_to_virt(unsigned long address)
-{
-       /*
-        * This check is a sanity check but also ensures that bus
-        * address 0 maps to virtual address 0 which is useful to
-        * detect null "pointers" (the NCR driver is much simpler if
-        * NULL pointers are preserved).
-        */
-#ifdef CONFIG_ALPHA_XL
-        if (address < APECS_XL_DMA_WIN1_BASE)
-                return 0;
-        else if (address < (APECS_XL_DMA_WIN1_BASE + APECS_XL_DMA_WIN1_SIZE))
-                return phys_to_virt(address - APECS_XL_DMA_WIN1_BASE);
-       else /* should be more checking here, maybe? */
-                return phys_to_virt(address - APECS_XL_DMA_WIN2_BASE);
-#else /* CONFIG_ALPHA_XL */
-       if (address < APECS_DMA_WIN_BASE)
-               return 0;
-       return phys_to_virt(address - APECS_DMA_WIN_BASE);
-#endif /* CONFIG_ALPHA_XL */
-}
-
-/*
- * I/O functions:
- *
- * Unlike Jensen, the APECS machines have no concept of local
- * I/O---everything goes over the PCI bus.
- *
- * There is plenty room for optimization here.  In particular,
- * the Alpha's insb/insw/extb/extw should be useful in moving
- * data to/from the right byte-lanes.
- */
-
-#define vuip   volatile unsigned int *
-#define vulp   volatile unsigned long *
-
-extern inline unsigned int __inb(unsigned long addr)
-{
-       long result = *(vuip) ((addr << 5) + APECS_IO + 0x00);
-       result >>= (addr & 3) * 8;
-       return 0xffUL & result;
-}
-
-extern inline void __outb(unsigned char b, unsigned long addr)
-{
-       unsigned int w;
-
-       w = __kernel_insbl(b, addr & 3);
-       *(vuip) ((addr << 5) + APECS_IO + 0x00) = w;
-       mb();
-}
-
-extern inline unsigned int __inw(unsigned long addr)
-{
-       long result = *(vuip) ((addr << 5) + APECS_IO + 0x08);
-       result >>= (addr & 3) * 8;
-       return 0xffffUL & result;
-}
-
-extern inline void __outw(unsigned short b, unsigned long addr)
-{
-       unsigned int w;
-
-       w = __kernel_inswl(b, addr & 3);
-       *(vuip) ((addr << 5) + APECS_IO + 0x08) = w;
-       mb();
-}
-
-extern inline unsigned int __inl(unsigned long addr)
-{
-       return *(vuip) ((addr << 5) + APECS_IO + 0x18);
-}
-
-extern inline void __outl(unsigned int b, unsigned long addr)
-{
-       *(vuip) ((addr << 5) + APECS_IO + 0x18) = b;
-       mb();
-}
-
-
-/*
- * Memory functions.  64-bit and 32-bit accesses are done through
- * dense memory space, everything else through sparse space.
- */
-extern inline unsigned long __readb(unsigned long addr)
-{
-       unsigned long result, shift, msb;
-
-       shift = (addr & 0x3) * 8;
-       if (addr >= (1UL << 24)) {
-               msb = addr & 0xf8000000;
-               addr -= msb;
-               if (msb != hae.cache) {
-                       set_hae(msb);
-               }
-       }
-       result = *(vuip) ((addr << 5) + APECS_SPARSE_MEM + 0x00);
-       result >>= shift;
-       return 0xffUL & result;
-}
-
-extern inline unsigned long __readw(unsigned long addr)
-{
-       unsigned long result, shift, msb;
-
-       shift = (addr & 0x3) * 8;
-       if (addr >= (1UL << 24)) {
-               msb = addr & 0xf8000000;
-               addr -= msb;
-               if (msb != hae.cache) {
-                       set_hae(msb);
-               }
-       }
-       result = *(vuip) ((addr << 5) + APECS_SPARSE_MEM + 0x08);
-       result >>= shift;
-       return 0xffffUL & result;
-}
-
-extern inline unsigned long __readl(unsigned long addr)
-{
-       return *(vuip) (addr + APECS_DENSE_MEM);
-}
-
-extern inline unsigned long __readq(unsigned long addr)
-{
-       return *(vulp) (addr + APECS_DENSE_MEM);
-}
-
-extern inline void __writeb(unsigned char b, unsigned long addr)
-{
-       unsigned long msb;
-
-       if (addr >= (1UL << 24)) {
-               msb = addr & 0xf8000000;
-               addr -= msb;
-               if (msb != hae.cache) {
-                       set_hae(msb);
-               }
-       }
-       *(vuip) ((addr << 5) + APECS_SPARSE_MEM + 0x00) = b * 0x01010101;
-}
-
-extern inline void __writew(unsigned short b, unsigned long addr)
-{
-       unsigned long msb;
-
-       if (addr >= (1UL << 24)) {
-               msb = addr & 0xf8000000;
-               addr -= msb;
-               if (msb != hae.cache) {
-                       set_hae(msb);
-               }
-       }
-       *(vuip) ((addr << 5) + APECS_SPARSE_MEM + 0x08) = b * 0x00010001;
-}
-
-extern inline void __writel(unsigned int b, unsigned long addr)
-{
-       *(vuip) (addr + APECS_DENSE_MEM) = b;
-}
-
-extern inline void __writeq(unsigned long b, unsigned long addr)
-{
-       *(vulp) (addr + APECS_DENSE_MEM) = b;
-}
-
-#define inb(port) \
-(__builtin_constant_p((port))?__inb(port):_inb(port))
-
-#define outb(x, port) \
-(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port)))
-
-#define readl(a)       __readl((unsigned long)(a))
-#define readq(a)       __readq((unsigned long)(a))
-#define writel(v,a)    __writel((v),(unsigned long)(a))
-#define writeq(v,a)    __writeq((v),(unsigned long)(a))
-
-#undef vuip
-#undef vulp
-
-extern unsigned long apecs_init (unsigned long mem_start,
-                                unsigned long mem_end);
-
-#endif /* __KERNEL__ */
-
-/*
- * Data structure for handling APECS machine checks:
- */
-#ifdef CONFIG_ALPHA_MIKASA
-struct el_apecs_sysdata_mcheck {
-    unsigned long coma_gcr;
-    unsigned long coma_edsr;
-    unsigned long coma_ter;
-    unsigned long coma_elar;
-    unsigned long coma_ehar;
-    unsigned long coma_ldlr;
-    unsigned long coma_ldhr;
-    unsigned long coma_base0;
-    unsigned long coma_base1;
-    unsigned long coma_base2;
-    unsigned long coma_base3;
-    unsigned long coma_cnfg0;
-    unsigned long coma_cnfg1;
-    unsigned long coma_cnfg2;
-    unsigned long coma_cnfg3;
-    unsigned long epic_dcsr;
-    unsigned long epic_pear;
-    unsigned long epic_sear;
-    unsigned long epic_tbr1;
-    unsigned long epic_tbr2;
-    unsigned long epic_pbr1;
-    unsigned long epic_pbr2;
-    unsigned long epic_pmr1;
-    unsigned long epic_pmr2;
-    unsigned long epic_harx1;
-    unsigned long epic_harx2;
-    unsigned long epic_pmlt;
-    unsigned long epic_tag0;
-    unsigned long epic_tag1;
-    unsigned long epic_tag2;
-    unsigned long epic_tag3;
-    unsigned long epic_tag4;
-    unsigned long epic_tag5;
-    unsigned long epic_tag6;
-    unsigned long epic_tag7;
-    unsigned long epic_data0;
-    unsigned long epic_data1;
-    unsigned long epic_data2;
-    unsigned long epic_data3;
-    unsigned long epic_data4;
-    unsigned long epic_data5;
-    unsigned long epic_data6;
-    unsigned long epic_data7;
-
-    unsigned long pceb_vid;
-    unsigned long pceb_did;
-    unsigned long pceb_revision;
-    unsigned long pceb_command;
-    unsigned long pceb_status;
-    unsigned long pceb_latency;
-    unsigned long pceb_control;
-    unsigned long pceb_arbcon;
-    unsigned long pceb_arbpri;
-
-    unsigned long esc_id;
-    unsigned long esc_revision;
-    unsigned long esc_int0;
-    unsigned long esc_int1;
-    unsigned long esc_elcr0;
-    unsigned long esc_elcr1;
-    unsigned long esc_last_eisa;
-    unsigned long esc_nmi_stat;
-
-    unsigned long pci_ir;
-    unsigned long pci_imr;
-    unsigned long svr_mgr;
-};
-#else /* CONFIG_ALPHA_MIKASA */
-/* this for the normal APECS machines */
-struct el_apecs_sysdata_mcheck {
-    unsigned long coma_gcr;
-    unsigned long coma_edsr;
-    unsigned long coma_ter;
-    unsigned long coma_elar;
-    unsigned long coma_ehar;
-    unsigned long coma_ldlr;
-    unsigned long coma_ldhr;
-    unsigned long coma_base0;
-    unsigned long coma_base1;
-    unsigned long coma_base2;
-    unsigned long coma_cnfg0;
-    unsigned long coma_cnfg1;
-    unsigned long coma_cnfg2;
-    unsigned long epic_dcsr;
-    unsigned long epic_pear;
-    unsigned long epic_sear;
-    unsigned long epic_tbr1;
-    unsigned long epic_tbr2;
-    unsigned long epic_pbr1;
-    unsigned long epic_pbr2;
-    unsigned long epic_pmr1;
-    unsigned long epic_pmr2;
-    unsigned long epic_harx1;
-    unsigned long epic_harx2;
-    unsigned long epic_pmlt;
-    unsigned long epic_tag0;
-    unsigned long epic_tag1;
-    unsigned long epic_tag2;
-    unsigned long epic_tag3;
-    unsigned long epic_tag4;
-    unsigned long epic_tag5;
-    unsigned long epic_tag6;
-    unsigned long epic_tag7;
-    unsigned long epic_data0;
-    unsigned long epic_data1;
-    unsigned long epic_data2;
-    unsigned long epic_data3;
-    unsigned long epic_data4;
-    unsigned long epic_data5;
-    unsigned long epic_data6;
-    unsigned long epic_data7;
-};
-#endif /* CONFIG_ALPHA_MIKASA */
-
-struct el_procdata {
-    unsigned long paltemp[32];  /* PAL TEMP REGS. */
-    /* EV4-specific fields */
-    unsigned long exc_addr;     /* Address of excepting instruction. */
-    unsigned long exc_sum;      /* Summary of arithmetic traps. */
-    unsigned long exc_mask;     /* Exception mask (from exc_sum). */
-    unsigned long iccsr;        /* IBox hardware enables. */
-    unsigned long pal_base;     /* Base address for PALcode. */
-    unsigned long hier;         /* Hardware Interrupt Enable. */
-    unsigned long hirr;         /* Hardware Interrupt Request. */
-    unsigned long csr;          /* D-stream fault info. */
-    unsigned long dc_stat;      /* D-cache status (ECC/Parity Err). */
-    unsigned long dc_addr;      /* EV3 Phys Addr for ECC/DPERR. */
-    unsigned long abox_ctl;     /* ABox Control Register. */
-    unsigned long biu_stat;     /* BIU Status. */
-    unsigned long biu_addr;     /* BUI Address. */
-    unsigned long biu_ctl;      /* BIU Control. */
-    unsigned long fill_syndrome;/* For correcting ECC errors. */
-    unsigned long fill_addr;    /* Cache block which was being read */
-    unsigned long va;           /* Effective VA of fault or miss. */
-    unsigned long bc_tag;       /* Backup Cache Tag Probe Results.*/
-};
-
-
-#define RTC_PORT(x)    (0x70 + (x))
-#define RTC_ADDR(x)    (0x80 | (x))
-#define RTC_ALWAYS_BCD 0
-
-#endif /* __ALPHA_APECS__H__ */
index 21ac4e76e1c18cbc441b5cef4425339b982eb436..140f5783afc5feb5f39d3b5dc8aa4712b7a7a3af 100644 (file)
@@ -46,10 +46,10 @@ extern __inline__ void clear_bit(unsigned long nr, volatile void * addr)
 
        __asm__ __volatile__(
        "1:     ldl_l %0,%1\n"
-       "       and %0,%3,%2\n\t"
-       "       beq %2,2f\n\t"
-       "       xor %0,%3,%0\n\t"
-       "       stl_c %0,%1\n\t"
+       "       and %0,%3,%2\n"
+       "       beq %2,2f\n"
+       "       xor %0,%3,%0\n"
+       "       stl_c %0,%1\n"
        "       beq %0,3f\n"
        "2:\n"
        ".section .text2,\"ax\"\n"
@@ -66,8 +66,8 @@ extern __inline__ void change_bit(unsigned long nr, volatile void * addr)
 
        __asm__ __volatile__(
        "1:     ldl_l %0,%1\n"
-       "       xor %0,%2,%0\n\t"
-       "       stl_c %0,%1\n\t"
+       "       xor %0,%2,%0\n"
+       "       stl_c %0,%1\n"
        "       beq %0,3f\n"
        ".section .text2,\"ax\"\n"
        "3:     br 1b\n"
@@ -109,10 +109,10 @@ extern __inline__ unsigned long test_and_clear_bit(unsigned long nr,
 
        __asm__ __volatile__(
        "1:     ldl_l %0,%1\n"
-       "       and %0,%3,%2\n\t"
-       "       beq %2,2f\n\t"
-       "       xor %0,%3,%0\n\t"
-       "       stl_c %0,%1\n\t"
+       "       and %0,%3,%2\n"
+       "       beq %2,2f\n"
+       "       xor %0,%3,%0\n"
+       "       stl_c %0,%1\n"
        "       beq %0,3f\n"
        "2:\n"
        ".section .text2,\"ax\"\n"
@@ -133,9 +133,9 @@ extern __inline__ unsigned long test_and_change_bit(unsigned long nr,
 
        __asm__ __volatile__(
        "1:     ldl_l %0,%1\n"
-       "       and %0,%3,%2\n\t"
-       "       xor %0,%3,%0\n\t"
-       "       stl_c %0,%1\n\t"
+       "       and %0,%3,%2\n"
+       "       xor %0,%3,%0\n"
+       "       stl_c %0,%1\n"
        "       beq %0,3f\n"
        ".section .text2,\"ax\"\n"
        "3:     br 1b\n"
@@ -172,6 +172,11 @@ extern inline unsigned long ffz_b(unsigned long x)
 
 extern inline unsigned long ffz(unsigned long word)
 {
+#ifdef __alpha_cix__
+       /* Whee.  EV6 can calculate it directly.  */
+       unsigned long result;
+       __asm__("ctlz %1,%0" : "=r"(result) : "r"(~word));
+#else
        unsigned long bits, qofs, bofs;
 
        __asm__("cmpbge %1,%2,%0" : "=r"(bits) : "r"(word), "r"(~0UL));
@@ -180,6 +185,7 @@ extern inline unsigned long ffz(unsigned long word)
        bofs = ffz_b(bits);
 
        return qofs*8 + bofs;
+#endif
 }
 
 #ifdef __KERNEL__
@@ -190,16 +196,34 @@ extern inline unsigned long ffz(unsigned long word)
  * differs in spirit from the above ffz (man ffs).
  */
 
-#define ffs(x) generic_ffs(x)
+extern inline int ffs(int word)
+{
+       int result = ffz(~word);
+       return word ? result+1 : 0;
+}
 
 /*
  * hweightN: returns the hamming weight (i.e. the number
  * of bits set) of a N-bit word
  */
 
+#ifdef __alpha_cix__
+/* Whee.  EV6 can calculate it directly.  */
+extern __inline__ unsigned long hweight64(unsigned long w)
+{
+       unsigned long result;
+       __asm__("ctpop %1,%0" : "=r"(result) : "r"(w));
+       return result;
+}
+
+#define hweight32(x) hweight64((x) & 0xfffffffful)
+#define hweight16(x) hweight64((x) & 0xfffful)
+#define hweight8(x)  hweight64((x) & 0xfful)
+#else
 #define hweight32(x) generic_hweight32(x)
 #define hweight16(x) generic_hweight16(x)
-#define hweight8(x) generic_hweight8(x)
+#define hweight8(x)  generic_hweight8(x)
+#endif
 
 #endif /* __KERNEL__ */
 
diff --git a/include/asm-alpha/cia.h b/include/asm-alpha/cia.h
deleted file mode 100644 (file)
index 93f044b..0000000
+++ /dev/null
@@ -1,606 +0,0 @@
-#ifndef __ALPHA_CIA__H__
-#define __ALPHA_CIA__H__
-
-#include <linux/config.h>
-#include <linux/types.h>
-
-/*
- * CIA is the internal name for the 2117x chipset which provides
- * memory controller and PCI access for the 21164 chip based systems.
- *
- * This file is based on:
- *
- * DECchip 21171 Core Logic Chipset 
- * Technical Reference Manual
- *
- * EC-QE18B-TE
- *
- * david.rusling@reo.mts.dec.com Initial Version.
- *
- */
-
-/*------------------------------------------------------------------------**
-**                                                                        **
-**  EB164 I/O procedures                                                   **
-**                                                                        **
-**      inport[b|w|t|l], outport[b|w|t|l] 8:16:24:32 IO xfers             **
-**     inportbxt: 8 bits only                                            **
-**      inport:    alias of inportw                                       **
-**      outport:   alias of outportw                                      **
-**                                                                        **
-**      inmem[b|w|t|l], outmem[b|w|t|l] 8:16:24:32 ISA memory xfers       **
-**     inmembxt: 8 bits only                                             **
-**      inmem:    alias of inmemw                                         **
-**      outmem:   alias of outmemw                                        **
-**                                                                        **
-**------------------------------------------------------------------------*/
-
-
-/* CIA ADDRESS BIT DEFINITIONS
- *
- *  3 3 3 3|3 3 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |1| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |0|0|0|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
- *  |                                                                        \_/ \_/
- *  |                                                                         |   |
- *  +-- IO space, not cached.                                   Byte Enable --+   |
- *                                                              Transfer Length --+
- *
- *
- *
- *   Byte      Transfer
- *   Enable    Length    Transfer  Byte    Address
- *   adr<6:5>  adr<4:3>  Length    Enable  Adder
- *   ---------------------------------------------
- *      00        00      Byte      1110   0x000
- *      01        00      Byte      1101   0x020
- *      10        00      Byte      1011   0x040
- *      11        00      Byte      0111   0x060
- *
- *      00        01      Word      1100   0x008
- *      01        01      Word      1001   0x028 <= Not supported in this code.
- *      10        01      Word      0011   0x048
- *
- *      00        10      Tribyte   1000   0x010
- *      01        10      Tribyte   0001   0x030
- *
- *      10        11      Longword  0000   0x058
- *
- *      Note that byte enables are asserted low.
- *
- */
-
-#define BYTE_ENABLE_SHIFT 5
-#define TRANSFER_LENGTH_SHIFT 3
-
-#define MEM_R1_MASK 0x1fffffff  /* SPARSE Mem region 1 mask is 29 bits */
-#define MEM_R2_MASK 0x07ffffff  /* SPARSE Mem region 2 mask is 27 bits */
-#define MEM_R3_MASK 0x03ffffff  /* SPARSE Mem region 3 mask is 26 bits */
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-/* if we are using the SRM PCI setup, we'll need to use variables instead */
-#define CIA_DMA_WIN_BASE_DEFAULT    (1024*1024*1024)
-#define CIA_DMA_WIN_SIZE_DEFAULT    (1024*1024*1024)
-
-extern unsigned int CIA_DMA_WIN_BASE;
-extern unsigned int CIA_DMA_WIN_SIZE;
-
-#else /* SRM_SETUP */
-#define CIA_DMA_WIN_BASE            (1024*1024*1024)
-#define CIA_DMA_WIN_SIZE       (1024*1024*1024)
-#endif /* SRM_SETUP */
-
-/*
- * 21171-CA Control and Status Registers (p4-1)
- */
-#define CIA_IOC_CIA_REV               (IDENT_ADDR + 0x8740000080UL)
-#define CIA_IOC_PCI_LAT               (IDENT_ADDR + 0x87400000C0UL)
-#define CIA_IOC_CIA_CTRL              (IDENT_ADDR + 0x8740000100UL)
-#define CIA_IOC_CIA_CNFG              (IDENT_ADDR + 0x8740000140UL)
-#define CIA_IOC_HAE_MEM               (IDENT_ADDR + 0x8740000400UL)
-#define CIA_IOC_HAE_IO                (IDENT_ADDR + 0x8740000440UL)
-#define CIA_IOC_CFG                   (IDENT_ADDR + 0x8740000480UL)
-#define CIA_IOC_CACK_EN               (IDENT_ADDR + 0x8740000600UL)
-
-/*
- * 21171-CA Diagnostic Registers (p4-2)
- */
-#define CIA_IOC_CIA_DIAG              (IDENT_ADDR + 0x8740002000UL)
-#define CIA_IOC_DIAG_CHECK            (IDENT_ADDR + 0x8740003000UL)
-
-/*
- * 21171-CA Performance Monitor registers (p4-3)
- */
-#define CIA_IOC_PERF_MONITOR          (IDENT_ADDR + 0x8740004000UL)
-#define CIA_IOC_PERF_CONTROL          (IDENT_ADDR + 0x8740004040UL)
-
-/*
- * 21171-CA Error registers (p4-3)
- */
-#define CIA_IOC_CPU_ERR0              (IDENT_ADDR + 0x8740008000UL)
-#define CIA_IOC_CPU_ERR1              (IDENT_ADDR + 0x8740008040UL)
-#define CIA_IOC_CIA_ERR               (IDENT_ADDR + 0x8740008200UL)
-#define CIA_IOC_CIA_STAT              (IDENT_ADDR + 0x8740008240UL)
-#define CIA_IOC_ERR_MASK              (IDENT_ADDR + 0x8740008280UL)
-#define CIA_IOC_CIA_SYN               (IDENT_ADDR + 0x8740008300UL)
-#define CIA_IOC_MEM_ERR0              (IDENT_ADDR + 0x8740008400UL)
-#define CIA_IOC_MEM_ERR1              (IDENT_ADDR + 0x8740008440UL)
-#define CIA_IOC_PCI_ERR0              (IDENT_ADDR + 0x8740008800UL)
-#define CIA_IOC_PCI_ERR1              (IDENT_ADDR + 0x8740008840UL)
-#define CIA_IOC_PCI_ERR3              (IDENT_ADDR + 0x8740008880UL)
-
-/*
- * 2117A-CA PCI Address Translation Registers.
- */
-#define CIA_IOC_PCI_TBIA              (IDENT_ADDR + 0x8760000100UL)
-
-#define CIA_IOC_PCI_W0_BASE           (IDENT_ADDR + 0x8760000400UL)
-#define CIA_IOC_PCI_W0_MASK           (IDENT_ADDR + 0x8760000440UL)
-#define CIA_IOC_PCI_T0_BASE           (IDENT_ADDR + 0x8760000480UL)
-
-#define CIA_IOC_PCI_W1_BASE           (IDENT_ADDR + 0x8760000500UL)
-#define CIA_IOC_PCI_W1_MASK           (IDENT_ADDR + 0x8760000540UL)
-#define CIA_IOC_PCI_T1_BASE           (IDENT_ADDR + 0x8760000580UL)
-
-#define CIA_IOC_PCI_W2_BASE           (IDENT_ADDR + 0x8760000600UL)
-#define CIA_IOC_PCI_W2_MASK           (IDENT_ADDR + 0x8760000640UL)
-#define CIA_IOC_PCI_T2_BASE           (IDENT_ADDR + 0x8760000680UL)
-
-#define CIA_IOC_PCI_W3_BASE           (IDENT_ADDR + 0x8760000700UL)
-#define CIA_IOC_PCI_W3_MASK           (IDENT_ADDR + 0x8760000740UL)
-#define CIA_IOC_PCI_T3_BASE           (IDENT_ADDR + 0x8760000780UL)
-
-/*
- * 21171-CA System configuration registers (p4-3)
- */
-#define CIA_IOC_MCR                   (IDENT_ADDR + 0x8750000000UL)
-#define CIA_IOC_MBA0                  (IDENT_ADDR + 0x8750000600UL)
-#define CIA_IOC_MBA2                  (IDENT_ADDR + 0x8750000680UL)
-#define CIA_IOC_MBA4                  (IDENT_ADDR + 0x8750000700UL)
-#define CIA_IOC_MBA6                  (IDENT_ADDR + 0x8750000780UL)
-#define CIA_IOC_MBA8                  (IDENT_ADDR + 0x8750000800UL)
-#define CIA_IOC_MBAA                  (IDENT_ADDR + 0x8750000880UL)
-#define CIA_IOC_MBAC                  (IDENT_ADDR + 0x8750000900UL)
-#define CIA_IOC_MBAE                  (IDENT_ADDR + 0x8750000980UL)
-#define CIA_IOC_TMG0                  (IDENT_ADDR + 0x8750000B00UL)
-#define CIA_IOC_TMG1                  (IDENT_ADDR + 0x8750000B40UL)
-#define CIA_IOC_TMG2                  (IDENT_ADDR + 0x8750000B80UL)
-
-/*
- * Memory spaces:
- */
-#define CIA_IACK_SC                    (IDENT_ADDR + 0x8720000000UL)
-#define CIA_CONF                       (IDENT_ADDR + 0x8700000000UL)
-#define CIA_IO                         (IDENT_ADDR + 0x8580000000UL)
-#define CIA_SPARSE_MEM                 (IDENT_ADDR + 0x8000000000UL)
-#define CIA_SPARSE_MEM_R2              (IDENT_ADDR + 0x8400000000UL)
-#define CIA_SPARSE_MEM_R3              (IDENT_ADDR + 0x8500000000UL)
-#define CIA_DENSE_MEM                  (IDENT_ADDR + 0x8600000000UL)
-#define DENSE_MEM(addr)                        CIA_DENSE_MEM
-
-/*
- * ALCOR's GRU ASIC registers
- */
-#define GRU_INT_REQ                    (IDENT_ADDR + 0x8780000000UL)
-#define GRU_INT_MASK                   (IDENT_ADDR + 0x8780000040UL)
-#define GRU_INT_EDGE                   (IDENT_ADDR + 0x8780000080UL)
-#define GRU_INT_HILO                   (IDENT_ADDR + 0x87800000C0UL)
-#define GRU_INT_CLEAR                  (IDENT_ADDR + 0x8780000100UL)
-
-#define GRU_CACHE_CNFG                 (IDENT_ADDR + 0x8780000200UL)
-#define GRU_SCR                                (IDENT_ADDR + 0x8780000300UL)
-#define GRU_LED                                (IDENT_ADDR + 0x8780000800UL)
-#define GRU_RESET                      (IDENT_ADDR + 0x8780000900UL)
-
-#if defined(CONFIG_ALPHA_ALCOR)
-#define GRU_INT_REQ_BITS               0x800fffffUL
-#elif defined(CONFIG_ALPHA_XLT)
-#define GRU_INT_REQ_BITS               0x80003fffUL
-#else
-#define GRU_INT_REQ_BITS               0xffffffffUL
-#endif
-
-/*
- * Bit definitions for I/O Controller status register 0:
- */
-#define CIA_IOC_STAT0_CMD              0xf
-#define CIA_IOC_STAT0_ERR              (1<<4)
-#define CIA_IOC_STAT0_LOST             (1<<5)
-#define CIA_IOC_STAT0_THIT             (1<<6)
-#define CIA_IOC_STAT0_TREF             (1<<7)
-#define CIA_IOC_STAT0_CODE_SHIFT       8
-#define CIA_IOC_STAT0_CODE_MASK                0x7
-#define CIA_IOC_STAT0_P_NBR_SHIFT      13
-#define CIA_IOC_STAT0_P_NBR_MASK       0x7ffff
-
-#define HAE_ADDRESS                    CIA_IOC_HAE_MEM
-
-#ifdef __KERNEL__
-
-/*
- * Translate physical memory address as seen on (PCI) bus into
- * a kernel virtual address and vv.
- */
-extern inline unsigned long virt_to_bus(void * address)
-{
-       return virt_to_phys(address) + CIA_DMA_WIN_BASE;
-}
-
-extern inline void * bus_to_virt(unsigned long address)
-{
-       return phys_to_virt(address - CIA_DMA_WIN_BASE);
-}
-
-/*
- * I/O functions:
- *
- * CIA (the 2117x PCI/memory support chipset for the EV5 (21164)
- * series of processors uses a sparse address mapping scheme to
- * get at PCI memory and I/O.
- */
-
-#define vuip   volatile unsigned int *
-#define vulp   volatile unsigned long *
-
-extern inline unsigned int __inb(unsigned long addr)
-{
-       long result = *(vuip) ((addr << 5) + CIA_IO + 0x00);
-       result >>= (addr & 3) * 8;
-       return 0xffUL & result;
-}
-
-extern inline void __outb(unsigned char b, unsigned long addr)
-{
-       unsigned int w;
-
-       w = __kernel_insbl(b, addr & 3);
-       *(vuip) ((addr << 5) + CIA_IO + 0x00) = w;
-       mb();
-}
-
-extern inline unsigned int __inw(unsigned long addr)
-{
-       long result = *(vuip) ((addr << 5) + CIA_IO + 0x08);
-       result >>= (addr & 3) * 8;
-       return 0xffffUL & result;
-}
-
-extern inline void __outw(unsigned short b, unsigned long addr)
-{
-       unsigned int w;
-
-       w = __kernel_inswl(b, addr & 3);
-       *(vuip) ((addr << 5) + CIA_IO + 0x08) = w;
-       mb();
-}
-
-extern inline unsigned int __inl(unsigned long addr)
-{
-       return *(vuip) ((addr << 5) + CIA_IO + 0x18);
-}
-
-extern inline void __outl(unsigned int b, unsigned long addr)
-{
-       *(vuip) ((addr << 5) + CIA_IO + 0x18) = b;
-       mb();
-}
-
-
-/*
- * Memory functions.  64-bit and 32-bit accesses are done through
- * dense memory space, everything else through sparse space.
- * 
- * For reading and writing 8 and 16 bit quantities we need to 
- * go through one of the three sparse address mapping regions
- * and use the HAE_MEM CSR to provide some bits of the address.
- * The following few routines use only sparse address region 1
- * which gives 1Gbyte of accessible space which relates exactly
- * to the amount of PCI memory mapping *into* system address space.
- * See p 6-17 of the specification but it looks something like this:
- *
- * 21164 Address:
- * 
- *          3         2         1                                                               
- * 9876543210987654321098765432109876543210
- * 1ZZZZ0.PCI.QW.Address............BBLL                 
- *
- * ZZ = SBZ
- * BB = Byte offset
- * LL = Transfer length
- *
- * PCI Address:
- *
- * 3         2         1                                                               
- * 10987654321098765432109876543210
- * HHH....PCI.QW.Address........ 00
- *
- * HHH = 31:29 HAE_MEM CSR
- * 
- */
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-
-extern unsigned long cia_sm_base_r1, cia_sm_base_r2, cia_sm_base_r3;
-
-extern inline unsigned long __readb(unsigned long addr)
-{
-       unsigned long result, shift, work;
-
-       if ((addr >= cia_sm_base_r1) &&
-           (addr <= (cia_sm_base_r1 + MEM_R1_MASK)))
-         work = (((addr & MEM_R1_MASK) << 5) + CIA_SPARSE_MEM + 0x00);
-       else
-       if ((addr >= cia_sm_base_r2) &&
-           (addr <= (cia_sm_base_r2 + MEM_R2_MASK)))
-         work = (((addr & MEM_R2_MASK) << 5) + CIA_SPARSE_MEM_R2 + 0x00);
-       else
-       if ((addr >= cia_sm_base_r3) &&
-           (addr <= (cia_sm_base_r3 + MEM_R3_MASK)))
-         work = (((addr & MEM_R3_MASK) << 5) + CIA_SPARSE_MEM_R3 + 0x00);
-       else
-       {
-#if 0
-         printk("__readb: address 0x%lx not covered by HAE\n", addr);
-#endif
-         return 0x0ffUL;
-       }
-       shift = (addr & 0x3) << 3;
-       result = *(vuip) work;
-       result >>= shift;
-       return 0x0ffUL & result;
-}
-
-extern inline unsigned long __readw(unsigned long addr)
-{
-       unsigned long result, shift, work;
-
-       if ((addr >= cia_sm_base_r1) &&
-           (addr <= (cia_sm_base_r1 + MEM_R1_MASK)))
-         work = (((addr & MEM_R1_MASK) << 5) + CIA_SPARSE_MEM + 0x08);
-       else
-       if ((addr >= cia_sm_base_r2) &&
-           (addr <= (cia_sm_base_r2 + MEM_R2_MASK)))
-         work = (((addr & MEM_R2_MASK) << 5) + CIA_SPARSE_MEM_R2 + 0x08);
-       else
-       if ((addr >= cia_sm_base_r3) &&
-           (addr <= (cia_sm_base_r3 + MEM_R3_MASK)))
-         work = (((addr & MEM_R3_MASK) << 5) + CIA_SPARSE_MEM_R3 + 0x08);
-       else
-       {
-#if 0
-         printk("__readw: address 0x%lx not covered by HAE\n", addr);
-#endif
-         return 0x0ffffUL;
-       }
-       shift = (addr & 0x3) << 3;
-       result = *(vuip) work;
-       result >>= shift;
-       return 0x0ffffUL & result;
-}
-
-extern inline void __writeb(unsigned char b, unsigned long addr)
-{
-       unsigned long work;
-
-       if ((addr >= cia_sm_base_r1) &&
-           (addr <= (cia_sm_base_r1 + MEM_R1_MASK)))
-         work = (((addr & MEM_R1_MASK) << 5) + CIA_SPARSE_MEM + 0x00);
-       else
-       if ((addr >= cia_sm_base_r2) &&
-           (addr <= (cia_sm_base_r2 + MEM_R2_MASK)))
-         work = (((addr & MEM_R2_MASK) << 5) + CIA_SPARSE_MEM_R2 + 0x00);
-       else
-       if ((addr >= cia_sm_base_r3) &&
-           (addr <= (cia_sm_base_r3 + MEM_R3_MASK)))
-         work = (((addr & MEM_R3_MASK) << 5) + CIA_SPARSE_MEM_R3 + 0x00);
-       else
-       {
-#if 0
-         printk("__writeb: address 0x%lx not covered by HAE\n", addr);
-#endif
-         return;
-       }
-       *(vuip) work = b * 0x01010101;
-}
-
-extern inline void __writew(unsigned short b, unsigned long addr)
-{
-       unsigned long work;
-
-       if ((addr >= cia_sm_base_r1) &&
-           (addr <= (cia_sm_base_r1 + MEM_R1_MASK)))
-         work = (((addr & MEM_R1_MASK) << 5) + CIA_SPARSE_MEM + 0x00);
-       else
-       if ((addr >= cia_sm_base_r2) &&
-           (addr <= (cia_sm_base_r2 + MEM_R2_MASK)))
-         work = (((addr & MEM_R2_MASK) << 5) + CIA_SPARSE_MEM_R2 + 0x00);
-       else
-       if ((addr >= cia_sm_base_r3) &&
-           (addr <= (cia_sm_base_r3 + MEM_R3_MASK)))
-         work = (((addr & MEM_R3_MASK) << 5) + CIA_SPARSE_MEM_R3 + 0x00);
-       else
-       {
-#if 0
-         printk("__writew: address 0x%lx not covered by HAE\n", addr);
-#endif
-         return;
-       }
-       *(vuip) work = b * 0x00010001;
-}
-
-#else /* SRM_SETUP */
-
-extern inline unsigned long __readb(unsigned long addr)
-{
-       unsigned long result, shift, msb;
-
-       shift = (addr & 0x3) * 8 ;
-       msb = addr & 0xE0000000 ;
-       addr &= MEM_R1_MASK ;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       result = *(vuip) ((addr << 5) + CIA_SPARSE_MEM + 0x00) ;
-       result >>= shift;
-       return 0xffUL & result;
-}
-
-extern inline unsigned long __readw(unsigned long addr)
-{
-       unsigned long result, shift, msb;
-
-       shift = (addr & 0x3) * 8;
-       msb = addr & 0xE0000000 ;
-       addr &= MEM_R1_MASK ;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       result = *(vuip) ((addr << 5) + CIA_SPARSE_MEM + 0x08);
-       result >>= shift;
-       return 0xffffUL & result;
-}
-
-extern inline void __writeb(unsigned char b, unsigned long addr)
-{
-        unsigned long msb ; 
-
-       msb = addr & 0xE0000000 ;
-       addr &= MEM_R1_MASK ;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       *(vuip) ((addr << 5) + CIA_SPARSE_MEM + 0x00) = b * 0x01010101;
-}
-
-extern inline void __writew(unsigned short b, unsigned long addr)
-{
-        unsigned long msb ; 
-
-       msb = addr & 0xE0000000 ;
-       addr &= MEM_R1_MASK ;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       *(vuip) ((addr << 5) + CIA_SPARSE_MEM + 0x08) = b * 0x00010001;
-}
-
-#endif /* SRM_SETUP */
-
-extern inline unsigned long __readl(unsigned long addr)
-{
-       return *(vuip) (addr + CIA_DENSE_MEM);
-}
-
-extern inline unsigned long __readq(unsigned long addr)
-{
-       return *(vulp) (addr + CIA_DENSE_MEM);
-}
-
-extern inline void __writel(unsigned int b, unsigned long addr)
-{
-       *(vuip) (addr + CIA_DENSE_MEM) = b;
-}
-
-extern inline void __writeq(unsigned long b, unsigned long addr)
-{
-       *(vulp) (addr + CIA_DENSE_MEM) = b;
-}
-
-#define inb(port) \
-(__builtin_constant_p((port))?__inb(port):_inb(port))
-
-#define outb(x, port) \
-(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port)))
-
-#define readl(a)       __readl((unsigned long)(a))
-#define readq(a)       __readq((unsigned long)(a))
-#define writel(v,a)    __writel((v),(unsigned long)(a))
-#define writeq(v,a)    __writeq((v),(unsigned long)(a))
-
-#undef vuip
-#undef vulp
-
-extern unsigned long cia_init (unsigned long mem_start,
-                                unsigned long mem_end);
-
-#endif /* __KERNEL__ */
-
-/*
- * Data structure for handling CIA machine checks:
- */
-/* ev5-specific info: */
-struct el_procdata {
-       unsigned long shadow[8];        /* PALmode shadow registers */
-       unsigned long paltemp[24];      /* PAL temporary registers */
-       /* EV5-specific fields */
-       unsigned long exc_addr;         /* Address of excepting instruction. */
-       unsigned long exc_sum;          /* Summary of arithmetic traps. */
-       unsigned long exc_mask;         /* Exception mask (from exc_sum). */
-       unsigned long exc_base;         /* PALbase at time of exception. */
-       unsigned long isr;              /* Interrupt summary register. */
-       unsigned long icsr;             /* Ibox control register. */
-       unsigned long ic_perr_stat;
-       unsigned long dc_perr_stat;
-       unsigned long va;               /* Effective VA of fault or miss. */
-       unsigned long mm_stat;
-       unsigned long sc_addr;
-       unsigned long sc_stat;
-       unsigned long bc_tag_addr;
-       unsigned long ei_addr;
-       unsigned long fill_syn;
-       unsigned long ei_stat;
-       unsigned long ld_lock;
-};
-
-/* system-specific info: */
-struct el_CIA_sysdata_mcheck {
-    unsigned long      coma_gcr;                       
-    unsigned long      coma_edsr;                      
-    unsigned long      coma_ter;                       
-    unsigned long      coma_elar;                      
-    unsigned long      coma_ehar;                      
-    unsigned long      coma_ldlr;                      
-    unsigned long      coma_ldhr;                      
-    unsigned long      coma_base0;                     
-    unsigned long      coma_base1;                     
-    unsigned long      coma_base2;                     
-    unsigned long      coma_cnfg0;                     
-    unsigned long      coma_cnfg1;                     
-    unsigned long      coma_cnfg2;                     
-    unsigned long      epic_dcsr;                      
-    unsigned long      epic_pear;                      
-    unsigned long      epic_sear;                      
-    unsigned long      epic_tbr1;                      
-    unsigned long      epic_tbr2;                      
-    unsigned long      epic_pbr1;                      
-    unsigned long      epic_pbr2;                      
-    unsigned long      epic_pmr1;                      
-    unsigned long      epic_pmr2;                      
-    unsigned long      epic_harx1;                     
-    unsigned long      epic_harx2;                     
-    unsigned long      epic_pmlt;                      
-    unsigned long      epic_tag0;                      
-    unsigned long      epic_tag1;                      
-    unsigned long      epic_tag2;                      
-    unsigned long      epic_tag3;                      
-    unsigned long      epic_tag4;                      
-    unsigned long      epic_tag5;                      
-    unsigned long      epic_tag6;                      
-    unsigned long      epic_tag7;                      
-    unsigned long      epic_data0;                     
-    unsigned long      epic_data1;                     
-    unsigned long      epic_data2;                     
-    unsigned long      epic_data3;                     
-    unsigned long      epic_data4;                     
-    unsigned long      epic_data5;                     
-    unsigned long      epic_data6;                     
-    unsigned long      epic_data7;                     
-};
-
-#define RTC_PORT(x)    (0x70 + (x))
-#define RTC_ADDR(x)    (0x80 | (x))
-#define RTC_ALWAYS_BCD 0
-
-#endif /* __ALPHA_CIA__H__ */
diff --git a/include/asm-alpha/compiler.h b/include/asm-alpha/compiler.h
new file mode 100644 (file)
index 0000000..5656ce9
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef __ALPHA_COMPILER_H
+#define __ALPHA_COMPILER_H
+
+/* 
+ * Herein are macros we use when describing various patterns we want to GCC.
+ * In all cases we can get better schedules out of the compiler if we hide
+ * as little as possible inside inline assembly.  However, we want to be
+ * able to know what we'll get out before giving up inline assembly.  Thus
+ * these tests and macros.
+ */
+
+/*
+ * EGCS (of varying versions) does a good job of using insxl and extxl.
+ */
+
+#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
+#define __kernel_insbl(val, shift) \
+  (((unsigned long)(val) & 0xfful) << ((shift) * 8))
+#define __kernel_inswl(val, shift) \
+  (((unsigned long)(val) & 0xfffful) << ((shift) * 8))
+#else
+#define __kernel_insbl(val, shift)                                     \
+  ({ unsigned long __kir;                                              \
+     __asm__("insbl %2,%1,%0" : "=r"(__kir) : "rI"(shift), "r"(val));  \
+     __kir; })
+#define __kernel_inswl(val, shift)                                     \
+  ({ unsigned long __kir;                                              \
+     __asm__("inswl %2,%1,%0" : "=r"(__kir) : "rI"(shift), "r"(val));  \
+     __kir; })
+#endif
+
+#if __GNUC__ > 2 || __GNUC_MINOR__ >= 92
+#define __kernel_extbl(val, shift)  (((val) >> (((shift) & 7) * 8)) & 0xfful)
+#define __kernel_extwl(val, shift)  (((val) >> (((shift) & 7) * 8)) & 0xfffful)
+#else
+#define __kernel_extbl(val, shift)                                     \
+  ({ unsigned long __kir;                                              \
+     __asm__("extbl %2,%1,%0" : "=r"(__kir) : "rI"(shift), "r"(val));  \
+     __kir; })
+#define __kernel_extwl(val, shift)                                     \
+  ({ unsigned long __kir;                                              \
+     __asm__("extwl %2,%1,%0" : "=r"(__kir) : "rI"(shift), "r"(val));  \
+     __kir; })
+#endif
+
+
+/* 
+ * Beginning with EGCS 1.1, GCC defines __alpha_bwx__ when the BWX 
+ * extension is enabled.  Previous versions did not define anything
+ * we could test during compilation, so allow users to tell us when
+ * the compiler will DTRT.
+ */
+
+#if defined(HAVE_BWX) || defined(__alpha_bwx__)
+#define __kernel_ldbu(mem)     (mem)
+#define __kernel_ldwu(mem)     (mem)
+#define __kernel_stb(val,mem)  ((mem) = (val))
+#define __kernel_stw(val,mem)  ((mem) = (val))
+#else
+#define __kernel_ldbu(mem)                             \
+  ({ unsigned char __kir;                              \
+     __asm__("ldbu %0,%1" : "=r"(__kir) : "m"(mem));   \
+     __kir; })
+#define __kernel_ldwu(mem)                             \
+  ({ unsigned short __kir;                             \
+     __asm__("ldwu %0,%1" : "=r"(__kir) : "m"(mem));   \
+     __kir; })
+#define __kernel_stb(val,mem) \
+  __asm__("stb %1,%0" : "=m"(mem) : "r"(val))
+#define __kernel_stw(val,mem) \
+  __asm__("stw %1,%0" : "=m"(mem) : "r"(val))
+#endif
+
+#endif /* __ALPHA_COMPILER_H */
diff --git a/include/asm-alpha/core_apecs.h b/include/asm-alpha/core_apecs.h
new file mode 100644 (file)
index 0000000..a8f0bd6
--- /dev/null
@@ -0,0 +1,627 @@
+#ifndef __ALPHA_APECS__H__
+#define __ALPHA_APECS__H__
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/compiler.h>
+
+/*
+ * APECS is the internal name for the 2107x chipset which provides
+ * memory controller and PCI access for the 21064 chip based systems.
+ *
+ * This file is based on:
+ *
+ * DECchip 21071-AA and DECchip 21072-AA Core Logic Chipsets
+ * Data Sheet
+ *
+ * EC-N0648-72
+ *
+ *
+ * david.rusling@reo.mts.dec.com Initial Version.
+ *
+ */
+
+/*
+   An AVANTI *might* be an XL, and an XL has only 27 bits of ISA address
+   that get passed through the PCI<->ISA bridge chip. So we've gotta use
+   both windows to max out the physical memory we can DMA to. Sigh...
+
+   If we try a window at 0 for 1GB as a work-around, we run into conflicts
+   with ISA/PCI bus memory which can't be relocated, like VGA aperture and
+   BIOS ROMs. So we must put the windows high enough to avoid these areas.
+
+   We put window 1 at BUS 64Mb for 64Mb, mapping physical 0 to 64Mb-1,
+   and window 2 at BUS 1Gb for 1Gb, mapping physical 0 to 1Gb-1.
+   Yes, this does map 0 to 64Mb-1 twice, but only window 1 will actually
+   be used for that range (via virt_to_bus()).
+
+   Note that we actually fudge the window 1 maximum as 48Mb instead of 64Mb,
+   to keep virt_to_bus() from returning an address in the first window, for
+   a data area that goes beyond the 64Mb first DMA window.  Sigh...
+   The fudge factor MUST match with <asm/dma.h> MAX_DMA_ADDRESS, but
+   we can't just use that here, because of header file looping... :-(
+
+   Window 1 will be used for all DMA from the ISA bus; yes, that does
+   limit what memory an ISA floppy or sound card or Ethernet can touch, but
+   it's also a known limitation on other platforms as well. We use the
+   same technique that is used on INTEL platforms with similar limitation:
+   set MAX_DMA_ADDRESS and clear some pages' DMAable flags during mem_init().
+   We trust that any ISA bus device drivers will *always* ask for DMAable
+   memory explicitly via kmalloc()/get_free_pages() flags arguments.
+
+   Note that most PCI bus devices' drivers do *not* explicitly ask for
+   DMAable memory; they count on being able to DMA to any memory they
+   get from kmalloc()/get_free_pages(). They will also use window 1 for
+   any physical memory accesses below 64Mb; the rest will be handled by
+   window 2, maxing out at 1Gb of memory. I trust this is enough... :-)
+
+   We hope that the area before the first window is large enough so that
+   there will be no overlap at the top end (64Mb). We *must* locate the
+   PCI cards' memory just below window 1, so that there's still the
+   possibility of being able to access it via SPARSE space. This is
+   important for cards such as the Matrox Millennium, whose Xserver
+   wants to access memory-mapped registers in byte and short lengths.
+
+   Note that the XL is treated differently from the AVANTI, even though
+   for most other things they are identical. It didn't seem reasonable to
+   make the AVANTI support pay for the limitations of the XL. It is true,
+   however, that an XL kernel will run on an AVANTI without problems.
+*/
+#define APECS_XL_DMA_WIN1_BASE         (64*1024*1024)
+#define APECS_XL_DMA_WIN1_SIZE         (64*1024*1024)
+#define APECS_XL_DMA_WIN1_SIZE_PARANOID        (48*1024*1024)
+#define APECS_XL_DMA_WIN2_BASE         (1024*1024*1024)
+#define APECS_XL_DMA_WIN2_SIZE         (1024*1024*1024)
+
+
+/* These are for normal APECS family machines, AVANTI/MUSTANG/EB64/PC64.  */
+
+#define APECS_DMA_WIN_BASE_DEFAULT     (1024*1024*1024)
+#define APECS_DMA_WIN_SIZE_DEFAULT     (1024*1024*1024)
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
+#define APECS_DMA_WIN_BASE             alpha_mv.dma_win_base
+#define APECS_DMA_WIN_SIZE             alpha_mv.dma_win_size
+#else
+#define APECS_DMA_WIN_BASE             APECS_DMA_WIN_BASE_DEFAULT
+#define APECS_DMA_WIN_SIZE             APECS_DMA_WIN_SIZE_DEFAULT
+#endif
+
+
+/*
+ * 21071-DA Control and Status registers.
+ * These are used for PCI memory access.
+ */
+#define APECS_IOC_DCSR                  (IDENT_ADDR + 0x1A0000000UL)
+#define APECS_IOC_PEAR                  (IDENT_ADDR + 0x1A0000020UL)
+#define APECS_IOC_SEAR                  (IDENT_ADDR + 0x1A0000040UL)
+#define APECS_IOC_DR1                   (IDENT_ADDR + 0x1A0000060UL)
+#define APECS_IOC_DR2                   (IDENT_ADDR + 0x1A0000080UL)
+#define APECS_IOC_DR3                   (IDENT_ADDR + 0x1A00000A0UL)
+
+#define APECS_IOC_TB1R                  (IDENT_ADDR + 0x1A00000C0UL)
+#define APECS_IOC_TB2R                  (IDENT_ADDR + 0x1A00000E0UL)
+
+#define APECS_IOC_PB1R                  (IDENT_ADDR + 0x1A0000100UL)
+#define APECS_IOC_PB2R                  (IDENT_ADDR + 0x1A0000120UL)
+
+#define APECS_IOC_PM1R                  (IDENT_ADDR + 0x1A0000140UL)
+#define APECS_IOC_PM2R                  (IDENT_ADDR + 0x1A0000160UL)
+
+#define APECS_IOC_HAXR0                 (IDENT_ADDR + 0x1A0000180UL)
+#define APECS_IOC_HAXR1                 (IDENT_ADDR + 0x1A00001A0UL)
+#define APECS_IOC_HAXR2                 (IDENT_ADDR + 0x1A00001C0UL)
+
+#define APECS_IOC_PMLT                  (IDENT_ADDR + 0x1A00001E0UL)
+
+#define APECS_IOC_TLBTAG0               (IDENT_ADDR + 0x1A0000200UL)
+#define APECS_IOC_TLBTAG1               (IDENT_ADDR + 0x1A0000220UL)
+#define APECS_IOC_TLBTAG2               (IDENT_ADDR + 0x1A0000240UL)
+#define APECS_IOC_TLBTAG3               (IDENT_ADDR + 0x1A0000260UL)
+#define APECS_IOC_TLBTAG4               (IDENT_ADDR + 0x1A0000280UL)
+#define APECS_IOC_TLBTAG5               (IDENT_ADDR + 0x1A00002A0UL)
+#define APECS_IOC_TLBTAG6               (IDENT_ADDR + 0x1A00002C0UL)
+#define APECS_IOC_TLBTAG7               (IDENT_ADDR + 0x1A00002E0UL)
+
+#define APECS_IOC_TLBDATA0              (IDENT_ADDR + 0x1A0000300UL)
+#define APECS_IOC_TLBDATA1              (IDENT_ADDR + 0x1A0000320UL)
+#define APECS_IOC_TLBDATA2              (IDENT_ADDR + 0x1A0000340UL)
+#define APECS_IOC_TLBDATA3              (IDENT_ADDR + 0x1A0000360UL)
+#define APECS_IOC_TLBDATA4              (IDENT_ADDR + 0x1A0000380UL)
+#define APECS_IOC_TLBDATA5              (IDENT_ADDR + 0x1A00003A0UL)
+#define APECS_IOC_TLBDATA6              (IDENT_ADDR + 0x1A00003C0UL)
+#define APECS_IOC_TLBDATA7              (IDENT_ADDR + 0x1A00003E0UL)
+
+#define APECS_IOC_TBIA                  (IDENT_ADDR + 0x1A0000400UL)
+
+
+/*
+ * 21071-CA Control and Status registers.
+ * These are used to program memory timing,
+ *  configure memory and initialise the B-Cache.
+ */
+#define APECS_MEM_GCR                  (IDENT_ADDR + 0x180000000UL)
+#define APECS_MEM_EDSR                 (IDENT_ADDR + 0x180000040UL)
+#define APECS_MEM_TAR                          (IDENT_ADDR + 0x180000060UL)
+#define APECS_MEM_ELAR                 (IDENT_ADDR + 0x180000080UL)
+#define APECS_MEM_EHAR                 (IDENT_ADDR + 0x1800000a0UL)
+#define APECS_MEM_SFT_RST              (IDENT_ADDR + 0x1800000c0UL)
+#define APECS_MEM_LDxLAR               (IDENT_ADDR + 0x1800000e0UL)
+#define APECS_MEM_LDxHAR               (IDENT_ADDR + 0x180000100UL)
+#define APECS_MEM_GTR                  (IDENT_ADDR + 0x180000200UL)
+#define APECS_MEM_RTR                  (IDENT_ADDR + 0x180000220UL)
+#define APECS_MEM_VFPR                 (IDENT_ADDR + 0x180000240UL)
+#define APECS_MEM_PDLDR                (IDENT_ADDR + 0x180000260UL)
+#define APECS_MEM_PDhDR                (IDENT_ADDR + 0x180000280UL)
+
+/* Bank x Base Address Register */
+#define APECS_MEM_B0BAR                (IDENT_ADDR + 0x180000800UL)
+#define APECS_MEM_B1BAR                (IDENT_ADDR + 0x180000820UL)
+#define APECS_MEM_B2BAR                (IDENT_ADDR + 0x180000840UL)
+#define APECS_MEM_B3BAR                (IDENT_ADDR + 0x180000860UL)
+#define APECS_MEM_B4BAR                (IDENT_ADDR + 0x180000880UL)
+#define APECS_MEM_B5BAR                (IDENT_ADDR + 0x1800008A0UL)
+#define APECS_MEM_B6BAR                (IDENT_ADDR + 0x1800008C0UL)
+#define APECS_MEM_B7BAR                (IDENT_ADDR + 0x1800008E0UL)
+#define APECS_MEM_B8BAR                (IDENT_ADDR + 0x180000900UL)
+
+/* Bank x Configuration Register */
+#define APECS_MEM_B0BCR                (IDENT_ADDR + 0x180000A00UL)
+#define APECS_MEM_B1BCR                (IDENT_ADDR + 0x180000A20UL)
+#define APECS_MEM_B2BCR                (IDENT_ADDR + 0x180000A40UL)
+#define APECS_MEM_B3BCR                (IDENT_ADDR + 0x180000A60UL)
+#define APECS_MEM_B4BCR                (IDENT_ADDR + 0x180000A80UL)
+#define APECS_MEM_B5BCR                (IDENT_ADDR + 0x180000AA0UL)
+#define APECS_MEM_B6BCR                (IDENT_ADDR + 0x180000AC0UL)
+#define APECS_MEM_B7BCR                (IDENT_ADDR + 0x180000AE0UL)
+#define APECS_MEM_B8BCR                (IDENT_ADDR + 0x180000B00UL)
+
+/* Bank x Timing Register A */
+#define APECS_MEM_B0TRA                (IDENT_ADDR + 0x180000C00UL)
+#define APECS_MEM_B1TRA                (IDENT_ADDR + 0x180000C20UL)
+#define APECS_MEM_B2TRA                (IDENT_ADDR + 0x180000C40UL)
+#define APECS_MEM_B3TRA                (IDENT_ADDR + 0x180000C60UL)
+#define APECS_MEM_B4TRA                (IDENT_ADDR + 0x180000C80UL)
+#define APECS_MEM_B5TRA                (IDENT_ADDR + 0x180000CA0UL)
+#define APECS_MEM_B6TRA                (IDENT_ADDR + 0x180000CC0UL)
+#define APECS_MEM_B7TRA                (IDENT_ADDR + 0x180000CE0UL)
+#define APECS_MEM_B8TRA                (IDENT_ADDR + 0x180000D00UL)
+
+/* Bank x Timing Register B */
+#define APECS_MEM_B0TRB                 (IDENT_ADDR + 0x180000E00UL)
+#define APECS_MEM_B1TRB                (IDENT_ADDR + 0x180000E20UL)
+#define APECS_MEM_B2TRB                (IDENT_ADDR + 0x180000E40UL)
+#define APECS_MEM_B3TRB                (IDENT_ADDR + 0x180000E60UL)
+#define APECS_MEM_B4TRB                (IDENT_ADDR + 0x180000E80UL)
+#define APECS_MEM_B5TRB                (IDENT_ADDR + 0x180000EA0UL)
+#define APECS_MEM_B6TRB                (IDENT_ADDR + 0x180000EC0UL)
+#define APECS_MEM_B7TRB                (IDENT_ADDR + 0x180000EE0UL)
+#define APECS_MEM_B8TRB                (IDENT_ADDR + 0x180000F00UL)
+
+
+/*
+ * Memory spaces:
+ */
+#define APECS_IACK_SC                  (IDENT_ADDR + 0x1b0000000UL)
+#define APECS_CONF                     (IDENT_ADDR + 0x1e0000000UL)
+#define APECS_IO                       (IDENT_ADDR + 0x1c0000000UL)
+#define APECS_SPARSE_MEM               (IDENT_ADDR + 0x200000000UL)
+#define APECS_DENSE_MEM                        (IDENT_ADDR + 0x300000000UL)
+
+
+/*
+ * Bit definitions for I/O Controller status register 0:
+ */
+#define APECS_IOC_STAT0_CMD            0xf
+#define APECS_IOC_STAT0_ERR            (1<<4)
+#define APECS_IOC_STAT0_LOST           (1<<5)
+#define APECS_IOC_STAT0_THIT           (1<<6)
+#define APECS_IOC_STAT0_TREF           (1<<7)
+#define APECS_IOC_STAT0_CODE_SHIFT     8
+#define APECS_IOC_STAT0_CODE_MASK      0x7
+#define APECS_IOC_STAT0_P_NBR_SHIFT    13
+#define APECS_IOC_STAT0_P_NBR_MASK     0x7ffff
+
+#define APECS_HAE_ADDRESS              APECS_IOC_HAXR1
+
+
+/*
+ * Data structure for handling APECS machine checks:
+ */
+
+struct el_apecs_mikasa_sysdata_mcheck
+{
+       unsigned long coma_gcr;
+       unsigned long coma_edsr;
+       unsigned long coma_ter;
+       unsigned long coma_elar;
+       unsigned long coma_ehar;
+       unsigned long coma_ldlr;
+       unsigned long coma_ldhr;
+       unsigned long coma_base0;
+       unsigned long coma_base1;
+       unsigned long coma_base2;
+       unsigned long coma_base3;
+       unsigned long coma_cnfg0;
+       unsigned long coma_cnfg1;
+       unsigned long coma_cnfg2;
+       unsigned long coma_cnfg3;
+       unsigned long epic_dcsr;
+       unsigned long epic_pear;
+       unsigned long epic_sear;
+       unsigned long epic_tbr1;
+       unsigned long epic_tbr2;
+       unsigned long epic_pbr1;
+       unsigned long epic_pbr2;
+       unsigned long epic_pmr1;
+       unsigned long epic_pmr2;
+       unsigned long epic_harx1;
+       unsigned long epic_harx2;
+       unsigned long epic_pmlt;
+       unsigned long epic_tag0;
+       unsigned long epic_tag1;
+       unsigned long epic_tag2;
+       unsigned long epic_tag3;
+       unsigned long epic_tag4;
+       unsigned long epic_tag5;
+       unsigned long epic_tag6;
+       unsigned long epic_tag7;
+       unsigned long epic_data0;
+       unsigned long epic_data1;
+       unsigned long epic_data2;
+       unsigned long epic_data3;
+       unsigned long epic_data4;
+       unsigned long epic_data5;
+       unsigned long epic_data6;
+       unsigned long epic_data7;
+
+       unsigned long pceb_vid;
+       unsigned long pceb_did;
+       unsigned long pceb_revision;
+       unsigned long pceb_command;
+       unsigned long pceb_status;
+       unsigned long pceb_latency;
+       unsigned long pceb_control;
+       unsigned long pceb_arbcon;
+       unsigned long pceb_arbpri;
+
+       unsigned long esc_id;
+       unsigned long esc_revision;
+       unsigned long esc_int0;
+       unsigned long esc_int1;
+       unsigned long esc_elcr0;
+       unsigned long esc_elcr1;
+       unsigned long esc_last_eisa;
+       unsigned long esc_nmi_stat;
+
+       unsigned long pci_ir;
+       unsigned long pci_imr;
+       unsigned long svr_mgr;
+};
+
+/* This for the normal APECS machines.  */
+struct el_apecs_sysdata_mcheck
+{
+       unsigned long coma_gcr;
+       unsigned long coma_edsr;
+       unsigned long coma_ter;
+       unsigned long coma_elar;
+       unsigned long coma_ehar;
+       unsigned long coma_ldlr;
+       unsigned long coma_ldhr;
+       unsigned long coma_base0;
+       unsigned long coma_base1;
+       unsigned long coma_base2;
+       unsigned long coma_cnfg0;
+       unsigned long coma_cnfg1;
+       unsigned long coma_cnfg2;
+       unsigned long epic_dcsr;
+       unsigned long epic_pear;
+       unsigned long epic_sear;
+       unsigned long epic_tbr1;
+       unsigned long epic_tbr2;
+       unsigned long epic_pbr1;
+       unsigned long epic_pbr2;
+       unsigned long epic_pmr1;
+       unsigned long epic_pmr2;
+       unsigned long epic_harx1;
+       unsigned long epic_harx2;
+       unsigned long epic_pmlt;
+       unsigned long epic_tag0;
+       unsigned long epic_tag1;
+       unsigned long epic_tag2;
+       unsigned long epic_tag3;
+       unsigned long epic_tag4;
+       unsigned long epic_tag5;
+       unsigned long epic_tag6;
+       unsigned long epic_tag7;
+       unsigned long epic_data0;
+       unsigned long epic_data1;
+       unsigned long epic_data2;
+       unsigned long epic_data3;
+       unsigned long epic_data4;
+       unsigned long epic_data5;
+       unsigned long epic_data6;
+       unsigned long epic_data7;
+};
+
+struct el_apecs_procdata
+{
+       unsigned long paltemp[32];  /* PAL TEMP REGS. */
+       /* EV4-specific fields */
+       unsigned long exc_addr;     /* Address of excepting instruction. */
+       unsigned long exc_sum;      /* Summary of arithmetic traps. */
+       unsigned long exc_mask;     /* Exception mask (from exc_sum). */
+       unsigned long iccsr;        /* IBox hardware enables. */
+       unsigned long pal_base;     /* Base address for PALcode. */
+       unsigned long hier;         /* Hardware Interrupt Enable. */
+       unsigned long hirr;         /* Hardware Interrupt Request. */
+       unsigned long csr;          /* D-stream fault info. */
+       unsigned long dc_stat;      /* D-cache status (ECC/Parity Err). */
+       unsigned long dc_addr;      /* EV3 Phys Addr for ECC/DPERR. */
+       unsigned long abox_ctl;     /* ABox Control Register. */
+       unsigned long biu_stat;     /* BIU Status. */
+       unsigned long biu_addr;     /* BUI Address. */
+       unsigned long biu_ctl;      /* BIU Control. */
+       unsigned long fill_syndrome;/* For correcting ECC errors. */
+       unsigned long fill_addr;    /* Cache block which was being read */
+       unsigned long va;           /* Effective VA of fault or miss. */
+       unsigned long bc_tag;       /* Backup Cache Tag Probe Results.*/
+};
+
+
+#ifdef __KERNEL__
+
+#ifndef __EXTERN_INLINE
+#define __EXTERN_INLINE extern inline
+#define __IO_EXTERN_INLINE
+#endif
+
+/*
+ * Translate physical memory address as seen on (PCI) bus into
+ * a kernel virtual address and vv.
+ */
+
+/*
+ * NOTE: we fudge the window 1 maximum as 48Mb instead of 64Mb, to prevent 
+ * virt_to_bus() from returning an address in the first window, for a
+ * data area that goes beyond the 64Mb first DMA window. Sigh...
+ * This MUST match with <asm/dma.h> MAX_DMA_ADDRESS for consistency, but
+ * we can't just use that here, because of header file looping... :-(
+ */
+
+__EXTERN_INLINE unsigned long apecs_virt_to_bus(void * address)
+{
+       unsigned long paddr = virt_to_phys(address);
+       return paddr + APECS_DMA_WIN_BASE;
+}
+
+static inline unsigned long apecs_xl_virt_to_bus(void * address)
+{
+       unsigned long paddr = virt_to_phys(address);
+       if (paddr < APECS_XL_DMA_WIN1_SIZE_PARANOID)
+         return paddr + APECS_XL_DMA_WIN1_BASE;
+       else
+         return paddr + APECS_XL_DMA_WIN2_BASE; /* win 2 xlates to 0 also */
+}
+
+__EXTERN_INLINE void * apecs_bus_to_virt(unsigned long address)
+{
+       /*
+        * This check is a sanity check but also ensures that bus
+        * address 0 maps to virtual address 0 which is useful to
+        * detect null "pointers" (the NCR driver is much simpler if
+        * NULL pointers are preserved).
+        */
+       if (address < APECS_DMA_WIN_BASE)
+               return 0;
+       return phys_to_virt(address - APECS_DMA_WIN_BASE);
+}
+
+static inline void * apecs_xl_bus_to_virt(unsigned long address)
+{
+       /*
+        * This check is a sanity check but also ensures that bus
+        * address 0 maps to virtual address 0 which is useful to
+        * detect null "pointers" (the NCR driver is much simpler if
+        * NULL pointers are preserved).
+        */
+        if (address < APECS_XL_DMA_WIN1_BASE)
+                return 0;
+        else if (address < (APECS_XL_DMA_WIN1_BASE + APECS_XL_DMA_WIN1_SIZE))
+                address -= APECS_XL_DMA_WIN1_BASE;
+       else /* should be more checking here, maybe? */
+                address -= APECS_XL_DMA_WIN2_BASE;
+       return phys_to_virt(address);
+}
+
+/*
+ * I/O functions:
+ *
+ * Unlike Jensen, the APECS machines have no concept of local
+ * I/O---everything goes over the PCI bus.
+ *
+ * There is plenty room for optimization here.  In particular,
+ * the Alpha's insb/insw/extb/extw should be useful in moving
+ * data to/from the right byte-lanes.
+ */
+
+#define vip    volatile int *
+#define vuip   volatile unsigned int *
+#define vulp   volatile unsigned long *
+
+__EXTERN_INLINE unsigned int apecs_inb(unsigned long addr)
+{
+       long result = *(vip) ((addr << 5) + APECS_IO + 0x00);
+       return __kernel_extbl(result, addr & 3);
+}
+
+__EXTERN_INLINE void apecs_outb(unsigned char b, unsigned long addr)
+{
+       unsigned int w;
+
+       w = __kernel_insbl(b, addr & 3);
+       *(vuip) ((addr << 5) + APECS_IO + 0x00) = w;
+       mb();
+}
+
+__EXTERN_INLINE unsigned int apecs_inw(unsigned long addr)
+{
+       long result = *(vip) ((addr << 5) + APECS_IO + 0x08);
+       return __kernel_extwl(result, addr & 3);
+}
+
+__EXTERN_INLINE void apecs_outw(unsigned short b, unsigned long addr)
+{
+       unsigned int w;
+
+       w = __kernel_inswl(b, addr & 3);
+       *(vuip) ((addr << 5) + APECS_IO + 0x08) = w;
+       mb();
+}
+
+__EXTERN_INLINE unsigned int apecs_inl(unsigned long addr)
+{
+       return *(vuip) ((addr << 5) + APECS_IO + 0x18);
+}
+
+__EXTERN_INLINE void apecs_outl(unsigned int b, unsigned long addr)
+{
+       *(vuip) ((addr << 5) + APECS_IO + 0x18) = b;
+       mb();
+}
+
+
+/*
+ * Memory functions.  64-bit and 32-bit accesses are done through
+ * dense memory space, everything else through sparse space.
+ */
+
+__EXTERN_INLINE unsigned long apecs_readb(unsigned long addr)
+{
+       unsigned long result, msb;
+
+       if (addr >= (1UL << 24)) {
+               msb = addr & 0xf8000000;
+               addr -= msb;
+               set_hae(msb);
+       }
+       result = *(vip) ((addr << 5) + APECS_SPARSE_MEM + 0x00);
+       return __kernel_extbl(result, addr & 3);
+}
+
+__EXTERN_INLINE unsigned long apecs_readw(unsigned long addr)
+{
+       unsigned long result, msb;
+
+       if (addr >= (1UL << 24)) {
+               msb = addr & 0xf8000000;
+               addr -= msb;
+               set_hae(msb);
+       }
+       result = *(vip) ((addr << 5) + APECS_SPARSE_MEM + 0x08);
+       return __kernel_extwl(result, addr & 3);
+}
+
+__EXTERN_INLINE unsigned long apecs_readl(unsigned long addr)
+{
+       return *(vuip) (addr + APECS_DENSE_MEM);
+}
+
+__EXTERN_INLINE unsigned long apecs_readq(unsigned long addr)
+{
+       return *(vulp) (addr + APECS_DENSE_MEM);
+}
+
+__EXTERN_INLINE void apecs_writeb(unsigned char b, unsigned long addr)
+{
+       unsigned long msb;
+
+       if (addr >= (1UL << 24)) {
+               msb = addr & 0xf8000000;
+               addr -= msb;
+               set_hae(msb);
+       }
+       *(vuip) ((addr << 5) + APECS_SPARSE_MEM + 0x00) = b * 0x01010101;
+}
+
+__EXTERN_INLINE void apecs_writew(unsigned short b, unsigned long addr)
+{
+       unsigned long msb;
+
+       if (addr >= (1UL << 24)) {
+               msb = addr & 0xf8000000;
+               addr -= msb;
+               set_hae(msb);
+       }
+       *(vuip) ((addr << 5) + APECS_SPARSE_MEM + 0x08) = b * 0x00010001;
+}
+
+__EXTERN_INLINE void apecs_writel(unsigned int b, unsigned long addr)
+{
+       *(vuip) (addr + APECS_DENSE_MEM) = b;
+}
+
+__EXTERN_INLINE void apecs_writeq(unsigned long b, unsigned long addr)
+{
+       *(vulp) (addr + APECS_DENSE_MEM) = b;
+}
+
+/* Find the DENSE memory area for a given bus address.  */
+
+__EXTERN_INLINE unsigned long apecs_dense_mem(unsigned long addr)
+{
+       return APECS_DENSE_MEM;
+}
+
+#undef vip
+#undef vuip
+#undef vulp
+
+#ifdef __WANT_IO_DEF
+
+#ifdef CONFIG_ALPHA_XL
+#define virt_to_bus    apecs_xl_virt_to_bus
+#define bus_to_virt    apecs_xl_bus_to_virt
+#else
+#define virt_to_bus    apecs_virt_to_bus
+#define bus_to_virt    apecs_bus_to_virt
+#endif
+
+#define __inb          apecs_inb
+#define __inw          apecs_inw
+#define __inl          apecs_inl
+#define __outb         apecs_outb
+#define __outw         apecs_outw
+#define __outl         apecs_outl
+#define __readb                apecs_readb
+#define __readw                apecs_readw
+#define __readl                apecs_readl
+#define __readq                apecs_readq
+#define __writeb       apecs_writeb
+#define __writew       apecs_writew
+#define __writel       apecs_writel
+#define __writeq       apecs_writeq
+#define dense_mem      apecs_dense_mem
+
+#define inb(port) \
+(__builtin_constant_p((port))?__inb(port):_inb(port))
+
+#define outb(x, port) \
+(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port)))
+
+#define readl(a)       __readl((unsigned long)(a))
+#define readq(a)       __readq((unsigned long)(a))
+#define writel(v,a)    __writel((v),(unsigned long)(a))
+#define writeq(v,a)    __writeq((v),(unsigned long)(a))
+
+#endif /* __WANT_IO_DEF */
+
+#ifdef __IO_EXTERN_INLINE
+#undef __EXTERN_INLINE
+#undef __IO_EXTERN_INLINE
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* __ALPHA_APECS__H__ */
diff --git a/include/asm-alpha/core_cia.h b/include/asm-alpha/core_cia.h
new file mode 100644 (file)
index 0000000..32fd81f
--- /dev/null
@@ -0,0 +1,601 @@
+#ifndef __ALPHA_CIA__H__
+#define __ALPHA_CIA__H__
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/compiler.h>
+
+/*
+ * CIA is the internal name for the 2117x chipset which provides
+ * memory controller and PCI access for the 21164 chip based systems.
+ *
+ * This file is based on:
+ *
+ * DECchip 21171 Core Logic Chipset 
+ * Technical Reference Manual
+ *
+ * EC-QE18B-TE
+ *
+ * david.rusling@reo.mts.dec.com Initial Version.
+ *
+ */
+
+/*------------------------------------------------------------------------**
+**                                                                        **
+**  EB164 I/O procedures                                                  **
+**                                                                        **
+**      inport[b|w|t|l], outport[b|w|t|l] 8:16:24:32 IO xfers             **
+**     inportbxt: 8 bits only                                            **
+**      inport:    alias of inportw                                       **
+**      outport:   alias of outportw                                      **
+**                                                                        **
+**      inmem[b|w|t|l], outmem[b|w|t|l] 8:16:24:32 ISA memory xfers       **
+**     inmembxt: 8 bits only                                             **
+**      inmem:    alias of inmemw                                         **
+**      outmem:   alias of outmemw                                        **
+**                                                                        **
+**------------------------------------------------------------------------*/
+
+
+/* CIA ADDRESS BIT DEFINITIONS
+ *
+ *  3 3 3 3|3 3 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |1| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |0|0|0|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
+ *  |                                                                        \_/ \_/
+ *  |                                                                         |   |
+ *  +-- IO space, not cached.                                   Byte Enable --+   |
+ *                                                              Transfer Length --+
+ *
+ *
+ *
+ *   Byte      Transfer
+ *   Enable    Length    Transfer  Byte    Address
+ *   adr<6:5>  adr<4:3>  Length    Enable  Adder
+ *   ---------------------------------------------
+ *      00        00      Byte      1110   0x000
+ *      01        00      Byte      1101   0x020
+ *      10        00      Byte      1011   0x040
+ *      11        00      Byte      0111   0x060
+ *
+ *      00        01      Word      1100   0x008
+ *      01        01      Word      1001   0x028 <= Not supported in this code.
+ *      10        01      Word      0011   0x048
+ *
+ *      00        10      Tribyte   1000   0x010
+ *      01        10      Tribyte   0001   0x030
+ *
+ *      10        11      Longword  0000   0x058
+ *
+ *      Note that byte enables are asserted low.
+ *
+ */
+
+#define CIA_MEM_R1_MASK 0x1fffffff  /* SPARSE Mem region 1 mask is 29 bits */
+#define CIA_MEM_R2_MASK 0x07ffffff  /* SPARSE Mem region 2 mask is 27 bits */
+#define CIA_MEM_R3_MASK 0x03ffffff  /* SPARSE Mem region 3 mask is 26 bits */
+
+#define CIA_DMA_WIN_BASE_DEFAULT       (1024*1024*1024)
+#define CIA_DMA_WIN_SIZE_DEFAULT       (1024*1024*1024)
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
+#define CIA_DMA_WIN_BASE               alpha_mv.dma_win_base
+#define CIA_DMA_WIN_SIZE               alpha_mv.dma_win_size
+#else
+#define CIA_DMA_WIN_BASE               CIA_DMA_WIN_SIZE_DEFAULT
+#define CIA_DMA_WIN_SIZE               CIA_DMA_WIN_SIZE_DEFAULT
+#endif
+
+/*
+ * 21171-CA Control and Status Registers (p4-1)
+ */
+#define CIA_IOC_CIA_REV               (IDENT_ADDR + 0x8740000080UL)
+#define CIA_IOC_PCI_LAT               (IDENT_ADDR + 0x87400000C0UL)
+#define CIA_IOC_CIA_CTRL              (IDENT_ADDR + 0x8740000100UL)
+#define CIA_IOC_CIA_CNFG              (IDENT_ADDR + 0x8740000140UL)
+#define CIA_IOC_HAE_MEM               (IDENT_ADDR + 0x8740000400UL)
+#define CIA_IOC_HAE_IO                (IDENT_ADDR + 0x8740000440UL)
+#define CIA_IOC_CFG                   (IDENT_ADDR + 0x8740000480UL)
+#define CIA_IOC_CACK_EN               (IDENT_ADDR + 0x8740000600UL)
+
+/*
+ * 21171-CA Diagnostic Registers (p4-2)
+ */
+#define CIA_IOC_CIA_DIAG              (IDENT_ADDR + 0x8740002000UL)
+#define CIA_IOC_DIAG_CHECK            (IDENT_ADDR + 0x8740003000UL)
+
+/*
+ * 21171-CA Performance Monitor registers (p4-3)
+ */
+#define CIA_IOC_PERF_MONITOR          (IDENT_ADDR + 0x8740004000UL)
+#define CIA_IOC_PERF_CONTROL          (IDENT_ADDR + 0x8740004040UL)
+
+/*
+ * 21171-CA Error registers (p4-3)
+ */
+#define CIA_IOC_CPU_ERR0              (IDENT_ADDR + 0x8740008000UL)
+#define CIA_IOC_CPU_ERR1              (IDENT_ADDR + 0x8740008040UL)
+#define CIA_IOC_CIA_ERR               (IDENT_ADDR + 0x8740008200UL)
+#define CIA_IOC_CIA_STAT              (IDENT_ADDR + 0x8740008240UL)
+#define CIA_IOC_ERR_MASK              (IDENT_ADDR + 0x8740008280UL)
+#define CIA_IOC_CIA_SYN               (IDENT_ADDR + 0x8740008300UL)
+#define CIA_IOC_MEM_ERR0              (IDENT_ADDR + 0x8740008400UL)
+#define CIA_IOC_MEM_ERR1              (IDENT_ADDR + 0x8740008440UL)
+#define CIA_IOC_PCI_ERR0              (IDENT_ADDR + 0x8740008800UL)
+#define CIA_IOC_PCI_ERR1              (IDENT_ADDR + 0x8740008840UL)
+#define CIA_IOC_PCI_ERR3              (IDENT_ADDR + 0x8740008880UL)
+
+/*
+ * 2117A-CA PCI Address Translation Registers.
+ */
+#define CIA_IOC_PCI_TBIA              (IDENT_ADDR + 0x8760000100UL)
+
+#define CIA_IOC_PCI_W0_BASE           (IDENT_ADDR + 0x8760000400UL)
+#define CIA_IOC_PCI_W0_MASK           (IDENT_ADDR + 0x8760000440UL)
+#define CIA_IOC_PCI_T0_BASE           (IDENT_ADDR + 0x8760000480UL)
+
+#define CIA_IOC_PCI_W1_BASE           (IDENT_ADDR + 0x8760000500UL)
+#define CIA_IOC_PCI_W1_MASK           (IDENT_ADDR + 0x8760000540UL)
+#define CIA_IOC_PCI_T1_BASE           (IDENT_ADDR + 0x8760000580UL)
+
+#define CIA_IOC_PCI_W2_BASE           (IDENT_ADDR + 0x8760000600UL)
+#define CIA_IOC_PCI_W2_MASK           (IDENT_ADDR + 0x8760000640UL)
+#define CIA_IOC_PCI_T2_BASE           (IDENT_ADDR + 0x8760000680UL)
+
+#define CIA_IOC_PCI_W3_BASE           (IDENT_ADDR + 0x8760000700UL)
+#define CIA_IOC_PCI_W3_MASK           (IDENT_ADDR + 0x8760000740UL)
+#define CIA_IOC_PCI_T3_BASE           (IDENT_ADDR + 0x8760000780UL)
+
+/*
+ * 21171-CA System configuration registers (p4-3)
+ */
+#define CIA_IOC_MCR                   (IDENT_ADDR + 0x8750000000UL)
+#define CIA_IOC_MBA0                  (IDENT_ADDR + 0x8750000600UL)
+#define CIA_IOC_MBA2                  (IDENT_ADDR + 0x8750000680UL)
+#define CIA_IOC_MBA4                  (IDENT_ADDR + 0x8750000700UL)
+#define CIA_IOC_MBA6                  (IDENT_ADDR + 0x8750000780UL)
+#define CIA_IOC_MBA8                  (IDENT_ADDR + 0x8750000800UL)
+#define CIA_IOC_MBAA                  (IDENT_ADDR + 0x8750000880UL)
+#define CIA_IOC_MBAC                  (IDENT_ADDR + 0x8750000900UL)
+#define CIA_IOC_MBAE                  (IDENT_ADDR + 0x8750000980UL)
+#define CIA_IOC_TMG0                  (IDENT_ADDR + 0x8750000B00UL)
+#define CIA_IOC_TMG1                  (IDENT_ADDR + 0x8750000B40UL)
+#define CIA_IOC_TMG2                  (IDENT_ADDR + 0x8750000B80UL)
+
+/*
+ * Memory spaces:
+ */
+#define CIA_IACK_SC                    (IDENT_ADDR + 0x8720000000UL)
+#define CIA_CONF                       (IDENT_ADDR + 0x8700000000UL)
+#define CIA_IO                         (IDENT_ADDR + 0x8580000000UL)
+#define CIA_SPARSE_MEM                 (IDENT_ADDR + 0x8000000000UL)
+#define CIA_SPARSE_MEM_R2              (IDENT_ADDR + 0x8400000000UL)
+#define CIA_SPARSE_MEM_R3              (IDENT_ADDR + 0x8500000000UL)
+#define CIA_DENSE_MEM                  (IDENT_ADDR + 0x8600000000UL)
+
+/*
+ * ALCOR's GRU ASIC registers
+ */
+#define GRU_INT_REQ                    (IDENT_ADDR + 0x8780000000UL)
+#define GRU_INT_MASK                   (IDENT_ADDR + 0x8780000040UL)
+#define GRU_INT_EDGE                   (IDENT_ADDR + 0x8780000080UL)
+#define GRU_INT_HILO                   (IDENT_ADDR + 0x87800000C0UL)
+#define GRU_INT_CLEAR                  (IDENT_ADDR + 0x8780000100UL)
+
+#define GRU_CACHE_CNFG                 (IDENT_ADDR + 0x8780000200UL)
+#define GRU_SCR                                (IDENT_ADDR + 0x8780000300UL)
+#define GRU_LED                                (IDENT_ADDR + 0x8780000800UL)
+#define GRU_RESET                      (IDENT_ADDR + 0x8780000900UL)
+
+#define ALCOR_GRU_INT_REQ_BITS         0x800fffffUL
+#define XLT_GRU_INT_REQ_BITS           0x80003fffUL
+#define GRU_INT_REQ_BITS               (alpha_mv.sys.cia.gru_int_req_bits+0)
+
+
+/*
+ * Bit definitions for I/O Controller status register 0:
+ */
+#define CIA_IOC_STAT0_CMD              0xf
+#define CIA_IOC_STAT0_ERR              (1<<4)
+#define CIA_IOC_STAT0_LOST             (1<<5)
+#define CIA_IOC_STAT0_THIT             (1<<6)
+#define CIA_IOC_STAT0_TREF             (1<<7)
+#define CIA_IOC_STAT0_CODE_SHIFT       8
+#define CIA_IOC_STAT0_CODE_MASK                0x7
+#define CIA_IOC_STAT0_P_NBR_SHIFT      13
+#define CIA_IOC_STAT0_P_NBR_MASK       0x7ffff
+
+#define CIA_HAE_ADDRESS                        CIA_IOC_HAE_MEM
+
+/*
+ * Data structure for handling CIA machine checks.
+ */
+
+/* EV5-specific info.  */
+struct el_CIA_procdata {
+       unsigned long shadow[8];        /* PALmode shadow registers */
+       unsigned long paltemp[24];      /* PAL temporary registers */
+       /* EV5-specific fields */
+       unsigned long exc_addr;         /* Address of excepting instruction. */
+       unsigned long exc_sum;          /* Summary of arithmetic traps. */
+       unsigned long exc_mask;         /* Exception mask (from exc_sum). */
+       unsigned long exc_base;         /* PALbase at time of exception. */
+       unsigned long isr;              /* Interrupt summary register. */
+       unsigned long icsr;             /* Ibox control register. */
+       unsigned long ic_perr_stat;
+       unsigned long dc_perr_stat;
+       unsigned long va;               /* Effective VA of fault or miss. */
+       unsigned long mm_stat;
+       unsigned long sc_addr;
+       unsigned long sc_stat;
+       unsigned long bc_tag_addr;
+       unsigned long ei_addr;
+       unsigned long fill_syn;
+       unsigned long ei_stat;
+       unsigned long ld_lock;
+};
+
+/* System-specific info.  */
+struct el_CIA_sysdata_mcheck {
+       unsigned long      coma_gcr;                       
+       unsigned long      coma_edsr;                      
+       unsigned long      coma_ter;                       
+       unsigned long      coma_elar;                      
+       unsigned long      coma_ehar;                      
+       unsigned long      coma_ldlr;                      
+       unsigned long      coma_ldhr;                      
+       unsigned long      coma_base0;                     
+       unsigned long      coma_base1;                     
+       unsigned long      coma_base2;                     
+       unsigned long      coma_cnfg0;                     
+       unsigned long      coma_cnfg1;                     
+       unsigned long      coma_cnfg2;                     
+       unsigned long      epic_dcsr;                      
+       unsigned long      epic_pear;                      
+       unsigned long      epic_sear;                      
+       unsigned long      epic_tbr1;                      
+       unsigned long      epic_tbr2;                      
+       unsigned long      epic_pbr1;                      
+       unsigned long      epic_pbr2;                      
+       unsigned long      epic_pmr1;                      
+       unsigned long      epic_pmr2;                      
+       unsigned long      epic_harx1;                     
+       unsigned long      epic_harx2;                     
+       unsigned long      epic_pmlt;                      
+       unsigned long      epic_tag0;                      
+       unsigned long      epic_tag1;                      
+       unsigned long      epic_tag2;                      
+       unsigned long      epic_tag3;                      
+       unsigned long      epic_tag4;                      
+       unsigned long      epic_tag5;                      
+       unsigned long      epic_tag6;                      
+       unsigned long      epic_tag7;                      
+       unsigned long      epic_data0;                     
+       unsigned long      epic_data1;                     
+       unsigned long      epic_data2;                     
+       unsigned long      epic_data3;                     
+       unsigned long      epic_data4;                     
+       unsigned long      epic_data5;                     
+       unsigned long      epic_data6;                     
+       unsigned long      epic_data7;                     
+};
+
+
+#ifdef __KERNEL__
+
+#ifndef __EXTERN_INLINE
+#define __EXTERN_INLINE extern inline
+#define __IO_EXTERN_INLINE
+#endif
+
+/*
+ * Translate physical memory address as seen on (PCI) bus into
+ * a kernel virtual address and vv.
+ */
+
+__EXTERN_INLINE unsigned long cia_virt_to_bus(void * address)
+{
+       return virt_to_phys(address) + CIA_DMA_WIN_BASE;
+}
+
+__EXTERN_INLINE void * cia_bus_to_virt(unsigned long address)
+{
+       return phys_to_virt(address - CIA_DMA_WIN_BASE);
+}
+
+/*
+ * I/O functions:
+ *
+ * CIA (the 2117x PCI/memory support chipset for the EV5 (21164)
+ * series of processors uses a sparse address mapping scheme to
+ * get at PCI memory and I/O.
+ */
+
+#define vip    volatile int *
+#define vuip   volatile unsigned int *
+#define vulp   volatile unsigned long *
+
+__EXTERN_INLINE unsigned int cia_inb(unsigned long addr)
+{
+       long result;
+       result = *(vip) ((addr << 5) + CIA_IO + 0x00);
+       return __kernel_extbl(result, addr & 3);
+}
+
+__EXTERN_INLINE void cia_outb(unsigned char b, unsigned long addr)
+{
+       unsigned int w = __kernel_insbl(b, addr & 3);
+       *(vuip) ((addr << 5) + CIA_IO + 0x00) = w;
+       wmb();
+}
+
+__EXTERN_INLINE unsigned int cia_inw(unsigned long addr)
+{
+       long result;
+       result = *(vip) ((addr << 5) + CIA_IO + 0x08);
+       return __kernel_extwl(result, addr & 3);
+}
+
+__EXTERN_INLINE void cia_outw(unsigned short b, unsigned long addr)
+{
+       unsigned int w = __kernel_inswl(b, addr & 3);
+       *(vuip) ((addr << 5) + CIA_IO + 0x08) = w;
+       wmb();
+}
+
+__EXTERN_INLINE unsigned int cia_inl(unsigned long addr)
+{
+       return *(vuip) ((addr << 5) + CIA_IO + 0x18);
+}
+
+__EXTERN_INLINE void cia_outl(unsigned int b, unsigned long addr)
+{
+       *(vuip) ((addr << 5) + CIA_IO + 0x18) = b;
+       wmb();
+}
+
+
+/*
+ * Memory functions.  64-bit and 32-bit accesses are done through
+ * dense memory space, everything else through sparse space.
+ * 
+ * For reading and writing 8 and 16 bit quantities we need to 
+ * go through one of the three sparse address mapping regions
+ * and use the HAE_MEM CSR to provide some bits of the address.
+ * The following few routines use only sparse address region 1
+ * which gives 1Gbyte of accessible space which relates exactly
+ * to the amount of PCI memory mapping *into* system address space.
+ * See p 6-17 of the specification but it looks something like this:
+ *
+ * 21164 Address:
+ * 
+ *          3         2         1                                                               
+ * 9876543210987654321098765432109876543210
+ * 1ZZZZ0.PCI.QW.Address............BBLL                 
+ *
+ * ZZ = SBZ
+ * BB = Byte offset
+ * LL = Transfer length
+ *
+ * PCI Address:
+ *
+ * 3         2         1                                                               
+ * 10987654321098765432109876543210
+ * HHH....PCI.QW.Address........ 00
+ *
+ * HHH = 31:29 HAE_MEM CSR
+ * 
+ */
+
+__EXTERN_INLINE unsigned long cia_srm_base(unsigned long addr)
+{
+       unsigned long mask, base;
+
+       if (addr >= alpha_mv.sm_base_r1
+           && addr <= alpha_mv.sm_base_r1 + CIA_MEM_R1_MASK) {
+               mask = CIA_MEM_R1_MASK;
+               base = CIA_SPARSE_MEM;
+       }
+       else if (addr >= alpha_mv.sm_base_r2
+                && addr <= alpha_mv.sm_base_r2 + CIA_MEM_R2_MASK) {
+               mask = CIA_MEM_R2_MASK;
+               base = CIA_SPARSE_MEM_R2;
+       }
+       else if (addr >= alpha_mv.sm_base_r3
+                && addr <= alpha_mv.sm_base_r3 + CIA_MEM_R3_MASK) {
+               mask = CIA_MEM_R3_MASK;
+               base = CIA_SPARSE_MEM_R3;
+       }
+       else
+       {
+#if 0
+               printk("cia: address 0x%lx not covered by HAE\n", addr);
+#endif
+               return 0;
+       }
+
+       return ((addr & mask) << 5) + base;
+}
+
+__EXTERN_INLINE unsigned long cia_srm_readb(unsigned long addr)
+{
+       unsigned long result, work;
+
+       if ((work = cia_srm_base(addr)) == 0)
+               return 0xff;
+       work += 0x00;   /* add transfer length */
+
+       result = *(vip) work;
+       return __kernel_extbl(result, addr & 3);
+}
+
+__EXTERN_INLINE unsigned long cia_srm_readw(unsigned long addr)
+{
+       unsigned long result, work;
+
+       if ((work = cia_srm_base(addr)) == 0)
+               return 0xffff;
+       work += 0x08;   /* add transfer length */
+
+       result = *(vip) work;
+       return __kernel_extwl(result, addr & 3);
+}
+
+__EXTERN_INLINE void cia_srm_writeb(unsigned char b, unsigned long addr)
+{
+       unsigned long work = cia_srm_base(addr), w;
+       if (work) {
+               work += 0x00;   /* add transfer length */
+               w = __kernel_insbl(b, addr & 3);
+               *(vuip) work = w;
+       }
+}
+
+__EXTERN_INLINE void cia_srm_writew(unsigned short b, unsigned long addr)
+{
+       unsigned long work = cia_srm_base(addr), w;
+       if (work) {
+               work += 0x08;   /* add transfer length */
+               w = __kernel_inswl(b, addr & 3);
+               *(vuip) work = w;
+       }
+}
+
+__EXTERN_INLINE unsigned long cia_readb(unsigned long addr)
+{
+       unsigned long result, msb;
+
+       msb = addr & 0xE0000000;
+       addr &= CIA_MEM_R1_MASK;
+       set_hae(msb);
+
+       result = *(vip) ((addr << 5) + CIA_SPARSE_MEM + 0x00);
+       return __kernel_extbl(result, addr & 3);
+}
+
+__EXTERN_INLINE unsigned long cia_readw(unsigned long addr)
+{
+       unsigned long result, msb;
+
+       msb = addr & 0xE0000000;
+       addr &= CIA_MEM_R1_MASK;
+       set_hae(msb);
+
+       result = *(vip) ((addr << 5) + CIA_SPARSE_MEM + 0x08);
+       return __kernel_extwl(result, addr & 3);
+}
+
+__EXTERN_INLINE void cia_writeb(unsigned char b, unsigned long addr)
+{
+        unsigned long msb, w; 
+
+       msb = addr & 0xE0000000;
+       addr &= CIA_MEM_R1_MASK;
+       set_hae(msb);
+
+       w = __kernel_insbl(b, addr & 3);
+       *(vuip) ((addr << 5) + CIA_SPARSE_MEM + 0x00) = w;
+}
+
+__EXTERN_INLINE void cia_writew(unsigned short b, unsigned long addr)
+{
+        unsigned long msb, w; 
+
+       msb = addr & 0xE0000000;
+       addr &= CIA_MEM_R1_MASK;
+       set_hae(msb);
+
+       w = __kernel_inswl(b, addr & 3);
+       *(vuip) ((addr << 5) + CIA_SPARSE_MEM + 0x08) = w;
+}
+
+__EXTERN_INLINE unsigned long cia_readl(unsigned long addr)
+{
+       return *(vuip) (addr + CIA_DENSE_MEM);
+}
+
+__EXTERN_INLINE unsigned long cia_readq(unsigned long addr)
+{
+       return *(vulp) (addr + CIA_DENSE_MEM);
+}
+
+__EXTERN_INLINE void cia_writel(unsigned int b, unsigned long addr)
+{
+       *(vuip) (addr + CIA_DENSE_MEM) = b;
+}
+
+__EXTERN_INLINE void cia_writeq(unsigned long b, unsigned long addr)
+{
+       *(vulp) (addr + CIA_DENSE_MEM) = b;
+}
+
+/* Find the DENSE memory area for a given bus address.  */
+
+__EXTERN_INLINE unsigned long cia_dense_mem(unsigned long addr)
+{
+       return CIA_DENSE_MEM;
+}
+
+#undef vip
+#undef vuip
+#undef vulp
+
+#ifdef __WANT_IO_DEF
+
+#define virt_to_bus    cia_virt_to_bus
+#define bus_to_virt    cia_bus_to_virt
+#define __inb          cia_inb
+#define __inw          cia_inw
+#define __inl          cia_inl
+#define __outb         cia_outb
+#define __outw         cia_outw
+#define __outl         cia_outl
+
+#ifdef CONFIG_ALPHA_SRM_SETUP
+#define __readb                cia_srm_readb
+#define __readw                cia_srm_readw
+#define __writeb       cia_srm_writeb
+#define __writew       cia_srm_writew
+#else
+#define __readb                cia_readb
+#define __readw                cia_readw
+#define __writeb       cia_writeb
+#define __writew       cia_writew
+#endif
+
+#define __readl                cia_readl
+#define __readq                cia_readq
+#define __writel       cia_writel
+#define __writeq       cia_writeq
+#define dense_mem      cia_dense_mem
+
+#define inb(port) \
+(__builtin_constant_p((port))?__inb(port):_inb(port))
+#define outb(x, port) \
+(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port)))
+
+#define inw(port) \
+(__builtin_constant_p((port))?__inw(port):_inw(port))
+#define outw(x, port) \
+(__builtin_constant_p((port))?__outw((x),(port)):_outw((x),(port)))
+
+#define inl(port)      __inl(port)
+#define outl(x,port)   __outl((x),(port))
+
+#define readl(a)       __readl((unsigned long)(a))
+#define readq(a)       __readq((unsigned long)(a))
+#define writel(v,a)    __writel((v),(unsigned long)(a))
+#define writeq(v,a)    __writeq((v),(unsigned long)(a))
+
+#endif /* __WANT_IO_DEF */
+
+#ifdef __IO_EXTERN_INLINE
+#undef __EXTERN_INLINE
+#undef __IO_EXTERN_INLINE
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* __ALPHA_CIA__H__ */
diff --git a/include/asm-alpha/core_lca.h b/include/asm-alpha/core_lca.h
new file mode 100644 (file)
index 0000000..bce449f
--- /dev/null
@@ -0,0 +1,429 @@
+#ifndef __ALPHA_LCA__H__
+#define __ALPHA_LCA__H__
+
+#include <linux/config.h>
+#include <asm/system.h>
+#include <asm/compiler.h>
+
+/*
+ * Low Cost Alpha (LCA) definitions (these apply to 21066 and 21068,
+ * for example).
+ *
+ * This file is based on:
+ *
+ *     DECchip 21066 and DECchip 21068 Alpha AXP Microprocessors
+ *     Hardware Reference Manual; Digital Equipment Corp.; May 1994;
+ *     Maynard, MA; Order Number: EC-N2681-71.
+ */
+
+/*
+ * NOTE: The LCA uses a Host Address Extension (HAE) register to access
+ *      PCI addresses that are beyond the first 27 bits of address
+ *      space.  Updating the HAE requires an external cycle (and
+ *      a memory barrier), which tends to be slow.  Instead of updating
+ *      it on each sparse memory access, we keep the current HAE value
+ *      cached in variable cache_hae.  Only if the cached HAE differs
+ *      from the desired HAE value do we actually updated HAE register.
+ *      The HAE register is preserved by the interrupt handler entry/exit
+ *      code, so this scheme works even in the presence of interrupts.
+ *
+ * Dense memory space doesn't require the HAE, but is restricted to
+ * aligned 32 and 64 bit accesses.  Special Cycle and Interrupt
+ * Acknowledge cycles may also require the use of the HAE.  The LCA
+ * limits I/O address space to the bottom 24 bits of address space,
+ * but this easily covers the 16 bit ISA I/O address space.
+ */
+
+/*
+ * NOTE 2! The memory operations do not set any memory barriers, as
+ * it's not needed for cases like a frame buffer that is essentially
+ * memory-like.  You need to do them by hand if the operations depend
+ * on ordering.
+ *
+ * Similarly, the port I/O operations do a "mb" only after a write
+ * operation: if an mb is needed before (as in the case of doing
+ * memory mapped I/O first, and then a port I/O operation to the same
+ * device), it needs to be done by hand.
+ *
+ * After the above has bitten me 100 times, I'll give up and just do
+ * the mb all the time, but right now I'm hoping this will work out.
+ * Avoiding mb's may potentially be a noticeable speed improvement,
+ * but I can't honestly say I've tested it.
+ *
+ * Handling interrupts that need to do mb's to synchronize to
+ * non-interrupts is another fun race area.  Don't do it (because if
+ * you do, I'll have to do *everything* with interrupts disabled,
+ * ugh).
+ */
+
+#define LCA_DMA_WIN_BASE_DEFAULT       (1024*1024*1024)
+#define LCA_DMA_WIN_SIZE_DEFAULT       (1024*1024*1024)
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
+#define LCA_DMA_WIN_BASE               alpha_mv.dma_win_base
+#define LCA_DMA_WIN_SIZE               alpha_mv.dma_win_size
+#else
+#define LCA_DMA_WIN_BASE               LCA_DMA_WIN_BASE_DEFAULT
+#define LCA_DMA_WIN_SIZE               LCA_DMA_WIN_SIZE_DEFAULT
+#endif
+
+/*
+ * Memory Controller registers:
+ */
+#define LCA_MEM_BCR0           (IDENT_ADDR + 0x120000000UL)
+#define LCA_MEM_BCR1           (IDENT_ADDR + 0x120000008UL)
+#define LCA_MEM_BCR2           (IDENT_ADDR + 0x120000010UL)
+#define LCA_MEM_BCR3           (IDENT_ADDR + 0x120000018UL)
+#define LCA_MEM_BMR0           (IDENT_ADDR + 0x120000020UL)
+#define LCA_MEM_BMR1           (IDENT_ADDR + 0x120000028UL)
+#define LCA_MEM_BMR2           (IDENT_ADDR + 0x120000030UL)
+#define LCA_MEM_BMR3           (IDENT_ADDR + 0x120000038UL)
+#define LCA_MEM_BTR0           (IDENT_ADDR + 0x120000040UL)
+#define LCA_MEM_BTR1           (IDENT_ADDR + 0x120000048UL)
+#define LCA_MEM_BTR2           (IDENT_ADDR + 0x120000050UL)
+#define LCA_MEM_BTR3           (IDENT_ADDR + 0x120000058UL)
+#define LCA_MEM_GTR            (IDENT_ADDR + 0x120000060UL)
+#define LCA_MEM_ESR            (IDENT_ADDR + 0x120000068UL)
+#define LCA_MEM_EAR            (IDENT_ADDR + 0x120000070UL)
+#define LCA_MEM_CAR            (IDENT_ADDR + 0x120000078UL)
+#define LCA_MEM_VGR            (IDENT_ADDR + 0x120000080UL)
+#define LCA_MEM_PLM            (IDENT_ADDR + 0x120000088UL)
+#define LCA_MEM_FOR            (IDENT_ADDR + 0x120000090UL)
+
+/*
+ * I/O Controller registers:
+ */
+#define LCA_IOC_HAE            (IDENT_ADDR + 0x180000000UL)
+#define LCA_IOC_CONF           (IDENT_ADDR + 0x180000020UL)
+#define LCA_IOC_STAT0          (IDENT_ADDR + 0x180000040UL)
+#define LCA_IOC_STAT1          (IDENT_ADDR + 0x180000060UL)
+#define LCA_IOC_TBIA           (IDENT_ADDR + 0x180000080UL)
+#define LCA_IOC_TB_ENA         (IDENT_ADDR + 0x1800000a0UL)
+#define LCA_IOC_SFT_RST                (IDENT_ADDR + 0x1800000c0UL)
+#define LCA_IOC_PAR_DIS                (IDENT_ADDR + 0x1800000e0UL)
+#define LCA_IOC_W_BASE0                (IDENT_ADDR + 0x180000100UL)
+#define LCA_IOC_W_BASE1                (IDENT_ADDR + 0x180000120UL)
+#define LCA_IOC_W_MASK0                (IDENT_ADDR + 0x180000140UL)
+#define LCA_IOC_W_MASK1                (IDENT_ADDR + 0x180000160UL)
+#define LCA_IOC_T_BASE0                (IDENT_ADDR + 0x180000180UL)
+#define LCA_IOC_T_BASE1                (IDENT_ADDR + 0x1800001a0UL)
+#define LCA_IOC_TB_TAG0                (IDENT_ADDR + 0x188000000UL)
+#define LCA_IOC_TB_TAG1                (IDENT_ADDR + 0x188000020UL)
+#define LCA_IOC_TB_TAG2                (IDENT_ADDR + 0x188000040UL)
+#define LCA_IOC_TB_TAG3                (IDENT_ADDR + 0x188000060UL)
+#define LCA_IOC_TB_TAG4                (IDENT_ADDR + 0x188000070UL)
+#define LCA_IOC_TB_TAG5                (IDENT_ADDR + 0x1880000a0UL)
+#define LCA_IOC_TB_TAG6                (IDENT_ADDR + 0x1880000c0UL)
+#define LCA_IOC_TB_TAG7                (IDENT_ADDR + 0x1880000e0UL)
+
+/*
+ * Memory spaces:
+ */
+#define LCA_IACK_SC            (IDENT_ADDR + 0x1a0000000UL)
+#define LCA_CONF               (IDENT_ADDR + 0x1e0000000UL)
+#define LCA_IO                 (IDENT_ADDR + 0x1c0000000UL)
+#define LCA_SPARSE_MEM         (IDENT_ADDR + 0x200000000UL)
+#define LCA_DENSE_MEM          (IDENT_ADDR + 0x300000000UL)
+
+/*
+ * Bit definitions for I/O Controller status register 0:
+ */
+#define LCA_IOC_STAT0_CMD              0xf
+#define LCA_IOC_STAT0_ERR              (1<<4)
+#define LCA_IOC_STAT0_LOST             (1<<5)
+#define LCA_IOC_STAT0_THIT             (1<<6)
+#define LCA_IOC_STAT0_TREF             (1<<7)
+#define LCA_IOC_STAT0_CODE_SHIFT       8
+#define LCA_IOC_STAT0_CODE_MASK                0x7
+#define LCA_IOC_STAT0_P_NBR_SHIFT      13
+#define LCA_IOC_STAT0_P_NBR_MASK       0x7ffff
+
+#define LCA_HAE_ADDRESS                LCA_IOC_HAE
+
+/* LCA PMR Power Management register defines */
+#define LCA_PMR_ADDR   (IDENT_ADDR + 0x120000098UL)
+#define LCA_PMR_PDIV    0x7                     /* Primary clock divisor */
+#define LCA_PMR_ODIV    0x38                    /* Override clock divisor */
+#define LCA_PMR_INTO    0x40                    /* Interrupt override */
+#define LCA_PMR_DMAO    0x80                    /* DMA override */
+#define LCA_PMR_OCCEB   0xffff0000L             /* Override cycle counter - even bits */
+#define LCA_PMR_OCCOB   0xffff000000000000L     /* Override cycle counter - even bits */
+#define LCA_PMR_PRIMARY_MASK    0xfffffffffffffff8
+
+/* LCA PMR Macros */
+
+#define LCA_READ_PMR        (*(volatile unsigned long *)LCA_PMR_ADDR)
+#define LCA_WRITE_PMR(d)    (*((volatile unsigned long *)LCA_PMR_ADDR) = (d))
+
+#define LCA_GET_PRIMARY(r)  ((r) & LCA_PMR_PDIV)
+#define LCA_GET_OVERRIDE(r) (((r) >> 3) & LCA_PMR_PDIV)
+#define LCA_SET_PRIMARY_CLOCK(r, c) ((r) = (((r) & LCA_PMR_PRIMARY_MASK)|(c)))
+
+/* LCA PMR Divisor values */
+#define LCA_PMR_DIV_1   0x0
+#define LCA_PMR_DIV_1_5 0x1
+#define LCA_PMR_DIV_2   0x2
+#define LCA_PMR_DIV_4   0x3
+#define LCA_PMR_DIV_8   0x4
+#define LCA_PMR_DIV_16  0x5
+#define LCA_PMR_DIV_MIN DIV_1
+#define LCA_PMR_DIV_MAX DIV_16
+
+
+/*
+ * Data structure for handling LCA machine checks.  Correctable errors
+ * result in a short logout frame, uncorrectable ones in a long one.
+ */
+struct el_lca_mcheck_short {
+       struct el_common        h;              /* common logout header */
+       unsigned long           esr;            /* error-status register */
+       unsigned long           ear;            /* error-address register */
+       unsigned long           dc_stat;        /* dcache status register */
+       unsigned long           ioc_stat0;      /* I/O controller status register 0 */
+       unsigned long           ioc_stat1;      /* I/O controller status register 1 */
+};
+
+struct el_lca_mcheck_long {
+       struct el_common        h;              /* common logout header */
+       unsigned long           pt[31];         /* PAL temps */
+       unsigned long           exc_addr;       /* exception address */
+       unsigned long           pad1[3];
+       unsigned long           pal_base;       /* PALcode base address */
+       unsigned long           hier;           /* hw interrupt enable */
+       unsigned long           hirr;           /* hw interrupt request */
+       unsigned long           mm_csr;         /* MMU control & status */
+       unsigned long           dc_stat;        /* data cache status */
+       unsigned long           dc_addr;        /* data cache addr register */
+       unsigned long           abox_ctl;       /* address box control register */
+       unsigned long           esr;            /* error status register */
+       unsigned long           ear;            /* error address register */
+       unsigned long           car;            /* cache control register */
+       unsigned long           ioc_stat0;      /* I/O controller status register 0 */
+       unsigned long           ioc_stat1;      /* I/O controller status register 1 */
+       unsigned long           va;             /* virtual address register */
+};
+
+union el_lca {
+       struct el_common *              c;
+       struct el_lca_mcheck_long *     l;
+       struct el_lca_mcheck_short *    s;
+};
+
+#ifdef __KERNEL__
+
+#ifndef __EXTERN_INLINE
+#define __EXTERN_INLINE extern inline
+#define __IO_EXTERN_INLINE
+#endif
+
+/*
+ * Translate physical memory address as seen on (PCI) bus into
+ * a kernel virtual address and vv.
+ */
+
+__EXTERN_INLINE unsigned long lca_virt_to_bus(void * address)
+{
+       return virt_to_phys(address) + LCA_DMA_WIN_BASE;
+}
+
+__EXTERN_INLINE void * lca_bus_to_virt(unsigned long address)
+{
+       /*
+        * This check is a sanity check but also ensures that bus
+        * address 0 maps to virtual address 0 which is useful to
+        * detect null "pointers" (the NCR driver is much simpler if
+        * NULL pointers are preserved).
+        */
+       if (address < LCA_DMA_WIN_BASE)
+               return 0;
+       return phys_to_virt(address - LCA_DMA_WIN_BASE);
+}
+
+/*
+ * I/O functions:
+ *
+ * Unlike Jensen, the Noname machines have no concept of local
+ * I/O---everything goes over the PCI bus.
+ *
+ * There is plenty room for optimization here.  In particular,
+ * the Alpha's insb/insw/extb/extw should be useful in moving
+ * data to/from the right byte-lanes.
+ */
+
+#define vip    volatile int *
+#define vuip   volatile unsigned int *
+#define vulp   volatile unsigned long *
+
+__EXTERN_INLINE unsigned int lca_inb(unsigned long addr)
+{
+       long result = *(vip) ((addr << 5) + LCA_IO + 0x00);
+       return __kernel_extbl(result, addr & 3);
+}
+
+__EXTERN_INLINE void lca_outb(unsigned char b, unsigned long addr)
+{
+       unsigned int w;
+
+       w = __kernel_insbl(b, addr & 3);
+       *(vuip) ((addr << 5) + LCA_IO + 0x00) = w;
+       mb();
+}
+
+__EXTERN_INLINE unsigned int lca_inw(unsigned long addr)
+{
+       long result = *(vip) ((addr << 5) + LCA_IO + 0x08);
+       return __kernel_extwl(result, addr & 3);
+}
+
+__EXTERN_INLINE void lca_outw(unsigned short b, unsigned long addr)
+{
+       unsigned int w;
+
+       w = __kernel_inswl(b, addr & 3);
+       *(vuip) ((addr << 5) + LCA_IO + 0x08) = w;
+       mb();
+}
+
+__EXTERN_INLINE unsigned int lca_inl(unsigned long addr)
+{
+       return *(vuip) ((addr << 5) + LCA_IO + 0x18);
+}
+
+__EXTERN_INLINE void lca_outl(unsigned int b, unsigned long addr)
+{
+       *(vuip) ((addr << 5) + LCA_IO + 0x18) = b;
+       mb();
+}
+
+
+/*
+ * Memory functions.  64-bit and 32-bit accesses are done through
+ * dense memory space, everything else through sparse space.
+ */
+
+__EXTERN_INLINE unsigned long lca_readb(unsigned long addr)
+{
+       unsigned long result, msb;
+
+       if (addr >= (1UL << 24)) {
+               msb = addr & 0xf8000000;
+               addr -= msb;
+               set_hae(msb);
+       }
+       result = *(vip) ((addr << 5) + LCA_SPARSE_MEM + 0x00);
+       return __kernel_extbl(result, addr & 3);
+}
+
+__EXTERN_INLINE unsigned long lca_readw(unsigned long addr)
+{
+       unsigned long result, msb;
+
+       if (addr >= (1UL << 24)) {
+               msb = addr & 0xf8000000;
+               addr -= msb;
+               set_hae(msb);
+       }
+       result = *(vip) ((addr << 5) + LCA_SPARSE_MEM + 0x08);
+       return __kernel_extwl(result, addr & 3);
+}
+
+__EXTERN_INLINE unsigned long lca_readl(unsigned long addr)
+{
+       return *(vuip) (addr + LCA_DENSE_MEM);
+}
+
+__EXTERN_INLINE unsigned long lca_readq(unsigned long addr)
+{
+       return *(vulp) (addr + LCA_DENSE_MEM);
+}
+
+__EXTERN_INLINE void lca_writeb(unsigned char b, unsigned long addr)
+{
+       unsigned long msb;
+       unsigned int w;
+
+       if (addr >= (1UL << 24)) {
+               msb = addr & 0xf8000000;
+               addr -= msb;
+               set_hae(msb);
+       }
+       w = __kernel_insbl(b, addr & 3);
+       *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x00) = w;
+}
+
+__EXTERN_INLINE void lca_writew(unsigned short b, unsigned long addr)
+{
+       unsigned long msb;
+       unsigned int w;
+
+       if (addr >= (1UL << 24)) {
+               msb = addr & 0xf8000000;
+               addr -= msb;
+               set_hae(msb);
+       }
+       w = __kernel_inswl(b, addr & 3);
+       *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x08) = w;
+}
+
+__EXTERN_INLINE void lca_writel(unsigned int b, unsigned long addr)
+{
+       *(vuip) (addr + LCA_DENSE_MEM) = b;
+}
+
+__EXTERN_INLINE void lca_writeq(unsigned long b, unsigned long addr)
+{
+       *(vulp) (addr + LCA_DENSE_MEM) = b;
+}
+
+/* Find the DENSE memory area for a given bus address.  */
+
+__EXTERN_INLINE unsigned long lca_dense_mem(unsigned long addr)
+{
+       return LCA_DENSE_MEM;
+}
+
+#undef vip
+#undef vuip
+#undef vulp
+
+#ifdef __WANT_IO_DEF
+
+#define virt_to_bus    lca_virt_to_bus
+#define bus_to_virt    lca_bus_to_virt
+#define __inb          lca_inb
+#define __inw          lca_inw
+#define __inl          lca_inl
+#define __outb         lca_outb
+#define __outw         lca_outw
+#define __outl         lca_outl
+#define __readb                lca_readb
+#define __readw                lca_readw
+#define __writeb       lca_writeb
+#define __writew       lca_writew
+#define __readl                lca_readl
+#define __readq                lca_readq
+#define __writel       lca_writel
+#define __writeq       lca_writeq
+#define dense_mem      lca_dense_mem
+
+#define inb(port) \
+(__builtin_constant_p((port))?__inb(port):_inb(port))
+
+#define outb(x, port) \
+(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port)))
+
+#define readl(a)       __readl((unsigned long)(a))
+#define readq(a)       __readq((unsigned long)(a))
+#define writel(v,a)    __writel((v),(unsigned long)(a))
+#define writeq(v,a)    __writeq((v),(unsigned long)(a))
+
+#endif /* __WANT_IO_DEF */
+
+#ifdef __IO_EXTERN_INLINE
+#undef __EXTERN_INLINE
+#undef __IO_EXTERN_INLINE
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* __ALPHA_LCA__H__ */
diff --git a/include/asm-alpha/core_mcpcia.h b/include/asm-alpha/core_mcpcia.h
new file mode 100644 (file)
index 0000000..8b0e03a
--- /dev/null
@@ -0,0 +1,632 @@
+#ifndef __ALPHA_MCPCIA__H__
+#define __ALPHA_MCPCIA__H__
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <asm/compiler.h>
+
+/*
+ * MCPCIA is the internal name for a core logic chipset which provides
+ * PCI access for the RAWHIDE family of systems.
+ *
+ * This file is based on:
+ *
+ * RAWHIDE System Programmer's Manual
+ * 16-May-96
+ * Rev. 1.4
+ *
+ */
+
+/*------------------------------------------------------------------------**
+**                                                                        **
+**  I/O procedures                                                        **
+**                                                                        **
+**      inport[b|w|t|l], outport[b|w|t|l] 8:16:24:32 IO xfers             **
+**     inportbxt: 8 bits only                                            **
+**      inport:    alias of inportw                                       **
+**      outport:   alias of outportw                                      **
+**                                                                        **
+**      inmem[b|w|t|l], outmem[b|w|t|l] 8:16:24:32 ISA memory xfers       **
+**     inmembxt: 8 bits only                                             **
+**      inmem:    alias of inmemw                                         **
+**      outmem:   alias of outmemw                                        **
+**                                                                        **
+**------------------------------------------------------------------------*/
+
+
+/* MCPCIA ADDRESS BIT DEFINITIONS
+ *
+ *  3 3 3 3|3 3 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |1| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |0|0|0|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
+ *  |                                                                        \_/ \_/
+ *  |                                                                         |   |
+ *  +-- IO space, not cached.                                   Byte Enable --+   |
+ *                                                              Transfer Length --+
+ *
+ *
+ *
+ *   Byte      Transfer
+ *   Enable    Length    Transfer  Byte    Address
+ *   adr<6:5>  adr<4:3>  Length    Enable  Adder
+ *   ---------------------------------------------
+ *      00        00      Byte      1110   0x000
+ *      01        00      Byte      1101   0x020
+ *      10        00      Byte      1011   0x040
+ *      11        00      Byte      0111   0x060
+ *
+ *      00        01      Word      1100   0x008
+ *      01        01      Word      1001   0x028 <= Not supported in this code.
+ *      10        01      Word      0011   0x048
+ *
+ *      00        10      Tribyte   1000   0x010
+ *      01        10      Tribyte   0001   0x030
+ *
+ *      10        11      Longword  0000   0x058
+ *
+ *      Note that byte enables are asserted low.
+ *
+ */
+
+#define MCPCIA_MEM_R1_MASK 0x1fffffff /* SPARSE Mem region 1 mask is 29 bits */
+#define MCPCIA_MEM_R2_MASK 0x07ffffff /* SPARSE Mem region 2 mask is 27 bits */
+#define MCPCIA_MEM_R3_MASK 0x03ffffff /* SPARSE Mem region 3 mask is 26 bits */
+
+#define MCPCIA_DMA_WIN_BASE_DEFAULT    (2*1024*1024*1024U)
+#define MCPCIA_DMA_WIN_SIZE_DEFAULT    (2*1024*1024*1024U)
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
+#define MCPCIA_DMA_WIN_BASE            alpha_mv.dma_win_base
+#define MCPCIA_DMA_WIN_SIZE            alpha_mv.dma_win_size
+#else
+#define MCPCIA_DMA_WIN_BASE            MCPCIA_DMA_WIN_BASE_DEFAULT
+#define MCPCIA_DMA_WIN_SIZE            MCPCIA_DMA_WIN_SIZE_DEFAULT
+#endif
+
+#define HOSE(h) (((unsigned long)(h)) << 33)
+
+/*
+ *  General Registers
+ */
+#define MCPCIA_REV(h)          (IDENT_ADDR + 0xf9e0000000UL + HOSE(h))
+#define MCPCIA_WHOAMI(h)       (IDENT_ADDR + 0xf9e0000040UL + HOSE(h))
+#define MCPCIA_PCI_LAT(h)      (IDENT_ADDR + 0xf9e0000080UL + HOSE(h))
+#define MCPCIA_CAP_CTRL(h)     (IDENT_ADDR + 0xf9e0000100UL + HOSE(h))
+#define MCPCIA_HAE_MEM(h)      (IDENT_ADDR + 0xf9e0000400UL + HOSE(h))
+#define MCPCIA_HAE_IO(h)       (IDENT_ADDR + 0xf9e0000440UL + HOSE(h))
+#if 0
+#define MCPCIA_IACK_SC(h)      (IDENT_ADDR + 0xf9e0000480UL + HOSE(h))
+#endif
+#define MCPCIA_HAE_DENSE(h)    (IDENT_ADDR + 0xf9e00004c0UL + HOSE(h))
+
+/*
+ * Interrupt Control registers
+ */
+#define MCPCIA_INT_CTL(h)      (IDENT_ADDR + 0xf9e0000500UL + HOSE(h))
+#define MCPCIA_INT_REQ(h)      (IDENT_ADDR + 0xf9e0000540UL + HOSE(h))
+#define MCPCIA_INT_TARG(h)     (IDENT_ADDR + 0xf9e0000580UL + HOSE(h))
+#define MCPCIA_INT_ADR(h)      (IDENT_ADDR + 0xf9e00005c0UL + HOSE(h))
+#define MCPCIA_INT_ADR_EXT(h)  (IDENT_ADDR + 0xf9e0000600UL + HOSE(h))
+#define MCPCIA_INT_MASK0(h)    (IDENT_ADDR + 0xf9e0000640UL + HOSE(h))
+#define MCPCIA_INT_MASK1(h)    (IDENT_ADDR + 0xf9e0000680UL + HOSE(h))
+#define MCPCIA_INT_ACK0(h)     (IDENT_ADDR + 0xf9f0003f00UL + HOSE(h))
+#define MCPCIA_INT_ACK1(h)     (IDENT_ADDR + 0xf9e0003f40UL + HOSE(h))
+
+/*
+ * Performance Monitor registers
+ */
+#define MCPCIA_PERF_MONITOR(h) (IDENT_ADDR + 0xf9e0000300UL + HOSE(h))
+#define MCPCIA_PERF_CONTROL(h) (IDENT_ADDR + 0xf9e0000340UL + HOSE(h))
+
+/*
+ * Diagnostic Registers
+ */
+#define MCPCIA_CAP_DIAG(h)     (IDENT_ADDR + 0xf9e0000700UL + HOSE(h))
+#define MCPCIA_TOP_OF_MEM(h)   (IDENT_ADDR + 0xf9e00007c0UL + HOSE(h))
+
+/*
+ * Error registers
+ */
+#define MCPCIA_CAP_ERR(h)      (IDENT_ADDR + 0xf9e0000880UL + HOSE(h))
+#define MCPCIA_PCI_ERR1(h)     (IDENT_ADDR + 0xf9e0001040UL + HOSE(h))
+
+/*
+ * PCI Address Translation Registers.
+ */
+#define MCPCIA_SG_TBIA(h)      (IDENT_ADDR + 0xf9e0001300UL + HOSE(h))
+#define MCPCIA_HBASE(h)                (IDENT_ADDR + 0xf9e0001340UL + HOSE(h))
+
+#define MCPCIA_W0_BASE(h)      (IDENT_ADDR + 0xf9e0001400UL + HOSE(h))
+#define MCPCIA_W0_MASK(h)      (IDENT_ADDR + 0xf9e0001440UL + HOSE(h))
+#define MCPCIA_T0_BASE(h)      (IDENT_ADDR + 0xf9e0001480UL + HOSE(h))
+
+#define MCPCIA_W1_BASE(h)      (IDENT_ADDR + 0xf9e0001500UL + HOSE(h))
+#define MCPCIA_W1_MASK(h)      (IDENT_ADDR + 0xf9e0001540UL + HOSE(h))
+#define MCPCIA_T1_BASE(h)      (IDENT_ADDR + 0xf9e0001580UL + HOSE(h))
+
+#define MCPCIA_W2_BASE(h)      (IDENT_ADDR + 0xf9e0001600UL + HOSE(h))
+#define MCPCIA_W2_MASK(h)      (IDENT_ADDR + 0xf9e0001640UL + HOSE(h))
+#define MCPCIA_T2_BASE(h)      (IDENT_ADDR + 0xf9e0001680UL + HOSE(h))
+
+#define MCPCIA_W3_BASE(h)      (IDENT_ADDR + 0xf9e0001700UL + HOSE(h))
+#define MCPCIA_W3_MASK(h)      (IDENT_ADDR + 0xf9e0001740UL + HOSE(h))
+#define MCPCIA_T3_BASE(h)      (IDENT_ADDR + 0xf9e0001780UL + HOSE(h))
+
+/*
+ * Memory spaces:
+ */
+#define MCPCIA_CONF(h)         (IDENT_ADDR + 0xf9c0000000UL + HOSE(h))
+#define MCPCIA_IO(h)           (IDENT_ADDR + 0xf980000000UL + HOSE(h))
+#define MCPCIA_SPARSE(h)       (IDENT_ADDR + 0xf800000000UL + HOSE(h))
+#define MCPCIA_DENSE(h)                (IDENT_ADDR + 0xf900000000UL + HOSE(h))
+#define _MCPCIA_IACK_SC(h)     (IDENT_ADDR + 0xf9f0003f00UL + HOSE(h))
+
+#define MCPCIA_HAE_ADDRESS     MCPCIA_HAE_MEM(0)
+#define MCPCIA_IACK_SC         _MCPCIA_IACK_SC(0)
+
+/*
+ * Data structure for handling MCPCIA machine checks:
+ */
+struct el_MCPCIA_uncorrected_frame_mcheck {
+        struct el_common header;
+        struct el_common_EV5_uncorrectable_mcheck procdata;
+};
+
+
+#ifdef __KERNEL__
+
+#ifndef __EXTERN_INLINE
+#define __EXTERN_INLINE extern inline
+#define __IO_EXTERN_INLINE
+#endif
+
+/*
+ * Translate physical memory address as seen on (PCI) bus into
+ * a kernel virtual address and vv.
+ */
+
+__EXTERN_INLINE unsigned long mcpcia_virt_to_bus(void * address)
+{
+       return virt_to_phys(address) + MCPCIA_DMA_WIN_BASE;
+}
+
+__EXTERN_INLINE void * mcpcia_bus_to_virt(unsigned long address)
+{
+       return phys_to_virt(address - MCPCIA_DMA_WIN_BASE);
+}
+
+/*
+ * I/O functions:
+ *
+ * MCPCIA, the RAWHIDE family PCI/memory support chipset for the EV5 (21164)
+ * and EV56 (21164a) processors, can use either a sparse address mapping
+ * scheme, or the so-called byte-word PCI address space, to get at PCI memory
+ * and I/O.
+ *
+ * Unfortunately, we can't use BWIO with EV5, so for now, we always use SPARSE.
+ */
+
+#define vucp   volatile unsigned char *
+#define vusp   volatile unsigned short *
+#define vip    volatile int *
+#define vuip   volatile unsigned int *
+#define vulp   volatile unsigned long *
+
+#if 0 /* BWIO */
+__EXTERN_INLINE unsigned int mcpcia_bw_inb(unsigned long addr)
+{
+       return __kernel_ldbu(*(vucp)(addr+MCPCIA_BW_IO));
+}
+
+__EXTERN_INLINE void mcpcia_bw_outb(unsigned char b, unsigned long addr)
+{
+       __kernel_stb(b, *(vucp)(addr+MCPCIA_BW_IO));
+       mb();
+}
+
+__EXTERN_INLINE unsigned int mcpcia_bw_inw(unsigned long addr)
+{
+       return __kernel_ldwu(*(vusp)(addr+MCPCIA_BW_IO));
+}
+
+__EXTERN_INLINE void mcpcia_bw_outw(unsigned short b, unsigned long addr)
+{
+       __kernel_stw(b, *(vusp)(addr+MCPCIA_BW_IO));
+       mb();
+}
+
+__EXTERN_INLINE unsigned int mcpcia_bw_inl(unsigned long addr)
+{
+       return *(vuip)(addr+MCPCIA_BW_IO);
+}
+
+__EXTERN_INLINE void mcpcia_bw_outl(unsigned int b, unsigned long addr)
+{
+       *(vuip)(addr+MCPCIA_BW_IO) = b;
+       mb();
+}
+#endif
+
+__EXTERN_INLINE unsigned int mcpcia_inb(unsigned long in_addr)
+{
+       unsigned long addr = in_addr & 0xffffffffUL;
+       unsigned long hose = (in_addr >> 32) & 3;
+       long result = *(vip) ((addr << 5) + MCPCIA_IO(hose) + 0x00);
+       return __kernel_extbl(result, addr & 3);
+}
+
+__EXTERN_INLINE void mcpcia_outb(unsigned char b, unsigned long in_addr)
+{
+       unsigned long addr = in_addr & 0xffffffffUL;
+       unsigned long hose = (in_addr >> 32) & 3;
+       unsigned int w;
+
+       w = __kernel_insbl(b, addr & 3);
+       *(vuip) ((addr << 5) + MCPCIA_IO(hose) + 0x00) = w;
+       mb();
+}
+
+__EXTERN_INLINE unsigned int mcpcia_inw(unsigned long in_addr)
+{
+       unsigned long addr = in_addr & 0xffffffffUL;
+       unsigned long hose = (in_addr >> 32) & 3;
+       long result = *(vip) ((addr << 5) + MCPCIA_IO(hose) + 0x08);
+       return __kernel_extwl(result, addr & 3);
+}
+
+__EXTERN_INLINE void mcpcia_outw(unsigned short b, unsigned long in_addr)
+{
+       unsigned long addr = in_addr & 0xffffffffUL;
+       unsigned long hose = (in_addr >> 32) & 3;
+       unsigned int w;
+
+       w = __kernel_inswl(b, addr & 3);
+       *(vuip) ((addr << 5) + MCPCIA_IO(hose) + 0x08) = w;
+       mb();
+}
+
+__EXTERN_INLINE unsigned int mcpcia_inl(unsigned long in_addr)
+{
+       unsigned long addr = in_addr & 0xffffffffUL;
+       unsigned long hose = (in_addr >> 32) & 3;
+       return *(vuip) ((addr << 5) + MCPCIA_IO(hose) + 0x18);
+}
+
+__EXTERN_INLINE void mcpcia_outl(unsigned int b, unsigned long in_addr)
+{
+       unsigned long addr = in_addr & 0xffffffffUL;
+       unsigned long hose = (in_addr >> 32) & 3;
+       *(vuip) ((addr << 5) + MCPCIA_IO(hose) + 0x18) = b;
+       mb();
+}
+
+
+/*
+ * Memory functions.  64-bit and 32-bit accesses are done through
+ * dense memory space, everything else through sparse space.
+ * 
+ * For reading and writing 8 and 16 bit quantities we need to 
+ * go through one of the three sparse address mapping regions
+ * and use the HAE_MEM CSR to provide some bits of the address.
+ * The following few routines use only sparse address region 1
+ * which gives 1Gbyte of accessible space which relates exactly
+ * to the amount of PCI memory mapping *into* system address space.
+ * See p 6-17 of the specification but it looks something like this:
+ *
+ * 21164 Address:
+ * 
+ *          3         2         1
+ * 9876543210987654321098765432109876543210
+ * 1ZZZZ0.PCI.QW.Address............BBLL                 
+ *
+ * ZZ = SBZ
+ * BB = Byte offset
+ * LL = Transfer length
+ *
+ * PCI Address:
+ *
+ * 3         2         1
+ * 10987654321098765432109876543210
+ * HHH....PCI.QW.Address........ 00
+ *
+ * HHH = 31:29 HAE_MEM CSR
+ * 
+ */
+
+#if 0 /* BWIO */
+__EXTERN_INLINE unsigned long mcpcia_bw_readb(unsigned long addr)
+{
+       return __kernel_ldbu(*(vucp)(addr+MCPCIA_BW_MEM));
+}
+
+__EXTERN_INLINE unsigned long mcpcia_bw_readw(unsigned long addr)
+{
+       return __kernel_ldbw(*(vusp)(addr+MCPCIA_BW_MEM));
+}
+
+__EXTERN_INLINE unsigned long mcpcia_bw_readl(unsigned long addr)
+{
+       return *(vuip)(addr + MCPCIA_BW_MEM);
+}
+
+__EXTERN_INLINE unsigned long mcpcia_bw_readq(unsigned long addr)
+{
+       return *(vulp)(addr + MCPCIA_BW_MEM);
+}
+
+__EXTERN_INLINE void mcpcia_bw_writeb(unsigned char b, unsigned long addr)
+{
+       __kernel_stb(b, *(vucp)(addr+MCPCIA_BW_MEM));
+}
+
+__EXTERN_INLINE void mcpcia_bw_writew(unsigned short b, unsigned long addr)
+{
+       __kernel_stw(b, *(vusp)(addr+MCPCIA_BW_MEM));
+}
+
+__EXTERN_INLINE void mcpcia_bw_writel(unsigned int b, unsigned long addr)
+{
+       *(vuip)(addr+MCPCIA_BW_MEM) = b;
+}
+
+__EXTERN_INLINE void mcpcia_bw_writeq(unsigned long b, unsigned long addr)
+{
+       *(vulp)(addr+MCPCIA_BW_MEM) = b;
+}
+#endif
+
+__EXTERN_INLINE unsigned long mcpcia_srm_base(unsigned long addr)
+{
+       unsigned long mask, base;
+       unsigned long hose = (addr >> 32) & 3;
+
+       if (addr >= alpha_mv.sm_base_r1
+           && addr <= alpha_mv.sm_base_r1 + MCPCIA_MEM_R1_MASK) {
+               mask = MCPCIA_MEM_R1_MASK;
+               base = MCPCIA_SPARSE(hose);
+       }
+#if 0
+       /* FIXME FIXME FIXME: SPARSE_MEM_R2 and R3 are not defined?  */
+       else if (addr >= alpha_mv.sm_base_r2
+                && addr <= alpha_mv.sm_base_r2 + MCPCIA_MEM_R2_MASK) {
+               mask = MCPCIA_MEM_R2_MASK;
+               base = MCPCIA_SPARSE_MEM_R2;
+       }
+       else if (addr >= alpha_mv.sm_base_r3
+                && addr <= alpha_mv.sm_base_r3 + MCPCIA_MEM_R3_MASK) {
+               mask = MCPCIA_MEM_R3_MASK;
+               base = MCPCIA_SPARSE_MEM_R3;
+       }
+#endif
+       else
+       {
+#if 0
+         printk("mcpcia: address 0x%lx not covered by HAE\n", addr);
+#endif
+         return 0;
+       }
+
+       return ((addr & mask) << 5) + base;
+}
+
+__EXTERN_INLINE unsigned long mcpcia_srm_readb(unsigned long addr)
+{
+       unsigned long result, work;
+
+       if ((work = mcpcia_srm_base(addr)) == 0)
+               return 0xff;
+       work += 0x00;   /* add transfer length */
+
+       result = *(vip) work;
+       return __kernel_extbl(result, addr & 3);
+}
+
+__EXTERN_INLINE unsigned long mcpcia_srm_readw(unsigned long addr)
+{
+       unsigned long result, work;
+
+       if ((work = mcpcia_srm_base(addr)) == 0)
+               return 0xffff;
+       work += 0x08;   /* add transfer length */
+
+       result = *(vip) work;
+       return __kernel_extwl(result, addr & 3);
+}
+
+__EXTERN_INLINE void mcpcia_srm_writeb(unsigned char b, unsigned long addr)
+{
+       unsigned long work = mcpcia_srm_base(addr);
+       if (work) {
+               work += 0x00;   /* add transfer length */
+               *(vuip) work = b * 0x01010101;
+       }
+}
+
+__EXTERN_INLINE void mcpcia_srm_writew(unsigned short b, unsigned long addr)
+{
+       unsigned long work = mcpcia_srm_base(addr);
+       if (work) {
+               work += 0x08;   /* add transfer length */
+               *(vuip) work = b * 0x00010001;
+       }
+}
+
+__EXTERN_INLINE unsigned long mcpcia_readb(unsigned long in_addr)
+{
+       unsigned long addr = in_addr & 0xffffffffUL;
+       unsigned long hose = (in_addr >> 32) & 3;
+       unsigned long result, msb, work, temp;
+
+       msb = addr & 0xE0000000UL;
+       temp = addr & MCPCIA_MEM_R1_MASK;
+       set_hae(msb);
+
+       work = ((temp << 5) + MCPCIA_SPARSE(hose) + 0x00);
+       result = *(vip) work;
+       return __kernel_extbl(result, addr & 3);
+}
+
+__EXTERN_INLINE unsigned long mcpcia_readw(unsigned long in_addr)
+{
+       unsigned long addr = in_addr & 0xffffffffUL;
+       unsigned long hose = (in_addr >> 32) & 3;
+       unsigned long result, msb, work, temp;
+
+       msb = addr & 0xE0000000UL;
+       temp = addr & MCPCIA_MEM_R1_MASK ;
+       set_hae(msb);
+
+       work = ((temp << 5) + MCPCIA_SPARSE(hose) + 0x08);
+       result = *(vip) work;
+       return __kernel_extwl(result, addr & 3);
+}
+
+__EXTERN_INLINE void mcpcia_writeb(unsigned char b, unsigned long in_addr)
+{
+       unsigned long addr = in_addr & 0xffffffffUL;
+       unsigned long hose = (in_addr >> 32) & 3;
+        unsigned long msb; 
+
+       msb = addr & 0xE0000000;
+       addr &= MCPCIA_MEM_R1_MASK;
+       set_hae(msb);
+
+       *(vuip) ((addr << 5) + MCPCIA_SPARSE(hose) + 0x00) = b * 0x01010101;
+}
+
+__EXTERN_INLINE void mcpcia_writew(unsigned short b, unsigned long in_addr)
+{
+       unsigned long addr = in_addr & 0xffffffffUL;
+       unsigned long hose = (in_addr >> 32) & 3;
+        unsigned long msb ; 
+
+       msb = addr & 0xE0000000 ;
+       addr &= MCPCIA_MEM_R1_MASK ;
+       set_hae(msb);
+
+       *(vuip) ((addr << 5) + MCPCIA_SPARSE(hose) + 0x08) = b * 0x00010001;
+}
+
+__EXTERN_INLINE unsigned long mcpcia_readl(unsigned long in_addr)
+{
+       unsigned long addr = in_addr & 0xffffffffUL;
+       unsigned long hose = (in_addr >> 32) & 3;
+       return *(vuip) (addr + MCPCIA_DENSE(hose));
+}
+
+__EXTERN_INLINE unsigned long mcpcia_readq(unsigned long in_addr)
+{
+       unsigned long addr = in_addr & 0xffffffffUL;
+       unsigned long hose = (in_addr >> 32) & 3;
+       return *(vulp) (addr + MCPCIA_DENSE(hose));
+}
+
+__EXTERN_INLINE void mcpcia_writel(unsigned int b, unsigned long in_addr)
+{
+       unsigned long addr = in_addr & 0xffffffffUL;
+       unsigned long hose = (in_addr >> 32) & 3;
+       *(vuip) (addr + MCPCIA_DENSE(hose)) = b;
+}
+
+__EXTERN_INLINE void mcpcia_writeq(unsigned long b, unsigned long in_addr)
+{
+       unsigned long addr = in_addr & 0xffffffffUL;
+       unsigned long hose = (in_addr >> 32) & 3;
+       *(vulp) (addr + MCPCIA_DENSE(hose)) = b;
+}
+
+/* Find the DENSE memory area for a given bus address.  */
+
+__EXTERN_INLINE unsigned long mcpcia_dense_mem(unsigned long addr)
+{
+       return MCPCIA_DENSE((addr >> 32) & 3);
+}
+
+#undef vucp
+#undef vusp
+#undef vip
+#undef vuip
+#undef vulp
+
+#ifdef __WANT_IO_DEF
+
+#define virt_to_bus    mcpcia_virt_to_bus
+#define bus_to_virt    mcpcia_bus_to_virt
+
+#if 0 /* BWIO */
+# define __inb         mcpcia_bw_inb
+# define __inw         mcpcia_bw_inw
+# define __inl         mcpcia_bw_inl
+# define __outb                mcpcia_bw_outb
+# define __outw                mcpcia_bw_outw
+# define __outl                mcpcia_bw_outl
+# define __readb       mcpcia_bw_readb
+# define __readw       mcpcia_bw_readw
+# define __writeb      mcpcia_bw_writeb
+# define __writew      mcpcia_bw_writew
+# define __readl       mcpcia_bw_readl
+# define __readq       mcpcia_bw_readq
+# define __writel      mcpcia_bw_writel
+# define __writeq      mcpcia_bw_writeq
+#else
+# define __inb         mcpcia_inb
+# define __inw         mcpcia_inw
+# define __inl         mcpcia_inl
+# define __outb                mcpcia_outb
+# define __outw                mcpcia_outw
+# define __outl                mcpcia_outl
+# ifdef CONFIG_ALPHA_SRM_SETUP
+#  define __readb      mcpcia_srm_readb
+#  define __readw      mcpcia_srm_readw
+#  define __writeb     mcpcia_srm_writeb
+#  define __writew     mcpcia_srm_writew
+# else
+#  define __readb      mcpcia_readb
+#  define __readw      mcpcia_readw
+#  define __writeb     mcpcia_writeb
+#  define __writew     mcpcia_writew
+# endif
+# define __readl       mcpcia_readl
+# define __readq       mcpcia_readq
+# define __writel      mcpcia_writel
+# define __writeq      mcpcia_writeq
+#endif /* BWIO */
+
+#define dense_mem      mcpcia_dense_mem
+
+#if 0 /* BWIO */
+# define inb(port) __inb((port))
+# define inw(port) __inw((port))
+# define inl(port) __inl((port))
+# define outb(x, port) __outb((x),(port))
+# define outw(x, port) __outw((x),(port))
+# define outl(x, port) __outl((x),(port))
+# define readb(addr) __readb((addr))
+# define readw(addr) __readw((addr))
+# define writeb(b, addr) __writeb((b),(addr))
+# define writew(b, addr) __writew((b),(addr))
+#else
+# define inb(port) \
+  (__builtin_constant_p((port))?__inb(port):_inb(port))
+# define outb(x, port) \
+  (__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port)))
+#endif /* BWIO */
+
+#define readl(a)       __readl((unsigned long)(a))
+#define readq(a)       __readq((unsigned long)(a))
+#define writel(v,a)    __writel((v),(unsigned long)(a))
+#define writeq(v,a)    __writeq((v),(unsigned long)(a))
+
+#endif /* __WANT_IO_DEF */
+
+#ifdef __IO_EXTERN_INLINE
+#undef __EXTERN_INLINE
+#undef __IO_EXTERN_INLINE
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* __ALPHA_MCPCIA__H__ */
diff --git a/include/asm-alpha/core_pyxis.h b/include/asm-alpha/core_pyxis.h
new file mode 100644 (file)
index 0000000..8b00d13
--- /dev/null
@@ -0,0 +1,684 @@
+#ifndef __ALPHA_PYXIS__H__
+#define __ALPHA_PYXIS__H__
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/compiler.h>
+
+/*
+ * PYXIS is the internal name for a core logic chipset which provides
+ * memory controller and PCI access for the 21164A chip based systems.
+ *
+ * This file is based on:
+ *
+ * Pyxis Chipset Spec
+ * 14-Jun-96
+ * Rev. X2.0
+ *
+ */
+
+/*------------------------------------------------------------------------**
+**                                                                        **
+**  I/O procedures                                                        **
+**                                                                        **
+**      inport[b|w|t|l], outport[b|w|t|l] 8:16:24:32 IO xfers             **
+**     inportbxt: 8 bits only                                            **
+**      inport:    alias of inportw                                       **
+**      outport:   alias of outportw                                      **
+**                                                                        **
+**      inmem[b|w|t|l], outmem[b|w|t|l] 8:16:24:32 ISA memory xfers       **
+**     inmembxt: 8 bits only                                             **
+**      inmem:    alias of inmemw                                         **
+**      outmem:   alias of outmemw                                        **
+**                                                                        **
+**------------------------------------------------------------------------*/
+
+
+/* CIA ADDRESS BIT DEFINITIONS
+ *
+ *  3 3 3 3|3 3 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |1| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |0|0|0|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
+ *  |                                                                        \_/ \_/
+ *  |                                                                         |   |
+ *  +-- IO space, not cached.                                   Byte Enable --+   |
+ *                                                              Transfer Length --+
+ *
+ *
+ *
+ *   Byte      Transfer
+ *   Enable    Length    Transfer  Byte    Address
+ *   adr<6:5>  adr<4:3>  Length    Enable  Adder
+ *   ---------------------------------------------
+ *      00        00      Byte      1110   0x000
+ *      01        00      Byte      1101   0x020
+ *      10        00      Byte      1011   0x040
+ *      11        00      Byte      0111   0x060
+ *
+ *      00        01      Word      1100   0x008
+ *      01        01      Word      1001   0x028 <= Not supported in this code.
+ *      10        01      Word      0011   0x048
+ *
+ *      00        10      Tribyte   1000   0x010
+ *      01        10      Tribyte   0001   0x030
+ *
+ *      10        11      Longword  0000   0x058
+ *
+ *      Note that byte enables are asserted low.
+ *
+ */
+
+#define PYXIS_MEM_R1_MASK 0x1fffffff  /* SPARSE Mem region 1 mask is 29 bits */
+#define PYXIS_MEM_R2_MASK 0x07ffffff  /* SPARSE Mem region 2 mask is 27 bits */
+#define PYXIS_MEM_R3_MASK 0x03ffffff  /* SPARSE Mem region 3 mask is 26 bits */
+
+#define PYXIS_DMA_WIN_BASE_DEFAULT     (1024*1024*1024)
+#define PYXIS_DMA_WIN_SIZE_DEFAULT     (1024*1024*1024)
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
+#define PYXIS_DMA_WIN_BASE             alpha_mv.dma_win_base
+#define PYXIS_DMA_WIN_SIZE             alpha_mv.dma_win_size
+#else
+#define PYXIS_DMA_WIN_BASE             PYXIS_DMA_WIN_BASE_DEFAULT
+#define PYXIS_DMA_WIN_SIZE             PYXIS_DMA_WIN_SIZE_DEFAULT
+#endif
+
+/*
+ *  General Registers
+ */
+#define PYXIS_REV                      (IDENT_ADDR + 0x8740000080UL)
+#define PYXIS_PCI_LAT                  (IDENT_ADDR + 0x87400000C0UL)
+#define PYXIS_CTRL                     (IDENT_ADDR + 0x8740000100UL)
+#define PYXIS_CTRL1                    (IDENT_ADDR + 0x8740000140UL)
+#define PYXIS_FLASH_CTRL               (IDENT_ADDR + 0x8740000200UL)
+
+#define PYXIS_HAE_MEM                  (IDENT_ADDR + 0x8740000400UL)
+#define PYXIS_HAE_IO                   (IDENT_ADDR + 0x8740000440UL)
+#define PYXIS_CFG                      (IDENT_ADDR + 0x8740000480UL)
+
+/*
+ * Diagnostic Registers
+ */
+#define PYXIS_DIAG                     (IDENT_ADDR + 0x8740002000UL)
+#define PYXIS_DIAG_CHECK               (IDENT_ADDR + 0x8740003000UL)
+
+/*
+ * Performance Monitor registers
+ */
+#define PYXIS_PERF_MONITOR             (IDENT_ADDR + 0x8740004000UL)
+#define PYXIS_PERF_CONTROL             (IDENT_ADDR + 0x8740004040UL)
+
+/*
+ * Error registers
+ */
+#define PYXIS_ERR                      (IDENT_ADDR + 0x8740008200UL)
+#define PYXIS_STAT                     (IDENT_ADDR + 0x8740008240UL)
+#define PYXIS_ERR_MASK                 (IDENT_ADDR + 0x8740008280UL)
+#define PYXIS_SYN                      (IDENT_ADDR + 0x8740008300UL)
+#define PYXIS_ERR_DATA                 (IDENT_ADDR + 0x8740008308UL)
+
+#define PYXIS_MEAR                     (IDENT_ADDR + 0x8740008400UL)
+#define PYXIS_MESR                     (IDENT_ADDR + 0x8740008440UL)
+#define PYXIS_PCI_ERR0                 (IDENT_ADDR + 0x8740008800UL)
+#define PYXIS_PCI_ERR1                 (IDENT_ADDR + 0x8740008840UL)
+#define PYXIS_PCI_ERR2                 (IDENT_ADDR + 0x8740008880UL)
+
+/*
+ * PCI Address Translation Registers.
+ */
+#define PYXIS_TBIA                     (IDENT_ADDR + 0x8760000100UL)
+
+#define PYXIS_W0_BASE                  (IDENT_ADDR + 0x8760000400UL)
+#define PYXIS_W0_MASK                  (IDENT_ADDR + 0x8760000440UL)
+#define PYXIS_T0_BASE                  (IDENT_ADDR + 0x8760000480UL)
+
+#define PYXIS_W1_BASE                  (IDENT_ADDR + 0x8760000500UL)
+#define PYXIS_W1_MASK                  (IDENT_ADDR + 0x8760000540UL)
+#define PYXIS_T1_BASE                  (IDENT_ADDR + 0x8760000580UL)
+
+#define PYXIS_W2_BASE                  (IDENT_ADDR + 0x8760000600UL)
+#define PYXIS_W2_MASK                  (IDENT_ADDR + 0x8760000640UL)
+#define PYXIS_T2_BASE                  (IDENT_ADDR + 0x8760000680UL)
+
+#define PYXIS_W3_BASE                  (IDENT_ADDR + 0x8760000700UL)
+#define PYXIS_W3_MASK                  (IDENT_ADDR + 0x8760000740UL)
+#define PYXIS_T3_BASE                  (IDENT_ADDR + 0x8760000780UL)
+
+/*
+ * Memory Control registers
+ */
+#define PYXIS_MCR                      (IDENT_ADDR + 0x8750000000UL)
+
+/*
+ * Memory spaces:
+ */
+#define PYXIS_IACK_SC                  (IDENT_ADDR + 0x8720000000UL)
+#define PYXIS_CONF                     (IDENT_ADDR + 0x8700000000UL)
+#define PYXIS_IO                       (IDENT_ADDR + 0x8580000000UL)
+#define PYXIS_SPARSE_MEM               (IDENT_ADDR + 0x8000000000UL)
+#define PYXIS_SPARSE_MEM_R2            (IDENT_ADDR + 0x8400000000UL)
+#define PYXIS_SPARSE_MEM_R3            (IDENT_ADDR + 0x8500000000UL)
+#define PYXIS_DENSE_MEM                        (IDENT_ADDR + 0x8600000000UL)
+
+/*
+ * Byte/Word PCI Memory Spaces:
+ */
+#define PYXIS_BW_MEM                   (IDENT_ADDR + 0x8800000000UL)
+#define PYXIS_BW_IO                    (IDENT_ADDR + 0x8900000000UL)
+#define PYXIS_BW_CFG_0                 (IDENT_ADDR + 0x8a00000000UL)
+#define PYXIS_BW_CFG_1                 (IDENT_ADDR + 0x8b00000000UL)
+
+/*
+ * Interrupt Control registers
+ */
+#define PYXIS_INT_REQ                  (IDENT_ADDR + 0x87A0000000UL)
+#define PYXIS_INT_MASK                 (IDENT_ADDR + 0x87A0000040UL)
+#define PYXIS_INT_HILO                 (IDENT_ADDR + 0x87A00000C0UL)
+#define PYXIS_INT_ROUTE                        (IDENT_ADDR + 0x87A0000140UL)
+#define PYXIS_GPO                      (IDENT_ADDR + 0x87A0000180UL)
+#define PYXIS_INT_CNFG                 (IDENT_ADDR + 0x87A00001C0UL)
+#define PYXIS_RT_COUNT                 (IDENT_ADDR + 0x87A0000200UL)
+#define PYXIS_INT_TIME                 (IDENT_ADDR + 0x87A0000240UL)
+#define PYXIS_IIC_CTRL                 (IDENT_ADDR + 0x87A00002C0UL)
+
+/*
+ * Bit definitions for I/O Controller status register 0:
+ */
+#define PYXIS_STAT0_CMD                        0xf
+#define PYXIS_STAT0_ERR                        (1<<4)
+#define PYXIS_STAT0_LOST               (1<<5)
+#define PYXIS_STAT0_THIT               (1<<6)
+#define PYXIS_STAT0_TREF               (1<<7)
+#define PYXIS_STAT0_CODE_SHIFT         8
+#define PYXIS_STAT0_CODE_MASK          0x7
+#define PYXIS_STAT0_P_NBR_SHIFT                13
+#define PYXIS_STAT0_P_NBR_MASK         0x7ffff
+
+#define PYXIS_HAE_ADDRESS                PYXIS_HAE_MEM
+
+/*
+ * Data structure for handling PYXIS machine checks:
+ */
+struct el_PYXIS_sysdata_mcheck {
+    u_long      coma_gcr;                       
+    u_long      coma_edsr;                      
+    u_long      coma_ter;                       
+    u_long      coma_elar;                      
+    u_long      coma_ehar;                      
+    u_long      coma_ldlr;                      
+    u_long      coma_ldhr;                      
+    u_long      coma_base0;                     
+    u_long      coma_base1;                     
+    u_long      coma_base2;                     
+    u_long      coma_cnfg0;                     
+    u_long      coma_cnfg1;                     
+    u_long      coma_cnfg2;                     
+    u_long      epic_dcsr;                      
+    u_long      epic_pear;                      
+    u_long      epic_sear;                      
+    u_long      epic_tbr1;                      
+    u_long      epic_tbr2;                      
+    u_long      epic_pbr1;                      
+    u_long      epic_pbr2;                      
+    u_long      epic_pmr1;                      
+    u_long      epic_pmr2;                      
+    u_long      epic_harx1;                     
+    u_long      epic_harx2;                     
+    u_long      epic_pmlt;                      
+    u_long      epic_tag0;                      
+    u_long      epic_tag1;                      
+    u_long      epic_tag2;                      
+    u_long      epic_tag3;                      
+    u_long      epic_tag4;                      
+    u_long      epic_tag5;                      
+    u_long      epic_tag6;                      
+    u_long      epic_tag7;                      
+    u_long      epic_data0;                     
+    u_long      epic_data1;                     
+    u_long      epic_data2;                     
+    u_long      epic_data3;                     
+    u_long      epic_data4;                     
+    u_long      epic_data5;                     
+    u_long      epic_data6;                     
+    u_long      epic_data7;                     
+};
+
+
+#ifdef __KERNEL__
+
+#ifndef __EXTERN_INLINE
+#define __EXTERN_INLINE extern inline
+#define __IO_EXTERN_INLINE
+#endif
+
+/*
+ * Translate physical memory address as seen on (PCI) bus into
+ * a kernel virtual address and vv.
+ */
+
+/* Ruffian doesn't do 1G PCI window */
+
+static inline unsigned long pyxis_ruffian_virt_to_bus(void * address)
+{
+       return virt_to_phys(address);
+}
+
+static inline void * pyxis_ruffian_bus_to_virt(unsigned long address)
+{
+       return phys_to_virt(address);
+}
+
+__EXTERN_INLINE unsigned long pyxis_virt_to_bus(void * address)
+{
+       return virt_to_phys(address) + PYXIS_DMA_WIN_BASE;
+}
+
+__EXTERN_INLINE void * pyxis_bus_to_virt(unsigned long address)
+{
+       return phys_to_virt(address - PYXIS_DMA_WIN_BASE);
+}
+
+
+/*
+ * I/O functions:
+ *
+ * PYXIS, the 21174 PCI/memory support chipset for the EV56 (21164A)
+ * and PCA56 (21164PC) processors, can use either a sparse address
+ * mapping scheme, or the so-called byte-word PCI address space, to
+ * get at PCI memory and I/O.
+ */
+
+#define vucp   volatile unsigned char *
+#define vusp   volatile unsigned short *
+#define vip    volatile int *
+#define vuip   volatile unsigned int *
+#define vulp   volatile unsigned long *
+
+__EXTERN_INLINE unsigned int pyxis_bw_inb(unsigned long addr)
+{
+       return __kernel_ldbu(*(vucp)(addr+PYXIS_BW_IO));
+}
+
+__EXTERN_INLINE void pyxis_bw_outb(unsigned char b, unsigned long addr)
+{
+       __kernel_stb(b, *(vucp)(addr+PYXIS_BW_IO));
+       mb();
+}
+
+__EXTERN_INLINE unsigned int pyxis_bw_inw(unsigned long addr)
+{
+       return __kernel_ldwu(*(vusp)(addr+PYXIS_BW_IO));
+}
+
+__EXTERN_INLINE void pyxis_bw_outw(unsigned short b, unsigned long addr)
+{
+       __kernel_stw(b, *(vusp)(addr+PYXIS_BW_IO));
+       mb();
+}
+
+__EXTERN_INLINE unsigned int pyxis_bw_inl(unsigned long addr)
+{
+       return *(vuip)(addr+PYXIS_BW_IO);
+}
+
+__EXTERN_INLINE void pyxis_bw_outl(unsigned int b, unsigned long addr)
+{
+       *(vuip)(addr+PYXIS_BW_IO) = b;
+       mb();
+}
+
+__EXTERN_INLINE unsigned int pyxis_inb(unsigned long addr)
+{
+       long result = *(vip) ((addr << 5) + PYXIS_IO + 0x00);
+       return __kernel_extbl(result, addr & 3);
+}
+
+__EXTERN_INLINE void pyxis_outb(unsigned char b, unsigned long addr)
+{
+       unsigned int w;
+
+       w = __kernel_insbl(b, addr & 3);
+       *(vuip) ((addr << 5) + PYXIS_IO + 0x00) = w;
+       mb();
+}
+
+__EXTERN_INLINE unsigned int pyxis_inw(unsigned long addr)
+{
+       long result = *(vip) ((addr << 5) + PYXIS_IO + 0x08);
+       return __kernel_extwl(result, addr & 3);
+}
+
+__EXTERN_INLINE void pyxis_outw(unsigned short b, unsigned long addr)
+{
+       unsigned int w;
+
+       w = __kernel_inswl(b, addr & 3);
+       *(vuip) ((addr << 5) + PYXIS_IO + 0x08) = w;
+       mb();
+}
+
+__EXTERN_INLINE unsigned int pyxis_inl(unsigned long addr)
+{
+       return *(vuip) ((addr << 5) + PYXIS_IO + 0x18);
+}
+
+__EXTERN_INLINE void pyxis_outl(unsigned int b, unsigned long addr)
+{
+       *(vuip) ((addr << 5) + PYXIS_IO + 0x18) = b;
+       mb();
+}
+
+
+/*
+ * Memory functions.  64-bit and 32-bit accesses are done through
+ * dense memory space, everything else through sparse space.
+ * 
+ * For reading and writing 8 and 16 bit quantities we need to 
+ * go through one of the three sparse address mapping regions
+ * and use the HAE_MEM CSR to provide some bits of the address.
+ * The following few routines use only sparse address region 1
+ * which gives 1Gbyte of accessible space which relates exactly
+ * to the amount of PCI memory mapping *into* system address space.
+ * See p 6-17 of the specification but it looks something like this:
+ *
+ * 21164 Address:
+ * 
+ *          3         2         1                                                               
+ * 9876543210987654321098765432109876543210
+ * 1ZZZZ0.PCI.QW.Address............BBLL                 
+ *
+ * ZZ = SBZ
+ * BB = Byte offset
+ * LL = Transfer length
+ *
+ * PCI Address:
+ *
+ * 3         2         1                                                               
+ * 10987654321098765432109876543210
+ * HHH....PCI.QW.Address........ 00
+ *
+ * HHH = 31:29 HAE_MEM CSR
+ * 
+ */
+
+__EXTERN_INLINE unsigned long pyxis_bw_readb(unsigned long addr)
+{
+       return __kernel_ldbu(*(vucp)(addr+PYXIS_BW_MEM));
+}
+
+__EXTERN_INLINE unsigned long pyxis_bw_readw(unsigned long addr)
+{
+       return __kernel_ldwu(*(vusp)(addr+PYXIS_BW_MEM));
+}
+
+__EXTERN_INLINE unsigned long pyxis_bw_readl(unsigned long addr)
+{
+       return *(vuip)(addr+PYXIS_BW_MEM);
+}
+
+__EXTERN_INLINE unsigned long pyxis_bw_readq(unsigned long addr)
+{
+       return *(vulp)(addr+PYXIS_BW_MEM);
+}
+
+__EXTERN_INLINE void pyxis_bw_writeb(unsigned char b, unsigned long addr)
+{
+       __kernel_stb(b, *(vucp)(addr+PYXIS_BW_MEM));
+       mb();
+}
+
+__EXTERN_INLINE void pyxis_bw_writew(unsigned short b, unsigned long addr)
+{
+       __kernel_stw(b, *(vusp)(addr+PYXIS_BW_MEM));
+       mb();
+}
+
+__EXTERN_INLINE void pyxis_bw_writel(unsigned int b, unsigned long addr)
+{
+       *(vuip)(addr+PYXIS_BW_MEM) = b;
+}
+
+__EXTERN_INLINE void pyxis_bw_writeq(unsigned long b, unsigned long addr)
+{
+       *(vulp)(addr+PYXIS_BW_MEM) = b;
+}
+
+__EXTERN_INLINE unsigned long pyxis_srm_base(unsigned long addr)
+{
+       unsigned long mask, base;
+
+       if (addr >= alpha_mv.sm_base_r1
+           && addr <= alpha_mv.sm_base_r1 + PYXIS_MEM_R1_MASK) {
+               mask = PYXIS_MEM_R1_MASK;
+               base = PYXIS_SPARSE_MEM;
+       }
+       else if (addr >= alpha_mv.sm_base_r2
+                && addr <= alpha_mv.sm_base_r2 + PYXIS_MEM_R2_MASK) {
+               mask = PYXIS_MEM_R2_MASK;
+               base = PYXIS_SPARSE_MEM_R2;
+       }
+       else if (addr >= alpha_mv.sm_base_r3
+                && addr <= alpha_mv.sm_base_r3 + PYXIS_MEM_R3_MASK) {
+               mask = PYXIS_MEM_R3_MASK;
+               base = PYXIS_SPARSE_MEM_R3;
+       }
+       else
+       {
+#if 0
+         printk("pyxis: address 0x%lx not covered by HAE\n", addr);
+#endif
+         return 0;
+       }
+
+       return ((addr & mask) << 5) + base;
+}
+
+__EXTERN_INLINE unsigned long pyxis_srm_readb(unsigned long addr)
+{
+       unsigned long result, work;
+
+       if ((work = pyxis_srm_base(addr)) == 0)
+               return 0xff;
+       work += 0x00;   /* add transfer length */
+
+       result = *(vip) work;
+       return __kernel_extbl(result, addr & 3);
+}
+
+__EXTERN_INLINE unsigned long pyxis_srm_readw(unsigned long addr)
+{
+       unsigned long result, work;
+
+       if ((work = pyxis_srm_base(addr)) == 0)
+               return 0xffff;
+       work += 0x08;   /* add transfer length */
+
+       result = *(vip) work;
+       return __kernel_extwl(result, addr & 3);
+}
+
+__EXTERN_INLINE void pyxis_srm_writeb(unsigned char b, unsigned long addr)
+{
+       unsigned long work = pyxis_srm_base(addr);
+       if (work) {
+               work += 0x00;   /* add transfer length */
+               *(vuip) work = b * 0x01010101;
+       }
+}
+
+__EXTERN_INLINE void pyxis_srm_writew(unsigned short b, unsigned long addr)
+{
+       unsigned long work = pyxis_srm_base(addr);
+       if (work) {
+               work += 0x08;   /* add transfer length */
+               *(vuip) work = b * 0x00010001;
+       }
+}
+
+__EXTERN_INLINE unsigned long pyxis_readb(unsigned long addr)
+{
+       unsigned long result, msb, work, temp;
+
+       msb = addr & 0xE0000000UL;
+       temp = addr & PYXIS_MEM_R1_MASK ;
+       set_hae(msb);
+
+       work = ((temp << 5) + PYXIS_SPARSE_MEM + 0x00);
+       result = *(vip) work;
+       return __kernel_extbl(result, addr & 3);
+}
+
+__EXTERN_INLINE unsigned long pyxis_readw(unsigned long addr)
+{
+       unsigned long result, msb, work, temp;
+
+       msb = addr & 0xE0000000UL;
+       temp = addr & PYXIS_MEM_R1_MASK ;
+       set_hae(msb);
+
+       work = ((temp << 5) + PYXIS_SPARSE_MEM + 0x08);
+       result = *(vip) work;
+       return __kernel_extwl(result, addr & 3);
+}
+
+__EXTERN_INLINE void pyxis_writeb(unsigned char b, unsigned long addr)
+{
+        unsigned long msb ; 
+
+       msb = addr & 0xE0000000 ;
+       addr &= PYXIS_MEM_R1_MASK ;
+       set_hae(msb);
+
+       *(vuip) ((addr << 5) + PYXIS_SPARSE_MEM + 0x00) = b * 0x01010101;
+}
+
+__EXTERN_INLINE void pyxis_writew(unsigned short b, unsigned long addr)
+{
+        unsigned long msb ; 
+
+       msb = addr & 0xE0000000 ;
+       addr &= PYXIS_MEM_R1_MASK ;
+       set_hae(msb);
+
+       *(vuip) ((addr << 5) + PYXIS_SPARSE_MEM + 0x08) = b * 0x00010001;
+}
+
+__EXTERN_INLINE unsigned long pyxis_readl(unsigned long addr)
+{
+       return *(vuip) (addr + PYXIS_DENSE_MEM);
+}
+
+__EXTERN_INLINE unsigned long pyxis_readq(unsigned long addr)
+{
+       return *(vulp) (addr + PYXIS_DENSE_MEM);
+}
+
+__EXTERN_INLINE void pyxis_writel(unsigned int b, unsigned long addr)
+{
+       *(vuip) (addr + PYXIS_DENSE_MEM) = b;
+}
+
+__EXTERN_INLINE void pyxis_writeq(unsigned long b, unsigned long addr)
+{
+       *(vulp) (addr + PYXIS_DENSE_MEM) = b;
+}
+
+/* Find the DENSE memory area for a given bus address.  */
+
+__EXTERN_INLINE unsigned long pyxis_dense_mem(unsigned long addr)
+{
+       return PYXIS_DENSE_MEM;
+}
+
+#undef vucp
+#undef vusp
+#undef vip
+#undef vuip
+#undef vulp
+
+#ifdef __WANT_IO_DEF
+
+#ifdef CONFIG_ALPHA_RUFFIAN
+#define virt_to_bus    pyxis_ruffian_virt_to_bus
+#define bus_to_virt    pyxis_ruffian_bus_to_virt
+#else
+#define virt_to_bus    pyxis_virt_to_bus
+#define bus_to_virt    pyxis_bus_to_virt
+#endif
+
+#ifdef BWIO_ENABLED
+# define __inb         pyxis_bw_inb
+# define __inw         pyxis_bw_inw
+# define __inl         pyxis_bw_inl
+# define __outb                pyxis_bw_outb
+# define __outw                pyxis_bw_outw
+# define __outl                pyxis_bw_outl
+# define __readb       pyxis_bw_readb
+# define __readw       pyxis_bw_readw
+# define __writeb      pyxis_bw_writeb
+# define __writew      pyxis_bw_writew
+# define __readl       pyxis_bw_readl
+# define __readq       pyxis_bw_readq
+# define __writel      pyxis_bw_writel
+# define __writeq      pyxis_bw_writeq
+#else
+# define __inb         pyxis_inb
+# define __inw         pyxis_inw
+# define __inl         pyxis_inl
+# define __outb                pyxis_outb
+# define __outw                pyxis_outw
+# define __outl                pyxis_outl
+# ifdef CONFIG_ALPHA_SRM_SETUP
+#  define __readb      pyxis_srm_readb
+#  define __readw      pyxis_srm_readw
+#  define __writeb     pyxis_srm_writeb
+#  define __writew     pyxis_srm_writew
+# else
+#  define __readb      pyxis_readb
+#  define __readw      pyxis_readw
+#  define __writeb     pyxis_writeb
+#  define __writew     pyxis_writew
+# endif
+# define __readl       pyxis_readl
+# define __readq       pyxis_readq
+# define __writel      pyxis_writel
+# define __writeq      pyxis_writeq
+#endif /* BWIO */
+
+#define dense_mem      pyxis_dense_mem
+
+#ifdef BWIO_ENABLED
+# define inb(port) __inb((port))
+# define inw(port) __inw((port))
+# define inl(port) __inl((port))
+# define outb(x, port) __outb((x),(port))
+# define outw(x, port) __outw((x),(port))
+# define outl(x, port) __outl((x),(port))
+# define readb(addr) __readb((addr))
+# define readw(addr) __readw((addr))
+# define writeb(b, addr) __writeb((b),(addr))
+# define writew(b, addr) __writew((b),(addr))
+#else
+# define inb(port) \
+  (__builtin_constant_p((port))?__inb(port):_inb(port))
+# define outb(x, port) \
+  (__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port)))
+#endif /* BWIO */
+
+#define readl(a)       __readl((unsigned long)(a))
+#define readq(a)       __readq((unsigned long)(a))
+#define writel(v,a)    __writel((v),(unsigned long)(a))
+#define writeq(v,a)    __writeq((v),(unsigned long)(a))
+
+#endif /* __WANT_IO_DEF */
+
+#ifdef __IO_EXTERN_INLINE
+#undef __EXTERN_INLINE
+#undef __IO_EXTERN_INLINE
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* __ALPHA_PYXIS__H__ */
diff --git a/include/asm-alpha/core_t2.h b/include/asm-alpha/core_t2.h
new file mode 100644 (file)
index 0000000..1f0984b
--- /dev/null
@@ -0,0 +1,691 @@
+#ifndef __ALPHA_T2__H__
+#define __ALPHA_T2__H__
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/compiler.h>
+
+
+/*
+ * T2 is the internal name for the core logic chipset which provides
+ * memory controller and PCI access for the SABLE-based systems.
+ *
+ * This file is based on:
+ *
+ * SABLE I/O Specification
+ * Revision/Update Information: 1.3
+ *
+ * jestabro@amt.tay1.dec.com Initial Version.
+ *
+ */
+
+#define T2_MEM_R1_MASK 0x03ffffff  /* Mem sparse region 1 mask is 26 bits */
+
+#define T2_DMA_WIN_BASE_DEFAULT        (1024*1024*1024)
+#define T2_DMA_WIN_SIZE_DEFAULT        (1024*1024*1024)
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
+#define T2_DMA_WIN_BASE                alpha_mv.dma_win_base
+#define T2_DMA_WIN_SIZE                alpha_mv.dma_win_size
+#else
+#define T2_DMA_WIN_BASE                T2_DMA_WIN_BASE_DEFAULT
+#define T2_DMA_WIN_SIZE                T2_DMA_WIN_SIZE_DEFAULT
+#endif
+
+/* GAMMA-SABLE is a SABLE with EV5-based CPUs */
+#define _GAMMA_BIAS            0x8000000000UL
+
+#if defined(CONFIG_ALPHA_GENERIC)
+#define GAMMA_BIAS             alpha_mv.sys.t2.gamma_bias
+#elif defined(CONFIG_ALPHA_GAMMA)
+#define GAMMA_BIAS             _GAMMA_BIAS
+#else
+#define GAMMA_BIAS             0
+#endif
+
+/*
+ * Memory spaces:
+ */
+#define T2_CONF                        (IDENT_ADDR + GAMMA_BIAS + 0x390000000UL)
+#define T2_IO                  (IDENT_ADDR + GAMMA_BIAS + 0x3a0000000UL)
+#define T2_SPARSE_MEM          (IDENT_ADDR + GAMMA_BIAS + 0x200000000UL)
+#define T2_DENSE_MEM           (IDENT_ADDR + GAMMA_BIAS + 0x3c0000000UL)
+
+#define T2_IOCSR               (IDENT_ADDR + GAMMA_BIAS + 0x38e000000UL)
+#define T2_CERR1               (IDENT_ADDR + GAMMA_BIAS + 0x38e000020UL)
+#define T2_CERR2               (IDENT_ADDR + GAMMA_BIAS + 0x38e000040UL)
+#define T2_CERR3               (IDENT_ADDR + GAMMA_BIAS + 0x38e000060UL)
+#define T2_PERR1               (IDENT_ADDR + GAMMA_BIAS + 0x38e000080UL)
+#define T2_PERR2               (IDENT_ADDR + GAMMA_BIAS + 0x38e0000a0UL)
+#define T2_PSCR                        (IDENT_ADDR + GAMMA_BIAS + 0x38e0000c0UL)
+#define T2_HAE_1               (IDENT_ADDR + GAMMA_BIAS + 0x38e0000e0UL)
+#define T2_HAE_2               (IDENT_ADDR + GAMMA_BIAS + 0x38e000100UL)
+#define T2_HBASE               (IDENT_ADDR + GAMMA_BIAS + 0x38e000120UL)
+#define T2_WBASE1              (IDENT_ADDR + GAMMA_BIAS + 0x38e000140UL)
+#define T2_WMASK1              (IDENT_ADDR + GAMMA_BIAS + 0x38e000160UL)
+#define T2_TBASE1              (IDENT_ADDR + GAMMA_BIAS + 0x38e000180UL)
+#define T2_WBASE2              (IDENT_ADDR + GAMMA_BIAS + 0x38e0001a0UL)
+#define T2_WMASK2              (IDENT_ADDR + GAMMA_BIAS + 0x38e0001c0UL)
+#define T2_TBASE2              (IDENT_ADDR + GAMMA_BIAS + 0x38e0001e0UL)
+#define T2_TLBBR               (IDENT_ADDR + GAMMA_BIAS + 0x38e000200UL)
+
+#define T2_HAE_3               (IDENT_ADDR + GAMMA_BIAS + 0x38e000240UL)
+#define T2_HAE_4               (IDENT_ADDR + GAMMA_BIAS + 0x38e000260UL)
+
+#define T2_HAE_ADDRESS         T2_HAE_1
+
+/*  T2 CSRs are in the non-cachable primary IO space from 3.8000.0000 to
+ 3.8fff.ffff
+ *
+ *  +--------------+ 3 8000 0000
+ *  | CPU 0 CSRs   |            
+ *  +--------------+ 3 8100 0000
+ *  | CPU 1 CSRs   |            
+ *  +--------------+ 3 8200 0000
+ *  | CPU 2 CSRs   |            
+ *  +--------------+ 3 8300 0000
+ *  | CPU 3 CSRs   |            
+ *  +--------------+ 3 8400 0000
+ *  | CPU Reserved |            
+ *  +--------------+ 3 8700 0000
+ *  | Mem Reserved |            
+ *  +--------------+ 3 8800 0000
+ *  | Mem 0 CSRs   |            
+ *  +--------------+ 3 8900 0000
+ *  | Mem 1 CSRs   |            
+ *  +--------------+ 3 8a00 0000
+ *  | Mem 2 CSRs   |            
+ *  +--------------+ 3 8b00 0000
+ *  | Mem 3 CSRs   |            
+ *  +--------------+ 3 8c00 0000           
+ *  | Mem Reserved |            
+ *  +--------------+ 3 8e00 0000           
+ *  | PCI Bridge   |            
+ *  +--------------+ 3 8f00 0000           
+ *  | Expansion IO |            
+ *  +--------------+ 3 9000 0000           
+ *                                              
+ *
+ */
+#define T2_CPU0_BASE            (IDENT_ADDR + GAMMA_BIAS + 0x380000000L)
+#define T2_CPU1_BASE            (IDENT_ADDR + GAMMA_BIAS + 0x381000000L)
+#define T2_CPU2_BASE            (IDENT_ADDR + GAMMA_BIAS + 0x382000000L)
+#define T2_CPU3_BASE            (IDENT_ADDR + GAMMA_BIAS + 0x383000000L)
+#define T2_MEM0_BASE            (IDENT_ADDR + GAMMA_BIAS + 0x388000000L)
+#define T2_MEM1_BASE            (IDENT_ADDR + GAMMA_BIAS + 0x389000000L)
+#define T2_MEM2_BASE            (IDENT_ADDR + GAMMA_BIAS + 0x38a000000L)
+#define T2_MEM3_BASE            (IDENT_ADDR + GAMMA_BIAS + 0x38b000000L)
+
+
+/*
+ * Sable CPU Module CSRS
+ *
+ * These are CSRs for hardware other than the CPU chip on the CPU module.
+ * The CPU module has Backup Cache control logic, Cbus control logic, and
+ * interrupt control logic on it.  There is a duplicate tag store to speed
+ * up maintaining cache coherency.
+ */
+
+struct sable_cpu_csr {
+  unsigned long bcc;     long fill_00[3]; /* Backup Cache Control */
+  unsigned long bcce;    long fill_01[3]; /* Backup Cache Correctable Error */
+  unsigned long bccea;   long fill_02[3]; /* B-Cache Corr Err Address Latch */
+  unsigned long bcue;    long fill_03[3]; /* B-Cache Uncorrectable Error */
+  unsigned long bcuea;   long fill_04[3]; /* B-Cache Uncorr Err Addr Latch */
+  unsigned long dter;    long fill_05[3]; /* Duplicate Tag Error */
+  unsigned long cbctl;   long fill_06[3]; /* CBus Control */
+  unsigned long cbe;     long fill_07[3]; /* CBus Error */
+  unsigned long cbeal;   long fill_08[3]; /* CBus Error Addr Latch low */
+  unsigned long cbeah;   long fill_09[3]; /* CBus Error Addr Latch high */
+  unsigned long pmbx;    long fill_10[3]; /* Processor Mailbox */
+  unsigned long ipir;    long fill_11[3]; /* Inter-Processor Int Request */
+  unsigned long sic;     long fill_12[3]; /* System Interrupt Clear */
+  unsigned long adlk;    long fill_13[3]; /* Address Lock (LDxL/STxC) */
+  unsigned long madrl;   long fill_14[3]; /* CBus Miss Address */
+  unsigned long rev;     long fill_15[3]; /* CMIC Revision */
+};
+
+/*
+ * Data structure for handling T2 machine checks:
+ */
+struct el_t2_frame_header {
+       unsigned int    elcf_fid;       /* Frame ID (from above) */
+       unsigned int    elcf_size;      /* Size of frame in bytes */
+};
+
+struct el_t2_procdata_mcheck {
+       unsigned long   elfmc_paltemp[32];      /* PAL TEMP REGS. */
+       /* EV4-specific fields */
+       unsigned long   elfmc_exc_addr; /* Addr of excepting insn. */
+       unsigned long   elfmc_exc_sum;  /* Summary of arith traps. */
+       unsigned long   elfmc_exc_mask; /* Exception mask (from exc_sum). */
+       unsigned long   elfmc_iccsr;    /* IBox hardware enables. */
+       unsigned long   elfmc_pal_base; /* Base address for PALcode. */
+       unsigned long   elfmc_hier;     /* Hardware Interrupt Enable. */
+       unsigned long   elfmc_hirr;     /* Hardware Interrupt Request. */
+       unsigned long   elfmc_mm_csr;   /* D-stream fault info. */
+       unsigned long   elfmc_dc_stat;  /* D-cache status (ECC/Parity Err). */
+       unsigned long   elfmc_dc_addr;  /* EV3 Phys Addr for ECC/DPERR. */
+       unsigned long   elfmc_abox_ctl; /* ABox Control Register. */
+       unsigned long   elfmc_biu_stat; /* BIU Status. */
+       unsigned long   elfmc_biu_addr; /* BUI Address. */
+       unsigned long   elfmc_biu_ctl;  /* BIU Control. */
+       unsigned long   elfmc_fill_syndrome; /* For correcting ECC errors. */
+       unsigned long   elfmc_fill_addr;/* Cache block which was being read. */
+       unsigned long   elfmc_va;       /* Effective VA of fault or miss. */
+       unsigned long   elfmc_bc_tag;   /* Backup Cache Tag Probe Results. */
+};
+
+/* 
+ * Sable processor specific Machine Check Data segment.
+ */
+
+struct el_t2_logout_header {
+       unsigned int    elfl_size;      /* size in bytes of logout area. */
+       int             elfl_sbz1:31;   /* Should be zero. */
+       char            elfl_retry:1;   /* Retry flag. */
+        unsigned int   elfl_procoffset; /* Processor-specific offset. */
+       unsigned int    elfl_sysoffset;  /* Offset of system-specific. */
+       unsigned int    elfl_error_type;        /* PAL error type code. */
+       unsigned int    elfl_frame_rev;         /* PAL Frame revision. */
+};
+struct el_t2_sysdata_mcheck {
+       unsigned long    elcmc_bcc;           /* CSR 0 */
+       unsigned long    elcmc_bcce;          /* CSR 1 */
+       unsigned long    elcmc_bccea;      /* CSR 2 */
+       unsigned long    elcmc_bcue;          /* CSR 3 */
+       unsigned long    elcmc_bcuea;      /* CSR 4 */
+       unsigned long    elcmc_dter;          /* CSR 5 */
+       unsigned long    elcmc_cbctl;      /* CSR 6 */
+       unsigned long    elcmc_cbe;           /* CSR 7 */
+       unsigned long    elcmc_cbeal;      /* CSR 8 */
+       unsigned long    elcmc_cbeah;      /* CSR 9 */
+       unsigned long    elcmc_pmbx;          /* CSR 10 */
+       unsigned long    elcmc_ipir;          /* CSR 11 */
+       unsigned long    elcmc_sic;           /* CSR 12 */
+       unsigned long    elcmc_adlk;          /* CSR 13 */
+       unsigned long    elcmc_madrl;      /* CSR 14 */
+       unsigned long    elcmc_crrev4;     /* CSR 15 */
+};
+
+/*
+ * Sable memory error frame - sable pfms section 3.42
+ */
+struct el_t2_data_memory {
+       struct  el_t2_frame_header elcm_hdr;    /* ID$MEM-FERR = 0x08 */
+       unsigned int  elcm_module;      /* Module id. */
+       unsigned int  elcm_res04;       /* Reserved. */
+       unsigned long elcm_merr;        /* CSR0: Error Reg 1. */
+       unsigned long elcm_mcmd1;       /* CSR1: Command Trap 1. */
+       unsigned long elcm_mcmd2;       /* CSR2: Command Trap 2. */
+       unsigned long elcm_mconf;       /* CSR3: Configuration. */
+       unsigned long elcm_medc1;       /* CSR4: EDC Status 1. */
+       unsigned long elcm_medc2;       /* CSR5: EDC Status 2. */
+       unsigned long elcm_medcc;       /* CSR6: EDC Control. */
+       unsigned long elcm_msctl;       /* CSR7: Stream Buffer Control. */
+       unsigned long elcm_mref;        /* CSR8: Refresh Control. */
+       unsigned long elcm_filter;      /* CSR9: CRD Filter Control. */
+};
+
+
+/*
+ * Sable other CPU error frame - sable pfms section 3.43
+ */
+struct el_t2_data_other_cpu {
+       short         elco_cpuid;       /* CPU ID */
+       short         elco_res02[3];    
+       unsigned long elco_bcc; /* CSR 0 */
+       unsigned long elco_bcce;        /* CSR 1 */
+       unsigned long elco_bccea;       /* CSR 2 */
+       unsigned long elco_bcue;        /* CSR 3 */
+       unsigned long elco_bcuea;       /* CSR 4 */
+       unsigned long elco_dter;        /* CSR 5 */
+       unsigned long elco_cbctl;       /* CSR 6 */
+       unsigned long elco_cbe; /* CSR 7 */
+       unsigned long elco_cbeal;       /* CSR 8 */
+       unsigned long elco_cbeah;       /* CSR 9 */
+       unsigned long elco_pmbx;        /* CSR 10 */
+       unsigned long elco_ipir;        /* CSR 11 */
+       unsigned long elco_sic; /* CSR 12 */
+       unsigned long elco_adlk;        /* CSR 13 */
+       unsigned long elco_madrl;       /* CSR 14 */
+       unsigned long elco_crrev4;      /* CSR 15 */
+};
+
+/*
+ * Sable other CPU error frame - sable pfms section 3.44
+ */
+struct el_t2_data_t2{
+        struct el_t2_frame_header elct_hdr;    /* ID$T2-FRAME */
+       unsigned long elct_iocsr;       /* IO Control and Status Register */
+       unsigned long elct_cerr1;       /* Cbus Error Register 1 */
+       unsigned long elct_cerr2;       /* Cbus Error Register 2 */
+       unsigned long elct_cerr3;       /* Cbus Error Register 3 */
+       unsigned long elct_perr1;       /* PCI Error Register 1 */
+       unsigned long elct_perr2;       /* PCI Error Register 2 */
+       unsigned long elct_hae0_1;      /* High Address Extension Register 1 */
+       unsigned long elct_hae0_2;      /* High Address Extension Register 2 */
+       unsigned long elct_hbase;       /* High Base Register */
+       unsigned long elct_wbase1;      /* Window Base Register 1 */
+       unsigned long elct_wmask1;      /* Window Mask Register 1 */
+       unsigned long elct_tbase1;      /* Translated Base Register 1 */
+       unsigned long elct_wbase2;      /* Window Base Register 2 */
+       unsigned long elct_wmask2;      /* Window Mask Register 2 */
+       unsigned long elct_tbase2;      /* Translated Base Register 2 */
+       unsigned long elct_tdr0;        /* TLB Data Register 0 */
+       unsigned long elct_tdr1;        /* TLB Data Register 1 */
+       unsigned long elct_tdr2;        /* TLB Data Register 2 */
+       unsigned long elct_tdr3;        /* TLB Data Register 3 */
+       unsigned long elct_tdr4;        /* TLB Data Register 4 */
+       unsigned long elct_tdr5;        /* TLB Data Register 5 */
+       unsigned long elct_tdr6;        /* TLB Data Register 6 */
+       unsigned long elct_tdr7;        /* TLB Data Register 7 */
+};
+
+/*
+ * Sable error log data structure - sable pfms section 3.40
+ */
+struct el_t2_data_corrected {
+       unsigned long elcpb_biu_stat;
+       unsigned long elcpb_biu_addr;
+       unsigned long elcpb_biu_ctl;
+       unsigned long elcpb_fill_syndrome;
+       unsigned long elcpb_fill_addr;
+       unsigned long elcpb_bc_tag;
+};
+
+/* 
+ * Sable error log data structure
+ * Note there are 4 memory slots on sable (see t2.h)
+ */
+struct el_t2_frame_mcheck {
+        struct el_t2_frame_header elfmc_header;        /* ID$P-FRAME_MCHECK */
+       struct el_t2_logout_header elfmc_hdr;
+       struct el_t2_procdata_mcheck elfmc_procdata;
+       struct el_t2_sysdata_mcheck elfmc_sysdata;
+       struct el_t2_data_t2 elfmc_t2data;
+       struct el_t2_data_memory elfmc_memdata[4]; 
+        struct el_t2_frame_header elfmc_footer;        /* empty */
+};
+
+
+/* 
+ * Sable error log data structures on memory errors
+ */
+struct el_t2_frame_corrected {
+        struct el_t2_frame_header elfcc_header;        /* ID$P-BC-COR */
+       struct el_t2_logout_header elfcc_hdr;
+       struct el_t2_data_corrected elfcc_procdata; 
+/*     struct el_t2_data_t2 elfcc_t2data;              */
+/*     struct el_t2_data_memory elfcc_memdata[4];      */
+        struct el_t2_frame_header elfcc_footer;        /* empty */
+};
+
+
+#ifdef __KERNEL__
+
+#ifndef __EXTERN_INLINE
+#define __EXTERN_INLINE extern inline
+#define __IO_EXTERN_INLINE
+#endif
+
+/*
+ * Translate physical memory address as seen on (PCI) bus into
+ * a kernel virtual address and vv.
+ */
+
+__EXTERN_INLINE unsigned long t2_virt_to_bus(void * address)
+{
+       return virt_to_phys(address) + T2_DMA_WIN_BASE;
+}
+
+__EXTERN_INLINE void * t2_bus_to_virt(unsigned long address)
+{
+       return phys_to_virt(address - T2_DMA_WIN_BASE);
+}
+
+/*
+ * I/O functions:
+ *
+ * T2 (the core logic PCI/memory support chipset for the SABLE
+ * series of processors uses a sparse address mapping scheme to
+ * get at PCI memory and I/O.
+ */
+
+#define vip    volatile int *
+#define vuip   volatile unsigned int *
+
+__EXTERN_INLINE unsigned int t2_inb(unsigned long addr)
+{
+       long result = *(vip) ((addr << 5) + T2_IO + 0x00);
+       return __kernel_extbl(result, addr & 3);
+}
+
+__EXTERN_INLINE void t2_outb(unsigned char b, unsigned long addr)
+{
+       unsigned long w;
+
+       w = __kernel_insbl(b, addr & 3);
+       *(vuip) ((addr << 5) + T2_IO + 0x00) = w;
+       mb();
+}
+
+__EXTERN_INLINE unsigned int t2_inw(unsigned long addr)
+{
+       long result = *(vip) ((addr << 5) + T2_IO + 0x08);
+       return __kernel_extwl(result, addr & 3);
+}
+
+__EXTERN_INLINE void t2_outw(unsigned short b, unsigned long addr)
+{
+       unsigned int w;
+
+       w = __kernel_inswl(b, addr & 3);
+       *(vuip) ((addr << 5) + T2_IO + 0x08) = w;
+       mb();
+}
+
+__EXTERN_INLINE unsigned int t2_inl(unsigned long addr)
+{
+       return *(vuip) ((addr << 5) + T2_IO + 0x18);
+}
+
+__EXTERN_INLINE void t2_outl(unsigned int b, unsigned long addr)
+{
+       *(vuip) ((addr << 5) + T2_IO + 0x18) = b;
+       mb();
+}
+
+
+/*
+ * Memory functions.  64-bit and 32-bit accesses are done through
+ * dense memory space, everything else through sparse space.
+ * 
+ * For reading and writing 8 and 16 bit quantities we need to 
+ * go through one of the three sparse address mapping regions
+ * and use the HAE_MEM CSR to provide some bits of the address.
+ * The following few routines use only sparse address region 1
+ * which gives 1Gbyte of accessible space which relates exactly
+ * to the amount of PCI memory mapping *into* system address space.
+ * See p 6-17 of the specification but it looks something like this:
+ *
+ * 21164 Address:
+ * 
+ *          3         2         1                                                               
+ * 9876543210987654321098765432109876543210
+ * 1ZZZZ0.PCI.QW.Address............BBLL                 
+ *
+ * ZZ = SBZ
+ * BB = Byte offset
+ * LL = Transfer length
+ *
+ * PCI Address:
+ *
+ * 3         2         1                                                               
+ * 10987654321098765432109876543210
+ * HHH....PCI.QW.Address........ 00
+ *
+ * HHH = 31:29 HAE_MEM CSR
+ * 
+ */
+
+__EXTERN_INLINE unsigned long t2_srm_base(unsigned long addr)
+{
+       if ((addr >= alpha_mv.sm_base_r1
+            && addr <= alpha_mv.sm_base_r1 + T2_MEM_R1_MASK)
+           || (addr >= 512*1024 && addr < 1024*1024)) {
+               return ((addr & T2_MEM_R1_MASK) << 5) + T2_SPARSE_MEM;
+       }
+#if 0
+       printk("T2: address 0x%lx not covered by HAE\n", addr);
+#endif
+       return 0;
+}
+
+__EXTERN_INLINE unsigned long t2_srm_readb(unsigned long addr)
+{
+       unsigned long result, work;
+
+       if ((work = t2_srm_base(addr)) == 0)
+               return 0xff;
+       work += 0x00;   /* add transfer length */
+
+       result = *(vip) work;
+       return __kernel_extbl(result, addr & 3);
+}
+
+__EXTERN_INLINE unsigned long t2_srm_readw(unsigned long addr)
+{
+       unsigned long result, work;
+
+       if ((work = t2_srm_base(addr)) == 0)
+               return 0xffff;
+       work += 0x08;   /* add transfer length */
+
+       result = *(vip) work;
+       return __kernel_extwl(result, addr & 3);
+}
+
+/* On SABLE with T2, we must use SPARSE memory even for 32-bit access ... */
+__EXTERN_INLINE unsigned long t2_srm_readl(unsigned long addr)
+{
+       unsigned long work;
+
+       if ((work = t2_srm_base(addr)) == 0)
+               return 0xffffffff;
+       work += 0x18;   /* add transfer length */
+
+       return *(vuip) work;
+}
+
+/* ... which makes me wonder why we advertise we have DENSE memory at all.
+   Anyway, guess that means we should emulate 64-bit access as two cycles.  */
+__EXTERN_INLINE unsigned long t2_srm_readq(unsigned long addr)
+{
+       unsigned long work, r0, r1;
+
+       if ((work = t2_srm_base(addr)) == 0)
+               return ~0UL;
+       work += 0x18;   /* add transfer length */
+
+       r0 = *(vuip) work;
+       r1 = *(vuip) (work + (4 << 5));
+       return r1 << 32 | r0;
+}
+
+__EXTERN_INLINE void t2_srm_writeb(unsigned char b, unsigned long addr)
+{
+       unsigned long work = t2_srm_base(addr);
+       if (work) {
+               work += 0x00;   /* add transfer length */
+               *(vuip) work = b * 0x01010101;
+       }
+}
+
+__EXTERN_INLINE void t2_srm_writew(unsigned short b, unsigned long addr)
+{
+       unsigned long work = t2_srm_base(addr);
+       if (work) {
+               work += 0x08;   /* add transfer length */
+               *(vuip) work = b * 0x00010001;
+       }
+}
+
+/* On SABLE with T2, we must use SPARSE memory even for 32-bit access ... */
+__EXTERN_INLINE void t2_srm_writel(unsigned int b, unsigned long addr)
+{
+       unsigned long work = t2_srm_base(addr);
+       if (work) {
+               work += 0x18;   /* add transfer length */
+               *(vuip) work = b;
+       }
+}
+
+/* ... which makes me wonder why we advertise we have DENSE memory at all.
+   Anyway, guess that means we should emulate 64-bit access as two cycles.  */
+__EXTERN_INLINE void t2_srm_writeq(unsigned long b, unsigned long addr)
+{
+       unsigned long work = t2_srm_base(addr);
+       if (work) {
+               work += 0x18;   /* add transfer length */
+               *(vuip) work = b;
+               *(vuip) (work + (4 << 5)) = b >> 32;
+       }
+}
+
+__EXTERN_INLINE unsigned long t2_readb(unsigned long addr)
+{
+       unsigned long result, msb;
+
+       msb = addr & 0xE0000000 ;
+       addr &= T2_MEM_R1_MASK ;
+       set_hae(msb);
+
+       result = *(vip) ((addr << 5) + T2_SPARSE_MEM + 0x00) ;
+       return __kernel_extbl(result, addr & 3);
+}
+
+__EXTERN_INLINE unsigned long t2_readw(unsigned long addr)
+{
+       unsigned long result, msb;
+
+       msb = addr & 0xE0000000 ;
+       addr &= T2_MEM_R1_MASK ;
+       set_hae(msb);
+
+       result = *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x08);
+       return __kernel_extwl(result, addr & 3);
+}
+
+/* On SABLE with T2, we must use SPARSE memory even for 32-bit access. */
+__EXTERN_INLINE unsigned long t2_readl(unsigned long addr)
+{
+       unsigned long msb;
+
+       msb = addr & 0xE0000000 ;
+       addr &= T2_MEM_R1_MASK ;
+       set_hae(msb);
+
+       return *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x18);
+}
+
+__EXTERN_INLINE unsigned long t2_readq(unsigned long addr)
+{
+       unsigned long r0, r1, work, msb;
+
+       msb = addr & 0xE0000000 ;
+       addr &= T2_MEM_R1_MASK ;
+       set_hae(msb);
+
+       work = (addr << 5) + T2_SPARSE_MEM + 0x18;
+       r0 = *(vuip)(work);
+       r1 = *(vuip)(work + (4 << 5));
+       return r1 << 32 | r0;
+}
+
+__EXTERN_INLINE void t2_writeb(unsigned char b, unsigned long addr)
+{
+        unsigned long msb ; 
+
+       msb = addr & 0xE0000000 ;
+       addr &= T2_MEM_R1_MASK ;
+       set_hae(msb);
+
+       *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x00) = b * 0x01010101;
+}
+
+__EXTERN_INLINE void t2_writew(unsigned short b, unsigned long addr)
+{
+        unsigned long msb ; 
+
+       msb = addr & 0xE0000000 ;
+       addr &= T2_MEM_R1_MASK ;
+       set_hae(msb);
+
+       *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x08) = b * 0x00010001;
+}
+
+/* On SABLE with T2, we must use SPARSE memory even for 32-bit access. */
+__EXTERN_INLINE void t2_writel(unsigned int b, unsigned long addr)
+{
+        unsigned long msb ; 
+
+       msb = addr & 0xE0000000 ;
+       addr &= T2_MEM_R1_MASK ;
+       set_hae(msb);
+
+       *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x18) = b;
+}
+
+__EXTERN_INLINE void t2_writeq(unsigned long b, unsigned long addr)
+{
+        unsigned long msb, work;
+
+       msb = addr & 0xE0000000 ;
+       addr &= T2_MEM_R1_MASK ;
+       set_hae(msb);
+
+       work = (addr << 5) + T2_SPARSE_MEM + 0x18;
+       *(vuip)work = b;
+       *(vuip)(work + (4 << 5)) = b >> 32;
+}
+
+/* Find the DENSE memory area for a given bus address.  */
+
+__EXTERN_INLINE unsigned long t2_dense_mem(unsigned long addr)
+{
+       return T2_DENSE_MEM;
+}
+
+#undef vip
+#undef vuip
+
+#ifdef __WANT_IO_DEF
+
+#define virt_to_bus    t2_virt_to_bus
+#define bus_to_virt    t2_bus_to_virt
+#define __inb          t2_inb
+#define __inw          t2_inw
+#define __inl          t2_inl
+#define __outb         t2_outb
+#define __outw         t2_outw
+#define __outl         t2_outl
+
+#ifdef CONFIG_ALPHA_SRM_SETUP
+#define __readb                t2_srm_readb
+#define __readw                t2_srm_readw
+#define __readl                t2_srm_readl
+#define __readq                t2_srm_readq
+#define __writeb       t2_srm_writeb
+#define __writew       t2_srm_writew
+#define __writel       t2_srm_writel
+#define __writeq       t2_srm_writeq
+#else
+#define __readb                t2_readb
+#define __readw                t2_readw
+#define __readl                t2_readl
+#define __readq                t2_readq
+#define __writeb       t2_writeb
+#define __writew       t2_writew
+#define __writel       t2_writel
+#define __writeq       t2_writeq
+#endif
+
+#define dense_mem      t2_dense_mem
+
+#define inb(port) \
+(__builtin_constant_p((port))?__inb(port):_inb(port))
+
+#define outb(x, port) \
+(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port)))
+
+#endif /* __WANT_IO_DEF */
+
+#ifdef __IO_EXTERN_INLINE
+#undef __EXTERN_INLINE
+#undef __IO_EXTERN_INLINE
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* __ALPHA_T2__H__ */
diff --git a/include/asm-alpha/core_tsunami.h b/include/asm-alpha/core_tsunami.h
new file mode 100644 (file)
index 0000000..5da9c08
--- /dev/null
@@ -0,0 +1,478 @@
+#ifndef __ALPHA_TSUNAMI__H__
+#define __ALPHA_TSUNAMI__H__
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/compiler.h>
+
+/*
+ * TSUNAMI/TYPHOON are the internal names for the core logic chipset which
+ * provides memory controller and PCI access for the 21264 based systems.
+ *
+ * This file is based on:
+ *
+ * Tsunami System Programmers Manual
+ * Preliminary, Chapters 2-5
+ *
+ */
+
+#define TSUNAMI_DMA_WIN_BASE_DEFAULT    (1024*1024*1024)
+#define TSUNAMI_DMA_WIN_SIZE_DEFAULT    (1024*1024*1024)
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
+#define TSUNAMI_DMA_WIN_BASE           alpha_mv.dma_win_base
+#define TSUNAMI_DMA_WIN_SIZE           alpha_mv.dma_win_size
+#else
+#define TSUNAMI_DMA_WIN_BASE           TSUNAMI_DMA_WIN_BASE_DEFAULT
+#define TSUNAMI_DMA_WIN_SIZE           TSUNAMI_DMA_WIN_SIZE_DEFAULT
+#endif
+
+/* XXX: Do we need to conditionalize on this?  */
+#ifdef USE_48_BIT_KSEG
+#define TS_BIAS 0x80000000000UL
+#else
+#define TS_BIAS 0x10000000000UL
+#endif
+
+/*
+ * CChip and DChip registers
+ */
+#define        TSUNAMI_CSR_CSC         (IDENT_ADDR + TS_BIAS + 0x1A0000000UL)
+#define        TSUNAMI_CSR_MTR         (IDENT_ADDR + TS_BIAS + 0x1A0000040UL)
+#define        TSUNAMI_CSR_MISC        (IDENT_ADDR + TS_BIAS + 0x1A0000080UL)
+#define        TSUNAMI_CSR_MPD         (IDENT_ADDR + TS_BIAS + 0x1A00000C0UL)
+#define        TSUNAMI_CSR_AAR0        (IDENT_ADDR + TS_BIAS + 0x1A0000100UL)
+#define        TSUNAMI_CSR_AAR1        (IDENT_ADDR + TS_BIAS + 0x1A0000140UL)
+#define        TSUNAMI_CSR_AAR2        (IDENT_ADDR + TS_BIAS + 0x1A0000180UL)
+#define        TSUNAMI_CSR_AAR3        (IDENT_ADDR + TS_BIAS + 0x1A00001C0UL)
+#define        TSUNAMI_CSR_DIM0        (IDENT_ADDR + TS_BIAS + 0x1A0000200UL)
+#define        TSUNAMI_CSR_DIM1        (IDENT_ADDR + TS_BIAS + 0x1A0000240UL)
+#define        TSUNAMI_CSR_DIR0        (IDENT_ADDR + TS_BIAS + 0x1A0000280UL)
+#define        TSUNAMI_CSR_DIR1        (IDENT_ADDR + TS_BIAS + 0x1A00002C0UL)
+
+#define        TSUNAMI_CSR_DRIR        (IDENT_ADDR + TS_BIAS + 0x1A0000300UL)
+#define        TSUNAMI_CSR_PRBEN       (IDENT_ADDR + TS_BIAS + 0x1A0000340UL)
+#define        TSUNAMI_CSR_IIC         (IDENT_ADDR + TS_BIAS + 0x1A0000380UL)
+#define        TSUNAMI_CSR_WDR         (IDENT_ADDR + TS_BIAS + 0x1A00003C0UL)
+#define        TSUNAMI_CSR_MPR0        (IDENT_ADDR + TS_BIAS + 0x1A0000400UL)
+#define        TSUNAMI_CSR_MPR1        (IDENT_ADDR + TS_BIAS + 0x1A0000440UL)
+#define        TSUNAMI_CSR_MPR2        (IDENT_ADDR + TS_BIAS + 0x1A0000480UL)
+#define        TSUNAMI_CSR_MPR3        (IDENT_ADDR + TS_BIAS + 0x1A00004C0UL)
+#define        TSUNAMI_CSR_TTR         (IDENT_ADDR + TS_BIAS + 0x1A0000580UL)
+#define        TSUNAMI_CSR_TDR         (IDENT_ADDR + TS_BIAS + 0x1A00005C0UL)
+#define        TSUNAMI_CSR_DSC         (IDENT_ADDR + TS_BIAS + 0x1B0000800UL)
+#define        TSUNAMI_CSR_STR         (IDENT_ADDR + TS_BIAS + 0x1B0000840UL)
+#define        TSUNAMI_CSR_DREV        (IDENT_ADDR + TS_BIAS + 0x1B0000880UL)
+
+/*
+ * PChip registers
+ */
+#define        TSUNAMI_PCHIP0_WSBA0    (IDENT_ADDR + TS_BIAS + 0x180000000UL)
+#define        TSUNAMI_PCHIP0_WSBA1    (IDENT_ADDR + TS_BIAS + 0x180000040UL)
+#define        TSUNAMI_PCHIP0_WSBA2    (IDENT_ADDR + TS_BIAS + 0x180000080UL)
+#define        TSUNAMI_PCHIP0_WSBA3    (IDENT_ADDR + TS_BIAS + 0x1800000C0UL)
+
+#define        TSUNAMI_PCHIP0_WSM0     (IDENT_ADDR + TS_BIAS + 0x180000100UL)
+#define        TSUNAMI_PCHIP0_WSM1     (IDENT_ADDR + TS_BIAS + 0x180000140UL)
+#define        TSUNAMI_PCHIP0_WSM2     (IDENT_ADDR + TS_BIAS + 0x180000180UL)
+#define        TSUNAMI_PCHIP0_WSM3     (IDENT_ADDR + TS_BIAS + 0x1800001C0UL)
+#define        TSUNAMI_PCHIP0_TBA0     (IDENT_ADDR + TS_BIAS + 0x180000200UL)
+#define        TSUNAMI_PCHIP0_TBA1     (IDENT_ADDR + TS_BIAS + 0x180000240UL)
+#define        TSUNAMI_PCHIP0_TBA2     (IDENT_ADDR + TS_BIAS + 0x180000280UL)
+#define        TSUNAMI_PCHIP0_TBA3     (IDENT_ADDR + TS_BIAS + 0x1800002C0UL)
+
+#define        TSUNAMI_PCHIP0_PCTL     (IDENT_ADDR + TS_BIAS + 0x180000300UL)
+#define        TSUNAMI_PCHIP0_PLAT     (IDENT_ADDR + TS_BIAS + 0x180000340UL)
+#define        TSUNAMI_PCHIP0_RESERVED (IDENT_ADDR + TS_BIAS + 0x180000380UL)
+#define        TSUNAMI_PCHIP0_PERROR   (IDENT_ADDR + TS_BIAS + 0x1800003c0UL)
+#define        TSUNAMI_PCHIP0_PERRMASK (IDENT_ADDR + TS_BIAS + 0x180000400UL)
+#define        TSUNAMI_PCHIP0_PERRSET  (IDENT_ADDR + TS_BIAS + 0x180000440UL)
+#define        TSUNAMI_PCHIP0_TLBIV    (IDENT_ADDR + TS_BIAS + 0x180000480UL)
+#define        TSUNAMI_PCHIP0_TLBIA    (IDENT_ADDR + TS_BIAS + 0x1800004C0UL)
+#define        TSUNAMI_PCHIP0_PMONCTL  (IDENT_ADDR + TS_BIAS + 0x180000500UL)
+#define        TSUNAMI_PCHIP0_PMONCNT  (IDENT_ADDR + TS_BIAS + 0x180000540UL)
+
+#define        TSUNAMI_PCHIP1_WSBA0    (IDENT_ADDR + TS_BIAS + 0x380000000UL)
+#define        TSUNAMI_PCHIP1_WSBA1    (IDENT_ADDR + TS_BIAS + 0x380000040UL)
+#define        TSUNAMI_PCHIP1_WSBA2    (IDENT_ADDR + TS_BIAS + 0x380000080UL)
+#define        TSUNAMI_PCHIP1_WSBA3    (IDENT_ADDR + TS_BIAS + 0x3800000C0UL)
+#define        TSUNAMI_PCHIP1_WSM0     (IDENT_ADDR + TS_BIAS + 0x380000100UL)
+#define        TSUNAMI_PCHIP1_WSM1     (IDENT_ADDR + TS_BIAS + 0x380000140UL)
+#define        TSUNAMI_PCHIP1_WSM2     (IDENT_ADDR + TS_BIAS + 0x380000180UL)
+#define        TSUNAMI_PCHIP1_WSM3     (IDENT_ADDR + TS_BIAS + 0x3800001C0UL)
+
+#define        TSUNAMI_PCHIP1_TBA0     (IDENT_ADDR + TS_BIAS + 0x380000200UL)
+#define        TSUNAMI_PCHIP1_TBA1     (IDENT_ADDR + TS_BIAS + 0x380000240UL)
+#define        TSUNAMI_PCHIP1_TBA2     (IDENT_ADDR + TS_BIAS + 0x380000280UL)
+#define        TSUNAMI_PCHIP1_TBA3     (IDENT_ADDR + TS_BIAS + 0x3800002C0UL)
+
+#define        TSUNAMI_PCHIP1_PCTL     (IDENT_ADDR + TS_BIAS + 0x380000300UL)
+#define        TSUNAMI_PCHIP1_PLAT     (IDENT_ADDR + TS_BIAS + 0x380000340UL)
+#define        TSUNAMI_PCHIP1_RESERVED (IDENT_ADDR + TS_BIAS + 0x380000380UL)
+#define        TSUNAMI_PCHIP1_PERROR   (IDENT_ADDR + TS_BIAS + 0x3800003c0UL)
+#define        TSUNAMI_PCHIP1_PERRMASK (IDENT_ADDR + TS_BIAS + 0x380000400UL)
+#define        TSUNAMI_PCHIP1_PERRSET  (IDENT_ADDR + TS_BIAS + 0x380000440UL)
+#define        TSUNAMI_PCHIP1_TLBIV    (IDENT_ADDR + TS_BIAS + 0x380000480UL)
+#define        TSUNAMI_PCHIP1_TLBIA    (IDENT_ADDR + TS_BIAS + 0x3800004C0UL)
+#define        TSUNAMI_PCHIP1_PMONCTL  (IDENT_ADDR + TS_BIAS + 0x380000500UL)
+#define        TSUNAMI_PCHIP1_PMONCNT  (IDENT_ADDR + TS_BIAS + 0x380000540UL)
+
+/*                                                                          */
+/* TSUNAMI Pchip Error register.                                            */
+/*                                                                          */
+#define perror_m_lost 0x1
+#define perror_m_serr 0x2
+#define perror_m_perr 0x4
+#define perror_m_dcrto 0x8
+#define perror_m_sge 0x10
+#define perror_m_ape 0x20
+#define perror_m_ta 0x40
+#define perror_m_rdpe 0x80
+#define perror_m_nds 0x100
+#define perror_m_rto 0x200
+#define perror_m_uecc 0x400
+#define perror_m_cre 0x800
+#define perror_m_addrl 0xFFFFFFFF0000UL
+#define perror_m_addrh 0x7000000000000UL
+#define perror_m_cmd 0xF0000000000000UL
+#define perror_m_syn 0xFF00000000000000UL
+union TPchipPERROR {   
+    struct  {
+        unsigned int perror_v_lost : 1;
+        unsigned perror_v_serr : 1;
+        unsigned perror_v_perr : 1;
+        unsigned perror_v_dcrto : 1;
+        unsigned perror_v_sge : 1;
+        unsigned perror_v_ape : 1;
+        unsigned perror_v_ta : 1;
+        unsigned perror_v_rdpe : 1;
+        unsigned perror_v_nds : 1;
+        unsigned perror_v_rto : 1;
+        unsigned perror_v_uecc : 1;
+        unsigned perror_v_cre : 1;                 
+        unsigned perror_v_rsvd1 : 4;
+        unsigned perror_v_addrl : 32;
+        unsigned perror_v_addrh : 3;
+        unsigned perror_v_rsvd2 : 1;
+        unsigned perror_v_cmd : 4;
+        unsigned perror_v_syn : 8;
+        } perror_r_bits;
+    int perror_q_whole [2];
+    } ;                       
+/*                                                                          */
+/* TSUNAMI Pchip Window Space Base Address register.                        */
+/*                                                                          */
+#define wsba_m_ena 0x1                
+#define wsba_m_sg 0x2
+#define wsba_m_ptp 0x4
+#define wsba_m_addr 0xFFF00000  
+#define wmask_k_sz1gb 0x3FF00000                   
+union TPchipWSBA {
+    struct  {
+        unsigned wsba_v_ena : 1;
+        unsigned wsba_v_sg : 1;
+        unsigned wsba_v_ptp : 1;
+        unsigned wsba_v_rsvd1 : 17;
+        unsigned wsba_v_addr : 12;
+        unsigned wsba_v_rsvd2 : 32;
+        } wsba_r_bits;
+    int wsba_q_whole [2];
+    } ;
+/*                                                                         */
+/* TSUNAMI Pchip Control Register                                          */
+/*                                                                         */
+#define pctl_m_fdsc 0x1
+#define pctl_m_fbtb 0x2
+#define pctl_m_thdis 0x4
+#define pctl_m_chaindis 0x8
+#define pctl_m_tgtlat 0x10
+#define pctl_m_hole 0x20
+#define pctl_m_mwin 0x40
+#define pctl_m_arbena 0x80
+#define pctl_m_prigrp 0x7F00
+#define pctl_m_ppri 0x8000
+#define pctl_m_rsvd1 0x30000
+#define pctl_m_eccen 0x40000
+#define pctl_m_padm 0x80000
+#define pctl_m_cdqmax 0xF00000
+#define pctl_m_rev 0xFF000000
+#define pctl_m_crqmax 0xF00000000UL
+#define pctl_m_ptpmax 0xF000000000UL
+#define pctl_m_pclkx 0x30000000000UL
+#define pctl_m_fdsdis 0x40000000000UL
+#define pctl_m_fdwdis 0x80000000000UL
+#define pctl_m_ptevrfy 0x100000000000UL
+#define pctl_m_rpp 0x200000000000UL
+#define pctl_m_pid 0xC00000000000UL
+#define pctl_m_rsvd2 0xFFFF000000000000UL
+
+union TPchipPCTL {
+    struct {
+       unsigned pctl_v_fdsc : 1;
+       unsigned pctl_v_fbtb : 1;
+       unsigned pctl_v_thdis : 1;
+       unsigned pctl_v_chaindis : 1;
+       unsigned pctl_v_tgtlat : 1;
+       unsigned pctl_v_hole : 1;
+       unsigned pctl_v_mwin : 1;
+       unsigned pctl_v_arbena : 1;
+       unsigned pctl_v_prigrp : 7;
+       unsigned pctl_v_ppri : 1;
+       unsigned pctl_v_rsvd1 : 2;
+       unsigned pctl_v_eccen : 1;
+       unsigned pctl_v_padm : 1;
+       unsigned pctl_v_cdqmax : 4;
+       unsigned pctl_v_rev : 8;
+       unsigned pctl_v_crqmax : 4;
+       unsigned pctl_v_ptpmax : 4;
+       unsigned pctl_v_pclkx : 2;
+       unsigned pctl_v_fdsdis : 1;
+       unsigned pctl_v_fdwdis : 1;
+       unsigned pctl_v_ptevrfy : 1;
+       unsigned pctl_v_rpp : 1;
+       unsigned pctl_v_pid : 2;
+       unsigned pctl_v_rsvd2 : 16;
+       } pctl_r_bits;
+    int pctl_q_whole [2];
+} ;
+/*                                                                          */
+/* TSUNAMI Pchip Error Mask Register.                                       */
+/*                                                                          */
+#define perrmask_m_lost 0x1
+#define perrmask_m_serr 0x2
+#define perrmask_m_perr 0x4
+#define perrmask_m_dcrto 0x8
+#define perrmask_m_sge 0x10
+#define perrmask_m_ape 0x20
+#define perrmask_m_ta 0x40
+#define perrmask_m_rdpe 0x80
+#define perrmask_m_nds 0x100
+#define perrmask_m_rto 0x200
+#define perrmask_m_uecc 0x400
+#define perrmask_m_cre 0x800
+#define perrmask_m_rsvd 0xFFFFFFFFFFFFF000UL
+union TPchipPERRMASK {   
+    struct  {
+        unsigned int perrmask_v_lost : 1;
+        unsigned perrmask_v_serr : 1;
+        unsigned perrmask_v_perr : 1;
+        unsigned perrmask_v_dcrto : 1;
+        unsigned perrmask_v_sge : 1;
+        unsigned perrmask_v_ape : 1;
+        unsigned perrmask_v_ta : 1;
+        unsigned perrmask_v_rdpe : 1;
+        unsigned perrmask_v_nds : 1;
+        unsigned perrmask_v_rto : 1;
+        unsigned perrmask_v_uecc : 1;
+        unsigned perrmask_v_cre : 1;                 
+        unsigned perrmask_v_rsvd1 : 20;
+       unsigned perrmask_v_rsvd2 : 32;
+        } perrmask_r_bits;
+    int perrmask_q_whole [2];
+    } ;                       
+
+/*
+ * Memory spaces:
+ */
+#define TSUNAMI_PCI0_MEM               (IDENT_ADDR + TS_BIAS + 0x000000000UL)
+#define TSUNAMI_PCI0_IACK_SC           (IDENT_ADDR + TS_BIAS + 0x1F8000000UL)
+#define TSUNAMI_PCI0_IO                        (IDENT_ADDR + TS_BIAS + 0x1FC000000UL)
+#define TSUNAMI_PCI0_CONF              (IDENT_ADDR + TS_BIAS + 0x1FE000000UL)
+
+#define TSUNAMI_PCI1_MEM               (IDENT_ADDR + TS_BIAS + 0x200000000UL)
+#define TSUNAMI_PCI1_IACK_SC           (IDENT_ADDR + TS_BIAS + 0x3F8000000UL)
+#define TSUNAMI_PCI1_IO                        (IDENT_ADDR + TS_BIAS + 0x3FC000000UL)
+#define TSUNAMI_PCI1_CONF              (IDENT_ADDR + TS_BIAS + 0x3FE000000UL)
+
+/*
+ * Data structure for handling TSUNAMI machine checks:
+ */
+struct el_TSUNAMI_sysdata_mcheck {
+};
+
+
+#ifdef __KERNEL__
+
+#ifndef __EXTERN_INLINE
+#define __EXTERN_INLINE extern inline
+#define __IO_EXTERN_INLINE
+#endif
+
+/*
+ * Translate physical memory address as seen on (PCI) bus into
+ * a kernel virtual address and vv.
+ */
+__EXTERN_INLINE unsigned long tsunami_virt_to_bus(void * address)
+{
+       return virt_to_phys(address) + TSUNAMI_DMA_WIN_BASE;
+}
+
+__EXTERN_INLINE void * tsunami_bus_to_virt(unsigned long address)
+{
+       return phys_to_virt(address - TSUNAMI_DMA_WIN_BASE);
+}
+
+/*
+ * I/O functions:
+ *
+ * TSUNAMI, the 21??? PCI/memory support chipset for the EV6 (21264)
+ * can only use linear accesses to get at PCI memory and I/O spaces.
+ */
+
+/* HACK ALERT! HACK ALERT! */
+/* HACK ALERT! HACK ALERT! */
+
+/* Only using PCI bus 0 for now in all routines.  */
+
+#define TSUNAMI_IACK_SC  TSUNAMI_PCI0_IACK_SC
+
+/* HACK ALERT! HACK ALERT! */
+/* HACK ALERT! HACK ALERT! */
+
+#define vucp   volatile unsigned char *
+#define vusp   volatile unsigned short *
+#define vuip   volatile unsigned int *
+#define vulp   volatile unsigned long *
+
+__EXTERN_INLINE unsigned int tsunami_inb(unsigned long addr)
+{
+       return __kernel_ldbu(*(vucp)(addr + TSUNAMI_PCI0_IO));
+}
+
+__EXTERN_INLINE void tsunami_outb(unsigned char b, unsigned long addr)
+{
+       __kernel_stb(b, *(vucp)(addr + TSUNAMI_PCI0_IO));
+       mb();
+}
+
+__EXTERN_INLINE unsigned int tsunami_inw(unsigned long addr)
+{
+       return __kernel_ldwu(*(vusp)(addr+TSUNAMI_PCI0_IO));
+}
+
+__EXTERN_INLINE void tsunami_outw(unsigned short b, unsigned long addr)
+{
+       __kernel_stw(b, *(vusp)(addr+TSUNAMI_PCI0_IO));
+       mb();
+}
+
+__EXTERN_INLINE unsigned int tsunami_inl(unsigned long addr)
+{
+       return *(vuip)(addr+TSUNAMI_PCI0_IO);
+}
+
+__EXTERN_INLINE void tsunami_outl(unsigned int b, unsigned long addr)
+{
+       *(vuip)(addr+TSUNAMI_PCI0_IO) = b;
+       mb();
+}
+
+/*
+ * Memory functions.  all accesses are done through linear space.
+ */
+
+__EXTERN_INLINE unsigned long tsunami_readb(unsigned long addr)
+{
+       return __kernel_ldbu(*(vucp)(addr+TSUNAMI_PCI0_MEM));
+}
+
+__EXTERN_INLINE unsigned long tsunami_readw(unsigned long addr)
+{
+       return __kernel_ldwu(*(vusp)(addr+TSUNAMI_PCI0_MEM));
+}
+
+__EXTERN_INLINE unsigned long tsunami_readl(unsigned long addr)
+{
+       return *(vuip)(addr+TSUNAMI_PCI0_MEM);
+}
+
+__EXTERN_INLINE unsigned long tsunami_readq(unsigned long addr)
+{
+       return *(vulp)(addr+TSUNAMI_PCI0_MEM);
+}
+
+__EXTERN_INLINE void tsunami_writeb(unsigned char b, unsigned long addr)
+{
+       __kernel_stb(b, *(vucp)(addr+TSUNAMI_PCI0_MEM));
+       mb();
+}
+
+__EXTERN_INLINE void tsunami_writew(unsigned short b, unsigned long addr)
+{
+       __kernel_stw(b, *(vusp)(addr+TSUNAMI_PCI0_MEM));
+       mb();
+}
+
+__EXTERN_INLINE void tsunami_writel(unsigned int b, unsigned long addr)
+{
+       *(vuip)(addr+TSUNAMI_PCI0_MEM) = b;
+       mb();
+}
+
+__EXTERN_INLINE void tsunami_writeq(unsigned long b, unsigned long addr)
+{
+       *(vulp)(addr+TSUNAMI_PCI0_MEM) = b;
+       mb();
+}
+
+/* Find the DENSE memory area for a given bus address.  */
+
+__EXTERN_INLINE unsigned long tsunami_dense_mem(unsigned long addr)
+{
+       return TSUNAMI_PCI0_MEM;
+}
+
+#undef vucp
+#undef vusp
+#undef vuip
+#undef vulp
+
+#ifdef __WANT_IO_DEF
+
+#define virt_to_bus    tsunami_virt_to_bus
+#define bus_to_virt    tsunami_bus_to_virt
+
+#define __inb          tsunami_inb
+#define __inw          tsunami_inw
+#define __inl          tsunami_inl
+#define __outb         tsunami_outb
+#define __outw         tsunami_outw
+#define __outl         tsunami_outl
+#define __readb                tsunami_readb
+#define __readw                tsunami_readw
+#define __writeb       tsunami_writeb
+#define __writew       tsunami_writew
+#define __readl                tsunami_readl
+#define __readq                tsunami_readq
+#define __writel       tsunami_writel
+#define __writeq       tsunami_writeq
+#define dense_mem      tsunami_dense_mem
+
+#define inb(port) __inb((port))
+#define inw(port) __inw((port))
+#define inl(port) __inl((port))
+
+#define outb(v, port) __outb((v),(port))
+#define outw(v, port) __outw((v),(port))
+#define outl(v, port) __outl((v),(port))
+
+#define readb(a)       __readb((unsigned long)(a))
+#define readw(a)       __readw((unsigned long)(a))
+#define readl(a)       __readl((unsigned long)(a))
+#define readq(a)       __readq((unsigned long)(a))
+
+#define writeb(v,a)    __writeb((v),(unsigned long)(a))
+#define writew(v,a)    __writew((v),(unsigned long)(a))
+#define writel(v,a)    __writel((v),(unsigned long)(a))
+#define writeq(v,a)    __writeq((v),(unsigned long)(a))
+
+#endif /* __WANT_IO_DEF */
+
+#ifdef __IO_EXTERN_INLINE
+#undef __EXTERN_INLINE
+#undef __IO_EXTERN_INLINE
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* __ALPHA_TSUNAMI__H__ */
index 738a15b7677fef99c1e71bda78792f3ca1bbbbc2..69fc00f85b807a0587167831ac282873ee0fc558 100644 (file)
@@ -19,8 +19,7 @@
 #define _ASM_DMA_H
 
 #include <linux/config.h>
-
-#include <asm/io.h>            /* need byte IO */
+#include <asm/io.h>
 
 #define dma_outb       outb
 #define dma_inb                inb
@@ -75,7 +74,6 @@
 
 #define MAX_DMA_CHANNELS       8
 
-#ifdef CONFIG_ALPHA_XL
 /* The maximum address that we can perform a DMA transfer to on Alpha XL,
    due to a hardware SIO (PCI<->ISA bus bridge) chip limitation, is 64MB.
    See <asm/apecs.h> for more info.
    We MUST coordinate the maximum with <asm/apecs.h> for consistency.
    For now, this limit is set to 48Mb...
 */
-#define MAX_DMA_ADDRESS                (0xfffffc0003000000UL)
-#else /* CONFIG_ALPHA_XL */
-/* The maximum address that we can perform a DMA transfer to on normal
-   Alpha platforms */
-#define MAX_DMA_ADDRESS                (~0UL)
-#endif /* CONFIG_ALPHA_XL */
+#define ALPHA_XL_MAX_DMA_ADDRESS       (0xfffffc0003000000UL)
+#define ALPHA_MAX_DMA_ADDRESS          (~0UL)
+
+#ifdef CONFIG_ALPHA_GENERIC
+# define MAX_DMA_ADDRESS               (alpha_mv.max_dma_address)
+#else
+# ifdef CONFIG_ALPHA_XL
+#  define MAX_DMA_ADDRESS              ALPHA_XL_MAX_DMA_ADDRESS
+# else
+#  define MAX_DMA_ADDRESS              ALPHA_MAX_DMA_ADDRESS
+# endif
+#endif
 
 /* 8237 DMA controllers */
 #define IO_DMA1_BASE   0x00    /* 8 bit slave DMA, channels 0..3 */
index 9be100c4fb4c75d4c51ce52b1a527c84ef992f51..d72e85c39dba0114f91f2d7313173d033c2e3380 100644 (file)
@@ -51,13 +51,24 @@ static int FDC2 = -1;
 #define FLOPPY_MOTOR_MASK 0xf0
 
 /*
- * Most Alphas have no problems with floppy DMA crossing 64k borders. Sigh...
+ * Most Alphas have no problems with floppy DMA crossing 64k borders,
+ * except for XL.  It is also the only one with DMA limits, so we use
+ * that to test in the generic kernel.
  */
-#ifdef CONFIG_ALPHA_XL
-#define CROSS_64KB(a,s) \
-    ((unsigned long)(a)/0x10000 != ((unsigned long)(a) + (s) - 1) / 0x10000)
-#else /* CONFIG_ALPHA_XL */
-#define CROSS_64KB(a,s) (0)
-#endif /* CONFIG_ALPHA_XL */
+
+#define __CROSS_64KB(a,s)                                      \
+({ unsigned long __s64 = (unsigned long)(a);                   \
+   unsigned long __e64 = __s64 + (unsigned long)(s) - 1;       \
+   (__s64 ^ __e64) & ~0xfffful; })
+
+#ifdef CONFIG_ALPHA_GENERIC
+# define CROSS_64KB(a,s)   (__CROSS_64KB(a,s) && ~alpha_mv.max_dma_address)
+#else
+# ifdef CONFIG_ALPHA_XL
+#  define CROSS_64KB(a,s)  __CROSS_64KB(a,s)
+# else
+#  define CROSS_64KB(a,s)  (0)
+# endif
+#endif
 
 #endif /* __ASM_ALPHA_FLOPPY_H */
index 6909f0b6bdb449219c6340536520cf7332d9b77c..5aaf9422390b21e378326bbb1e24937baf0b8d86 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _HWRPB_H
-#define _HWRPB_H
+#ifndef __ALPHA_HWRPB_H
+#define __ALPHA_HWRPB_H
 
 #define INIT_HWRPB ((struct hwrpb_struct *) 0x10000000)
 
@@ -34,6 +34,7 @@
 #define ST_DEC_AXPPCI_33        11     /* NoName system type   */
 #define ST_DEC_TLASER           12     /* Turbolaser systype   */
 #define ST_DEC_2100_A50                 13     /* Avanti systype       */
+#define ST_DEC_MUSTANG          14     /* Mustang systype      */
 #define ST_DEC_ALCOR            15     /* Alcor (EV5) systype  */
 #define ST_DEC_1000             17     /* Mikasa systype       */
 #define ST_DEC_EB64             18     /* EB64 systype         */
@@ -92,7 +93,7 @@ struct percpu_struct {
        unsigned long halt_pv;
        unsigned long halt_reason;
        unsigned long res;
-       unsigned long ipc_buffer[21];
+       char ipc_buffer[168];
        unsigned long palcode_avail[16];
        unsigned long compatibility;
 };
@@ -184,4 +185,6 @@ struct hwrpb_struct {
        unsigned long dsr_offset;       /* "Dynamic System Recognition Data Block Table" */
 };
 
-#endif
+extern struct hwrpb_struct *hwrpb;
+
+#endif /* __ALPHA_HWRPB_H */
index 9ce618965c70d54af0db9c63537e355c38a0ac21..7d769dfcd0fc20f93a1c889ed0ba097c9c18536e 100644 (file)
@@ -7,12 +7,6 @@
        __arginit __init; \
        __arginit
 
-#if __GNUC__ >= 2 && __GNUC_MINOR__ >= 8
-#define __initlocaldata  __initdata
-#else
-#define __initlocaldata
-#endif
-
 /* For assembly routines */
 #define __INIT         .section        .text.init,"ax"
 #define __FINIT                .previous
index e65a7308f0cf6f17577e0fa8fb412c8fe736da81..61da10c8e0763f1c66bebf89378400792a4a6e45 100644 (file)
@@ -2,29 +2,17 @@
 #define __ALPHA_IO_H
 
 #include <linux/config.h>
-
 #include <asm/system.h>
+#include <asm/machvec.h>
 
 /* We don't use IO slowdowns on the Alpha, but.. */
 #define __SLOW_DOWN_IO do { } while (0)
 #define SLOW_DOWN_IO   do { } while (0)
 
-/*
- * The hae (hardware address extension) register is used to
- * access high IO addresses. To avoid doing an external cycle
- * every time we need to set the hae, we have a hae cache in
- * memory. The kernel entry code makes sure that the hae is
- * preserved across interrupts, so it is safe to set the hae
- * once and then depend on it staying the same in kernel code.
- */
-extern struct hae {
-       unsigned long   cache;
-       unsigned long   *reg;
-} hae;
-
 /*
  * Virtual -> physical identity mapping starts at this offset
  */
+/* XXX: Do we need to conditionalize on this?  */
 #ifdef USE_48_BIT_KSEG
 #define IDENT_ADDR     (0xffff800000000000UL)
 #else
@@ -40,25 +28,34 @@ extern struct hae {
  * register not being up-to-date with respect to the hardware
  * value.
  */
-extern inline void set_hae(unsigned long new_hae)
+static inline void __set_hae(unsigned long new_hae)
 {
        unsigned long ipl = swpipl(7);
-       hae.cache = new_hae;
-       *hae.reg = new_hae;
+
+       alpha_mv.hae_cache = new_hae;
+       *alpha_mv.hae_register = new_hae;
        mb();
-       new_hae = *hae.reg; /* read to make sure it was written */
+
+       /* Re-read to make sure it was written.  */
+       new_hae = *alpha_mv.hae_register;
        setipl(ipl);
 }
 
+static inline void set_hae(unsigned long new_hae)
+{
+       if (new_hae != alpha_mv.hae_cache)
+               __set_hae(new_hae);
+}
+
 /*
  * Change virtual addresses to physical addresses and vv.
  */
-extern inline unsigned long virt_to_phys(volatile void * address)
+static inline unsigned long virt_to_phys(volatile void * address)
 {
        return 0xffffffffUL & (unsigned long) address;
 }
 
-extern inline void * phys_to_virt(unsigned long address)
+static inline void * phys_to_virt(unsigned long address)
 {
        return (void *) (address + IDENT_ADDR);
 }
@@ -76,45 +73,79 @@ extern void _sethae (unsigned long addr);   /* cached version */
 #endif /* !__KERNEL__ */
 
 /*
- * EGCS 1.1 does a good job of using insxl.  Expose this bit of
- * the I/O process to the compiler.
+ * There are different chipsets to interface the Alpha CPUs to the world.
  */
 
-#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
-# define __kernel_insbl(val, shift)  (((val) & 0xfful) << ((shift) * 8))
-# define __kernel_inswl(val, shift)  (((val) & 0xfffful) << ((shift) * 8))
+#ifdef CONFIG_ALPHA_GENERIC
+
+/* In a generic kernel, we always go through the machine vector.  */
+
+# define virt_to_bus(a)        alpha_mv.mv_virt_to_bus(a)
+# define bus_to_virt(a)        alpha_mv.mv_bus_to_virt(a)
+
+# define __inb         alpha_mv.mv_inb
+# define __inw         alpha_mv.mv_inw
+# define __inl         alpha_mv.mv_inl
+# define __outb                alpha_mv.mv_outb
+# define __outw                alpha_mv.mv_outw
+# define __outl                alpha_mv.mv_outl
+
+# define __readb(a)    alpha_mv.mv_readb((unsigned long)(a))
+# define __readw(a)    alpha_mv.mv_readw((unsigned long)(a))
+# define __readl(a)    alpha_mv.mv_readl((unsigned long)(a))
+# define __readq(a)    alpha_mv.mv_readq((unsigned long)(a))
+# define __writeb(v,a) alpha_mv.mv_writeb((v),(unsigned long)(a))
+# define __writew(v,a) alpha_mv.mv_writew((v),(unsigned long)(a))
+# define __writel(v,a) alpha_mv.mv_writel((v),(unsigned long)(a))
+# define __writeq(v,a) alpha_mv.mv_writeq((v),(unsigned long)(a))
+
+# define inb           __inb
+# define inw           __inw
+# define inl           __inl
+# define outb          __outb
+# define outw          __outw
+# define outl          __outl
+
+# define readb         __readb
+# define readw         __readw
+# define readl         __readl
+# define readq         __readq
+# define writeb                __writeb
+# define writew                __writew
+# define writel                __writel
+# define writeq                __writeq
+
+# define dense_mem(a)  alpha_mv.mv_dense_mem(a)
+
 #else
-# define __kernel_insbl(val, shift)                                    \
-  ({ unsigned long __kir;                                              \
-     __asm__("insbl %2,%1,%0" : "=r"(__kir) : "ri"(shift), "r"(val));  \
-     __kir; })
-# define __kernel_inswl(val, shift)                                    \
-  ({ unsigned long __kir;                                              \
-     __asm__("inswl %2,%1,%0" : "=r"(__kir) : "ri"(shift), "r"(val));  \
-     __kir; })
-#endif
-       
-/*
- * There are different chipsets to interface the Alpha CPUs to the world.
- */
-#if defined(CONFIG_ALPHA_LCA)
-# include <asm/lca.h>          /* get chip-specific definitions */
-#elif defined(CONFIG_ALPHA_APECS)
-# include <asm/apecs.h>                /* get chip-specific definitions */
+
+/* Control how and what gets defined within the core logic headers.  */
+#define __WANT_IO_DEF
+
+#if defined(CONFIG_ALPHA_APECS)
+# include <asm/core_apecs.h>
 #elif defined(CONFIG_ALPHA_CIA)
-# include <asm/cia.h>          /* get chip-specific definitions */
-#elif defined(CONFIG_ALPHA_T2)
-# include <asm/t2.h>           /* get chip-specific definitions */
+# include <asm/core_cia.h>
+#elif defined(CONFIG_ALPHA_LCA)
+# include <asm/core_lca.h>
+#elif defined(CONFIG_ALPHA_MCPCIA)
+# include <asm/core_mcpcia.h>
 #elif defined(CONFIG_ALPHA_PYXIS)
-# include <asm/pyxis.h>                /* get chip-specific definitions */
+# include <asm/core_pyxis.h>
+#elif defined(CONFIG_ALPHA_T2)
+# include <asm/core_t2.h>
 #elif defined(CONFIG_ALPHA_TSUNAMI)
-# include <asm/tsunami.h>      /* get chip-specific definitions */
-#elif defined(CONFIG_ALPHA_MCPCIA)
-# include <asm/mcpcia.h>       /* get chip-specific definitions */
-#else
+# include <asm/core_tsunami.h>
+#elif defined(CONFIG_ALPHA_JENSEN)
 # include <asm/jensen.h>
+#else
+#error "What system is this?"
 #endif
 
+#undef __WANT_IO_DEF
+
+#endif /* GENERIC */
+
 /*
  * The convention used for inb/outb etc. is that names starting with
  * two underscores are the inline versions, names starting with a
@@ -190,12 +221,12 @@ extern void               _writeq(unsigned long b, unsigned long addr);
  * On the alpha, we have the whole physical address space mapped at all
  * times, so "ioremap()" and "iounmap()" do not need to do anything.
  */
-extern inline void * ioremap(unsigned long offset, unsigned long size)
+static inline void * ioremap(unsigned long offset, unsigned long size)
 {
        return (void *) offset;
 } 
 
-extern inline void iounmap(void *addr)
+static inline void iounmap(void *addr)
 {
 }
 
@@ -263,8 +294,9 @@ extern void outsl (unsigned long port, const void *src, unsigned long count);
 #define eth_io_copy_and_sum(skb,src,len,unused) \
   memcpy_fromio((skb)->data,(src),(len))
 
-static inline int check_signature(unsigned long io_addr,
-       const unsigned char *signature, int length)
+static inline int
+check_signature(unsigned long io_addr, const unsigned char *signature,
+               int length)
 {
        int retval = 0;
        do {
@@ -279,6 +311,29 @@ out:
        return retval;
 }
 
-#endif /* __KERNEL__ */
+/*
+ * The Alpha Jensen hardware for some rather strange reason puts
+ * the RTC clock at 0x170 instead of 0x70. Probably due to some
+ * misguided idea about using 0x70 for NMI stuff.
+ *
+ * These defines will override the defaults when doing RTC queries
+ */
 
+#ifdef CONFIG_ALPHA_GENERIC
+# define RTC_PORT(x)   ((x) + alpha_mv.rtc_port)
+# define RTC_ADDR(x)   ((x) | alpha_mv.rtc_addr)
+#else
+# ifdef CONFIG_ALPHA_JENSEN
+#  define RTC_PORT(x)  (0x170+(x))
+#  define RTC_ADDR(x)  (x)
+# else
+#  define RTC_PORT(x)  (0x70 + (x))
+#  define RTC_ADDR(x)  (0x80 | (x))
+# endif
 #endif
+
+#define RTC_ALWAYS_BCD 0
+
+#endif /* __KERNEL__ */
+
+#endif /* __ALPHA_IO_H */
index 7140a14370203e2fba7acf96f543fa52e68c044b..7f8853c5584c98be71b5a865614cadfa2755fe84 100644 (file)
 #include <linux/linkage.h>
 #include <linux/config.h>
 
-#if   defined(CONFIG_ALPHA_CABRIOLET) || \
+#if   defined(CONFIG_ALPHA_GENERIC)
+
+/* Here NR_IRQS is not exact, but rather an upper bound.  This is used
+   many places throughout the kernel to size static arrays.  That's ok,
+   we'll use alpha_mv.nr_irqs when we want the real thing.  */
+
+# define NR_IRQS       64
+
+#elif defined(CONFIG_ALPHA_CABRIOLET) || \
       defined(CONFIG_ALPHA_EB66P)     || \
       defined(CONFIG_ALPHA_EB164)     || \
       defined(CONFIG_ALPHA_PC164)     || \
-       defined(CONFIG_ALPHA_LX164)
-
+      defined(CONFIG_ALPHA_LX164)
 # define NR_IRQS       35
 
 #elif defined(CONFIG_ALPHA_EB66)      || \
       defined(CONFIG_ALPHA_EB64P)     || \
-       defined(CONFIG_ALPHA_MIKASA)
-
+      defined(CONFIG_ALPHA_MIKASA)
 # define NR_IRQS       32
 
 #elif defined(CONFIG_ALPHA_ALCOR)     || \
       defined(CONFIG_ALPHA_MIATA)     || \
       defined(CONFIG_ALPHA_RUFFIAN)   || \
       defined(CONFIG_ALPHA_NORITAKE)
-
 # define NR_IRQS       48
 
 #elif defined(CONFIG_ALPHA_SABLE)     || \
       defined(CONFIG_ALPHA_SX164)
-
 # define NR_IRQS       40
 
 #elif defined(CONFIG_ALPHA_DP264) || \
       defined(CONFIG_ALPHA_RAWHIDE)
-
 # define NR_IRQS       64
 
 #elif defined(CONFIG_ALPHA_TAKARA)
-
 # define NR_IRQS       20
 
 #else /* everyone else */
-
 # define NR_IRQS       16
+#endif
+
+/*
+ * PROBE_MASK is the bitset of irqs that we consider for autoprobing.
+ */
+
+/* The normal mask includes all the IRQs except the timer.  */
+#define _PROBE_MASK(nr_irqs)   (((1UL << (nr_irqs & 63)) - 1) & ~1UL)
 
+/* Mask out unused timer irq 0 and RTC irq 8. */
+#define P2K_PROBE_MASK         (_PROBE_MASK(16) & ~0x101UL)
+
+/* Mask out unused timer irq 0, "irqs" 20-30, and the EISA cascade. */
+#define ALCOR_PROBE_MASK       (_PROBE_MASK(48) & ~0xfff000000001UL)
+
+/* Leave timer irq 0 in the mask.  */
+#define RUFFIAN_PROBE_MASK     (_PROBE_MASK(48) | 1UL)
+
+#if defined(CONFIG_ALPHA_GENERIC)
+# define PROBE_MASK    alpha_mv.irq_probe_mask
+#elif defined(CONFIG_ALPHA_P2K)
+# define PROBE_MASK    P2K_PROBE_MASK
+#elif defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
+# define PROBE_MASK    ALCOR_PROBE_MASK
+#elif defined(CONFIG_ALPHA_RUFFIAN)
+# define PROBE_MASK    RUFFIAN_PROBE_MASK
+#else
+# define PROBE_MASK    _PROBE_MASK(NR_IRQS)
 #endif
 
+
 static __inline__ int irq_cannonicalize(int irq)
 {
        /*
@@ -64,4 +93,4 @@ static __inline__ int irq_cannonicalize(int irq)
 extern void disable_irq(unsigned int);
 extern void enable_irq(unsigned int);
 
-#endif
+#endif /* _ALPHA_IRQ_H */
index ff0ad54b5886e4a8f795e677c72a0af27af0f090..75f99ea3326175bd8a453716c33ede60cb88778b 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef __ALPHA_JENSEN_H
 #define __ALPHA_JENSEN_H
 
+#include <asm/compiler.h>
+
 /*
  * Defines for the AlphaPC EISA IO and memory address space.
  */
  */
 #define EISA_IO                        (IDENT_ADDR + 0x300000000UL)
 
+
+#ifdef __KERNEL__
+
+#ifndef __EXTERN_INLINE
+#define __EXTERN_INLINE extern inline
+#define __IO_EXTERN_INLINE
+#endif
+
 /*
  * Change virtual addresses to bus addresses and vv.
  *
  * as the bus address, but this is not necessarily true on
  * other alpha hardware.
  */
-#define virt_to_bus virt_to_phys
-#define bus_to_virt phys_to_virt
+__EXTERN_INLINE unsigned long jensen_virt_to_bus(void * address)
+{
+       return virt_to_phys(address);
+}
+
+__EXTERN_INLINE void * jensen_bus_to_virt(unsigned long address)
+{
+       return phys_to_virt(address);
+}
 
-#define HAE_ADDRESS    EISA_HAE
 
 /*
  * Handle the "host address register". This needs to be set
  *
  * HAE isn't needed for the local IO operations, though.
  */
-#define __HAE_MASK 0x1ffffff
-extern inline void __set_hae(unsigned long addr)
+
+#define JENSEN_HAE_ADDRESS     EISA_HAE
+#define JENSEN_HAE_MASK                0x1ffffff
+
+__EXTERN_INLINE void jensen_set_hae(unsigned long addr)
 {
        /* hae on the Jensen is bits 31:25 shifted right */
        addr >>= 25;
-       if (addr != hae.cache)
+       if (addr != alpha_mv.hae_cache)
                set_hae(addr);
 }
 
-#ifdef __KERNEL__
+#define vuip   volatile unsigned int *
 
 /*
  * IO functions
@@ -108,36 +127,31 @@ extern inline void __set_hae(unsigned long addr)
  * gone in the PCI version. I hope I can get DEC suckered^H^H^H^H^H^H^H^H
  * convinced that I need one of the newer machines.
  */
-extern inline unsigned int __local_inb(unsigned long addr)
+
+static inline unsigned int jensen_local_inb(unsigned long addr)
 {
-       long result = *(volatile int *) ((addr << 9) + EISA_VL82C106);
-       return 0xffUL & result;
+       return 0xff & *(vuip)((addr << 9) + EISA_VL82C106);
 }
 
-extern inline void __local_outb(unsigned char b, unsigned long addr)
+static inline void jensen_local_outb(unsigned char b, unsigned long addr)
 {
-       *(volatile unsigned int *) ((addr << 9) + EISA_VL82C106) = b;
+       *(vuip)((addr << 9) + EISA_VL82C106) = b;
        mb();
 }
 
-extern unsigned int _bus_inb(unsigned long addr);
-
-extern inline unsigned int __bus_inb(unsigned long addr)
+static inline unsigned int jensen_bus_inb(unsigned long addr)
 {
        long result;
 
-       __set_hae(0);
-       result = *(volatile int *) ((addr << 7) + EISA_IO + 0x00);
-       result >>= (addr & 3) * 8;
-       return 0xffUL & result;
+       jensen_set_hae(0);
+       result = *(volatile int *)((addr << 7) + EISA_IO + 0x00);
+       return __kernel_extbl(result, addr & 3);
 }
 
-extern void _bus_outb(unsigned char b, unsigned long addr);
-
-extern inline void __bus_outb(unsigned char b, unsigned long addr)
+static inline void jensen_bus_outb(unsigned char b, unsigned long addr)
 {
-       __set_hae(0);
-       *(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x00) = b * 0x01010101;
+       jensen_set_hae(0);
+       *(vuip)((addr << 7) + EISA_IO + 0x00) = b * 0x01010101;
        mb();
 }
 
@@ -146,131 +160,165 @@ extern inline void __bus_outb(unsigned char b, unsigned long addr)
  * operations that result in operations across inline functions.
  * Which is why this is a macro.
  */
-#define __is_local(addr) ( \
+
+#define jensen_is_local(addr) ( \
 /* keyboard */ (addr == 0x60 || addr == 0x64) || \
 /* RTC */      (addr == 0x170 || addr == 0x171) || \
 /* mb COM2 */  (addr >= 0x2f8 && addr <= 0x2ff) || \
 /* mb LPT1 */  (addr >= 0x3bc && addr <= 0x3be) || \
 /* mb COM2 */  (addr >= 0x3f8 && addr <= 0x3ff))
 
-extern inline unsigned int __inb(unsigned long addr)
+__EXTERN_INLINE unsigned int jensen_inb(unsigned long addr)
 {
-       if (__is_local(addr))
-               return __local_inb(addr);
-       return _bus_inb(addr);
+       if (jensen_is_local(addr))
+               return jensen_local_inb(addr);
+       else
+               return jensen_bus_inb(addr);
 }
 
-extern inline void __outb(unsigned char b, unsigned long addr)
+__EXTERN_INLINE void jensen_outb(unsigned char b, unsigned long addr)
 {
-       if (__is_local(addr))
-               __local_outb(b, addr);
+       if (jensen_is_local(addr))
+               jensen_local_outb(b, addr);
        else
-               _bus_outb(b, addr);
+               jensen_bus_outb(b, addr);
 }
 
-extern inline unsigned int __inw(unsigned long addr)
+__EXTERN_INLINE unsigned int jensen_inw(unsigned long addr)
 {
        long result;
 
-       __set_hae(0);
+       jensen_set_hae(0);
        result = *(volatile int *) ((addr << 7) + EISA_IO + 0x20);
        result >>= (addr & 3) * 8;
        return 0xffffUL & result;
 }
 
-extern inline unsigned int __inl(unsigned long addr)
+__EXTERN_INLINE unsigned int jensen_inl(unsigned long addr)
 {
-       __set_hae(0);
-       return *(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x60);
+       jensen_set_hae(0);
+       return *(vuip) ((addr << 7) + EISA_IO + 0x60);
 }
 
-extern inline void __outw(unsigned short b, unsigned long addr)
+__EXTERN_INLINE void jensen_outw(unsigned short b, unsigned long addr)
 {
-       __set_hae(0);
-       *(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x20) = b * 0x00010001;
+       jensen_set_hae(0);
+       *(vuip) ((addr << 7) + EISA_IO + 0x20) = b * 0x00010001;
        mb();
 }
 
-extern inline void __outl(unsigned int b, unsigned long addr)
+__EXTERN_INLINE void jensen_outl(unsigned int b, unsigned long addr)
 {
-       __set_hae(0);
-       *(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x60) = b;
+       jensen_set_hae(0);
+       *(vuip) ((addr << 7) + EISA_IO + 0x60) = b;
        mb();
 }
 
 /*
  * Memory functions.
  */
-extern inline unsigned long __readb(unsigned long addr)
+
+__EXTERN_INLINE unsigned long jensen_readb(unsigned long addr)
 {
        long result;
 
-       __set_hae(addr);
-       addr &= __HAE_MASK;
+       jensen_set_hae(addr);
+       addr &= JENSEN_HAE_MASK;
        result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x00);
        result >>= (addr & 3) * 8;
        return 0xffUL & result;
 }
 
-extern inline unsigned long __readw(unsigned long addr)
+__EXTERN_INLINE unsigned long jensen_readw(unsigned long addr)
 {
        long result;
 
-       __set_hae(addr);
-       addr &= __HAE_MASK;
+       jensen_set_hae(addr);
+       addr &= JENSEN_HAE_MASK;
        result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x20);
        result >>= (addr & 3) * 8;
        return 0xffffUL & result;
 }
 
-extern inline unsigned long __readl(unsigned long addr)
+__EXTERN_INLINE unsigned long jensen_readl(unsigned long addr)
 {
-       __set_hae(addr);
-       addr &= __HAE_MASK;
-       return *(volatile unsigned int *) ((addr << 7) + EISA_MEM + 0x60);
+       jensen_set_hae(addr);
+       addr &= JENSEN_HAE_MASK;
+       return *(vuip) ((addr << 7) + EISA_MEM + 0x60);
 }
 
-extern inline unsigned long __readq(unsigned long addr)
+__EXTERN_INLINE unsigned long jensen_readq(unsigned long addr)
 {
        unsigned long r0, r1;
-       __set_hae(addr);
-       addr &= __HAE_MASK;
+
+       jensen_set_hae(addr);
+       addr &= JENSEN_HAE_MASK;
        addr = (addr << 7) + EISA_MEM + 0x60;
-       r0 = *(volatile unsigned int *) (addr);
-       r1 = *(volatile unsigned int *) (addr + (4 << 7));
+       r0 = *(vuip) (addr);
+       r1 = *(vuip) (addr + (4 << 7));
        return r1 << 32 | r0;
 }
 
-extern inline void __writeb(unsigned short b, unsigned long addr)
+__EXTERN_INLINE void jensen_writeb(unsigned char b, unsigned long addr)
 {
-       __set_hae(addr);
-       addr &= __HAE_MASK;
-       *(volatile unsigned int *) ((addr << 7) + EISA_MEM + 0x00) = b * 0x01010101;
+       jensen_set_hae(addr);
+       addr &= JENSEN_HAE_MASK;
+       *(vuip) ((addr << 7) + EISA_MEM + 0x00) = b * 0x01010101;
 }
 
-extern inline void __writew(unsigned short b, unsigned long addr)
+__EXTERN_INLINE void jensen_writew(unsigned short b, unsigned long addr)
 {
-       __set_hae(addr);
-       addr &= __HAE_MASK;
-       *(volatile unsigned int *) ((addr << 7) + EISA_MEM + 0x20) = b * 0x00010001;
+       jensen_set_hae(addr);
+       addr &= JENSEN_HAE_MASK;
+       *(vuip) ((addr << 7) + EISA_MEM + 0x20) = b * 0x00010001;
 }
 
-extern inline void __writel(unsigned int b, unsigned long addr)
+__EXTERN_INLINE void jensen_writel(unsigned int b, unsigned long addr)
 {
-       __set_hae(addr);
-       addr &= __HAE_MASK;
-       *(volatile unsigned int *) ((addr << 7) + EISA_MEM + 0x60) = b;
+       jensen_set_hae(addr);
+       addr &= JENSEN_HAE_MASK;
+       *(vuip) ((addr << 7) + EISA_MEM + 0x60) = b;
 }
 
-extern inline void __writeq(unsigned long b, unsigned long addr)
+__EXTERN_INLINE void jensen_writeq(unsigned long b, unsigned long addr)
 {
-       __set_hae(addr);
-       addr &= __HAE_MASK;
+       jensen_set_hae(addr);
+       addr &= JENSEN_HAE_MASK;
        addr = (addr << 7) + EISA_MEM + 0x60;
-       *(volatile unsigned int *) (addr) = b;
-       *(volatile unsigned int *) (addr + (4 << 7)) = b >> 32;
+       *(vuip) (addr) = b;
+       *(vuip) (addr + (4 << 7)) = b >> 32;
+}
+
+/* Find the DENSE memory area for a given bus address.
+   Whee, there is none.  */
+
+__EXTERN_INLINE unsigned long jensen_dense_mem(unsigned long addr)
+{
+       return 0;
 }
 
+#undef vuip
+
+#ifdef __WANT_IO_DEF
+
+#define virt_to_bus    jensen_virt_to_bus
+#define bus_to_virt    jensen_bus_to_virt
+#define __inb          jensen_inb
+#define __inw          jensen_inw
+#define __inl          jensen_inl
+#define __outb         jensen_outb
+#define __outw         jensen_outw
+#define __outl         jensen_outl
+#define __readb                jensen_readb
+#define __readw                jensen_readw
+#define __writeb       jensen_writeb
+#define __writew       jensen_writew
+#define __readl                jensen_readl
+#define __readq                jensen_readq
+#define __writel       jensen_writel
+#define __writeq       jensen_writeq
+#define dense_mem      jensen_dense_mem
+
 /*
  * The above have so much overhead that it probably doesn't make
  * sense to have them inlined (better icache behaviour).
@@ -281,17 +329,13 @@ extern inline void __writeq(unsigned long b, unsigned long addr)
 #define outb(x, port) \
 (__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port)))
 
-#endif /* __KERNEL__ */
-
-/*
- * The Alpha Jensen hardware for some rather strange reason puts
- * the RTC clock at 0x170 instead of 0x70. Probably due to some
- * misguided idea about using 0x70 for NMI stuff.
- *
- * These defines will override the defaults when doing RTC queries
- */
-#define RTC_PORT(x)    (0x170+(x))
-#define RTC_ADDR(x)    (x)
-#define RTC_ALWAYS_BCD 0
+#endif /* __WANT_IO_DEF */
 
+#ifdef __IO_EXTERN_INLINE
+#undef __EXTERN_INLINE
+#undef __IO_EXTERN_INLINE
 #endif
+
+#endif /* __KERNEL__ */
+
+#endif /* __ALPHA_JENSEN_H */
diff --git a/include/asm-alpha/lca.h b/include/asm-alpha/lca.h
deleted file mode 100644 (file)
index 7eb85b8..0000000
+++ /dev/null
@@ -1,414 +0,0 @@
-#ifndef __ALPHA_LCA__H__
-#define __ALPHA_LCA__H__
-
-/*
- * Low Cost Alpha (LCA) definitions (these apply to 21066 and 21068,
- * for example).
- *
- * This file is based on:
- *
- *     DECchip 21066 and DECchip 21068 Alpha AXP Microprocessors
- *     Hardware Reference Manual; Digital Equipment Corp.; May 1994;
- *     Maynard, MA; Order Number: EC-N2681-71.
- */
-
-/*
- * NOTE: The LCA uses a Host Address Extension (HAE) register to access
- *      PCI addresses that are beyond the first 27 bits of address
- *      space.  Updating the HAE requires an external cycle (and
- *      a memory barrier), which tends to be slow.  Instead of updating
- *      it on each sparse memory access, we keep the current HAE value
- *      cached in variable cache_hae.  Only if the cached HAE differs
- *      from the desired HAE value do we actually updated HAE register.
- *      The HAE register is preserved by the interrupt handler entry/exit
- *      code, so this scheme works even in the presence of interrupts.
- *
- * Dense memory space doesn't require the HAE, but is restricted to
- * aligned 32 and 64 bit accesses.  Special Cycle and Interrupt
- * Acknowledge cycles may also require the use of the HAE.  The LCA
- * limits I/O address space to the bottom 24 bits of address space,
- * but this easily covers the 16 bit ISA I/O address space.
- */
-
-/*
- * NOTE 2! The memory operations do not set any memory barriers, as
- * it's not needed for cases like a frame buffer that is essentially
- * memory-like.  You need to do them by hand if the operations depend
- * on ordering.
- *
- * Similarly, the port I/O operations do a "mb" only after a write
- * operation: if an mb is needed before (as in the case of doing
- * memory mapped I/O first, and then a port I/O operation to the same
- * device), it needs to be done by hand.
- *
- * After the above has bitten me 100 times, I'll give up and just do
- * the mb all the time, but right now I'm hoping this will work out.
- * Avoiding mb's may potentially be a noticeable speed improvement,
- * but I can't honestly say I've tested it.
- *
- * Handling interrupts that need to do mb's to synchronize to
- * non-interrupts is another fun race area.  Don't do it (because if
- * you do, I'll have to do *everything* with interrupts disabled,
- * ugh).
- */
-
-#include <linux/config.h>
-#include <asm/system.h>
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-/* if we are using the SRM PCI setup, we'll need to use variables instead */
-#define LCA_DMA_WIN_BASE_DEFAULT    (1024*1024*1024)
-#define LCA_DMA_WIN_SIZE_DEFAULT    (1024*1024*1024)
-
-extern unsigned int LCA_DMA_WIN_BASE;
-extern unsigned int LCA_DMA_WIN_SIZE;
-
-#else /* SRM_SETUP */
-#define LCA_DMA_WIN_BASE       (1024*1024*1024)
-#define LCA_DMA_WIN_SIZE       (1024*1024*1024)
-#endif /* SRM_SETUP */
-
-/*
- * Memory Controller registers:
- */
-#define LCA_MEM_BCR0           (IDENT_ADDR + 0x120000000UL)
-#define LCA_MEM_BCR1           (IDENT_ADDR + 0x120000008UL)
-#define LCA_MEM_BCR2           (IDENT_ADDR + 0x120000010UL)
-#define LCA_MEM_BCR3           (IDENT_ADDR + 0x120000018UL)
-#define LCA_MEM_BMR0           (IDENT_ADDR + 0x120000020UL)
-#define LCA_MEM_BMR1           (IDENT_ADDR + 0x120000028UL)
-#define LCA_MEM_BMR2           (IDENT_ADDR + 0x120000030UL)
-#define LCA_MEM_BMR3           (IDENT_ADDR + 0x120000038UL)
-#define LCA_MEM_BTR0           (IDENT_ADDR + 0x120000040UL)
-#define LCA_MEM_BTR1           (IDENT_ADDR + 0x120000048UL)
-#define LCA_MEM_BTR2           (IDENT_ADDR + 0x120000050UL)
-#define LCA_MEM_BTR3           (IDENT_ADDR + 0x120000058UL)
-#define LCA_MEM_GTR            (IDENT_ADDR + 0x120000060UL)
-#define LCA_MEM_ESR            (IDENT_ADDR + 0x120000068UL)
-#define LCA_MEM_EAR            (IDENT_ADDR + 0x120000070UL)
-#define LCA_MEM_CAR            (IDENT_ADDR + 0x120000078UL)
-#define LCA_MEM_VGR            (IDENT_ADDR + 0x120000080UL)
-#define LCA_MEM_PLM            (IDENT_ADDR + 0x120000088UL)
-#define LCA_MEM_FOR            (IDENT_ADDR + 0x120000090UL)
-
-/*
- * I/O Controller registers:
- */
-#define LCA_IOC_HAE            (IDENT_ADDR + 0x180000000UL)
-#define LCA_IOC_CONF           (IDENT_ADDR + 0x180000020UL)
-#define LCA_IOC_STAT0          (IDENT_ADDR + 0x180000040UL)
-#define LCA_IOC_STAT1          (IDENT_ADDR + 0x180000060UL)
-#define LCA_IOC_TBIA           (IDENT_ADDR + 0x180000080UL)
-#define LCA_IOC_TB_ENA         (IDENT_ADDR + 0x1800000a0UL)
-#define LCA_IOC_SFT_RST                (IDENT_ADDR + 0x1800000c0UL)
-#define LCA_IOC_PAR_DIS                (IDENT_ADDR + 0x1800000e0UL)
-#define LCA_IOC_W_BASE0                (IDENT_ADDR + 0x180000100UL)
-#define LCA_IOC_W_BASE1                (IDENT_ADDR + 0x180000120UL)
-#define LCA_IOC_W_MASK0                (IDENT_ADDR + 0x180000140UL)
-#define LCA_IOC_W_MASK1                (IDENT_ADDR + 0x180000160UL)
-#define LCA_IOC_T_BASE0                (IDENT_ADDR + 0x180000180UL)
-#define LCA_IOC_T_BASE1                (IDENT_ADDR + 0x1800001a0UL)
-#define LCA_IOC_TB_TAG0                (IDENT_ADDR + 0x188000000UL)
-#define LCA_IOC_TB_TAG1                (IDENT_ADDR + 0x188000020UL)
-#define LCA_IOC_TB_TAG2                (IDENT_ADDR + 0x188000040UL)
-#define LCA_IOC_TB_TAG3                (IDENT_ADDR + 0x188000060UL)
-#define LCA_IOC_TB_TAG4                (IDENT_ADDR + 0x188000070UL)
-#define LCA_IOC_TB_TAG5                (IDENT_ADDR + 0x1880000a0UL)
-#define LCA_IOC_TB_TAG6                (IDENT_ADDR + 0x1880000c0UL)
-#define LCA_IOC_TB_TAG7                (IDENT_ADDR + 0x1880000e0UL)
-
-/*
- * Memory spaces:
- */
-#define LCA_IACK_SC            (IDENT_ADDR + 0x1a0000000UL)
-#define LCA_CONF               (IDENT_ADDR + 0x1e0000000UL)
-#define LCA_IO                 (IDENT_ADDR + 0x1c0000000UL)
-#define LCA_SPARSE_MEM         (IDENT_ADDR + 0x200000000UL)
-#define LCA_DENSE_MEM          (IDENT_ADDR + 0x300000000UL)
-#define DENSE_MEM(addr)                LCA_DENSE_MEM
-
-/*
- * Bit definitions for I/O Controller status register 0:
- */
-#define LCA_IOC_STAT0_CMD              0xf
-#define LCA_IOC_STAT0_ERR              (1<<4)
-#define LCA_IOC_STAT0_LOST             (1<<5)
-#define LCA_IOC_STAT0_THIT             (1<<6)
-#define LCA_IOC_STAT0_TREF             (1<<7)
-#define LCA_IOC_STAT0_CODE_SHIFT       8
-#define LCA_IOC_STAT0_CODE_MASK                0x7
-#define LCA_IOC_STAT0_P_NBR_SHIFT      13
-#define LCA_IOC_STAT0_P_NBR_MASK       0x7ffff
-
-#define HAE_ADDRESS    LCA_IOC_HAE
-
-/* LCA PMR Power Management register defines */
-#define LCA_PMR_ADDR   (IDENT_ADDR + 0x120000098UL)
-#define LCA_PMR_PDIV    0x7                     /* Primary clock divisor */
-#define LCA_PMR_ODIV    0x38                    /* Override clock divisor */
-#define LCA_PMR_INTO    0x40                    /* Interrupt override */
-#define LCA_PMR_DMAO    0x80                    /* DMA override */
-#define LCA_PMR_OCCEB   0xffff0000L             /* Override cycle counter - even
- bits */
-#define LCA_PMR_OCCOB   0xffff000000000000L     /* Override cycle counter - even
- bits */
-#define LCA_PMR_PRIMARY_MASK    0xfffffffffffffff8
-/* LCA PMR Macros */
-
-#define READ_PMR        (*(volatile unsigned long *)LCA_PMR_ADDR)
-#define WRITE_PMR(d)    (*((volatile unsigned long *)LCA_PMR_ADDR) = (d))
-
-#define GET_PRIMARY(r)  ((r) & LCA_PMR_PDIV)
-#define GET_OVERRIDE(r) (((r) >> 3) & LCA_PMR_PDIV)
-#define SET_PRIMARY_CLOCK(r, c) ((r) = (((r) & LCA_PMR_PRIMARY_MASK) | (c)))
-
-/* LCA PMR Divisor values */
-#define DIV_1   0x0
-#define DIV_1_5 0x1
-#define DIV_2   0x2
-#define DIV_4   0x3
-#define DIV_8   0x4
-#define DIV_16  0x5
-#define DIV_MIN DIV_1
-#define DIV_MAX DIV_16
-
-
-#ifdef __KERNEL__
-
-/*
- * Translate physical memory address as seen on (PCI) bus into
- * a kernel virtual address and vv.
- */
-extern inline unsigned long virt_to_bus(void * address)
-{
-       return virt_to_phys(address) + LCA_DMA_WIN_BASE;
-}
-
-extern inline void * bus_to_virt(unsigned long address)
-{
-       /*
-        * This check is a sanity check but also ensures that bus
-        * address 0 maps to virtual address 0 which is useful to
-        * detect null "pointers" (the NCR driver is much simpler if
-        * NULL pointers are preserved).
-        */
-       if (address < LCA_DMA_WIN_BASE)
-               return 0;
-       return phys_to_virt(address - LCA_DMA_WIN_BASE);
-}
-
-/*
- * I/O functions:
- *
- * Unlike Jensen, the Noname machines have no concept of local
- * I/O---everything goes over the PCI bus.
- *
- * There is plenty room for optimization here.  In particular,
- * the Alpha's insb/insw/extb/extw should be useful in moving
- * data to/from the right byte-lanes.
- */
-
-#define vuip   volatile unsigned int *
-#define vulp   volatile unsigned long *
-
-extern inline unsigned int __inb(unsigned long addr)
-{
-       long result = *(vuip) ((addr << 5) + LCA_IO + 0x00);
-       result >>= (addr & 3) * 8;
-       return 0xffUL & result;
-}
-
-extern inline void __outb(unsigned char b, unsigned long addr)
-{
-       unsigned int w;
-
-       w = __kernel_insbl(b, addr & 3);
-       *(vuip) ((addr << 5) + LCA_IO + 0x00) = w;
-       mb();
-}
-
-extern inline unsigned int __inw(unsigned long addr)
-{
-       long result = *(vuip) ((addr << 5) + LCA_IO + 0x08);
-       result >>= (addr & 3) * 8;
-       return 0xffffUL & result;
-}
-
-extern inline void __outw(unsigned short b, unsigned long addr)
-{
-       unsigned int w;
-
-       w = __kernel_inswl(b, addr & 3);
-       *(vuip) ((addr << 5) + LCA_IO + 0x08) = w;
-       mb();
-}
-
-extern inline unsigned int __inl(unsigned long addr)
-{
-       return *(vuip) ((addr << 5) + LCA_IO + 0x18);
-}
-
-extern inline void __outl(unsigned int b, unsigned long addr)
-{
-       *(vuip) ((addr << 5) + LCA_IO + 0x18) = b;
-       mb();
-}
-
-
-/*
- * Memory functions.  64-bit and 32-bit accesses are done through
- * dense memory space, everything else through sparse space.
- */
-extern inline unsigned long __readb(unsigned long addr)
-{
-       unsigned long result, shift, msb;
-
-       shift = (addr & 0x3) * 8;
-       if (addr >= (1UL << 24)) {
-               msb = addr & 0xf8000000;
-               addr -= msb;
-               if (msb != hae.cache) {
-                       set_hae(msb);
-               }
-       }
-       result = *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x00);
-       result >>= shift;
-       return 0xffUL & result;
-}
-
-extern inline unsigned long __readw(unsigned long addr)
-{
-       unsigned long result, shift, msb;
-
-       shift = (addr & 0x3) * 8;
-       if (addr >= (1UL << 24)) {
-               msb = addr & 0xf8000000;
-               addr -= msb;
-               if (msb != hae.cache) {
-                       set_hae(msb);
-               }
-       }
-       result = *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x08);
-       result >>= shift;
-       return 0xffffUL & result;
-}
-
-extern inline unsigned long __readl(unsigned long addr)
-{
-       return *(vuip) (addr + LCA_DENSE_MEM);
-}
-
-extern inline unsigned long __readq(unsigned long addr)
-{
-       return *(vulp) (addr + LCA_DENSE_MEM);
-}
-
-extern inline void __writeb(unsigned char b, unsigned long addr)
-{
-       unsigned long msb;
-       unsigned int w;
-
-       if (addr >= (1UL << 24)) {
-               msb = addr & 0xf8000000;
-               addr -= msb;
-               if (msb != hae.cache) {
-                       set_hae(msb);
-               }
-       }
-       asm ("insbl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b));
-       *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x00) = w;
-}
-
-extern inline void __writew(unsigned short b, unsigned long addr)
-{
-       unsigned long msb;
-       unsigned int w;
-
-       if (addr >= (1UL << 24)) {
-               msb = addr & 0xf8000000;
-               addr -= msb;
-               if (msb != hae.cache) {
-                       set_hae(msb);
-               }
-       }
-       asm ("inswl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b));
-       *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x08) = w;
-}
-
-extern inline void __writel(unsigned int b, unsigned long addr)
-{
-       *(vuip) (addr + LCA_DENSE_MEM) = b;
-}
-
-extern inline void __writeq(unsigned long b, unsigned long addr)
-{
-       *(vulp) (addr + LCA_DENSE_MEM) = b;
-}
-
-/*
- * Most of the above have so much overhead that it probably doesn't
- * make sense to have them inlined (better icache behavior).
- */
-
-#define inb(port) \
-(__builtin_constant_p((port))?__inb(port):_inb(port))
-
-#define outb(x, port) \
-(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port)))
-
-#define readl(a)       __readl((unsigned long)(a))
-#define readq(a)       __readq((unsigned long)(a))
-#define writel(v,a)    __writel((v),(unsigned long)(a))
-#define writeq(v,a)    __writeq((v),(unsigned long)(a))
-
-#undef vuip
-#undef vulp
-
-extern unsigned long lca_init (unsigned long mem_start, unsigned long mem_end);
-
-#endif /* __KERNEL__ */
-
-/*
- * Data structure for handling LCA machine checks.  Correctable errors
- * result in a short logout frame, uncorrectable ones in a long one.
- */
-struct el_lca_mcheck_short {
-       struct el_common        h;              /* common logout header */
-       unsigned long           esr;            /* error-status register */
-       unsigned long           ear;            /* error-address register */
-       unsigned long           dc_stat;        /* dcache status register */
-       unsigned long           ioc_stat0;      /* I/O controller status register 0 */
-       unsigned long           ioc_stat1;      /* I/O controller status register 1 */
-};
-
-struct el_lca_mcheck_long {
-       struct el_common        h;              /* common logout header */
-       unsigned long           pt[31];         /* PAL temps */
-       unsigned long           exc_addr;       /* exception address */
-       unsigned long           pad1[3];
-       unsigned long           pal_base;       /* PALcode base address */
-       unsigned long           hier;           /* hw interrupt enable */
-       unsigned long           hirr;           /* hw interrupt request */
-       unsigned long           mm_csr;         /* MMU control & status */
-       unsigned long           dc_stat;        /* data cache status */
-       unsigned long           dc_addr;        /* data cache addr register */
-       unsigned long           abox_ctl;       /* address box control register */
-       unsigned long           esr;            /* error status register */
-       unsigned long           ear;            /* error address register */
-       unsigned long           car;            /* cache control register */
-       unsigned long           ioc_stat0;      /* I/O controller status register 0 */
-       unsigned long           ioc_stat1;      /* I/O controller status register 1 */
-       unsigned long           va;             /* virtual address register */
-};
-
-union el_lca {
-       struct el_common *              c;
-       struct el_lca_mcheck_long *     l;
-       struct el_lca_mcheck_short *    s;
-};
-
-#define RTC_PORT(x)    (0x70 + (x))
-#define RTC_ADDR(x)    (0x80 | (x))
-#define RTC_ALWAYS_BCD 0
-
-#endif /* __ALPHA_LCA__H__ */
diff --git a/include/asm-alpha/machvec.h b/include/asm-alpha/machvec.h
new file mode 100644 (file)
index 0000000..e3d247a
--- /dev/null
@@ -0,0 +1,118 @@
+#ifndef __ALPHA_MACHVEC_H
+#define __ALPHA_MACHVEC_H 1
+
+#include <linux/config.h>
+#include <linux/types.h>
+
+
+/* The following structure vectors all of the I/O and IRQ manipulation
+   from the generic kernel to the hardware specific backend.  */
+
+struct task_struct;
+struct mm_struct;
+struct pt_regs;
+struct vm_area_struct;
+
+struct alpha_machine_vector
+{
+       /* This "belongs" down below with the rest of the runtime
+          variables, but it is convenient for entry.S if these 
+          two slots are at the beginning of the struct.  */
+       unsigned long hae_cache;
+       unsigned long *hae_register;
+
+       unsigned long max_dma_address;
+       unsigned int nr_irqs;
+       unsigned int rtc_port, rtc_addr;
+       unsigned int max_asn;
+       unsigned long mmu_context_mask;
+       unsigned long irq_probe_mask;
+       unsigned long iack_sc;
+
+       unsigned long (*mv_virt_to_bus)(void *);
+       void * (*mv_bus_to_virt)(unsigned long);
+
+       unsigned int (*mv_inb)(unsigned long);
+       unsigned int (*mv_inw)(unsigned long);
+       unsigned int (*mv_inl)(unsigned long);
+
+       void (*mv_outb)(unsigned char, unsigned long);
+       void (*mv_outw)(unsigned short, unsigned long);
+       void (*mv_outl)(unsigned int, unsigned long);
+       
+       unsigned long (*mv_readb)(unsigned long);
+       unsigned long (*mv_readw)(unsigned long);
+       unsigned long (*mv_readl)(unsigned long);
+       unsigned long (*mv_readq)(unsigned long);
+
+       void (*mv_writeb)(unsigned char, unsigned long);
+       void (*mv_writew)(unsigned short, unsigned long);
+       void (*mv_writel)(unsigned int, unsigned long);
+       void (*mv_writeq)(unsigned long, unsigned long);
+
+       unsigned long (*mv_dense_mem)(unsigned long);
+
+       int (*pci_read_config_byte)(u8, u8, u8, u8 *value);
+       int (*pci_read_config_word)(u8, u8, u8, u16 *value);
+       int (*pci_read_config_dword)(u8, u8, u8, u32 *value);
+
+       int (*pci_write_config_byte)(u8, u8, u8, u8 value);
+       int (*pci_write_config_word)(u8, u8, u8, u16 value);
+       int (*pci_write_config_dword)(u8, u8, u8, u32 value);
+       
+       void (*mv_get_mmu_context)(struct task_struct *);
+       void (*mv_flush_tlb_current)(struct mm_struct *);
+       void (*mv_flush_tlb_other)(struct mm_struct *);
+       void (*mv_flush_tlb_current_page)(struct mm_struct * mm,
+                                         struct vm_area_struct *vma,
+                                         unsigned long addr);
+
+       void (*update_irq_hw)(unsigned long, unsigned long, int);
+       void (*ack_irq)(unsigned long);
+       void (*device_interrupt)(unsigned long vector, struct pt_regs *regs);
+       void (*machine_check)(u64 vector, u64 la, struct pt_regs *regs);
+
+       void (*init_arch)(unsigned long *, unsigned long *);
+       void (*init_irq)(void);
+       void (*init_pit)(void);
+       void (*pci_fixup)(void);
+       void (*kill_arch)(int, char *);
+
+       const char *vector_name;
+
+       /* System specific parameters.  */
+       union {
+           struct {
+               unsigned long gru_int_req_bits;
+           } cia;
+
+           struct {
+               unsigned long gamma_bias;
+           } t2;
+       } sys;
+
+       /* Runtime variables it is handy to keep close.  */
+       unsigned long dma_win_base;
+       unsigned long dma_win_size;
+       unsigned long sm_base_r1, sm_base_r2, sm_base_r3;
+};
+
+extern struct alpha_machine_vector alpha_mv;
+
+#ifdef CONFIG_ALPHA_GENERIC
+extern int alpha_using_srm;
+extern int alpha_use_srm_setup;
+#else
+#ifdef CONFIG_ALPHA_SRM
+#define alpha_using_srm 1
+#else
+#define alpha_using_srm 0
+#endif
+#if defined(CONFIG_ALPHA_SRM_SETUP)
+#define alpha_use_srm_setup 1
+#else
+#define alpha_use_srm_setup 0
+#endif
+#endif /* GENERIC */
+
+#endif /* __ALPHA_MACHVEC_H */
diff --git a/include/asm-alpha/mcpcia.h b/include/asm-alpha/mcpcia.h
deleted file mode 100644 (file)
index 116fde5..0000000
+++ /dev/null
@@ -1,690 +0,0 @@
-#ifndef __ALPHA_MCPCIA__H__
-#define __ALPHA_MCPCIA__H__
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-
-/*
- * MCPCIA is the internal name for a core logic chipset which provides
- * PCI access for the RAWHIDE family of systems.
- *
- * This file is based on:
- *
- * RAWHIDE System Programmer's Manual
- * 16-May-96
- * Rev. 1.4
- *
- */
-
-/*------------------------------------------------------------------------**
-**                                                                        **
-**  I/O procedures                                                   **
-**                                                                        **
-**      inport[b|w|t|l], outport[b|w|t|l] 8:16:24:32 IO xfers             **
-**     inportbxt: 8 bits only                                            **
-**      inport:    alias of inportw                                       **
-**      outport:   alias of outportw                                      **
-**                                                                        **
-**      inmem[b|w|t|l], outmem[b|w|t|l] 8:16:24:32 ISA memory xfers       **
-**     inmembxt: 8 bits only                                             **
-**      inmem:    alias of inmemw                                         **
-**      outmem:   alias of outmemw                                        **
-**                                                                        **
-**------------------------------------------------------------------------*/
-
-
-/* MCPCIA ADDRESS BIT DEFINITIONS
- *
- *  3 3 3 3|3 3 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |1| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |0|0|0|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
- *  |                                                                        \_/ \_/
- *  |                                                                         |   |
- *  +-- IO space, not cached.                                   Byte Enable --+   |
- *                                                              Transfer Length --+
- *
- *
- *
- *   Byte      Transfer
- *   Enable    Length    Transfer  Byte    Address
- *   adr<6:5>  adr<4:3>  Length    Enable  Adder
- *   ---------------------------------------------
- *      00        00      Byte      1110   0x000
- *      01        00      Byte      1101   0x020
- *      10        00      Byte      1011   0x040
- *      11        00      Byte      0111   0x060
- *
- *      00        01      Word      1100   0x008
- *      01        01      Word      1001   0x028 <= Not supported in this code.
- *      10        01      Word      0011   0x048
- *
- *      00        10      Tribyte   1000   0x010
- *      01        10      Tribyte   0001   0x030
- *
- *      10        11      Longword  0000   0x058
- *
- *      Note that byte enables are asserted low.
- *
- */
-
-#define BYTE_ENABLE_SHIFT 5
-#define TRANSFER_LENGTH_SHIFT 3
-
-#define MEM_R1_MASK 0x1fffffff  /* SPARSE Mem region 1 mask is 29 bits */
-#define MEM_R2_MASK 0x07ffffff  /* SPARSE Mem region 2 mask is 27 bits */
-#define MEM_R3_MASK 0x03ffffff  /* SPARSE Mem region 3 mask is 26 bits */
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-/* if we are using the SRM PCI setup, we'll need to use variables instead */
-#define MCPCIA_DMA_WIN_BASE_DEFAULT    (2*1024*1024*1024U)
-#define MCPCIA_DMA_WIN_SIZE_DEFAULT    (2*1024*1024*1024U)
-
-extern unsigned int MCPCIA_DMA_WIN_BASE;
-extern unsigned int MCPCIA_DMA_WIN_SIZE;
-
-#else /* SRM_SETUP */
-#define MCPCIA_DMA_WIN_BASE    (2*1024*1024*1024UL)
-#define MCPCIA_DMA_WIN_SIZE    (2*1024*1024*1024UL)
-#endif /* SRM_SETUP */
-
-#define HOSE(h) (((unsigned long)(h)) << 33)
-/*
- *  General Registers
- */
-#define MCPCIA_REV(h)          (IDENT_ADDR + 0xf9e0000000UL + HOSE(h))
-#define MCPCIA_WHOAMI(h)       (IDENT_ADDR + 0xf9e0000040UL + HOSE(h))
-#define MCPCIA_PCI_LAT(h)      (IDENT_ADDR + 0xf9e0000080UL + HOSE(h))
-#define MCPCIA_CAP_CTRL(h)     (IDENT_ADDR + 0xf9e0000100UL + HOSE(h))
-#define MCPCIA_HAE_MEM(h)      (IDENT_ADDR + 0xf9e0000400UL + HOSE(h))
-#define MCPCIA_HAE_IO(h)       (IDENT_ADDR + 0xf9e0000440UL + HOSE(h))
-#if 0
-#define MCPCIA_IACK_SC(h)      (IDENT_ADDR + 0xf9e0000480UL + HOSE(h))
-#endif
-#define MCPCIA_HAE_DENSE(h)    (IDENT_ADDR + 0xf9e00004c0UL + HOSE(h))
-
-/*
- * Interrupt Control registers
- */
-#define MCPCIA_INT_CTL(h)      (IDENT_ADDR + 0xf9e0000500UL + HOSE(h))
-#define MCPCIA_INT_REQ(h)      (IDENT_ADDR + 0xf9e0000540UL + HOSE(h))
-#define MCPCIA_INT_TARG(h)     (IDENT_ADDR + 0xf9e0000580UL + HOSE(h))
-#define MCPCIA_INT_ADR(h)      (IDENT_ADDR + 0xf9e00005c0UL + HOSE(h))
-#define MCPCIA_INT_ADR_EXT(h)  (IDENT_ADDR + 0xf9e0000600UL + HOSE(h))
-#define MCPCIA_INT_MASK0(h)    (IDENT_ADDR + 0xf9e0000640UL + HOSE(h))
-#define MCPCIA_INT_MASK1(h)    (IDENT_ADDR + 0xf9e0000680UL + HOSE(h))
-#define MCPCIA_INT_ACK0(h)     (IDENT_ADDR + 0xf9f0003f00UL + HOSE(h))
-#define MCPCIA_INT_ACK1(h)     (IDENT_ADDR + 0xf9e0003f40UL + HOSE(h))
-
-/*
- * Performance Monitor registers
- */
-#define MCPCIA_PERF_MONITOR(h) (IDENT_ADDR + 0xf9e0000300UL + HOSE(h))
-#define MCPCIA_PERF_CONTROL(h) (IDENT_ADDR + 0xf9e0000340UL + HOSE(h))
-
-/*
- * Diagnostic Registers
- */
-#define MCPCIA_CAP_DIAG(h)     (IDENT_ADDR + 0xf9e0000700UL + HOSE(h))
-#define MCPCIA_TOP_OF_MEM(h)   (IDENT_ADDR + 0xf9e00007c0UL + HOSE(h))
-
-/*
- * Error registers
- */
-#define MCPCIA_CAP_ERR(h)      (IDENT_ADDR + 0xf9e0000880UL + HOSE(h))
-#define MCPCIA_PCI_ERR1(h)     (IDENT_ADDR + 0xf9e0001040UL + HOSE(h))
-
-/*
- * PCI Address Translation Registers.
- */
-#define MCPCIA_SG_TBIA(h)      (IDENT_ADDR + 0xf9e0001300UL + HOSE(h))
-#define MCPCIA_HBASE(h)                (IDENT_ADDR + 0xf9e0001340UL + HOSE(h))
-
-#define MCPCIA_W0_BASE(h)      (IDENT_ADDR + 0xf9e0001400UL + HOSE(h))
-#define MCPCIA_W0_MASK(h)      (IDENT_ADDR + 0xf9e0001440UL + HOSE(h))
-#define MCPCIA_T0_BASE(h)      (IDENT_ADDR + 0xf9e0001480UL + HOSE(h))
-
-#define MCPCIA_W1_BASE(h)      (IDENT_ADDR + 0xf9e0001500UL + HOSE(h))
-#define MCPCIA_W1_MASK(h)      (IDENT_ADDR + 0xf9e0001540UL + HOSE(h))
-#define MCPCIA_T1_BASE(h)      (IDENT_ADDR + 0xf9e0001580UL + HOSE(h))
-
-#define MCPCIA_W2_BASE(h)      (IDENT_ADDR + 0xf9e0001600UL + HOSE(h))
-#define MCPCIA_W2_MASK(h)      (IDENT_ADDR + 0xf9e0001640UL + HOSE(h))
-#define MCPCIA_T2_BASE(h)      (IDENT_ADDR + 0xf9e0001680UL + HOSE(h))
-
-#define MCPCIA_W3_BASE(h)      (IDENT_ADDR + 0xf9e0001700UL + HOSE(h))
-#define MCPCIA_W3_MASK(h)      (IDENT_ADDR + 0xf9e0001740UL + HOSE(h))
-#define MCPCIA_T3_BASE(h)      (IDENT_ADDR + 0xf9e0001780UL + HOSE(h))
-
-/*
- * Memory spaces:
- */
-#define MCPCIA_CONF(h)         (IDENT_ADDR + 0xf9c0000000UL + HOSE(h))
-#define MCPCIA_IO(h)           (IDENT_ADDR + 0xf980000000UL + HOSE(h))
-#define MCPCIA_SPARSE(h)       (IDENT_ADDR + 0xf800000000UL + HOSE(h))
-#define MCPCIA_DENSE(h)                (IDENT_ADDR + 0xf900000000UL + HOSE(h))
-#define MCPCIA_IACK_SC(h)      (IDENT_ADDR + 0xf9f0003f00UL + HOSE(h))
-
-#define DENSE_MEM(addr)                MCPCIA_DENSE(((unsigned long)(addr) >> 32) & 3)
-
-#define HAE_ADDRESS            MCPCIA_HAE_MEM(0)
-
-#ifdef __KERNEL__
-
-/*
- * Translate physical memory address as seen on (PCI) bus into
- * a kernel virtual address and vv.
- */
-extern inline unsigned long virt_to_bus(void * address)
-{
-       return virt_to_phys(address) + MCPCIA_DMA_WIN_BASE;
-}
-
-extern inline void * bus_to_virt(unsigned long address)
-{
-       return phys_to_virt(address - MCPCIA_DMA_WIN_BASE);
-}
-
-/*
- * I/O functions:
- *
- * MCPCIA, the RAWHIDE family PCI/memory support chipset for the EV5 (21164)
- * and EV56 (21164a) processors, can use either a sparse address mapping
- * scheme, or the so-called byte-word PCI address space, to get at PCI memory
- * and I/O.
- *
- * Unfortunately, we can't use BWIO with EV5, so for now, we always use SPARSE.
- */
-
-#define vuip   volatile unsigned int *
-#define vulp   volatile unsigned long *
-
-#ifdef DISABLE_BWIO_ENABLED
-
-extern inline unsigned int __inb(unsigned long addr)
-{
-       register unsigned long result;
-
-       __asm__ __volatile__ (
-                "ldbu %0,%1"
-                : "=r" (result)
-                : "m"  (*(unsigned char *)(addr+MCPCIA_BW_IO)));
-
-       return result;
-}
-
-extern inline void __outb(unsigned char b, unsigned long addr)
-{
-       __asm__ __volatile__ (
-                "stb %1,%0\n\t"
-                "mb"
-                : : "m" (*(unsigned char *)(addr+MCPCIA_BW_IO)), "r" (b));
-}
-
-extern inline unsigned int __inw(unsigned long addr)
-{
-       register unsigned long result;
-
-       __asm__ __volatile__ (
-                "ldwu %0,%1"
-                : "=r" (result)
-                : "m"  (*(unsigned short *)(addr+MCPCIA_BW_IO)));
-
-       return result;
-}
-
-extern inline void __outw(unsigned short b, unsigned long addr)
-{
-       __asm__ __volatile__ (
-                "stw %1,%0\n\t"
-                "mb"
-                : : "m" (*(unsigned short *)(addr+MCPCIA_BW_IO)), "r" (b));
-}
-
-extern inline unsigned int __inl(unsigned long addr)
-{
-       register unsigned long result;
-
-       __asm__ __volatile__ (
-                "ldl %0,%1"
-                : "=r" (result)
-                : "m"  (*(unsigned int *)(addr+MCPCIA_BW_IO)));
-
-       return result;
-}
-
-extern inline void __outl(unsigned int b, unsigned long addr)
-{
-       __asm__ __volatile__ (
-                "stl %1,%0\n\t"
-                "mb"
-                : : "m" (*(unsigned int *)(addr+MCPCIA_BW_IO)), "r" (b));
-}
-
-#define inb(port) __inb((port))
-#define inw(port) __inw((port))
-#define inl(port) __inl((port))
-
-#define outb(x, port) __outb((x),(port))
-#define outw(x, port) __outw((x),(port))
-#define outl(x, port) __outl((x),(port))
-
-#else /* BWIO_ENABLED */
-
-extern inline unsigned int __inb(unsigned long in_addr)
-{
-       unsigned long addr = in_addr & 0xffffffffUL;
-       unsigned long hose = (in_addr >> 32) & 3;
-       long result = *(vuip) ((addr << 5) + MCPCIA_IO(hose) + 0x00);
-       result >>= (addr & 3) * 8;
-       return 0xffUL & result;
-}
-
-extern inline void __outb(unsigned char b, unsigned long in_addr)
-{
-       unsigned long addr = in_addr & 0xffffffffUL;
-       unsigned long hose = (in_addr >> 32) & 3;
-       unsigned int w;
-
-       w = __kernel_insbl(b, addr & 3);
-       *(vuip) ((addr << 5) + MCPCIA_IO(hose) + 0x00) = w;
-       mb();
-}
-
-extern inline unsigned int __inw(unsigned long in_addr)
-{
-       unsigned long addr = in_addr & 0xffffffffUL;
-       unsigned long hose = (in_addr >> 32) & 3;
-       long result = *(vuip) ((addr << 5) + MCPCIA_IO(hose) + 0x08);
-       result >>= (addr & 3) * 8;
-       return 0xffffUL & result;
-}
-
-extern inline void __outw(unsigned short b, unsigned long in_addr)
-{
-       unsigned long addr = in_addr & 0xffffffffUL;
-       unsigned long hose = (in_addr >> 32) & 3;
-       unsigned int w;
-
-       w = __kernel_inswl(b, addr & 3);
-       *(vuip) ((addr << 5) + MCPCIA_IO(hose) + 0x08) = w;
-       mb();
-}
-
-extern inline unsigned int __inl(unsigned long in_addr)
-{
-       unsigned long addr = in_addr & 0xffffffffUL;
-       unsigned long hose = (in_addr >> 32) & 3;
-       return *(vuip) ((addr << 5) + MCPCIA_IO(hose) + 0x18);
-}
-
-extern inline void __outl(unsigned int b, unsigned long in_addr)
-{
-       unsigned long addr = in_addr & 0xffffffffUL;
-       unsigned long hose = (in_addr >> 32) & 3;
-       *(vuip) ((addr << 5) + MCPCIA_IO(hose) + 0x18) = b;
-       mb();
-}
-
-#define inb(port) \
-(__builtin_constant_p((port))?__inb(port):_inb(port))
-
-#define outb(x, port) \
-(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port)))
-
-#endif /* BWIO_ENABLED */
-
-
-/*
- * Memory functions.  64-bit and 32-bit accesses are done through
- * dense memory space, everything else through sparse space.
- * 
- * For reading and writing 8 and 16 bit quantities we need to 
- * go through one of the three sparse address mapping regions
- * and use the HAE_MEM CSR to provide some bits of the address.
- * The following few routines use only sparse address region 1
- * which gives 1Gbyte of accessible space which relates exactly
- * to the amount of PCI memory mapping *into* system address space.
- * See p 6-17 of the specification but it looks something like this:
- *
- * 21164 Address:
- * 
- *          3         2         1
- * 9876543210987654321098765432109876543210
- * 1ZZZZ0.PCI.QW.Address............BBLL                 
- *
- * ZZ = SBZ
- * BB = Byte offset
- * LL = Transfer length
- *
- * PCI Address:
- *
- * 3         2         1
- * 10987654321098765432109876543210
- * HHH....PCI.QW.Address........ 00
- *
- * HHH = 31:29 HAE_MEM CSR
- * 
- */
-
-#ifdef DISABLE_BWIO_ENABLED
-
-extern inline unsigned long __readb(unsigned long addr)
-{
-       register unsigned long result;
-
-       __asm__ __volatile__ (
-                "ldbu %0,%1"
-                : "=r" (result)
-                : "m"  (*(volatile unsigned char *)(addr+MCPCIA_BW_MEM)));
-
-       return result;
-}
-
-extern inline unsigned long __readw(unsigned long addr)
-{
-       register unsigned long result;
-
-       __asm__ __volatile__ (
-                "ldwu %0,%1"
-                : "=r" (result)
-                : "m"  (*(volatile unsigned short *)(addr+MCPCIA_BW_MEM)));
-
-       return result;
-}
-
-extern inline unsigned long __readl(unsigned long addr)
-{
-       return *(vuip)(addr + MCPCIA_BW_MEM);
-}
-
-extern inline unsigned long __readq(unsigned long addr)
-{
-       return *(vulp)(addr + MCPCIA_BW_MEM);
-}
-
-extern inline void __writeb(unsigned char b, unsigned long addr)
-{
-       __asm__ __volatile__ (
-                "stb %1,%0\n\t"
-                "mb"
-                : "m" (*(volatile unsigned char *)(addr+MCPCIA_BW_MEM))
-                : "r" (b));
-}
-
-extern inline void __writew(unsigned short b, unsigned long addr)
-{
-       __asm__ __volatile__ (
-                "stw %1,%0\n\t"
-                "mb"
-                : "m" (*(volatile unsigned short *)(addr+MCPCIA_BW_MEM))
-                : "r" (b));
-}
-
-extern inline void __writel(unsigned int b, unsigned long addr)
-{
-       *(vuip)(addr+MCPCIA_BW_MEM) = b;
-       mb();
-}
-
-extern inline void __writeq(unsigned long b, unsigned long addr)
-{
-       *(vulp)(addr+MCPCIA_BW_MEM) = b;
-       mb();
-}
-
-#define readb(addr) __readb((addr))
-#define readw(addr) __readw((addr))
-
-#define writeb(b, addr) __writeb((b),(addr))
-#define writew(b, addr) __writew((b),(addr))
-
-#else /* BWIO_ENABLED */
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-
-extern unsigned long mcpcia_sm_base_r1, mcpcia_sm_base_r2, mcpcia_sm_base_r3;
-
-extern inline unsigned long __readb(unsigned long addr)
-{
-       unsigned long result, shift, work;
-
-       if ((addr >= mcpcia_sm_base_r1) &&
-           (addr <= (mcpcia_sm_base_r1 + MEM_R1_MASK)))
-         work = (((addr & MEM_R1_MASK) << 5) + MCPCIA_SPARSE_MEM + 0x00);
-       else
-       if ((addr >= mcpcia_sm_base_r2) &&
-           (addr <= (mcpcia_sm_base_r2 + MEM_R2_MASK)))
-         work = (((addr & MEM_R2_MASK) << 5) + MCPCIA_SPARSE_MEM_R2 + 0x00);
-       else
-       if ((addr >= mcpcia_sm_base_r3) &&
-           (addr <= (mcpcia_sm_base_r3 + MEM_R3_MASK)))
-         work = (((addr & MEM_R3_MASK) << 5) + MCPCIA_SPARSE_MEM_R3 + 0x00);
-       else
-       {
-#if 0
-         printk("__readb: address 0x%lx not covered by HAE\n", addr);
-#endif
-         return 0x0ffUL;
-       }
-       shift = (addr & 0x3) << 3;
-       result = *(vuip) work;
-       result >>= shift;
-       return 0x0ffUL & result;
-}
-
-extern inline unsigned long __readw(unsigned long addr)
-{
-       unsigned long result, shift, work;
-
-       if ((addr >= mcpcia_sm_base_r1) &&
-           (addr <= (mcpcia_sm_base_r1 + MEM_R1_MASK)))
-         work = (((addr & MEM_R1_MASK) << 5) + MCPCIA_SPARSE_MEM + 0x08);
-       else
-       if ((addr >= mcpcia_sm_base_r2) &&
-           (addr <= (mcpcia_sm_base_r2 + MEM_R2_MASK)))
-         work = (((addr & MEM_R2_MASK) << 5) + MCPCIA_SPARSE_MEM_R2 + 0x08);
-       else
-       if ((addr >= mcpcia_sm_base_r3) &&
-           (addr <= (mcpcia_sm_base_r3 + MEM_R3_MASK)))
-         work = (((addr & MEM_R3_MASK) << 5) + MCPCIA_SPARSE_MEM_R3 + 0x08);
-       else
-       {
-#if 0
-         printk("__readw: address 0x%lx not covered by HAE\n", addr);
-#endif
-         return 0x0ffffUL;
-       }
-       shift = (addr & 0x3) << 3;
-       result = *(vuip) work;
-       result >>= shift;
-       return 0x0ffffUL & result;
-}
-
-extern inline void __writeb(unsigned char b, unsigned long addr)
-{
-       unsigned long work;
-
-       if ((addr >= mcpcia_sm_base_r1) &&
-           (addr <= (mcpcia_sm_base_r1 + MEM_R1_MASK)))
-         work = (((addr & MEM_R1_MASK) << 5) + MCPCIA_SPARSE_MEM + 0x00);
-       else
-       if ((addr >= mcpcia_sm_base_r2) &&
-           (addr <= (mcpcia_sm_base_r2 + MEM_R2_MASK)))
-         work = (((addr & MEM_R2_MASK) << 5) + MCPCIA_SPARSE_MEM_R2 + 0x00);
-       else
-       if ((addr >= mcpcia_sm_base_r3) &&
-           (addr <= (mcpcia_sm_base_r3 + MEM_R3_MASK)))
-         work = (((addr & MEM_R3_MASK) << 5) + MCPCIA_SPARSE_MEM_R3 + 0x00);
-       else
-       {
-#if 0
-         printk("__writeb: address 0x%lx not covered by HAE\n", addr);
-#endif
-         return;
-       }
-       *(vuip) work = b * 0x01010101;
-}
-
-extern inline void __writew(unsigned short b, unsigned long addr)
-{
-       unsigned long work;
-
-       if ((addr >= mcpcia_sm_base_r1) &&
-           (addr <= (mcpcia_sm_base_r1 + MEM_R1_MASK)))
-         work = (((addr & MEM_R1_MASK) << 5) + MCPCIA_SPARSE_MEM + 0x00);
-       else
-       if ((addr >= mcpcia_sm_base_r2) &&
-           (addr <= (mcpcia_sm_base_r2 + MEM_R2_MASK)))
-         work = (((addr & MEM_R2_MASK) << 5) + MCPCIA_SPARSE_MEM_R2 + 0x00);
-       else
-       if ((addr >= mcpcia_sm_base_r3) &&
-           (addr <= (mcpcia_sm_base_r3 + MEM_R3_MASK)))
-         work = (((addr & MEM_R3_MASK) << 5) + MCPCIA_SPARSE_MEM_R3 + 0x00);
-       else
-       {
-#if 0
-         printk("__writew: address 0x%lx not covered by HAE\n", addr);
-#endif
-         return;
-       }
-       *(vuip) work = b * 0x00010001;
-}
-
-#else /* SRM_SETUP */
-
-extern inline unsigned long __readb(unsigned long in_addr)
-{
-       unsigned long addr = in_addr & 0xffffffffUL;
-       unsigned long hose = (in_addr >> 32) & 3;
-       unsigned long result, shift, msb, work, temp;
-
-       shift = (addr & 0x3) << 3;
-       msb = addr & 0xE0000000UL;
-       temp = addr & MEM_R1_MASK;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       work = ((temp << 5) + MCPCIA_SPARSE(hose) + 0x00);
-       result = *(vuip) work;
-       result >>= shift;
-       return 0x0ffUL & result;
-}
-
-extern inline unsigned long __readw(unsigned long in_addr)
-{
-       unsigned long addr = in_addr & 0xffffffffUL;
-       unsigned long hose = (in_addr >> 32) & 3;
-       unsigned long result, shift, msb, work, temp;
-
-       shift = (addr & 0x3) << 3;
-       msb = addr & 0xE0000000UL;
-       temp = addr & MEM_R1_MASK ;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       work = ((temp << 5) + MCPCIA_SPARSE(hose) + 0x08);
-       result = *(vuip) work;
-       result >>= shift;
-       return 0x0ffffUL & result;
-}
-
-extern inline void __writeb(unsigned char b, unsigned long in_addr)
-{
-       unsigned long addr = in_addr & 0xffffffffUL;
-       unsigned long hose = (in_addr >> 32) & 3;
-        unsigned long msb; 
-
-       msb = addr & 0xE0000000;
-       addr &= MEM_R1_MASK;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       *(vuip) ((addr << 5) + MCPCIA_SPARSE(hose) + 0x00) = b * 0x01010101;
-}
-
-extern inline void __writew(unsigned short b, unsigned long in_addr)
-{
-       unsigned long addr = in_addr & 0xffffffffUL;
-       unsigned long hose = (in_addr >> 32) & 3;
-        unsigned long msb ; 
-
-       msb = addr & 0xE0000000 ;
-       addr &= MEM_R1_MASK ;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       *(vuip) ((addr << 5) + MCPCIA_SPARSE(hose) + 0x08) = b * 0x00010001;
-}
-#endif /* SRM_SETUP */
-
-extern inline unsigned long __readl(unsigned long in_addr)
-{
-       unsigned long addr = in_addr & 0xffffffffUL;
-       unsigned long hose = (in_addr >> 32) & 3;
-       return *(vuip) (addr + MCPCIA_DENSE(hose));
-}
-
-extern inline unsigned long __readq(unsigned long in_addr)
-{
-       unsigned long addr = in_addr & 0xffffffffUL;
-       unsigned long hose = (in_addr >> 32) & 3;
-       return *(vulp) (addr + MCPCIA_DENSE(hose));
-}
-
-extern inline void __writel(unsigned int b, unsigned long in_addr)
-{
-       unsigned long addr = in_addr & 0xffffffffUL;
-       unsigned long hose = (in_addr >> 32) & 3;
-       *(vuip) (addr + MCPCIA_DENSE(hose)) = b;
-}
-
-extern inline void __writeq(unsigned long b, unsigned long in_addr)
-{
-       unsigned long addr = in_addr & 0xffffffffUL;
-       unsigned long hose = (in_addr >> 32) & 3;
-       *(vulp) (addr + MCPCIA_DENSE(hose)) = b;
-}
-
-#endif /* BWIO_ENABLED */
-
-#define readl(a)       __readl((unsigned long)(a))
-#define readq(a)       __readq((unsigned long)(a))
-#define writel(v,a)    __writel((v),(unsigned long)(a))
-#define writeq(v,a)    __writeq((v),(unsigned long)(a))
-
-#undef vuip
-#undef vulp
-
-struct linux_hose_info {
-        struct pci_bus                  pci_bus;
-       struct linux_hose_info         *next;
-       unsigned long                   pci_io_space;
-       unsigned long                   pci_mem_space;
-       unsigned long                   pci_config_space;
-       unsigned long                   pci_sparse_space;
-        unsigned int                    pci_first_busno;
-        unsigned int                    pci_last_busno;
-       unsigned int                    pci_hose_index;
-};
-
-extern unsigned long mcpcia_init (unsigned long, unsigned long);
-extern void mcpcia_fixup (void);
-
-#endif /* __KERNEL__ */
-
-/*
- * Data structure for handling MCPCIA machine checks:
- */
-struct el_MCPCIA_uncorrected_frame_mcheck {
-        struct el_common header;
-        struct el_common_EV5_uncorrectable_mcheck procdata;
-};
-
-#define RTC_PORT(x)    (0x70 + (x))
-#define RTC_ADDR(x)    (0x80 | (x))
-#define RTC_ALWAYS_BCD 0
-
-#endif /* __ALPHA_MCPCIA__H__ */
index 0d4ab6b214c725c11a33deef9050bbf44e124d8a..af97b674090632a93ae7648e1542ba3e0c5953fb 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/config.h>
 #include <asm/system.h>
+#include <asm/machvec.h>
 
 /*
  * The maximum ASN's the processor supports.  On the EV4 this is 63
  * work correctly and can thus not be used (explaining the lack of PAL-code
  * support).
  */
-#ifdef CONFIG_ALPHA_EV5
-#define MAX_ASN 127
+#define EV4_MAX_ASN 63
+#define EV5_MAX_ASN 127
+
+#ifdef CONFIG_ALPHA_GENERIC
+# define MAX_ASN       (alpha_mv.max_asn)
 #else
-#define MAX_ASN 63
-#define BROKEN_ASN 1
+# ifdef CONFIG_ALPHA_EV4
+#  define MAX_ASN      EV4_MAX_ASN
+# else
+#  define MAX_ASN      EV5_MAX_ASN
+# endif
 #endif
 
 #ifdef __SMP__
@@ -78,26 +85,21 @@ extern unsigned long asn_cache;
  * force a new asn for any other processes the next time they want to
  * run.
  */
-extern inline void
-get_new_mmu_context(struct task_struct *p, struct mm_struct *mm)
+
+#ifndef __EXTERN_INLINE
+#define __EXTERN_INLINE extern inline
+#define __MMU_EXTERN_INLINE
+#endif
+
+extern void get_new_mmu_context(struct task_struct *p, struct mm_struct *mm);
+
+__EXTERN_INLINE void ev4_get_mmu_context(struct task_struct *p)
 {
-       unsigned long asn = asn_cache;
-
-       if ((asn & HARDWARE_ASN_MASK) < MAX_ASN)
-               ++asn;
-       else {
-               tbiap();
-               imb();
-               asn = (asn & ~HARDWARE_ASN_MASK) + ASN_FIRST_VERSION;
-       }
-       asn_cache = asn;
-       mm->context = asn;                      /* full version + asn */
-       p->tss.asn = asn & HARDWARE_ASN_MASK;   /* just asn */
+       /* As described, ASN's are broken.  */
 }
 
-extern inline void get_mmu_context(struct task_struct *p)
+__EXTERN_INLINE void ev5_get_mmu_context(struct task_struct *p)
 {
-#ifndef BROKEN_ASN
        struct mm_struct * mm = p->mm;
 
        if (mm) {
@@ -106,27 +108,81 @@ extern inline void get_mmu_context(struct task_struct *p)
                if ((mm->context ^ asn) & ~HARDWARE_ASN_MASK)
                        get_new_mmu_context(p, mm);
        }
-#endif
 }
 
+#ifdef CONFIG_ALPHA_GENERIC
+# define get_mmu_context               (alpha_mv.mv_get_mmu_context)
+#else
+# ifdef CONFIG_ALPHA_EV4
+#  define get_mmu_context              ev4_get_mmu_context
+# else
+#  define get_mmu_context              ev5_get_mmu_context
+# endif
+#endif
+
 extern inline void init_new_context(struct mm_struct *mm)
 {
        mm->context = 0;
 }
 
-#define destroy_context(mm)    do { } while(0)
+extern inline void destroy_context(struct mm_struct *mm)
+{
+       /* Nothing to do.  */
+}
+
 
 /*
- * After we have set current->mm to a new value, this activates
- * the context for the new mm so we see the new mappings.
- * Ideally this would be an extern inline function, but reload_context
- * is declared in pgtable.h, which includes this file. :-(
+ * Force a context reload. This is needed when we change the page
+ * table pointer or when we update the ASN of the current process.
  */
-#define activate_context(tsk)          \
-       do {                            \
-               get_mmu_context(tsk);   \
-               reload_context(tsk);    \
-       } while (0)
 
+#if defined(CONFIG_ALPHA_GENERIC)
+#define MASK_CONTEXT(tss) \
+ ((struct thread_struct *)((unsigned long)(tss) & alpha_mv.mmu_context_mask))
+#elif defined(CONFIG_ALPHA_DP264)
+#define MASK_CONTEXT(tss) \
+ ((struct thread_struct *)((unsigned long)(tss) & 0xfffffffffful))
+#else
+#define MASK_CONTEXT(tss)  (tss)
+#endif
+
+__EXTERN_INLINE struct thread_struct *
+__reload_tss(struct thread_struct *tss)
+{
+       register struct thread_struct *a0 __asm__("$16");
+       register struct thread_struct *v0 __asm__("$0");
+
+       a0 = MASK_CONTEXT(tss);
+
+       __asm__ __volatile__(
+               "call_pal %2" : "=r"(v0), "=r"(a0)
+               : "i"(PAL_swpctx), "r"(a0)
+               : "$1", "$16", "$22", "$23", "$24", "$25");
+
+       return v0;
+}
+
+__EXTERN_INLINE void
+reload_context(struct task_struct *task)
+{
+       __reload_tss(&task->tss);
+}
+
+/*
+ * After we have set current->mm to a new value, this activates the
+ * context for the new mm so we see the new mappings.
+ */
+
+__EXTERN_INLINE void
+activate_context(struct task_struct *task)
+{
+       get_mmu_context(task);
+       reload_context(task);
+}
+
+#ifdef __MMU_EXTERN_INLINE
+#undef __EXTERN_INLINE
+#undef __MMU_EXTERN_INLINE
 #endif
 
+#endif /* __ALPHA_MMU_CONTEXT_H */
diff --git a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h
new file mode 100644 (file)
index 0000000..2dd28c3
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef __ALPHA_PCI_H
+#define __ALPHA_PCI_H
+
+#include <linux/config.h>
+#include <linux/pci.h>
+
+
+/*
+ * The following structure is used to manage multiple PCI busses.
+ *
+ * XXX: We should solve thos problem in an architecture independant
+ * way, rather than hacking something up here.
+ */
+
+struct linux_hose_info {
+        struct pci_bus                  pci_bus;
+       struct linux_hose_info         *next;
+       unsigned long                   pci_io_space;
+       unsigned long                   pci_mem_space;
+       unsigned long                   pci_config_space;
+       unsigned long                   pci_sparse_space;
+        unsigned int                    pci_first_busno;
+        unsigned int                    pci_last_busno;
+       unsigned int                    pci_hose_index;
+};
+
+/* This is indexed by a pseudo- PCI bus number to obtain the real deal.  */
+extern struct linux_hose_info *bus2hose[256];
+
+/* Create a handle that is OR-ed into the reported I/O space address
+   for a device.  We use this later to find the bus a device lives on.  */
+
+#if defined(CONFIG_ALPHA_GENERIC) \
+    || defined(CONFIG_ALPHA_MCPCIA) \
+    /* || defined(CONFIG_ALPHA_TSUNAMI) */
+
+#define PCI_HANDLE(bus)   ((bus2hose[bus]->pci_hose_index & 3UL) << 32)
+#define DEV_IS_ON_PRIMARY(dev) \
+  (bus2hose[(dev)->bus->number]->pci_first_busno == (dev)->bus->number)
+
+#else
+
+#define PCI_HANDLE(bus)         0
+#define DEV_IS_ON_PRIMARY(dev)  ((dev)->bus->number == 0)
+
+#endif /* Multiple busses */
+
+#endif /* __ALPHA_PCI_H */
index e9a8fb47bd137648629aa57e3de2d56355a099fc..3cbbaa17aa26410f54d8df08f4c2b0f017e018a1 100644 (file)
@@ -13,6 +13,8 @@
 #include <asm/system.h>
 #include <asm/processor.h>     /* For TASK_SIZE */
 #include <asm/mmu_context.h>
+#include <asm/machvec.h>
+
 
 /* Caches aren't brain-dead on the Alpha. */
 #define flush_cache_all()                      do { } while (0)
 #define flush_page_to_ram(page)                        do { } while (0)
 #define flush_icache_range(start, end)         do { } while (0)
 
-/*
- * Force a context reload. This is needed when we
- * change the page table pointer or when we update
- * the ASN of the current process.
- */
-static inline void reload_context(struct task_struct *task)
-{
-       __asm__ __volatile__(
-#ifdef CONFIG_ALPHA_DP264
-               "zap %0,0xe0,$16\n\t"
-#else
-               "bis %0,%0,$16\n\t"
-#endif
-               "call_pal %1"
-               : /* no outputs */
-               : "r" (&task->tss), "i" (PAL_swpctx)
-               : "$0", "$1", "$16", "$22", "$23", "$24", "$25");
-}
-
 /*
  * Use a few helper functions to hide the ugly broken ASN
  * numbers on early Alphas (ev4 and ev45)
  */
-#ifdef BROKEN_ASN
 
-#define flush_tlb_current(x) tbiap()
-#define flush_tlb_other(x) do { } while (0)
+#ifndef __EXTERN_INLINE
+#define __EXTERN_INLINE extern inline
+#define __MMU_EXTERN_INLINE
+#endif
 
-#else
+__EXTERN_INLINE void
+ev4_flush_tlb_current(struct mm_struct *mm)
+{
+       tbiap();
+}
 
-extern void get_new_asn_and_reload(struct task_struct *, struct mm_struct *);
+__EXTERN_INLINE void
+ev4_flush_tlb_other(struct mm_struct *mm)
+{
+}
 
-#define flush_tlb_current(mm) get_new_asn_and_reload(current, mm)
-#define flush_tlb_other(mm) do { (mm)->context = 0; } while (0)
+__EXTERN_INLINE void
+ev5_flush_tlb_current(struct mm_struct *mm)
+{
+       mm->context = 0;
+       get_new_mmu_context(current, mm);
+       reload_context(current);
+}
 
-#endif
+__EXTERN_INLINE void
+ev5_flush_tlb_other(struct mm_struct *mm)
+{
+       mm->context = 0;
+}
 
 /*
  * Flush just one page in the current TLB set.
  * We need to be very careful about the icache here, there
  * is no way to invalidate a specific icache page..
  */
-static inline void flush_tlb_current_page(struct mm_struct * mm,
-       struct vm_area_struct *vma,
-       unsigned long addr)
+
+__EXTERN_INLINE void
+ev4_flush_tlb_current_page(struct mm_struct * mm,
+                          struct vm_area_struct *vma,
+                          unsigned long addr)
 {
-#ifdef BROKEN_ASN
        tbi(2 + ((vma->vm_flags & VM_EXEC) != 0), addr);
-#else
+}
+
+__EXTERN_INLINE void
+ev5_flush_tlb_current_page(struct mm_struct * mm,
+                          struct vm_area_struct *vma,
+                          unsigned long addr)
+{
        if (vma->vm_flags & VM_EXEC)
-               flush_tlb_current(mm);
+               ev5_flush_tlb_current(mm);
        else
                tbi(2, addr);
-#endif
 }
 
+
+#ifdef CONFIG_ALPHA_GENERIC
+# define flush_tlb_current             alpha_mv.mv_flush_tlb_current
+# define flush_tlb_other               alpha_mv.mv_flush_tlb_other
+# define flush_tlb_current_page                alpha_mv.mv_flush_tlb_current_page
+#else
+# ifdef CONFIG_ALPHA_EV4
+#  define flush_tlb_current            ev4_flush_tlb_current
+#  define flush_tlb_other              ev4_flush_tlb_other
+#  define flush_tlb_current_page       ev4_flush_tlb_current_page
+# else
+#  define flush_tlb_current            ev5_flush_tlb_current
+#  define flush_tlb_other              ev5_flush_tlb_other
+#  define flush_tlb_current_page       ev5_flush_tlb_current_page
+# endif
+#endif
+
+#ifdef __MMU_EXTERN_INLINE
+#undef __EXTERN_INLINE
+#undef __MMU_EXTERN_INLINE
+#endif
+
 /*
  * Flush current user mapping.
  */
index b98290660f326c12e29ef54c4096800420090ce2..3cbf6d573fbc2d7b1b2b10d701f9673a6c48e2b5 100644 (file)
@@ -34,6 +34,8 @@ typedef struct {
        int     val[2];
 } __kernel_fsid_t;
 
+#ifdef __KERNEL__
+
 #ifndef __GNUC__
 
 #define        __FD_SET(d, set)        ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
@@ -109,4 +111,6 @@ static __inline__ void __FD_ZERO(__kernel_fd_set *p)
 
 #endif /* __GNUC__ */
 
+#endif /* __KERNEL__ */
+
 #endif /* _ALPHA_POSIX_TYPES_H */
index dbeee15fbfb84b7990d068eb87faf8a715c69bb2..803ba998a317425010f5d05578d019af03b00982 100644 (file)
@@ -82,13 +82,23 @@ struct thread_struct {
  * holds provided the thread blocked through a call to schedule() ($15
  * is the frame pointer in schedule() and $15 is saved at offset 48 by
  * entry.S:do_switch_stack).
+ *
+ * Under heavy swap load I've seen this loose in an ugly way.  So do
+ * some extra sanity checking on the ranges we expect these pointers
+ * to be in so that we can fail gracefully.  This is just for ps after
+ * all.  -- r~
  */
 extern inline unsigned long thread_saved_pc(struct thread_struct *t)
 {
-       unsigned long fp;
-
-       fp = ((unsigned long*)t->ksp)[6];
-       return *(unsigned long*)fp;
+       unsigned long fp, sp = t->ksp, base = (unsigned long)t;
+       if (sp > base && sp+6*8 < base + 16*1024) {
+               fp = ((unsigned long*)sp)[6];
+               if (fp > sp && fp < base + 16*1024)
+                       return *(unsigned long *)fp;
+       }
+
+       return 0;
 }
 
 /*
diff --git a/include/asm-alpha/pyxis.h b/include/asm-alpha/pyxis.h
deleted file mode 100644 (file)
index 0369f48..0000000
+++ /dev/null
@@ -1,724 +0,0 @@
-#ifndef __ALPHA_PYXIS__H__
-#define __ALPHA_PYXIS__H__
-
-#include <linux/config.h>
-#include <linux/types.h>
-
-/*
- * PYXIS is the internal name for a core logic chipset which provides
- * memory controller and PCI access for the 21164A chip based systems.
- *
- * This file is based on:
- *
- * Pyxis Chipset Spec
- * 14-Jun-96
- * Rev. X2.0
- *
- */
-
-/*------------------------------------------------------------------------**
-**                                                                        **
-**  I/O procedures                                                   **
-**                                                                        **
-**      inport[b|w|t|l], outport[b|w|t|l] 8:16:24:32 IO xfers             **
-**     inportbxt: 8 bits only                                            **
-**      inport:    alias of inportw                                       **
-**      outport:   alias of outportw                                      **
-**                                                                        **
-**      inmem[b|w|t|l], outmem[b|w|t|l] 8:16:24:32 ISA memory xfers       **
-**     inmembxt: 8 bits only                                             **
-**      inmem:    alias of inmemw                                         **
-**      outmem:   alias of outmemw                                        **
-**                                                                        **
-**------------------------------------------------------------------------*/
-
-
-/* CIA ADDRESS BIT DEFINITIONS
- *
- *  3 3 3 3|3 3 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |1| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |0|0|0|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
- *  |                                                                        \_/ \_/
- *  |                                                                         |   |
- *  +-- IO space, not cached.                                   Byte Enable --+   |
- *                                                              Transfer Length --+
- *
- *
- *
- *   Byte      Transfer
- *   Enable    Length    Transfer  Byte    Address
- *   adr<6:5>  adr<4:3>  Length    Enable  Adder
- *   ---------------------------------------------
- *      00        00      Byte      1110   0x000
- *      01        00      Byte      1101   0x020
- *      10        00      Byte      1011   0x040
- *      11        00      Byte      0111   0x060
- *
- *      00        01      Word      1100   0x008
- *      01        01      Word      1001   0x028 <= Not supported in this code.
- *      10        01      Word      0011   0x048
- *
- *      00        10      Tribyte   1000   0x010
- *      01        10      Tribyte   0001   0x030
- *
- *      10        11      Longword  0000   0x058
- *
- *      Note that byte enables are asserted low.
- *
- */
-
-#define BYTE_ENABLE_SHIFT 5
-#define TRANSFER_LENGTH_SHIFT 3
-
-#define MEM_R1_MASK 0x1fffffff  /* SPARSE Mem region 1 mask is 29 bits */
-#define MEM_R2_MASK 0x07ffffff  /* SPARSE Mem region 2 mask is 27 bits */
-#define MEM_R3_MASK 0x03ffffff  /* SPARSE Mem region 3 mask is 26 bits */
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-/* if we are using the SRM PCI setup, we'll need to use variables instead */
-#define PYXIS_DMA_WIN_BASE_DEFAULT    (1024*1024*1024)
-#define PYXIS_DMA_WIN_SIZE_DEFAULT    (1024*1024*1024)
-
-extern unsigned int PYXIS_DMA_WIN_BASE;
-extern unsigned int PYXIS_DMA_WIN_SIZE;
-
-#else /* SRM_SETUP */
-#define PYXIS_DMA_WIN_BASE     (1024*1024*1024)
-#define PYXIS_DMA_WIN_SIZE     (1024*1024*1024)
-#endif /* SRM_SETUP */
-
-/*
- *  General Registers
- */
-#define PYXIS_REV                      (IDENT_ADDR + 0x8740000080UL)
-#define PYXIS_PCI_LAT                  (IDENT_ADDR + 0x87400000C0UL)
-#define PYXIS_CTRL                     (IDENT_ADDR + 0x8740000100UL)
-#define PYXIS_CTRL1                    (IDENT_ADDR + 0x8740000140UL)
-#define PYXIS_FLASH_CTRL               (IDENT_ADDR + 0x8740000200UL)
-
-#define PYXIS_HAE_MEM                  (IDENT_ADDR + 0x8740000400UL)
-#define PYXIS_HAE_IO                   (IDENT_ADDR + 0x8740000440UL)
-#define PYXIS_CFG                      (IDENT_ADDR + 0x8740000480UL)
-
-/*
- * Diagnostic Registers
- */
-#define PYXIS_DIAG                     (IDENT_ADDR + 0x8740002000UL)
-#define PYXIS_DIAG_CHECK               (IDENT_ADDR + 0x8740003000UL)
-
-/*
- * Performance Monitor registers
- */
-#define PYXIS_PERF_MONITOR             (IDENT_ADDR + 0x8740004000UL)
-#define PYXIS_PERF_CONTROL             (IDENT_ADDR + 0x8740004040UL)
-
-/*
- * Error registers
- */
-#define PYXIS_ERR                      (IDENT_ADDR + 0x8740008200UL)
-#define PYXIS_STAT                     (IDENT_ADDR + 0x8740008240UL)
-#define PYXIS_ERR_MASK                 (IDENT_ADDR + 0x8740008280UL)
-#define PYXIS_SYN                      (IDENT_ADDR + 0x8740008300UL)
-#define PYXIS_ERR_DATA                 (IDENT_ADDR + 0x8740008308UL)
-
-#define PYXIS_MEAR                     (IDENT_ADDR + 0x8740008400UL)
-#define PYXIS_MESR                     (IDENT_ADDR + 0x8740008440UL)
-#define PYXIS_PCI_ERR0                 (IDENT_ADDR + 0x8740008800UL)
-#define PYXIS_PCI_ERR1                 (IDENT_ADDR + 0x8740008840UL)
-#define PYXIS_PCI_ERR2                 (IDENT_ADDR + 0x8740008880UL)
-
-/*
- * PCI Address Translation Registers.
- */
-#define PYXIS_TBIA                     (IDENT_ADDR + 0x8760000100UL)
-
-#define PYXIS_W0_BASE                  (IDENT_ADDR + 0x8760000400UL)
-#define PYXIS_W0_MASK                  (IDENT_ADDR + 0x8760000440UL)
-#define PYXIS_T0_BASE                  (IDENT_ADDR + 0x8760000480UL)
-
-#define PYXIS_W1_BASE                  (IDENT_ADDR + 0x8760000500UL)
-#define PYXIS_W1_MASK                  (IDENT_ADDR + 0x8760000540UL)
-#define PYXIS_T1_BASE                  (IDENT_ADDR + 0x8760000580UL)
-
-#define PYXIS_W2_BASE                  (IDENT_ADDR + 0x8760000600UL)
-#define PYXIS_W2_MASK                  (IDENT_ADDR + 0x8760000640UL)
-#define PYXIS_T2_BASE                  (IDENT_ADDR + 0x8760000680UL)
-
-#define PYXIS_W3_BASE                  (IDENT_ADDR + 0x8760000700UL)
-#define PYXIS_W3_MASK                  (IDENT_ADDR + 0x8760000740UL)
-#define PYXIS_T3_BASE                  (IDENT_ADDR + 0x8760000780UL)
-
-/*
- * Memory Control registers
- */
-#define PYXIS_MCR                      (IDENT_ADDR + 0x8750000000UL)
-
-/*
- * Memory spaces:
- */
-#define PYXIS_IACK_SC                  (IDENT_ADDR + 0x8720000000UL)
-#define PYXIS_CONF                     (IDENT_ADDR + 0x8700000000UL)
-#define PYXIS_IO                       (IDENT_ADDR + 0x8580000000UL)
-#define PYXIS_SPARSE_MEM               (IDENT_ADDR + 0x8000000000UL)
-#define PYXIS_SPARSE_MEM_R2            (IDENT_ADDR + 0x8400000000UL)
-#define PYXIS_SPARSE_MEM_R3            (IDENT_ADDR + 0x8500000000UL)
-#define PYXIS_DENSE_MEM                        (IDENT_ADDR + 0x8600000000UL)
-#define DENSE_MEM(addr)                        PYXIS_DENSE_MEM
-
-/*
- * Byte/Word PCI Memory Spaces:
- */
-#define PYXIS_BW_MEM                   (IDENT_ADDR + 0x8800000000UL)
-#define PYXIS_BW_IO                    (IDENT_ADDR + 0x8900000000UL)
-#define PYXIS_BW_CFG_0                 (IDENT_ADDR + 0x8a00000000UL)
-#define PYXIS_BW_CFG_1                 (IDENT_ADDR + 0x8b00000000UL)
-
-/*
- * Interrupt Control registers
- */
-#define PYXIS_INT_REQ                  (IDENT_ADDR + 0x87A0000000UL)
-#define PYXIS_INT_MASK                 (IDENT_ADDR + 0x87A0000040UL)
-#define PYXIS_INT_HILO                 (IDENT_ADDR + 0x87A00000C0UL)
-#define PYXIS_INT_ROUTE                        (IDENT_ADDR + 0x87A0000140UL)
-#define PYXIS_GPO                      (IDENT_ADDR + 0x87A0000180UL)
-#define PYXIS_INT_CNFG                 (IDENT_ADDR + 0x87A00001C0UL)
-#define PYXIS_RT_COUNT                 (IDENT_ADDR + 0x87A0000200UL)
-#define PYXIS_INT_TIME                 (IDENT_ADDR + 0x87A0000240UL)
-#define PYXIS_IIC_CTRL                 (IDENT_ADDR + 0x87A00002C0UL)
-
-/*
- * Bit definitions for I/O Controller status register 0:
- */
-#define PYXIS_STAT0_CMD                        0xf
-#define PYXIS_STAT0_ERR                        (1<<4)
-#define PYXIS_STAT0_LOST               (1<<5)
-#define PYXIS_STAT0_THIT               (1<<6)
-#define PYXIS_STAT0_TREF               (1<<7)
-#define PYXIS_STAT0_CODE_SHIFT         8
-#define PYXIS_STAT0_CODE_MASK          0x7
-#define PYXIS_STAT0_P_NBR_SHIFT                13
-#define PYXIS_STAT0_P_NBR_MASK         0x7ffff
-
-#define HAE_ADDRESS                    PYXIS_HAE_MEM
-
-#ifdef __KERNEL__
-
-/*
- * Translate physical memory address as seen on (PCI) bus into
- * a kernel virtual address and vv.
- */
-#if defined(CONFIG_ALPHA_RUFFIAN)
-/* Ruffian doesn't do 1G PCI window */
-
-extern inline unsigned long virt_to_bus(void * address)
-{
-       return virt_to_phys(address);
-}
-
-extern inline void * bus_to_virt(unsigned long address)
-{
-       return phys_to_virt(address);
-}
-#else /* RUFFIAN */
-extern inline unsigned long virt_to_bus(void * address)
-{
-       return virt_to_phys(address) + PYXIS_DMA_WIN_BASE;
-}
-
-extern inline void * bus_to_virt(unsigned long address)
-{
-       return phys_to_virt(address - PYXIS_DMA_WIN_BASE);
-}
-#endif /* RUFFIAN */
-
-/*
- * I/O functions:
- *
- * PYXIS, the 21174 PCI/memory support chipset for the EV56 (21164A)
- * and PCA56 (21164PC) processors, can use either a sparse address
- * mapping scheme, or the so-called byte-word PCI address space, to
- * get at PCI memory and I/O.
- */
-
-#define vuip   volatile unsigned int *
-#define vulp   volatile unsigned long *
-
-#ifdef BWIO_ENABLED
-
-extern inline unsigned int __inb(unsigned long addr)
-{
-       register unsigned long result;
-
-       __asm__ __volatile__ (
-                "ldbu %0,%1"
-                : "=r" (result)
-                : "m"  (*(volatile unsigned char *)(addr+PYXIS_BW_IO)));
-
-       return result;
-}
-
-extern inline void __outb(unsigned char b, unsigned long addr)
-{
-       __asm__ __volatile__ (
-                "stb %1,%0\n\t"
-                "mb"
-                : "=m" (*(volatile unsigned char *)(addr+PYXIS_BW_IO))
-                : "r" (b));
-}
-
-extern inline unsigned int __inw(unsigned long addr)
-{
-       register unsigned long result;
-
-       __asm__ __volatile__ (
-                "ldwu %0,%1"
-                : "=r" (result)
-                : "m"  (*(volatile unsigned short *)(addr+PYXIS_BW_IO)));
-
-       return result;
-}
-
-extern inline void __outw(unsigned short b, unsigned long addr)
-{
-       __asm__ __volatile__ (
-                "stw %1,%0\n\t"
-                "mb"
-                : "=m" (*(volatile unsigned short *)(addr+PYXIS_BW_IO))
-                : "r" (b));
-}
-
-extern inline unsigned int __inl(unsigned long addr)
-{
-       return *(vuip)(addr+PYXIS_BW_IO);
-}
-
-extern inline void __outl(unsigned int b, unsigned long addr)
-{
-       *(vuip)(addr+PYXIS_BW_IO) = b;
-       mb();
-}
-
-#define inb(port) __inb((port))
-#define inw(port) __inw((port))
-#define inl(port) __inl((port))
-
-#define outb(x, port) __outb((x),(port))
-#define outw(x, port) __outw((x),(port))
-#define outl(x, port) __outl((x),(port))
-
-#else /* BWIO_ENABLED */
-
-extern inline unsigned int __inb(unsigned long addr)
-{
-       long result = *(vuip) ((addr << 5) + PYXIS_IO + 0x00);
-       result >>= (addr & 3) * 8;
-       return 0xffUL & result;
-}
-
-extern inline void __outb(unsigned char b, unsigned long addr)
-{
-       unsigned int w;
-
-       w = __kernel_insbl(b, addr & 3);
-       *(vuip) ((addr << 5) + PYXIS_IO + 0x00) = w;
-       mb();
-}
-
-extern inline unsigned int __inw(unsigned long addr)
-{
-       long result = *(vuip) ((addr << 5) + PYXIS_IO + 0x08);
-       result >>= (addr & 3) * 8;
-       return 0xffffUL & result;
-}
-
-extern inline void __outw(unsigned short b, unsigned long addr)
-{
-       unsigned int w;
-
-       w = __kernel_inswl(b, addr & 3);
-       *(vuip) ((addr << 5) + PYXIS_IO + 0x08) = w;
-       mb();
-}
-
-extern inline unsigned int __inl(unsigned long addr)
-{
-       return *(vuip) ((addr << 5) + PYXIS_IO + 0x18);
-}
-
-extern inline void __outl(unsigned int b, unsigned long addr)
-{
-       *(vuip) ((addr << 5) + PYXIS_IO + 0x18) = b;
-       mb();
-}
-
-#define inb(port) \
-(__builtin_constant_p((port))?__inb(port):_inb(port))
-
-#define outb(x, port) \
-(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port)))
-
-#endif /* BWIO_ENABLED */
-
-
-/*
- * Memory functions.  64-bit and 32-bit accesses are done through
- * dense memory space, everything else through sparse space.
- * 
- * For reading and writing 8 and 16 bit quantities we need to 
- * go through one of the three sparse address mapping regions
- * and use the HAE_MEM CSR to provide some bits of the address.
- * The following few routines use only sparse address region 1
- * which gives 1Gbyte of accessible space which relates exactly
- * to the amount of PCI memory mapping *into* system address space.
- * See p 6-17 of the specification but it looks something like this:
- *
- * 21164 Address:
- * 
- *          3         2         1                                                               
- * 9876543210987654321098765432109876543210
- * 1ZZZZ0.PCI.QW.Address............BBLL                 
- *
- * ZZ = SBZ
- * BB = Byte offset
- * LL = Transfer length
- *
- * PCI Address:
- *
- * 3         2         1                                                               
- * 10987654321098765432109876543210
- * HHH....PCI.QW.Address........ 00
- *
- * HHH = 31:29 HAE_MEM CSR
- * 
- */
-
-#ifdef BWIO_ENABLED
-
-extern inline unsigned long __readb(unsigned long addr)
-{
-       register unsigned long result;
-
-       __asm__ __volatile__ (
-                "ldbu %0,%1"
-                : "=r" (result)
-                : "m"  (*(volatile unsigned char *)(addr+PYXIS_BW_MEM)));
-
-       return result;
-}
-
-extern inline unsigned long __readw(unsigned long addr)
-{
-       register unsigned long result;
-
-       __asm__ __volatile__ (
-                "ldwu %0,%1"
-                : "=r" (result)
-                : "m"  (*(volatile unsigned short *)(addr+PYXIS_BW_MEM)));
-
-       return result;
-}
-
-extern inline unsigned long __readl(unsigned long addr)
-{
-       return *(vuip)(addr+PYXIS_BW_MEM);
-}
-
-extern inline unsigned long __readq(unsigned long addr)
-{
-       return *(vulp)(addr+PYXIS_BW_MEM);
-}
-
-extern inline void __writeb(unsigned char b, unsigned long addr)
-{
-       __asm__ __volatile__ (
-                "stb %1,%0\n\t"
-                "mb"
-                : "=m" (*(volatile unsigned char *)(addr+PYXIS_BW_MEM))
-                : "r" (b));
-}
-
-extern inline void __writew(unsigned short b, unsigned long addr)
-{
-       __asm__ __volatile__ (
-                "stw %1,%0\n\t"
-                "mb"
-                : "=m" (*(volatile unsigned short *)(addr+PYXIS_BW_MEM))
-                : "r" (b));
-}
-
-extern inline void __writel(unsigned int b, unsigned long addr)
-{
-       *(vuip)(addr+PYXIS_BW_MEM) = b;
-}
-
-extern inline void __writeq(unsigned long b, unsigned long addr)
-{
-       *(vulp)(addr+PYXIS_BW_MEM) = b;
-}
-
-#define readb(addr) __readb((addr))
-#define readw(addr) __readw((addr))
-
-#define writeb(b, addr) __writeb((b),(addr))
-#define writew(b, addr) __writew((b),(addr))
-
-#else /* BWIO_ENABLED */
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-
-extern unsigned long pyxis_sm_base_r1, pyxis_sm_base_r2, pyxis_sm_base_r3;
-
-extern inline unsigned long __readb(unsigned long addr)
-{
-       unsigned long result, shift, work;
-
-       if ((addr >= pyxis_sm_base_r1) &&
-           (addr <= (pyxis_sm_base_r1 + MEM_R1_MASK)))
-         work = (((addr & MEM_R1_MASK) << 5) + PYXIS_SPARSE_MEM + 0x00);
-       else
-       if ((addr >= pyxis_sm_base_r2) &&
-           (addr <= (pyxis_sm_base_r2 + MEM_R2_MASK)))
-         work = (((addr & MEM_R2_MASK) << 5) + PYXIS_SPARSE_MEM_R2 + 0x00);
-       else
-       if ((addr >= pyxis_sm_base_r3) &&
-           (addr <= (pyxis_sm_base_r3 + MEM_R3_MASK)))
-         work = (((addr & MEM_R3_MASK) << 5) + PYXIS_SPARSE_MEM_R3 + 0x00);
-       else
-       {
-#if 0
-         printk("__readb: address 0x%lx not covered by HAE\n", addr);
-#endif
-         return 0x0ffUL;
-       }
-       shift = (addr & 0x3) << 3;
-       result = *(vuip) work;
-       result >>= shift;
-       return 0x0ffUL & result;
-}
-
-extern inline unsigned long __readw(unsigned long addr)
-{
-       unsigned long result, shift, work;
-
-       if ((addr >= pyxis_sm_base_r1) &&
-           (addr <= (pyxis_sm_base_r1 + MEM_R1_MASK)))
-         work = (((addr & MEM_R1_MASK) << 5) + PYXIS_SPARSE_MEM + 0x08);
-       else
-       if ((addr >= pyxis_sm_base_r2) &&
-           (addr <= (pyxis_sm_base_r2 + MEM_R2_MASK)))
-         work = (((addr & MEM_R2_MASK) << 5) + PYXIS_SPARSE_MEM_R2 + 0x08);
-       else
-       if ((addr >= pyxis_sm_base_r3) &&
-           (addr <= (pyxis_sm_base_r3 + MEM_R3_MASK)))
-         work = (((addr & MEM_R3_MASK) << 5) + PYXIS_SPARSE_MEM_R3 + 0x08);
-       else
-       {
-#if 0
-         printk("__readw: address 0x%lx not covered by HAE\n", addr);
-#endif
-         return 0x0ffffUL;
-       }
-       shift = (addr & 0x3) << 3;
-       result = *(vuip) work;
-       result >>= shift;
-       return 0x0ffffUL & result;
-}
-
-extern inline void __writeb(unsigned char b, unsigned long addr)
-{
-       unsigned long work;
-
-       if ((addr >= pyxis_sm_base_r1) &&
-           (addr <= (pyxis_sm_base_r1 + MEM_R1_MASK)))
-         work = (((addr & MEM_R1_MASK) << 5) + PYXIS_SPARSE_MEM + 0x00);
-       else
-       if ((addr >= pyxis_sm_base_r2) &&
-           (addr <= (pyxis_sm_base_r2 + MEM_R2_MASK)))
-         work = (((addr & MEM_R2_MASK) << 5) + PYXIS_SPARSE_MEM_R2 + 0x00);
-       else
-       if ((addr >= pyxis_sm_base_r3) &&
-           (addr <= (pyxis_sm_base_r3 + MEM_R3_MASK)))
-         work = (((addr & MEM_R3_MASK) << 5) + PYXIS_SPARSE_MEM_R3 + 0x00);
-       else
-       {
-#if 0
-         printk("__writeb: address 0x%lx not covered by HAE\n", addr);
-#endif
-         return;
-       }
-       *(vuip) work = b * 0x01010101;
-}
-
-extern inline void __writew(unsigned short b, unsigned long addr)
-{
-       unsigned long work;
-
-       if ((addr >= pyxis_sm_base_r1) &&
-           (addr <= (pyxis_sm_base_r1 + MEM_R1_MASK)))
-         work = (((addr & MEM_R1_MASK) << 5) + PYXIS_SPARSE_MEM + 0x00);
-       else
-       if ((addr >= pyxis_sm_base_r2) &&
-           (addr <= (pyxis_sm_base_r2 + MEM_R2_MASK)))
-         work = (((addr & MEM_R2_MASK) << 5) + PYXIS_SPARSE_MEM_R2 + 0x00);
-       else
-       if ((addr >= pyxis_sm_base_r3) &&
-           (addr <= (pyxis_sm_base_r3 + MEM_R3_MASK)))
-         work = (((addr & MEM_R3_MASK) << 5) + PYXIS_SPARSE_MEM_R3 + 0x00);
-       else
-       {
-#if 0
-         printk("__writew: address 0x%lx not covered by HAE\n", addr);
-#endif
-         return;
-       }
-       *(vuip) work = b * 0x00010001;
-}
-
-#else /* SRM_SETUP */
-
-extern inline unsigned long __readb(unsigned long addr)
-{
-       unsigned long result, shift, msb, work, temp;
-
-       shift = (addr & 0x3) << 3;
-       msb = addr & 0xE0000000UL;
-       temp = addr & MEM_R1_MASK ;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       work = ((temp << 5) + PYXIS_SPARSE_MEM + 0x00);
-       result = *(vuip) work;
-       result >>= shift;
-       return 0x0ffUL & result;
-}
-
-extern inline unsigned long __readw(unsigned long addr)
-{
-       unsigned long result, shift, msb, work, temp;
-
-       shift = (addr & 0x3) << 3;
-       msb = addr & 0xE0000000UL;
-       temp = addr & MEM_R1_MASK ;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       work = ((temp << 5) + PYXIS_SPARSE_MEM + 0x08);
-       result = *(vuip) work;
-       result >>= shift;
-       return 0x0ffffUL & result;
-}
-
-extern inline void __writeb(unsigned char b, unsigned long addr)
-{
-        unsigned long msb ; 
-
-       msb = addr & 0xE0000000 ;
-       addr &= MEM_R1_MASK ;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       *(vuip) ((addr << 5) + PYXIS_SPARSE_MEM + 0x00) = b * 0x01010101;
-}
-
-extern inline void __writew(unsigned short b, unsigned long addr)
-{
-        unsigned long msb ; 
-
-       msb = addr & 0xE0000000 ;
-       addr &= MEM_R1_MASK ;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       *(vuip) ((addr << 5) + PYXIS_SPARSE_MEM + 0x08) = b * 0x00010001;
-}
-#endif /* SRM_SETUP */
-
-extern inline unsigned long __readl(unsigned long addr)
-{
-       return *(vuip) (addr + PYXIS_DENSE_MEM);
-}
-
-extern inline unsigned long __readq(unsigned long addr)
-{
-       return *(vulp) (addr + PYXIS_DENSE_MEM);
-}
-
-extern inline void __writel(unsigned int b, unsigned long addr)
-{
-       *(vuip) (addr + PYXIS_DENSE_MEM) = b;
-}
-
-extern inline void __writeq(unsigned long b, unsigned long addr)
-{
-       *(vulp) (addr + PYXIS_DENSE_MEM) = b;
-}
-
-#endif /* BWIO_ENABLED */
-
-#define readl(a)       __readl((unsigned long)(a))
-#define readq(a)       __readq((unsigned long)(a))
-#define writel(v,a)    __writel((v),(unsigned long)(a))
-#define writeq(v,a)    __writeq((v),(unsigned long)(a))
-
-#undef vuip
-#undef vulp
-
-extern unsigned long pyxis_init (unsigned long mem_start,
-                                unsigned long mem_end);
-
-#endif /* __KERNEL__ */
-
-/*
- * Data structure for handling PYXIS machine checks:
- */
-struct el_PYXIS_sysdata_mcheck {
-    u_long      coma_gcr;                       
-    u_long      coma_edsr;                      
-    u_long      coma_ter;                       
-    u_long      coma_elar;                      
-    u_long      coma_ehar;                      
-    u_long      coma_ldlr;                      
-    u_long      coma_ldhr;                      
-    u_long      coma_base0;                     
-    u_long      coma_base1;                     
-    u_long      coma_base2;                     
-    u_long      coma_cnfg0;                     
-    u_long      coma_cnfg1;                     
-    u_long      coma_cnfg2;                     
-    u_long      epic_dcsr;                      
-    u_long      epic_pear;                      
-    u_long      epic_sear;                      
-    u_long      epic_tbr1;                      
-    u_long      epic_tbr2;                      
-    u_long      epic_pbr1;                      
-    u_long      epic_pbr2;                      
-    u_long      epic_pmr1;                      
-    u_long      epic_pmr2;                      
-    u_long      epic_harx1;                     
-    u_long      epic_harx2;                     
-    u_long      epic_pmlt;                      
-    u_long      epic_tag0;                      
-    u_long      epic_tag1;                      
-    u_long      epic_tag2;                      
-    u_long      epic_tag3;                      
-    u_long      epic_tag4;                      
-    u_long      epic_tag5;                      
-    u_long      epic_tag6;                      
-    u_long      epic_tag7;                      
-    u_long      epic_data0;                     
-    u_long      epic_data1;                     
-    u_long      epic_data2;                     
-    u_long      epic_data3;                     
-    u_long      epic_data4;                     
-    u_long      epic_data5;                     
-    u_long      epic_data6;                     
-    u_long      epic_data7;                     
-};
-
-#define RTC_PORT(x)    (0x70 + (x))
-#define RTC_ADDR(x)    (0x80 | (x))
-#define RTC_ALWAYS_BCD 0
-
-#endif /* __ALPHA_PYXIS__H__ */
index e21e56eb1de75de0fd9445719469f98f067c306d..11495a0b689fd23970ac57baf5a4652801c5c3f1 100644 (file)
@@ -56,6 +56,8 @@ extern void * __memsetw(void *dest, unsigned short, size_t count);
  ? __constant_c_memset((s),0x0001000100010001UL*(unsigned short)(c),(n)) \
  : __memsetw((s),(c),(n)))
 
+extern int strcasecmp(const char *, const char *);
+
 #endif /* __KERNEL__ */
 
 #endif /* __ALPHA_STRING_H__ */
index 72b91317ef43134bb9347af0cc4bb4879c357ce9..a4f18c347ab20b6d54c8dece8f2a618225215e2f 100644 (file)
@@ -100,7 +100,7 @@ extern void wripir(unsigned long);
 
 #define switch_to(prev,next) do { \
        current = next; \
-       alpha_switch_to((unsigned long) &current->tss - 0xfffffc0000000000); \
+       alpha_switch_to((unsigned long) &current->tss - IDENT_ADDR); \
 } while (0)
 
 extern void alpha_switch_to(unsigned long pctxp);
@@ -108,6 +108,9 @@ extern void alpha_switch_to(unsigned long pctxp);
 #define mb() \
 __asm__ __volatile__("mb": : :"memory")
 
+#define wmb() \
+__asm__ __volatile__("wmb": : :"memory")
+
 #define imb() \
 __asm__ __volatile__ ("call_pal %0" : : "i" (PAL_imb) : "memory")
 
diff --git a/include/asm-alpha/t2.h b/include/asm-alpha/t2.h
deleted file mode 100644 (file)
index ec7100a..0000000
+++ /dev/null
@@ -1,671 +0,0 @@
-#ifndef __ALPHA_T2__H__
-#define __ALPHA_T2__H__
-
-#include <linux/config.h>
-#include <linux/types.h>
-
-/*
- * T2 is the internal name for the core logic chipset which provides
- * memory controller and PCI access for the SABLE-based systems.
- *
- * This file is based on:
- *
- * SABLE I/O Specification
- * Revision/Update Information: 1.3
- *
- * jestabro@amt.tay1.dec.com Initial Version.
- *
- */
-
-#define BYTE_ENABLE_SHIFT 5
-#define TRANSFER_LENGTH_SHIFT 3
-#define MEM_R1_MASK 0x03ffffff  /* Mem sparse space region 1 mask is 26 bits */
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-/* if we are using the SRM PCI setup, we'll need to use variables instead */
-#define T2_DMA_WIN_BASE_DEFAULT    (1024*1024*1024)
-#define T2_DMA_WIN_SIZE_DEFAULT    (1024*1024*1024)
-
-extern unsigned int T2_DMA_WIN_BASE;
-extern unsigned int T2_DMA_WIN_SIZE;
-
-#else /* SRM_SETUP */
-#define T2_DMA_WIN_BASE        (1024*1024*1024)
-#define T2_DMA_WIN_SIZE        (1024*1024*1024)
-#endif /* SRM_SETUP */
-
-/* GAMMA-SABLE is a SABLE with EV5-based CPUs */
-#ifdef CONFIG_ALPHA_GAMMA
-#  define GAMMA_BIAS           0x8000000000UL
-#else /* GAMMA */
-#  define GAMMA_BIAS           0x0000000000UL
-#endif /* GAMMA */
-
-/*
- * Memory spaces:
- */
-#define T2_CONF                        (IDENT_ADDR + GAMMA_BIAS + 0x390000000UL)
-#define T2_IO                  (IDENT_ADDR + GAMMA_BIAS + 0x3a0000000UL)
-#define T2_SPARSE_MEM          (IDENT_ADDR + GAMMA_BIAS + 0x200000000UL)
-#define T2_DENSE_MEM           (IDENT_ADDR + GAMMA_BIAS + 0x3c0000000UL)
-#define DENSE_MEM(addr)                T2_DENSE_MEM
-
-#define T2_IOCSR               (IDENT_ADDR + GAMMA_BIAS + 0x38e000000UL)
-#define T2_CERR1               (IDENT_ADDR + GAMMA_BIAS + 0x38e000020UL)
-#define T2_CERR2               (IDENT_ADDR + GAMMA_BIAS + 0x38e000040UL)
-#define T2_CERR3               (IDENT_ADDR + GAMMA_BIAS + 0x38e000060UL)
-#define T2_PERR1               (IDENT_ADDR + GAMMA_BIAS + 0x38e000080UL)
-#define T2_PERR2               (IDENT_ADDR + GAMMA_BIAS + 0x38e0000a0UL)
-#define T2_PSCR                        (IDENT_ADDR + GAMMA_BIAS + 0x38e0000c0UL)
-#define T2_HAE_1               (IDENT_ADDR + GAMMA_BIAS + 0x38e0000e0UL)
-#define T2_HAE_2               (IDENT_ADDR + GAMMA_BIAS + 0x38e000100UL)
-#define T2_HBASE               (IDENT_ADDR + GAMMA_BIAS + 0x38e000120UL)
-#define T2_WBASE1              (IDENT_ADDR + GAMMA_BIAS + 0x38e000140UL)
-#define T2_WMASK1              (IDENT_ADDR + GAMMA_BIAS + 0x38e000160UL)
-#define T2_TBASE1              (IDENT_ADDR + GAMMA_BIAS + 0x38e000180UL)
-#define T2_WBASE2              (IDENT_ADDR + GAMMA_BIAS + 0x38e0001a0UL)
-#define T2_WMASK2              (IDENT_ADDR + GAMMA_BIAS + 0x38e0001c0UL)
-#define T2_TBASE2              (IDENT_ADDR + GAMMA_BIAS + 0x38e0001e0UL)
-#define T2_TLBBR               (IDENT_ADDR + GAMMA_BIAS + 0x38e000200UL)
-
-#define T2_HAE_3               (IDENT_ADDR + GAMMA_BIAS + 0x38e000240UL)
-#define T2_HAE_4               (IDENT_ADDR + GAMMA_BIAS + 0x38e000260UL)
-
-#define HAE_ADDRESS                    T2_HAE_1
-
-/*  T2 CSRs are in the non-cachable primary IO space from 3.8000.0000 to
- 3.8fff.ffff
- *
- *  +--------------+ 3 8000 0000
- *  | CPU 0 CSRs   |            
- *  +--------------+ 3 8100 0000
- *  | CPU 1 CSRs   |            
- *  +--------------+ 3 8200 0000
- *  | CPU 2 CSRs   |            
- *  +--------------+ 3 8300 0000
- *  | CPU 3 CSRs   |            
- *  +--------------+ 3 8400 0000
- *  | CPU Reserved |            
- *  +--------------+ 3 8700 0000
- *  | Mem Reserved |            
- *  +--------------+ 3 8800 0000
- *  | Mem 0 CSRs   |            
- *  +--------------+ 3 8900 0000
- *  | Mem 1 CSRs   |            
- *  +--------------+ 3 8a00 0000
- *  | Mem 2 CSRs   |            
- *  +--------------+ 3 8b00 0000
- *  | Mem 3 CSRs   |            
- *  +--------------+ 3 8c00 0000           
- *  | Mem Reserved |            
- *  +--------------+ 3 8e00 0000           
- *  | PCI Bridge   |            
- *  +--------------+ 3 8f00 0000           
- *  | Expansion IO |            
- *  +--------------+ 3 9000 0000           
- *                                              
- *
- */
-#define CPU0_BASE               (IDENT_ADDR + GAMMA_BIAS + 0x380000000L)
-#define CPU1_BASE               (IDENT_ADDR + GAMMA_BIAS + 0x381000000L)
-#define CPU2_BASE               (IDENT_ADDR + GAMMA_BIAS + 0x382000000L)
-#define CPU3_BASE               (IDENT_ADDR + GAMMA_BIAS + 0x383000000L)
-#define MEM0_BASE               (IDENT_ADDR + GAMMA_BIAS + 0x388000000L)
-#define MEM1_BASE               (IDENT_ADDR + GAMMA_BIAS + 0x389000000L)
-#define MEM2_BASE               (IDENT_ADDR + GAMMA_BIAS + 0x38a000000L)
-#define MEM3_BASE               (IDENT_ADDR + GAMMA_BIAS + 0x38b000000L)
-
-#ifdef __KERNEL__
-
-/*
- * Translate physical memory address as seen on (PCI) bus into
- * a kernel virtual address and vv.
- */
-extern inline unsigned long virt_to_bus(void * address)
-{
-       return virt_to_phys(address) + T2_DMA_WIN_BASE;
-}
-
-extern inline void * bus_to_virt(unsigned long address)
-{
-       return phys_to_virt(address - T2_DMA_WIN_BASE);
-}
-
-/*
- * I/O functions:
- *
- * T2 (the core logic PCI/memory support chipset for the SABLE
- * series of processors uses a sparse address mapping scheme to
- * get at PCI memory and I/O.
- */
-
-#define vuip   volatile unsigned int *
-
-extern inline unsigned int __inb(unsigned long addr)
-{
-       long result = *(vuip) ((addr << 5) + T2_IO + 0x00);
-       result >>= (addr & 3) * 8;
-       return 0xffUL & result;
-}
-
-extern inline void __outb(unsigned char b, unsigned long addr)
-{
-       unsigned int w;
-
-       w = __kernel_insbl(b, addr & 3);
-       *(vuip) ((addr << 5) + T2_IO + 0x00) = w;
-       mb();
-}
-
-extern inline unsigned int __inw(unsigned long addr)
-{
-       long result = *(vuip) ((addr << 5) + T2_IO + 0x08);
-       result >>= (addr & 3) * 8;
-       return 0xffffUL & result;
-}
-
-extern inline void __outw(unsigned short b, unsigned long addr)
-{
-       unsigned int w;
-
-       w = __kernel_inswl(b, addr & 3);
-       *(vuip) ((addr << 5) + T2_IO + 0x08) = w;
-       mb();
-}
-
-extern inline unsigned int __inl(unsigned long addr)
-{
-       return *(vuip) ((addr << 5) + T2_IO + 0x18);
-}
-
-extern inline void __outl(unsigned int b, unsigned long addr)
-{
-       *(vuip) ((addr << 5) + T2_IO + 0x18) = b;
-       mb();
-}
-
-
-/*
- * Memory functions.  64-bit and 32-bit accesses are done through
- * dense memory space, everything else through sparse space.
- * 
- * For reading and writing 8 and 16 bit quantities we need to 
- * go through one of the three sparse address mapping regions
- * and use the HAE_MEM CSR to provide some bits of the address.
- * The following few routines use only sparse address region 1
- * which gives 1Gbyte of accessible space which relates exactly
- * to the amount of PCI memory mapping *into* system address space.
- * See p 6-17 of the specification but it looks something like this:
- *
- * 21164 Address:
- * 
- *          3         2         1                                                               
- * 9876543210987654321098765432109876543210
- * 1ZZZZ0.PCI.QW.Address............BBLL                 
- *
- * ZZ = SBZ
- * BB = Byte offset
- * LL = Transfer length
- *
- * PCI Address:
- *
- * 3         2         1                                                               
- * 10987654321098765432109876543210
- * HHH....PCI.QW.Address........ 00
- *
- * HHH = 31:29 HAE_MEM CSR
- * 
- */
-#ifdef CONFIG_ALPHA_SRM_SETUP
-
-extern unsigned long t2_sm_base;
-
-extern int __t2_ioaddr_check(unsigned long addr)
-{
-       if ((addr >= t2_sm_base && addr <= t2_sm_base + MEM_R1_MASK)
-           || (addr >= 512*1024 && addr < 1024*1024))
-               return 1;
-#if 0
-         printk("T2: address 0x%lx not covered by HAE\n", addr);
-#endif
-       return 0;
-}
-
-
-extern inline unsigned long __readb(unsigned long addr)
-{
-       unsigned long result, shift, work;
-
-       if (!__t2_addr_check(addr))
-               return 0xFF;
-
-       work = (((addr & MEM_R1_MASK) << 5) + T2_SPARSE_MEM + 0x00);
-       result = *(vuip) work;
-       shift = (addr & 0x3) << 3;
-       return (result >> shift) & 0xFF;
-}
-
-extern inline unsigned long __readw(unsigned long addr)
-{
-       unsigned long result, shift, work;
-
-       if (!__t2_addr_check(addr))
-               return 0xFFFF;
-
-       work = (((addr & MEM_R1_MASK) << 5) + T2_SPARSE_MEM + 0x08);
-       result = *(vuip) work;
-       shift = (addr & 0x3) << 3;
-       return (result >> shift) & 0xFF;
-}
-
-/* On SABLE with T2, we must use SPARSE memory even for 32-bit access ... */
-extern inline unsigned long __readl(unsigned long addr)
-{
-       unsigned long work;
-
-       if (!__t2_addr_check(addr))
-               return 0xFFFFFFFF;
-
-       work = (((addr & MEM_R1_MASK) << 5) + T2_SPARSE_MEM + 0x18);
-       return *(vuip) work;
-}
-
-/* ... which makes me wonder why we advertise we have DENSE memory at all.
-   Anyway, guess that means we should emulate 64-bit access as two cycles.  */
-extern inline unsigned long __readq(unsigned long addr)
-{
-       unsigned long work, r0, r1;
-
-       if (!__t2_addr_check(addr))
-               return ~0UL;
-
-       work = (((addr & MEM_R1_MASK) << 5) + T2_SPARSE_MEM + 0x18);
-       r0 = *(vuip) work0;
-       r1 = *(vuip) (work0 + (4 << 5));
-       return r1 << 32 | r0;
-}
-
-extern inline void __writeb(unsigned char b, unsigned long addr)
-{
-       unsigned long work;
-
-       if (!__t2_addr_check(addr))
-               return;
-
-       work = (((addr & MEM_R1_MASK) << 5) + T2_SPARSE_MEM + 0x00);
-       *(vuip) work = b * 0x01010101;
-}
-
-extern inline void __writew(unsigned short b, unsigned long addr)
-{
-       unsigned long work;
-
-       if (!__t2_addr_check(addr))
-               return;
-
-       work = (((addr & MEM_R1_MASK) << 5) + T2_SPARSE_MEM + 0x08);
-       *(vuip) work = b * 0x00010001;
-}
-
-/* On SABLE with T2, we must use SPARSE memory even for 32-bit access ... */
-extern inline void __writel(unsigned int b, unsigned long addr)
-{
-       unsigned long work;
-
-       if (!__t2_addr_check(addr))
-               return;
-
-       work = (((addr & MEM_R1_MASK) << 5) + T2_SPARSE_MEM + 0x18);
-       *(vuip) work = b;
-}
-
-/* ... which makes me wonder why we advertise we have DENSE memory at all.
-   Anyway, guess that means we should emulate 64-bit access as two cycles.  */
-extern inline void __writeq(unsigned long b, unsigned long addr)
-{
-       unsigned long work;
-
-       if (!__t2_addr_check(addr))
-               return;
-
-       work = (((addr & MEM_R1_MASK) << 5) + T2_SPARSE_MEM + 0x18);
-       *(vuip) work0 = b;
-       *(vuip) (work0 + (4 << 5)) = (b >> 32);
-}
-
-#else /* SRM_SETUP */
-
-extern inline unsigned long __readb(unsigned long addr)
-{
-       unsigned long result, shift, msb;
-
-       shift = (addr & 0x3) * 8 ;
-       msb = addr & 0xE0000000 ;
-       addr &= MEM_R1_MASK ;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       result = *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x00) ;
-       result >>= shift;
-       return 0xffUL & result;
-}
-
-extern inline unsigned long __readw(unsigned long addr)
-{
-       unsigned long result, shift, msb;
-
-       shift = (addr & 0x3) * 8;
-       msb = addr & 0xE0000000 ;
-       addr &= MEM_R1_MASK ;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       result = *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x08);
-       result >>= shift;
-       return 0xffffUL & result;
-}
-
-/* on SABLE with T2, we must use SPARSE memory even for 32-bit access */
-extern inline unsigned long __readl(unsigned long addr)
-{
-       unsigned long result, msb;
-
-       msb = addr & 0xE0000000 ;
-       addr &= MEM_R1_MASK ;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       result = *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x18);
-       return 0xffffffffUL & result;
-}
-
-extern inline unsigned long __readq(unsigned long addr)
-{
-       unsigned long r0, r1, work, msb;
-
-       msb = addr & 0xE0000000 ;
-       addr &= MEM_R1_MASK ;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       work = (addr << 5) + T2_SPARSE_MEM + 0x18;
-       r0 = *(vuip)(work);
-       r1 = *(vuip)(work + (4 << 5));
-       return r1 << 32 | r0;
-}
-extern inline void __writeb(unsigned char b, unsigned long addr)
-{
-        unsigned long msb ; 
-
-       msb = addr & 0xE0000000 ;
-       addr &= MEM_R1_MASK ;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x00) = b * 0x01010101;
-}
-
-extern inline void __writew(unsigned short b, unsigned long addr)
-{
-        unsigned long msb ; 
-
-       msb = addr & 0xE0000000 ;
-       addr &= MEM_R1_MASK ;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x08) = b * 0x00010001;
-}
-
-/* on SABLE with T2, we must use SPARSE memory even for 32-bit access */
-extern inline void __writel(unsigned int b, unsigned long addr)
-{
-        unsigned long msb ; 
-
-       msb = addr & 0xE0000000 ;
-       addr &= MEM_R1_MASK ;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       *(vuip) ((addr << 5) + T2_SPARSE_MEM + 0x18) = b;
-}
-
-extern inline void __writeq(unsigned long b, unsigned long addr)
-{
-        unsigned long msb, work;
-
-       msb = addr & 0xE0000000 ;
-       addr &= MEM_R1_MASK ;
-       if (msb != hae.cache) {
-         set_hae(msb);
-       }
-       work = (addr << 5) + T2_SPARSE_MEM + 0x18;
-       *(vuip)work = b;
-       *(vuip)(work + (4 << 5)) = b >> 32;
-}
-
-#endif /* SRM_SETUP */
-
-#define inb(port) \
-(__builtin_constant_p((port))?__inb(port):_inb(port))
-
-#define outb(x, port) \
-(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port)))
-
-#undef vuip
-
-extern unsigned long t2_init (unsigned long mem_start,
-                                unsigned long mem_end);
-
-#endif /* __KERNEL__ */
-
-/*
- * Sable CPU Module CSRS
- *
- * These are CSRs for hardware other than the CPU chip on the CPU module.
- * The CPU module has Backup Cache control logic, Cbus control logic, and
- * interrupt control logic on it.  There is a duplicate tag store to speed
- * up maintaining cache coherency.
- */
-
-struct sable_cpu_csr {
-unsigned long bcc;     long fill_00[3]; /* Backup Cache Control */
-unsigned long bcce;    long fill_01[3]; /* Backup Cache Correctable Error */
-unsigned long bccea;   long fill_02[3]; /* B-Cache Corr Err Address Latch */
-unsigned long bcue;    long fill_03[3]; /* B-Cache Uncorrectable Error */
-unsigned long bcuea;   long fill_04[3]; /* B-Cache Uncorr Err Addr Latch */
-unsigned long dter;    long fill_05[3]; /* Duplicate Tag Error */
-unsigned long cbctl;   long fill_06[3]; /* CBus Control */
-unsigned long cbe;     long fill_07[3]; /* CBus Error */
-unsigned long cbeal;   long fill_08[3]; /* CBus Error Addr Latch low */
-unsigned long cbeah;   long fill_09[3]; /* CBus Error Addr Latch high */
-unsigned long pmbx;    long fill_10[3]; /* Processor Mailbox */
-unsigned long ipir;    long fill_11[3]; /* Inter-Processor Int Request */
-unsigned long sic;     long fill_12[3]; /* System Interrupt Clear */
-unsigned long adlk;    long fill_13[3]; /* Address Lock (LDxL/STxC) */
-unsigned long madrl;   long fill_14[3]; /* CBus Miss Address */
-unsigned long rev;     long fill_15[3]; /* CMIC Revision */
-};
-
-/*
- * Data structure for handling T2 machine checks:
- */
-struct el_t2_frame_header {
-       unsigned int    elcf_fid;       /* Frame ID (from above) */
-       unsigned int    elcf_size;      /* Size of frame in bytes */
-};
-
-struct el_t2_procdata_mcheck {
-       unsigned long   elfmc_paltemp[32];      /* PAL TEMP REGS. */
-       /* EV4-specific fields */
-       unsigned long   elfmc_exc_addr; /* Addr of excepting insn. */
-       unsigned long   elfmc_exc_sum;  /* Summary of arith traps. */
-       unsigned long   elfmc_exc_mask; /* Exception mask (from exc_sum). */
-       unsigned long   elfmc_iccsr;    /* IBox hardware enables. */
-       unsigned long   elfmc_pal_base; /* Base address for PALcode. */
-       unsigned long   elfmc_hier;     /* Hardware Interrupt Enable. */
-       unsigned long   elfmc_hirr;     /* Hardware Interrupt Request. */
-       unsigned long   elfmc_mm_csr;   /* D-stream fault info. */
-       unsigned long   elfmc_dc_stat;  /* D-cache status (ECC/Parity Err). */
-       unsigned long   elfmc_dc_addr;  /* EV3 Phys Addr for ECC/DPERR. */
-       unsigned long   elfmc_abox_ctl; /* ABox Control Register. */
-       unsigned long   elfmc_biu_stat; /* BIU Status. */
-       unsigned long   elfmc_biu_addr; /* BUI Address. */
-       unsigned long   elfmc_biu_ctl;  /* BIU Control. */
-       unsigned long   elfmc_fill_syndrome;    /* For correcting ECC errors. */
-       unsigned long   elfmc_fill_addr;/* Cache block which was being read. */
-       unsigned long   elfmc_va;       /* Effective VA of fault or miss. */
-       unsigned long   elfmc_bc_tag;   /* Backup Cache Tag Probe Results. */
-};
-
-/* 
- * Sable processor specific Machine Check Data segment.
- */
-
-struct el_t2_logout_header {
-       unsigned int    elfl_size;      /* size in bytes of logout area. */
-       int     elfl_sbz1:31;           /* Should be zero. */
-       char    elfl_retry:1;           /* Retry flag. */
-        unsigned int   elfl_procoffset;        /* Processor-specific offset. */
-       unsigned int    elfl_sysoffset;         /* Offset of system-specific. */
-       unsigned int    elfl_error_type;        /* PAL error type code. */
-       unsigned int    elfl_frame_rev;         /* PAL Frame revision. */
-};
-struct el_t2_sysdata_mcheck {
-       unsigned long    elcmc_bcc;           /* CSR 0 */
-       unsigned long    elcmc_bcce;          /* CSR 1 */
-       unsigned long    elcmc_bccea;      /* CSR 2 */
-       unsigned long    elcmc_bcue;          /* CSR 3 */
-       unsigned long    elcmc_bcuea;      /* CSR 4 */
-       unsigned long    elcmc_dter;          /* CSR 5 */
-       unsigned long    elcmc_cbctl;      /* CSR 6 */
-       unsigned long    elcmc_cbe;           /* CSR 7 */
-       unsigned long    elcmc_cbeal;      /* CSR 8 */
-       unsigned long    elcmc_cbeah;      /* CSR 9 */
-       unsigned long    elcmc_pmbx;          /* CSR 10 */
-       unsigned long    elcmc_ipir;          /* CSR 11 */
-       unsigned long    elcmc_sic;           /* CSR 12 */
-       unsigned long    elcmc_adlk;          /* CSR 13 */
-       unsigned long    elcmc_madrl;      /* CSR 14 */
-       unsigned long    elcmc_crrev4;     /* CSR 15 */
-};
-
-/*
- * Sable memory error frame - sable pfms section 3.42
- */
-struct el_t2_data_memory {
-       struct  el_t2_frame_header elcm_hdr;    /* ID$MEM-FERR = 0x08 */
-       unsigned int  elcm_module;      /* Module id. */
-       unsigned int  elcm_res04;       /* Reserved. */
-       unsigned long elcm_merr;        /* CSR0: Error Reg 1. */
-       unsigned long elcm_mcmd1;       /* CSR1: Command Trap 1. */
-       unsigned long elcm_mcmd2;       /* CSR2: Command Trap 2. */
-       unsigned long elcm_mconf;       /* CSR3: Configuration. */
-       unsigned long elcm_medc1;       /* CSR4: EDC Status 1. */
-       unsigned long elcm_medc2;       /* CSR5: EDC Status 2. */
-       unsigned long elcm_medcc;       /* CSR6: EDC Control. */
-       unsigned long elcm_msctl;       /* CSR7: Stream Buffer Control. */
-       unsigned long elcm_mref;        /* CSR8: Refresh Control. */
-       unsigned long elcm_filter;      /* CSR9: CRD Filter Control. */
-};
-
-
-/*
- * Sable other CPU error frame - sable pfms section 3.43
- */
-struct el_t2_data_other_cpu {
-       short         elco_cpuid;       /* CPU ID */
-       short         elco_res02[3];    
-       unsigned long elco_bcc; /* CSR 0 */
-       unsigned long elco_bcce;        /* CSR 1 */
-       unsigned long elco_bccea;       /* CSR 2 */
-       unsigned long elco_bcue;        /* CSR 3 */
-       unsigned long elco_bcuea;       /* CSR 4 */
-       unsigned long elco_dter;        /* CSR 5 */
-       unsigned long elco_cbctl;       /* CSR 6 */
-       unsigned long elco_cbe; /* CSR 7 */
-       unsigned long elco_cbeal;       /* CSR 8 */
-       unsigned long elco_cbeah;       /* CSR 9 */
-       unsigned long elco_pmbx;        /* CSR 10 */
-       unsigned long elco_ipir;        /* CSR 11 */
-       unsigned long elco_sic; /* CSR 12 */
-       unsigned long elco_adlk;        /* CSR 13 */
-       unsigned long elco_madrl;       /* CSR 14 */
-       unsigned long elco_crrev4;      /* CSR 15 */
-};
-
-/*
- * Sable other CPU error frame - sable pfms section 3.44
- */
-struct el_t2_data_t2{
-        struct el_t2_frame_header elct_hdr;    /* ID$T2-FRAME */
-       unsigned long elct_iocsr;       /* IO Control and Status Register */
-       unsigned long elct_cerr1;       /* Cbus Error Register 1 */
-       unsigned long elct_cerr2;       /* Cbus Error Register 2 */
-       unsigned long elct_cerr3;       /* Cbus Error Register 3 */
-       unsigned long elct_perr1;       /* PCI Error Register 1 */
-       unsigned long elct_perr2;       /* PCI Error Register 2 */
-       unsigned long elct_hae0_1;      /* High Address Extension Register 1 */
-       unsigned long elct_hae0_2;      /* High Address Extension Register 2 */
-       unsigned long elct_hbase;       /* High Base Register */
-       unsigned long elct_wbase1;      /* Window Base Register 1 */
-       unsigned long elct_wmask1;      /* Window Mask Register 1 */
-       unsigned long elct_tbase1;      /* Translated Base Register 1 */
-       unsigned long elct_wbase2;      /* Window Base Register 2 */
-       unsigned long elct_wmask2;      /* Window Mask Register 2 */
-       unsigned long elct_tbase2;      /* Translated Base Register 2 */
-       unsigned long elct_tdr0;        /* TLB Data Register 0 */
-       unsigned long elct_tdr1;        /* TLB Data Register 1 */
-       unsigned long elct_tdr2;        /* TLB Data Register 2 */
-       unsigned long elct_tdr3;        /* TLB Data Register 3 */
-       unsigned long elct_tdr4;        /* TLB Data Register 4 */
-       unsigned long elct_tdr5;        /* TLB Data Register 5 */
-       unsigned long elct_tdr6;        /* TLB Data Register 6 */
-       unsigned long elct_tdr7;        /* TLB Data Register 7 */
-};
-
-/*
- * Sable error log data structure - sable pfms section 3.40
- */
-struct el_t2_data_corrected {
-       unsigned long elcpb_biu_stat;
-       unsigned long elcpb_biu_addr;
-       unsigned long elcpb_biu_ctl;
-       unsigned long elcpb_fill_syndrome;
-       unsigned long elcpb_fill_addr;
-       unsigned long elcpb_bc_tag;
-};
-
-/* 
- * Sable error log data structure
- * Note there are 4 memory slots on sable (see t2.h)
- */
-struct el_t2_frame_mcheck {
-        struct el_t2_frame_header elfmc_header;        /* ID$P-FRAME_MCHECK */
-       struct el_t2_logout_header elfmc_hdr;
-       struct el_t2_procdata_mcheck elfmc_procdata;
-       struct el_t2_sysdata_mcheck elfmc_sysdata;
-       struct el_t2_data_t2 elfmc_t2data;
-       struct el_t2_data_memory elfmc_memdata[4]; 
-        struct el_t2_frame_header elfmc_footer;        /* empty */
-};
-
-
-/* 
- * Sable error log data structures on memory errors
- */
-struct el_t2_frame_corrected {
-        struct el_t2_frame_header elfcc_header;        /* ID$P-BC-COR */
-       struct el_t2_logout_header elfcc_hdr;
-       struct el_t2_data_corrected elfcc_procdata; 
-/*     struct el_t2_data_t2 elfcc_t2data;              */
-/*     struct el_t2_data_memory elfcc_memdata[4];      */
-        struct el_t2_frame_header elfcc_footer;        /* empty */
-};
-
-
-#define RTC_PORT(x)    (0x70 + (x))
-#define RTC_ADDR(x)    (0x80 | (x))
-#define RTC_ALWAYS_BCD 0
-
-#endif /* __ALPHA_T2__H__ */
diff --git a/include/asm-alpha/tsunami.h b/include/asm-alpha/tsunami.h
deleted file mode 100644 (file)
index fe48e28..0000000
+++ /dev/null
@@ -1,451 +0,0 @@
-#ifndef __ALPHA_TSUNAMI__H__
-#define __ALPHA_TSUNAMI__H__
-
-#include <linux/config.h>
-#include <linux/types.h>
-
-/*
- * TSUNAMI/TYPHOON are the internal names for the core logic chipset which
- * provides memory controller and PCI access for the 21264 based systems.
- *
- * This file is based on:
- *
- * Tsunami System Programmers Manual
- * Preliminary, Chapters 2-5
- *
- */
-
-#define BYTE_ENABLE_SHIFT 5
-#define TRANSFER_LENGTH_SHIFT 3
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
-/* if we are using the SRM PCI setup, we'll need to use variables instead */
-#define TSUNAMI_DMA_WIN_BASE_DEFAULT    (1024*1024*1024)
-#define TSUNAMI_DMA_WIN_SIZE_DEFAULT    (1024*1024*1024)
-
-extern unsigned int TSUNAMI_DMA_WIN_BASE;
-extern unsigned int TSUNAMI_DMA_WIN_SIZE;
-
-#else /* SRM_SETUP */
-#define TSUNAMI_DMA_WIN_BASE   (1024*1024*1024)
-#define TSUNAMI_DMA_WIN_SIZE   (1024*1024*1024)
-#endif /* SRM_SETUP */
-
-#ifdef USE_48_BIT_KSEG
-#define TS_BIAS 0x80000000000UL
-#else
-#define TS_BIAS 0x10000000000UL
-#endif
-
-/*
- * CChip and DChip registers
- */
-#define        TSUNAMI_CSR_CSC         (IDENT_ADDR + TS_BIAS + 0x1A0000000UL)
-#define        TSUNAMI_CSR_MTR         (IDENT_ADDR + TS_BIAS + 0x1A0000040UL)
-#define        TSUNAMI_CSR_MISC        (IDENT_ADDR + TS_BIAS + 0x1A0000080UL)
-#define        TSUNAMI_CSR_MPD         (IDENT_ADDR + TS_BIAS + 0x1A00000C0UL)
-#define        TSUNAMI_CSR_AAR0        (IDENT_ADDR + TS_BIAS + 0x1A0000100UL)
-#define        TSUNAMI_CSR_AAR1        (IDENT_ADDR + TS_BIAS + 0x1A0000140UL)
-#define        TSUNAMI_CSR_AAR2        (IDENT_ADDR + TS_BIAS + 0x1A0000180UL)
-#define        TSUNAMI_CSR_AAR3        (IDENT_ADDR + TS_BIAS + 0x1A00001C0UL)
-#define        TSUNAMI_CSR_DIM0        (IDENT_ADDR + TS_BIAS + 0x1A0000200UL)
-#define        TSUNAMI_CSR_DIM1        (IDENT_ADDR + TS_BIAS + 0x1A0000240UL)
-#define        TSUNAMI_CSR_DIR0        (IDENT_ADDR + TS_BIAS + 0x1A0000280UL)
-#define        TSUNAMI_CSR_DIR1        (IDENT_ADDR + TS_BIAS + 0x1A00002C0UL)
-
-#define        TSUNAMI_CSR_DRIR        (IDENT_ADDR + TS_BIAS + 0x1A0000300UL)
-#define        TSUNAMI_CSR_PRBEN       (IDENT_ADDR + TS_BIAS + 0x1A0000340UL)
-#define        TSUNAMI_CSR_IIC         (IDENT_ADDR + TS_BIAS + 0x1A0000380UL)
-#define        TSUNAMI_CSR_WDR         (IDENT_ADDR + TS_BIAS + 0x1A00003C0UL)
-#define        TSUNAMI_CSR_MPR0        (IDENT_ADDR + TS_BIAS + 0x1A0000400UL)
-#define        TSUNAMI_CSR_MPR1        (IDENT_ADDR + TS_BIAS + 0x1A0000440UL)
-#define        TSUNAMI_CSR_MPR2        (IDENT_ADDR + TS_BIAS + 0x1A0000480UL)
-#define        TSUNAMI_CSR_MPR3        (IDENT_ADDR + TS_BIAS + 0x1A00004C0UL)
-#define        TSUNAMI_CSR_TTR         (IDENT_ADDR + TS_BIAS + 0x1A0000580UL)
-#define        TSUNAMI_CSR_TDR         (IDENT_ADDR + TS_BIAS + 0x1A00005C0UL)
-#define        TSUNAMI_CSR_DSC         (IDENT_ADDR + TS_BIAS + 0x1B0000800UL)
-#define        TSUNAMI_CSR_STR         (IDENT_ADDR + TS_BIAS + 0x1B0000840UL)
-#define        TSUNAMI_CSR_DREV        (IDENT_ADDR + TS_BIAS + 0x1B0000880UL)
-
-/*
- * PChip registers
- */
-#define        TSUNAMI_PCHIP0_WSBA0    (IDENT_ADDR + TS_BIAS + 0x180000000UL)
-#define        TSUNAMI_PCHIP0_WSBA1    (IDENT_ADDR + TS_BIAS + 0x180000040UL)
-#define        TSUNAMI_PCHIP0_WSBA2    (IDENT_ADDR + TS_BIAS + 0x180000080UL)
-#define        TSUNAMI_PCHIP0_WSBA3    (IDENT_ADDR + TS_BIAS + 0x1800000C0UL)
-
-#define        TSUNAMI_PCHIP0_WSM0     (IDENT_ADDR + TS_BIAS + 0x180000100UL)
-#define        TSUNAMI_PCHIP0_WSM1     (IDENT_ADDR + TS_BIAS + 0x180000140UL)
-#define        TSUNAMI_PCHIP0_WSM2     (IDENT_ADDR + TS_BIAS + 0x180000180UL)
-#define        TSUNAMI_PCHIP0_WSM3     (IDENT_ADDR + TS_BIAS + 0x1800001C0UL)
-#define        TSUNAMI_PCHIP0_TBA0     (IDENT_ADDR + TS_BIAS + 0x180000200UL)
-#define        TSUNAMI_PCHIP0_TBA1     (IDENT_ADDR + TS_BIAS + 0x180000240UL)
-#define        TSUNAMI_PCHIP0_TBA2     (IDENT_ADDR + TS_BIAS + 0x180000280UL)
-#define        TSUNAMI_PCHIP0_TBA3     (IDENT_ADDR + TS_BIAS + 0x1800002C0UL)
-
-#define        TSUNAMI_PCHIP0_PCTL     (IDENT_ADDR + TS_BIAS + 0x180000300UL)
-#define        TSUNAMI_PCHIP0_PLAT     (IDENT_ADDR + TS_BIAS + 0x180000340UL)
-#define        TSUNAMI_PCHIP0_RESERVED (IDENT_ADDR + TS_BIAS + 0x180000380UL)
-#define        TSUNAMI_PCHIP0_PERROR   (IDENT_ADDR + TS_BIAS + 0x1800003c0UL)
-#define        TSUNAMI_PCHIP0_PERRMASK (IDENT_ADDR + TS_BIAS + 0x180000400UL)
-#define        TSUNAMI_PCHIP0_PERRSET  (IDENT_ADDR + TS_BIAS + 0x180000440UL)
-#define        TSUNAMI_PCHIP0_TLBIV    (IDENT_ADDR + TS_BIAS + 0x180000480UL)
-#define        TSUNAMI_PCHIP0_TLBIA    (IDENT_ADDR + TS_BIAS + 0x1800004C0UL)
-#define        TSUNAMI_PCHIP0_PMONCTL  (IDENT_ADDR + TS_BIAS + 0x180000500UL)
-#define        TSUNAMI_PCHIP0_PMONCNT  (IDENT_ADDR + TS_BIAS + 0x180000540UL)
-
-#define        TSUNAMI_PCHIP1_WSBA0    (IDENT_ADDR + TS_BIAS + 0x380000000UL)
-#define        TSUNAMI_PCHIP1_WSBA1    (IDENT_ADDR + TS_BIAS + 0x380000040UL)
-#define        TSUNAMI_PCHIP1_WSBA2    (IDENT_ADDR + TS_BIAS + 0x380000080UL)
-#define        TSUNAMI_PCHIP1_WSBA3    (IDENT_ADDR + TS_BIAS + 0x3800000C0UL)
-#define        TSUNAMI_PCHIP1_WSM0     (IDENT_ADDR + TS_BIAS + 0x380000100UL)
-#define        TSUNAMI_PCHIP1_WSM1     (IDENT_ADDR + TS_BIAS + 0x380000140UL)
-#define        TSUNAMI_PCHIP1_WSM2     (IDENT_ADDR + TS_BIAS + 0x380000180UL)
-#define        TSUNAMI_PCHIP1_WSM3     (IDENT_ADDR + TS_BIAS + 0x3800001C0UL)
-
-#define        TSUNAMI_PCHIP1_TBA0     (IDENT_ADDR + TS_BIAS + 0x380000200UL)
-#define        TSUNAMI_PCHIP1_TBA1     (IDENT_ADDR + TS_BIAS + 0x380000240UL)
-#define        TSUNAMI_PCHIP1_TBA2     (IDENT_ADDR + TS_BIAS + 0x380000280UL)
-#define        TSUNAMI_PCHIP1_TBA3     (IDENT_ADDR + TS_BIAS + 0x3800002C0UL)
-
-#define        TSUNAMI_PCHIP1_PCTL     (IDENT_ADDR + TS_BIAS + 0x380000300UL)
-#define        TSUNAMI_PCHIP1_PLAT     (IDENT_ADDR + TS_BIAS + 0x380000340UL)
-#define        TSUNAMI_PCHIP1_RESERVED (IDENT_ADDR + TS_BIAS + 0x380000380UL)
-#define        TSUNAMI_PCHIP1_PERROR   (IDENT_ADDR + TS_BIAS + 0x3800003c0UL)
-#define        TSUNAMI_PCHIP1_PERRMASK (IDENT_ADDR + TS_BIAS + 0x380000400UL)
-#define        TSUNAMI_PCHIP1_PERRSET  (IDENT_ADDR + TS_BIAS + 0x380000440UL)
-#define        TSUNAMI_PCHIP1_TLBIV    (IDENT_ADDR + TS_BIAS + 0x380000480UL)
-#define        TSUNAMI_PCHIP1_TLBIA    (IDENT_ADDR + TS_BIAS + 0x3800004C0UL)
-#define        TSUNAMI_PCHIP1_PMONCTL  (IDENT_ADDR + TS_BIAS + 0x380000500UL)
-#define        TSUNAMI_PCHIP1_PMONCNT  (IDENT_ADDR + TS_BIAS + 0x380000540UL)
-
-/*                                                                          */
-/* TSUNAMI Pchip Error register.                                            */
-/*                                                                          */
-#define perror_m_lost 0x1
-#define perror_m_serr 0x2
-#define perror_m_perr 0x4
-#define perror_m_dcrto 0x8
-#define perror_m_sge 0x10
-#define perror_m_ape 0x20
-#define perror_m_ta 0x40
-#define perror_m_rdpe 0x80
-#define perror_m_nds 0x100
-#define perror_m_rto 0x200
-#define perror_m_uecc 0x400
-#define perror_m_cre 0x800
-#define perror_m_addrl 0xFFFFFFFF0000UL
-#define perror_m_addrh 0x7000000000000UL
-#define perror_m_cmd 0xF0000000000000UL
-#define perror_m_syn 0xFF00000000000000UL
-union TPchipPERROR {   
-    struct  {
-        unsigned int perror_v_lost : 1;
-        unsigned perror_v_serr : 1;
-        unsigned perror_v_perr : 1;
-        unsigned perror_v_dcrto : 1;
-        unsigned perror_v_sge : 1;
-        unsigned perror_v_ape : 1;
-        unsigned perror_v_ta : 1;
-        unsigned perror_v_rdpe : 1;
-        unsigned perror_v_nds : 1;
-        unsigned perror_v_rto : 1;
-        unsigned perror_v_uecc : 1;
-        unsigned perror_v_cre : 1;                 
-        unsigned perror_v_rsvd1 : 4;
-        unsigned perror_v_addrl : 32;
-        unsigned perror_v_addrh : 3;
-        unsigned perror_v_rsvd2 : 1;
-        unsigned perror_v_cmd : 4;
-        unsigned perror_v_syn : 8;
-        } perror_r_bits;
-    int perror_q_whole [2];
-    } ;                       
-/*                                                                          */
-/* TSUNAMI Pchip Window Space Base Address register.                        */
-/*                                                                          */
-#define wsba_m_ena 0x1                
-#define wsba_m_sg 0x2
-#define wsba_m_ptp 0x4
-#define wsba_m_addr 0xFFF00000  
-#define wmask_k_sz1gb 0x3FF00000                   
-union TPchipWSBA {
-    struct  {
-        unsigned wsba_v_ena : 1;
-        unsigned wsba_v_sg : 1;
-        unsigned wsba_v_ptp : 1;
-        unsigned wsba_v_rsvd1 : 17;
-        unsigned wsba_v_addr : 12;
-        unsigned wsba_v_rsvd2 : 32;
-        } wsba_r_bits;
-    int wsba_q_whole [2];
-    } ;
-/*                                                                         */
-/* TSUNAMI Pchip Control Register                                          */
-/*                                                                         */
-#define pctl_m_fdsc 0x1
-#define pctl_m_fbtb 0x2
-#define pctl_m_thdis 0x4
-#define pctl_m_chaindis 0x8
-#define pctl_m_tgtlat 0x10
-#define pctl_m_hole 0x20
-#define pctl_m_mwin 0x40
-#define pctl_m_arbena 0x80
-#define pctl_m_prigrp 0x7F00
-#define pctl_m_ppri 0x8000
-#define pctl_m_rsvd1 0x30000
-#define pctl_m_eccen 0x40000
-#define pctl_m_padm 0x80000
-#define pctl_m_cdqmax 0xF00000
-#define pctl_m_rev 0xFF000000
-#define pctl_m_crqmax 0xF00000000UL
-#define pctl_m_ptpmax 0xF000000000UL
-#define pctl_m_pclkx 0x30000000000UL
-#define pctl_m_fdsdis 0x40000000000UL
-#define pctl_m_fdwdis 0x80000000000UL
-#define pctl_m_ptevrfy 0x100000000000UL
-#define pctl_m_rpp 0x200000000000UL
-#define pctl_m_pid 0xC00000000000UL
-#define pctl_m_rsvd2 0xFFFF000000000000UL
-
-union TPchipPCTL {
-    struct {
-       unsigned pctl_v_fdsc : 1;
-       unsigned pctl_v_fbtb : 1;
-       unsigned pctl_v_thdis : 1;
-       unsigned pctl_v_chaindis : 1;
-       unsigned pctl_v_tgtlat : 1;
-       unsigned pctl_v_hole : 1;
-       unsigned pctl_v_mwin : 1;
-       unsigned pctl_v_arbena : 1;
-       unsigned pctl_v_prigrp : 7;
-       unsigned pctl_v_ppri : 1;
-       unsigned pctl_v_rsvd1 : 2;
-       unsigned pctl_v_eccen : 1;
-       unsigned pctl_v_padm : 1;
-       unsigned pctl_v_cdqmax : 4;
-       unsigned pctl_v_rev : 8;
-       unsigned pctl_v_crqmax : 4;
-       unsigned pctl_v_ptpmax : 4;
-       unsigned pctl_v_pclkx : 2;
-       unsigned pctl_v_fdsdis : 1;
-       unsigned pctl_v_fdwdis : 1;
-       unsigned pctl_v_ptevrfy : 1;
-       unsigned pctl_v_rpp : 1;
-       unsigned pctl_v_pid : 2;
-       unsigned pctl_v_rsvd2 : 16;
-       } pctl_r_bits;
-    int pctl_q_whole [2];
-} ;
-/*                                                                          */
-/* TSUNAMI Pchip Error Mask Register.                                       */
-/*                                                                          */
-#define perrmask_m_lost 0x1
-#define perrmask_m_serr 0x2
-#define perrmask_m_perr 0x4
-#define perrmask_m_dcrto 0x8
-#define perrmask_m_sge 0x10
-#define perrmask_m_ape 0x20
-#define perrmask_m_ta 0x40
-#define perrmask_m_rdpe 0x80
-#define perrmask_m_nds 0x100
-#define perrmask_m_rto 0x200
-#define perrmask_m_uecc 0x400
-#define perrmask_m_cre 0x800
-#define perrmask_m_rsvd 0xFFFFFFFFFFFFF000UL
-union TPchipPERRMASK {   
-    struct  {
-        unsigned int perrmask_v_lost : 1;
-        unsigned perrmask_v_serr : 1;
-        unsigned perrmask_v_perr : 1;
-        unsigned perrmask_v_dcrto : 1;
-        unsigned perrmask_v_sge : 1;
-        unsigned perrmask_v_ape : 1;
-        unsigned perrmask_v_ta : 1;
-        unsigned perrmask_v_rdpe : 1;
-        unsigned perrmask_v_nds : 1;
-        unsigned perrmask_v_rto : 1;
-        unsigned perrmask_v_uecc : 1;
-        unsigned perrmask_v_cre : 1;                 
-        unsigned perrmask_v_rsvd1 : 20;
-       unsigned perrmask_v_rsvd2 : 32;
-        } perrmask_r_bits;
-    int perrmask_q_whole [2];
-    } ;                       
-
-/*
- * Memory spaces:
- */
-#define TSUNAMI_PCI0_MEM               (IDENT_ADDR + TS_BIAS + 0x000000000UL)
-#define TSUNAMI_PCI0_IACK_SC           (IDENT_ADDR + TS_BIAS + 0x1F8000000UL)
-#define TSUNAMI_PCI0_IO                        (IDENT_ADDR + TS_BIAS + 0x1FC000000UL)
-#define TSUNAMI_PCI0_CONF              (IDENT_ADDR + TS_BIAS + 0x1FE000000UL)
-
-#define TSUNAMI_PCI1_MEM               (IDENT_ADDR + TS_BIAS + 0x200000000UL)
-#define TSUNAMI_PCI1_IACK_SC           (IDENT_ADDR + TS_BIAS + 0x3F8000000UL)
-#define TSUNAMI_PCI1_IO                        (IDENT_ADDR + TS_BIAS + 0x3FC000000UL)
-#define TSUNAMI_PCI1_CONF              (IDENT_ADDR + TS_BIAS + 0x3FE000000UL)
-
-#define HAE_ADDRESS 0
-
-#ifdef __KERNEL__
-
-/*
- * Translate physical memory address as seen on (PCI) bus into
- * a kernel virtual address and vv.
- */
-extern inline unsigned long virt_to_bus(void * address)
-{
-       return virt_to_phys(address) + TSUNAMI_DMA_WIN_BASE;
-}
-
-extern inline void * bus_to_virt(unsigned long address)
-{
-       return phys_to_virt(address - TSUNAMI_DMA_WIN_BASE);
-}
-
-/*
- * I/O functions:
- *
- * TSUNAMI, the 21??? PCI/memory support chipset for the EV6 (21264)
- * can only use linear accesses to get at PCI memory and I/O spaces.
- */
-
-/* HACK ALERT! HACK ALERT! */
-/* HACK ALERT! HACK ALERT! */
-
-/* only using PCI bus 0 for now in all routines */
-
-#define DENSE_MEM(addr)                        TSUNAMI_PCI0_MEM
-
-/* HACK ALERT! HACK ALERT! */
-/* HACK ALERT! HACK ALERT! */
-
-/* Also assume we are optimizing for EV6, and so the compiler knows about
-   byte/word instructions.  */
-
-#define vucp   volatile unsigned char *
-#define vusp   volatile unsigned short *
-#define vuip   volatile unsigned int *
-#define vulp   volatile unsigned long *
-
-extern inline unsigned int __inb(unsigned long addr)
-{
-       return *(vucp)(addr + TSUNAMI_PCI0_IO);
-}
-
-extern inline void __outb(unsigned char b, unsigned long addr)
-{
-       *(vucp)(addr + TSUNAMI_PCI0_IO) = b;
-       mb();
-}
-
-extern inline unsigned int __inw(unsigned long addr)
-{
-       return *(vusp)(addr+TSUNAMI_PCI0_IO);
-}
-
-extern inline void __outw(unsigned short b, unsigned long addr)
-{
-       *(vusp)(addr+TSUNAMI_PCI0_IO) = b;
-       mb();
-}
-
-extern inline unsigned int __inl(unsigned long addr)
-{
-       return *(vuip)(addr+TSUNAMI_PCI0_IO);
-}
-
-extern inline void __outl(unsigned int b, unsigned long addr)
-{
-       *(vuip)(addr+TSUNAMI_PCI0_IO) = b;
-       mb();
-}
-
-/*
- * Memory functions.  all accesses are done through linear space.
- */
-
-extern inline unsigned long __readb(unsigned long addr)
-{
-       return *(vucp)(addr+TSUNAMI_PCI0_MEM);
-}
-
-extern inline unsigned long __readw(unsigned long addr)
-{
-       return *(vusp)(addr+TSUNAMI_PCI0_MEM);
-}
-
-extern inline unsigned long __readl(unsigned long addr)
-{
-       return *(vuip)(addr+TSUNAMI_PCI0_MEM);
-}
-
-extern inline unsigned long __readq(unsigned long addr)
-{
-       return *(vulp)(addr+TSUNAMI_PCI0_MEM);
-}
-
-extern inline void __writeb(unsigned char b, unsigned long addr)
-{
-       *(vucp)(addr+TSUNAMI_PCI0_MEM) = b;
-       mb();
-}
-
-extern inline void __writew(unsigned short b, unsigned long addr)
-{
-       *(vusp)(addr+TSUNAMI_PCI0_MEM) = b;
-       mb();
-}
-
-extern inline void __writel(unsigned int b, unsigned long addr)
-{
-       *(vuip)(addr+TSUNAMI_PCI0_MEM) = b;
-       mb();
-}
-
-extern inline void __writeq(unsigned long b, unsigned long addr)
-{
-       *(vulp)(addr+TSUNAMI_PCI0_MEM) = b;
-       mb();
-}
-
-#define inb(port) __inb((port))
-#define inw(port) __inw((port))
-#define inl(port) __inl((port))
-
-#define outb(v, port) __outb((v),(port))
-#define outw(v, port) __outw((v),(port))
-#define outl(v, port) __outl((v),(port))
-
-#define readb(a)       __readb((unsigned long)(a))
-#define readw(a)       __readw((unsigned long)(a))
-#define readl(a)       __readl((unsigned long)(a))
-#define readq(a)       __readq((unsigned long)(a))
-
-#define writeb(v,a)    __writeb((v),(unsigned long)(a))
-#define writew(v,a)    __writew((v),(unsigned long)(a))
-#define writel(v,a)    __writel((v),(unsigned long)(a))
-#define writeq(v,a)    __writeq((v),(unsigned long)(a))
-
-#undef vucp
-#undef vusp
-#undef vuip
-#undef vulp
-
-extern unsigned long tsunami_init (unsigned long, unsigned long);
-
-#endif /* __KERNEL__ */
-
-/*
- * Data structure for handling TSUNAMI machine checks:
- */
-struct el_TSUNAMI_sysdata_mcheck {
-};
-
-#define RTC_PORT(x)    (0x70 + (x))
-#define RTC_ADDR(x)    (0x80 | (x))
-#define RTC_ALWAYS_BCD 0
-
-#endif /* __ALPHA_TSUNAMI__H__ */
index 017ee2ba5ff30a99edf0ad4f42b0c861fd66fbc0..f56ce91e707103ee958e0fbcb66a6958dca7ff5f 100644 (file)
@@ -113,37 +113,6 @@ extern inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx)
                : "cc");
 }
 
-/*
- *      Cyrix CPU configuration register indexes
- */
-#define CX86_CCR2 0xc2
-#define CX86_CCR3 0xc3
-#define CX86_CCR4 0xe8
-#define CX86_CCR5 0xe9
-#define CX86_DIR0 0xfe
-#define CX86_DIR1 0xff
-
-/*
- *      Cyrix CPU indexed register access macros
- */
-
-extern inline unsigned char getCx86(unsigned char reg)
-{
-       unsigned char data;
-
-       __asm__ __volatile__("movb %1,%%al\n\t"
-                     "outb %%al,$0x22\n\t"
-                     "inb $0x23,%%al" : "=a" (data) : "q" (reg));
-       return data;
-}
-
-extern inline void setCx86(unsigned char reg, unsigned char data)
-{
-       __asm__ __volatile__("outb %%al,$0x22\n\t"
-            "movb %1,%%al\n\t"
-            "outb %%al,$0x23" : : "a" (reg), "q" (data));
-}
-
 /*
  * Bus types (default is ISA, but people can check others with these..)
  */
index aa5aa860575cb1e29e97dfebf4368fe094aac530..1b23625c626a2838c917a8c2ae2762fe031e92c0 100644 (file)
@@ -27,7 +27,7 @@
 #define __NR_lseek              19
 #define __NR_getpid             20
 #define __NR_mount              21
-#define __NR_umount             22
+#define __NR_oldumount          22
 #define __NR_setuid             23
 #define __NR_getuid             24
 #define __NR_stime              25
@@ -57,7 +57,7 @@
 #define __NR_geteuid            49
 #define __NR_getegid            50
 #define __NR_acct               51
-#define __NR_phys               52
+#define __NR_umount             52
 #define __NR_lock               53
 #define __NR_ioctl              54
 #define __NR_fcntl              55
index 29f2149eca8028941abbc9675199d69343f902a4..b2b747d20fbba6ab1f72b8b28812768ed35f57ac 100644 (file)
@@ -26,6 +26,7 @@
 #define DOS_EXTENDED_PARTITION 5
 #define LINUX_EXTENDED_PARTITION 0x85
 #define WIN98_EXTENDED_PARTITION 0x0f
+
 #define LINUX_SWAP_PARTITION   0x82
 
 #ifdef CONFIG_SOLARIS_X86_PARTITION
index 7377867e70eec0b3a507691d109e9ec3b70f2cfb..57ffd730ae2a004e0336fe65e7e7752b7ddc8c45 100644 (file)
@@ -18,6 +18,7 @@ struct shaper
 {
        struct sk_buff_head sendq;
        __u32 bytespertick;
+       __u32 bitspersec;
        __u32 shapelatency;
        __u32 shapeclock;
        __u32 recovery;         /* Time we can next clock a packet out on
@@ -44,6 +45,8 @@ struct shaper
 
 #define SHAPER_SET_DEV         0x0001
 #define SHAPER_SET_SPEED       0x0002
+#define SHAPER_GET_DEV         0x0003
+#define SHAPER_GET_SPEED       0x0004
 
 struct shaperconf
 {
diff --git a/include/linux/if_wic.h b/include/linux/if_wic.h
deleted file mode 100644 (file)
index cca15f8..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef _LINUX_IF_WIC_H
-#define _LINUX_IF_WIC_H
-
-#include <linux/sockios.h>
-
-#define        SIOCDEVWIC      SIOCDEVPRIVATE
-
-struct wicconf
-{
-       unsigned char   pcmd;
-       unsigned char   data[120];
-       unsigned char   len;
-};
-
-/* WIC host to controller commands */
-
-#define WIC_AYT                0x10    /* test dki */
-#define WIC_RESET      0x11    /* reset controller */
-#define WIC_SETSN      0x21    /* set station name */
-#define WIC_SETPS      0x22    /* set power saving mode */
-#define WIC_SETAF      0x23    /* set announce filter */
-#define WIC_SETGPF     0x24    /* set GPSP filter */
-#define WIC_GETVERH    0x61    /* get interface controller version */
-#define WIC_GETNL      0x62    /* get neighbor list */
-#define WIC_GETSN      0x65    /* get station name */
-#define WIC_CLRSTATS   0x83    /* clear controller statistics */
-#define WIC_SETNET     0x84    /* set network configuration */
-#define WIC_SETSYS     0x85    /* set system configuration */
-#define WIC_GETSTATS   0xc1    /* get statistics */
-#define WIC_GETVERM    0xc3    /* get MAC version */
-#define WIC_GETNET     0xc4    /* get network configuration */
-#define WIC_GETSYS     0xc5    /* get system configuration */
-
-/*
- * structure used for the GETNET/SETNET command
- */
-
-struct wic_net {
-       unsigned char ula[6];           /* ula of interface */
-       unsigned char mode;             /* operating mode */
-#define NET_MODE_ME            0x01    /* receive my ula */
-#define NET_MODE_BCAST         0x02    /* receive bcasts */
-#define NET_MODE_MCAST         0x04    /* receive mcasts */
-#define NET_MODE_PROM          0x08    /* promiscuous */
-#define NET_MODE_HC            0x10    /* is a hop coordinator */
-#define NET_MODE_HC_VALID      0x20    /* hc address is valid */
-#define NET_MODE_HCAP          0x40    /* hc is also ap */
-#define NET_MODE_HC_KNOWN      0x80    /* hc is known */
-       unsigned char rts_lo;           /* rts threshold */
-       unsigned char rts_hi;           /* rts threshold */
-       unsigned char retry;            /* retry limit */
-       unsigned char hc_ula[6];        /* ula of hc */
-       unsigned char key[4];           /* network key */
-       unsigned char dsl;              /* direct send limit */
-       unsigned char res1;             /* reserved */
-};
-
-/*
- * structure used for the GETSYS/SETSYS command 
- */
-
-struct wic_sys {
-       unsigned char mode;             /* set operating mode */
-#define SYS_MODE_ANT_DIV       0x00    /* use antenna diversity */
-#define SYS_MODE_ANT_1         0x01    /* use ant 1 for tx */
-#define SYS_MODE_ANT_2         0x02    /* use ant 2 for tx */
-#define SYS_MODE_HC_LOCK       0x04    /* lock onto current hc */
-#define SYS_MODE_DEBUG         0x08    /* upload failed frames */
-#define SYS_MODE_IAM_AP                0x10    /* I am AP */
-#define SYS_MODE_IAM_HC                0x20    /* I am HC */
-#define SYS_MODE_USE_SKIP      0x40    /* use skipping mechanism */
-#define SYS_MODE_AUTO          0x80    /* station is in auto mode */
-       unsigned char switches;         /* radio/controller switches */
-#define SYS_SWITCH_STDBY       0x01    /* switch radio to standby */
-#define SYS_SWITCH_TXRX                0x02    /* 1 = tx, manual mode only */
-#define SYS_SWITCH_PA          0x04    /* 1 = enable PA on radio */
-#define SYS_SWITCH_PWR         0x10    /* 1 = hi, 0 = lo power output */
-#define SYS_SWITCH_RES1                0x20    /* reserved, must be 0 */
-#define SYS_SWITCH_LIGHTS      0x40    /* light for tx & rx */
-#define SYS_SWITCH_LIGHTS_HC   0x80    /* light for rx while coordinated */
-       unsigned char hop_min;          /* hop range */
-       unsigned char hop_max;          /* hop range */
-       unsigned char pre_len;          /* preamble length (bytes) */
-       unsigned char pre_match;        /* valid preamble match (bytes) */
-       unsigned char mod;              /* data mod: 1 = 8:1, 0 = none */
-       unsigned char cca_mode;         /* cca flags */
-#define CCA_PKT_DET_BSY                0x01    /* busy if packet is detected */
-#define CCA_VIRT_CARR          0x02    /* use virtual carrier */
-#define CCA_RSSI_BSY           0x04    /* busy if rssi > threshold */
-#define CCA_DATA_BSY           0x08    /* busy if valid data > XXX usec */
-       unsigned char dwell_hi;         /* dwell time */
-       unsigned char dwell_lo;         /* dwell time */
-       unsigned char hc_timeout;       /* HC timeout */
-       unsigned char rssi;             /* rssi threshold */
-       unsigned char hc_rssi;          /* rssi of last hc frame */
-       unsigned char hc_rssi_chan;     /* channel of hc rssi value */
-};
-
-
-#endif /* _LINUX_IF_WIC_H */
-
-
index a0dbd0eaaa866595d578c6914457d8846732daa3..7e7ccb266cb60d3f0aec7b33fa7de8d30463ba8d 100644 (file)
@@ -37,4 +37,10 @@ struct vfsmount
 
 struct vfsmount *lookup_vfsmnt(kdev_t dev);
 
+/*
+ *     Umount options
+ */
+#define MNT_FORCE      0x00000001      /* Attempt to forcibily umount */
+
 #endif /* _LINUX_MOUNT_H */
index f8437c686b189b3d899240e551433509ed2fd269..aefb1bf40ddd47814614b8440911d868ae3424bf 100644 (file)
@@ -31,6 +31,7 @@ enum root_directory_inos {
        PROC_MODULES,
        PROC_STAT,
        PROC_DEVICES,
+       PROC_PARTITIONS,
        PROC_INTERRUPTS,
        PROC_FILESYSTEMS,
        PROC_KSYMS,
index 7d3ffc97372f553deafd9447e7f4415803189f69..701fb88706595bc74a485bc9849a945f812087e1 100644 (file)
@@ -3,6 +3,8 @@
 
 #ifdef __KERNEL__
 
+#include <linux/poll.h>
+
 struct video_device
 {
        char name[32];
@@ -14,6 +16,7 @@ struct video_device
        long (*read)(struct video_device *, char *, unsigned long, int noblock);
        /* Do we need a write method ? */
        long (*write)(struct video_device *, const char *, unsigned long, int noblock);
+       unsigned int (*poll)(struct video_device *, struct file *, poll_table *);
        int (*ioctl)(struct video_device *, unsigned int , void *);
        int (*mmap)(struct video_device *, const char *, unsigned long);
        int (*initialize)(struct video_device *);       
@@ -109,6 +112,10 @@ struct video_picture
 #define VIDEO_PALETTE_YUYV     8
 #define VIDEO_PALETTE_UYVY     9       /* The great thing about standards is ... */
 #define VIDEO_PALETTE_YUV420   10
+#define VIDEO_PALETTE_YUV411   11      /* YUV411 capture */
+#define VIDEO_PALETTE_RAW      12      /* RAW capture (BT848) */
+#define VIDEO_PALETTE_YUV422P  13      /* YUV 4:2:2 Planar */
+#define VIDEO_PALETTE_YUV411P  14      /* YUV 4:1:1 Planar */
 };
 
 struct video_audio
@@ -160,7 +167,7 @@ struct video_mmap
 {
        unsigned int frame;             /* Frame (0 or 1) for double buffer */
        int height,width;
-       unsigned int format;
+       unsigned int format;    /* should be VIDEO_PALETTE_* */
 };
 
 struct video_key
@@ -205,6 +212,7 @@ struct video_key
 #define VID_HARDWARE_ZOLTRIX   10
 #define VID_HARDWARE_SAA7146    11
 #define VID_HARDWARE_VIDEUM    12      /* Reserved for Winnov videum */
+#define VID_HARDWARE_RTRACK2   13
 
 /*
  *     Initialiser list
index e505bcc0168430d1c5f94835ed6f7c9bb38f2012..217967e026f91052d0bc3d1ac4dafa5cabf8b079 100644 (file)
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -29,7 +29,7 @@ static int used_queues = 0;
 static int max_msqid = 0;
 static struct wait_queue *msg_lock = NULL;
 
-__initfunc(void msg_init (void))
+void __init msg_init (void)
 {
        int id;
        
@@ -47,16 +47,11 @@ static int real_msgsnd (int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg
        struct ipc_perm *ipcp;
        struct msg *msgh;
        long mtype;
-       unsigned long flags;
        
        if (msgsz > MSGMAX || (long) msgsz < 0 || msqid < 0)
                return -EINVAL;
-       if (!msgp) 
-               return -EFAULT;
-       err = verify_area (VERIFY_READ, msgp->mtext, msgsz);
-       if (err) 
-               return err;
-       get_user(mtype, &msgp->mtype);
+       if (get_user(mtype, &msgp->mtype))
+               return -EFAULT; 
        if (mtype < 1)
                return -EINVAL;
        id = (unsigned int) msqid % MSGMNI;
@@ -103,8 +98,6 @@ static int real_msgsnd (int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg
        msgh->msg_type = mtype;
        msgh->msg_stime = CURRENT_TIME;
 
-       save_flags(flags);
-       cli();
        if (!msq->msg_first)
                msq->msg_first = msq->msg_last = msgh;
        else {
@@ -117,7 +110,6 @@ static int real_msgsnd (int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg
        msq->msg_qnum++;
        msq->msg_lspid = current->pid;
        msq->msg_stime = CURRENT_TIME;
-       restore_flags(flags);
        wake_up (&msq->rwait);
        return 0;
 }
@@ -129,16 +121,9 @@ static int real_msgrcv (int msqid, struct msgbuf *msgp, size_t msgsz, long msgty
        struct msg *tmsg, *leastp = NULL;
        struct msg *nmsg = NULL;
        int id, err;
-       unsigned long flags;
 
        if (msqid < 0 || (long) msgsz < 0)
                return -EINVAL;
-       if (!msgp || !msgp->mtext)
-           return -EFAULT;
-
-       err = verify_area (VERIFY_WRITE, msgp->mtext, msgsz);
-       if (err)
-               return err;
 
        id = (unsigned int) msqid % MSGMNI;
        msq = msgque [id];
@@ -160,8 +145,6 @@ static int real_msgrcv (int msqid, struct msgbuf *msgp, size_t msgsz, long msgty
                        return -EACCES;
                }
 
-               save_flags(flags);
-               cli();
                if (msgtyp == 0) 
                        nmsg = msq->msg_first;
                else if (msgtyp > 0) {
@@ -186,15 +169,12 @@ static int real_msgrcv (int msqid, struct msgbuf *msgp, size_t msgsz, long msgty
                        if (leastp && leastp->msg_type <= - msgtyp)
                                nmsg = leastp;
                }
-               restore_flags(flags);
                
                if (nmsg) { /* done finding a message */
                        if ((msgsz < nmsg->msg_ts) && !(msgflg & MSG_NOERROR)) {
                                return -E2BIG;
                        }
                        msgsz = (msgsz > nmsg->msg_ts)? nmsg->msg_ts : msgsz;
-                       save_flags(flags);
-                       cli();
                        if (nmsg ==  msq->msg_first)
                                msq->msg_first = nmsg->msg_next;
                        else {
@@ -214,10 +194,10 @@ static int real_msgrcv (int msqid, struct msgbuf *msgp, size_t msgsz, long msgty
                        msgbytes -= nmsg->msg_ts; 
                        msghdrs--; 
                        msq->msg_cbytes -= nmsg->msg_ts;
-                       restore_flags(flags);
                        wake_up (&msq->wwait);
-                       put_user (nmsg->msg_type, &msgp->mtype);
-                       copy_to_user (msgp->mtext, nmsg->msg_spot, msgsz);
+                       if (put_user (nmsg->msg_type, &msgp->mtype) ||
+                           copy_to_user (msgp->mtext, nmsg->msg_spot, msgsz))
+                               msgsz = -EFAULT; 
                        kfree(nmsg);
                        return msgsz;
                } else {  /* did not find a message */
@@ -395,19 +375,16 @@ asmlinkage int sys_msgctl (int msqid, int cmd, struct msqid_ds *buf)
                        msginfo.msgmap = msghdrs;
                        msginfo.msgtql = msgbytes;
                }
-               err = verify_area (VERIFY_WRITE, buf, sizeof (struct msginfo));
-               if (err)
-                       goto out;
-               copy_to_user (buf, &msginfo, sizeof(struct msginfo));
+
+               err = -EFAULT; 
+               if (copy_to_user (buf, &msginfo, sizeof(struct msginfo)))
+                       goto out; 
                err = max_msqid;
                goto out;
        }
        case MSG_STAT:
                if (!buf)
                        goto out;
-               err = verify_area (VERIFY_WRITE, buf, sizeof (*buf));
-               if (err)
-                       goto out;
                err = -EINVAL;
                if (msqid > max_msqid)
                        goto out;
@@ -427,23 +404,21 @@ asmlinkage int sys_msgctl (int msqid, int cmd, struct msqid_ds *buf)
                tbuf.msg_qbytes = msq->msg_qbytes;
                tbuf.msg_lspid  = msq->msg_lspid;
                tbuf.msg_lrpid  = msq->msg_lrpid;
-               copy_to_user (buf, &tbuf, sizeof(*buf));
+               err = -EFAULT;
+               if (copy_to_user (buf, &tbuf, sizeof(*buf)))
+                       goto out; 
                err = id;
                goto out;
        case IPC_SET:
                if (!buf)
                        goto out;
-               err = verify_area (VERIFY_READ, buf, sizeof (*buf));
-               if (err)
-                       goto out;
-               copy_from_user (&tbuf, buf, sizeof (*buf));
+               err = -EFAULT; 
+               if (!copy_from_user (&tbuf, buf, sizeof (*buf)))
+                       err = 0; 
                break;
        case IPC_STAT:
                if (!buf)
                        goto out;
-               err = verify_area (VERIFY_WRITE, buf, sizeof(*buf));
-               if (err)
-                       goto out;
                break;
        }
 
@@ -471,8 +446,9 @@ asmlinkage int sys_msgctl (int msqid, int cmd, struct msqid_ds *buf)
                tbuf.msg_qbytes = msq->msg_qbytes;
                tbuf.msg_lspid  = msq->msg_lspid;
                tbuf.msg_lrpid  = msq->msg_lrpid;
-               copy_to_user (buf, &tbuf, sizeof (*buf));
-               err = 0;
+               err = -EFAULT;
+               if (!copy_to_user (buf, &tbuf, sizeof (*buf)))
+                       err = 0;
                goto out;
        case IPC_SET:
                err = -EPERM;
index b815fd0378d1fff5d9e46b1987cfd3f4d7467081..e9cb2ea7046f1bb25ebf1b90af62fc0c4580f714 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/ctype.h>
 #include <linux/file.h>
 #include <linux/console.h>
+#include <linux/time.h>
 
 extern unsigned char aux_device_present, pckbd_read_mask;
 
@@ -389,7 +390,7 @@ EXPORT_SYMBOL(pckbd_read_mask);
 #ifdef CONFIG_BLK_DEV_MD
 EXPORT_SYMBOL(disk_name);      /* for md.c */
 #endif
-       
+
 /* binfmt_aout */
 EXPORT_SYMBOL(get_write_access);
 EXPORT_SYMBOL(put_write_access);
@@ -397,3 +398,6 @@ EXPORT_SYMBOL(put_write_access);
 /* dynamic registering of consoles */
 EXPORT_SYMBOL(register_console);
 EXPORT_SYMBOL(unregister_console);
+
+/* time */
+EXPORT_SYMBOL(get_fast_time);
index 6be5b48c2fd1979d9c7ddf6609bb78bf21733aef..3cedb215c8b710eb2228d42d6387e8dc5106e883 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -67,9 +67,9 @@ swap_control_t swap_control = {
 swapstat_t swapstats = {0};
 
 buffer_mem_t buffer_mem = {
-       3,      /* minimum percent buffer */
-       10,     /* borrow percent buffer */
-       30      /* maximum percent buffer */
+       5,      /* minimum percent buffer */
+       25,     /* borrow percent buffer */
+       50      /* maximum percent buffer */
 };
 
 buffer_mem_t page_cache = {
index 3edee0168d65913b0064d1b4b3f9b16338533304..71999a41652cc58fd0ca392736a960972a62bd63 100644 (file)
@@ -1009,7 +1009,10 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        if (sk->zapped == 0)
                return -EINVAL;
 
-       if (addr_len != sizeof(struct sockaddr_ax25) && addr_len != sizeof(struct full_sockaddr_ax25))
+       if (addr_len < sizeof(struct sockaddr_ax25) || addr_len > sizeof(struct full_sockaddr_ax25))
+               return -EINVAL;
+
+       if (addr_len < (addr->fsa_ax25.sax25_ndigis * sizeof(ax25_address) + sizeof(struct sockaddr_ax25)))
                return -EINVAL;
 
        if (addr->fsa_ax25.sax25_family != AF_AX25)
index cfb9298c4d254eb6d01575e5f7f3cb1d056d4619..a17baa52f640c6ab1498cf14a7b76ab1ebc61538 100644 (file)
@@ -740,21 +740,20 @@ static inline void handle_bridge(struct sk_buff *skb, unsigned short type)
                 *      recovering the MAC header first.
                 */
                
-               int offset=skb->data-skb->mac.raw;
-               cli();
+               int offset;
+
+               skb=skb_clone(skb, GFP_ATOMIC);
+               if(skb==NULL)           
+                       return;
+                       
+               offset=skb->data-skb->mac.raw;
                skb_push(skb,offset);   /* Put header back on for bridge */
+
                if(br_receive_frame(skb))
-               {
-                       sti();
                        return;
-               }
-               /*
-                *      Pull the MAC header off for the copy going to
-                *      the upper layers.
-                */
-               skb_pull(skb,offset);
-               sti();
+               kfree_skb(skb, FREE_READ);
        }
+       return;
 }
 #endif
 
index 5b5a543357f07c9a5d53e4486701d9d38e642582..92bdc4c97f013398d6d1face46ab8f7fc33cd0b6 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/inet.h>
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
+#include <linux/wireless.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
 #include <net/inet_common.h>
@@ -48,6 +49,8 @@
 static struct proto_ops econet_ops;
 static struct sock *econet_sklist;
 
+static spinlock_t aun_queue_lock;
+
 #ifdef CONFIG_ECONET_AUNUDP
 static struct socket *udpsock;
 #define AUN_PORT       0x8000
@@ -343,7 +346,7 @@ static int econet_sendmsg(struct socket *sock, struct msghdr *msg, int len,
                
                eb->cookie = saddr->cookie;
                eb->sec = *saddr;
-               eb->sent - ec_tx_done;
+               eb->sent = ec_tx_done;
 
                if (dev->hard_header) {
                        int res;
@@ -965,7 +968,6 @@ static void aun_data_available(struct sock *sk, int slen)
  *     drop the packet.
  */
 
-static spinlock_t aun_queue_lock;
 
 static void ab_cleanup(unsigned long h)
 {
index 39ed076ed511ccd505e829638fcf945847402546..e6e272b0e60529b67e16f1b99adbd52ae015b1a1 100644 (file)
@@ -163,7 +163,7 @@ static struct neigh_ops arp_direct_ops =
        dev_queue_xmit
 };
 
-#if defined(CONFIG_AX25) || defined(CONFIG_AX25) || \
+#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) || \
     defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE)
 struct neigh_ops arp_broken_ops =
 {
@@ -261,7 +261,7 @@ static int arp_constructor(struct neighbour *neigh)
                default:
                        break;
                case ARPHRD_ROSE:       
-#if defined(CONFIG_AX25) || defined(CONFIG_AX25)
+#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
                case ARPHRD_AX25:
 #if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)
                case ARPHRD_NETROM:
index 5f760d394fb620fab9d172d7eeb9e20ed2eeeda8..1e5a509d473c5ef3ec19421ed22562fb5f43fd96 100644 (file)
@@ -1204,8 +1204,8 @@ struct proto_ops packet_ops = {
        packet_release,
        packet_bind,
        sock_no_connect,
-       NULL,
-       NULL,
+       sock_no_socketpair,
+       sock_no_accept,
        packet_getname, 
        datagram_poll,
        packet_ioctl,