diff -u --recursive --new-file v2.1.115/linux/CREDITS linux/CREDITS --- v2.1.115/linux/CREDITS Thu Aug 6 14:06:27 1998 +++ linux/CREDITS Sun Aug 9 12:09:05 1998 @@ -706,8 +706,8 @@ 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 diff -u --recursive --new-file v2.1.115/linux/Documentation/magic-number.txt linux/Documentation/magic-number.txt --- v2.1.115/linux/Documentation/magic-number.txt Tue Sep 23 19:17:35 1997 +++ linux/Documentation/magic-number.txt Sun Aug 9 12:15:49 1998 @@ -26,7 +26,7 @@ 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 @@ 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 + + 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 -u --recursive --new-file v2.1.115/linux/Documentation/radiotrack.txt linux/Documentation/radiotrack.txt --- v2.1.115/linux/Documentation/radiotrack.txt Wed Dec 31 16:00:00 1969 +++ linux/Documentation/radiotrack.txt Sun Aug 9 12:15:49 1998 @@ -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 -u --recursive --new-file v2.1.115/linux/Documentation/sound/ChangeLog.multisound linux/Documentation/sound/ChangeLog.multisound --- v2.1.115/linux/Documentation/sound/ChangeLog.multisound Wed Dec 31 16:00:00 1969 +++ linux/Documentation/sound/ChangeLog.multisound Sun Aug 9 12:15:49 1998 @@ -0,0 +1,137 @@ +1998-08-06 Andrew Veliath + + * 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 + + * Update version to 0.7.1 + + * Add more OSS ioctls + +1998-07-19 Andrew Veliath + + * 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 + + * 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 + + * 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 + + * 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 + + * Update version to 0.5 + + * Separate reset queue functions for play and record + + * Add delays in dsp_halt + +1998-05-24 Andrew Veliath + + * 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 + + * Update version to 0.4c + + * Hopefully fix the mixer volume problem + +1998-05-19 Andrew Veliath + + * 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 + + * 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 + + * Update version to 0.4 + + * Fix read/write return values + +1998-05-13 Andrew Veliath + + * 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 + + * Update version to 0.2 + + * Add preliminary playback support + + * Use new Turtle Beach DSP code \ No newline at end of file diff -u --recursive --new-file v2.1.115/linux/Documentation/sound/MultiSound linux/Documentation/sound/MultiSound --- v2.1.115/linux/Documentation/sound/MultiSound Thu Jul 16 18:09:22 1998 +++ linux/Documentation/sound/MultiSound Sun Aug 9 12:15:49 1998 @@ -9,8 +9,8 @@ ~~~~~~~~~~~~~~~~~~ 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 @@ 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 @@ 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 @@ -- 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 @@ 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 +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + int fd; + unsigned long recmask, recsrc; + + if (argc != 2) { + fprintf(stderr, "usage: setdigital \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 -- diff -u --recursive --new-file v2.1.115/linux/Documentation/sound/OPL3-SA linux/Documentation/sound/OPL3-SA --- v2.1.115/linux/Documentation/sound/OPL3-SA Tue Jul 21 00:15:29 1998 +++ linux/Documentation/sound/OPL3-SA Sun Aug 9 12:15:49 1998 @@ -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 @@ Questions? Comments? - diff -u --recursive --new-file v2.1.115/linux/Documentation/sound/Wavefront linux/Documentation/sound/Wavefront --- v2.1.115/linux/Documentation/sound/Wavefront Tue Jul 21 00:15:29 1998 +++ linux/Documentation/sound/Wavefront Sun Aug 9 12:15:49 1998 @@ -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 @@ 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 @@ 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 @@ * 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 @@ 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 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 @@ cd 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 @@ #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 @@ 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 @@ 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 @@ %% ^S[28].*\r$ printf ("%c%.*s", yyleng-1,yyleng-1,yytext); <> { fputc ('\0', stdout); return; } -\n {} +\n {} . {} ---- cut here ------------------------- @@ -241,7 +248,7 @@ 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 @@ 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 @@ 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 @@ 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,45 +339,33 @@ 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. > + 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. + 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? ********************************************************************** Just me: Paul Barton-Davis - diff -u --recursive --new-file v2.1.115/linux/MAINTAINERS linux/MAINTAINERS --- v2.1.115/linux/MAINTAINERS Mon Aug 3 12:45:43 1998 +++ linux/MAINTAINERS Sun Aug 9 12:15:49 1998 @@ -330,9 +330,9 @@ 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) diff -u --recursive --new-file v2.1.115/linux/Makefile linux/Makefile --- v2.1.115/linux/Makefile Thu Aug 6 14:06:28 1998 +++ linux/Makefile Thu Aug 6 14:06:13 1998 @@ -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/) diff -u --recursive --new-file v2.1.115/linux/arch/alpha/Makefile linux/arch/alpha/Makefile --- v2.1.115/linux/arch/alpha/Makefile Tue Jul 21 00:15:29 1998 +++ linux/arch/alpha/Makefile Sun Aug 9 12:09:05 1998 @@ -10,35 +10,42 @@ 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 @@ @$(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: diff -u --recursive --new-file v2.1.115/linux/arch/alpha/config.in linux/arch/alpha/config.in --- v2.1.115/linux/arch/alpha/config.in Thu Aug 6 14:06:28 1998 +++ linux/arch/alpha/config.in Sun Aug 9 12:09:05 1998 @@ -31,30 +31,30 @@ 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_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 diff -u --recursive --new-file v2.1.115/linux/arch/alpha/defconfig linux/arch/alpha/defconfig --- v2.1.115/linux/arch/alpha/defconfig Thu Aug 6 14:06:28 1998 +++ linux/arch/alpha/defconfig Sun Aug 9 12:14:08 1998 @@ -18,35 +18,32 @@ # 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 diff -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/Makefile linux/arch/alpha/kernel/Makefile --- v2.1.115/linux/arch/alpha/kernel/Makefile Wed Apr 1 20:11:47 1998 +++ linux/arch/alpha/kernel/Makefile Sun Aug 9 12:09:05 1998 @@ -20,44 +20,101 @@ 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 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 diff -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/alpha_ksyms.c linux/arch/alpha/kernel/alpha_ksyms.c --- v2.1.115/linux/arch/alpha/kernel/alpha_ksyms.c Thu Jul 16 18:09:23 1998 +++ linux/arch/alpha/kernel/alpha_ksyms.c Sun Aug 9 12:09:05 1998 @@ -25,6 +25,7 @@ #include #include #include +#include #define __KERNEL_SYSCALLS__ #include @@ -43,6 +44,7 @@ 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 @@ #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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/apecs.c linux/arch/alpha/kernel/apecs.c --- v2.1.115/linux/arch/alpha/kernel/apecs.c Wed Jun 24 22:54:02 1998 +++ linux/arch/alpha/kernel/apecs.c Wed Dec 31 16:00:00 1969 @@ -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 -#include -#include -#include - -#include -#include -#include -#include - -/* - * 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 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 - } -} diff -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/bios32.c linux/arch/alpha/kernel/bios32.c --- v2.1.115/linux/arch/alpha/kernel/bios32.c Tue Jul 21 00:15:29 1998 +++ linux/arch/alpha/kernel/bios32.c Sun Aug 9 12:09:05 1998 @@ -31,9 +31,15 @@ #include #include #include +#include #include -#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) @@ -43,161 +49,288 @@ asmlinkage int sys_pciconfig_read() { return -ENOSYS; } asmlinkage int sys_pciconfig_write() { return -ENOSYS; } +void reset_for_srm(void) { } #else /* CONFIG_PCI */ #include #include -#include #include #include #include #include - -#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) +{ +} -/* - * 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; +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; +} -#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. - */ -#define DEFAULT_MEM_BASE (16*MB + 2*MB) /* 16M to 64M-1 is avail */ -#elif defined(CONFIG_ALPHA_LCA) || defined(CONFIG_ALPHA_APECS) /* - * 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. + * Gory details start here... */ -#define DEFAULT_MEM_BASE (64*MB + 2*MB) -#else +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. - * - * Because CIA and PYXIS and T2 have more bits for physical addresses, - * they support an expanded range of SPARSE memory addresses. + * Align VAL to ALIGN, which must be a power of two. */ -#define DEFAULT_MEM_BASE (128*MB + 16*MB) +#define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1)) + + +/* + * 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. + */ + +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 @@ */ 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 @@ 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 @@ */ #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 @@ */ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ * 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 @@ 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 @@ 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) -{ - struct pci_dev *dev, *curr; - unsigned char pin; - unsigned char slot; + +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; + 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 */ + /* + * 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; - /* 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); + 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; + + if (!DEV_IS_ON_PRIMARY(dev)) { + /* Follow the chain of bridges, swizzling as we go. */ + + int spill = pin; + slot = (*swizzle)(dev, &spill); + pin = spill; + + /* 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); + } - 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)); + irq = (*map_irq)(dev, slot, pin); - /* - * 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); + DBG_DEVS(("common_pci_fixup: bus %d slot %d " + "pin %d irq %d\n", + dev->bus->number, slot, pin, irq)); + + if (irq != -1) + dev->irq = irq; + + 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); + + if (irq_orig != dev->irq) { + struct reset_irq *r; + + 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)); + + r = &srm_resets.irq[srm_resets.irq_count++]; + r->dev = dev; + r->irq = irq_orig; } } - } - 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); -} + /* 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); -/* - * 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 - -/* - * 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 - * - */ - -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 - * - */ - -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(); -} - -/* - * 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 - * - */ - -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); -} - -/* - * 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]); - - /* - * 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 defined(CONFIG_ALPHA_BOOK1) - /* for the AlphaBook1, NCR810 SCSI is 14, PCMCIA controller is 15 */ - const unsigned int new_route_tab = 0x0e0f0a0a; - -#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 - - /* - * 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; - - 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); - } - - 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]; + 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 @@ } 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) +/* Most Alphas have straight-forward swizzling needs. */ -/* - 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) +int __init +common_swizzle(struct pci_dev *dev, int *pinp) { - extern void cserve_ena(unsigned long); - extern void cserve_dis(unsigned long); + 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; - if (mask & (1UL << irq)) - /* disable */ - cserve_dis(irq - 16); - else - /* enable */ - cserve_ena(irq - 16); - return; + /* The slot is the slot of the last bridge. */ + return PCI_SLOT(dev->devfn); } -#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 */ - -__initfunc(char *pcibios_setup(char *str)) -{ - return str; -} - -#ifdef CONFIG_ALPHA_SRM_SETUP -void reset_for_srm(void) -{ - struct pci_dev *dev; - int i; - - /* 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 -} - /* FIXME: reset the video origin. */ -} -#endif /* CONFIG_ALPHA_SRM_SETUP */ - #endif /* CONFIG_PCI */ diff -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/bios32.h linux/arch/alpha/kernel/bios32.h --- v2.1.115/linux/arch/alpha/kernel/bios32.h Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/bios32.h Sun Aug 9 12:09:05 1998 @@ -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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/cia.c linux/arch/alpha/kernel/cia.c --- v2.1.115/linux/arch/alpha/kernel/cia.c Wed Jun 24 22:54:02 1998 +++ linux/arch/alpha/kernel/cia.c Wed Dec 31 16:00:00 1969 @@ -1,735 +0,0 @@ -/* - * Code common to all CIA chips. - * - * Written by David A Rusling (david.rusling@reo.mts.dec.com). - * December 1995. - * - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/* - * 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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/core_apecs.c linux/arch/alpha/kernel/core_apecs.c --- v2.1.115/linux/arch/alpha/kernel/core_apecs.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/core_apecs.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include + +#include +#include + +#define __EXTERN_INLINE inline +#include +#include +#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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/core_cia.c linux/arch/alpha/kernel/core_cia.c --- v2.1.115/linux/arch/alpha/kernel/core_cia.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/core_cia.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include +#include + +#include +#include + +#define __EXTERN_INLINE inline +#include +#include +#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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/core_lca.c linux/arch/alpha/kernel/core_lca.c --- v2.1.115/linux/arch/alpha/kernel/core_lca.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/core_lca.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include +#include + +#include +#include +#include + +#define __EXTERN_INLINE inline +#include +#include +#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_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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/core_mcpcia.c linux/arch/alpha/kernel/core_mcpcia.c --- v2.1.115/linux/arch/alpha/kernel/core_mcpcia.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/core_mcpcia.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include + +#include +#include +#include + +#define __EXTERN_INLINE inline +#include +#include +#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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/core_pyxis.c linux/arch/alpha/kernel/core_pyxis.c --- v2.1.115/linux/arch/alpha/kernel/core_pyxis.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/core_pyxis.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include +#include + +#include +#include + +#define __EXTERN_INLINE inline +#include +#include +#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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/core_t2.c linux/arch/alpha/kernel/core_t2.c --- v2.1.115/linux/arch/alpha/kernel/core_t2.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/core_t2.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include +#include + +#include +#include + +#define __EXTERN_INLINE +#include +#include +#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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/core_tsunami.c linux/arch/alpha/kernel/core_tsunami.c --- v2.1.115/linux/arch/alpha/kernel/core_tsunami.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/core_tsunami.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include +#include + +#include +#include + +#define __EXTERN_INLINE inline +#include +#include +#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 +} diff -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S --- v2.1.115/linux/arch/alpha/kernel/entry.S Sun Jul 26 11:57:14 1998 +++ linux/arch/alpha/kernel/entry.S Sun Aug 9 12:25:11 1998 @@ -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 . */ #define HAE_CACHE 0 #define HAE_REG 8 @@ -109,7 +109,7 @@ 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); \ @@ -130,7 +130,7 @@ 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 @@ .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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/es1888.c linux/arch/alpha/kernel/es1888.c --- v2.1.115/linux/arch/alpha/kernel/es1888.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/es1888.c Sun Aug 9 12:09:05 1998 @@ -0,0 +1,47 @@ +/* + * linux/arch/alpha/kernel/es1888.c + * + * Init the built-in ES1888 sound chip (SB16 compatible) + */ + +#include +#include +#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 */ +} diff -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/fpreg.c linux/arch/alpha/kernel/fpreg.c --- v2.1.115/linux/arch/alpha/kernel/fpreg.c Tue Feb 17 13:12:44 1998 +++ linux/arch/alpha/kernel/fpreg.c Sun Aug 9 12:09:05 1998 @@ -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 @@ case 29: LDT(29, val); break; case 30: LDT(30, val); break; case 31: LDT(31, val); break; - default: - break; } } diff -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/head.S linux/arch/alpha/kernel/head.S --- v2.1.115/linux/arch/alpha/kernel/head.S Sun Jun 7 11:16:26 1998 +++ linux/arch/alpha/kernel/head.S Sun Aug 9 12:09:05 1998 @@ -7,7 +7,6 @@ * the kernel global pointer and jump to the kernel entry-point. */ -#define __ASSEMBLY__ #include #define halt call_pal PAL_halt diff -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c --- v2.1.115/linux/arch/alpha/kernel/irq.c Wed Jun 24 22:54:02 1998 +++ linux/arch/alpha/kernel/irq.c Sun Aug 9 12:09:05 1998 @@ -25,14 +25,17 @@ #include #include #include -#include +#include + +#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 @@ # 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 @@ 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 @@ 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 @@ *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 @@ 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 @@ 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 @@ #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 @@ #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 @@ previous_irqholder = where; } -void __global_cli(void) +void +__global_cli(void) { int cpu = smp_processor_id(); unsigned long where; @@ -754,27 +457,30 @@ __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 @@ #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 @@ 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_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 @@ #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 @@ * 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 @@ } /* 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 @@ } } -#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,32 +676,15 @@ #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); @@ -992,8 +700,10 @@ * 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 @@ 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 @@ 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 @@ * 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 @@ 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 @@ switch (type) { case 0: #ifdef __SMP__ -/* irq_enter(smp_processor_id(), 0); ??????? */ handle_ipi(®s); -/* 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, ®s); + handle_irq(RTC_IRQ, -1, ®s); return; case 2: - machine_check(vector, la_ptr, ®s); + alpha_mv.machine_check(vector, la_ptr, ®s); return; case 3: -#if defined(CONFIG_ALPHA_JENSEN) || \ - defined(CONFIG_ALPHA_NONAME) || \ - defined(CONFIG_ALPHA_P2K) || \ - defined(CONFIG_ALPHA_SRM) - srm_device_interrupt(vector, ®s); -#elif defined(CONFIG_ALPHA_MIATA) || \ - defined(CONFIG_ALPHA_SX164) - miata_device_interrupt(vector, ®s); -#elif defined(CONFIG_ALPHA_NORITAKE) - noritake_device_interrupt(vector, ®s); -#elif defined(CONFIG_ALPHA_ALCOR) || \ - defined(CONFIG_ALPHA_XLT) - alcor_and_xlt_device_interrupt(vector, ®s); -#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, ®s); -#elif defined(CONFIG_ALPHA_MIKASA) - mikasa_device_interrupt(vector, ®s); -#elif defined(CONFIG_ALPHA_EB66) || \ - defined(CONFIG_ALPHA_EB64P) - eb66_and_eb64p_device_interrupt(vector, ®s); -#elif defined(CONFIG_ALPHA_RUFFIAN) - ruffian_device_interrupt(vector, ®s); -#elif defined(CONFIG_ALPHA_DP264) - dp264_device_interrupt(vector, ®s); -#elif defined(CONFIG_ALPHA_RAWHIDE) - rawhide_device_interrupt(vector, ®s); -#elif defined(CONFIG_ALPHA_TAKARA) - takara_device_interrupt(vector, ®s); -#elif NR_IRQS == 16 - isa_device_interrupt(vector, ®s); -#endif + alpha_mv.device_interrupt(vector, ®s); return; case 4: printk("Performance counter interrupt\n"); @@ -1761,226 +811,9 @@ 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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/irq.h linux/arch/alpha/kernel/irq.h --- v2.1.115/linux/arch/alpha/kernel/irq.h Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/irq.h Sun Aug 9 12:09:05 1998 @@ -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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/lca.c linux/arch/alpha/kernel/lca.c --- v2.1.115/linux/arch/alpha/kernel/lca.c Tue Jul 21 00:15:29 1998 +++ linux/arch/alpha/kernel/lca.c Wed Dec 31 16:00:00 1969 @@ -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 -#include -#include -#include - -#include -#include -#include -#include - -/* - * 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_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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/machvec.h linux/arch/alpha/kernel/machvec.h --- v2.1.115/linux/arch/alpha/kernel/machvec.h Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/machvec.h Sun Aug 9 12:09:05 1998 @@ -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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/mcpcia.c linux/arch/alpha/kernel/mcpcia.c --- v2.1.115/linux/arch/alpha/kernel/mcpcia.c Tue Jul 21 00:15:29 1998 +++ linux/arch/alpha/kernel/mcpcia.c Wed Dec 31 16:00:00 1969 @@ -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 -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/* - * 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 */ diff -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/osf_sys.c linux/arch/alpha/kernel/osf_sys.c --- v2.1.115/linux/arch/alpha/kernel/osf_sys.c Thu Aug 6 14:06:28 1998 +++ linux/arch/alpha/kernel/osf_sys.c Sun Aug 9 12:25:11 1998 @@ -47,7 +47,7 @@ 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 @@ int ret; lock_kernel(); - ret = sys_umount(path); + ret = sys_umount(path,flag); unlock_kernel(); return ret; } diff -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c --- v2.1.115/linux/arch/alpha/kernel/process.c Thu Aug 6 14:06:28 1998 +++ linux/arch/alpha/kernel/process.c Sun Aug 9 12:09:05 1998 @@ -28,6 +28,7 @@ #include #include #include +#include #ifdef CONFIG_RTC #include @@ -41,6 +42,9 @@ #include #include +#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 @@ /* * 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) (®s)->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 @@ } } -asmlinkage int sys_idle(void) +asmlinkage int +sys_idle(void) { if(current->pid != 0) return -EPERM; @@ -101,7 +106,8 @@ #else /* __SMP__ */ -asmlinkage int sys_idle(void) +asmlinkage int +sys_idle(void) { int ret = -EPERM; @@ -122,90 +128,101 @@ } #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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/proto.h linux/arch/alpha/kernel/proto.h --- v2.1.115/linux/arch/alpha/kernel/proto.h Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/proto.h Sun Aug 9 12:09:05 1998 @@ -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); diff -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/ptrace.c linux/arch/alpha/kernel/ptrace.c --- v2.1.115/linux/arch/alpha/kernel/ptrace.c Mon Aug 3 12:45:43 1998 +++ linux/arch/alpha/kernel/ptrace.c Sun Aug 9 12:09:05 1998 @@ -281,10 +281,8 @@ 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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/pyxis.c linux/arch/alpha/kernel/pyxis.c --- v2.1.115/linux/arch/alpha/kernel/pyxis.c Wed Jun 24 22:54:03 1998 +++ linux/arch/alpha/kernel/pyxis.c Wed Dec 31 16:00:00 1969 @@ -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 /* CONFIG_ALPHA_RUFFIAN. */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/* 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 */ diff -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c --- v2.1.115/linux/arch/alpha/kernel/setup.c Thu Aug 6 14:06:28 1998 +++ linux/arch/alpha/kernel/setup.c Sun Aug 9 12:10:58 1998 @@ -5,10 +5,9 @@ */ /* - * bootup setup stuff.. + * Bootup setup stuff. */ -#include #include #include #include @@ -24,6 +23,9 @@ #include #include #include +#include +#include +#include #ifdef CONFIG_RTC #include @@ -36,8 +38,8 @@ #include #include -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 @@ # 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 @@ #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); -#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); + /* Leave refresh timer alone---nobody should depend on a + particular value anyway. */ + outb(0x54, 0x43); /* counter 1: refresh timer */ + outb(0x18, 0x41); +#endif + + 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 + + +/* + * Declare all of the machine vectors. + */ + +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; 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 */ - - wrmces(0x7); /* reset enable correctable error reports */ - - ROOT_DEV = to_kdev_t(0x0802); /* sda2 */ - command_line[COMMAND_LINE_SIZE - 1] = '\0'; - - /* 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 @@ 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? + */ + + if (hwrpb->max_asn != MAX_ASN) { + printk("Max ASN from HWRPB is bad (0x%lx)\n", hwrpb->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) + /* + * Identify the flock of penguins. + */ + +#ifdef __SMP__ + setup_smp(); +#endif +} + +static unsigned long __init +find_end_memory(void) { - struct dsr_struct *dsr; - static char unk_system_string[] = "N/A"; + int i; + unsigned long high = 0; + struct memclust_struct * cluster; + struct memdesc_struct * memdesc; - /* 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))); - } + 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 void -get_sysnames(long type, long variation, - char **type_name, char **variation_name) + +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) { - 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" +#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 char *unofficial_names[] = {"100", "Ruffian"}; + static struct alpha_machine_vector *unofficial_vecs[] __initlocaldata = + { + NULL, /* 100 */ + &ruffian_mv, + }; - 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}; + static struct alpha_machine_vector *alcor_vecs[] __initlocaldata = + { + &alcor_mv, &xlt_mv, &xlt_mv + }; - 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}; + static struct alpha_machine_vector *eb164_vecs[] __initlocaldata = + { + &eb164_mv, &pc164_mv, &lx164_mv, &sx164_mv + }; - static char * eb64p_names[] = {"EB64+", "Cabriolet", "AlphaPCI64"}; - static int eb64p_indices[] = {0,0,1,2}; + static struct alpha_machine_vector *eb64p_vecs[] __initlocaldata = + { + &eb64p_mv, + &cabriolet_mv, + NULL /* AlphaPCI64 */ + }; - static char * eb66_names[] = {"EB66", "EB66+"}; - static int eb66_indices[] = {0,0,1}; + static struct alpha_machine_vector *eb66_vecs[] __initlocaldata = + { + &eb66_mv, + &eb66p_mv + }; + + /* ??? Do we need to distinguish between Rawhides? */ - static char * rawhide_names[] = {"Dodge", "Wrangler", "Durango", - "Tincup", "DaVinci"}; - static int rawhide_indices[] = {0,0,0,1,1,2,2,3,3,4,4}; + struct alpha_machine_vector *vec; + /* 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]; + } + + /* 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 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 + }; + + 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 @@ 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 @@ */ 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 @@ 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 @@ 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 - ); } diff -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/smp.c linux/arch/alpha/kernel/smp.c --- v2.1.115/linux/arch/alpha/kernel/smp.c Thu Aug 6 14:06:28 1998 +++ linux/arch/alpha/kernel/smp.c Sun Aug 9 12:09:05 1998 @@ -24,6 +24,8 @@ #define __KERNEL_SYSCALLS__ #include +#include "proto.h" + struct ipi_msg_flush_tb_struct ipi_msg_flush_tb; struct cpuinfo_alpha cpu_data[NR_CPUS]; @@ -735,15 +737,11 @@ } } -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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/sys_alcor.c linux/arch/alpha/kernel/sys_alcor.c --- v2.1.115/linux/arch/alpha/kernel/sys_alcor.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/sys_alcor.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/sys_cabriolet.c linux/arch/alpha/kernel/sys_cabriolet.c --- v2.1.115/linux/arch/alpha/kernel/sys_cabriolet.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/sys_cabriolet.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/sys_dp264.c linux/arch/alpha/kernel/sys_dp264.c --- v2.1.115/linux/arch/alpha/kernel/sys_dp264.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/sys_dp264.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/sys_eb64p.c linux/arch/alpha/kernel/sys_eb64p.c --- v2.1.115/linux/arch/alpha/kernel/sys_eb64p.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/sys_eb64p.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/sys_jensen.c linux/arch/alpha/kernel/sys_jensen.c --- v2.1.115/linux/arch/alpha/kernel/sys_jensen.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/sys_jensen.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include +#include + +#include +#include + +#define __EXTERN_INLINE inline +#include +#include +#undef __EXTERN_INLINE + +#include +#include +#include +#include + +#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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/sys_miata.c linux/arch/alpha/kernel/sys_miata.c --- v2.1.115/linux/arch/alpha/kernel/sys_miata.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/sys_miata.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/sys_mikasa.c linux/arch/alpha/kernel/sys_mikasa.c --- v2.1.115/linux/arch/alpha/kernel/sys_mikasa.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/sys_mikasa.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/sys_noritake.c linux/arch/alpha/kernel/sys_noritake.c --- v2.1.115/linux/arch/alpha/kernel/sys_noritake.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/sys_noritake.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/sys_rawhide.c linux/arch/alpha/kernel/sys_rawhide.c --- v2.1.115/linux/arch/alpha/kernel/sys_rawhide.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/sys_rawhide.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/sys_ruffian.c linux/arch/alpha/kernel/sys_ruffian.c --- v2.1.115/linux/arch/alpha/kernel/sys_ruffian.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/sys_ruffian.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/sys_sable.c linux/arch/alpha/kernel/sys_sable.c --- v2.1.115/linux/arch/alpha/kernel/sys_sable.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/sys_sable.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/sys_sio.c linux/arch/alpha/kernel/sys_sio.c --- v2.1.115/linux/arch/alpha/kernel/sys_sio.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/sys_sio.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/sys_sx164.c linux/arch/alpha/kernel/sys_sx164.c --- v2.1.115/linux/arch/alpha/kernel/sys_sx164.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/sys_sx164.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/sys_takara.c linux/arch/alpha/kernel/sys_takara.c --- v2.1.115/linux/arch/alpha/kernel/sys_takara.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/sys_takara.c Sun Aug 9 12:09:05 1998 @@ -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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/t2.c linux/arch/alpha/kernel/t2.c --- v2.1.115/linux/arch/alpha/kernel/t2.c Wed Jun 24 22:54:03 1998 +++ linux/arch/alpha/kernel/t2.c Wed Dec 31 16:00:00 1969 @@ -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 -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/* - * 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]); - } -} diff -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c --- v2.1.115/linux/arch/alpha/kernel/traps.c Tue Jul 28 14:21:07 1998 +++ linux/arch/alpha/kernel/traps.c Sun Aug 9 12:09:05 1998 @@ -20,8 +20,10 @@ #include #include +#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 @@ 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 @@ 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 @@ 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 @@ } #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 @@ } 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", ®s, 0, 0); force_sig(SIGFPE, current); unlock_kernel(); @@ -202,7 +207,6 @@ 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 @@ #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 @@ * 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 @@ * 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 @@ #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 @@ /* * 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 @@ 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 -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/tsunami.c linux/arch/alpha/kernel/tsunami.c --- v2.1.115/linux/arch/alpha/kernel/tsunami.c Wed Jun 24 22:54:03 1998 +++ linux/arch/alpha/kernel/tsunami.c Wed Dec 31 16:00:00 1969 @@ -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 -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/* - * 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 */ diff -u --recursive --new-file v2.1.115/linux/arch/alpha/lib/Makefile linux/arch/alpha/lib/Makefile --- v2.1.115/linux/arch/alpha/lib/Makefile Thu Feb 12 20:56:04 1998 +++ linux/arch/alpha/lib/Makefile Sun Aug 9 12:09:05 1998 @@ -7,7 +7,7 @@ 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) diff -u --recursive --new-file v2.1.115/linux/arch/alpha/lib/io.c linux/arch/alpha/lib/io.c --- v2.1.115/linux/arch/alpha/lib/io.c Tue Jul 21 00:15:29 1998 +++ linux/arch/alpha/lib/io.c Sun Aug 9 12:09:05 1998 @@ -6,23 +6,6 @@ #include #include -/* - * 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 @@ /* * "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 -u --recursive --new-file v2.1.115/linux/arch/alpha/lib/strcasecmp.c linux/arch/alpha/lib/strcasecmp.c --- v2.1.115/linux/arch/alpha/lib/strcasecmp.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/lib/strcasecmp.c Sun Aug 9 12:09:05 1998 @@ -0,0 +1,26 @@ +/* + * linux/arch/alpha/lib/strcasecmp.c + */ + +#include + + +/* 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; +} diff -u --recursive --new-file v2.1.115/linux/arch/alpha/math-emu/fp-emul.c linux/arch/alpha/math-emu/fp-emul.c --- v2.1.115/linux/arch/alpha/math-emu/fp-emul.c Tue Jul 21 00:15:29 1998 +++ linux/arch/alpha/math-emu/fp-emul.c Sun Aug 9 12:09:06 1998 @@ -61,23 +61,33 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ * result: */ alpha_write_fp_reg(fc, vc); + + MOD_DEC_USE_COUNT; return 1; } diff -u --recursive --new-file v2.1.115/linux/arch/alpha/mm/fault.c linux/arch/alpha/mm/fault.c --- v2.1.115/linux/arch/alpha/mm/fault.c Wed Jun 24 22:54:03 1998 +++ linux/arch/alpha/mm/fault.c Sun Aug 9 12:09:06 1998 @@ -4,23 +4,31 @@ * Copyright (C) 1995 Linus Torvalds */ -#include #include -#include #include +#include + +#define __EXTERN_INLINE inline +#include +#include +#undef __EXTERN_INLINE + +#include +#include +#include #include #include #include #include #include -#include #include #include #include #include -#include -#include + +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 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 @@ */ /* 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; diff -u --recursive --new-file v2.1.115/linux/arch/alpha/mm/init.c linux/arch/alpha/mm/init.c --- v2.1.115/linux/arch/alpha/mm/init.c Thu Aug 6 14:06:28 1998 +++ linux/arch/alpha/mm/init.c Sun Aug 9 12:09:06 1998 @@ -32,19 +32,22 @@ 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 @@ 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 @@ * 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 @@ 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 @@ 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 @@ * 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 @@ } #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 @@ return; } -void free_initmem (void) +void +free_initmem (void) { extern char __init_begin, __init_end; unsigned long addr; @@ -306,7 +307,8 @@ (&__init_end - &__init_begin) >> 10); } -void si_meminfo(struct sysinfo *val) +void +si_meminfo(struct sysinfo *val) { int i; diff -u --recursive --new-file v2.1.115/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S --- v2.1.115/linux/arch/i386/kernel/entry.S Thu Aug 6 14:06:28 1998 +++ linux/arch/i386/kernel/entry.S Sun Aug 9 12:25:11 1998 @@ -396,7 +396,7 @@ .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 @@ .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 */ diff -u --recursive --new-file v2.1.115/linux/arch/i386/kernel/head.S linux/arch/i386/kernel/head.S --- v2.1.115/linux/arch/i386/kernel/head.S Thu Jul 16 18:09:23 1998 +++ linux/arch/i386/kernel/head.S Sat Aug 8 10:44:15 1998 @@ -241,9 +241,6 @@ #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: diff -u --recursive --new-file v2.1.115/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c --- v2.1.115/linux/arch/i386/kernel/setup.c Tue Jul 21 00:15:30 1998 +++ linux/arch/i386/kernel/setup.c Fri Aug 7 16:55:22 1998 @@ -36,6 +36,7 @@ #include #include #include +#include #include /* @@ -81,12 +82,10 @@ 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 @@ -254,6 +253,27 @@ c->x86_model_id[48] = 0; 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. diff -u --recursive --new-file v2.1.115/linux/drivers/block/genhd.c linux/drivers/block/genhd.c --- v2.1.115/linux/drivers/block/genhd.c Thu Aug 6 14:06:31 1998 +++ linux/drivers/block/genhd.c Sun Aug 9 10:42:40 1998 @@ -1101,7 +1101,6 @@ extern int soc_probe(void); #endif struct gendisk *p; - int nr=0; #ifdef CONFIG_PARPORT parport_init(); @@ -1123,10 +1122,9 @@ 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 @@ 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 diff -u --recursive --new-file v2.1.115/linux/drivers/block/loop.c linux/drivers/block/loop.c --- v2.1.115/linux/drivers/block/loop.c Tue Jul 21 00:15:30 1998 +++ linux/drivers/block/loop.c Fri Aug 7 17:56:09 1998 @@ -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 - 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 @@ 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) diff -u --recursive --new-file v2.1.115/linux/drivers/block/trm290.c linux/drivers/block/trm290.c --- v2.1.115/linux/drivers/block/trm290.c Thu May 7 22:51:48 1998 +++ linux/drivers/block/trm290.c Fri Aug 7 17:56:09 1998 @@ -249,7 +249,7 @@ 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 { /* diff -u --recursive --new-file v2.1.115/linux/drivers/char/apm_bios.c linux/drivers/char/apm_bios.c --- v2.1.115/linux/drivers/char/apm_bios.c Sun Jun 7 11:16:29 1998 +++ linux/drivers/char/apm_bios.c Sun Aug 9 10:42:41 1998 @@ -515,6 +515,8 @@ 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 @@ return (error >> 8); return APM_SUCCESS; } +#endif static inline int apm_engage_power_management(u_short device) { diff -u --recursive --new-file v2.1.115/linux/drivers/char/bttv.c linux/drivers/char/bttv.c --- v2.1.115/linux/drivers/char/bttv.c Sun Jul 26 11:57:15 1998 +++ linux/drivers/char/bttv.c Sun Aug 9 12:16:36 1998 @@ -156,6 +156,7 @@ 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 @@ 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 @@ */ 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 @@ 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 @@ bttv_close, bttv_read, bttv_write, + NULL, /* poll */ bttv_ioctl, bttv_mmap, bttv_init_done, @@ -1980,6 +1997,20 @@ 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 @@ vbi_close, vbi_read, bttv_write, + vbi_poll, vbi_ioctl, NULL, /* no mmap yet */ bttv_init_done, @@ -2113,6 +2145,7 @@ 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 @@ 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 @@ 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 @@ 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); diff -u --recursive --new-file v2.1.115/linux/drivers/char/bw-qcam.c linux/drivers/char/bw-qcam.c --- v2.1.115/linux/drivers/char/bw-qcam.c Sun Jun 7 11:16:29 1998 +++ linux/drivers/char/bw-qcam.c Sun Aug 9 12:17:56 1998 @@ -842,6 +842,7 @@ qcam_close, qcam_read, qcam_write, + NULL, qcam_ioctl, NULL, qcam_init_done, diff -u --recursive --new-file v2.1.115/linux/drivers/char/c-qcam.c linux/drivers/char/c-qcam.c --- v2.1.115/linux/drivers/char/c-qcam.c Tue Jul 21 00:15:31 1998 +++ linux/drivers/char/c-qcam.c Sun Aug 9 12:20:30 1998 @@ -646,6 +646,7 @@ qcam_close, qcam_read, qcam_write, + NULL, qcam_ioctl, NULL, qcam_init_done, diff -u --recursive --new-file v2.1.115/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c --- v2.1.115/linux/drivers/char/cyclades.c Thu Aug 6 14:06:31 1998 +++ linux/drivers/char/cyclades.c Sun Aug 9 10:42:41 1998 @@ -4949,7 +4949,7 @@ 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", diff -u --recursive --new-file v2.1.115/linux/drivers/char/keyboard.c linux/drivers/char/keyboard.c --- v2.1.115/linux/drivers/char/keyboard.c Thu Aug 6 14:06:31 1998 +++ linux/drivers/char/keyboard.c Fri Aug 7 17:56:09 1998 @@ -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 @@ if (ch == ' ' || ch == d) return d; + put_queue(d); return ch; } diff -u --recursive --new-file v2.1.115/linux/drivers/char/lp.c linux/drivers/char/lp.c --- v2.1.115/linux/drivers/char/lp.c Sun Jul 26 11:57:15 1998 +++ linux/drivers/char/lp.c Fri Aug 7 18:02:41 1998 @@ -564,7 +564,7 @@ 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; diff -u --recursive --new-file v2.1.115/linux/drivers/char/msp3400.c linux/drivers/char/msp3400.c --- v2.1.115/linux/drivers/char/msp3400.c Tue Jul 28 14:21:08 1998 +++ linux/drivers/char/msp3400.c Sun Aug 9 12:18:37 1998 @@ -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 @@ 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; diff -u --recursive --new-file v2.1.115/linux/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c --- v2.1.115/linux/drivers/char/pc_keyb.c Thu Aug 6 14:06:31 1998 +++ linux/drivers/char/pc_keyb.c Fri Aug 7 17:56:09 1998 @@ -50,7 +50,7 @@ */ /* - * 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] */ diff -u --recursive --new-file v2.1.115/linux/drivers/char/pms.c linux/drivers/char/pms.c --- v2.1.115/linux/drivers/char/pms.c Sun Jun 7 11:16:30 1998 +++ linux/drivers/char/pms.c Sun Aug 9 12:18:37 1998 @@ -893,6 +893,7 @@ pms_close, pms_read, pms_write, + NULL, /* FIXME - we can use POLL on this board with the irq */ pms_ioctl, NULL, pms_init_done, diff -u --recursive --new-file v2.1.115/linux/drivers/char/pty.c linux/drivers/char/pty.c --- v2.1.115/linux/drivers/char/pty.c Thu Aug 6 14:06:31 1998 +++ linux/drivers/char/pty.c Fri Aug 7 12:25:57 1998 @@ -7,6 +7,7 @@ * -- C. Scott Ananian , 14-Jan-1998 */ +#include #include /* For EXPORT_SYMBOL */ #include diff -u --recursive --new-file v2.1.115/linux/drivers/char/radio-aimslab.c linux/drivers/char/radio-aimslab.c --- v2.1.115/linux/drivers/char/radio-aimslab.c Thu Aug 6 14:06:31 1998 +++ linux/drivers/char/radio-aimslab.c Sun Aug 9 12:18:37 1998 @@ -155,7 +155,11 @@ /* 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 @@ rt_close, NULL, /* Can't read (no capture ability) */ NULL, /* Can't write */ + NULL, /* No poll */ rt_ioctl, NULL, NULL diff -u --recursive --new-file v2.1.115/linux/drivers/char/radio-aztech.c linux/drivers/char/radio-aztech.c --- v2.1.115/linux/drivers/char/radio-aztech.c Thu Aug 6 14:06:31 1998 +++ linux/drivers/char/radio-aztech.c Sun Aug 9 12:18:37 1998 @@ -113,7 +113,8 @@ { 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 @@ az_close, NULL, /* Can't read (no capture ability) */ NULL, /* Can't write */ + NULL, /* No poll */ az_ioctl, NULL, NULL diff -u --recursive --new-file v2.1.115/linux/drivers/char/radio-rtrack2.c linux/drivers/char/radio-rtrack2.c --- v2.1.115/linux/drivers/char/radio-rtrack2.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/radio-rtrack2.c Sun Aug 9 12:18:37 1998 @@ -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 + * Various bugfixes and enhancements by Russell Kroll + * + * TODO: Allow for more than one of these foolish entities :-) + * + */ + +#include /* Modules */ +#include /* Initdata */ +#include /* check_region, request_region */ +#include /* udelay */ +#include /* outb, outb_p */ +#include /* copy to/from user */ +#include /* kernel radio structs */ +#include /* 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: +*/ diff -u --recursive --new-file v2.1.115/linux/drivers/char/radio-sf16fmi.c linux/drivers/char/radio-sf16fmi.c --- v2.1.115/linux/drivers/char/radio-sf16fmi.c Tue Jul 21 00:15:31 1998 +++ linux/drivers/char/radio-sf16fmi.c Sun Aug 9 12:18:37 1998 @@ -29,6 +29,7 @@ int port; int curvol; unsigned long curfreq; + int flags; }; #ifndef CONFIG_RADIO_SF16FMI_PORT @@ -39,7 +40,8 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } 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) diff -u --recursive --new-file v2.1.115/linux/drivers/char/radio-zoltrix.c linux/drivers/char/radio-zoltrix.c --- v2.1.115/linux/drivers/char/radio-zoltrix.c Tue Jul 21 00:15:31 1998 +++ linux/drivers/char/radio-zoltrix.c Sun Aug 9 12:18:37 1998 @@ -2,14 +2,14 @@ * (c) 1998 C. van Schaik * * 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 @@ 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 @@ { /* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ zol_close, NULL, /* Can't read (no capture ability) */ NULL, /* Can't write */ + NULL, zol_ioctl, NULL, NULL diff -u --recursive --new-file v2.1.115/linux/drivers/char/videodev.c linux/drivers/char/videodev.c --- v2.1.115/linux/drivers/char/videodev.c Tue Jul 21 00:15:31 1998 +++ linux/drivers/char/videodev.c Sun Aug 9 12:18:37 1998 @@ -108,7 +108,6 @@ } - /* * Write for now does nothing. No reason it shouldnt do overlay setting * for some boards I guess.. @@ -124,6 +123,21 @@ 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 @@ video_read, video_write, NULL, /* readdir */ - NULL, /* poll */ + video_poll, /* poll */ video_ioctl, video_mmap, video_open, diff -u --recursive --new-file v2.1.115/linux/drivers/net/3c509.c linux/drivers/net/3c509.c --- v2.1.115/linux/drivers/net/3c509.c Tue Jul 28 14:21:08 1998 +++ linux/drivers/net/3c509.c Sun Aug 9 10:42:41 1998 @@ -178,6 +178,9 @@ } #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++) @@ -195,6 +198,7 @@ } #endif +#endif /* Reset the ISA PnP mechanism on 3c509b. */ outb(0x02, 0x279); /* Select PnP config control register. */ @@ -208,7 +212,7 @@ 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; diff -u --recursive --new-file v2.1.115/linux/drivers/net/plip.c linux/drivers/net/plip.c --- v2.1.115/linux/drivers/net/plip.c Tue Jul 28 14:21:08 1998 +++ linux/drivers/net/plip.c Sun Aug 9 12:27:52 1998 @@ -382,7 +382,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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; diff -u --recursive --new-file v2.1.115/linux/drivers/net/shaper.c linux/drivers/net/shaper.c --- v2.1.115/linux/drivers/net/shaper.c Tue Jun 9 11:57:30 1998 +++ linux/drivers/net/shaper.c Sun Aug 9 12:27:52 1998 @@ -128,6 +128,7 @@ static void shaper_setspeed(struct shaper *shaper, int bitspersec) { + shaper->bitspersec=bitspersec; shaper->bytespertick=(bitspersec/HZ)/8; if(!shaper->bytespertick) shaper->bytespertick++; @@ -549,17 +550,27 @@ { 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; diff -u --recursive --new-file v2.1.115/linux/drivers/net/tlan.c linux/drivers/net/tlan.c --- v2.1.115/linux/drivers/net/tlan.c Sun Jul 26 11:57:16 1998 +++ linux/drivers/net/tlan.c Sun Aug 9 10:42:41 1998 @@ -48,15 +48,16 @@ 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; diff -u --recursive --new-file v2.1.115/linux/drivers/net/tlan.h linux/drivers/net/tlan.h --- v2.1.115/linux/drivers/net/tlan.h Tue Jul 21 00:15:31 1998 +++ linux/drivers/net/tlan.h Sun Aug 9 10:42:41 1998 @@ -496,6 +496,24 @@ #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 @@ } - - - +#endif /* I_LIKE_A_FAST_HASH_FUNCTION */ #endif diff -u --recursive --new-file v2.1.115/linux/drivers/video/tgafb.c linux/drivers/video/tgafb.c --- v2.1.115/linux/drivers/video/tgafb.c Mon Aug 3 12:45:47 1998 +++ linux/drivers/video/tgafb.c Sun Aug 9 12:09:06 1998 @@ -688,7 +688,7 @@ 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 @@ 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; diff -u --recursive --new-file v2.1.115/linux/drivers/video/vgacon.c linux/drivers/video/vgacon.c --- v2.1.115/linux/drivers/video/vgacon.c Thu Aug 6 14:06:33 1998 +++ linux/drivers/video/vgacon.c Sun Aug 9 12:06:00 1998 @@ -453,6 +453,8 @@ */ 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 @@ 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); } diff -u --recursive --new-file v2.1.115/linux/fs/exec.c linux/fs/exec.c --- v2.1.115/linux/fs/exec.c Sun Jun 7 11:16:36 1998 +++ linux/fs/exec.c Sun Aug 9 12:06:35 1998 @@ -392,7 +392,7 @@ 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 @@ 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 @@ /* 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: diff -u --recursive --new-file v2.1.115/linux/fs/nfsd/vfs.c linux/fs/nfsd/vfs.c --- v2.1.115/linux/fs/nfsd/vfs.c Tue Jul 21 00:15:32 1998 +++ linux/fs/nfsd/vfs.c Thu Aug 6 22:15:29 1998 @@ -1157,10 +1157,7 @@ /* 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; diff -u --recursive --new-file v2.1.115/linux/fs/proc/array.c linux/fs/proc/array.c --- v2.1.115/linux/fs/proc/array.c Mon Aug 3 12:45:47 1998 +++ linux/fs/proc/array.c Sun Aug 9 10:42:41 1998 @@ -35,6 +35,8 @@ * - Incorporation and non-SMP safe operation * of forissier patch in 2.1.78 by * Hans Marcus + * + * aeb@cwi.nl : /proc/partitions */ #include @@ -1191,6 +1193,7 @@ 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 *); @@ -1249,6 +1252,9 @@ case PROC_DEVICES: return get_device_list(page); + + case PROC_PARTITIONS: + return get_partition_list(page); case PROC_INTERRUPTS: return get_irq_list(page); diff -u --recursive --new-file v2.1.115/linux/fs/proc/generic.c linux/fs/proc/generic.c --- v2.1.115/linux/fs/proc/generic.c Sun Jul 26 11:57:18 1998 +++ linux/fs/proc/generic.c Sun Aug 9 10:42:41 1998 @@ -283,7 +283,11 @@ 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); } /* diff -u --recursive --new-file v2.1.115/linux/fs/proc/root.c linux/fs/proc/root.c --- v2.1.115/linux/fs/proc/root.c Mon Aug 3 12:45:47 1998 +++ linux/fs/proc/root.c Sun Aug 9 10:42:41 1998 @@ -560,6 +560,11 @@ 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 @@ #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); diff -u --recursive --new-file v2.1.115/linux/fs/super.c linux/fs/super.c --- v2.1.115/linux/fs/super.c Tue Jul 21 00:15:32 1998 +++ linux/fs/super.c Sun Aug 9 12:25:12 1998 @@ -633,7 +633,7 @@ 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 @@ * 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 @@ 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 @@ 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 @@ * 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,13 +795,22 @@ 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. */ int fs_may_mount(kdev_t dev) @@ -1263,7 +1273,7 @@ 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); diff -u --recursive --new-file v2.1.115/linux/fs/vfat/namei.c linux/fs/vfat/namei.c --- v2.1.115/linux/fs/vfat/namei.c Thu Jul 16 18:09:28 1998 +++ linux/fs/vfat/namei.c Sat Aug 8 10:27:42 1998 @@ -1822,6 +1822,8 @@ put_new_inode = 0; } + clear_inode(old_inode); + rename_done: if (locked) fat_unlock_creation(); diff -u --recursive --new-file v2.1.115/linux/include/asm-alpha/apecs.h linux/include/asm-alpha/apecs.h --- v2.1.115/linux/include/asm-alpha/apecs.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-alpha/apecs.h Wed Dec 31 16:00:00 1969 @@ -1,588 +0,0 @@ -#ifndef __ALPHA_APECS__H__ -#define __ALPHA_APECS__H__ - -#include - -/* - * 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 - -#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 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 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__ */ diff -u --recursive --new-file v2.1.115/linux/include/asm-alpha/bitops.h linux/include/asm-alpha/bitops.h --- v2.1.115/linux/include/asm-alpha/bitops.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-alpha/bitops.h Sun Aug 9 12:09:06 1998 @@ -46,10 +46,10 @@ __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 @@ __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 @@ __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 @@ __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(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 @@ bofs = ffz_b(bits); return qofs*8 + bofs; +#endif } #ifdef __KERNEL__ @@ -190,16 +196,34 @@ * 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 -u --recursive --new-file v2.1.115/linux/include/asm-alpha/cia.h linux/include/asm-alpha/cia.h --- v2.1.115/linux/include/asm-alpha/cia.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-alpha/cia.h Wed Dec 31 16:00:00 1969 @@ -1,606 +0,0 @@ -#ifndef __ALPHA_CIA__H__ -#define __ALPHA_CIA__H__ - -#include -#include - -/* - * 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 -u --recursive --new-file v2.1.115/linux/include/asm-alpha/compiler.h linux/include/asm-alpha/compiler.h --- v2.1.115/linux/include/asm-alpha/compiler.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-alpha/compiler.h Sun Aug 9 12:09:06 1998 @@ -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 -u --recursive --new-file v2.1.115/linux/include/asm-alpha/core_apecs.h linux/include/asm-alpha/core_apecs.h --- v2.1.115/linux/include/asm-alpha/core_apecs.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-alpha/core_apecs.h Sun Aug 9 12:09:06 1998 @@ -0,0 +1,627 @@ +#ifndef __ALPHA_APECS__H__ +#define __ALPHA_APECS__H__ + +#include +#include +#include + +/* + * 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 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 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 -u --recursive --new-file v2.1.115/linux/include/asm-alpha/core_cia.h linux/include/asm-alpha/core_cia.h --- v2.1.115/linux/include/asm-alpha/core_cia.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-alpha/core_cia.h Sun Aug 9 12:09:06 1998 @@ -0,0 +1,601 @@ +#ifndef __ALPHA_CIA__H__ +#define __ALPHA_CIA__H__ + +#include +#include +#include + +/* + * 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 -u --recursive --new-file v2.1.115/linux/include/asm-alpha/core_lca.h linux/include/asm-alpha/core_lca.h --- v2.1.115/linux/include/asm-alpha/core_lca.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-alpha/core_lca.h Sun Aug 9 12:09:06 1998 @@ -0,0 +1,429 @@ +#ifndef __ALPHA_LCA__H__ +#define __ALPHA_LCA__H__ + +#include +#include +#include + +/* + * 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 -u --recursive --new-file v2.1.115/linux/include/asm-alpha/core_mcpcia.h linux/include/asm-alpha/core_mcpcia.h --- v2.1.115/linux/include/asm-alpha/core_mcpcia.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-alpha/core_mcpcia.h Sun Aug 9 12:09:06 1998 @@ -0,0 +1,632 @@ +#ifndef __ALPHA_MCPCIA__H__ +#define __ALPHA_MCPCIA__H__ + +#include +#include +#include +#include + +/* + * 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 -u --recursive --new-file v2.1.115/linux/include/asm-alpha/core_pyxis.h linux/include/asm-alpha/core_pyxis.h --- v2.1.115/linux/include/asm-alpha/core_pyxis.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-alpha/core_pyxis.h Sun Aug 9 12:09:06 1998 @@ -0,0 +1,684 @@ +#ifndef __ALPHA_PYXIS__H__ +#define __ALPHA_PYXIS__H__ + +#include +#include +#include + +/* + * 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 -u --recursive --new-file v2.1.115/linux/include/asm-alpha/core_t2.h linux/include/asm-alpha/core_t2.h --- v2.1.115/linux/include/asm-alpha/core_t2.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-alpha/core_t2.h Sun Aug 9 12:09:06 1998 @@ -0,0 +1,691 @@ +#ifndef __ALPHA_T2__H__ +#define __ALPHA_T2__H__ + +#include +#include +#include + + +/* + * 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 -u --recursive --new-file v2.1.115/linux/include/asm-alpha/core_tsunami.h linux/include/asm-alpha/core_tsunami.h --- v2.1.115/linux/include/asm-alpha/core_tsunami.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-alpha/core_tsunami.h Sun Aug 9 12:09:06 1998 @@ -0,0 +1,478 @@ +#ifndef __ALPHA_TSUNAMI__H__ +#define __ALPHA_TSUNAMI__H__ + +#include +#include +#include + +/* + * 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__ */ diff -u --recursive --new-file v2.1.115/linux/include/asm-alpha/dma.h linux/include/asm-alpha/dma.h --- v2.1.115/linux/include/asm-alpha/dma.h Mon Feb 23 18:12:11 1998 +++ linux/include/asm-alpha/dma.h Sun Aug 9 12:09:06 1998 @@ -19,8 +19,7 @@ #define _ASM_DMA_H #include - -#include /* need byte IO */ +#include #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 for more info. @@ -86,12 +84,18 @@ We MUST coordinate the maximum with 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 */ diff -u --recursive --new-file v2.1.115/linux/include/asm-alpha/floppy.h linux/include/asm-alpha/floppy.h --- v2.1.115/linux/include/asm-alpha/floppy.h Sat Sep 6 10:09:56 1997 +++ linux/include/asm-alpha/floppy.h Sun Aug 9 12:09:06 1998 @@ -51,13 +51,24 @@ #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 */ diff -u --recursive --new-file v2.1.115/linux/include/asm-alpha/hwrpb.h linux/include/asm-alpha/hwrpb.h --- v2.1.115/linux/include/asm-alpha/hwrpb.h Wed Apr 1 20:11:53 1998 +++ linux/include/asm-alpha/hwrpb.h Sun Aug 9 12:09:06 1998 @@ -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 @@ 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 @@ unsigned long dsr_offset; /* "Dynamic System Recognition Data Block Table" */ }; -#endif +extern struct hwrpb_struct *hwrpb; + +#endif /* __ALPHA_HWRPB_H */ diff -u --recursive --new-file v2.1.115/linux/include/asm-alpha/init.h linux/include/asm-alpha/init.h --- v2.1.115/linux/include/asm-alpha/init.h Thu Mar 26 15:57:05 1998 +++ linux/include/asm-alpha/init.h Sun Aug 9 12:09:06 1998 @@ -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 diff -u --recursive --new-file v2.1.115/linux/include/asm-alpha/io.h linux/include/asm-alpha/io.h --- v2.1.115/linux/include/asm-alpha/io.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-alpha/io.h Sun Aug 9 12:09:06 1998 @@ -2,29 +2,17 @@ #define __ALPHA_IO_H #include - #include +#include /* 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 @@ * 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 @@ #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 /* get chip-specific definitions */ -#elif defined(CONFIG_ALPHA_APECS) -# include /* 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 #elif defined(CONFIG_ALPHA_CIA) -# include /* get chip-specific definitions */ -#elif defined(CONFIG_ALPHA_T2) -# include /* get chip-specific definitions */ +# include +#elif defined(CONFIG_ALPHA_LCA) +# include +#elif defined(CONFIG_ALPHA_MCPCIA) +# include #elif defined(CONFIG_ALPHA_PYXIS) -# include /* get chip-specific definitions */ +# include +#elif defined(CONFIG_ALPHA_T2) +# include #elif defined(CONFIG_ALPHA_TSUNAMI) -# include /* get chip-specific definitions */ -#elif defined(CONFIG_ALPHA_MCPCIA) -# include /* get chip-specific definitions */ -#else +# include +#elif defined(CONFIG_ALPHA_JENSEN) # include +#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 @@ * 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 @@ #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 @@ 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 */ diff -u --recursive --new-file v2.1.115/linux/include/asm-alpha/irq.h linux/include/asm-alpha/irq.h --- v2.1.115/linux/include/asm-alpha/irq.h Thu Apr 23 20:21:37 1998 +++ linux/include/asm-alpha/irq.h Sun Aug 9 12:09:06 1998 @@ -10,18 +10,24 @@ #include #include -#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) || \ @@ -29,29 +35,52 @@ 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 @@ extern void disable_irq(unsigned int); extern void enable_irq(unsigned int); -#endif +#endif /* _ALPHA_IRQ_H */ diff -u --recursive --new-file v2.1.115/linux/include/asm-alpha/jensen.h linux/include/asm-alpha/jensen.h --- v2.1.115/linux/include/asm-alpha/jensen.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-alpha/jensen.h Sun Aug 9 12:09:06 1998 @@ -1,6 +1,8 @@ #ifndef __ALPHA_JENSEN_H #define __ALPHA_JENSEN_H +#include + /* * Defines for the AlphaPC EISA IO and memory address space. */ @@ -66,6 +68,14 @@ */ #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. * @@ -73,10 +83,16 @@ * 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 @@ -86,16 +102,19 @@ * * 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 @@ * 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 @@ * 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 @@ #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 -u --recursive --new-file v2.1.115/linux/include/asm-alpha/lca.h linux/include/asm-alpha/lca.h --- v2.1.115/linux/include/asm-alpha/lca.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-alpha/lca.h Wed Dec 31 16:00:00 1969 @@ -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 -#include - -#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 -u --recursive --new-file v2.1.115/linux/include/asm-alpha/machvec.h linux/include/asm-alpha/machvec.h --- v2.1.115/linux/include/asm-alpha/machvec.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-alpha/machvec.h Sun Aug 9 12:09:06 1998 @@ -0,0 +1,118 @@ +#ifndef __ALPHA_MACHVEC_H +#define __ALPHA_MACHVEC_H 1 + +#include +#include + + +/* 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 -u --recursive --new-file v2.1.115/linux/include/asm-alpha/mcpcia.h linux/include/asm-alpha/mcpcia.h --- v2.1.115/linux/include/asm-alpha/mcpcia.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-alpha/mcpcia.h Wed Dec 31 16:00:00 1969 @@ -1,690 +0,0 @@ -#ifndef __ALPHA_MCPCIA__H__ -#define __ALPHA_MCPCIA__H__ - -#include -#include -#include - -/* - * 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__ */ diff -u --recursive --new-file v2.1.115/linux/include/asm-alpha/mmu_context.h linux/include/asm-alpha/mmu_context.h --- v2.1.115/linux/include/asm-alpha/mmu_context.h Thu May 7 22:51:54 1998 +++ linux/include/asm-alpha/mmu_context.h Sun Aug 9 12:09:06 1998 @@ -9,6 +9,7 @@ #include #include +#include /* * The maximum ASN's the processor supports. On the EV4 this is 63 @@ -32,11 +33,17 @@ * 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 @@ * 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) -{ - 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 */ +#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) +{ + /* 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 @@ 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. :-( - */ -#define activate_context(tsk) \ - do { \ - get_mmu_context(tsk); \ - reload_context(tsk); \ - } 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. + */ + +#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 -u --recursive --new-file v2.1.115/linux/include/asm-alpha/pci.h linux/include/asm-alpha/pci.h --- v2.1.115/linux/include/asm-alpha/pci.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-alpha/pci.h Sun Aug 9 12:09:06 1998 @@ -0,0 +1,48 @@ +#ifndef __ALPHA_PCI_H +#define __ALPHA_PCI_H + +#include +#include + + +/* + * 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 */ diff -u --recursive --new-file v2.1.115/linux/include/asm-alpha/pgtable.h linux/include/asm-alpha/pgtable.h --- v2.1.115/linux/include/asm-alpha/pgtable.h Thu Aug 6 14:06:33 1998 +++ linux/include/asm-alpha/pgtable.h Sun Aug 9 12:09:06 1998 @@ -13,6 +13,8 @@ #include #include /* For TASK_SIZE */ #include +#include + /* Caches aren't brain-dead on the Alpha. */ #define flush_cache_all() do { } while (0) @@ -23,60 +25,86 @@ #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. diff -u --recursive --new-file v2.1.115/linux/include/asm-alpha/posix_types.h linux/include/asm-alpha/posix_types.h --- v2.1.115/linux/include/asm-alpha/posix_types.h Mon Dec 8 23:58:04 1997 +++ linux/include/asm-alpha/posix_types.h Sun Aug 9 12:09:06 1998 @@ -34,6 +34,8 @@ int val[2]; } __kernel_fsid_t; +#ifdef __KERNEL__ + #ifndef __GNUC__ #define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) @@ -108,5 +110,7 @@ } #endif /* __GNUC__ */ + +#endif /* __KERNEL__ */ #endif /* _ALPHA_POSIX_TYPES_H */ diff -u --recursive --new-file v2.1.115/linux/include/asm-alpha/processor.h linux/include/asm-alpha/processor.h --- v2.1.115/linux/include/asm-alpha/processor.h Sun Jul 26 11:57:19 1998 +++ linux/include/asm-alpha/processor.h Sun Aug 9 12:09:06 1998 @@ -82,13 +82,23 @@ * 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; + 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; + } - fp = ((unsigned long*)t->ksp)[6]; - return *(unsigned long*)fp; + return 0; } /* diff -u --recursive --new-file v2.1.115/linux/include/asm-alpha/pyxis.h linux/include/asm-alpha/pyxis.h --- v2.1.115/linux/include/asm-alpha/pyxis.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-alpha/pyxis.h Wed Dec 31 16:00:00 1969 @@ -1,724 +0,0 @@ -#ifndef __ALPHA_PYXIS__H__ -#define __ALPHA_PYXIS__H__ - -#include -#include - -/* - * 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__ */ diff -u --recursive --new-file v2.1.115/linux/include/asm-alpha/string.h linux/include/asm-alpha/string.h --- v2.1.115/linux/include/asm-alpha/string.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-alpha/string.h Sun Aug 9 12:09:06 1998 @@ -56,6 +56,8 @@ ? __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__ */ diff -u --recursive --new-file v2.1.115/linux/include/asm-alpha/system.h linux/include/asm-alpha/system.h --- v2.1.115/linux/include/asm-alpha/system.h Wed Apr 1 20:11:54 1998 +++ linux/include/asm-alpha/system.h Sun Aug 9 12:09:06 1998 @@ -100,13 +100,16 @@ #define switch_to(prev,next) do { \ current = next; \ - alpha_switch_to((unsigned long) ¤t->tss - 0xfffffc0000000000); \ + alpha_switch_to((unsigned long) ¤t->tss - IDENT_ADDR); \ } while (0) 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 -u --recursive --new-file v2.1.115/linux/include/asm-alpha/t2.h linux/include/asm-alpha/t2.h --- v2.1.115/linux/include/asm-alpha/t2.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-alpha/t2.h Wed Dec 31 16:00:00 1969 @@ -1,671 +0,0 @@ -#ifndef __ALPHA_T2__H__ -#define __ALPHA_T2__H__ - -#include -#include - -/* - * 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 -u --recursive --new-file v2.1.115/linux/include/asm-alpha/tsunami.h linux/include/asm-alpha/tsunami.h --- v2.1.115/linux/include/asm-alpha/tsunami.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-alpha/tsunami.h Wed Dec 31 16:00:00 1969 @@ -1,451 +0,0 @@ -#ifndef __ALPHA_TSUNAMI__H__ -#define __ALPHA_TSUNAMI__H__ - -#include -#include - -/* - * 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__ */ diff -u --recursive --new-file v2.1.115/linux/include/asm-i386/processor.h linux/include/asm-i386/processor.h --- v2.1.115/linux/include/asm-i386/processor.h Tue Jul 21 00:15:33 1998 +++ linux/include/asm-i386/processor.h Fri Aug 7 16:50:59 1998 @@ -114,37 +114,6 @@ } /* - * 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..) */ extern int EISA_bus; diff -u --recursive --new-file v2.1.115/linux/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h --- v2.1.115/linux/include/asm-i386/unistd.h Thu Aug 6 14:06:33 1998 +++ linux/include/asm-i386/unistd.h Sun Aug 9 12:25:12 1998 @@ -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 diff -u --recursive --new-file v2.1.115/linux/include/linux/genhd.h linux/include/linux/genhd.h --- v2.1.115/linux/include/linux/genhd.h Mon Jan 5 00:22:44 1998 +++ linux/include/linux/genhd.h Sun Aug 9 10:42:41 1998 @@ -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 diff -u --recursive --new-file v2.1.115/linux/include/linux/if_shaper.h linux/include/linux/if_shaper.h --- v2.1.115/linux/include/linux/if_shaper.h Tue Mar 10 10:03:35 1998 +++ linux/include/linux/if_shaper.h Sun Aug 9 12:27:53 1998 @@ -18,6 +18,7 @@ { 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 @@ #define SHAPER_SET_DEV 0x0001 #define SHAPER_SET_SPEED 0x0002 +#define SHAPER_GET_DEV 0x0003 +#define SHAPER_GET_SPEED 0x0004 struct shaperconf { diff -u --recursive --new-file v2.1.115/linux/include/linux/if_wic.h linux/include/linux/if_wic.h --- v2.1.115/linux/include/linux/if_wic.h Thu Apr 11 23:49:46 1996 +++ linux/include/linux/if_wic.h Wed Dec 31 16:00:00 1969 @@ -1,102 +0,0 @@ -#ifndef _LINUX_IF_WIC_H -#define _LINUX_IF_WIC_H - -#include - -#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 */ - - diff -u --recursive --new-file v2.1.115/linux/include/linux/mount.h linux/include/linux/mount.h --- v2.1.115/linux/include/linux/mount.h Fri May 8 23:14:56 1998 +++ linux/include/linux/mount.h Sun Aug 9 12:25:12 1998 @@ -37,4 +37,10 @@ struct vfsmount *lookup_vfsmnt(kdev_t dev); +/* + * Umount options + */ + +#define MNT_FORCE 0x00000001 /* Attempt to forcibily umount */ + #endif /* _LINUX_MOUNT_H */ diff -u --recursive --new-file v2.1.115/linux/include/linux/proc_fs.h linux/include/linux/proc_fs.h --- v2.1.115/linux/include/linux/proc_fs.h Mon Aug 3 12:45:47 1998 +++ linux/include/linux/proc_fs.h Sun Aug 9 10:42:41 1998 @@ -31,6 +31,7 @@ PROC_MODULES, PROC_STAT, PROC_DEVICES, + PROC_PARTITIONS, PROC_INTERRUPTS, PROC_FILESYSTEMS, PROC_KSYMS, diff -u --recursive --new-file v2.1.115/linux/include/linux/videodev.h linux/include/linux/videodev.h --- v2.1.115/linux/include/linux/videodev.h Sun Jul 26 11:57:19 1998 +++ linux/include/linux/videodev.h Sun Aug 9 12:18:38 1998 @@ -3,6 +3,8 @@ #ifdef __KERNEL__ +#include + struct video_device { char name[32]; @@ -14,6 +16,7 @@ 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 @@ #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 @@ { 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 @@ #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 diff -u --recursive --new-file v2.1.115/linux/ipc/msg.c linux/ipc/msg.c --- v2.1.115/linux/ipc/msg.c Thu May 7 22:51:55 1998 +++ linux/ipc/msg.c Fri Aug 7 18:28:50 1998 @@ -29,7 +29,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ return -EACCES; } - save_flags(flags); - cli(); if (msgtyp == 0) nmsg = msq->msg_first; else if (msgtyp > 0) { @@ -186,15 +169,12 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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; diff -u --recursive --new-file v2.1.115/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v2.1.115/linux/kernel/ksyms.c Thu Aug 6 14:06:34 1998 +++ linux/kernel/ksyms.c Sun Aug 9 12:23:47 1998 @@ -51,6 +51,7 @@ #include #include #include +#include extern unsigned char aux_device_present, pckbd_read_mask; @@ -389,7 +390,7 @@ #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 @@ /* dynamic registering of consoles */ EXPORT_SYMBOL(register_console); EXPORT_SYMBOL(unregister_console); + +/* time */ +EXPORT_SYMBOL(get_fast_time); diff -u --recursive --new-file v2.1.115/linux/mm/swap.c linux/mm/swap.c --- v2.1.115/linux/mm/swap.c Wed Jun 24 22:54:14 1998 +++ linux/mm/swap.c Sun Aug 9 11:17:49 1998 @@ -67,9 +67,9 @@ 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 = { diff -u --recursive --new-file v2.1.115/linux/net/ax25/af_ax25.c linux/net/ax25/af_ax25.c --- v2.1.115/linux/net/ax25/af_ax25.c Tue Jul 28 14:21:10 1998 +++ linux/net/ax25/af_ax25.c Sun Aug 9 12:23:47 1998 @@ -1009,7 +1009,10 @@ 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) diff -u --recursive --new-file v2.1.115/linux/net/core/dev.c linux/net/core/dev.c --- v2.1.115/linux/net/core/dev.c Tue Jun 23 10:01:30 1998 +++ linux/net/core/dev.c Sun Aug 9 12:23:47 1998 @@ -740,21 +740,20 @@ * 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 diff -u --recursive --new-file v2.1.115/linux/net/econet/econet.c linux/net/econet/econet.c --- v2.1.115/linux/net/econet/econet.c Tue Jul 28 14:21:10 1998 +++ linux/net/econet/econet.c Sun Aug 9 12:23:47 1998 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -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 @@ 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 @@ * drop the packet. */ -static spinlock_t aun_queue_lock; static void ab_cleanup(unsigned long h) { diff -u --recursive --new-file v2.1.115/linux/net/ipv4/arp.c linux/net/ipv4/arp.c --- v2.1.115/linux/net/ipv4/arp.c Tue Jul 28 14:21:10 1998 +++ linux/net/ipv4/arp.c Sun Aug 9 12:23:47 1998 @@ -163,7 +163,7 @@ 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 @@ 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: diff -u --recursive --new-file v2.1.115/linux/net/packet/af_packet.c linux/net/packet/af_packet.c --- v2.1.115/linux/net/packet/af_packet.c Tue Jul 28 14:21:10 1998 +++ linux/net/packet/af_packet.c Sun Aug 9 12:23:47 1998 @@ -1204,8 +1204,8 @@ packet_release, packet_bind, sock_no_connect, - NULL, - NULL, + sock_no_socketpair, + sock_no_accept, packet_getname, datagram_poll, packet_ioctl,