diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Documentation/Configure.help linux.ac/Documentation/Configure.help --- linux.vanilla/Documentation/Configure.help Sun Dec 31 19:41:40 2000 +++ linux.ac/Documentation/Configure.help Sun Dec 31 17:09:09 2000 @@ -268,6 +268,11 @@ Most normal users won't need the RAM disk functionality, and can thus say N here. +Default RAM disk size +CONFIG_BLK_DEV_RAM_SIZE + The default value is 4096. Only change this if you know what are + you doing. If you are using IBM S/390, then set this to 8192. + Initial RAM disk (initrd) support CONFIG_BLK_DEV_INITRD The initial RAM disk is a RAM disk that is loaded by the boot loader @@ -868,9 +873,9 @@ This is a driver for the OPTi 82C621 EIDE controller. Please read the comments at the top of drivers/ide/opti621.c. -ServerWorks OSB4 chipset support (EXPERIMENTAL) +ServerWorks OSB4 chipset support CONFIG_BLK_DEV_OSB4 - This driver adds PIO/DMA support for the Serverworks OSB4 chipset + This driver adds PIO/(U)DMA support for the ServerWorks OSB4 chipset. Intel PIIXn chipsets support CONFIG_BLK_DEV_PIIX @@ -898,7 +903,7 @@ If unsure, say N. -PROMISE PDC20246/PDC20262/PDC20267 support +PROMISE PDC20246/PDC20262/PDC20265/PDC20267 support CONFIG_BLK_DEV_PDC202XX Promise Ultra33 or PDC20246 Promise Ultra66 or PDC20262 @@ -971,13 +976,11 @@ VIA82CXXX chipset support CONFIG_BLK_DEV_VIA82CXXX - This allows you to configure your chipset for a better use while - running (U)DMA: it will allow you to enable efficiently the second - channel dma usage, as it may not be set by BIOS. It allows you to - pass a kernel command line at boot time in order to set fifo - config. If no command line is provided, it will try to set fifo + This allows you to to configure your chipset for a better use while + running PIO/(U)DMA, it will allow you to enable efficiently the second + channel dma usage, as it may not be set by BIOS. It will try to set fifo configuration at its best. It will allow you to get information from - /proc/ide/via provided you enabled "proc" support. + /proc/ide/via provided you enabled "/proc file system" support. Please read the comments at the top of drivers/ide/via82cxxx.c @@ -986,12 +989,6 @@ If unsure, say N. -VIA82CXXX Tuning support (WIP) -CONFIG_VIA82CXXX_TUNING - Please read the comments at the top of drivers/ide/via82cxxx.c - - If unsure, say N. - Other IDE chipset support CONFIG_IDE_CHIPSETS Say Y here if you want to include enhanced support for various IDE @@ -4188,11 +4185,10 @@ want to join the conversation, say Y. You will need to use the netatalk package so that your Linux box can act as a print and file server for Macs as well as access AppleTalk printers. Check out - http://threepio.hitchcock.org/cgi-bin/faq/netatalk/faq.pl on the WWW - for details. EtherTalk is the name used for AppleTalk over Ethernet - and the cheaper and slower LocalTalk is AppleTalk over a proprietary - Apple network using serial links. EtherTalk and LocalTalk are fully - supported by Linux. + http://www.zettabyte.net/netatalk/ on the WWW for details. EtherTalk + is the name used for AppleTalk over Ethernet and the cheaper and + slower LocalTalk is AppleTalk over a proprietary Apple network using + serial links. EtherTalk and LocalTalk are fully supported by Linux. General information about how to connect Linux, Windows machines and Macs is on the WWW at http://www.eats.com/linux_mac_win.html . The @@ -4203,8 +4199,10 @@ This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). The module is called appletalk.o. If you want to compile it as a - module, say M here and read Documentation/modules.txt. I hear that - the GNU boycott of Apple is over, so even politically correct people + module, say M here and read Documentation/modules.txt. You almost + certainly want to compile it as a module so you can restart your + AppleTalk stack without rebooting your machine. I hear that the + GNU boycott of Apple is over, so even politically correct people are allowed to say Y here. AppleTalk-IP driver support @@ -4958,6 +4956,15 @@ Note that extended debugging may create certain race conditions itself. Enable this ONLY if you suspect problems with the driver. +Fujitsu FireStream (FS50/FS155) +CONFIG_ATM_FIRESTREAM + Driver for the Fujitsu FireStream 155 (MB86697) and + FireStream 50 (MB86695) ATM PCI chips. + + This driver is also available as a module. If you want to compile + it as a module, say M here and read Documentation/modules.txt. The + module will be called firestream.o. + Enable usec resolution timestamps CONFIG_ATM_ZATM_EXACT_TS The uPD98401 SAR chip supports a high-resolution timer (approx. 30 @@ -5178,6 +5185,117 @@ the performances of the driver, and the size of your syslog files! Keep the debugging level to 0 during normal operations. +Fusion MPT device support +CONFIG_FUSION + LSI Logic Fusion(TM) Message Passing Technology (MPT) device support + provides high performance SCSI host initiator, and LAN [1] interface + services to a host system. The Fusion architecture is capable of + duplexing these protocols on high-speed Fibre Channel + (up to 2 GHz x 2 ports = 4 GHz) and parallel SCSI (up to Ultra-320) + physical medium. + + [1] LAN is not supported on parallel SCSI medium. + + These drivers require a Fusion MPT compatible PCI adapter installed in + the host system. MPT adapters contain specialized I/O processors + to handle I/O workload, and more importantly to offload this work + from the host CPU(s). + + If you have Fusion MPT hardware and want to use it, you can say + Y or M here to add MPT (base + ScsiHost) drivers. + = build lib (fusion.o), and link [static] into the kernel [2] proper + = compiled as [dynamic] modules [3] named: (mptbase.o, mptscsih.o) + + [2] In order enable capability to boot the linux kernel natively + from a Fusion MPT target device, you MUST answer Y here! + (currently requires CONFIG_BLK_DEV_SD) + [3] This support is also available as a module + ( = code which can be inserted in and removed + from the running kernel whenever you want). + If you want to compile as modules, say M here and read + Documentation/modules.txt. + + If unsure, say N. + + If you say Y or M here you will get a choice of these + additional protocol and support module options: Module Name: + Enhanced SCSI error reporting (isense.o) + Fusion MPT misc device (ioctl) driver (mptctl.o) + Fusion MPT LAN driver (mptlan.o) + + --- + Fusion MPT is trademark of LSI Logic Corporation, and it's architecture + is based on LSI Logic's Message Passing Interface (MPI) specification. + +Fusion MPT enhanced SCSI error reporting [optional] module +CONFIG_FUSION_ISENSE + The isense module (roughly stands for Interpret SENSE data) is + completely optional. It simply provides extra English readable + strings in SCSI Error Report(s) that might be generated from the + Fusion MPT SCSI Host driver, for example when a target device + returns a SCSI check condition on a I/O. Without this module + loaded you might see: + + SCSI Error Report =-=-= (ioc0,scsi5:0) + SCSI_Status=02h (CHECK_CONDITION) + Original_CDB[]: 2A 00 00 00 00 41 00 00 02 00 + SenseData[12h]: 70 00 02 00 00 00 00 0A 00 00 00 00 04 02 02 00 00 00 + SenseKey=2h (NOT READY); FRU=02h + ASC/ASCQ=29h/00h + + Where otherwise, if this module had been loaded, you would see: + + SCSI Error Report =-=-= (ioc0,scsi5:0) + SCSI_Status=02h (CHECK_CONDITION) + Original_CDB[]: 2A 00 00 00 00 41 00 00 02 00 - "WRITE(10)" + SenseData[12h]: 70 00 02 00 00 00 00 0A 00 00 00 00 04 02 02 00 00 00 + SenseKey=2h (NOT READY); FRU=02h + ASC/ASCQ=29h/00h "LOGICAL UNIT NOT READY, INITIALIZING CMD. REQUIRED" + + Say M for "Enhanced SCSI error reporting" to compile this optional module, + creating a driver named: isense.o + + NOTE: Support for building this feature into the kernel is not + available, due to kernel size considerations. + +Fusion MPT misc device (ioctl) driver [optional] module +CONFIG_FUSION_CTL + The Fusion MPT misc device driver provides specialized control + of MPT adapters via system ioctl calls. Use of ioctl calls to + the MPT driver requires that you create and use a misc device + node ala: + mknod /dev/mptctl c 10 167 + + One use of this ioctl interface is to perform an upgrade (reflash) + of the MPT adapter firmware. Refer to readme file(s) distributed + with the Fusion MPT linux driver for additional details. + + If enabled by saying M to this, a driver named: mptctl.o + will be compiled. + + If unsure whether you really want or need this, say no. + +Fusion MPT LAN driver [optional] +CONFIG_FUSION_LAN + This module supports LAN IP traffic over Fibre Channel port(s) + on Fusion MPT compatible hardware (SYMFC9xx chips). + The physical interface used is defined in RFC 2625. + Please refer to that document for details. + + Installing this driver requires the knowledge to configure and + activate a new network interface, "fc0", using standard Linux tools. + + If enabled by saying M to this, a driver named: mptlan.o + will be compiled. + + If unsure whether you really want or need this, say no. + + NOTES: This feature is NOT available nor supported for linux-2.2.x + kernels. You must be building a linux-2.3.x or linux-2.4.x kernel + in order to configure this option. + Support for building this feature into the linux kernel is not + yet available. + SCSI support? CONFIG_SCSI If you want to use a SCSI hard disk, SCSI tape drive, SCSI CDROM or @@ -8120,7 +8238,7 @@ If you want to compile this as a module, say M and read Documentation/modules.txt. The module will be called i810-tco.o. - + MultiGate Cisco-HDLC and synchronous PPP protocol support CONFIG_COMX_PROTO_PPP Cisco-HDLC and synchronous PPP protocol driver for all MultiGate @@ -11022,6 +11140,16 @@ (the one containing the directory /) cannot be a module, so saying M could be dangerous. If unsure, say N. +PReP residual data support +CONFIG_PREP_RESIDUAL + Some PReP systems have residual data passed to the kernel by the + firmware. This allows detection of memory size, devices present and + other useful pieces of information. Sometimes this information is not + present or incorrect. + + Unless you expect to boot on a PReP system, there is not need to select + yes. + /proc file system support CONFIG_PROC_FS This is a virtual file system providing information about the status @@ -14336,6 +14464,18 @@ If unsure, say Y. +Yamaha PCI native mode support (EXPERIMENTAL) +CONFIG_SOUND_YMFPCI + This is an experimental driver that uses Yamaha PCI sound cards in + the native mode. You may also want to try another driver, + "Yamaha PCI legacy mode support" under the OSS drivers. + +Yamaha PCI legacy mode support +CONFIG_SOUND_YMPCI + This is a driver for Yamaha PCI sound cards that turns them + to the Sound Blaster compatible mode. You don't need to enable + Sound Blaster support to use it. + ACI mixer (miroPCM12/PCM20) CONFIG_SOUND_ACI_MIXER ACI (Audio Command Interface) is a protocol used to communicate with @@ -14419,6 +14559,11 @@ driver as a module you have to specify the MPU I/O base address with the parameter 'mpu_base=0xNNN'. +C-Media PCI (CMI8338/8378) +CONFIG_SOUND_CMPCI + Say Y or M if you have a PCI sound card using the CMI8338 + or the CMI8378 chip.set. + Creative EMU10K1 based PCI sound cards CONFIG_SOUND_EMU10K1 Say Y or M if you have a PCI sound card using the EMU10K1 @@ -15737,6 +15882,18 @@ processor systems, or a 64 bit IBM RS/6000, choose 6xx. Note that the kernel runs in 32-bit mode even on 64-bit chips. +Workarounds for PPC601 bugs +CONFIG_PPC601_SYNC_FIX + Some versions of the PPC601 (the first PowerPC chip) have bugs which + mean that extra synchronization instructions are required near certain + instructions, typically those that make major changes to the CPU state. + These extra instructions reduce performance slightly. If you say N + here, these extra instructions will not be included, resulting in a + kernel which will run faster but may not run at all on some systems + with the PPC601 chip. + + If in doubt, say Y here. + Machine Type CONFIG_PMAC Linux currently supports several different kinds of PowerPC-based @@ -15805,6 +15962,37 @@ an image of the device tree that the kernel copies from Open Firmware. If unsure, say Y here. +RTAS proc interface +CONFIG_PPC_RTAS + When you use this option, you will be able to use RTAS from + userspace. + + RTAS stands for RunTime Abstraction Services and should + provide a portable way to access and set system information. This is + commonly used on RS/6000 (pSeries) computers. + + You can access RTAS via the special proc filesystem entry rtas. + Don't confuse this rtas entry with the one in /proc/device-tree/rtas + which is readonly. + + If you don't know if you can use RTAS look into + /proc/device-tree/rtas. If there are some entries, it is very likely + that you will be able to use RTAS. + + You can do cool things with rtas. To print out information about + various sensors in the system, just do a + + $ cat /proc/rtas/sensors + + or if you power off your machine at night but want it running when + you enter your office at 7:45 am, do a + + # date -d 'tomorrow 7:30' +%s > /proc/rtas/poweron + + and shutdown. + + If unsure, say Y + MESH (Power Mac internal SCSI) support CONFIG_SCSI_MESH Many Power Macintoshes and clones have a MESH (Macintosh Enhanced @@ -16660,6 +16848,10 @@ This support is also available as a module called irda.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. + +IrDA protocol options +CONFIG_IRDA_OPTIONS + Say Y here if you want to configure any of the following IrDA options. IrDA Cache last LSAP CONFIG_IRDA_CACHE_LAST_LSAP diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Documentation/DocBook/kernel-api.tmpl linux.ac/Documentation/DocBook/kernel-api.tmpl --- linux.vanilla/Documentation/DocBook/kernel-api.tmpl Sun Dec 31 19:41:40 2000 +++ linux.ac/Documentation/DocBook/kernel-api.tmpl Sun Dec 31 17:04:46 2000 @@ -34,6 +34,18 @@ + + + Driver Basic + Driver Entry and Exit points +!Iinclude/linux/init.h + + + Atomics +!Iinclude/asm-i386/atomic.h + + + Data Types Doubly Linked Lists diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Documentation/DocBook/mousedrivers.tmpl linux.ac/Documentation/DocBook/mousedrivers.tmpl --- linux.vanilla/Documentation/DocBook/mousedrivers.tmpl Tue Jul 11 12:53:53 2000 +++ linux.ac/Documentation/DocBook/mousedrivers.tmpl Mon Jan 1 22:05:05 2001 @@ -335,7 +335,7 @@ We count off a user and provided that there are still other users need take no further action. The last person closing the mouse causes us to - free up the interrupt. This stopps interrupts from the mouse from using + free up the interrupt. This stops interrupts from the mouse from using our CPU time, and lets us use MOD_DEC_USE_COUNT so that the mouse can now be unloaded. @@ -404,7 +404,7 @@ play with them. - If a change has occured we also need to wake sleeping processes, so we + If a change has occurred we also need to wake sleeping processes, so we add a wakeup call and a wait_queue to use when we wish to await a mouse event. @@ -426,7 +426,7 @@ This is fairly standard poll code. First we add the wait queue to the list of queues we want to monitor for an event. Secondly we check if an - event has occured. We only have one kind of event - the + event has occurred. We only have one kind of event - the mouse_event flag tells us that something happened. We know that this something can only be mouse data. We return the flags indicating input and normal reading will succeed. @@ -476,7 +476,7 @@ Next we wait for an event to occur. The loop is fairly standard event - waiting in Linux. Having checked that the event has not yet occured, we + waiting in Linux. Having checked that the event has not yet occurred, we then check if an event is pending and if not we need to sleep. @@ -488,7 +488,7 @@ Next we sleep until the mouse or a signal awakens us. A signal will awaken us as we have used wakeup_interruptible. This is important as it means a user can kill processes waiting for - the mouse - clearly a desireable property. If we are interrupted we + the mouse - clearly a desirable property. If we are interrupted we exit the call and the kernel will then process signals and maybe restart the call again - from the beginning. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Documentation/DocBook/videobook.tmpl linux.ac/Documentation/DocBook/videobook.tmpl --- linux.vanilla/Documentation/DocBook/videobook.tmpl Tue Dec 12 13:05:11 2000 +++ linux.ac/Documentation/DocBook/videobook.tmpl Mon Jan 1 22:05:05 2001 @@ -486,7 +486,7 @@ We copy the user supplied structure into kernel memory so we can examine it. If the user has selected a tuner other than zero we reject the request. If - they wanted tuner 0 then, suprisingly enough, that is the current tuner already. + they wanted tuner 0 then, surprisingly enough, that is the current tuner already. The next two ioctls we need to provide are to get and set the frequency of @@ -652,7 +652,7 @@ The VIDIOCSAUDIO ioctl allows the user to set the audio parameters in the - video_audio stucture. The driver does its best to honour the request. + video_audio structure. The driver does its best to honour the request. @@ -812,7 +812,7 @@ Chroma keying is a technique used by cards to get around this. It is an old television mixing trick where you mark all the areas you wish to replace with a single clear colour that isn't used in the image - TV people use an - incredibly bright blue while computing people often use a paticularly + incredibly bright blue while computing people often use a particularly virulent purple. Bright blue occurs on the desktop. Anyone with virulent purple windows has another problem besides their TV overlay. @@ -1259,7 +1259,7 @@ VIDEO_MODE_NTSC<>NTSC (US) encoded Television - VIDEO_MODE_SECAM<>SECAM (French) Televison + VIDEO_MODE_SECAM<>SECAM (French) Television VIDEO_MODE_AUTO<>Automatic switching, or format does not matter @@ -1269,7 +1269,7 @@ The corresponding VIDIOCSCHAN ioctl allows a user to change channel and to - request the norm is changed - for exaple to switch between a PAL or an NTSC + request the norm is changed - for example to switch between a PAL or an NTSC format camera. @@ -1332,7 +1332,7 @@ it make a best effort attempt. - Our depth is 24, as this is in bits. We will be returing RGB24 format. This + Our depth is 24, as this is in bits. We will be returning RGB24 format. This has one byte of red, then one of green, then one of blue. This then repeats for every other pixel in the image. The other common formats the interface defines are diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Documentation/DocBook/z8530book.tmpl linux.ac/Documentation/DocBook/z8530book.tmpl --- linux.vanilla/Documentation/DocBook/z8530book.tmpl Mon Mar 13 03:39:47 2000 +++ linux.ac/Documentation/DocBook/z8530book.tmpl Mon Jan 1 22:05:05 2001 @@ -57,7 +57,7 @@ Introduction The Z85x30 family synchronous/asynchronous controller chips are - used on a larg number of cheap network interface cards. The + used on a large number of cheap network interface cards. The kernel provides a core interface layer that is designed to make it easy to provide WAN services using this chip. @@ -124,7 +124,7 @@ for allocating the interrupt line. The interrupt handler should be set to z8530_interrupt. The device id should be set to the z8530_dev structure pointer. Whether the interrupt can - be shared or not is board dependant, and up to you to initialise. + be shared or not is board dependent, and up to you to initialise. The structure holds two channel structures. @@ -143,19 +143,19 @@ Repeat the same operation with the B channel if your chip has - both channels wired to something useful. This isnt always the + both channels wired to something useful. This isn't always the case. If it is not wired then the I/O values do not matter, but you must initialise chanB.dev. If your board has DMA facilities then initialise the txdma and rxdma fields for the relevant channels. You must also allocate the - ISA DMA channels and do any neccessary board level initialisation + ISA DMA channels and do any necessary board level initialisation to configure them. The low level driver will do the Z8530 and DMA controller programming but not board specific magic. - Having intialised the device you can then call + Having initialised the device you can then call z8530_init. This will probe the chip and reset it into a known state. An identification sequence is then run to identify the chip type. If the checks fail to pass the @@ -167,7 +167,7 @@ Once you have called z8530_init you can also make use of the utility function z8530_describe. This provides a - consistant reporting format for the Z8530 devices, and allows all + consistent reporting format for the Z8530 devices, and allows all the drivers to provide consistent reporting. @@ -191,7 +191,7 @@ to the syncppp structures. - The way most drivers approach this paticular problem is to + The way most drivers approach this particular problem is to create a structure holding the Z8530 device definition and put that and the syncppp pointer into the private field of the network device. The network device fields of the channels @@ -330,7 +330,7 @@ The Z8530 driver is written to be portable. In DMA mode it makes assumptions about the use of ISA DMA. These are probably warranted - in most cases as the Z85230 in paticular was designed to glue to PC + in most cases as the Z85230 in particular was designed to glue to PC type machines. The PIO mode makes no real assumptions. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Documentation/filesystems/ramfs.txt linux.ac/Documentation/filesystems/ramfs.txt --- linux.vanilla/Documentation/filesystems/ramfs.txt Thu Jan 1 01:00:00 1970 +++ linux.ac/Documentation/filesystems/ramfs.txt Wed Nov 22 01:14:10 2000 @@ -0,0 +1,47 @@ + ramfs - An automatically resizing memory based filesystem + + + Ramfs is a file system which keeps all files in RAM. It allows read + and write access. In contrast to RAM disks, which get allocated a + fixed amount of RAM, ramfs grows and shrinks to accommodate the + files it contains. + + You can mount the ramfs with: + mount -t ramfs none /mnt/wherever + + Then just create and use files. When the filesystem is unmounted, all + its contents are lost. + + NOTE! This filesystem is probably most useful not as a real + filesystem, but as an example of how virtual filesystems can be + written. + +Resource limits: + +By default a ramfs will be limited to using half of (physical) memory +for storing file contents, a bit over that when the metadata is +included. The resource usage limits of ramfs can be controlled with +the following mount options: + + maxsize=NNN + Sets the maximum allowed memory usage of the +filesystem to NNN kilobytes. This will be rounded down to a multiple +of the page size. The default is half of physical memory. NB. unlike +most of the other limits, setting this to zero does *not* mean no +limit, but will actually limit the size of the filesystem data to zero +pages. There might be a use for this in some perverse situation. + + maxfilesize=NNN + Sets the maximum size of a single file on the +filesystem to NNN kilobytes. This will be rounded down to a multiple +of the page size. If NNN=0 there is no limit. The default is no limit. + + maxdentries=NNN + Sets the maximum number of directory entries (hard +links) on the filesystem to NNN. If NNN=0 there is no limit. By +default this is set to maxsize/4. + + maxinodes=NNN + Sets the maximum number of inodes (i.e. distinct +files) on the filesystem to NNN. If NNN=0 there is no limit. The +default is no limit (but there can never be more inodes than dentries). diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Documentation/magic-number.txt linux.ac/Documentation/magic-number.txt --- linux.vanilla/Documentation/magic-number.txt Mon Feb 21 04:37:09 2000 +++ linux.ac/Documentation/magic-number.txt Mon Jan 1 20:57:14 2001 @@ -65,7 +65,6 @@ 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 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Documentation/usb/usb-serial.txt linux.ac/Documentation/usb/usb-serial.txt --- linux.vanilla/Documentation/usb/usb-serial.txt Tue Dec 12 13:05:12 2000 +++ linux.ac/Documentation/usb/usb-serial.txt Thu Dec 21 21:23:32 2000 @@ -223,7 +223,7 @@ To enable the generic driver to recognize your device, build the driver as a module and load it by the following invocation: - insmod usb-serial vendor=0x#### product=0x#### + insmod usbserial vendor=0x#### product=0x#### where the #### is replaced with the hex representation of your device's vendor id and product id. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Makefile linux.ac/Makefile --- linux.vanilla/Makefile Sun Dec 31 19:41:41 2000 +++ linux.ac/Makefile Mon Jan 1 20:54:02 2001 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 0 -EXTRAVERSION = -prerelease +EXTRAVERSION = -prerelease-ac3 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) @@ -145,6 +145,7 @@ DRIVERS-$(CONFIG_ATM) += drivers/atm/atm.o DRIVERS-$(CONFIG_IDE) += drivers/ide/idedriver.o DRIVERS-$(CONFIG_SCSI) += drivers/scsi/scsidrv.o +DRIVERS-$(CONFIG_FUSION_BOOT) += drivers/message/fusion/fusion.o DRIVERS-$(CONFIG_IEEE1394) += drivers/ieee1394/ieee1394.a ifneq ($(CONFIG_CD_NO_IDESCSI)$(CONFIG_BLK_DEV_IDECD)$(CONFIG_BLK_DEV_SR)$(CONFIG_PARIDE_PCD),) @@ -171,7 +172,7 @@ DRIVERS-$(CONFIG_TC) += drivers/tc/tc.a DRIVERS-$(CONFIG_USB) += drivers/usb/usbdrv.o DRIVERS-$(CONFIG_INPUT) += drivers/input/inputdrv.o -DRIVERS-$(CONFIG_I2O) += drivers/i2o/i2o.o +DRIVERS-$(CONFIG_I2O) += drivers/message/i2o/i2o.o DRIVERS-$(CONFIG_IRDA) += drivers/net/irda/irda.o DRIVERS-$(CONFIG_I2C) += drivers/i2c/i2c.o DRIVERS-$(CONFIG_PHONE) += drivers/telephony/telephony.o @@ -188,6 +189,7 @@ .tmp* \ drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c \ drivers/char/conmakehash \ + drivers/char/drm/*-mod.c \ drivers/pci/devlist.h drivers/pci/classlist.h drivers/pci/gen-devlist \ drivers/zorro/devlist.h drivers/zorro/gen-devlist \ drivers/sound/bin2hex drivers/sound/hex2hex \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/alpha/config.in linux.ac/arch/alpha/config.in --- linux.vanilla/arch/alpha/config.in Sun Dec 31 19:41:41 2000 +++ linux.ac/arch/alpha/config.in Sun Dec 31 22:30:03 2000 @@ -278,6 +278,8 @@ fi endmenu +source drivers/message/fusion/Config.in + if [ "$CONFIG_NET" = "y" ]; then mainmenu_option next_comment comment 'Network device support' diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/alpha/kernel/setup.c linux.ac/arch/alpha/kernel/setup.c --- linux.vanilla/arch/alpha/kernel/setup.c Tue Oct 31 20:25:58 2000 +++ linux.ac/arch/alpha/kernel/setup.c Fri Dec 22 16:25:58 2000 @@ -1089,7 +1089,7 @@ hwrpb->pagesize, hwrpb->pa_bits, hwrpb->max_asn, - loops_per_sec / 500000, (loops_per_sec / 5000) % 100, + loops_per_jiffy * HZ / 500000, (loops_per_jiffy * HZ / 5000) % 100, unaligned[0].count, unaligned[0].pc, unaligned[0].va, unaligned[1].count, unaligned[1].pc, unaligned[1].va, platform_string(), nr_processors); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/alpha/kernel/smp.c linux.ac/arch/alpha/kernel/smp.c --- linux.vanilla/arch/alpha/kernel/smp.c Sun Dec 31 19:41:41 2000 +++ linux.ac/arch/alpha/kernel/smp.c Fri Dec 22 16:27:21 2000 @@ -105,7 +105,7 @@ static inline void __init smp_store_cpu_info(int cpuid) { - cpu_data[cpuid].loops_per_sec = loops_per_sec; + cpu_data[cpuid].loops_per_jiffy = loops_per_jiffy; cpu_data[cpuid].last_asn = ASN_FIRST_VERSION; cpu_data[cpuid].need_new_asn = 0; cpu_data[cpuid].asn_lock = 0; @@ -601,12 +601,12 @@ bogosum = 0; for (i = 0; i < NR_CPUS; i++) { if (cpu_present_mask & (1L << i)) - bogosum += cpu_data[i].loops_per_sec; + bogosum += cpu_data[i].loops_per_jiffy; } printk(KERN_INFO "SMP: Total of %d processors activated " "(%lu.%02lu BogoMIPS).\n", - cpu_count, (bogosum + 2500) / 500000, - ((bogosum + 2500) / 5000) % 100); + cpu_count, (bogosum + 2500) / (500000 / HZ), + ((bogosum + 2500) / (5000 / HZ)) % 100); smp_num_cpus = cpu_count; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/Makefile linux.ac/arch/arm/Makefile --- linux.vanilla/arch/arm/Makefile Sat Oct 28 16:15:42 2000 +++ linux.ac/arch/arm/Makefile Sun Dec 31 14:57:34 2000 @@ -12,25 +12,18 @@ # # Copyright (C) 1995-2000 by Russell King -OBJCOPY := $(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S -CPP := $(CC) -E -LINKFLAGS := -p -X -T arch/arm/vmlinux.lds -ARCHCC := $(word 1,$(CC)) - -AFLAGS += -mno-fpu -CFLAGS_PIPE := -pipe -CFLAGS := $(CFLAGS) $(CFLAGS_PIPE) -msoft-float +LINKFLAGS :=-p -X -T arch/arm/vmlinux.lds +GZFLAGS :=-9 +CFLAGS +=-fno-common -pipe ifdef CONFIG_FRAME_POINTER -CFLAGS := $(CFLAGS:-fomit-frame-pointer=) +CFLAGS :=$(CFLAGS:-fomit-frame-pointer=) endif ifdef CONFIG_DEBUG_INFO -CFLAGS += -g +CFLAGS +=-g endif -GZFLAGS = -9 - # Ensure this is ld "2.9.4" or later NEW_LINKER := $(shell $(LD) --gc-sections --version >/dev/null 2>&1; echo $$?) @@ -40,61 +33,42 @@ @false endif -# GCC 2.7 uses different options to later compilers; sort out which we have -NEW_GCC := $(shell $(CC) --version 2>&1 | grep '^2\.7' > /dev/null; echo $$?) - -# -# select flags depending on the compiler +# Select CPU dependent flags. Note that order of declaration is important; +# the options further down the list override previous items. # -ifneq ($(NEW_GCC),0) -CFLAGS += -mshort-load-bytes -CFLAGS_PROC_CPU_26 := -mcpu=arm3 -mapcs-26 -Os -CFLAGS_PROC_CPU_32v3 := -march=armv3 -CFLAGS_PROC_CPU_32v4 := -march=armv4 -else -CFLAGS += -DNO_TEXT_SECTIONS -CFLAGS_PROC_CPU_26 := -m3 -CFLAGS_PROC_CPU_32v3 := -m6 -CFLAGS_PROC_CPU_32v4 := -m6 -endif +apcs-$(CONFIG_CPU_26) :=-mapcs-26 -mcpu=arm3 -Os +apcs-$(CONFIG_CPU_32) :=-mapcs-32 + +arch-$(CONFIG_CPU_32v3) :=-march=armv3 +arch-$(CONFIG_CPU_32v4) :=-march=armv4 +arch-$(CONFIG_CPU_32v5) :=-march=armv5 + +proc-$(CONFIG_CPU_32v3) :=-marmv3m +proc-$(CONFIG_CPU_32v4) :=-marmv4 +proc-$(CONFIG_CPU_32v5) :=-marmv5 + +tune-$(CONFIG_CPU_ARM610) :=-mtune=arm610 +tune-$(CONFIG_CPU_ARM710) :=-mtune=arm710 +tune-$(CONFIG_CPU_ARM720T) :=-mtune=arm7tdmi +tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi +tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110 +tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100 + +CFLAGS += $(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float +AFLAGS += $(apcs-y) $(proc-y) -mno-fpu + +LIBGCC := $(shell $(CC) $(CFLAGS) --print-libgcc-file-name) -# -# Select CPU dependent flags -# ifeq ($(CONFIG_CPU_26),y) - PROCESSOR = armo - TEXTADDR = 0x02080000 - CFLAGS += $(CFLAGS_PROC_CPU_26) - AFLAGS += -mapcs-26 +PROCESSOR = armo +TEXTADDR = 0x02080000 endif ifeq ($(CONFIG_CPU_32),y) - PROCESSOR = armv - TEXTADDR = 0xC0008000 - ifeq ($(CONFIG_CPU_32v4),y) - CFLAGS += $(CFLAGS_PROC_CPU_32v4) - AFLAGS += -mapcs-32 -marmv4 - else - CFLAGS += $(CFLAGS_PROC_CPU_32v3) - AFLAGS += -mapcs-32 -marmv3m - endif - - opt-$(CONFIG_CPU_ARM6) := -mtune=arm6 - opt-$(CONFIG_CPU_ARM7) := -mtune=arm7 - opt-$(CONFIG_CPU_ARM720) := -mtune=arm7tdmi - opt-$(CONFIG_CPU_ARM920) := -mtune=arm9tdmi - opt-$(CONFIG_CPU_SA110) := -mtune=strongarm110 - opt-$(CONFIG_CPU_SA1100) := -mtune=strongarm110 - - ifneq ($(NEW_GCC),0) - CFLAGS += $(opt-y) - endif +PROCESSOR = armv +TEXTADDR = 0xC0008000 endif -LIBGCC := $(shell $(CC) $(CFLAGS) --print-libgcc-file-name) - -export LIBGCC MACHINE PROCESSOR TEXTADDR GZFLAGS - ifeq ($(CONFIG_ARCH_ARCA5K),y) MACHINE = arc endif @@ -132,6 +106,10 @@ endif ifeq ($(CONFIG_ARCH_SA1100),y) +ifeq ($(CONFIG_SA1111),y) +# SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory +TEXTADDR = 0xc0208000 +endif MACHINE = sa1100 endif @@ -143,6 +121,13 @@ MACHINE = integrator endif +ifeq ($(CONFIG_ARCH_CLPS711X),y) +TEXTADDR = 0xc0018000 +MACHINE = clps711x +endif + +export LIBGCC MACHINE PROCESSOR TEXTADDR GZFLAGS + # Only set INCDIR if its not already defined above # Grr, ?= doesn't work as all the other assignment operators do. Make bug? ifeq ($(origin INCDIR), undefined) @@ -158,8 +143,7 @@ HEAD := arch/arm/kernel/head-$(PROCESSOR).o \ arch/arm/kernel/init_task.o -SUBDIRS += arch/arm/kernel arch/arm/mm arch/arm/lib \ - arch/arm/nwfpe +SUBDIRS += arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwfpe CORE_FILES := arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES) LIBS := arch/arm/lib/lib.o arch/arm/lib/lib.a $(LIBS) $(LIBGCC) @@ -167,14 +151,6 @@ LIBS := arch/arm/nwfpe/math-emu.o $(LIBS) endif -ifeq ($(CONFIG_ARCH_ACORN),y) -SUBDIRS += drivers/acorn -DRIVERS += drivers/acorn/block/acorn-block.a -DRIVERS += drivers/acorn/char/acorn-char.o -DRIVERS += drivers/acorn/net/acorn-net.o -DRIVERS += drivers/acorn/scsi/acorn-scsi.a -endif - ifeq ($(CONFIG_ARCH_CLPS7500),y) SUBDIRS += drivers/acorn/char DRIVERS += drivers/acorn/char/acorn-char.o @@ -230,6 +206,7 @@ Img:; @$(MAKEBOOT) Image i:; @$(MAKEBOOT) install zi:; @$(MAKEBOOT) zinstall +bp:; @$(MAKEBOOT) bootpImage # # Configuration targets. Use these to select a @@ -237,9 +214,10 @@ CFGS= a5k_config ebsa110_config \ footbridge_config rpc_config \ brutus_config victor_config \ - empeg_config thinclient_config \ + empeg_config graphicsclient_config \ assabet_config lart_config \ - cerf_config lusl7200_config + cerf_config lusl7200_config \ + sherman_config pangolin_config $(CFGS): @( \ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/boot/Makefile linux.ac/arch/arm/boot/Makefile --- linux.vanilla/arch/arm/boot/Makefile Tue Dec 12 13:05:12 2000 +++ linux.ac/arch/arm/boot/Makefile Sun Dec 31 14:57:34 2000 @@ -83,15 +83,18 @@ ZRELADDR = 0xc0008000 ifeq ($(CONFIG_SA1100_VICTOR),y) ZTEXTADDR = 0x00002000 - ZBSSADDR = 0xc0100000 + ZBSSADDR = 0xc0200000 endif ifeq ($(CONFIG_SA1100_SHERMAN),y) ZTEXTADDR = 0x00050000 - ZBSSADDR = 0xc0100000 + ZBSSADDR = 0xc0200000 endif ifeq ($(CONFIG_SA1100_GRAPHICSCLIENT),y) ZTEXTADDR = 0xC0200000 endif +ifeq ($(CONFIG_SA1111),y) + ZRELADDR = 0xc0208000 +endif endif # @@ -105,15 +108,15 @@ export SYSTEM ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS INITRD_VIRT PARAMS_PHYS Image: $(CONFIGURE) $(SYSTEM) - $(OBJCOPY) $(SYSTEM) $@ + $(OBJCOPY) -O binary -R .note -R .comment -S $(SYSTEM) $@ bzImage: zImage zImage: $(CONFIGURE) compressed/vmlinux - $(OBJCOPY) compressed/vmlinux $@ + $(OBJCOPY) -O binary -R .note -R .comment -S compressed/vmlinux $@ bootpImage: bootp/bootp - $(OBJCOPY) bootp/bootp $@ + $(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@ compressed/vmlinux: $(TOPDIR)/vmlinux dep @$(MAKE) -C compressed vmlinux diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/boot/bootp/Makefile linux.ac/arch/arm/boot/bootp/Makefile --- linux.vanilla/arch/arm/boot/bootp/Makefile Sun Sep 17 12:23:02 2000 +++ linux.ac/arch/arm/boot/bootp/Makefile Sun Dec 31 14:55:50 2000 @@ -7,7 +7,8 @@ ZLDFLAGS =-p -X -T bootp.lds \ --defsym initrd_addr=$(INITRD_PHYS) \ --defsym initrd_virt=$(INITRD_VIRT) \ - --defsym params=$(PARAMS_PHYS) + --defsym params=$(PARAMS_PHYS) \ + --defsym kernel_addr=$(ZTEXTADDR) all: bootp diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/boot/bootp/init.S linux.ac/arch/arm/boot/bootp/init.S --- linux.vanilla/arch/arm/boot/bootp/init.S Sat Oct 28 16:15:42 2000 +++ linux.ac/arch/arm/boot/bootp/init.S Sun Dec 31 14:55:50 2000 @@ -12,33 +12,59 @@ */ .section .start,#alloc,#execinstr .type _entry, #function -_entry: -kernel_addr: adr r10, initdata - ldmia r10, {r11, r12} +_entry: adr r10, initdata + ldr r11, initdata sub r11, r10, r11 @ work out exec offset - add r12, r12, r11 @ correct "splitify" - mov pc, r12 @ jump to splitify + b splitify .size _entry,. - _entry .type initdata, #object initdata: .word initdata @ compiled address of this - .word splitify .size initdata,. - initdata .text splitify: adr r13, data - ldmia r13!, {r4-r6} @ move the kernel + ldmia r13!, {r4-r6} @ move the initrd add r4, r4, r11 @ correction - mov r12, r5 bl move - ldmia r13!, {r4-r6} @ then the initrd + ldmia r13!, {r4-r6} @ then the kernel + mov r12, r5 add r4, r4, r11 @ correction bl move - ldmib r13, {r5,r6,r7} @ get size and addr of initrd - add r7, r7, #16*4 @ offset of initrd_start in param_struct - stmia r7, {r5,r6} @ save in param_struct +/* + * Setup the initrd parameters to pass to the kernel. This can either be + * passed in via a param_struct or a tag list. We spot the param_struct + * method by looking at the first word; this should either indicate a page + * size of 4K, 16K or 32K. + */ + ldmia r13, {r5-r8} @ get size and addr of initrd + @ r5 = ATAG_INITRD + @ r6 = initrd start + @ r7 = initrd end + @ r8 = param_struct address + ldr r9, [r8, #0] @ no param struct? + teq r9, #0x1000 @ 4K? + teqne r9, #0x4000 @ 16K? + teqne r9, #0x8000 @ 32K? + beq no_taglist + +/* + * find the end of the tag list, and then add an INITRD tag on the end. + */ +taglist: ldr r9, [r8, #0] @ tag length + teq r9, #0 @ last tag? + addne r8, r8, r9 + bne taglist + + mov r4, #16 @ length of initrd tag + mov r9, #0 @ end of tag list terminator + stmia r8, {r4, r5, r6, r7, r9} + mov pc, r12 @ call kernel + +no_taglist: add r8, r8, #16*4 + stmia r8, {r6,r7} @ save in param_struct mov pc, r12 @ call kernel move: ldmia r4!, {r7 - r10} @ move 32-bytes at a time @@ -49,17 +75,18 @@ bcs move mov pc, lr -data: .word kernel_start - .word kernel_addr - .word kernel_len - - .word initrd_start +data: .word initrd_start .word initrd_addr .word initrd_len - .word initrd_virt - .word initrd_len - .word params + .word kernel_start + .word kernel_addr + .word kernel_len + + .word 0x54410005 @ r5 = ATAG_INITRD + .word initrd_virt @ r6 + .word initrd_len @ r7 + .word params @ r8 .type kernel_start,#object .type initrd_start,#object diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/boot/compressed/Makefile linux.ac/arch/arm/boot/compressed/Makefile --- linux.vanilla/arch/arm/boot/compressed/Makefile Tue Dec 12 13:05:12 2000 +++ linux.ac/arch/arm/boot/compressed/Makefile Sun Dec 31 14:57:34 2000 @@ -66,7 +66,7 @@ $(CC) $(AFLAGS) -traditional -c $(HEAD:.o=.S) piggy.o: $(SYSTEM) - $(OBJCOPY) $(SYSTEM) piggy + $(OBJCOPY) -O binary -R .note -R .comment -S $(SYSTEM) piggy gzip $(GZFLAGS) < piggy > piggy.gz $(LD) -r -o $@ -b binary piggy.gz rm -f piggy piggy.gz diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/boot/compressed/head-ftvpci.S linux.ac/arch/arm/boot/compressed/head-ftvpci.S --- linux.vanilla/arch/arm/boot/compressed/head-ftvpci.S Sun Sep 17 12:23:02 2000 +++ linux.ac/arch/arm/boot/compressed/head-ftvpci.S Sun Dec 31 14:56:45 2000 @@ -6,6 +6,13 @@ * Special startup code for FTV PCI board. */ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + .section ".start", #alloc, #execinstr ftv_start: mcr p15, 0, r0, c7, c5, 0 @ flush I cache diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/boot/compressed/head-l7200.S linux.ac/arch/arm/boot/compressed/head-l7200.S --- linux.vanilla/arch/arm/boot/compressed/head-l7200.S Sun Sep 17 12:22:44 2000 +++ linux.ac/arch/arm/boot/compressed/head-l7200.S Sun Dec 31 14:56:45 2000 @@ -3,7 +3,7 @@ * * Copyright (C) 2000 Steve Hill * - * Some code borrowed from Nicola Pitre's 'head-sa1100.S' file. This + * Some code borrowed from Nicolas Pitre's 'head-sa1100.S' file. This * is merged with head.S by the linker. */ @@ -16,15 +16,14 @@ .section ".start", #alloc, #execinstr __L7200_start: - mov r0, #0x00100000 @ FLASH address of initrd mov r2, #0xf1000000 @ RAM address of initrd - add r1, r2, #0x00700000 @ Size of initrd + add r3, r2, #0x00700000 @ Size of initrd 1: - ldmia r0!, {r3, r4, r5, r6} - stmia r2!, {r3, r4, r5, r6} - cmp r2, r1 + ldmia r0!, {r4, r5, r6, r7} + stmia r2!, {r4, r5, r6, r7} + cmp r2, r3 ble 1b - + mov r8, #0 @ Zero it out mov r7, #19 @ Set architecture ID diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/boot/compressed/head-sa1100.S linux.ac/arch/arm/boot/compressed/head-sa1100.S --- linux.vanilla/arch/arm/boot/compressed/head-sa1100.S Sun Sep 17 12:22:44 2000 +++ linux.ac/arch/arm/boot/compressed/head-sa1100.S Sun Dec 31 14:56:45 2000 @@ -11,10 +11,6 @@ #include #include -#ifndef CONFIG_ARCH_SA1100 -#error What am I doing here... -#endif - .section ".start", #alloc, #execinstr __SA1100_start: @@ -54,6 +50,8 @@ bic r0, r0, #0x0d @ clear WB, DC, MMU bic r0, r0, #0x1000 @ clear Icache mcr p15, 0, r0, c1, c0, 0 + +#ifdef CONFIG_ANGELBOOT /* * Pause for a short time so that we give enough time * for the host to start a terminal up. @@ -61,3 +59,5 @@ mov r0, #0x00200000 1: subs r0, r0, #1 bne 1b +#endif + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/boot/compressed/head-shark.S linux.ac/arch/arm/boot/compressed/head-shark.S --- linux.vanilla/arch/arm/boot/compressed/head-shark.S Thu Jan 1 01:00:00 1970 +++ linux.ac/arch/arm/boot/compressed/head-shark.S Sun Dec 31 14:56:45 2000 @@ -0,0 +1,121 @@ +/* The head-file for the Shark + * by Alexander.Schulz@stud.uni-karlsruhe.de + * + * Does the following: + * - get the memory layout from firmware. This can only be done as long as the mmu + * is still on. + * - switch the mmu off, so we have physical addresses + * - copy the kernel to 0x08508000. This is done to have a fixed address where the + * C-parts (misc.c) are executed. This address must be known at compile-time, + * but the load-address of the kernel depends on how much memory is installed. + * - Jump to this location. + * - Set r8 with 0, r7 with the architecture ID for head.S + */ + +#include + +#include + + .section ".start", #alloc, #execinstr + + b __beginning + +__serial_addr: .long 0xf7eff3f8 + .long 0 @ space +__ofw_data: .long 0 @ the number of memory blocks + .space 128 @ (startaddr,size) ... + .space 128 @ bootargs + .align + +__beginning: mov r4, r0 @ save the entry to the firmware + + mov r0, #0xC0 @ disable irq and fiq + mov r1, r0 + mrs r3, cpsr_all + bic r2, r3, r0 + eor r2, r2, r1 + msr cpsr_all, r2 + + ldr r0, __serial_addr @ disable serial interrupt + mov r1, #0 @ hangs the machine, I don t know why. + strb r1, [r0, #0x01] + + mov r0, r4 @ get the Memory layout from firmware + adr r1, __ofw_data + add r2, r1, #4 + mov lr, pc + b SYMBOL_NAME(ofw_init) + mov r1, #0 + + adr r2, __mmu_off @ calculate physical address + sub r2, r2, #0xf0000000 @ openprom maps us at f000 virt, 0e50 phys + adr r0, __ofw_data + ldr r0, [r0, #4] + add r2, r2, r0 + add r2, r2, #0x00500000 + + mrc p15, 0, r3, c1, c0 + bic r3, r3, #0xC @ Write Buffer and DCache + bic r3, r3, #0x1000 @ ICache + mcr p15, 0, r3, c1, c0 @ disabled + + mov r0, #0 + mcr p15, 0, r0, c7, c7 @ flush I,D caches on v4 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 + mcr p15, 0, r0, c8, c7 @ flush I,D TLBs on v4 + + bic r3, r3, #0x1 @ MMU + mcr p15, 0, r3, c1, c0 @ disabled + + mov pc, r2 + +__copy_target: .long 0x08508000 +__copy_end: .long 0x08608000 + + .word _start + .word __bss_start + + .align +__temp_stack: .space 128 + +__mmu_off: + adr r0, __ofw_data + ldr r0, [r0, #4] + orr r0, r0, #0x00600000 + + ldr r1, __copy_end + ldr r3, __copy_target + +/* r0 = 0x0e600000 (current end of kernelcode) + * r3 = 0x08508000 (where it should begin) + * r1 = 0x08608000 (end of copying area, 1MB) + * The kernel is compressed, so 1 MB should be enough. + * copy the kernel to the beginning of physical memory + * We start from the highest address, so we can copy + * from 0x08500000 to 0x08508000 if we have only 8MB + */ + + +__Copy: ldr r2, [r0], #-4 + str r2, [r1], #-4 + teq r1, r3 + bne __Copy + /* and jump to it */ + adr r2, __go_on + adr r0, __ofw_data + ldr r0, [r0, #4] + sub r2, r2, r0 + sub r2, r2, #0x00500000 + ldr r0, __copy_target + add r2, r2, r0 + mov pc, r2 + +__go_on: + adr sp, __temp_stack + add sp, sp, #128 + adr r0, __ofw_data + mov lr, pc + b SYMBOL_NAME(create_params) + + mov r8, #0 + mov r7, #15 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/boot/compressed/head.S linux.ac/arch/arm/boot/compressed/head.S --- linux.vanilla/arch/arm/boot/compressed/head.S Sat Oct 28 16:15:42 2000 +++ linux.ac/arch/arm/boot/compressed/head.S Sun Dec 31 14:56:45 2000 @@ -112,8 +112,7 @@ */ .text -1: mrc p15, 0, r6, c0, c0 @ get processor ID - adr r2, LC0 +1: adr r2, LC0 ldmia r2, {r2, r3, r4, r5, sp} mov r0, #0 @@ -124,14 +123,15 @@ cmp r2, r3 blt 1b + mrc p15, 0, r6, c0, c0 @ get processor ID bl cache_on mov r1, sp @ malloc space above stack add r2, sp, #0x10000 @ 64k max teq r4, r5 @ will we overwrite ourselves? - moveq r5, r2 - movne r5, r4 + moveq r5, r2 @ decompress after image + movne r5, r4 @ decompress to final location mov r0, r5 mov r3, r7 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/boot/compressed/ofw-shark.c linux.ac/arch/arm/boot/compressed/ofw-shark.c --- linux.vanilla/arch/arm/boot/compressed/ofw-shark.c Thu Jan 1 01:00:00 1970 +++ linux.ac/arch/arm/boot/compressed/ofw-shark.c Sun Dec 31 14:56:45 2000 @@ -0,0 +1,216 @@ +/* + * linux/arch/arm/boot/compressed/ofw-shark.c + * + * by Alexander.Schulz@stud.uni-karlsruhe.de + * + * This file is used to get some basic information + * about the memory layout of the shark we are running + * on. Memory is usually divided in blocks a 8 MB. + * And bootargs are copied from OpenFirmware. + */ + + +#include +#include +#include + + +asmlinkage void +create_params (unsigned long *buffer) +{ + /* Is there a better address? Also change in kernel/arch.c */ + struct param_struct *params = (struct param_struct *) 0x08003000; + int j,i,m,k,nr_banks,size; + + for (j=0;j<256;j++) params->u1.unused[j]=0; + + size=0; + nr_banks=(unsigned int) buffer[0]; + if (nr_banks > NR_BANKS) nr_banks = NR_BANKS; + for (j=0;ju1.s.pages_in_bank[j]=buffer[2*k+1]|(buffer[2*k+2]/PAGE_SIZE); + size += buffer[2*k+2]; + + buffer[2*k+1]=0xffffffff; /* mark as copied */ + } + + params->u1.s.page_size = PAGE_SIZE; + params->u1.s.nr_pages = size/PAGE_SIZE; + params->u1.s.flags = FLAG_READONLY; + + /* Copy over the bootargs */ + for (j=0;j<128/4;j++) { + ((unsigned long *) params->commandline)[j]=buffer[33+j]; + } +} + + +typedef int (*ofw_handle_t)(void *); + +/* Everything below is called with a wrong MMU setting. + * This means: no string constants, no initialization of + * arrays, no global variables! This is ugly but I didn't + * want to write this in assembler :-) + */ + +int +of_decode_int(const unsigned char *p) +{ + unsigned int i = *p++ << 8; + i = (i + *p++) << 8; + i = (i + *p++) << 8; + return (i + *p); +} + +int +OF_finddevice(ofw_handle_t openfirmware, char *name) +{ + unsigned int args[8]; + char service[12]; + + service[0]='f'; + service[1]='i'; + service[2]='n'; + service[3]='d'; + service[4]='d'; + service[5]='e'; + service[6]='v'; + service[7]='i'; + service[8]='c'; + service[9]='e'; + service[10]='\0'; + + args[0]=(unsigned int)service; + args[1]=1; + args[2]=1; + args[3]=(unsigned int)name; + + if (openfirmware(args) == -1) + return -1; + return args[4]; +} + +int +OF_getproplen(ofw_handle_t openfirmware, int handle, char *prop) +{ + unsigned int args[8]; + char service[12]; + + service[0]='g'; + service[1]='e'; + service[2]='t'; + service[3]='p'; + service[4]='r'; + service[5]='o'; + service[6]='p'; + service[7]='l'; + service[8]='e'; + service[9]='n'; + service[10]='\0'; + + args[0] = (unsigned int)service; + args[1] = 2; + args[2] = 1; + args[3] = (unsigned int)handle; + args[4] = (unsigned int)prop; + + if (openfirmware(args) == -1) + return -1; + return args[5]; +} + +int +OF_getprop(ofw_handle_t openfirmware, int handle, char *prop, void *buf, unsigned int buflen) +{ + unsigned int args[8]; + char service[8]; + + service[0]='g'; + service[1]='e'; + service[2]='t'; + service[3]='p'; + service[4]='r'; + service[5]='o'; + service[6]='p'; + service[7]='\0'; + + args[0] = (unsigned int)service; + args[1] = 4; + args[2] = 1; + args[3] = (unsigned int)handle; + args[4] = (unsigned int)prop; + args[5] = (unsigned int)buf; + args[6] = buflen; + + if (openfirmware(args) == -1) + return -1; + return args[7]; +} + +asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer) +{ + int phandle,i,mem_len,buffer[32]; + char temp[12]; + + temp[0]='/'; + temp[1]='m'; + temp[2]='e'; + temp[3]='m'; + temp[4]='o'; + temp[5]='r'; + temp[6]='y'; + temp[7]='\0'; + + phandle=OF_finddevice(o,temp); + + temp[0]='r'; + temp[1]='e'; + temp[2]='g'; + temp[3]='\0'; + + mem_len = OF_getproplen(o,phandle, temp); + OF_getprop(o,phandle, temp, buffer, mem_len); + *nomr=mem_len >> 3; + + for (i=0; i<=mem_len/4; i++) pointer[i]=of_decode_int((const unsigned char *)&buffer[i]); + + temp[0]='/'; + temp[1]='c'; + temp[2]='h'; + temp[3]='o'; + temp[4]='s'; + temp[5]='e'; + temp[6]='n'; + temp[7]='\0'; + + phandle=OF_finddevice(o,temp); + + temp[0]='b'; + temp[1]='o'; + temp[2]='o'; + temp[3]='t'; + temp[4]='a'; + temp[5]='r'; + temp[6]='g'; + temp[7]='s'; + temp[8]='\0'; + + mem_len = OF_getproplen(o,phandle, temp); + OF_getprop(o,phandle, temp, buffer, mem_len); + for (i=0; i<=mem_len/4; i++) pointer[i+32]=buffer[i]; + +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/boot/compressed/setup-sa1100.S linux.ac/arch/arm/boot/compressed/setup-sa1100.S --- linux.vanilla/arch/arm/boot/compressed/setup-sa1100.S Sat Oct 28 16:15:42 2000 +++ linux.ac/arch/arm/boot/compressed/setup-sa1100.S Sun Dec 31 14:56:45 2000 @@ -33,13 +33,11 @@ #define UTSR0 0x1c #define UTSR1 0x20 -#define BAUD_DIV_230400 0x000 -#define BAUD_DIV_115200 0x001 -#define BAUD_DIV_57600 0x003 -#define BAUD_DIV_38400 0x005 -#define BAUD_DIV_19200 0x00b -#define BAUD_DIV_9600 0x017 -#define BAUD_DIV BAUD_DIV_9600 +#ifndef CONFIG_SA1100_DEFAULT_BAUDRATE +#define CONFIG_SA1100_DEFAULT_BAUDRATE 9600 +#endif + +#define BAUD_DIV ((230400/CONFIG_SA1100_DEFAULT_BAUDRATE)-1) SCR_loc: .long SYMBOL_NAME(SCR_value) #define GPIO_2_9 0x3fc @@ -92,7 +90,7 @@ bne skip_uart @ UART3 if Assabet is used with Neponset - teq r3, #25 @ if Assabet + teq r3, #MACH_TYPE_ASSABET @ if Assabet tsteq r2, #(1 << 9) @ ... and Neponset present ldreq r0, UART3_BASE beq uart_init diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/boot/compressed/vmlinux.lds.in linux.ac/arch/arm/boot/compressed/vmlinux.lds.in --- linux.vanilla/arch/arm/boot/compressed/vmlinux.lds.in Sat Oct 28 16:15:42 2000 +++ linux.ac/arch/arm/boot/compressed/vmlinux.lds.in Sun Dec 31 14:57:57 2000 @@ -19,12 +19,13 @@ .text : { _start = .; - head.o(.start) *(.start) - head.o(.text) *(.text) *(.fixup) *(.gnu.warning) + *(.rodata) + *(.glue_7) + *(.glue_7t) input_data = .; piggy.o input_data_end = .; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/config.in linux.ac/arch/arm/config.in --- linux.vanilla/arch/arm/config.in Mon Nov 20 15:11:55 2000 +++ linux.ac/arch/arm/config.in Sun Dec 31 18:02:14 2000 @@ -352,7 +352,7 @@ source drivers/ieee1394/Config.in -source drivers/i2o/Config.in +source drivers/message/i2o/Config.in mainmenu_option next_comment comment 'ISDN subsystem' diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/Makefile linux.ac/arch/arm/kernel/Makefile --- linux.vanilla/arch/arm/kernel/Makefile Sat Oct 28 16:15:42 2000 +++ linux.ac/arch/arm/kernel/Makefile Sun Dec 31 14:57:34 2000 @@ -10,16 +10,14 @@ HEAD_OBJ = head-$(PROCESSOR).o ENTRY_OBJ = entry-$(PROCESSOR).o -AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -traditional -AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional +AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) +AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) O_OBJS_arc = dma-arc.o oldlatches.o O_OBJS_rpc = dma-rpc.o O_OBJS_footbridge = dma-footbridge.o isa.o O_OBJS_l7200 = fiq.o -leds-ebsa110 = leds-ebsa110.o - pci-nexuspci = plx90x0.o pci-footbridge = dec21285.o pci-shark = via82c505.o @@ -31,36 +29,28 @@ # Object file lists. -obj-y := arch.o dma.o $(ENTRY_OBJ) irq.o process.o ptrace.o \ - semaphore.o setup.o signal.o sys_arm.o time.o \ - traps.o $(O_OBJS_$(MACHINE)) -obj-m := -obj-n := -obj- := - -export-objs := armksyms.o dma.o ecard.o \ - $(leds-$(MACHINE)) oldlatches.o \ - time.o +obj-y := arch.o dma.o $(ENTRY_OBJ) irq.o process.o ptrace.o \ + semaphore.o setup.o signal.o sys_arm.o time.o traps.o \ + $(O_OBJS_$(MACHINE)) +obj-m := +obj-n := +obj- := + +export-objs := armksyms.o dma.o ecard.o fiq.o oldlatches.o time.o + +no-irq-arch := $(CONFIG_ARCH_INTEGRATOR) $(CONFIG_ARCH_CLPS711X) \ + $(CONFIG_ARCH_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110) + +ifneq ($(findstring y,$(no-irq-arch)),y) + obj-y += irq-arch.o +endif obj-$(CONFIG_ARCH_ACORN) += ecard.o fiq.o time-acorn.o obj-$(CONFIG_DEBUG_LL) += debug-$(PROCESSOR).o obj-$(CONFIG_MODULES) += armksyms.o -obj-$(CONFIG_LEDS) += $(leds-$(MACHINE)) obj-$(CONFIG_ARTHUR) += arthur.o obj-$(CONFIG_ISA_DMA) += dma-isa.o - obj-$(CONFIG_PCI) += bios32.o $(pci-$(MACHINE)) $(pci-y) - -# Files that are both resident and modular; remove from modular. - -obj-m := $(filter-out $(obj-y), $(obj-m)) - -# Translate to Rules.make lists. - -O_OBJS := $(filter-out $(export-objs), $(obj-y)) -OX_OBJS := $(filter $(export-objs), $(obj-y)) -M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) -MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) all: kernel.o $(HEAD_OBJ) init_task.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/bios32.c linux.ac/arch/arm/kernel/bios32.c --- linux.vanilla/arch/arm/kernel/bios32.c Tue Dec 12 13:05:13 2000 +++ linux.ac/arch/arm/kernel/bios32.c Sun Dec 31 15:02:32 2000 @@ -257,11 +257,30 @@ (struct arm_pci_sysdata *)bus->sysdata; struct arm_bus_sysdata *busdata; - if (bus->number < MAX_NR_BUS) - busdata = sysdata->bus + bus->number; - else + if (bus->number >= MAX_NR_BUS) BUG(); + if (bus->self) { + struct pci_dev *dev = bus->self; + int i; + + for (i = 0; i < 3; i++) { + bus->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES + i]; + bus->resource[i]->name = bus->name; + } + bus->resource[0]->start = ioport_resource.start; + bus->resource[0]->end = ioport_resource.end; + bus->resource[0]->flags |= pci_bridge_check_io(dev); + bus->resource[1]->start = iomem_resource.start; + bus->resource[1]->end = iomem_resource.end; + bus->resource[1]->flags |= IORESOURCE_MEM; + + /* Turn off downsteam prefetchable memory address range */ + bus->resource[2]->start = 1024*1024; + bus->resource[2]->end = bus->resource[2]->start - 1; + } + + busdata = sysdata->bus + bus->number; busdata->max_lat = 255; /* @@ -363,10 +382,6 @@ void __init pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges) { - ranges->io_start -= bus->resource[0]->start; - ranges->io_end -= bus->resource[0]->start; - ranges->mem_start -= bus->resource[1]->start; - ranges->mem_end -= bus->resource[1]->start; } u8 __init no_swizzle(struct pci_dev *dev, u8 *pin) @@ -442,7 +457,8 @@ hw_pci->init(&sysdata); /* - * Other architectures don't seem to do this... should we? + * Claim the currently allocated resources. This ensures + * that we will not allocate an already inuse region. */ pcibios_claim_resources(); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/dma-arc.c linux.ac/arch/arm/kernel/dma-arc.c --- linux.vanilla/arch/arm/kernel/dma-arc.c Tue Dec 12 13:05:13 2000 +++ linux.ac/arch/arm/kernel/dma-arc.c Sun Dec 31 14:53:48 2000 @@ -40,7 +40,7 @@ memcpy ((void *)0x1c, (void *)&fdc1772_dma_read, &fdc1772_dma_read_end - &fdc1772_dma_read); fdc1772_setupdma(dma->buf.length, dma->buf.address); /* Sets data pointer up */ - enable_irq (64); + enable_fiq(FIQ_FLOPPYDATA); restore_flags(flags); } break; @@ -55,7 +55,7 @@ memcpy ((void *)0x1c, (void *)&fdc1772_dma_write, &fdc1772_dma_write_end - &fdc1772_dma_write); fdc1772_setupdma(dma->buf.length, dma->buf.address); /* Sets data pointer up */ - enable_irq (64); + enable_fiq(FIQ_FLOPPYDATA; restore_flags(flags); } @@ -102,7 +102,7 @@ static void arc_disable_dma(dmach_t channel, dma_t *dma) { - disable_irq(dma->dma_irq); + disable_fiq(dma->dma_irq); } static struct dma_ops arc_floppy_data_dma_ops = { @@ -158,12 +158,12 @@ regs.ARM_r10 = dma->buf.address; regs.ARM_fp = FLOPPYDMA_BASE; set_fiq_regs(®s); - enable_irq(dma->dma_irq); + enable_fiq(dma->dma_irq); } static void a5k_floppy_disable_dma(dmach_t channel, dma_t *dma) { - disable_irq(dma->dma_irq); + disable_fiq(dma->dma_irq); release_fiq(&fh); } @@ -192,15 +192,15 @@ { #if defined(CONFIG_BLK_DEV_FD1772) || defined(CONFIG_BLK_DEV_FD1772_MODULE) if (machine_is_archimedes()) { - dma[DMA_VIRTUAL_FLOPPY0].dma_irq = 64; + dma[DMA_VIRTUAL_FLOPPY0].dma_irq = FIQ_FLOPPYDATA; dma[DMA_VIRTUAL_FLOPPY0].d_ops = &arc_floppy_data_dma_ops; - dma[DMA_VIRTUAL_FLOPPY1].dma_irq = 65; + dma[DMA_VIRTUAL_FLOPPY1].dma_irq = 1; dma[DMA_VIRTUAL_FLOPPY1].d_ops = &arc_floppy_cmdend_dma_ops; } #endif #ifdef CONFIG_ARCH_A5K if (machine_is_a5k()) { - dma[DMA_VIRTUAL_FLOPPY0].dma_irq = 64; + dma[DMA_VIRTUAL_FLOPPY0].dma_irq = FIQ_FLOPPYDATA; dma[DMA_VIRTUAL_FLOPPY0].d_ops = &a5k_floppy_dma_ops; } #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/dma-rpc.c linux.ac/arch/arm/kernel/dma-rpc.c --- linux.vanilla/arch/arm/kernel/dma-rpc.c Sat Oct 28 16:15:42 2000 +++ linux.ac/arch/arm/kernel/dma-rpc.c Sun Dec 31 14:53:48 2000 @@ -42,11 +42,11 @@ #define TRANSFER_SIZE 2 #define CURA (0) -#define ENDA ((IOMD_IO0ENDA - IOMD_IO0CURA) << 2) -#define CURB ((IOMD_IO0CURB - IOMD_IO0CURA) << 2) -#define ENDB ((IOMD_IO0ENDB - IOMD_IO0CURA) << 2) -#define CR ((IOMD_IO0CR - IOMD_IO0CURA) << 2) -#define ST ((IOMD_IO0ST - IOMD_IO0CURA) << 2) +#define ENDA (IOMD_IO0ENDA - IOMD_IO0CURA) +#define CURB (IOMD_IO0CURB - IOMD_IO0CURA) +#define ENDB (IOMD_IO0ENDB - IOMD_IO0CURA) +#define CR (IOMD_IO0CR - IOMD_IO0CURA) +#define ST (IOMD_IO0ST - IOMD_IO0CURA) #define state_prog_a 0 #define state_wait_a 1 @@ -93,14 +93,14 @@ static inline void iomd_setup_dma_a(struct scatterlist *sg, dma_t *dma) { - outl_t(sg->dma_address, dma->dma_base + CURA); - outl_t(sg->length, dma->dma_base + ENDA); + iomd_writel(sg->dma_address, dma->dma_base + CURA); + iomd_writel(sg->length, dma->dma_base + ENDA); } static inline void iomd_setup_dma_b(struct scatterlist *sg, dma_t *dma) { - outl_t(sg->dma_address, dma->dma_base + CURB); - outl_t(sg->length, dma->dma_base + ENDB); + iomd_writel(sg->dma_address, dma->dma_base + CURB); + iomd_writel(sg->length, dma->dma_base + ENDB); } static void iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs) @@ -116,7 +116,7 @@ dma->state = state_wait_a; case state_wait_a: - status = inb_t(dma->dma_base + ST); + status = iomd_readb(dma->dma_base + ST); switch (status & (DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB)) { case DMA_ST_OFL|DMA_ST_INT: iomd_get_next_sg(&dma->cur_sg, dma); @@ -137,7 +137,7 @@ break; case state_wait_b: - status = inb_t(dma->dma_base + ST); + status = iomd_readb(dma->dma_base + ST); switch (status & (DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB)) { case DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB: iomd_get_next_sg(&dma->cur_sg, dma); @@ -193,14 +193,14 @@ PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); } - outb_t(DMA_CR_C, dma_base + CR); + iomd_writeb(DMA_CR_C, dma_base + CR); dma->state = state_prog_a; } if (dma->dma_mode == DMA_MODE_READ) ctrl |= DMA_CR_D; - outb_t(ctrl, dma_base + CR); + iomd_writeb(ctrl, dma_base + CR); enable_irq(dma->dma_irq); } @@ -210,8 +210,8 @@ unsigned int ctrl; disable_irq(dma->dma_irq); - ctrl = inb_t(dma_base + CR); - outb_t(ctrl & ~DMA_CR_E, dma_base + CR); + ctrl = iomd_readb(dma_base + CR); + iomd_writeb(ctrl & ~DMA_CR_E, dma_base + CR); } static int iomd_set_dma_speed(dmach_t channel, dma_t *dma, int cycle) @@ -227,7 +227,7 @@ else speed = 0; - tcr = inb(IOMD_DMATCR); + tcr = iomd_readb(IOMD_DMATCR); speed &= 3; switch (channel) { @@ -251,7 +251,7 @@ break; } - outb(tcr, IOMD_DMATCR); + iomd_writeb(tcr, IOMD_DMATCR); return speed; } @@ -287,7 +287,7 @@ regs.ARM_r9 = dma->buf.length; regs.ARM_r10 = (unsigned long)dma->buf.address; - regs.ARM_fp = (unsigned long)PCIO_FLOPPYDMABASE; + regs.ARM_fp = FLOPPYDMA_BASE; if (claim_fiq(&fh)) { printk("floppydma: couldn't claim FIQ.\n"); @@ -296,12 +296,12 @@ set_fiq_handler(fiqhandler_start, fiqhandler_length); set_fiq_regs(®s); - enable_irq(dma->dma_irq); + enable_fiq(dma->dma_irq); } static void floppy_disable_dma(dmach_t channel, dma_t *dma) { - disable_irq(dma->dma_irq); + disable_fiq(dma->dma_irq); release_fiq(&fh); } @@ -334,32 +334,32 @@ void __init arch_dma_init(dma_t *dma) { - outb(0, IOMD_IO0CR); - outb(0, IOMD_IO1CR); - outb(0, IOMD_IO2CR); - outb(0, IOMD_IO3CR); + iomd_writeb(0, IOMD_IO0CR); + iomd_writeb(0, IOMD_IO1CR); + iomd_writeb(0, IOMD_IO2CR); + iomd_writeb(0, IOMD_IO3CR); - outb(0xa0, IOMD_DMATCR); + iomd_writeb(0xa0, IOMD_DMATCR); - dma[DMA_0].dma_base = ioaddr(IOMD_IO0CURA); + dma[DMA_0].dma_base = IOMD_IO0CURA; dma[DMA_0].dma_irq = IRQ_DMA0; dma[DMA_0].d_ops = &iomd_dma_ops; - dma[DMA_1].dma_base = ioaddr(IOMD_IO1CURA); + dma[DMA_1].dma_base = IOMD_IO1CURA; dma[DMA_1].dma_irq = IRQ_DMA1; dma[DMA_1].d_ops = &iomd_dma_ops; - dma[DMA_2].dma_base = ioaddr(IOMD_IO2CURA); + dma[DMA_2].dma_base = IOMD_IO2CURA; dma[DMA_2].dma_irq = IRQ_DMA2; dma[DMA_2].d_ops = &iomd_dma_ops; - dma[DMA_3].dma_base = ioaddr(IOMD_IO3CURA); + dma[DMA_3].dma_base = IOMD_IO3CURA; dma[DMA_3].dma_irq = IRQ_DMA3; dma[DMA_3].d_ops = &iomd_dma_ops; - dma[DMA_S0].dma_base = ioaddr(IOMD_SD0CURA); + dma[DMA_S0].dma_base = IOMD_SD0CURA; dma[DMA_S0].dma_irq = IRQ_DMAS0; dma[DMA_S0].d_ops = &iomd_dma_ops; - dma[DMA_S1].dma_base = ioaddr(IOMD_SD1CURA); + dma[DMA_S1].dma_base = IOMD_SD1CURA; dma[DMA_S1].dma_irq = IRQ_DMAS1; dma[DMA_S1].d_ops = &iomd_dma_ops; - dma[DMA_VIRTUAL_FLOPPY].dma_irq = 64; + dma[DMA_VIRTUAL_FLOPPY].dma_irq = FIQ_FLOPPYDATA; dma[DMA_VIRTUAL_FLOPPY].d_ops = &floppy_dma_ops; dma[DMA_VIRTUAL_SOUND].d_ops = &sound_dma_ops; @@ -367,5 +367,5 @@ * Setup DMA channels 2,3 to be for podules * and channels 0,1 for internal devices */ - outb(DMA_EXT_IO3|DMA_EXT_IO2, IOMD_DMAEXT); + iomd_writeb(DMA_EXT_IO3|DMA_EXT_IO2, IOMD_DMAEXT); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/entry-armo.S linux.ac/arch/arm/kernel/entry-armo.S --- linux.vanilla/arch/arm/kernel/entry-armo.S Sat Oct 28 16:15:42 2000 +++ linux.ac/arch/arm/kernel/entry-armo.S Sun Dec 31 14:54:31 2000 @@ -197,8 +197,7 @@ #endif #define FAULT_CODE_PREFETCH 0x04 #define FAULT_CODE_WRITE 0x02 -#define FAULT_CODE_USER 0x01 - +#define FAULT_CODE_FORCECOW 0x01 #define SVC_SAVE_ALL \ str sp, [sp, #-16]! ;\ @@ -487,7 +486,6 @@ save_user_regs teqp pc, #0x00000003 @ NOT a problem - doesnt change mode mask_pc r0, lr - mov r2, #FAULT_CODE_USER bl Ldata_do b ret_from_exception @@ -499,7 +497,6 @@ tst lr, #0x08000000 teqeqp pc, #0x00000003 @ NOT a problem - doesnt change mode mask_pc r0, lr - mov r2, #0 bl Ldata_do SVC_RESTORE_ALL @@ -510,6 +507,7 @@ Ldata_do: mov r3, sp ldr r4, [r0] @ Get instruction + mov r2, #0 tst r4, #1 << 20 @ Check to see if it is a write instruction orreq r2, r2, #FAULT_CODE_WRITE @ Indicate write instruction mov r1, r4, lsr #22 @ Now branch to the relevent processing routine diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/fiq.c linux.ac/arch/arm/kernel/fiq.c --- linux.vanilla/arch/arm/kernel/fiq.c Tue Dec 12 13:05:13 2000 +++ linux.ac/arch/arm/kernel/fiq.c Sun Dec 31 14:53:48 2000 @@ -36,12 +36,14 @@ * 6. Goto 3 */ #include +#include #include #include #include #include #include +#include #include #include #include @@ -71,7 +73,7 @@ * - we always relinquish FIQ control * - we always reacquire FIQ control */ -int fiq_def_op(void *ref, int relinquish) +static int fiq_def_op(void *ref, int relinquish) { if (!relinquish) { unprotect_page_0(); @@ -213,6 +215,24 @@ current_fiq = current_fiq->next; while (current_fiq->fiq_op(current_fiq->dev_id, 0)); } + +void enable_fiq(int fiq) +{ + enable_irq(fiq + FIQ_START); +} + +void disable_fiq(int fiq) +{ + disable_irq(fiq + FIQ_START); +} + +EXPORT_SYMBOL(set_fiq_handler); +EXPORT_SYMBOL(set_fiq_regs); +EXPORT_SYMBOL(get_fiq_regs); +EXPORT_SYMBOL(claim_fiq); +EXPORT_SYMBOL(release_fiq); +EXPORT_SYMBOL(enable_fiq); +EXPORT_SYMBOL(disable_fiq); void __init init_FIQ(void) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/process.c linux.ac/arch/arm/kernel/process.c --- linux.vanilla/arch/arm/kernel/process.c Sat Oct 28 16:15:42 2000 +++ linux.ac/arch/arm/kernel/process.c Sun Dec 31 14:55:03 2000 @@ -92,8 +92,10 @@ void (*idle)(void) = pm_idle; if (!idle) idle = arch_idle; + leds_event(led_idle_start); while (!current->need_resched) idle(); + leds_event(led_idle_end); schedule(); #ifndef CONFIG_NO_PGT_CACHE check_pgt_cache(); @@ -364,20 +366,23 @@ */ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) { - extern long sys_exit(int) __attribute__((noreturn)); pid_t __ret; __asm__ __volatile__( - "mov r0, %1 @ kernel_thread sys_clone + "orr r0, %1, %2 @ kernel_thread sys_clone mov r1, #0 "__syscall(clone)" - teq r0, #0 @ if we are the child - moveq fp, #0 @ ensure that fp is zero - mov %0, r0" + movs %0, r0 @ if we are the child + bne 1f + mov fp, #0 @ ensure that fp is zero + mov r0, %4 + mov lr, pc + mov pc, %3 + b sys_exit +1: " : "=r" (__ret) - : "Ir" (flags | CLONE_VM) : "r0", "r1"); - if (__ret == 0) - sys_exit((fn)(arg)); + : "Ir" (flags), "I" (CLONE_VM), "r" (fn), "r" (arg) + : "r0", "r1", "lr"); return __ret; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/kernel/traps.c linux.ac/arch/arm/kernel/traps.c --- linux.vanilla/arch/arm/kernel/traps.c Tue Dec 12 13:05:13 2000 +++ linux.ac/arch/arm/kernel/traps.c Sun Dec 31 14:59:49 2000 @@ -107,7 +107,7 @@ bad = __get_user(val, &((u32 *)addr)[i]); if (!bad) - printk(i == 0 ? "(%0*x) " : "%0*x", width, val); + printk(i == 0 ? "(%0*x) " : "%0*x ", width, val); else { printk("bad PC value."); break; @@ -133,7 +133,7 @@ printk("no frame pointer"); ok = 0; } else if (verify_stack(fp)) { - printk("invalid frame pointer %08lx", fp); + printk("invalid frame pointer 0x%08x", fp); ok = 0; } else if (fp < 4096+(unsigned long)tsk) printk("frame pointer underflow"); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/Makefile linux.ac/arch/arm/lib/Makefile --- linux.vanilla/arch/arm/lib/Makefile Tue Dec 12 13:05:13 2000 +++ linux.ac/arch/arm/lib/Makefile Sun Dec 31 14:57:34 2000 @@ -1,57 +1,57 @@ # # linux/arch/arm/lib/Makefile # -# Copyright (C) 1995-1999 Russell King +# Copyright (C) 1995-2000 Russell King # USE_STANDARD_AS_RULE := true -L_TARGET := lib.a -L_OBJS := changebit.o csumipv6.o csumpartial.o csumpartialcopy.o \ - csumpartialcopyuser.o clearbit.o copy_page.o findbit.o \ - memchr.o memcpy.o memset.o memzero.o setbit.o \ - strncpy_from_user.o strnlen_user.o strchr.o strrchr.o \ - testchangebit.o testclearbit.o testsetbit.o uaccess.o - -l-obj-y := -l-obj-n := - -O_TARGET := lib.o -O_OBJS := backtrace.o delay.o - -ifeq ($(CONFIG_ARCH_ACORN),y) - half := n - full := y +L_TARGET := lib.a + +obj-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ + csumpartialcopy.o csumpartialcopyuser.o clearbit.o \ + copy_page.o delay.o findbit.o memchr.o memcpy.o \ + memset.o memzero.o setbit.o strncpy_from_user.o \ + strnlen_user.o strchr.o strrchr.o testchangebit.o \ + testclearbit.o testsetbit.o uaccess.o +obj-m := +obj-n := + +export-objs := io.o + +obj-arc := ecard.o io-acorn.o floppydma.o +obj-rpc := ecard.o io-acorn.o floppydma.o +obj-clps7500 := io-acorn.o +obj-footbridge := io-pcio.o +obj-l7200 := io-acorn.o +obj-nexuspci := io-pcio.o +obj-sa1100 := io-pcio.o +obj-shark := io-shark.o +obj-integrator := io-pcio.o +obj-clps711x := io-shark.o + +obj-y += $(obj-$(MACHINE)) + +ifeq ($(CONFIG_CPU_32v4),y) + v3 := n + v4 := y else - half := y - full := n + v3 := y + v4 := n endif -L_OBJS_arc := ecard.o io-acorn.o floppydma.o -L_OBJS_rpc := ecard.o io-acorn.o floppydma.o -L_OBJS_clps7500 := io-acorn.o -L_OBJS_footbridge := io-pcio.o -L_OBJS_l7200 := io-acorn.o -L_OBJS_nexuspci := io-pcio.o -L_OBJS_sa1100 := io-pcio.o -L_OBJS_shark := io-shark.o -L_OBJS_integrator := io-pcio.o -L_OBJS_clps711x := io-shark.o - -l-obj-y += io-readsb.o io-writesb.o -l-obj-$(full) += io-readsw-armv3.o io-writesw-armv3.o -l-obj-$(half) += io-readsw-armv4.o io-writesw-armv4.o -l-obj-y += io-readsl.o io-writesl.o +obj-y += io-readsb.o io-writesb.o +obj-$(v3) += io-readsw-armv3.o io-writesw-armv3.o io-readsl-armv3.o +obj-$(v4) += io-readsw-armv4.o io-writesw-armv4.o io-readsl-armv4.o +obj-y += io-writesl.o ifeq ($(PROCESSOR),armo) - L_OBJS += uaccess-armo.o + obj-y += uaccess-armo.o endif ifneq ($(MACHINE),ebsa110) - OX_OBJS += io.o + obj-y += io.o endif - -L_OBJS += $(L_OBJS_$(MACHINE)) $(l-obj-y) include $(TOPDIR)/Rules.make diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/io-acorn.S linux.ac/arch/arm/lib/io-acorn.S --- linux.vanilla/arch/arm/lib/io-acorn.S Tue Dec 12 13:05:13 2000 +++ linux.ac/arch/arm/lib/io-acorn.S Sun Dec 31 14:56:20 2000 @@ -60,32 +60,32 @@ */ ENTRY(insw) - teq r2, #0 - RETINSTR(moveq, pc, lr) addr r0 - b __arch_readsw + teq r2, #0 + bne __arch_readsw + RETINSTR(mov, pc, lr) ENTRY(insb) - teq r2, #0 - RETINSTR(moveq, pc, lr) addr r0 - b __arch_readsb + teq r2, #0 + bne __arch_readsb + RETINSTR(mov, pc, lr) @ Purpose: write a block of data from memory to a hardware register. @ Proto : outsw(int to_reg, void *from, int len_in_words); @ Notes : increments from ENTRY(outsw) - teq r2, #0 - RETINSTR(moveq, pc, lr) addr r0 - b __arch_writesw + teq r2, #0 + bne __arch_writesw + RETINSTR(mov, pc, lr) ENTRY(outsb) - teq r2, #0 - RETINSTR(moveq, pc, lr) addr r0 - b __arch_writesb + teq r2, #0 + bne __arch_writesb + RETINSTR(mov, pc, lr) @ Purpose: write a memc register @ Proto : void memc_write(int register, int value); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/io-pcio.S linux.ac/arch/arm/lib/io-pcio.S --- linux.vanilla/arch/arm/lib/io-pcio.S Tue Dec 12 13:05:13 2000 +++ linux.ac/arch/arm/lib/io-pcio.S Sun Dec 31 14:56:20 2000 @@ -1,4 +1,5 @@ #include +#include #include .equ pcio_high, PCIO_BASE & 0xff000000 @@ -13,26 +14,37 @@ ENTRY(insl) ioaddr r0, r0 - b __arch_readsl + teq r2, #0 + bne __arch_readsl + RETINSTR(mov, pc, lr) ENTRY(outsl) ioaddr r0, r0 - b __arch_writesl - - /* Nobody could say these are optimal, but not to worry. */ + teq r2, #0 + bne __arch_writesl + RETINSTR(mov, pc, lr) ENTRY(outsw) ioaddr r0, r0 - b __arch_writesw + teq r2, #0 + bne __arch_writesw + RETINSTR(mov, pc, lr) ENTRY(insw) ioaddr r0, r0 - b __arch_readsw + teq r2, #0 + bne __arch_readsw + RETINSTR(mov, pc, lr) ENTRY(insb) ioaddr r0, r0 - b __arch_readsb + teq r2, #0 + bne __arch_readsb + RETINSTR(mov, pc, lr) ENTRY(outsb) ioaddr r0, r0 - b __arch_writesb + teq r2, #0 + bne __arch_writesb + RETINSTR(mov, pc, lr) + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/io-readsb.S linux.ac/arch/arm/lib/io-readsb.S --- linux.vanilla/arch/arm/lib/io-readsb.S Tue Dec 12 13:05:13 2000 +++ linux.ac/arch/arm/lib/io-readsb.S Sun Dec 31 14:56:20 2000 @@ -62,6 +62,7 @@ ldrb ip, [r0] orr r6, r6, ip, lsl #24 stmia r1!, {r3 - r6} + subs r2, r2, #16 bpl .insb_16_lp @@ -88,7 +89,7 @@ stmia r1!, {r3, r4} .insb_no_8: tst r2, #4 - bne .insb_no_4 + beq .insb_no_4 ldrb r3, [r0] ldrb r4, [r0] @@ -101,6 +102,7 @@ .insb_no_4: ands r2, r2, #3 LOADREGS(eqfd, sp!, {r4 - r6, pc}) + cmp r2, #2 ldrb r3, [r0] strb r3, [r1], #1 @@ -108,4 +110,5 @@ strgeb r3, [r1], #1 ldrgtb r3, [r0] strgtb r3, [r1] + LOADREGS(fd, sp!, {r4 - r6, pc}) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/io-readsl-armv3.S linux.ac/arch/arm/lib/io-readsl-armv3.S --- linux.vanilla/arch/arm/lib/io-readsl-armv3.S Thu Jan 1 01:00:00 1970 +++ linux.ac/arch/arm/lib/io-readsl-armv3.S Sun Dec 31 14:56:20 2000 @@ -0,0 +1,76 @@ +/* + * linux/arch/arm/lib/io-readsl-armv3.S + * + * Copyright (C) 1995-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include + +/* + * Note that some reads can be aligned on half-word boundaries. + */ +ENTRY(__arch_readsl) + ands ip, r1, #3 + bne 2f + +1: ldr r3, [r0] + str r3, [r1], #4 + subs r2, r2, #1 + bne 1b + mov pc, lr + +2: cmp ip, #2 + ldr ip, [r0] + blt 4f + bgt 6f + + strb ip, [r1], #1 + mov ip, ip, lsr #8 + strb ip, [r1], #1 + mov ip, ip, lsr #8 +3: subs r2, r2, #1 + ldrne r3, [r0] + orrne ip, ip, r3, lsl #16 + strne ip, [r1], #4 + movne ip, r3, lsr #16 + bne 3b + strb ip, [r1], #1 + mov ip, ip, lsr #8 + strb ip, [r1], #1 + mov pc, lr + +4: strb ip, [r1], #1 + mov ip, ip, lsr #8 + strb ip, [r1], #1 + mov ip, ip, lsr #8 + strb ip, [r1], #1 + mov ip, ip, lsr #8 +5: subs r2, r2, #1 + ldrne r3, [r0] + orrne ip, ip, r3, lsl #8 + strne ip, [r1], #4 + movne ip, r3, lsr #24 + bne 5b + strb ip, [r1], #1 + mov pc, lr + +6: strb ip, [r1], #1 + mov ip, ip, lsr #8 +7: subs r2, r2, #1 + ldrne r3, [r0] + orrne ip, ip, r3, lsl #24 + strne ip, [r1], #4 + movne ip, r3, lsr #8 + bne 7b + strb ip, [r1], #1 + mov ip, ip, lsr #8 + strb ip, [r1], #1 + mov ip, ip, lsr #8 + strb ip, [r1], #1 + mov pc, lr + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/io-readsl-armv4.S linux.ac/arch/arm/lib/io-readsl-armv4.S --- linux.vanilla/arch/arm/lib/io-readsl-armv4.S Thu Jan 1 01:00:00 1970 +++ linux.ac/arch/arm/lib/io-readsl-armv4.S Sun Dec 31 14:56:20 2000 @@ -0,0 +1,68 @@ +/* + * linux/arch/arm/lib/io-readsl-armv4.S + * + * Copyright (C) 1995-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include + +/* + * Note that some reads can be aligned on half-word boundaries. + */ +ENTRY(__arch_readsl) + ands ip, r1, #3 + bne 2f + +1: ldr r3, [r0] + str r3, [r1], #4 + subs r2, r2, #1 + bne 1b + mov pc, lr + +2: cmp ip, #2 + ldr ip, [r0] + blt 4f + bgt 6f + + strh ip, [r1], #2 + mov ip, ip, lsr #16 +3: subs r2, r2, #1 + ldrne r3, [r0] + orrne ip, ip, r3, lsl #16 + strne ip, [r1], #4 + movne ip, r3, lsr #16 + bne 3b + strh ip, [r1], #2 + mov pc, lr + +4: strb ip, [r1], #1 + mov ip, ip, lsr #8 + strh ip, [r1], #2 + mov ip, ip, lsr #16 +5: subs r2, r2, #1 + ldrne r3, [r0] + orrne ip, ip, r3, lsl #8 + strne ip, [r1], #4 + movne ip, r3, lsr #24 + bne 5b + strb ip, [r1], #1 + mov pc, lr + +6: strb ip, [r1], #1 + mov ip, ip, lsr #8 +7: subs r2, r2, #1 + ldrne r3, [r0] + orrne ip, ip, r3, lsl #24 + strne ip, [r1], #4 + movne ip, r3, lsr #8 + bne 7b + strb ip, [r1], #1 + mov ip, ip, lsr #8 + strh ip, [r1], #2 + mov pc, lr + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/io-readsl.S linux.ac/arch/arm/lib/io-readsl.S --- linux.vanilla/arch/arm/lib/io-readsl.S Tue Dec 12 13:05:13 2000 +++ linux.ac/arch/arm/lib/io-readsl.S Thu Jan 1 01:00:00 1970 @@ -1,65 +0,0 @@ -/* - * linux/arch/arm/lib/io-readsb.S - * - * Copyright (C) 1995-2000 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include - -ENTRY(__arch_readsl) - ands ip, r1, #3 - bne 2f - -1: ldr r3, [r0] - str r3, [r1], #4 - subs r2, r2, #1 - bne 1b - mov pc, lr - -2: cmp ip, #2 - ldr ip, [r0] - blt 4f - bgt 6f - - strh ip, [r1], #2 - mov ip, ip, lsr #16 -3: subs r2, r2, #1 - ldrne r3, [r0] - orrne ip, ip, r3, lsl #16 - strne ip, [r1], #4 - movne ip, r3, lsr #16 - bne 3b - strh ip, [r1], #2 - mov pc, lr - -4: strb ip, [r1], #1 - mov ip, ip, lsr #8 - strh ip, [r1], #2 - mov ip, ip, lsr #16 -5: subs r2, r2, #1 - ldrne r3, [r0] - orrne ip, ip, r3, lsl #8 - strne ip, [r1], #4 - movne ip, r3, lsr #24 - bne 5b - strb ip, [r1], #1 - mov pc, lr - -6: strb ip, [r1], #1 - mov ip, ip, lsr #8 -7: subs r2, r2, #1 - ldrne r3, [r0] - orrne ip, ip, r3, lsl #24 - strne ip, [r1], #4 - movne ip, r3, lsr #8 - bne 7b - strb ip, [r1], #1 - mov ip, ip, lsr #8 - strh ip, [r1], #2 - mov pc, lr - diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/io-readsw-armv3.S linux.ac/arch/arm/lib/io-readsw-armv3.S --- linux.vanilla/arch/arm/lib/io-readsw-armv3.S Tue Dec 12 13:05:13 2000 +++ linux.ac/arch/arm/lib/io-readsw-armv3.S Sun Dec 31 14:56:20 2000 @@ -1,5 +1,5 @@ /* - * linux/arch/arm/lib/io-readsb.S + * linux/arch/arm/lib/io-readsw-armv3.S * * Copyright (C) 1995-2000 Russell King * @@ -62,8 +62,10 @@ orr r6, r6, lr, lsl #16 stmia r1!, {r3 - r6} + subs r2, r2, #8 bpl .insw_8_lp + tst r2, #7 LOADREGS(eqfd, sp!, {r4, r5, r6, pc}) @@ -97,6 +99,7 @@ strneb r3, [r1], #1 movne r3, r3, lsr #8 strneb r3, [r1] + LOADREGS(fd, sp!, {r4, r5, r6, pc}) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/io-readsw-armv4.S linux.ac/arch/arm/lib/io-readsw-armv4.S --- linux.vanilla/arch/arm/lib/io-readsw-armv4.S Tue Dec 12 13:05:13 2000 +++ linux.ac/arch/arm/lib/io-readsw-armv4.S Sun Dec 31 14:56:20 2000 @@ -1,5 +1,5 @@ /* - * linux/arch/arm/lib/io-readsb.S + * linux/arch/arm/lib/io-readsw-armv4.S * * Copyright (C) 1995-2000 Russell King * @@ -46,16 +46,18 @@ orr r4, r4, r5, lsl #16 ldrh r5, [r0] - ldrh r6, [r0] - orr r5, r5, r6, lsl #16 + ldrh ip, [r0] + orr r5, r5, ip, lsl #16 ldrh ip, [r0] ldrh lr, [r0] orr ip, ip, lr, lsl #16 stmia r1!, {r3 - r5, ip} + subs r2, r2, #8 bpl .insw_8_lp + tst r2, #7 LOADREGS(eqfd, sp!, {r4, r5, pc}) @@ -84,4 +86,5 @@ .no_insw_2: tst r2, #1 ldrneh r3, [r0] strneh r3, [r1] + LOADREGS(fd, sp!, {r4, r5, pc}) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/io-writesb.S linux.ac/arch/arm/lib/io-writesb.S --- linux.vanilla/arch/arm/lib/io-writesb.S Tue Dec 12 13:05:13 2000 +++ linux.ac/arch/arm/lib/io-writesb.S Sun Dec 31 14:56:20 2000 @@ -1,5 +1,5 @@ /* - * linux/arch/arm/lib/io-readsb.S + * linux/arch/arm/lib/io-writesb.S * * Copyright (C) 1995-2000 Russell King * @@ -13,7 +13,7 @@ .outsb_align: rsb ip, ip, #4 cmp ip, r2 - mov ip, r2 + movgt ip, r2 cmp ip, #2 ldrb r3, [r1], #1 strb r3, [r0] @@ -34,6 +34,7 @@ bmi .outsb_no_16 .outsb_16_lp: ldmia r1!, {r3 - r6} + strb r3, [r0] mov r3, r3, lsr #8 strb r3, [r0] @@ -65,6 +66,7 @@ strb r6, [r0] mov r6, r6, lsr #8 strb r6, [r0] + subs r2, r2, #16 bpl .outsb_16_lp @@ -74,7 +76,8 @@ .outsb_no_16: tst r2, #8 beq .outsb_no_8 - ldmia r1, {r3, r4} + ldmia r1!, {r3, r4} + strb r3, [r0] mov r3, r3, lsr #8 strb r3, [r0] @@ -92,7 +95,7 @@ strb r4, [r0] .outsb_no_8: tst r2, #4 - bne .outsb_no_4 + beq .outsb_no_4 ldr r3, [r1], #4 strb r3, [r0] @@ -105,6 +108,7 @@ .outsb_no_4: ands r2, r2, #3 LOADREGS(eqfd, sp!, {r4 - r6, pc}) + cmp r2, #2 ldrb r3, [r1], #1 strb r3, [r0] @@ -112,4 +116,5 @@ strgeb r3, [r0] ldrgtb r3, [r1] strgtb r3, [r0] + LOADREGS(fd, sp!, {r4 - r6, pc}) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/io-writesl.S linux.ac/arch/arm/lib/io-writesl.S --- linux.vanilla/arch/arm/lib/io-writesl.S Tue Dec 12 13:05:13 2000 +++ linux.ac/arch/arm/lib/io-writesl.S Sun Dec 31 14:56:20 2000 @@ -1,5 +1,5 @@ /* - * linux/arch/arm/lib/io-readsb.S + * linux/arch/arm/lib/io-writesl.S * * Copyright (C) 1995-2000 Russell King * diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/io-writesw-armv3.S linux.ac/arch/arm/lib/io-writesw-armv3.S --- linux.vanilla/arch/arm/lib/io-writesw-armv3.S Tue Dec 12 13:05:13 2000 +++ linux.ac/arch/arm/lib/io-writesw-armv3.S Sun Dec 31 14:56:20 2000 @@ -1,5 +1,5 @@ /* - * linux/arch/arm/lib/io-readsb.S + * linux/arch/arm/lib/io-writesw-armv3.S * * Copyright (C) 1995-2000 Russell King * @@ -39,6 +39,7 @@ subs r2, r2, #8 bmi .no_outsw_8 + .outsw_8_lp: ldmia r1!, {r3, r4, r5, r6} mov ip, r3, lsl #16 @@ -75,6 +76,7 @@ subs r2, r2, #8 bpl .outsw_8_lp + tst r2, #7 LOADREGS(eqfd, sp!, {r4, r5, r6, pc}) @@ -121,5 +123,3 @@ strne ip, [r0] LOADREGS(fd, sp!, {r4, r5, r6, pc}) - - diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/lib/io-writesw-armv4.S linux.ac/arch/arm/lib/io-writesw-armv4.S --- linux.vanilla/arch/arm/lib/io-writesw-armv4.S Tue Dec 12 13:05:13 2000 +++ linux.ac/arch/arm/lib/io-writesw-armv4.S Sun Dec 31 14:56:20 2000 @@ -1,5 +1,5 @@ /* - * linux/arch/arm/lib/io-readsb.S + * linux/arch/arm/lib/io-writesw-armv4.S * * Copyright (C) 1995-2000 Russell King * @@ -32,11 +32,11 @@ tst r1, #3 bne .outsw_align + stmfd sp!, {r4, r5, lr} + subs r2, r2, #8 bmi .no_outsw_8 - stmfd sp!, {r4, r5, lr} - .outsw_8_lp: ldmia r1!, {r3, r4, r5, ip} strh r3, [r0] @@ -54,26 +54,31 @@ subs r2, r2, #8 bpl .outsw_8_lp - ldmfd sp!, {r4, r5, lr} + tst r2, #7 - RETINSTR(moveq, pc, lr) + LOADREGS(eqfd, sp!, {r4, r5, pc}) .no_outsw_8: tst r2, #4 - ldmneia r1!, {r3, ip} - strneh r3, [r0] - movne r3, r3, lsr #16 - strneh r3, [r0] - strneh ip, [r0] - movne ip, ip, lsr #16 - strneh ip, [r0] - tst r2, #2 - ldrne r3, [r1], #4 - strneh r3, [r0] - movne r3, r3, lsr #16 - strneh r3, [r0] - tst r2, #1 + beq .no_outsw_4 + + ldmia r1!, {r3, ip} + strh r3, [r0] + mov r3, r3, lsr #16 + strh r3, [r0] + strh ip, [r0] + mov ip, ip, lsr #16 + strh ip, [r0] + +.no_outsw_4: tst r2, #2 + beq .no_outsw_2 + + ldr r3, [r1], #4 + strh r3, [r0] + mov r3, r3, lsr #16 + strh r3, [r0] + +.no_outsw_2: tst r2, #1 ldrneh r3, [r1] strneh r3, [r0] - RETINSTR(mov, pc, lr) - + LOADREGS(fd, sp!, {r4, r5, pc}) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mach-sa1100/Makefile linux.ac/arch/arm/mach-sa1100/Makefile --- linux.vanilla/arch/arm/mach-sa1100/Makefile Sat Oct 28 16:15:43 2000 +++ linux.ac/arch/arm/mach-sa1100/Makefile Sun Dec 31 14:57:34 2000 @@ -20,15 +20,4 @@ obj-$(CONFIG_LEDS) += leds.o -# Files that are both resident and modular; remove from modular. - -obj-m := $(filter-out $(obj-y), $(obj-m)) - -# Translate to Rules.make lists. - -O_OBJS := $(filter-out $(export-objs), $(obj-y)) -OX_OBJS := $(filter $(export-objs), $(obj-y)) -M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) -MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) - include $(TOPDIR)/Rules.make diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mach-shark/Makefile linux.ac/arch/arm/mach-shark/Makefile --- linux.vanilla/arch/arm/mach-shark/Makefile Sat Oct 28 16:15:43 2000 +++ linux.ac/arch/arm/mach-shark/Makefile Sun Dec 31 14:57:34 2000 @@ -5,6 +5,8 @@ # removes any old dependencies. DON'T put your own dependencies here # unless it's something special (ie not a .c file). +USE_STANDARD_AS_RULE := true + O_TARGET := shark.o # Object file lists. @@ -17,16 +19,5 @@ export-objs := #obj-$(CONFIG_LEDS) += leds.o - -# Files that are both resident and modular; remove from modular. - -obj-m := $(filter-out $(obj-y), $(obj-m)) - -# Translate to Rules.make lists. - -O_OBJS := $(filter-out $(export-objs), $(obj-y)) -OX_OBJS := $(filter $(export-objs), $(obj-y)) -M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) -MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) include $(TOPDIR)/Rules.make diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/Makefile linux.ac/arch/arm/mm/Makefile --- linux.vanilla/arch/arm/mm/Makefile Sat Oct 28 16:15:43 2000 +++ linux.ac/arch/arm/mm/Makefile Sun Dec 31 14:57:34 2000 @@ -9,12 +9,11 @@ USE_STANDARD_AS_RULE := true -EXTRA_AFLAGS := -traditional O_TARGET := mm.o # Object file lists. -obj-y := extable.o fault-$(PROCESSOR).o init.o \ +obj-y := extable.o fault-common.o fault-$(PROCESSOR).o init.o \ mm-$(PROCESSOR).o small_page.o obj-m := obj-n := @@ -22,10 +21,10 @@ export-objs := proc-syms.o p-$(CONFIG_CPU_26) += proc-arm2,3.o -p-$(CONFIG_CPU_ARM6) += proc-arm6,7.o -p-$(CONFIG_CPU_ARM7) += proc-arm6,7.o -p-$(CONFIG_CPU_ARM720) += proc-arm720.o -p-$(CONFIG_CPU_ARM920) += proc-arm920.o +p-$(CONFIG_CPU_ARM610) += proc-arm6,7.o +p-$(CONFIG_CPU_ARM710) += proc-arm6,7.o +p-$(CONFIG_CPU_ARM720T) += proc-arm720.o +p-$(CONFIG_CPU_ARM920T) += proc-arm920.o p-$(CONFIG_CPU_ARM10) += proc-arm10.o p-$(CONFIG_CPU_SA110) += proc-sa110.o p-$(CONFIG_CPU_SA1100) += proc-sa110.o @@ -37,29 +36,16 @@ # Integrator follows "new style" # Soon, others will do too, and we can get rid of this -MMMACH := mm-$(MACHINE).o +MMMACH := mm-$(MACHINE).c ifeq ($(MMMACH),$(wildcard $(MMMACH))) -obj-$(CONFIG_CPU_32) += $(MMMACH) +obj-$(CONFIG_CPU_32) += $(MMMACH:.c=.o) endif obj-y += $(sort $(p-y)) -# Files that are both resident and modular; remove from modular. - -obj-m := $(filter-out $(obj-y), $(obj-m)) - -# Translate to Rules.make lists. - -O_OBJS := $(filter-out $(export-objs), $(obj-y)) -OX_OBJS := $(filter $(export-objs), $(obj-y)) -M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) -MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) - include $(TOPDIR)/Rules.make # Special dependencies -fault-armv.o: fault-common.c -fault-armo.o: fault-common.c proc-arm2,3.o: ../lib/constants.h proc-arm6,7.o: ../lib/constants.h proc-arm720.o: ../lib/constants.h diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/fault-armo.c linux.ac/arch/arm/mm/fault-armo.c --- linux.vanilla/arch/arm/mm/fault-armo.c Sat Oct 28 16:15:43 2000 +++ linux.ac/arch/arm/mm/fault-armo.c Sun Dec 31 14:54:31 2000 @@ -23,14 +23,20 @@ #include #include -#define FAULT_CODE_FORCECOW 0x80 +#define FAULT_CODE_LDRSTRPOST 0x80 +#define FAULT_CODE_LDRSTRPRE 0x40 +#define FAULT_CODE_LDRSTRREG 0x20 +#define FAULT_CODE_LDMSTM 0x10 +#define FAULT_CODE_LDCSTC 0x08 #define FAULT_CODE_PREFETCH 0x04 #define FAULT_CODE_WRITE 0x02 +#define FAULT_CODE_FORCECOW 0x01 #define DO_COW(m) ((m) & (FAULT_CODE_WRITE|FAULT_CODE_FORCECOW)) #define READ_FAULT(m) (!((m) & FAULT_CODE_WRITE)) -#include "fault-common.c" +extern int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs); +extern void show_pte(struct mm_struct *mm, unsigned long addr); /* * Handle a data abort. Note that we have to handle a range of addresses diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/fault-armv.c linux.ac/arch/arm/mm/fault-armv.c --- linux.vanilla/arch/arm/mm/fault-armv.c Sat Oct 28 16:15:43 2000 +++ linux.ac/arch/arm/mm/fault-armv.c Sun Dec 31 14:54:31 2000 @@ -27,27 +27,9 @@ #include #include -#define FAULT_CODE_READ 0x02 - -#define DO_COW(m) (!((m) & FAULT_CODE_READ)) -#define READ_FAULT(m) ((m) & FAULT_CODE_READ) - extern void die_if_kernel(const char *str, struct pt_regs *regs, int err); - -#include "fault-common.c" - -#ifdef DEBUG -static int sp_valid(unsigned long *sp) -{ - unsigned long addr = (unsigned long) sp; - - if (addr >= 0xb0000000 && addr < 0xd0000000) - return 1; - if (addr >= 0x03ff0000 && addr < 0x04000000) - return 1; - return 0; -} -#endif +extern void show_pte(struct mm_struct *mm, unsigned long addr); +extern int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs); #ifdef CONFIG_ALIGNMENT_TRAP /* @@ -178,6 +160,15 @@ eaddr -= offset.un; } + /* + * This is a "hint" - we already have eaddr worked out by the + * processor for us. + */ + if (addr != eaddr) + printk(KERN_ERR "LDRHSTRH: PC = %08lx, instr = %08x, " + "addr = %08lx, eaddr = %08lx\n", + instruction_pointer(regs), instr, addr, eaddr); + if (LDST_L_BIT(instr)) regs->uregs[rd] = get_unaligned((unsigned short *)eaddr); else @@ -253,8 +244,15 @@ } } -if (addr != eaddr) -printk("PC = %08lx, instr = %08x, addr = %08lx, eaddr = %08lx\n", instruction_pointer(regs), instr, addr, eaddr); + /* + * This is a "hint" - we already have eaddr worked out by the + * processor for us. + */ + if (addr != eaddr) + printk(KERN_ERR "LDRSTR: PC = %08lx, instr = %08x, " + "addr = %08lx, eaddr = %08lx\n", + instruction_pointer(regs), instr, addr, eaddr); + if (LDST_L_BIT(instr)) { regs->uregs[rd] = get_unaligned((unsigned long *)eaddr); if (rd == 15) @@ -284,6 +282,15 @@ if (!LDST_U_BIT(instr)) eaddr -= nr_regs; + /* + * This is a "hint" - we already have eaddr worked out by the + * processor for us. + */ + if (addr != eaddr) + printk(KERN_ERR "LDMSTM: PC = %08lx, instr = %08x, " + "addr = %08lx, eaddr = %08lx\n", + instruction_pointer(regs), instr, addr, eaddr); + if ((LDST_U_BIT(instr) == 0 && LDST_P_BIT(instr) == 0) || (LDST_U_BIT(instr) && LDST_P_BIT(instr))) eaddr += 4; @@ -322,39 +329,39 @@ #endif -#ifdef CONFIG_DEBUG_USER - +/* + * Some section permission faults need to be handled gracefully, for + * instance, when they happen due to a __{get,put}_user during an oops). + * In this case, we should return an error to the __{get,put}_user caller + * instead of causing another oops. We should also fixup this fault as + * the user could pass a pointer to a section to the kernel. + */ static int do_sect_fault(unsigned long addr, int error_code, struct pt_regs *regs) { + unsigned long fixup; + if (user_mode(regs)) { +#ifdef CONFIG_DEBUG_USER printk("%s: permission fault on section, " "address=0x%08lx, code %d\n", current->comm, addr, error_code); +#endif + goto fail; + } + + fixup = search_exception_table(instruction_pointer(regs)); + if (fixup != 0) { #ifdef DEBUG - { - unsigned int i, j; - unsigned long *sp; - - sp = (unsigned long *) (regs->ARM_sp - 128); - for (j = 0; j < 20 && sp_valid(sp); j++) { - printk("%p: ", sp); - for (i = 0; i < 8 && sp_valid(sp); i += 1, sp++) - printk("%08lx ", *sp); - printk("\n"); - } - show_regs(regs); - c_backtrace(regs->ARM_fp, regs->ARM_cpsr); - } + printk(KERN_DEBUG "%s: Exception at [<%lx>] addr=%lx (fixup: %lx)\n", + tsk->comm, regs->ARM_pc, addr, fixup); #endif + regs->ARM_pc = fixup; + return 0; } +fail: return 1; /* not fixed up */ } -#else - -#define do_sect_fault NULL - -#endif static const struct fsr_info { int (*fn)(unsigned long addr, int error_code, struct pt_regs *regs); @@ -382,18 +389,19 @@ /* * Currently dropped down to debug level */ -#define BUG_PROC_MSG \ - KERN_DEBUG "Weird data abort (%08X).\n" \ - KERN_DEBUG "Please see http://www.arm.linux.org.uk/state.html for " \ - "more information\n" - asmlinkage void do_DataAbort(unsigned long addr, int error_code, struct pt_regs *regs, int fsr) { const struct fsr_info *inf = fsr_info + (fsr & 15); +#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100) if (addr == regs->ARM_pc) - goto weirdness; + goto sa1_weirdness; +#endif +#if defined(CONFIG_CPU_ARM720T) && defined(CONFIG_ALIGNMENT_TRAP) + if (addr & 3 && (fsr & 13) != 1) + goto arm720_weirdness; +#endif if (!inf->fn) goto bad; @@ -409,26 +417,51 @@ die_if_kernel("Oops", regs, 0); return; -weirdness: +#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100) +sa1_weirdness: if (user_mode(regs)) { static int first = 1; if (first) - /* - * I want statistical information on this problem, - * but we don't want to hastle the users too much. - */ - printk(BUG_PROC_MSG, fsr); + printk(KERN_DEBUG "Weird data abort detected\n"); first = 0; return; } if (!inf->fn || inf->fn(addr, error_code, regs)) goto bad; + return; +#endif +#if defined(CONFIG_CPU_ARM720T) && defined(CONFIG_ALIGNMENT_TRAP) +arm720_weirdness: + if (!user_mode(regs)) { + unsigned long instr; + + instr = *(unsigned long *)instruction_pointer(regs); + + if ((instr & 0x04400000) != 0x04400000) { + static int first = 1; + if (first) + printk("Mis-reported alignment fault at " + "0x%08lx, fsr 0x%02x, code 0x%02x, " + "PC = 0x%08lx, instr = 0x%08lx\n", + addr, fsr, error_code, regs->ARM_pc, + instr); + first = 0; + cpu_tlb_invalidate_all(); + cpu_cache_clean_invalidate_all(); + return; + } + } + + if (!inf->fn || inf->fn(addr, error_code, regs)) + goto bad; + return; +#endif } asmlinkage int do_PrefetchAbort(unsigned long addr, struct pt_regs *regs) { - do_page_fault(addr, FAULT_CODE_READ, regs); + do_page_fault(addr, 0, regs); return 1; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/fault-common.c linux.ac/arch/arm/mm/fault-common.c --- linux.vanilla/arch/arm/mm/fault-common.c Tue Dec 12 13:05:13 2000 +++ linux.ac/arch/arm/mm/fault-common.c Sun Dec 31 14:54:31 2000 @@ -9,8 +9,41 @@ * published by the Free Software Foundation. */ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_CPU_26 +#define FAULT_CODE_WRITE 0x02 +#define FAULT_CODE_FORCECOW 0x01 +#define DO_COW(m) ((m) & (FAULT_CODE_WRITE|FAULT_CODE_FORCECOW)) +#define READ_FAULT(m) (!((m) & FAULT_CODE_WRITE)) +#else +/* + * On 32-bit processors, we define "mode" to be zero when reading, + * non-zero when writing. This now ties up nicely with the polarity + * of the 26-bit machines, and also means that we avoid the horrible + * gcc code for "int val = !other_val;". + */ +#define DO_COW(m) (m) +#define READ_FAULT(m) (!(m)) +#endif -extern void die(const char *msg, struct pt_regs *regs, int err); +NORET_TYPE void die(const char *msg, struct pt_regs *regs, int err) ATTRIB_NORET; /* * This is useful to dump out the page tables associated with @@ -60,7 +93,9 @@ printk("\n"); } -static int __do_page_fault(struct mm_struct *mm, unsigned long addr, int mode, struct task_struct *tsk) +static int +__do_page_fault(struct mm_struct *mm, unsigned long addr, int mode, + struct task_struct *tsk) { struct vm_area_struct *vma; int fault, mask; @@ -159,7 +194,7 @@ return -2; } -static int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs) +int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs) { struct task_struct *tsk; struct mm_struct *mm; @@ -278,8 +313,10 @@ * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice. */ - printk(KERN_ALERT "Unable to handle kernel %s at virtual address %08lx\n", - (addr < PAGE_SIZE) ? "NULL pointer dereference" : "paging request", addr); + printk(KERN_ALERT + "Unable to handle kernel %s at virtual address %08lx\n", + (addr < PAGE_SIZE) ? "NULL pointer dereference" : + "paging request", addr); show_pte(mm, addr); die("Oops", regs, mode); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/mm-armv.c linux.ac/arch/arm/mm/mm-armv.c --- linux.vanilla/arch/arm/mm/mm-armv.c Tue Dec 12 13:05:13 2000 +++ linux.ac/arch/arm/mm/mm-armv.c Sun Dec 31 14:59:49 2000 @@ -275,7 +275,7 @@ off = md->physical - virt; length = md->length; - while ((virt & 1048575 || (virt + off) & 1048575) && length >= PAGE_SIZE) { + while ((virt & 0xfffff || (virt + off) & 0xfffff) && length >= PAGE_SIZE) { alloc_init_page(virt, virt + off, md->domain, prot_pte); virt += PAGE_SIZE; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/proc-arm6,7.S linux.ac/arch/arm/mm/proc-arm6,7.S --- linux.vanilla/arch/arm/mm/proc-arm6,7.S Sat Oct 28 16:15:43 2000 +++ linux.ac/arch/arm/mm/proc-arm6,7.S Sun Dec 31 14:54:31 2000 @@ -7,10 +7,8 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * - * MMU functions for ARM6 - * * These are the low level assembler for performing cache and TLB - * functions on the ARM6 & ARM7. + * functions on the ARM610 & ARM710. */ #include #include @@ -105,9 +103,9 @@ ENTRY(cpu_arm6_data_abort) ldr r4, [r0] @ read instruction causing problem - mov r1, r4, lsr #19 @ r1 b1 = L + tst r4, r4, lsr #21 @ C = bit 20 + sbc r1, r1, r1 @ r1 = C - 1 and r2, r4, #14 << 24 - and r1, r1, #2 @ check read/write bit teq r2, #8 << 24 @ was it ldm/stm bne Ldata_simple @@ -138,9 +136,9 @@ ENTRY(cpu_arm7_data_abort) ldr r4, [r0] @ read instruction causing problem - mov r1, r4, lsr #19 @ r1 b1 = L + tst r4, r4, lsr #21 @ C = bit 20 + sbc r1, r1, r1 @ r1 = C - 1 and r2, r4, #15 << 24 - and r1, r1, #2 @ check read/write bit add pc, pc, r2, lsr #22 @ Now branch to the relevent processing routine movs pc, lr diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/proc-arm720.S linux.ac/arch/arm/mm/proc-arm720.S --- linux.vanilla/arch/arm/mm/proc-arm720.S Tue Dec 12 13:05:13 2000 +++ linux.ac/arch/arm/mm/proc-arm720.S Sun Dec 31 14:54:31 2000 @@ -144,9 +144,9 @@ ENTRY(cpu_arm720_data_abort) ldr r4, [r0] @ read instruction causing problem - mov r1, r4, lsr #19 @ r1 b1 = L + tst r4, r4, lsr #21 @ C = bit 20 + sbc r1, r1, r1 @ r1 = C - 1 and r2, r4, #15 << 24 - and r1, r1, #2 @ check read/write bit add pc, pc, r2, lsr #22 @ Now branch to the relevent processing routine movs pc, lr @@ -283,23 +283,11 @@ ldmfd sp!, {pc} /* - * Function: arm720_proc_do_idle (void) - * - * Params : r0 = call type: - * 0 = slow idle - * 1 = fast idle - * 2 = switch to slow processor clock - * 3 = switch to fast processor clock - * + * Function: arm720_proc_do_idle(void) + * Params : r0 = unused * Purpose : put the processer in proper idle mode */ ENTRY(cpu_arm720_do_idle) -#if 0 /* FIXME: is this part of the processor? */ - ldr r2, =IO_BASE @ Virt addr of IO - add r2, r2, #0x00050000 @ Start of PMU regs - mov r1, #0x01 @ Idle mode - str r1, [r2, #4] -#endif mov pc, lr /* diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/proc-arm920.S linux.ac/arch/arm/mm/proc-arm920.S --- linux.vanilla/arch/arm/mm/proc-arm920.S Sat Oct 28 16:15:44 2000 +++ linux.ac/arch/arm/mm/proc-arm920.S Sun Dec 31 14:54:31 2000 @@ -68,9 +68,9 @@ ENTRY(cpu_arm920_data_abort) ldr r1, [r0] @ read aborted instruction mrc p15, 0, r0, c6, c0, 0 @ get FAR - mov r1, r1, lsr #19 @ b1 = L + tst r1, r1, lsr #21 @ C = bit 20 mrc p15, 0, r3, c5, c0, 0 @ get FSR - and r1, r1, #2 + sbc r1, r1, r1 @ r1 = C - 1 and r3, r3, #255 mov pc, lr @@ -330,7 +330,7 @@ mov r0, #0 mcr p15, 0, r0, c7, c10, 4 @ drain WB ENTRY(cpu_arm920_icache_invalidate_page) - /* why no invalidate I cache --rmk */ + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache mov pc, lr diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/mm/proc-sa110.S linux.ac/arch/arm/mm/proc-sa110.S --- linux.vanilla/arch/arm/mm/proc-sa110.S Sat Oct 28 16:15:44 2000 +++ linux.ac/arch/arm/mm/proc-sa110.S Sun Dec 31 14:54:31 2000 @@ -83,9 +83,9 @@ ENTRY(cpu_sa1100_data_abort) ldr r1, [r0] @ read aborted instruction mrc p15, 0, r0, c6, c0, 0 @ get FAR - mov r1, r1, lsr #19 @ b1 = L + tst r1, r1, lsr #21 @ C = bit 20 mrc p15, 0, r3, c5, c0, 0 @ get FSR - and r1, r1, #2 + sbc r1, r1, r1 @ r1 = C - 1 and r3, r3, #255 mov pc, lr diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/nwfpe/Makefile linux.ac/arch/arm/nwfpe/Makefile --- linux.vanilla/arch/arm/nwfpe/Makefile Sun Sep 17 12:22:44 2000 +++ linux.ac/arch/arm/nwfpe/Makefile Sun Dec 31 14:57:34 2000 @@ -6,27 +6,27 @@ USE_STANDARD_AS_RULE := true -NWFPE_OBJS := fpa11.o fpa11_cpdo.o fpa11_cpdt.o fpa11_cprt.o \ - fpmodule.o fpopcode.o softfloat.o \ - single_cpdo.o double_cpdo.o extended_cpdo.o +O_TARGET := math-emu.o -ifeq ($(CONFIG_CPU_26),y) -NWFPE_OBJS += entry26.o -else -NWFPE_OBJS += entry.o -endif +obj-y := +obj-m := +obj-n := + +list-multi := nwfpe.o -ifeq ($(CONFIG_NWFPE),y) -O_TARGET := math-emu.o -O_OBJS = $(NWFPE_OBJS) +obj-$(CONFIG_NWFPE) += nwfpe.o + +nwfpe-objs := fpa11.o fpa11_cpdo.o fpa11_cpdt.o fpa11_cprt.o \ + fpmodule.o fpopcode.o softfloat.o \ + single_cpdo.o double_cpdo.o extended_cpdo.o + +ifeq ($(CONFIG_CPU_26),y) +nwfpe-objs += entry26.o else - ifeq ($(CONFIG_NWFPE),m) - M_OBJS = nwfpe.o - MI_OBJS = $(NWFPE_OBJS) - endif +nwfpe-objs += entry.o endif include $(TOPDIR)/Rules.make -nwfpe.o: $(MI_OBJS) $(MIX_OBJS) - $(LD) $(LD_RFLAG) -r -o $@ $(MI_OBJS) $(MIX_OBJS) +nwfpe.o: $(nwfpe-objs) + $(LD) -r -o $@ $(nwfpe-objs) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/vmlinux-armo.lds.in linux.ac/arch/arm/vmlinux-armo.lds.in --- linux.vanilla/arch/arm/vmlinux-armo.lds.in Tue Dec 12 13:05:14 2000 +++ linux.ac/arch/arm/vmlinux-armo.lds.in Sun Dec 31 14:57:57 2000 @@ -47,6 +47,8 @@ *(.gnu.warning) *(.text.lock) /* out-of-line lock text */ *(.rodata) + *(.glue_7) + *(.glue_7t) *(.kstrtab) . = ALIGN(16); /* Exception table */ __start___ex_table = .; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/arm/vmlinux-armv.lds.in linux.ac/arch/arm/vmlinux-armv.lds.in --- linux.vanilla/arch/arm/vmlinux-armv.lds.in Tue Dec 12 13:05:14 2000 +++ linux.ac/arch/arm/vmlinux-armv.lds.in Sun Dec 31 14:57:57 2000 @@ -42,6 +42,8 @@ *(.gnu.warning) *(.text.lock) /* out-of-line lock text */ *(.rodata) + *(.glue_7) + *(.glue_7t) *(.kstrtab) . = ALIGN(16); __start___ex_table = .; /* Exception table */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/i386/config.in linux.ac/arch/i386/config.in --- linux.vanilla/arch/i386/config.in Sun Dec 31 19:41:41 2000 +++ linux.ac/arch/i386/config.in Sun Dec 31 22:29:20 2000 @@ -293,9 +293,11 @@ fi endmenu +source drivers/message/fusion/Config.in + source drivers/ieee1394/Config.in -source drivers/i2o/Config.in +source drivers/message/i2o/Config.in if [ "$CONFIG_NET" = "y" ]; then mainmenu_option next_comment diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/i386/kernel/Makefile linux.ac/arch/i386/kernel/Makefile --- linux.vanilla/arch/i386/kernel/Makefile Sun Dec 31 19:41:41 2000 +++ linux.ac/arch/i386/kernel/Makefile Sat Dec 30 01:04:51 2000 @@ -41,4 +41,9 @@ obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o obj-$(CONFIG_X86_VISWS_APIC) += visws_apic.o +O_OBJS := $(filter-out $(export-objs), $(obj-y)) +OX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) +MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) + include $(TOPDIR)/Rules.make diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ia64/config.in linux.ac/arch/ia64/config.in --- linux.vanilla/arch/ia64/config.in Mon Nov 20 15:11:56 2000 +++ linux.ac/arch/ia64/config.in Sun Dec 31 18:02:25 2000 @@ -119,7 +119,7 @@ source drivers/mtd/Config.in source drivers/pnp/Config.in source drivers/block/Config.in -source drivers/i2o/Config.in +source drivers/message/i2o/Config.in source drivers/md/Config.in mainmenu_option next_comment diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/mips/config.in linux.ac/arch/mips/config.in --- linux.vanilla/arch/mips/config.in Mon Nov 20 15:11:56 2000 +++ linux.ac/arch/mips/config.in Sun Dec 31 18:02:39 2000 @@ -233,7 +233,7 @@ if [ "$CONFIG_DECSTATION" != "y" -a \ "$CONFIG_SGI_IP22" != "y" ]; then - source drivers/i2o/Config.in + source drivers/message/i2o/Config.in fi if [ "$CONFIG_NET" = "y" ]; then diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/mips64/config.in linux.ac/arch/mips64/config.in --- linux.vanilla/arch/mips64/config.in Tue Dec 12 13:05:15 2000 +++ linux.ac/arch/mips64/config.in Sun Dec 31 18:02:48 2000 @@ -164,7 +164,7 @@ fi endmenu -source drivers/i2o/Config.in +source drivers/message/i2o/Config.in if [ "$CONFIG_NET" = "y" ]; then mainmenu_option next_comment diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/boot/vreset.c linux.ac/arch/ppc/boot/vreset.c --- linux.vanilla/arch/ppc/boot/vreset.c Thu May 21 22:24:05 1998 +++ linux.ac/arch/ppc/boot/vreset.c Fri Dec 22 16:33:12 2000 @@ -19,12 +19,16 @@ */ #include "iso_font.h" -#include extern char *vidmem; extern int lines, cols; -/* estimate for delay */ -unsigned long loops_per_sec = 50000000;; + +static void mdelay(int ms) +{ + for (; ms > 0; --ms) + udelay(1000); +} + /* * VGA Register */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/coffboot/coffmain.c linux.ac/arch/ppc/coffboot/coffmain.c --- linux.vanilla/arch/ppc/coffboot/coffmain.c Sat Jan 8 20:59:39 2000 +++ linux.ac/arch/ppc/coffboot/coffmain.c Mon Dec 18 20:41:38 2000 @@ -22,11 +22,18 @@ #define get_32be(x) (*(unsigned *)(x)) #define RAM_START 0xc0000000 -#define PROG_START RAM_START #define RAM_END (RAM_START + 0x800000) /* only 8M mapped with BATs */ +#define PROG_START RAM_START +#define PROG_SIZE 0x00400000 + +#define SCRATCH_SIZE (128 << 10) + char *avail_ram; -char *end_avail; +char *begin_avail, *end_avail; +char *avail_high; +unsigned int heap_use; +unsigned int heap_max; extern char _start[], _end[]; extern char image_data[]; @@ -34,6 +41,7 @@ extern char initrd_data[]; extern int initrd_len; +char heap[SCRATCH_SIZE]; boot(int a1, int a2, void *prom) { @@ -58,16 +66,18 @@ im = image_data; len = image_len; /* claim 3MB starting at 0 */ - claim(0, 3 << 20, 0); + claim(0, PROG_SIZE, 0); dst = (void *) RAM_START; if (im[0] == 0x1f && im[1] == 0x8b) { - /* claim 512kB for scratch space */ - avail_ram = claim(0, 512 << 10, 0x10) + RAM_START; - end_avail = avail_ram + (512 << 10); - printf("avail_ram = %x\n", avail_ram); + /* claim some memory for scratch space */ + begin_avail = avail_high = avail_ram = heap; + end_avail = heap + sizeof(heap); + printf("heap at 0x%x\n", avail_ram); printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len); - gunzip(dst, 3 << 20, im, &len); + gunzip(dst, PROG_SIZE, im, &len); printf("done %u bytes\n", len); + printf("%u bytes of heap consumed, max in use %u\n", + avail_high - begin_avail, heap_max); } else { memmove(dst, im, len); } @@ -78,9 +88,6 @@ sa = (unsigned long)PROG_START; printf("start address = 0x%x\n", sa); -#if 0 - pause(); -#endif (*(void (*)())sa)(a1, a2, prom); printf("returned?\n"); @@ -114,13 +121,33 @@ rec = (struct bi_record *)((unsigned long)rec + rec->size); } +struct memchunk { + unsigned int size; + struct memchunk *next; +}; + +static struct memchunk *freechunks; + void *zalloc(void *x, unsigned items, unsigned size) { - void *p = avail_ram; + void *p; + struct memchunk **mpp, *mp; size *= items; size = (size + 7) & -8; + heap_use += size; + if (heap_use > heap_max) + heap_max = heap_use; + for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) { + if (mp->size == size) { + *mpp = mp->next; + return mp; + } + } + p = avail_ram; avail_ram += size; + if (avail_ram > avail_high) + avail_high = avail_ram; if (avail_ram > end_avail) { printf("oops... out of memory\n"); pause(); @@ -130,6 +157,17 @@ void zfree(void *x, void *addr, unsigned nb) { + struct memchunk *mp = addr; + + nb = (nb + 7) & -8; + heap_use -= nb; + if (avail_ram == addr + nb) { + avail_ram = addr; + return; + } + mp->size = nb; + mp->next = freechunks; + freechunks = mp; } #define HEAD_CRC 2 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/config.in linux.ac/arch/ppc/config.in --- linux.vanilla/arch/ppc/config.in Mon Nov 20 15:11:56 2000 +++ linux.ac/arch/ppc/config.in Mon Dec 18 20:41:38 2000 @@ -35,6 +35,10 @@ define_bool CONFIG_PPC64BRIDGE y define_bool CONFIG_ALL_PPC y fi + +if [ "$CONFIG_PPC64BRIDGE" != "y" ]; then + bool 'Workarounds for PPC601 bugs' CONFIG_PPC601_SYNC_FIX +fi if [ "$CONFIG_8260" = "y" ]; then define_bool CONFIG_6xx y @@ -151,11 +155,13 @@ tristate 'Support for /dev/rtc' CONFIG_PPC_RTC bool 'Support for Open Firmware device tree in /proc' CONFIG_PROC_DEVICETREE + bool 'Support for RTAS (RunTime Abstraction Services) in /proc' CONFIG_PPC_RTAS bool 'Support for early boot text console (BootX only)' CONFIG_BOOTX_TEXT bool 'Support for Motorola Hot Swap' CONFIG_MOTOROLA_HOTSWAP fi if [ "$CONFIG_PREP" = "y" -o "$CONFIG_ALL_PPC" = "y" ]; then + bool 'Support for PReP Residual Data' CONFIG_PREP_RESIDUAL bool 'PReP bootloader kernel arguments' CONFIG_CMDLINE_BOOL if [ "$CONFIG_CMDLINE_BOOL" = "y" ] ; then string 'Initial kernel command string' CONFIG_CMDLINE "console=ttyS0,9600 console=tty0 root=/dev/sda2" diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/configs/common_defconfig linux.ac/arch/ppc/configs/common_defconfig --- linux.vanilla/arch/ppc/configs/common_defconfig Mon Nov 20 15:11:56 2000 +++ linux.ac/arch/ppc/configs/common_defconfig Mon Dec 18 20:41:44 2000 @@ -12,7 +12,7 @@ # Loadable module support # CONFIG_MODULES=y -CONFIG_MODVERSIONS=y +# CONFIG_MODVERSIONS is not set CONFIG_KMOD=y # @@ -38,7 +38,9 @@ # CONFIG_HIGHMEM is not set # CONFIG_MOL is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set CONFIG_PCI=y CONFIG_NET=y CONFIG_SYSCTL=y @@ -48,7 +50,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y CONFIG_BINFMT_MISC=m -CONFIG_PCI_NAMES=y +# CONFIG_PCI_NAMES is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -58,11 +60,13 @@ # CONFIG_PARPORT is not set CONFIG_VGA_CONSOLE=y CONFIG_FB=y -CONFIG_FB_COMPAT_XPMAC=y +# CONFIG_FB_COMPAT_XPMAC is not set CONFIG_PPC_RTC=y CONFIG_PROC_DEVICETREE=y -CONFIG_BOOTX_TEXT=y +CONFIG_PPC_RTAS=y +# CONFIG_BOOTX_TEXT is not set # CONFIG_MOTOROLA_HOTSWAP is not set +# CONFIG_PREP_RESIDUAL is not set # CONFIG_CMDLINE_BOOL is not set # @@ -74,14 +78,11 @@ # Plug and Play configuration # # CONFIG_PNP is not set -# CONFIG_ISAPNP is not set # # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set @@ -95,13 +96,6 @@ # Multi-device support (RAID and LVM) # # CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_LVM is not set -# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -111,7 +105,8 @@ CONFIG_NETLINK=y # CONFIG_RTNETLINK is not set # CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y @@ -123,6 +118,34 @@ # CONFIG_IP_MROUTE is not set # CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set @@ -166,15 +189,7 @@ CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set # CONFIG_BLK_DEV_IDEDISK_VENDOR is not set -# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set -# CONFIG_BLK_DEV_IDEDISK_IBM is not set -# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set -# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set -# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set -# CONFIG_BLK_DEV_IDEDISK_WD is not set # CONFIG_BLK_DEV_COMMERIAL is not set -# CONFIG_BLK_DEV_TIVO is not set -# CONFIG_BLK_DEV_IDECS is not set CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDETAPE is not set CONFIG_BLK_DEV_IDEFLOPPY=y @@ -184,8 +199,6 @@ # IDE chipset support/bugfixes # # CONFIG_BLK_DEV_CMD640 is not set -# CONFIG_BLK_DEV_CMD640_ENHANCED is not set -# CONFIG_BLK_DEV_ISAPNP is not set # CONFIG_BLK_DEV_RZ1000 is not set CONFIG_BLK_DEV_IDEPCI=y CONFIG_IDEPCI_SHARE_IRQ=y @@ -194,24 +207,17 @@ CONFIG_IDEDMA_PCI_AUTO=y CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_PCI_WIP is not set -# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set # CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_AEC62XX_TUNING is not set # CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_WDC_ALI15X3 is not set # CONFIG_BLK_DEV_AMD7409 is not set -# CONFIG_AMD7409_OVERRIDE is not set CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_CY82C693 is not set # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_HPT34X_AUTODMA is not set # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_PDC202XX is not set -# CONFIG_PDC202XX_BURST is not set -# CONFIG_BLK_DEV_OSB4 is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set @@ -347,37 +353,31 @@ # CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set # CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set CONFIG_NET_PCI=y CONFIG_PCNET32=y # CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_AC3200 is not set # CONFIG_APRICOT is not set -# CONFIG_CS89x0 is not set -CONFIG_DE4X5=y # CONFIG_TULIP is not set +CONFIG_DE4X5=y # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set -# CONFIG_LNE390 is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set -# CONFIG_NE3210 is not set -# CONFIG_ES3210 is not set -# CONFIG_RTL8129 is not set # CONFIG_8139TOO is not set +# CONFIG_RTL8129 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set # CONFIG_WINBOND_840 is not set +# CONFIG_HAPPYMEAL is not set # CONFIG_NET_POCKET is not set # @@ -458,9 +458,9 @@ # CONFIG_FB_S3TRIO is not set # CONFIG_FB_VGA16 is not set CONFIG_FB_MATROX=y -CONFIG_FB_MATROX_MILLENIUM=y +# CONFIG_FB_MATROX_MILLENIUM is not set CONFIG_FB_MATROX_MYSTIQUE=y -CONFIG_FB_MATROX_G100=y +# CONFIG_FB_MATROX_G100 is not set # CONFIG_FB_MATROX_MULTIHEAD is not set CONFIG_FB_ATY=y CONFIG_FB_ATY128=y @@ -498,11 +498,10 @@ # CONFIG_ADB_CUDA=y CONFIG_ADB_PMU=y -CONFIG_PMAC_PBOOK=y -CONFIG_PMAC_BACKLIGHT=y -CONFIG_MAC_FLOPPY=y -CONFIG_MAC_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set +# CONFIG_PMAC_PBOOK is not set +# CONFIG_PMAC_BACKLIGHT is not set +# CONFIG_MAC_FLOPPY is not set +CONFIG_MAC_SERIAL=m CONFIG_ADB=y CONFIG_ADB_MACIO=y CONFIG_INPUT_ADBHID=y @@ -575,26 +574,24 @@ # File systems # # CONFIG_QUOTA is not set -CONFIG_AUTOFS_FS=y -CONFIG_AUTOFS4_FS=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set # CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m # CONFIG_UMSDOS_FS is not set -CONFIG_VFAT_FS=y +CONFIG_VFAT_FS=m # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set +CONFIG_JFFS_FS_VERBOSE=0 # CONFIG_CRAMFS is not set # CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_MINIX_FS is not set # CONFIG_NTFS_FS is not set -# CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y CONFIG_DEVFS_FS=y @@ -602,39 +599,22 @@ # CONFIG_DEVFS_DEBUG is not set CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set -# CONFIG_SYSV_FS_WRITE is not set # CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # # CONFIG_CODA_FS is not set -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_ROOT_NFS is not set -CONFIG_NFSD=y -# CONFIG_NFSD_V3 is not set -CONFIG_SUNRPC=y -CONFIG_LOCKD=y +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SUNRPC is not set +# CONFIG_LOCKD is not set # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set # # Partition Types @@ -695,64 +675,18 @@ # # Sound # -CONFIG_SOUND=y -CONFIG_DMASOUND_AWACS=y -CONFIG_DMASOUND=y -# CONFIG_SOUND_CMPCI is not set -# CONFIG_SOUND_EMU10K1 is not set -# CONFIG_SOUND_FUSION is not set -# CONFIG_SOUND_CS4281 is not set -# CONFIG_SOUND_ES1370 is not set -# CONFIG_SOUND_ES1371 is not set -# CONFIG_SOUND_ESSSOLO1 is not set -# CONFIG_SOUND_MAESTRO is not set -# CONFIG_SOUND_SONICVIBES is not set -# CONFIG_SOUND_TRIDENT is not set -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set -# CONFIG_SOUND_VIA82CXXX is not set -CONFIG_SOUND_OSS=y -# CONFIG_SOUND_TRACEINIT is not set -# CONFIG_SOUND_DMAP is not set -# CONFIG_SOUND_AD1816 is not set -# CONFIG_SOUND_SGALAXY is not set -# CONFIG_SOUND_ADLIB is not set -# CONFIG_SOUND_ACI_MIXER is not set -CONFIG_SOUND_CS4232=m -# CONFIG_SOUND_SSCAPE is not set -# CONFIG_SOUND_GUS is not set -# CONFIG_SOUND_ICH is not set -# CONFIG_SOUND_VMIDI is not set -# CONFIG_SOUND_TRIX is not set -# CONFIG_SOUND_MSS is not set -# CONFIG_SOUND_MPU401 is not set -# CONFIG_SOUND_NM256 is not set -# CONFIG_SOUND_MAD16 is not set -# CONFIG_SOUND_PAS is not set -# CONFIG_PAS_JOYSTICK is not set -# CONFIG_SOUND_PSS is not set -# CONFIG_SOUND_SB is not set -# CONFIG_SOUND_AWE32_SYNTH is not set -# CONFIG_SOUND_WAVEFRONT is not set -# CONFIG_SOUND_MAUI is not set -# CONFIG_SOUND_YM3812 is not set -# CONFIG_SOUND_OPL3SA1 is not set -# CONFIG_SOUND_OPL3SA2 is not set -# CONFIG_SOUND_YMPCI is not set -# CONFIG_SOUND_UART6850 is not set -# CONFIG_SOUND_AEDSP16 is not set -# CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND is not set # # USB support # CONFIG_USB=y -CONFIG_USB_DEBUG=y +# CONFIG_USB_DEBUG is not set # # Miscellaneous USB options # -CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICEFS is not set # CONFIG_USB_BANDWIDTH is not set # @@ -768,20 +702,15 @@ # CONFIG_USB_PRINTER is not set # CONFIG_USB_SCANNER is not set # CONFIG_USB_MICROTEK is not set -# CONFIG_USB_AUDIO is not set # CONFIG_USB_ACM is not set # CONFIG_USB_SERIAL is not set -# CONFIG_USB_IBMCAM is not set -# CONFIG_USB_OV511 is not set # CONFIG_USB_DC2XX is not set # CONFIG_USB_MDC800 is not set # CONFIG_USB_STORAGE is not set -# CONFIG_USB_USS720 is not set # CONFIG_USB_DABUSB is not set # CONFIG_USB_PLUSB is not set # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RIO500 is not set -# CONFIG_USB_DSBR is not set # CONFIG_USB_BLUETOOTH is not set # CONFIG_USB_NET1080 is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/configs/est8260_defconfig linux.ac/arch/ppc/configs/est8260_defconfig --- linux.vanilla/arch/ppc/configs/est8260_defconfig Mon Nov 20 15:11:56 2000 +++ linux.ac/arch/ppc/configs/est8260_defconfig Mon Dec 18 20:41:44 2000 @@ -63,6 +63,7 @@ # CONFIG_PROC_DEVICETREE is not set # CONFIG_BOOTX_TEXT is not set # CONFIG_MOTOROLA_HOTSWAP is not set +CONFIG_PREP_RESIDUAL=y # # Memory Technology Devices (MTD) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/defconfig linux.ac/arch/ppc/defconfig --- linux.vanilla/arch/ppc/defconfig Mon Nov 20 15:11:56 2000 +++ linux.ac/arch/ppc/defconfig Mon Dec 18 20:42:03 2000 @@ -12,7 +12,7 @@ # Loadable module support # CONFIG_MODULES=y -CONFIG_MODVERSIONS=y +# CONFIG_MODVERSIONS is not set CONFIG_KMOD=y # @@ -38,7 +38,9 @@ # CONFIG_HIGHMEM is not set # CONFIG_MOL is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set CONFIG_PCI=y CONFIG_NET=y CONFIG_SYSCTL=y @@ -48,7 +50,7 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y CONFIG_BINFMT_MISC=m -CONFIG_PCI_NAMES=y +# CONFIG_PCI_NAMES is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -58,11 +60,13 @@ # CONFIG_PARPORT is not set CONFIG_VGA_CONSOLE=y CONFIG_FB=y -CONFIG_FB_COMPAT_XPMAC=y +# CONFIG_FB_COMPAT_XPMAC is not set CONFIG_PPC_RTC=y CONFIG_PROC_DEVICETREE=y -CONFIG_BOOTX_TEXT=y +CONFIG_PPC_RTAS=y +# CONFIG_BOOTX_TEXT is not set # CONFIG_MOTOROLA_HOTSWAP is not set +# CONFIG_PREP_RESIDUAL is not set # CONFIG_CMDLINE_BOOL is not set # @@ -74,14 +78,11 @@ # Plug and Play configuration # # CONFIG_PNP is not set -# CONFIG_ISAPNP is not set # # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set @@ -95,13 +96,6 @@ # Multi-device support (RAID and LVM) # # CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_LVM is not set -# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -111,7 +105,8 @@ CONFIG_NETLINK=y # CONFIG_RTNETLINK is not set # CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y @@ -123,6 +118,34 @@ # CONFIG_IP_MROUTE is not set # CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set @@ -166,15 +189,7 @@ CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set # CONFIG_BLK_DEV_IDEDISK_VENDOR is not set -# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set -# CONFIG_BLK_DEV_IDEDISK_IBM is not set -# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set -# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set -# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set -# CONFIG_BLK_DEV_IDEDISK_WD is not set # CONFIG_BLK_DEV_COMMERIAL is not set -# CONFIG_BLK_DEV_TIVO is not set -# CONFIG_BLK_DEV_IDECS is not set CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDETAPE is not set CONFIG_BLK_DEV_IDEFLOPPY=y @@ -184,8 +199,6 @@ # IDE chipset support/bugfixes # # CONFIG_BLK_DEV_CMD640 is not set -# CONFIG_BLK_DEV_CMD640_ENHANCED is not set -# CONFIG_BLK_DEV_ISAPNP is not set # CONFIG_BLK_DEV_RZ1000 is not set CONFIG_BLK_DEV_IDEPCI=y CONFIG_IDEPCI_SHARE_IRQ=y @@ -194,24 +207,17 @@ CONFIG_IDEDMA_PCI_AUTO=y CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_PCI_WIP is not set -# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set # CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_AEC62XX_TUNING is not set # CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_WDC_ALI15X3 is not set # CONFIG_BLK_DEV_AMD7409 is not set -# CONFIG_AMD7409_OVERRIDE is not set CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_CY82C693 is not set # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_HPT34X_AUTODMA is not set # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_PDC202XX is not set -# CONFIG_PDC202XX_BURST is not set -# CONFIG_BLK_DEV_OSB4 is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set @@ -347,37 +353,31 @@ # CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set # CONFIG_DEPCA is not set # CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set CONFIG_NET_PCI=y CONFIG_PCNET32=y # CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_AC3200 is not set # CONFIG_APRICOT is not set -# CONFIG_CS89x0 is not set -CONFIG_DE4X5=y # CONFIG_TULIP is not set +CONFIG_DE4X5=y # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set -# CONFIG_LNE390 is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set -# CONFIG_NE3210 is not set -# CONFIG_ES3210 is not set -# CONFIG_RTL8129 is not set # CONFIG_8139TOO is not set +# CONFIG_RTL8129 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set # CONFIG_WINBOND_840 is not set +# CONFIG_HAPPYMEAL is not set # CONFIG_NET_POCKET is not set # @@ -458,9 +458,9 @@ # CONFIG_FB_S3TRIO is not set # CONFIG_FB_VGA16 is not set CONFIG_FB_MATROX=y -CONFIG_FB_MATROX_MILLENIUM=y +# CONFIG_FB_MATROX_MILLENIUM is not set CONFIG_FB_MATROX_MYSTIQUE=y -CONFIG_FB_MATROX_G100=y +# CONFIG_FB_MATROX_G100 is not set # CONFIG_FB_MATROX_MULTIHEAD is not set CONFIG_FB_ATY=y CONFIG_FB_ATY128=y @@ -498,11 +498,10 @@ # CONFIG_ADB_CUDA=y CONFIG_ADB_PMU=y -CONFIG_PMAC_PBOOK=y -CONFIG_PMAC_BACKLIGHT=y -CONFIG_MAC_FLOPPY=y -CONFIG_MAC_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set +# CONFIG_PMAC_PBOOK is not set +# CONFIG_PMAC_BACKLIGHT is not set +# CONFIG_MAC_FLOPPY is not set +CONFIG_MAC_SERIAL=m CONFIG_ADB=y CONFIG_ADB_MACIO=y CONFIG_INPUT_ADBHID=y @@ -575,26 +574,24 @@ # File systems # # CONFIG_QUOTA is not set -CONFIG_AUTOFS_FS=y -CONFIG_AUTOFS4_FS=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set # CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m # CONFIG_UMSDOS_FS is not set -CONFIG_VFAT_FS=y +CONFIG_VFAT_FS=m # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set +CONFIG_JFFS_FS_VERBOSE=0 # CONFIG_CRAMFS is not set # CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_MINIX_FS is not set # CONFIG_NTFS_FS is not set -# CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y CONFIG_DEVFS_FS=y @@ -602,39 +599,22 @@ # CONFIG_DEVFS_DEBUG is not set CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set -# CONFIG_SYSV_FS_WRITE is not set # CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # # CONFIG_CODA_FS is not set -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_ROOT_NFS is not set -CONFIG_NFSD=y -# CONFIG_NFSD_V3 is not set -CONFIG_SUNRPC=y -CONFIG_LOCKD=y +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SUNRPC is not set +# CONFIG_LOCKD is not set # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set # # Partition Types @@ -695,64 +675,18 @@ # # Sound # -CONFIG_SOUND=y -CONFIG_DMASOUND_AWACS=y -CONFIG_DMASOUND=y -# CONFIG_SOUND_CMPCI is not set -# CONFIG_SOUND_EMU10K1 is not set -# CONFIG_SOUND_FUSION is not set -# CONFIG_SOUND_CS4281 is not set -# CONFIG_SOUND_ES1370 is not set -# CONFIG_SOUND_ES1371 is not set -# CONFIG_SOUND_ESSSOLO1 is not set -# CONFIG_SOUND_MAESTRO is not set -# CONFIG_SOUND_SONICVIBES is not set -# CONFIG_SOUND_TRIDENT is not set -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set -# CONFIG_SOUND_VIA82CXXX is not set -CONFIG_SOUND_OSS=y -# CONFIG_SOUND_TRACEINIT is not set -# CONFIG_SOUND_DMAP is not set -# CONFIG_SOUND_AD1816 is not set -# CONFIG_SOUND_SGALAXY is not set -# CONFIG_SOUND_ADLIB is not set -# CONFIG_SOUND_ACI_MIXER is not set -CONFIG_SOUND_CS4232=m -# CONFIG_SOUND_SSCAPE is not set -# CONFIG_SOUND_GUS is not set -# CONFIG_SOUND_ICH is not set -# CONFIG_SOUND_VMIDI is not set -# CONFIG_SOUND_TRIX is not set -# CONFIG_SOUND_MSS is not set -# CONFIG_SOUND_MPU401 is not set -# CONFIG_SOUND_NM256 is not set -# CONFIG_SOUND_MAD16 is not set -# CONFIG_SOUND_PAS is not set -# CONFIG_PAS_JOYSTICK is not set -# CONFIG_SOUND_PSS is not set -# CONFIG_SOUND_SB is not set -# CONFIG_SOUND_AWE32_SYNTH is not set -# CONFIG_SOUND_WAVEFRONT is not set -# CONFIG_SOUND_MAUI is not set -# CONFIG_SOUND_YM3812 is not set -# CONFIG_SOUND_OPL3SA1 is not set -# CONFIG_SOUND_OPL3SA2 is not set -# CONFIG_SOUND_YMPCI is not set -# CONFIG_SOUND_UART6850 is not set -# CONFIG_SOUND_AEDSP16 is not set -# CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND is not set # # USB support # CONFIG_USB=y -CONFIG_USB_DEBUG=y +# CONFIG_USB_DEBUG is not set # # Miscellaneous USB options # -CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICEFS is not set # CONFIG_USB_BANDWIDTH is not set # @@ -768,20 +702,15 @@ # CONFIG_USB_PRINTER is not set # CONFIG_USB_SCANNER is not set # CONFIG_USB_MICROTEK is not set -# CONFIG_USB_AUDIO is not set # CONFIG_USB_ACM is not set # CONFIG_USB_SERIAL is not set -# CONFIG_USB_IBMCAM is not set -# CONFIG_USB_OV511 is not set # CONFIG_USB_DC2XX is not set # CONFIG_USB_MDC800 is not set # CONFIG_USB_STORAGE is not set -# CONFIG_USB_USS720 is not set # CONFIG_USB_DABUSB is not set # CONFIG_USB_PLUSB is not set # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RIO500 is not set -# CONFIG_USB_DSBR is not set # CONFIG_USB_BLUETOOTH is not set # CONFIG_USB_NET1080 is not set diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/apus_setup.c linux.ac/arch/ppc/kernel/apus_setup.c --- linux.vanilla/arch/ppc/kernel/apus_setup.c Tue Oct 31 20:26:00 2000 +++ linux.ac/arch/ppc/kernel/apus_setup.c Mon Dec 18 20:42:03 2000 @@ -647,25 +647,6 @@ return 0; } -int -apus_ide_check_region(ide_ioreg_t from, unsigned int extent) -{ - return 0; -} - -void -apus_ide_request_region(ide_ioreg_t from, - unsigned int extent, - const char *name) -{ -} - -void -apus_ide_release_region(ide_ioreg_t from, - unsigned int extent) -{ -} - void apus_ide_fix_driveid(struct hd_driveid *id) { @@ -1131,9 +1112,6 @@ ppc_ide_md.outsw = apus_ide_outsw; ppc_ide_md.default_irq = apus_ide_default_irq; ppc_ide_md.default_io_base = apus_ide_default_io_base; - ppc_ide_md.ide_check_region = apus_ide_check_region; - ppc_ide_md.ide_request_region = apus_ide_request_region; - ppc_ide_md.ide_release_region = apus_ide_release_region; ppc_ide_md.fix_driveid = apus_ide_fix_driveid; ppc_ide_md.ide_init_hwif = apus_ide_init_hwif_ports; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/chrp_pci.c linux.ac/arch/ppc/kernel/chrp_pci.c --- linux.vanilla/arch/ppc/kernel/chrp_pci.c Sat Oct 28 16:15:46 2000 +++ linux.ac/arch/ppc/kernel/chrp_pci.c Mon Dec 18 20:42:30 2000 @@ -8,8 +8,8 @@ #include #include #include -#include #include +#include #include #include @@ -19,16 +19,19 @@ #include #include #include +#include +#include "open_pic.h" #include "pci.h" + #ifdef CONFIG_POWER4 -static unsigned long pci_address_offset(int, unsigned int); +extern unsigned long pci_address_offset(int, unsigned int); #endif /* CONFIG_POWER4 */ /* LongTrail */ -#define pci_config_addr(bus, dev, offset) \ -(GG2_PCI_CONFIG_BASE | ((bus)<<16) | ((dev)<<8) | (offset)) +#define pci_config_addr(dev, offset) \ +(GG2_PCI_CONFIG_BASE | ((dev->bus->number)<<16) | ((dev->devfn)<<8) | (offset)) volatile struct Hydra *Hydra = NULL; @@ -37,205 +40,127 @@ * limit the bus number to 3 bits */ -int __chrp gg2_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) -{ - if (bus > 7) { - *val = 0xff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - *val = in_8((unsigned char *)pci_config_addr(bus, dev_fn, offset)); - return PCIBIOS_SUCCESSFUL; -} - -int __chrp gg2_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) -{ - if (bus > 7) { - *val = 0xffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - *val = in_le16((unsigned short *)pci_config_addr(bus, dev_fn, offset)); - return PCIBIOS_SUCCESSFUL; -} - +#define cfg_read(val, addr, type, op) *val = op((type)(addr)) +#define cfg_write(val, addr, type, op) op((type *)(addr), (val)) -int __chrp gg2_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) -{ - if (bus > 7) { - *val = 0xffffffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - *val = in_le32((unsigned int *)pci_config_addr(bus, dev_fn, offset)); - return PCIBIOS_SUCCESSFUL; -} - -int __chrp gg2_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) -{ - if (bus > 7) - return PCIBIOS_DEVICE_NOT_FOUND; - out_8((unsigned char *)pci_config_addr(bus, dev_fn, offset), val); - return PCIBIOS_SUCCESSFUL; -} - -int __chrp gg2_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) -{ - if (bus > 7) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le16((unsigned short *)pci_config_addr(bus, dev_fn, offset), val); - return PCIBIOS_SUCCESSFUL; -} +#define cfg_read_bad(val, size) *val = bad_##size; +#define cfg_write_bad(val, size) -int __chrp gg2_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) -{ - if (bus > 7) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32((unsigned int *)pci_config_addr(bus, dev_fn, offset), val); - return PCIBIOS_SUCCESSFUL; -} +#define bad_byte 0xff +#define bad_word 0xffff +#define bad_dword 0xffffffffU + +#define GG2_PCI_OP(rw, size, type, op) \ +int __chrp gg2_##rw##_config_##size(struct pci_dev *dev, int off, type val) \ +{ \ + if (dev->bus->number > 7) { \ + cfg_##rw##_bad(val, size) \ + return PCIBIOS_DEVICE_NOT_FOUND; \ + } \ + cfg_##rw(val, pci_config_addr(dev, off), type, op); \ + return PCIBIOS_SUCCESSFUL; \ +} + +GG2_PCI_OP(read, byte, u8 *, in_8) +GG2_PCI_OP(read, word, u16 *, in_le16) +GG2_PCI_OP(read, dword, u32 *, in_le32) +GG2_PCI_OP(write, byte, u8, out_8) +GG2_PCI_OP(write, word, u16, out_le16) +GG2_PCI_OP(write, dword, u32, out_le32) + +static struct pci_ops gg2_pci_ops = +{ + gg2_read_config_byte, + gg2_read_config_word, + gg2_read_config_dword, + gg2_write_config_byte, + gg2_write_config_word, + gg2_write_config_dword +}; -#define python_config_address(bus) (unsigned *)((0xfef00000+0xf8000)-(bus*0x100000)) -#define python_config_data(bus) ((0xfef00000+0xf8010)-(bus*0x100000)) -#define PYTHON_CFA(b, d, o) (0x80 | ((b<<6) << 8) | ((d) << 16) \ +/* + * Access functions for PCI config space on IBM "python" host bridges. + */ +#define PYTHON_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \ | (((o) & ~3) << 24)) -unsigned int python_busnr = 0; - -int __chrp python_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) -{ - if (bus > python_busnr) { - *val = 0xff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset)); - *val = in_8((unsigned char *)python_config_data(bus) + (offset&3)); - return PCIBIOS_SUCCESSFUL; -} - -int __chrp python_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) -{ - if (bus > python_busnr) { - *val = 0xffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset)); - *val = in_le16((unsigned short *)(python_config_data(bus) + (offset&3))); - return PCIBIOS_SUCCESSFUL; -} - - -int __chrp python_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) -{ - if (bus > python_busnr) { - *val = 0xffffffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset)); - *val = in_le32((unsigned *)python_config_data(bus)); - return PCIBIOS_SUCCESSFUL; -} -int __chrp python_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) -{ - if (bus > python_busnr) - return PCIBIOS_DEVICE_NOT_FOUND; - out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset)); - out_8((volatile unsigned char *)python_config_data(bus) + (offset&3), val); - return PCIBIOS_SUCCESSFUL; -} - -int __chrp python_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) -{ - if (bus > python_busnr) - return PCIBIOS_DEVICE_NOT_FOUND; - out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset)); - out_le16((volatile unsigned short *)python_config_data(bus) + (offset&3), - val); - return PCIBIOS_SUCCESSFUL; -} - -int __chrp python_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) -{ - if (bus > python_busnr) - return PCIBIOS_DEVICE_NOT_FOUND; - out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset)); - out_le32((unsigned *)python_config_data(bus) + (offset&3), val); - return PCIBIOS_SUCCESSFUL; -} - - -int __chrp rtas_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) -{ - unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); - unsigned long ret; - - if (call_rtas( "read-pci-config", 2, 2, &ret, addr, 1) != 0) - return PCIBIOS_DEVICE_NOT_FOUND; - *val = ret; - return PCIBIOS_SUCCESSFUL; -} - -int __chrp rtas_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) -{ - unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); - unsigned long ret; - - if (call_rtas("read-pci-config", 2, 2, &ret, addr, 2) != 0) - return PCIBIOS_DEVICE_NOT_FOUND; - *val = ret; - return PCIBIOS_SUCCESSFUL; -} - - -int __chrp rtas_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) -{ - unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); - unsigned long ret; - - if (call_rtas("read-pci-config", 2, 2, &ret, addr, 4) != 0) - return PCIBIOS_DEVICE_NOT_FOUND; - *val = ret; - return PCIBIOS_SUCCESSFUL; -} - -int __chrp rtas_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) -{ - unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); - if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 1, (ulong)val ) != 0 ) - return PCIBIOS_DEVICE_NOT_FOUND; - return PCIBIOS_SUCCESSFUL; -} - -int __chrp rtas_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) -{ - unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); - if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 2, (ulong)val ) != 0 ) - return PCIBIOS_DEVICE_NOT_FOUND; - return PCIBIOS_SUCCESSFUL; -} +#define PYTHON_PCI_OP(rw, size, type, op, mask) \ +int __chrp \ +python_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + struct pci_controller *hose = dev->sysdata; \ + \ + out_be32(hose->cfg_addr, \ + PYTHON_CFA(dev->bus->number, dev->devfn, offset)); \ + cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \ + return PCIBIOS_SUCCESSFUL; \ +} + +PYTHON_PCI_OP(read, byte, u8 *, in_8, 3) +PYTHON_PCI_OP(read, word, u16 *, in_le16, 2) +PYTHON_PCI_OP(read, dword, u32 *, in_le32, 0) +PYTHON_PCI_OP(write, byte, u8, out_8, 3) +PYTHON_PCI_OP(write, word, u16, out_le16, 2) +PYTHON_PCI_OP(write, dword, u32, out_le32, 0) + +static struct pci_ops python_pci_ops = +{ + python_read_config_byte, + python_read_config_word, + python_read_config_dword, + python_write_config_byte, + python_write_config_word, + python_write_config_dword +}; -int __chrp rtas_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) -{ - unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); - if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 4, (ulong)val ) != 0 ) - return PCIBIOS_DEVICE_NOT_FOUND; - return PCIBIOS_SUCCESSFUL; -} +#ifdef CONFIG_POWER4 +/* + * Access functions for PCI config space using RTAS calls. + */ +#define RTAS_PCI_READ_OP(size, type, nbytes) \ +int __chrp \ +rtas_read_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + unsigned long addr = (offset & 0xff) | ((dev->devfn & 0xff) << 8) \ + | ((dev->bus->number & 0xff) << 16); \ + unsigned long ret = ~0UL; \ + int rval; \ + \ + rval = call_rtas("read-pci-config", 2, 2, &ret, addr, nbytes); \ + *val = ret; \ + return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; \ +} + +#define RTAS_PCI_WRITE_OP(size, type, nbytes) \ +int __chrp \ +rtas_write_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + unsigned long addr = (offset & 0xff) | ((dev->devfn & 0xff) << 8) \ + | ((dev->bus->number & 0xff) << 16); \ + int rval; \ + \ + rval = call_rtas("write-pci-config", 3, 1, NULL, \ + addr, nbytes, (ulong)val); \ + return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; \ +} + +RTAS_PCI_READ_OP(byte, u8 *, 1) +RTAS_PCI_READ_OP(word, u16 *, 2) +RTAS_PCI_READ_OP(dword, u32 *, 4) +RTAS_PCI_WRITE_OP(byte, u8, 1) +RTAS_PCI_WRITE_OP(word, u16, 2) +RTAS_PCI_WRITE_OP(dword, u32, 4) + +static struct pci_ops rtas_pci_ops = +{ + rtas_read_config_byte, + rtas_read_config_word, + rtas_read_config_dword, + rtas_write_config_byte, + rtas_write_config_word, + rtas_write_config_dword +}; +#endif /* CONFIG_POWER4 */ /* * Temporary fixes for PCI devices. These should be replaced by OF query @@ -278,7 +203,7 @@ HYDRA_FC_MPIC_ENABLE | HYDRA_FC_SLOW_SCC_PCLK | HYDRA_FC_MPIC_IS_MASTER)); - OpenPIC = (volatile struct OpenPIC *)&Hydra->OpenPIC; + OpenPIC_Addr = &Hydra->OpenPIC; OpenPIC_InitSenses = hydra_openpic_initsenses; OpenPIC_NumInitSenses = sizeof(hydra_openpic_initsenses); return 1; @@ -316,54 +241,25 @@ chrp_pcibios_fixup(void) { struct pci_dev *dev; - int *brp; struct device_node *np; - extern struct pci_ops generic_pci_ops; - -#ifndef CONFIG_POWER4 - np = find_devices("device-tree"); - if (np != 0) { - for (np = np->child; np != NULL; np = np->sibling) { - if (np->type == NULL || strcmp(np->type, "pci") != 0) - continue; - if ((brp = (int *) get_property(np, "bus-range", NULL)) == 0) - continue; - if (brp[0] != 0) /* bus 0 is already done */ - pci_scan_bus(brp[0], &generic_pci_ops, NULL); - } - } -#else - /* XXX kludge for now because we can't properly handle - physical addresses > 4GB. -- paulus */ - pci_scan_bus(0x1e, &generic_pci_ops, NULL); -#endif /* CONFIG_POWER4 */ /* PCI interrupts are controlled by the OpenPIC */ pci_for_each_dev(dev) { - np = find_pci_device_OFnode(dev->bus->number, dev->devfn); + np = pci_device_to_OF_node(dev); if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0)) dev->irq = np->intrs[0].line; - /* these need to be absolute addrs for OF and Matrox FB -- Cort */ - if ( dev->vendor == PCI_VENDOR_ID_MATROX ) - { - if ( dev->resource[0].start < isa_mem_base ) - dev->resource[0].start += isa_mem_base; - if ( dev->resource[1].start < isa_mem_base ) - dev->resource[1].start += isa_mem_base; - } + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + /* the F50 identifies the amd as a trident */ if ( (dev->vendor == PCI_VENDOR_ID_TRIDENT) && (dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET) ) { dev->vendor = PCI_VENDOR_ID_AMD; - pcibios_write_config_word(dev->bus->number, - dev->devfn, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD); + pci_write_config_word(dev, PCI_VENDOR_ID, + PCI_VENDOR_ID_AMD); } #ifdef CONFIG_POWER4 power4_fixup_dev(dev); -#else - if (dev->bus->number > 0 && python_busnr > 0) - dev->resource[0].start += dev->bus->number*0x01000000; #endif } } @@ -402,86 +298,213 @@ bus->resource[1] = &gg2_resources.pci_mem; } -decl_config_access_method(grackle); -decl_config_access_method(indirect); -decl_config_access_method(rtas); +static void process_bridge_ranges(struct pci_controller *hose, + struct device_node *dev, int index) +{ + unsigned int *ranges; + int rlen = 0; + int memno = 0; + struct resource *res; + + hose->io_base_phys = 0; + ranges = (unsigned int *) get_property(dev, "ranges", &rlen); + while ((rlen -= 6 * sizeof(unsigned int)) >= 0) { + res = NULL; + switch (ranges[0] >> 24) { + case 1: /* I/O space */ + if (ranges[2] != 0) + break; + hose->io_base_phys = ranges[3]; + hose->io_base_virt = ioremap(ranges[3], ranges[5]); + if (index == 0) { + isa_io_base = (unsigned long) hose->io_base_virt; + printk("isa_io_base=%lx\n", isa_io_base); + } + res = &hose->io_resource; + res->flags = IORESOURCE_IO; + break; + case 2: /* memory space */ + if (index == 0 && ranges[1] == 0 && ranges[2] == 0){ + isa_mem_base = ranges[3]; + printk("isa_mem_base=%lx\n", isa_mem_base); + } + if (memno == 0) { + hose->pci_mem_offset = ranges[3] - ranges[2]; + printk("pci_mem_offset=%lx for this bridge\n", + hose->pci_mem_offset); + } + res = &hose->mem_resources[memno]; + res->flags = IORESOURCE_MEM; + ++memno; + break; + } + if (res != NULL) { + res->name = dev->full_name; + res->start = ranges[3]; + res->end = res->start + ranges[5] - 1; + res->parent = NULL; + res->sibling = NULL; + res->child = NULL; + } + ranges += 6; + } +} + +/* this is largely modeled and stolen after the pmac_pci code -- tgall + */ + +static void __init +ibm_add_bridges(struct device_node *dev) +{ + int *bus_range; + int len, index = 0; + struct pci_controller *hose; + volatile unsigned char *cfg; + unsigned int *dma; +#ifdef CONFIG_POWER3 + unsigned long *opprop = (unsigned long *) + get_property(find_path_device("/"), "platform-open-pic", NULL); +#endif + + for(; dev != NULL; dev = dev->next, ++index) { + if (dev->n_addrs < 1) { + printk(KERN_WARNING "Can't use %s: no address\n", + dev->full_name); + continue; + } + bus_range = (int *) get_property(dev, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s\n", + dev->full_name); + continue; + } + if (bus_range[1] == bus_range[0]) + printk(KERN_INFO "PCI bus %d", bus_range[0]); + else + printk(KERN_INFO "PCI buses %d..%d", + bus_range[0], bus_range[1]); + printk(" controlled by %s at %x\n", dev->type, + dev->addrs[0].address); + + hose = pcibios_alloc_controller(); + if (!hose) { + printk("Can't allocate PCI controller structure for %s\n", + dev->full_name); + continue; + } + hose->arch_data = dev; + hose->first_busno = bus_range[0]; + hose->last_busno = bus_range[1]; + hose->ops = &python_pci_ops; + + cfg = ioremap(dev->addrs[0].address + 0xf8000, 0x20); + hose->cfg_addr = (volatile unsigned int *) cfg; + hose->cfg_data = cfg + 0x10; + + process_bridge_ranges(hose, dev, index); + +#ifdef CONFIG_POWER3 + openpic_setup_ISU(index, opprop[index+1]); +#endif /* CONFIG_POWER3 */ + + /* check the first bridge for a property that we can + use to set pci_dram_offset */ + dma = (unsigned int *) + get_property(dev, "ibm,dma-ranges", &len); + if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) { + pci_dram_offset = dma[2] - dma[3]; + printk("pci_dram_offset = %lx\n", pci_dram_offset); + } + } +} +#ifdef CONFIG_POWER4 void __init -chrp_setup_pci_ptrs(void) +power4_add_bridge(void) +{ + struct pci_controller* hose; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + hose->first_busno = 0; + hose->last_busno = 0xff; + + hose->ops = &rtas_pci_ops; + pci_dram_offset = 0; +} +#endif /* CONFIG_POWER4 */ + +void __init +chrp_find_bridges(void) { struct device_node *py; + char *model, *name; + struct pci_controller* hose; ppc_md.pcibios_fixup = chrp_pcibios_fixup; + #ifdef CONFIG_POWER4 - set_config_access_method(rtas); - pci_dram_offset = 0; + power4_add_bridge(); #else /* CONFIG_POWER4 */ - if ( !strncmp("MOT", - get_property(find_path_device("/"), "model", NULL),3) ) - { - pci_dram_offset = 0; - isa_mem_base = 0xf7000000; - isa_io_base = 0xfe000000; - set_config_access_method(grackle); + model = get_property(find_path_device("/"), "model", NULL); + if (!strncmp("MOT", model, 3)) { + struct pci_controller* hose; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + hose->first_busno = 0; + hose->last_busno = 0xff; + /* Check that please. This must be the root of the OF + * PCI tree (the root host bridge + */ + hose->arch_data = find_devices("pci"); + setup_grackle(hose, 0x20000); + return; } - else - { - if ((py = find_compatible_devices("pci", "IBM,python")) != 0 - || (py = find_compatible_devices("pci", "IBM,python3.0")) != 0) - { - char *name = get_property(find_path_device("/"), "name", NULL); - /* find out how many pythons */ - while ( (py = py->next) ) python_busnr++; - set_config_access_method(python); - - /* - * We base these values on the machine type but should - * try to read them from the python controller itself. - * -- Cort - */ - if ( !strncmp("IBM,7025-F50", name, 12) ) - { - pci_dram_offset = 0x80000000; - isa_mem_base = 0xa0000000; - isa_io_base = 0x88000000; - } else if ( !strncmp("IBM,7043-260", name, 12) - || !strncmp("IBM,7044-270", name, 12)) - { - pci_dram_offset = 0x0; - isa_mem_base = 0xc0000000; - isa_io_base = 0xf8000000; - } - } - else - { - if ( !strncmp("IBM,7043-150", get_property(find_path_device("/"), "name", NULL),12) || - !strncmp("IBM,7046-155", get_property(find_path_device("/"), "name", NULL),12) || - !strncmp("IBM,7046-B50", get_property(find_path_device("/"), "name", NULL),12) ) - { - pci_dram_offset = 0; - isa_mem_base = 0x80000000; - isa_io_base = 0xfe000000; - pci_config_address = (unsigned int *)0xfec00000; - pci_config_data = (unsigned char *)0xfee00000; - set_config_access_method(indirect); - } - else - { - /* LongTrail */ - pci_dram_offset = 0; - isa_mem_base = 0xf7000000; - isa_io_base = 0xf8000000; - set_config_access_method(gg2); - ppc_md.pcibios_fixup = gg2_pcibios_fixup; - ppc_md.pcibios_fixup_bus = gg2_pcibios_fixup_bus; - } - } - } + if ((py = find_compatible_devices("pci", "IBM,python"))) + { + /* XXX xmon_init_scc needs this set and the BAT + set up in MMU_init */ + ibm_add_bridges(find_devices("pci")); + return; + } + + + hose = pcibios_alloc_controller(); + if (!hose) + return; + hose->first_busno = 0; + hose->last_busno = 0xff; + /* Check that please. This must be the root of the OF + * PCI tree (the root host bridge + */ + hose->arch_data = find_devices("pci"); + name = get_property(find_path_device("/"), "name", NULL); + if (!strncmp("IBM,7043-150", name, 12) || + !strncmp("IBM,7046-155", name, 12) || + !strncmp("IBM,7046-B50", name, 12) ) { + setup_grackle(hose, 0x01000000); + isa_mem_base = 0x80000000; + return; + } + + /* LongTrail */ + hose->ops = &gg2_pci_ops; + pci_dram_offset = 0; + isa_mem_base = 0xf7000000; + hose->io_base_phys = (unsigned long) 0xf8000000; + hose->io_base_virt = ioremap(hose->io_base_phys, 0x10000); + isa_io_base = (unsigned long) hose->io_base_virt; + ppc_md.pcibios_fixup = gg2_pcibios_fixup; + ppc_md.pcibios_fixup_bus = gg2_pcibios_fixup_bus; #endif /* CONFIG_POWER4 */ } #ifdef CONFIG_PPC64BRIDGE +#ifdef CONFIG_POWER4 /* * Hack alert!!! * 64-bit machines like POWER3 and POWER4 have > 32 bit @@ -490,9 +513,7 @@ * page table gives us into parts of the physical address * space above 4GB so we can access the I/O devices. */ - -#ifdef CONFIG_POWER4 -static unsigned long pci_address_offset(int busnr, unsigned int flags) +unsigned long pci_address_offset(int busnr, unsigned int flags) { unsigned long offset = 0; @@ -507,35 +528,6 @@ else } return offset; -} - -unsigned long phys_to_bus(unsigned long pa) -{ - if (pa >= 0xf8000000) - pa -= 0x38000000; - else if (pa >= 0x80000000 && pa < 0xc0000000) - pa += 0x40000000; - return pa; -} - -unsigned long bus_to_phys(unsigned int ba, int busnr) -{ - return ba + pci_address_offset(busnr, IORESOURCE_MEM); -} - -#else /* CONFIG_POWER4 */ -/* - * For now assume I/O addresses are < 4GB and PCI bridges don't - * remap addresses on POWER3 machines. - */ -unsigned long phys_to_bus(unsigned long pa) -{ - return pa; -} - -unsigned long bus_to_phys(unsigned int ba, int busnr) -{ - return ba; } #endif /* CONFIG_POWER4 */ #endif /* CONFIG_PPC64BRIDGE */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/chrp_setup.c linux.ac/arch/ppc/kernel/chrp_setup.c --- linux.vanilla/arch/ppc/kernel/chrp_setup.c Sat Oct 28 16:15:46 2000 +++ linux.ac/arch/ppc/kernel/chrp_setup.c Fri Dec 22 16:33:56 2000 @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -50,21 +49,19 @@ #include #include #include - #include + #include "local_irq.h" #include "i8259.h" #include "open_pic.h" #include "xics.h" -extern volatile unsigned char *chrp_int_ack_special; - unsigned long chrp_get_rtc_time(void); int chrp_set_rtc_time(unsigned long nowtime); void chrp_calibrate_decr(void); long chrp_time_init(void); -void chrp_setup_pci_ptrs(void); +void chrp_find_bridges(void); void chrp_event_scan(void); void rtas_display_progress(char *, unsigned short); void rtas_indicator_progress(char *, unsigned short); @@ -92,7 +89,7 @@ extern PTE *Hash, *Hash_end; extern unsigned long Hash_size, Hash_mask; extern int probingmem; -extern unsigned long loops_per_sec; +extern unsigned long loops_per_jiffy; extern int bootx_text_mapped; static int max_width; @@ -244,7 +241,7 @@ struct device_node *device; /* init to some ~sane value until calibrate_delay() runs */ - loops_per_sec = 50000000; + loops_per_jiffy = 50000000/HZ; #ifdef CONFIG_BLK_DEV_INITRD /* this is fine for chrp */ @@ -257,6 +254,9 @@ ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */ printk("Boot arguments: %s\n", cmd_line); + /* Lookup PCI host bridges */ + chrp_find_bridges(); + #ifndef CONFIG_PPC64BRIDGE /* PCI bridge config space access area - * appears to be not in devtree on longtrail. */ @@ -266,11 +266,12 @@ * -- Geert */ hydra_init(); /* Mac I/O */ + #endif /* CONFIG_PPC64BRIDGE */ #ifndef CONFIG_POWER4 /* Some IBM machines don't have the hydra -- Cort */ - if ( !OpenPIC ) + if ( !OpenPIC_Addr ) { unsigned long *opprop; @@ -279,7 +280,7 @@ if (opprop != 0) { printk("OpenPIC addrs: %lx %lx %lx\n", opprop[0], opprop[1], opprop[2]); - OpenPIC = ioremap(opprop[0], sizeof(struct OpenPIC)); + OpenPIC_Addr = ioremap(opprop[0], 0x40000); } } #endif @@ -292,23 +293,17 @@ conswitchp = &dummy_con; #endif -#ifndef CONFIG_PPC64BRIDGE - pmac_find_bridges(); -#endif /* CONFIG_PPC64BRIDGE */ - /* Get the event scan rate for the rtas so we know how * often it expects a heartbeat. -- Cort */ - if ( rtas_data ) - { + if ( rtas_data ) { struct property *p; device = find_devices("rtas"); for ( p = device->properties; p && strncmp(p->name, "rtas-event-scan-rate", 20); p = p->next ) /* nothing */ ; - if ( p && *(unsigned long *)p->value ) - { + if ( p && *(unsigned long *)p->value ) { ppc_md.heartbeat = chrp_event_scan; ppc_md.heartbeat_reset = (HZ/(*(unsigned long *)p->value)*30)-1; ppc_md.heartbeat_count = 1; @@ -365,79 +360,44 @@ } } -int __chrp chrp_get_irq( struct pt_regs *regs ) -{ - int irq; - - irq = openpic_irq( smp_processor_id() ); - if (irq == IRQ_8259_CASCADE) - { - /* - * This magic address generates a PCI IACK cycle. - */ - if ( chrp_int_ack_special ) - irq = *chrp_int_ack_special; - else - irq = i8259_irq( smp_processor_id() ); - openpic_eoi( smp_processor_id() ); - } - if (irq == OPENPIC_VEC_SPURIOUS) - /* - * Spurious interrupts should never be - * acknowledged - */ - irq = -1; - /* - * I would like to openpic_eoi here but there seem to be timing problems - * between the openpic ack and the openpic eoi. - * -- Cort - */ - return irq; -} - -void __chrp chrp_post_irq(struct pt_regs* regs, int irq) -{ - /* - * If it's an i8259 irq then we've already done the - * openpic irq. So we just check to make sure the controller - * is an openpic and if it is then eoi - * - * We do it this way since our irq_desc[irq].handler can change - * with RTL and no longer be open_pic -- Cort - */ - if ( irq >= open_pic_irq_offset) - openpic_eoi( smp_processor_id() ); -} - void __init chrp_init_IRQ(void) { struct device_node *np; int i; unsigned long *addrp; + unsigned char* chrp_int_ack_special = 0; + unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS]; + int nmi_irq = -1; +#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON) + struct device_node *kbd; +#endif if (!(np = find_devices("pci")) || !(addrp = (unsigned long *) get_property(np, "8259-interrupt-acknowledge", NULL))) printk("Cannot find pci to get ack address\n"); else - chrp_int_ack_special = (volatile unsigned char *) - ioremap(*addrp, 1); - open_pic_irq_offset = 16; - for ( i = 16 ; i < NR_IRQS ; i++ ) - irq_desc[i].handler = &open_pic; - openpic_init(1); - enable_irq(IRQ_8259_CASCADE); - for ( i = 0 ; i < 16 ; i++ ) + chrp_int_ack_special = (unsigned char *)ioremap(*addrp, 1); + /* hydra still sets OpenPIC_InitSenses to a static set of values */ + if (OpenPIC_InitSenses == NULL) { + prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS); + OpenPIC_InitSenses = init_senses; + OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS; + } + openpic_init(1, NUM_8259_INTERRUPTS, chrp_int_ack_special, nmi_irq); + for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ ) irq_desc[i].handler = &i8259_pic; i8259_init(); -#ifdef CONFIG_XMON - request_irq(openpic_to_irq(HYDRA_INT_ADB_NMI), - xmon_irq, 0, "NMI", 0); -#endif /* CONFIG_XMON */ -#ifdef CONFIG_SMP - request_irq(openpic_to_irq(OPENPIC_VEC_IPI), - openpic_ipi_action, 0, "IPI0", 0); -#endif /* CONFIG_SMP */ +#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON) + /* see if there is a keyboard in the device tree + with a parent of type "adb" */ + for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next) + if (kbd->parent && kbd->parent->type + && strcmp(kbd->parent->type, "adb") == 0) + break; + if (kbd) + request_irq( HYDRA_INT_ADB_NMI, xmon_irq, 0, "XMON break", 0); +#endif } void __init @@ -556,12 +516,6 @@ } void __chrp -chrp_ide_fix_driveid(struct hd_driveid *id) -{ - ppc_generic_ide_fix_driveid(id); -} - -void __chrp chrp_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq) { ide_ioreg_t reg = data_port; @@ -586,7 +540,6 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { - chrp_setup_pci_ptrs(); #ifdef CONFIG_BLK_DEV_INITRD /* take care of initrd if we have one */ if ( r6 ) @@ -596,10 +549,10 @@ } #endif /* CONFIG_BLK_DEV_INITRD */ - /* pci_dram_offset/isa_io_base/isa_mem_base set by setup_pci_ptrs() */ ISA_DMA_THRESHOLD = ~0L; DMA_MODE_READ = 0x44; DMA_MODE_WRITE = 0x48; + isa_io_base = CHRP_ISA_IO_BASE; /* default value */ ppc_md.setup_arch = chrp_setup_arch; ppc_md.setup_residual = NULL; @@ -607,8 +560,8 @@ ppc_md.irq_cannonicalize = chrp_irq_cannonicalize; #ifndef CONFIG_POWER4 ppc_md.init_IRQ = chrp_init_IRQ; - ppc_md.get_irq = chrp_get_irq; - ppc_md.post_irq = chrp_post_irq; + ppc_md.get_irq = openpic_get_irq; + ppc_md.post_irq = NULL; #else ppc_md.init_IRQ = xics_init_IRQ; ppc_md.get_irq = xics_get_irq; @@ -669,11 +622,12 @@ ppc_ide_md.ide_check_region = chrp_ide_check_region; ppc_ide_md.ide_request_region = chrp_ide_request_region; ppc_ide_md.ide_release_region = chrp_ide_release_region; - ppc_ide_md.fix_driveid = chrp_ide_fix_driveid; + ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid; ppc_ide_md.ide_init_hwif = chrp_ide_init_hwif_ports; ppc_ide_md.io_base = _IO_BASE; #endif + /* * Print the banner, then scroll down so boot progress * can be printed. -- Cort diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/entry.S linux.ac/arch/ppc/kernel/entry.S --- linux.vanilla/arch/ppc/kernel/entry.S Mon Nov 20 15:11:56 2000 +++ linux.ac/arch/ppc/kernel/entry.S Mon Dec 18 20:42:37 2000 @@ -234,7 +234,6 @@ li r0,0x0ff0 stw r0,TRAP(r1) stw r1,KSP(r3) /* Set old stack pointer */ - sync tophys(r0,r4) CLR_TOP32(r0) mtspr SPRG3,r0 /* Update current THREAD phys addr */ @@ -251,7 +250,7 @@ #endif mtspr M_TWB,r9 /* Update MMU base address */ tlbia - SYNC + sync #endif /* CONFIG_8xx */ lwz r1,KSP(r4) /* Load new stack pointer */ /* save the old current 'last' for return value */ @@ -342,23 +341,23 @@ do_bottom_half_ret: 2: lwz r3,_MSR(r1) /* Returning to user mode? */ andi. r3,r3,MSR_PR - beq+ restore /* if so, check need_resched and signals */ - .globl ret_to_user_hook -ret_to_user_hook: - nop + beq+ do_signal_ret /* if so, check need_resched and signals */ lwz r3,NEED_RESCHED(r2) cmpi 0,r3,0 /* check need_resched flag */ beq+ 7f bl schedule 7: lwz r5,SIGPENDING(r2) /* Check for pending unblocked signals */ cmpwi 0,r5,0 - beq+ restore + beq+ do_signal_ret li r3,0 addi r4,r1,STACK_FRAME_OVERHEAD MOL_HOOK_MMU(8,r8) bl do_signal .globl do_signal_ret do_signal_ret: + .globl ret_to_user_hook +ret_to_user_hook: + nop restore: lwz r3,_XER(r1) mtspr XER,r3 @@ -372,7 +371,7 @@ */ mfmsr r0 /* Get current interrupt state */ rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */ - sync /* Some chip revs have problems here... */ + SYNC /* Some chip revs have problems here... */ mtmsr r0 /* Update machine state */ /* if returning to user mode, set new sprg2 and save kernel SP */ @@ -468,7 +467,7 @@ andc r0,r9,r0 li r10,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP andc r9,r0,r10 - sync /* disable interrupts so SRR0/1 */ + SYNC /* disable interrupts so SRR0/1 */ mtmsr r0 /* don't get trashed */ mtlr r6 CLR_TOP32(r7) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/error_log.c linux.ac/arch/ppc/kernel/error_log.c --- linux.vanilla/arch/ppc/kernel/error_log.c Thu Jan 1 01:00:00 1970 +++ linux.ac/arch/ppc/kernel/error_log.c Thu Dec 21 21:33:07 2000 @@ -0,0 +1,179 @@ +/* + * arch/ppc/kernel/error_log.c + * + * Copyright (c) 2000 Tilmann Bitterberg + * (tilmann@bitterberg.de) + * + * Error processing of errors found by rtas even-scan routine + * which is done with every heartbeat. (chrp_setup.c) + */ + +#include + +#include + +#include "error_log.h" + +/* ****************************************************************** */ +/* + * EVENT-SCAN + * The whole stuff below here doesn't take any action when it found + * an error, it just prints as much information as possible and + * then its up to the user to decide what to do. + * + * Returns 0 if no errors were found + * Returns 1 if there may be more errors + */ +int ppc_rtas_errorlog_scan(void) +{ +const char *_errlog_severity[] = { +#ifdef VERBOSE_ERRORS + "No Error\n\t\ +Should require no further information", + "Event\n\t\ +This is not really an error, it is an event. I use events\n\t\ +to communicate with RTAS back and forth.", + "Warning\n\t\ +Indicates a non-state-losing error, either fully recovered\n\t\ +by RTAS or not needing recovery. Ignore it.", + "Error sync\n\t\ +May only be fatal to a certain program or thread. Recovery\n\t\ +and continuation is possible, if I only had a handler for\n\t\ +this. Less serious", + "Error\n\t\ +Less serious, but still causing a loss of data and state.\n\t\ +I can't tell you exactly what to do, You have to decide\n\t\ +with help from the target and initiator field, what kind\n\t\ +of further actions may take place.", + "Fatal\n\t\ +Represent a permanent hardware failure and I believe this\n\t\ +affects my overall performance and behaviour. I would not\n\t\ +attempt to continue normal operation." +#else + "No Error", + "Event", + "Warning", + "Error sync", + "Error", + "Fatal" +#endif /* VERBOSE_ERRORS */ +}; + +const char *_errlog_disposition[] = { +#ifdef VERBOSE_ERRORS + "Fully recovered\n\t\ +There was an error, but it is fully recovered by RTAS.", + "Limited recovery\n\t\ +RTAS was able to recover the state of the machine, but some\n\t\ +feature of the machine has been disabled or lost (for example\n\t\ +error checking) or performance may suffer.", + "Not recovered\n\t\ +Whether RTAS did not try to recover anything or recovery failed:\n\t\ +HOUSTON, WE HAVE A PROBLEM!" +#else + "Fully recovered", + "Limited recovery", + "Not recovered" +#endif /* VERBOSE_ERRORS */ +}; + +const char *_errlog_extended[] = { +#ifdef VERBOSE_ERRORS + "Not present\n\t\ +Sad, the RTAS call didn't return an extended error log.", + "Present\n\t\ +The extended log is present and hopefully it contains a lot of\n\t\ +useful information, which leads to the solution of the problem." +#else + "Not present", + "Present" +#endif /* VERBOSE_ERRORS */ +}; + +const char *_errlog_initiator[] = { + "Unknown or not applicable", + "CPU", + "PCI", + "ISA", + "Memory", + "Power management" +}; + +const char *_errlog_target[] = { + "Unknown or not applicable", + "CPU", + "PCI", + "ISA", + "Memory", + "Power management" +}; + rtas_error_log error_log; + char logdata[1024]; + int error; + int retries = 0; /* if HW error, try 10 times */ + + error = call_rtas ("event-scan", 4, 1, (unsigned long *)&error_log, + INTERNAL_ERROR | EPOW_WARNING, + 0, __pa(logdata), 1024); + + if (error == 1) /* no errors found */ + return 0; + + if (error == -1) { + printk(KERN_ERR "Unable to get errors. Do you a favor and throw this box away\n"); + return 0; + } + if (error_log.version != 1) + printk(KERN_WARNING "Unknown version (%d), please implement me\n", + error_log.version); + + switch (error_log.disposition) { + case DISP_FULLY_RECOVERED: + /* there was an error, but everything is fine now */ + return 0; + case DISP_NOT_RECOVERED: + printk("We have a really serious Problem!\n"); + case DISP_LIMITED_RECOVERY: + printk("Error classification\n"); + printk("Severity : %s\n", + ppc_rtas_errorlog_check_severity (error_log)); + printk("Initiator : %s\n", + ppc_rtas_errorlog_check_initiator (error_log)); + printk("Target : %s\n", + ppc_rtas_errorlog_check_target (error_log)); + printk("Type : %s\n", + ppc_rtas_errorlog_check_type (error_log)); + printk("Ext. log : %s\n", + ppc_rtas_errorlog_check_extended (error_log)); + if (error_log.extended) + ppc_rtas_errorlog_disect_extended (logdata); + return 1; + default: + /* nothing */ + break; + } + return 0; +} +/* ****************************************************************** */ +const char * ppc_rtas_errorlog_check_type (rtas_error_log error_log) +{ + const char *_errlog_type[] = { + "unknown type", + "too many tries failed", + "TCE error", + "RTAS device failed", + "target timed out", + "parity error on data", /* 5 */ + "parity error on address", + "parity error on external cache", + "access to invalid address", + "uncorrectable ECC error", + "corrected ECC error" /* 10 */ + }; + if (error_log.type == TYPE_EPOW) + return "EPOW"; + if (error_log.type >= TYPE_PMGM_POWER_SW_ON) + return "PowerMGM Event (not handled right now)"; + return _errlog_type[error_log.type]; +} + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/error_log.h linux.ac/arch/ppc/kernel/error_log.h --- linux.vanilla/arch/ppc/kernel/error_log.h Thu Jan 1 01:00:00 1970 +++ linux.ac/arch/ppc/kernel/error_log.h Mon Dec 18 20:42:50 2000 @@ -0,0 +1,95 @@ +#ifndef __ERROR_LOG_H__ +#define __ERROR_LOG_H__ + +#define VERBOSE_ERRORS 1 /* Maybe I enlarge the kernel too much */ +#undef VERBOSE_ERRORS + +/* Event classes */ +/* XXX: Endianess correct? NOW*/ +#define INTERNAL_ERROR 0x80000000 /* set bit 0 */ +#define EPOW_WARNING 0x40000000 /* set bit 1 */ +#define POWERMGM_EVENTS 0x20000000 /* set bit 2 */ + +/* event-scan returns */ +#define SEVERITY_FATAL 0x5 +#define SEVERITY_ERROR 0x4 +#define SEVERITY_ERROR_SYNC 0x3 +#define SEVERITY_WARNING 0x2 +#define SEVERITY_EVENT 0x1 +#define SEVERITY_NO_ERROR 0x0 +#define DISP_FULLY_RECOVERED 0x0 +#define DISP_LIMITED_RECOVERY 0x1 +#define DISP_NOT_RECOVERED 0x2 +#define PART_PRESENT 0x0 +#define PART_NOT_PRESENT 0x1 +#define INITIATOR_UNKNOWN 0x0 +#define INITIATOR_CPU 0x1 +#define INITIATOR_PCI 0x2 +#define INITIATOR_ISA 0x3 +#define INITIATOR_MEMORY 0x4 +#define INITIATOR_POWERMGM 0x5 +#define TARGET_UNKNOWN 0x0 +#define TARGET_CPU 0x1 +#define TARGET_PCI 0x2 +#define TARGET_ISA 0x3 +#define TARGET_MEMORY 0x4 +#define TARGET_POWERMGM 0x5 +#define TYPE_RETRY 0x01 +#define TYPE_TCE_ERR 0x02 +#define TYPE_INTERN_DEV_FAIL 0x03 +#define TYPE_TIMEOUT 0x04 +#define TYPE_DATA_PARITY 0x05 +#define TYPE_ADDR_PARITY 0x06 +#define TYPE_CACHE_PARITY 0x07 +#define TYPE_ADDR_INVALID 0x08 +#define TYPE_ECC_UNCORR 0x09 +#define TYPE_ECC_CORR 0x0a +#define TYPE_EPOW 0x40 +/* I don't add PowerMGM events right now, this is a different topic */ +#define TYPE_PMGM_POWER_SW_ON 0x60 +#define TYPE_PMGM_POWER_SW_OFF 0x61 +#define TYPE_PMGM_LID_OPEN 0x62 +#define TYPE_PMGM_LID_CLOSE 0x63 +#define TYPE_PMGM_SLEEP_BTN 0x64 +#define TYPE_PMGM_WAKE_BTN 0x65 +#define TYPE_PMGM_BATTERY_WARN 0x66 +#define TYPE_PMGM_BATTERY_CRIT 0x67 +#define TYPE_PMGM_SWITCH_TO_BAT 0x68 +#define TYPE_PMGM_SWITCH_TO_AC 0x69 +#define TYPE_PMGM_KBD_OR_MOUSE 0x6a +#define TYPE_PMGM_ENCLOS_OPEN 0x6b +#define TYPE_PMGM_ENCLOS_CLOSED 0x6c +#define TYPE_PMGM_RING_INDICATE 0x6d +#define TYPE_PMGM_LAN_ATTENTION 0x6e +#define TYPE_PMGM_TIME_ALARM 0x6f +#define TYPE_PMGM_CONFIG_CHANGE 0x70 +#define TYPE_PMGM_SERVICE_PROC 0x71 + +typedef struct _rtas_error_log { + unsigned long version:8; /* Architectural version */ + unsigned long severity:3; /* Severity level of error */ + unsigned long disposition:2; /* Degree of recovery */ + unsigned long extended:1; /* extended log present? */ + unsigned long /* reserved */ :2; /* Reserved for future use */ + unsigned long initiator:4; /* Initiator of event */ + unsigned long target:4; /* Target of failed operation */ + unsigned long type:8; /* General event or error*/ + unsigned long extended_log_length:32; /* length in bytes */ +} rtas_error_log; + +/* ****************************************************************** */ +#define ppc_rtas_errorlog_check_severity(x) \ + (_errlog_severity[x.severity]) +#define ppc_rtas_errorlog_check_target(x) \ + (_errlog_target[x.target]) +#define ppc_rtas_errorlog_check_initiator(x) \ + (_errlog_initiator[x.initiator]) +#define ppc_rtas_errorlog_check_extended(x) \ + (_errlog_extended[x.extended]) +#define ppc_rtas_errorlog_disect_extended(x) \ + do { /* implement me */ } while(0) +extern const char * ppc_rtas_errorlog_check_type (rtas_error_log error_log); +extern int ppc_rtas_errorlog_scan(void); + + +#endif /* __ERROR_LOG_H__ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/feature.c linux.ac/arch/ppc/kernel/feature.c --- linux.vanilla/arch/ppc/kernel/feature.c Sat Oct 28 16:15:46 2000 +++ linux.ac/arch/ppc/kernel/feature.c Mon Dec 18 20:42:50 2000 @@ -238,12 +238,15 @@ static struct feature_controller* feature_lookup_controller(struct device_node *device); +#ifdef CONFIG_PMAC_PBOOK static void heathrow_prepare_for_sleep(struct feature_controller* ctrler); static void heathrow_wakeup(struct feature_controller* ctrler); -static void keylargo_init(void); -static void uninorth_init(void); static void core99_prepare_for_sleep(struct feature_controller* ctrler); static void core99_wake_up(struct feature_controller* ctrler); +#endif /* CONFIG_PMAC_PBOOK */ + +static void keylargo_init(void); +static void uninorth_init(void); /* static variables */ static struct feature_controller controllers[MAX_FEATURE_CONTROLLERS]; @@ -255,6 +258,10 @@ static int uninorth_rev; static int keylargo_rev; +/* + * WARNING ! This function is called early in setup_arch, neither the IO base + * nor the udelay calibration have been done yet + */ void feature_init(void) { @@ -527,14 +534,31 @@ void feature_set_firewire_power(struct device_node* device, int power) { + if (!uninorth_base) + return; + if (power) + UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW); + else + UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW); + udelay(20); +} + +#ifdef CONFIG_SMP +void +feature_core99_kick_cpu1(void) +{ + out_8((volatile u8 *)KL_FCR(KL_GPIO_KICK_CPU1), KL_GPIO_KICK_CPU1_UP); + udelay(1); + out_8((volatile u8 *)KL_FCR(KL_GPIO_KICK_CPU1), KL_GPIO_KICK_CPU1_DOWN); } +#endif /* CONFIG_SMP */ /* Initialize the Core99 UniNorth host bridge and memory controller */ static void uninorth_init(void) { - struct device_node* gmac; + struct device_node* gmac, *fw; unsigned long actrl; /* Set the arbitrer QAck delay according to what Apple does @@ -564,6 +588,11 @@ } if (gmac) feature_set_gmac_power(gmac, 0); + + /* Kludge (enable FW before PCI probe) */ + fw = find_devices("firewire"); + if (fw && device_is_compatible(fw, "pci106b,18")) + feature_set_firewire_power(fw, 1); } /* Initialize the Core99 KeyLargo ASIC. Currently, we just make sure @@ -576,6 +605,43 @@ } #ifdef CONFIG_PMAC_PBOOK + +static u32 save_fcr[5]; +static u32 save_mbcr; + +static void +heathrow_prepare_for_sleep(struct feature_controller* ctrler) +{ + save_mbcr = in_le32(FREG(ctrler, 0x34)); + save_fcr[0] = in_le32(FREG(ctrler, 0x38)); + save_fcr[1] = in_le32(FREG(ctrler, 0x3c)); + + out_le32(FREG(ctrler, 0x38), save_fcr[0] & ~HRW_IOBUS_ENABLE); +} + +static void +heathrow_wakeup(struct feature_controller* ctrler) +{ + out_le32(FREG(ctrler, 0x38), save_fcr[0]); + out_le32(FREG(ctrler, 0x3c), save_fcr[1]); + out_le32(FREG(ctrler, 0x34), save_mbcr); + mdelay(1); + out_le32(FREG(ctrler, 0x38), save_fcr[0] | HRW_IOBUS_ENABLE); + mdelay(1); +} + +static void +core99_prepare_for_sleep(struct feature_controller* ctrler) +{ + /* Not yet implemented */ +} + +static void +core99_wake_up(struct feature_controller* ctrler) +{ + /* Not yet implemented */ +} + void feature_prepare_for_sleep(void) { @@ -599,7 +665,6 @@ } } - void feature_wake_up(void) { @@ -622,39 +687,4 @@ } } -static u32 save_fcr[5]; -static u32 save_mbcr; - -static void -heathrow_prepare_for_sleep(struct feature_controller* ctrler) -{ - save_mbcr = in_le32(FREG(ctrler, 0x34)); - save_fcr[0] = in_le32(FREG(ctrler, 0x38)); - save_fcr[1] = in_le32(FREG(ctrler, 0x3c)); - - out_le32(FREG(ctrler, 0x38), save_fcr[0] & ~HRW_IOBUS_ENABLE); -} - -static void -heathrow_wakeup(struct feature_controller* ctrler) -{ - out_le32(FREG(ctrler, 0x38), save_fcr[0]); - out_le32(FREG(ctrler, 0x3c), save_fcr[1]); - out_le32(FREG(ctrler, 0x34), save_mbcr); - mdelay(1); - out_le32(FREG(ctrler, 0x38), save_fcr[0] | HRW_IOBUS_ENABLE); - mdelay(1); -} - -static void -core99_prepare_for_sleep(struct feature_controller* ctrler) -{ - /* Not yet implemented */ -} - -static void -core99_wake_up(struct feature_controller* ctrler) -{ - /* Not yet implemented */ -} #endif /* CONFIG_PMAC_PBOOK */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/galaxy_pci.c linux.ac/arch/ppc/kernel/galaxy_pci.c --- linux.vanilla/arch/ppc/kernel/galaxy_pci.c Thu Feb 10 20:37:51 2000 +++ linux.ac/arch/ppc/kernel/galaxy_pci.c Mon Dec 18 20:42:50 2000 @@ -36,67 +36,84 @@ /* Function Prototypes */ -decl_config_access_method(galaxy); - - void __init galaxy_pcibios_fixup(void) { } -void __init -galaxy_setup_pci_ptrs(void) +static int +galaxy_pcibios_read_config_byte(struct pci_controller* hose, + u8 bus, u8 dev, u8 offset, u8 *val) { - set_config_access_method(galaxy); - ppc_md.pcibios_fixup = galaxy_pcibios_fixup; + return (PCIBIOS_SUCCESSFUL); } -int -galaxy_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) +static int +galaxy_pcibios_read_config_word(struct pci_controller* hose, + u8 bus, u8 dev, u8 offset, u16 *val) { return (PCIBIOS_SUCCESSFUL); } -int -galaxy_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) +static int +galaxy_pcibios_read_config_dword(struct pci_controller* hose, + u8 bus, u8 dev, u8 offset, u32 *val) { return (PCIBIOS_SUCCESSFUL); } -int -galaxy_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) +static int +galaxy_pcibios_write_config_byte(struct pci_controller* hose, + u8 bus, u8 dev, u8 offset, u8 val) { return (PCIBIOS_SUCCESSFUL); } -int -galaxy_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) +static int +galaxy_pcibios_write_config_word(struct pci_controller* hose, + u8 bus, u8 dev, u8 offset, u16 val) { return (PCIBIOS_SUCCESSFUL); } -int -galaxy_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) +static int +galaxy_pcibios_write_config_dword(struct pci_controller* hose, + u8 bus, u8 dev, u8 offset, u32 val) { return (PCIBIOS_SUCCESSFUL); } -int -galaxy_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) +static struct pci_controller_ops galaxy_pci_ops = { + galaxy_pcibios_read_config_byte, + galaxy_pcibios_read_config_word, + galaxy_pcibios_read_config_dword, + galaxy_pcibios_write_config_byte, + galaxy_pcibios_write_config_word, + galaxy_pcibios_write_config_dword +}; - return (PCIBIOS_SUCCESSFUL); +void __init +galaxy_find_bridges(void) +{ + struct pci_controller* hose; + + set_config_access_method(galaxy); + + ppc_md.pcibios_fixup = galaxy_pcibios_fixup; + hose = pcibios_alloc_controller(); + if (!hose) + return; + hose->ops = &galaxy_pci_ops; + /* Todo ... + hose->cfg_data = ioremap(PCICFGDATA, ...); + hose->cfg_addr = ioremap(PCICFGADDR, ...); + */ } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/gemini_pci.c linux.ac/arch/ppc/kernel/gemini_pci.c --- linux.vanilla/arch/ppc/kernel/gemini_pci.c Tue May 2 21:05:39 2000 +++ linux.ac/arch/ppc/kernel/gemini_pci.c Mon Dec 18 20:42:50 2000 @@ -8,6 +8,7 @@ #include #include #include +#include #include "pci.h" @@ -16,67 +17,79 @@ int -gemini_pcibios_read_config_byte(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned char *val) +gemini_pcibios_read_config_byte(struct pci_dev *dev, int offset, u8 *val) { unsigned long reg; - reg = grackle_read( pci_config_addr( bus, dev, (offset & ~(0x3)))); + reg = grackle_read(pci_config_addr(dev->bus->number, dev->devfn, + (offset & ~(0x3)))); *val = ((reg >> ((offset & 0x3) << 3)) & 0xff); return PCIBIOS_SUCCESSFUL; } int -gemini_pcibios_read_config_word(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned short *val) +gemini_pcibios_read_config_word(struct pci_dev *dev, int offset, u16 *val) { unsigned long reg; - reg = grackle_read( pci_config_addr( bus, dev, (offset & ~(0x3)))); + reg = grackle_read(pci_config_addr(dev->bus->number, dev->devfn, + (offset & ~(0x3)))); *val = ((reg >> ((offset & 0x3) << 3)) & 0xffff); return PCIBIOS_SUCCESSFUL; } int -gemini_pcibios_read_config_dword(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned int *val) +gemini_pcibios_read_config_dword(struct pci_dev *dev, int offset, u32 *val) { - *val = grackle_read( pci_config_addr( bus, dev, (offset & ~(0x3)))); + *val = grackle_read(pci_config_addr(dev->bus->number, dev->devfn, + (offset & ~(0x3)))); return PCIBIOS_SUCCESSFUL; } int -gemini_pcibios_write_config_byte(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned char val) +gemini_pcibios_write_config_byte(struct pci_dev *dev, int offset, u8 val) { unsigned long reg; int shifts = offset & 0x3; + unsigned int addr = pci_config_addr(dev->bus->number, dev->devfn, + (offset & ~(0x3))) - reg = grackle_read( pci_config_addr( bus, dev, (offset & ~(0x3)))); + reg = grackle_read(addr); reg = (reg & ~(0xff << (shifts << 3))) | (val << (shifts << 3)); - grackle_write( pci_config_addr( bus, dev, (offset & ~(0x3))), reg ); + grackle_write(addr, reg ); return PCIBIOS_SUCCESSFUL; } int -gemini_pcibios_write_config_word(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned short val) +gemini_pcibios_write_config_word(struct pci_dev *dev, int offset, u16 val) { unsigned long reg; int shifts = offset & 0x3; + unsigned int addr = pci_config_addr(dev->bus->number, dev->devfn, + (offset & ~(0x3))) - reg = grackle_read( pci_config_addr( bus, dev, (offset & ~(0x3)))); + reg = grackle_read(addr); reg = (reg & ~(0xffff << (shifts << 3))) | (val << (shifts << 3)); - grackle_write( pci_config_addr( bus, dev, (offset & ~(0x3))), reg ); + grackle_write(addr, reg ); return PCIBIOS_SUCCESSFUL; } int -gemini_pcibios_write_config_dword(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned int val) +gemini_pcibios_write_config_dword(struct pci_dev *dev, int offset, u32 val) { - grackle_write( pci_config_addr( bus, dev, (offset & ~(0x3))), val ); + grackle_write(pci_config_addr(dev->bus->number, dev->devfn, + (offset & ~(0x3))), val); return PCIBIOS_SUCCESSFUL; } +static struct pci_ops gemini_pci_ops = +{ + gemini_read_config_byte, + gemini_read_config_word, + gemini_read_config_dword, + gemini_write_config_byte, + gemini_write_config_word, + gemini_write_config_dword +}; + void __init gemini_pcibios_fixup(void) { int i; @@ -92,12 +105,17 @@ } } -decl_config_access_method(gemini); /* The "bootloader" for Synergy boards does none of this for us, so we need to lay it all out ourselves... --Dan */ -void __init gemini_setup_pci_ptrs(void) +void __init gemini_find_bridges(void) { - set_config_access_method(gemini); + struct pci_controller* hose; + ppc_md.pcibios_fixup = gemini_pcibios_fixup; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + hose->ops = &gemini_pci_ops; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/gemini_prom.S linux.ac/arch/ppc/kernel/gemini_prom.S --- linux.vanilla/arch/ppc/kernel/gemini_prom.S Mon Apr 24 21:39:36 2000 +++ linux.ac/arch/ppc/kernel/gemini_prom.S Mon Dec 18 20:42:50 2000 @@ -39,6 +39,7 @@ ori r3,r3,MSR_IR|MSR_DR andc r4,r4,r3 mtmsr r4 + isync #if 0 /* zero out the bats now that the MMU is off */ prom_no_mmu: diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/gemini_setup.c linux.ac/arch/ppc/kernel/gemini_setup.c --- linux.vanilla/arch/ppc/kernel/gemini_setup.c Sat Oct 28 16:15:46 2000 +++ linux.ac/arch/ppc/kernel/gemini_setup.c Fri Dec 22 16:34:39 2000 @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -30,12 +29,12 @@ #include #include #include - #include + #include "local_irq.h" #include "open_pic.h" -void gemini_setup_pci_ptrs(void); +void gemini_find_bridges(void); static int gemini_get_clock_speed(void); extern void gemini_pcibios_fixup(void); @@ -116,23 +115,15 @@ void __init gemini_openpic_init(void) { - OpenPIC = (volatile struct OpenPIC *) - grackle_read(0x80005800 + 0x10); -#if 0 - grackle_write(GEMINI_MPIC_PCI_CFG + PCI_BASE_ADDRESS_0, - GEMINI_MPIC_ADDR); - grackle_write(GEMINI_MPIC_PCI_CFG + PCI_COMMAND, PCI_COMMAND_MEMORY); - - OpenPIC = (volatile struct OpenPIC *) GEMINI_MPIC_ADDR; -#endif + OpenPIC_Addr = grackle_read(GEMINI_MPIC_PCI_CFG + 0x10); OpenPIC_InitSenses = gemini_openpic_initsenses; OpenPIC_NumInitSenses = sizeof( gemini_openpic_initsenses ); - ioremap( GEMINI_MPIC_ADDR, sizeof( struct OpenPIC )); + ioremap( GEMINI_MPIC_ADDR, OPENPIC_SIZE); } -extern unsigned long loops_per_sec; +extern unsigned long loops_per_jiffy; extern int root_mountflags; extern char cmd_line[]; @@ -155,7 +146,7 @@ extern char cmd_line[]; - loops_per_sec = 50000000; + loops_per_jiffy = 50000000/HZ; #ifdef CONFIG_BLK_DEV_INITRD /* bootable off CDROM */ @@ -174,6 +165,8 @@ ppc_md.heartbeat_reset = HZ/8; ppc_md.heartbeat_count = 1; + /* Lookup PCI hosts */ + gemini_find_bridges(); /* take special pains to map the MPIC, since it isn't mapped yet */ gemini_openpic_init(); /* start the L2 */ @@ -213,13 +206,6 @@ return clock; } -#define L2CR_PIPE_LATEWR (0x01800000) /* late-write SRAM */ -#define L2CR_L2CTL (0x00100000) /* RAM control */ -#define L2CR_INST_DISABLE (0x00400000) /* disable for insn's */ -#define L2CR_L2I (0x00200000) /* global invalidate */ -#define L2CR_L2E (0x80000000) /* enable */ -#define L2CR_L2WT (0x00080000) /* write-through */ - void __init gemini_init_l2(void) { unsigned char reg, brev, fam, creg; @@ -286,7 +272,7 @@ cache |= ((1<>2)&0x3) { case 0: default: - freq = 66; + freq = 66667; break; case 1: - freq = 83; + freq = 83000; break; case 2: - freq = 100; + freq = 100000; break; } - freq *= 1000000; + freq *= 1000; divisor = 4; - decrementer_count = freq / HZ / divisor; - count_period_num = divisor; - count_period_den = freq / 1000000; -} - -int gemini_get_irq( struct pt_regs *regs ) -{ - int irq; - - irq = openpic_irq( smp_processor_id() ); - if (irq == OPENPIC_VEC_SPURIOUS) - /* - * Spurious interrupts should never be - * acknowledged - */ - irq = -1; - /* - * I would like to openpic_eoi here but there seem to be timing problems - * between the openpic ack and the openpic eoi. - * -- Cort - */ - return irq; -} - -void gemini_post_irq(struct pt_regs* regs, int irq) -{ - /* - * If it's an i8259 irq then we've already done the - * openpic irq. So we just check to make sure the controller - * is an openpic and if it is then eoi - * - * We do it this way since our irq_desc[irq].handler can change - * with RTL and no longer be open_pic -- Cort - */ - if ( irq >= open_pic_irq_offset) - openpic_eoi( smp_processor_id() ); + tb_ticks_per_jiffy = freq / HZ / divisor; + tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); } - void __init gemini_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { @@ -516,8 +452,6 @@ for(i = 0; i < GEMINI_LEDS; i++) gemini_led_off(i); - gemini_setup_pci_ptrs(); - ISA_DMA_THRESHOLD = 0; DMA_MODE_READ = 0; DMA_MODE_WRITE = 0; @@ -535,8 +469,8 @@ ppc_md.get_cpuinfo = gemini_get_cpuinfo; ppc_md.irq_cannonicalize = NULL; ppc_md.init_IRQ = gemini_init_IRQ; - ppc_md.get_irq = gemini_get_irq; - ppc_md.post_irq = gemini_post_irq; + ppc_md.get_irq = openpic_get_irq; + ppc_md.post_irq = NULL; ppc_md.init = NULL; ppc_md.restart = gemini_restart; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/hashtable.S linux.ac/arch/ppc/kernel/hashtable.S --- linux.vanilla/arch/ppc/kernel/hashtable.S Mon Nov 20 15:11:56 2000 +++ linux.ac/arch/ppc/kernel/hashtable.S Mon Dec 18 20:42:50 2000 @@ -56,7 +56,6 @@ #ifdef CONFIG_PPC64BRIDGE mfmsr r0 clrldi r0,r0,1 /* make sure it's in 32-bit mode */ - sync MTMSRD(r0) isync #endif @@ -112,23 +111,31 @@ #endif tophys(r2,r5) rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */ - lwz r6,0(r2) /* get linux-style pte */ ori r4,r4,1 /* set _PAGE_PRESENT bit in access */ + rlwinm r5,r4,5,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */ + rlwimi r5,r4,7,22,22 /* _PAGE_RW -> _PAGE_HWWRITE */ + ori r5,r5,0x100 /* set _PAGE_ACCESSED */ +retry: + lwz r6,0(r2) /* get linux-style pte */ andc. r0,r4,r6 /* check access & ~permission */ #ifdef CONFIG_SMP bne- hash_page_out /* return if access not permitted */ #else bnelr- #endif + andc. r0,r5,r6 /* any bits not yet set? */ + beq 2f - ori r6,r6,0x100 /* set _PAGE_ACCESSED in pte */ - rlwinm r5,r4,5,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */ - rlwimi r5,r4,7,22,22 /* _PAGE_RW -> _PAGE_HWWRITE */ - or r6,r6,r5 - stw r6,0(r2) /* update PTE (accessed/dirty bits) */ + /* Update the linux PTE atomically */ + lwarx r0,0,r2 /* refetch the pte and check */ + cmpw 0,r0,r6 /* that it hasn't been changed */ + bne- retry /* retry if it has */ + or r6,r6,r5 /* set accessed/dirty bits */ + stwcx. r6,0,r2 /* attempt to update PTE */ + bne- retry /* retry if someone got there first */ /* Convert linux-style PTE to low word of PPC-style PTE */ - rlwinm r4,r6,32-9,31,31 /* _PAGE_HWWRITE -> PP lsb */ +2: rlwinm r4,r6,32-9,31,31 /* _PAGE_HWWRITE -> PP lsb */ rlwimi r6,r6,32-1,31,31 /* _PAGE_USER -> PP (both bits now) */ ori r4,r4,0xe04 /* clear out reserved bits */ andc r6,r6,r4 /* PP=2 or 0, when _PAGE_HWWRITE */ @@ -263,7 +270,6 @@ std r5,0(r3) found_slot: std r6,8(r3) - sync #else /* CONFIG_SMP */ /* @@ -394,7 +400,6 @@ stw r5,0(r3) found_slot: stw r6,4(r3) - sync #else /* CONFIG_SMP */ /* @@ -428,6 +433,8 @@ #endif /* CONFIG_SMP */ #endif /* CONFIG_PPC64BRIDGE */ + sync /* make sure pte updates get to memory */ + /* * Update the hash table miss count. We only want misses here * that _are_ valid addresses and have a pte otherwise we don't @@ -517,7 +524,7 @@ a hash table miss while we have the hash table locked, or we'll get a deadlock. -paulus */ mfmsr r10 - sync + SYNC rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ mtmsr r0 SYNC @@ -616,7 +623,7 @@ a hash table miss while we have the hash table locked, or we'll get a deadlock. -paulus */ mfmsr r10 - sync + SYNC rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ mtmsr r0 SYNC diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/head.S linux.ac/arch/ppc/kernel/head.S --- linux.vanilla/arch/ppc/kernel/head.S Mon Nov 20 15:11:56 2000 +++ linux.ac/arch/ppc/kernel/head.S Mon Dec 18 20:42:50 2000 @@ -149,6 +149,8 @@ mr r28,r6 mr r27,r7 li r24,0 /* cpu # */ + /* N.B. prom_init clears the BSS even if it doesn't do + * anything else -- paulus. */ bl prom_init #ifdef CONFIG_APUS @@ -290,6 +292,7 @@ addi r3,r1,STACK_FRAME_OVERHEAD; \ li r20,MSR_KERNEL; \ bl transfer_to_handler; \ +i##n: \ .long hdlr; \ .long ret_from_except @@ -301,6 +304,7 @@ addi r3,r1,STACK_FRAME_OVERHEAD; \ li r20,MSR_KERNEL; \ bl transfer_to_handler; \ +i##n: \ .long hdlr; \ .long ret_from_except @@ -344,6 +348,7 @@ li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ bl transfer_to_handler +i0x300: .long do_page_fault .long ret_from_except @@ -384,6 +389,7 @@ li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ bl transfer_to_handler +i0x400: .long do_page_fault .long ret_from_except @@ -429,6 +435,7 @@ li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ bl transfer_to_handler +i0x600: .long AlignmentException .long ret_from_except @@ -441,6 +448,7 @@ li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ bl transfer_to_handler +i0x700: .long ProgramCheckException .long ret_from_except @@ -452,6 +460,7 @@ bne load_up_fpu /* if from user, just load it up */ li r20,MSR_KERNEL bl transfer_to_handler /* if from kernel, take a trap */ +i0x800: .long KernelFP .long ret_from_except @@ -575,7 +584,7 @@ mfmsr r0 /* Restore "normal" registers */ xoris r0,r0,MSR_TGPR>>16 mtcrf 0x80,r3 /* Restore CR0 */ - sync /* Some chip revs have problems here... */ + SYNC /* Some chip revs have problems here... */ mtmsr r0 b InstructionAccess @@ -646,7 +655,7 @@ mfmsr r0 /* Restore "normal" registers */ xoris r0,r0,MSR_TGPR>>16 mtcrf 0x80,r3 /* Restore CR0 */ - sync /* Some chip revs have problems here... */ + SYNC /* Some chip revs have problems here... */ mtmsr r0 b DataAccess @@ -843,7 +852,7 @@ #endif /* CONFIG_PPC64BRIDGE */ SYNC MTMSRD(r5) /* enable use of fpu now */ - SYNC + isync /* * For SMP, we don't do lazy FPU switching because it just gets too * horrendously complex, especially when a task switches from one CPU @@ -929,7 +938,7 @@ oris r5,r5,MSR_VEC@h SYNC mtmsr r5 /* enable use of AltiVec now */ - SYNC + isync /* * For SMP, we don't do lazy AltiVec switching because it just gets too * horrendously complex, especially when a task switches from one CPU @@ -1023,7 +1032,7 @@ oris r5,r5,MSR_VEC@h SYNC mtmsr r5 /* enable use of AltiVec now */ - SYNC + isync cmpi 0,r3,0 beqlr- /* if no previous owner, done */ addi r3,r3,THREAD /* want THREAD of task */ @@ -1064,7 +1073,7 @@ ori r5,r5,MSR_FP SYNC mtmsr r5 /* enable use of fpu now */ - SYNC + isync cmpi 0,r3,0 beqlr- /* if no previous owner, done */ addi r3,r3,THREAD /* want THREAD of task */ @@ -1163,6 +1172,7 @@ icbi r0,r14 /* flush the icache line */ cmpw r12,r13 bne 1b + isync /* * Map the memory where the exception handlers will @@ -1208,9 +1218,9 @@ mfmsr 20 xori r20,r20,MSR_DR - sync + SYNC mtmsr r20 - sync + isync lis r4,APUS_IPL_EMU@h @@ -1243,9 +1253,9 @@ mfmsr r20 xori r20,r20,MSR_DR - sync + SYNC mtmsr r20 - sync + isync stw r3,(_CCR+4)(r21); @@ -1284,7 +1294,7 @@ set to map the 0xf0000000 - 0xffffffff region */ mfmsr r0 rlwinm r0,r0,0,28,26 /* clear DR (0x10) */ - sync + SYNC mtmsr r0 isync @@ -1293,7 +1303,7 @@ #ifdef CONFIG_PPC64BRIDGE mfmsr r0 clrldi r0,r0,1 /* make sure it's in 32-bit mode */ - sync + SYNC MTMSRD(r0) isync #else @@ -1445,21 +1455,6 @@ li r3,0 mtspr SPRG2,r3 /* 0 => r1 has kernel sp */ - /* Clear out the BSS */ - lis r11,_end@ha - addi r11,r11,_end@l - lis r8,__bss_start@ha - addi r8,r8,__bss_start@l - subf r11,r8,r11 - addi r11,r11,3 - rlwinm. r11,r11,30,2,31 - beq 2f - addi r8,r8,-4 - mtctr r11 - li r0,0 -3: stwu r0,4(r8) - bdnz 3b -2: /* stack */ addi r1,r2,TASK_UNION_SIZE li r0,0 @@ -1504,7 +1499,7 @@ RFI /* Load up the kernel context */ 2: - SYNC /* Force all PTE updates to finish */ + sync /* Force all PTE updates to finish */ tlbia /* Clear all TLB entries */ sync /* wait for tlbia/tlbie to finish */ #ifdef CONFIG_SMP @@ -1745,3 +1740,12 @@ .globl cmd_line cmd_line: .space 512 + + .globl intercept_table +intercept_table: + .long 0, i0x100, i0x200, i0x300, i0x400, 0, i0x600, i0x700 + .long i0x800, 0, 0, 0, 0, i0xd00, 0, 0 + .long 0, 0, 0, i0x1300, 0, 0, 0, 0 + .long 0, 0, 0, 0, 0, 0, 0, 0 + .long 0, 0, 0, 0, 0, 0, 0, 0 + .long 0, 0, 0, 0, 0, 0, 0, 0 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/i8259.c linux.ac/arch/ppc/kernel/i8259.c --- linux.vanilla/arch/ppc/kernel/i8259.c Tue Jul 11 12:53:54 2000 +++ linux.ac/arch/ppc/kernel/i8259.c Mon Dec 18 20:42:55 2000 @@ -10,12 +10,15 @@ #define cached_A1 (cached_8259[0]) #define cached_21 (cached_8259[1]) +spinlock_t i8259_lock = SPIN_LOCK_UNLOCKED; + int i8259_pic_irq_offset; int i8259_irq(int cpu) { int irq; + spin_lock/*_irqsave*/(&i8259_lock/*, flags*/); /* * Perform an interrupt acknowledge cycle on controller 1 */ @@ -40,14 +43,20 @@ * interrupt */ outb(0x0b, 0x20); - if(~inb(0x20)&0x80) + if(~inb(0x20)&0x80) { + spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/); return -1; + } } + spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/); return irq; } static void i8259_mask_and_ack_irq(unsigned int irq_nr) { + unsigned long flags; + + spin_lock_irqsave(&i8259_lock, flags); if ( irq_nr >= i8259_pic_irq_offset ) irq_nr -= i8259_pic_irq_offset; @@ -63,6 +72,7 @@ outb(cached_21,0x21); outb(0x20,0x20); /* Non-specific EOI */ } + spin_unlock_irqrestore(&i8259_lock, flags); } static void i8259_set_irq_mask(int irq_nr) @@ -73,6 +83,9 @@ static void i8259_mask_irq(unsigned int irq_nr) { + unsigned long flags; + + spin_lock_irqsave(&i8259_lock, flags); if ( irq_nr >= i8259_pic_irq_offset ) irq_nr -= i8259_pic_irq_offset; if ( irq_nr < 8 ) @@ -80,11 +93,14 @@ else cached_A1 |= 1 << (irq_nr-8); i8259_set_irq_mask(irq_nr); + spin_unlock_irqrestore(&i8259_lock, flags); } static void i8259_unmask_irq(unsigned int irq_nr) { + unsigned long flags; + spin_lock_irqsave(&i8259_lock, flags); if ( irq_nr >= i8259_pic_irq_offset ) irq_nr -= i8259_pic_irq_offset; if ( irq_nr < 8 ) @@ -92,6 +108,13 @@ else cached_A1 &= ~(1 << (irq_nr-8)); i8259_set_irq_mask(irq_nr); + spin_unlock_irqrestore(&i8259_lock, flags); +} + +static void i8259_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + i8259_unmask_irq(irq); } struct hw_interrupt_type i8259_pic = { @@ -101,11 +124,15 @@ i8259_unmask_irq, i8259_mask_irq, i8259_mask_and_ack_irq, - 0 + i8259_end_irq, + NULL }; void __init i8259_init(void) { + unsigned long flags; + + spin_lock_irqsave(&i8259_lock, flags); /* init master interrupt controller */ outb(0x11, 0x20); /* Start init sequence */ outb(0x00, 0x21); /* Vector base */ @@ -120,7 +147,7 @@ outb(0xFF, 0xA1); /* Mask all */ outb(cached_A1, 0xA1); outb(cached_21, 0x21); + spin_unlock_irqrestore(&i8259_lock, flags); request_irq( i8259_pic_irq_offset + 2, no_action, SA_INTERRUPT, "82c59 secondary cascade", NULL ); - enable_irq(i8259_pic_irq_offset + 2); /* Enable cascade interrupt */ } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/idle.c linux.ac/arch/ppc/kernel/idle.c --- linux.vanilla/arch/ppc/kernel/idle.c Sat Oct 28 16:15:46 2000 +++ linux.ac/arch/ppc/kernel/idle.c Mon Dec 18 20:43:01 2000 @@ -47,24 +47,35 @@ int idled(void) { + int do_power_save = 0; + + /* only sleep on the 603-family/750 processors */ + switch (_get_PVR() >> 16) { + case 3: /* 603 */ + case 6: /* 603e */ + case 7: /* 603ev */ + case 8: /* 750 */ + case 12: /* 7400 */ + do_power_save = 1; + } + /* endless loop with no priority at all */ current->nice = 20; current->counter = -100; init_idle(); for (;;) { - __sti(); - - check_pgt_cache(); - - /*if ( !current->need_resched && zero_paged_on ) zero_paged();*/ - if ( !current->need_resched && htab_reclaim_on ) htab_reclaim(); - if ( !current->need_resched ) power_save(); + /*if ( !current->need_resched && zero_paged_on ) + zero_paged();*/ + if (!current->need_resched && htab_reclaim_on) + htab_reclaim(); + if (do_power_save && !current->need_resched) + power_save(); -#ifdef CONFIG_SMP - if (current->need_resched) -#endif + if (current->need_resched) { schedule(); + check_pgt_cache(); + } } return 0; } @@ -280,29 +291,23 @@ { unsigned long msr, hid0; - /* only sleep on the 603-family/750 processors */ - switch (_get_PVR() >> 16) { - case 3: /* 603 */ - case 6: /* 603e */ - case 7: /* 603ev */ - case 8: /* 750 */ - case 12: /* 7400 */ - save_flags(msr); - __cli(); - if (!current->need_resched) { - asm("mfspr %0,1008" : "=r" (hid0) :); - hid0 &= ~(HID0_NAP | HID0_SLEEP | HID0_DOZE); - hid0 |= (powersave_nap? HID0_NAP: HID0_DOZE) | HID0_DPM; - asm("mtspr 1008,%0" : : "r" (hid0)); + __save_flags(msr); + __cli(); + if (!current->need_resched) { + asm("mfspr %0,1008" : "=r" (hid0) :); + hid0 &= ~(HID0_NAP | HID0_SLEEP | HID0_DOZE); + hid0 |= (powersave_nap? HID0_NAP: HID0_DOZE) | HID0_DPM; + asm("mtspr 1008,%0" : : "r" (hid0)); - /* set the POW bit in the MSR, and enable interrupts - * so we wake up sometime! */ - __sti(); /* this keeps rtl from getting confused -- Cort */ - _nmask_and_or_msr(0, MSR_POW | MSR_EE); - } - restore_flags(msr); - default: - return; + /* set the POW bit in the MSR, and enable interrupts + * so we wake up sometime! */ + __sti(); /* this keeps rtl from getting confused -- Cort */ + /* but introduces a race - if an interrupt occurs here + which makes a task runnable, we still go to sleep. + Fortunately, only until the next interrupt. + -- paulus. */ + _nmask_and_or_msr(0, MSR_POW | MSR_EE); } + __restore_flags(msr); } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/indirect_pci.c linux.ac/arch/ppc/kernel/indirect_pci.c --- linux.vanilla/arch/ppc/kernel/indirect_pci.c Thu Oct 7 18:17:08 1999 +++ linux.ac/arch/ppc/kernel/indirect_pci.c Mon Dec 18 20:43:01 2000 @@ -9,113 +9,59 @@ * 2 of the License, or (at your option) any later version. */ +#include #include -#include -#include - -unsigned int * pci_config_address; -unsigned char * pci_config_data; - -int indirect_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) -{ - unsigned long flags; - - save_flags(flags); cli(); - - out_be32(pci_config_address, - ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80); - - *val= in_8(pci_config_data + (offset&3)); - - restore_flags(flags); - return PCIBIOS_SUCCESSFUL; -} - -int indirect_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) -{ - unsigned long flags; - - if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER; - - save_flags(flags); cli(); - - out_be32(pci_config_address, - ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80); - - *val= in_le16((unsigned short *)(pci_config_data + (offset&3))); - - restore_flags(flags); - return PCIBIOS_SUCCESSFUL; -} - -int indirect_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) -{ - unsigned long flags; - - if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER; - - save_flags(flags); cli(); - - out_be32(pci_config_address, - ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80); - - *val= in_le32((unsigned *)pci_config_data); - - restore_flags(flags); - return PCIBIOS_SUCCESSFUL; -} +#include +#include +#include +#include -int indirect_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) -{ - unsigned long flags; - - save_flags(flags); cli(); - - out_be32(pci_config_address, - ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80); - - out_8(pci_config_data + (offset&3), val); - - restore_flags(flags); - return PCIBIOS_SUCCESSFUL; -} - -int indirect_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) -{ - unsigned long flags; - - if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER; - - save_flags(flags); cli(); - - out_be32(pci_config_address, - ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80); - - out_le16((unsigned short *)(pci_config_data + (offset&3)), val); - - restore_flags(flags); - return PCIBIOS_SUCCESSFUL; +#include +#include +#include +#include +#include + +#include "pci.h" + +#define cfg_read(val, addr, type, op) *val = op((type)(addr)) +#define cfg_write(val, addr, type, op) op((type *)(addr), (val)) + +#define INDIRECT_PCI_OP(rw, size, type, op, mask) \ +static int \ +indirect_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + struct pci_controller *hose = dev->sysdata; \ + \ + out_be32(hose->cfg_addr, \ + ((offset & 0xfc) << 24) | (dev->devfn << 16) \ + | (dev->bus->number << 8) | 0x80); \ + cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \ + return PCIBIOS_SUCCESSFUL; \ +} + +INDIRECT_PCI_OP(read, byte, u8 *, in_8, 3) +INDIRECT_PCI_OP(read, word, u16 *, in_le16, 2) +INDIRECT_PCI_OP(read, dword, u32 *, in_le32, 0) +INDIRECT_PCI_OP(write, byte, u8, out_8, 3) +INDIRECT_PCI_OP(write, word, u16, out_le16, 2) +INDIRECT_PCI_OP(write, dword, u32, out_le32, 0) + +static struct pci_ops indirect_pci_ops = +{ + indirect_read_config_byte, + indirect_read_config_word, + indirect_read_config_dword, + indirect_write_config_byte, + indirect_write_config_word, + indirect_write_config_dword +}; + +void __init +setup_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data) +{ + hose->ops = &indirect_pci_ops; + hose->cfg_addr = (unsigned int *) ioremap(cfg_addr, 4); + hose->cfg_data = (unsigned char *) ioremap(cfg_data, 4); } -int indirect_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) -{ - unsigned long flags; - - if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER; - - save_flags(flags); cli(); - - out_be32(pci_config_address, - ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80); - - out_le32((unsigned *)pci_config_data, val); - - restore_flags(flags); - return PCIBIOS_SUCCESSFUL; -} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/irq.c linux.ac/arch/ppc/kernel/irq.c --- linux.vanilla/arch/ppc/kernel/irq.c Mon Nov 20 15:11:56 2000 +++ linux.ac/arch/ppc/kernel/irq.c Mon Dec 18 20:43:11 2000 @@ -41,11 +41,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include @@ -64,15 +64,18 @@ #include "local_irq.h" -extern volatile unsigned long ipi_count; +atomic_t ipi_recv; +atomic_t ipi_sent; void enable_irq(unsigned int irq_nr); void disable_irq(unsigned int irq_nr); -volatile unsigned char *chrp_int_ack_special; +static void register_irq_proc (unsigned int irq); #define MAXCOUNT 10000000 -irq_desc_t irq_desc[NR_IRQS]; +irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = + { [0 ... NR_IRQS-1] = { 0, NULL, NULL, 0, SPIN_LOCK_UNLOCKED}}; + int ppc_spurious_interrupts = 0; struct irqaction *ppc_irq_action[NR_IRQS]; unsigned int ppc_cached_irq_mask[NR_MASK_WORDS]; @@ -115,52 +118,136 @@ kfree(ptr); } +int +setup_irq(unsigned int irq, struct irqaction * new) +{ + int shared = 0; + unsigned long flags; + struct irqaction *old, **p; + irq_desc_t *desc = irq_desc + irq; + + /* + * Some drivers like serial.c use request_irq() heavily, + * so we have to be careful not to interfere with a + * running system. + */ + if (new->flags & SA_SAMPLE_RANDOM) { + /* + * This function might sleep, we want to call it first, + * outside of the atomic block. + * Yes, this might clear the entropy pool if the wrong + * driver is attempted to be loaded, without actually + * installing a new handler, but is this really a problem, + * only the sysadmin is able to do this. + */ + rand_initialize_irq(irq); + } + + /* + * The following block of code has to be executed atomically + */ + spin_lock_irqsave(&desc->lock,flags); + p = &desc->action; + if ((old = *p) != NULL) { + /* Can't share interrupts unless both agree to */ + if (!(old->flags & new->flags & SA_SHIRQ)) { + spin_unlock_irqrestore(&desc->lock,flags); + return -EBUSY; + } + + /* add new interrupt at end of irq queue */ + do { + p = &old->next; + old = *p; + } while (old); + shared = 1; + } + + *p = new; + + if (!shared) { + desc->depth = 0; + desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING); + unmask_irq(irq); + } + spin_unlock_irqrestore(&desc->lock,flags); + + register_irq_proc(irq); + return 0; +} + +/* This could be promoted to a real free_irq() ... */ +static int +do_free_irq(int irq, void* dev_id) +{ + irq_desc_t *desc; + struct irqaction **p; + unsigned long flags; + + desc = irq_desc + irq; + spin_lock_irqsave(&desc->lock,flags); + p = &desc->action; + for (;;) { + struct irqaction * action = *p; + if (action) { + struct irqaction **pp = p; + p = &action->next; + if (action->dev_id != dev_id) + continue; + + /* Found it - now remove it from the list of entries */ + *pp = action->next; + if (!desc->action) { + desc->status |= IRQ_DISABLED; + mask_irq(irq); + } + spin_unlock_irqrestore(&desc->lock,flags); + +#ifdef CONFIG_SMP + /* Wait to make sure it's not being used on another CPU */ + while (desc->status & IRQ_INPROGRESS) + barrier(); +#endif + irq_kfree(action); + return 0; + } + printk("Trying to free free IRQ%d\n",irq); + spin_unlock_irqrestore(&desc->lock,flags); + break; + } + return -ENOENT; +} + #if (defined(CONFIG_8xx) || defined(CONFIG_8260)) /* Name change so we can catch standard drivers that potentially mess up * the internal interrupt controller on 8xx and 8260. Just bear with me, * I don't like this either and I am searching a better solution. For * now, this is what I need. -- Dan */ -int request_8xxirq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), +#define request_irq request_8xxirq #elif defined(CONFIG_APUS) -int request_sysirq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), -#else -int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), +#define request_irq request_sysirq +#define free_irq sys_free_irq #endif + +int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char * devname, void *dev_id) { - struct irqaction *old, **p, *action; - unsigned long flags; + struct irqaction *action; + int retval; if (irq >= NR_IRQS) return -EINVAL; if (!handler) - { - /* Free */ - p = &irq_desc[irq].action; - while ((action = *p) != NULL && action->dev_id != dev_id) - p = &action->next; - if (action == NULL) - return -ENOENT; - - /* Found it - now free it */ - save_flags(flags); - cli(); - *p = action->next; - if (irq_desc[irq].action == NULL) - disable_irq(irq); - restore_flags(flags); - irq_kfree(action); - return 0; - } + /* We could implement really free_irq() instead of that... */ + return do_free_irq(irq, dev_id); action = (struct irqaction *) irq_kmalloc(sizeof(struct irqaction), GFP_KERNEL); - if (!action) + if (!action) { + printk(KERN_ERR "irq_kmalloc() failed for irq %d !\n", irq); return -ENOMEM; - - save_flags(flags); - cli(); + } action->handler = handler; action->flags = irqflags; @@ -168,57 +255,109 @@ action->name = devname; action->dev_id = dev_id; action->next = NULL; - enable_irq(irq); - - p = &irq_desc[irq].action; - if ((old = *p) != NULL) { - /* Can't share interrupts unless both agree to */ - if (!(old->flags & action->flags & SA_SHIRQ)) - return -EBUSY; - /* add new interrupt at end of irq queue */ - do { - p = &old->next; - old = *p; - } while (old); - } - *p = action; - - restore_flags(flags); + retval = setup_irq(irq, action); + if (retval) + kfree(action); + return 0; } -#ifdef CONFIG_APUS -void sys_free_irq(unsigned int irq, void *dev_id) -{ - sys_request_irq(irq, NULL, 0, NULL, dev_id); -} -#else void free_irq(unsigned int irq, void *dev_id) { -#if (defined(CONFIG_8xx) || defined(CONFIG_8260)) - request_8xxirq(irq, NULL, 0, NULL, dev_id); -#else request_irq(irq, NULL, 0, NULL, dev_id); -#endif } -#endif -/* XXX should implement irq disable depth like on intel */ -void disable_irq_nosync(unsigned int irq_nr) +/* + * Generic enable/disable code: this just calls + * down into the PIC-specific version for the actual + * hardware disable after having gotten the irq + * controller lock. + */ + +/** + * disable_irq_nosync - disable an irq without waiting + * @irq: Interrupt to disable + * + * Disable the selected interrupt line. Disables of an interrupt + * stack. Unlike disable_irq(), this function does not ensure existing + * instances of the IRQ handler have completed before returning. + * + * This function may be called from IRQ context. + */ + + void disable_irq_nosync(unsigned int irq) { - mask_irq(irq_nr); + irq_desc_t *desc = irq_desc + irq; + unsigned long flags; + + spin_lock_irqsave(&desc->lock, flags); + if (!desc->depth++) { + if (!(desc->status & IRQ_PER_CPU)) + desc->status |= IRQ_DISABLED; + mask_irq(irq); + } + spin_unlock_irqrestore(&desc->lock, flags); } -void disable_irq(unsigned int irq_nr) +/** + * disable_irq - disable an irq and wait for completion + * @irq: Interrupt to disable + * + * Disable the selected interrupt line. Disables of an interrupt + * stack. That is for two disables you need two enables. This + * function waits for any pending IRQ handlers for this interrupt + * to complete before returning. If you use this function while + * holding a resource the IRQ handler may need you will deadlock. + * + * This function may be called - with care - from IRQ context. + */ + +void disable_irq(unsigned int irq) { - mask_irq(irq_nr); - synchronize_irq(); + disable_irq_nosync(irq); + + if (!local_irq_count(smp_processor_id())) { + do { + barrier(); + } while (irq_desc[irq].status & IRQ_INPROGRESS); + } } -void enable_irq(unsigned int irq_nr) +/** + * enable_irq - enable interrupt handling on an irq + * @irq: Interrupt to enable + * + * Re-enables the processing of interrupts on this IRQ line + * providing no disable_irq calls are now in effect. + * + * This function may be called from IRQ context. + */ + +void enable_irq(unsigned int irq) { - unmask_irq(irq_nr); + irq_desc_t *desc = irq_desc + irq; + unsigned long flags; + + spin_lock_irqsave(&desc->lock, flags); + switch (desc->depth) { + case 1: { + unsigned int status = desc->status & ~IRQ_DISABLED; + desc->status = status; + if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { + desc->status = status | IRQ_REPLAY; + hw_resend_irq(desc->handler,irq); + } + unmask_irq(irq); + /* fall-through */ + } + default: + desc->depth--; + break; + case 0: + printk("enable_irq(%u) unbalanced\n", irq); + } + spin_unlock_irqrestore(&desc->lock, flags); } int get_irq_list(char *buf) @@ -257,15 +396,41 @@ } len += sprintf(buf+len, "\n"); } +#ifdef CONFIG_TAU + len += sprintf(buf+len, "TAU: "); + for (j = 0; j < smp_num_cpus; j++) + len += sprintf(buf+len, "%10u ", + tau_interrupts(j)); + len += sprintf(buf+len, "\n"); +#endif #ifdef CONFIG_SMP /* should this be per processor send/receive? */ - len += sprintf(buf+len, "IPI: %10lu\n", ipi_count); + len += sprintf(buf+len, "IPI (recv/sent): %10u/%u\n", + atomic_read(&ipi_recv), atomic_read(&ipi_sent)); #endif len += sprintf(buf+len, "BAD: %10u\n", ppc_spurious_interrupts); return len; #endif /* CONFIG_APUS */ } +static inline void +handle_irq_event(int irq, struct pt_regs *regs, struct irqaction *action) +{ + int status = 0; + + if (!(action->flags & SA_INTERRUPT)) + __sti(); + + do { + status |= action->flags; + action->handler(irq, action->dev_id, regs); + action = action->next; + } while (action); + if (status & SA_SAMPLE_RANDOM) + add_interrupt_randomness(irq); + __cli(); +} + /* * Eventually, this should take an array of interrupts and an array size * so it can dispatch multiple interrupts. @@ -275,33 +440,80 @@ int status; struct irqaction *action; int cpu = smp_processor_id(); + irq_desc_t *desc = irq_desc + irq; - mask_and_ack_irq(irq); - status = 0; - action = irq_desc[irq].action; kstat.irqs[cpu][irq]++; - if (action && action->handler) { - if (!(action->flags & SA_INTERRUPT)) - __sti(); - do { - status |= action->flags; - action->handler(irq, action->dev_id, regs); - action = action->next; - } while ( action ); - __cli(); - if (irq_desc[irq].handler) { - if (irq_desc[irq].handler->end) - irq_desc[irq].handler->end(irq); - else if (irq_desc[irq].handler->enable) - irq_desc[irq].handler->enable(irq); - } - } else { - ppc_spurious_interrupts++; - printk(KERN_DEBUG "Unhandled interrupt %x, disabled\n", irq); - disable_irq(irq); + spin_lock(&desc->lock); + ack_irq(irq); + /* + REPLAY is when Linux resends an IRQ that was dropped earlier + WAITING is used by probe to mark irqs that are being tested + */ + status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING); + if (!(status & IRQ_PER_CPU)) + status |= IRQ_PENDING; /* we _want_ to handle it */ + + /* + * If the IRQ is disabled for whatever reason, we cannot + * use the action we have. + */ + action = NULL; + if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + action = desc->action; + if (!action || !action->handler) { + ppc_spurious_interrupts++; + printk(KERN_DEBUG "Unhandled interrupt %x, disabled\n", irq); + disable_irq(irq); + goto out; + } + status &= ~IRQ_PENDING; /* we commit to handling */ + if (!(status & IRQ_PER_CPU)) + status |= IRQ_INPROGRESS; /* we are handling it */ + } + desc->status = status; + + /* + * If there is no IRQ handler or it was disabled, exit early. + Since we set PENDING, if another processor is handling + a different instance of this same irq, the other processor + will take care of it. + */ + if (!action) + goto out; + + + /* + * Edge triggered interrupts need to remember + * pending events. + * This applies to any hw interrupts that allow a second + * instance of the same irq to arrive while we are in do_IRQ + * or in the handler. But the code here only handles the _second_ + * instance of the irq, not the third or fourth. So it is mostly + * useful for irq hardware that does not mask cleanly in an + * SMP environment. + */ + for (;;) { + spin_unlock(&desc->lock); + handle_irq_event(irq, regs, action); + spin_lock(&desc->lock); + + if (!(desc->status & IRQ_PENDING)) + break; + desc->status &= ~IRQ_PENDING; + } + desc->status &= ~IRQ_INPROGRESS; +out: + /* + * The ->end() handler has to deal with interrupts which got + * disabled while the handler was running. + */ + if (irq_desc[irq].handler) { if (irq_desc[irq].handler->end) irq_desc[irq].handler->end(irq); + else if (irq_desc[irq].handler->enable) + irq_desc[irq].handler->enable(irq); } + spin_unlock(&desc->lock); } int do_IRQ(struct pt_regs *regs, int isfake) @@ -320,6 +532,7 @@ { printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n", irq, regs->nip); + /* That's not SMP safe ... but who cares ? */ ppc_spurious_interrupts++; } goto out; @@ -362,7 +575,7 @@ #ifdef CONFIG_SMP unsigned char global_irq_holder = NO_PROC_ID; -unsigned volatile int global_irq_lock; +unsigned volatile long global_irq_lock; /* pendantic :long for set_bit--RR*/ atomic_t global_irq_count; atomic_t global_bh_count; @@ -694,6 +907,7 @@ err = parse_hex_value(buffer, count, &new_value); +/* Why is this disabled ? --BenH */ #if 0/*CONFIG_SMP*/ /* * Do not allow disabling IRQs completely - it's a too easy diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/local_irq.h linux.ac/arch/ppc/kernel/local_irq.h --- linux.vanilla/arch/ppc/kernel/local_irq.h Sun Sep 17 12:22:37 2000 +++ linux.ac/arch/ppc/kernel/local_irq.h Mon Nov 20 17:10:46 2000 @@ -15,8 +15,9 @@ extern int ppc_spurious_interrupts; extern int ppc_second_irq; extern struct irqaction *ppc_irq_action[NR_IRQS]; -extern unsigned int ppc_cached_irq_mask[NR_MASK_WORDS]; -extern unsigned int ppc_lost_interrupts[NR_MASK_WORDS]; +/* pendatic: these are long because they are used with set_bit --RR */ +extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; +extern unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; extern atomic_t ppc_n_lost_interrupts; #endif /* _PPC_KERNEL_LOCAL_IRQ_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/m8260_setup.c linux.ac/arch/ppc/kernel/m8260_setup.c --- linux.vanilla/arch/ppc/kernel/m8260_setup.c Sat Oct 28 16:15:46 2000 +++ linux.ac/arch/ppc/kernel/m8260_setup.c Mon Dec 18 20:44:15 2000 @@ -289,7 +289,7 @@ ppc_ide_md.check_region = m8xx_ide_check_region; ppc_ide_md.request_region = m8xx_ide_request_region; ppc_ide_md.release_region = m8xx_ide_release_region; - ppc_ide_md.fix_driveid = m8xx_ide_fix_driveid; + ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid; ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports; ppc_ide_md.ide_request_irq = m8xx_ide_request_irq; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/m8xx_setup.c linux.ac/arch/ppc/kernel/m8xx_setup.c --- linux.vanilla/arch/ppc/kernel/m8xx_setup.c Sat Oct 28 16:15:46 2000 +++ linux.ac/arch/ppc/kernel/m8xx_setup.c Mon Dec 18 20:44:15 2000 @@ -376,12 +376,6 @@ #endif } -void -m8xx_ide_fix_driveid(struct hd_driveid *id) -{ - ppc_generic_ide_fix_driveid(id); -} - /* We can use an external IDE controller or wire the IDE interface to * the internal PCMCIA controller. */ @@ -518,7 +512,7 @@ ppc_ide_md.check_region = m8xx_ide_check_region; ppc_ide_md.request_region = m8xx_ide_request_region; ppc_ide_md.release_region = m8xx_ide_release_region; - ppc_ide_md.fix_driveid = m8xx_ide_fix_driveid; + ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid; ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports; ppc_ide_md.ide_request_irq = m8xx_ide_request_irq; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/misc.S linux.ac/arch/ppc/kernel/misc.S --- linux.vanilla/arch/ppc/kernel/misc.S Mon Nov 20 15:11:56 2000 +++ linux.ac/arch/ppc/kernel/misc.S Mon Dec 18 20:44:15 2000 @@ -37,6 +37,14 @@ .text + .align 5 +_GLOBAL(__delay) + cmpwi 0,r3,0 + mtctr r3 + beqlr +1: bdnz 1b + blr + /* * Returns (address we're running at) - (address we were linked at) * for use before the text and data are mapped to KERNELBASE. @@ -82,16 +90,16 @@ lwz r7,ppc_n_lost_interrupts@l(r7) cmpi 0,r7,0 /* lost interrupts to process first? */ bne- do_lost_interrupts -1: sync +1: SYNC mtmsr r3 - isync + SYNC blr _GLOBAL(__no_use_cli) mfmsr r0 /* Get current interrupt state */ rlwinm r3,r0,16+1,32-1,31 /* Extract old value of 'EE' */ rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */ - sync /* Some chip revs have problems here... */ + SYNC /* Some chip revs have problems here... */ mtmsr r0 /* Update machine state */ blr /* Done */ @@ -102,7 +110,7 @@ ori r3,r3,MSR_EE /* Turn on 'EE' bit */ cmpi 0,r4,0 /* lost interrupts to process first? */ bne- do_lost_interrupts - sync /* Some chip revs have problems here... */ + SYNC /* Some chip revs have problems here... */ mtmsr r3 /* Update machine state */ blr @@ -121,7 +129,7 @@ cmpi 0,r4,0 bne- 1b lwz r3,8(r1) - sync + SYNC mtmsr r3 lwz r0,20(r1) mtlr r0 @@ -137,8 +145,9 @@ mfmsr r0 /* Get current msr */ andc r0,r0,r3 /* And off the bits set in r3 (first parm) */ or r0,r0,r4 /* Or on the bits in r4 (second parm) */ - sync /* Some chip revs have problems here... */ + SYNC /* Some chip revs have problems here... */ mtmsr r0 /* Update machine state */ + isync blr /* Done */ @@ -148,7 +157,7 @@ _GLOBAL(_tlbia) #if defined(CONFIG_SMP) mfmsr r10 - sync + SYNC rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ mtmsr r0 SYNC @@ -161,7 +170,6 @@ bne- 10b stwcx. r8,0,r9 bne- 10b - eieio #endif /* CONFIG_SMP */ sync tlbia @@ -182,7 +190,7 @@ _GLOBAL(_tlbie) #if defined(CONFIG_SMP) mfmsr r10 - sync + SYNC rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ mtmsr r0 SYNC @@ -228,7 +236,7 @@ ori r3,r3,HID0_ICFI mtspr HID0,r3 #endif /* CONFIG_8xx */ - SYNC + isync blr /* @@ -259,7 +267,6 @@ 2: icbi 0,r6 addi r6,r6,CACHE_LINE_SIZE bdnz 2b - sync isync blr @@ -717,6 +724,8 @@ mr r3,r1 /* Close enough */ blr +#if 0 +/* isn't it just easier to use the mtspr/mfspr inline macros?? --Troy */ _GLOBAL(_get_THRM1) mfspr r3,THRM1 blr @@ -740,6 +749,7 @@ _GLOBAL(_set_THRM3) mtspr THRM3,r3 blr +#endif _GLOBAL(_get_PVR) mfspr r3,PVR @@ -755,6 +765,12 @@ mfspr r3,HID0 blr +_GLOBAL(_set_HID0) + sync + mtspr HID0, r3 + SYNC /* Handle erratas in some cases */ + blr + _GLOBAL(_get_ICTC) mfspr r3,ICTC blr @@ -763,7 +779,6 @@ mtspr ICTC,r3 blr - /* L2CR functions Copyright © 1997-1998 by PowerLogix R & D, Inc. @@ -785,6 +800,17 @@ /* Thur, Dec. 12, 1998. - First public release, contributed by PowerLogix. + *********** + Sat, Aug. 7, 1999. + - Terry: Made sure code disabled interrupts before running. (Previously + it was assumed interrupts were already disabled). + - Terry: Updated for tentative G4 support. 4MB of memory is now flushed + instead of 2MB. (Prob. only 3 is necessary). + - Terry: Updated for workaround to HID0[DPM] processor bug + during global invalidates. + *********** + Thu, July 13, 2000. + - Terry: Added isync to correct for an errata. Author: Terry Greeniaus (tgree@phys.ualberta.ca) Please e-mail updates to this file to me, thanks! @@ -823,82 +849,94 @@ causes cache pushes from the L1 cache to go to the L2 cache instead of to main memory. */ - +/* + * Summary: this procedure ignores the L2I bit in the value passed in, + * flushes the cache if it was already enabled, always invalidates the + * cache, then enables the cache if the L2E bit is set in the value + * passed in. + * -- paulus. + */ _GLOBAL(_set_L2CR) - /* Make sure this is a 750 chip */ + /* Make sure this is a 750 or 7400 chip */ mfspr r4,PVR rlwinm r4,r4,16,16,31 - cmplwi r4,0x0008 - beq thisIs750 - cmplwi r4,0x000c - beq thisIs750 - li r3,-1 - blr - -thisIs750: - /* Get the current enable bit of the L2CR into r4 */ - mfspr r4,L2CR - mfmsr r7 - - /* See if we want to perform a global inval this time. */ - rlwinm r6,r3,0,10,10 /* r6 contains the new invalidate bit */ - rlwinm. r5,r3,0,0,0 /* r5 contains the new enable bit */ - rlwinm r3,r3,0,11,9 /* Turn off the invalidate bit */ - rlwimi r3,r4,0,0,0 /* Keep the enable bit the same as it was. */ - bne dontDisableCache /* Only disable the cache if L2CRApply - has the enable bit off */ - -disableCache: - /* Disable the cache. First, we turn off interrupts. - An interrupt while we are flushing the cache could bring - in data which may not get properly flushed. */ - rlwinm r4,r7,0,17,15 /* Turn off EE bit */ + cmpwi r4,0x0008 + cmpwi cr1,r4,0x000c + cror 2,2,4*cr1+2 + bne 99f + + /* Turn off interrupts and data relocation. */ + mfmsr r7 /* Save MSR in r7 */ + rlwinm r4,r7,0,17,15 + rlwinm r4,r4,0,28,26 /* Turn off DR bit */ sync mtmsr r4 - sync + isync + + /* Get the current enable bit of the L2CR into r4 */ + mfspr r4,L2CR -/* - Now, read the first 2MB of memory to put new data in the cache. - (Actually we only need the size of the L2 cache plus the size - of the L1 cache, but 2MB will cover everything just to be safe). -*/ - lis r4,0x0001 + /* Tweak some bits */ + rlwinm r5,r3,0,0,0 /* r5 contains the new enable bit */ + rlwinm r3,r3,0,11,9 /* Turn off the invalidate bit */ + rlwinm r3,r3,0,1,31 /* Turn off the enable bit */ + + /* Check to see if we need to flush */ + rlwinm. r4,r4,0,0,0 + beq 2f + + /* Flush the cache. First, read the first 4MB of memory (physical) to + * put new data in the cache. (Actually we only need + * the size of the L2 cache plus the size of the L1 cache, but 4MB will + * cover everything just to be safe). + */ + + /**** Might be a good idea to set L2DO here - to prevent instructions + from getting into the cache. But since we invalidate + the next time we enable the cache it doesn't really matter. + ****/ + + lis r4,0x0002 mtctr r4 - lis r4,KERNELBASE@h -1: lwzx r0,r0,r4 - addi r4,r4,0x0020 /* Go to start of next cache line */ + li r4,0 +1: + lwzx r0,r0,r4 + addi r4,r4,32 /* Go to start of next cache line */ bdnz 1b - /* Now, flush the first 2MB of memory */ - lis r4,0x0001 + /* Now, flush the first 4MB of memory */ + lis r4,0x0002 mtctr r4 - lis r4,KERNELBASE@h + li r4,0 sync -2: dcbf r0,r4 - addi r4,r4,0x0020 /* Go to start of next cache line */ - bdnz 2b - - /* Turn off the L2CR enable bit. */ - rlwinm r3,r3,0,1,31 - -dontDisableCache: - /* Set up the L2CR configuration bits */ +1: + dcbf r0,r4 + addi r4,r4,32 /* Go to start of next cache line */ + bdnz 1b + +2: + /* Set up the L2CR configuration bits (and switch L2 off) */ sync mtspr L2CR,r3 sync - /* Reenable interrupts if necessary. */ - mtmsr r7 + /* Before we perform the global invalidation, we must disable dynamic + * power management via HID0[DPM] to work around a processor bug where + * DPM can possibly interfere with the state machine in the processor + * that invalidates the L2 cache tags. + */ + mfspr r8,HID0 /* Save HID0 in r8 */ + rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */ sync - - cmplwi r6,0 - beq noInval - + mtspr HID0,r4 /* Disable DPM */ + sync + /* Perform a global invalidation */ oris r3,r3,0x0020 sync mtspr L2CR,r3 sync + isync /* For errata */ /* Wait for the invalidation to complete */ 3: mfspr r3,L2CR @@ -910,27 +948,38 @@ mtspr L2CR,r3 sync -noInval: + /* Restore HID0[DPM] to whatever it was before */ + sync + mtspr 1008,r8 + sync + /* See if we need to enable the cache */ cmplwi r5,0 - beqlr + beq 4f /* Enable the cache */ oris r3,r3,0x8000 mtspr L2CR,r3 sync + + /* Restore MSR (restores EE and DR bits to original state) */ +4: SYNC + mtmsr r7 + isync + blr + +99: li r3,-1 blr _GLOBAL(_get_L2CR) /* Make sure this is a 750 chip */ mfspr r3,PVR - rlwinm r3,r3,16,16,31 - cmplwi r3,0x0008 - beq 1f - cmplwi r3,0x000c + srwi r3,r3,16 + cmpwi r3,0x0008 + cmpwi cr1,r3,0x000c li r3,0 + cror 2,2,4*cr1+2 bnelr -1: /* Return the L2CR contents */ mfspr r3,L2CR blr @@ -986,15 +1035,6 @@ blr #endif -_GLOBAL(__clear_msr_me) - mfmsr r0 /* Get current interrupt state */ - lis r3,0 - ori r3,r3,MSR_ME - andc r0,r0,r3 /* Clears bit in (r4) */ - sync /* Some chip revs have problems here */ - mtmsr r0 /* Update machine state */ - blr - /* * Create a kernel thread * kernel_thread(fn, arg, flags) @@ -1244,16 +1284,20 @@ .long sys_getrlimit /* 190 */ .long sys_ni_syscall /* 191 */ /* Unused */ .long sys_ni_syscall /* 192 - reserved - mmap2 */ - .long sys_ni_syscall /* 193 - reserved - truncate64 */ - .long sys_ni_syscall /* 194 - reserved - ftruncate64 */ - .long sys_ni_syscall /* 195 - reserved - stat64 */ - .long sys_ni_syscall /* 196 - reserved - lstat64 */ - .long sys_ni_syscall /* 197 - reserved - fstat64 */ + .long sys_truncate64 /* 193 */ + .long sys_ftruncate64 /* 194 */ + .long sys_stat64 /* 195 */ + .long sys_lstat64 /* 196 */ + .long sys_fstat64 /* 197 */ .long sys_pciconfig_read /* 198 */ .long sys_pciconfig_write /* 199 */ .long sys_pciconfig_iobase /* 200 */ .long sys_ni_syscall /* 201 - reserved - MacOnLinux - new */ .long sys_getdents64 /* 202 */ + .long sys_pivot_root /* 203 */ + .long sys_fcntl64 /* 204 */ + .long sys_madvise /* 205 */ + .long sys_mincore /* 206 */ .rept NR_syscalls-(.-sys_call_table)/4 .long sys_ni_syscall .endr diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/open_pic.c linux.ac/arch/ppc/kernel/open_pic.c --- linux.vanilla/arch/ppc/kernel/open_pic.c Sat Oct 28 16:15:46 2000 +++ linux.ac/arch/ppc/kernel/open_pic.c Mon Dec 18 20:44:19 2000 @@ -1,5 +1,5 @@ /* - * arch/ppc/kernel/openpic.c -- OpenPIC Interrupt Handling + * arch/ppc/kernel/open_pic.c -- OpenPIC Interrupt Handling * * Copyright (C) 1997 Geert Uytterhoeven * @@ -13,35 +13,36 @@ #include #include #include -#include +#include #include #include #include #include #include + #include "local_irq.h" +#include "open_pic.h" +#include "open_pic_defs.h" -volatile struct OpenPIC *OpenPIC = NULL; +void* OpenPIC_Addr; +static volatile struct OpenPIC *OpenPIC = NULL; u_int OpenPIC_NumInitSenses __initdata = 0; u_char *OpenPIC_InitSenses __initdata = NULL; -int open_pic_irq_offset; extern int use_of_interrupt_tree; -void chrp_mask_irq(unsigned int); -void chrp_unmask_irq(unsigned int); void find_ISUs(void); static u_int NumProcessors; static u_int NumSources; -OpenPIC_Source *ISU; -/* - * We should use this if we have > 1 ISU. - * We can just point each entry to the - * appropriate source regs but it wastes a lot of space - * so until we have >1 ISU I'll leave it unimplemented. - * -- Cort -OpenPIC_Source ISU[128]; -*/ +static int NumISUs; +static int open_pic_irq_offset; +static volatile unsigned char* chrp_int_ack_special; + +OpenPIC_SourcePtr ISU[OPENPIC_MAX_ISU]; + +static void openpic_end_irq(unsigned int irq_nr); +static void openpic_ack_irq(unsigned int irq_nr); +static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask); struct hw_interrupt_type open_pic = { " OpenPIC ", @@ -49,45 +50,63 @@ NULL, openpic_enable_irq, openpic_disable_irq, - 0, + openpic_ack_irq, + openpic_end_irq, + openpic_set_affinity +}; + +#ifdef CONFIG_SMP +static void openpic_end_ipi(unsigned int irq_nr); +static void openpic_ack_ipi(unsigned int irq_nr); +static void openpic_enable_ipi(unsigned int irq_nr); +static void openpic_disable_ipi(unsigned int irq_nr); + +struct hw_interrupt_type open_pic_ipi = { + " OpenPIC ", + NULL, + NULL, + openpic_enable_ipi, + openpic_disable_ipi, + openpic_ack_ipi, + openpic_end_ipi, 0 }; +#endif /* CONFIG_SMP */ /* * Accesses to the current processor's registers */ -#ifndef __powerpc__ -#define THIS_CPU Private -#define CHECK_THIS_CPU do {} while (0) -#else #define THIS_CPU Processor[cpu] +#define DECL_THIS_CPU int cpu = smp_processor_id() #define CHECK_THIS_CPU check_arg_cpu(cpu) -#endif #if 1 #define check_arg_ipi(ipi) \ if (ipi < 0 || ipi >= OPENPIC_NUM_IPI) \ - printk("openpic.c:%d: illegal ipi %d\n", __LINE__, ipi); + printk("open_pic.c:%d: illegal ipi %d\n", __LINE__, ipi); #define check_arg_timer(timer) \ if (timer < 0 || timer >= OPENPIC_NUM_TIMERS) \ - printk("openpic.c:%d: illegal timer %d\n", __LINE__, timer); + printk("open_pic.c:%d: illegal timer %d\n", __LINE__, timer); #define check_arg_vec(vec) \ if (vec < 0 || vec >= OPENPIC_NUM_VECTORS) \ - printk("openpic.c:%d: illegal vector %d\n", __LINE__, vec); + printk("open_pic.c:%d: illegal vector %d\n", __LINE__, vec); #define check_arg_pri(pri) \ if (pri < 0 || pri >= OPENPIC_NUM_PRI) \ - printk("openpic.c:%d: illegal priority %d\n", __LINE__, pri); + printk("open_pic.c:%d: illegal priority %d\n", __LINE__, pri); /* - * I changed this to return to keep us from from trying to use irq #'s - * that we're using for IPI's. - * -- Cort - */ + * Print out a backtrace if it's out of range, since if it's larger than NR_IRQ's + * data has probably been corrupted and we're going to panic or deadlock later + * anyway --Troy + */ +extern unsigned long* _get_SP(void); #define check_arg_irq(irq) \ - /*if (irq < 0 || irq >= (NumSources+open_pic_irq_offset)) \ - printk("openpic.c:%d: illegal irq %d\n", __LINE__, irq);*/ + if (irq < open_pic_irq_offset || irq >= (NumSources+open_pic_irq_offset)){ \ + printk("open_pic.c:%d: illegal irq %d\n", __LINE__, irq); \ + print_backtrace(_get_SP()); } #define check_arg_cpu(cpu) \ - if (cpu < 0 || cpu >= NumProcessors) \ - printk("openpic.c:%d: illegal cpu %d\n", __LINE__, cpu); + if (cpu < 0 || cpu >= NumProcessors){ \ + printk("open_pic.c:%d: illegal cpu %d\n", __LINE__, cpu); \ + print_backtrace(_get_SP()); } #else #define check_arg_ipi(ipi) do {} while (0) #define check_arg_timer(timer) do {} while (0) @@ -97,23 +116,10 @@ #define check_arg_cpu(cpu) do {} while (0) #endif -#ifdef CONFIG_SMP -void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs) -{ - smp_message_recv(cpl-OPENPIC_VEC_IPI, regs); -} -#endif /* CONFIG_SMP */ - -#ifdef __i386__ -static inline u_int in_le32(volatile u_int *addr) -{ - return *addr; -} - -static inline void out_le32(volatile u_int *addr, u_int val) -{ - *addr = val; -} +#ifdef CONFIG_POWER3 + #define GET_ISU(source) ISU[(source) >> 4][(source) & 0xf] +#else + #define GET_ISU(source) ISU[0][(source)] #endif u_int openpic_read(volatile u_int *addr) @@ -156,22 +162,22 @@ u_int field) { openpic_setfield(addr, OPENPIC_MASK); - /* wait until it's not in use */ - /* BenH: Is this code really enough ? I would rather check the result - * and eventually retry ... - */ while (openpic_read(addr) & OPENPIC_ACTIVITY); openpic_writefield(addr, mask | OPENPIC_MASK, field | OPENPIC_MASK); } -void __init openpic_init(int main_pic) +void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, + int programmer_switch_irq) { u_int t, i; u_int timerfreq; const char *version; - if (!OpenPIC) - panic("No OpenPIC found"); + if (!OpenPIC_Addr) { + printk("No OpenPIC found !\n"); + return; + } + OpenPIC = (volatile struct OpenPIC *)OpenPIC_Addr; if ( ppc_md.progress ) ppc_md.progress("openpic enter",0x122); @@ -194,113 +200,121 @@ OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT) + 1; NumSources = ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK) >> OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1; - if ( _machine != _MACH_Pmac ) - { - printk("OpenPIC Version %s (%d CPUs and %d IRQ sources) at %p\n", version, - NumProcessors, NumSources, OpenPIC); - timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency); - printk("OpenPIC timer frequency is "); - if (timerfreq) - printk("%d MHz\n", timerfreq>>20); - else - printk("not set\n"); + printk("OpenPIC Version %s (%d CPUs and %d IRQ sources) at %p\n", + version, NumProcessors, NumSources, OpenPIC); + timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency); + if (timerfreq) + printk("OpenPIC timer frequency is %d.%06d MHz\n", + timerfreq / 1000000, timerfreq % 1000000); + + if (!main_pic) + return; + + open_pic_irq_offset = offset; + chrp_int_ack_special = (volatile unsigned char*)chrp_ack; + + /* Initialize timer interrupts */ + if ( ppc_md.progress ) ppc_md.progress("openpic timer",0x3ba); + for (i = 0; i < OPENPIC_NUM_TIMERS; i++) { + /* Disabled, Priority 0 */ + openpic_inittimer(i, 0, OPENPIC_VEC_TIMER+i+offset); + /* No processor */ + openpic_maptimer(i, 0); } - - if ( main_pic ) - { - /* Initialize timer interrupts */ - if ( ppc_md.progress ) ppc_md.progress("openpic timer",0x3ba); - for (i = 0; i < OPENPIC_NUM_TIMERS; i++) { - /* Disabled, Priority 0 */ - openpic_inittimer(i, 0, OPENPIC_VEC_TIMER+i); - /* No processor */ - openpic_maptimer(i, 0); - } - - /* Initialize IPI interrupts */ - if ( ppc_md.progress ) ppc_md.progress("openpic ipi",0x3bb); - for (i = 0; i < OPENPIC_NUM_IPI; i++) { - /* Disabled, Priority 8 */ - openpic_initipi(i, 8, OPENPIC_VEC_IPI+i); - } - find_ISUs(); - if ( _machine != _MACH_Pmac ) - { - /* Initialize external interrupts */ - if ( ppc_md.progress ) ppc_md.progress("openpic ext",0x3bc); - /* SIOint (8259 cascade) is special */ - openpic_initirq(0, 8, open_pic_irq_offset, 1, 1); - openpic_mapirq(0, 1<<0); - for (i = 1; i < NumSources; i++) { - /* Enabled, Priority 8 */ - openpic_initirq(i, 8, open_pic_irq_offset+i, 0, - i < OpenPIC_NumInitSenses ? OpenPIC_InitSenses[i] : 1); - /* Processor 0 */ - openpic_mapirq(i, 1<<0); - } - } - else - { - /* Prevent any interrupt from occuring during initialisation. - * Hum... I believe this is not necessary, Apple does that in - * Darwin's PowerExpress code. - */ - openpic_set_priority(0, 0xf); - - /* First disable all interrupts and map them to CPU 0 */ - for (i = 0; i < NumSources; i++) { - openpic_disable_irq(i); - openpic_mapirq(i, 1<<0); - } - - /* If we use the device tree, then lookup all interrupts and - * initialize them according to sense infos found in the tree - */ - if (use_of_interrupt_tree) { - struct device_node* np = find_all_nodes(); - while(np) { - int j, pri; - pri = strcmp(np->name, "programmer-switch") ? 2 : 7; - for (j=0;jn_intrs;j++) { - openpic_initirq(np->intrs[j].line, - pri, - np->intrs[j].line, - 0, - np->intrs[j].sense); - if (np->intrs[j].sense) - irq_desc[np->intrs[j].line].status = IRQ_LEVEL; - } - np = np->next; - } - } - } - - /* Initialize the spurious interrupt */ - if ( ppc_md.progress ) ppc_md.progress("openpic spurious",0x3bd); - openpic_set_spurious(OPENPIC_VEC_SPURIOUS); - if ( !(_machine & (_MACH_gemini|_MACH_Pmac)) ) - { - if (request_irq(IRQ_8259_CASCADE, no_action, SA_INTERRUPT, - "82c59 cascade", NULL)) - printk("Unable to get OpenPIC IRQ 0 for cascade\n"); - } - openpic_set_priority(0, 0); - openpic_disable_8259_pass_through(); + +#ifdef CONFIG_SMP + /* Initialize IPI interrupts */ + if ( ppc_md.progress ) ppc_md.progress("openpic ipi",0x3bb); + for (i = 0; i < OPENPIC_NUM_IPI; i++) { + /* Disabled, Priority 10..13 */ + openpic_initipi(i, 10+i, OPENPIC_VEC_IPI+i+offset); + /* IPIs are per-CPU */ + irq_desc[OPENPIC_VEC_IPI+i+offset].status |= IRQ_PER_CPU; + irq_desc[OPENPIC_VEC_IPI+i+offset].handler = &open_pic_ipi; } - if ( ppc_md.progress ) ppc_md.progress("openpic exit",0x222); +#endif + + find_ISUs(); + + /* Initialize external interrupts */ + if (ppc_md.progress) ppc_md.progress("openpic ext",0x3bc); + + openpic_set_priority(0xf); + + /* SIOint (8259 cascade) is special */ + if (offset) { + openpic_initirq(0, 8, offset, 1, 1); + openpic_mapirq(0, 1<<0); + } + + /* Init all external sources */ + for (i = 1; i < NumSources; i++) { + int pri, sense; + + /* the bootloader may have left it enabled (bad !) */ + openpic_disable_irq(i+offset); + + pri = (i == programmer_switch_irq)? 9: 8; + sense = (i < OpenPIC_NumInitSenses)? OpenPIC_InitSenses[i]: 1; + if (sense) + irq_desc[i+offset].status = IRQ_LEVEL; + + /* Enabled, Priority 8 or 9 */ + openpic_initirq(i, pri, i+offset, !sense, sense); + /* Processor 0 */ + openpic_mapirq(i, 1<<0); + } + + /* Init descriptors */ + for (i = offset; i < NumSources + offset; i++) + irq_desc[i].handler = &open_pic; + + /* Initialize the spurious interrupt */ + if (ppc_md.progress) ppc_md.progress("openpic spurious",0x3bd); + openpic_set_spurious(OPENPIC_VEC_SPURIOUS+offset); + + /* Initialize the cascade */ + if (offset) { + if (request_irq(offset, no_action, SA_INTERRUPT, + "82c59 cascade", NULL)) + printk("Unable to get OpenPIC IRQ 0 for cascade\n"); + } + openpic_set_priority(0); + openpic_disable_8259_pass_through(); + + if (ppc_md.progress) ppc_md.progress("openpic exit",0x222); } +#ifdef CONFIG_POWER3 +void openpic_setup_ISU(int isu_num, unsigned long addr) +{ + if (isu_num >= OPENPIC_MAX_ISU) + return; + ISU[isu_num] = (OpenPIC_SourcePtr) ioremap(addr, 0x400); + if (isu_num >= NumISUs) + NumISUs = isu_num + 1; +} +#endif + void find_ISUs(void) { -#ifdef CONFIG_PPC64BRIDGE - /* hardcode this for now since the IBM 260 is the only thing with - * a distributed openpic right now. -- Cort +#ifdef CONFIG_POWER3 + /* Use /interrupt-controller/reg and + * /interrupt-controller/interrupt-ranges from OF device tree + * the ISU array is setup in chrp_pci.c in ibm_add_bridges + * as a result + * -- tgall + */ + + /* basically each ISU is a bus, and this assumes that + * open_pic_isu_count interrupts per bus are possible + * ISU == Interrupt Source */ - ISU = (OpenPIC_Source *)0xfeff7c00; - NumSources = 0x10; + NumSources = NumISUs * 0x10; + #else /* for non-distributed OpenPIC implementations it's in the IDU -- Cort */ - ISU = (OpenPIC_Source *)OpenPIC->Source; + ISU[0] = (OpenPIC_Source *)OpenPIC->Source; #endif } @@ -322,51 +336,44 @@ OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE); } -#ifndef __i386__ /* * Find out the current interrupt */ -u_int openpic_irq(u_int cpu) +u_int openpic_irq(void) { u_int vec; + DECL_THIS_CPU; - check_arg_cpu(cpu); + CHECK_THIS_CPU; vec = openpic_readfield(&OpenPIC->THIS_CPU.Interrupt_Acknowledge, OPENPIC_VECTOR_MASK); return vec; } -#endif -#ifndef __powerpc__ void openpic_eoi(void) -#else -void openpic_eoi(u_int cpu) -#endif { - check_arg_cpu(cpu); + DECL_THIS_CPU; + + CHECK_THIS_CPU; openpic_write(&OpenPIC->THIS_CPU.EOI, 0); /* Handle PCI write posting */ (void)openpic_read(&OpenPIC->THIS_CPU.EOI); } -#ifndef __powerpc__ u_int openpic_get_priority(void) -#else -u_int openpic_get_priority(u_int cpu) -#endif { + DECL_THIS_CPU; + CHECK_THIS_CPU; return openpic_readfield(&OpenPIC->THIS_CPU.Current_Task_Priority, OPENPIC_CURRENT_TASK_PRIORITY_MASK); } -#ifndef __powerpc__ void openpic_set_priority(u_int pri) -#else -void openpic_set_priority(u_int cpu, u_int pri) -#endif { + DECL_THIS_CPU; + CHECK_THIS_CPU; check_arg_pri(pri); openpic_writefield(&OpenPIC->THIS_CPU.Current_Task_Priority, @@ -394,6 +401,7 @@ openpic_write(&OpenPIC->Global.Processor_Initialization, cpumask); } +#ifdef CONFIG_SMP /* * Initialize an interprocessor interrupt (and disable it) * @@ -403,7 +411,7 @@ */ void openpic_initipi(u_int ipi, u_int pri, u_int vec) { - check_arg_timer(ipi); + check_arg_ipi(ipi); check_arg_pri(pri); check_arg_vec(vec); openpic_safe_writefield(&OpenPIC->Global.IPI_Vector_Priority(ipi), @@ -413,23 +421,42 @@ /* * Send an IPI to one or more CPUs + * + * Externally called, however, it takes an IPI number (0...OPENPIC_NUM_IPI) + * and not a system-wide interrupt number */ -#ifndef __powerpc__ void openpic_cause_IPI(u_int ipi, u_int cpumask) -#else -void openpic_cause_IPI(u_int cpu, u_int ipi, u_int cpumask) -#endif { + DECL_THIS_CPU; + CHECK_THIS_CPU; check_arg_ipi(ipi); openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), cpumask); } -void openpic_enable_IPI(u_int ipi) +void openpic_request_IPIs(void) { - check_arg_ipi(ipi); - openpic_clearfield(&OpenPIC->Global.IPI_Vector_Priority(ipi), - OPENPIC_MASK); + int i; + + /* + * Make sure this matches what is defined in smp.c for + * smp_message_{pass|recv}() or what shows up in + * /proc/interrupts will be wrong!!! --Troy */ + + if (OpenPIC == NULL) + return; + + request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset, + openpic_ipi_action, 0, "IPI0 (call function)", 0); + request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+1, + openpic_ipi_action, 0, "IPI1 (reschedule)", 0); + request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+2, + openpic_ipi_action, 0, "IPI2 (invalidate tlb)", 0); + request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+3, + openpic_ipi_action, 0, "IPI3 (xmon break)", 0); + + for ( i = 0; i < OPENPIC_NUM_IPI ; i++ ) + openpic_enable_ipi(OPENPIC_VEC_IPI+open_pic_irq_offset+i); } /* @@ -437,21 +464,27 @@ * * Get IPI's working and start taking interrupts. * -- Cort - */ + */ + void do_openpic_setup_cpu(void) { int i; +#if 0 /* IPIs have already been enabled --BenH */ for ( i = 0; i < OPENPIC_NUM_IPI ; i++ ) - openpic_enable_IPI(i); -#if 0 - /* let the openpic know we want intrs */ - for ( i = 0; i < NumSources ; i++ ) - openpic_mapirq(i, openpic_read(ISU[i].Destination) + openpic_enable_ipi(OPENPIC_VEC_IPI+open_pic_irq_offset+i); +#endif + + /* let the openpic know we want intrs. default affinity + * is 0xffffffff until changed via /proc + */ + for (i = 0; i < NumSources ; i++) + openpic_mapirq(i, openpic_read(&GET_ISU(i).Destination) | (1<Global.Timer[timer].Destination, cpumask); } + +/* + * + * All functions below take an offset'ed irq argument + * + */ + + /* - * Enable/disable an interrupt source + * Enable/disable an external interrupt source + * + * Externally called, irq is an offseted system-wide interrupt number */ void openpic_enable_irq(u_int irq) { check_arg_irq(irq); - openpic_clearfield(&ISU[irq - open_pic_irq_offset].Vector_Priority, OPENPIC_MASK); + openpic_clearfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK); /* make sure mask gets to controller before we return to user */ do { mb(); /* sync is probably useless here */ - } while(openpic_readfield(&ISU[irq - open_pic_irq_offset].Vector_Priority, + } while(openpic_readfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK)); } void openpic_disable_irq(u_int irq) { + u32 vp; + check_arg_irq(irq); - openpic_setfield(&ISU[irq - open_pic_irq_offset].Vector_Priority, OPENPIC_MASK); + openpic_setfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK); /* make sure mask gets to controller before we return to user */ do { mb(); /* sync is probably useless here */ - } while(!openpic_readfield(&ISU[irq - open_pic_irq_offset].Vector_Priority, - OPENPIC_MASK)); + vp = openpic_readfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, + OPENPIC_MASK | OPENPIC_ACTIVITY); + } while((vp & OPENPIC_ACTIVITY) && !(vp & OPENPIC_MASK)); } +#ifdef CONFIG_SMP +/* + * Enable/disable an IPI interrupt source + * + * Externally called, irq is an offseted system-wide interrupt number + */ +void openpic_enable_ipi(u_int irq) +{ + irq -= (OPENPIC_VEC_IPI+open_pic_irq_offset); + check_arg_ipi(irq); + openpic_clearfield(&OpenPIC->Global.IPI_Vector_Priority(irq), OPENPIC_MASK); + /* make sure mask gets to controller before we return to user */ + do { + mb(); /* sync is probably useless here */ + } while(openpic_readfield(&OpenPIC->Global.IPI_Vector_Priority(irq), + OPENPIC_MASK)); +} +void openpic_disable_ipi(u_int irq) +{ + u32 vp; + + irq -= (OPENPIC_VEC_IPI+open_pic_irq_offset); + check_arg_ipi(irq); + openpic_setfield(&OpenPIC->Global.IPI_Vector_Priority(irq), OPENPIC_MASK); + /* make sure mask gets to controller before we return to user */ + do { + mb(); /* sync is probably useless here */ + vp = openpic_readfield(&OpenPIC->Global.IPI_Vector_Priority(irq), + OPENPIC_MASK | OPENPIC_ACTIVITY); + } while((vp & OPENPIC_ACTIVITY) && !(vp & OPENPIC_MASK)); +} +#endif + /* * Initialize an interrupt source (and disable it!) * @@ -515,10 +594,7 @@ */ void openpic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense) { - check_arg_irq(irq); - check_arg_pri(pri); - check_arg_vec(vec); - openpic_safe_writefield(&ISU[irq].Vector_Priority, + openpic_safe_writefield(&GET_ISU(irq).Vector_Priority, OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK | OPENPIC_SENSE_MASK | OPENPIC_POLARITY_MASK, (pri << OPENPIC_PRIORITY_SHIFT) | vec | @@ -532,8 +608,7 @@ */ void openpic_mapirq(u_int irq, u_int cpumask) { - check_arg_irq(irq); - openpic_write(&ISU[irq].Destination, cpumask); + openpic_write(&GET_ISU(irq).Destination, cpumask); } /* @@ -543,8 +618,93 @@ */ void openpic_set_sense(u_int irq, int sense) { - check_arg_irq(irq); - openpic_safe_writefield(&ISU[irq].Vector_Priority, + openpic_safe_writefield(&GET_ISU(irq).Vector_Priority, OPENPIC_SENSE_LEVEL, (sense ? OPENPIC_SENSE_LEVEL : 0)); } + +/* No spinlocks, should not be necessary with the OpenPIC + * (1 register = 1 interrupt and we have the desc lock). + */ +static void openpic_ack_irq(unsigned int irq_nr) +{ +#if 1 /* masking should be unnecessary, but I still get spurrious */ + openpic_disable_irq(irq_nr); +#endif + if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0) + openpic_eoi(); +} + +static void openpic_end_irq(unsigned int irq_nr) +{ + if ((irq_desc[irq_nr].status & IRQ_LEVEL) != 0) + openpic_eoi(); + +#if 1 /* masking should be unnecessary, but I still get spurrious */ + if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + openpic_enable_irq(irq_nr); +#endif +} + +static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask) +{ + openpic_mapirq(irq_nr - open_pic_irq_offset, (u_int)cpumask); +} + +#ifdef CONFIG_SMP +static void openpic_ack_ipi(unsigned int irq_nr) +{ +} + +static void openpic_end_ipi(unsigned int irq_nr) +{ + /* IPIs are marked IRQ_PER_CPU. This has the side effect of + * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from + * applying to them. We EOI them late to avoid re-entering. + * however, I'm wondering if we could simply let them have the + * SA_INTERRUPT flag and let them execute with all interrupts OFF. + * This would have the side effect of either running cross-CPU + * functions with interrupts off, or we can re-enable them explicitely + * with a __sti() in smp_call_function_interrupt(), since + * smp_call_function() is protected by a spinlock. + * Or maybe we shouldn't set the IRQ_PER_CPU flag on cross-CPU + * function calls IPI at all but that would make a special case. + */ + openpic_eoi(); +} + +static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs) +{ + smp_message_recv(cpl-OPENPIC_VEC_IPI-open_pic_irq_offset, regs); +} + +#endif /* CONFIG_SMP */ + +/* This one may be merged with PReP and CHRP */ +int +openpic_get_irq(struct pt_regs *regs) +{ + extern int i8259_irq(int cpu); + + int irq = openpic_irq(); + + /* Management of the cascade should be moved out of here */ + if (open_pic_irq_offset && irq == open_pic_irq_offset) + { + /* + * This magic address generates a PCI IACK cycle. + */ + if ( chrp_int_ack_special ) + irq = *chrp_int_ack_special; + else + irq = i8259_irq( smp_processor_id() ); + openpic_eoi(); + } + if (irq == OPENPIC_VEC_SPURIOUS + open_pic_irq_offset) { + irq = -1; + /* That's not SMP safe ... but who cares ? */ + ppc_spurious_interrupts++; + } + return irq; +} + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/open_pic.h linux.ac/arch/ppc/kernel/open_pic.h --- linux.vanilla/arch/ppc/kernel/open_pic.h Tue Jan 11 02:25:06 2000 +++ linux.ac/arch/ppc/kernel/open_pic.h Thu Dec 21 21:33:07 2000 @@ -1,11 +1,45 @@ +/* + * arch/ppc/kernel/open_pic.h -- OpenPIC Interrupt Handling + * + * Copyright (C) 1997 Geert Uytterhoeven + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + */ + #ifndef _PPC_KERNEL_OPEN_PIC_H #define _PPC_KERNEL_OPEN_PIC_H +#include + +#define OPENPIC_SIZE 0x40000 + +/* OpenPIC IRQ controller structure */ extern struct hw_interrupt_type open_pic; -void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs); -void openpic_enable_IPI(u_int ipi); -void do_openpic_setup_cpu(void); +/* OpenPIC IPI controller structure */ +#ifdef CONFIG_SMP +extern struct hw_interrupt_type open_pic_ipi; +#endif /* CONFIG_SMP */ + +extern u_int OpenPIC_NumInitSenses; +extern u_char *OpenPIC_InitSenses; +extern void* OpenPIC_Addr; + +/* Exported functions */ +extern void openpic_init(int, int, unsigned char *, int); +extern void openpic_request_IPIs(void); +extern void do_openpic_setup_cpu(void); +extern int openpic_get_irq(struct pt_regs *regs); +extern void openpic_init_processor(u_int cpumask); +extern void openpic_setup_ISU(int isu_num, unsigned long addr); +extern void openpic_cause_IPI(u_int ipi, u_int cpumask); -extern int open_pic_irq_offset; +extern inline int openpic_to_irq(int irq) +{ + return irq += NUM_8259_INTERRUPTS; +} +/*extern int open_pic_irq_offset;*/ #endif /* _PPC_KERNEL_OPEN_PIC_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/open_pic_defs.h linux.ac/arch/ppc/kernel/open_pic_defs.h --- linux.vanilla/arch/ppc/kernel/open_pic_defs.h Thu Jan 1 01:00:00 1970 +++ linux.ac/arch/ppc/kernel/open_pic_defs.h Thu Dec 21 21:33:07 2000 @@ -0,0 +1,357 @@ +/* + * linux/openpic.h -- OpenPIC definitions + * + * Copyright (C) 1997 Geert Uytterhoeven + * + * This file is based on the following documentation: + * + * The Open Programmable Interrupt Controller (PIC) + * Register Interface Specification Revision 1.2 + * + * Issue Date: October 1995 + * + * Issued jointly by Advanced Micro Devices and Cyrix Corporation + * + * AMD is a registered trademark of Advanced Micro Devices, Inc. + * Copyright (C) 1995, Advanced Micro Devices, Inc. and Cyrix, Inc. + * All Rights Reserved. + * + * To receive a copy of this documentation, send an email to openpic@amd.com. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#ifndef _LINUX_OPENPIC_H +#define _LINUX_OPENPIC_H + +#if !defined(__powerpc__) && !defined(__i386__) +#error Unsupported OpenPIC platform +#endif + + +#ifdef __KERNEL__ + +#include + + /* + * OpenPIC supports up to 2048 interrupt sources and up to 32 processors + */ + +#define OPENPIC_MAX_SOURCES 2048 +#define OPENPIC_MAX_PROCESSORS 32 +#define OPENPIC_MAX_ISU 16 + +#define OPENPIC_NUM_TIMERS 4 +#define OPENPIC_NUM_IPI 4 +#define OPENPIC_NUM_PRI 16 +#define OPENPIC_NUM_VECTORS 256 + + + /* + * Non-offset'ed vector numbers + */ + +#define OPENPIC_VEC_TIMER 64 /* and up */ +#define OPENPIC_VEC_IPI 72 /* and up */ +#define OPENPIC_VEC_SPURIOUS 127 + + + /* + * OpenPIC Registers are 32 bits and aligned on 128 bit boundaries + */ + +typedef struct _OpenPIC_Reg { + u_int Reg; /* Little endian! */ + char Pad[0xc]; +} OpenPIC_Reg; + + + /* + * Per Processor Registers + */ + +typedef struct _OpenPIC_Processor { + /* + * Private Shadow Registers (for SLiC backwards compatibility) + */ + u_int IPI0_Dispatch_Shadow; /* Write Only */ + char Pad1[0x4]; + u_int IPI0_Vector_Priority_Shadow; /* Read/Write */ + char Pad2[0x34]; + /* + * Interprocessor Interrupt Command Ports + */ + OpenPIC_Reg _IPI_Dispatch[OPENPIC_NUM_IPI]; /* Write Only */ + /* + * Current Task Priority Register + */ + OpenPIC_Reg _Current_Task_Priority; /* Read/Write */ +#ifndef __powerpc__ + /* + * Who Am I Register + */ + OpenPIC_Reg _Who_Am_I; /* Read Only */ +#else + char Pad3[0x10]; +#endif +#ifndef __i386__ + /* + * Interrupt Acknowledge Register + */ + OpenPIC_Reg _Interrupt_Acknowledge; /* Read Only */ +#else + char Pad4[0x10]; +#endif + /* + * End of Interrupt (EOI) Register + */ + OpenPIC_Reg _EOI; /* Read/Write */ + char Pad5[0xf40]; +} OpenPIC_Processor; + + + /* + * Timer Registers + */ + +typedef struct _OpenPIC_Timer { + OpenPIC_Reg _Current_Count; /* Read Only */ + OpenPIC_Reg _Base_Count; /* Read/Write */ + OpenPIC_Reg _Vector_Priority; /* Read/Write */ + OpenPIC_Reg _Destination; /* Read/Write */ +} OpenPIC_Timer; + + + /* + * Global Registers + */ + +typedef struct _OpenPIC_Global { + /* + * Feature Reporting Registers + */ + OpenPIC_Reg _Feature_Reporting0; /* Read Only */ + OpenPIC_Reg _Feature_Reporting1; /* Future Expansion */ + /* + * Global Configuration Registers + */ + OpenPIC_Reg _Global_Configuration0; /* Read/Write */ + OpenPIC_Reg _Global_Configuration1; /* Future Expansion */ + /* + * Vendor Specific Registers + */ + OpenPIC_Reg _Vendor_Specific[4]; + /* + * Vendor Identification Register + */ + OpenPIC_Reg _Vendor_Identification; /* Read Only */ + /* + * Processor Initialization Register + */ + OpenPIC_Reg _Processor_Initialization; /* Read/Write */ + /* + * IPI Vector/Priority Registers + */ + OpenPIC_Reg _IPI_Vector_Priority[OPENPIC_NUM_IPI]; /* Read/Write */ + /* + * Spurious Vector Register + */ + OpenPIC_Reg _Spurious_Vector; /* Read/Write */ + /* + * Global Timer Registers + */ + OpenPIC_Reg _Timer_Frequency; /* Read/Write */ + OpenPIC_Timer Timer[OPENPIC_NUM_TIMERS]; + char Pad1[0xee00]; +} OpenPIC_Global; + + + /* + * Interrupt Source Registers + */ + +typedef struct _OpenPIC_Source { + OpenPIC_Reg _Vector_Priority; /* Read/Write */ + OpenPIC_Reg _Destination; /* Read/Write */ +} OpenPIC_Source, *OpenPIC_SourcePtr; + + + /* + * OpenPIC Register Map + */ + +struct OpenPIC { +#ifndef __powerpc__ + /* + * Per Processor Registers --- Private Access + */ + OpenPIC_Processor Private; +#else + char Pad1[0x1000]; +#endif + /* + * Global Registers + */ + OpenPIC_Global Global; + /* + * Interrupt Source Configuration Registers + */ + OpenPIC_Source Source[OPENPIC_MAX_SOURCES]; + /* + * Per Processor Registers + */ + OpenPIC_Processor Processor[OPENPIC_MAX_PROCESSORS]; +}; + +extern volatile struct OpenPIC *OpenPIC; + + + /* + * Current Task Priority Register + */ + +#define OPENPIC_CURRENT_TASK_PRIORITY_MASK 0x0000000f + + /* + * Who Am I Register + */ + +#define OPENPIC_WHO_AM_I_ID_MASK 0x0000001f + + /* + * Feature Reporting Register 0 + */ + +#define OPENPIC_FEATURE_LAST_SOURCE_MASK 0x07ff0000 +#define OPENPIC_FEATURE_LAST_SOURCE_SHIFT 16 +#define OPENPIC_FEATURE_LAST_PROCESSOR_MASK 0x00001f00 +#define OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT 8 +#define OPENPIC_FEATURE_VERSION_MASK 0x000000ff + + /* + * Global Configuration Register 0 + */ + +#define OPENPIC_CONFIG_RESET 0x80000000 +#define OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE 0x20000000 +#define OPENPIC_CONFIG_BASE_MASK 0x000fffff + + /* + * Vendor Identification Register + */ + +#define OPENPIC_VENDOR_ID_STEPPING_MASK 0x00ff0000 +#define OPENPIC_VENDOR_ID_STEPPING_SHIFT 16 +#define OPENPIC_VENDOR_ID_DEVICE_ID_MASK 0x0000ff00 +#define OPENPIC_VENDOR_ID_DEVICE_ID_SHIFT 8 +#define OPENPIC_VENDOR_ID_VENDOR_ID_MASK 0x000000ff + + /* + * Vector/Priority Registers + */ + +#define OPENPIC_MASK 0x80000000 +#define OPENPIC_ACTIVITY 0x40000000 /* Read Only */ +#define OPENPIC_PRIORITY_MASK 0x000f0000 +#define OPENPIC_PRIORITY_SHIFT 16 +#define OPENPIC_VECTOR_MASK 0x000000ff + + + /* + * Interrupt Source Registers + */ + +#define OPENPIC_POLARITY_POSITIVE 0x00800000 +#define OPENPIC_POLARITY_NEGATIVE 0x00000000 +#define OPENPIC_POLARITY_MASK 0x00800000 +#define OPENPIC_SENSE_LEVEL 0x00400000 +#define OPENPIC_SENSE_EDGE 0x00000000 +#define OPENPIC_SENSE_MASK 0x00400000 + + + /* + * Timer Registers + */ + +#define OPENPIC_COUNT_MASK 0x7fffffff +#define OPENPIC_TIMER_TOGGLE 0x80000000 +#define OPENPIC_TIMER_COUNT_INHIBIT 0x80000000 + + + /* + * Aliases to make life simpler + */ + +/* Per Processor Registers */ +#define IPI_Dispatch(i) _IPI_Dispatch[i].Reg +#define Current_Task_Priority _Current_Task_Priority.Reg +#ifndef __powerpc__ +#define Who_Am_I _Who_Am_I.Reg +#endif +#ifndef __i386__ +#define Interrupt_Acknowledge _Interrupt_Acknowledge.Reg +#endif +#define EOI _EOI.Reg + +/* Global Registers */ +#define Feature_Reporting0 _Feature_Reporting0.Reg +#define Feature_Reporting1 _Feature_Reporting1.Reg +#define Global_Configuration0 _Global_Configuration0.Reg +#define Global_Configuration1 _Global_Configuration1.Reg +#define Vendor_Specific(i) _Vendor_Specific[i].Reg +#define Vendor_Identification _Vendor_Identification.Reg +#define Processor_Initialization _Processor_Initialization.Reg +#define IPI_Vector_Priority(i) _IPI_Vector_Priority[i].Reg +#define Spurious_Vector _Spurious_Vector.Reg +#define Timer_Frequency _Timer_Frequency.Reg + +/* Timer Registers */ +#define Current_Count _Current_Count.Reg +#define Base_Count _Base_Count.Reg +#define Vector_Priority _Vector_Priority.Reg +#define Destination _Destination.Reg + +/* Interrupt Source Registers */ +#define Vector_Priority _Vector_Priority.Reg +#define Destination _Destination.Reg + + /* + * Local (static) OpenPIC Operations + */ + + +/* Global Operations */ +static void openpic_reset(void); +static void openpic_enable_8259_pass_through(void); +static void openpic_disable_8259_pass_through(void); +static u_int openpic_irq(void); +static void openpic_eoi(void); +static u_int openpic_get_priority(void); +static void openpic_set_priority(u_int pri); +static u_int openpic_get_spurious(void); +static void openpic_set_spurious(u_int vector); + +/* Interprocessor Interrupts */ +static void openpic_initipi(u_int ipi, u_int pri, u_int vector); + +/* Timer Interrupts */ +static void openpic_inittimer(u_int timer, u_int pri, u_int vector); +static void openpic_maptimer(u_int timer, u_int cpumask); + +/* Interrupt Sources */ +static void openpic_enable_irq(u_int irq); +static void openpic_disable_irq(u_int irq); +static void openpic_initirq(u_int irq, u_int pri, u_int vector, int polarity, + int is_level); +static void openpic_mapirq(u_int irq, u_int cpumask); +static void openpic_set_sense(u_int irq, int sense); + +#ifdef CONFIG_SMP +static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs); +#endif + +#endif /* __KERNEL__ */ + +#endif /* _LINUX_OPENPIC_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/pci.c linux.ac/arch/ppc/kernel/pci.c --- linux.vanilla/arch/ppc/kernel/pci.c Mon Nov 20 15:11:56 2000 +++ linux.ac/arch/ppc/kernel/pci.c Thu Dec 21 21:33:07 2000 @@ -3,15 +3,16 @@ * Common pmac/prep/chrp pci routines. -- Cort */ +#include #include #include #include #include #include -#include #include #include #include +#include #include #include @@ -25,7 +26,7 @@ #include "pci.h" -#undef DEBUG +#define DEBUG #ifdef DEBUG #define DBG(x...) printk(x) @@ -37,54 +38,44 @@ unsigned long isa_mem_base = 0; unsigned long pci_dram_offset = 0; -struct pci_fixup pcibios_fixups[] = { - { 0 } -}; +static u8* pci_to_OF_bus_map; -int generic_pcibios_read_byte(struct pci_dev *dev, int where, u8 *val) -{ - return ppc_md.pcibios_read_config_byte(dev->bus->number,dev->devfn,where,val); -} -int generic_pcibios_read_word(struct pci_dev *dev, int where, u16 *val) -{ - return ppc_md.pcibios_read_config_word(dev->bus->number,dev->devfn,where,val); -} -int generic_pcibios_read_dword(struct pci_dev *dev, int where, u32 *val) -{ - return ppc_md.pcibios_read_config_dword(dev->bus->number,dev->devfn,where,val); -} -int generic_pcibios_write_byte(struct pci_dev *dev, int where, u8 val) -{ - return ppc_md.pcibios_write_config_byte(dev->bus->number,dev->devfn,where,val); -} -int generic_pcibios_write_word(struct pci_dev *dev, int where, u16 val) -{ - return ppc_md.pcibios_write_config_word(dev->bus->number,dev->devfn,where,val); -} -int generic_pcibios_write_dword(struct pci_dev *dev, int where, u32 val) -{ - return ppc_md.pcibios_write_config_dword(dev->bus->number,dev->devfn,where,val); -} +static void pcibios_fixup_resources(struct pci_dev* dev); +#ifdef CONFIG_ALL_PPC +static void pcibios_fixup_cardbus(struct pci_dev* dev); +#endif -struct pci_ops generic_pci_ops = -{ - generic_pcibios_read_byte, - generic_pcibios_read_word, - generic_pcibios_read_dword, - generic_pcibios_write_byte, - generic_pcibios_write_word, - generic_pcibios_write_dword -}; +/* By default, we don't re-assign bus numbers. We do this only on + * some pmacs + */ +int pci_assign_all_busses; +struct pci_controller* hose_head; +struct pci_controller** hose_tail = &hose_head; +static int pci_bus_count; -void pcibios_update_resource(struct pci_dev *dev, struct resource *root, +struct pci_fixup pcibios_fixups[] = { + { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources }, +#ifdef CONFIG_ALL_PPC + /* We should add per-machine fixup support in xxx_setup.c or xxx_pci.c */ + { PCI_FIXUP_FINAL, PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1211, pcibios_fixup_cardbus }, +#endif /* CONFIG_ALL_PPC */ + { 0 } +}; + +void +pcibios_update_resource(struct pci_dev *dev, struct resource *root, struct resource *res, int resource) { u32 new, check; int reg; - - new = res->start | (res->flags & PCI_REGION_FLAG_MASK); + struct pci_controller* hose = dev->sysdata; + + new = res->start; + if (hose && res->flags & IORESOURCE_MEM) + new -= hose->pci_mem_offset; + new |= (res->flags & PCI_REGION_FLAG_MASK); if (resource < 6) { reg = PCI_BASE_ADDRESS_0 + 4*resource; } else if (resource == PCI_ROM_RESOURCE) { @@ -104,6 +95,62 @@ } } +static void +pcibios_fixup_resources(struct pci_dev* dev) +{ + struct pci_controller* hose = + (struct pci_controller *)dev->sysdata; + int i; + if (!hose) { + printk("No hose for PCI dev %x.%x !\n", dev->bus->number, dev->devfn >> 3); + return; + } + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + struct resource *res = dev->resource + i; + if (!res->start) + continue; + if (res->flags & IORESOURCE_MEM) { + res->start += hose->pci_mem_offset; + res->end += hose->pci_mem_offset; +#ifdef DEBUG + printk("Fixup mem res, dev: %x.%x, res_start: %lx->%lx\n", + dev->bus->number, dev->devfn>>3, res->start-hose->pci_mem_offset, + res->start); +#endif + } + + if ((res->flags & IORESOURCE_IO) + && (unsigned long) hose->io_base_virt != isa_io_base) { + unsigned long offs = (unsigned long) hose->io_base_virt - isa_io_base; + res->start += offs; + res->end += offs; + printk("Fixup IO res, dev: %x.%x, res_start: %lx->%lx\n", + dev->bus->number, dev->devfn>>3, + res->start - offs, res->start); + } + } +} + +#ifdef CONFIG_ALL_PPC +static void +pcibios_fixup_cardbus(struct pci_dev* dev) +{ + /* + * Fix the interrupt routing on the TI1211 chip on the 1999 + * G3 powerbook, which doesn't get initialized properly by OF. + */ + if (dev->vendor == PCI_VENDOR_ID_TI + && dev->device == PCI_DEVICE_ID_TI_1211) { + u32 val; + /* 0x8c == TI122X_IRQMUX, 2 says to route the INTA + signal out the MFUNC0 pin */ + if (pci_read_config_dword(dev, 0x8c, &val) == 0 + && val == 0) + pci_write_config_dword(dev, 0x8c, 2); + } +} +#endif /* CONFIG_ALL_PPC */ + /* * We need to avoid collisions with `mirrored' VGA ports * and other strange ISA hardware, so we always want the @@ -172,7 +219,8 @@ * as well. */ -static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) +static void __init +pcibios_allocate_bus_resources(struct list_head *bus_list) { struct list_head *ln; struct pci_bus *bus; @@ -197,7 +245,8 @@ } } -static void __init pcibios_allocate_resources(int pass) +static void __init +pcibios_allocate_resources(int pass) { struct pci_dev *dev; int idx, disabled; @@ -250,7 +299,8 @@ } } -static void __init pcibios_assign_resources(void) +static void __init +pcibios_assign_resources(void) { struct pci_dev *dev; int idx; @@ -278,7 +328,8 @@ * the BIOS forgot to do so or because we have decided the old * address was unusable for some reason. */ - if (!r->start && r->end) + if (!r->start && r->end && ppc_md.pcibios_enable_device_hook && + !ppc_md.pcibios_enable_device_hook(dev, 1)) pci_assign_resource(dev, idx); } @@ -293,7 +344,8 @@ } -int pcibios_enable_resources(struct pci_dev *dev) +int +pcibios_enable_resources(struct pci_dev *dev) { u16 cmd, old_cmd; int idx; @@ -321,18 +373,267 @@ return 0; } +struct pci_controller * __init +pcibios_alloc_controller(void) +{ + struct pci_controller *hose; + + hose = (struct pci_controller *)alloc_bootmem(sizeof(*hose)); + memset(hose, 0, sizeof(struct pci_controller)); + + *hose_tail = hose; + hose_tail = &hose->next; + return hose; +} + +static void +make_one_node_map(struct device_node* node, u8 pci_bus) +{ + int *bus_range; + int len; + + if (pci_bus >= pci_bus_count) + return; + bus_range = (int *) get_property(node, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s\n", + node->full_name); + return; + } + pci_to_OF_bus_map[pci_bus] = bus_range[0]; + + for (node=node->child; node != 0;node = node->sibling) { + struct pci_dev* dev; + unsigned int *class_code, *reg; + + class_code = (unsigned int *) get_property(node, "class-code", 0); + if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && + (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) + continue; + reg = (unsigned int *)get_property(node, "reg", 0); + if (!reg) + continue; + dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff)); + if (!dev || !dev->subordinate) + continue; + make_one_node_map(node, dev->subordinate->number); + } +} + +void +pcibios_make_OF_bus_map(void) +{ + int i; + struct pci_controller* hose; + u8* of_prop_map; + + pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL); + if (!pci_to_OF_bus_map) { + printk(KERN_ERR "Can't allocate OF bus map !\n"); + return; + } + + /* We fill the bus map with invalid values, that helps + * debugging. + */ + for (i=0; inext) { + struct device_node* node; + node = (struct device_node *)hose->arch_data; + if (!node) + continue; + make_one_node_map(node, hose->first_busno); + } + of_prop_map = get_property(find_path_device("/"), "pci-OF-bus-map", 0); + if (of_prop_map) + memcpy(of_prop_map, pci_to_OF_bus_map, pci_bus_count); +#ifdef DEBUG + printk("PCI->OF bus map:\n"); + for (i=0; i %d\n", i, pci_to_OF_bus_map[i]); + } +#endif +} -void __init pcibios_init(void) +static struct device_node* +scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn) { + struct device_node* sub_node; + + for (; node != 0;node = node->sibling) { + unsigned int *class_code, *reg; + + reg = (unsigned int *) get_property(node, "reg", 0); + if (reg && ((reg[0] >> 8) & 0xff) == dev_fn + && ((reg[0] >> 16) & 0xff) == bus) + return node; + + /* For PCI<->PCI bridges or CardBus bridges, we go down */ + class_code = (unsigned int *) get_property(node, "class-code", 0); + if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && + (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) + continue; + sub_node = scan_OF_childs_for_device(node->child, bus, dev_fn); + if (sub_node) + return sub_node; + } + return NULL; +} + +/* + * Scans the OF tree for a device node matching a PCI device + */ +struct device_node* +pci_device_to_OF_node(struct pci_dev *dev) +{ + struct pci_controller *hose; + struct device_node *node; + int bus; + + if (!have_of) + return NULL; + + /* Lookup the hose */ + bus = dev->bus->number; + hose = pci_bus_to_hose(bus); + if (!hose) + return NULL; + + /* Check it has an OF node associated */ + node = (struct device_node *) hose->arch_data; + if (!node) + return NULL; + + /* Fixup bus number according to what OF think it is. */ + if (pci_to_OF_bus_map) + bus = pci_to_OF_bus_map[bus]; + if (bus == 0xff) + return NULL; + + /* Now, lookup childs of the hose */ + return scan_OF_childs_for_device(node->child, bus, dev->devfn); +} + +/* This routine is meant to be used early during boot, when the + * PCI bus numbers have not yet been assigned, and you need to + * issue PCI config cycles to an OF device. + * It could also be used to "fix" RTAS config cycles if you want + * to set pci_assign_all_busses to 1 and still use RTAS for PCI + * config cycles. + */ +struct pci_controller* +pci_find_hose_for_OF_device(struct device_node* node) +{ + if (!have_of) + return NULL; + while(node) { + struct pci_controller* hose; + for (hose=hose_head;hose;hose=hose->next) + if (hose->arch_data == node) + return hose; + node=node->parent; + } + return NULL; +} + +/* + * Returns the PCI device matching a given OF node + */ +int +pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn) +{ + unsigned int *reg; + int i; + + if (!have_of) + return -ENODEV; + reg = (unsigned int *) get_property(node, "reg", 0); + if (!reg) + return -ENODEV; + *bus = (reg[0] >> 16) & 0xff; + for (i=0; pci_to_OF_bus_map && i> 8) & 0xff); + return 0; +} + +void __init +pcibios_init(void) +{ + struct pci_controller *hose; + struct pci_bus *bus; + int next_busno; + struct pci_dev *dev; + printk("PCI: Probing PCI hardware\n"); - pci_scan_bus(0, &generic_pci_ops, NULL); + + /* Scan all of the recorded PCI controllers. */ + for (next_busno = 0, hose = hose_head; hose; hose = hose->next) { + if (pci_assign_all_busses) + hose->first_busno = next_busno; + hose->last_busno = 0xff; + bus = pci_scan_bus(hose->first_busno, hose->ops, hose); + hose->bus = bus; + hose->last_busno = bus->subordinate; + if (pci_assign_all_busses || next_busno <= hose->last_busno) + next_busno = hose->last_busno+1; + } + pci_bus_count = next_busno; + + /* OpenFirmware based machines need a map of OF bus + * numbers vs. kernel bus numbers since we may have to + * remap them. + */ + if (pci_assign_all_busses && have_of) + pcibios_make_OF_bus_map(); + + /* Call machine dependant fixup */ if (ppc_md.pcibios_fixup) ppc_md.pcibios_fixup(); + + /* Allocate and assign resources */ pcibios_allocate_bus_resources(&pci_root_buses); pcibios_allocate_resources(0); pcibios_allocate_resources(1); pcibios_assign_resources(); + +#ifdef CONFIG_BLK_DEV_IDE + /* OF fails to initialize IDE controllers on macs + * (and maybe other machines) + * + * This late fixup is done here since I want it to happen after + * resource assignement, and there's no "late-init" arch hook + * + * Ideally, this should be moved to the IDE layer, but we need + * to check specifically with Andre Hedrick how to do it cleanly + * since the common IDE code seem to care about the fact that the + * BIOS may have disabled a controller. + * + * -- BenH + */ + if (_machine == _MACH_Pmac) { + pci_for_each_dev(dev) + { + if ((dev->class >> 16) == PCI_BASE_CLASS_STORAGE) + pci_enable_device(dev); + } + } +#endif /* CONFIG_BLK_DEV_IDE */ +} + +int __init +pcibios_assign_all_busses(void) +{ + return pci_assign_all_busses; } void __init @@ -344,9 +645,16 @@ ranges->mem_end -= bus->resource[1]->start; } +unsigned long resource_fixup(struct pci_dev * dev, struct resource * res, + unsigned long start, unsigned long size) +{ + return start; +} void __init pcibios_fixup_bus(struct pci_bus *bus) { + pci_read_bridge_bases(bus); + if ( ppc_md.pcibios_fixup_bus ) ppc_md.pcibios_fixup_bus(bus); } @@ -370,6 +678,10 @@ int idx; struct resource *r; + if (ppc_md.pcibios_enable_device_hook) + if (ppc_md.pcibios_enable_device_hook(dev, 0)) + return -EINVAL; + pci_read_config_word(dev, PCI_COMMAND, &cmd); old_cmd = cmd; for (idx=0; idx<6; idx++) { @@ -391,37 +703,99 @@ return 0; } -void * -pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical) +struct pci_controller* +pci_bus_to_hose(int bus) { - if (!ppc_md.pci_dev_io_base) { - /* Please, someone fix this for non-pmac machines, we - * need either the virtual or physical PCI IO base - */ - return 0; - } - return ppc_md.pci_dev_io_base(bus, devfn, physical); + struct pci_controller* hose = hose_head; + + for (; hose; hose = hose->next) + if (bus >= hose->first_busno && bus <= hose->last_busno) + return hose; + return NULL; } -void * -pci_dev_mem_base(unsigned char bus, unsigned char devfn) +void* +pci_bus_io_base(unsigned int bus) { - /* Default memory base is 0 (1:1 mapping) */ - if (!ppc_md.pci_dev_mem_base) { - /* Please, someone fix this for non-pmac machines.*/ + struct pci_controller *hose; + + hose = pci_bus_to_hose(bus); + if (!hose) + return NULL; + return hose->io_base_virt; +} + +unsigned long +pci_bus_io_base_phys(unsigned int bus) +{ + struct pci_controller *hose; + + hose = pci_bus_to_hose(bus); + if (!hose) return 0; - } - return ppc_md.pci_dev_mem_base(bus, devfn); + return hose->io_base_phys; } -/* Returns the root-bridge number (Uni-N number) of a device */ -int -pci_dev_root_bridge(unsigned char bus, unsigned char devfn) +unsigned long +pci_bus_mem_base_phys(unsigned int bus) { - /* Defaults to 0 */ - if (!ppc_md.pci_dev_root_bridge) + struct pci_controller *hose; + + hose = pci_bus_to_hose(bus); + if (!hose) return 0; - return ppc_md.pci_dev_root_bridge(bus, devfn); + return hose->pci_mem_offset; +} + +#ifdef CONFIG_POWER4 +extern unsigned long pci_address_offset(int, unsigned int); +#endif /* CONFIG_POWER4 */ + +unsigned long +pci_resource_to_bus(struct pci_dev *pdev, struct resource *res) +{ + /* Hack alert again ! See comments in chrp_pci.c + */ +#ifdef CONFIG_POWER4 + unsigned long offset = pci_address_offset(pdev->bus->number, res->flags); + return res->start - offset; +#else /* CONFIG_POWER4 */ + struct pci_controller* hose = + (struct pci_controller *)pdev->sysdata; + if (hose && res->flags & IORESOURCE_MEM) + return res->start - hose->pci_mem_offset; + /* We may want to do something with IOs here... */ + return res->start; +#endif +} + +/* Obsolete functions. Should be removed once the symbios driver + * is fixed + */ +unsigned long +pci_phys_to_bus(unsigned long pa, int busnr) +{ +#ifdef CONFIG_POWER4 + return pa - pci_address_offset(busnr, IORESOURCE_MEM); +#else /* CONFIG_POWER4 */ + struct pci_controller* hose = pci_bus_to_hose(busnr); + if (!hose) + return pa; + return pa - hose->pci_mem_offset; +#endif +} + +unsigned long +pci_bus_to_phys(unsigned int ba, int busnr) +{ +#ifdef CONFIG_POWER4 + return ba + pci_address_offset(dev->bus->number, IORESOURCE_MEM); +#else /* CONFIG_POWER4 */ + struct pci_controller* hose = pci_bus_to_hose(busnr); + if (!hose) + return ba; + return ba + hose->pci_mem_offset; +#endif } /* Provide information on locations of various I/O regions in physical @@ -430,23 +804,93 @@ * Note that the returned IO or memory base is a physical address */ -asmlinkage long +long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) { + struct pci_controller* hose = pci_bus_to_hose(bus); long result = -EOPNOTSUPP; + + if (!hose) + return -ENODEV; switch (which) { case IOBASE_BRIDGE_NUMBER: - return (long)pci_dev_root_bridge(bus, devfn); + return (long)hose->first_busno; case IOBASE_MEMORY: - return (long)pci_dev_mem_base(bus, devfn); + return (long)hose->pci_mem_offset; case IOBASE_IO: - result = (long)pci_dev_io_base(bus, devfn, 1); - if (result == 0) - result = -EOPNOTSUPP; - break; + return (long)hose->io_base_phys; + case IOBASE_ISA_IO: + return (long)isa_io_base; + case IOBASE_ISA_MEM: + return (long)isa_mem_base; } return result; } +/* + * Null PCI config access functions, for the case when we can't + * find a hose. + */ +#define NULL_PCI_OP(rw, size, type) \ +static int \ +null_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + return PCIBIOS_DEVICE_NOT_FOUND; \ +} + +NULL_PCI_OP(read, byte, u8 *) +NULL_PCI_OP(read, word, u16 *) +NULL_PCI_OP(read, dword, u32 *) +NULL_PCI_OP(write, byte, u8) +NULL_PCI_OP(write, word, u16) +NULL_PCI_OP(write, dword, u32) + +static struct pci_ops null_pci_ops = +{ + null_read_config_byte, + null_read_config_word, + null_read_config_dword, + null_write_config_byte, + null_write_config_word, + null_write_config_dword +}; + +/* + * These functions are used early on before PCI scanning is done + * and all of the pci_dev and pci_bus structures have been created. + */ +static struct pci_dev * +fake_pci_dev(struct pci_controller *hose, int busnr, int devfn) +{ + static struct pci_dev dev; + static struct pci_bus bus; + + if (hose == 0) { + hose = pci_bus_to_hose(busnr); + if (hose == 0) + printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr); + } + dev.bus = &bus; + dev.sysdata = hose; + dev.devfn = devfn; + bus.number = busnr; + bus.ops = hose? hose->ops: &null_pci_ops; + return &dev; +} + +#define EARLY_PCI_OP(rw, size, type) \ +int early_##rw##_config_##size(struct pci_controller *hose, int bus, \ + int devfn, int offset, type value) \ +{ \ + return pci_##rw##_config_##size(fake_pci_dev(hose, bus, devfn), \ + offset, value); \ +} + +EARLY_PCI_OP(read, byte, u8 *) +EARLY_PCI_OP(read, word, u16 *) +EARLY_PCI_OP(read, dword, u32 *) +EARLY_PCI_OP(write, byte, u8) +EARLY_PCI_OP(write, word, u16) +EARLY_PCI_OP(write, dword, u32) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/pci.h linux.ac/arch/ppc/kernel/pci.h --- linux.vanilla/arch/ppc/kernel/pci.h Tue Aug 31 19:36:43 1999 +++ linux.ac/arch/ppc/kernel/pci.h Mon Dec 18 20:45:15 2000 @@ -2,47 +2,23 @@ #ifndef __PPC_KERNEL_PCI_H__ #define __PPC_KERNEL_PCI_H__ +/* Configure those in your xxx_init() or xxx_setup_arch() function */ extern unsigned long isa_io_base; extern unsigned long isa_mem_base; extern unsigned long pci_dram_offset; -extern unsigned int *pci_config_address; -extern unsigned char *pci_config_data; +/* Set this to 1 if you want the kernel to re-assign all PCI + * bus numbers + */ +extern int pci_assign_all_busses; -void fix_intr(struct device_node *node, struct pci_dev *dev); -#if 0 -#define decl_config_access_method(name) \ -struct pci_ops name##_pci_ops = { \ - name##_pcibios_read_config_byte, \ - name##_pcibios_read_config_word, \ - name##_pcibios_read_config_dword, \ - name##_pcibios_write_config_byte, \ - name##_pcibios_write_config_word, \ - name##_pcibios_write_config_dword \ -} -#endif +extern struct pci_controller* pcibios_alloc_controller(void); +extern struct pci_controller* pci_find_hose_for_OF_device( + struct device_node* node); -#define decl_config_access_method(name) \ -extern int name##_pcibios_read_config_byte(unsigned char bus, \ - unsigned char dev_fn, unsigned char offset, unsigned char *val); \ -extern int name##_pcibios_read_config_word(unsigned char bus, \ - unsigned char dev_fn, unsigned char offset, unsigned short *val); \ -extern int name##_pcibios_read_config_dword(unsigned char bus, \ - unsigned char dev_fn, unsigned char offset, unsigned int *val); \ -extern int name##_pcibios_write_config_byte(unsigned char bus, \ - unsigned char dev_fn, unsigned char offset, unsigned char val); \ -extern int name##_pcibios_write_config_word(unsigned char bus, \ - unsigned char dev_fn, unsigned char offset, unsigned short val); \ -extern int name##_pcibios_write_config_dword(unsigned char bus, \ - unsigned char dev_fn, unsigned char offset, unsigned int val) - -#define set_config_access_method(name) \ - ppc_md.pcibios_read_config_byte = name##_pcibios_read_config_byte; \ - ppc_md.pcibios_read_config_word = name##_pcibios_read_config_word; \ - ppc_md.pcibios_read_config_dword = name##_pcibios_read_config_dword; \ - ppc_md.pcibios_write_config_byte = name##_pcibios_write_config_byte; \ - ppc_md.pcibios_write_config_word = name##_pcibios_write_config_word; \ - ppc_md.pcibios_write_config_dword = name##_pcibios_write_config_dword +extern void setup_indirect_pci(struct pci_controller* hose, + u32 cfg_addr, u32 cfg_data); +extern void setup_grackle(struct pci_controller *hose, unsigned io_space_size); #endif /* __PPC_KERNEL_PCI_H__ */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/pmac_pci.c linux.ac/arch/ppc/kernel/pmac_pci.c --- linux.vanilla/arch/ppc/kernel/pmac_pci.c Sat Oct 28 16:15:46 2000 +++ linux.ac/arch/ppc/kernel/pmac_pci.c Mon Dec 18 20:45:24 2000 @@ -27,23 +27,14 @@ #include "pci.h" -struct bridge_data **bridges, *bridge_list; -static int max_bus; - -struct uninorth_data { - struct device_node* node; - volatile unsigned int* cfg_addr; - volatile unsigned int* cfg_data; - void* iobase; - unsigned long iobase_phys; -}; - -static struct uninorth_data uninorth_bridges[3]; -static int uninorth_count; -static int uninorth_default = -1; +#undef DEBUG static void add_bridges(struct device_node *dev); +/* XXX Could be per-controller, but I don't think we risk anything by + * assuming we won't have both UniNorth and Bandit */ +static int has_uninorth; + /* * Magic constants for enabling cache coherency in the bandit/PSX bridge. */ @@ -56,477 +47,201 @@ #define BANDIT_MAGIC 0x50 #define BANDIT_COHERENT 0x40 -/* Obsolete, should be replaced by pmac_pci_dev_io_base() (below) */ -__pmac -void *pci_io_base(unsigned int bus) +static int __init +fixup_one_level_bus_range(struct device_node *node, int higher) { - struct bridge_data *bp; - - if (bus > max_bus || (bp = bridges[bus]) == 0) - return 0; - return bp->io_base; -} - -__pmac -int pci_device_loc(struct device_node *dev, unsigned char *bus_ptr, - unsigned char *devfn_ptr) -{ - unsigned int *reg; - int len; + for (; node != 0;node = node->sibling) { + int * bus_range; + unsigned int *class_code; + int len; - reg = (unsigned int *) get_property(dev, "reg", &len); - if (reg == 0 || len < 5 * sizeof(unsigned int)) { - /* doesn't look like a PCI device */ - *bus_ptr = 0xff; - *devfn_ptr = 0xff; - return -1; + /* For PCI<->PCI bridges or CardBus bridges, we go down */ + class_code = (unsigned int *) get_property(node, "class-code", 0); + if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && + (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) + continue; + bus_range = (int *) get_property(node, "bus-range", &len); + if (bus_range != NULL && len > 2 * sizeof(int)) { + if (bus_range[1] > higher) + higher = bus_range[1]; + } + higher = fixup_one_level_bus_range(node->child, higher); } - *bus_ptr = reg[0] >> 16; - *devfn_ptr = reg[0] >> 8; - return 0; + return higher; } -/* This routines figures out on which root bridge a given PCI device - * is attached. +/* This routine fixes the "bus-range" property of all bridges in the + * system since they tend to have their "last" member wrong on macs + * + * Note that the bus numbers manipulated here are OF bus numbers, they + * are not Linux bus numbers. */ -__pmac -int -pmac_pci_dev_root_bridge(unsigned char bus, unsigned char dev_fn) +static void __init +fixup_bus_range(struct device_node *bridge) { - struct device_node *node, *bridge_node; - int bridge = uninorth_default; - - if (uninorth_count == 0) - return 0; - if (bus == 0 && PCI_SLOT(dev_fn) < 11) - return 0; + int * bus_range; + int len; - /* We look for the OF device corresponding to this bus/devfn pair. If we - * don't find it, we default to the external PCI */ - bridge_node = NULL; - node = find_pci_device_OFnode(bus, dev_fn & 0xf8); - if (node) { - /* note: we don't stop on the first occurence since we need to go - * up to the root bridge */ - do { - if (node->type && !strcmp(node->type, "pci") - && device_is_compatible(node, "uni-north")) - bridge_node = node; - node=node->parent; - } while (node); - } - if (bridge_node) { - int i; - for (i=0;i max_bus || (bp = bridges[bus]) == 0) - return 0; - return physical ? (void *) bp->io_base_phys : bp->io_base; + /* Lookup the "bus-range" property for the hose */ + bus_range = (int *) get_property(bridge, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s\n", + bridge->full_name); + return; } - return physical ? (void *) uninorth_bridges[bridge].iobase_phys - : uninorth_bridges[bridge].iobase; + bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]); } -__pmac -void * -pmac_pci_dev_mem_base(unsigned char bus, unsigned char devfn) -{ - return 0; -} - -/* This function only works for bus 0, uni-N uses a different mecanism for - * other busses (see below) +/* + * Apple MacRISC (UniNorth, Bandit) PCI controllers. + * + * The "Bandit" version is present in all early PCI PowerMacs, + * and up to the first ones using Grackle. Some machines may + * have 2 bandit controllers (2 PCI busses). + * + * The "UniNorth" version is present in all Core99 machines + * (iBook, G4, new IMacs, and all the recent Apple machines). + * It contains 3 controllers in one ASIC. */ -#define UNI_N_CFA0(devfn, off) \ + +#define MACRISC_CFA0(devfn, off) \ ((1 << (unsigned long)PCI_SLOT(dev_fn)) \ | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \ | (((unsigned long)(off)) & 0xFCUL)) -/* This one is for type 1 config accesses */ -#define UNI_N_CFA1(bus, devfn, off) \ +#define MACRISC_CFA1(bus, devfn, off) \ ((((unsigned long)(bus)) << 16) \ |(((unsigned long)(devfn)) << 8) \ |(((unsigned long)(off)) & 0xFCUL) \ |1UL) -__pmac static -unsigned int -uni_north_access_data(unsigned char bus, unsigned char dev_fn, - unsigned char offset) +static unsigned int __pmac +macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset) { - int bridge; unsigned int caddr; - - bridge = pmac_pci_dev_root_bridge(bus, dev_fn); - if (bus == 0) - caddr = UNI_N_CFA0(dev_fn, offset); - else - caddr = UNI_N_CFA1(bus, dev_fn, offset); - - if (bridge == -1) { - printk(KERN_WARNING "pmac_pci: no default bridge !\n"); - return 0; - } - - /* Uninorth will return garbage if we don't read back the value ! */ - out_le32(uninorth_bridges[bridge].cfg_addr, caddr); - (void)in_le32(uninorth_bridges[bridge].cfg_addr); - /* Yes, offset is & 7, not & 3 ! */ - return (unsigned int)(uninorth_bridges[bridge].cfg_data) + (offset & 0x07); -} - -__pmac -int uni_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) -{ - unsigned int addr; - - *val = 0xff; - addr = uni_north_access_data(bus, dev_fn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - *val = in_8((volatile unsigned char*)addr); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int uni_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) -{ - unsigned int addr; - - *val = 0xffff; - addr = uni_north_access_data(bus, dev_fn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - *val = in_le16((volatile unsigned short*)addr); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int uni_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) -{ - unsigned int addr; - - *val = 0xffff; - addr = uni_north_access_data(bus, dev_fn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - *val = in_le32((volatile unsigned int*)addr); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int uni_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) -{ - unsigned int addr; - - addr = uni_north_access_data(bus, dev_fn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - out_8((volatile unsigned char *)addr, val); - (void)in_8((volatile unsigned char *)addr); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int uni_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) -{ - unsigned int addr; - - addr = uni_north_access_data(bus, dev_fn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le16((volatile unsigned short *)addr, val); - (void)in_le16((volatile unsigned short *)addr); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int uni_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) -{ - unsigned int addr; - addr = uni_north_access_data(bus, dev_fn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32((volatile unsigned int *)addr, val); - (void)in_le32((volatile unsigned int *)addr); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int pmac_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) -{ - struct bridge_data *bp; - - *val = 0xff; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if (bus == bp->bus_number) { - if (dev_fn < (11 << 3)) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32(bp->cfg_addr, - (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8) - + (offset & ~3)); - } else { - /* Bus number once again taken into consideration. - * Change applied from 2.1.24. This makes devices located - * behind PCI-PCI bridges visible. - * -Ranjit Deshpande, 01/20/99 - */ - out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1); - } - udelay(2); - *val = in_8(bp->cfg_data + (offset & 3)); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int pmac_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) -{ - struct bridge_data *bp; - - *val = 0xffff; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 1) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == bp->bus_number) { - if (dev_fn < (11 << 3)) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32(bp->cfg_addr, - (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8) - + (offset & ~3)); - } else { - /* See pci_read_config_byte */ - out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1); - } - udelay(2); - *val = in_le16((volatile unsigned short *)(bp->cfg_data + (offset & 3))); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int pmac_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) -{ - struct bridge_data *bp; - - *val = 0xffffffff; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 3) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == bp->bus_number) { - if (dev_fn < (11 << 3)) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32(bp->cfg_addr, - (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8) - + offset); - } else { - /* See pci_read_config_byte */ - out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + offset + 1); - } - udelay(2); - *val = in_le32((volatile unsigned int *)bp->cfg_data); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int pmac_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) -{ - struct bridge_data *bp; - - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if (bus == bp->bus_number) { +#ifdef DEBUG +// printk("macrisc_config_access(hose: 0x%08lx, bus: 0x%x, devfb: 0x%x, offset: 0x%x)\n", +// hose, bus, dev_fn, offset); +#endif + if (bus == hose->first_busno) { if (dev_fn < (11 << 3)) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32(bp->cfg_addr, - (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8) - + (offset & ~3)); - } else { - /* See pci_read_config_byte */ - out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1); - } - udelay(2); - out_8(bp->cfg_data + (offset & 3), val); - return PCIBIOS_SUCCESSFUL; -} + return 0; + caddr = MACRISC_CFA0(dev_fn, offset); + } else + caddr = MACRISC_CFA1(bus, dev_fn, offset); + + /* Uninorth will return garbage if we don't read back the value ! */ + do { + out_le32(hose->cfg_addr, caddr); + } while(in_le32(hose->cfg_addr) != caddr); + + offset &= has_uninorth ? 0x07 : 0x03; + return (unsigned int)(hose->cfg_data) + (unsigned int)offset; +} + +#define cfg_read(val, addr, type, op, op2) \ + *val = op((type)(addr)) +#define cfg_write(val, addr, type, op, op2) \ + op((type *)(addr), (val)); (void) op2((type *)(addr)) + +#define cfg_read_bad(val, size) *val = bad_##size; +#define cfg_write_bad(val, size) + +#define bad_byte 0xff +#define bad_word 0xffff +#define bad_dword 0xffffffffU + +#define MACRISC_PCI_OP(rw, size, type, op, op2) \ +static int __pmac \ +macrisc_##rw##_config_##size(struct pci_dev *dev, int off, type val) \ +{ \ + struct pci_controller *hose = dev->sysdata; \ + unsigned int addr; \ + \ + addr = macrisc_cfg_access(hose, dev->bus->number, dev->devfn, off); \ + if (!addr) { \ + cfg_##rw##_bad(val, size) \ + return PCIBIOS_DEVICE_NOT_FOUND; \ + } \ + cfg_##rw(val, addr, type, op, op2); \ + return PCIBIOS_SUCCESSFUL; \ +} + +MACRISC_PCI_OP(read, byte, u8 *, in_8, x) +MACRISC_PCI_OP(read, word, u16 *, in_le16, x) +MACRISC_PCI_OP(read, dword, u32 *, in_le32, x) +MACRISC_PCI_OP(write, byte, u8, out_8, in_8) +MACRISC_PCI_OP(write, word, u16, out_le16, in_le16) +MACRISC_PCI_OP(write, dword, u32, out_le32, in_le32) + +static struct pci_ops macrisc_pci_ops = +{ + macrisc_read_config_byte, + macrisc_read_config_word, + macrisc_read_config_dword, + macrisc_write_config_byte, + macrisc_write_config_word, + macrisc_write_config_dword +}; -__pmac -int pmac_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) -{ - struct bridge_data *bp; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 1) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == bp->bus_number) { - if (dev_fn < (11 << 3)) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32(bp->cfg_addr, - (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8) - + (offset & ~3)); - } else { - /* See pci_read_config_byte */ - out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1); - } - udelay(2); - out_le16((volatile unsigned short *)(bp->cfg_data + (offset & 3)), val); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int pmac_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) +/* + * Apple "Chaos" PCI controller. + * + * This controller is present on some first generation "PowerSurge" + * machines (8500, 8600, ...). It's a very weird beast and will die + * in flames if we try to probe the config space. + * The long-term solution is to provide a config space "emulation" + * based on what we find in OF device tree + */ + +static int chaos_config_read_byte(struct pci_dev *dev, int offset, u8 *val) { - struct bridge_data *bp; - - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 3) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == bp->bus_number) { - if (dev_fn < (11 << 3)) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32(bp->cfg_addr, - (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8) - + offset); - } else { - /* See pci_read_config_byte */ - out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1); - } - udelay(2); - out_le32((volatile unsigned int *)bp->cfg_data, val); - return PCIBIOS_SUCCESSFUL; + return PCIBIOS_DEVICE_NOT_FOUND; } -#define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \ - | (((o) & ~3) << 24)) - -int grackle_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) +static int chaos_config_read_word(struct pci_dev *dev, int offset, u16 *val) { - struct bridge_data *bp; - - *val = 0xff; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset)); - *val = in_8(bp->cfg_data + (offset & 3)); - return PCIBIOS_SUCCESSFUL; + return PCIBIOS_DEVICE_NOT_FOUND; } -int grackle_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) +static int chaos_config_read_dword(struct pci_dev *dev, int offset, u32 *val) { - struct bridge_data *bp; - - *val = 0xffff; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 1) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset)); - *val = in_le16((volatile unsigned short *)(bp->cfg_data + (offset&3))); - return PCIBIOS_SUCCESSFUL; + return PCIBIOS_DEVICE_NOT_FOUND; } -int grackle_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) +static int chaos_config_write_byte(struct pci_dev *dev, int offset, u8 val) { - struct bridge_data *bp; - - *val = 0xffffffff; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 3) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset)); - *val = in_le32((volatile unsigned int *)bp->cfg_data); - return PCIBIOS_SUCCESSFUL; + return PCIBIOS_DEVICE_NOT_FOUND; } -int grackle_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) +static int chaos_config_write_word(struct pci_dev *dev, int offset, u16 val) { - struct bridge_data *bp; - - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset)); - out_8(bp->cfg_data + (offset & 3), val); - return PCIBIOS_SUCCESSFUL; + return PCIBIOS_DEVICE_NOT_FOUND; } -int grackle_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) +static int chaos_config_write_dword(struct pci_dev *dev, int offset, u32 val) { - struct bridge_data *bp; - - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 1) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset)); - out_le16((volatile unsigned short *)(bp->cfg_data + (offset&3)), val); - return PCIBIOS_SUCCESSFUL; + return PCIBIOS_DEVICE_NOT_FOUND; } -int grackle_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) +static struct pci_ops chaos_pci_ops = { - struct bridge_data *bp; + chaos_config_read_byte, + chaos_config_read_word, + chaos_config_read_dword, + chaos_config_write_byte, + chaos_config_write_word, + chaos_config_write_dword +}; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 1) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset)); - out_le32((volatile unsigned int *)bp->cfg_data, val); - return PCIBIOS_SUCCESSFUL; -} /* * For a bandit bridge, turn on cache coherency if necessary. - * N.B. we can't use pcibios_*_config_* here because bridges[] - * is not initialized yet. + * N.B. we could clean this up using the hose ops directly. */ -static void __init init_bandit(struct bridge_data *bp) +static void __init init_bandit(struct pci_controller *bp) { unsigned int vendev, magic; int rev; @@ -543,8 +258,8 @@ rev = in_8(bp->cfg_data); if (rev != BANDIT_REVID) printk(KERN_WARNING - "Unknown revision %d for bandit at %p\n", - rev, bp->io_base); + "Unknown revision %d for bandit at %08lx\n", + rev, bp->io_base_phys); } else if (vendev != (BANDIT_DEVID_2 << 16) + APPLE_VENDID) { printk(KERN_WARNING "bandit isn't? (%x)\n", vendev); return; @@ -555,8 +270,8 @@ udelay(2); rev = in_8(bp->cfg_data); if (rev != BANDIT_REVID) - printk(KERN_WARNING "Unknown revision %d for bandit at %p\n", - rev, bp->io_base); + printk(KERN_WARNING "Unknown revision %d for bandit at %08lx\n", + rev, bp->io_base_phys); /* read the word at offset 0x50 */ out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + BANDIT_MAGIC); @@ -567,16 +282,71 @@ magic |= BANDIT_COHERENT; udelay(2); out_le32((volatile unsigned int *)bp->cfg_data, magic); - printk(KERN_INFO "Cache coherency enabled for bandit/PSX at %p\n", - bp->io_base); + printk(KERN_INFO "Cache coherency enabled for bandit/PSX at %08lx\n", + bp->io_base_phys); +} + + +/* + * Tweak the PCI-PCI bridge chip on the blue & white G3s. + */ +static void __init +init_p2pbridge(void) +{ + struct device_node *p2pbridge; + struct pci_controller* hose; + u8 bus, devfn; + u16 val; + + /* XXX it would be better here to identify the specific + PCI-PCI bridge chip we have. */ + if ((p2pbridge = find_devices("pci-bridge")) == 0 + || p2pbridge->parent == NULL + || strcmp(p2pbridge->parent->name, "pci") != 0) + return; + if (pci_device_from_OF_node(p2pbridge, &bus, &devfn) < 0) { +#ifdef DEBUG + printk("Can't find PCI infos for PCI<->PCI bridge\n"); +#endif + return; + } + /* Warning: At this point, we have not yet renumbered all busses. + * So we must use OF walking to find out hose + */ + hose = pci_find_hose_for_OF_device(p2pbridge); + if (!hose) { +#ifdef DEBUG + printk("Can't find hose for PCI<->PCI bridge\n"); +#endif + return; + } + if (early_read_config_word(hose, bus, devfn, + PCI_BRIDGE_CONTROL, &val) < 0) { + printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n"); + return; + } + val &= ~PCI_BRIDGE_CTL_MASTER_ABORT; + early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val); } +void __init +pmac_find_bridges(void) +{ + add_bridges(find_devices("bandit")); + add_bridges(find_devices("chaos")); + add_bridges(find_devices("pci")); + init_p2pbridge(); +} + +#define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \ + | (((o) & ~3) << 24)) + #define GRACKLE_PICR1_STG 0x00000040 #define GRACKLE_PICR1_LOOPSNOOP 0x00000010 /* N.B. this is called before bridges is initialized, so we can't use grackle_pcibios_{read,write}_config_dword. */ -static inline void grackle_set_stg(struct bridge_data *bp, int enable) +static inline void grackle_set_stg(struct pci_controller* bp, int enable) { unsigned int val; @@ -586,9 +356,10 @@ (val & ~GRACKLE_PICR1_STG); out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); out_le32((volatile unsigned int *)bp->cfg_data, val); + (void)in_le32((volatile unsigned int *)bp->cfg_data); } -static inline void grackle_set_loop_snoop(struct bridge_data *bp, int enable) +static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable) { unsigned int val; @@ -598,25 +369,68 @@ (val & ~GRACKLE_PICR1_LOOPSNOOP); out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); out_le32((volatile unsigned int *)bp->cfg_data, val); + (void)in_le32((volatile unsigned int *)bp->cfg_data); } +static void __init +setup_uninorth(struct pci_controller* hose, struct reg_property* addr) +{ + pci_assign_all_busses = 1; + has_uninorth = 1; + hose->ops = ¯isc_pci_ops; + hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); + hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); + hose->io_base_phys = addr->address; + /* is 0x10000 enough for io space ? */ + hose->io_base_virt = (void *)ioremap(addr->address, 0x10000); + + /* XXX This is the bridge with the PCI expansion bus. We route + * legacy IOs to it. + */ + if (addr->address == 0xf2000000) + isa_io_base = (unsigned long)hose->io_base_virt; +} -void __init pmac_find_bridges(void) +static void __init +setup_bandit(struct pci_controller* hose, struct reg_property* addr) { - int bus; - struct bridge_data *bridge; + hose->ops = ¯isc_pci_ops; + hose->cfg_addr = (volatile unsigned int *) + ioremap(addr->address + 0x800000, 0x1000); + hose->cfg_data = (volatile unsigned char *) + ioremap(addr->address + 0xc00000, 0x1000); + hose->io_base_phys = addr->address; + hose->io_base_virt = (void *) ioremap(addr->address, 0x10000); + init_bandit(hose); +} + +static void __init +setup_chaos(struct pci_controller* hose, struct reg_property* addr) +{ + /* assume a `chaos' bridge */ + hose->ops = &chaos_pci_ops; + hose->cfg_addr = (volatile unsigned int *) + ioremap(addr->address + 0x800000, 0x1000); + hose->cfg_data = (volatile unsigned char *) + ioremap(addr->address + 0xc00000, 0x1000); + hose->io_base_phys = addr->address; + hose->io_base_virt = (void *) ioremap(addr->address, 0x10000); +} - bridge_list = 0; - max_bus = 0; - add_bridges(find_devices("bandit")); - add_bridges(find_devices("chaos")); - add_bridges(find_devices("pci")); - bridges = (struct bridge_data **) - alloc_bootmem((max_bus + 1) * sizeof(struct bridge_data *)); - memset(bridges, 0, (max_bus + 1) * sizeof(struct bridge_data *)); - for (bridge = bridge_list; bridge != NULL; bridge = bridge->next) - for (bus = bridge->bus_number; bus <= bridge->max_bus; ++bus) - bridges[bus] = bridge; +void __init +setup_grackle(struct pci_controller *hose, unsigned io_space_size) +{ + setup_indirect_pci(hose, 0xfec00000, 0xfee00000); + hose->io_base_phys = 0xfe000000; + hose->io_base_virt = (void *) ioremap(0xfe000000, io_space_size); + pci_dram_offset = 0; + isa_mem_base = 0xfd000000; + isa_io_base = (unsigned long) hose->io_base_virt; + if (machine_is_compatible("AAPL,PowerBook1998")) + grackle_set_loop_snoop(hose, 1); +#if 0 /* Disabled for now, HW problems ??? */ + grackle_set_stg(hose, 1); +#endif } /* @@ -626,11 +440,12 @@ */ static void __init add_bridges(struct device_node *dev) { - int *bus_range; int len; - struct bridge_data *bp; + struct pci_controller *hose; struct reg_property *addr; - + char* disp_name; + int *bus_range; + for (; dev != NULL; dev = dev->next) { addr = (struct reg_property *) get_property(dev, "reg", &len); if (addr == NULL || len < sizeof(*addr)) { @@ -640,108 +455,52 @@ } bus_range = (int *) get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s\n", - dev->full_name); - continue; - } - if (bus_range[1] == bus_range[0]) - printk(KERN_INFO "PCI bus %d", bus_range[0]); - else - printk(KERN_INFO "PCI buses %d..%d", bus_range[0], - bus_range[1]); - printk(" controlled by %s at %x\n", dev->name, addr->address); - if (device_is_compatible(dev, "uni-north")) { - int i = uninorth_count++; - uninorth_bridges[i].cfg_addr = ioremap(addr->address + 0x800000, 0x1000); - uninorth_bridges[i].cfg_data = ioremap(addr->address + 0xc00000, 0x1000); - uninorth_bridges[i].node = dev; - uninorth_bridges[i].iobase_phys = addr->address; - /* is 0x10000 enough for io space ? */ - uninorth_bridges[i].iobase = (void *)ioremap(addr->address, 0x10000); - /* XXX This is the bridge with the PCI expansion bus. This is also the - * address of the bus that will receive type 1 config accesses and io - * accesses. Appears to be correct for iMac DV and G4 Sawtooth too. - * That means that we cannot do io cycles on the AGP bus nor the internal - * ethernet/fw bus. Fortunately, they appear not to be needed on iMac DV - * and G4 neither. - */ - if (addr->address == 0xf2000000) - uninorth_default = i; - else - continue; + printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", + dev->full_name); } - bp = (struct bridge_data *) alloc_bootmem(sizeof(*bp)); + hose = pcibios_alloc_controller(); + if (!hose) + continue; + hose->arch_data = dev; + hose->first_busno = bus_range ? bus_range[0] : 0; + hose->last_busno = bus_range ? bus_range[1] : 0xff; + + disp_name = NULL; if (device_is_compatible(dev, "uni-north")) { - bp->cfg_addr = 0; - bp->cfg_data = 0; - bp->io_base = uninorth_bridges[uninorth_count-1].iobase; - bp->io_base_phys = uninorth_bridges[uninorth_count-1].iobase_phys; + setup_uninorth(hose, addr); + disp_name = "UniNorth"; } else if (strcmp(dev->name, "pci") == 0) { /* XXX assume this is a mpc106 (grackle) */ - bp->cfg_addr = (volatile unsigned int *) - ioremap(0xfec00000, 0x1000); - bp->cfg_data = (volatile unsigned char *) - ioremap(0xfee00000, 0x1000); - bp->io_base_phys = 0xfe000000; - bp->io_base = (void *) ioremap(0xfe000000, 0x20000); - if (machine_is_compatible("AAPL,PowerBook1998")) - grackle_set_loop_snoop(bp, 1); -#if 0 /* Disabled for now, HW problems ??? */ - grackle_set_stg(bp, 1); -#endif - } else { - /* a `bandit' or `chaos' bridge */ - bp->cfg_addr = (volatile unsigned int *) - ioremap(addr->address + 0x800000, 0x1000); - bp->cfg_data = (volatile unsigned char *) - ioremap(addr->address + 0xc00000, 0x1000); - bp->io_base_phys = addr->address; - bp->io_base = (void *) ioremap(addr->address, 0x10000); + setup_grackle(hose, 0x20000); + disp_name = "Grackle (MPC106)"; + } else if (strcmp(dev->name, "bandit") == 0) { + setup_bandit(hose, addr); + disp_name = "Bandit"; + } else if (strcmp(dev->name, "chaos") == 0) { + setup_chaos(hose, addr); + disp_name = "Chaos"; } + printk(KERN_INFO "Found %s PCI host bridge at 0x%08x. Firmware bus number: %d->%d\n", + disp_name, addr->address, hose->first_busno, hose->last_busno); +#ifdef DEBUG + printk(" ->Hose at 0x%08lx, cfg_addr=0x%08lx,cfg_data=0x%08lx\n", + hose, hose->cfg_addr, hose->cfg_data); +#endif + + /* Setup a default isa_io_base */ if (isa_io_base == 0) - isa_io_base = (unsigned long) bp->io_base; - bp->bus_number = bus_range[0]; - bp->max_bus = bus_range[1]; - bp->next = bridge_list; - bp->node = dev; - bridge_list = bp; - if (bp->max_bus > max_bus) - max_bus = bp->max_bus; + isa_io_base = (unsigned long)hose->io_base_virt; - if (strcmp(dev->name, "bandit") == 0) - init_bandit(bp); + /* Fixup "bus-range" OF property */ + fixup_bus_range(dev); } } -/* Recursively searches any node that is of type PCI-PCI bridge. Without - * this, the old code would miss children of P2P bridges and hence not - * fix IRQ's for cards located behind P2P bridges. - * - Ranjit Deshpande, 01/20/99 - */ -void __init -fix_intr(struct device_node *node, struct pci_dev *dev) -{ - unsigned int *reg, *class_code; - - for (; node != 0;node = node->sibling) { - class_code = (unsigned int *) get_property(node, "class-code", 0); - if(class_code && (*class_code >> 8) == PCI_CLASS_BRIDGE_PCI) - fix_intr(node->child, dev); - reg = (unsigned int *) get_property(node, "reg", 0); - if (reg == 0 || ((reg[0] >> 8) & 0xff) != dev->devfn) - continue; - /* this is the node, see if it has interrupts */ - if (node->n_intrs > 0) - dev->irq = node->intrs[0].line; - break; - } -} - -void __init -pmac_pcibios_fixup(void) -{ - struct pci_dev *dev; +static void +pcibios_fixup_OF_interrupts(void) +{ + struct pci_dev* dev; /* * FIXME: This is broken: We should not assign IRQ's to IRQless @@ -757,44 +516,43 @@ * should find the device node and se if it has an * AAPL,interrupts property. */ - struct bridge_data *bp = bridges[dev->bus->number]; unsigned char pin; + struct device_node* node; - if (pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin) || - !pin) + if (pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin) || !pin) continue; /* No interrupt generated -> no fixup */ - /* We iterate all instances of uninorth for now */ - if (uninorth_count && dev->bus->number == 0) { - int i; - for (i=0;ichild, dev); - } else - fix_intr(bp->node->child, dev); + node = pci_device_to_OF_node(dev); + if (!node) { + printk("No OF node for device %x:%x\n", dev->bus->number, dev->devfn >> 3); + continue; + } + /* this is the node, see if it has interrupts */ + if (node->n_intrs > 0) + dev->irq = node->intrs[0].line; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); } } void __init -pmac_setup_pci_ptrs(void) +pmac_pcibios_fixup(void) { - struct device_node* np; + /* Fixup interrupts according to OF tree */ + pcibios_fixup_OF_interrupts(); +} - np = find_devices("pci"); - if (np != 0) - { - if (device_is_compatible(np, "uni-north")) - { - /* looks like an Core99 powermac */ - set_config_access_method(uni); - } else - { - /* looks like a G3 powermac */ - set_config_access_method(grackle); - } - } else - { - set_config_access_method(pmac); +/* We don't want to enable USB controllers absent from the OF tree + * (iBook second controller) + */ +int +pmac_pci_enable_device_hook(struct pci_dev *dev) +{ + if (dev->vendor == PCI_VENDOR_ID_APPLE + && dev->device == PCI_DEVICE_ID_APPLE_KL_USB) { + struct device_node* node; + node = pci_device_to_OF_node(dev); + if (!node) + return -EINVAL; } - - ppc_md.pcibios_fixup = pmac_pcibios_fixup; + return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/pmac_pic.c linux.ac/arch/ppc/kernel/pmac_pic.c --- linux.vanilla/arch/ppc/kernel/pmac_pic.c Sat Oct 28 16:15:46 2000 +++ linux.ac/arch/ppc/kernel/pmac_pic.c Mon Dec 18 20:45:24 2000 @@ -4,14 +4,15 @@ #include #include #include -#include #include #include #include #include #include + #include "pmac_pic.h" +#include "open_pic.h" /* pmac */struct pmac_irq_hw { unsigned int flag; @@ -30,16 +31,14 @@ static int max_irqs; static int max_real_irqs; -static int has_openpic = 0; +static int pmac_has_openpic; + +spinlock_t pmac_pic_lock = SPIN_LOCK_UNLOCKED; + #define GATWICK_IRQ_POOL_SIZE 10 static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; -extern int pmac_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val); -extern int pmac_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val); - /* * Mark an irq as "lost". This is only used on the pmac * since it can lose interrupts (see pmac_set_irq_mask). @@ -51,48 +50,11 @@ atomic_inc(&ppc_n_lost_interrupts); } -static void pmac_openpic_mask_irq(unsigned int irq_nr) -{ - openpic_disable_irq(irq_nr); -} - -static void pmac_openpic_unmask_irq(unsigned int irq_nr) -{ - openpic_enable_irq(irq_nr); -} - -static void pmac_openpic_ack_irq(unsigned int irq_nr) -{ - if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0) - openpic_eoi(smp_processor_id()); - openpic_disable_irq(irq_nr); -} - -static void pmac_openpic_end_irq(unsigned int irq_nr) -{ - if ((irq_desc[irq_nr].status & IRQ_LEVEL) != 0) - openpic_eoi(smp_processor_id()); - openpic_enable_irq(irq_nr); -} - -struct hw_interrupt_type pmac_open_pic = { - " OpenPIC ", - NULL, - NULL, - pmac_openpic_unmask_irq, - pmac_openpic_mask_irq, - /* Theorically, the mask&ack should be NULL for OpenPIC. However, doing - * so shows tons of bogus interrupts coming in. - */ - pmac_openpic_ack_irq, - pmac_openpic_end_irq, - NULL -}; - static void __pmac pmac_mask_and_ack_irq(unsigned int irq_nr) { unsigned long bit = 1UL << (irq_nr & 0x1f); int i = irq_nr >> 5; + unsigned long flags; if ((unsigned)irq_nr >= max_irqs) return; @@ -100,6 +62,7 @@ clear_bit(irq_nr, ppc_cached_irq_mask); if (test_and_clear_bit(irq_nr, ppc_lost_interrupts)) atomic_dec(&ppc_n_lost_interrupts); + spin_lock_irqsave(&pmac_pic_lock, flags); out_le32(&pmac_irq_hw[i]->ack, bit); out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]); out_le32(&pmac_irq_hw[i]->ack, bit); @@ -108,16 +71,19 @@ interrupts */ mb(); } while(in_le32(&pmac_irq_hw[i]->flag) & bit); + spin_unlock_irqrestore(&pmac_pic_lock, flags); } static void __pmac pmac_set_irq_mask(unsigned int irq_nr) { unsigned long bit = 1UL << (irq_nr & 0x1f); int i = irq_nr >> 5; + unsigned long flags; if ((unsigned)irq_nr >= max_irqs) return; + spin_lock_irqsave(&pmac_pic_lock, flags); /* enable unmasked interrupts */ out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]); @@ -137,6 +103,7 @@ && (ld_le32(&pmac_irq_hw[i]->level) & bit) && !(ld_le32(&pmac_irq_hw[i]->flag) & bit)) __set_lost((ulong)irq_nr); + spin_unlock_irqrestore(&pmac_pic_lock, flags); } static void __pmac pmac_mask_irq(unsigned int irq_nr) @@ -152,6 +119,15 @@ pmac_set_irq_mask(irq_nr); } +static void __pmac pmac_end_irq(unsigned int irq_nr) +{ + if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + set_bit(irq_nr, ppc_cached_irq_mask); + pmac_set_irq_mask(irq_nr); + } +} + + struct hw_interrupt_type pmac_pic = { " PMAC-PIC ", NULL, @@ -159,7 +135,7 @@ pmac_unmask_irq, pmac_mask_irq, pmac_mask_and_ack_irq, - pmac_unmask_irq, + pmac_end_irq, NULL }; @@ -170,7 +146,7 @@ pmac_unmask_irq, pmac_mask_irq, pmac_mask_and_ack_irq, - pmac_unmask_irq, + pmac_end_irq, NULL }; @@ -204,35 +180,22 @@ unsigned long bits = 0; #ifdef CONFIG_SMP - void pmac_smp_message_recv(struct pt_regs *); + void psurge_smp_message_recv(struct pt_regs *); - /* IPI's are a hack on the powersurge -- Cort */ - if ( smp_processor_id() != 0 ) - { - pmac_smp_message_recv(regs); + /* IPI's are a hack on the powersurge -- Cort */ + if ( smp_processor_id() != 0 ) { + psurge_smp_message_recv(regs); return -2; /* ignore, already handled */ } #endif /* CONFIG_SMP */ - - if (has_openpic) { - irq = openpic_irq(smp_processor_id()); - if (irq == OPENPIC_VEC_SPURIOUS) - /* We get those when doing polled ADB requests, - * using -2 is a temp hack to disable the printk - */ - irq = -2; /*-1; */ - } - else - { - for (irq = max_real_irqs; (irq -= 32) >= 0; ) { - int i = irq >> 5; - bits = ld_le32(&pmac_irq_hw[i]->flag) - | ppc_lost_interrupts[i]; - if (bits == 0) - continue; - irq += __ilog2(bits); - break; - } + for (irq = max_real_irqs; (irq -= 32) >= 0; ) { + int i = irq >> 5; + bits = ld_le32(&pmac_irq_hw[i]->flag) + | ppc_lost_interrupts[i]; + if (bits == 0) + continue; + irq += __ilog2(bits); + break; } return irq; @@ -336,11 +299,16 @@ addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40); pmac_irq_hw[1] = (volatile struct pmac_irq_hw *)(addr + 0x20); max_irqs = 64; - if (pci_device_loc(irqctrler, &bus, &devfn) == 0) { - pmac_pcibios_read_config_word(bus, devfn, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - cmd &= ~PCI_COMMAND_IO; - pmac_pcibios_write_config_word(bus, devfn, PCI_COMMAND, cmd); + if (pci_device_from_OF_node(irqctrler, &bus, &devfn) == 0) { + struct pci_controller* hose = pci_find_hose_for_OF_device(irqctrler); + if (!hose) + printk(KERN_ERR "Can't find PCI hose for OHare2 !\n"); + else { + early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + cmd &= ~PCI_COMMAND_IO; + early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd); + } } second_irq = irqctrler->intrs[0].line; @@ -378,20 +346,26 @@ printk("PowerMac using OpenPIC irq controller\n"); if (irqctrler->n_addrs > 0) { + int nmi_irq = -1; + unsigned char senses[NR_IRQS]; #ifdef CONFIG_XMON struct device_node* pswitch; -#endif /* CONFIG_XMON */ - OpenPIC = (volatile struct OpenPIC *) - ioremap(irqctrler->addrs[0].address, - irqctrler->addrs[0].size); - for ( i = 0 ; i < NR_IRQS ; i++ ) - irq_desc[i].handler = &pmac_open_pic; - openpic_init(1); - has_openpic = 1; -#ifdef CONFIG_XMON + pswitch = find_devices("programmer-switch"); if (pswitch && pswitch->n_intrs) - request_irq(pswitch->intrs[0].line, xmon_irq, 0, + nmi_irq = pswitch->intrs[0].line; +#endif /* CONFIG_XMON */ + prom_get_irq_senses(senses, 0, NR_IRQS); + OpenPIC_InitSenses = senses; + OpenPIC_NumInitSenses = NR_IRQS; + ppc_md.get_irq = openpic_get_irq; + OpenPIC_Addr = ioremap(irqctrler->addrs[0].address, + irqctrler->addrs[0].size); + openpic_init(1, 0, 0, nmi_irq); + pmac_has_openpic = 1; +#ifdef CONFIG_XMON + if (nmi_irq >= 0) + request_irq(nmi_irq, xmon_irq, 0, "NMI - XMON", 0); #endif /* CONFIG_XMON */ return; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/pmac_setup.c linux.ac/arch/ppc/kernel/pmac_setup.c --- linux.vanilla/arch/ppc/kernel/pmac_setup.c Sat Oct 28 16:15:46 2000 +++ linux.ac/arch/ppc/kernel/pmac_setup.c Fri Dec 22 16:36:26 2000 @@ -47,6 +47,7 @@ #include #include +#include #include #include #include @@ -73,7 +74,8 @@ extern int pmac_set_rtc_time(unsigned long nowtime); extern void pmac_read_rtc_time(void); extern void pmac_calibrate_decr(void); -extern void pmac_setup_pci_ptrs(void); +extern void pmac_pcibios_fixup(void); +extern void pmac_find_bridges(void); extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode); extern int mackbd_getkeycode(unsigned int scancode); @@ -99,9 +101,7 @@ extern int keyboard_sends_linux_keycodes; extern void pmac_nvram_update(void); -extern void *pmac_pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical); -extern void *pmac_pci_dev_mem_base(unsigned char bus, unsigned char devfn); -extern int pmac_pci_dev_root_bridge(unsigned char bus, unsigned char devfn); +extern int pmac_pci_enable_device_hook(struct pci_dev *dev); unsigned char drive_info; @@ -119,13 +119,34 @@ extern void zs_kgdb_hook(int tty_num); static void ohare_init(void); -static void init_p2pbridge(void); #ifdef CONFIG_BOOTX_TEXT void pmac_progress(char *s, unsigned short hex); #endif sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN; +#ifdef CONFIG_SMP +volatile static long int core99_l2_cache; +void core99_init_l2(void) +{ + int cpu = smp_processor_id(); + + if ( (_get_PVR() >> 16) != 8 && (_get_PVR() >> 16) != 12 ) + return; + + if (cpu == 0){ + core99_l2_cache = _get_L2CR(); + printk("CPU0: L2CR is %lx\n", core99_l2_cache); + } else { + printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR()); + _set_L2CR(0); + _set_L2CR(core99_l2_cache); + printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache); + } +} +#endif /* CONFIG_SMP */ + + __pmac int pmac_get_cpuinfo(char *buffer) @@ -250,7 +271,7 @@ struct device_node *cpu; int *fp; - /* Set loops_per_sec to a half-way reasonable value, + /* Set loops_per_jiffy to a half-way reasonable value, for use until calibrate_delay gets called. */ cpu = find_type_devices("cpu"); if (cpu != 0) { @@ -263,13 +284,13 @@ case 10: /* mach V (604ev5) */ case 12: /* G4 */ case 20: /* 620 */ - loops_per_sec = *fp; + loops_per_jiffy = *fp / HZ; break; default: /* 601, 603, etc. */ - loops_per_sec = *fp / 2; + loops_per_jiffy = *fp / (2*HZ); } } else - loops_per_sec = 50000000; + loops_per_jiffy = 50000000 / HZ; } /* this area has the CPU identification register @@ -278,8 +299,8 @@ __ioremap(0xffc00000, 0x400000, pgprot_val(PAGE_READONLY)); ohare_init(); + /* Lookup PCI hosts */ pmac_find_bridges(); - init_p2pbridge(); /* Checks "l2cr-value" property in the registry */ if ( (_get_PVR() >> 16) == 8 || (_get_PVR() >> 16) == 12 ) { @@ -303,6 +324,11 @@ ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000) ? "enabled" : "disabled"); +#ifdef CONFIG_SMP + /* somewhat of a hack */ + core99_init_l2(); +#endif + #ifdef CONFIG_KGDB zs_kgdb_hook(0); #endif @@ -330,32 +356,6 @@ ROOT_DEV = to_kdev_t(DEFAULT_ROOT_DEVICE); } -/* - * Tweak the PCI-PCI bridge chip on the blue & white G3s. - */ -static void __init init_p2pbridge(void) -{ - struct device_node *p2pbridge; - unsigned char bus, devfn; - unsigned short val; - - /* XXX it would be better here to identify the specific - PCI-PCI bridge chip we have. */ - if ((p2pbridge = find_devices("pci-bridge")) == 0 - || p2pbridge->parent == NULL - || strcmp(p2pbridge->parent->name, "pci") != 0) - return; - if (pci_device_loc(p2pbridge, &bus, &devfn) < 0) - return; - if (ppc_md.pcibios_read_config_word(bus, devfn, PCI_BRIDGE_CONTROL, &val) < 0) { - printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n"); - return; - } - val &= ~PCI_BRIDGE_CTL_MASTER_ABORT; - ppc_md.pcibios_write_config_word(bus, devfn, PCI_BRIDGE_CONTROL, val); - ppc_md.pcibios_read_config_word(bus, devfn, PCI_BRIDGE_CONTROL, &val); -} - static void __init ohare_init(void) { /* @@ -448,7 +448,7 @@ void __init find_boot_device(void) { -#ifdef CONFIG_SCSI +#if defined(CONFIG_SCSI) && defined(CONFIG_BLK_DEV_SD) if (boot_host != NULL) { boot_dev = sd_find_target(boot_host, boot_target); if (boot_dev != 0) @@ -493,7 +493,9 @@ struct adb_request req; #endif /* CONFIG_ADB_CUDA */ +#ifdef CONFIG_NVRAM pmac_nvram_update(); +#endif switch (sys_ctrler) { #ifdef CONFIG_ADB_CUDA @@ -509,7 +511,7 @@ pmu_restart(); break; #endif /* CONFIG_ADB_PMU */ - default: + default: ; } } @@ -520,7 +522,9 @@ struct adb_request req; #endif /* CONFIG_ADB_CUDA */ +#ifdef CONFIG_NVRAM pmac_nvram_update(); +#endif switch (sys_ctrler) { #ifdef CONFIG_ADB_CUDA @@ -536,7 +540,7 @@ pmu_shutdown(); break; #endif /* CONFIG_ADB_PMU */ - default: + default: ; } } @@ -566,17 +570,19 @@ int pmac_ide_default_irq(ide_ioreg_t base) { - return 0; -} - #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) -extern ide_ioreg_t pmac_ide_get_base(int index); + extern int pmac_ide_get_irq(ide_ioreg_t base); + return pmac_ide_get_irq(base); +#else + return 0; #endif +} ide_ioreg_t pmac_ide_default_io_base(int index) { #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) + extern ide_ioreg_t pmac_ide_get_base(int index); return pmac_ide_get_base(index); #else return 0; @@ -586,7 +592,14 @@ int pmac_ide_check_region(ide_ioreg_t from, unsigned int extent) { - return 0; + /* + * We only do the check_region if `from' looks like a genuine + * I/O port number. If it actually refers to a memory-mapped + * register, it should be OK. + */ + if (from < ~_IO_BASE) + return 0; + return check_region(from, extent); } void @@ -594,24 +607,16 @@ unsigned int extent, const char *name) { + if (from < ~_IO_BASE) + request_region(from, extent, name); } void pmac_ide_release_region(ide_ioreg_t from, unsigned int extent) { -} - -/* Convert the shorts/longs in hd_driveid from little to big endian; - * chars are endian independant, of course, but strings need to be flipped. - * (Despite what it says in drivers/block/ide.h, they come up as little - * endian...) - * - * Changes to linux/hdreg.h may require changes here. */ -void -pmac_ide_fix_driveid(struct hd_driveid *id) -{ - ppc_generic_ide_fix_driveid(id); + if (from < ~_IO_BASE) + release_region(from, extent); } #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) @@ -632,8 +637,6 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { - pmac_setup_pci_ptrs(); - /* isa_io_base gets set in pmac_find_bridges */ isa_mem_base = PMAC_ISA_MEM_BASE; pci_dram_offset = PMAC_PCI_DRAM_OFFSET; @@ -646,8 +649,11 @@ ppc_md.get_cpuinfo = pmac_get_cpuinfo; ppc_md.irq_cannonicalize = NULL; ppc_md.init_IRQ = pmac_pic_init; - ppc_md.get_irq = pmac_get_irq; + ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */ ppc_md.init = pmac_init2; + + ppc_md.pcibios_fixup = pmac_pcibios_fixup; + ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook; ppc_md.restart = pmac_restart; ppc_md.power_off = pmac_power_off; @@ -658,10 +664,6 @@ ppc_md.get_rtc_time = pmac_get_rtc_time; ppc_md.calibrate_decr = pmac_calibrate_decr; - ppc_md.pci_dev_io_base = pmac_pci_dev_io_base; - ppc_md.pci_dev_mem_base = pmac_pci_dev_mem_base; - ppc_md.pci_dev_root_bridge = pmac_pci_dev_root_bridge; - #ifdef CONFIG_VT #ifdef CONFIG_INPUT_ADBHID ppc_md.kbd_init_hw = mac_hid_init_hw; @@ -682,35 +684,33 @@ } #endif /* CONFIG_MAGIC_SYSRQ */ #elif defined(CONFIG_ADB_KEYBOARD) - ppc_md.kbd_setkeycode = mackbd_setkeycode; - ppc_md.kbd_getkeycode = mackbd_getkeycode; - ppc_md.kbd_translate = mackbd_translate; - ppc_md.kbd_unexpected_up = mackbd_unexpected_up; - ppc_md.kbd_leds = mackbd_leds; - ppc_md.kbd_init_hw = mackbd_init_hw; + ppc_md.kbd_setkeycode = mackbd_setkeycode; + ppc_md.kbd_getkeycode = mackbd_getkeycode; + ppc_md.kbd_translate = mackbd_translate; + ppc_md.kbd_unexpected_up = mackbd_unexpected_up; + ppc_md.kbd_leds = mackbd_leds; + ppc_md.kbd_init_hw = mackbd_init_hw; #ifdef CONFIG_MAGIC_SYSRQ - ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate; + ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate; SYSRQ_KEY = 0x69; #endif /* CONFIG_MAGIC_SYSRQ */ #endif /* CONFIG_INPUT_ADBHID/CONFIG_ADB_KEYBOARD */ #endif /* CONFIG_VT */ #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) - ppc_ide_md.insw = pmac_ide_insw; - ppc_ide_md.outsw = pmac_ide_outsw; - ppc_ide_md.default_irq = pmac_ide_default_irq; - ppc_ide_md.default_io_base = pmac_ide_default_io_base; - ppc_ide_md.ide_check_region = pmac_ide_check_region; - ppc_ide_md.ide_request_region = pmac_ide_request_region; - ppc_ide_md.ide_release_region = pmac_ide_release_region; - ppc_ide_md.fix_driveid = pmac_ide_fix_driveid; - ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports; - - ppc_ide_md.io_base = _IO_BASE; /* actually too early for this :-( */ -#endif + ppc_ide_md.insw = pmac_ide_insw; + ppc_ide_md.outsw = pmac_ide_outsw; + ppc_ide_md.default_irq = pmac_ide_default_irq; + ppc_ide_md.default_io_base = pmac_ide_default_io_base; + ppc_ide_md.ide_check_region = pmac_ide_check_region; + ppc_ide_md.ide_request_region = pmac_ide_request_region; + ppc_ide_md.ide_release_region = pmac_ide_release_region; + ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid; + ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports; +#endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */ #ifdef CONFIG_BOOTX_TEXT ppc_md.progress = pmac_progress; -#endif +#endif /* CONFIG_BOOTX_TEXT */ if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0); } @@ -727,5 +727,5 @@ prom_drawstring(s); prom_drawchar('\n'); } -#endif CONFIG_BOOTX_TEXT +#endif /* CONFIG_BOOTX_TEXT */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/pmac_time.c linux.ac/arch/ppc/kernel/pmac_time.c --- linux.vanilla/arch/ppc/kernel/pmac_time.c Sat Oct 28 16:15:46 2000 +++ linux.ac/arch/ppc/kernel/pmac_time.c Mon Dec 18 20:45:24 2000 @@ -114,7 +114,7 @@ + (req.reply[3] << 8) + req.reply[4]; return now - RTC_OFFSET; #endif /* CONFIG_ADB_PMU */ - default: + default: ; } return 0; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/ppc_asm.h linux.ac/arch/ppc/kernel/ppc_asm.h --- linux.vanilla/arch/ppc/kernel/ppc_asm.h Tue Jul 11 12:53:54 2000 +++ linux.ac/arch/ppc/kernel/ppc_asm.h Mon Dec 18 20:45:33 2000 @@ -66,9 +66,13 @@ #define REST_16VR(n,b,base) REST_8VR(n,b,base); REST_8VR(n+8,b,base) #define REST_32VR(n,b,base) REST_16VR(n,b,base); REST_16VR(n+16,b,base) +#ifdef CONFIG_PPC601_SYNC_FIX #define SYNC \ sync; \ isync +#else +#define SYNC +#endif /* * This instruction is not implemented on the PPC 603 or 601; however, on diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/ppc_htab.c linux.ac/arch/ppc/kernel/ppc_htab.c --- linux.vanilla/arch/ppc/kernel/ppc_htab.c Tue Jul 11 12:53:54 2000 +++ linux.ac/arch/ppc/kernel/ppc_htab.c Mon Dec 18 20:45:33 2000 @@ -555,10 +555,7 @@ break; buffer += len; left -= len; - _set_L2CR(0); _set_L2CR(val); - while ( _get_L2CR() & 0x1 ) - /* wait for invalidate to finish */; } else { p = buf; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/ppc_ksyms.c linux.ac/arch/ppc/kernel/ppc_ksyms.c --- linux.vanilla/arch/ppc/kernel/ppc_ksyms.c Mon Nov 20 15:11:56 2000 +++ linux.ac/arch/ppc/kernel/ppc_ksyms.c Mon Dec 18 20:45:33 2000 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -40,6 +41,7 @@ #include #ifdef CONFIG_SMP #include +#include #endif /* CONFIG_SMP */ #include @@ -98,10 +100,6 @@ EXPORT_SYMBOL(ucSystemType); #endif #endif -#ifdef CONFIG_PCI -EXPORT_SYMBOL(pci_dev_io_base); -EXPORT_SYMBOL(pci_dev_mem_base); -#endif #if !__INLINE_BITOPS EXPORT_SYMBOL(set_bit); @@ -202,6 +200,10 @@ EXPORT_SYMBOL(_read_unlock); EXPORT_SYMBOL(_write_lock); EXPORT_SYMBOL(_write_unlock); +EXPORT_SYMBOL(smp_call_function); +EXPORT_SYMBOL(smp_hw_index); +EXPORT_SYMBOL(smp_num_cpus); +EXPORT_SYMBOL(synchronize_irq); #endif #ifndef CONFIG_MACH_SPECIFIC @@ -247,11 +249,17 @@ EXPORT_SYMBOL(find_phandle); EXPORT_SYMBOL(device_is_compatible); EXPORT_SYMBOL(machine_is_compatible); -EXPORT_SYMBOL(find_pci_device_OFnode); EXPORT_SYMBOL(find_all_nodes); EXPORT_SYMBOL(get_property); -EXPORT_SYMBOL(pci_io_base); -EXPORT_SYMBOL(pci_device_loc); +EXPORT_SYMBOL(pci_bus_io_base); +EXPORT_SYMBOL(pci_bus_io_base_phys); +EXPORT_SYMBOL(pci_bus_mem_base_phys); +EXPORT_SYMBOL(pci_device_to_OF_node); +EXPORT_SYMBOL(pci_device_from_OF_node); +EXPORT_SYMBOL(pci_bus_to_hose); +EXPORT_SYMBOL(pci_resource_to_bus); +EXPORT_SYMBOL(pci_phys_to_bus); +EXPORT_SYMBOL(pci_bus_to_phys); EXPORT_SYMBOL(feature_set); EXPORT_SYMBOL(feature_clear); EXPORT_SYMBOL(feature_test); @@ -286,6 +294,7 @@ EXPORT_SYMBOL(screen_info); #endif +EXPORT_SYMBOL(__delay); EXPORT_SYMBOL(int_control); EXPORT_SYMBOL(timer_interrupt_intercept); EXPORT_SYMBOL(timer_interrupt); @@ -300,6 +309,10 @@ #ifdef CONFIG_XMON EXPORT_SYMBOL(xmon); #endif +EXPORT_SYMBOL(__up); +EXPORT_SYMBOL(__down); +EXPORT_SYMBOL(__down_interruptible); +EXPORT_SYMBOL(__down_trylock); EXPORT_SYMBOL(down_read_failed); EXPORT_SYMBOL(down_write_failed); @@ -324,6 +337,10 @@ EXPORT_SYMBOL(next_mmu_context); EXPORT_SYMBOL(set_context); EXPORT_SYMBOL(mmu_context_overflow); +extern long *intercept_table; +extern long *ret_from_intercept; +EXPORT_SYMBOL(intercept_table); +EXPORT_SYMBOL(ret_from_intercept); #ifdef CONFIG_MOL extern ulong mol_interface[]; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/prep_nvram.c linux.ac/arch/ppc/kernel/prep_nvram.c --- linux.vanilla/arch/ppc/kernel/prep_nvram.c Thu Oct 7 18:17:08 1999 +++ linux.ac/arch/ppc/kernel/prep_nvram.c Mon Dec 18 20:45:33 2000 @@ -16,17 +16,9 @@ #include #include -/* - * Allow for a maximum of 32K of PReP NvRAM data - */ -#define MAX_PREP_NVRAM 0x8000 static char nvramData[MAX_PREP_NVRAM]; static NVRAM_MAP *nvram=(NVRAM_MAP *)&nvramData[0]; -#define PREP_NVRAM_AS0 0x74 -#define PREP_NVRAM_AS1 0x75 -#define PREP_NVRAM_DATA 0x77 - unsigned char *rs_pcNvRAM; unsigned char __prep prep_nvram_read_val(int addr) @@ -72,8 +64,8 @@ */ if ( _prep_type == _PREP_Radstone ) rs_pcNvRAM = (unsigned char *)ioremap(_ISA_MEM_BASE+0x00800000, - 32<<10); - request_region(PREP_NVRAM_AS0, 0x8, "PReP NVRAM"); + 32<<10); + /* * The following could fail if the NvRAM were corrupt but * we expect the boot firmware to have checked its checksum diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/prep_pci.c linux.ac/arch/ppc/kernel/prep_pci.c --- linux.vanilla/arch/ppc/kernel/prep_pci.c Thu Feb 10 03:43:47 2000 +++ linux.ac/arch/ppc/kernel/prep_pci.c Thu Dec 21 21:33:08 2000 @@ -7,11 +7,11 @@ * The motherboard routes/maps will disappear shortly. -- Cort */ +#include #include #include #include #include -#include #include #include @@ -25,6 +25,7 @@ #include #include "pci.h" +#include "open_pic.h" #define MAX_DEVNR 22 @@ -39,9 +40,6 @@ /* Used for Motorola to store system config register */ static unsigned long *ProcInfo; -extern int chrp_get_irq(struct pt_regs *); -extern void chrp_post_irq(struct pt_regs* regs, int); - /* Tables for known hardware */ /* Motorola PowerStackII - Utah */ @@ -534,128 +532,45 @@ #define CFGPTR(dev) (0x80800000 | (1<<(dev>>3)) | ((dev&7)<<8) | offset) #define DEVNO(dev) (dev>>3) -__prep -int -prep_pcibios_read_config_dword (unsigned char bus, - unsigned char dev, unsigned char offset, unsigned int *val) -{ - unsigned long _val; - unsigned long *ptr; - - if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR)) - { - *val = 0xFFFFFFFF; - return PCIBIOS_DEVICE_NOT_FOUND; - } else - { - ptr = (unsigned long *)CFGPTR(dev); - _val = le32_to_cpu(*ptr); - } - *val = _val; - return PCIBIOS_SUCCESSFUL; -} +#define cfg_read(val, addr, type, op) *val = op((type)(addr)) +#define cfg_write(val, addr, type, op) op((type *)(addr), (val)) -__prep -int -prep_pcibios_read_config_word (unsigned char bus, - unsigned char dev, unsigned char offset, unsigned short *val) -{ - unsigned short _val; - unsigned short *ptr; - - if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR)) - { - *val = 0xFFFF; - return PCIBIOS_DEVICE_NOT_FOUND; - } else - { - ptr = (unsigned short *)CFGPTR(dev); - _val = le16_to_cpu(*ptr); - } - *val = _val; - return PCIBIOS_SUCCESSFUL; -} +#define cfg_read_bad(val, size) *val = bad_##size; +#define cfg_write_bad(val, size) -__prep -int -prep_pcibios_read_config_byte (unsigned char bus, - unsigned char dev, unsigned char offset, unsigned char *val) -{ - unsigned char _val; - unsigned char *ptr; - - if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR)) - { - *val = 0xFF; - return PCIBIOS_DEVICE_NOT_FOUND; - } else - { - ptr = (unsigned char *)CFGPTR(dev); - _val = *ptr; - } - *val = _val; - return PCIBIOS_SUCCESSFUL; +#define bad_byte 0xff +#define bad_word 0xffff +#define bad_dword 0xffffffffU + +#define PREP_PCI_OP(rw, size, type, op) \ +static int __prep \ +prep_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + if ((dev->bus->number != 0) || (DEVNO(dev->devfn) > MAX_DEVNR)) \ + { \ + cfg_##rw##_bad(val, size) \ + return PCIBIOS_DEVICE_NOT_FOUND; \ + } \ + cfg_##rw(val, CFGPTR(dev->devfn), type, op); \ + return PCIBIOS_SUCCESSFUL; \ } -__prep -int -prep_pcibios_write_config_dword (unsigned char bus, - unsigned char dev, unsigned char offset, unsigned int val) -{ - unsigned long _val; - unsigned long *ptr; - - _val = le32_to_cpu(val); - if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR)) - { - return PCIBIOS_DEVICE_NOT_FOUND; - } else - { - ptr = (unsigned long *)CFGPTR(dev); - *ptr = _val; - } - return PCIBIOS_SUCCESSFUL; -} - -__prep -int -prep_pcibios_write_config_word (unsigned char bus, - unsigned char dev, unsigned char offset, unsigned short val) -{ - unsigned short _val; - unsigned short *ptr; - - _val = le16_to_cpu(val); - if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR)) - { - return PCIBIOS_DEVICE_NOT_FOUND; - } else - { - ptr = (unsigned short *)CFGPTR(dev); - *ptr = _val; - } - return PCIBIOS_SUCCESSFUL; -} - -__prep -int -prep_pcibios_write_config_byte (unsigned char bus, - unsigned char dev, unsigned char offset, unsigned char val) -{ - unsigned char _val; - unsigned char *ptr; - - _val = val; - if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR)) - { - return PCIBIOS_DEVICE_NOT_FOUND; - } else - { - ptr = (unsigned char *)CFGPTR(dev); - *ptr = _val; - } - return PCIBIOS_SUCCESSFUL; -} +PREP_PCI_OP(read, byte, u8 *, in_8) +PREP_PCI_OP(read, word, u16 *, in_le16) +PREP_PCI_OP(read, dword, u32 *, in_le32) +PREP_PCI_OP(write, byte, u8, out_8) +PREP_PCI_OP(write, word, u16, out_le16) +PREP_PCI_OP(write, dword, u32, out_le32) + +static struct pci_ops prep_pci_ops = +{ + prep_read_config_byte, + prep_read_config_word, + prep_read_config_dword, + prep_write_config_byte, + prep_write_config_word, + prep_write_config_dword +}; #define MOTOROLA_CPUTYPE_REG 0x800 #define MOTOROLA_BASETYPE_REG 0x803 @@ -686,6 +601,7 @@ int prep_keybd_present = 1; int MotMPIC = 0; +int mot_multi = 0; int __init raven_init(void) { @@ -695,18 +611,18 @@ /* Check to see if the Raven chip exists. */ if ( _prep_type != _PREP_Motorola) { - OpenPIC = NULL; + OpenPIC_Addr = NULL; return 0; } /* Check to see if this board is a type that might have a Raven. */ if ((inb(MOTOROLA_CPUTYPE_REG) & 0xF0) != 0xE0) { - OpenPIC = NULL; + OpenPIC_Addr = NULL; return 0; } /* Check the first PCI device to see if it is a Raven. */ - pcibios_read_config_dword(0, 0, PCI_VENDOR_ID, &devid); + early_read_config_dword(0, 0, 0, PCI_VENDOR_ID, &devid); switch (devid & 0xffff0000) { case MPIC_RAVEN_ID: @@ -716,33 +632,37 @@ MotMPIC = MOT_HAWK_PRESENT; break; default: - OpenPIC = NULL; + OpenPIC_Addr = NULL; return 0; } /* Read the memory base register. */ - pcibios_read_config_dword(0, 0, PCI_BASE_ADDRESS_1, &pci_membase); + early_read_config_dword(0, 0, 0, PCI_BASE_ADDRESS_1, &pci_membase); if (pci_membase == 0) { - OpenPIC = NULL; + OpenPIC_Addr = NULL; return 0; } /* Map the Raven MPIC registers to virtual memory. */ - OpenPIC = (struct OpenPIC *)ioremap(pci_membase+0xC0000000, 0x22000); + OpenPIC_Addr = ioremap(pci_membase+0xC0000000, 0x22000); OpenPIC_InitSenses = mvme2600_openpic_initsenses; OpenPIC_NumInitSenses = sizeof(mvme2600_openpic_initsenses); - ppc_md.get_irq = chrp_get_irq; - ppc_md.post_irq = chrp_post_irq; + ppc_md.get_irq = openpic_get_irq; /* If raven is present on Motorola store the system config register * for later use. */ ProcInfo = (unsigned long *)ioremap(0xfef80400, 4); + /* Indicate to system if this is a multiprocessor board */ + if (!(*ProcInfo & MOT_PROC2_BIT)) { + mot_multi = 1; + } + /* This is a hack. If this is a 2300 or 2400 mot board then there is * no keyboard controller and we have to indicate that. */ @@ -996,7 +916,7 @@ prep_route_pci_interrupts(); printk("Setting PCI interrupts for a \"%s\"\n", Motherboard_map_name); - if (OpenPIC) { + if (OpenPIC_Addr) { /* PCI interrupts are controlled by the OpenPIC */ pci_for_each_dev(dev) { if (dev->bus->number == 0) { @@ -1018,7 +938,12 @@ for ( i = 0 ; i <= 5 ; i++ ) { - if ( dev->resource[i].start > 0x10000000 ) + /* + * Relocate PCI I/O resources if necessary so the + * standard 256MB BAT covers them. + */ + if ( (pci_resource_flags(dev, i) & IORESOURCE_IO) && + (dev->resource[i].start > 0x10000000) ) { printk("Relocating PCI address %lx -> %lx\n", dev->resource[i].start, @@ -1043,49 +968,54 @@ } } -decl_config_access_method(indirect); - void __init -prep_setup_pci_ptrs(void) +prep_find_bridges(void) { PPC_DEVICE *hostbridge; + struct pci_controller* hose; - printk("PReP architecture\n"); - if ( _prep_type == _PREP_Radstone ) - { - pci_config_address = (unsigned *)0x80000cf8; - pci_config_data = (char *)0x80000cfc; - set_config_access_method(indirect); - } - else - { - hostbridge = residual_find_device(PROCESSORDEVICE, NULL, - BridgeController, PCIBridge, -1, 0); - if (hostbridge && - hostbridge->DeviceId.Interface == PCIBridgeIndirect) { - PnP_TAG_PACKET * pkt; - set_config_access_method(indirect); - pkt = PnP_find_large_vendor_packet( + hose = pcibios_alloc_controller(); + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + hose->pci_mem_offset = PREP_ISA_MEM_BASE; + + printk("PReP architecture\n"); + if ( _prep_type == _PREP_Radstone ) + { + setup_indirect_pci(hose, 0x80000cf8, 0x80000cfc); + } + else + { +#ifdef CONFIG_PREP_RESIDUAL + hostbridge = residual_find_device(PROCESSORDEVICE, NULL, + BridgeController, PCIBridge, -1, 0); + if (hostbridge && + hostbridge->DeviceId.Interface == PCIBridgeIndirect) { + PnP_TAG_PACKET * pkt; + pkt = PnP_find_large_vendor_packet( res->DevicePnPHeap+hostbridge->AllocatedOffset, 3, 0); - if(pkt) + if(pkt) { #define p pkt->L4_Pack.L4_Data.L4_PPCPack - pci_config_address= (unsigned *)ld_le32((unsigned *) p.PPCData); - pci_config_data= (unsigned char *)ld_le32((unsigned *) (p.PPCData+8)); - } + setup_indirect_pci(hose, + ld_le32((unsigned *) (p.PPCData)), + ld_le32((unsigned *) (p.PPCData+8))); + } else { - pci_config_address= (unsigned *) 0x80000cf8; - pci_config_data= (unsigned char *) 0x80000cfc; - } - } + setup_indirect_pci(hose, 0x80000cf8, 0x80000cfc); + } + } else +#endif /* CONFIG_PREP_RESIDUAL */ { - set_config_access_method(prep); - } - - } + hose->ops = &prep_pci_ops; + } + } ppc_md.pcibios_fixup = prep_pcibios_fixup; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/prep_setup.c linux.ac/arch/ppc/kernel/prep_setup.c --- linux.vanilla/arch/ppc/kernel/prep_setup.c Tue Oct 31 20:26:00 2000 +++ linux.ac/arch/ppc/kernel/prep_setup.c Fri Dec 22 16:37:08 2000 @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -48,8 +47,9 @@ #include #include #include - +#include #include + #include "local_irq.h" #include "i8259.h" #include "open_pic.h" @@ -84,7 +84,7 @@ extern void pckbd_init_hw(void); extern unsigned char pckbd_sysrq_xlate[128]; -extern void prep_setup_pci_ptrs(void); +extern void prep_find_bridges(void); extern char saved_command_line[256]; int _prep_type; @@ -101,16 +101,13 @@ extern PTE *Hash, *Hash_end; extern unsigned long Hash_size, Hash_mask; extern int probingmem; -extern unsigned long loops_per_sec; +extern unsigned long loops_per_jiffy; #ifdef CONFIG_BLK_DEV_RAM extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */ extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */ extern int rd_image_start; /* starting block # of image */ #endif -#ifdef CONFIG_VGA_CONSOLE -unsigned long vgacon_remap_base; -#endif int __prep prep_get_cpuinfo(char *buffer) @@ -190,7 +187,10 @@ } -no_l2: +no_l2: +#ifndef CONFIG_PREP_RESIDUAL + return len; +#else if ( res->ResidualLength == 0 ) return len; @@ -205,8 +205,8 @@ res->Memories[i].SIMMSize); } len += sprintf(buffer+len,"\n"); - return len; +#endif } void __init @@ -218,7 +218,10 @@ unsigned char ucEquipPres1; /* init to some ~sane value until calibrate_delay() runs */ - loops_per_sec = 50000000; + loops_per_sec = 50000000/HZ; + + /* Lookup PCI host bridges */ + prep_find_bridges(); /* Set up floppy in PS/2 mode */ outb(0x09, SIO_CONFIG_RA); @@ -341,12 +344,6 @@ #endif /* CONFIG_SOUND_CS4232 */ /*print_residual_device_info();*/ - request_region(0x20,0x20,"pic1"); - request_region(0xa0,0x20,"pic2"); - request_region(0x00,0x20,"dma1"); - request_region(0x40,0x20,"timer"); - request_region(0x80,0x10,"dma page reg"); - request_region(0xc0,0x20,"dma2"); raven_init(); @@ -367,11 +364,13 @@ { unsigned long freq, divisor=4; +#ifdef CONFIG_PREP_RESIDUAL freq = res->VitalProductData.ProcessorBusHz; printk("time_init: decrementer frequency = %lu.%.6lu MHz\n", (freq/divisor)/1000000, (freq/divisor)%1000000); tb_ticks_per_jiffy = freq / HZ / divisor; tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); +#endif } /* @@ -585,15 +584,16 @@ { int len = 0; - /* PREP's without residual data will give incorrect values here */ len += sprintf(len+buffer, "clock\t\t: "); +#ifdef CONFIG_PREP_RESIDUAL if ( res->ResidualLength ) len += sprintf(len+buffer, "%ldMHz\n", (res->VitalProductData.ProcessorHz > 1024) ? res->VitalProductData.ProcessorHz>>20 : res->VitalProductData.ProcessorHz); else +#endif /* CONFIG_PREP_RESIDUAL */ len += sprintf(len+buffer, "???\n"); return len; @@ -640,19 +640,11 @@ { int i; - if (OpenPIC != NULL) { - for ( i = 16 ; i < 36 ; i++ ) - irq_desc[i].handler = &open_pic; - openpic_init(1); - } - - for ( i = 0 ; i < 16 ; i++ ) + if (OpenPIC_Addr != NULL) + openpic_init(1, NUM_8259_INTERRUPTS, 0, -1); + for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ ) irq_desc[i].handler = &i8259_pic; - i8259_init(); -#ifdef CONFIG_SMP - request_irq(openpic_to_irq(OPENPIC_VEC_SPURIOUS), openpic_ipi_action, - 0, "IPI0", 0); -#endif /* CONFIG_SMP */ + i8259_init(); } #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) @@ -708,19 +700,14 @@ unsigned int extent, const char *name) { - request_region(from, extent, name); + request_region(from, extent, name); } void __prep prep_ide_release_region(ide_ioreg_t from, unsigned int extent) { - release_region(from, extent); -} - -void __prep -prep_ide_fix_driveid(struct hd_driveid *id) -{ + release_region(from, extent); } void __init @@ -743,17 +730,52 @@ } #endif +unsigned long *MotSave_SmpIar; +unsigned char *MotSave_CpusState[2]; + +void __init +prep_init2(void) +{ +#ifdef CONFIG_NVRAM + request_region(PREP_NVRAM_AS0, 0x8, "nvram"); +#endif + request_region(0x20,0x20,"pic1"); + request_region(0xa0,0x20,"pic2"); + request_region(0x00,0x20,"dma1"); + request_region(0x40,0x20,"timer"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xc0,0x20,"dma2"); +} + void __init prep_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { + RESIDUAL *old_res = (RESIDUAL *)(r3 + KERNELBASE); + /* make a copy of residual data */ +#ifdef CONFIG_PREP_RESIDUAL if ( r3 ) { memcpy((void *)res,(void *)(r3+KERNELBASE), sizeof(RESIDUAL)); + + /* These need to be saved for the Motorola Prep + * MVME4600 and Dual MTX boards. + */ + MotSave_SmpIar = &old_res->VitalProductData.SmpIar; + MotSave_CpusState[0] = &old_res->Cpus[0].CpuState; + MotSave_CpusState[1] = &old_res->Cpus[1].CpuState; } +#endif + /* Copy cmd_line parameters */ + if ( r6) + { + *(char *)(r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *)(r6 + KERNELBASE)); + } + isa_io_base = PREP_ISA_IO_BASE; isa_mem_base = PREP_ISA_MEM_BASE; pci_dram_offset = PREP_PCI_DRAM_OFFSET; @@ -762,6 +784,7 @@ DMA_MODE_WRITE = 0x48; /* figure out what kind of prep workstation we are */ +#ifdef CONFIG_PREP_RESIDUAL if ( res->ResidualLength != 0 ) { if ( !strncmp(res->VitalProductData.PrintableModel,"IBM",3) ) @@ -779,12 +802,11 @@ _prep_type = _PREP_Motorola; } else /* assume motorola if no residual (netboot?) */ +#endif { _prep_type = _PREP_Motorola; } - prep_setup_pci_ptrs(); - ppc_md.setup_arch = prep_setup_arch; ppc_md.setup_residual = prep_setup_residual; ppc_md.get_cpuinfo = prep_get_cpuinfo; @@ -792,7 +814,7 @@ ppc_md.init_IRQ = prep_init_IRQ; /* this gets changed later on if we have an OpenPIC -- Cort */ ppc_md.get_irq = prep_get_irq; - ppc_md.init = NULL; + ppc_md.init = prep_init2; ppc_md.restart = prep_restart; ppc_md.power_off = prep_power_off; @@ -845,7 +867,7 @@ ppc_ide_md.ide_check_region = prep_ide_check_region; ppc_ide_md.ide_request_region = prep_ide_request_region; ppc_ide_md.ide_release_region = prep_ide_release_region; - ppc_ide_md.fix_driveid = prep_ide_fix_driveid; + ppc_ide_md.fix_driveid = NULL; ppc_ide_md.ide_init_hwif = prep_ide_init_hwif_ports; #endif ppc_ide_md.io_base = _IO_BASE; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/proc_rtas.c linux.ac/arch/ppc/kernel/proc_rtas.c --- linux.vanilla/arch/ppc/kernel/proc_rtas.c Thu Jan 1 01:00:00 1970 +++ linux.ac/arch/ppc/kernel/proc_rtas.c Thu Dec 21 21:33:08 2000 @@ -0,0 +1,786 @@ +/* + * arch/ppc/kernel/proc_rtas.c + * Copyright (C) 2000 Tilmann Bitterberg + * (tilmann@bitterberg.de) + * + * RTAS (Runtime Abstraction Services) stuff + * Intention is to provide a clean user interface + * to use the RTAS. + * + * TODO: + * Split off a header file and maybe move it to a different + * location. Write Documentation on what the /proc/rtas/ entries + * actually do. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include /* for ppc_md */ +#include + +/* Token for Sensors */ +#define KEY_SWITCH 0x0001 +#define ENCLOSURE_SWITCH 0x0002 +#define THERMAL_SENSOR 0x0003 +#define LID_STATUS 0x0004 +#define POWER_SOURCE 0x0005 +#define BATTERY_VOLTAGE 0x0006 +#define BATTERY_REMAINING 0x0007 +#define BATTERY_PERCENTAGE 0x0008 +#define EPOW_SENSOR 0x0009 +#define BATTERY_CYCLESTATE 0x000a +#define BATTERY_CHARGING 0x000b + +/* IBM specific sensors */ +#define IBM_SURVEILLANCE 0x2328 /* 9000 */ +#define IBM_FANRPM 0x2329 /* 9001 */ +#define IBM_VOLTAGE 0x232a /* 9002 */ +#define IBM_DRCONNECTOR 0x232b /* 9003 */ +#define IBM_POWERSUPPLY 0x232c /* 9004 */ +#define IBM_INTQUEUE 0x232d /* 9005 */ + +/* Status return values */ +#define SENSOR_CRITICAL_HIGH 13 +#define SENSOR_WARNING_HIGH 12 +#define SENSOR_NORMAL 11 +#define SENSOR_WARNING_LOW 10 +#define SENSOR_CRITICAL_LOW 9 +#define SENSOR_SUCCESS 0 +#define SENSOR_HW_ERROR -1 +#define SENSOR_BUSY -2 +#define SENSOR_NOT_EXIST -3 +#define SENSOR_DR_ENTITY -9000 + +/* Location Codes */ +#define LOC_SCSI_DEV_ADDR 'A' +#define LOC_SCSI_DEV_LOC 'B' +#define LOC_CPU 'C' +#define LOC_DISKETTE 'D' +#define LOC_ETHERNET 'E' +#define LOC_FAN 'F' +#define LOC_GRAPHICS 'G' +/* reserved / not used 'H' */ +#define LOC_IO_ADAPTER 'I' +/* reserved / not used 'J' */ +#define LOC_KEYBOARD 'K' +#define LOC_LCD 'L' +#define LOC_MEMORY 'M' +#define LOC_NV_MEMORY 'N' +#define LOC_MOUSE 'O' +#define LOC_PLANAR 'P' +#define LOC_OTHER_IO 'Q' +#define LOC_PARALLEL 'R' +#define LOC_SERIAL 'S' +#define LOC_DEAD_RING 'T' +#define LOC_RACKMOUNTED 'U' /* for _u_nit is rack mounted */ +#define LOC_VOLTAGE 'V' +#define LOC_SWITCH_ADAPTER 'W' +#define LOC_OTHER 'X' +#define LOC_FIRMWARE 'Y' +#define LOC_SCSI 'Z' + +/* Tokens for indicators */ +#define TONE_FREQUENCY 0x0001 /* 0 - 1000 (HZ)*/ +#define TONE_VOLUME 0x0002 /* 0 - 100 (%) */ +#define SYSTEM_POWER_STATE 0x0003 +#define WARNING_LIGHT 0x0004 +#define DISK_ACTIVITY_LIGHT 0x0005 +#define HEX_DISPLAY_UNIT 0x0006 +#define BATTERY_WARNING_TIME 0x0007 +#define CONDITION_CYCLE_REQUEST 0x0008 +#define SURVEILLANCE_INDICATOR 0x2328 /* 9000 */ +#define DR_ACTION 0x2329 /* 9001 */ +#define DR_INDICATOR 0x232a /* 9002 */ +/* 9003 - 9004: Vendor specific */ +#define GLOBAL_INTERRUPT_QUEUE 0x232d /* 9005 */ +/* 9006 - 9999: Vendor specific */ + +/* other */ +#define MAX_SENSORS 17 /* I only know of 17 sensors */ +#define MAX_LINELENGTH 256 +#define SENSOR_PREFIX "ibm,sensor-" +#define cel_to_fahr(x) ((x*9/5)+32) + + +/* Globals */ +static struct proc_dir_entry *proc_rtas; +static struct rtas_sensors sensors; +static struct device_node *rtas; +static unsigned long power_on_time = 0; /* Save the time the user set */ +static char progress_led[MAX_LINELENGTH]; + +static unsigned long rtas_tone_frequency = 1000; +static unsigned long rtas_tone_volume = 0; + +/* ****************STRUCTS******************************************* */ +struct individual_sensor { + unsigned int token; + unsigned int quant; +}; + +struct rtas_sensors { + struct individual_sensor sensor[MAX_SENSORS]; + unsigned int quant; +}; + +/* ****************************************************************** */ +/* Declarations */ +static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off, + int count, int *eof, void *data); +static ssize_t ppc_rtas_clock_read(struct file * file, char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_progress_read(struct file * file, char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_progress_write(struct file * file, const char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf, + size_t count, loff_t *ppos); + +static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf, + size_t count, loff_t *ppos); + +struct file_operations ppc_rtas_poweron_operations = { + read: ppc_rtas_poweron_read, + write: ppc_rtas_poweron_write +}; +struct file_operations ppc_rtas_progress_operations = { + read: ppc_rtas_progress_read, + write: ppc_rtas_progress_write +}; + +struct file_operations ppc_rtas_clock_operations = { + read: ppc_rtas_clock_read, + write: ppc_rtas_clock_write +}; + +struct file_operations ppc_rtas_tone_freq_operations = { + read: ppc_rtas_tone_freq_read, + write: ppc_rtas_tone_freq_write +}; +struct file_operations ppc_rtas_tone_volume_operations = { + read: ppc_rtas_tone_volume_read, + write: ppc_rtas_tone_volume_write +}; + +int ppc_rtas_find_all_sensors (void); +int ppc_rtas_process_sensor(struct individual_sensor s, int state, + int error, char * buf); +char * ppc_rtas_process_error(int error); +int get_location_code(struct individual_sensor s, char * buf); +int check_location_string (char *c, char * buf); +int check_location (char *c, int idx, char * buf); + +/* ****************************************************************** */ +/* MAIN */ +/* ****************************************************************** */ +void proc_rtas_init(void) +{ + struct proc_dir_entry *entry; + + rtas = find_devices("rtas"); + if ((rtas == 0) || (_machine != _MACH_chrp)) { + return; + } + + proc_rtas = proc_mkdir("rtas", 0); + if (proc_rtas == 0) + return; + + /* /proc/rtas entries */ + + entry = create_proc_entry("progress", S_IRUGO|S_IWUSR, proc_rtas); + if (entry) entry->proc_fops = &ppc_rtas_progress_operations; + + entry = create_proc_entry("clock", S_IRUGO|S_IWUSR, proc_rtas); + if (entry) entry->proc_fops = &ppc_rtas_clock_operations; + + entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, proc_rtas); + if (entry) entry->proc_fops = &ppc_rtas_poweron_operations; + + create_proc_read_entry("sensors", S_IRUGO, proc_rtas, + ppc_rtas_sensor_read, NULL); + + entry = create_proc_entry("frequency", S_IWUSR|S_IRUGO, proc_rtas); + if (entry) entry->proc_fops = &ppc_rtas_tone_freq_operations; + + entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, proc_rtas); + if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations; + create_proc_read_entry("errors", S_IRUGO, proc_rtas, + ppc_rtas_errorlog_read, NULL); +} + +/* ****************************************************************** */ +/* POWER-ON-TIME */ +/* ****************************************************************** */ +static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + struct rtc_time tm; + unsigned long nowtime; + char *dest; + int error; + + nowtime = simple_strtoul(buf, &dest, 10); + if (*dest != '\0' && *dest != '\n') { + printk("ppc_rtas_poweron_write: Invalid time\n"); + return count; + } + power_on_time = nowtime; /* save the time */ + + to_tm(nowtime, &tm); + + error = call_rtas("set-time-for-power-on", 7, 1, NULL, + tm.tm_year, tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec, 0 /* nano */); + if (error != 0) + printk(KERN_WARNING "error: setting poweron time returned: %s\n", + ppc_rtas_process_error(error)); + return count; +} +/* ****************************************************************** */ +static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + int n; + if (power_on_time == 0) + n = sprintf(buf, "Power on time not set\n"); + else + n = sprintf(buf, "%lu\n", power_on_time); + + if (*ppos >= strlen(buf)) + return 0; + if (n > strlen(buf) - *ppos) + n = strlen(buf) - *ppos; + if (n > count) + n = count; + *ppos += n; + return n; +} + +/* ****************************************************************** */ +/* PROGRESS */ +/* ****************************************************************** */ +static ssize_t ppc_rtas_progress_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + unsigned long hex; + + strcpy(progress_led, buf); /* save the string */ + /* Lets see if the user passed hexdigits */ + hex = simple_strtoul(buf, NULL, 10); + + ppc_md.progress ((char *)buf, hex); + return count; + + /* clear the line */ /* ppc_md.progress(" ", 0xffff);*/ +} +/* ****************************************************************** */ +static ssize_t ppc_rtas_progress_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + int n = 0; + if (progress_led != NULL) + n = sprintf (buf, "%s\n", progress_led); + if (*ppos >= strlen(buf)) + return 0; + if (n > strlen(buf) - *ppos) + n = strlen(buf) - *ppos; + if (n > count) + n = count; + *ppos += n; + return n; +} + +/* ****************************************************************** */ +/* CLOCK */ +/* ****************************************************************** */ +static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + struct rtc_time tm; + unsigned long nowtime; + char *dest; + int error; + + nowtime = simple_strtoul(buf, &dest, 10); + if (*dest != '\0' && *dest != '\n') { + printk("ppc_rtas_clock_write: Invalid time\n"); + return count; + } + + to_tm(nowtime, &tm); + error = call_rtas("set-time-of-day", 7, 1, NULL, + tm.tm_year, tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec, 0); + if (error != 0) + printk(KERN_WARNING "error: setting the clock returned: %s\n", + ppc_rtas_process_error(error)); + return count; +} +/* ****************************************************************** */ +static ssize_t ppc_rtas_clock_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + unsigned int year, mon, day, hour, min, sec; + unsigned long *ret = kmalloc(4*8, GFP_KERNEL); + int n, error; + + error = call_rtas("get-time-of-day", 0, 8, ret); + + year = ret[0]; mon = ret[1]; day = ret[2]; + hour = ret[3]; min = ret[4]; sec = ret[5]; + + if (error != 0){ + printk(KERN_WARNING "error: reading the clock returned: %s\n", + ppc_rtas_process_error(error)); + n = sprintf (buf, "0"); + } else { + n = sprintf (buf, "%lu\n", mktime(year, mon, day, hour, min, sec)); + } + kfree(ret); + + if (*ppos >= strlen(buf)) + return 0; + if (n > strlen(buf) - *ppos) + n = strlen(buf) - *ppos; + if (n > count) + n = count; + *ppos += n; + return n; +} + +/* ****************************************************************** */ +/* SENSOR STUFF */ +/* ****************************************************************** */ +static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off, + int count, int *eof, void *data) +{ + int i,j,n; + unsigned long ret; + int state, error; + char buffer[MAX_LINELENGTH*MAX_SENSORS]; /* May not be enough */ + + if (count < 0) + return -EINVAL; + + n = sprintf ( buffer , "RTAS (RunTime Abstraction Services) Sensor Information\n"); + n += sprintf ( buffer+n, "Sensor\t\tValue\t\tCondition\tLocation\n"); + n += sprintf ( buffer+n, "********************************************************\n"); + + if (ppc_rtas_find_all_sensors() != 0) { + n += sprintf ( buffer+n, "\nNo sensors are available\n"); + goto return_string; + } + + for (i=0; i= 0) { + error = call_rtas("get-sensor-state", 2, 2, &ret, + sensors.sensor[i].token, sensors.sensor[i].quant-j); + state = (int) ret; + n += ppc_rtas_process_sensor(sensors.sensor[i], state, error, buffer+n ); + n += sprintf (buffer+n, "\n"); + j--; + } /* while */ + } /* for */ + +return_string: + if (off >= strlen(buffer)) { + *eof = 1; + return 0; + } + if (n > strlen(buffer) - off) + n = strlen(buffer) - off; + if (n > count) + n = count; + else + *eof = 1; + memcpy(buf, buffer + off, n); + *start = buf; + return n; +} + +/* ****************************************************************** */ + +int ppc_rtas_find_all_sensors (void) +{ + unsigned long *utmp; + int len, i, j; + + utmp = (unsigned long *) get_property(rtas, "rtas-sensors", &len); + if (utmp == NULL) { + printk (KERN_ERR "error: could not get rtas-sensors\n"); + return 1; + } + + sensors.quant = len / 8; /* int + int */ + + for (i=0, j=0; j= llen) pos=0; + } + return n; +} +/* ****************************************************************** */ +/* INDICATORS - Tone Frequency */ +/* ****************************************************************** */ +static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + unsigned long freq; + char *dest; + int error; + freq = simple_strtoul(buf, &dest, 10); + if (*dest != '\0' && *dest != '\n') { + printk("ppc_rtas_tone_freq_write: Invalid tone freqency\n"); + return count; + } + if (freq < 0) freq = 0; + rtas_tone_frequency = freq; /* save it for later */ + error = call_rtas("set-indicator", 3, 1, NULL, + TONE_FREQUENCY, 0, freq); + if (error != 0) + printk(KERN_WARNING "error: setting tone frequency returned: %s\n", + ppc_rtas_process_error(error)); + return count; +} +/* ****************************************************************** */ +static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + int n; + n = sprintf(buf, "%lu\n", rtas_tone_frequency); + + if (*ppos >= strlen(buf)) + return 0; + if (n > strlen(buf) - *ppos) + n = strlen(buf) - *ppos; + if (n > count) + n = count; + *ppos += n; + return n; +} +/* ****************************************************************** */ +/* INDICATORS - Tone Volume */ +/* ****************************************************************** */ +static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + unsigned long volume; + char *dest; + int error; + volume = simple_strtoul(buf, &dest, 10); + if (*dest != '\0' && *dest != '\n') { + printk("ppc_rtas_tone_volume_write: Invalid tone volume\n"); + return count; + } + if (volume < 0) volume = 0; + if (volume > 100) volume = 100; + + rtas_tone_volume = volume; /* save it for later */ + error = call_rtas("set-indicator", 3, 1, NULL, + TONE_VOLUME, 0, volume); + if (error != 0) + printk(KERN_WARNING "error: setting tone volume returned: %s\n", + ppc_rtas_process_error(error)); + return count; +} +/* ****************************************************************** */ +static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + int n; + n = sprintf(buf, "%lu\n", rtas_tone_volume); + + if (*ppos >= strlen(buf)) + return 0; + if (n > strlen(buf) - *ppos) + n = strlen(buf) - *ppos; + if (n > count) + n = count; + *ppos += n; + return n; +} diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/process.c linux.ac/arch/ppc/kernel/process.c --- linux.vanilla/arch/ppc/kernel/process.c Mon Nov 20 15:11:56 2000 +++ linux.ac/arch/ppc/kernel/process.c Mon Dec 18 20:45:53 2000 @@ -285,7 +285,7 @@ printk("\n"); } } -out: +out: ; } void exit_thread(void) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/prom.c linux.ac/arch/ppc/kernel/prom.c --- linux.vanilla/arch/ppc/kernel/prom.c Sat Oct 28 16:15:46 2000 +++ linux.ac/arch/ppc/kernel/prom.c Mon Dec 18 20:45:53 2000 @@ -32,6 +32,8 @@ #include #include #include +/* for openpic_to_irq */ +#include "open_pic.h" #ifdef CONFIG_FB #include @@ -95,26 +97,28 @@ #define FB_MAX 8 #endif char *prom_display_paths[FB_MAX] __initdata = { 0, }; -unsigned int prom_num_displays = 0; -char *of_stdout_device = 0; - -prom_entry prom = 0; -ihandle prom_chosen = 0, prom_stdout = 0, prom_disp_node = 0; +unsigned int prom_num_displays __initdata = 0; +char *of_stdout_device __initdata = 0; +ihandle prom_disp_node __initdata = 0; + +prom_entry prom __initdata = 0; +ihandle prom_chosen __initdata = 0; +ihandle prom_stdout __initdata = 0; extern char *klimit; -char *bootpath = 0; -char *bootdevice = 0; +char *bootpath; +char *bootdevice; -unsigned int rtas_data = 0; /* physical pointer */ -unsigned int rtas_entry = 0; /* physical pointer */ -unsigned int rtas_size = 0; -unsigned int old_rtas = 0; +unsigned int rtas_data; /* physical pointer */ +unsigned int rtas_entry; /* physical pointer */ +unsigned int rtas_size; +unsigned int old_rtas; /* Set for a newworld machine */ -int use_of_interrupt_tree = 0; -int pmac_newworld = 0; +int use_of_interrupt_tree; +int pmac_newworld; -static struct device_node *allnodes = 0; +static struct device_node *allnodes; #ifdef CONFIG_BOOTX_TEXT @@ -134,13 +138,12 @@ static void draw_byte_16(unsigned char *bits, unsigned long *base, int rb); static void draw_byte_8(unsigned char *bits, unsigned long *base, int rb); -/* We want those in data, not BSS */ -static long g_loc_X = 0; -static long g_loc_Y = 0; -static long g_max_loc_X = 0; -static long g_max_loc_Y = 0; +static int g_loc_X; +static int g_loc_Y; +static int g_max_loc_X; +static int g_max_loc_Y; -unsigned long disp_BAT[2] = {0, 0}; +unsigned long disp_BAT[2] __initdata = {0, 0}; #define cmapsz (16*256) @@ -173,10 +176,10 @@ void phys_call_rtas(int, int, int, ...); extern char cmd_line[512]; /* XXX */ -boot_infos_t *boot_infos = 0; /* init it so it's in data segment not bss */ +boot_infos_t *boot_infos; #ifdef CONFIG_BOOTX_TEXT -boot_infos_t *disp_bi = 0; -boot_infos_t fake_bi = {0,}; +boot_infos_t *disp_bi; +boot_infos_t fake_bi; #endif unsigned long dev_tree_size; @@ -195,10 +198,6 @@ * OF calls should be done within prom_init(), and prom_init() * and all routines called within it must be careful to relocate * references as necessary. - * - * Note that the bss is cleared *after* prom_init runs, so we have - * to make sure that any static or extern variables it accesses - * are put in the data segment. */ #define PTRRELOC(x) ((typeof(x))((unsigned long)(x) + offset)) #define PTRUNRELOC(x) ((typeof(x))((unsigned long)(x) - offset)) @@ -618,6 +617,10 @@ char *p, *d; int prom_version = 0; unsigned long phys; + extern char __bss_start, _end; + + /* First zero the BSS */ + cacheable_memzero(PTRRELOC(&__bss_start), &_end - &__bss_start); /* Default */ phys = offset + KERNELBASE; @@ -948,34 +951,6 @@ if ((int) call_prom(RELOC("package-to-path"), 3, 1, node, path, 255) < 0) continue; - prom_print(RELOC("opening display ")); - prom_print(path); - ih = call_prom(RELOC("open"), 1, 1, path); - if (ih == 0 || ih == (ihandle) -1) { - prom_print(RELOC("... failed\n")); - continue; - } - prom_print(RELOC("... ok\n")); - - if (RELOC(prom_disp_node) == 0) - RELOC(prom_disp_node) = node; - - /* Setup a useable color table when the appropriate - * method is available. Should update this to set-colors */ - for (i = 0; i < 32; i++) - if (prom_set_color(ih, i, RELOC(default_colors)[i*3], - RELOC(default_colors)[i*3+1], - RELOC(default_colors)[i*3+2]) != 0) - break; - -#ifdef CONFIG_FB - for (i = 0; i < LINUX_LOGO_COLORS; i++) - if (prom_set_color(ih, i + 32, - RELOC(linux_logo_red)[i], - RELOC(linux_logo_green)[i], - RELOC(linux_logo_blue)[i]) != 0) - break; -#endif /* CONFIG_FB */ /* * If this display is the device that OF is using for stdout, @@ -990,9 +965,44 @@ = RELOC(prom_display_paths[i-1]); } RELOC(prom_display_paths[i]) = PTRUNRELOC(path); + if (i == 0) + RELOC(prom_disp_node) = node; if (RELOC(prom_num_displays) >= FB_MAX) break; } + + /* + * Open the first display and set its colormap. + */ + if (RELOC(prom_num_displays) > 0) { + path = PTRRELOC(RELOC(prom_display_paths[0])); + prom_print(RELOC("opening display ")); + prom_print(path); + ih = call_prom(RELOC("open"), 1, 1, path); + if (ih == 0 || ih == (ihandle) -1) { + prom_print(RELOC("... failed\n")); + } else { + prom_print(RELOC("... ok\n")); + + /* Setup a useable color table when the appropriate + * method is available. Should update this to set-colors */ + for (i = 0; i < 32; i++) + if (prom_set_color(ih, i, RELOC(default_colors)[i*3], + RELOC(default_colors)[i*3+1], + RELOC(default_colors)[i*3+2]) != 0) + break; + +#ifdef CONFIG_FB + for (i = 0; i < LINUX_LOGO_COLORS; i++) + if (prom_set_color(ih, i + 32, + RELOC(linux_logo_red)[i], + RELOC(linux_logo_green)[i], + RELOC(linux_logo_blue)[i]) != 0) + break; +#endif /* CONFIG_FB */ + } + } + return ALIGN(mem); } @@ -1277,7 +1287,7 @@ if (!strcmp(np->name, "display")) np->name = get_property(np, "compatible", 0); - if (!strcmp(np->name, "device-tree")) + if (np->parent == NULL) ifunc = interpret_root_props; else if (np->type == 0) ifunc = NULL; @@ -1370,7 +1380,7 @@ np->intrs[i].line = *interrupts++; if (cvt_irq) np->intrs[i].line = openpic_to_irq(np->intrs[i].line); - np->intrs[i].sense = 0; + np->intrs[i].sense = 1; if (isize > 1) np->intrs[i].sense = *interrupts++; for (j=2; j= 0; ++i) { if (imp->addr.a_hi == devfn) { np->intrs[np->n_intrs].line = imp->intr; - np->intrs[np->n_intrs].sense = 0; /* FIXME */ + np->intrs[np->n_intrs].sense = 1; /* FIXME */ ++np->n_intrs; } imp = (struct pci_intr_map *)(((unsigned int)imp) @@ -1561,7 +1571,7 @@ mem_start += np->n_intrs * sizeof(struct interrupt_info); for (i = 0; i < np->n_intrs; ++i) { np->intrs[i].line = *ip++; - np->intrs[i].sense = 0; + np->intrs[i].sense = 1; } } @@ -1614,7 +1624,7 @@ mem_start += np->n_intrs * sizeof(struct interrupt_info); for (i = 0; i < np->n_intrs; ++i) { np->intrs[i].line = *ip++; - np->intrs[i].sense = 0; + np->intrs[i].sense = 1; } } @@ -1675,7 +1685,7 @@ if (keylargo) np->intrs[i].sense = *ip++; else - np->intrs[i].sense = 0; + np->intrs[i].sense = 1; } } else { /* CHRP machines */ @@ -1771,7 +1781,7 @@ mem_start += np->n_intrs * sizeof(struct interrupt_info); for (i = 0; i < np->n_intrs; ++i) { np->intrs[i].line = *ip++; - np->intrs[i].sense = 0; + np->intrs[i].sense = 1; } } @@ -1779,6 +1789,30 @@ } /* + * Work out the sense (active-low level / active-high edge) + * of each interrupt from the device tree. + */ +void __init +prom_get_irq_senses(unsigned char *senses, int off, int max) +{ + struct device_node *np; + int i, j; + + /* default to level-triggered */ + memset(senses, 1, max - off); + if (!use_of_interrupt_tree) + return; + + for (np = allnodes; np != 0; np = np->allnext) { + for (j = 0; j < np->n_intrs; j++) { + i = np->intrs[j].line; + if (i >= off && i < max) + senses[i-off] = np->intrs[j].sense; + } + } +} + +/* * Construct and return a list of the device_nodes with a given name. */ __openfirmware @@ -1818,39 +1852,6 @@ return head; } -/* Finds a device node given its PCI bus number, device number - * and function number - */ -__openfirmware -struct device_node * -find_pci_device_OFnode(unsigned char bus, unsigned char dev_fn) -{ - struct device_node* np; - unsigned int *reg; - int l; - - for (np = allnodes; np != 0; np = np->allnext) { - int in_macio = 0; - struct device_node* parent = np->parent; - while(parent) { - char *pname = (char *)get_property(parent, "name", &l); - if (pname && strcmp(pname, "mac-io") == 0) { - in_macio = 1; - break; - } - parent = parent->parent; - } - if (in_macio) - continue; - reg = (unsigned int *) get_property(np, "reg", &l); - if (reg == 0 || l < sizeof(struct reg_property)) - continue; - if (((reg[0] >> 8) & 0xff) == dev_fn && ((reg[0] >> 16) & 0xff) == bus) - break; - } - return np; -} - /* * Returns all nodes linked together */ @@ -1981,6 +1982,21 @@ return pp->value; } return 0; +} + +/* + * Add a property to a node + */ +__openfirmware +void +prom_add_property(struct device_node* np, struct property* prop) +{ + struct property **next = &np->properties; + + prop->next = NULL; + while (*next) + next = &(*next)->next; + *next = prop; } #if 0 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/setup.c linux.ac/arch/ppc/kernel/setup.c --- linux.vanilla/arch/ppc/kernel/setup.c Sat Oct 28 16:15:46 2000 +++ linux.ac/arch/ppc/kernel/setup.c Fri Dec 22 16:37:58 2000 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -106,6 +107,10 @@ unsigned long SYSRQ_KEY; #endif /* CONFIG_MAGIC_SYSRQ */ +#ifdef CONFIG_VGA_CONSOLE +unsigned long vgacon_remap_base; +#endif + struct machdep_calls ppc_md; /* @@ -377,9 +382,9 @@ len += sprintf(len+buffer, "revision\t: %hd.%hd\n", maj, min); len += sprintf(buffer+len, "bogomips\t: %lu.%02lu\n", - (CD(loops_per_sec)+2500)/500000, - (CD(loops_per_sec)+2500)/5000 % 100); - bogosum += CD(loops_per_sec); + (CD(loops_per_jiffy)+2500)/(500000/HZ), + (CD(loops_per_jiffy)+2500)/(5000/HZ) % 100); + bogosum += CD(loops_per_jiffy); } #ifdef CONFIG_SMP @@ -673,13 +678,14 @@ void __init ppc_init(void) { /* clear the progress line */ - if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); + if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); if (ppc_md.init != NULL) { ppc_md.init(); } } +/* Warning, IO base is not yet inited */ void __init setup_arch(char **cmdline_p) { extern int panic_timeout; @@ -688,7 +694,7 @@ extern void do_init_bootmem(void); /* so udelay does something sensible, assume <= 1000 bogomips */ - loops_per_sec = 500000000; + loops_per_jiffy = 500000000 / HZ; #ifdef CONFIG_ALL_PPC feature_init(); @@ -743,10 +749,34 @@ ppc_md.setup_arch(); if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); +#ifdef CONFIG_PCI + /* We create the "pci-OF-bus-map" property now so it appear in the + * /proc device tree + */ + if (have_of) { + struct property* of_prop; + + of_prop = (struct property*)alloc_bootmem(sizeof(struct property) + 256); + if (of_prop && find_path_device("/")) { + memset(of_prop, -1, sizeof(struct property) + 256); + of_prop->name = "pci-OF-bus-map"; + of_prop->length = 256; + of_prop->value = (unsigned char *)&of_prop[1]; + prom_add_property(find_path_device("/"), of_prop); + } + } +#endif /* CONFIG_PCI */ + paging_init(); sort_exception_table(); } +/* Convert the shorts/longs in hd_driveid from little to big endian; + * chars are endian independant, of course, but strings need to be flipped. + * (Despite what it says in drivers/block/ide.h, they come up as little + * endian...) + * + * Changes to linux/hdreg.h may require changes here. */ void ppc_generic_ide_fix_driveid(struct hd_driveid *id) { int i; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/smp.c linux.ac/arch/ppc/kernel/smp.c --- linux.vanilla/arch/ppc/kernel/smp.c Tue Oct 31 20:26:00 2000 +++ linux.ac/arch/ppc/kernel/smp.c Fri Dec 22 16:38:34 2000 @@ -1,6 +1,4 @@ /* - * $Id: smp.c,v 1.68 1999/09/17 19:38:05 cort Exp $ - * * Smp support for ppc. * * Written by Cort Dougan (cort@cs.nmt.edu) borrowing a great @@ -8,8 +6,8 @@ * * Copyright (C) 1999 Cort Dougan * - * Support for PReP (Motorola MTX/MVME) SMP by Troy Benjegerdes - * (troy@microux.com, hozer@drgw.net) + * Support for PReP (Motorola MTX/MVME) and Macintosh G4 SMP + * by Troy Benjegerdes (hozer@drgw.net) */ #include @@ -23,7 +21,6 @@ #define __KERNEL_SYSCALLS__ #include #include -#include #include #include @@ -38,30 +35,37 @@ #include #include #include - +#include +#include #include + #include "open_pic.h" int smp_threads_ready; volatile int smp_commenced; int smp_num_cpus = 1; +int smp_tb_synchronized; struct cpuinfo_PPC cpu_data[NR_CPUS]; struct klock_info_struct klock_info = { KLOCK_CLEAR, 0 }; volatile unsigned char active_kernel_processor = NO_PROC_ID; /* Processor holding kernel spinlock */ -volatile unsigned long ipi_count; +atomic_t ipi_recv; +atomic_t ipi_sent; spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED; unsigned int prof_multiplier[NR_CPUS]; unsigned int prof_counter[NR_CPUS]; cycles_t cacheflush_time; +static int max_cpus __initdata = NR_CPUS; -/* this has to go in the data section because it is accessed from prom_init */ int smp_hw_index[NR_CPUS]; /* all cpu mappings are 1-1 -- Cort */ volatile unsigned long cpu_callin_map[NR_CPUS]; +#define TB_SYNC_PASSES 4 +volatile unsigned long __initdata tb_sync_flag = 0; +volatile unsigned long __initdata tb_offset = 0; + int start_secondary(void *); extern int cpu_idle(void *unused); -u_int openpic_read(volatile u_int *addr); void smp_call_function_interrupt(void); void smp_message_pass(int target, int msg, unsigned long data, int wait); @@ -77,54 +81,26 @@ volatile u32 *psurge_sec_intr; volatile u32 *psurge_start; -/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. */ +/* l2 cache stuff for dual G4 macs */ +extern void core99_init_l2(void); + +/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. + * + * Make sure this matches openpic_request_IPIs in open_pic.c, or what shows up + * in /proc/interrupts will be wrong!!! --Troy */ #define PPC_MSG_CALL_FUNCTION 0 #define PPC_MSG_RESCHEDULE 1 #define PPC_MSG_INVALIDATE_TLB 2 #define PPC_MSG_XMON_BREAK 3 + static inline void set_tb(unsigned int upper, unsigned int lower) { + mtspr(SPRN_TBWL, 0); mtspr(SPRN_TBWU, upper); mtspr(SPRN_TBWL, lower); } -void smp_local_timer_interrupt(struct pt_regs * regs) -{ - int cpu = smp_processor_id(); - - if (!--prof_counter[cpu]) { - update_process_times(user_mode(regs)); - prof_counter[cpu]=prof_multiplier[cpu]; - } -} - -void smp_message_recv(int msg, struct pt_regs *regs) -{ - ipi_count++; - - switch( msg ) { - case PPC_MSG_CALL_FUNCTION: - smp_call_function_interrupt(); - break; - case PPC_MSG_RESCHEDULE: - current->need_resched = 1; - break; - case PPC_MSG_INVALIDATE_TLB: - _tlbia(); - break; -#ifdef CONFIG_XMON - case PPC_MSG_XMON_BREAK: - xmon(regs); - break; -#endif /* CONFIG_XMON */ - default: - printk("SMP %d: smp_message_recv(): unknown msg %d\n", - smp_processor_id(), msg); - break; - } -} - /* * As it is now, if we're sending two message at the same time * we have race conditions on Pmac. The PowerSurge doesn't easily @@ -135,9 +111,15 @@ * we do on the chrp. It would be nice to use actual IPI's such as with * openpic rather than this. * -- Cort + * + * Well, we could easily handle that by using bits in the message and + * atomically set/clear them, one for each message. --BenH */ -int pmac_smp_message[NR_CPUS]; -void pmac_smp_message_recv(struct pt_regs *regs) + +int psurge_smp_message[NR_CPUS]; +extern void __secondary_start_psurge(void); + +void psurge_smp_message_recv(struct pt_regs *regs) { int cpu = smp_processor_id(); int msg; @@ -150,20 +132,505 @@ return; /* make sure there is a message there */ - msg = pmac_smp_message[cpu]; + msg = psurge_smp_message[cpu]; if (msg == 0) return; /* reset message */ - pmac_smp_message[cpu] = 0; + psurge_smp_message[cpu] = 0; smp_message_recv(msg - 1, regs); } void -pmac_primary_intr(int irq, void *d, struct pt_regs *regs) +psurge_primary_intr(int irq, void *d, struct pt_regs *regs) +{ + psurge_smp_message_recv(regs); +} + +static void +smp_psurge_message_pass(int target, int msg, unsigned long data, int wait) +{ + /* + * IPI's on the Pmac are a hack but without reasonable + * IPI hardware SMP on Pmac is a hack. + * + * We assume here that the msg is not -1. If it is, + * the recipient won't know the message was destined + * for it. -- Cort + */ + if (smp_num_cpus < 2) + return; + if (smp_processor_id() == 0) { + /* primary cpu */ + if (target == 1 || target == MSG_ALL_BUT_SELF + || target == MSG_ALL) { + psurge_smp_message[1] = msg + 1; + /* interrupt secondary processor */ + out_be32(psurge_sec_intr, ~0); + out_be32(psurge_sec_intr, 0); + } + } else { + /* secondary cpu */ + if (target == 0 || target == MSG_ALL_BUT_SELF + || target == MSG_ALL) { + psurge_smp_message[0] = msg + 1; + /* interrupt primary processor */ + in_be32(psurge_pri_intr); + } + } + if (target == smp_processor_id() || target == MSG_ALL) { + /* sending a message to ourself */ + /* XXX maybe we shouldn't do this if ints are off */ + smp_message_recv(msg, NULL); + } +} + +static int +smp_psurge_probe(void) +{ + /* + * The powersurge cpu board can be used in the generation + * of powermacs that have a socket for an upgradeable cpu card, + * including the 7500, 8500, 9500, 9600. + * The device tree doesn't tell you if you have 2 cpus because + * OF doesn't know anything about the 2nd processor. + * Instead we look for a hammerhead memory controller; I believe + * that it was only used on the machines with an upgradeable + * cpu card, and used on all such machines. If you have evidence + * to the contrary, let me know. + * If we find a hammerhead, we return 2 since we may have a + * powersurge cpu board. -- paulus + */ + if (find_devices("hammerhead") == NULL) + return 1; + + psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); + psurge_sec_intr = ioremap(PSURGE_SEC_INTR, 4); + psurge_start = ioremap(PSURGE_START, 4); + + return 2; +} + +static void +smp_psurge_kick_cpu(int nr) +{ + extern void __secondary_start_psurge(void); + + /* setup entry point of secondary processor */ + out_be32(psurge_start, __pa(__secondary_start_psurge)); + /* interrupt secondary to begin executing code */ + out_be32(psurge_sec_intr, ~0); + udelay(1); + out_be32(psurge_sec_intr, 0); +} + +static void +smp_psurge_setup_cpu(int cpu_nr) +{ + static volatile int sec_tb_reset = 0; + int t; + + if (cpu_nr == 0) { + if (smp_num_cpus < 2) + return; + /* reset the entry point so if we get another intr we won't + * try to startup again */ + out_be32(psurge_start, 0x100); + if (request_irq(30, psurge_primary_intr, 0, "primary IPI", 0)) + printk(KERN_ERR "Couldn't get primary IPI interrupt"); + /* + * The decrementers of both cpus are frozen at this point + * until we give the secondary cpu another interrupt. + * We set them both to decrementer_count and then send + * the interrupt. This should get the decrementers + * synchronized. + * -- paulus. + */ + set_dec(tb_ticks_per_jiffy); + if ((_get_PVR() >> 16) != 1) { + set_tb(0, 0); /* set timebase if not 601 */ + last_jiffy_stamp(0) = 0; + } + /* wait for the secondary to have reset its TB + before proceeding */ + for (t = 10000000; t > 0 && !sec_tb_reset; --t) + ; + /* now interrupt the secondary, starting both TBs */ + out_be32(psurge_sec_intr, ~0); + udelay(1); + out_be32(psurge_sec_intr, 0); + smp_tb_synchronized = 1; + + } else { + if ((_get_PVR() >> 16) != 1) { + set_tb(0,0); + last_jiffy_stamp(cpu_nr) = 0; + } + mb(); + sec_tb_reset = 1; + } +} + + +static void +smp_openpic_message_pass(int target, int msg, unsigned long data, int wait) +{ + /* make sure we're sending something that translates to an IPI */ + if ( msg > 0x3 ){ + printk("SMP %d: smp_message_pass: unknown msg %d\n", + smp_processor_id(), msg); + return; + } + switch ( target ) + { + case MSG_ALL: + openpic_cause_IPI(msg, 0xffffffff); + break; + case MSG_ALL_BUT_SELF: + openpic_cause_IPI(msg, + 0xffffffff & ~(1 << smp_processor_id())); + break; + default: + openpic_cause_IPI(msg, 1< 1) + openpic_request_IPIs(); + + return ncpus; +} + +static void +smp_core99_kick_cpu(int nr) +{ + extern void __secondary_start_psurge(void); + + unsigned long save_int; + unsigned long flags; + volatile unsigned long *vector + = ((volatile unsigned long *)(KERNELBASE+0x500)); + + if (nr != 1) + return; + if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346); + + local_irq_save(flags); + local_irq_disable(); + + /* Save EE vector */ + save_int = *vector; + + /* Setup fake EE vector that does + * b __secondary_start_psurge - KERNELBASE + */ + *vector = 0x48000002 + + ((unsigned long)__secondary_start_psurge - KERNELBASE); + + /* flush data cache and inval instruction cache */ + flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); + + /* Put some life in our friend */ + feature_core99_kick_cpu1(); + + /* FIXME: We wait a bit for the CPU to take the exception, I should + * instead wait for the entry code to set something for me. Well, + * ideally, all that crap will be done in prom.c and the CPU left + * in a RAM-based wait loop like CHRP. + */ + mdelay(1); + + /* Restore our exception vector */ + *vector = save_int; + flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); + + local_irq_restore(flags); + if (ppc_md.progress) ppc_md.progress("smp_core99_probe done", 0x347); +} + +static void +smp_core99_setup_cpu(int cpu_nr) +{ + /* Setup openpic */ + do_openpic_setup_cpu(); + + /* Setup L2 */ + if (cpu_nr != 0) + core99_init_l2(); + else + if (ppc_md.progress) ppc_md.progress("core99_setup_cpu 0 done", 0x349); +} + +static int +smp_chrp_probe(void) +{ + extern unsigned long smp_chrp_cpu_nr; + extern int mot_multi; + + openpic_request_IPIs(); + + return mot_multi ? 2 : smp_chrp_cpu_nr; +} + +static void +smp_chrp_kick_cpu(int nr) { - pmac_smp_message_recv(regs); + *(unsigned long *)KERNELBASE = nr; + asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory"); +} + +static void +smp_chrp_setup_cpu(int cpu_nr) +{ + static atomic_t ready = ATOMIC_INIT(1); + static volatile int frozen = 0; + + if (cpu_nr == 0) { + /* wait for all the others */ + while (atomic_read(&ready) < smp_num_cpus) + barrier(); + atomic_set(&ready, 1); + /* freeze the timebase */ + call_rtas("freeze-time-base", 0, 1, NULL); + mb(); + frozen = 1; + /* XXX assumes this is not a 601 */ + set_tb(0, 0); + last_jiffy_stamp(0) = 0; + while (atomic_read(&ready) < smp_num_cpus) + barrier(); + /* thaw the timebase again */ + call_rtas("thaw-time-base", 0, 1, NULL); + mb(); + frozen = 0; + smp_tb_synchronized = 1; + } else { + atomic_inc(&ready); + while (!frozen) + barrier(); + set_tb(0, 0); + last_jiffy_stamp(0) = 0; + mb(); + atomic_inc(&ready); + while (frozen) + barrier(); + } + + if (OpenPIC_Addr) + do_openpic_setup_cpu(); +} + +#ifdef CONFIG_POWER4 +static void +smp_xics_message_pass(int target, int msg, unsigned long data, int wait) +{ + /* for now, only do reschedule messages + since we only have one IPI */ + if (msg != PPC_MSG_RESCHEDULE) + return; + for (i = 0; i < smp_num_cpus; ++i) { + if (target == MSG_ALL || target == i + || (target == MSG_ALL_BUT_SELF + && i != smp_processor_id())) + xics_cause_IPI(i); + } +} + +static int +smp_xics_probe(void) +{ + return smp_chrp_cpu_nr; +} + +static void +smp_xics_setup_cpu(int cpu_nr) +{ + if (cpu_nr > 0) + xics_setup_cpu(); +} +#endif /* CONFIG_POWER4 */ + +static int +smp_prep_probe(void) +{ + extern int mot_multi; + + openpic_request_IPIs(); + + return mot_multi ? 2 : 0; +} + +static void +smp_prep_kick_cpu(int nr) +{ + extern unsigned long *MotSave_SmpIar; + extern unsigned char *MotSave_CpusState[2]; + + *MotSave_SmpIar = (unsigned long)__secondary_start_psurge - KERNELBASE; + *MotSave_CpusState[1] = CPU_GOOD; + printk("CPU1 reset, waiting\n"); +} + +static void +smp_prep_setup_cpu(int cpu_nr) +{ + if (OpenPIC_Addr) + do_openpic_setup_cpu(); +} + +#ifdef CONFIG_GEMINI +static int +smp_gemini_probe(void) +{ + int i, nr; + + openpic_request_IPIs(); + + nr = (readb(GEMINI_CPUSTAT) & GEMINI_CPU_COUNT_MASK)>>2; + return (nr == 0) ? 4 : nr; +} + +static void +smp_gemini_kick_cpu(int nr) +{ + openpic_init_processor( 1< 0) + gemini_init_l2(); +} +#endif /* CONFIG_GEMINI */ + + +static struct smp_ops_t { + void (*message_pass)(int target, int msg, unsigned long data, int wait); + int (*probe)(void); + void (*kick_cpu)(int nr); + void (*setup_cpu)(int nr); + +} *smp_ops; + +#define smp_message_pass(t,m,d,w) \ + do { if (smp_ops) \ + atomic_inc(&ipi_sent); \ + smp_ops->message_pass((t),(m),(d),(w)); \ + } while(0) + + +/* PowerSurge-style Macs */ +static struct smp_ops_t psurge_smp_ops = { + smp_psurge_message_pass, + smp_psurge_probe, + smp_psurge_kick_cpu, + smp_psurge_setup_cpu, +}; + +/* Core99 Macs (dual G4s) */ +static struct smp_ops_t core99_smp_ops = { + smp_openpic_message_pass, + smp_core99_probe, + smp_core99_kick_cpu, + smp_core99_setup_cpu, +}; + +/* CHRP with openpic */ +static struct smp_ops_t chrp_smp_ops = { + smp_openpic_message_pass, + smp_chrp_probe, + smp_chrp_kick_cpu, + smp_chrp_setup_cpu, +}; + +#ifdef CONFIG_POWER4 +/* CHRP with new XICS interrupt controller */ +static struct smp_ops_t xics_smp_ops = { + smp_xics_message_pass, + smp_xics_probe, + smp_chrp_kick_cpu, + smp_xics_setup_cpu, +}; +#endif /* CONFIG_POWER4 */ + +/* PReP (MTX) */ +static struct smp_ops_t prep_smp_ops = { + smp_openpic_message_pass, + smp_prep_probe, + smp_prep_kick_cpu, + smp_prep_setup_cpu, +}; + +#ifdef CONFIG_GEMINI +/* Gemini */ +static struct smp_ops_t gemini_smp_ops = { + smp_openpic_message_pass, + smp_gemini_probe, + smp_gemini_kick_cpu, + smp_gemini_setup_cpu, +}; +#endif /* CONFIG_GEMINI */ + +/* + * Common functions + */ + + +void smp_local_timer_interrupt(struct pt_regs * regs) +{ + int cpu = smp_processor_id(); + + if (!--prof_counter[cpu]) { + update_process_times(user_mode(regs)); + prof_counter[cpu]=prof_multiplier[cpu]; + } +} + +void smp_message_recv(int msg, struct pt_regs *regs) +{ + atomic_inc(&ipi_recv); + + switch( msg ) { + case PPC_MSG_CALL_FUNCTION: + smp_call_function_interrupt(); + break; + case PPC_MSG_RESCHEDULE: + current->need_resched = 1; + break; + case PPC_MSG_INVALIDATE_TLB: + _tlbia(); + break; +#ifdef CONFIG_XMON + case PPC_MSG_XMON_BREAK: + xmon(regs); + break; +#endif /* CONFIG_XMON */ + default: + printk("SMP %d: smp_message_recv(): unknown msg %d\n", + smp_processor_id(), msg); + break; + } } /* @@ -220,7 +687,7 @@ */ static spinlock_t call_lock = SPIN_LOCK_UNLOCKED; -static volatile struct call_data_struct { +static struct call_data_struct { void (*func) (void *info); void *info; atomic_t started; @@ -317,87 +784,9 @@ atomic_inc(&call_data->finished); } -void smp_message_pass(int target, int msg, unsigned long data, int wait) -{ - if ( !(_machine & (_MACH_Pmac|_MACH_chrp|_MACH_prep|_MACH_gemini)) ) - return; - - switch (_machine) { - case _MACH_Pmac: - /* - * IPI's on the Pmac are a hack but without reasonable - * IPI hardware SMP on Pmac is a hack. - * - * We assume here that the msg is not -1. If it is, - * the recipient won't know the message was destined - * for it. -- Cort - */ - if (smp_processor_id() == 0) { - /* primary cpu */ - if (target == 1 || target == MSG_ALL_BUT_SELF - || target == MSG_ALL) { - pmac_smp_message[1] = msg + 1; - /* interrupt secondary processor */ - out_be32(psurge_sec_intr, ~0); - out_be32(psurge_sec_intr, 0); - } - } else { - /* secondary cpu */ - if (target == 0 || target == MSG_ALL_BUT_SELF - || target == MSG_ALL) { - pmac_smp_message[0] = msg + 1; - /* interrupt primary processor */ - in_be32(psurge_pri_intr); - } - } - if (target == smp_processor_id() || target == MSG_ALL) { - /* sending a message to ourself */ - /* XXX maybe we shouldn't do this if ints are off */ - smp_message_recv(msg, NULL); - } - break; - case _MACH_chrp: - case _MACH_prep: - case _MACH_gemini: -#ifndef CONFIG_POWER4 - /* make sure we're sending something that translates to an IPI */ - if ( msg > 0x3 ) - break; - switch ( target ) - { - case MSG_ALL: - openpic_cause_IPI(smp_processor_id(), msg, 0xffffffff); - break; - case MSG_ALL_BUT_SELF: - openpic_cause_IPI(smp_processor_id(), msg, - 0xffffffff & ~(1 << smp_processor_id())); - break; - default: - openpic_cause_IPI(smp_processor_id(), msg, 1<>2; - cpu_nr = (cpu_nr == 0) ? 4 : cpu_nr; + smp_ops = &gemini_smp_ops; break; +#endif /* CONFIG_GEMINI */ + default: + printk("SMP not supported on this machine.\n"); + return; } + + /* Probe arch for CPUs */ + cpu_nr = smp_ops->probe(); /* * only check for cpus we know exist. We keep the callin map * with cpus at the bottom -- Cort */ - for ( i = 1 ; i < cpu_nr; i++ ) - { + if (cpu_nr > max_cpus) + cpu_nr = max_cpus; + for (i = 1; i < cpu_nr; i++) { int c; struct pt_regs regs; @@ -487,25 +880,7 @@ asm volatile("sync"); /* wake up cpus */ - switch ( _machine ) - { - case _MACH_Pmac: - /* setup entry point of secondary processor */ - out_be32(psurge_start, __pa(__secondary_start_psurge)); - /* interrupt secondary to begin executing code */ - out_be32(psurge_sec_intr, ~0); - udelay(1); - out_be32(psurge_sec_intr, 0); - break; - case _MACH_chrp: - *(unsigned long *)KERNELBASE = i; - asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory"); - break; - case _MACH_gemini: - openpic_init_processor( 1<kick_cpu(i); /* * wait to see if the cpu made a callin (is actually up). @@ -517,40 +892,100 @@ if ( cpu_callin_map[i] ) { + char buf[32]; + sprintf(buf, "found cpu %d", i); + if (ppc_md.progress) ppc_md.progress(buf, 0x350+i); printk("Processor %d found.\n", i); smp_num_cpus++; } else { + char buf[32]; + sprintf(buf, "didn't find cpu %d", i); + if (ppc_md.progress) ppc_md.progress(buf, 0x360+i); printk("Processor %d is stuck.\n", i); } } - if (OpenPIC && (_machine & (_MACH_gemini|_MACH_chrp|_MACH_prep))) - do_openpic_setup_cpu(); + /* Setup CPU 0 last (important) */ + smp_ops->setup_cpu(0); +} - if ( _machine == _MACH_Pmac ) - { - /* reset the entry point so if we get another intr we won't - * try to startup again */ - out_be32(psurge_start, 0x100); - if (request_irq(30, pmac_primary_intr, 0, "primary IPI", 0)) - printk(KERN_ERR "Couldn't get primary IPI interrupt"); - /* - * The decrementers of both cpus are frozen at this point - * until we give the secondary cpu another interrupt. - * We set them both to decrementer_count and then send - * the interrupt. This should get the decrementers - * synchronized. - * -- paulus. - */ - set_dec(tb_ticks_per_jiffy); - if ((_get_PVR() >> 16) != 1) { - set_tb(0, 0); /* set timebase if not 601 */ - last_jiffy_stamp(0) = 0; +void __init smp_software_tb_sync(int cpu) +{ +#define PASSES 4 /* 4 passes.. */ + int pass; + int i, j; + + /* stop - start will be the number of timebase ticks it takes for cpu0 + * to send a message to all others and the first reponse to show up. + * + * ASSUMPTION: this time is similiar for all cpus + * ASSUMPTION: the time to send a one-way message is ping/2 + */ + register unsigned long start = 0; + register unsigned long stop = 0; + register unsigned long temp = 0; + + if (smp_num_cpus < 2) + return; + + set_tb(0, 0); + + /* multiple passes to get in l1 cache.. */ + for (pass = 2; pass < 2+PASSES; pass++){ + if (cpu == 0){ + mb(); + for (i = j = 1; i < smp_num_cpus; i++, j++){ + /* skip stuck cpus */ + while (!cpu_callin_map[j]) + ++j; + while (cpu_callin_map[j] != pass) + barrier(); + } + mb(); + tb_sync_flag = pass; + start = get_tbl(); /* start timing */ + while (tb_sync_flag) + mb(); + stop = get_tbl(); /* end timing */ + /* theoretically, the divisor should be 2, but + * I get better results on my dual mtx. someone + * please report results on other smp machines.. + */ + tb_offset = (stop-start)/4; + mb(); + tb_sync_flag = pass; + udelay(10); + mb(); + tb_sync_flag = 0; + mb(); + set_tb(0,0); + mb(); + } else { + cpu_callin_map[cpu] = pass; + mb(); + while (!tb_sync_flag) + mb(); /* wait for cpu0 */ + mb(); + tb_sync_flag = 0; /* send response for timing */ + mb(); + while (!tb_sync_flag) + mb(); + temp = tb_offset; /* make sure offset is loaded */ + while (tb_sync_flag) + mb(); + set_tb(0,temp); /* now, set the timebase */ + mb(); } - out_be32(psurge_sec_intr, ~0); - udelay(1); - out_be32(psurge_sec_intr, 0); } + if (cpu == 0) { + smp_tb_synchronized = 1; + printk("smp_software_tb_sync: %d passes, final offset: %d\n", + PASSES, tb_offset); + } + /* so time.c doesn't get confused */ + set_dec(tb_ticks_per_jiffy); + last_jiffy_stamp(cpu) = 0; + cpu_callin_map[cpu] = 1; } void __init smp_commence(void) @@ -558,8 +993,48 @@ /* * Lets the callin's below out of their loop. */ + if (ppc_md.progress) ppc_md.progress("smp_commence", 0x370); wmb(); smp_commenced = 1; + /* if the smp_ops->setup_cpu function has not already synched the + * timebases with a nicer hardware-based method, do so now + * + * I am open to suggestions for improvements to this method + * -- Troy + * + * NOTE: if you are debugging, set smp_tb_synchronized for now + * since if this code runs pretty early and needs all cpus that + * reported in in smp_callin_map to be working + * + * NOTE2: this code doesn't seem to work on > 2 cpus. -- paulus + */ + if (!smp_tb_synchronized) { + unsigned long flags; + __save_and_cli(flags); + smp_software_tb_sync(0); + __restore_flags(flags); + } +} + +void __init smp_callin(void) +{ + int cpu = current->processor; + + smp_store_cpu_info(cpu); + set_dec(tb_ticks_per_jiffy); + cpu_callin_map[cpu] = 1; + + smp_ops->setup_cpu(cpu); + + init_idle(); + + while(!smp_commenced) + barrier(); + /* see smp_commence for more info */ + if (!smp_tb_synchronized){ + smp_software_tb_sync(cpu); + } + __sti(); } /* intel needs this */ @@ -576,37 +1051,6 @@ return cpu_idle(NULL); } -void __init smp_callin(void) -{ - smp_store_cpu_info(current->processor); - set_dec(tb_ticks_per_jiffy); - if (_machine == _MACH_Pmac && (_get_PVR() >> 16) != 1) { - set_tb(0, 0); /* set timebase if not 601 */ - last_jiffy_stamp(current->processor) = 0; - } - init_idle(); - cpu_callin_map[current->processor] = 1; - -#ifndef CONFIG_POWER4 - /* - * Each processor has to do this and this is the best - * place to stick it for now. - * -- Cort - */ - if (OpenPIC && _machine & (_MACH_gemini|_MACH_chrp|_MACH_prep)) - do_openpic_setup_cpu(); -#else - xics_setup_cpu(); -#endif /* CONFIG_POWER4 */ -#ifdef CONFIG_GEMINI - if ( _machine == _MACH_gemini ) - gemini_init_l2(); -#endif - while(!smp_commenced) - barrier(); - __sti(); -} - void __init smp_setup(char *str, int *ints) { } @@ -621,6 +1065,14 @@ struct cpuinfo_PPC *c = &cpu_data[id]; /* assume bogomips are same for everything */ - c->loops_per_sec = loops_per_sec; + c->loops_per_jiffy = loops_per_jiffy; c->pvr = _get_PVR(); } + +static int __init maxcpus(char *str) +{ + get_option(&str, &max_cpus); + return 1; +} + +__setup("maxcpus=", maxcpus); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/kernel/time.c linux.ac/arch/ppc/kernel/time.c --- linux.vanilla/arch/ppc/kernel/time.c Sat Oct 28 16:15:46 2000 +++ linux.ac/arch/ppc/kernel/time.c Mon Dec 18 20:45:53 2000 @@ -67,7 +67,12 @@ #include -void smp_local_timer_interrupt(struct pt_regs *); +#ifdef CONFIG_SMP +extern void smp_local_timer_interrupt(struct pt_regs *); +extern int smp_tb_synchronized; +#endif /* CONFIG_SMP */ + +extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz); /* keep track of when we need to update the rtc */ time_t last_rtc_update; @@ -97,6 +102,36 @@ return delta; } +extern unsigned long prof_cpu_mask; +extern unsigned int * prof_buffer; +extern unsigned long prof_len; +extern unsigned long prof_shift; +extern char _stext; + +static inline void ppc_do_profile (unsigned long nip) +{ + if (!prof_buffer) + return; + + /* + * Only measure the CPUs specified by /proc/irq/prof_cpu_mask. + * (default is all CPUs.) + */ + if (!((1<>= prof_shift; + /* + * Don't ignore out-of-bounds EIP values silently, + * put them into the last histogram slot, so if + * present, they will show up as a sharp peak. + */ + if (nip > prof_len-1) + nip = prof_len-1; + atomic_inc((atomic_t *)&prof_buffer[nip]); +} + /* * timer_interrupt - gets called when the decrementer overflows, * with interrupts disabled. @@ -110,6 +145,9 @@ hardirq_enter(cpu); + if (!user_mode(regs)) + ppc_do_profile(instruction_pointer(regs)); + do { jiffy_stamp += tb_ticks_per_jiffy; if (smp_processor_id()) continue; @@ -151,7 +189,7 @@ #ifdef CONFIG_SMP smp_local_timer_interrupt(regs); -#endif +#endif /* CONFIG_SMP */ if (ppc_md.heartbeat && !ppc_md.heartbeat_count--) ppc_md.heartbeat(); @@ -176,7 +214,7 @@ /* As long as timebases are not in sync, gettimeofday can only * have jiffy resolution on SMP. */ - if (_machine != _MACH_Pmac) + if (!smp_tb_synchronized) delta = 0; #endif /* CONFIG_SMP */ lost_ticks = jiffies - wall_jiffies; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/mm/init.c linux.ac/arch/ppc/mm/init.c --- linux.vanilla/arch/ppc/mm/init.c Tue Dec 12 13:05:16 2000 +++ linux.ac/arch/ppc/mm/init.c Mon Dec 18 20:45:53 2000 @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #ifdef CONFIG_BLK_DEV_INITRD @@ -70,7 +69,7 @@ #include "4xx_tlb.h" #endif -#define MAX_LOW_MEM (640 << 20) +#define MAX_LOW_MEM (512 << 20) #define PGTOKB(pages) (((pages) * PAGE_SIZE) >> 10) @@ -79,6 +78,7 @@ unsigned long *end_of_DRAM; unsigned long total_memory; unsigned long total_lowmem; +unsigned long ram_phys_base; int mem_init_done; int init_bootmem_done; int boot_mapsize; @@ -127,21 +127,25 @@ #endif /* CONFIG_8260 */ static void mapin_ram(void); void map_page(unsigned long va, unsigned long pa, int flags); -void set_phys_avail(struct mem_pieces *mp); +void set_phys_avail(unsigned long total_ram); extern void die_if_kernel(char *,struct pt_regs *,long); extern char _start[], _end[]; extern char _stext[], etext[]; extern struct task_struct *current_set[NR_CPUS]; -struct mem_pieces phys_mem; char *klimit = _end; struct mem_pieces phys_avail; -PTE *Hash, *Hash_end; -unsigned long Hash_size, Hash_mask; +/* + * N.B. Hash, Hash_size and _SDR1 need to be in the data segment + * because they are accessed within prom_init if CONFIG_PPC64BRIDGE. + * -- paulus + */ +PTE *Hash = 0, *Hash_end; +unsigned long Hash_size = 0, Hash_mask; #if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) -unsigned long _SDR1; +unsigned long _SDR1 = 0; static void hash_init(void); union ubat { /* BAT register values to be loaded */ @@ -199,6 +203,8 @@ /* max amount of RAM to use */ unsigned long __max_memory; +/* max amount of low RAM to map in */ +unsigned long __max_low_memory = MAX_LOW_MEM; void __bad_pte(pmd_t *pmd) { @@ -399,8 +405,8 @@ * If the address lies within the first 16 MB, assume it's in ISA * memory space */ - if (p < 16*1024*1024) - p += _ISA_MEM_BASE; + if ( p < 16*1024*1024 ) + p += _ISA_MEM_BASE; /* * Don't allow anybody to remap normal RAM that we're using. @@ -437,7 +443,11 @@ return NULL; v = VMALLOC_VMADDR(area->addr); } else { +#ifndef CONFIG_HIGHMEM if (p >= ioremap_base) +#else + if (p >= ioremap_base && p < PKMAP_BASE) +#endif /* CONFIG_HIGHMEM */ v = p; else v = (ioremap_bot -= size); @@ -491,16 +501,13 @@ void map_page(unsigned long va, unsigned long pa, int flags) { - pmd_t *pd, oldpd; + pmd_t *pd; pte_t *pg; /* Use upper 10 bits of VA to index the first level map */ pd = pmd_offset(pgd_offset_k(va), va); - oldpd = *pd; /* Use middle 10 bits of VA to index the second-level map */ pg = pte_alloc(pd, va); - if (pmd_none(oldpd) && mem_init_done) - set_pgdir(va, *(pgd_t *)pd); set_pte(pg, mk_pte_phys(pa & PAGE_MASK, __pgprot(flags))); if (mem_init_done) flush_hash_page(0, va); @@ -626,6 +633,12 @@ */ set_context(current->mm->context, current->mm->pgd); } +#else /* CONFIG_8xx */ +void +mmu_context_overflow(void) +{ + atomic_set(&next_mmu_context, -1); +} #endif /* CONFIG_8xx */ void flush_page_to_ram(struct page *page) @@ -727,22 +740,20 @@ static void __init mapin_ram(void) { - int i; unsigned long v, p, s, f; #if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) && !defined(CONFIG_POWER4) if (!__map_without_bats) { - unsigned long tot, mem_base, bl, done; + unsigned long tot, bl, done; unsigned long max_size = (256<<20); unsigned long align; /* Set up BAT2 and if necessary BAT3 to cover RAM. */ - mem_base = __pa(KERNELBASE); /* Make sure we don't map a block larger than the smallest alignment of the physical address. */ - /* alignment of mem_base */ - align = ~(mem_base-1) & mem_base; + /* alignment of ram_phys_base */ + align = ~(ram_phys_base-1) & ram_phys_base; /* set BAT block size to MIN(max_size, align) */ if (align && align < max_size) max_size = align; @@ -753,7 +764,7 @@ break; } - setbat(2, KERNELBASE, mem_base, bl, RAM_PAGE); + setbat(2, KERNELBASE, ram_phys_base, bl, RAM_PAGE); done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1; if ((done < tot) && !bat_addrs[3].limit) { /* use BAT3 to cover a bit more */ @@ -761,41 +772,35 @@ for (bl = 128<<10; bl < max_size; bl <<= 1) if (bl * 2 > tot) break; - setbat(3, KERNELBASE+done, mem_base+done, bl, + setbat(3, KERNELBASE+done, ram_phys_base+done, bl, RAM_PAGE); } } #endif /* !CONFIG_4xx && !CONFIG_8xx && !CONFIG_POWER4 */ - for (i = 0; i < phys_mem.n_regions; ++i) { - v = (ulong)__va(phys_mem.regions[i].address); - p = phys_mem.regions[i].address; - if (p >= total_lowmem) - break; - for (s = 0; s < phys_mem.regions[i].size; s += PAGE_SIZE) { - /* On the MPC8xx, we want the page shared so we - * don't get ASID compares on kernel space. - */ - f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED; + v = KERNELBASE; + p = ram_phys_base; + for (s = 0; s < total_lowmem; s += PAGE_SIZE) { + /* On the MPC8xx, we want the page shared so we + * don't get ASID compares on kernel space. + */ + f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED; #if defined(CONFIG_KGDB) || defined(CONFIG_XMON) - /* Allows stub to set breakpoints everywhere */ - f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE; + /* Allows stub to set breakpoints everywhere */ + f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE; #else - if ((char *) v < _stext || (char *) v >= etext) - f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE; + if ((char *) v < _stext || (char *) v >= etext) + f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE; #ifndef CONFIG_8xx - else - /* On the powerpc (not 8xx), no user access - forces R/W kernel access */ - f |= _PAGE_USER; + else + /* On the powerpc (not 8xx), no user access + forces R/W kernel access */ + f |= _PAGE_USER; #endif /* CONFIG_8xx */ #endif /* CONFIG_KGDB */ - map_page(v, p, f); - v += PAGE_SIZE; - p += PAGE_SIZE; - if (p >= total_lowmem) - break; - } + map_page(v, p, f); + v += PAGE_SIZE; + p += PAGE_SIZE; } } @@ -922,17 +927,58 @@ mtspr(SPRN_DCCR, 0x80000000); /* 128 MB of data space at 0x0. */ mtspr(SPRN_ICCR, 0x80000000); /* 128 MB of instr. space at 0x0. */ } -#else - /* How about ppc_md.md_find_end_of_memory instead of these - * ifdefs? -- Dan. - */ -#ifdef CONFIG_BOOTX_TEXT -extern boot_infos_t *disp_bi; + +#elif defined(CONFIG_8xx) +void __init MMU_init(void) +{ + if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111); + + total_memory = total_lowmem = m8xx_find_end_of_memory(); +#ifdef CONFIG_HIGHMEM + if (total_lowmem > MAX_LOW_MEM) { + total_lowmem = MAX_LOW_MEM; + mem_pieces_remove(&phys_avail, total_lowmem, + total_memory - total_lowmem, 0); + } +#endif /* CONFIG_HIGHMEM */ + end_of_DRAM = __va(total_lowmem); + set_phys_avail(total_lowmem); + + /* Map in all of RAM starting at KERNELBASE */ + mapin_ram(); + + /* Now map in some of the I/O space that is generically needed + * or shared with multiple devices. + * All of this fits into the same 4Mbyte region, so it only + * requires one page table page. + */ + ioremap(IMAP_ADDR, IMAP_SIZE); +#ifdef CONFIG_MBX + ioremap(NVRAM_ADDR, NVRAM_SIZE); + ioremap(MBX_CSR_ADDR, MBX_CSR_SIZE); + ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE); + + /* Map some of the PCI/ISA I/O space to get the IDE interface. + */ + ioremap(PCI_ISA_IO_ADDR, 0x4000); + ioremap(PCI_IDE_ADDR, 0x4000); #endif +#ifdef CONFIG_RPXLITE + ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE); + ioremap(HIOX_CSR_ADDR, HIOX_CSR_SIZE); +#endif +#ifdef CONFIG_RPXCLASSIC + ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE); + ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE); +#endif + if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211); +} + +#else /* not 4xx or 8xx */ void __init MMU_init(void) { if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111); -#ifndef CONFIG_8xx + if (have_of) total_memory = pmac_find_end_of_memory(); #ifdef CONFIG_APUS @@ -950,16 +996,17 @@ else /* prep */ total_memory = prep_find_end_of_memory(); #endif - + if (__max_memory && total_memory > __max_memory) + total_memory = __max_memory; total_lowmem = total_memory; -#ifdef CONFIG_HIGHMEM - if (total_lowmem > MAX_LOW_MEM) { - total_lowmem = MAX_LOW_MEM; - mem_pieces_remove(&phys_avail, total_lowmem, - total_memory - total_lowmem, 0); - } + if (total_lowmem > __max_low_memory) { + total_lowmem = __max_low_memory; +#ifndef CONFIG_HIGHMEM + total_memory = total_lowmem; #endif /* CONFIG_HIGHMEM */ + } end_of_DRAM = __va(total_lowmem); + set_phys_avail(total_lowmem); if ( ppc_md.progress ) ppc_md.progress("MMU:hash init", 0x300); hash_init(); @@ -991,13 +1038,14 @@ ioremap_base = 0xf0000000; break; case _MACH_chrp: - setbat(0, 0xf8000000, 0xf8000000, 0x08000000, IO_PAGE); -#ifdef CONFIG_PPC64BRIDGE - setbat(1, 0x80000000, 0xc0000000, 0x10000000, IO_PAGE); -#else - setbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE); - setbat(3, 0x90000000, 0x90000000, 0x10000000, IO_PAGE); -#endif + /* + * The code below tends to get removed, please don't take it out. + * The F50 needs this mapping and it you take it out I'll track you + * down and slap your hands. If it causes problems please email me. + * -- Cort + */ + setbat(0, 0x80000000, 0x80000000, 0x10000000, IO_PAGE); + setbat(1, 0x90000000, 0x90000000, 0x10000000, IO_PAGE); break; case _MACH_Pmac: ioremap_base = 0xfe000000; @@ -1025,46 +1073,7 @@ } ioremap_bot = ioremap_base; #endif /* CONFIG_POWER4 */ -#else /* CONFIG_8xx */ - - total_memory = total_lowmem = m8xx_find_end_of_memory(); -#ifdef CONFIG_HIGHMEM - if (total_lowmem > MAX_LOW_MEM) { - total_lowmem = MAX_LOW_MEM; - mem_pieces_remove(&phys_avail, total_lowmem, - total_memory - total_lowmem, 0); - } -#endif /* CONFIG_HIGHMEM */ - end_of_DRAM = __va(total_lowmem); - - /* Map in all of RAM starting at KERNELBASE */ - mapin_ram(); - - /* Now map in some of the I/O space that is generically needed - * or shared with multiple devices. - * All of this fits into the same 4Mbyte region, so it only - * requires one page table page. - */ - ioremap(IMAP_ADDR, IMAP_SIZE); -#ifdef CONFIG_MBX - ioremap(NVRAM_ADDR, NVRAM_SIZE); - ioremap(MBX_CSR_ADDR, MBX_CSR_SIZE); - ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE); - /* Map some of the PCI/ISA I/O space to get the IDE interface. - */ - ioremap(PCI_ISA_IO_ADDR, 0x4000); - ioremap(PCI_IDE_ADDR, 0x4000); -#endif -#ifdef CONFIG_RPXLITE - ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE); - ioremap(HIOX_CSR_ADDR, HIOX_CSR_SIZE); -#endif -#ifdef CONFIG_RPXCLASSIC - ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE); - ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE); -#endif -#endif /* CONFIG_8xx */ if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211); #ifdef CONFIG_BOOTX_TEXT /* Must be done last, or ppc_md.progress will die */ @@ -1189,7 +1198,8 @@ #if defined(CONFIG_ALL_PPC) /* mark the RTAS pages as reserved */ if ( rtas_data ) - for (addr = rtas_data; addr < PAGE_ALIGN(rtas_data+rtas_size) ; + for (addr = (ulong)__va(rtas_data); + addr < PAGE_ALIGN((ulong)__va(rtas_data)+rtas_size) ; addr += PAGE_SIZE) SetPageReserved(virt_to_page(addr)); #endif /* defined(CONFIG_ALL_PPC) */ @@ -1249,7 +1259,7 @@ unsigned long __init pmac_find_end_of_memory(void) { unsigned long a, total; - unsigned long ram_limit = 0xe0000000 - KERNELBASE; + struct mem_pieces phys_mem; memory_node = find_devices("memory"); if (memory_node == NULL) { @@ -1260,8 +1270,7 @@ /* * Find out where physical memory is, and check that it * starts at 0 and is contiguous. It seems that RAM is - * always physically contiguous on Power Macintoshes, - * because MacOS can't cope if it isn't. + * always physically contiguous on Power Macintoshes. * * Supporting discontiguous physical memory isn't hard, * it just makes the virtual <-> physical mapping functions @@ -1274,23 +1283,14 @@ a = phys_mem.regions[0].address; if (a != 0) panic("RAM doesn't start at physical address 0"); - if (__max_memory == 0 || __max_memory > ram_limit) - __max_memory = ram_limit; - if (phys_mem.regions[0].size >= __max_memory) { - phys_mem.regions[0].size = __max_memory; - phys_mem.n_regions = 1; - } total = phys_mem.regions[0].size; - + if (phys_mem.n_regions > 1) { printk("RAM starting at 0x%x is not contiguous\n", phys_mem.regions[1].address); printk("Using RAM from 0 to 0x%lx\n", total-1); - phys_mem.n_regions = 1; } - set_phys_avail(&phys_mem); - return total; } #endif /* CONFIG_ALL_PPC */ @@ -1305,7 +1305,11 @@ unsigned long __init prep_find_end_of_memory(void) { unsigned long total; +#ifdef CONFIG_PREP_RESIDUAL total = res->TotalMemory; +#else + total = 0; +#endif if (total == 0 ) { @@ -1317,14 +1321,11 @@ total = 0x02000000; printk("Ramsize default to be %ldM\n", total>>20); } - mem_pieces_append(&phys_mem, 0, total); - set_phys_avail(&phys_mem); return (total); } #endif /* defined(CONFIG_ALL_PPC) */ - #if defined(CONFIG_GEMINI) unsigned long __init gemini_find_end_of_memory(void) { @@ -1335,12 +1336,8 @@ total = ((1<<((reg & 0x7) - 1)) * (8<<((reg >> 3) & 0x7))); total *= (1024*1024); - phys_mem.regions[0].address = 0; - phys_mem.regions[0].size = total; - phys_mem.n_regions = 1; - - set_phys_avail(&phys_mem); - return phys_mem.regions[0].size; + + return total; } #endif /* defined(CONFIG_GEMINI) */ @@ -1355,12 +1352,7 @@ binfo = (bd_t *)__res; - phys_mem.regions[0].address = 0; - phys_mem.regions[0].size = binfo->bi_memsize; - phys_mem.n_regions = 1; - - set_phys_avail(&phys_mem); - return phys_mem.regions[0].size; + return binfo->bi_memsize; } #endif /* CONFIG_8260 */ @@ -1369,6 +1361,7 @@ unsigned long __init apus_find_end_of_memory(void) { int shadow = 0; + unsigned long total; /* The memory size reported by ADOS excludes the 512KB reserved for PPC exception registers and possibly 512KB @@ -1394,43 +1387,28 @@ memory[0].size = ((size+0x001fffff) & 0xffe00000); } - /* Now register the memory block. */ - mem_pieces_append(&phys_mem, memory[0].addr, memory[0].size); - set_phys_avail(&phys_mem); + total = memory[0].size; /* Remove the memory chunks that are controlled by special Phase5 hardware. */ - { - unsigned long top = memory[0].addr + memory[0].size; - - /* Remove the upper 512KB if it contains a shadow of - the ADOS ROM. FIXME: It might be possible to - disable this shadow HW. Check the booter - (ppc_boot.c) */ - if (shadow) - { - top -= HARDWARE_MAPPED_SIZE; - mem_pieces_remove(&phys_avail, top, - HARDWARE_MAPPED_SIZE, 0); - } - /* Remove the upper 512KB where the PPC exception - vectors are mapped. */ - top -= HARDWARE_MAPPED_SIZE; -#if 0 - /* This would be neat, but it breaks on A3000 machines!? */ - mem_pieces_remove(&phys_avail, top, 16384, 0); -#else - mem_pieces_remove(&phys_avail, top, HARDWARE_MAPPED_SIZE, 0); -#endif - - } + /* Remove the upper 512KB if it contains a shadow of + the ADOS ROM. FIXME: It might be possible to + disable this shadow HW. Check the booter + (ppc_boot.c) */ + if (shadow) + total -= HARDWARE_MAPPED_SIZE; + + /* Remove the upper 512KB where the PPC exception + vectors are mapped. */ + total -= HARDWARE_MAPPED_SIZE; /* Linux/APUS only handles one block of memory -- the one on the PowerUP board. Other system memory is horrible slow in comparison. The user can use other memory for swapping using the z2ram device. */ - return memory[0].addr + memory[0].size; + ram_phys_base = memory[0].addr; + return total; } #endif /* CONFIG_APUS */ @@ -1440,12 +1418,11 @@ static void __init hash_init(void) { int Hash_bits, mb, mb2; - unsigned int hmask, ramsize, h; + unsigned int hmask, h; extern unsigned int hash_page_patch_A[], hash_page_patch_B[], hash_page_patch_C[], hash_page[]; - ramsize = (ulong)end_of_DRAM - KERNELBASE; #ifdef CONFIG_PPC64BRIDGE /* The hash table has already been allocated and initialized in prom.c */ @@ -1464,7 +1441,7 @@ * Allow 64k of hash table for every 16MB of memory, * up to a maximum of 2MB. */ - for (h = 64<<10; h < ramsize / 256 && h < (2<<20); h *= 2) + for (h = 64<<10; h < total_memory / 256 && h < (2<<20); h *= 2) ; Hash_size = h; Hash_mask = (h >> 6) - 1; @@ -1498,8 +1475,8 @@ Hash = 0; #endif /* CONFIG_PPC64BRIDGE */ - printk("Total memory = %dMB; using %ldkB for hash table (at %p)\n", - ramsize >> 20, Hash_size >> 10, Hash); + printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n", + total_memory >> 20, Hash_size >> 10, Hash); if ( Hash_size ) { if ( ppc_md.progress ) ppc_md.progress("hash:patch", 0x345); @@ -1560,12 +1537,7 @@ binfo = (bd_t *)__res; - phys_mem.regions[0].address = 0; - phys_mem.regions[0].size = binfo->bi_memsize; - phys_mem.n_regions = 1; - - set_phys_avail(&phys_mem); - return phys_mem.regions[0].address + phys_mem.regions[0].size; + return binfo->bi_memsize; } #endif /* !CONFIG_4xx && !CONFIG_8xx */ @@ -1582,20 +1554,16 @@ unsigned long *ret; bd_t *bip = (bd_t *)__res; - phys_mem.regions[0].address = 0; - phys_mem.regions[0].size = bip->bi_memsize; - phys_mem.n_regions = 1; - - set_phys_avail(&phys_mem); - return (phys_mem.regions[0].address + phys_mem.regions[0].size); + return bip->bi_memsize; } #endif /* - * Set phys_avail to phys_mem less the kernel text/data/bss. + * Set phys_avail to the amount of physical memory, + * less the kernel text/data/bss. */ void __init -set_phys_avail(struct mem_pieces *mp) +set_phys_avail(unsigned long total_memory) { unsigned long kstart, ksize; @@ -1604,7 +1572,9 @@ * physical memory. */ - phys_avail = *mp; + phys_avail.regions[0].address = 0; + phys_avail.regions[0].size = total_memory; + phys_avail.n_regions = 1; /* * Map out the kernel text/data/bss from the available physical diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/ppc/xmon/xmon.c linux.ac/arch/ppc/xmon/xmon.c --- linux.vanilla/arch/ppc/xmon/xmon.c Sat Oct 28 16:15:46 2000 +++ linux.ac/arch/ppc/xmon/xmon.c Mon Dec 18 20:45:53 2000 @@ -406,6 +406,7 @@ break; case 'M': print_sysmap(); + break; case 'S': super_regs(); break; @@ -795,6 +796,8 @@ extern char *sysmap; if ( sysmap ) printf("System.map: \n%s", sysmap); + else + printf("No System.map\n"); } void diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/s390/kernel/irq.c linux.ac/arch/s390/kernel/irq.c --- linux.vanilla/arch/s390/kernel/irq.c Sun Sep 17 12:22:37 2000 +++ linux.ac/arch/s390/kernel/irq.c Mon Nov 20 17:10:46 2000 @@ -205,6 +205,8 @@ if (!local_bh_count(cpu) && atomic_read(&global_bh_count)) continue; + /* this works even though global_irq_lock not + a long, but is arch-specific --RR */ if (!test_and_set_bit(0,&global_irq_lock)) break; } @@ -243,6 +245,8 @@ static inline void get_irqlock(int cpu) { + /* this works even though global_irq_lock not a long, but is + arch-specific --RR */ if (test_and_set_bit(0,&global_irq_lock)) { /* do we already hold the lock? */ if ( cpu == atomic_read(&global_irq_holder)) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/s390/kernel/setup.c linux.ac/arch/s390/kernel/setup.c --- linux.vanilla/arch/s390/kernel/setup.c Fri May 12 19:41:45 2000 +++ linux.ac/arch/s390/kernel/setup.c Fri Dec 22 16:40:31 2000 @@ -368,8 +368,8 @@ p += sprintf(p,"vendor_id : IBM/S390\n" "# processors : %i\n" "bogomips per cpu: %lu.%02lu\n", - smp_num_cpus, loops_per_sec/500000, - (loops_per_sec/5000)%100); + smp_num_cpus, loops_per_jiffy/(500000/HZ), + (loops_per_sec/(5000/HZ))%100); for (i = 0; i < smp_num_cpus; i++) { cpuinfo = &safe_get_cpu_lowcore(i).cpu_data; p += sprintf(p,"processor %i: " diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/sparc/kernel/entry.S linux.ac/arch/sparc/kernel/entry.S --- linux.vanilla/arch/sparc/kernel/entry.S Sun Sep 17 12:23:02 2000 +++ linux.ac/arch/sparc/kernel/entry.S Fri Dec 22 16:41:30 2000 @@ -1806,13 +1806,13 @@ C_LABEL(udelay): save %sp, -REGWIN_SZ, %sp mov %i0, %o0 - sethi %hi(0x10c6), %o1 + sethi %hi(0x10c600), %o1 call .umul - or %o1, %lo(0x10c6), %o1 + or %o1, %lo(0x10c600), %o1 #ifndef CONFIG_SMP - sethi %hi(C_LABEL(loops_per_sec)), %o3 + sethi %hi(C_LABEL(loops_per_jiffy)), %o3 call .umul - ld [%o3 + %lo(C_LABEL(loops_per_sec))], %o1 + ld [%o3 + %lo(C_LABEL(loops_per_jiffy))], %o1 #else GET_PROCESSOR_OFFSET(o4, o2) set C_LABEL(cpu_data), %o3 diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/sparc/kernel/setup.c linux.ac/arch/sparc/kernel/setup.c --- linux.vanilla/arch/sparc/kernel/setup.c Tue Oct 31 20:26:00 2000 +++ linux.ac/arch/sparc/kernel/setup.c Fri Dec 22 16:42:12 2000 @@ -485,7 +485,7 @@ &cputypval, linux_num_cpus, smp_num_cpus #ifndef CONFIG_SMP - , loops_per_sec/500000, (loops_per_sec/5000) % 100 + , loops_per_jiffy/(500000/HZ), (loops_per_jiffy/(5000/HZ)) % 100 #endif ); #ifdef CONFIG_SMP diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/sparc/kernel/smp.c linux.ac/arch/sparc/kernel/smp.c --- linux.vanilla/arch/sparc/kernel/smp.c Tue Dec 12 13:05:16 2000 +++ linux.ac/arch/sparc/kernel/smp.c Fri Dec 22 16:42:44 2000 @@ -86,7 +86,7 @@ void __init smp_store_cpu_info(int id) { - cpu_data[id].udelay_val = loops_per_sec; /* this is it on sparc. */ + cpu_data[id].udelay_val = loops_per_jiffy; /* this is it on sparc. */ } void __init smp_commence(void) @@ -284,8 +284,8 @@ if (cpu_present_map & (1 << i)) len += sprintf(buf + len, "Cpu%dBogo\t: %lu.%02lu\n", i, - cpu_data[i].udelay_val/500000, - (cpu_data[i].udelay_val/5000)%100); + cpu_data[i].udelay_val/(500000/HZ), + (cpu_data[i].udelay_val/(5000/HZ))%100); return len; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/sparc/kernel/sun4d_smp.c linux.ac/arch/sparc/kernel/sun4d_smp.c --- linux.vanilla/arch/sparc/kernel/sun4d_smp.c Tue Dec 12 13:05:16 2000 +++ linux.ac/arch/sparc/kernel/sun4d_smp.c Fri Dec 22 16:44:22 2000 @@ -287,11 +287,11 @@ smp_highest_cpu = i; } } - SMP_PRINTK(("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n", cpucount + 1, (bogosum + 2500)/500000, ((bogosum + 2500)/5000)%100)); + SMP_PRINTK(("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n", cpucount + 1, bogosum/(500000/HZ), (bogosum/(5000/HZ))%100)); printk("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n", cpucount + 1, - (bogosum + 2500)/500000, - ((bogosum + 2500)/5000)%100); + bogosum/(500000/HZ), + (bogosum/(5000/HZ))%100); smp_activated = 1; smp_num_cpus = cpucount + 1; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/sparc/kernel/sun4m_smp.c linux.ac/arch/sparc/kernel/sun4m_smp.c --- linux.vanilla/arch/sparc/kernel/sun4m_smp.c Tue Dec 12 13:05:16 2000 +++ linux.ac/arch/sparc/kernel/sun4m_smp.c Fri Dec 22 16:44:24 2000 @@ -256,8 +256,8 @@ } printk("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n", cpucount + 1, - (bogosum + 2500)/500000, - ((bogosum + 2500)/5000)%100); + bogosum/(500000/HZ), + (bogosum/(5000/HZ))%100); smp_activated = 1; smp_num_cpus = cpucount + 1; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/sparc64/config.in linux.ac/arch/sparc64/config.in --- linux.vanilla/arch/sparc64/config.in Mon Nov 20 15:11:57 2000 +++ linux.ac/arch/sparc64/config.in Sun Dec 31 22:29:32 2000 @@ -193,6 +193,8 @@ fi endmenu +source drivers/message/fusion/Config.in + source drivers/fc4/Config.in if [ "$CONFIG_PCI" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/sparc64/kernel/smp.c linux.ac/arch/sparc64/kernel/smp.c --- linux.vanilla/arch/sparc64/kernel/smp.c Tue Oct 31 20:26:01 2000 +++ linux.ac/arch/sparc64/kernel/smp.c Fri Dec 22 16:44:47 2000 @@ -79,8 +79,8 @@ if(cpu_present_map & (1UL << i)) len += sprintf(buf + len, "Cpu%dBogo\t: %lu.%02lu\n", - i, cpu_data[i].udelay_val / 500000, - (cpu_data[i].udelay_val / 5000) % 100); + i, cpu_data[i].udelay_val / (500000/HZ), + (cpu_data[i].udelay_val / (5000/HZ)) % 100); return len; } @@ -90,7 +90,7 @@ /* multiplier and counter set by smp_setup_percpu_timer() */ - cpu_data[id].udelay_val = loops_per_sec; + cpu_data[id].udelay_val = loops_per_jiffy; cpu_data[id].pgcache_size = 0; cpu_data[id].pte_cache[0] = NULL; @@ -290,8 +290,8 @@ } printk("Total of %d processors activated (%lu.%02lu BogoMIPS).\n", cpucount + 1, - (bogosum + 2500)/500000, - ((bogosum + 2500)/5000)%100); + (bogosum + 2500)/(500000/HZ), + ((bogosum + 2500)/(5000/HZ))%100); smp_activated = 1; smp_num_cpus = cpucount + 1; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/Makefile linux.ac/drivers/Makefile --- linux.vanilla/drivers/Makefile Sun Dec 31 19:41:44 2000 +++ linux.ac/drivers/Makefile Sun Dec 31 22:32:01 2000 @@ -6,7 +6,7 @@ # -mod-subdirs := dio mtd sbus video macintosh usb input telephony sgi i2o ide \ +mod-subdirs := dio mtd sbus video macintosh usb input telephony sgi message/i2o message/fusion ide \ scsi md ieee1394 pnp isdn atm fc4 net/hamradio i2c acpi subdir-y := block char net parport sound misc media cdrom @@ -30,7 +30,8 @@ subdir-$(CONFIG_SGI) += sgi subdir-$(CONFIG_IDE) += ide subdir-$(CONFIG_SCSI) += scsi -subdir-$(CONFIG_I2O) += i2o +subdir-$(CONFIG_I2O) += message/i2o +subdir-$(CONFIG_FUSION) += message/fusion subdir-$(CONFIG_MD) += md subdir-$(CONFIG_IEEE1394) += ieee1394 subdir-$(CONFIG_PNP) += pnp @@ -44,4 +45,3 @@ subdir-$(CONFIG_ACPI) += acpi include $(TOPDIR)/Rules.make - diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/Makefile linux.ac/drivers/acorn/Makefile --- linux.vanilla/drivers/acorn/Makefile Thu Oct 21 00:29:08 1999 +++ linux.ac/drivers/acorn/Makefile Sun Dec 31 14:57:34 2000 @@ -5,8 +5,11 @@ # removes any old dependencies. DON'T put your own dependencies here # unless it's something special (not a .c file). -SUB_DIRS := block char net scsi -MOD_SUB_DIRS := $(SUB_DIRS) -ALL_SUB_DIRS := $(SUB_DIRS) +subdir-y := char +subdir-m := $(subdir-y) + +# the BLOCK subdir is included from drivers/block now +# the SCSI subdir is included from drivers/scsi now +# the NET subdir is included from drivers/net now include $(TOPDIR)/Rules.make diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/block/Makefile linux.ac/drivers/acorn/block/Makefile --- linux.vanilla/drivers/acorn/block/Makefile Sun Sep 17 12:22:44 2000 +++ linux.ac/drivers/acorn/block/Makefile Sun Dec 31 14:57:34 2000 @@ -11,7 +11,7 @@ USE_STANDARD_AS_RULE := true -L_TARGET := acorn-block.a +O_TARGET := acorn-block.o obj-y := obj-m := @@ -24,36 +24,12 @@ mfmhd_mod-objs := mfmhd.o mfm.o obj-$(CONFIG_BLK_DEV_FD1772) += fd1772_mod.o -obj-$(CONFIG_BLK_DEV_MFM) += mfmhd.o mfm.o - -# Extract lists of the multi-part drivers. -# The 'int-*' lists are intermediate files used to build the multi's. - -multi-y := $(filter $(list-multi), $(obj-y)) -multi-m := $(filter $(list-multi), $(obj-m)) -int-y := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs))) -int-m := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs))) - -# Files that are both resident and modular; remove from modular. - -obj-m := $(filter-out $(obj-y), $(obj-m)) -int-m := $(filter-out $(int-y), $(int-m)) - -# Take multi-part drivers out of obj-y and put components in. - -obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y) - -# Translate to Rules.make lists. - -L_OBJS := $(filter-out $(export-objs), $(obj-y)) -LX_OBJS := $(filter $(export-objs), $(obj-y)) -M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) -MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) +obj-$(CONFIG_BLK_DEV_MFM) += mfmhd_mod.o include $(TOPDIR)/Rules.make -fd1772_mod.o: $(FLOPPY) - $(LD) -r -o $@ $(FLOPPY) +fd1772_mod.o: $(fd1772_mod-objs) + $(LD) -r -o $@ $(fd1772_mod-objs) -mfmhd_mod.o: mfmhd.o mfm.o - $(LD) -r -o $@ mfmhd.o mfm.o +mfmhd_mod.o: $(mfmhd_mod-objs) + $(LD) -r -o $@ $(mfmhd_mod-objs) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/block/fd1772.c linux.ac/drivers/acorn/block/fd1772.c --- linux.vanilla/drivers/acorn/block/fd1772.c Sat Oct 28 16:15:48 2000 +++ linux.ac/drivers/acorn/block/fd1772.c Mon Nov 20 17:10:46 2000 @@ -276,8 +276,8 @@ static volatile int fdc_busy = 0; static DECLARE_WAIT_QUEUE_HEAD(fdc_wait); - -static unsigned int changed_floppies = 0xff, fake_change = 0; +/* long req'd for set_bit --RR */ +static unsigned long changed_floppies = 0xff, fake_change = 0; #define CHECK_CHANGE_DELAY HZ/2 /* DAG - increased to 30*HZ - not sure if this is the correct thing to do */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/char/Makefile linux.ac/drivers/acorn/char/Makefile --- linux.vanilla/drivers/acorn/char/Makefile Sat Oct 28 16:15:48 2000 +++ linux.ac/drivers/acorn/char/Makefile Sun Dec 31 14:57:35 2000 @@ -11,11 +11,6 @@ O_TARGET := acorn-char.o -O_OBJS := -OX_OBJS := -M_OBJS := -MX_OBJS := - # Object file lists. obj-y := @@ -37,10 +32,5 @@ # Do the i2c and rtc last obj-y += $(obj-$(MACHINE)) - -O_OBJS := $(filter-out $(export-objs), $(obj-y)) -OX_OBJS := $(filter $(export-objs), $(obj-y)) -M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) -MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) include $(TOPDIR)/Rules.make diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/net/Makefile linux.ac/drivers/acorn/net/Makefile --- linux.vanilla/drivers/acorn/net/Makefile Sun Sep 17 12:22:37 2000 +++ linux.ac/drivers/acorn/net/Makefile Sun Dec 31 14:57:35 2000 @@ -14,7 +14,4 @@ obj-$(CONFIG_ARM_ETHER3) += ether3.o obj-$(CONFIG_ARM_ETHER1) += ether1.o -O_OBJS := $(obj-y) -M_OBJS := $(obj-m) - include $(TOPDIR)/Rules.make diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/scsi/Makefile linux.ac/drivers/acorn/scsi/Makefile --- linux.vanilla/drivers/acorn/scsi/Makefile Sun Sep 17 12:22:44 2000 +++ linux.ac/drivers/acorn/scsi/Makefile Sun Dec 31 14:57:35 2000 @@ -4,7 +4,7 @@ USE_STANDARD_AS_RULE := true -L_TARGET := acorn-scsi.a +O_TARGET := acorn-scsi.o obj-y := obj-m := @@ -24,31 +24,7 @@ obj-$(CONFIG_SCSI_POWERTECSCSI) += powertec.o fas216.o queue.o msgqueue.o obj-$(CONFIG_SCSI_EESOXSCSI) += eesox.o fas216.o queue.o msgqueue.o -# Extract lists of the multi-part drivers. -# The 'int-*' lists are intermediate files used to build the multi's. - -multi-y := $(filter $(list-multi), $(obj-y)) -multi-m := $(filter $(list-multi), $(obj-m)) -int-y := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs))) -int-m := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs))) - -# Files that are both resident and modular; remove from modular. - -obj-m := $(filter-out $(obj-y), $(obj-m)) -int-m := $(filter-out $(int-y), $(int-m)) - -# Take multi-part drivers out of obj-y and put components in. - -obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y) - -# Translate to Rules.make lists. - -L_OBJS := $(filter-out $(export-objs), $(obj-y)) -LX_OBJS := $(filter $(export-objs), $(obj-y)) -M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) -MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) - include $(TOPDIR)/Rules.make -acornscsi_mod.o: acornscsi.o acornscsi-io.o - $(LD) $(LD_RFLAG) -r -o $@ acornscsi.o acornscsi-io.o +acornscsi_mod.o: $(acornscsi_mod-objs) + $(LD) -r -o $@ $(acornscsi_mod-objs) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/scsi/arxescsi.c linux.ac/drivers/acorn/scsi/arxescsi.c --- linux.vanilla/drivers/acorn/scsi/arxescsi.c Sat Oct 28 16:15:48 2000 +++ linux.ac/drivers/acorn/scsi/arxescsi.c Sun Dec 31 14:57:10 2000 @@ -16,6 +16,7 @@ * 01-01-2000 SH 0.1.0 Added *real* pseudo dma writing * (arxescsi_pseudo_dma_write) * 02-04-2000 RMK 0.1.1 Updated for new error handling code. + * 22-10-2000 SH Updated for new registering scheme. */ #include #include @@ -27,6 +28,7 @@ #include #include #include +#include #include #include @@ -416,8 +418,24 @@ return pos; } -#ifdef MODULE -Scsi_Host_Template driver_template = ARXEScsi; +static Scsi_Host_Template arxescsi_template = ARXEScsi; + +static int __init init_arxe_scsi_driver(void) +{ + arxescsi_template.module = THIS_MODULE; + scsi_register_module(MODULE_SCSI_HA, &arxescsi_template); + if (arxescsi_template.present) + return 0; + + scsi_unregister_module(MODULE_SCSI_HA, &arxescsi_template); + return -ENODEV; +} + +static void __exit exit_arxe_scsi_driver(void) +{ + scsi_unregister_module(MODULE_SCSI_HA, &arxescsi_template); +} + +module_init(init_arxe_scsi_driver); +module_exit(exit_arxe_scsi_driver); -#include "../../scsi/scsi_module.c" -#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/scsi/cumana_1.c linux.ac/drivers/acorn/scsi/cumana_1.c --- linux.vanilla/drivers/acorn/scsi/cumana_1.c Fri Nov 12 00:57:30 1999 +++ linux.ac/drivers/acorn/scsi/cumana_1.c Sun Dec 31 14:57:10 2000 @@ -51,24 +51,53 @@ #include #include #include -#include #include +#include #include #include +#include #include #include "../../scsi/scsi.h" #include "../../scsi/hosts.h" -#include "cumana_1.h" -#include "../../scsi/NCR5380.h" #include "../../scsi/constants.h" +#include + +#define CUMANASCSI_PUBLIC_RELEASE 1 + static const card_ids cumanascsi_cids[] = { { MANU_CUMANA, PROD_CUMANA_SCSI_1 }, { 0xffff, 0xffff } }; +#define NCR5380_implementation_fields \ + int port, ctrl + +#define NCR5380_local_declare() \ + struct Scsi_Host *_instance + +#define NCR5380_setup(instance) \ + _instance = instance + +#define NCR5380_read(reg) cumanascsi_read(_instance, reg) +#define NCR5380_write(reg, value) cumanascsi_write(_instance, reg, value) + +#define do_NCR5380_intr do_cumanascsi_intr +#define NCR5380_queue_command cumanascsi_queue_command +#define NCR5380_abort cumanascsi_abort +#define NCR5380_reset cumanascsi_reset +#define NCR5380_proc_info cumanascsi_proc_info + +int NCR5380_proc_info(char *buffer, char **start, off_t offset, + int length, int hostno, int inout); + +#define BOARD_NORMAL 0 +#define BOARD_NCR53C400 1 + +#include "../../scsi/NCR5380.h" + /* * Function : cumanascsi_setup(char *str, int *ints) * @@ -79,7 +108,8 @@ * */ -void cumanascsi_setup(char *str, int *ints) { +void cumanascsi_setup(char *str, int *ints) +{ } #define CUMANA_ADDRESS(card) (ecard_address((card), ECARD_IOC, ECARD_SLOW) + 0x800) @@ -141,7 +171,7 @@ else printk (" %d", instance->irq); printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", - CAN_QUEUE, CMD_PER_LUN, CUMANASCSI_PUBLIC_RELEASE); + tpnt->can_queue, tpnt->cmd_per_lun, CUMANASCSI_PUBLIC_RELEASE); printk("\nscsi%d:", instance->host_no); NCR5380_print_options(instance); printk("\n"); @@ -359,9 +389,38 @@ #include "../../scsi/NCR5380.c" -#ifdef MODULE +static Scsi_Host_Template cumanascsi_template = { + module: THIS_MODULE, + name: "Cumana 16-bit SCSI", + detect: cumanascsi_detect, + release: cumanascsi_release, + info: cumanascsi_info, + queuecommand: cumanascsi_queue_command, + abort: cumanascsi_abort, + reset: cumanascsi_reset, + bios_param: scsicam_bios_param, + can_queue: 16, + this_id: 7, + sg_tablesize: SG_ALL, + cmd_per_lun: 2, + unchecked_isa_dma: 0, + use_clustering: DISABLE_CLUSTERING +}; -Scsi_Host_Template driver_template = CUMANA_NCR5380; +static int __init cumanascsi_init(void) +{ + scsi_register_module(MODULE_SCSI_HA, &cumanascsi_template); + if (cumanascsi_template.present) + return 0; -#include "../../scsi/scsi_module.c" -#endif + scsi_unregister_module(MODULE_SCSI_HA, &cumanascsi_template); + return -ENODEV; +} + +static void __exit cumanascsi_exit(void) +{ + scsi_unregister_module(MODULE_SCSI_HA, &cumanascsi_template); +} + +module_init(cumanascsi_init); +module_exit(cumanascsi_exit); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/scsi/cumana_1.h linux.ac/drivers/acorn/scsi/cumana_1.h --- linux.vanilla/drivers/acorn/scsi/cumana_1.h Sat Jul 18 19:55:24 1998 +++ linux.ac/drivers/acorn/scsi/cumana_1.h Thu Jan 1 01:00:00 1970 @@ -1,105 +0,0 @@ -/* - * Cumana Generic NCR5380 driver defines - * - * Copyright 1993, Drew Eckhardt - * Visionary Computing - * (Unix and Linux consulting and custom programming) - * drew@colorado.edu - * +1 (303) 440-4894 - * - * ALPHA RELEASE 1. - * - * For more information, please consult - * - * NCR 5380 Family - * SCSI Protocol Controller - * Databook - * - * NCR Microelectronics - * 1635 Aeroplaza Drive - * Colorado Springs, CO 80916 - * 1+ (719) 578-3400 - * 1+ (800) 334-5454 - */ - -/* - * $Log: cumana_1.h,v $ - * Revision 1.1 1998/02/23 02:45:22 davem - * Merge to 2.1.88 - * - */ - -#ifndef CUMANA_NCR5380_H -#define CUMANA_NCR5380_H - -#define CUMANASCSI_PUBLIC_RELEASE 1 - - -#ifndef ASM -int cumanascsi_abort (Scsi_Cmnd *); -int cumanascsi_detect (Scsi_Host_Template *); -int cumanascsi_release (struct Scsi_Host *); -const char *cumanascsi_info (struct Scsi_Host *); -int cumanascsi_reset(Scsi_Cmnd *, unsigned int); -int cumanascsi_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); -int cumanascsi_proc_info (char *buffer, char **start, off_t offset, - int length, int hostno, int inout); - -#ifndef NULL -#define NULL 0 -#endif - -#ifndef CMD_PER_LUN -#define CMD_PER_LUN 2 -#endif - -#ifndef CAN_QUEUE -#define CAN_QUEUE 16 -#endif - -#include - -#define CUMANA_NCR5380 { \ -name: "Cumana 16-bit SCSI", \ -detect: cumanascsi_detect, \ -release: cumanascsi_release, /* Release */ \ -info: cumanascsi_info, \ -queuecommand: cumanascsi_queue_command, \ -abort: cumanascsi_abort, \ -reset: cumanascsi_reset, \ -bios_param: scsicam_bios_param, /* biosparam */ \ -can_queue: CAN_QUEUE, /* can queue */ \ -this_id: 7, /* id */ \ -sg_tablesize: SG_ALL, /* sg_tablesize */ \ -cmd_per_lun: CMD_PER_LUN, /* cmd per lun */ \ -unchecked_isa_dma: 0, /* unchecked_isa_dma */ \ -use_clustering: DISABLE_CLUSTERING \ - } - -#ifndef HOSTS_C - -#define NCR5380_implementation_fields \ - int port, ctrl - -#define NCR5380_local_declare() \ - struct Scsi_Host *_instance - -#define NCR5380_setup(instance) \ - _instance = instance - -#define NCR5380_read(reg) cumanascsi_read(_instance, reg) -#define NCR5380_write(reg, value) cumanascsi_write(_instance, reg, value) - -#define do_NCR5380_intr do_cumanascsi_intr -#define NCR5380_queue_command cumanascsi_queue_command -#define NCR5380_abort cumanascsi_abort -#define NCR5380_reset cumanascsi_reset -#define NCR5380_proc_info cumanascsi_proc_info - -#define BOARD_NORMAL 0 -#define BOARD_NCR53C400 1 - -#endif /* ndef HOSTS_C */ -#endif /* ndef ASM */ -#endif /* CUMANA_NCR5380_H */ - diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/scsi/cumana_2.c linux.ac/drivers/acorn/scsi/cumana_2.c --- linux.vanilla/drivers/acorn/scsi/cumana_2.c Sat Oct 28 16:15:48 2000 +++ linux.ac/drivers/acorn/scsi/cumana_2.c Sun Dec 31 14:57:10 2000 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -36,7 +37,9 @@ #include "../../scsi/sd.h" #include "../../scsi/hosts.h" -#include "cumana_2.h" +#include "fas216.h" + +#include /* Configuration */ #define CUMANASCSI2_XTALFREQ 40 @@ -89,6 +92,22 @@ */ int term[MAX_ECARDS] = { 1, 1, 1, 1, 1, 1, 1, 1 }; +#define NR_SG 256 + +typedef struct { + FAS216_Info info; + + /* other info... */ + unsigned int status; /* card status register */ + unsigned int alatch; /* Control register */ + unsigned int terms; /* Terminator state */ + unsigned int dmaarea; /* Pseudo DMA area */ + struct scatterlist sg[NR_SG]; /* Scatter DMA list */ +} CumanaScsi2_Info; + +#define CSTATUS_IRQ (1 << 0) +#define CSTATUS_DRQ (1 << 1) + /* Prototype: void cumanascsi_2_irqenable(ec, irqnr) * Purpose : Enable interrupts on Cumana SCSI 2 card * Params : ec - expansion card structure @@ -541,8 +560,42 @@ return pos; } -#ifdef MODULE -Scsi_Host_Template driver_template = CUMANASCSI_2; +static Scsi_Host_Template cumanascsi2_template = { + module: THIS_MODULE, + proc_info: cumanascsi_2_proc_info, + name: "Cumana SCSI II", + detect: cumanascsi_2_detect, + release: cumanascsi_2_release, + info: cumanascsi_2_info, + bios_param: scsicam_bios_param, + can_queue: 1, + this_id: 7, + sg_tablesize: SG_ALL, + cmd_per_lun: 1, + use_clustering: DISABLE_CLUSTERING, + command: fas216_command, + queuecommand: fas216_queue_command, + eh_host_reset_handler: fas216_eh_host_reset, + eh_bus_reset_handler: fas216_eh_bus_reset, + eh_device_reset_handler: fas216_eh_device_reset, + eh_abort_handler: fas216_eh_abort, + use_new_eh_code: 1 +}; -#include "../../scsi/scsi_module.c" -#endif +static int __init cumanascsi2_init(void) +{ + scsi_register_module(MODULE_SCSI_HA, &cumanascsi2_template); + if (cumanascsi2_template.present) + return 0; + + scsi_unregister_module(MODULE_SCSI_HA, &cumanascsi2_template); + return -ENODEV; +} + +static void __exit cumanascsi2_exit(void) +{ + scsi_unregister_module(MODULE_SCSI_HA, &cumanascsi2_template); +} + +module_init(cumanascsi2_init); +module_exit(cumanascsi2_exit); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/scsi/cumana_2.h linux.ac/drivers/acorn/scsi/cumana_2.h --- linux.vanilla/drivers/acorn/scsi/cumana_2.h Sat Oct 28 16:15:48 2000 +++ linux.ac/drivers/acorn/scsi/cumana_2.h Thu Jan 1 01:00:00 1970 @@ -1,93 +0,0 @@ -/* - * linux/drivers/acorn/scsi/cumana_2.h - * - * Copyright (C) 1997-2000 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Cumana SCSI II driver - */ -#ifndef CUMANA_2_H -#define CUMANA_2_H - -extern int cumanascsi_2_detect (Scsi_Host_Template *); -extern int cumanascsi_2_release (struct Scsi_Host *); -extern const char *cumanascsi_2_info (struct Scsi_Host *); -extern int cumanascsi_2_proc_info (char *buffer, char **start, off_t offset, - int length, int hostno, int inout); - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#ifndef CAN_QUEUE -/* - * Default queue size - */ -#define CAN_QUEUE 1 -#endif - -#ifndef CMD_PER_LUN -/* - * Default queue size - */ -#define CMD_PER_LUN 1 -#endif - -#ifndef SCSI_ID -/* - * Default SCSI host ID - */ -#define SCSI_ID 7 -#endif - -#include - -#include "fas216.h" - -#define CUMANASCSI_2 { \ -proc_info: cumanascsi_2_proc_info, \ -name: "Cumana SCSI II", \ -detect: cumanascsi_2_detect, \ -release: cumanascsi_2_release, \ -info: cumanascsi_2_info, \ -bios_param: scsicam_bios_param, \ -can_queue: CAN_QUEUE, \ -this_id: SCSI_ID, \ -sg_tablesize: SG_ALL, \ -cmd_per_lun: CMD_PER_LUN, \ -use_clustering: DISABLE_CLUSTERING, \ -command: fas216_command, \ -queuecommand: fas216_queue_command, \ -eh_host_reset_handler: fas216_eh_host_reset, \ -eh_bus_reset_handler: fas216_eh_bus_reset, \ -eh_device_reset_handler: fas216_eh_device_reset, \ -eh_abort_handler: fas216_eh_abort, \ -use_new_eh_code: 1 \ - } - -#ifndef HOSTS_C - -#include - -#define NR_SG 256 - -typedef struct { - FAS216_Info info; - - /* other info... */ - unsigned int status; /* card status register */ - unsigned int alatch; /* Control register */ - unsigned int terms; /* Terminator state */ - unsigned int dmaarea; /* Pseudo DMA area */ - struct scatterlist sg[NR_SG]; /* Scatter DMA list */ -} CumanaScsi2_Info; - -#define CSTATUS_IRQ (1 << 0) -#define CSTATUS_DRQ (1 << 1) - -#endif /* HOSTS_C */ - -#endif /* CUMANASCSI_2_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/scsi/ecoscsi.c linux.ac/drivers/acorn/scsi/ecoscsi.c --- linux.vanilla/drivers/acorn/scsi/ecoscsi.c Fri Nov 12 00:57:30 1999 +++ linux.ac/drivers/acorn/scsi/ecoscsi.c Sun Dec 31 14:57:10 2000 @@ -53,10 +53,11 @@ #include "../../scsi/scsi.h" #include "../../scsi/hosts.h" -#include "ecoscsi.h" #include "../../scsi/NCR5380.h" #include "../../scsi/constants.h" +#define ECOSCSI_PUBLIC_RELEASE 1 + static char ecoscsi_read(struct Scsi_Host *instance, int reg) { int iobase = instance->io_port; @@ -231,11 +232,63 @@ #endif #undef STAT +#ifndef HOSTS_C +#define NCR5380_implementation_fields \ + int port, ctrl + +#define NCR5380_local_declare() \ + struct Scsi_Host *_instance + +#define NCR5380_setup(instance) \ + _instance = instance + +#define NCR5380_read(reg) ecoscsi_read(_instance, reg) +#define NCR5380_write(reg, value) ecoscsi_write(_instance, reg, value) + +#define do_NCR5380_intr do_ecoscsi_intr +#define NCR5380_queue_command ecoscsi_queue_command +#define NCR5380_abort ecoscsi_abort +#define NCR5380_reset ecoscsi_reset +#define NCR5380_proc_info ecoscsi_proc_info + +int NCR5380_proc_info(char *buffer, char **start, off_t offset, + int length, int hostno, int inout); + +#define BOARD_NORMAL 0 +#define BOARD_NCR53C400 1 + #include "../../scsi/NCR5380.c" -#ifdef MODULE +static Scsi_Host_Template ecoscsi_template = { + module: THIS_MODULE, + name: "Serial Port EcoSCSI NCR5380", + detect: ecoscsi_detect, + release: ecoscsi_release, + info: ecoscsi_info, + queuecommand: ecoscsi_queue_command, + abort: ecoscsi_abort, + reset: ecoscsi_reset, + can_queue: 16, + this_id: 7, + sg_tablesize: SG_ALL, + cmd_per_lun: 2, + use_clustering: DISABLE_CLUSTERING +}; + +static int __init ecoscsi_init(void) +{ + scsi_register_module(MODULE_SCSI_HA, &ecoscsi_template); + if (ecoscsi_template.present) + return 0; + + scsi_unregister_module(MODULE_SCSI_HA, &ecoscsi_template); + return -ENODEV; +} -Scsi_Host_Template driver_template = ECOSCSI_NCR5380; +static void __exit ecoscsi_exit(void) +{ + scsi_unregister_module(MODULE_SCSI_HA, &ecoscsi_template); +} -#include "../../scsi/scsi_module.c" -#endif +module_init(ecoscsi_init); +module_exit(ecoscsi_exit); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/scsi/ecoscsi.h linux.ac/drivers/acorn/scsi/ecoscsi.h --- linux.vanilla/drivers/acorn/scsi/ecoscsi.h Sat Jul 18 19:55:24 1998 +++ linux.ac/drivers/acorn/scsi/ecoscsi.h Thu Jan 1 01:00:00 1970 @@ -1,96 +0,0 @@ -/* - * Cumana Generic NCR5380 driver defines - * - * Copyright 1995, Russell King - * - * ALPHA RELEASE 1. - * - * For more information, please consult - * - * NCR 5380 Family - * SCSI Protocol Controller - * Databook - * - * NCR Microelectronics - * 1635 Aeroplaza Drive - * Colorado Springs, CO 80916 - * 1+ (719) 578-3400 - * 1+ (800) 334-5454 - */ - -/* - * $Log: ecoscsi.h,v $ - * Revision 1.1 1998/02/23 02:45:24 davem - * Merge to 2.1.88 - * - */ - -#ifndef ECOSCSI_NCR5380_H -#define ECOSCSI_NCR5380_H - -#define ECOSCSI_PUBLIC_RELEASE 1 - - -#ifndef ASM -int ecoscsi_abort (Scsi_Cmnd *); -int ecoscsi_detect (Scsi_Host_Template *); -int ecoscsi_release (struct Scsi_Host *); -const char *ecoscsi_info (struct Scsi_Host *); -int ecoscsi_reset(Scsi_Cmnd *, unsigned int); -int ecoscsi_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); -int ecoscsi_proc_info (char *buffer, char **start, off_t offset, - int length, int hostno, int inout); - -#ifndef NULL -#define NULL 0 -#endif - -#ifndef CMD_PER_LUN -#define CMD_PER_LUN 2 -#endif - -#ifndef CAN_QUEUE -#define CAN_QUEUE 16 -#endif - -#define ECOSCSI_NCR5380 { \ -name: "Serial Port EcoSCSI NCR5380", \ -detect: ecoscsi_detect, \ -release: ecoscsi_release, \ -info: ecoscsi_info, \ -queuecommand: ecoscsi_queue_command, \ -abort: ecoscsi_abort, \ -reset: ecoscsi_reset, \ -can_queue: CAN_QUEUE, /* can queue */ \ -this_id: 7, /* id */ \ -sg_tablesize: SG_ALL, \ -cmd_per_lun: CMD_PER_LUN, /* cmd per lun */ \ -use_clustering: DISABLE_CLUSTERING \ - } - -#ifndef HOSTS_C -#define NCR5380_implementation_fields \ - int port, ctrl - -#define NCR5380_local_declare() \ - struct Scsi_Host *_instance - -#define NCR5380_setup(instance) \ - _instance = instance - -#define NCR5380_read(reg) ecoscsi_read(_instance, reg) -#define NCR5380_write(reg, value) ecoscsi_write(_instance, reg, value) - -#define do_NCR5380_intr do_ecoscsi_intr -#define NCR5380_queue_command ecoscsi_queue_command -#define NCR5380_abort ecoscsi_abort -#define NCR5380_reset ecoscsi_reset -#define NCR5380_proc_info ecoscsi_proc_info - -#define BOARD_NORMAL 0 -#define BOARD_NCR53C400 1 - -#endif /* ndef HOSTS_C */ -#endif /* ndef ASM */ -#endif /* ECOSCSI_NCR5380_H */ - diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/scsi/eesox.c linux.ac/drivers/acorn/scsi/eesox.c --- linux.vanilla/drivers/acorn/scsi/eesox.c Sat Oct 28 16:15:48 2000 +++ linux.ac/drivers/acorn/scsi/eesox.c Sun Dec 31 14:57:10 2000 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -42,7 +43,9 @@ #include "../../scsi/sd.h" #include "../../scsi/hosts.h" -#include "eesox.h" +#include "fas216.h" + +#include /* Configuration */ #define EESOX_XTALFREQ 40 @@ -87,6 +90,22 @@ */ int term[MAX_ECARDS] = { 1, 1, 1, 1, 1, 1, 1, 1 }; +#define NR_SG 256 + +struct control { + unsigned int io_port; + unsigned int control; +}; + +typedef struct { + FAS216_Info info; + + struct control control; + + unsigned int dmaarea; /* Pseudo DMA area */ + struct scatterlist sg[NR_SG]; /* Scatter DMA list */ +} EESOXScsi_Info; + /* Prototype: void eesoxscsi_irqenable(ec, irqnr) * Purpose : Enable interrupts on EESOX SCSI card * Params : ec - expansion card structure @@ -543,8 +562,43 @@ return pos; } -#ifdef MODULE -Scsi_Host_Template driver_template = EESOXSCSI; +static Scsi_Host_Template eesox_template = { + module: THIS_MODULE, + proc_info: eesoxscsi_proc_info, + name: "EESOX SCSI", + detect: eesoxscsi_detect, + release: eesoxscsi_release, + info: eesoxscsi_info, + bios_param: scsicam_bios_param, + can_queue: 1, + this_id: 7, + sg_tablesize: SG_ALL, + cmd_per_lun: 1, + use_clustering: DISABLE_CLUSTERING, + command: fas216_command, + queuecommand: fas216_queue_command, + eh_host_reset_handler: fas216_eh_host_reset, + eh_bus_reset_handler: fas216_eh_bus_reset, + eh_device_reset_handler: fas216_eh_device_reset, + eh_abort_handler: fas216_eh_abort, + use_new_eh_code: 1 +}; + +static int __init eesox_init(void) +{ + scsi_register_module(MODULE_SCSI_HA, &eesox_template); + if (eesox_template.present) + return 0; + + scsi_unregister_module(MODULE_SCSI_HA, &eesox_template); + return -ENODEV; +} + +static void __exit eesox_exit(void) +{ + scsi_unregister_module(MODULE_SCSI_HA, &eesox_template); +} + +module_init(eesox_init); +module_exit(eesox_exit); -#include "../../scsi/scsi_module.c" -#endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/scsi/eesox.h linux.ac/drivers/acorn/scsi/eesox.h --- linux.vanilla/drivers/acorn/scsi/eesox.h Sat Oct 28 16:15:48 2000 +++ linux.ac/drivers/acorn/scsi/eesox.h Thu Jan 1 01:00:00 1970 @@ -1,90 +0,0 @@ -/* - * linux/drivers/acorn/scsi/eesox.h - * - * Copyright (C) 1997-2000 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * EESOX SCSI driver - */ -#ifndef EESOXSCSI_H -#define EESOXSCSI_H - -extern int eesoxscsi_detect (Scsi_Host_Template *); -extern int eesoxscsi_release (struct Scsi_Host *); -extern const char *eesoxscsi_info (struct Scsi_Host *); -extern int eesoxscsi_proc_info (char *buffer, char **start, off_t offset, - int length, int hostno, int inout); - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#ifndef CAN_QUEUE -/* - * Default queue size - */ -#define CAN_QUEUE 1 -#endif - -#ifndef CMD_PER_LUN -#define CMD_PER_LUN 1 -#endif - -#ifndef SCSI_ID -/* - * Default SCSI host ID - */ -#define SCSI_ID 7 -#endif - -#include - -#include "fas216.h" - -#define EESOXSCSI { \ -proc_info: eesoxscsi_proc_info, \ -name: "EESOX SCSI", \ -detect: eesoxscsi_detect, \ -release: eesoxscsi_release, \ -info: eesoxscsi_info, \ -bios_param: scsicam_bios_param, \ -can_queue: CAN_QUEUE, \ -this_id: SCSI_ID, \ -sg_tablesize: SG_ALL, \ -cmd_per_lun: CAN_QUEUE, \ -use_clustering: DISABLE_CLUSTERING, \ -command: fas216_command, \ -queuecommand: fas216_queue_command, \ -eh_host_reset_handler: fas216_eh_host_reset, \ -eh_bus_reset_handler: fas216_eh_bus_reset, \ -eh_device_reset_handler: fas216_eh_device_reset, \ -eh_abort_handler: fas216_eh_abort, \ -use_new_eh_code: 1 \ - } - -#ifndef HOSTS_C - -#include - -#define NR_SG 256 - -struct control { - unsigned int io_port; - unsigned int control; -}; - -typedef struct { - FAS216_Info info; - - struct control control; - - unsigned int dmaarea; /* Pseudo DMA area */ - struct scatterlist sg[NR_SG]; /* Scatter DMA list */ -} EESOXScsi_Info; - -#endif /* HOSTS_C */ - -#endif /* EESOXSCSI_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/scsi/fas216.c linux.ac/drivers/acorn/scsi/fas216.c --- linux.vanilla/drivers/acorn/scsi/fas216.c Sat Oct 28 16:15:48 2000 +++ linux.ac/drivers/acorn/scsi/fas216.c Sun Dec 31 14:57:10 2000 @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -2767,12 +2768,12 @@ EXPORT_SYMBOL(fas216_print_device); #ifdef MODULE -int init_module(void) +int __init init_module(void) { return 0; } -void cleanup_module(void) +void __exit cleanup_module(void) { } #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/scsi/msgqueue.c linux.ac/drivers/acorn/scsi/msgqueue.c --- linux.vanilla/drivers/acorn/scsi/msgqueue.c Sat Oct 28 16:15:48 2000 +++ linux.ac/drivers/acorn/scsi/msgqueue.c Sun Dec 31 14:57:10 2000 @@ -12,6 +12,7 @@ #include #include #include +#include #include "msgqueue.h" @@ -128,7 +129,7 @@ va_start(ap, length); for (i = 0; i < length; i++) - mq->msg.msg[i] = va_arg(ap, unsigned char); + mq->msg.msg[i] = va_arg(ap, unsigned int); va_end(ap); mq->msg.length = length; @@ -169,12 +170,12 @@ EXPORT_SYMBOL(msgqueue_flush); #ifdef MODULE -int init_module(void) +int __init init_module(void) { return 0; } -void cleanup_module(void) +void __exit cleanup_module(void) { } #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/scsi/oak.c linux.ac/drivers/acorn/scsi/oak.c --- linux.vanilla/drivers/acorn/scsi/oak.c Fri Nov 12 00:57:30 1999 +++ linux.ac/drivers/acorn/scsi/oak.c Sun Dec 31 14:57:10 2000 @@ -59,10 +59,35 @@ #include "../../scsi/scsi.h" #include "../../scsi/hosts.h" -#include "oak.h" -#include "../../scsi/NCR5380.h" #include "../../scsi/constants.h" +#define OAKSCSI_PUBLIC_RELEASE 1 + +#define NCR5380_read(reg) oakscsi_read(_instance, reg) +#define NCR5380_write(reg, value) oakscsi_write(_instance, reg, value) +#define do_NCR5380_intr do_oakscsi_intr +#define NCR5380_queue_command oakscsi_queue_command +#define NCR5380_abort oakscsi_abort +#define NCR5380_reset oakscsi_reset +#define NCR5380_proc_info oakscsi_proc_info + +int NCR5380_proc_info(char *buffer, char **start, off_t offset, + int length, int hostno, int inout); + +#define NCR5380_implementation_fields \ + int port, ctrl + +#define NCR5380_local_declare() \ + struct Scsi_Host *_instance + +#define NCR5380_setup(instance) \ + _instance = instance + +#define BOARD_NORMAL 0 +#define BOARD_NCR53C400 1 + +#include "../../scsi/NCR5380.h" + #undef START_DMA_INITIATOR_RECEIVE_REG #define START_DMA_INITIATOR_RECEIVE_REG (7 + 128) @@ -129,7 +154,7 @@ else printk (" %d", instance->irq); printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", - CAN_QUEUE, CMD_PER_LUN, OAKSCSI_PUBLIC_RELEASE); + tpnt->can_queue, tpnt->cmd_per_lun, OAKSCSI_PUBLIC_RELEASE); printk("\nscsi%d:", instance->host_no); NCR5380_print_options(instance); printk("\n"); @@ -226,9 +251,37 @@ #include "../../scsi/NCR5380.c" -#ifdef MODULE +static Scsi_Host_Template oakscsi_template = { + module: THIS_MODULE, + proc_info: oakscsi_proc_info, + name: "Oak 16-bit SCSI", + detect: oakscsi_detect, + release: oakscsi_release, + info: oakscsi_info, + queuecommand: oakscsi_queue_command, + abort: oakscsi_abort, + reset: oakscsi_reset, + can_queue: 16, + this_id: 7, + sg_tablesize: SG_ALL, + cmd_per_lun: 2, + use_clustering: DISABLE_CLUSTERING +}; -Scsi_Host_Template driver_template = OAK_NCR5380; +static int __init oakscsi_init(void) +{ + scsi_register_module(MODULE_SCSI_HA, &oakscsi_template); + if (oakscsi_template.present) + return 0; -#include "../../scsi/scsi_module.c" -#endif + scsi_unregister_module(MODULE_SCSI_HA, &oakscsi_template); + return -ENODEV; +} + +static void __exit oakscsi_exit(void) +{ + scsi_unregister_module(MODULE_SCSI_HA, &oakscsi_template); +} + +module_init(oakscsi_init); +module_exit(oakscsi_exit); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/scsi/oak.h linux.ac/drivers/acorn/scsi/oak.h --- linux.vanilla/drivers/acorn/scsi/oak.h Sat Jul 18 19:55:24 1998 +++ linux.ac/drivers/acorn/scsi/oak.h Thu Jan 1 01:00:00 1970 @@ -1,100 +0,0 @@ -/* - * Cumana Generic NCR5380 driver defines - * - * Copyright 1993, Drew Eckhardt - * Visionary Computing - * (Unix and Linux consulting and custom programming) - * drew@colorado.edu - * +1 (303) 440-4894 - * - * ALPHA RELEASE 1. - * - * For more information, please consult - * - * NCR 5380 Family - * SCSI Protocol Controller - * Databook - * - * NCR Microelectronics - * 1635 Aeroplaza Drive - * Colorado Springs, CO 80916 - * 1+ (719) 578-3400 - * 1+ (800) 334-5454 - */ - -/* - * $Log: oak.h,v $ - * Revision 1.1 1998/02/23 02:45:27 davem - * Merge to 2.1.88 - * - */ - -#ifndef OAK_NCR5380_H -#define OAK_NCR5380_H - -#define OAKSCSI_PUBLIC_RELEASE 1 - - -#ifndef ASM -int oakscsi_abort(Scsi_Cmnd *); -int oakscsi_detect(Scsi_Host_Template *); -int oakscsi_release(struct Scsi_Host *); -const char *oakscsi_info(struct Scsi_Host *); -int oakscsi_reset(Scsi_Cmnd *, unsigned int); -int oakscsi_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); -int oakscsi_proc_info (char *buffer, char **start, off_t off, - int length, int hostno, int inout); - -#ifndef NULL -#define NULL 0 -#endif - -#ifndef CMD_PER_LUN -#define CMD_PER_LUN 2 -#endif - -#ifndef CAN_QUEUE -#define CAN_QUEUE 16 -#endif - -#define OAK_NCR5380 { \ -proc_info: oakscsi_proc_info, \ -name: "Oak 16-bit SCSI", \ -detect: oakscsi_detect, \ -release: oakscsi_release, /* Release */ \ -info: oakscsi_info, \ -queuecommand: oakscsi_queue_command, \ -abort: oakscsi_abort, \ -reset: oakscsi_reset, \ -can_queue: CAN_QUEUE, /* can queue */ \ -this_id: 7, /* id */ \ -sg_tablesize: SG_ALL, /* sg_tablesize */ \ -cmd_per_lun: CMD_PER_LUN, /* cmd per lun */ \ -use_clustering: DISABLE_CLUSTERING \ - } - -#ifndef HOSTS_C -#define NCR5380_implementation_fields \ - int port, ctrl - -#define NCR5380_local_declare() \ - struct Scsi_Host *_instance - -#define NCR5380_setup(instance) \ - _instance = instance - -#define NCR5380_read(reg) oakscsi_read(_instance, reg) -#define NCR5380_write(reg, value) oakscsi_write(_instance, reg, value) -#define do_NCR5380_intr do_oakscsi_intr -#define NCR5380_queue_command oakscsi_queue_command -#define NCR5380_abort oakscsi_abort -#define NCR5380_reset oakscsi_reset -#define NCR5380_proc_info oakscsi_proc_info - -#define BOARD_NORMAL 0 -#define BOARD_NCR53C400 1 - -#endif /* else def HOSTS_C */ -#endif /* ndef ASM */ -#endif /* OAK_NCR5380_H */ - diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/scsi/powertec.c linux.ac/drivers/acorn/scsi/powertec.c --- linux.vanilla/drivers/acorn/scsi/powertec.c Sat Oct 28 16:15:48 2000 +++ linux.ac/drivers/acorn/scsi/powertec.c Sun Dec 31 14:57:10 2000 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -39,7 +40,9 @@ #include "../../scsi/sd.h" #include "../../scsi/hosts.h" -#include "powertec.h" +#include "fas216.h" + +#include /* Configuration */ #define POWERTEC_XTALFREQ 40 @@ -86,6 +89,20 @@ */ int term[MAX_ECARDS] = { 1, 1, 1, 1, 1, 1, 1, 1 }; +#define NR_SG 256 + +typedef struct { + FAS216_Info info; + + struct { + unsigned int term_port; + unsigned int terms; + } control; + + /* other info... */ + struct scatterlist sg[NR_SG]; /* Scatter DMA list */ +} PowerTecScsi_Info; + /* Prototype: void powertecscsi_irqenable(ec, irqnr) * Purpose : Enable interrupts on Powertec SCSI card * Params : ec - expansion card structure @@ -445,8 +462,42 @@ return pos; } -#ifdef MODULE -Scsi_Host_Template driver_template = POWERTECSCSI; +static Scsi_Host_Template powertecscsi_template = { + module: THIS_MODULE, + proc_info: powertecscsi_proc_info, + name: "PowerTec SCSI", + detect: powertecscsi_detect, + release: powertecscsi_release, + info: powertecscsi_info, + bios_param: scsicam_bios_param, + can_queue: 1, + this_id: 7, + sg_tablesize: SG_ALL, + cmd_per_lun: 1, + use_clustering: ENABLE_CLUSTERING, + command: fas216_command, + queuecommand: fas216_queue_command, + eh_host_reset_handler: fas216_eh_host_reset, + eh_bus_reset_handler: fas216_eh_bus_reset, + eh_device_reset_handler: fas216_eh_device_reset, + eh_abort_handler: fas216_eh_abort, + use_new_eh_code: 1 +}; + +static int __init powertecscsi_init(void) +{ + scsi_register_module(MODULE_SCSI_HA, &powertecscsi_template); + if (powertecscsi_template.present) + return 0; + + scsi_unregister_module(MODULE_SCSI_HA, &powertecscsi_template); + return -ENODEV; +} + +static void __exit powertecscsi_exit(void) +{ + scsi_unregister_module(MODULE_SCSI_HA, &powertecscsi_template); +} -#include "../../scsi/scsi_module.c" -#endif +module_init(powertecscsi_init); +module_exit(powertecscsi_exit); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/scsi/powertec.h linux.ac/drivers/acorn/scsi/powertec.h --- linux.vanilla/drivers/acorn/scsi/powertec.h Sat Oct 28 16:15:48 2000 +++ linux.ac/drivers/acorn/scsi/powertec.h Thu Jan 1 01:00:00 1970 @@ -1,88 +0,0 @@ -/* - * linux/drivers/acorn/scsi/powertec.h - * - * Copyright (C) 1997-2000 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * PowerTec SCSI driver - */ -#ifndef POWERTECSCSI_H -#define POWERTECSCSI_H - -extern int powertecscsi_detect (Scsi_Host_Template *); -extern int powertecscsi_release (struct Scsi_Host *); -extern const char *powertecscsi_info (struct Scsi_Host *); -extern int powertecscsi_proc_info (char *buffer, char **start, off_t offset, - int length, int hostno, int inout); - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#ifndef CAN_QUEUE -/* - * Default queue size - */ -#define CAN_QUEUE 1 -#endif - -#ifndef CMD_PER_LUN -#define CMD_PER_LUN 1 -#endif - -#ifndef SCSI_ID -/* - * Default SCSI host ID - */ -#define SCSI_ID 7 -#endif - -#include - -#include "fas216.h" - -#define POWERTECSCSI { \ -proc_info: powertecscsi_proc_info, \ -name: "PowerTec SCSI", \ -detect: powertecscsi_detect, \ -release: powertecscsi_release, \ -info: powertecscsi_info, \ -bios_param: scsicam_bios_param, \ -can_queue: CAN_QUEUE, \ -this_id: SCSI_ID, \ -sg_tablesize: SG_ALL, \ -cmd_per_lun: CMD_PER_LUN, \ -use_clustering: ENABLE_CLUSTERING, \ -command: fas216_command, \ -queuecommand: fas216_queue_command, \ -eh_host_reset_handler: fas216_eh_host_reset, \ -eh_bus_reset_handler: fas216_eh_bus_reset, \ -eh_device_reset_handler: fas216_eh_device_reset, \ -eh_abort_handler: fas216_eh_abort, \ -use_new_eh_code: 1 \ - } - -#ifndef HOSTS_C - -#include - -#define NR_SG 256 - -typedef struct { - FAS216_Info info; - - struct { - unsigned int term_port; - unsigned int terms; - } control; - - /* other info... */ - struct scatterlist sg[NR_SG]; /* Scatter DMA list */ -} PowerTecScsi_Info; - -#endif /* HOSTS_C */ - -#endif /* POWERTECSCSI_H */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acorn/scsi/queue.c linux.ac/drivers/acorn/scsi/queue.c --- linux.vanilla/drivers/acorn/scsi/queue.c Sat Oct 28 16:15:48 2000 +++ linux.ac/drivers/acorn/scsi/queue.c Sun Dec 31 14:57:10 2000 @@ -21,6 +21,7 @@ #include #include #include +#include #include "../../scsi/scsi.h" @@ -295,12 +296,12 @@ EXPORT_SYMBOL(queue_probetgtlun); #ifdef MODULE -int init_module (void) +int __init init_module (void) { return 0; } -void cleanup_module (void) +void __exit cleanup_module (void) { } #endif diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acpi/hardware/hwcpu32.c linux.ac/drivers/acpi/hardware/hwcpu32.c --- linux.vanilla/drivers/acpi/hardware/hwcpu32.c Sun Dec 31 19:41:44 2000 +++ linux.ac/drivers/acpi/hardware/hwcpu32.c Mon Jan 1 17:22:07 2001 @@ -708,4 +708,4 @@ return; } - \ No newline at end of file + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/acpi/namespace/nsxfobj.c linux.ac/drivers/acpi/namespace/nsxfobj.c --- linux.vanilla/drivers/acpi/namespace/nsxfobj.c Sun Dec 31 19:41:45 2000 +++ linux.ac/drivers/acpi/namespace/nsxfobj.c Mon Jan 1 17:22:07 2001 @@ -694,4 +694,5 @@ acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); return (status); -} \ No newline at end of file +} + diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/block/Makefile linux.ac/drivers/block/Makefile --- linux.vanilla/drivers/block/Makefile Sun Dec 31 19:41:47 2000 +++ linux.ac/drivers/block/Makefile Sun Dec 31 22:30:22 2000 @@ -10,6 +10,8 @@ O_TARGET := block.o +mod-subdirs := paride + export-objs := ll_rw_blk.o blkpg.o loop.o DAC960.o obj-y := ll_rw_blk.o blkpg.o genhd.o elevator.o @@ -27,7 +29,7 @@ obj-$(CONFIG_BLK_DEV_PS2) += ps2esdi.o obj-$(CONFIG_BLK_DEV_XD) += xd.o obj-$(CONFIG_BLK_CPQ_DA) += cpqarray.o -obj-$(CONFIG_BLK_CPQ_CISS_DA) += cciss.o +obj-$(CONFIG_BLK_CPQ_CISS_DA) += cciss.o obj-$(CONFIG_BLK_DEV_DAC960) += DAC960.o obj-$(CONFIG_BLK_DEV_NBD) += nbd.o diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/block/cpqarray.c linux.ac/drivers/block/cpqarray.c --- linux.vanilla/drivers/block/cpqarray.c Mon Nov 20 15:11:57 2000 +++ linux.ac/drivers/block/cpqarray.c Mon Nov 20 15:21:15 2000 @@ -103,7 +103,9 @@ static int * ida_hardsizes; static struct gendisk ida_gendisk[MAX_CTLR]; +#ifdef CONFIG_PROC_FS static struct proc_dir_entry *proc_array; +#endif /* Debug... */ #define DBG(s) do { s } while(0) @@ -173,10 +175,6 @@ #ifdef CONFIG_PROC_FS static void ida_procinit(int i); static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data); -#else -static void ida_procinit(int i) {} -static int ida_proc_get_info(char *buffer, char **start, off_t offset, - int length, int *eof, void *data) { return 0;} #endif static void ida_geninit(int ctlr) @@ -495,8 +493,9 @@ hba[i]->access.set_intr_mask(hba[i], FIFO_NOT_EMPTY); - +#ifdef CONFIG_PROC_FS ida_procinit(i); +#endif blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR + i), request_fns[i]); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/block/genhd.c linux.ac/drivers/block/genhd.c --- linux.vanilla/drivers/block/genhd.c Sat Oct 28 16:15:51 2000 +++ linux.ac/drivers/block/genhd.c Mon Dec 18 21:16:54 2000 @@ -23,6 +23,9 @@ #ifdef CONFIG_BLK_DEV_DAC960 extern void DAC960_Initialize(void); #endif +#ifdef CONFIG_FUSION_BOOT +extern int fusion_init(void); +#endif extern int net_dev_init(void); extern void console_map_init(void); extern int soc_probe(void); @@ -44,6 +47,9 @@ #endif #ifdef CONFIG_BLK_DEV_DAC960 DAC960_Initialize(); +#endif +#ifdef CONFIG_FUSION_BOOT + fusion_init(); #endif #ifdef CONFIG_FC4_SOC /* This has to be done before scsi_dev_init */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/block/rd.c linux.ac/drivers/block/rd.c --- linux.vanilla/drivers/block/rd.c Mon Nov 20 15:11:57 2000 +++ linux.ac/drivers/block/rd.c Thu Nov 23 11:40:45 2000 @@ -466,7 +466,7 @@ * romfs * gzip */ -int __init +static int __init identify_ramdisk_image(kdev_t device, struct file *fp, int start_block) { const int size = 512; @@ -690,6 +690,7 @@ done: if (infile.f_op->release) infile.f_op->release(inode, &infile); + blkdev_put(out_inode->i_bdev, BDEV_FILE); set_fs(fs); return; free_inodes: /* free inodes on error */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/console.c linux.ac/drivers/char/console.c --- linux.vanilla/drivers/char/console.c Mon Nov 20 15:11:58 2000 +++ linux.ac/drivers/char/console.c Sun Dec 31 15:24:51 2000 @@ -103,8 +103,6 @@ #include #include -#include - #include "console_macros.h" diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/drm/Makefile linux.ac/drivers/char/drm/Makefile --- linux.vanilla/drivers/char/drm/Makefile Sun Dec 31 19:41:47 2000 +++ linux.ac/drivers/char/drm/Makefile Mon Jan 1 17:24:15 2001 @@ -55,13 +55,23 @@ # When linking into the kernel, link the library just once. # If making modules, we include the library into each module +lib-objs-mod := $(patsubst %.o,%-mod.o,$(lib-objs)) +obj-m += $(lib-objs-mod) + ifdef MAKING_MODULES - lib = drmlib.a + lib = drmlib-mod.a else obj-y += drmlib.a endif include $(TOPDIR)/Rules.make + +$(patsubst %.o,%.c,$(lib-objs-mod)): + @ln -sf $(subst -mod,,$@) $@ + +drmlib-mod.a: $(lib-objs-mod) + rm -f $@ + $(AR) $(EXTRA_ARFLAGS) rcs $@ $(lib-objs-mod) drmlib.a: $(lib-objs) rm -f $@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/keyboard.c linux.ac/drivers/char/keyboard.c --- linux.vanilla/drivers/char/keyboard.c Tue Oct 31 20:26:02 2000 +++ linux.ac/drivers/char/keyboard.c Mon Dec 11 00:53:13 2000 @@ -322,7 +322,7 @@ compute_shiftstate(); kbd->slockstate = 0; /* play it safe */ #else - keysym = U(plain_map[keycode]); + keysym = U(key_maps[0][keycode]); type = KTYP(keysym); if (type == KT_SHIFT) (*key_handler[type])(keysym & 0xff, up_flag); @@ -750,7 +750,7 @@ k = i*BITS_PER_LONG; for(j=0; j