## Automatically generated incremental diff ## From: linux-2.4.21-bk37 ## To: linux-2.4.21-bk38 ## Robot: $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $ diff -urN linux-2.4.21-bk37/Documentation/Configure.help linux-2.4.21-bk38/Documentation/Configure.help --- linux-2.4.21-bk37/Documentation/Configure.help 2003-08-24 02:55:48.000000000 -0700 +++ linux-2.4.21-bk38/Documentation/Configure.help 2003-08-24 02:55:57.000000000 -0700 @@ -467,6 +467,18 @@ "real" root file system, etc. See for details. +Embed root filesystem ramdisk into the kernel +CONFIG_EMBEDDED_RAMDISK + Select this option if you want to build the ramdisk image into the + the final kernel binary. + +Filename of gziped ramdisk image +CONFIG_EMBEDDED_RAMDISK_IMAGE + This is the filename of the ramdisk image to be built into the + kernel. Relative pathnames are relative to arch/mips/ramdisk/. + The ramdisk image is not part of the kernel distribution; you must + provide one yourself. + Loopback device support CONFIG_BLK_DEV_LOOP Saying Y here will allow you to use a regular file as a block @@ -1474,6 +1486,11 @@ to transfer data to and from memory. Saying Y is safe and improves performance. +Broadcom SiByte onboard IDE support +CONFIG_BLK_DEV_IDE_SIBYTE + Include the driver for on-board IDE on the SiByte Generic Bus. Note + that this limits the number of IDE devices to 4 (ide0...ide3). + Use DMA by default CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO This option allows the driver for the built-in IDE controller on @@ -2095,6 +2112,78 @@ This enables support for the VR5000-based MIPS Malta evaluation board. +# Choice: bcmboard +Support for Broadcom SiByte boards +CONFIG_SIBYTE_SWARM + Enable support for boards based on the Broadcom SiByte family: + + BCM91250A-SWARM BCM1250 ATX size Eval Board (BCM91250A-SWARM) + + BCM91250E-Sentosa BCM1250 PCI card Eval Board (BCM91250E-Sentosa) + + BCM91125E-Rhone BCM1125 PCI card Eval Board (BCM91125E-Rhone) + + Other Non-Broadcom SiByte-based platform + +# Choice: bcmsoc +Support for Broadcom BCM1xxx SOCs +CONFIG_SIBYTE_SB1250 + + BCM1250 Dual-CPU SB1 with PCI and HyperTransport. + + BCM1120 Uniprocessor SB1. + + BCM1125 Uniprocessor SB1 with PCI (and HyperTransport for 1125H). + +BCM1250 Stepping +CONFIG_CPU_SB1_PASS_1 + Which pass of the SOC is supported (see the "system_revision" + register in the User Manual for more discussion of revisions): + + Pass1 1250 "Pass 1" + + An 1250 "Pass 2" + + Bn 1250 "Pass 2.2" + + Cn 1250 "Pass 3" + +BCM112x Stepping +CONFIG_CPU_SB1_PASS_2 + Which pass of the SOC is supported (see the "system_revision" + register in the User Manual for more discussion of revisions): + + Hybrid 1250 "Pass 2" + + An 112x "Pass 1" + +Booting from CFE +CONFIG_SIBYTE_CFE + Make use of the CFE API for enumerating available memory, + controlling secondary CPUs, and possibly console output. + +Use firmware console +CONFIG_SIBYTE_CFE_CONSOLE + Use the CFE API's console write routines during boot. Other console + options (VT console, sb1250 duart console, etc.) should not be + configured. + +Support for Bus Watcher statistics +CONFIG_SIBYTE_BUS_WATCHER + Handle and keep statistics on the bus error interrupts (COR_ECC, + BAD_ECC, IO_BUS). + +Corelis Debugger +CONFIG_SB1XXX_CORELIS + Select compile flags that produce code that can be processed by the + Corelis mksym utility and UDB Emulator. + +DMA for page clear and copy +CONFIG_SIBYTE_DMA_PAGEOPS + Instead of using the CPU to zero and copy pages, use a Data Mover + channel. These DMA channels are otherwise unused by the standard + SiByte Linux port. Seems to give a small performance benefit. + Support for Galileo Evaluation board or CoSine Orion CONFIG_ORION Say Y if configuring for the Galileo evaluation board @@ -2164,11 +2253,6 @@ 4000, Acer PICA, Olivetti M700-10 and a few other identical OEM systems. -MIPS GT96100 support -CONFIG_MIPS_GT96100 - Say Y here to support the Galileo Technology GT96100 communications - controller card. There is a web page at . - MIPS GT96100 Ethernet support CONFIG_MIPS_GT96100ETH Say Y here to support the Ethernet subsystem on your GT96100 card. @@ -2181,16 +2265,31 @@ workstations). Say Y here to make sure it gets initialized correctly before the Linux kernel tries to talk to the controller. -Kernel floating-point instruction emulation -CONFIG_MIPS_FPU_EMULATOR - This option enables the MIPS software floating support. Due to - the way floating point works you should always enable this option - unless you exactly know what you're doing. - SGI PROM Console Support CONFIG_SGI_PROM_CONSOLE Say Y here to set up the boot console on serial port 0. +DECstation serial support +CONFIG_SERIAL_DEC + This selects whether you want to be asked about drivers for + DECstation serial ports. + + Note that the answer to this question won't directly affect the + kernel: saying N will just cause the configurator to skip all + the questions about DECstation serial ports. + + If unsure, say Y. + +Support for console on a DECstation serial port +CONFIG_SERIAL_DEC_CONSOLE + If you say Y here, it will be possible to use a serial port as the + system console (the system console is the device which receives all + kernel messages and warnings and which allows logins in single user + mode). Note that the firmware uses ttyS0 as the serial console on + the Maxine and ttyS2 on the others. + + If unsure, say Y. + DZ11 Serial Support CONFIG_DZ DZ11-family serial controllers for VAXstations, including the @@ -2310,6 +2409,8 @@ R10000 MIPS Technologies R10000-series processors. + SB1 Broadcom SiByte SB1 processor. + R6000 CONFIG_CPU_R6000 MIPS Technologies R6000-series processors, including the 64474, @@ -2340,6 +2441,10 @@ CONFIG_CPU_R10000 MIPS Technologies R10000-series processors. +SB1 +CONFIG_CPU_SB1 + Broadcom SiByte SB1 processor. + Discontiguous Memory Support CONFIG_DISCONTIGMEM Say Y to support efficient handling of discontiguous physical memory, @@ -3448,18 +3553,11 @@ servicing. Say Y here to enable the serial driver to take advantage of those special I/O ports. -SGI Zilog85C30 serial support -CONFIG_SGI_SERIAL - If you want to use your SGI's built-in serial ports under Linux, +SGI IP22 Zilog85C30 serial support +CONFIG_IP22_SERIAL + If you want to use your IP22's built-in serial ports under Linux, answer Y. -SGI Newport Graphics support -CONFIG_SGI_NEWPORT_GFX - If you have an SGI machine and you want to compile the graphics - drivers, say Y here. This will include the code for the - /dev/graphics and /dev/gfx drivers into the kernel for supporting - virtualized access to your graphics hardware. - SGI Newport Console support CONFIG_SGI_NEWPORT_CONSOLE Say Y here if you want the console on the Newport aka XL graphics @@ -4001,6 +4099,11 @@ "Bridge" is the name used for the hardware inside your computer that PCMCIA cards are plugged into. If unsure, say N. +CONFIG_PCMCIA_SIBYTE + Say Y here to include support for the SiByte SOC's built-in PCMCIA + interface. Only ATA cards and CompactFlash are currently + supported. + System V IPC CONFIG_SYSVIPC Inter Process Communication is a suite of library functions and @@ -4521,21 +4624,20 @@ Maxine (Personal DECstation) onboard framebuffer support CONFIG_FB_MAXINE - Say Y here to directly support the on-board framebuffer in the - Maxine (5000/20, /25, /33) version of the DECstation. There is a - page dedicated to Linux on DECstations at . + Support for the onboard framebuffer (1024x768x8) in the Personal + DECstation series (Personal DECstation 5000/20, /25, /33, /50, + Codename "Maxine"). PMAG-BA TURBOchannel framebuffer support CONFIG_FB_PMAG_BA - Say Y here to directly support the on-board PMAG-BA framebuffer in - the 5000/1xx versions of the DECstation. There is a page dedicated - to Linux on DECstations at . + Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8) + used mainly in the MIPS-based DECstation series. PMAGB-B TURBOchannel framebuffer support CONFIG_FB_PMAGB_B - Say Y here to directly support the on-board PMAGB-B framebuffer in - the 5000/1xx versions of the DECstation. There is a page dedicated - to Linux on DECstations at . + Support for the PMAGB-B TURBOchannel framebuffer card used mainly + in the MIPS-based DECstation series. The card is currently only + supported in 1280x1024x8 mode. FutureTV PCI card CONFIG_ARCH_FTVPCI @@ -13703,6 +13805,18 @@ . The module will be called slram.o +DEC MS02-NV NVRAM module support +CONFIG_MTD_MS02NV + This is a MTD driver for the DEC's MS02-NV (54-20948-01) battery + backed-up NVRAM module. The module was originally meant as an NFS + accelerator. Say Y here if you have a DECstation 5000/2x0 or a + DECsystem 5900 equipped with such a module. + + If you want to compile this driver as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read . The module will + be called ms02-nv.o. + Debugging RAM test driver CONFIG_MTD_MTDRAM This enables a test MTD device driver which uses vmalloc() to @@ -18114,6 +18228,16 @@ . The module will be called i2c-adap-ite.o. +SiByte I2C Algorithm +CONFIG_I2C_ALGO_SIBYTE + Supports the SiByte SOC on-chip I2C interfaces (2 channels). + +MAX1617 Temperature Sensor +CONFIG_I2C_MAX1617 + This builds a simple polling driver for the Maxim 1617 temperature + sensor. Currently the device is only supported on a SiByte I2C + adapter, and the driver prints status updates to the system log. + I2C device interface CONFIG_I2C_CHARDEV Say Y here to use i2c-* device files, usually found in the /dev @@ -19503,6 +19627,17 @@ The module is called rtc.o. If you want to compile it as a module, say M here and read . +Generic MIPS RTC Support +CONFIG_MIPS_RTC + + If your machine is a MIPS machine, this option provides a simple, + generic RTC driver for /dev/rtc device. It only implements two IOCTL + operations of the standard PC RTC driver: RTC_RD_TIME and RTC_SET_TIME. + It is sufficient to run hwclock program. + + You should say Y here if there is no machine-specific RTC driver for your + MIPS machine but you do want a simple RTC driver for your RTC device. + Generic Real Time Clock Support CONFIG_GEN_RTC If you say Y here and create a character special file /dev/rtc with @@ -20253,6 +20388,14 @@ See for more information on configuring this card. +Support for Crystal CS4297a on SiByte syncser +CONFIG_SOUND_BCM_CS4297A + The BCM91250A has a Crystal CS4297a on synchronous serial port B (in + addition to the DB-9 serial port). Say Y or M here to enable the + sound chip instead of the UART. Also note that CONFIG_KGDB should + not be enabled at the same time, since it also attempts to use this + UART port. + Support for Yamaha OPL3-SA2 and SA3 based PnP cards CONFIG_SOUND_OPL3SA2 Say Y or M if you have a card based on one of these Yamaha sound @@ -20855,6 +20998,23 @@ compatibility. Since all software available for Linux/MIPS is currently 32-bit you should say Y here. +Kernel support for o32 binaries +CONFIG_MIPS32_O32 + Select this option if you want to run o32 binaries. These are pure + 32-bit binaries as used by the 32-bit Linux/MIPS port. Most of + existing binaries are in this format. + + If unsure, say Y. + +Kernel support for n32 binaries +CONFIG_MIPS32_N32 + Select this option if you want to run n32 binaries. These are + 64-bit binaries using 32-bit quantities for addressing and certain + data that would normally be 64-bit. They are used in special + cases. + + If unsure, say N. + Build fp exception handler module CONFIG_MIPS_FPE_MODULE Build the floating point exception handler module. This option is @@ -20923,19 +21083,12 @@ Palm PCs from Philips (INCOMPLETE). Model-300/301/302/319 -Low-level debugging -CONFIG_LL_DEBUG - Enable low-level debugging assertion macros in the kernel code. - Currently used only by the time services code in the MIPS port. - Don't turn this on unless you know what you are doing. - -Remote GDB kernel debugging -CONFIG_REMOTE_DEBUG - If you say Y here, it will be possible to remotely debug the MIPS - kernel using gdb. This enlarges your kernel image disk size by - several megabytes and requires a machine with more than 16 MB, - better 32 MB RAM to avoid excessive linking time. This is only - useful for kernel hackers. If unsure, say N. +Enable run-time debugging +CONFIG_RUNTIME_DEBUG + If you say Y here, some debugging macros will do run-time checking. + If you say N here, those macros will mostly turn to no-ops. Currently + supported by MIPS arch. See include/asm-mips/debug.h for debuging macros. + If unsure, say N. Run uncached CONFIG_MIPS_UNCACHED @@ -23919,6 +24072,12 @@ Check out and for more information. +Philips SAA7114H for SiByte BCM91250A +CONFIG_VIDEO_SWARM_7114H + Say Y or M to build the video4linux driver for the Philips SAA7114H + video decoder on Broadcom SWARM board (BCM91250A). The decoder chip + is on the BCM1250's "E2" 8-bit FIFO port. + CPiA Video For Linux CONFIG_VIDEO_CPIA This is the video4linux driver for cameras based on Vision's CPiA diff -urN linux-2.4.21-bk37/Documentation/mips/time.README linux-2.4.21-bk38/Documentation/mips/time.README --- linux-2.4.21-bk37/Documentation/mips/time.README 2001-04-20 16:23:12.000000000 -0700 +++ linux-2.4.21-bk38/Documentation/mips/time.README 2003-08-24 02:55:57.000000000 -0700 @@ -103,9 +103,9 @@ Do you plan to use the CPU counter register as the timer interrupt or use an exnternal timer? - In order to CPU counter register as the timer interrupt source, you must - know the counter speed (mips_counter_frequency). It is usually the - same as the CPU speed (Or it is ALWAYS the same?) + In order to use CPU counter register as the timer interrupt source, you + must know the counter speed (mips_counter_frequency). It is usually the + same as the CPU speed or an integral divisor of it. d) decide on whether you want to use high-level or low-level timer interrupt routines. The low-level one is presumably faster, but should @@ -154,8 +154,45 @@ for some of the functions in time.c. For example, you may define your own timer interrupt routine, which does -its own processing and in turn calls timer_interrupt(). +some of its own processing and then calls timer_interrupt(). You can also over-ride any of the built-in functions (gettimeoffset, RTC routines and/or timer interrupt routine). + +PORTING NOTES FOR SMP +---------------------- + +If you have a SMP box, things are slightly more complicated. + +The time service running every jiffy is logically divided into two parts: + + 1) the one for the whole system (defined in timer_interrupt()) + 2) the one that should run for each CPU (defined in local_timer_interrupt()) + +You need to decide on your timer interrupt sources. + + case 1) - whole system has only one timer interrupt delivered to one CPU + + In this case, you set up timer interrupt as in UP systems. In addtion, + you need to set emulate_local_timer_interrupt to 1 so that other + CPUs get to call local_timer_interrupt(). + + THIS IS CURRENTLY NOT IMPLEMNETED. However, it is rather easy to write + one should such a need arise. You simply make a IPI call. + + case 2) - each CPU has a separate timer interrupt + + In this case, you need to set up IRQ such that each of them will + call local_timer_interrupt(). In addition, you need to arrange + one and only one of them to call timer_interrupt(). + + You can also do the low-level version of those interrupt routines, + following similar dispatching routes described above. + +Note about do_gettimeoffset(): + + It is very likely the CPU counter registers are not sync'ed up in a SMP box. + Therefore you cannot really use the many of the existing routines that + are based on CPU counter. You should wirte your own gettimeoffset rouinte + if you want intra-jiffy resolution. diff -urN linux-2.4.21-bk37/Makefile linux-2.4.21-bk38/Makefile --- linux-2.4.21-bk37/Makefile 2003-08-24 02:55:48.000000000 -0700 +++ linux-2.4.21-bk38/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 21 -EXTRAVERSION = -bk37 +EXTRAVERSION = -bk38 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -urN linux-2.4.21-bk37/arch/mips/Makefile linux-2.4.21-bk38/arch/mips/Makefile --- linux-2.4.21-bk37/arch/mips/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -18,14 +18,19 @@ # ifdef CONFIG_CPU_LITTLE_ENDIAN tool-prefix = mipsel-linux- +ld-emul = elf32ltsmip else tool-prefix = mips-linux- +ld-emul = elf32btsmip endif ifdef CONFIG_CROSSCOMPILE CROSS_COMPILE = $(tool-prefix) endif +check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) + +# # # GCC uses -G 0 -mabicalls -fpic as default. We don't want PIC in the kernel # code since it only slows down the whole thing. At some point we might make @@ -38,14 +43,17 @@ # GCCFLAGS := -I $(TOPDIR)/include/asm/gcc GCCFLAGS += -G 0 -mno-abicalls -fno-pic -pipe +GCCFLAGS += $(call check_gcc, -mabi=32,) LINKFLAGS += -G 0 -static # -N MODFLAGS += -mlong-calls -ifdef CONFIG_REMOTE_DEBUG +ifdef CONFIG_KGDB GCCFLAGS += -g +ifdef CONFIG_SB1XXX_CORELIS +GCCFLAGS += -mno-sched-prolog -fno-omit-frame-pointer +endif endif -# # CPU-dependent compiler/assembler options for optimization. # ifdef CONFIG_CPU_R3000 @@ -86,10 +94,12 @@ GCCFLAGS += -mcpu=r5000 -mips2 -Wa,--trap endif ifdef CONFIG_CPU_RM7000 -GCCFLAGS += -mcpu=r5000 -mips2 -Wa,--trap +GCCFLAGS += $(call check_gcc, -march=rm7000, -mcpu=r5000) \ + -mips2 -Wa,--trap endif ifdef CONFIG_CPU_SB1 -GCCFLAGS += -mcpu=sb1 -mips2 -Wa,--trap +GCCFLAGS += $(call check_gcc, -mcpu=sb1, -mcpu=r5000) \ + -mips2 -Wa,--trap ifdef CONFIG_SB1_PASS_1_WORKAROUNDS MODFLAGS += -msb1-pass1-workarounds endif @@ -97,6 +107,7 @@ AFLAGS += $(GCCFLAGS) CFLAGS += $(GCCFLAGS) +LDFLAGS += -m $(ld-emul) # @@ -161,6 +172,63 @@ endif # +# Au1x00 (AMD/Alchemy) eval boards +# +ifdef CONFIG_MIPS_DB1000 +LIBS += arch/mips/au1000/db1x00/db1x00.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/db1x00 arch/mips/au1000/common +LOADADDR += 0x80100000 +endif + +ifdef CONFIG_MIPS_DB1500 +LIBS += arch/mips/au1000/db1x00/db1x00.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/db1x00 arch/mips/au1000/common +LOADADDR += 0x80100000 +endif + +ifdef CONFIG_MIPS_DB1100 +LIBS += arch/mips/au1000/db1x00/db1x00.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/db1x00 arch/mips/au1000/common +LOADADDR += 0x80100000 +endif + +ifdef CONFIG_MIPS_BOSPORUS +LIBS += arch/mips/au1000/db1x00/db1x00.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/db1x00 arch/mips/au1000/common +LOADADDR += 0x80100000 +endif + +ifdef CONFIG_MIPS_MIRAGE +LIBS += arch/mips/au1000/db1x00/db1x00.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/db1x00 arch/mips/au1000/common +LOADADDR += 0x80100000 +endif + +ifdef CONFIG_MIPS_XXS1500 +LIBS += arch/mips/au1000/xxs1500/xxs1500.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/xxs1500 arch/mips/au1000/common +LOADADDR += 0x80100000 +endif + +ifdef CONFIG_MIPS_MTX1 +LIBS += arch/mips/au1000/mtx-1/mtx-1.o \ + arch/mips/au1000/common/au1000.o +SUBDIRS += arch/mips/au1000/mtx-1 arch/mips/au1000/common +LOADADDR += 0x80100000 +endif + +ifdef CONFIG_PCI +CORE_FILES += arch/mips/pci/pci-core.o +SUBDIRS += arch/mips/pci +endif + +# # Algorithmics P4032 # ifdef CONFIG_ALGOR_P4032 @@ -201,8 +269,9 @@ # Galileo EV64120 Board # ifdef CONFIG_MIPS_EV64120 -LIBS += arch/mips/galileo-boards/ev64120/ev64120.o -SUBDIRS += arch/mips/galileo-boards/ev64120 +LIBS += arch/mips/gt64120/common/gt64120.o \ + arch/mips/gt64120/ev64120/ev64120.o +SUBDIRS += arch/mips/gt64120/common arch/mips/gt64120/ev64120 LOADADDR := 0x80100000 endif @@ -210,10 +279,8 @@ # Galileo EV96100 Board # ifdef CONFIG_MIPS_EV96100 -LIBS += arch/mips/galileo-boards/ev96100/ev96100.o \ - arch/mips/galileo-boards/generic/galboards.o -SUBDIRS += arch/mips/galileo-boards/generic \ - arch/mips/galileo-boards/ev96100 +LIBS += arch/mips/galileo-boards/ev96100/ev96100.o +SUBDIRS += arch/mips/galileo-boards/ev96100 LOADADDR := 0x80100000 endif @@ -300,6 +367,17 @@ endif # +# Momentum Ocelot-C and -CS boards +# +ifdef CONFIG_MOMENCO_OCELOT_C +# The Ocelot-C[S] setup.o must be linked early - it does the ioremap() for the +# mips_io_port_base. +CORE_FILES += arch/mips/momentum/ocelot_c/ocelot_c.o +SUBDIRS += arch/mips/momentum/ocelot_c +LOADADDR := 0x80100000 +endif + +# # NEC DDB Vrc-5074 # ifdef CONFIG_DDB5074 @@ -328,6 +406,11 @@ LOADADDR := 0x80100000 endif +ifdef CONFIG_LASAT +LIBS += arch/mips/lasat/lasatkern.o +SUBDIRS += arch/mips/lasat +LOADADDR += 0x80000000 +endif # # NEC Osprey (vr4181) board # @@ -344,7 +427,7 @@ ifdef CONFIG_NEC_EAGLE SUBDIRS += arch/mips/vr41xx/common \ arch/mips/vr41xx/nec-eagle -LIBS += arch/mips/vr41xx/common/vr41xx.o \ +CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \ arch/mips/vr41xx/nec-eagle/eagle.o LOADADDR := 0x80000000 endif @@ -355,12 +438,67 @@ ifdef CONFIG_ZAO_CAPCELLA SUBDIRS += arch/mips/vr41xx/common \ arch/mips/vr41xx/zao-capcella -LIBS += arch/mips/vr41xx/common/vr41xx.o \ +CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \ arch/mips/vr41xx/zao-capcella/capcella.o LOADADDR := 0x80000000 endif # +# Victor MP-C303/304 (VR4122) +# +ifdef CONFIG_VICTOR_MPC30X +SUBDIRS += arch/mips/vr41xx/common \ + arch/mips/vr41xx/victor-mpc30x +CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \ + arch/mips/vr41xx/victor-mpc30x/mpc30x.o +LOADADDR := 0x80001000 +endif + +# +# IBM WorkPad z50 (VR4121) +# +ifdef CONFIG_IBM_WORKPAD +SUBDIRS += arch/mips/vr41xx/common \ + arch/mips/vr41xx/ibm-workpad +CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \ + arch/mips/vr41xx/ibm-workpad/workpad.o +LOADADDR += 0x80004000 +endif + +# +# CASIO CASSIPEIA E-55/65 (VR4111) +# +ifdef CONFIG_CASIO_E55 +SUBDIRS += arch/mips/vr41xx/common \ + arch/mips/vr41xx/casio-e55 +CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \ + arch/mips/vr41xx/casio-e55/e55.o +LOADADDR += 0x80004000 +endif + +# +# TANBAC TB0226 Mbase (VR4131) +# +ifdef CONFIG_TANBAC_TB0226 +SUBDIRS += arch/mips/vr41xx/common \ + arch/mips/vr41xx/tanbac-tb0226 +CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \ + arch/mips/vr41xx/tanbac-tb0226/tb0226.o +LOADADDR := 0x80000000 +endif + +# +# TANBAC TB0229 (VR4131DIMM) +# +ifdef CONFIG_TANBAC_TB0229 +SUBDIRS += arch/mips/vr41xx/common \ + arch/mips/vr41xx/tanbac-tb0229 +CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \ + arch/mips/vr41xx/tanbac-tb0229/tb0229.o +LOADADDR := 0x80000000 +endif + +# # Philips Nino # ifdef CONFIG_NINO @@ -385,23 +523,30 @@ endif # -# Sibyte SB1250 SOC +# Sibyte SB1250 SOC and Broadcom (SiByte) BCM112x SOCs # -ifdef CONFIG_SIBYTE_SB1250 +ifneq ($(CONFIG_SIBYTE_SB1250)$(CONFIG_SIBYTE_BCM112X),) # This is a LIB so that it links at the end, and initcalls are later # the sequence; but it is built as an object so that modules don't get # removed (as happens, even if they have __initcall/module_init) LIBS += arch/mips/sibyte/sb1250/sb1250.o SUBDIRS += arch/mips/sibyte/sb1250 +LOADADDR := 0x80100000 endif # -# Sibyte SWARM board +# Sibyte boards: # -ifdef CONFIG_SIBYTE_SWARM +# BCM91250A (SWARM), +# BCM91250E (Sentosa), +# BCM91120C (CRhine), +# BCM91120x (Carmel), +# BCM91125C (CRhone), +# BCM91125E (Rhone). +# +ifdef CONFIG_SIBYTE_BOARD LIBS += arch/mips/sibyte/swarm/sbswarm.a SUBDIRS += arch/mips/sibyte/swarm -LOADADDR := 0x80100000 endif # @@ -413,14 +558,6 @@ endif # -# SB1 Cache Error handler -# -ifdef CONFIG_SB1_CACHE_ERROR -LIBS += arch/mips/sibyte/sb1/sb1kern.a -SUBDIRS += arch/mips/sibyte/sb1 -endif - -# # SNI RM200 PCI # ifdef CONFIG_SNI_RM200_PCI @@ -440,6 +577,19 @@ LOADADDR := 0x80050000 endif +# +# Toshiba RBTX4927 board or +# Toshiba RBTX4937 board +# +ifdef CONFIG_TOSHIBA_RBTX4927 +MIPS = arch/mips +CEC = tx4927 +COMMON = $(MIPS)/$(CEC)/common +BOARD = $(MIPS)/$(CEC)/toshiba_rbtx4927 +LIBS += $(BOARD)/toshiba_rbtx4927.o $(COMMON)/tx4927.o +SUBDIRS += $(BOARD) $(COMMON) +LOADADDR += 0x80020000 +endif # # Choosing incompatible machines durings configuration will result in @@ -468,12 +618,15 @@ endif ifdef CONFIG_MIPS_EV64120 -GALILEOBOOT = $(MAKE) -C arch/$(ARCH)/galileo-boards/ev64120 - gboot: vmlinux $(MAKE) -C arch/$(ARCH)/galileo-boards/ev64120/compressed endif +ifdef CONFIG_LASAT +rom.bin rom.sw: vmlinux + $(MAKE) -C arch/$(ARCH)/lasat/image $@ +endif + MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot vmlinux.ecoff: vmlinux @@ -484,9 +637,11 @@ rm -f arch/$(ARCH)/ld.script $(MAKE) -C arch/$(ARCH)/tools clean $(MAKE) -C arch/mips/baget clean + $(MAKE) -C arch/mips/lasat clean archmrproper: @$(MAKEBOOT) mrproper + $(RM) $(TOPDIR)/include/asm-$(ARCH)/offset.h $(MAKE) -C arch/$(ARCH)/tools mrproper archdep: diff -urN linux-2.4.21-bk37/arch/mips/algor/README linux-2.4.21-bk38/arch/mips/algor/README --- linux-2.4.21-bk37/arch/mips/algor/README 1999-06-25 17:40:12.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/algor/README 1969-12-31 16:00:00.000000000 -0800 @@ -1,5 +0,0 @@ -The code for the Algorithmics P4032 evaluation board is currently under -development. I'll release it when it's up to the same strength as -the other ports. - - Ralf diff -urN linux-2.4.21-bk37/arch/mips/arc/Makefile linux-2.4.21-bk38/arch/mips/arc/Makefile --- linux-2.4.21-bk37/arch/mips/arc/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/arc/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -4,10 +4,11 @@ L_TARGET = arclib.a -obj-y += cmdline.o console.o env.o file.o \ - identify.o init.o misc.o time.o tree.o +obj-y += cmdline.o env.o file.o identify.o init.o \ + misc.o time.o tree.o obj-$(CONFIG_ARC_MEMORY) += memory.o obj-$(CONFIG_ARC_CONSOLE) += arc_con.o +obj-$(CONFIG_ARC_PROMLIB) += promlib.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/arc/arc_con.c linux-2.4.21-bk38/arch/mips/arc/arc_con.c --- linux-2.4.21-bk37/arch/mips/arc/arc_con.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/arc/arc_con.c 2003-08-24 02:55:57.000000000 -0700 @@ -32,19 +32,16 @@ static int __init prom_console_setup(struct console *co, char *options) { - if (prom_flags & PROM_FLAG_USE_AS_CONSOLE) - return 0; - else - return 1; + return !(prom_flags & PROM_FLAG_USE_AS_CONSOLE); } static struct console arc_cons = { - name: "ttyS", - write: prom_console_write, - device: prom_console_device, - setup: prom_console_setup, - flags: CON_PRINTBUFFER, - index: -1, + .name = "arc", + .write = prom_console_write, + .device = prom_console_device, + .setup = prom_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, }; /* diff -urN linux-2.4.21-bk37/arch/mips/arc/cmdline.c linux-2.4.21-bk38/arch/mips/arc/cmdline.c --- linux-2.4.21-bk37/arch/mips/arc/cmdline.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/arc/cmdline.c 2003-08-24 02:55:57.000000000 -0700 @@ -20,7 +20,7 @@ char * __init prom_getcmdline(void) { - return &(arcs_cmdline[0]); + return arcs_cmdline; } static char *ignored[] = { @@ -32,7 +32,6 @@ "OSLoadFilename=", "OSLoadOptions=" }; -#define NENTS(foo) ((sizeof((foo)) / (sizeof((foo[0]))))) static char *used_arc[][2] = { { "OSLoadPartition=", "root=" }, @@ -47,7 +46,7 @@ actr = 1; /* Always ignore argv[0] */ while (actr < prom_argc) { - for(i = 0; i < NENTS(used_arc); i++) { + for(i = 0; i < ARRAY_SIZE(used_arc); i++) { int len = strlen(used_arc[i][0]); if (!strncmp(prom_argv(actr), used_arc[i][0], len)) { @@ -71,7 +70,6 @@ return cp; } - void __init prom_init_cmdline(void) { char *cp; @@ -79,7 +77,7 @@ actr = 1; /* Always ignore argv[0] */ - cp = &(arcs_cmdline[0]); + cp = arcs_cmdline; /* * Move ARC variables to the beginning to make sure they can be * overridden by later arguments. @@ -87,7 +85,7 @@ cp = move_firmware_args(cp); while (actr < prom_argc) { - for (i = 0; i < NENTS(ignored); i++) { + for (i = 0; i < ARRAY_SIZE(ignored); i++) { int len = strlen(ignored[i]); if (!strncmp(prom_argv(actr), ignored[i], len)) @@ -101,11 +99,12 @@ pic_cont: actr++; } - if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + + if (cp != arcs_cmdline) /* get rid of trailing space */ --cp; *cp = '\0'; #ifdef DEBUG_CMDLINE - prom_printf("prom_init_cmdline: %s\n", &(arcs_cmdline[0])); + printk(KERN_DEBUG "prom cmdline: %s\n", arcs_cmdline); #endif } diff -urN linux-2.4.21-bk37/arch/mips/arc/console.c linux-2.4.21-bk38/arch/mips/arc/console.c --- linux-2.4.21-bk37/arch/mips/arc/console.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/arc/console.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,63 +0,0 @@ -/* - * 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. - * - * Copyright (C) 1996 David S. Miller (dm@sgi.com) - * Compability with board caches, Ulf Carlsson - */ -#include -#include -#include - -/* - * IP22 boardcache is not compatible with board caches. Thus we disable it - * during romvec action. Since r4xx0.c is always compiled and linked with your - * kernel, this shouldn't cause any harm regardless what MIPS processor you - * have. - * - * The ARC write and read functions seem to interfere with the serial lines - * in some way. You should be careful with them. - */ - -void prom_putchar(char c) -{ - ULONG cnt; - CHAR it = c; - - bc_disable(); - ArcWrite(1, &it, 1, &cnt); - bc_enable(); -} - -char prom_getchar(void) -{ - ULONG cnt; - CHAR c; - - bc_disable(); - ArcRead(0, &c, 1, &cnt); - bc_enable(); - - return c; -} - -void prom_printf(char *fmt, ...) -{ - va_list args; - char ppbuf[1024]; - char *bptr; - - va_start(args, fmt); - vsprintf(ppbuf, fmt, args); - - bptr = ppbuf; - - while (*bptr != 0) { - if (*bptr == '\n') - prom_putchar('\r'); - - prom_putchar(*bptr++); - } - va_end(args); -} diff -urN linux-2.4.21-bk37/arch/mips/arc/identify.c linux-2.4.21-bk38/arch/mips/arc/identify.c --- linux-2.4.21-bk37/arch/mips/arc/identify.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/arc/identify.c 2003-08-24 02:55:57.000000000 -0700 @@ -32,7 +32,7 @@ { "SGI-IP22", "SGI Indy", MACH_GROUP_SGI, - MACH_SGI_INDY, + MACH_SGI_IP22, PROM_FLAG_ARCS }, { "SGI-IP27", "SGI Origin", diff -urN linux-2.4.21-bk37/arch/mips/arc/promlib.c linux-2.4.21-bk38/arch/mips/arc/promlib.c --- linux-2.4.21-bk37/arch/mips/arc/promlib.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/arc/promlib.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,43 @@ +/* + * 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. + * + * Copyright (C) 1996 David S. Miller (dm@sgi.com) + * Compability with board caches, Ulf Carlsson + */ +#include +#include +#include + +/* + * IP22 boardcache is not compatible with board caches. Thus we disable it + * during romvec action. Since r4xx0.c is always compiled and linked with your + * kernel, this shouldn't cause any harm regardless what MIPS processor you + * have. + * + * The ARC write and read functions seem to interfere with the serial lines + * in some way. You should be careful with them. + */ + +void prom_putchar(char c) +{ + ULONG cnt; + CHAR it = c; + + bc_disable(); + ArcWrite(1, &it, 1, &cnt); + bc_enable(); +} + +char prom_getchar(void) +{ + ULONG cnt; + CHAR c; + + bc_disable(); + ArcRead(0, &c, 1, &cnt); + bc_enable(); + + return c; +} diff -urN linux-2.4.21-bk37/arch/mips/au1000/common/Makefile linux-2.4.21-bk38/arch/mips/au1000/common/Makefile --- linux-2.4.21-bk37/arch/mips/au1000/common/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/common/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -16,14 +16,14 @@ O_TARGET := au1000.o -export-objs = prom.o serial.o clocks.o power.o usbdev.o +export-objs = prom.o clocks.o power.o usbdev.o obj-y := prom.o int-handler.o dma.o irq.o puts.o time.o reset.o \ - clocks.o power.o usbdev.o + clocks.o power.o setup.o -obj-$(CONFIG_AU1000_UART) += serial.o -obj-$(CONFIG_AU1000_USB_DEVICE) += usbdev.o -obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o +obj-$(CONFIG_AU1X00_USB_DEVICE) += usbdev.o +obj-$(CONFIG_KGDB) += dbg_io.o obj-$(CONFIG_RTC) += rtc.o +obj-$(CONFIG_PCI) += pci_ops.o pci_fixup.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/au1000/common/clocks.c linux-2.4.21-bk38/arch/mips/au1000/common/clocks.c --- linux-2.4.21-bk37/arch/mips/au1000/common/clocks.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/common/clocks.c 2003-08-24 02:55:57.000000000 -0700 @@ -30,21 +30,21 @@ #include #include -static unsigned int au1000_clock; // Hz +static unsigned int au1x00_clock; // Hz static unsigned int lcd_clock; // KHz static unsigned long uart_baud_base; /* * Set the au1000_clock */ -void set_au1000_speed(unsigned int new_freq) +void set_au1x00_speed(unsigned int new_freq) { - au1000_clock = new_freq; + au1x00_clock = new_freq; } -unsigned int get_au1000_speed(void) +unsigned int get_au1x00_speed(void) { - return au1000_clock; + return au1x00_clock; } @@ -54,27 +54,27 @@ * we want to be able to use the same code on different * speed CPUs. */ -unsigned long get_au1000_uart_baud_base(void) +unsigned long get_au1x00_uart_baud_base(void) { return uart_baud_base; } -void set_au1000_uart_baud_base(unsigned long new_baud_base) +void set_au1x00_uart_baud_base(unsigned long new_baud_base) { uart_baud_base = new_baud_base; } /* - * Calculate the Au1000's LCD clock based on the current + * Calculate the Au1x00's LCD clock based on the current * cpu clock and the system bus clock, and try to keep it * below 40 MHz (the Pb1000 board can lock-up if the LCD * clock is over 40 MHz). */ -void set_au1000_lcd_clock(void) +void set_au1x00_lcd_clock(void) { unsigned int static_cfg0; unsigned int sys_busclk = - (get_au1000_speed()/1000) / + (get_au1x00_speed()/1000) / ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2); static_cfg0 = au_readl(MEM_STCFG0); @@ -90,9 +90,9 @@ lcd_clock); } -unsigned int get_au1000_lcd_clock(void) +unsigned int get_au1x00_lcd_clock(void) { return lcd_clock; } -EXPORT_SYMBOL(get_au1000_lcd_clock); +EXPORT_SYMBOL(get_au1x00_lcd_clock); diff -urN linux-2.4.21-bk37/arch/mips/au1000/common/dbg_io.c linux-2.4.21-bk38/arch/mips/au1000/common/dbg_io.c --- linux-2.4.21-bk37/arch/mips/au1000/common/dbg_io.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/common/dbg_io.c 2003-08-24 02:55:57.000000000 -0700 @@ -3,13 +3,13 @@ #include #include -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB /* * FIXME the user should be able to select the * uart to be used for debugging. */ -#define DEBUG_BASE UART2_ADDR +#define DEBUG_BASE UART_DEBUG_BASE /**/ /* we need uint32 uint8 */ @@ -56,7 +56,7 @@ #define UART16550_READ(y) (au_readl(DEBUG_BASE + y) & 0xff) #define UART16550_WRITE(y,z) (au_writel(z&0xff, DEBUG_BASE + y)) -extern unsigned long get_au1000_uart_baud_base(void); +extern unsigned long get_au1x00_uart_baud_base(void); extern unsigned long cal_r4koff(void); void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) @@ -75,7 +75,7 @@ uint32 divisor; /* set divisor */ - divisor = get_au1000_uart_baud_base() / baud; + divisor = get_au1x00_uart_baud_base() / baud; UART16550_WRITE(UART_CLK, divisor & 0xffff); } diff -urN linux-2.4.21-bk37/arch/mips/au1000/common/irq.c linux-2.4.21-bk38/arch/mips/au1000/common/irq.c --- linux-2.4.21-bk37/arch/mips/au1000/common/irq.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/common/irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -28,6 +28,7 @@ */ #include #include +#include #include #include #include @@ -46,15 +47,8 @@ #include #include #include - -#if defined(CONFIG_MIPS_PB1000) +#ifdef CONFIG_MIPS_PB1000 #include -#elif defined(CONFIG_MIPS_PB1500) -#include -#elif defined(CONFIG_MIPS_PB1100) -#include -#else -#error unsupported alchemy board #endif #undef DEBUG_IRQ @@ -71,7 +65,7 @@ #define EXT_INTC1_REQ1 5 /* IP 5 */ #define MIPS_TIMER_IP 7 /* IP 7 */ -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void breakpoint(void); #endif @@ -90,13 +84,13 @@ inline void local_enable_irq(unsigned int irq_nr); inline void local_disable_irq(unsigned int irq_nr); -extern unsigned int do_IRQ(int irq, struct pt_regs *regs); extern void __init init_generic_irq(void); #ifdef CONFIG_PM extern void counter0_irq(int irq, void *dev_id, struct pt_regs *regs); #endif +static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED; static void setup_local_irq(unsigned int irq_nr, int type, int int_req) { @@ -280,10 +274,6 @@ if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { local_enable_irq(irq_nr); } - else { - printk("warning: end_irq %d did not enable (%x)\n", - irq_nr, irq_desc[irq_nr].status); - } #if defined(CONFIG_MIPS_PB1000) if (irq_nr == AU1000_GPIO_15) { au_writel(0x4000, PB1000_MDR); /* enable int */ @@ -296,8 +286,8 @@ { int i; unsigned long flags, mask; - save_and_cli(flags); + spin_lock_irqsave(&irq_lock, flags); if (controller) { mask = au_readl(IC1_MASKSET); for (i=32; i<64; i++) { @@ -310,7 +300,8 @@ local_disable_irq(i); } } - restore_flags(flags); + spin_unlock_irqrestore(&irq_lock, flags); + return mask; } @@ -318,8 +309,8 @@ { int i; unsigned long flags, new_mask; - save_and_cli(flags); + spin_lock_irqsave(&irq_lock, flags); for (i=0; i<32; i++) { if (mask & (1<im_irq, imp->im_type, imp->im_request); - case AU1000_IRDA_TX_INT: - case AU1000_IRDA_RX_INT: + switch (imp->im_type) { - case AU1000_MAC0_DMA_INT: -#ifdef CONFIG_MIPS_PB1000 - case AU1000_MAC1_DMA_INT: -#endif -#ifdef CONFIG_MIPS_PB1500 - case AU1000_MAC1_DMA_INT: -#endif - case AU1500_GPIO_204: + case INTC_INT_HIGH_LEVEL: + irq_desc[imp->im_irq].handler = &level_irq_type; + break; - setup_local_irq(i, INTC_INT_HIGH_LEVEL, 0); - irq_desc[i].handler = &level_irq_type; - break; + case INTC_INT_LOW_LEVEL: + irq_desc[imp->im_irq].handler = &level_irq_type; + break; -#ifdef CONFIG_MIPS_PB1000 - case AU1000_GPIO_15: -#endif - case AU1000_USB_HOST_INT: -#ifdef CONFIG_MIPS_PB1500 - case AU1000_PCI_INTA: - case AU1000_PCI_INTB: - case AU1000_PCI_INTC: - case AU1000_PCI_INTD: - case AU1500_GPIO_201: - case AU1500_GPIO_202: - case AU1500_GPIO_203: - case AU1500_GPIO_205: - case AU1500_GPIO_207: -#endif + case INTC_INT_RISE_EDGE: + irq_desc[imp->im_irq].handler = &rise_edge_irq_type; + break; -#ifdef CONFIG_MIPS_PB1100 - case AU1000_GPIO_9: // PCMCIA Card Fully_Interted# - case AU1000_GPIO_10: // PCMCIA_STSCHG# - case AU1000_GPIO_11: // PCMCIA_IRQ# - case AU1000_GPIO_13: // DC_IRQ# - case AU1000_GPIO_23: // 2-wire SCL -#endif - setup_local_irq(i, INTC_INT_LOW_LEVEL, 0); - irq_desc[i].handler = &level_irq_type; - break; - case AU1000_ACSYNC_INT: - case AU1000_AC97C_INT: - case AU1000_TOY_INT: - case AU1000_TOY_MATCH0_INT: - case AU1000_TOY_MATCH1_INT: - case AU1000_USB_DEV_SUS_INT: - case AU1000_USB_DEV_REQ_INT: - case AU1000_RTC_INT: - case AU1000_RTC_MATCH0_INT: - case AU1000_RTC_MATCH1_INT: - case AU1000_RTC_MATCH2_INT: - setup_local_irq(i, INTC_INT_RISE_EDGE, 0); - irq_desc[i].handler = &rise_edge_irq_type; - break; - - // Careful if you change match 2 request! - // The interrupt handler is called directly - // from the low level dispatch code. - case AU1000_TOY_MATCH2_INT: - setup_local_irq(i, INTC_INT_RISE_EDGE, 1); - irq_desc[i].handler = &rise_edge_irq_type; - break; - default: /* active high, level interrupt */ - setup_local_irq(i, INTC_INT_HIGH_LEVEL, 0); - irq_desc[i].handler = &level_irq_type; - break; + default: + panic("Unknown au1xxx irq map"); + break; } + imp++; } - set_cp0_status(ALLINTS); -#ifdef CONFIG_REMOTE_DEBUG + set_c0_status(ALLINTS); +#ifdef CONFIG_KGDB /* If local serial I/O used for debug port, enter kgdb at once */ puts("Waiting for kgdb to connect..."); set_debug_traps(); @@ -508,7 +437,7 @@ void intc0_req0_irqdispatch(struct pt_regs *regs) { - int irq = 0, i; + int irq = 0; static unsigned long intc0_req0 = 0; intc0_req0 |= au_readl(IC0_REQ0INT); @@ -526,43 +455,33 @@ return; } - for (i=0; i<32; i++) { - if ((intc0_req0 & (1< + +#ifdef CONFIG_PCI + +#include +#include +#include +#include + +#include +//#include +#ifdef CONFIG_MIPS_PB1000 +#include +#endif + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +static void fixup_resource(int r_num, struct pci_dev *dev) ; +#ifdef CONFIG_SOC_AU1500 +static unsigned long virt_io_addr; +#endif + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ + /* will need to fixup IO resources */ +} + +void __init pcibios_fixup(void) +{ +#ifdef CONFIG_SOC_AU1500 + int i; + struct pci_dev *dev; + + virt_io_addr = (unsigned long)ioremap(Au1500_PCI_IO_START, + Au1500_PCI_IO_END - Au1500_PCI_IO_START + 1); + + if (!virt_io_addr) { + printk(KERN_ERR "Unable to ioremap pci space\n"); + return; + } + +#ifdef CONFIG_NONCOHERENT_IO + /* + * Set the NC bit in controller for pre-AC silicon + */ + au_writel( 1<<16 | au_readl(Au1500_PCI_CFG), Au1500_PCI_CFG); + printk("Non-coherent PCI accesses enabled\n"); +#endif + + set_io_port_base(virt_io_addr); +#endif + +#ifdef CONFIG_MIPS_PB1000 /* This is truly board specific */ + unsigned long pci_mem_start = (unsigned long) PCI_MEM_START; + + au_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0 + au_writel(0, SDRAM_MBAR); // set mbar to 0 + au_writel(0x2, SDRAM_CMD); // enable memory accesses + au_sync_delay(1); + + // set extend byte to mbar of ext slot + au_writel(((pci_mem_start >> 24) & 0xff) | + (1 << 8 | 1 << 9 | 1 << 10 | 1 << 27), PCI_BRIDGE_CONFIG); + DBG("Set bridge config to %x\n", au_readl(PCI_BRIDGE_CONFIG)); +#endif +} + +void __init pcibios_fixup_irqs(void) +{ +#ifdef CONFIG_SOC_AU1500 + unsigned int slot, func; + unsigned char pin; + struct pci_dev *dev; + + pci_for_each_dev(dev) { + if (dev->bus->number != 0) + return; + + dev->irq = 0xff; + slot = PCI_SLOT(dev->devfn); + switch (slot) { + case 12: + case 13: + default: + dev->irq = AU1000_PCI_INTA; + break; + + } + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + DBG("slot %d irq %d\n", slot, dev->irq); + } +#endif +} +unsigned int pcibios_assign_all_busses(void) +{ + return 0; +} + +static void fixup_resource(int r_num, struct pci_dev *dev) +{ +} +#endif diff -urN linux-2.4.21-bk37/arch/mips/au1000/common/pci_ops.c linux-2.4.21-bk38/arch/mips/au1000/common/pci_ops.c --- linux-2.4.21-bk37/arch/mips/au1000/common/pci_ops.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/common/pci_ops.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,285 @@ +/* + * BRIEF MODULE DESCRIPTION + * Alchemy/AMD Au1x00 pci support. + * + * Copyright 2001,2002,2003 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * Support for all devices (greater than 16) added by David Gathright. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include + +#ifdef CONFIG_PCI + +#include +#include +#include +#include + +#include +#ifdef CONFIG_MIPS_PB1000 +#include +#endif +#include + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +/* TBD */ +static struct resource pci_io_resource = { + "pci IO space", + (u32)PCI_IO_START, + (u32)PCI_IO_END, + IORESOURCE_IO +}; + +static struct resource pci_mem_resource = { + "pci memory space", + (u32)PCI_MEM_START, + (u32)PCI_MEM_END, + IORESOURCE_MEM +}; + +extern struct pci_ops au1x_pci_ops; + +struct pci_channel mips_pci_channels[] = { + {&au1x_pci_ops, &pci_io_resource, &pci_mem_resource, + PCI_FIRST_DEVFN,PCI_LAST_DEVFN}, + {(struct pci_ops *) NULL, (struct resource *) NULL, + (struct resource *) NULL, (int) NULL, (int) NULL} +}; + + +#ifdef CONFIG_MIPS_PB1000 +/* + * "Bus 2" is really the first and only external slot on the pb1000. + * We'll call that bus 0, and limit the accesses to that single + * external slot only. The SDRAM is already initialized in setup.c. + */ +static int config_access(unsigned char access_type, struct pci_dev *dev, + unsigned char where, u32 * data) +{ + unsigned char bus = dev->bus->number; + unsigned char dev_fn = dev->devfn; + unsigned long config; + + if (((dev_fn >> 3) != 0) || (bus != 0)) { + *data = 0xffffffff; + return -1; + } + + config = PCI_CONFIG_BASE | (where & ~0x3); + + if (access_type == PCI_ACCESS_WRITE) { + au_writel(*data, config); + } else { + *data = au_readl(config); + } + au_sync_udelay(1); + + DBG("config_access: %d bus %d dev_fn %x at %x *data %x, conf %x\n", + access_type, bus, dev_fn, where, *data, config); + + DBG("bridge config reg: %x (%x)\n", au_readl(PCI_BRIDGE_CONFIG), *data); + + if (au_readl(PCI_BRIDGE_CONFIG) & (1 << 16)) { + *data = 0xffffffff; + return -1; + } else { + return PCIBIOS_SUCCESSFUL; + } +} + +#else + +static int config_access(unsigned char access_type, struct pci_dev *dev, + unsigned char where, u32 * data) +{ +#ifdef CONFIG_SOC_AU1500 + unsigned char bus = dev->bus->number; + unsigned int dev_fn = dev->devfn; + unsigned int device = PCI_SLOT(dev_fn); + unsigned int function = PCI_FUNC(dev_fn); + unsigned long config, status; + unsigned long cfg_addr; + + if (device > 19) { + *data = 0xffffffff; + return -1; + } + + au_writel(((0x2000 << 16) | (au_readl(Au1500_PCI_STATCMD) & 0xffff)), + Au1500_PCI_STATCMD); + //au_writel(au_readl(Au1500_PCI_CFG) & ~PCI_ERROR, Au1500_PCI_CFG); + au_sync_udelay(1); + + /* setup the config window */ + if (bus == 0) { + cfg_addr = ioremap( Au1500_EXT_CFG | ((1<> 28) & 0xf) { + DBG("PCI ERR detected: status %x\n", status); + *data = 0xffffffff; + return -1; + } else { + return PCIBIOS_SUCCESSFUL; + } +#endif +} +#endif + +static int read_config_byte(struct pci_dev *dev, int where, u8 * val) +{ + u32 data; + int ret; + + ret = config_access(PCI_ACCESS_READ, dev, where, &data); + if (where & 1) data >>= 8; + if (where & 2) data >>= 16; + *val = data & 0xff; + return ret; +} + + +static int read_config_word(struct pci_dev *dev, int where, u16 * val) +{ + u32 data; + int ret; + + ret = config_access(PCI_ACCESS_READ, dev, where, &data); + if (where & 2) data >>= 16; + *val = data & 0xffff; + return ret; +} + +static int read_config_dword(struct pci_dev *dev, int where, u32 * val) +{ + int ret; + + ret = config_access(PCI_ACCESS_READ, dev, where, val); + return ret; +} + + +static int write_config_byte(struct pci_dev *dev, int where, u8 val) +{ + u32 data = 0; + + if (config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +static int write_config_word(struct pci_dev *dev, int where, u16 val) +{ + u32 data = 0; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return -1; + + + return PCIBIOS_SUCCESSFUL; +} + +static int write_config_dword(struct pci_dev *dev, int where, u32 val) +{ + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (config_access(PCI_ACCESS_WRITE, dev, where, &val)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops au1x_pci_ops = { + read_config_byte, + read_config_word, + read_config_dword, + write_config_byte, + write_config_word, + write_config_dword +}; +#endif /* CONFIG_PCI */ diff -urN linux-2.4.21-bk37/arch/mips/au1000/common/power.c linux-2.4.21-bk38/arch/mips/au1000/common/power.c --- linux-2.4.21-bk37/arch/mips/au1000/common/power.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/common/power.c 2003-08-24 02:55:57.000000000 -0700 @@ -67,6 +67,8 @@ #ifdef CONFIG_PM +static spinlock_t pm_lock = SPIN_LOCK_UNLOCKED; + unsigned long suspend_mode; void wakeup_from_suspend(void) @@ -77,7 +79,7 @@ int au_sleep(void) { unsigned long wakeup, flags; - save_and_cli(flags); + spin_lock_irqsave(&pm_lock,flags); flush_cache_all(); /* pin 6 is gpio */ @@ -104,7 +106,7 @@ /* after a wakeup, the cpu vectors back to 0x1fc00000 so * it's up to the boot code to get us back here. */ - restore_flags(flags); + spin_unlock_irqrestore(&pm_lock, flags); return 0; } @@ -158,31 +160,31 @@ old_refresh; unsigned long new_baud_base, new_cpu_freq, new_clk, new_refresh; - save_and_cli(flags); + spin_lock_irqsave(&pm_lock, flags); if (!write) { *len = 0; } else { /* Parse the new frequency */ if (*len > TMPBUFLEN - 1) { - restore_flags(flags); + spin_unlock_irqrestore(&pm_lock, flags); return -EFAULT; } if (copy_from_user(buf, buffer, *len)) { - restore_flags(flags); + spin_unlock_irqrestore(&pm_lock, flags); return -EFAULT; } buf[*len] = 0; p = buf; val = simple_strtoul(p, &p, 0); if (val > MAX_CPU_FREQ) { - restore_flags(flags); + spin_unlock_irqrestore(&pm_lock, flags); return -EFAULT; } pll = val / 12; if ((pll > 33) || (pll < 7)) { /* 396 MHz max, 84 MHz min */ /* revisit this for higher speed cpus */ - restore_flags(flags); + spin_unlock_irqrestore(&pm_lock, flags); return -EFAULT; } @@ -247,7 +249,7 @@ intc0_mask = save_local_and_disable(0); intc1_mask = save_local_and_disable(1); local_enable_irq(AU1000_TOY_MATCH2_INT); - restore_flags(flags); + spin_unlock_irqrestore(&pm_lock, flags); calibrate_delay(); restore_local_and_enable(0, intc0_mask); restore_local_and_enable(1, intc1_mask); @@ -323,4 +325,9 @@ } } +void au1k_wait(void) +{ + __asm__("nop\n\t" "nop\n\t"); +} + #endif /* CONFIG_PM */ diff -urN linux-2.4.21-bk37/arch/mips/au1000/common/prom.c linux-2.4.21-bk38/arch/mips/au1000/common/prom.c --- linux-2.4.21-bk37/arch/mips/au1000/common/prom.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/common/prom.c 2003-08-24 02:55:57.000000000 -0700 @@ -105,9 +105,11 @@ inline unsigned char str2hexnum(unsigned char c) { if(c >= '0' && c <= '9') - return c - '0'; + return c - '0'; if(c >= 'a' && c <= 'f') - return c - 'a' + 10; + return c - 'a' + 10; + if(c >= 'A' && c <= 'F') + return c - 'A' + 10; return 0; /* foo */ } @@ -128,7 +130,6 @@ int get_ethernet_addr(char *ethernet_addr) { - int i; char *ethaddr_str; ethaddr_str = prom_getenv("ethaddr"); @@ -139,10 +140,14 @@ str2eaddr(ethernet_addr, ethaddr_str); #if 0 + { + int i; + printk("get_ethernet_addr: "); for (i=0; i<5; i++) printk("%02x:", (unsigned char)*(ethernet_addr+i)); printk("%02x\n", *(ethernet_addr+i)); + } #endif return 0; @@ -151,3 +156,4 @@ void prom_free_prom_memory (void) {} EXPORT_SYMBOL(prom_getcmdline); EXPORT_SYMBOL(get_ethernet_addr); +EXPORT_SYMBOL(str2eaddr); diff -urN linux-2.4.21-bk37/arch/mips/au1000/common/puts.c linux-2.4.21-bk38/arch/mips/au1000/common/puts.c --- linux-2.4.21-bk37/arch/mips/au1000/common/puts.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/au1000/common/puts.c 2003-08-24 02:55:57.000000000 -0700 @@ -29,8 +29,9 @@ */ #include +#include -#define SERIAL_BASE 0xB1100000 /* au1000, uart 0 */ +#define SERIAL_BASE UART_BASE #define SER_CMD 0x7 #define SER_DATA 0x1 #define TX_BUSY 0x20 diff -urN linux-2.4.21-bk37/arch/mips/au1000/common/reset.c linux-2.4.21-bk38/arch/mips/au1000/common/reset.c --- linux-2.4.21-bk37/arch/mips/au1000/common/reset.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/common/reset.c 2003-08-24 02:55:57.000000000 -0700 @@ -42,7 +42,7 @@ void au1000_restart(char *command) { /* Set all integrated peripherals to disabled states */ - u32 prid = read_32bit_cp0_register(CP0_PRID); + u32 prid = read_c0_prid(); printk(KERN_NOTICE "\n** Resetting Integrated Peripherals\n"); switch (prid & 0xFF000000) @@ -107,10 +107,17 @@ break; } - set_cp0_status(ST0_BEV | ST0_ERL); - set_cp0_config(CONF_CM_UNCACHED); + set_c0_status(ST0_BEV | ST0_ERL); + set_c0_config(CONF_CM_UNCACHED); flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); + write_c0_wired(0); + +#if defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) + /* Do a HW reset if the board can do it */ + + au_writel(0x00000000, 0xAE00001C); +#endif + __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); } diff -urN linux-2.4.21-bk37/arch/mips/au1000/common/serial.c linux-2.4.21-bk38/arch/mips/au1000/common/serial.c --- linux-2.4.21-bk37/arch/mips/au1000/common/serial.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/common/serial.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,3072 +0,0 @@ -/* - * - * BRIEF MODULE DESCRIPTION - * Au1000 serial port driver. - * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * Derived almost entirely from drivers/char/serial.c: - * - * Copyright (C) 1991, 1992 Linus Torvalds - * Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, - * 1998, 1999 Theodore Ts'o - * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -static char *serial_version = "1.01"; -static char *serial_revdate = "2001-02-08"; - - -#include -#include - -#undef SERIAL_PARANOIA_CHECK -#define CONFIG_SERIAL_NOPAUSE_IO -#define SERIAL_DO_RESTART - - -/* Set of debugging defines */ - -#undef SERIAL_DEBUG_INTR -#undef SERIAL_DEBUG_OPEN -#undef SERIAL_DEBUG_FLOW -#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT -#undef SERIAL_DEBUG_PCI -#undef SERIAL_DEBUG_AUTOCONF - -#ifdef MODULE -#undef CONFIG_AU1000_SERIAL_CONSOLE -#endif - -#define CONFIG_SERIAL_RSA - -#define RS_STROBE_TIME (10*HZ) -#define RS_ISR_PASS_LIMIT 256 - -/* - * End of serial driver configuration section. - */ - -#include - -#include -#ifdef LOCAL_HEADERS -#include "serial_local.h" -#else -#include -#include -#include -#include -#define LOCAL_VERSTRING "" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_AU1000_SERIAL_CONSOLE -#include -#endif -#ifdef CONFIG_MAGIC_SYSRQ -#include -#endif - -#include -#include -#include -#include - -#ifdef CONFIG_MAC_SERIAL -#define SERIAL_DEV_OFFSET 2 -#else -#define SERIAL_DEV_OFFSET 0 -#endif - -#ifdef SERIAL_INLINE -#define _INLINE_ inline -#else -#define _INLINE_ -#endif - -static char *serial_name = "Serial driver"; - -static DECLARE_TASK_QUEUE(tq_serial); - -static struct tty_driver serial_driver, callout_driver; -static int serial_refcount; - -static struct timer_list serial_timer; - -extern unsigned long get_au1000_uart_baud_base(void); - -/* serial subtype definitions */ -#ifndef SERIAL_TYPE_NORMAL -#define SERIAL_TYPE_NORMAL 1 -#define SERIAL_TYPE_CALLOUT 2 -#endif - -/* number of characters left in xmit buffer before we ask for more */ -#define WAKEUP_CHARS 256 - -/* - * IRQ_timeout - How long the timeout should be for each IRQ - * should be after the IRQ has been active. - */ - -static struct async_struct *IRQ_ports[NR_IRQS]; -static int IRQ_timeout[NR_IRQS]; -#ifdef CONFIG_AU1000_SERIAL_CONSOLE -static struct console sercons; -static int lsr_break_flag; -#endif -#if defined(CONFIG_AU1000_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -static unsigned long break_pressed; /* break, really ... */ -#endif - -static void autoconfig(struct serial_state * state); -static void change_speed(struct async_struct *info, struct termios *old); -static void rs_wait_until_sent(struct tty_struct *tty, int timeout); - -/* - * Here we define the default xmit fifo size used for each type of - * UART - */ -static struct serial_uart_config uart_config[] = { - { "unknown", 1, 0 }, - { "8250", 1, 0 }, - { "16450", 1, 0 }, - { "16550", 1, 0 }, - { 0, 0} -}; - - -static struct serial_state rs_table[RS_TABLE_SIZE] = { - SERIAL_PORT_DFNS /* Defined in serial.h */ -}; - -#define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state)) - -#ifndef PREPARE_FUNC -#define PREPARE_FUNC(dev) (dev->prepare) -#define ACTIVATE_FUNC(dev) (dev->activate) -#define DEACTIVATE_FUNC(dev) (dev->deactivate) -#endif - -#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) - -static struct tty_struct *serial_table[NR_PORTS]; -static struct termios *serial_termios[NR_PORTS]; -static struct termios *serial_termios_locked[NR_PORTS]; - - -#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) -#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \ - kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s) -#else -#define DBG_CNT(s) -#endif - -/* - * tmp_buf is used as a temporary buffer by serial_write. We need to - * lock it in case the copy_from_user blocks while swapping in a page, - * and some other program tries to do a serial write at the same time. - * Since the lock will only come under contention when the system is - * swapping and available memory is low, it makes sense to share one - * buffer across all the serial ports, since it significantly saves - * memory if large numbers of serial ports are open. - */ -static unsigned char *tmp_buf; -#ifdef DECLARE_MUTEX -static DECLARE_MUTEX(tmp_buf_sem); -#else -static struct semaphore tmp_buf_sem = MUTEX; -#endif - - -static inline int serial_paranoia_check(struct async_struct *info, - kdev_t device, const char *routine) -{ -#ifdef SERIAL_PARANOIA_CHECK - static const char *badmagic = - "Warning: bad magic number for serial struct (%s) in %s\n"; - static const char *badinfo = - "Warning: null async_struct for (%s) in %s\n"; - - if (!info) { - printk(badinfo, kdevname(device), routine); - return 1; - } - if (info->magic != SERIAL_MAGIC) { - printk(badmagic, kdevname(device), routine); - return 1; - } -#endif - return 0; -} - -static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset) -{ - return (au_readl(info->port+offset) & 0xffff); -} - -static _INLINE_ void serial_out(struct async_struct *info, int offset, int value) -{ - au_writel(value & 0xffff, info->port+offset); -} - - -/* - * We used to support using pause I/O for certain machines. We - * haven't supported this for a while, but just in case it's badly - * needed for certain old 386 machines, I've left these #define's - * in.... - */ -#define serial_inp(info, offset) serial_in(info, offset) -#define serial_outp(info, offset, value) serial_out(info, offset, value) - - -/* - * ------------------------------------------------------------ - * rs_stop() and rs_start() - * - * This routines are called before setting or resetting tty->stopped. - * They enable or disable transmitter interrupts, as necessary. - * ------------------------------------------------------------ - */ -static void rs_stop(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_stop")) - return; - - save_flags(flags); cli(); - if (info->IER & UART_IER_THRI) { - info->IER &= ~UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } - restore_flags(flags); -} - -static void rs_start(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_start")) - return; - - save_flags(flags); cli(); - if (info->xmit.head != info->xmit.tail - && info->xmit.buf - && !(info->IER & UART_IER_THRI)) { - info->IER |= UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } - restore_flags(flags); -} - -/* - * ---------------------------------------------------------------------- - * - * Here starts the interrupt handling routines. All of the following - * subroutines are declared as inline and are folded into - * rs_interrupt(). They were separated out for readability's sake. - * - * Note: rs_interrupt() is a "fast" interrupt, which means that it - * runs with interrupts turned off. People who may want to modify - * rs_interrupt() should try to keep the interrupt handler as fast as - * possible. After you are done making modifications, it is not a bad - * idea to do: - * - * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c - * - * and look at the resulting assemble code in serial.s. - * - * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 - * ----------------------------------------------------------------------- - */ - -/* - * This routine is used by the interrupt handler to schedule - * processing in the software interrupt portion of the driver. - */ -static _INLINE_ void rs_sched_event(struct async_struct *info, - int event) -{ - info->event |= 1 << event; - queue_task(&info->tqueue, &tq_serial); - mark_bh(SERIAL_BH); -} - -static _INLINE_ void receive_chars(struct async_struct *info, - int *status, struct pt_regs * regs) -{ - struct tty_struct *tty = info->tty; - unsigned char ch; - int ignored = 0; - struct async_icount *icount; - - icount = &info->state->icount; - do { - ch = serial_inp(info, UART_RX); - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - goto ignore_char; - *tty->flip.char_buf_ptr = ch; - icount->rx++; - -#ifdef SERIAL_DEBUG_INTR - printk("DR%02x:%02x...", ch, *status); -#endif - *tty->flip.flag_buf_ptr = 0; - if (*status & (UART_LSR_BI | UART_LSR_PE | - UART_LSR_FE | UART_LSR_OE)) { - /* - * For statistics only - */ - if (*status & UART_LSR_BI) { - *status &= ~(UART_LSR_FE | UART_LSR_PE); - icount->brk++; - /* - * We do the SysRQ and SAK checking - * here because otherwise the break - * may get masked by ignore_status_mask - * or read_status_mask. - */ -#if defined(CONFIG_AU1000_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) - if (info->line == sercons.index) { - if (!break_pressed) { - break_pressed = jiffies; - goto ignore_char; - } - break_pressed = 0; - } -#endif - if (info->flags & ASYNC_SAK) - do_SAK(tty); - } else if (*status & UART_LSR_PE) - icount->parity++; - else if (*status & UART_LSR_FE) - icount->frame++; - if (*status & UART_LSR_OE) - icount->overrun++; - - /* - * Now check to see if character should be - * ignored, and mask off conditions which - * should be ignored. - */ - if (*status & info->ignore_status_mask) { - if (++ignored > 100) - break; - goto ignore_char; - } - *status &= info->read_status_mask; - -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - if (info->line == sercons.index) { - /* Recover the break flag from console xmit */ - *status |= lsr_break_flag; - lsr_break_flag = 0; - } -#endif - if (*status & (UART_LSR_BI)) { -#ifdef SERIAL_DEBUG_INTR - printk("handling break...."); -#endif - *tty->flip.flag_buf_ptr = TTY_BREAK; - } else if (*status & UART_LSR_PE) - *tty->flip.flag_buf_ptr = TTY_PARITY; - else if (*status & UART_LSR_FE) - *tty->flip.flag_buf_ptr = TTY_FRAME; - if (*status & UART_LSR_OE) { - /* - * Overrun is special, since it's - * reported immediately, and doesn't - * affect the current character - */ - tty->flip.count++; - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - *tty->flip.flag_buf_ptr = TTY_OVERRUN; - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - goto ignore_char; - } - } -#if defined(CONFIG_AU1000_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) - if (break_pressed && info->line == sercons.index) { - if (ch != 0 && - time_before(jiffies, break_pressed + HZ*5)) { - handle_sysrq(ch, regs, NULL, NULL); - break_pressed = 0; - goto ignore_char; - } - break_pressed = 0; - } -#endif - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - tty->flip.count++; - ignore_char: - *status = serial_inp(info, UART_LSR); - } while (*status & UART_LSR_DR); - tty_flip_buffer_push(tty); -} - -static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) -{ - int count; - - if (info->x_char) { - serial_outp(info, UART_TX, info->x_char); - info->state->icount.tx++; - info->x_char = 0; - if (intr_done) - *intr_done = 0; - return; - } - if (info->xmit.head == info->xmit.tail - || info->tty->stopped - || info->tty->hw_stopped) { - info->IER &= ~UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - return; - } - - count = info->xmit_fifo_size; - do { - serial_out(info, UART_TX, info->xmit.buf[info->xmit.tail]); - info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1); - info->state->icount.tx++; - if (info->xmit.head == info->xmit.tail) - break; - } while (--count > 0); - - if (CIRC_CNT(info->xmit.head, - info->xmit.tail, - SERIAL_XMIT_SIZE) < WAKEUP_CHARS) - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); - -#ifdef SERIAL_DEBUG_INTR - printk("THRE..."); -#endif - if (intr_done) - *intr_done = 0; - - if (info->xmit.head == info->xmit.tail) { - info->IER &= ~UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } -} - -static _INLINE_ void check_modem_status(struct async_struct *info) -{ - int status; - struct async_icount *icount; - - status = serial_in(info, UART_MSR); - - if (status & UART_MSR_ANY_DELTA) { - icount = &info->state->icount; - /* update input line counters */ - if (status & UART_MSR_TERI) - icount->rng++; - if (status & UART_MSR_DDSR) - icount->dsr++; - if (status & UART_MSR_DDCD) { - icount->dcd++; -#ifdef CONFIG_HARD_PPS - if ((info->flags & ASYNC_HARDPPS_CD) && - (status & UART_MSR_DCD)) - hardpps(); -#endif - } - if (status & UART_MSR_DCTS) - icount->cts++; - wake_up_interruptible(&info->delta_msr_wait); - } - - if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { -#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) - printk("ttys%d CD now %s...", info->line, - (status & UART_MSR_DCD) ? "on" : "off"); -#endif - if (status & UART_MSR_DCD) - wake_up_interruptible(&info->open_wait); - else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) && - (info->flags & ASYNC_CALLOUT_NOHUP))) { -#ifdef SERIAL_DEBUG_OPEN - printk("doing serial hangup..."); -#endif - if (info->tty) - tty_hangup(info->tty); - } - } - if (info->flags & ASYNC_CTS_FLOW) { - if (info->tty->hw_stopped) { - if (status & UART_MSR_CTS) { -#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) - printk("CTS tx start..."); -#endif - info->tty->hw_stopped = 0; - info->IER |= UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); - return; - } - } else { - if (!(status & UART_MSR_CTS)) { -#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) - printk("CTS tx stop..."); -#endif - info->tty->hw_stopped = 1; - info->IER &= ~UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } - } - } -} - - - -/* - * This is the serial driver's interrupt routine for a single port - */ -static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs) -{ - int status; - int pass_counter = 0; - struct async_struct * info; - -#ifdef SERIAL_DEBUG_INTR - printk("rs_interrupt_single(%d)...", irq); -#endif - - info = IRQ_ports[irq]; - if (!info || !info->tty) - return; - - do { - status = serial_inp(info, UART_LSR); -#ifdef SERIAL_DEBUG_INTR - printk("status = %x...", status); -#endif - if (status & UART_LSR_DR) - receive_chars(info, &status, regs); - check_modem_status(info); - if (status & UART_LSR_THRE) - transmit_chars(info, 0); - if (pass_counter++ > RS_ISR_PASS_LIMIT) { -#if 0 - printk("rs_single loop break.\n"); -#endif - break; - } - } while (!(serial_in(info, UART_IIR) & UART_IIR_NO_INT)); - info->last_active = jiffies; -#ifdef SERIAL_DEBUG_INTR - printk("end.\n"); -#endif -} - - -/* - * ------------------------------------------------------------------- - * Here ends the serial interrupt routines. - * ------------------------------------------------------------------- - */ - -/* - * This routine is used to handle the "bottom half" processing for the - * serial driver, known also the "software interrupt" processing. - * This processing is done at the kernel interrupt level, after the - * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This - * is where time-consuming activities which can not be done in the - * interrupt driver proper are done; the interrupt driver schedules - * them using rs_sched_event(), and they get done here. - */ -static void do_serial_bh(void) -{ - run_task_queue(&tq_serial); -} - -static void do_softint(void *private_) -{ - struct async_struct *info = (struct async_struct *) private_; - struct tty_struct *tty; - - tty = info->tty; - if (!tty) - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); - wake_up_interruptible(&tty->write_wait); -#ifdef SERIAL_HAVE_POLL_WAIT - wake_up_interruptible(&tty->poll_wait); -#endif - } -} - -/* - * This subroutine is called when the RS_TIMER goes off. It is used - * by the serial driver to handle ports that do not have an interrupt - * (irq=0). This doesn't work very well for 16450's, but gives barely - * passable results for a 16550A. (Although at the expense of much - * CPU overhead). - */ -static void rs_timer(unsigned long dummy) -{ - static unsigned long last_strobe; - struct async_struct *info; - unsigned int i; - unsigned long flags; - - if ((jiffies - last_strobe) >= RS_STROBE_TIME) { - for (i=0; i < NR_IRQS; i++) { - info = IRQ_ports[i]; - if (!info) - continue; - save_flags(flags); cli(); - rs_interrupt_single(i, NULL, NULL); - restore_flags(flags); - } - } - last_strobe = jiffies; - mod_timer(&serial_timer, jiffies + RS_STROBE_TIME); - -#if 0 - if (IRQ_ports[0]) { - save_flags(flags); cli(); - rs_interrupt_single(0, NULL, NULL); - restore_flags(flags); - - mod_timer(&serial_timer, jiffies + IRQ_timeout[0]); - } -#endif -} - -/* - * --------------------------------------------------------------- - * Low level utility subroutines for the serial driver: routines to - * figure out the appropriate timeout for an interrupt chain, routines - * to initialize and startup a serial port, and routines to shutdown a - * serial port. Useful stuff like that. - * --------------------------------------------------------------- - */ - -/* - * This routine figures out the correct timeout for a particular IRQ. - * It uses the smallest timeout of all of the serial ports in a - * particular interrupt chain. Now only used for IRQ 0.... - */ -static void figure_IRQ_timeout(int irq) -{ - struct async_struct *info; - int timeout = 60*HZ; /* 60 seconds === a long time :-) */ - - info = IRQ_ports[irq]; - if (!info) { - IRQ_timeout[irq] = 60*HZ; - return; - } - while (info) { - if (info->timeout < timeout) - timeout = info->timeout; - info = info->next_port; - } - if (!irq) - timeout = timeout / 2; - IRQ_timeout[irq] = (timeout > 3) ? timeout-2 : 1; -} - - -static int startup(struct async_struct * info) -{ - unsigned long flags; - int retval=0; - void (*handler)(int, void *, struct pt_regs *); - struct serial_state *state= info->state; - unsigned long page; - - page = get_zeroed_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - - save_flags(flags); cli(); - - if (info->flags & ASYNC_INITIALIZED) { - free_page(page); - goto errout; - } - - if (!CONFIGURED_SERIAL_PORT(state) || !state->type) { - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - free_page(page); - goto errout; - } - if (info->xmit.buf) - free_page(page); - else - info->xmit.buf = (unsigned char *) page; - - - if (au_readl(UART_MOD_CNTRL + state->port) != 0x3) { - au_writel(3, UART_MOD_CNTRL + state->port); - au_sync_delay(10); - } -#ifdef SERIAL_DEBUG_OPEN - printk("starting up ttys%d (irq %d)...", info->line, state->irq); -#endif - - - /* - * Clear the FIFO buffers and disable them - * (they will be reenabled in change_speed()) - */ - if (uart_config[state->type].flags & UART_CLEAR_FIFO) { - serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO); - serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | - UART_FCR_CLEAR_XMIT)); - serial_outp(info, UART_FCR, 0); - } - - /* - * Clear the interrupt registers. - */ - (void) serial_inp(info, UART_LSR); - (void) serial_inp(info, UART_RX); - (void) serial_inp(info, UART_IIR); - (void) serial_inp(info, UART_MSR); - - /* - * At this point there's no way the LSR could still be 0xFF; - * if it is, then bail out, because there's likely no UART - * here. - */ - if (!(info->flags & ASYNC_BUGGY_UART) && - (serial_inp(info, UART_LSR) == 0xff)) { - printk("LSR safety check engaged!\n"); - if (capable(CAP_SYS_ADMIN)) { - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - } else - retval = -ENODEV; - goto errout; - } - - /* - * Allocate the IRQ if necessary - */ -#if 0 - /* au1000, uart0 irq is 0 */ - if (state->irq && (!IRQ_ports[state->irq] || !IRQ_ports[state->irq]->next_port)) { -#endif - if ((!IRQ_ports[state->irq] || !IRQ_ports[state->irq]->next_port)) { - if (IRQ_ports[state->irq]) { - retval = -EBUSY; - goto errout; - } else - handler = rs_interrupt_single; - - retval = request_irq(state->irq, handler, SA_SHIRQ, - "serial", &IRQ_ports[state->irq]); - if (retval) { - if (capable(CAP_SYS_ADMIN)) { - if (info->tty) - set_bit(TTY_IO_ERROR, - &info->tty->flags); - retval = 0; - } - goto errout; - } - } - - /* - * Insert serial port into IRQ chain. - */ - info->prev_port = 0; - info->next_port = IRQ_ports[state->irq]; - if (info->next_port) - info->next_port->prev_port = info; - IRQ_ports[state->irq] = info; - figure_IRQ_timeout(state->irq); - - /* - * Now, initialize the UART - */ - serial_outp(info, UART_LCR, UART_LCR_WLEN8); - - info->MCR = 0; - if (info->tty->termios->c_cflag & CBAUD) - info->MCR = UART_MCR_DTR | UART_MCR_RTS; - { - if (state->irq != 0) - info->MCR |= UART_MCR_OUT2; - } - info->MCR |= ALPHA_KLUDGE_MCR; /* Don't ask */ - serial_outp(info, UART_MCR, info->MCR); - - /* - * Finally, enable interrupts - */ - info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI; - serial_outp(info, UART_IER, info->IER); /* enable interrupts */ - - - /* - * And clear the interrupt registers again for luck. - */ - (void)serial_inp(info, UART_LSR); - (void)serial_inp(info, UART_RX); - (void)serial_inp(info, UART_IIR); - (void)serial_inp(info, UART_MSR); - - if (info->tty) - clear_bit(TTY_IO_ERROR, &info->tty->flags); - info->xmit.head = info->xmit.tail = 0; - - /* - * Set up serial timers... - */ - mod_timer(&serial_timer, jiffies + 2*HZ/100); - - /* - * Set up the tty->alt_speed kludge - */ - if (info->tty) { - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - info->tty->alt_speed = 57600; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - info->tty->alt_speed = 115200; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - info->tty->alt_speed = 230400; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - info->tty->alt_speed = 460800; - } - - /* - * and set the speed of the serial port - */ - change_speed(info, 0); - - info->flags |= ASYNC_INITIALIZED; - restore_flags(flags); - return 0; - -errout: - restore_flags(flags); - return retval; -} - -/* - * This routine will shutdown a serial port; interrupts are disabled, and - * DTR is dropped if the hangup on close termio flag is on. - */ -static void shutdown(struct async_struct * info) -{ - unsigned long flags; - struct serial_state *state; - int retval; - - if (!(info->flags & ASYNC_INITIALIZED)) - return; - - state = info->state; - -#ifdef SERIAL_DEBUG_OPEN - printk("Shutting down serial port %d (irq %d)....", info->line, - state->irq); -#endif - - save_flags(flags); cli(); /* Disable interrupts */ - - /* - * clear delta_msr_wait queue to avoid mem leaks: we may free the irq - * here so the queue might never be waken up - */ - wake_up_interruptible(&info->delta_msr_wait); - - /* - * First unlink the serial port from the IRQ chain... - */ - if (info->next_port) - info->next_port->prev_port = info->prev_port; - if (info->prev_port) - info->prev_port->next_port = info->next_port; - else - IRQ_ports[state->irq] = info->next_port; - figure_IRQ_timeout(state->irq); - - /* - * Free the IRQ, if necessary - */ -// if (state->irq && (!IRQ_ports[state->irq] || - if ((!IRQ_ports[state->irq] || - !IRQ_ports[state->irq]->next_port)) { - if (IRQ_ports[state->irq]) { - free_irq(state->irq, &IRQ_ports[state->irq]); - retval = request_irq(state->irq, rs_interrupt_single, - SA_SHIRQ, "serial", - &IRQ_ports[state->irq]); - - if (retval) - printk("serial shutdown: request_irq: error %d" - " Couldn't reacquire IRQ.\n", retval); - } else - free_irq(state->irq, &IRQ_ports[state->irq]); - } - - if (info->xmit.buf) { - unsigned long pg = (unsigned long) info->xmit.buf; - info->xmit.buf = 0; - free_page(pg); - } - - info->IER = 0; - serial_outp(info, UART_IER, 0x00); /* disable all intrs */ - info->MCR &= ~UART_MCR_OUT2; - info->MCR |= ALPHA_KLUDGE_MCR; /* Don't ask */ - - /* disable break condition */ - serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC); - - if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) - info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); - serial_outp(info, UART_MCR, info->MCR); - - /* disable FIFO's */ - serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | - UART_FCR_CLEAR_XMIT)); - serial_outp(info, UART_FCR, 0); - - (void)serial_in(info, UART_RX); /* read data port to reset things */ - - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - - info->flags &= ~ASYNC_INITIALIZED; -#ifndef CONFIG_REMOTE_DEBUG - au_writel(0, UART_MOD_CNTRL + state->port); - au_sync_delay(10); -#endif - restore_flags(flags); -} - - -/* - * This routine is called to set the UART divisor registers to match - * the specified baud rate for a serial port. - */ -static void change_speed(struct async_struct *info, - struct termios *old_termios) -{ - int quot = 0, baud_base, baud; - unsigned cflag, cval, fcr = 0; - int bits; - unsigned long flags; - - if (!info->tty || !info->tty->termios) - return; - cflag = info->tty->termios->c_cflag; - if (!CONFIGURED_SERIAL_PORT(info)) - return; - - /* byte size and parity */ - switch (cflag & CSIZE) { - case CS5: cval = 0x00; bits = 7; break; - case CS6: cval = 0x01; bits = 8; break; - case CS7: cval = 0x02; bits = 9; break; - case CS8: cval = 0x03; bits = 10; break; - /* Never happens, but GCC is too dumb to figure it out */ - default: cval = 0x00; bits = 7; break; - } - if (cflag & CSTOPB) { - cval |= 0x04; - bits++; - } - if (cflag & PARENB) { - cval |= UART_LCR_PARITY; - bits++; - } - if (!(cflag & PARODD)) - cval |= UART_LCR_EPAR; -#ifdef CMSPAR - if (cflag & CMSPAR) - cval |= UART_LCR_SPAR; -#endif - - /* Determine divisor based on baud rate */ - baud = tty_get_baud_rate(info->tty); - if (!baud) { - baud = 9600; /* B0 transition handled in rs_set_termios */ - } - baud_base = get_au1000_uart_baud_base(); - - //if (baud == 38400 && - if (((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) { - quot = info->state->custom_divisor; - } - else { - if (baud == 134) - /* Special case since 134 is really 134.5 */ - quot = (2*baud_base / 269); - else if (baud) - quot = baud_base / baud; - } - /* If the quotient is zero refuse the change */ - if (!quot && old_termios) { - info->tty->termios->c_cflag &= ~CBAUD; - info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD); - baud = tty_get_baud_rate(info->tty); - if (!baud) - baud = 9600; - if (baud == 38400 && - ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) - quot = info->state->custom_divisor; - else { - if (baud == 134) - /* Special case since 134 is really 134.5 */ - quot = (2*baud_base / 269); - else if (baud) - quot = baud_base / baud; - } - } - /* As a last resort, if the quotient is zero, default to 9600 bps */ - if (!quot) - quot = baud_base / 9600; - - info->quot = quot; - info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base); - info->timeout += HZ/50; /* Add .02 seconds of slop */ - - /* Set up FIFO's */ - if (uart_config[info->state->type].flags & UART_USE_FIFO) { - if ((info->state->baud_base / quot) < 2400) - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIGGER_1; - else - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIGGER_8; - } - - /* CTS flow control flag and modem status interrupts */ - info->IER &= ~UART_IER_MSI; - if (info->flags & ASYNC_HARDPPS_CD) - info->IER |= UART_IER_MSI; - if (cflag & CRTSCTS) { - info->flags |= ASYNC_CTS_FLOW; - info->IER |= UART_IER_MSI; - } else - info->flags &= ~ASYNC_CTS_FLOW; - if (cflag & CLOCAL) - info->flags &= ~ASYNC_CHECK_CD; - else { - info->flags |= ASYNC_CHECK_CD; - info->IER |= UART_IER_MSI; - } - serial_out(info, UART_IER, info->IER); - - /* - * Set up parity check flag - */ -#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) - - info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; - if (I_INPCK(info->tty)) - info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; - if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) - info->read_status_mask |= UART_LSR_BI; - - /* - * Characters to ignore - */ - info->ignore_status_mask = 0; - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; - if (I_IGNBRK(info->tty)) { - info->ignore_status_mask |= UART_LSR_BI; - /* - * If we're ignore parity and break indicators, ignore - * overruns too. (For real raw support). - */ - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= UART_LSR_OE; - } - /* - * !!! ignore all characters if CREAD is not set - */ - if ((cflag & CREAD) == 0) - info->ignore_status_mask |= UART_LSR_DR; - save_flags(flags); cli(); - - serial_outp(info, UART_CLK, quot & 0xffff); - serial_outp(info, UART_LCR, cval); - info->LCR = cval; /* Save LCR */ - restore_flags(flags); -} - -static void rs_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_put_char")) - return; - - if (!tty || !info->xmit.buf) - return; - - save_flags(flags); cli(); - if (CIRC_SPACE(info->xmit.head, - info->xmit.tail, - SERIAL_XMIT_SIZE) == 0) { - restore_flags(flags); - return; - } - - info->xmit.buf[info->xmit.head] = ch; - info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1); - restore_flags(flags); -} - -static void rs_flush_chars(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_flush_chars")) - return; - - if (info->xmit.head == info->xmit.tail - || tty->stopped - || tty->hw_stopped - || !info->xmit.buf) - return; - - save_flags(flags); cli(); - info->IER |= UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - restore_flags(flags); -} - -static int rs_write(struct tty_struct * tty, int from_user, - const unsigned char *buf, int count) -{ - int c, ret = 0; - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_write")) - return 0; - - if (!tty || !info->xmit.buf || !tmp_buf) - return 0; - - save_flags(flags); - if (from_user) { - down(&tmp_buf_sem); - while (1) { - int c1; - c = CIRC_SPACE_TO_END(info->xmit.head, - info->xmit.tail, - SERIAL_XMIT_SIZE); - if (count < c) - c = count; - if (c <= 0) - break; - - c -= copy_from_user(tmp_buf, buf, c); - if (!c) { - if (!ret) - ret = -EFAULT; - break; - } - cli(); - c1 = CIRC_SPACE_TO_END(info->xmit.head, - info->xmit.tail, - SERIAL_XMIT_SIZE); - if (c1 < c) - c = c1; - memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c); - info->xmit.head = ((info->xmit.head + c) & - (SERIAL_XMIT_SIZE-1)); - restore_flags(flags); - buf += c; - count -= c; - ret += c; - } - up(&tmp_buf_sem); - } else { - cli(); - while (1) { - c = CIRC_SPACE_TO_END(info->xmit.head, - info->xmit.tail, - SERIAL_XMIT_SIZE); - if (count < c) - c = count; - if (c <= 0) { - break; - } - memcpy(info->xmit.buf + info->xmit.head, buf, c); - info->xmit.head = ((info->xmit.head + c) & - (SERIAL_XMIT_SIZE-1)); - buf += c; - count -= c; - ret += c; - } - restore_flags(flags); - } - if (info->xmit.head != info->xmit.tail - && !tty->stopped - && !tty->hw_stopped - && !(info->IER & UART_IER_THRI)) { - info->IER |= UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } - return ret; -} - -static int rs_write_room(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - - if (serial_paranoia_check(info, tty->device, "rs_write_room")) - return 0; - return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); -} - -static int rs_chars_in_buffer(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - - if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer")) - return 0; - return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); -} - -static void rs_flush_buffer(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_flush_buffer")) - return; - save_flags(flags); cli(); - info->xmit.head = info->xmit.tail = 0; - restore_flags(flags); - wake_up_interruptible(&tty->write_wait); -#ifdef SERIAL_HAVE_POLL_WAIT - wake_up_interruptible(&tty->poll_wait); -#endif - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); -} - -/* - * This function is used to send a high-priority XON/XOFF character to - * the device - */ -static void rs_send_xchar(struct tty_struct *tty, char ch) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - - if (serial_paranoia_check(info, tty->device, "rs_send_char")) - return; - - info->x_char = ch; - if (ch) { - /* Make sure transmit interrupts are on */ - info->IER |= UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } -} - -/* - * ------------------------------------------------------------ - * rs_throttle() - * - * This routine is called by the upper-layer tty layer to signal that - * incoming characters should be throttled. - * ------------------------------------------------------------ - */ -static void rs_throttle(struct tty_struct * tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("throttle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->device, "rs_throttle")) - return; - - if (I_IXOFF(tty)) - rs_send_xchar(tty, STOP_CHAR(tty)); - - if (tty->termios->c_cflag & CRTSCTS) - info->MCR &= ~UART_MCR_RTS; - - save_flags(flags); cli(); - serial_out(info, UART_MCR, info->MCR); - restore_flags(flags); -} - -static void rs_unthrottle(struct tty_struct * tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("unthrottle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->device, "rs_unthrottle")) - return; - - if (I_IXOFF(tty)) { - if (info->x_char) - info->x_char = 0; - else - rs_send_xchar(tty, START_CHAR(tty)); - } - if (tty->termios->c_cflag & CRTSCTS) - info->MCR |= UART_MCR_RTS; - save_flags(flags); cli(); - serial_out(info, UART_MCR, info->MCR); - restore_flags(flags); -} - -/* - * ------------------------------------------------------------ - * rs_ioctl() and friends - * ------------------------------------------------------------ - */ - -static int get_serial_info(struct async_struct * info, - struct serial_struct * retinfo) -{ - struct serial_struct tmp; - struct serial_state *state = info->state; - - if (!retinfo) - return -EFAULT; - memset(&tmp, 0, sizeof(tmp)); - tmp.type = state->type; - tmp.line = state->line; - tmp.port = state->port; - if (HIGH_BITS_OFFSET) - tmp.port_high = state->port >> HIGH_BITS_OFFSET; - else - tmp.port_high = 0; - tmp.irq = state->irq; - tmp.flags = state->flags; - tmp.xmit_fifo_size = state->xmit_fifo_size; - tmp.baud_base = state->baud_base; - tmp.close_delay = state->close_delay; - tmp.closing_wait = state->closing_wait; - tmp.custom_divisor = state->custom_divisor; - tmp.hub6 = state->hub6; - tmp.io_type = state->io_type; - if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int set_serial_info(struct async_struct * info, - struct serial_struct * new_info) -{ - struct serial_struct new_serial; - struct serial_state old_state, *state; - unsigned int i,change_irq,change_port; - int retval = 0; - unsigned long new_port; - - if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) - return -EFAULT; - state = info->state; - old_state = *state; - - new_port = new_serial.port; - if (HIGH_BITS_OFFSET) - new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET; - - change_irq = new_serial.irq != state->irq; - change_port = (new_port != ((int) state->port)) || - (new_serial.hub6 != state->hub6); - - if (!capable(CAP_SYS_ADMIN)) { - if (change_irq || change_port || - (new_serial.baud_base != state->baud_base) || - (new_serial.type != state->type) || - (new_serial.close_delay != state->close_delay) || - (new_serial.xmit_fifo_size != state->xmit_fifo_size) || - ((new_serial.flags & ~ASYNC_USR_MASK) != - (state->flags & ~ASYNC_USR_MASK))) - return -EPERM; - state->flags = ((state->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - info->flags = ((info->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - state->custom_divisor = new_serial.custom_divisor; - goto check_and_exit; - } - - new_serial.irq = irq_cannonicalize(new_serial.irq); - - if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || - (new_serial.baud_base < 9600)|| (new_serial.type < PORT_UNKNOWN) || - (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) || - (new_serial.type == PORT_STARTECH)) { - return -EINVAL; - } - - if ((new_serial.type != state->type) || - (new_serial.xmit_fifo_size <= 0)) - new_serial.xmit_fifo_size = - uart_config[new_serial.type].dfl_xmit_fifo_size; - - /* Make sure address is not already in use */ - if (new_serial.type) { - for (i = 0 ; i < NR_PORTS; i++) - if ((state != &rs_table[i]) && - (rs_table[i].port == new_port) && - rs_table[i].type) - return -EADDRINUSE; - } - - if ((change_port || change_irq) && (state->count > 1)) - return -EBUSY; - - /* - * OK, past this point, all the error checking has been done. - * At this point, we start making changes..... - */ - - state->baud_base = new_serial.baud_base; - state->flags = ((state->flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS)); - info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | - (info->flags & ASYNC_INTERNAL_FLAGS)); - state->custom_divisor = new_serial.custom_divisor; - state->close_delay = new_serial.close_delay * HZ/100; - state->closing_wait = new_serial.closing_wait * HZ/100; - info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - info->xmit_fifo_size = state->xmit_fifo_size = - new_serial.xmit_fifo_size; - - if ((state->type != PORT_UNKNOWN) && state->port) { - release_region(state->port,8); - } - state->type = new_serial.type; - if (change_port || change_irq) { - /* - * We need to shutdown the serial port at the old - * port/irq combination. - */ - shutdown(info); - state->irq = new_serial.irq; - info->port = state->port = new_port; - info->hub6 = state->hub6 = new_serial.hub6; - if (info->hub6) - info->io_type = state->io_type = SERIAL_IO_HUB6; - else if (info->io_type == SERIAL_IO_HUB6) - info->io_type = state->io_type = SERIAL_IO_PORT; - } - if ((state->type != PORT_UNKNOWN) && state->port) { - request_region(state->port,8,"serial(set)"); - } - - -check_and_exit: - if (!state->port || !state->type) - return 0; - if (info->flags & ASYNC_INITIALIZED) { - if (((old_state.flags & ASYNC_SPD_MASK) != - (state->flags & ASYNC_SPD_MASK)) || - (old_state.custom_divisor != state->custom_divisor)) { - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - info->tty->alt_speed = 57600; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - info->tty->alt_speed = 115200; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - info->tty->alt_speed = 230400; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - info->tty->alt_speed = 460800; - change_speed(info, 0); - } - } else { - retval = startup(info); - } - return retval; -} - - -/* - * get_lsr_info - get line status register info - * - * Purpose: Let user call ioctl() to get info when the UART physically - * is emptied. On bus types like RS485, the transmitter must - * release the bus after transmitting. This must be done when - * the transmit shift register is empty, not be done when the - * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. - */ -static int get_lsr_info(struct async_struct * info, unsigned int *value) -{ - unsigned char status; - unsigned int result; - unsigned long flags; - - save_flags(flags); cli(); - status = serial_in(info, UART_LSR); - restore_flags(flags); - result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); - - /* - * If we're about to load something into the transmit - * register, we'll pretend the transmitter isn't empty to - * avoid a race condition (depending on when the transmit - * interrupt happens). - */ - if (info->x_char || - ((CIRC_CNT(info->xmit.head, info->xmit.tail, - SERIAL_XMIT_SIZE) > 0) && - !info->tty->stopped && !info->tty->hw_stopped)) - result &= TIOCSER_TEMT; - - if (copy_to_user(value, &result, sizeof(int))) - return -EFAULT; - return 0; -} - - -static int get_modem_info(struct async_struct * info, unsigned int *value) -{ - unsigned char control, status; - unsigned int result; - unsigned long flags; - - control = info->MCR; - save_flags(flags); cli(); - status = serial_in(info, UART_MSR); - restore_flags(flags); - result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) - | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) -#ifdef TIOCM_OUT1 - | ((control & UART_MCR_OUT1) ? TIOCM_OUT1 : 0) - | ((control & UART_MCR_OUT2) ? TIOCM_OUT2 : 0) -#endif - | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) - | ((status & UART_MSR_RI) ? TIOCM_RNG : 0) - | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) - | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0); - - if (copy_to_user(value, &result, sizeof(int))) - return -EFAULT; - return 0; -} - -static int set_modem_info(struct async_struct * info, unsigned int cmd, - unsigned int *value) -{ - unsigned int arg; - unsigned long flags; - - if (copy_from_user(&arg, value, sizeof(int))) - return -EFAULT; - - switch (cmd) { - case TIOCMBIS: - if (arg & TIOCM_RTS) - info->MCR |= UART_MCR_RTS; - if (arg & TIOCM_DTR) - info->MCR |= UART_MCR_DTR; -#ifdef TIOCM_OUT1 - if (arg & TIOCM_OUT1) - info->MCR |= UART_MCR_OUT1; - if (arg & TIOCM_OUT2) - info->MCR |= UART_MCR_OUT2; -#endif - if (arg & TIOCM_LOOP) - info->MCR |= UART_MCR_LOOP; - break; - case TIOCMBIC: - if (arg & TIOCM_RTS) - info->MCR &= ~UART_MCR_RTS; - if (arg & TIOCM_DTR) - info->MCR &= ~UART_MCR_DTR; -#ifdef TIOCM_OUT1 - if (arg & TIOCM_OUT1) - info->MCR &= ~UART_MCR_OUT1; - if (arg & TIOCM_OUT2) - info->MCR &= ~UART_MCR_OUT2; -#endif - if (arg & TIOCM_LOOP) - info->MCR &= ~UART_MCR_LOOP; - break; - case TIOCMSET: - info->MCR = ((info->MCR & ~(UART_MCR_RTS | -#ifdef TIOCM_OUT1 - UART_MCR_OUT1 | - UART_MCR_OUT2 | -#endif - UART_MCR_LOOP | - UART_MCR_DTR)) - | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0) -#ifdef TIOCM_OUT1 - | ((arg & TIOCM_OUT1) ? UART_MCR_OUT1 : 0) - | ((arg & TIOCM_OUT2) ? UART_MCR_OUT2 : 0) -#endif - | ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0) - | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0)); - break; - default: - return -EINVAL; - } - save_flags(flags); cli(); - info->MCR |= ALPHA_KLUDGE_MCR; /* Don't ask */ - serial_out(info, UART_MCR, info->MCR); - restore_flags(flags); - return 0; -} - -static int do_autoconfig(struct async_struct * info) -{ - int retval; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (info->state->count > 1) - return -EBUSY; - - shutdown(info); - - autoconfig(info->state); - retval = startup(info); - if (retval) - return retval; - return 0; -} - -/* - * rs_break() --- routine which turns the break handling on or off - */ -static void rs_break(struct tty_struct *tty, int break_state) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_break")) - return; - - if (!CONFIGURED_SERIAL_PORT(info)) - return; - save_flags(flags); cli(); - if (break_state == -1) - info->LCR |= UART_LCR_SBC; - else - info->LCR &= ~UART_LCR_SBC; - serial_out(info, UART_LCR, info->LCR); - restore_flags(flags); -} - - -static int rs_ioctl(struct tty_struct *tty, struct file * file, - unsigned int cmd, unsigned long arg) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct async_icount cprev, cnow; /* kernel counter temps */ - struct serial_icounter_struct icount; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_ioctl")) - return -ENODEV; - - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && - (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - } - - switch (cmd) { - case TIOCMGET: - return get_modem_info(info, (unsigned int *) arg); - case TIOCMBIS: - case TIOCMBIC: - case TIOCMSET: - return set_modem_info(info, cmd, (unsigned int *) arg); - case TIOCGSERIAL: - return get_serial_info(info, - (struct serial_struct *) arg); - case TIOCSSERIAL: - return set_serial_info(info, - (struct serial_struct *) arg); - case TIOCSERCONFIG: - return do_autoconfig(info); - - case TIOCSERGETLSR: /* Get line status register */ - return get_lsr_info(info, (unsigned int *) arg); - - case TIOCSERGSTRUCT: - if (copy_to_user((struct async_struct *) arg, - info, sizeof(struct async_struct))) - return -EFAULT; - return 0; - - - /* - * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - * - mask passed in arg for lines of interest - * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) - * Caller should use TIOCGICOUNT to see which one it was - */ - case TIOCMIWAIT: - save_flags(flags); cli(); - /* note the counters on entry */ - cprev = info->state->icount; - restore_flags(flags); - /* Force modem status interrupts on */ - info->IER |= UART_IER_MSI; - serial_out(info, UART_IER, info->IER); - while (1) { - interruptible_sleep_on(&info->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - save_flags(flags); cli(); - cnow = info->state->icount; /* atomic copy */ - restore_flags(flags); - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) - return -EIO; /* no change => error */ - if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { - return 0; - } - cprev = cnow; - } - /* NOTREACHED */ - - /* - * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) - * Return: write counters to the user passed counter struct - * NB: both 1->0 and 0->1 transitions are counted except for - * RI where only 0->1 is counted. - */ - case TIOCGICOUNT: - save_flags(flags); cli(); - cnow = info->state->icount; - restore_flags(flags); - icount.cts = cnow.cts; - icount.dsr = cnow.dsr; - icount.rng = cnow.rng; - icount.dcd = cnow.dcd; - icount.rx = cnow.rx; - icount.tx = cnow.tx; - icount.frame = cnow.frame; - icount.overrun = cnow.overrun; - icount.parity = cnow.parity; - icount.brk = cnow.brk; - icount.buf_overrun = cnow.buf_overrun; - - if (copy_to_user((void *)arg, &icount, sizeof(icount))) - return -EFAULT; - return 0; - case TIOCSERGWILD: - case TIOCSERSWILD: - /* "setserial -W" is called in Debian boot */ - printk ("TIOCSER?WILD ioctl obsolete, ignored.\n"); - return 0; - - default: - return -ENOIOCTLCMD; - } - return 0; -} - -static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - unsigned int cflag = tty->termios->c_cflag; - - if ( (cflag == old_termios->c_cflag) - && ( RELEVANT_IFLAG(tty->termios->c_iflag) - == RELEVANT_IFLAG(old_termios->c_iflag))) - return; - - change_speed(info, old_termios); - - /* Handle transition to B0 status */ - if ((old_termios->c_cflag & CBAUD) && - !(cflag & CBAUD)) { - info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); - save_flags(flags); cli(); - serial_out(info, UART_MCR, info->MCR); - restore_flags(flags); - } - - /* Handle transition away from B0 status */ - if (!(old_termios->c_cflag & CBAUD) && - (cflag & CBAUD)) { - info->MCR |= UART_MCR_DTR; - if (!(tty->termios->c_cflag & CRTSCTS) || - !test_bit(TTY_THROTTLED, &tty->flags)) { - info->MCR |= UART_MCR_RTS; - } - save_flags(flags); cli(); - serial_out(info, UART_MCR, info->MCR); - restore_flags(flags); - } - - /* Handle turning off CRTSCTS */ - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - rs_start(tty); - } -} - -/* - * ------------------------------------------------------------ - * rs_close() - * - * This routine is called when the serial port gets closed. First, we - * wait for the last remaining data to be sent. Then, we unlink its - * async structure from the interrupt chain if necessary, and we free - * that IRQ if nothing is left in the chain. - * ------------------------------------------------------------ - */ -static void rs_close(struct tty_struct *tty, struct file * filp) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct serial_state *state; - unsigned long flags; - - if (!info || serial_paranoia_check(info, tty->device, "rs_close")) - return; - - state = info->state; - - save_flags(flags); cli(); - - if (tty_hung_up_p(filp)) { - DBG_CNT("before DEC-hung"); - MOD_DEC_USE_COUNT; - restore_flags(flags); - return; - } - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_close ttys%d, count = %d\n", info->line, state->count); -#endif - if ((tty->count == 1) && (state->count != 1)) { - /* - * Uh, oh. tty->count is 1, which means that the tty - * structure will be freed. state->count should always - * be one in these conditions. If it's greater than - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ - printk("rs_close: bad serial port count; tty->count is 1, " - "state->count is %d\n", state->count); - state->count = 1; - } - if (--state->count < 0) { - printk("rs_close: bad serial port count for ttys%d: %d\n", - info->line, state->count); - state->count = 0; - } - if (state->count) { - DBG_CNT("before DEC-2"); - MOD_DEC_USE_COUNT; - restore_flags(flags); - return; - } - info->flags |= ASYNC_CLOSING; - restore_flags(flags); - /* - * Save the termios structure, since this port may have - * separate termios for callout and dialin. - */ - if (info->flags & ASYNC_NORMAL_ACTIVE) - info->state->normal_termios = *tty->termios; - if (info->flags & ASYNC_CALLOUT_ACTIVE) - info->state->callout_termios = *tty->termios; - /* - * Now we wait for the transmit buffer to clear; and we notify - * the line discipline to only process XON/XOFF characters. - */ - tty->closing = 1; - if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) - tty_wait_until_sent(tty, info->closing_wait); - /* - * At this point we stop accepting input. To do this, we - * disable the receive line status interrupts, and tell the - * interrupt driver to stop checking the data ready bit in the - * line status register. - */ - info->IER &= ~UART_IER_RLSI; - info->read_status_mask &= ~UART_LSR_DR; - if (info->flags & ASYNC_INITIALIZED) { - serial_out(info, UART_IER, info->IER); - /* - * Before we drop DTR, make sure the UART transmitter - * has completely drained; this is especially - * important if there is a transmit FIFO! - */ - rs_wait_until_sent(tty, info->timeout); - } - shutdown(info); - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - tty->closing = 0; - info->event = 0; - info->tty = 0; - if (info->blocked_open) { - if (info->close_delay) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(info->close_delay); - } - wake_up_interruptible(&info->open_wait); - } - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE| - ASYNC_CLOSING); - wake_up_interruptible(&info->close_wait); - MOD_DEC_USE_COUNT; -} - -/* - * rs_wait_until_sent() --- wait until the transmitter is empty - */ -static void rs_wait_until_sent(struct tty_struct *tty, int timeout) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - unsigned long orig_jiffies, char_time; - int lsr; - - if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent")) - return; - - if (info->state->type == PORT_UNKNOWN) - return; - - if (info->xmit_fifo_size == 0) - return; /* Just in case.... */ - - orig_jiffies = jiffies; - /* - * Set the check interval to be 1/5 of the estimated time to - * send a single character, and make it at least 1. The check - * interval should also be less than the timeout. - * - * Note: we have to use pretty tight timings here to satisfy - * the NIST-PCTS. - */ - char_time = (info->timeout - HZ/50) / info->xmit_fifo_size; - char_time = char_time / 5; - if (char_time == 0) - char_time = 1; - if (timeout && timeout < char_time) - char_time = timeout; - /* - * If the transmitter hasn't cleared in twice the approximate - * amount of time to send the entire FIFO, it probably won't - * ever clear. This assumes the UART isn't doing flow - * control, which is currently the case. Hence, if it ever - * takes longer than info->timeout, this is probably due to a - * UART bug of some kind. So, we clamp the timeout parameter at - * 2*info->timeout. - */ - if (!timeout || timeout > 2*info->timeout) - timeout = 2*info->timeout; -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time); - printk("jiff=%lu...", jiffies); -#endif - while (!((lsr = serial_inp(info, UART_LSR)) & UART_LSR_TEMT)) { -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("lsr = %d (jiff=%lu)...", lsr, jiffies); -#endif - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(char_time); - if (signal_pending(current)) - break; - if (timeout && time_after(jiffies, orig_jiffies + timeout)) - break; - } - set_current_state(TASK_RUNNING); -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); -#endif -} - -/* - * rs_hangup() --- called by tty_hangup() when a hangup is signaled. - */ -static void rs_hangup(struct tty_struct *tty) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct serial_state *state = info->state; - - if (serial_paranoia_check(info, tty->device, "rs_hangup")) - return; - - state = info->state; - - rs_flush_buffer(tty); - if (info->flags & ASYNC_CLOSING) - return; - shutdown(info); - info->event = 0; - state->count = 0; - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE); - info->tty = 0; - wake_up_interruptible(&info->open_wait); -} - -/* - * ------------------------------------------------------------ - * rs_open() and friends - * ------------------------------------------------------------ - */ -static int block_til_ready(struct tty_struct *tty, struct file * filp, - struct async_struct *info) -{ - DECLARE_WAITQUEUE(wait, current); - struct serial_state *state = info->state; - int retval; - int do_clocal = 0, extra_count = 0; - unsigned long flags; - - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); -#ifdef SERIAL_DO_RESTART - return ((info->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); -#else - return -EAGAIN; -#endif - } - - /* - * If this is a callout device, then just make sure the normal - * device isn't being used. - */ - if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) { - if (info->flags & ASYNC_NORMAL_ACTIVE) - return -EBUSY; - if ((info->flags & ASYNC_CALLOUT_ACTIVE) && - (info->flags & ASYNC_SESSION_LOCKOUT) && - (info->session != current->session)) - return -EBUSY; - if ((info->flags & ASYNC_CALLOUT_ACTIVE) && - (info->flags & ASYNC_PGRP_LOCKOUT) && - (info->pgrp != current->pgrp)) - return -EBUSY; - info->flags |= ASYNC_CALLOUT_ACTIVE; - return 0; - } - - /* - * If non-blocking mode is set, or the port is not enabled, - * then make the check up front and then exit. - */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR))) { - if (info->flags & ASYNC_CALLOUT_ACTIVE) - return -EBUSY; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - if (info->flags & ASYNC_CALLOUT_ACTIVE) { - if (state->normal_termios.c_cflag & CLOCAL) - do_clocal = 1; - } else { - if (tty->termios->c_cflag & CLOCAL) - do_clocal = 1; - } - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, state->count is dropped by one, so that - * rs_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; - add_wait_queue(&info->open_wait, &wait); -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready before block: ttys%d, count = %d\n", - state->line, state->count); -#endif - save_flags(flags); cli(); - if (!tty_hung_up_p(filp)) { - extra_count = 1; - state->count--; - } - restore_flags(flags); - info->blocked_open++; - while (1) { - save_flags(flags); cli(); - if (!(info->flags & ASYNC_CALLOUT_ACTIVE) && - (tty->termios->c_cflag & CBAUD)) - serial_out(info, UART_MCR, - serial_inp(info, UART_MCR) | - (UART_MCR_DTR | UART_MCR_RTS)); - restore_flags(flags); - set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !(info->flags & ASYNC_INITIALIZED)) { -#ifdef SERIAL_DO_RESTART - if (info->flags & ASYNC_HUP_NOTIFY) - retval = -EAGAIN; - else - retval = -ERESTARTSYS; -#else - retval = -EAGAIN; -#endif - break; - } - if (!(info->flags & ASYNC_CALLOUT_ACTIVE) && - !(info->flags & ASYNC_CLOSING) && - (do_clocal || (serial_in(info, UART_MSR) & - UART_MSR_DCD))) - break; - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif - schedule(); - } - set_current_state(TASK_RUNNING); - remove_wait_queue(&info->open_wait, &wait); - if (extra_count) - state->count++; - info->blocked_open--; -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready after blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif - if (retval) - return retval; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; -} - -static int get_async_struct(int line, struct async_struct **ret_info) -{ - struct async_struct *info; - struct serial_state *sstate; - - sstate = rs_table + line; - sstate->count++; - if (sstate->info) { - *ret_info = sstate->info; - return 0; - } - info = kmalloc(sizeof(struct async_struct), GFP_KERNEL); - if (!info) { - sstate->count--; - return -ENOMEM; - } - memset(info, 0, sizeof(struct async_struct)); - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - init_waitqueue_head(&info->delta_msr_wait); - info->magic = SERIAL_MAGIC; - info->port = sstate->port; - info->flags = sstate->flags; - info->io_type = sstate->io_type; - info->iomem_base = sstate->iomem_base; - info->iomem_reg_shift = sstate->iomem_reg_shift; - info->xmit_fifo_size = sstate->xmit_fifo_size; - info->line = line; - info->tqueue.routine = do_softint; - info->tqueue.data = info; - info->state = sstate; - if (sstate->info) { - kfree(info); - *ret_info = sstate->info; - return 0; - } - *ret_info = sstate->info = info; - return 0; -} - -/* - * This routine is called whenever a serial port is opened. It - * enables interrupts for a serial port, linking in its async structure into - * the IRQ chain. It also performs the serial-specific - * initialization for the tty structure. - */ -static int rs_open(struct tty_struct *tty, struct file * filp) -{ - struct async_struct *info; - int retval, line; - unsigned long page; - - MOD_INC_USE_COUNT; - line = MINOR(tty->device) - tty->driver.minor_start; - if ((line < 0) || (line >= NR_PORTS)) { - MOD_DEC_USE_COUNT; - return -ENODEV; - } - retval = get_async_struct(line, &info); - if (retval) { - MOD_DEC_USE_COUNT; - return retval; - } - tty->driver_data = info; - info->tty = tty; - if (serial_paranoia_check(info, tty->device, "rs_open")) { - MOD_DEC_USE_COUNT; - return -ENODEV; - } - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line, - info->state->count); -#endif - info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - - if (!tmp_buf) { - page = get_zeroed_page(GFP_KERNEL); - if (!page) { - MOD_DEC_USE_COUNT; - return -ENOMEM; - } - if (tmp_buf) - free_page(page); - else - tmp_buf = (unsigned char *) page; - } - - /* - * If the port is the middle of closing, bail out now - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); - MOD_DEC_USE_COUNT; -#ifdef SERIAL_DO_RESTART - return ((info->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); -#else - return -EAGAIN; -#endif - } - - /* - * Start up serial port - */ - retval = startup(info); - if (retval) { - MOD_DEC_USE_COUNT; - return retval; - } - - retval = block_til_ready(tty, filp, info); - if (retval) { -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open returning after block_til_ready with %d\n", - retval); -#endif - MOD_DEC_USE_COUNT; - return retval; - } - - if ((info->state->count == 1) && - (info->flags & ASYNC_SPLIT_TERMIOS)) { - if (tty->driver.subtype == SERIAL_TYPE_NORMAL) - *tty->termios = info->state->normal_termios; - else - *tty->termios = info->state->callout_termios; - change_speed(info, 0); - } -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - if (sercons.cflag && sercons.index == line) { - tty->termios->c_cflag = sercons.cflag; - sercons.cflag = 0; - change_speed(info, 0); - } -#endif - info->session = current->session; - info->pgrp = current->pgrp; - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open ttys%d successful...", info->line); -#endif - return 0; -} - -/* - * /proc fs routines.... - */ - -static inline int line_info(char *buf, struct serial_state *state) -{ - struct async_struct *info = state->info, scr_info; - char stat_buf[30], control, status; - int ret; - unsigned long flags; - - ret = sprintf(buf, "%d: uart:%s port:%lX irq:%d", - state->line, uart_config[state->type].name, - state->port, state->irq); - - if (!state->port || (state->type == PORT_UNKNOWN)) { - ret += sprintf(buf+ret, "\n"); - return ret; - } - - /* - * Figure out the current RS-232 lines - */ - if (!info) { - info = &scr_info; /* This is just for serial_{in,out} */ - - info->magic = SERIAL_MAGIC; - info->port = state->port; - info->flags = state->flags; - info->quot = 0; - info->tty = 0; - } - save_flags(flags); cli(); - status = serial_in(info, UART_MSR); - control = info != &scr_info ? info->MCR : serial_in(info, UART_MCR); - restore_flags(flags); - - stat_buf[0] = 0; - stat_buf[1] = 0; - if (control & UART_MCR_RTS) - strcat(stat_buf, "|RTS"); - if (status & UART_MSR_CTS) - strcat(stat_buf, "|CTS"); - if (control & UART_MCR_DTR) - strcat(stat_buf, "|DTR"); - if (status & UART_MSR_DSR) - strcat(stat_buf, "|DSR"); - if (status & UART_MSR_DCD) - strcat(stat_buf, "|CD"); - if (status & UART_MSR_RI) - strcat(stat_buf, "|RI"); - - if (info->quot) { - ret += sprintf(buf+ret, " baud:%d", - state->baud_base / info->quot); - } - - ret += sprintf(buf+ret, " tx:%d rx:%d", - state->icount.tx, state->icount.rx); - - if (state->icount.frame) - ret += sprintf(buf+ret, " fe:%d", state->icount.frame); - - if (state->icount.parity) - ret += sprintf(buf+ret, " pe:%d", state->icount.parity); - - if (state->icount.brk) - ret += sprintf(buf+ret, " brk:%d", state->icount.brk); - - if (state->icount.overrun) - ret += sprintf(buf+ret, " oe:%d", state->icount.overrun); - - /* - * Last thing is the RS-232 status lines - */ - ret += sprintf(buf+ret, " %s\n", stat_buf+1); - return ret; -} - -int rs_read_proc(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - int i, len = 0, l; - off_t begin = 0; - - len += sprintf(page, "serinfo:1.0 driver:%s%s revision:%s\n", - serial_version, LOCAL_VERSTRING, serial_revdate); - for (i = 0; i < NR_PORTS && len < 4000; i++) { - l = line_info(page + len, &rs_table[i]); - len += l; - if (len+begin > off+count) - goto done; - if (len+begin < off) { - begin += len; - len = 0; - } - } - *eof = 1; -done: - if (off >= len+begin) - return 0; - *start = page + (off-begin); - return ((count < begin+len-off) ? count : begin+len-off); -} - -/* - * --------------------------------------------------------------------- - * rs_init() and friends - * - * rs_init() is called at boot-time to initialize the serial driver. - * --------------------------------------------------------------------- - */ - -/* - * This routine prints out the appropriate serial driver version - * number, and identifies which options were configured into this - * driver. - */ -static char serial_options[] __initdata = - " no serial options enabled\n"; -#undef SERIAL_OPT - -static _INLINE_ void show_serial_version(void) -{ - printk(KERN_INFO "%s version %s%s (%s) with%s", serial_name, - serial_version, LOCAL_VERSTRING, serial_revdate, - serial_options); -} - - -/* - * This routine is called by rs_init() to initialize a specific serial - * port. It determines what type of UART chip this serial port is - * using: 8250, 16450, 16550, 16550A. The important question is - * whether or not this UART is a 16550A or not, since this will - * determine whether or not we can use its FIFO features or not. - */ -static void autoconfig(struct serial_state * state) -{ - struct async_struct *info, scr_info; - unsigned long flags; - - -#ifdef SERIAL_DEBUG_AUTOCONF - printk("Testing ttyS%d (0x%04lx, 0x%04x)...\n", state->line, - state->port, (unsigned) state->iomem_base); -#endif - - if (!CONFIGURED_SERIAL_PORT(state)) - return; - - if (au_readl(UART_MOD_CNTRL + state->port) != 0x3) { - au_writel(3, UART_MOD_CNTRL + state->port); - au_sync_delay(10); - } - - state->type = PORT_16550; - info = &scr_info; /* This is just for serial_{in,out} */ - - info->magic = SERIAL_MAGIC; - info->state = state; - info->port = state->port; - info->flags = state->flags; - info->io_type = state->io_type; - info->iomem_base = state->iomem_base; - info->iomem_reg_shift = state->iomem_reg_shift; - - - save_flags(flags); cli(); - state->xmit_fifo_size = uart_config[state->type].dfl_xmit_fifo_size; - - if (info->port) { - request_region(info->port,8,"serial(auto)"); - } - - /* - * Reset the UART. - */ - serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | - UART_FCR_CLEAR_XMIT)); - serial_outp(info, UART_FCR, 0); - (void)serial_in(info, UART_RX); - serial_outp(info, UART_IER, 0); - restore_flags(flags); -} - -int register_serial(struct serial_struct *req); -void unregister_serial(int line); - -EXPORT_SYMBOL(register_serial); -EXPORT_SYMBOL(unregister_serial); - - -/* - * The serial driver boot-time initialization code! - */ -static int __init rs_init(void) -{ - int i; - struct serial_state * state; - - init_bh(SERIAL_BH, do_serial_bh); - init_timer(&serial_timer); - serial_timer.function = rs_timer; - mod_timer(&serial_timer, jiffies + RS_STROBE_TIME); - - for (i = 0; i < NR_IRQS; i++) { - IRQ_ports[i] = 0; - IRQ_timeout[i] = 0; - } -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - /* - * The interrupt of the serial console port - * can't be shared. - */ - if (sercons.flags & CON_CONSDEV) { - for(i = 0; i < NR_PORTS; i++) - if (i != sercons.index && - rs_table[i].irq == rs_table[sercons.index].irq) - rs_table[i].irq = 0; - } -#endif - show_serial_version(); - - /* Initialize the tty_driver structure */ - - memset(&serial_driver, 0, sizeof(struct tty_driver)); - serial_driver.magic = TTY_DRIVER_MAGIC; - serial_driver.driver_name = "serial"; -#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS)) - serial_driver.name = "tts/%d"; -#else - serial_driver.name = "ttyS"; -#endif - serial_driver.major = TTY_MAJOR; - serial_driver.minor_start = 64 + SERIAL_DEV_OFFSET; - serial_driver.num = NR_PORTS; - serial_driver.type = TTY_DRIVER_TYPE_SERIAL; - serial_driver.subtype = SERIAL_TYPE_NORMAL; - serial_driver.init_termios = tty_std_termios; - serial_driver.init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; - serial_driver.refcount = &serial_refcount; - serial_driver.table = serial_table; - serial_driver.termios = serial_termios; - serial_driver.termios_locked = serial_termios_locked; - - serial_driver.open = rs_open; - serial_driver.close = rs_close; - serial_driver.write = rs_write; - serial_driver.put_char = rs_put_char; - serial_driver.flush_chars = rs_flush_chars; - serial_driver.write_room = rs_write_room; - serial_driver.chars_in_buffer = rs_chars_in_buffer; - serial_driver.flush_buffer = rs_flush_buffer; - serial_driver.ioctl = rs_ioctl; - serial_driver.throttle = rs_throttle; - serial_driver.unthrottle = rs_unthrottle; - serial_driver.set_termios = rs_set_termios; - serial_driver.stop = rs_stop; - serial_driver.start = rs_start; - serial_driver.hangup = rs_hangup; - serial_driver.break_ctl = rs_break; - serial_driver.send_xchar = rs_send_xchar; - serial_driver.wait_until_sent = rs_wait_until_sent; - serial_driver.read_proc = rs_read_proc; - - /* - * The callout device is just like normal device except for - * major number and the subtype code. - */ - callout_driver = serial_driver; -#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS)) - callout_driver.name = "cua/%d"; -#else - callout_driver.name = "cua"; -#endif - callout_driver.major = TTYAUX_MAJOR; - callout_driver.subtype = SERIAL_TYPE_CALLOUT; - callout_driver.read_proc = 0; - callout_driver.proc_entry = 0; - - if (tty_register_driver(&serial_driver)) - panic("Couldn't register serial driver"); - if (tty_register_driver(&callout_driver)) - panic("Couldn't register callout driver"); - - for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { - state->baud_base = get_au1000_uart_baud_base(); - state->magic = SSTATE_MAGIC; - state->line = i; - state->type = PORT_UNKNOWN; - state->custom_divisor = 0; - state->close_delay = 5*HZ/10; - state->closing_wait = 30*HZ; - state->callout_termios = callout_driver.init_termios; - state->normal_termios = serial_driver.init_termios; - state->icount.cts = state->icount.dsr = - state->icount.rng = state->icount.dcd = 0; - state->icount.rx = state->icount.tx = 0; - state->icount.frame = state->icount.parity = 0; - state->icount.overrun = state->icount.brk = 0; - state->irq = irq_cannonicalize(state->irq); - if (state->hub6) - state->io_type = SERIAL_IO_HUB6; - if (state->port && check_region(state->port,8)) { - continue; - } - - if (state->flags & ASYNC_BOOT_AUTOCONF) { - autoconfig(state); - } - } - for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { - if (state->type == PORT_UNKNOWN) { - continue; - } - printk(KERN_INFO "ttyS%02d%s at 0x%04lx (irq = %d) is a %s\n", - state->line + SERIAL_DEV_OFFSET, - (state->flags & ASYNC_FOURPORT) ? " FourPort" : "", - state->port, state->irq, - uart_config[state->type].name); - tty_register_devfs(&serial_driver, 0, - serial_driver.minor_start + state->line); - tty_register_devfs(&callout_driver, 0, - callout_driver.minor_start + state->line); - } - return 0; -} - -/* - * register_serial and unregister_serial allows for 16x50 serial ports to be - * configured at run-time, to support PCMCIA modems. - */ - -/** - * register_serial - configure a 16x50 serial port at runtime - * @req: request structure - * - * Configure the serial port specified by the request. If the - * port exists and is in use an error is returned. If the port - * is not currently in the table it is added. - * - * The port is then probed and if neccessary the IRQ is autodetected - * If this fails an error is returned. - * - * On success the port is ready to use and the line number is returned. - */ - -int register_serial(struct serial_struct *req) -{ - int i; - unsigned long flags; - struct serial_state *state; - struct async_struct *info; - unsigned long port; - - port = req->port; - if (HIGH_BITS_OFFSET) - port += (unsigned long) req->port_high << HIGH_BITS_OFFSET; - - save_flags(flags); cli(); - for (i = 0; i < NR_PORTS; i++) { - if ((rs_table[i].port == port) && - (rs_table[i].iomem_base == req->iomem_base)) - break; - } - if (i == NR_PORTS) { - for (i = 0; i < NR_PORTS; i++) - if ((rs_table[i].type == PORT_UNKNOWN) && - (rs_table[i].count == 0)) - break; - } - if (i == NR_PORTS) { - restore_flags(flags); - return -1; - } - state = &rs_table[i]; - if (rs_table[i].count) { - restore_flags(flags); - printk("Couldn't configure serial #%d (port=%ld,irq=%d): " - "device already open\n", i, port, req->irq); - return -1; - } - state->irq = req->irq; - state->port = port; - state->flags = req->flags; - state->io_type = req->io_type; - state->iomem_base = req->iomem_base; - state->iomem_reg_shift = req->iomem_reg_shift; - if (req->baud_base) - state->baud_base = req->baud_base; - if ((info = state->info) != NULL) { - info->port = port; - info->flags = req->flags; - info->io_type = req->io_type; - info->iomem_base = req->iomem_base; - info->iomem_reg_shift = req->iomem_reg_shift; - } - autoconfig(state); - if (state->type == PORT_UNKNOWN) { - restore_flags(flags); - printk("register_serial(): autoconfig failed\n"); - return -1; - } - restore_flags(flags); - - printk(KERN_INFO "ttyS%02d at %s 0x%04lx (irq = %d) is a %s\n", - state->line + SERIAL_DEV_OFFSET, - state->iomem_base ? "iomem" : "port", - state->iomem_base ? (unsigned long)state->iomem_base : - state->port, state->irq, uart_config[state->type].name); - tty_register_devfs(&serial_driver, 0, - serial_driver.minor_start + state->line); - tty_register_devfs(&callout_driver, 0, - callout_driver.minor_start + state->line); - return state->line + SERIAL_DEV_OFFSET; -} - -/** - * unregister_serial - deconfigure a 16x50 serial port - * @line: line to deconfigure - * - * The port specified is deconfigured and its resources are freed. Any - * user of the port is disconnected as if carrier was dropped. Line is - * the port number returned by register_serial(). - */ - -void unregister_serial(int line) -{ - unsigned long flags; - struct serial_state *state = &rs_table[line]; - - save_flags(flags); cli(); - if (state->info && state->info->tty) - tty_hangup(state->info->tty); - state->type = PORT_UNKNOWN; - printk(KERN_INFO "tty%02d unloaded\n", state->line); - /* These will be hidden, because they are devices that will no longer - * be available to the system. (ie, PCMCIA modems, once ejected) - */ - tty_unregister_devfs(&serial_driver, - serial_driver.minor_start + state->line); - tty_unregister_devfs(&callout_driver, - callout_driver.minor_start + state->line); - restore_flags(flags); -} - -static void __exit rs_fini(void) -{ - unsigned long flags; - int e1, e2; - int i; - struct async_struct *info; - - /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ - del_timer_sync(&serial_timer); - save_flags(flags); cli(); - remove_bh(SERIAL_BH); - if ((e1 = tty_unregister_driver(&serial_driver))) - printk("serial: failed to unregister serial driver (%d)\n", - e1); - if ((e2 = tty_unregister_driver(&callout_driver))) - printk("serial: failed to unregister callout driver (%d)\n", - e2); - restore_flags(flags); - - for (i = 0; i < NR_PORTS; i++) { - if ((info = rs_table[i].info)) { - rs_table[i].info = NULL; - kfree(info); - } - if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port) { - release_region(rs_table[i].port, 8); - } - } - if (tmp_buf) { - unsigned long pg = (unsigned long) tmp_buf; - tmp_buf = NULL; - free_page(pg); - } -} - -module_init(rs_init); -module_exit(rs_fini); -MODULE_DESCRIPTION("Au1000 serial driver"); - - -/* - * ------------------------------------------------------------ - * Serial console driver - * ------------------------------------------------------------ - */ -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - -#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) - -static struct async_struct async_sercons; - -/* - * Wait for transmitter & holding register to empty - */ -static inline void wait_for_xmitr(struct async_struct *info) -{ - unsigned int status, tmout = 0xffffff; - - do { - status = serial_in(info, UART_LSR); - - if (status & UART_LSR_BI) - lsr_break_flag = UART_LSR_BI; - - if (--tmout == 0) - break; - } while((status & BOTH_EMPTY) != BOTH_EMPTY); -} - - -/* - * Print a string to the serial port trying not to disturb - * any possible real use of the port... - * - * The console_lock must be held when we get here. - */ -static void serial_console_write(struct console *co, const char *s, - unsigned count) -{ - static struct async_struct *info = &async_sercons; - int ier; - unsigned i; - - /* - * First save the IER then disable the interrupts - */ - ier = serial_in(info, UART_IER); - serial_out(info, UART_IER, 0x00); - - /* - * Now, do each character - */ - for (i = 0; i < count; i++, s++) { - wait_for_xmitr(info); - - /* - * Send the character out. - * If a LF, also do CR... - */ - serial_out(info, UART_TX, *s); - if (*s == 10) { - wait_for_xmitr(info); - serial_out(info, UART_TX, 13); - } - } - - /* - * Finally, Wait for transmitter & holding register to empty - * and restore the IER - */ - wait_for_xmitr(info); - serial_out(info, UART_IER, ier); -} - -static kdev_t serial_console_device(struct console *c) -{ - return MKDEV(TTY_MAJOR, 64 + c->index); -} - -/* - * Setup initial baud/bits/parity. We do two things here: - * - construct a cflag setting for the first rs_open() - * - initialize the serial port - * Return non-zero if we didn't find a serial port. - */ -static int __init serial_console_setup(struct console *co, char *options) -{ - static struct async_struct *info; - struct serial_state *state; - unsigned cval; - int baud = 9600; - int bits = 8; - int parity = 'n'; - int cflag = CREAD | HUPCL | CLOCAL; - int quot = 0; - char *s; - - if (options) { - baud = simple_strtoul(options, NULL, 10); - s = options; - while(*s >= '0' && *s <= '9') - s++; - if (*s) parity = *s++; - if (*s) bits = *s - '0'; - } - - /* - * Now construct a cflag setting. - */ - switch(baud) { - case 1200: - cflag |= B1200; - break; - case 2400: - cflag |= B2400; - break; - case 4800: - cflag |= B4800; - break; - case 19200: - cflag |= B19200; - break; - case 38400: - cflag |= B38400; - break; - case 57600: - cflag |= B57600; - break; - case 115200: - cflag |= B115200; - break; - case 9600: - default: - cflag |= B9600; - break; - } - switch(bits) { - case 7: - cflag |= CS7; - break; - default: - case 8: - cflag |= CS8; - break; - } - switch(parity) { - case 'o': case 'O': - cflag |= PARODD; - break; - case 'e': case 'E': - cflag |= PARENB; - break; - } - co->cflag = cflag; - - /* - * Divisor, bytesize and parity - */ - state = rs_table + co->index; - info = &async_sercons; - info->magic = SERIAL_MAGIC; - info->state = state; - info->port = state->port; - info->flags = state->flags; - info->io_type = state->io_type; - info->iomem_base = state->iomem_base; - info->iomem_reg_shift = state->iomem_reg_shift; - state->baud_base = get_au1000_uart_baud_base(); - quot = state->baud_base / baud; - - cval = cflag & (CSIZE | CSTOPB); - cval >>= 4; - if (cflag & PARENB) - cval |= UART_LCR_PARITY; - if (!(cflag & PARODD)) - cval |= UART_LCR_EPAR; - - /* - * Disable UART interrupts, set DTR and RTS high - * and set speed. - */ - serial_out(info, UART_CLK, quot & 0xffff); - serial_out(info, UART_IER, 0); - serial_out(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS); - - /* - * If we read 0xff from the LSR, there is no UART here. - */ - if (serial_in(info, UART_LSR) == 0xff) - return -1; - - return 0; -} - -static struct console sercons = { - name: "ttyS", - write: serial_console_write, - device: serial_console_device, - setup: serial_console_setup, - flags: CON_PRINTBUFFER, - index: -1, -}; - -/* - * Register console. - */ -void __init au1000_serial_console_init(void) -{ - register_console(&sercons); -} -#endif - -/* - Local variables: - compile-command: "gcc -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -fno-strength-reduce -march=i586 -DMODULE -DMODVERSIONS -include ../../include/linux/modversions.h -DEXPORT_SYMTAB -c serial.c" - End: -*/ diff -urN linux-2.4.21-bk37/arch/mips/au1000/common/setup.c linux-2.4.21-bk38/arch/mips/au1000/common/setup.c --- linux-2.4.21-bk37/arch/mips/au1000/common/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/common/setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,205 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Alchemy Au1x00 board setup. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_AU1X00_SERIAL_CONSOLE) +extern void console_setup(char *, int *); +char serial_console[20]; +#endif + +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +#ifdef CONFIG_BLK_DEV_IDE +extern struct ide_ops std_ide_ops; +extern struct ide_ops *ide_ops; +#endif + +extern struct rtc_ops no_rtc_ops; +extern char * __init prom_getcmdline(void); +extern void __init board_setup(void); +extern void au1000_restart(char *); +extern void au1000_halt(void); +extern void au1000_power_off(void); +extern struct resource ioport_resource; +extern struct resource iomem_resource; +#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_SOC_AU1500) +extern phys_t (*fixup_bigphys_addr)(phys_t phys_addr, phys_t size); +static phys_t au1500_fixup_bigphys_addr(phys_t phys_addr, phys_t size); +#endif + +void __init au1x00_setup(void) +{ + char *argptr; + + /* Various early Au1000 Errata corrected by this */ + set_c0_config(1<<19); /* Config[OD] */ + + board_setup(); /* board specific setup */ + + argptr = prom_getcmdline(); + +#ifdef CONFIG_AU1X00_SERIAL_CONSOLE + if ((argptr = strstr(argptr, "console=")) == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " console=ttyS0,115200"); + } +#endif + +#ifdef CONFIG_FB_AU1100 + if ((argptr = strstr(argptr, "video=")) == NULL) { + argptr = prom_getcmdline(); + /* default panel */ + //strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16"); + strcat(argptr, " video=au1100fb:panel:s10,nohwcursor"); + } +#endif + +#ifdef CONFIG_FB_E1356 + if ((argptr = strstr(argptr, "video=")) == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " video=e1356fb:system:pb1500"); + } +#endif + +#ifdef CONFIG_FB_XPERT98 + if ((argptr = strstr(argptr, "video=")) == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " video=atyfb:1024x768-8@70"); + } +#endif + +#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000) + // au1000 does not support vra, au1500 and au1100 do + strcat(argptr, " au1000_audio=vra"); + argptr = prom_getcmdline(); +#endif + _machine_restart = au1000_restart; + _machine_halt = au1000_halt; + _machine_power_off = au1000_power_off; +#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_SOC_AU1500) + fixup_bigphys_addr = au1500_fixup_bigphys_addr; +#endif + + // IO/MEM resources. + set_io_port_base(0); + ioport_resource.start = IOPORT_RESOURCE_START; + ioport_resource.end = IOPORT_RESOURCE_END; + iomem_resource.start = IOMEM_RESOURCE_START; + iomem_resource.end = IOMEM_RESOURCE_END; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + +#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) +#ifdef CONFIG_USB_OHCI + if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) { + char usb_args[80]; + argptr = prom_getcmdline(); + memset(usb_args, 0, sizeof(usb_args)); + sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d", + USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT); + strcat(argptr, usb_args); + } +#endif + +#ifdef CONFIG_USB_OHCI + // enable host controller and wait for reset done + au_writel(0x08, USB_HOST_CONFIG); + udelay(1000); + au_writel(0x0E, USB_HOST_CONFIG); + udelay(1000); + au_readl(USB_HOST_CONFIG); // throw away first read + while (!(au_readl(USB_HOST_CONFIG) & 0x10)) + au_readl(USB_HOST_CONFIG); +#endif +#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + +#ifdef CONFIG_FB + // Needed if PCI video card in use + conswitchp = &dummy_con; +#endif + +#ifndef CONFIG_SERIAL_NONSTANDARD + /* don't touch the default serial console */ + au_writel(0, UART0_ADDR + UART_CLK); +#endif + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &std_ide_ops; +#endif + + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S); + au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL); + au_sync(); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S); + au_writel(0, SYS_TOYTRIM); +} + +#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_SOC_AU1500) +/* This routine should be valid for all Au1500 based boards */ +static phys_t au1500_fixup_bigphys_addr(phys_t phys_addr, phys_t size) +{ + u32 pci_start = (u32)Au1500_PCI_MEM_START; + u32 pci_end = (u32)Au1500_PCI_MEM_END; + + /* Don't fixup 36 bit addresses */ + if ((phys_addr >> 32) != 0) return phys_addr; + + /* check for pci memory window */ + if ((phys_addr >= pci_start) && ((phys_addr + size) < pci_end)) { + return (phys_t)((phys_addr - pci_start) + + Au1500_PCI_MEM_START); + } + else + return phys_addr; +} +#endif diff -urN linux-2.4.21-bk37/arch/mips/au1000/common/time.c linux-2.4.21-bk38/arch/mips/au1000/common/time.c --- linux-2.4.21-bk37/arch/mips/au1000/common/time.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/common/time.c 2003-08-24 02:55:57.000000000 -0700 @@ -45,7 +45,7 @@ #include extern void startup_match20_interrupt(void); - +extern void do_softirq(void); extern volatile unsigned long wall_jiffies; unsigned long missed_heart_beats = 0; @@ -63,9 +63,11 @@ static unsigned long last_pc0, last_match20; #endif +static spinlock_t time_lock = SPIN_LOCK_UNLOCKED; + static inline void ack_r4ktimer(unsigned long newval) { - write_32bit_cp0_register(CP0_COMPARE, newval); + write_c0_compare(newval); } /* @@ -93,7 +95,7 @@ goto null; do { - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); timerhi += (count < timerlo); /* Wrap around */ timerlo = count; @@ -102,7 +104,7 @@ r4k_cur += r4k_offset; ack_r4ktimer(r4k_cur); - } while (((unsigned long)read_32bit_cp0_register(CP0_COUNT) + } while (((unsigned long)read_c0_count() - r4k_cur) < 0x7fffffff); irq_exit(cpu, irq); @@ -174,7 +176,7 @@ int trim_divide = 16; unsigned long flags; - save_and_cli(flags); + spin_lock_irqsave(&time_lock, flags); counter = au_readl(SYS_COUNTER_CNTRL); au_writel(counter | SYS_CNTRL_EN1, SYS_COUNTER_CNTRL); @@ -193,16 +195,16 @@ while (au_readl(SYS_RTCREAD) < start); /* Start r4k counter. */ - write_32bit_cp0_register(CP0_COUNT, 0); + write_c0_count(0); end = start + (32768 / trim_divide)/2; /* wait 0.5 seconds */ while (end > au_readl(SYS_RTCREAD)); - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); cpu_speed = count * 2; mips_counter_frequency = count; - set_au1000_uart_baud_base(((cpu_speed) / 4) / 16); - restore_flags(flags); + set_au1x00_uart_baud_base(((cpu_speed) / 4) / 16); + spin_unlock_irqrestore(&time_lock, flags); return (cpu_speed / HZ); } @@ -221,11 +223,11 @@ est_freq -= est_freq%10000; printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, (est_freq%1000000)*100/1000000); - set_au1000_speed(est_freq); - set_au1000_lcd_clock(); // program the LCD clock - r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset); + set_au1x00_speed(est_freq); + set_au1x00_lcd_clock(); // program the LCD clock + r4k_cur = (read_c0_count() + r4k_offset); - write_32bit_cp0_register(CP0_COMPARE, r4k_cur); + write_c0_compare(r4k_cur); /* no RTC on the pb1000 */ xtime.tv_sec = 0; @@ -258,7 +260,7 @@ startup_match20_interrupt(); #endif - //set_cp0_status(ALLINTS); + //set_c0_status(ALLINTS); au_sync(); } @@ -266,7 +268,7 @@ #define USECS_PER_JIFFY (1000000/HZ) #define USECS_PER_JIFFY_FRAC (0x100000000*1000000/HZ&0xffffffff) - +#ifndef CONFIG_PM static unsigned long div64_32(unsigned long v1, unsigned long v2, unsigned long v3) { @@ -274,7 +276,7 @@ do_div64_32(r0, v1, v2, v3); return r0; } - +#endif static unsigned long do_fast_gettimeoffset(void) { @@ -326,7 +328,7 @@ } /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; @@ -350,7 +352,7 @@ void do_gettimeofday(struct timeval *tv) { - unsigned int flags; + unsigned long flags; read_lock_irqsave (&xtime_lock, flags); *tv = xtime; @@ -376,7 +378,7 @@ write_lock_irq (&xtime_lock); /* This is revolting. We need to set the xtime.tv_usec correctly. - * However, the value in this location is is value at the last tick. + * However, the value in this location is value at the last tick. * Discover what correction gettimeofday would have done, and then * undo it! */ diff -urN linux-2.4.21-bk37/arch/mips/au1000/common/usbdev.c linux-2.4.21-bk38/arch/mips/au1000/common/usbdev.c --- linux-2.4.21-bk37/arch/mips/au1000/common/usbdev.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/common/usbdev.c 2003-08-24 02:55:57.000000000 -0700 @@ -199,7 +199,7 @@ #if 0 static void -dump_setup(devrequest* s) +dump_setup(struct usb_ctrlrequest* s) { dbg(__FUNCTION__ ": requesttype=%d", s->requesttype); dbg(__FUNCTION__ ": request=%d %s", s->request, @@ -635,9 +635,9 @@ */ static ep0_stage_t -do_get_status(struct usb_dev* dev, devrequest* setup) +do_get_status(struct usb_dev* dev, struct usb_ctrlrequest* setup) { - switch (setup->requesttype) { + switch (setup->bRequestType) { case 0x80: // Device // FIXME: send device status break; @@ -657,9 +657,9 @@ } static ep0_stage_t -do_clear_feature(struct usb_dev* dev, devrequest* setup) +do_clear_feature(struct usb_dev* dev, struct usb_ctrlrequest* setup) { - switch (setup->requesttype) { + switch (setup->bRequestType) { case 0x00: // Device if ((le16_to_cpu(setup->wValue) & 0xff) == 1) dev->remote_wakeup_en = 0; @@ -670,7 +670,7 @@ if ((le16_to_cpu(setup->wValue) & 0xff) == 0) { endpoint_t *ep = epaddr_to_ep(dev, - le16_to_cpu(setup->index) & 0xff); + le16_to_cpu(setup->wIndex) & 0xff); endpoint_unstall(ep); endpoint_reset_datatoggle(ep); @@ -683,7 +683,7 @@ } static ep0_stage_t -do_reserved(struct usb_dev* dev, devrequest* setup) +do_reserved(struct usb_dev* dev, struct usb_ctrlrequest* setup) { // Invalid request, stall End Point 0 endpoint_stall(&dev->ep[0]); @@ -691,9 +691,9 @@ } static ep0_stage_t -do_set_feature(struct usb_dev* dev, devrequest* setup) +do_set_feature(struct usb_dev* dev, struct usb_ctrlrequest* setup) { - switch (setup->requesttype) { + switch (setup->bRequestType) { case 0x00: // Device if ((le16_to_cpu(setup->wValue) & 0xff) == 1) dev->remote_wakeup_en = 1; @@ -701,10 +701,10 @@ endpoint_stall(&dev->ep[0]); break; case 0x02: // End Point - if ((le16_to_cpu(setup->vwValue) & 0xff) == 0) { + if ((le16_to_cpu(setup->wValue) & 0xff) == 0) { endpoint_t *ep = epaddr_to_ep(dev, - le16_to_cpu(setup->index) & 0xff); + le16_to_cpu(setup->wIndex) & 0xff); endpoint_stall(ep); } else @@ -716,7 +716,7 @@ } static ep0_stage_t -do_set_address(struct usb_dev* dev, devrequest* setup) +do_set_address(struct usb_dev* dev, struct usb_ctrlrequest* setup) { int new_state = dev->state; int new_addr = le16_to_cpu(setup->wValue); @@ -743,9 +743,9 @@ } static ep0_stage_t -do_get_descriptor(struct usb_dev* dev, devrequest* setup) +do_get_descriptor(struct usb_dev* dev, struct usb_ctrlrequest* setup) { - int strnum, desc_len = le16_to_cpu(setup->length); + int strnum, desc_len = le16_to_cpu(setup->wLength); switch (le16_to_cpu(setup->wValue) >> 8) { case USB_DT_DEVICE: @@ -812,7 +812,7 @@ } static ep0_stage_t -do_set_descriptor(struct usb_dev* dev, devrequest* setup) +do_set_descriptor(struct usb_dev* dev, struct usb_ctrlrequest* setup) { // TODO: implement // there will be an OUT data stage (the descriptor to set) @@ -820,7 +820,7 @@ } static ep0_stage_t -do_get_configuration(struct usb_dev* dev, devrequest* setup) +do_get_configuration(struct usb_dev* dev, struct usb_ctrlrequest* setup) { // send dev->configuration dbg("sending config"); @@ -830,7 +830,7 @@ } static ep0_stage_t -do_set_configuration(struct usb_dev* dev, devrequest* setup) +do_set_configuration(struct usb_dev* dev, struct usb_ctrlrequest* setup) { // set active config to low-byte of setup->wValue dev->configuration = le16_to_cpu(setup->wValue) & 0xff; @@ -851,10 +851,10 @@ } static ep0_stage_t -do_get_interface(struct usb_dev* dev, devrequest* setup) +do_get_interface(struct usb_dev* dev, struct usb_ctrlrequest* setup) { // interface must be zero. - if ((le16_to_cpu(setup->index) & 0xff) || dev->state == ADDRESS) { + if ((le16_to_cpu(setup->wIndex) & 0xff) || dev->state == ADDRESS) { // FIXME: respond with "request error". how? } else if (dev->state == CONFIGURED) { // send dev->alternate_setting @@ -868,12 +868,12 @@ } static ep0_stage_t -do_set_interface(struct usb_dev* dev, devrequest* setup) +do_set_interface(struct usb_dev* dev, struct usb_ctrlrequest* setup) { if (dev->state == ADDRESS) { // FIXME: respond with "request error". how? } else if (dev->state == CONFIGURED) { - dev->interface = le16_to_cpu(setup->index) & 0xff; + dev->interface = le16_to_cpu(setup->wIndex) & 0xff; dev->alternate_setting = le16_to_cpu(setup->wValue) & 0xff; // interface and alternate_setting must be zero @@ -886,14 +886,14 @@ } static ep0_stage_t -do_synch_frame(struct usb_dev* dev, devrequest* setup) +do_synch_frame(struct usb_dev* dev, struct usb_ctrlrequest* setup) { // TODO return SETUP_STAGE; } typedef ep0_stage_t (*req_method_t)(struct usb_dev* dev, - devrequest* setup); + struct usb_ctrlrequest* setup); /* Table of the standard device request handlers */ @@ -916,25 +916,25 @@ // SETUP packet request dispatcher static void -do_setup (struct usb_dev* dev, devrequest* setup) +do_setup (struct usb_dev* dev, struct usb_ctrlrequest* setup) { req_method_t m; - dbg(__FUNCTION__ ": req %d %s", setup->request, - get_std_req_name(setup->request)); + dbg(__FUNCTION__ ": req %d %s", setup->bRequestType, + get_std_req_name(setup->bRequestType)); - if ((setup->requesttype & USB_TYPE_MASK) != USB_TYPE_STANDARD || - (setup->requesttype & USB_RECIP_MASK) != USB_RECIP_DEVICE) { + if ((setup->bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD || + (setup->bRequestType & USB_RECIP_MASK) != USB_RECIP_DEVICE) { err(__FUNCTION__ ": invalid requesttype 0x%02x", - setup->requesttype); + setup->bRequestType); return; } - if ((setup->requesttype & 0x80) == USB_DIR_OUT && setup->length) - dbg(__FUNCTION__ ": OUT phase! length=%d", setup->length); + if ((setup->bRequestType & 0x80) == USB_DIR_OUT && setup->wLength) + dbg(__FUNCTION__ ": OUT phase! length=%d", setup->wLength); - if (setup->request < sizeof(req_method)/sizeof(req_method_t)) - m = req_method[setup->request]; + if (setup->bRequestType < sizeof(req_method)/sizeof(req_method_t)) + m = req_method[setup->bRequestType]; else m = do_reserved; @@ -973,14 +973,14 @@ vdbg("SU bit is %s in setup stage", (pkt->status & PKT_STATUS_SU) ? "set" : "not set"); - if (pkt->size == sizeof(devrequest)) { + if (pkt->size == sizeof(struct usb_ctrlrequest)) { #ifdef VDEBUG if (pkt->status & PKT_STATUS_ACK) vdbg("received SETUP"); else vdbg("received NAK SETUP"); #endif - do_setup(dev, (devrequest*)pkt->payload); + do_setup(dev, (struct usb_ctrlrequest*)pkt->payload); } else err(__FUNCTION__ ": wrong size SETUP received"); break; diff -urN linux-2.4.21-bk37/arch/mips/au1000/db1x00/Makefile linux-2.4.21-bk38/arch/mips/au1000/db1x00/Makefile --- linux-2.4.21-bk37/arch/mips/au1000/db1x00/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/db1x00/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,22 @@ +# +# Copyright 2000 MontaVista Software Inc. +# Author: MontaVista Software, Inc. +# ppopov@mvista.com or source@mvista.com +# +# Makefile for the Alchemy Semiconductor PB1000 board. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +.S.s: + $(CPP) $(CFLAGS) $< -o $*.s +.S.o: + $(CC) $(CFLAGS) -c $< -o $*.o + +O_TARGET := db1x00.o + +obj-y := init.o board_setup.o irqmap.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/au1000/db1x00/board_setup.c linux-2.4.21-bk38/arch/mips/au1000/db1x00/board_setup.c --- linux-2.4.21-bk37/arch/mips/au1000/db1x00/board_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/db1x00/board_setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,91 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Alchemy Db1x00 board setup. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern struct rtc_ops no_rtc_ops; + +static BCSR * const bcsr = (BCSR *)0xAE000000; + +void __init board_setup(void) +{ + u32 pin_func; + + rtc_ops = &no_rtc_ops; + +#ifdef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB device + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); + au_writel(pin_func, SYS_PINFUNC); +#endif + +#if defined(CONFIG_IRDA) && (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1000)) + /* set IRFIRSEL instead of GPIO15 */ + pin_func = au_readl(SYS_PINFUNC) | (u32)((1<<8)); + au_writel(pin_func, SYS_PINFUNC); + /* power off until the driver is in use */ + bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK; + bcsr->resets |= BCSR_RESETS_IRDA_MODE_OFF; + au_sync(); +#endif + au_writel(0, 0xAE000010); /* turn off pcmcia power */ + +#ifdef CONFIG_MIPS_DB1000 + printk("AMD Alchemy Au1000/Db1000 Board\n"); +#endif +#ifdef CONFIG_MIPS_DB1500 + printk("AMD Alchemy Au1500/Db1500 Board\n"); +#endif +#ifdef CONFIG_MIPS_DB1100 + printk("AMD Alchemy Au1100/Db1100 Board\n"); +#endif +#ifdef CONFIG_MIPS_BOSPORUS + printk("AMD Alchemy Bosporus Board\n"); +#endif +#ifdef CONFIG_MIPS_MIRAGE + printk("AMD Alchemy Mirage Board\n"); +#endif +} diff -urN linux-2.4.21-bk37/arch/mips/au1000/db1x00/init.c linux-2.4.21-bk38/arch/mips/au1000/db1x00/init.c --- linux-2.4.21-bk37/arch/mips/au1000/db1x00/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/db1x00/init.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,77 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * PB1000 board setup + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int prom_argc; +char **prom_argv, **prom_envp; +extern void __init prom_init_cmdline(void); +extern char *prom_getenv(char *envname); + +const char *get_system_type(void) +{ +#ifdef CONFIG_MIPS_BOSPORUS + return "Alchemy Bosporus Gateway Reference"; +#else + return "Alchemy Db1x00"; +#endif +} + +int __init prom_init(int argc, char **argv, char **envp, int *prom_vec) +{ + unsigned char *memsize_str; + unsigned long memsize; + + prom_argc = argc; + prom_argv = argv; + prom_envp = envp; + + mips_machgroup = MACH_GROUP_ALCHEMY; + mips_machtype = MACH_DB1000; /* set the platform # */ + prom_init_cmdline(); + + memsize_str = prom_getenv("memsize"); + if (!memsize_str) { + memsize = 0x04000000; + } else { + memsize = simple_strtol(memsize_str, NULL, 0); + } + add_memory_region(0, memsize, BOOT_MEM_RAM); + return 0; +} diff -urN linux-2.4.21-bk37/arch/mips/au1000/db1x00/irqmap.c linux-2.4.21-bk38/arch/mips/au1000/db1x00/irqmap.c --- linux-2.4.21-bk37/arch/mips/au1000/db1x00/irqmap.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/db1x00/irqmap.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,118 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1xxx irq map table + * + * Copyright 2003 Embedded Edge, LLC + * dan@embeddededge.com + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +au1xxx_irq_map_t au1xxx_irq_map[] = { + { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, +#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_MIRAGE) + { AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, +#endif +#ifndef CONFIG_MIPS_MIRAGE + { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, +#endif + + { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, + +#ifdef CONFIG_SOC_AU1500 + { AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 }, +#endif + +#ifdef CONFIG_MIPS_DB1500 + { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_207, INTC_INT_LOW_LEVEL, 0 }, +#endif + +#ifndef CONFIG_MIPS_MIRAGE + { AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 Fully_Interted# + { AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 STSCHG# + { AU1000_GPIO_2, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 IRQ# + + { AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 1 Fully_Interted# + { AU1000_GPIO_4, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 1 STSCHG# + { AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 1 IRQ# +#endif + { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, + + /* Careful if you change match 2 request! + * The interrupt handler is called directly + * from the low level dispatch code. + */ + { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, +}; + +int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); diff -urN linux-2.4.21-bk37/arch/mips/au1000/mtx-1/Makefile linux-2.4.21-bk38/arch/mips/au1000/mtx-1/Makefile --- linux-2.4.21-bk37/arch/mips/au1000/mtx-1/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/mtx-1/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,23 @@ +# +# Copyright 2003 MontaVista Software Inc. +# Author: MontaVista Software, Inc. +# ppopov@mvista.com or source@mvista.com +# Bruno Randolf +# +# Makefile for 4G Systems MTX-1 board. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +.S.s: + $(CPP) $(CFLAGS) $< -o $*.s +.S.o: + $(CC) $(CFLAGS) -c $< -o $*.o + +O_TARGET := mtx-1.o + +obj-y := init.o board_setup.o irqmap.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/au1000/mtx-1/board_setup.c linux-2.4.21-bk38/arch/mips/au1000/mtx-1/board_setup.c --- linux-2.4.21-bk37/arch/mips/au1000/mtx-1/board_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/mtx-1/board_setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,91 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * MTX-1 board setup. + * + * Copyright 2003 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * Bruno Randolf + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +extern struct rtc_ops no_rtc_ops; + +void __init board_setup(void) +{ + u32 pin_func; + + rtc_ops = &no_rtc_ops; + +#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + +#ifdef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB device + au_writel(au_readl(SYS_PINFUNC) & (u32)(~0x8000), SYS_PINFUNC); +#endif + // enable USB power switch + au_writel( au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR ); + au_writel( 0x100000, GPIO2_OUTPUT ); + +#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE) + + +#ifdef CONFIG_PCI +#if defined(__MIPSEB__) + au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG); +#else + au_writel(0xf, Au1500_PCI_CFG); +#endif +#endif + + // initialize sys_pinfunc: + // disable second ethernet port (SYS_PF_NI2) + // set U3/GPIO23 to GPIO23 (SYS_PF_U3) + au_writel( SYS_PF_NI2 | SYS_PF_U3, SYS_PINFUNC ); + + // initialize GPIO: none used ATM + au_writel( 0xFFFFFFFF, SYS_TRIOUTCLR ); + + // enable LED and set it to green + au_writel( au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR ); + au_writel( 0x18000800, GPIO2_OUTPUT ); + + printk("4G Systems MTX-1 Board\n"); +} diff -urN linux-2.4.21-bk37/arch/mips/au1000/mtx-1/init.c linux-2.4.21-bk38/arch/mips/au1000/mtx-1/init.c --- linux-2.4.21-bk37/arch/mips/au1000/mtx-1/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/mtx-1/init.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,74 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * MTX-1 board setup + * + * Copyright 2003 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * Bruno Randolf + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int prom_argc; +char **prom_argv, **prom_envp; +extern void __init prom_init_cmdline(void); +extern char *prom_getenv(char *envname); + +const char *get_system_type(void) +{ + return "MTX-1"; +} + +int __init prom_init(int argc, char **argv, char **envp, int *prom_vec) +{ + unsigned char *memsize_str; + unsigned long memsize; + + prom_argc = argc; + prom_argv = argv; + prom_envp = envp; + + mips_machgroup = MACH_GROUP_ALCHEMY; + mips_machtype = MACH_MTX1; /* set the platform # */ + prom_init_cmdline(); + + memsize_str = prom_getenv("memsize"); + if (!memsize_str) { + memsize = 0x04000000; + } else { + memsize = simple_strtol(memsize_str, NULL, 0); + } + add_memory_region(0, memsize, BOOT_MEM_RAM); + return 0; +} diff -urN linux-2.4.21-bk37/arch/mips/au1000/mtx-1/irqmap.c linux-2.4.21-bk38/arch/mips/au1000/mtx-1/irqmap.c --- linux-2.4.21-bk37/arch/mips/au1000/mtx-1/irqmap.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/mtx-1/irqmap.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,93 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1xxx irq map table + * + * Copyright 2003 Embedded Edge, LLC + * dan@embeddededge.com + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +au1xxx_irq_map_t au1xxx_irq_map[] = { + { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, + + { AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 }, + + { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, + + { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + + { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 }, + + { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, + + /* Careful if you change match 2 request! + * The interrupt handler is called directly + * from the low level dispatch code. + */ + { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, +}; + +int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); diff -urN linux-2.4.21-bk37/arch/mips/au1000/pb1000/Makefile linux-2.4.21-bk38/arch/mips/au1000/pb1000/Makefile --- linux-2.4.21-bk37/arch/mips/au1000/pb1000/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/pb1000/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -14,8 +14,6 @@ O_TARGET := pb1000.o -obj-y := init.o setup.o - -obj-$(CONFIG_PCI) += pci_fixup.o pci_ops.o +obj-y := init.o board_setup.o irqmap.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/au1000/pb1000/board_setup.c linux-2.4.21-bk38/arch/mips/au1000/pb1000/board_setup.c --- linux-2.4.21-bk37/arch/mips/au1000/pb1000/board_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/pb1000/board_setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,192 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Alchemy Pb1000 board setup. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_USB_OHCI +// Enable the workaround for the OHCI DoneHead +// register corruption problem. +#define CONFIG_AU1000_OHCI_FIX +#endif + +extern struct rtc_ops no_rtc_ops; + +void __init board_setup(void) +{ + u32 pin_func, static_cfg0; + u32 sys_freqctrl, sys_clksrc; + u32 prid = read_c0_prid(); + + rtc_ops = &no_rtc_ops; + + // set AUX clock to 12MHz * 8 = 96 MHz + au_writel(8, SYS_AUXPLL); + au_writel(0, SYS_PINSTATERD); + udelay(100); + +#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + /* zero and disable FREQ2 */ + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* zero and disable USBH/USBD clocks */ + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x00007FE0; + au_writel(sys_clksrc, SYS_CLKSRC); + + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x00007FE0; + + switch (prid & 0x000000FF) + { + case 0x00: /* DA */ + case 0x01: /* HA */ + case 0x02: /* HB */ + /* CPU core freq to 48MHz to slow it way down... */ + au_writel(4, SYS_CPUPLL); + + /* + * Setup 48MHz FREQ2 from CPUPLL for USB Host + */ + /* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */ + sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20)); + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* CPU core freq to 384MHz */ + au_writel(0x20, SYS_CPUPLL); + + printk("Au1000: 48MHz OHCI workaround enabled\n"); + break; + + default: /* HC and newer */ + // FREQ2 = aux/2 = 48 MHz + sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); + au_writel(sys_freqctrl, SYS_FREQCTRL0); + break; + } + + /* + * Route 48MHz FREQ2 into USB Host and/or Device + */ +#ifdef CONFIG_USB_OHCI + sys_clksrc |= ((4<<12) | (0<<11) | (0<<10)); +#endif +#ifdef CONFIG_AU1X00_USB_DEVICE + sys_clksrc |= ((4<<7) | (0<<6) | (0<<5)); +#endif + au_writel(sys_clksrc, SYS_CLKSRC); + + // configure pins GPIO[14:9] as GPIO + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080); + +#ifndef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB host + pin_func |= 0x8000; +#endif + au_writel(pin_func, SYS_PINFUNC); + au_writel(0x2800, SYS_TRIOUTCLR); + au_writel(0x0030, SYS_OUTPUTCLR); +#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + + // make gpio 15 an input (for interrupt line) + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x100); + // we don't need I2S, so make it available for GPIO[31:29] + pin_func |= (1<<5); + au_writel(pin_func, SYS_PINFUNC); + + au_writel(0x8000, SYS_TRIOUTCLR); + + static_cfg0 = au_readl(MEM_STCFG0) & (u32)(~0xc00); + au_writel(static_cfg0, MEM_STCFG0); + + // configure RCE2* for LCD + au_writel(0x00000004, MEM_STCFG2); + + // MEM_STTIME2 + au_writel(0x09000000, MEM_STTIME2); + + // Set 32-bit base address decoding for RCE2* + au_writel(0x10003ff0, MEM_STADDR2); + + // PCI CPLD setup + // expand CE0 to cover PCI + au_writel(0x11803e40, MEM_STADDR1); + + // burst visibility on + au_writel(au_readl(MEM_STCFG0) | 0x1000, MEM_STCFG0); + + au_writel(0x83, MEM_STCFG1); // ewait enabled, flash timing + au_writel(0x33030a10, MEM_STTIME1); // slower timing for FPGA + + /* setup the static bus controller */ + au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */ + au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */ + au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */ + +#ifdef CONFIG_PCI + au_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0 + au_writel(0, SDRAM_MBAR); // set mbar to 0 + au_writel(0x2, SDRAM_CMD); // enable memory accesses + au_sync_delay(1); +#endif + + /* Enable Au1000 BCLK switching - note: sed1356 must not use + * its BCLK (Au1000 LCLK) for any timings */ + switch (prid & 0x000000FF) + { + case 0x00: /* DA */ + case 0x01: /* HA */ + case 0x02: /* HB */ + break; + default: /* HC and newer */ + au_writel(0x00000060, 0xb190003c); + break; + } +} diff -urN linux-2.4.21-bk37/arch/mips/au1000/pb1000/irqmap.c linux-2.4.21-bk38/arch/mips/au1000/pb1000/irqmap.c --- linux-2.4.21-bk37/arch/mips/au1000/pb1000/irqmap.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/pb1000/irqmap.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,96 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1xxx irq map table + * + * Copyright 2003 Embedded Edge, LLC + * dan@embeddededge.com + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +au1xxx_irq_map_t au1xxx_irq_map[] = { + { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_UART2_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_GPIO_15, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, + + { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, + + /* Careful if you change match 2 request! + * The interrupt handler is called directly + * from the low level dispatch code. + */ + { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, +}; + +int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); diff -urN linux-2.4.21-bk37/arch/mips/au1000/pb1000/pci_fixup.c linux-2.4.21-bk38/arch/mips/au1000/pb1000/pci_fixup.c --- linux-2.4.21-bk37/arch/mips/au1000/pb1000/pci_fixup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/pb1000/pci_fixup.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,90 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Board specific pci fixups. - * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include - -#ifdef CONFIG_PCI - -#include -#include -#include -#include - -#include -#include - -#undef DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -void __init pcibios_fixup_resources(struct pci_dev *dev) -{ - /* will need to fixup IO resources */ -} - -void __init pcibios_fixup(void) -{ - unsigned long pci_mem_start = (unsigned long) PCI_MEM_START; - - au_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0 - au_writel(0, SDRAM_MBAR); // set mbar to 0 - au_writel(0x2, SDRAM_CMD); // enable memory accesses - au_sync_delay(1); - - // set extend byte to mbar of ext slot - au_writel(((pci_mem_start >> 24) & 0xff) | - (1 << 8 | 1 << 9 | 1 << 10 | 1 << 27), PCI_BRIDGE_CONFIG); - DBG("Set bridge config to %x\n", au_readl(PCI_BRIDGE_CONFIG)); -} - -void __init pcibios_fixup_irqs(void) -{ - unsigned int slot, func; - unsigned char pin; - struct pci_dev *dev; - - pci_for_each_dev(dev) { - if (dev->bus->number != 0) - return; - - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); - slot = PCI_SLOT(dev->devfn); - func = PCI_FUNC(dev->devfn); - dev->irq = AU1000_GPIO_15; - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); - DBG("slot %d func %d irq %d\n", slot, func, dev->irq); - } -} -unsigned int pcibios_assign_all_busses(void) -{ - return 0; -} -#endif diff -urN linux-2.4.21-bk37/arch/mips/au1000/pb1000/pci_ops.c linux-2.4.21-bk38/arch/mips/au1000/pb1000/pci_ops.c --- linux-2.4.21-bk37/arch/mips/au1000/pb1000/pci_ops.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/pb1000/pci_ops.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,200 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * PB1000 specific pci support. - * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include - -#ifdef CONFIG_PCI - -#include -#include -#include -#include - -#include -#include -#include - -#define PCI_ACCESS_READ 0 -#define PCI_ACCESS_WRITE 1 - -#undef DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -static struct resource pci_io_resource = { - "pci IO space", - PCI_IO_START, - PCI_IO_END, - IORESOURCE_IO -}; - -static struct resource pci_mem_resource = { - "pci memory space", - PCI_MEM_START, - PCI_MEM_END, - IORESOURCE_MEM -}; - -extern struct pci_ops pb1000_pci_ops; - -struct pci_channel mips_pci_channels[] = { - {&pb1000_pci_ops, &pci_io_resource, &pci_mem_resource, 0, 1}, - {(struct pci_ops *) NULL, (struct resource *) NULL, - (struct resource *) NULL, (int) NULL, (int) NULL} -}; - - -/* - * "Bus 2" is really the first and only external slot on the pb1000. - * We'll call that bus 0, and limit the accesses to that single - * external slot only. The SDRAM is already initialized in setup.c. - */ -static int config_access(unsigned char access_type, struct pci_dev *dev, - unsigned char where, u32 * data) -{ - unsigned char bus = dev->bus->number; - unsigned char dev_fn = dev->devfn; - unsigned long config; - - if (((dev_fn >> 3) != 0) || (bus != 0)) { - *data = 0xffffffff; - return -1; - } - - config = PCI_CONFIG_BASE | (where & ~0x3); - - if (access_type == PCI_ACCESS_WRITE) { - au_writel(*data, config); - } else { - *data = au_readl(config); - } - au_sync_udelay(1); - - DBG("config_access: %d bus %d dev_fn %x at %x *data %x, conf %x\n", - access_type, bus, dev_fn, where, *data, config); - - DBG("bridge config reg: %x (%x)\n", au_readl(PCI_BRIDGE_CONFIG), *data); - - if (au_readl(PCI_BRIDGE_CONFIG) & (1 << 16)) { - *data = 0xffffffff; - return -1; - } else { - return PCIBIOS_SUCCESSFUL; - } -} - - -static int read_config_byte(struct pci_dev *dev, int where, u8 * val) -{ - u32 data; - int ret; - - ret = config_access(PCI_ACCESS_READ, dev, where, &data); - *val = data & 0xff; - return ret; -} - - -static int read_config_word(struct pci_dev *dev, int where, u16 * val) -{ - u32 data; - int ret; - - ret = config_access(PCI_ACCESS_READ, dev, where, &data); - *val = data & 0xffff; - return ret; -} - -static int read_config_dword(struct pci_dev *dev, int where, u32 * val) -{ - int ret; - - ret = config_access(PCI_ACCESS_READ, dev, where, val); - return ret; -} - - -static int write_config_byte(struct pci_dev *dev, int where, u8 val) -{ - u32 data = 0; - - if (config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - data = (data & ~(0xff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - - if (config_access(PCI_ACCESS_WRITE, dev, where, &data)) - return -1; - - return PCIBIOS_SUCCESSFUL; -} - -static int write_config_word(struct pci_dev *dev, int where, u16 val) -{ - u32 data = 0; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - data = (data & ~(0xffff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - - if (config_access(PCI_ACCESS_WRITE, dev, where, &data)) - return -1; - - - return PCIBIOS_SUCCESSFUL; -} - -static int write_config_dword(struct pci_dev *dev, int where, u32 val) -{ - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (config_access(PCI_ACCESS_WRITE, dev, where, &val)) - return -1; - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops pb1000_pci_ops = { - read_config_byte, - read_config_word, - read_config_dword, - write_config_byte, - write_config_word, - write_config_dword -}; -#endif /* CONFIG_PCI */ diff -urN linux-2.4.21-bk37/arch/mips/au1000/pb1000/setup.c linux-2.4.21-bk38/arch/mips/au1000/pb1000/setup.c --- linux-2.4.21-bk37/arch/mips/au1000/pb1000/setup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/pb1000/setup.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,302 +0,0 @@ -/* - * - * BRIEF MODULE DESCRIPTION - * Alchemy Pb1000 board setup. - * - * Copyright 2000 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_USB_OHCI -// Enable the workaround for the OHCI DoneHead -// register corruption problem. -#define CONFIG_AU1000_OHCI_FIX -#endif - -#if defined(CONFIG_AU1000_SERIAL_CONSOLE) -extern void console_setup(char *, int *); -char serial_console[20]; -#endif - -#ifdef CONFIG_BLK_DEV_INITRD -extern unsigned long initrd_start, initrd_end; -extern void * __rd_start, * __rd_end; -#endif - -#ifdef CONFIG_BLK_DEV_IDE -extern struct ide_ops std_ide_ops; -extern struct ide_ops *ide_ops; -#endif - -extern struct rtc_ops no_rtc_ops; -extern char * __init prom_getcmdline(void); -extern void au1000_restart(char *); -extern void au1000_halt(void); -extern void au1000_power_off(void); -extern struct resource ioport_resource; -extern struct resource iomem_resource; - -void __init bus_error_init(void) { /* nothing */ } - -void __init au1000_setup(void) -{ - char *argptr; - u32 pin_func, static_cfg0; - u32 sys_freqctrl, sys_clksrc; - u32 prid = read_32bit_cp0_register(CP0_PRID); - - argptr = prom_getcmdline(); - - /* Various early Au1000 Errata corrected by this */ - set_cp0_config(1<<19); /* Config[OD] */ - -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - if ((argptr = strstr(argptr, "console=")) == NULL) { - argptr = prom_getcmdline(); - strcat(argptr, " console=ttyS0,115200"); - } -#endif - - rtc_ops = &no_rtc_ops; - _machine_restart = au1000_restart; - _machine_halt = au1000_halt; - _machine_power_off = au1000_power_off; - - // IO/MEM resources. - set_io_port_base(0); - ioport_resource.start = 0x10000000; - ioport_resource.end = 0xffffffff; - iomem_resource.start = 0x10000000; - iomem_resource.end = 0xffffffff; - -#ifdef CONFIG_BLK_DEV_INITRD - ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); - initrd_start = (unsigned long)&__rd_start; - initrd_end = (unsigned long)&__rd_end; -#endif - - // set AUX clock to 12MHz * 8 = 96 MHz - au_writel(8, SYS_AUXPLL); - au_writel(0, SYS_PINSTATERD); - udelay(100); - -#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE) -#ifdef CONFIG_USB_OHCI - if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) { - char usb_args[80]; - argptr = prom_getcmdline(); - memset(usb_args, 0, sizeof(usb_args)); - sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d", - USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT); - strcat(argptr, usb_args); - } -#endif - - /* zero and disable FREQ2 */ - sys_freqctrl = au_readl(SYS_FREQCTRL0); - sys_freqctrl &= ~0xFFF00000; - au_writel(sys_freqctrl, SYS_FREQCTRL0); - - /* zero and disable USBH/USBD clocks */ - sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x00007FE0; - au_writel(sys_clksrc, SYS_CLKSRC); - - sys_freqctrl = au_readl(SYS_FREQCTRL0); - sys_freqctrl &= ~0xFFF00000; - - sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x00007FE0; - - switch (prid & 0x000000FF) - { - case 0x00: /* DA */ - case 0x01: /* HA */ - case 0x02: /* HB */ - /* CPU core freq to 48MHz to slow it way down... */ - au_writel(4, SYS_CPUPLL); - - /* - * Setup 48MHz FREQ2 from CPUPLL for USB Host - */ - /* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */ - sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20)); - au_writel(sys_freqctrl, SYS_FREQCTRL0); - - /* CPU core freq to 384MHz */ - au_writel(0x20, SYS_CPUPLL); - - printk("Au1000: 48MHz OHCI workaround enabled\n"); - break; - - default: /* HC and newer */ - // FREQ2 = aux/2 = 48 MHz - sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); - au_writel(sys_freqctrl, SYS_FREQCTRL0); - break; - } - - /* - * Route 48MHz FREQ2 into USB Host and/or Device - */ -#ifdef CONFIG_USB_OHCI - sys_clksrc |= ((4<<12) | (0<<11) | (0<<10)); -#endif -#ifdef CONFIG_AU1000_USB_DEVICE - sys_clksrc |= ((4<<7) | (0<<6) | (0<<5)); -#endif - au_writel(sys_clksrc, SYS_CLKSRC); - -#ifdef CONFIG_USB_OHCI - // enable host controller and wait for reset done - au_writel(0x08, USB_HOST_CONFIG); - udelay(1000); - au_writel(0x0E, USB_HOST_CONFIG); - udelay(1000); - au_readl(USB_HOST_CONFIG); // throw away first read - while (!(au_readl(USB_HOST_CONFIG) & 0x10)) - au_readl(USB_HOST_CONFIG); -#endif - - // configure pins GPIO[14:9] as GPIO - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080); - -#ifndef CONFIG_AU1000_USB_DEVICE - // 2nd USB port is USB host - pin_func |= 0x8000; -#endif - au_writel(pin_func, SYS_PINFUNC); - au_writel(0x2800, SYS_TRIOUTCLR); - au_writel(0x0030, SYS_OUTPUTCLR); -#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE) - - // make gpio 15 an input (for interrupt line) - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x100); - // we don't need I2S, so make it available for GPIO[31:29] - pin_func |= (1<<5); - au_writel(pin_func, SYS_PINFUNC); - - au_writel(0x8000, SYS_TRIOUTCLR); - -#ifdef CONFIG_FB - conswitchp = &dummy_con; -#endif - - static_cfg0 = au_readl(MEM_STCFG0) & (u32)(~0xc00); - au_writel(static_cfg0, MEM_STCFG0); - - // configure RCE2* for LCD - au_writel(0x00000004, MEM_STCFG2); - - // MEM_STTIME2 - au_writel(0x09000000, MEM_STTIME2); - - // Set 32-bit base address decoding for RCE2* - au_writel(0x10003ff0, MEM_STADDR2); - - // PCI CPLD setup - // expand CE0 to cover PCI - au_writel(0x11803e40, MEM_STADDR1); - - // burst visibility on - au_writel(au_readl(MEM_STCFG0) | 0x1000, MEM_STCFG0); - - au_writel(0x83, MEM_STCFG1); // ewait enabled, flash timing - au_writel(0x33030a10, MEM_STTIME1); // slower timing for FPGA - - /* setup the static bus controller */ - au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */ - au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */ - au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */ - -#ifdef CONFIG_FB_E1356 - if ((argptr = strstr(argptr, "video=")) == NULL) { - argptr = prom_getcmdline(); - strcat(argptr, " video=e1356fb:system:pb1000,mmunalign:1"); - } -#endif // CONFIG_FB_E1356 - - -#ifdef CONFIG_PCI - au_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0 - au_writel(0, SDRAM_MBAR); // set mbar to 0 - au_writel(0x2, SDRAM_CMD); // enable memory accesses - au_sync_delay(1); -#endif - -#ifndef CONFIG_SERIAL_NONSTANDARD - /* don't touch the default serial console */ - au_writel(0, UART0_ADDR + UART_CLK); -#endif - au_writel(0, UART1_ADDR + UART_CLK); - au_writel(0, UART2_ADDR + UART_CLK); - au_writel(0, UART3_ADDR + UART_CLK); - -#ifdef CONFIG_BLK_DEV_IDE - ide_ops = &std_ide_ops; -#endif - - // setup irda clocks - // aux clock, divide by 2, clock from 2/4 divider - au_writel(au_readl(SYS_CLKSRC) | 0x7, SYS_CLKSRC); - pin_func = au_readl(SYS_PINFUNC) & (u32)(~(1<<2)); // clear IRTXD - au_writel(pin_func, SYS_PINFUNC); - - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S); - au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL); - au_sync(); - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S); - au_writel(0, SYS_TOYTRIM); - - /* Enable Au1000 BCLK switching - note: sed1356 must not use - * its BCLK (Au1000 LCLK) for any timings */ - switch (prid & 0x000000FF) - { - case 0x00: /* DA */ - case 0x01: /* HA */ - case 0x02: /* HB */ - break; - default: /* HC and newer */ - au_writel(0x00000060, 0xb190003c); - break; - } -} diff -urN linux-2.4.21-bk37/arch/mips/au1000/pb1100/Makefile linux-2.4.21-bk38/arch/mips/au1000/pb1100/Makefile --- linux-2.4.21-bk37/arch/mips/au1000/pb1100/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/pb1100/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -10,15 +10,10 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true O_TARGET := pb1100.o -obj-y := init.o setup.o - -obj-$(CONFIG_PCI) += pci_fixup.o pci_ops.o +obj-y := init.o board_setup.o irqmap.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/au1000/pb1100/board_setup.c linux-2.4.21-bk38/arch/mips/au1000/pb1100/board_setup.c --- linux-2.4.21-bk37/arch/mips/au1000/pb1100/board_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/pb1100/board_setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,138 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Alchemy Pb1100 board setup. + * + * Copyright 2002 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_USB_OHCI +// Enable the workaround for the OHCI DoneHead +// register corruption problem. +#define CONFIG_AU1000_OHCI_FIX +#endif + +#ifdef CONFIG_RTC +extern struct rtc_ops pb1500_rtc_ops; +#endif + +void __init board_setup(void) +{ + u32 pin_func; + u32 sys_freqctrl, sys_clksrc; + + // set AUX clock to 12MHz * 8 = 96 MHz + au_writel(8, SYS_AUXPLL); + au_writel(0, SYS_PININPUTEN); + udelay(100); + +#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) +#ifdef CONFIG_USB_OHCI + if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) { + char usb_args[80]; + argptr = prom_getcmdline(); + memset(usb_args, 0, sizeof(usb_args)); + sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d", + USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT); + strcat(argptr, usb_args); + } +#endif + // configure pins GPIO[14:9] as GPIO + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80); + + /* zero and disable FREQ2 */ + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* zero and disable USBH/USBD/IrDA clock */ + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x0000001F; + au_writel(sys_clksrc, SYS_CLKSRC); + + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x0000001F; + + // FREQ2 = aux/2 = 48 MHz + sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* + * Route 48MHz FREQ2 into USBH/USBD/IrDA + */ + sys_clksrc |= ((4<<2) | (0<<1) | 0 ); + au_writel(sys_clksrc, SYS_CLKSRC); + + /* setup the static bus controller */ + au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */ + au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */ + au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */ + + // get USB Functionality pin state (device vs host drive pins) + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); +#ifndef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB host + pin_func |= 0x8000; +#endif + au_writel(pin_func, SYS_PINFUNC); +#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + + au_writel(0x00000060, 0xb190003c); + +#ifdef CONFIG_RTC + rtc_ops = &pb1500_rtc_ops; + // Enable the RTC if not already enabled + if (!(readb(0xac000028) & 0x20)) { + writeb(readb(0xac000028) | 0x20, 0xac000028); + au_sync(); + } + // Put the clock in BCD mode + if (readb(0xac00002C) & 0x4) { /* reg B */ + writeb(readb(0xac00002c) & ~0x4, 0xac00002c); + au_sync(); + } +#endif +} diff -urN linux-2.4.21-bk37/arch/mips/au1000/pb1100/irqmap.c linux-2.4.21-bk38/arch/mips/au1000/pb1100/irqmap.c --- linux-2.4.21-bk37/arch/mips/au1000/pb1100/irqmap.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/pb1100/irqmap.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,100 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1xxx irq map table + * + * Copyright 2003 Embedded Edge, LLC + * dan@embeddededge.com + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +au1xxx_irq_map_t au1xxx_irq_map[] = { + { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_GPIO_9, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card Fully_Interted# + { AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card STSCHG# + { AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card IRQ# + { AU1000_GPIO_13, INTC_INT_LOW_LEVEL, 0 }, // DC_IRQ# + { AU1000_GPIO_23, INTC_INT_LOW_LEVEL, 0 }, // 2-wire SCL + + { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, + + /* Careful if you change match 2 request! + * The interrupt handler is called directly + * from the low level dispatch code. + */ + { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, +}; + +int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); diff -urN linux-2.4.21-bk37/arch/mips/au1000/pb1100/pci_fixup.c linux-2.4.21-bk38/arch/mips/au1000/pb1100/pci_fixup.c --- linux-2.4.21-bk37/arch/mips/au1000/pb1100/pci_fixup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/pb1100/pci_fixup.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,68 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Board specific pci fixups. - * - * Copyright 2002 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include - -#ifdef CONFIG_PCI - -#include -#include -#include -#include - -#include -#include - -#undef DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -static void fixup_resource(int r_num, struct pci_dev *dev) ; -static unsigned long virt_io_addr; - -void __init pcibios_fixup_resources(struct pci_dev *dev) -{ -} - -void __init pcibios_fixup(void) -{ -} - -void __init pcibios_fixup_irqs(void) -{ -} - -unsigned int pcibios_assign_all_busses(void) -{ - return 0; -} - -#endif diff -urN linux-2.4.21-bk37/arch/mips/au1000/pb1100/pci_ops.c linux-2.4.21-bk38/arch/mips/au1000/pb1100/pci_ops.c --- linux-2.4.21-bk37/arch/mips/au1000/pb1100/pci_ops.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/pb1100/pci_ops.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,57 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Pb1100 specific pci support. - * - * Copyright 2002 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include - -#ifdef CONFIG_PCI - -#include -#include -#include -#include - -#include -#include -#include - -#define PCI_ACCESS_READ 0 -#define PCI_ACCESS_WRITE 1 - -#undef DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -struct pci_channel mips_pci_channels[] = { - {(struct pci_ops *) NULL, (struct resource *) NULL, - (struct resource *) NULL, (int) NULL, (int) NULL} -}; - -#endif /* CONFIG_PCI */ diff -urN linux-2.4.21-bk37/arch/mips/au1000/pb1100/setup.c linux-2.4.21-bk38/arch/mips/au1000/pb1100/setup.c --- linux-2.4.21-bk37/arch/mips/au1000/pb1100/setup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/pb1100/setup.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,248 +0,0 @@ -/* - * - * BRIEF MODULE DESCRIPTION - * Alchemy Pb1100 board setup. - * - * Copyright 2002 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_USB_OHCI -// Enable the workaround for the OHCI DoneHead -// register corruption problem. -#define CONFIG_AU1000_OHCI_FIX -#endif - -#if defined(CONFIG_AU1000_SERIAL_CONSOLE) -extern void console_setup(char *, int *); -char serial_console[20]; -#endif - -#ifdef CONFIG_BLK_DEV_INITRD -extern unsigned long initrd_start, initrd_end; -extern void * __rd_start, * __rd_end; -#endif - -#ifdef CONFIG_BLK_DEV_IDE -extern struct ide_ops std_ide_ops; -extern struct ide_ops *ide_ops; -#endif - -#ifdef CONFIG_RTC -extern struct rtc_ops pb1500_rtc_ops; -#endif - -extern char * __init prom_getcmdline(void); -extern void au1000_restart(char *); -extern void au1000_halt(void); -extern void au1000_power_off(void); -extern struct resource ioport_resource; -extern struct resource iomem_resource; - - -void __init bus_error_init(void) { /* nothing */ } - -void __init au1100_setup(void) -{ - char *argptr; - u32 pin_func, static_cfg0; - u32 sys_freqctrl, sys_clksrc; - - argptr = prom_getcmdline(); - - /* NOTE: The memory map is established by YAMON 2.08+ */ - - /* Various early Au1000 Errata corrected by this */ - set_cp0_config(1<<19); /* Config[OD] */ - -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - if ((argptr = strstr(argptr, "console=")) == NULL) { - argptr = prom_getcmdline(); - strcat(argptr, " console=ttyS0,115200"); - } -#endif - -#ifdef CONFIG_SOUND_AU1000 - strcat(argptr, " au1000_audio=vra"); - argptr = prom_getcmdline(); -#endif - - _machine_restart = au1000_restart; - _machine_halt = au1000_halt; - _machine_power_off = au1000_power_off; - - // IO/MEM resources. - set_io_port_base(0); - ioport_resource.start = 0x10000000; - ioport_resource.end = 0xffffffff; - iomem_resource.start = 0x10000000; - iomem_resource.end = 0xffffffff; - -#ifdef CONFIG_BLK_DEV_INITRD - ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); - initrd_start = (unsigned long)&__rd_start; - initrd_end = (unsigned long)&__rd_end; -#endif - - // set AUX clock to 12MHz * 8 = 96 MHz - au_writel(8, SYS_AUXPLL); - au_writel(0, SYS_PININPUTEN); - udelay(100); - -#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE) -#ifdef CONFIG_USB_OHCI - if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) { - char usb_args[80]; - argptr = prom_getcmdline(); - memset(usb_args, 0, sizeof(usb_args)); - sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d", - USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT); - strcat(argptr, usb_args); - } -#endif - // configure pins GPIO[14:9] as GPIO - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80); - - /* zero and disable FREQ2 */ - sys_freqctrl = au_readl(SYS_FREQCTRL0); - sys_freqctrl &= ~0xFFF00000; - au_writel(sys_freqctrl, SYS_FREQCTRL0); - - /* zero and disable USBH/USBD/IrDA clock */ - sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x0000001F; - au_writel(sys_clksrc, SYS_CLKSRC); - - sys_freqctrl = au_readl(SYS_FREQCTRL0); - sys_freqctrl &= ~0xFFF00000; - - sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x0000001F; - - // FREQ2 = aux/2 = 48 MHz - sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); - au_writel(sys_freqctrl, SYS_FREQCTRL0); - - /* - * Route 48MHz FREQ2 into USBH/USBD/IrDA - */ - sys_clksrc |= ((4<<2) | (0<<1) | 0 ); - au_writel(sys_clksrc, SYS_CLKSRC); - - /* setup the static bus controller */ - au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */ - au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */ - au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */ - - // get USB Functionality pin state (device vs host drive pins) - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); -#ifndef CONFIG_AU1000_USB_DEVICE - // 2nd USB port is USB host - pin_func |= 0x8000; -#endif - au_writel(pin_func, SYS_PINFUNC); -#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE) - -#ifdef CONFIG_USB_OHCI - // enable host controller and wait for reset done - au_writel(0x08, USB_HOST_CONFIG); - udelay(1000); - au_writel(0x0c, USB_HOST_CONFIG); - udelay(1000); - au_readl(USB_HOST_CONFIG); - while (!(au_readl(USB_HOST_CONFIG) & 0x10)) - ; - au_readl(USB_HOST_CONFIG); -#endif - -#ifdef CONFIG_FB - conswitchp = &dummy_con; -#endif - -#ifdef CONFIG_FB_AU1100 - if ((argptr = strstr(argptr, "video=")) == NULL) { - argptr = prom_getcmdline(); - /* default panel */ - strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16"); - } -#endif - -#ifdef CONFIG_FB_E1356 - if ((argptr = strstr(argptr, "video=")) == NULL) { - argptr = prom_getcmdline(); - strcat(argptr, " video=e1356fb:system:pb1500"); - } -#endif - -#ifndef CONFIG_SERIAL_NONSTANDARD - /* don't touch the default serial console */ - au_writel(0, UART0_ADDR + UART_CLK); -#endif - au_writel(0, UART1_ADDR + UART_CLK); - au_writel(0, UART3_ADDR + UART_CLK); - -#ifdef CONFIG_BLK_DEV_IDE - ide_ops = &std_ide_ops; -#endif - - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S); - au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL); - au_sync(); - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S); - au_writel(0, SYS_TOYTRIM); - - au_writel(0x00000060, 0xb190003c); - -#ifdef CONFIG_RTC - rtc_ops = &pb1500_rtc_ops; - // Enable the RTC if not already enabled - if (!(readb(0xac000028) & 0x20)) { - writeb(readb(0xac000028) | 0x20, 0xac000028); - au_sync(); - } - // Put the clock in BCD mode - if (readb(0xac00002C) & 0x4) { /* reg B */ - writeb(readb(0xac00002c) & ~0x4, 0xac00002c); - au_sync(); - } -#endif -} diff -urN linux-2.4.21-bk37/arch/mips/au1000/pb1500/Makefile linux-2.4.21-bk38/arch/mips/au1000/pb1500/Makefile --- linux-2.4.21-bk37/arch/mips/au1000/pb1500/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/pb1500/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -14,8 +14,6 @@ O_TARGET := pb1500.o -obj-y := init.o setup.o - -obj-$(CONFIG_PCI) += pci_fixup.o pci_ops.o +obj-y := init.o board_setup.o irqmap.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/au1000/pb1500/board_setup.c linux-2.4.21-bk38/arch/mips/au1000/pb1500/board_setup.c --- linux-2.4.21-bk37/arch/mips/au1000/pb1500/board_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/pb1500/board_setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,151 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Alchemy Pb1500 board setup. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_USB_OHCI +// Enable the workaround for the OHCI DoneHead +// register corruption problem. +#define CONFIG_AU1000_OHCI_FIX +#endif + +#ifdef CONFIG_RTC +extern struct rtc_ops pb1500_rtc_ops; +#endif + +void __init board_setup(void) +{ + u32 pin_func; + u32 sys_freqctrl, sys_clksrc; + + + // set AUX clock to 12MHz * 8 = 96 MHz + au_writel(8, SYS_AUXPLL); + au_writel(0, SYS_PINSTATERD); + udelay(100); + +#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + + /* GPIO201 is input for PCMCIA card detect */ + /* GPIO203 is input for PCMCIA interrupt request */ + au_writel(au_readl(GPIO2_DIR) & (u32)(~((1<<1)|(1<<3))), GPIO2_DIR); + + /* zero and disable FREQ2 */ + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* zero and disable USBH/USBD clocks */ + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x00007FE0; + au_writel(sys_clksrc, SYS_CLKSRC); + + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x00007FE0; + + // FREQ2 = aux/2 = 48 MHz + sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* + * Route 48MHz FREQ2 into USB Host and/or Device + */ +#ifdef CONFIG_USB_OHCI + sys_clksrc |= ((4<<12) | (0<<11) | (0<<10)); +#endif +#ifdef CONFIG_AU1X00_USB_DEVICE + sys_clksrc |= ((4<<7) | (0<<6) | (0<<5)); +#endif + au_writel(sys_clksrc, SYS_CLKSRC); + + + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); +#ifndef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB host + pin_func |= 0x8000; +#endif + au_writel(pin_func, SYS_PINFUNC); +#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + + + +#ifdef CONFIG_PCI + // Setup PCI bus controller + au_writel(0, Au1500_PCI_CMEM); + au_writel(0x00003fff, Au1500_CFG_BASE); +#if defined(__MIPSEB__) + au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG); +#else + au_writel(0xf, Au1500_PCI_CFG); +#endif + au_writel(0xf0000000, Au1500_PCI_MWMASK_DEV); + au_writel(0, Au1500_PCI_MWBASE_REV_CCL); + au_writel(0x02a00356, Au1500_PCI_STATCMD); + au_writel(0x00003c04, Au1500_PCI_HDRTYPE); + au_writel(0x00000008, Au1500_PCI_MBAR); + au_sync(); +#endif + + /* Enable BCLK switching */ + au_writel(0x00000060, 0xb190003c); + +#ifdef CONFIG_RTC + rtc_ops = &pb1500_rtc_ops; + // Enable the RTC if not already enabled + if (!(au_readl(0xac000028) & 0x20)) { + printk("enabling clock ...\n"); + au_writel((au_readl(0xac000028) | 0x20), 0xac000028); + } + // Put the clock in BCD mode + if (readl(0xac00002C) & 0x4) { /* reg B */ + au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c); + au_sync(); + } +#endif +} diff -urN linux-2.4.21-bk37/arch/mips/au1000/pb1500/irqmap.c linux-2.4.21-bk38/arch/mips/au1000/pb1500/irqmap.c --- linux-2.4.21-bk37/arch/mips/au1000/pb1500/irqmap.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/pb1500/irqmap.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,100 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1xxx irq map table + * + * Copyright 2003 Embedded Edge, LLC + * dan@embeddededge.com + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +au1xxx_irq_map_t au1xxx_irq_map[] = { + { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, + + { AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_207, INTC_INT_LOW_LEVEL, 0 }, + + { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, + + /* Careful if you change match 2 request! + * The interrupt handler is called directly + * from the low level dispatch code. + */ + { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, +}; + +int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); diff -urN linux-2.4.21-bk37/arch/mips/au1000/pb1500/pci_fixup.c linux-2.4.21-bk38/arch/mips/au1000/pb1500/pci_fixup.c --- linux-2.4.21-bk37/arch/mips/au1000/pb1500/pci_fixup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/pb1500/pci_fixup.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,119 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Board specific pci fixups. - * - * Copyright 2001,2002 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include - -#ifdef CONFIG_PCI - -#include -#include -#include -#include - -#include -#include - -#undef DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -static void fixup_resource(int r_num, struct pci_dev *dev) ; -static unsigned long virt_io_addr; - -void __init pcibios_fixup_resources(struct pci_dev *dev) -{ - /* will need to fixup IO resources */ -} - -void __init pcibios_fixup(void) -{ - int i; - struct pci_dev *dev; - - virt_io_addr = (unsigned long)ioremap(Au1500_PCI_IO_START, - Au1500_PCI_IO_END - Au1500_PCI_IO_START + 1); - - if (!virt_io_addr) { - printk(KERN_ERR "Unable to ioremap pci space\n"); - return; - } - - pci_for_each_dev(dev) { - for (i=0; i < DEVICE_COUNT_RESOURCE; i++) { - if (dev->resource[i].start) { - fixup_resource(i, dev); - } - } - } -} - -void __init pcibios_fixup_irqs(void) -{ - unsigned int slot, func; - unsigned char pin; - struct pci_dev *dev; - - pci_for_each_dev(dev) { - if (dev->bus->number != 0) - return; - - dev->irq = 0xff; - slot = PCI_SLOT(dev->devfn); - switch (slot) { - case 12: - case 13: - dev->irq = AU1000_PCI_INTA; - break; - - } - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); - DBG("slot %d irq %d\n", slot, dev->irq); - } -} -unsigned int pcibios_assign_all_busses(void) -{ - return 0; -} - -static void fixup_resource(int r_num, struct pci_dev *dev) -{ - unsigned long start, size, new_start; - - if (dev->resource[r_num].flags & IORESOURCE_IO) { - start = dev->resource[r_num].start; - size = dev->resource[r_num].end - start; - new_start = virt_io_addr + (start - Au1500_PCI_IO_START); - dev->resource[r_num].start = new_start; - dev->resource[r_num].end = new_start + size; - } -} - -#endif diff -urN linux-2.4.21-bk37/arch/mips/au1000/pb1500/pci_ops.c linux-2.4.21-bk38/arch/mips/au1000/pb1500/pci_ops.c --- linux-2.4.21-bk37/arch/mips/au1000/pb1500/pci_ops.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/pb1500/pci_ops.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,241 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Pb1500 specific pci support. - * - * Copyright 2001,2002 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include - -#ifdef CONFIG_PCI - -#include -#include -#include -#include - -#include -#include -#include - -#define PCI_ACCESS_READ 0 -#define PCI_ACCESS_WRITE 1 - -#undef DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -/* TBD */ -static struct resource pci_io_resource = { - "pci IO space", - Au1500_PCI_IO_START, - Au1500_PCI_IO_END, - IORESOURCE_IO -}; - -static struct resource pci_mem_resource = { - "pci memory space", - Au1500_PCI_MEM_START, - Au1500_PCI_MEM_END, - IORESOURCE_MEM -}; - -extern struct pci_ops pb1500_pci_ops; - -struct pci_channel mips_pci_channels[] = { - {&pb1500_pci_ops, &pci_io_resource, &pci_mem_resource, (10<<3),(16<<3)}, - {(struct pci_ops *) NULL, (struct resource *) NULL, - (struct resource *) NULL, (int) NULL, (int) NULL} -}; - -static unsigned long cfg_addr; -static int config_access(unsigned char access_type, struct pci_dev *dev, - unsigned char where, u32 * data) -{ - unsigned char bus = dev->bus->number; - unsigned int dev_fn = dev->devfn; - unsigned int device, function; - unsigned long config, status; - static int first = 1; - - /* - * 7:3 = slot - * 2:0 = function - */ - - if (bus != 0) { - *data = 0xffffffff; - return -1; - } - - if (first) { - first = 0; - cfg_addr = ioremap(Au1500_EXT_CFG, 0x10000000); - if (!cfg_addr) - printk (KERN_ERR "PCI unable to ioremap cfg space\n"); - } - - device = (dev_fn >> 3) & 0x1f; - function = dev_fn & 0x7; - -#if 1 - //if (!cfg_addr || (device < 10) || (device > 16)) { - if (!cfg_addr || (device > 16)) { - *data = 0xffffffff; - return -1; - } -#endif - - au_writel(((0x2000 << 16) | (au_readl(Au1500_PCI_STATCMD) & 0xffff)), - Au1500_PCI_STATCMD); - //au_writel(au_readl(Au1500_PCI_CFG) & ~PCI_ERROR, Au1500_PCI_CFG); - au_sync_udelay(1); - - /* setup the lower 31 bits of the 36 bit address */ - config = cfg_addr | - ((1<> 28) & 0xf) { - DBG("PCI ERR detected: status %x\n", status); - *data = 0xffffffff; - return -1; - } - else { - return PCIBIOS_SUCCESSFUL; - } -} - - -static int read_config_byte(struct pci_dev *dev, int where, u8 * val) -{ - u32 data; - int ret; - - ret = config_access(PCI_ACCESS_READ, dev, where, &data); - if (where & 1) data >>= 8; - if (where & 2) data >>= 16; - *val = data & 0xff; - return ret; -} - - -static int read_config_word(struct pci_dev *dev, int where, u16 * val) -{ - u32 data; - int ret; - - ret = config_access(PCI_ACCESS_READ, dev, where, &data); - if (where & 2) data >>= 16; - *val = data & 0xffff; - return ret; -} - -static int read_config_dword(struct pci_dev *dev, int where, u32 * val) -{ - int ret; - - ret = config_access(PCI_ACCESS_READ, dev, where, val); - return ret; -} - - -static int write_config_byte(struct pci_dev *dev, int where, u8 val) -{ - u32 data = 0; - - if (config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - data = (data & ~(0xff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - - if (config_access(PCI_ACCESS_WRITE, dev, where, &data)) - return -1; - - return PCIBIOS_SUCCESSFUL; -} - -static int write_config_word(struct pci_dev *dev, int where, u16 val) -{ - u32 data = 0; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - data = (data & ~(0xffff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - - if (config_access(PCI_ACCESS_WRITE, dev, where, &data)) - return -1; - - - return PCIBIOS_SUCCESSFUL; -} - -static int write_config_dword(struct pci_dev *dev, int where, u32 val) -{ - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (config_access(PCI_ACCESS_WRITE, dev, where, &val)) - return -1; - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops pb1500_pci_ops = { - read_config_byte, - read_config_word, - read_config_dword, - write_config_byte, - write_config_word, - write_config_dword -}; -#endif /* CONFIG_PCI */ diff -urN linux-2.4.21-bk37/arch/mips/au1000/pb1500/setup.c linux-2.4.21-bk38/arch/mips/au1000/pb1500/setup.c --- linux-2.4.21-bk37/arch/mips/au1000/pb1500/setup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/pb1500/setup.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,261 +0,0 @@ -/* - * - * BRIEF MODULE DESCRIPTION - * Alchemy Pb1000 board setup. - * - * Copyright 2000 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_USB_OHCI -// Enable the workaround for the OHCI DoneHead -// register corruption problem. -#define CONFIG_AU1000_OHCI_FIX -#endif - -#if defined(CONFIG_AU1000_SERIAL_CONSOLE) -extern void console_setup(char *, int *); -char serial_console[20]; -#endif - -#ifdef CONFIG_BLK_DEV_INITRD -extern unsigned long initrd_start, initrd_end; -extern void * __rd_start, * __rd_end; -#endif - -#ifdef CONFIG_BLK_DEV_IDE -extern struct ide_ops std_ide_ops; -extern struct ide_ops *ide_ops; -#endif - -#ifdef CONFIG_RTC -extern struct rtc_ops pb1500_rtc_ops; -#endif - -extern char * __init prom_getcmdline(void); -extern void au1000_restart(char *); -extern void au1000_halt(void); -extern void au1000_power_off(void); -extern struct resource ioport_resource; -extern struct resource iomem_resource; - - -void __init bus_error_init(void) { /* nothing */ } - -void __init au1500_setup(void) -{ - char *argptr; - u32 pin_func, static_cfg0; - u32 sys_freqctrl, sys_clksrc; - - argptr = prom_getcmdline(); - - /* NOTE: The memory map is established by YAMON 2.08+ */ - - /* Various early Au1500 Errata corrected by this */ - set_cp0_config(1<<19); /* Config[OD] */ - -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - if ((argptr = strstr(argptr, "console=")) == NULL) { - argptr = prom_getcmdline(); - strcat(argptr, " console=ttyS0,115200"); - } -#endif - -#ifdef CONFIG_SOUND_AU1000 - strcat(argptr, " au1000_audio=vra"); - argptr = prom_getcmdline(); -#endif - - _machine_restart = au1000_restart; - _machine_halt = au1000_halt; - _machine_power_off = au1000_power_off; - - // IO/MEM resources. - set_io_port_base(0); - ioport_resource.start = 0x10000000; - ioport_resource.end = 0xffffffff; - iomem_resource.start = 0x10000000; - iomem_resource.end = 0xffffffff; - -#ifdef CONFIG_BLK_DEV_INITRD - ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); - initrd_start = (unsigned long)&__rd_start; - initrd_end = (unsigned long)&__rd_end; -#endif - - // set AUX clock to 12MHz * 8 = 96 MHz - au_writel(8, SYS_AUXPLL); - au_writel(0, SYS_PINSTATERD); - udelay(100); - -#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE) -#ifdef CONFIG_USB_OHCI - if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) { - char usb_args[80]; - argptr = prom_getcmdline(); - memset(usb_args, 0, sizeof(usb_args)); - sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d", - USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT); - strcat(argptr, usb_args); - } -#endif - - /* zero and disable FREQ2 */ - sys_freqctrl = au_readl(SYS_FREQCTRL0); - sys_freqctrl &= ~0xFFF00000; - au_writel(sys_freqctrl, SYS_FREQCTRL0); - - /* zero and disable USBH/USBD clocks */ - sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x00007FE0; - au_writel(sys_clksrc, SYS_CLKSRC); - - sys_freqctrl = au_readl(SYS_FREQCTRL0); - sys_freqctrl &= ~0xFFF00000; - - sys_clksrc = au_readl(SYS_CLKSRC); - sys_clksrc &= ~0x00007FE0; - - // FREQ2 = aux/2 = 48 MHz - sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); - au_writel(sys_freqctrl, SYS_FREQCTRL0); - - /* - * Route 48MHz FREQ2 into USB Host and/or Device - */ -#ifdef CONFIG_USB_OHCI - sys_clksrc |= ((4<<12) | (0<<11) | (0<<10)); -#endif -#ifdef CONFIG_AU1000_USB_DEVICE - sys_clksrc |= ((4<<7) | (0<<6) | (0<<5)); -#endif - au_writel(sys_clksrc, SYS_CLKSRC); - - - pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); -#ifndef CONFIG_AU1000_USB_DEVICE - // 2nd USB port is USB host - pin_func |= 0x8000; -#endif - au_writel(pin_func, SYS_PINFUNC); -#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE) - - -#ifdef CONFIG_USB_OHCI - // enable host controller and wait for reset done - au_writel(0x08, USB_HOST_CONFIG); - udelay(1000); - au_writel(0x0c, USB_HOST_CONFIG); - udelay(1000); - au_readl(USB_HOST_CONFIG); - while (!(au_readl(USB_HOST_CONFIG) & 0x10)) - ; - au_readl(USB_HOST_CONFIG); -#endif - -#ifdef CONFIG_FB - conswitchp = &dummy_con; -#endif - -#ifdef CONFIG_FB_E1356 - if ((argptr = strstr(argptr, "video=")) == NULL) { - argptr = prom_getcmdline(); - strcat(argptr, " video=e1356fb:system:pb1500"); - } -#elif defined (CONFIG_FB_XPERT98) - if ((argptr = strstr(argptr, "video=")) == NULL) { - argptr = prom_getcmdline(); - strcat(argptr, " video=atyfb:1024x768-8@70"); - } -#endif // CONFIG_FB_E1356 - -#ifndef CONFIG_SERIAL_NONSTANDARD - /* don't touch the default serial console */ - au_writel(0, UART0_ADDR + UART_CLK); -#endif - au_writel(0, UART3_ADDR + UART_CLK); - -#ifdef CONFIG_BLK_DEV_IDE - ide_ops = &std_ide_ops; -#endif - -#ifdef CONFIG_PCI - // Setup PCI bus controller - au_writel(0, Au1500_PCI_CMEM); - au_writel(0x00003fff, Au1500_CFG_BASE); -#if defined(__MIPSEB__) - au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG); -#else - au_writel(0xf, Au1500_PCI_CFG); -#endif - au_writel(0xf0000000, Au1500_PCI_MWMASK_DEV); - au_writel(0, Au1500_PCI_MWBASE_REV_CCL); - au_writel(0x02a00356, Au1500_PCI_STATCMD); - au_writel(0x00003c04, Au1500_PCI_HDRTYPE); - au_writel(0x00000008, Au1500_PCI_MBAR); - au_sync(); -#endif - - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S); - au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL); - au_sync(); - while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S); - au_writel(0, SYS_TOYTRIM); - - /* Enable BCLK switching */ - au_writel(0x00000060, 0xb190003c); - -#ifdef CONFIG_RTC - rtc_ops = &pb1500_rtc_ops; - // Enable the RTC if not already enabled - if (!(au_readl(0xac000028) & 0x20)) { - printk("enabling clock ...\n"); - au_writel((au_readl(0xac000028) | 0x20), 0xac000028); - } - // Put the clock in BCD mode - if (readl(0xac00002C) & 0x4) { /* reg B */ - au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c); - au_sync(); - } -#endif -} diff -urN linux-2.4.21-bk37/arch/mips/au1000/xxs1500/Makefile linux-2.4.21-bk38/arch/mips/au1000/xxs1500/Makefile --- linux-2.4.21-bk37/arch/mips/au1000/xxs1500/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/xxs1500/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,22 @@ +# +# Copyright 2003 MontaVista Software Inc. +# Author: MontaVista Software, Inc. +# ppopov@mvista.com or source@mvista.com +# +# Makefile for MyCable XXS1500 board. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +.S.s: + $(CPP) $(CFLAGS) $< -o $*.s +.S.o: + $(CC) $(CFLAGS) -c $< -o $*.o + +O_TARGET := xxs1500.o + +obj-y := init.o board_setup.o irqmap.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/au1000/xxs1500/board_setup.c linux-2.4.21-bk38/arch/mips/au1000/xxs1500/board_setup.c --- linux-2.4.21-bk37/arch/mips/au1000/xxs1500/board_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/xxs1500/board_setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,94 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * MyCable XXS1500 board setup. + * + * Copyright 2000-2003 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +extern struct rtc_ops no_rtc_ops; + +void __init board_setup(void) +{ + u32 pin_func; + + rtc_ops = &no_rtc_ops; + + // set multiple use pins (UART3/GPIO) to UART (it's used as UART too) + pin_func = au_readl(SYS_PINFUNC) & (u32)(~SYS_PF_UR3); + pin_func |= SYS_PF_UR3; + au_writel(pin_func, SYS_PINFUNC); + + // enable UART + au_writel(0x01, UART3_ADDR+UART_MOD_CNTRL); // clock enable (CE) + mdelay(10); + au_writel(0x03, UART3_ADDR+UART_MOD_CNTRL); // CE and "enable" + mdelay(10); + + // enable DTR = USB power up + au_writel(0x01, UART3_ADDR+UART_MCR); //? UART_MCR_DTR is 0x01??? + +#ifdef CONFIG_PCMCIA_XXS1500 + /* setup pcmcia signals */ + au_writel(0, SYS_PININPUTEN); + + /* gpio 0, 1, and 4 are inputs */ + au_writel(1 | (1<<1) | (1<<4), SYS_TRIOUTCLR); + + /* enable GPIO2 if not already enabled */ + au_writel(1, GPIO2_ENABLE); + /* gpio2 208/9/10/11 are inputs */ + au_writel((1<<8) | (1<<9) | (1<<10) | (1<<11), GPIO2_DIR); + + /* turn off power */ + au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<14))|(1<<30), GPIO2_OUTPUT); +#endif + + +#ifdef CONFIG_PCI +#if defined(__MIPSEB__) + au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG); +#else + au_writel(0xf, Au1500_PCI_CFG); +#endif +#endif +} diff -urN linux-2.4.21-bk37/arch/mips/au1000/xxs1500/init.c linux-2.4.21-bk38/arch/mips/au1000/xxs1500/init.c --- linux-2.4.21-bk37/arch/mips/au1000/xxs1500/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/xxs1500/init.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,73 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * XXS1500 board setup + * + * Copyright 2003 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int prom_argc; +char **prom_argv, **prom_envp; +extern void __init prom_init_cmdline(void); +extern char *prom_getenv(char *envname); + +const char *get_system_type(void) +{ + return "XXS1500"; +} + +int __init prom_init(int argc, char **argv, char **envp, int *prom_vec) +{ + unsigned char *memsize_str; + unsigned long memsize; + + prom_argc = argc; + prom_argv = argv; + prom_envp = envp; + + mips_machgroup = MACH_GROUP_ALCHEMY; + mips_machtype = MACH_XXS1500; /* set the platform # */ + prom_init_cmdline(); + + memsize_str = prom_getenv("memsize"); + if (!memsize_str) { + memsize = 0x04000000; + } else { + memsize = simple_strtol(memsize_str, NULL, 0); + } + add_memory_region(0, memsize, BOOT_MEM_RAM); + return 0; +} diff -urN linux-2.4.21-bk37/arch/mips/au1000/xxs1500/irqmap.c linux-2.4.21-bk38/arch/mips/au1000/xxs1500/irqmap.c --- linux-2.4.21-bk37/arch/mips/au1000/xxs1500/irqmap.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/au1000/xxs1500/irqmap.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,106 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1xxx irq map table + * + * Copyright 2003 Embedded Edge, LLC + * dan@embeddededge.com + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +au1xxx_irq_map_t au1xxx_irq_map[] = { + { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0}, + + { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_207, INTC_INT_LOW_LEVEL, 0 }, + + { AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_GPIO_2, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, + { AU1000_GPIO_4, INTC_INT_LOW_LEVEL, 0 }, /* CF interrupt */ + { AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, + + { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, + { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, + + /* Careful if you change match 2 request! + * The interrupt handler is called directly + * from the low level dispatch code. + */ + { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, +}; + +int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); diff -urN linux-2.4.21-bk37/arch/mips/baget/Makefile linux-2.4.21-bk38/arch/mips/baget/Makefile --- linux-2.4.21-bk37/arch/mips/baget/Makefile 2001-04-13 20:26:07.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/baget/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -8,14 +8,13 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -all: baget.a +all: baget.a O_TARGET := baget.a -export-objs := vacserial.o vacrtc.o +export-objs := vacrtc.o obj-y := baget.o print.o setup.o time.o irq.o bagetIRQ.o \ - reset.o wbflush.o -obj-$(CONFIG_SERIAL) += vacserial.o + reset.o obj-$(CONFIG_VAC_RTC) += vacrtc.o bagetIRQ.o : bagetIRQ.S @@ -39,7 +38,7 @@ dummy.o: dummy.c image.bin ramdisk.bin $(CC) $(CFLAGS) -c -o $@ $< $(OBJCOPY) --add-section=.vmlinux=image.bin \ - --add-section=.ramdisk=ramdisk.bin $@ + --add-section=.ramdisk=ramdisk.bin $@ balo.h: image $(NM) $< | awk ' \ @@ -50,13 +49,13 @@ /balo_ramdisk_size/ { printf "#define RAMDISK_SIZE 0x%s\n", $$1 } \ ' > $@ balo.o: balo.c balo.h - $(CC) $(CFLAGS) -c $< + $(CC) $(CFLAGS) -c $< balo_supp.o: balo_supp.S $(CC) $(CFLAGS) -c $< balo: balo.o dummy.o balo_supp.o print.o - $(LD) $(LDFLAGS) -T ld.script.balo -o $@ $^ + $(LD) $(LDFLAGS) -T ld.script.balo -o $@ $^ clean: rm -f balo balo.h dummy.c image image.bin diff -urN linux-2.4.21-bk37/arch/mips/baget/baget.c linux-2.4.21-bk38/arch/mips/baget/baget.c --- linux-2.4.21-bk37/arch/mips/baget/baget.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/baget/baget.c 2003-08-24 02:55:57.000000000 -0700 @@ -20,7 +20,7 @@ * Following code is based on routines from 'mm/vmalloc.c' * Additional parameters ioaddr is needed to iterate across real I/O address. */ -static inline int alloc_area_pte(pte_t * pte, unsigned long address, +static inline int alloc_area_pte(pte_t * pte, unsigned long address, unsigned long size, unsigned long ioaddr) { unsigned long end; @@ -35,7 +35,7 @@ printk("kseg2_alloc_io: page already exists\n"); /* * For MIPS looks pretty to have transparent mapping - * for KSEG2 areas -- user can't access one, and no + * for KSEG2 areas -- user can't access one, and no * problems with virtual <--> physical translation. */ page = ioaddr & PAGE_MASK; @@ -49,7 +49,7 @@ return 0; } -static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address, +static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, unsigned long ioaddr) { unsigned long end; diff -urN linux-2.4.21-bk37/arch/mips/baget/bagetIRQ.S linux-2.4.21-bk38/arch/mips/baget/bagetIRQ.S --- linux-2.4.21-bk37/arch/mips/baget/bagetIRQ.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/baget/bagetIRQ.S 2003-08-24 02:55:57.000000000 -0700 @@ -24,28 +24,28 @@ .set push .set noreorder jal a1 - .set pop - move a0, sp + .set pop + move a0, sp la a1, ret_from_irq jr a1 END(bagetIRQ) - + #define DBE_HANDLER 0x1C - + NESTED(try_read, PT_SIZE, sp) mfc0 t3, CP0_STATUS # save flags and CLI # disable interrupts li t0, KSEG2 - sltu t1, t0, a0 # Is it KSEG2 address ? - beqz t1, mapped # No - already mapped ! - - move t0, a0 + sltu t1, t0, a0 # Is it KSEG2 address ? + beqz t1, mapped # No - already mapped ! + + move t0, a0 ori t0, 0xfff xori t0, 0xfff # round address to page - ori t1, t0, 0xf00 # prepare EntryLo (N,V,D,G) + ori t1, t0, 0xf00 # prepare EntryLo (N,V,D,G) mfc0 t2, CP0_ENTRYHI # save ASID value mtc0 zero, CP0_INDEX @@ -56,15 +56,15 @@ tlbwi # ... and write ones nop nop - mtc0 t2, CP0_ENTRYHI - -mapped: + mtc0 t2, CP0_ENTRYHI + +mapped: la t0, exception_handlers lw t1, DBE_HANDLER(t0) # save real handler - la t2, dbe_handler + la t2, dbe_handler sw t2, DBE_HANDLER(t0) # set temporary local handler li v0, -1 # default (failure) value - + li t2, 1 beq t2, a1, 1f li t2, 2 @@ -80,13 +80,13 @@ b out 4: lw v0, (a0) # word - -out: + +out: sw t1, DBE_HANDLER(t0) # restore real handler mtc0 t3, CP0_STATUS # restore CPU flags - jr ra - -dbe_handler: + jr ra + +dbe_handler: li v0, -1 # mark our failure .set push .set noreorder diff -urN linux-2.4.21-bk37/arch/mips/baget/balo.c linux-2.4.21-bk38/arch/mips/baget/balo.c --- linux-2.4.21-bk37/arch/mips/baget/balo.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/baget/balo.c 2003-08-24 02:55:57.000000000 -0700 @@ -16,7 +16,7 @@ static void mem_move (long *to, long *from, long size) { - while (size > 0) { + while (size > 0) { *to++ = *from++; size -= sizeof(long); } @@ -59,7 +59,7 @@ "jr\t%1\n\t" "nop\n\t" ".set\tat\n\t" - ".set\treorder" + ".set\treorder" : "=&r" (tmp) : "Ir" (start), "Ir" (mem_upper) : "memory"); @@ -71,7 +71,7 @@ extern char _ramdisk_start, _ramdisk_end; outs( "Relocating Linux... " ); - mem_move((long*)KSEG0, (long*)&_vmlinux_start, + mem_move((long*)KSEG0, (long*)&_vmlinux_start, &_vmlinux_end-&_vmlinux_start); outs("done.\n"); @@ -86,7 +86,7 @@ outs("done.\n"); } - { + { extern void flush_cache_low(int isize, int dsize); flush_cache_low(256*1024,256*1024); } @@ -102,10 +102,10 @@ balo_state = MEM_PROBE; outs("RAM: <"); while(mem_limit < mem_limit_dbe) { - if (can_write(mem_limit) && *mem_limit != 0) + if (can_write(mem_limit) && *mem_limit != 0) break; /* cycle found */ outc('.'); - if (can_write(mem_limit)) + if (can_write(mem_limit)) *mem_limit = -1; /* mark */ mem_limit += 0x40000; } @@ -124,7 +124,7 @@ } void int_handler(struct pt_regs *regs) -{ +{ switch (balo_state) { case BALO_INIT: balo_printf("\nBALO: trap in balo itself.\n"); @@ -162,7 +162,7 @@ while(1) { *mem_limit_dbe; - if (can_write(mem_limit_dbe)) + if (can_write(mem_limit_dbe)) *mem_limit_dbe = 0; mem_limit_dbe += 0x40000; /* +1M */ @@ -174,7 +174,7 @@ { extern void except_vec3_generic(void); - cli(); + cli(); outs(banner); memcpy((void *)(KSEG0 + 0x80), &except_vec3_generic, 0x80); mem_init(); diff -urN linux-2.4.21-bk37/arch/mips/baget/balo_supp.S linux-2.4.21-bk38/arch/mips/baget/balo_supp.S --- linux-2.4.21-bk37/arch/mips/baget/balo_supp.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/baget/balo_supp.S 2003-08-24 02:55:57.000000000 -0700 @@ -8,10 +8,10 @@ #include #include #include - + .text .set mips1 - + /* General exception vector. */ NESTED(except_vec3_generic, 0, sp) .set noat @@ -20,7 +20,7 @@ END(except_vec3_generic) NESTED(except_vec3_generic_code, 0, sp) - SAVE_ALL + SAVE_ALL mfc0 k1, CP0_CAUSE la k0, int_cause sw k1, (k0) @@ -33,7 +33,7 @@ la k0, badvaddr sw k1, (k0) - la k0, int_handler + la k0, int_handler .set noreorder jal k0 .set reorder @@ -47,7 +47,7 @@ .set at .set macro .set noreorder - + move t1, a0 # ISIZE move t2, a1 # DSIZE @@ -88,7 +88,7 @@ sb zero, -8(t0) bne t0, t1, 1b sb zero, -4(t0) - + la v0, 1f or v0, KSEG1 j v0 # Run uncached diff -urN linux-2.4.21-bk37/arch/mips/baget/irq.c linux-2.4.21-bk38/arch/mips/baget/irq.c --- linux-2.4.21-bk37/arch/mips/baget/irq.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/baget/irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -32,19 +32,19 @@ /* * This table is a correspondence between IRQ numbers and CPU PILs */ - -static int irq_to_pil_map[BAGET_IRQ_NR] = { + +static int irq_to_pil_map[BAGET_IRQ_NR] = { 7/*fixme: dma_err -1*/,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 0x00 - 0x0f */ -1,-1,-1,-1, 3,-1,-1,-1, 2, 2, 2,-1, 3,-1,-1,3/*fixme: lance*/, /* 0x10 - 0x1f */ -1,-1,-1,-1,-1,-1, 5,-1,-1,-1,-1,-1, 7,-1,-1,-1, /* 0x20 - 0x2f */ -1, 3, 2/*fixme systimer:3*/, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 /* 0x30 - 0x3f */ }; -static inline int irq_to_pil(int irq_nr) +static inline int irq_to_pil(int irq_nr) { int pil = -1; - if (irq_nr >= BAGET_IRQ_NR) + if (irq_nr >= BAGET_IRQ_NR) baget_printk("irq_to_pil: too large irq_nr = 0x%x\n", irq_nr); else { pil = irq_to_pil_map[irq_nr]; @@ -59,13 +59,13 @@ static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) { - unsigned long status = read_32bit_cp0_register(CP0_STATUS); + unsigned long status = read_c0_status(); status &= ~((clr_mask & 0xFF) << 8); status |= (set_mask & 0xFF) << 8; - write_32bit_cp0_register(CP0_STATUS, status); + write_c0_status(status); } -/* +/* * These two functions may be used for unconditional IRQ * masking via their PIL protection. */ @@ -91,22 +91,22 @@ static volatile unsigned int pil_in_use[BAGET_PIL_NR] = { 0, }; -void mask_irq_count(int irq_nr) +void mask_irq_count(int irq_nr) { unsigned long flags; int pil = irq_to_pil(irq_nr); - + save_and_cli(flags); if (!--pil_in_use[pil]) mask_irq(irq_nr); restore_flags(flags); } -void unmask_irq_count(int irq_nr) +void unmask_irq_count(int irq_nr) { unsigned long flags; int pil = irq_to_pil(irq_nr); - + save_and_cli(flags); if (!pil_in_use[pil]++) unmask_irq(irq_nr); @@ -148,7 +148,7 @@ for (i = 0 ; i < BAGET_IRQ_NR ; i++) { action = irq_action[i]; - if (!action) + if (!action) continue; len += sprintf(buf+len, "%2d: %8d %c %s", i, kstat.irqs[0][i], @@ -181,7 +181,7 @@ irq_enter(cpu, irq); kstat.irqs[cpu][irq]++; - mask_irq(irq); + mask_irq(irq); action = *(irq + irq_action); if (action) { if (!(action->flags & SA_INTERRUPT)) @@ -208,14 +208,14 @@ /* * What to do in case of 'no VIC register available' for current interrupt */ -static void vic_reg_error(unsigned long address, unsigned char active_pils) +static void vic_reg_error(unsigned long address, unsigned char active_pils) { printk("\nNo VIC register found: reg=%08lx active_pils=%02x\n" - "Current interrupt mask from CP0_CAUSE: %02x\n", - address, 0xff & active_pils, - 0xff & (read_32bit_cp0_register(CP0_CAUSE)>>8)); + "Current interrupt mask from CP0_CAUSE: %02x\n", + address, 0xff & active_pils, + 0xff & (read_c0_cause()>>8)); { int i; for (i=0; i<10000; i++) udelay(1000); } -} +} static char baget_fpu_irq = BAGET_FPU_IRQ; #define BAGET_INT_FPU {(unsigned long)&baget_fpu_irq, 1} @@ -225,27 +225,27 @@ */ asmlinkage void baget_interrupt(struct pt_regs *regs) { - static struct baget_int_reg int_reg[BAGET_PIL_NR] = { + static struct baget_int_reg int_reg[BAGET_PIL_NR] = { BAGET_INT_NONE, BAGET_INT_NONE, BAGET_INT0_ACK, BAGET_INT1_ACK, - BAGET_INT_NONE, BAGET_INT_FPU, BAGET_INT_NONE, BAGET_INT5_ACK + BAGET_INT_NONE, BAGET_INT_FPU, BAGET_INT_NONE, BAGET_INT5_ACK }; unsigned char active_pils; - while ((active_pils = read_32bit_cp0_register(CP0_CAUSE)>>8)) { + while ((active_pils = read_c0_cause()>>8)) { int pil; struct baget_int_reg* reg; for (pil = 0; pil < BAGET_PIL_NR; pil++) { if (!(active_pils & (1<address) { extern int try_read(unsigned long,int); int irq = try_read(reg->address, reg->size); - if (irq != -1) + if (irq != -1) do_IRQ(BAGET_IRQ_MASK(irq), regs); - else + else vic_reg_error(reg->address, active_pils); } else { printk("baget_interrupt: unknown interrupt " @@ -297,9 +297,9 @@ return 0; } -int request_irq(unsigned int irq, +int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, + unsigned long irqflags, const char * devname, void *dev_id) { @@ -310,12 +310,12 @@ return -EINVAL; if (!handler) return -EINVAL; - if (irq_to_pil_map[irq] < 0) + if (irq_to_pil_map[irq] < 0) return -EINVAL; action = (struct irqaction *) kmalloc(sizeof(struct irqaction), GFP_KERNEL); - if (!action) + if (!action) return -ENOMEM; action->handler = handler; @@ -332,13 +332,13 @@ return retval; } - + void free_irq(unsigned int irq, void *dev_id) { struct irqaction * action, **p; unsigned long flags; - if (irq >= BAGET_IRQ_NR) + if (irq >= BAGET_IRQ_NR) printk("Trying to free IRQ%d\n",irq); for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) { @@ -375,7 +375,7 @@ *(volatile char*) BAGET_WRERR_ACK = 0; } -static struct irqaction irq0 = +static struct irqaction irq0 = { write_err_interrupt, SA_INTERRUPT, 0, "bus write error", NULL, NULL}; void __init init_IRQ(void) @@ -388,6 +388,6 @@ /* Enable interrupts for pils 2 and 3 (lines 0 and 1) */ modify_cp0_intmask(0, (1<<2)|(1<<3)); - if (setup_baget_irq(0, &irq0) < 0) + if (setup_baget_irq(0, &irq0) < 0) printk("init_IRQ: unable to register write_err irq\n"); } diff -urN linux-2.4.21-bk37/arch/mips/baget/ld.script.balo linux-2.4.21-bk38/arch/mips/baget/ld.script.balo --- linux-2.4.21-bk37/arch/mips/baget/ld.script.balo 2001-07-02 14:40:14.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/baget/ld.script.balo 2003-08-24 02:55:57.000000000 -0700 @@ -1,4 +1,4 @@ -OUTPUT_FORMAT("elf32-bigmips") +OUTPUT_FORMAT("elf32-tradbigmips") OUTPUT_ARCH(mips) ENTRY(balo_entry) SECTIONS @@ -42,13 +42,13 @@ /* Startup code */ . = ALIGN(4096); __init_begin = .; - *(.text.init) - *(.data.init) + *(.text.init) + *(.data.init) . = ALIGN(4096); /* Align double page for init_task_union */ __init_end = .; - *(.fini) - *(.reginfo) + *(.fini) + *(.reginfo) /* Adjust the address for the data segment. We want to adjust up to the same address within the page on the next page up. It would be more correct to do this: @@ -68,18 +68,18 @@ *(.data) CONSTRUCTORS - *(.data1) + *(.data1) _gp = . + 0x8000; - *(.lit8) - *(.lit4) - *(.ctors) - *(.dtors) - *(.got.plt) *(.got) - *(.dynamic) + *(.lit8) + *(.lit4) + *(.ctors) + *(.dtors) + *(.got.plt) *(.got) + *(.dynamic) /* We want the small data sections together, so single-instruction offsets can access them all, and initialized data all before uninitialized, so we can shorten the on-disk segment size. */ - *(.sdata) + *(.sdata) _edata = .; PROVIDE (edata = .); @@ -96,21 +96,21 @@ /* These are needed for ELF backends which have not yet been converted to the new style linker. */ - *(.stab) - *(.stabstr) + *(.stab) + *(.stabstr) /* DWARF debug sections. Symbols in the .debug DWARF section are relative to the beginning of the section so we begin .debug at 0. It's not clear yet what needs to happen for the others. */ - *(.debug) - *(.debug_srcinfo) - *(.debug_aranges) - *(.debug_pubnames) - *(.debug_sfnames) - *(.line) + *(.debug) + *(.debug_srcinfo) + *(.debug_aranges) + *(.debug_pubnames) + *(.debug_sfnames) + *(.line) /* These must appear regardless of . */ - *(.gptab.data) *(.gptab.sdata) - *(.gptab.bss) *(.gptab.sbss) + *(.gptab.data) *(.gptab.sdata) + *(.gptab.bss) *(.gptab.sbss) _vmlinux_start = .; *(.vmlinux) diff -urN linux-2.4.21-bk37/arch/mips/baget/print.c linux-2.4.21-bk38/arch/mips/baget/print.c --- linux-2.4.21-bk37/arch/mips/baget/print.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/baget/print.c 2003-08-24 02:55:57.000000000 -0700 @@ -14,7 +14,7 @@ */ // #define BAGET_PRINTK -/* +/* * This function is same for BALO and Linux baget_printk, * and normally prints characted to second (UART A) console. */ @@ -25,7 +25,7 @@ { int i; vac_outb(c, VAC_UART_B_TX); - for (i=0; i<10000; i++) + for (i=0; i<10000; i++) delay(); } @@ -36,7 +36,7 @@ outc_low(c); } -void outs(char *s) +void outs(char *s) { while(*s) outc(*s++); } @@ -77,7 +77,7 @@ void __init balo_printf( char *f, ... ) { int *arg = (int*)&f + 1; - char c; + char c; int format = 0; while((c = *f++) != 0) { @@ -110,7 +110,7 @@ } void __init balo_hungup(void) -{ +{ outs("Hunging up.\n"); - while(1); + while(1); } diff -urN linux-2.4.21-bk37/arch/mips/baget/prom/init.c linux-2.4.21-bk38/arch/mips/baget/prom/init.c --- linux-2.4.21-bk37/arch/mips/baget/prom/init.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/baget/prom/init.c 2003-08-24 02:55:57.000000000 -0700 @@ -1,7 +1,7 @@ /* * init.c: PROM library initialisation code. * - * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov + * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov */ #include #include diff -urN linux-2.4.21-bk37/arch/mips/baget/setup.c linux-2.4.21-bk38/arch/mips/baget/setup.c --- linux-2.4.21-bk37/arch/mips/baget/setup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/baget/setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -15,10 +15,10 @@ long int vac_memory_upper; #define CACHEABLE_STR(val) ((val) ? "not cached" : "cached") -#define MIN(a,b) (((a)<(b)) ? (a):(b)) - +#define MIN(a,b) (((a)<(b)) ? (a):(b)) + static void __init vac_show(void) -{ +{ int i; unsigned short val, decode = vac_inw(VAC_DECODE_CTRL); unsigned short a24_base = vac_inw(VAC_A24_BASE); @@ -37,7 +37,7 @@ VAC_IOSEL3_CTRL, VAC_IOSEL4_CTRL, VAC_IOSEL5_CTRL }; - + printk("[DSACKi %s, DRAMCS%s qualified, boundary%s qualified%s]\n", (decode & VAC_DECODE_DSACKI) ? "on" : "off", (decode & VAC_DECODE_QFY_DRAMCS) ? "" : " not", @@ -71,24 +71,24 @@ VAC_ICFSEL_MODULE_VAL(vac_inw(VAC_ICFSEL_BASE)))<<4, (decode & VAC_DECODE_QFY_ICFSEL) ? "qualified" : ""); - + printk("region0 at 00000000 (%dMB)\t[dram, %s, delay %d cpuclk" ", cached]\n", (vac_inw(VAC_DRAM_MASK)+1)>>4, (decode & VAC_DECODE_DSACK) ? "D32" : "3state", VAC_DECODE_CPUCLK_VAL(decode)); - + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++) { - unsigned long from = + unsigned long from = ((unsigned long)vac_inw(bndr[i]))<<16; - unsigned long to = + unsigned long to = ((unsigned long) - ((i+1 == sizeof(bndr)/sizeof(bndr[0])) ? + ((i+1 == sizeof(bndr)/sizeof(bndr[0])) ? 0xff00 : vac_inw(bndr[i+1])))<<16; - - + + val = vac_inw(regs[i]); - printk("region%d at %08lx (%dMB)\t[%s %s/%s, %s]\n", + printk("region%d at %08lx (%dMB)\t[%s %s/%s, %s]\n", i+1, from, (unsigned int)((to - from) >> 20), @@ -96,13 +96,13 @@ asiz[VAC_REG_ASIZ_VAL(val)], ((val & VAC_REG_WORD) ? "D16" : "D32"), CACHEABLE_STR(val&VAC_A24_A24_CACHINH)); - + if (a24_addr >= from && a24_addr < to) printk("\ta24 at %08lx (%dMB)\t[vme, A24/%s, %s]\n", a24_addr, MIN((unsigned int)(a24_addr - from)>>20, 32), (a24_base & VAC_A24_DATAPATH) ? "user" : - ((a24_base & VAC_A24_D32_ENABLE) ? + ((a24_base & VAC_A24_D32_ENABLE) ? "D32" : "D16"), CACHEABLE_STR(a24_base & VAC_A24_A24_CACHINH)); } @@ -122,7 +122,7 @@ (VAC_CTRL_DELAY_IOWR_VAL(val)&1) ? ".5" : "", VAC_CTRL_DELAY_IOSELI_VAL(val)/2, (VAC_CTRL_DELAY_IOSELI_VAL(val)&1) ? ".5" : ""); - + printk("region5 at fff00000 (896KB)\t[local io, %s]\n", CACHEABLE_STR(vac_inw(VAC_A24_BASE) & VAC_A24_IO_CACHINH)); @@ -131,7 +131,7 @@ printk("\tio%d[ack %d cpuclk%s, %s%srecovery %d cpuclk, " "\n\t read %d%s cpuclk, write %d%s cpuclk, " "assert %d%s%s cpuclk]\n", - i, + i, VAC_CTRL_DELAY_DSACKI_VAL(val), state[val & (VAC_CTRL_IORD|VAC_CTRL_IOWR)], (val & VAC_CTRL_DSACK0) ? "dsack0*, " : "", @@ -143,15 +143,15 @@ (VAC_CTRL_DELAY_IOWR_VAL(val)&1) ? ".5" : "", VAC_CTRL_DELAY_IOSELI_VAL(val)/2, (VAC_CTRL_DELAY_IOSELI_VAL(val)&1) ? ".5" : "", - (vac_inw(VAC_DEV_LOC) & VAC_DEV_LOC_IOSEL(i)) ? + (vac_inw(VAC_DEV_LOC) & VAC_DEV_LOC_IOSEL(i)) ? ", id" : ""); } - + printk("region6 at fffe0000 (128KB)\t[vme, A16/%s, " "not cached]\n", - (a24_base & VAC_A24_A16D32_ENABLE) ? + (a24_base & VAC_A24_A16D32_ENABLE) ? ((a24_base & VAC_A24_A16D32) ? "D32" : "D16") : "user"); - + val = vac_inw(VAC_SHRCS_CTRL); printk("shared[ack %d cpuclk%s, %s%srecovery %d cpuclk, " "read %d%s, write %d%s, assert %d%s]\n", @@ -182,8 +182,8 @@ default: panic("Unknown VAC revision number"); } - - vac_outw(mem_limit-1, VAC_DRAM_MASK); + + vac_outw(mem_limit-1, VAC_DRAM_MASK); vac_outw(mem_limit, VAC_BNDR2); vac_outw(mem_limit, VAC_BNDR3); vac_outw(((BAGET_A24M_BASE>>16)&~VAC_A24_D32_ENABLE)|VAC_A24_DATAPATH, @@ -293,19 +293,19 @@ vac_outw(VAC_INT_CTRL_TIMER_PIO10| VAC_INT_CTRL_UART_B_PIO7| VAC_INT_CTRL_UART_A_PIO7,VAC_INT_CTRL); - /* + /* * Set quadro speed for both UARTs. * To do it we need use formulae from VIC/VAC manual, * keeping in mind Baget's 50MHz frequency... */ - vac_outw((500000/(384*16))<<8,VAC_CPU_CLK_DIV); + vac_outw((500000/(384*16))<<8,VAC_CPU_CLK_DIV); } static void __init vic_show(void) { unsigned char val; char *timeout[] = { "4", "16", "32", "64", "128", "256", "disabled" }; - char *deadlock[] = { "[dedlk only]", "[dedlk only]", + char *deadlock[] = { "[dedlk only]", "[dedlk only]", "[dedlk], [halt w/ rmc], [lberr]", "[dedlk], [halt w/o rmc], [lberr]" }; @@ -318,7 +318,7 @@ printk("metastability delay "); printk("%s ", deadlock[VIC_IFACE_CFG_DEADLOCK_VAL(val)]); - + printk("interrupts: "); val = vic_inb(VIC_ERR_INT); @@ -331,7 +331,7 @@ if (!(val & VIC_ERR_INT_ACFAIL)) printk("[acfail] "); printk("\n"); - + printk("timeouts: "); val = vic_inb(VIC_XFER_TIMO); printk("local %s, vme %s ", @@ -357,7 +357,7 @@ printk("[local boundary cross]"); if (val & VIC_BXFER_DEF_VME_CROSS) printk("[vme boundary cross]"); - + } static void __init vic_init(void) @@ -372,7 +372,7 @@ vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE,VIC_VME_INT2); vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE,VIC_VME_INT3); vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE,VIC_VME_INT4); -/* +/* vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE, VIC_VME_INT5); */ vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE, VIC_VME_INT6); @@ -387,7 +387,7 @@ VIC_INT_HIGH|VIC_INT_DISABLE, VIC_LINT3); vic_outb(VIC_INT_IPL(3)|VIC_INT_NOAUTO|VIC_INT_EDGE| VIC_INT_LOW|VIC_INT_DISABLE, VIC_LINT4); -/* +/* vic_outb(VIC_INT_IPL(3)|VIC_INT_NOAUTO|VIC_INT_LEVEL| VIC_INT_LOW|VIC_INT_DISABLE, VIC_LINT5); */ @@ -446,7 +446,7 @@ VIC_RELEASE_RWD, VIC_RELEASE); vic_outb(VIC_IC6_RUN, VIC_IC6); vic_outb(0, VIC_IC7); - + vic_show(); } @@ -470,7 +470,7 @@ extern void baget_machine_restart(char *command); extern void baget_machine_halt(void); extern void baget_machine_power_off(void); - + void __init baget_setup(void) { printk("BT23/63-201n found.\n"); diff -urN linux-2.4.21-bk37/arch/mips/baget/time.c linux-2.4.21-bk38/arch/mips/baget/time.c --- linux-2.4.21-bk37/arch/mips/baget/time.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/baget/time.c 2003-08-24 02:55:57.000000000 -0700 @@ -19,25 +19,25 @@ #include #include #include -#include +#include #include extern rwlock_t xtime_lock; -/* +/* * To have precision clock, we need to fix available clock frequency */ #define FREQ_NOM 79125 /* Baget frequency ratio */ #define FREQ_DEN 10000 -static inline int timer_intr_valid(void) +static inline int timer_intr_valid(void) { static unsigned long long ticks, valid_ticks; if (ticks++ * FREQ_DEN >= valid_ticks * FREQ_NOM) { - /* - * We need no overflow checks, + /* + * We need no overflow checks, * due baget unable to work 3000 years... * At least without reboot... */ @@ -63,10 +63,10 @@ vic_outb(ss0cr0, VIC_SS0CR0); vic_outb(VIC_INT_IPL(6)|VIC_INT_NOAUTO|VIC_INT_EDGE| - VIC_INT_LOW|VIC_INT_ENABLE, VIC_LINT2); + VIC_INT_LOW|VIC_INT_ENABLE, VIC_LINT2); } -static struct irqaction timer_irq = +static struct irqaction timer_irq = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; void __init time_init(void) diff -urN linux-2.4.21-bk37/arch/mips/baget/vacserial.c linux-2.4.21-bk38/arch/mips/baget/vacserial.c --- linux-2.4.21-bk37/arch/mips/baget/vacserial.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/baget/vacserial.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,2905 +0,0 @@ -/* - * vacserial.c: VAC UART serial driver - * This code stealed and adopted from linux/drivers/char/serial.c - * See that for author info - * - * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov - */ - -#undef SERIAL_PARANOIA_CHECK -#define CONFIG_SERIAL_NOPAUSE_IO -#define SERIAL_DO_RESTART - -#define CONFIG_SERIAL_SHARE_IRQ - -/* Set of debugging defines */ - -#undef SERIAL_DEBUG_INTR -#undef SERIAL_DEBUG_OPEN -#undef SERIAL_DEBUG_FLOW -#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - -#define RS_STROBE_TIME (10*HZ) -#define RS_ISR_PASS_LIMIT 2 /* Beget is not a super-computer (old=256) */ - -#define IRQ_T(state) \ - ((state->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT) - -#define SERIAL_INLINE - -#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) -#define DBG_CNT(s) baget_printk("(%s):[%x] refc=%d, serc=%d, ttyc=%d-> %s\n", \ - kdevname(tty->device),(info->flags),serial_refcount,info->count,tty->count,s) -#else -#define DBG_CNT(s) -#endif - -#define QUAD_UART_SPEED /* Useful for Baget */ - -/* - * End of serial driver configuration section. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_SERIAL_CONSOLE -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#define BAGET_VAC_UART_IRQ 0x35 - -/* - * Implementation note: - * It was descovered by means of advanced electronic tools, - * if the driver works via TX_READY interrupts then VIC generates - * strange self-eliminating traps. Thus, the driver is rewritten to work - * via TX_EMPTY - */ - -/* VAC-specific check/debug switches */ - -#undef CHECK_REG_INDEX -#undef DEBUG_IO_PORT_A - -#ifdef SERIAL_INLINE -#define _INLINE_ inline -#endif - -static char *serial_name = "VAC Serial driver"; -static char *serial_version = "4.26"; - -static DECLARE_TASK_QUEUE(tq_serial); - -static struct tty_driver serial_driver, callout_driver; -static int serial_refcount; - -/* number of characters left in xmit buffer before we ask for more */ -#define WAKEUP_CHARS 256 - -/* - * IRQ_timeout - How long the timeout should be for each IRQ - * should be after the IRQ has been active. - */ - -static struct async_struct *IRQ_ports[NR_IRQS]; -static int IRQ_timeout[NR_IRQS]; -#ifdef CONFIG_SERIAL_CONSOLE -static struct console sercons; -#endif - -static void autoconfig(struct serial_state * info); -static void change_speed(struct async_struct *info); -static void rs_wait_until_sent(struct tty_struct *tty, int timeout); -static void rs_timer(unsigned long dummy); - -static struct timer_list vacs_timer; - -/* - * Here we define the default xmit fifo size used for each type of - * UART - */ -static struct serial_uart_config uart_config[] = { - { "unknown", 1, 0 }, /* Must go first -- used as unasigned */ - { "VAC UART", 1, 0 } -}; -#define VAC_UART_TYPE 1 /* Just index in above array */ - -static struct serial_state rs_table[] = { -/* - * VAC has tricky layout for pair of his SIO registers, - * so we need special function to access ones. - * To identify port we use their TX offset - */ - { 0, 9600, VAC_UART_B_TX, BAGET_VAC_UART_IRQ, - STD_COM_FLAGS }, /* VAC UART B */ - { 0, 9600, VAC_UART_A_TX, BAGET_VAC_UART_IRQ, - STD_COM_FLAGS } /* VAC UART A */ -}; - -#define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state)) - -static struct tty_struct *serial_table[NR_PORTS]; -static struct termios *serial_termios[NR_PORTS]; -static struct termios *serial_termios_locked[NR_PORTS]; - -#ifndef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif - -/* - * tmp_buf is used as a temporary buffer by serial_write. We need to - * lock it in case the copy_from_user blocks while swapping in a page, - * and some other program tries to do a serial write at the same time. - * Since the lock will only come under contention when the system is - * swapping and available memory is low, it makes sense to share one - * buffer across all the serial ports, since it significantly saves - * memory if large numbers of serial ports are open. - */ -static unsigned char *tmp_buf; -static DECLARE_MUTEX(tmp_buf_sem); - -static inline int serial_paranoia_check(struct async_struct *info, - kdev_t device, const char *routine) -{ -#ifdef SERIAL_PARANOIA_CHECK - static const char *badmagic = - "Warning: bad magic number for serial struct (%s) in %s\n"; - static const char *badinfo = - "Warning: null async_struct for (%s) in %s\n"; - - if (!info) { - printk(badinfo, kdevname(device), routine); - return 1; - } - if (info->magic != SERIAL_MAGIC) { - printk(badmagic, kdevname(device), routine); - return 1; - } -#endif - return 0; -} - -/* - To unify UART A/B access we will use following function - to compute register offsets by register index. - */ - -#define VAC_UART_MODE 0 -#define VAC_UART_TX 1 -#define VAC_UART_RX 2 -#define VAC_UART_INT_MASK 3 -#define VAC_UART_INT_STATUS 4 - -#define VAC_UART_REG_NR 5 - -static inline int uart_offset_map(unsigned long port, int reg_index) -{ - static const unsigned int ind_to_reg[VAC_UART_REG_NR][NR_PORTS] = { - { VAC_UART_B_MODE, VAC_UART_A_MODE }, - { VAC_UART_B_TX, VAC_UART_A_TX }, - { VAC_UART_B_RX, VAC_UART_A_RX }, - { VAC_UART_B_INT_MASK, VAC_UART_A_INT_MASK }, - { VAC_UART_B_INT_STATUS, VAC_UART_A_INT_STATUS } - }; -#ifdef CHECK_REG_INDEX - if (reg_index > VAC_UART_REG_NR) panic("vacserial: bad reg_index"); -#endif - return ind_to_reg[reg_index][port == VAC_UART_B_TX ? 0 : 1]; -} - -static inline unsigned int serial_inw(struct async_struct *info, int offset) -{ - int val = vac_inw(uart_offset_map(info->port,offset)); -#ifdef DEBUG_IO_PORT_A - if (info->port == VAC_UART_A_TX) - printk("UART_A_IN: reg = 0x%04x, val = 0x%04x\n", - uart_offset_map(info->port,offset), val); -#endif - return val; -} - -static inline unsigned int serial_inp(struct async_struct *info, int offset) -{ - return serial_inw(info, offset); -} - -static inline unsigned int serial_in(struct async_struct *info, int offset) -{ - return serial_inw(info, offset); -} - -static inline void serial_outw(struct async_struct *info,int offset, int value) -{ -#ifdef DEBUG_IO_PORT_A - if (info->port == VAC_UART_A_TX) - printk("UART_A_OUT: offset = 0x%04x, val = 0x%04x\n", - uart_offset_map(info->port,offset), value); -#endif - vac_outw(value, uart_offset_map(info->port,offset)); -} - -static inline void serial_outp(struct async_struct *info,int offset, int value) -{ - serial_outw(info,offset,value); -} - -static inline void serial_out(struct async_struct *info,int offset, int value) -{ - serial_outw(info,offset,value); -} - -/* - * ------------------------------------------------------------ - * rs_stop() and rs_start() - * - * This routines are called before setting or resetting tty->stopped. - * They enable or disable transmitter interrupts, as necessary. - * ------------------------------------------------------------ - */ -static void rs_stop(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_stop")) - return; - - save_flags(flags); cli(); - if (info->IER & VAC_UART_INT_TX_EMPTY) { - info->IER &= ~VAC_UART_INT_TX_EMPTY; - serial_out(info, VAC_UART_INT_MASK, info->IER); - } - restore_flags(flags); -} - -static void rs_start(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_start")) - return; - - save_flags(flags); cli(); - if (info->xmit_cnt && info->xmit_buf - && !(info->IER & VAC_UART_INT_TX_EMPTY)) { - info->IER |= VAC_UART_INT_TX_EMPTY; - serial_out(info, VAC_UART_INT_MASK, info->IER); - } - restore_flags(flags); -} - -/* - * ---------------------------------------------------------------------- - * - * Here starts the interrupt handling routines. All of the following - * subroutines are declared as inline and are folded into - * rs_interrupt(). They were separated out for readability's sake. - * - * Note: rs_interrupt() is a "fast" interrupt, which means that it - * runs with interrupts turned off. People who may want to modify - * rs_interrupt() should try to keep the interrupt handler as fast as - * possible. After you are done making modifications, it is not a bad - * idea to do: - * - * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c - * - * and look at the resulting assemble code in serial.s. - * - * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 - * ----------------------------------------------------------------------- - */ - -/* - * This routine is used by the interrupt handler to schedule - * processing in the software interrupt portion of the driver. - */ -static _INLINE_ void rs_sched_event(struct async_struct *info, - int event) -{ - info->event |= 1 << event; - queue_task(&info->tqueue, &tq_serial); - mark_bh(SERIAL_BH); -} - -static _INLINE_ void receive_chars(struct async_struct *info, - int *status) -{ - struct tty_struct *tty = info->tty; - unsigned short rx; - unsigned char ch; - int ignored = 0; - struct async_icount *icount; - - icount = &info->state->icount; - do { - rx = serial_inw(info, VAC_UART_RX); - ch = VAC_UART_RX_DATA_MASK & rx; - - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - break; - *tty->flip.char_buf_ptr = ch; - icount->rx++; - -#ifdef SERIAL_DEBUG_INTR - baget_printk("DR%02x:%02x...", rx, *status); -#endif - *tty->flip.flag_buf_ptr = 0; - if (*status & (VAC_UART_STATUS_RX_BREAK_CHANGE - | VAC_UART_STATUS_RX_ERR_PARITY - | VAC_UART_STATUS_RX_ERR_FRAME - | VAC_UART_STATUS_RX_ERR_OVERRUN)) { - /* - * For statistics only - */ - if (*status & VAC_UART_STATUS_RX_BREAK_CHANGE) { - *status &= ~(VAC_UART_STATUS_RX_ERR_FRAME - | VAC_UART_STATUS_RX_ERR_PARITY); - icount->brk++; - } else if (*status & VAC_UART_STATUS_RX_ERR_PARITY) - icount->parity++; - else if (*status & VAC_UART_STATUS_RX_ERR_FRAME) - icount->frame++; - if (*status & VAC_UART_STATUS_RX_ERR_OVERRUN) - icount->overrun++; - - /* - * Now check to see if character should be - * ignored, and mask off conditions which - * should be ignored. - */ - if (*status & info->ignore_status_mask) { - if (++ignored > 100) - break; - goto ignore_char; - } - *status &= info->read_status_mask; - - if (*status & (VAC_UART_STATUS_RX_BREAK_CHANGE)) { -#ifdef SERIAL_DEBUG_INTR - baget_printk("handling break...."); -#endif - *tty->flip.flag_buf_ptr = TTY_BREAK; - if (info->flags & ASYNC_SAK) - do_SAK(tty); - } else if (*status & VAC_UART_STATUS_RX_ERR_PARITY) - *tty->flip.flag_buf_ptr = TTY_PARITY; - else if (*status & VAC_UART_STATUS_RX_ERR_FRAME) - *tty->flip.flag_buf_ptr = TTY_FRAME; - if (*status & VAC_UART_STATUS_RX_ERR_OVERRUN) { - /* - * Overrun is special, since it's - * reported immediately, and doesn't - * affect the current character - */ - if (tty->flip.count < TTY_FLIPBUF_SIZE) { - tty->flip.count++; - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - *tty->flip.flag_buf_ptr = TTY_OVERRUN; - } - } - } - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - tty->flip.count++; - ignore_char: - *status = serial_inw(info, VAC_UART_INT_STATUS); - } while ((*status & VAC_UART_STATUS_RX_READY)); - tty_flip_buffer_push(tty); -} - -static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) -{ - int count; - - if (info->x_char) { - serial_outw(info, VAC_UART_TX, - (((unsigned short)info->x_char)<<8)); - info->state->icount.tx++; - info->x_char = 0; - if (intr_done) - *intr_done = 0; - return; - } - if ((info->xmit_cnt <= 0) || info->tty->stopped || - info->tty->hw_stopped) { - info->IER &= ~VAC_UART_INT_TX_EMPTY; - serial_outw(info, VAC_UART_INT_MASK, info->IER); - return; - } - count = info->xmit_fifo_size; - do { - serial_out(info, VAC_UART_TX, - (unsigned short)info->xmit_buf[info->xmit_tail++] \ - << 8); - info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); - info->state->icount.tx++; - if (--info->xmit_cnt <= 0) - break; - } while (--count > 0); - - if (info->xmit_cnt < WAKEUP_CHARS) - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); - -#ifdef SERIAL_DEBUG_INTR - baget_printk("THRE..."); -#endif - if (intr_done) - *intr_done = 0; - - if (info->xmit_cnt <= 0) { - info->IER &= ~VAC_UART_INT_TX_EMPTY; - serial_outw(info, VAC_UART_INT_MASK, info->IER); - } -} - -static _INLINE_ void check_modem_status(struct async_struct *info) -{ -#if 0 /* VAC hasn't modem control */ - wake_up_interruptible(&info->open_wait); - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); -#endif -} - -#ifdef CONFIG_SERIAL_SHARE_IRQ - - -/* - * Specific functions needed for VAC UART interrupt enter/leave - */ - -#define VAC_INT_CTRL_UART_ENABLE \ - (VAC_INT_CTRL_TIMER_PIO10|VAC_INT_CTRL_UART_B_PIO7|VAC_INT_CTRL_UART_A_PIO7) - -#define VAC_INT_CTRL_UART_DISABLE(info) \ - (VAC_INT_CTRL_TIMER_PIO10 | \ - ((info->port == VAC_UART_A_TX) ? \ - (VAC_INT_CTRL_UART_A_DISABLE|VAC_INT_CTRL_UART_B_PIO7) : \ - (VAC_INT_CTRL_UART_A_PIO7|VAC_INT_CTRL_UART_B_DISABLE))) - -/* - * Following two functions were proposed by Pavel Osipenko - * to make VAC/VIC behaviour more regular. - */ -static void intr_begin(struct async_struct* info) -{ - serial_outw(info, VAC_UART_INT_MASK, 0); -} - -static void intr_end(struct async_struct* info) -{ - vac_outw(VAC_INT_CTRL_UART_DISABLE(info), VAC_INT_CTRL); - vac_outw(VAC_INT_CTRL_UART_ENABLE, VAC_INT_CTRL); - - serial_outw(info, VAC_UART_INT_MASK, info->IER); -} - -/* - * This is the serial driver's generic interrupt routine - */ -static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) -{ - int status; - struct async_struct * info; - int pass_counter = 0; - struct async_struct *end_mark = 0; - -#ifdef SERIAL_DEBUG_INTR - baget_printk("rs_interrupt(%d)...", irq); -#endif - - info = IRQ_ports[irq]; - if (!info) - return; - - do { - intr_begin(info); /* Mark we begin port handling */ - - if (!info->tty || - (serial_inw (info, VAC_UART_INT_STATUS) - & VAC_UART_STATUS_INTS) == 0) - { - if (!end_mark) - end_mark = info; - goto next; - } - end_mark = 0; - - info->last_active = jiffies; - - status = serial_inw(info, VAC_UART_INT_STATUS); -#ifdef SERIAL_DEBUG_INTR - baget_printk("status = %x...", status); -#endif - if (status & VAC_UART_STATUS_RX_READY) { - receive_chars(info, &status); - } - check_modem_status(info); - if (status & VAC_UART_STATUS_TX_EMPTY) - transmit_chars(info, 0); - - next: - intr_end(info); /* Mark this port handled */ - - info = info->next_port; - if (!info) { - info = IRQ_ports[irq]; - if (pass_counter++ > RS_ISR_PASS_LIMIT) { - break; /* Prevent infinite loops */ - } - continue; - } - } while (end_mark != info); -#ifdef SERIAL_DEBUG_INTR - baget_printk("end.\n"); -#endif - - -} -#endif /* #ifdef CONFIG_SERIAL_SHARE_IRQ */ - - -/* The original driver was simplified here: - two functions were joined to reduce code */ - -#define rs_interrupt_single rs_interrupt - - -/* - * ------------------------------------------------------------------- - * Here ends the serial interrupt routines. - * ------------------------------------------------------------------- - */ - -/* - * This routine is used to handle the "bottom half" processing for the - * serial driver, known also the "software interrupt" processing. - * This processing is done at the kernel interrupt level, after the - * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This - * is where time-consuming activities which can not be done in the - * interrupt driver proper are done; the interrupt driver schedules - * them using rs_sched_event(), and they get done here. - */ -static void do_serial_bh(void) -{ - run_task_queue(&tq_serial); -} - -static void do_softint(void *private_) -{ - struct async_struct *info = (struct async_struct *) private_; - struct tty_struct *tty; - - tty = info->tty; - if (!tty) - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); - wake_up_interruptible(&tty->write_wait); - } -} - -/* - * --------------------------------------------------------------- - * Low level utility subroutines for the serial driver: routines to - * figure out the appropriate timeout for an interrupt chain, routines - * to initialize and startup a serial port, and routines to shutdown a - * serial port. Useful stuff like that. - * --------------------------------------------------------------- - */ - -/* - * This routine figures out the correct timeout for a particular IRQ. - * It uses the smallest timeout of all of the serial ports in a - * particular interrupt chain. Now only used for IRQ 0.... - */ -static void figure_IRQ_timeout(int irq) -{ - struct async_struct *info; - int timeout = 60*HZ; /* 60 seconds === a long time :-) */ - - info = IRQ_ports[irq]; - if (!info) { - IRQ_timeout[irq] = 60*HZ; - return; - } - while (info) { - if (info->timeout < timeout) - timeout = info->timeout; - info = info->next_port; - } - if (!irq) - timeout = timeout / 2; - IRQ_timeout[irq] = timeout ? timeout : 1; -} - -static int startup(struct async_struct * info) -{ - unsigned long flags; - int retval=0; - void (*handler)(int, void *, struct pt_regs *); - struct serial_state *state= info->state; - unsigned long page; - - page = get_free_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - - save_flags(flags); cli(); - - if (info->flags & ASYNC_INITIALIZED) { - free_page(page); - goto errout; - } - if (!state->port || !state->type) { - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - free_page(page); - goto errout; - } - if (info->xmit_buf) - free_page(page); - else - info->xmit_buf = (unsigned char *) page; - -#ifdef SERIAL_DEBUG_OPEN - baget_printk("starting up ttys%d (irq %d)...", info->line, state->irq); -#endif - - if (uart_config[info->state->type].flags & UART_STARTECH) { - /* Wake up UART */ - serial_outp(info, VAC_UART_MODE, 0); - serial_outp(info, VAC_UART_INT_MASK, 0); - } - - /* - * Allocate the IRQ if necessary - */ - if (state->irq && (!IRQ_ports[state->irq] || - !IRQ_ports[state->irq]->next_port)) { - - if (IRQ_ports[state->irq]) { -#ifdef CONFIG_SERIAL_SHARE_IRQ - free_irq(state->irq, NULL); - handler = rs_interrupt; -#else - retval = -EBUSY; - goto errout; -#endif /* CONFIG_SERIAL_SHARE_IRQ */ - } else - handler = rs_interrupt_single; - - - retval = request_irq(state->irq, handler, IRQ_T(state), - "serial", NULL); - if (retval) { - if (capable(CAP_SYS_ADMIN)) { - if (info->tty) - set_bit(TTY_IO_ERROR, - &info->tty->flags); - retval = 0; - } - goto errout; - } - } - - /* - * Insert serial port into IRQ chain. - */ - info->prev_port = 0; - info->next_port = IRQ_ports[state->irq]; - if (info->next_port) - info->next_port->prev_port = info; - IRQ_ports[state->irq] = info; - figure_IRQ_timeout(state->irq); - - /* - * Clear the interrupt registers. - */ - /* (void) serial_inw(info, VAC_UART_INT_STATUS); */ /* (see above) */ - (void) serial_inw(info, VAC_UART_RX); - - /* - * Now, initialize the UART - */ - serial_outp(info, VAC_UART_MODE, VAC_UART_MODE_INITIAL); /*reset DLAB*/ - - /* - * Finally, enable interrupts - */ - info->IER = VAC_UART_INT_RX_BREAK_CHANGE | VAC_UART_INT_RX_ERRS | \ - VAC_UART_INT_RX_READY; - serial_outp(info, VAC_UART_INT_MASK, info->IER); /*enable interrupts*/ - - /* - * And clear the interrupt registers again for luck. - */ - (void)serial_inp(info, VAC_UART_INT_STATUS); - (void)serial_inp(info, VAC_UART_RX); - - if (info->tty) - clear_bit(TTY_IO_ERROR, &info->tty->flags); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - - /* - * Set up serial timers... - */ - mod_timer(&vacs_timer, jiffies + 2*HZ/100); - - /* - * and set the speed of the serial port - */ - change_speed(info); - - info->flags |= ASYNC_INITIALIZED; - restore_flags(flags); - return 0; - -errout: - restore_flags(flags); - return retval; -} - -/* - * This routine will shutdown a serial port; interrupts are disabled, and - * DTR is dropped if the hangup on close termio flag is on. - */ -static void shutdown(struct async_struct * info) -{ - unsigned long flags; - struct serial_state *state; - int retval; - - if (!(info->flags & ASYNC_INITIALIZED)) - return; - - state = info->state; - -#ifdef SERIAL_DEBUG_OPEN - baget_printk("Shutting down serial port %d (irq %d)....", info->line, - state->irq); -#endif - - save_flags(flags); cli(); /* Disable interrupts */ - - /* - * clear delta_msr_wait queue to avoid mem leaks: we may free the irq - * here so the queue might never be waken up - */ - wake_up_interruptible(&info->delta_msr_wait); - - /* - * First unlink the serial port from the IRQ chain... - */ - if (info->next_port) - info->next_port->prev_port = info->prev_port; - if (info->prev_port) - info->prev_port->next_port = info->next_port; - else - IRQ_ports[state->irq] = info->next_port; - figure_IRQ_timeout(state->irq); - - /* - * Free the IRQ, if necessary - */ - if (state->irq && (!IRQ_ports[state->irq] || - !IRQ_ports[state->irq]->next_port)) { - if (IRQ_ports[state->irq]) { - free_irq(state->irq, NULL); - retval = request_irq(state->irq, rs_interrupt_single, - IRQ_T(state), "serial", NULL); - - if (retval) - printk("serial shutdown: request_irq: error %d" - " Couldn't reacquire IRQ.\n", retval); - } else - free_irq(state->irq, NULL); - } - - if (info->xmit_buf) { - free_page((unsigned long) info->xmit_buf); - info->xmit_buf = 0; - } - - info->IER = 0; - serial_outp(info, VAC_UART_INT_MASK, 0x00); /* disable all intrs */ - - /* disable break condition */ - serial_out(info, VAC_UART_MODE, serial_inp(info, VAC_UART_MODE) & \ - ~VAC_UART_MODE_SEND_BREAK); - - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - - info->flags &= ~ASYNC_INITIALIZED; - restore_flags(flags); -} - -/* - * When we set line mode, we call this function - * for Baget-specific adjustments. - */ - -static inline unsigned short vac_uart_mode_fixup (unsigned short cval) -{ -#ifdef QUAD_UART_SPEED - /* - * When we are using 4-x advantage in speed: - * - * Disadvantage : can't support 75, 150 bauds - * Advantage : can support 19200, 38400 bauds - */ - char speed = 7 & (cval >> 10); - cval &= ~(7 << 10); - cval |= VAC_UART_MODE_BAUD(speed-2); -#endif - - /* - * In general, we have Tx and Rx ON all time - * and use int mask flag for their disabling. - */ - cval |= VAC_UART_MODE_RX_ENABLE; - cval |= VAC_UART_MODE_TX_ENABLE; - cval |= VAC_UART_MODE_CHAR_RX_ENABLE; - cval |= VAC_UART_MODE_CHAR_TX_ENABLE; - - /* Low 4 bits are not used in UART */ - cval &= ~0xf; - - return cval; -} - -/* - * This routine is called to set the UART divisor registers to match - * the specified baud rate for a serial port. - */ -static void change_speed(struct async_struct *info) -{ - unsigned short port; - int quot = 0, baud_base, baud; - unsigned cflag, cval; - int bits; - unsigned long flags; - - if (!info->tty || !info->tty->termios) - return; - cflag = info->tty->termios->c_cflag; - if (!(port = info->port)) - return; - - /* byte size and parity */ - switch (cflag & CSIZE) { - case CS7: cval = 0x0; bits = 9; break; - case CS8: cval = VAC_UART_MODE_8BIT_CHAR; bits = 10; break; - /* Never happens, but GCC is too dumb to figure it out */ - case CS5: - case CS6: - default: cval = 0x0; bits = 9; break; - } - cval &= ~VAC_UART_MODE_PARITY_ENABLE; - if (cflag & PARENB) { - cval |= VAC_UART_MODE_PARITY_ENABLE; - bits++; - } - if (cflag & PARODD) - cval |= VAC_UART_MODE_PARITY_ODD; - - /* Determine divisor based on baud rate */ - baud = tty_get_baud_rate(info->tty); - if (!baud) - baud = 9600; /* B0 transition handled in rs_set_termios */ - baud_base = info->state->baud_base; - if (baud == 38400 && - ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) - quot = info->state->custom_divisor; - else { - if (baud == 134) - /* Special case since 134 is really 134.5 */ - quot = (2*baud_base / 269); - else if (baud) - quot = baud_base / baud; - } - /* If the quotient is ever zero, default to 9600 bps */ - if (!quot) - quot = baud_base / 9600; - info->quot = quot; - info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base); - info->timeout += HZ/50; /* Add .02 seconds of slop */ - - serial_out(info, VAC_UART_INT_MASK, info->IER); - - /* - * Set up parity check flag - */ -#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) - - info->read_status_mask = VAC_UART_STATUS_RX_ERR_OVERRUN | \ - VAC_UART_STATUS_TX_EMPTY | VAC_UART_STATUS_RX_READY; - if (I_INPCK(info->tty)) - info->read_status_mask |= VAC_UART_STATUS_RX_ERR_FRAME | \ - VAC_UART_STATUS_RX_ERR_PARITY; - if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) - info->read_status_mask |= VAC_UART_STATUS_RX_BREAK_CHANGE; - - /* - * Characters to ignore - */ - info->ignore_status_mask = 0; - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= VAC_UART_STATUS_RX_ERR_PARITY | \ - VAC_UART_STATUS_RX_ERR_FRAME; - if (I_IGNBRK(info->tty)) { - info->ignore_status_mask |= VAC_UART_STATUS_RX_BREAK_CHANGE; - /* - * If we're ignore parity and break indicators, ignore - * overruns too. (For real raw support). - */ - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= \ - VAC_UART_STATUS_RX_ERR_OVERRUN; - } - /* - * !!! ignore all characters if CREAD is not set - */ - if ((cflag & CREAD) == 0) - info->ignore_status_mask |= VAC_UART_STATUS_RX_READY; - save_flags(flags); cli(); - - - switch (baud) { - default: - case 9600: - cval |= VAC_UART_MODE_BAUD(7); - break; - case 4800: - cval |= VAC_UART_MODE_BAUD(6); - break; - case 2400: - cval |= VAC_UART_MODE_BAUD(5); - break; - case 1200: - cval |= VAC_UART_MODE_BAUD(4); - break; - case 600: - cval |= VAC_UART_MODE_BAUD(3); - break; - case 300: - cval |= VAC_UART_MODE_BAUD(2); - break; -#ifndef QUAD_UART_SPEED - case 150: -#else - case 38400: -#endif - cval |= VAC_UART_MODE_BAUD(1); - break; -#ifndef QUAD_UART_SPEED - case 75: -#else - case 19200: -#endif - cval |= VAC_UART_MODE_BAUD(0); - break; - } - - /* Baget VAC need some adjustments for computed value */ - cval = vac_uart_mode_fixup(cval); - - serial_outp(info, VAC_UART_MODE, cval); - restore_flags(flags); -} - -static void rs_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_put_char")) - return; - - if (!tty || !info->xmit_buf) - return; - - save_flags(flags); cli(); - if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { - restore_flags(flags); - return; - } - - info->xmit_buf[info->xmit_head++] = ch; - info->xmit_head &= SERIAL_XMIT_SIZE-1; - info->xmit_cnt++; - restore_flags(flags); -} - -static void rs_flush_chars(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_flush_chars")) - return; - - if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || - !info->xmit_buf) - return; - - save_flags(flags); cli(); - info->IER |= VAC_UART_INT_TX_EMPTY; - serial_out(info, VAC_UART_INT_MASK, info->IER); - restore_flags(flags); -} - -static int rs_write(struct tty_struct * tty, int from_user, - const unsigned char *buf, int count) -{ - int c, ret = 0; - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_write")) - return 0; - - if (!tty || !info->xmit_buf || !tmp_buf) - return 0; - - save_flags(flags); - if (from_user) { - down(&tmp_buf_sem); - while (1) { - c = MIN(count, - MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - if (c <= 0) - break; - - c -= copy_from_user(tmp_buf, buf, c); - if (!c) { - if (!ret) - ret = -EFAULT; - break; - } - cli(); - c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c); - info->xmit_head = ((info->xmit_head + c) & - (SERIAL_XMIT_SIZE-1)); - info->xmit_cnt += c; - restore_flags(flags); - buf += c; - count -= c; - ret += c; - } - up(&tmp_buf_sem); - } else { - while (1) { - cli(); - c = MIN(count, - MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - if (c <= 0) { - restore_flags(flags); - break; - } - memcpy(info->xmit_buf + info->xmit_head, buf, c); - info->xmit_head = ((info->xmit_head + c) & - (SERIAL_XMIT_SIZE-1)); - info->xmit_cnt += c; - restore_flags(flags); - buf += c; - count -= c; - ret += c; - } - } - if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped && - !(info->IER & VAC_UART_INT_TX_EMPTY)) { - info->IER |= VAC_UART_INT_TX_EMPTY; - serial_out(info, VAC_UART_INT_MASK, info->IER); - } - return ret; -} - -static int rs_write_room(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - int ret; - - if (serial_paranoia_check(info, tty->device, "rs_write_room")) - return 0; - ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; - if (ret < 0) - ret = 0; - return ret; -} - -static int rs_chars_in_buffer(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - - if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer")) - return 0; - return info->xmit_cnt; -} - -static void rs_flush_buffer(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_flush_buffer")) - return; - - save_flags(flags); cli(); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - restore_flags(flags); - - wake_up_interruptible(&tty->write_wait); - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); -} - -/* - * This function is used to send a high-priority XON/XOFF character to - * the device - */ -static void rs_send_xchar(struct tty_struct *tty, char ch) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - - if (serial_paranoia_check(info, tty->device, "rs_send_char")) - return; - - info->x_char = ch; - if (ch) { - /* Make sure transmit interrupts are on */ - info->IER |= VAC_UART_INT_TX_EMPTY; - serial_out(info, VAC_UART_INT_MASK, info->IER); - } -} - -/* - * ------------------------------------------------------------ - * rs_throttle() - * - * This routine is called by the upper-layer tty layer to signal that - * incoming characters should be throttled. - * ------------------------------------------------------------ - */ -static void rs_throttle(struct tty_struct * tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - baget_printk("throttle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->device, "rs_throttle")) - return; - - if (I_IXOFF(tty)) - rs_send_xchar(tty, STOP_CHAR(tty)); -} - -static void rs_unthrottle(struct tty_struct * tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - baget_printk("unthrottle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->device, "rs_unthrottle")) - return; - - if (I_IXOFF(tty)) { - if (info->x_char) - info->x_char = 0; - else - rs_send_xchar(tty, START_CHAR(tty)); - } -} - -/* - * ------------------------------------------------------------ - * rs_ioctl() and friends - * ------------------------------------------------------------ - */ - -static int get_serial_info(struct async_struct * info, - struct serial_struct * retinfo) -{ - struct serial_struct tmp; - struct serial_state *state = info->state; - - if (!retinfo) - return -EFAULT; - memset(&tmp, 0, sizeof(tmp)); - tmp.type = state->type; - tmp.line = state->line; - tmp.port = state->port; - tmp.irq = state->irq; - tmp.flags = state->flags; - tmp.xmit_fifo_size = state->xmit_fifo_size; - tmp.baud_base = state->baud_base; - tmp.close_delay = state->close_delay; - tmp.closing_wait = state->closing_wait; - tmp.custom_divisor = state->custom_divisor; - tmp.hub6 = state->hub6; - if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int set_serial_info(struct async_struct * info, - struct serial_struct * new_info) -{ - struct serial_struct new_serial; - struct serial_state old_state, *state; - unsigned int i,change_irq,change_port; - int retval = 0; - - if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) - return -EFAULT; - state = info->state; - old_state = *state; - - change_irq = new_serial.irq != state->irq; - change_port = (new_serial.port != state->port) || - (new_serial.hub6 != state->hub6); - - if (!capable(CAP_SYS_ADMIN)) { - if (change_irq || change_port || - (new_serial.baud_base != state->baud_base) || - (new_serial.type != state->type) || - (new_serial.close_delay != state->close_delay) || - (new_serial.xmit_fifo_size != state->xmit_fifo_size) || - ((new_serial.flags & ~ASYNC_USR_MASK) != - (state->flags & ~ASYNC_USR_MASK))) - return -EPERM; - state->flags = ((state->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - info->flags = ((state->flags & ~ASYNC_USR_MASK) | - (info->flags & ASYNC_USR_MASK)); - state->custom_divisor = new_serial.custom_divisor; - goto check_and_exit; - } - - new_serial.irq = new_serial.irq; - - if ((new_serial.irq >= NR_IRQS) || (new_serial.port > 0xffff) || - (new_serial.baud_base == 0) || (new_serial.type < PORT_UNKNOWN) || - (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) || - (new_serial.type == PORT_STARTECH)) { - return -EINVAL; - } - - if ((new_serial.type != state->type) || - (new_serial.xmit_fifo_size <= 0)) - new_serial.xmit_fifo_size = - uart_config[state->type].dfl_xmit_fifo_size; - - /* Make sure address is not already in use */ - if (new_serial.type) { - for (i = 0 ; i < NR_PORTS; i++) - if ((state != &rs_table[i]) && - (rs_table[i].port == new_serial.port) && - rs_table[i].type) - return -EADDRINUSE; - } - - if ((change_port || change_irq) && (state->count > 1)) - return -EBUSY; - - /* - * OK, past this point, all the error checking has been done. - * At this point, we start making changes..... - */ - - state->baud_base = new_serial.baud_base; - state->flags = ((state->flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS)); - info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | - (info->flags & ASYNC_INTERNAL_FLAGS)); - state->custom_divisor = new_serial.custom_divisor; - state->type = new_serial.type; - state->close_delay = new_serial.close_delay * HZ/100; - state->closing_wait = new_serial.closing_wait * HZ/100; - info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - info->xmit_fifo_size = state->xmit_fifo_size = - new_serial.xmit_fifo_size; - - release_region(state->port,8); - if (change_port || change_irq) { - /* - * We need to shutdown the serial port at the old - * port/irq combination. - */ - shutdown(info); - state->irq = new_serial.irq; - info->port = state->port = new_serial.port; - info->hub6 = state->hub6 = new_serial.hub6; - } - if (state->type != PORT_UNKNOWN) - request_region(state->port,8,"serial(set)"); - - -check_and_exit: - if (!state->port || !state->type) - return 0; - if (info->flags & ASYNC_INITIALIZED) { - if (((old_state.flags & ASYNC_SPD_MASK) != - (state->flags & ASYNC_SPD_MASK)) || - (old_state.custom_divisor != state->custom_divisor)) { - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - info->tty->alt_speed = 57600; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - info->tty->alt_speed = 115200; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - info->tty->alt_speed = 230400; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - info->tty->alt_speed = 460800; - change_speed(info); - } - } else - retval = startup(info); - return retval; -} - - -/* - * get_lsr_info - get line status register info - * - * Purpose: Let user call ioctl() to get info when the UART physically - * is emptied. On bus types like RS485, the transmitter must - * release the bus after transmitting. This must be done when - * the transmit shift register is empty, not be done when the - * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. - */ -static int get_lsr_info(struct async_struct * info, unsigned int *value) -{ - unsigned short status; - unsigned int result; - unsigned long flags; - - save_flags(flags); cli(); - status = serial_inw(info, VAC_UART_INT_STATUS); - restore_flags(flags); - result = ((status & VAC_UART_STATUS_TX_EMPTY) ? TIOCSER_TEMT : 0); - return put_user(result,value); -} - - -static int get_modem_info(struct async_struct * info, unsigned int *value) -{ - unsigned int result; - - result = TIOCM_CAR | TIOCM_DSR; - return put_user(result,value); -} - -static int set_modem_info(struct async_struct * info, unsigned int cmd, - unsigned int *value) -{ - unsigned int arg; - - if (get_user(arg, value)) - return -EFAULT; - switch (cmd) { - default: - return -EINVAL; - } - return 0; -} - -static int do_autoconfig(struct async_struct * info) -{ - int retval; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (info->state->count > 1) - return -EBUSY; - - shutdown(info); - - autoconfig(info->state); - - retval = startup(info); - if (retval) - return retval; - return 0; -} - -/* - * rs_break() --- routine which turns the break handling on or off - */ -static void rs_break(struct tty_struct *tty, int break_state) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_break")) - return; - - if (!info->port) - return; - save_flags(flags); cli(); - if (break_state == -1) - serial_outp(info, VAC_UART_MODE, - serial_inp(info, VAC_UART_MODE) | \ - VAC_UART_MODE_SEND_BREAK); - else - serial_outp(info, VAC_UART_MODE, - serial_inp(info, VAC_UART_MODE) & \ - ~VAC_UART_MODE_SEND_BREAK); - restore_flags(flags); -} - -static int rs_ioctl(struct tty_struct *tty, struct file * file, - unsigned int cmd, unsigned long arg) -{ - int error; - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct async_icount cprev, cnow; /* kernel counter temps */ - struct serial_icounter_struct *p_cuser; /* user space */ - unsigned long flags; - - if (serial_paranoia_check(info, tty->device, "rs_ioctl")) - return -ENODEV; - - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && - (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - } - - switch (cmd) { - case TIOCMGET: - return get_modem_info(info, (unsigned int *) arg); - case TIOCMBIS: - case TIOCMBIC: - case TIOCMSET: - return set_modem_info(info, cmd, (unsigned int *) arg); - case TIOCGSERIAL: - return get_serial_info(info, - (struct serial_struct *) arg); - case TIOCSSERIAL: - return set_serial_info(info, - (struct serial_struct *) arg); - case TIOCSERCONFIG: - return do_autoconfig(info); - - case TIOCSERGETLSR: /* Get line status register */ - return get_lsr_info(info, (unsigned int *) arg); - - case TIOCSERGSTRUCT: - if (copy_to_user((struct async_struct *) arg, - info, sizeof(struct async_struct))) - return -EFAULT; - return 0; - - /* - * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)to change - * - mask passed in arg for lines of interest - * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) - * Caller should use TIOCGICOUNT to see which one it was - */ - case TIOCMIWAIT: - save_flags(flags); cli(); - /* note the counters on entry */ - cprev = info->state->icount; - restore_flags(flags); - while (1) { - interruptible_sleep_on(&info->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - save_flags(flags); cli(); - cnow = info->state->icount; /* atomic copy */ - restore_flags(flags); - if (cnow.rng == cprev.rng && - cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && - cnow.cts == cprev.cts) - return -EIO; /* no change => error */ - if ( ((arg & TIOCM_RNG) && - (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && - (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && - (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && - (cnow.cts != cprev.cts)) ) { - return 0; - } - cprev = cnow; - } - /* NOTREACHED */ - - /* - * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) - * Return: write counters to the user passed counter struct - * NB: both 1->0 and 0->1 transitions are counted except for - * RI where only 0->1 is counted. - */ - case TIOCGICOUNT: - save_flags(flags); cli(); - cnow = info->state->icount; - restore_flags(flags); - p_cuser = (struct serial_icounter_struct *) arg; - error = put_user(cnow.cts, &p_cuser->cts); - if (error) return error; - error = put_user(cnow.dsr, &p_cuser->dsr); - if (error) return error; - error = put_user(cnow.rng, &p_cuser->rng); - if (error) return error; - error = put_user(cnow.dcd, &p_cuser->dcd); - if (error) return error; - error = put_user(cnow.rx, &p_cuser->rx); - if (error) return error; - error = put_user(cnow.tx, &p_cuser->tx); - if (error) return error; - error = put_user(cnow.frame, &p_cuser->frame); - if (error) return error; - error = put_user(cnow.overrun, &p_cuser->overrun); - if (error) return error; - error = put_user(cnow.parity, &p_cuser->parity); - if (error) return error; - error = put_user(cnow.brk, &p_cuser->brk); - if (error) return error; - error = put_user(cnow.buf_overrun, &p_cuser->buf_overrun); - - if (error) return error; - return 0; - - case TIOCSERGWILD: - case TIOCSERSWILD: - /* "setserial -W" is called in Debian boot */ - printk ("TIOCSER?WILD ioctl obsolete, ignored.\n"); - return 0; - - default: - return -ENOIOCTLCMD; - } - return 0; -} - -static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned int cflag = tty->termios->c_cflag; - - if ( (cflag == old_termios->c_cflag) - && ( RELEVANT_IFLAG(tty->termios->c_iflag) - == RELEVANT_IFLAG(old_termios->c_iflag))) - return; - - change_speed(info); - - /* Handle turning off CRTSCTS */ - if ((old_termios->c_cflag & CRTSCTS) && - !(cflag & CRTSCTS)) { - tty->hw_stopped = 0; - rs_start(tty); - } - -} - -/* - * ------------------------------------------------------------ - * rs_close() - * - * This routine is called when the serial port gets closed. First, we - * wait for the last remaining data to be sent. Then, we unlink its - * async structure from the interrupt chain if necessary, and we free - * that IRQ if nothing is left in the chain. - * ------------------------------------------------------------ - */ -static void rs_close(struct tty_struct *tty, struct file * filp) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct serial_state *state; - unsigned long flags; - - if (!info || serial_paranoia_check(info, tty->device, "rs_close")) - return; - - state = info->state; - - save_flags(flags); cli(); - - if (tty_hung_up_p(filp)) { - DBG_CNT("before DEC-hung"); - MOD_DEC_USE_COUNT; - restore_flags(flags); - return; - } - -#ifdef SERIAL_DEBUG_OPEN - baget_printk("rs_close ttys%d, count = %d\n", - info->line, state->count); -#endif - if ((tty->count == 1) && (state->count != 1)) { - /* - * Uh, oh. tty->count is 1, which means that the tty - * structure will be freed. state->count should always - * be one in these conditions. If it's greater than - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ - baget_printk("rs_close: bad serial port count; " - "tty->count is 1, " - "state->count is %d\n", state->count); - state->count = 1; - } - if (--state->count < 0) { - baget_printk("rs_close: bad serial port count for " - "ttys%d: %d\n", - info->line, state->count); - state->count = 0; - } - if (state->count) { - DBG_CNT("before DEC-2"); - MOD_DEC_USE_COUNT; - restore_flags(flags); - return; - } - info->flags |= ASYNC_CLOSING; - /* - * Save the termios structure, since this port may have - * separate termios for callout and dialin. - */ - if (info->flags & ASYNC_NORMAL_ACTIVE) - info->state->normal_termios = *tty->termios; - if (info->flags & ASYNC_CALLOUT_ACTIVE) - info->state->callout_termios = *tty->termios; - /* - * Now we wait for the transmit buffer to clear; and we notify - * the line discipline to only process XON/XOFF characters. - */ - tty->closing = 1; - if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) - tty_wait_until_sent(tty, info->closing_wait); - /* - * At this point we stop accepting input. To do this, we - * disable the receive line status interrupts, and tell the - * interrupt driver to stop checking the data ready bit in the - * line status register. - */ - info->IER &= ~(VAC_UART_INT_RX_BREAK_CHANGE | VAC_UART_INT_RX_ERRS); - info->read_status_mask &= ~VAC_UART_STATUS_RX_READY; - if (info->flags & ASYNC_INITIALIZED) { - serial_outw(info, VAC_UART_INT_MASK, info->IER); - /* - * Before we drop DTR, make sure the UART transmitter - * has completely drained; this is especially - * important if there is a transmit FIFO! - */ - rs_wait_until_sent(tty, info->timeout); - } - shutdown(info); - if (tty->driver.flush_buffer) - tty->driver.flush_buffer(tty); - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - tty->closing = 0; - info->event = 0; - info->tty = 0; - if (info->blocked_open) { - if (info->close_delay) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(info->close_delay); - } - wake_up_interruptible(&info->open_wait); - } - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE| - ASYNC_CLOSING); - wake_up_interruptible(&info->close_wait); - MOD_DEC_USE_COUNT; - restore_flags(flags); -} - -/* - * rs_wait_until_sent() --- wait until the transmitter is empty - */ -static void rs_wait_until_sent(struct tty_struct *tty, int timeout) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - unsigned long orig_jiffies, char_time; - int lsr; - - if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent")) - return; - - if (info->state->type == PORT_UNKNOWN) - return; - - if (info->xmit_fifo_size == 0) - return; /* Just in case.... */ - - orig_jiffies = jiffies; - /* - * Set the check interval to be 1/5 of the estimated time to - * send a single character, and make it at least 1. The check - * interval should also be less than the timeout. - * - * Note: we have to use pretty tight timings here to satisfy - * the NIST-PCTS. - */ - char_time = (info->timeout - HZ/50) / info->xmit_fifo_size; - char_time = char_time / 5; - if (char_time == 0) - char_time = 1; - if (timeout) - char_time = MIN(char_time, timeout); -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - baget_printk("In rs_wait_until_sent(%d) check=%lu...", - timeout, char_time); - baget_printk("jiff=%lu...", jiffies); -#endif - while (!((lsr = serial_inp(info, VAC_UART_INT_STATUS)) & \ - VAC_UART_STATUS_TX_EMPTY)) { -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - baget_printk("lsr = %d (jiff=%lu)...", lsr, jiffies); -#endif - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(char_time); - if (signal_pending(current)) - break; - if (timeout && time_after(jiffies, orig_jiffies + timeout)) - break; - } - current->state = TASK_RUNNING; -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - baget_printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); -#endif -} - -/* - * rs_hangup() --- called by tty_hangup() when a hangup is signaled. - */ -static void rs_hangup(struct tty_struct *tty) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct serial_state *state = info->state; - - if (serial_paranoia_check(info, tty->device, "rs_hangup")) - return; - - state = info->state; - - rs_flush_buffer(tty); - shutdown(info); - info->event = 0; - state->count = 0; - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE); - info->tty = 0; - wake_up_interruptible(&info->open_wait); -} - -/* - * ------------------------------------------------------------ - * rs_open() and friends - * ------------------------------------------------------------ - */ -static int block_til_ready(struct tty_struct *tty, struct file * filp, - struct async_struct *info) -{ - DECLARE_WAITQUEUE(wait, current); - struct serial_state *state = info->state; - int retval; - int do_clocal = 0, extra_count = 0; - unsigned long flags; - - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); -#ifdef SERIAL_DO_RESTART - return ((info->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); -#else - return -EAGAIN; -#endif - } - - /* - * If this is a callout device, then just make sure the normal - * device isn't being used. - */ - if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) { - if (info->flags & ASYNC_NORMAL_ACTIVE) - return -EBUSY; - if ((info->flags & ASYNC_CALLOUT_ACTIVE) && - (info->flags & ASYNC_SESSION_LOCKOUT) && - (info->session != current->session)) - return -EBUSY; - if ((info->flags & ASYNC_CALLOUT_ACTIVE) && - (info->flags & ASYNC_PGRP_LOCKOUT) && - (info->pgrp != current->pgrp)) - return -EBUSY; - info->flags |= ASYNC_CALLOUT_ACTIVE; - return 0; - } - - /* - * If non-blocking mode is set, or the port is not enabled, - * then make the check up front and then exit. - */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR))) { - if (info->flags & ASYNC_CALLOUT_ACTIVE) - return -EBUSY; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - if (info->flags & ASYNC_CALLOUT_ACTIVE) { - if (state->normal_termios.c_cflag & CLOCAL) - do_clocal = 1; - } else { - if (tty->termios->c_cflag & CLOCAL) - do_clocal = 1; - } - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, state->count is dropped by one, so that - * rs_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; - add_wait_queue(&info->open_wait, &wait); -#ifdef SERIAL_DEBUG_OPEN - baget_printk("block_til_ready before block: ttys%d, count = %d\n", - state->line, state->count); -#endif - save_flags(flags); cli(); - if (!tty_hung_up_p(filp)) { - extra_count = 1; - state->count--; - } - restore_flags(flags); - info->blocked_open++; - while (1) { - set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !(info->flags & ASYNC_INITIALIZED)) { -#ifdef SERIAL_DO_RESTART - if (info->flags & ASYNC_HUP_NOTIFY) - retval = -EAGAIN; - else - retval = -ERESTARTSYS; -#else - retval = -EAGAIN; -#endif - break; - } - if (!(info->flags & ASYNC_CALLOUT_ACTIVE) && - !(info->flags & ASYNC_CLOSING)) - break; - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } -#ifdef SERIAL_DEBUG_OPEN - baget_printk("block_til_ready blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif - schedule(); - } - current->state = TASK_RUNNING; - remove_wait_queue(&info->open_wait, &wait); - if (extra_count) - state->count++; - info->blocked_open--; -#ifdef SERIAL_DEBUG_OPEN - baget_printk("block_til_ready after blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif - if (retval) - return retval; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; -} - -static int get_async_struct(int line, struct async_struct **ret_info) -{ - struct async_struct *info; - struct serial_state *sstate; - - sstate = rs_table + line; - sstate->count++; - if (sstate->info) { - *ret_info = sstate->info; - return 0; - } - info = kmalloc(sizeof(struct async_struct), GFP_KERNEL); - if (!info) { - sstate->count--; - return -ENOMEM; - } - memset(info, 0, sizeof(struct async_struct)); - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - init_waitqueue_head(&info->delta_msr_wait); - info->magic = SERIAL_MAGIC; - info->port = sstate->port; - info->flags = sstate->flags; - info->xmit_fifo_size = sstate->xmit_fifo_size; - info->line = line; - info->tqueue.routine = do_softint; - info->tqueue.data = info; - info->state = sstate; - if (sstate->info) { - kfree(info); - *ret_info = sstate->info; - return 0; - } - *ret_info = sstate->info = info; - return 0; -} - -/* - * This routine is called whenever a serial port is opened. It - * enables interrupts for a serial port, linking in its async structure into - * the IRQ chain. It also performs the serial-specific - * initialization for the tty structure. - */ -static int rs_open(struct tty_struct *tty, struct file * filp) -{ - struct async_struct *info; - int retval, line; - unsigned long page; - - MOD_INC_USE_COUNT; - line = MINOR(tty->device) - tty->driver.minor_start; - if ((line < 0) || (line >= NR_PORTS)) { - MOD_DEC_USE_COUNT; - return -ENODEV; - } - retval = get_async_struct(line, &info); - if (retval) { - MOD_DEC_USE_COUNT; - return retval; - } - tty->driver_data = info; - info->tty = tty; - if (serial_paranoia_check(info, tty->device, "rs_open")) { - /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ - return -ENODEV; - } - -#ifdef SERIAL_DEBUG_OPEN - baget_printk("rs_open %s%d, count = %d\n", - tty->driver.name, info->line, - info->state->count); -#endif - info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - - if (!tmp_buf) { - page = get_free_page(GFP_KERNEL); - if (!page) { - /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ - return -ENOMEM; - } - if (tmp_buf) - free_page(page); - else - tmp_buf = (unsigned char *) page; - } - - /* - * If the port is the middle of closing, bail out now - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); - /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ -#ifdef SERIAL_DO_RESTART - return ((info->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); -#else - return -EAGAIN; -#endif - } - - /* - * Start up serial port - */ - retval = startup(info); - if (retval) { - /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ - return retval; - } - - retval = block_til_ready(tty, filp, info); - if (retval) { - /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ -#ifdef SERIAL_DEBUG_OPEN - baget_printk("rs_open returning after block_til_ready " - "with %d\n", - retval); -#endif - return retval; - } - - if ((info->state->count == 1) && - (info->flags & ASYNC_SPLIT_TERMIOS)) { - if (tty->driver.subtype == SERIAL_TYPE_NORMAL) - *tty->termios = info->state->normal_termios; - else - *tty->termios = info->state->callout_termios; - change_speed(info); - } -#ifdef CONFIG_SERIAL_CONSOLE - if (sercons.cflag && sercons.index == line) { - tty->termios->c_cflag = sercons.cflag; - sercons.cflag = 0; - change_speed(info); - } -#endif - info->session = current->session; - info->pgrp = current->pgrp; - -#ifdef SERIAL_DEBUG_OPEN - baget_printk("rs_open ttys%d successful...", info->line); -#endif - return 0; -} - -/* - * /proc fs routines.... - */ - -static inline int line_info(char *buf, struct serial_state *state) -{ - struct async_struct *info = state->info, scr_info; - int ret; - - ret = sprintf(buf, "%d: uart:%s port:%X irq:%d", - state->line, uart_config[state->type].name, - state->port, state->irq); - - if (!state->port || (state->type == PORT_UNKNOWN)) { - ret += sprintf(buf+ret, "\n"); - return ret; - } - - /* - * Figure out the current RS-232 lines - */ - if (!info) { - info = &scr_info; /* This is just for serial_{in,out} */ - - info->magic = SERIAL_MAGIC; - info->port = state->port; - info->flags = state->flags; - info->quot = 0; - info->tty = 0; - } - - if (info->quot) { - ret += sprintf(buf+ret, " baud:%d", - state->baud_base / info->quot); - } - - ret += sprintf(buf+ret, " tx:%d rx:%d", - state->icount.tx, state->icount.rx); - - if (state->icount.frame) - ret += sprintf(buf+ret, " fe:%d", state->icount.frame); - - if (state->icount.parity) - ret += sprintf(buf+ret, " pe:%d", state->icount.parity); - - if (state->icount.brk) - ret += sprintf(buf+ret, " brk:%d", state->icount.brk); - - if (state->icount.overrun) - ret += sprintf(buf+ret, " oe:%d", state->icount.overrun); - - return ret; -} - -int rs_read_proc(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - int i, len = 0, l; - off_t begin = 0; - - len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version); - for (i = 0; i < NR_PORTS && len < 4000; i++) { - l = line_info(page + len, &rs_table[i]); - len += l; - if (len+begin > off+count) - goto done; - if (len+begin < off) { - begin += len; - len = 0; - } - } - *eof = 1; -done: - if (off >= len+begin) - return 0; - *start = page + (off-begin); - return ((count < begin+len-off) ? count : begin+len-off); -} - -/* - * --------------------------------------------------------------------- - * rs_init() and friends - * - * rs_init() is called at boot-time to initialize the serial driver. - * --------------------------------------------------------------------- - */ - -/* - * This routine prints out the appropriate serial driver version - * number, and identifies which options were configured into this - * driver. - */ -static _INLINE_ void show_serial_version(void) -{ - printk(KERN_INFO "%s version %s with", serial_name, serial_version); -#ifdef CONFIG_SERIAL_SHARE_IRQ - printk(" SHARE_IRQ"); -#endif -#define SERIAL_OPT -#ifdef CONFIG_SERIAL_DETECT_IRQ - printk(" DETECT_IRQ"); -#endif -#ifdef SERIAL_OPT - printk(" enabled\n"); -#else - printk(" no serial options enabled\n"); -#endif -#undef SERIAL_OPT -} - - -/* - * This routine is called by rs_init() to initialize a specific serial - * port. It determines what type of UART chip this serial port is - * using: 8250, 16450, 16550, 16550A. The important question is - * whether or not this UART is a 16550A or not, since this will - * determine whether or not we can use its FIFO features or not. - */ - -/* - * Functionality of this function is reduced: we already know we have a VAC, - * but still need to perform some important actions (see code :-). - */ -static void autoconfig(struct serial_state * state) -{ - struct async_struct *info, scr_info; - unsigned long flags; - - /* Setting up important parameters */ - state->type = VAC_UART_TYPE; - state->xmit_fifo_size = uart_config[state->type].dfl_xmit_fifo_size; - - info = &scr_info; /* This is just for serial_{in,out} */ - - info->magic = SERIAL_MAGIC; - info->port = state->port; - info->flags = state->flags; - - save_flags(flags); cli(); - - /* + Flush VAC input fifo */ - (void)serial_in(info, VAC_UART_RX); - (void)serial_in(info, VAC_UART_RX); - (void)serial_in(info, VAC_UART_RX); - (void)serial_in(info, VAC_UART_RX); - - /* Disable interrupts */ - serial_outp(info, VAC_UART_INT_MASK, 0); - - restore_flags(flags); -} - -int register_serial(struct serial_struct *req); -void unregister_serial(int line); - -EXPORT_SYMBOL(register_serial); -EXPORT_SYMBOL(unregister_serial); - -/* - * Important function for VAC UART check and reanimation. - */ - -static void rs_timer(unsigned long dummy) -{ - static unsigned long last_strobe = 0; - struct async_struct *info; - unsigned int i; - unsigned long flags; - - if ((jiffies - last_strobe) >= RS_STROBE_TIME) { - for (i=1; i < NR_IRQS; i++) { - info = IRQ_ports[i]; - if (!info) - continue; - save_flags(flags); cli(); -#ifdef CONFIG_SERIAL_SHARE_IRQ - if (info->next_port) { - do { - serial_out(info, VAC_UART_INT_MASK, 0); - info->IER |= VAC_UART_INT_TX_EMPTY; - serial_out(info, VAC_UART_INT_MASK, - info->IER); - info = info->next_port; - } while (info); - rs_interrupt(i, NULL, NULL); - } else -#endif /* CONFIG_SERIAL_SHARE_IRQ */ - rs_interrupt_single(i, NULL, NULL); - restore_flags(flags); - } - } - last_strobe = jiffies; - mod_timer(&vacs_timer, jiffies + RS_STROBE_TIME); - - /* - * It looks this code for case we share IRQ with console... - */ - - if (IRQ_ports[0]) { - save_flags(flags); cli(); -#ifdef CONFIG_SERIAL_SHARE_IRQ - rs_interrupt(0, NULL, NULL); -#else - rs_interrupt_single(0, NULL, NULL); -#endif - restore_flags(flags); - - mod_timer(&vacs_timer, jiffies + IRQ_timeout[0] - 2); - } -} - -/* - * The serial driver boot-time initialization code! - */ -int __init rs_init(void) -{ - int i; - struct serial_state * state; - extern void atomwide_serial_init (void); - extern void dualsp_serial_init (void); - -#ifdef CONFIG_ATOMWIDE_SERIAL - atomwide_serial_init (); -#endif -#ifdef CONFIG_DUALSP_SERIAL - dualsp_serial_init (); -#endif - - init_bh(SERIAL_BH, do_serial_bh); - init_timer(&vacs_timer); - vacs_timer.function = rs_timer; - vacs_timer.expires = 0; - - for (i = 0; i < NR_IRQS; i++) { - IRQ_ports[i] = 0; - IRQ_timeout[i] = 0; - } - - -/* - * It is not a good idea to share interrupts with console, - * but it looks we cannot avoid it. - */ -#if 0 - -#ifdef CONFIG_SERIAL_CONSOLE - /* - * The interrupt of the serial console port - * can't be shared. - */ - if (sercons.flags & CON_CONSDEV) { - for(i = 0; i < NR_PORTS; i++) - if (i != sercons.index && - rs_table[i].irq == rs_table[sercons.index].irq) - rs_table[i].irq = 0; - } -#endif - -#endif - show_serial_version(); - - /* Initialize the tty_driver structure */ - - memset(&serial_driver, 0, sizeof(struct tty_driver)); - serial_driver.magic = TTY_DRIVER_MAGIC; - serial_driver.driver_name = "serial"; - serial_driver.name = "ttyS"; - serial_driver.major = TTY_MAJOR; - serial_driver.minor_start = 64; - serial_driver.num = NR_PORTS; - serial_driver.type = TTY_DRIVER_TYPE_SERIAL; - serial_driver.subtype = SERIAL_TYPE_NORMAL; - serial_driver.init_termios = tty_std_termios; - serial_driver.init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - serial_driver.flags = TTY_DRIVER_REAL_RAW; - serial_driver.refcount = &serial_refcount; - serial_driver.table = serial_table; - serial_driver.termios = serial_termios; - serial_driver.termios_locked = serial_termios_locked; - - serial_driver.open = rs_open; - serial_driver.close = rs_close; - serial_driver.write = rs_write; - serial_driver.put_char = rs_put_char; - serial_driver.flush_chars = rs_flush_chars; - serial_driver.write_room = rs_write_room; - serial_driver.chars_in_buffer = rs_chars_in_buffer; - serial_driver.flush_buffer = rs_flush_buffer; - serial_driver.ioctl = rs_ioctl; - serial_driver.throttle = rs_throttle; - serial_driver.unthrottle = rs_unthrottle; - serial_driver.send_xchar = rs_send_xchar; - serial_driver.set_termios = rs_set_termios; - serial_driver.stop = rs_stop; - serial_driver.start = rs_start; - serial_driver.hangup = rs_hangup; - serial_driver.break_ctl = rs_break; - serial_driver.wait_until_sent = rs_wait_until_sent; - serial_driver.read_proc = rs_read_proc; - - /* - * The callout device is just like normal device except for - * major number and the subtype code. - */ - callout_driver = serial_driver; - callout_driver.name = "cua"; - callout_driver.major = TTYAUX_MAJOR; - callout_driver.subtype = SERIAL_TYPE_CALLOUT; - callout_driver.read_proc = 0; - callout_driver.proc_entry = 0; - - if (tty_register_driver(&serial_driver)) - panic("Couldn't register serial driver"); - if (tty_register_driver(&callout_driver)) - panic("Couldn't register callout driver"); - - for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { - state->magic = SSTATE_MAGIC; - state->line = i; - state->type = PORT_UNKNOWN; - state->custom_divisor = 0; - state->close_delay = 5*HZ/10; - state->closing_wait = 30*HZ; - state->callout_termios = callout_driver.init_termios; - state->normal_termios = serial_driver.init_termios; - state->icount.cts = state->icount.dsr = - state->icount.rng = state->icount.dcd = 0; - state->icount.rx = state->icount.tx = 0; - state->icount.frame = state->icount.parity = 0; - state->icount.overrun = state->icount.brk = 0; - state->irq = state->irq; - if (check_region(state->port,8)) - continue; - if (state->flags & ASYNC_BOOT_AUTOCONF) - autoconfig(state); - } - - /* - * Detect the IRQ only once every port is initialised, - * because some 16450 do not reset to 0 the MCR register. - */ - for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { - if (state->type == PORT_UNKNOWN) - continue; - printk(KERN_INFO "ttyS%02d%s at 0x%04x (irq = %d) is a %s\n", - state->line, - (state->flags & ASYNC_FOURPORT) ? " FourPort" : "", - state->port, state->irq, - uart_config[state->type].name); - } - return 0; -} - -/* - * register_serial and unregister_serial allows for serial ports to be - * configured at run-time, to support PCMCIA modems. - */ -int register_serial(struct serial_struct *req) -{ - int i; - unsigned long flags; - struct serial_state *state; - - save_flags(flags); - cli(); - for (i = 0; i < NR_PORTS; i++) { - if (rs_table[i].port == req->port) - break; - } - if (i == NR_PORTS) { - for (i = 0; i < NR_PORTS; i++) - if ((rs_table[i].type == PORT_UNKNOWN) && - (rs_table[i].count == 0)) - break; - } - if (i == NR_PORTS) { - restore_flags(flags); - return -1; - } - state = &rs_table[i]; - if (rs_table[i].count) { - restore_flags(flags); - printk("Couldn't configure serial #%d (port=%d,irq=%d): " - "device already open\n", i, req->port, req->irq); - return -1; - } - state->irq = req->irq; - state->port = req->port; - state->flags = req->flags; - - autoconfig(state); - if (state->type == PORT_UNKNOWN) { - restore_flags(flags); - printk("register_serial(): autoconfig failed\n"); - return -1; - } - restore_flags(flags); - - printk(KERN_INFO "tty%02d at 0x%04x (irq = %d) is a %s\n", - state->line, state->port, state->irq, - uart_config[state->type].name); - return state->line; -} - -void unregister_serial(int line) -{ - unsigned long flags; - struct serial_state *state = &rs_table[line]; - - save_flags(flags); - cli(); - if (state->info && state->info->tty) - tty_hangup(state->info->tty); - state->type = PORT_UNKNOWN; - printk(KERN_INFO "tty%02d unloaded\n", state->line); - restore_flags(flags); -} - -#ifdef MODULE -int init_module(void) -{ - return rs_init(); -} - -void cleanup_module(void) -{ - unsigned long flags; - int e1, e2; - int i; - - printk("Unloading %s: version %s\n", serial_name, serial_version); - save_flags(flags); - cli(); - - del_timer_sync(&vacs_timer); - remove_bh(SERIAL_BH); - - if ((e1 = tty_unregister_driver(&serial_driver))) - printk("SERIAL: failed to unregister serial driver (%d)\n", - e1); - if ((e2 = tty_unregister_driver(&callout_driver))) - printk("SERIAL: failed to unregister callout driver (%d)\n", - e2); - restore_flags(flags); - - for (i = 0; i < NR_PORTS; i++) { - if (rs_table[i].type != PORT_UNKNOWN) - release_region(rs_table[i].port, 8); - } - if (tmp_buf) { - free_page((unsigned long) tmp_buf); - tmp_buf = NULL; - } -} -#endif /* MODULE */ - - -/* - * ------------------------------------------------------------ - * Serial console driver - * ------------------------------------------------------------ - */ -#ifdef CONFIG_SERIAL_CONSOLE - -#define BOTH_EMPTY (VAC_UART_STATUS_TX_EMPTY | VAC_UART_STATUS_TX_EMPTY) - -/* - * Wait for transmitter & holding register to empty - */ -static inline void wait_for_xmitr(struct async_struct *info) -{ - int lsr; - unsigned int tmout = 1000000; - - do { - lsr = serial_inp(info, VAC_UART_INT_STATUS); - if (--tmout == 0) break; - } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY); -} - -/* - * Print a string to the serial port trying not to disturb - * any possible real use of the port... - */ -static void serial_console_write(struct console *co, const char *s, - unsigned count) -{ - struct serial_state *ser; - int ier; - unsigned i; - struct async_struct scr_info; /* serial_{in,out} because HUB6 */ - - ser = rs_table + co->index; - scr_info.magic = SERIAL_MAGIC; - scr_info.port = ser->port; - scr_info.flags = ser->flags; - - /* - * First save the IER then disable the interrupts - */ - ier = serial_inp(&scr_info, VAC_UART_INT_MASK); - serial_outw(&scr_info, VAC_UART_INT_MASK, 0x00); - - /* - * Now, do each character - */ - for (i = 0; i < count; i++, s++) { - wait_for_xmitr(&scr_info); - - /* - * Send the character out. - * If a LF, also do CR... - */ - serial_outp(&scr_info, VAC_UART_TX, (unsigned short)*s << 8); - if (*s == 10) { - wait_for_xmitr(&scr_info); - serial_outp(&scr_info, VAC_UART_TX, 13 << 8); - } - } - - /* - * Finally, Wait for transmitter & holding register to empty - * and restore the IER - */ - wait_for_xmitr(&scr_info); - serial_outp(&scr_info, VAC_UART_INT_MASK, ier); -} - -static kdev_t serial_console_device(struct console *c) -{ - return MKDEV(TTY_MAJOR, 64 + c->index); -} - -/* - * Setup initial baud/bits/parity. We do two things here: - * - construct a cflag setting for the first rs_open() - * - initialize the serial port - * Return non-zero if we didn't find a serial port. - */ -static int __init serial_console_setup(struct console *co, char *options) -{ - struct serial_state *ser; - unsigned cval; - int baud = 9600; - int bits = 8; - int parity = 'n'; - int cflag = CREAD | HUPCL | CLOCAL; - int quot = 0; - char *s; - struct async_struct scr_info; /* serial_{in,out} because HUB6 */ - - if (options) { - baud = simple_strtoul(options, NULL, 10); - s = options; - while(*s >= '0' && *s <= '9') - s++; - if (*s) parity = *s++; - if (*s) bits = *s - '0'; - } - - /* - * Now construct a cflag setting. - */ - switch(baud) { - case 1200: - cflag |= B1200; - break; - case 2400: - cflag |= B2400; - break; - case 4800: - cflag |= B4800; - break; - case 19200: - cflag |= B19200; - break; - case 38400: - cflag |= B38400; - break; - case 57600: - cflag |= B57600; - break; - case 115200: - cflag |= B115200; - break; - case 9600: - default: - cflag |= B9600; - break; - } - switch(bits) { - case 7: - cflag |= CS7; - break; - default: - case 8: - cflag |= CS8; - break; - } - switch(parity) { - case 'o': case 'O': - cflag |= PARODD; - break; - case 'e': case 'E': - cflag |= PARENB; - break; - } - co->cflag = cflag; - - /* - * Divisor, bytesize and parity - */ - ser = rs_table + co->index; - scr_info.magic = SERIAL_MAGIC; - scr_info.port = ser->port; - scr_info.flags = ser->flags; - - quot = ser->baud_base / baud; - cval = cflag & (CSIZE | CSTOPB); - - cval >>= 4; - - cval &= ~VAC_UART_MODE_PARITY_ENABLE; - if (cflag & PARENB) - cval |= VAC_UART_MODE_PARITY_ENABLE; - if (cflag & PARODD) - cval |= VAC_UART_MODE_PARITY_ODD; - - /* - * Disable UART interrupts, set DTR and RTS high - * and set speed. - */ - switch (baud) { - default: - case 9600: - cval |= VAC_UART_MODE_BAUD(7); - break; - case 4800: - cval |= VAC_UART_MODE_BAUD(6); - break; - case 2400: - cval |= VAC_UART_MODE_BAUD(5); - break; - case 1200: - cval |= VAC_UART_MODE_BAUD(4); - break; - case 600: - cval |= VAC_UART_MODE_BAUD(3); - break; - case 300: - cval |= VAC_UART_MODE_BAUD(2); - break; -#ifndef QUAD_UART_SPEED - case 150: -#else - case 38400: -#endif - cval |= VAC_UART_MODE_BAUD(1); - break; -#ifndef QUAD_UART_SPEED - case 75: -#else - case 19200: -#endif - cval |= VAC_UART_MODE_BAUD(0); - break; - } - - /* Baget VAC need some adjustments for computed value */ - cval = vac_uart_mode_fixup(cval); - - serial_outp(&scr_info, VAC_UART_MODE, cval); - serial_outp(&scr_info, VAC_UART_INT_MASK, 0); - - return 0; -} - -static struct console sercons = { - name: "ttyS", - write: serial_console_write, - device: serial_console_device, - setup: serial_console_setup, - flags: CON_PRINTBUFFER, - index: -1, -}; - -/* - * Register console. - */ -long __init serial_console_init(long kmem_start, long kmem_end) -{ - register_console(&sercons); - return kmem_start; -} -#endif - -#ifdef CONFIG_REMOTE_DEBUG -#undef PRINT_DEBUG_PORT_INFO - -/* - * This is the interface to the remote debugger stub. - * I've put that here to be able to control the serial - * device more directly. - */ - -static int initialized; - -static int rs_debug_init(struct async_struct *info) -{ - int quot; - - autoconfig(info); /* autoconfigure ttyS0, whatever that is */ - -#ifdef PRINT_DEBUG_PORT_INFO - baget_printk("kgdb debug interface:: tty%02d at 0x%04x", - info->line, info->port); - switch (info->type) { - case PORT_8250: - baget_printk(" is a 8250\n"); - break; - case PORT_16450: - baget_printk(" is a 16450\n"); - break; - case PORT_16550: - baget_printk(" is a 16550\n"); - break; - case PORT_16550A: - baget_printk(" is a 16550A\n"); - break; - case PORT_16650: - baget_printk(" is a 16650\n"); - break; - default: - baget_printk(" is of unknown type -- unusable\n"); - break; - } -#endif - - if (info->port == PORT_UNKNOWN) - return -1; - - /* - * Clear all interrupts - */ - - (void)serial_inp(info, VAC_UART_INT_STATUS); - (void)serial_inp(info, VAC_UART_RX); - - /* - * Now, initialize the UART - */ - serial_outp(info,VAC_UART_MODE,VAC_UART_MODE_INITIAL); /* reset DLAB */ - if (info->flags & ASYNC_FOURPORT) { - info->MCR = UART_MCR_DTR | UART_MCR_RTS; - info->MCR_noint = UART_MCR_DTR | UART_MCR_OUT1; - } else { - info->MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; - info->MCR_noint = UART_MCR_DTR | UART_MCR_RTS; - } - - info->MCR = info->MCR_noint; /* no interrupts, please */ - /* - * and set the speed of the serial port - * (currently hardwired to 9600 8N1 - */ - - quot = info->baud_base / 9600; /* baud rate is fixed to 9600 */ - /* FIXME: if rs_debug interface is needed, we need to set speed here */ - - return 0; -} - -int putDebugChar(char c) -{ - struct async_struct *info = rs_table; - - if (!initialized) { /* need to init device first */ - if (rs_debug_init(info) == 0) - initialized = 1; - else - return 0; - } - - while ((serial_inw(info, VAC_UART_INT_STATUS) & \ - VAC_UART_STATUS_TX_EMPTY) == 0) - ; - serial_out(info, VAC_UART_TX, (unsigned short)c << 8); - - return 1; -} - -char getDebugChar(void) -{ - struct async_struct *info = rs_table; - - if (!initialized) { /* need to init device first */ - if (rs_debug_init(info) == 0) - initialized = 1; - else - return 0; - } - while (!(serial_inw(info, VAC_UART_INT_STATUS) & \ - VAC_UART_STATUS_RX_READY)) - ; - - return(serial_inp(info, VAC_UART_RX)); -} - -#endif /* CONFIG_REMOTE_DEBUG */ diff -urN linux-2.4.21-bk37/arch/mips/baget/wbflush.c linux-2.4.21-bk38/arch/mips/baget/wbflush.c --- linux-2.4.21-bk37/arch/mips/baget/wbflush.c 2000-02-24 22:52:30.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/baget/wbflush.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,24 +0,0 @@ -/* - * Setup the right wbflush routine for Baget/MIPS. - * - * Copyright (C) 1999 Gleb Raiko & Vladimir Roganov - */ - -#include -#include - -void (*__wbflush) (void); - -static void wbflush_baget(void); - -void __init wbflush_setup(void) -{ - __wbflush = wbflush_baget; -} - -/* - * Baget/MIPS doesnt need to write back the WB. - */ -static void wbflush_baget(void) -{ -} diff -urN linux-2.4.21-bk37/arch/mips/boot/elf2ecoff.c linux-2.4.21-bk38/arch/mips/boot/elf2ecoff.c --- linux-2.4.21-bk37/arch/mips/boot/elf2ecoff.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/boot/elf2ecoff.c 2003-08-24 02:55:57.000000000 -0700 @@ -285,7 +285,7 @@ if (argc < 3 || argc > 4) { usage: fprintf(stderr, - "usage: elf2aout [-a]\n"); + "usage: elf2ecoff [-a]\n"); exit(1); } if (argc == 4) { diff -urN linux-2.4.21-bk37/arch/mips/cobalt/Makefile linux-2.4.21-bk38/arch/mips/cobalt/Makefile --- linux-2.4.21-bk37/arch/mips/cobalt/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/cobalt/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -11,6 +11,7 @@ O_TARGET := cobalt.o -obj-y := irq.o int-handler.o pci.o reset.o setup.o via.o promcon.o +obj-y := irq.o int-handler.o reset.o setup.o via.o promcon.o +obj-$(CONFIG_PCI) += pci.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/cobalt/int-handler.S linux-2.4.21-bk38/arch/mips/cobalt/int-handler.S --- linux-2.4.21-bk37/arch/mips/cobalt/int-handler.S 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/cobalt/int-handler.S 2003-08-24 02:55:57.000000000 -0700 @@ -6,8 +6,7 @@ * for more details. * * Copyright (C) 1995, 1996, 1997 by Ralf Baechle - * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv) - * + * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) */ #include #include @@ -30,7 +29,9 @@ /* * Get pending Interrupts */ - mfc0 s0,CP0_CAUSE # get irq mask + mfc0 s0,CP0_CAUSE # get raw irq status + mfc0 a0,CP0_STATUS # get irq mask + and s0,s0,a0 # compute masked irq status andi a0,s0,CAUSEF_IP2 /* Check for Galileo timer */ beq a0,zero,1f @@ -57,7 +58,7 @@ andi a0,s0,CAUSEF_IP4 /* Ethernet 0 interrupt */ - li a0,COBALT_RAQ_ETH0_IRQ + li a0,COBALT_ETH0_IRQ jal do_IRQ move a1,sp @@ -69,7 +70,7 @@ andi a0,s0,CAUSEF_IP5 /* Ethernet 1 interrupt */ - li a0,COBALT_RAQ_ETH1_IRQ + li a0,COBALT_ETH1_IRQ jal do_IRQ move a1,sp @@ -80,7 +81,7 @@ andi a0,s0,CAUSEF_IP7 /* Serial interrupt */ - li a0,7 + li a0,COBALT_SERIAL_IRQ jal do_IRQ move a1,sp @@ -91,7 +92,7 @@ nop /* PCI interrupt */ - li a0,9 + li a0,COBALT_QUBE_SLOT_IRQ jal do_IRQ move a1,sp diff -urN linux-2.4.21-bk37/arch/mips/cobalt/irq.c linux-2.4.21-bk38/arch/mips/cobalt/irq.c --- linux-2.4.21-bk37/arch/mips/cobalt/irq.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/cobalt/irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -77,7 +78,7 @@ unsigned long flags; save_and_cli(flags); - change_cp0_status(irqnr_to_type[irq], irqnr_to_type[irq]); + change_c0_status(irqnr_to_type[irq], irqnr_to_type[irq]); restore_flags(flags); } @@ -93,7 +94,7 @@ unsigned long flags; save_and_cli(flags); - change_cp0_status(irqnr_to_type[irq], ~(irqnr_to_type[irq])); + change_c0_status(irqnr_to_type[irq], ~(irqnr_to_type[irq])); restore_flags(flags); } @@ -133,8 +134,8 @@ /* Mask all cpu interrupts (except IE4, we already masked those at VIA level) */ - clear_cp0_status(ST0_IM); - set_cp0_status(IE_IRQ4); + clear_c0_status(ST0_IM); + set_c0_status(IE_IRQ4); cli(); diff -urN linux-2.4.21-bk37/arch/mips/cobalt/pci.c linux-2.4.21-bk38/arch/mips/cobalt/pci.c --- linux-2.4.21-bk37/arch/mips/cobalt/pci.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/cobalt/pci.c 2003-08-24 02:55:57.000000000 -0700 @@ -6,8 +6,7 @@ * for more details. * * Copyright (C) 1995, 1996, 1997 by Ralf Baechle - * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv) - * + * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) */ #include @@ -16,9 +15,10 @@ #include #include -#include #include #include +#include +#include #ifdef CONFIG_PCI @@ -48,7 +48,7 @@ { unsigned short pci_cmd; unsigned long ioaddr_base = 0x10108000; /* It's magic, ask Doug. */ - unsigned long memaddr_base = 0x12000000; + unsigned long memaddr_base = 0x12001000; int i; /* Enable bits in COMMAND so driver can talk to it. */ @@ -60,6 +60,9 @@ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, COBALT_QUBE_SLOT_IRQ); dev->irq = COBALT_QUBE_SLOT_IRQ; + ioaddr_base += 0x2000 * PCI_FUNC(dev->devfn); + memaddr_base += 0x2000 * PCI_FUNC(dev->devfn); + /* Fixup base addresses, we only support I/O at the moment. */ for(i = 0; i <= 5; i++) { unsigned int regaddr = (PCI_BASE_ADDRESS_0 + (i * 4)); @@ -125,27 +128,18 @@ /* Fixup the first tulip located at device PCICONF_ETH0 */ if (PCI_SLOT(dev->devfn) == COBALT_PCICONF_ETH0) { - /* - * The IRQ of the first Tulip is different on Qube and RaQ - */ - if (cobalt_board_id == COBALT_BRD_ID_RAQ2) { - /* Setup the first Tulip on the RAQ */ - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, - COBALT_RAQ_ETH0_IRQ); - dev->irq = COBALT_RAQ_ETH0_IRQ; - } else { - /* All Qube's route this the same way. */ - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, - COBALT_QUBE_ETH_IRQ); - dev->irq = COBALT_QUBE_ETH_IRQ; - } + /* Setup the first Tulip */ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + COBALT_ETH0_IRQ); + dev->irq = COBALT_ETH0_IRQ; + dev->resource[0].start = 0x100000; dev->resource[0].end = 0x10007f; - if (dev->resource[1].start < 0x10000000) { - dev->resource[1].start = 0xe9ffec00; - dev->resource[1].end = 0xe9ffefff; - pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0xe9ffec00); - } + + dev->resource[1].start = 0x12000000; + dev->resource[1].end = dev->resource[1].start + 0x3ff; + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, dev->resource[1].start); + /* Fixup the second tulip located at device PCICONF_ETH1 */ } else if (PCI_SLOT(dev->devfn) == COBALT_PCICONF_ETH1) { @@ -156,14 +150,18 @@ /* Give it it's IRQ. */ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, - COBALT_RAQ_ETH1_IRQ); - dev->irq = COBALT_RAQ_ETH1_IRQ; + COBALT_ETH1_IRQ); + dev->irq = COBALT_ETH1_IRQ; /* And finally, a usable I/O space allocation, right after what * the first Tulip uses. */ dev->resource[0].start = 0x101000; dev->resource[0].end = 0x10107f; + + dev->resource[1].start = 0x12000400; + dev->resource[1].end = dev->resource[1].start + 0x3ff; + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, dev->resource[1].start); } } @@ -194,7 +192,10 @@ /* And finally, a usable I/O space allocation, right after what * the second Tulip uses. */ - pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x10102001); + dev->resource[0].start = 0x102000; + dev->resource[0].end = dev->resource[0].start + 0xff; + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x10102000); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0x00002000); pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, 0x00100000); } @@ -219,15 +220,15 @@ */ pci_read_config_word(dev, PCI_REVISION_ID, &galileo_id); galileo_id &= 0xff; /* mask off class info */ - if (galileo_id == 0x10) { + if (galileo_id >= 0x10) { /* New Galileo, assumes PCI stop line to VIA is connected. */ - *((volatile unsigned int *)0xb4000c04) = 0x00004020; + GALILEO_OUTL(0x4020, GT_PCI0_TOR_OFS); } else if (galileo_id == 0x1 || galileo_id == 0x2) { signed int timeo; /* XXX WE MUST DO THIS ELSE GALILEO LOCKS UP! -DaveM */ - timeo = *((volatile unsigned int *)0xb4000c04); + timeo = GALILEO_INL(GT_PCI0_TOR_OFS); /* Old Galileo, assumes PCI STOP line to VIA is disconnected. */ - *((volatile unsigned int *)0xb4000c04) = 0x0000ffff; + GALILEO_OUTL(0xffff, GT_PCI0_TOR_OFS); } } @@ -266,12 +267,9 @@ return -1; /* NOT ok device number */ } -#define PCI_CFG_DATA ((volatile unsigned long *)0xb4000cfc) -#define PCI_CFG_CTRL ((volatile unsigned long *)0xb4000cf8) - #define PCI_CFG_SET(dev,where) \ - ((*PCI_CFG_CTRL) = (0x80000000 | (PCI_SLOT ((dev)->devfn) << 11) | \ - (PCI_FUNC ((dev)->devfn) << 8) | (where))) + GALILEO_OUTL((0x80000000 | (((dev)->devfn) << 8) | \ + (where)), GT_PCI0_CFGADDR_OFS) static int qube_pci_read_config_dword (struct pci_dev *dev, int where, @@ -284,7 +282,7 @@ return PCIBIOS_DEVICE_NOT_FOUND; } PCI_CFG_SET(dev, where); - *val = *PCI_CFG_DATA; + *val = GALILEO_INL(GT_PCI0_CFGDATA_OFS); return PCIBIOS_SUCCESSFUL; } @@ -299,7 +297,7 @@ return PCIBIOS_DEVICE_NOT_FOUND; } PCI_CFG_SET(dev, (where & ~0x3)); - *val = *PCI_CFG_DATA >> ((where & 3) * 8); + *val = GALILEO_INL(GT_PCI0_CFGDATA_OFS) >> ((where & 3) * 8); return PCIBIOS_SUCCESSFUL; } @@ -312,7 +310,7 @@ return PCIBIOS_DEVICE_NOT_FOUND; } PCI_CFG_SET(dev, (where & ~0x3)); - *val = *PCI_CFG_DATA >> ((where & 3) * 8); + *val = GALILEO_INL(GT_PCI0_CFGDATA_OFS) >> ((where & 3) * 8); return PCIBIOS_SUCCESSFUL; } @@ -325,7 +323,7 @@ if (pci_range_ck (dev)) return PCIBIOS_DEVICE_NOT_FOUND; PCI_CFG_SET(dev, where); - *PCI_CFG_DATA = val; + GALILEO_OUTL(val, GT_PCI0_CFGDATA_OFS); return PCIBIOS_SUCCESSFUL; } @@ -341,10 +339,10 @@ if (pci_range_ck (dev)) return PCIBIOS_DEVICE_NOT_FOUND; PCI_CFG_SET(dev, (where & ~0x3)); - tmp = *PCI_CFG_DATA; + tmp = GALILEO_INL(GT_PCI0_CFGDATA_OFS); tmp &= ~(0xffff << ((where & 0x3) * 8)); tmp |= (val << ((where & 0x3) * 8)); - *PCI_CFG_DATA = tmp; + GALILEO_OUTL(tmp, GT_PCI0_CFGDATA_OFS); return PCIBIOS_SUCCESSFUL; } @@ -358,10 +356,10 @@ if (pci_range_ck (dev)) return PCIBIOS_DEVICE_NOT_FOUND; PCI_CFG_SET(dev, (where & ~0x3)); - tmp = *PCI_CFG_DATA; + tmp = GALILEO_INL(GT_PCI0_CFGDATA_OFS); tmp &= ~(0xff << ((where & 0x3) * 8)); tmp |= (val << ((where & 0x3) * 8)); - *PCI_CFG_DATA = tmp; + GALILEO_OUTL(tmp, GT_PCI0_CFGDATA_OFS); return PCIBIOS_SUCCESSFUL; } @@ -384,7 +382,7 @@ /* Read the cobalt id register out of the PCI config space */ dev.devfn = PCI_DEVFN(COBALT_PCICONF_VIA, 0); PCI_CFG_SET(&dev, (VIA_COBALT_BRD_ID_REG & ~0x3)); - cobalt_board_id = *PCI_CFG_DATA >> ((VIA_COBALT_BRD_ID_REG & 3) * 8); + cobalt_board_id = GALILEO_INL(GT_PCI0_CFGDATA_OFS) >> ((VIA_COBALT_BRD_ID_REG & 3) * 8); cobalt_board_id = VIA_COBALT_BRD_REG_to_ID(cobalt_board_id); printk("Cobalt Board ID: %d\n", cobalt_board_id); @@ -398,37 +396,6 @@ pci_scan_bus(0, &qube_pci_ops, NULL); } -char *pcibios_setup(char *str) -{ - return str; -} - -int pcibios_enable_device(struct pci_dev *dev) -{ - u16 cmd, status; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - pci_read_config_word(dev, PCI_STATUS, &status); - printk("PCI: Enabling device %s (%04x %04x)\n", dev->slot_name, cmd, status); - /* We'll sort this out when we know it isn't enabled ;) */ - - return 0; -} - -void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ - - panic("Uhhoh called pcibios_align_resource\n"); -} - -void pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - - panic("Uhhoh called pcibios_update_resource\n"); -} - void __init pcibios_fixup_bus(struct pci_bus *bus) { /* We don't have sub-busses to fixup here */ diff -urN linux-2.4.21-bk37/arch/mips/cobalt/promcon.c linux-2.4.21-bk38/arch/mips/cobalt/promcon.c --- linux-2.4.21-bk37/arch/mips/cobalt/promcon.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/cobalt/promcon.c 2003-08-24 02:55:57.000000000 -0700 @@ -77,12 +77,12 @@ } static struct console ns16550_console = { - name: "prom", - setup: NULL, - write: ns16550_console_write, - device: ns16550_console_dev, - flags: CON_PRINTBUFFER, - index: -1, + .name = "prom", + .setup = NULL, + .write = ns16550_console_write, + .device = ns16550_console_dev, + .flags = CON_PRINTBUFFER, + .index = -1, }; void __init ns16550_setup_console(void) diff -urN linux-2.4.21-bk37/arch/mips/cobalt/reset.c linux-2.4.21-bk38/arch/mips/cobalt/reset.c --- linux-2.4.21-bk37/arch/mips/cobalt/reset.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/cobalt/reset.c 2003-08-24 02:55:57.000000000 -0700 @@ -28,10 +28,10 @@ * kernel in the flush locks up somewhen during of after the PCI * detection stuff. */ - set_cp0_status(ST0_BEV | ST0_ERL); - change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + set_c0_status(ST0_BEV | ST0_ERL); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); + write_c0_wired(0); __asm__ __volatile__( "jr\t%0" : diff -urN linux-2.4.21-bk37/arch/mips/cobalt/setup.c linux-2.4.21-bk38/arch/mips/cobalt/setup.c --- linux-2.4.21-bk37/arch/mips/cobalt/setup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/cobalt/setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -6,7 +6,7 @@ * for more details. * * Copyright (C) 1996, 1997 by Ralf Baechle - * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv) + * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) * */ @@ -21,11 +21,11 @@ #include #include #include -#include -#include #include #include -#include +#include + +#include extern void cobalt_machine_restart(char *command); extern void cobalt_machine_halt(void); @@ -53,13 +53,6 @@ } -#define GALILEO_T0_VAL 0xb4000850 -#define GALILEO_TIMER_CTRL 0xb4000864 -#define GALILEO_CPU_MASK 0xb4000c1c - -#define GALILEO_ENTC0 0x01 -#define GALILEO_SELTC0 0x02 - static void __init cobalt_time_init(void) { rtc_ops = &std_rtc_ops; @@ -68,24 +61,18 @@ static void __init cobalt_timer_setup(struct irqaction *irq) { /* Load timer value for 150 Hz */ - volatile unsigned long *timer_reg = (volatile unsigned long *)GALILEO_T0_VAL; - - *timer_reg = 500000; + GALILEO_OUTL(500000, GT_TC0_OFS); /* Register our timer interrupt */ setup_irq(COBALT_TIMER_IRQ, irq); /* Enable timer ints */ - *((volatile unsigned long *) GALILEO_TIMER_CTRL) = - (unsigned long) (GALILEO_ENTC0 | GALILEO_SELTC0); + GALILEO_OUTL((GALILEO_ENTC0 | GALILEO_SELTC0), GT_TC_CONTROL_OFS); /* Unmask timer int */ - *((volatile unsigned long *) GALILEO_CPU_MASK) = (unsigned long) 0x00000100; + GALILEO_OUTL(0x100, GT_INTRMASK_OFS); } -void __init bus_error_init(void) { /* nothing */ } - - void __init cobalt_setup(void) { @@ -99,7 +86,8 @@ #ifdef CONFIG_BLK_DEV_IDE ide_ops = &std_ide_ops; #endif - set_io_port_base(0xb0000000); + + set_io_port_base(KSEG1ADDR(0x10000000)); /* * This is a prom style console. We just poke at the diff -urN linux-2.4.21-bk37/arch/mips/cobalt/via.c linux-2.4.21-bk38/arch/mips/cobalt/via.c --- linux-2.4.21-bk37/arch/mips/cobalt/via.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/cobalt/via.c 2003-08-24 02:55:57.000000000 -0700 @@ -6,17 +6,17 @@ * for more details. * * Copyright (C) 1996, 1997 by Ralf Baechle - * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv) + * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) * */ +#include #include -#include + #include #include -#include - -extern void do_IRQ(int irq, struct pt_regs * regs); +#include +#include asmlinkage void via_irq(struct pt_regs *regs) { @@ -50,17 +50,16 @@ printk("Spurious master interrupt..."); } -#define GALILEO_INTCAUSE 0xb4000c18 -#define GALILEO_T0EXP 0x00000100 - asmlinkage void galileo_irq(struct pt_regs *regs) { - unsigned long irq_src = *((unsigned long *) GALILEO_INTCAUSE); + unsigned long irq_src; + + irq_src = GALILEO_INL(GT_INTRCAUSE_OFS); /* Check for timer irq ... */ if (irq_src & GALILEO_T0EXP) { /* Clear the int line */ - *((volatile unsigned long *) GALILEO_INTCAUSE) = 0; + GALILEO_OUTL(0, GT_INTRCAUSE_OFS); do_IRQ(COBALT_TIMER_IRQ, regs); } else printk("Spurious Galileo interrupt...\n"); diff -urN linux-2.4.21-bk37/arch/mips/config-shared.in linux-2.4.21-bk38/arch/mips/config-shared.in --- linux-2.4.21-bk37/arch/mips/config-shared.in 2003-08-24 02:55:49.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/config-shared.in 2003-08-24 02:55:57.000000000 -0700 @@ -14,19 +14,33 @@ fi endmenu +# +# Keep these alphabetically sorted +# mainmenu_option next_comment comment 'Machine selection' dep_bool 'Support for Acer PICA 1 chipset (EXPERIMENTAL)' CONFIG_ACER_PICA_61 $CONFIG_EXPERIMENTAL -dep_bool 'Support for Alchemy Semi PB1000 board' CONFIG_MIPS_PB1000 $CONFIG_MIPS32 +dep_bool 'Support for Alchemy Bosporus board' CONFIG_MIPS_BOSPORUS $CONFIG_MIPS32 +dep_bool 'Support for Alchemy Mirage board' CONFIG_MIPS_MIRAGE $CONFIG_MIPS32 +dep_bool 'Support for Alchemy Db1000 board' CONFIG_MIPS_DB1000 $CONFIG_MIPS32 +dep_bool 'Support for Alchemy Db1100 board' CONFIG_MIPS_DB1100 $CONFIG_MIPS32 +dep_bool 'Support for Alchemy Db1500 board' CONFIG_MIPS_DB1500 $CONFIG_MIPS32 +dep_bool 'Support for Alchemy PB1000 board' CONFIG_MIPS_PB1000 $CONFIG_MIPS32 if [ "$CONFIG_MIPS_PB1000" = "y" ]; then bool ' Support for PCI AUTO Config' CONFIG_PCI_AUTO fi -dep_bool 'Support for Alchemy Semi PB1100 board' CONFIG_MIPS_PB1100 $CONFIG_MIPS32 -dep_bool 'Support for Alchemy Semi PB1500 board' CONFIG_MIPS_PB1500 $CONFIG_MIPS32 -dep_bool 'Support for Algorithmics P4032 (EXPERIMENTAL)' CONFIG_ALGOR_P4032 $CONFIG_EXPERIMENTAL +dep_bool 'Support for Alchemy PB1100 board' CONFIG_MIPS_PB1100 $CONFIG_MIPS32 +dep_bool 'Support for Alchemy PB1500 board' CONFIG_MIPS_PB1500 $CONFIG_MIPS32 +dep_bool 'Support for MyCable XXS1500 board' CONFIG_MIPS_XXS1500 $CONFIG_MIPS32 +dep_bool 'Support for 4G Systems MTX-1 board' CONFIG_MIPS_MTX1 $CONFIG_MIPS32 dep_bool 'Support for BAGET MIPS series (EXPERIMENTAL)' CONFIG_BAGET_MIPS $CONFIG_MIPS32 $CONFIG_EXPERIMENTAL +bool 'Support for CASIO CASSIOPEIA E-10/15/55/65' CONFIG_CASIO_E55 dep_bool 'Support for Cobalt Server (EXPERIMENTAL)' CONFIG_MIPS_COBALT $CONFIG_EXPERIMENTAL -dep_bool 'Support for DECstations' CONFIG_DECSTATION $CONFIG_MIPS32 +if [ "$CONFIG_MIPS32" = "y" ]; then + bool 'Support for DECstations' CONFIG_DECSTATION +else + dep_bool 'Support for DECstations (EXPERIMENTAL)' CONFIG_DECSTATION $CONFIG_EXPERIMENTAL +fi dep_bool 'Support for Galileo EV64120 Evaluation board (EXPERIMENTAL)' CONFIG_MIPS_EV64120 $CONFIG_EXPERIMENTAL if [ "$CONFIG_MIPS_EV64120" = "y" ]; then bool ' Enable Second PCI (PCI1)' CONFIG_EVB_PCI1 @@ -38,16 +52,25 @@ dep_bool 'Support for Galileo EV96100 Evaluation board (EXPERIMENTAL)' CONFIG_MIPS_EV96100 $CONFIG_EXPERIMENTAL bool 'Support for Globespan IVR board' CONFIG_MIPS_IVR bool 'Support for Hewlett Packard LaserJet board' CONFIG_HP_LASERJET +bool 'Support for IBM WorkPad z50' CONFIG_IBM_WORKPAD +bool 'Support for LASAT Networks platforms' CONFIG_LASAT +if [ "$CONFIG_LASAT" = "y" ]; then + tristate ' PICVUE LCD display driver' CONFIG_PICVUE + dep_tristate ' PICVUE LCD display driver /proc interface' CONFIG_PICVUE_PROC $CONFIG_PICVUE + bool ' DS1603 RTC driver' CONFIG_DS1603 + bool ' LASAT sysctl interface' CONFIG_LASAT_SYSCTL +fi bool 'Support for ITE 8172G board' CONFIG_MIPS_ITE8172 if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then bool ' Support for older IT8172 (Rev C)' CONFIG_IT8172_REVC fi -dep_bool 'Support for MIPS Atlas board (EXPERIMENTAL)' CONFIG_MIPS_ATLAS $CONFIG_EXPERIMENTAL +bool 'Support for MIPS Atlas board' CONFIG_MIPS_ATLAS bool 'Support for MIPS Magnum 4000' CONFIG_MIPS_MAGNUM_4000 -dep_bool 'Support for MIPS Malta board (EXPERIMENTAL)' CONFIG_MIPS_MALTA $CONFIG_EXPERIMENTAL +bool 'Support for MIPS Malta board' CONFIG_MIPS_MALTA dep_bool 'Support for MIPS SEAD board (EXPERIMENTAL)' CONFIG_MIPS_SEAD $CONFIG_EXPERIMENTAL bool 'Support for Momentum Ocelot board' CONFIG_MOMENCO_OCELOT bool 'Support for Momentum Ocelot-G board' CONFIG_MOMENCO_OCELOT_G +bool 'Support for Momentum Ocelot-C and -CS boards' CONFIG_MOMENCO_OCELOT_C dep_bool 'Support for NEC DDB Vrc-5074 (EXPERIMENTAL)' CONFIG_DDB5074 $CONFIG_EXPERIMENTAL bool 'Support for NEC DDB Vrc-5476' CONFIG_DDB5476 bool 'Support for NEC DDB Vrc-5477' CONFIG_DDB5477 @@ -56,6 +79,9 @@ fi bool 'Support for NEC Osprey board' CONFIG_NEC_OSPREY bool 'Support for NEC Eagle/Hawk board' CONFIG_NEC_EAGLE +if [ "$CONFIG_NEC_EAGLE" = "y" ]; then + tristate ' NEC VRC4173 support' CONFIG_VRC4173 +fi bool 'Support for Olivetti M700-10' CONFIG_OLIVETTI_M700 dep_bool 'Support for Philips Nino (EXPERIMENTAL)' CONFIG_NINO $CONFIG_MIPS32 $CONFIG_EXPERIMENTAL if [ "$CONFIG_NINO" = "y" ]; then @@ -65,7 +91,7 @@ Model-500/510 CONFIG_NINO_16MB" Model-200 fi bool 'Support for SGI IP22 (Indy/Indigo2)' CONFIG_SGI_IP22 -dep_bool 'Support for SGI-IP27 (Origin200/2000)' CONFIG_SGI_IP27 $CONFIG_MIPS64 +dep_bool 'Support for SGI IP27 (Origin200/2000)' CONFIG_SGI_IP27 $CONFIG_MIPS64 if [ "$CONFIG_SGI_IP27" = "y" ]; then bool ' IP27 N-Mode' CONFIG_SGI_SN0_N_MODE bool ' Discontiguous Memory Support' CONFIG_DISCONTIGMEM @@ -73,16 +99,72 @@ bool ' Mapped kernel support' CONFIG_MAPPED_KERNEL bool ' Kernel text replication support' CONFIG_REPLICATE_KTEXT bool ' Exception handler replication support' CONFIG_REPLICATE_EXHANDLERS - bool ' Multi-Processing support' CONFIG_SMP + define_bool CONFIG_SMP_CAPABLE y #bool ' IP27 XXL' CONFIG_SGI_SN0_XXL fi -dep_bool 'Support for SGI-IP32 (O2) (EXPERIMENTAL)' CONFIG_SGI_IP32 $CONFIG_EXPERIMENTAL dep_bool 'Support for Broadcom BCM1xxx SOCs (EXPERIMENTAL)' CONFIG_SIBYTE_SB1xxx_SOC $CONFIG_EXPERIMENTAL if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then - choice ' BCM1xxx SOC Type' \ - "BCM1250 CONFIG_SIBYTE_SB1250" BCM1250 + choice ' BCM1xxx SOC-based board' \ + "BCM91250A-SWARM CONFIG_SIBYTE_SWARM \ + BCM91250E-Sentosa CONFIG_SIBYTE_SENTOSA \ + BCM91125E-Rhone CONFIG_SIBYTE_RHONE \ + BCM91120x-Carmel CONFIG_SIBYTE_CARMEL \ + BCM91250PT-PTSwarm CONFIG_SIBYTE_PTSWARM \ + BCM91250C2-LittleSur CONFIG_SIBYTE_LITTLESUR \ + BCM91120C-CRhine CONFIG_SIBYTE_CRHINE \ + BCM91125C-CRhone CONFIG_SIBYTE_CRHONE \ + Other CONFIG_SIBYTE_UNKNOWN" CONFIG_SIBYTE_SWARM + + if [ "$CONFIG_SIBYTE_UNKNOWN" = "y" ]; then + choice ' BCM1xxx SOC Type' \ + "BCM91250 CONFIG_SIBYTE_SB1250 \ + BCM91120 CONFIG_SIBYTE_BCM1120 \ + BCM91125 CONFIG_SIBYTE_BCM1125 \ + BCM91125H CONFIG_SIBYTE_BCM1125H" CONFIG_SIBYTE_SB1250 + unset CONFIG_SIBYTE_BOARD + else + define_bool CONFIG_SIBYTE_BOARD y + if [ "$CONFIG_SIBYTE_SWARM" = "y" -o \ + "$CONFIG_SIBYTE_LITTLESUR" = "y" -o \ + "$CONFIG_SIBYTE_PTSWARM" = "y" -o \ + "$CONFIG_SIBYTE_SENTOSA" = "y" ]; then + define_bool CONFIG_SIBYTE_SB1250 y + unset CONFIG_SIBYTE_BCM1120 + unset CONFIG_SIBYTE_BCM1125 + unset CONFIG_SIBYTE_BCM1125H + fi + if [ "$CONFIG_SIBYTE_CRHINE" = "y" -o \ + "$CONFIG_SIBYTE_CARMEL" = "y" ]; then + define_bool CONFIG_SIBYTE_BCM1120 y + unset CONFIG_SIBYTE_SB1250 + unset CONFIG_SIBYTE_BCM1125 + unset CONFIG_SIBYTE_BCM1125H + fi + if [ "$CONFIG_SIBYTE_CRHONE" = "y" -o \ + "$CONFIG_SIBYTE_RHONE" = "y" ]; then + define_bool CONFIG_SIBYTE_BCM1125H y + unset CONFIG_SIBYTE_SB1250 + unset CONFIG_SIBYTE_BCM1120 + unset CONFIG_SIBYTE_BCM1125 + fi + fi + + if [ "$CONFIG_SIBYTE_BCM1120" = "y" -o \ + "$CONFIG_SIBYTE_BCM1125" = "y" -o \ + "$CONFIG_SIBYTE_BCM1125H" = "y" ]; then + define_bool CONFIG_SIBYTE_BCM112X y + choice 'BCM112x Stepping' \ + "Hybrid CONFIG_CPU_SB1_PASS_2 \ + An CONFIG_CPU_SB1_PASS_3" An + else + unset CONFIG_SIBYTE_BCM112X + choice 'BCM1250 Stepping' \ + "Pass1 CONFIG_CPU_SB1_PASS_1 \ + An CONFIG_CPU_SB1_PASS_2 \ + Bn CONFIG_CPU_SB1_PASS_2_2 \ + Cn CONFIG_CPU_SB1_PASS_4" An + fi - bool ' Running under simulation' CONFIG_SIMULATION bool ' Booting from CFE' CONFIG_SIBYTE_CFE dep_bool ' Use firmware console' CONFIG_SIBYTE_CFE_CONSOLE $CONFIG_SIBYTE_CFE if [ "$CONFIG_SIBYTE_CFE" = "n" ]; then @@ -90,25 +172,48 @@ int ' Memory size (in megabytes)' CONFIG_SIBYTE_STANDALONE_RAM_SIZE 32 fi + bool ' Support for Bus Watcher statistics' CONFIG_SIBYTE_BUS_WATCHER bool ' Support for SB1/SOC profiling - SB1/SCD perf counters' CONFIG_SIBYTE_SB1250_PROF - bool ' Support for ZBbus profiling' CONFIG_BCM1250_TBPROF + bool ' Support for ZBbus profiling' CONFIG_SIBYTE_TBPROF - if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then - if [ "$CONFIG_SIBYTE_STANDALONE" != "y" ]; then - bool ' Multi-Processing support' CONFIG_SMP + if [ "$CONFIG_SIBYTE_SB1250" = "y" -o \ + "$CONFIG_SIBYTE_BCM1125" = "y" -o \ + "$CONFIG_SIBYTE_BCM1125H" = "y" ]; then + bool ' Support for BCM1250/BCM1125 onchip PCI controller' CONFIG_PCI + fi + + if [ "$CONFIG_SIBYTE_SB1250" = "y" -o \ + "$CONFIG_SIBYTE_BCM1125H" = "y" ]; then + if [ "$CONFIG_PCI" = "y" ]; then + define_bool CONFIG_SIBYTE_HAS_LDT y fi fi - if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then - bool ' Support for BCM1250/BCM112x onchip PCI controller' CONFIG_PCI + if [ "$CONFIG_SIBYTE_SWARM" = "y" -o \ + "$CONFIG_SIBYTE_LITTLESUR" = "y" -o \ + "$CONFIG_SIBYTE_PTSWARM" = "y" -o \ + "$CONFIG_SIBYTE_CARMEL" = "y" ]; then + define_bool CONFIG_SIBYTE_GENBUS_IDE y fi - if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then - bool ' Support for SWARM board' CONFIG_SIBYTE_SWARM + if [ "$CONFIG_SIBYTE_SB1250" = "y" -a \ + "$CONFIG_SIBYTE_STANDALONE" != "y" ]; then + define_bool CONFIG_SMP_CAPABLE y fi fi bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI +bool 'Support for TANBAC TB0226 (Mbase)' CONFIG_TANBAC_TB0226 +bool 'Support for TANBAC TB0229 (VR4131DIMM)' CONFIG_TANBAC_TB0229 +if [ "$CONFIG_TANBAC_TB0229" = "y" ]; then + bool ' Add TANBAC TB0219 Base board support' CONFIG_TANBAC_TB0219 +fi + dep_bool 'Support for Toshiba JMR-TX3927 board' CONFIG_TOSHIBA_JMR3927 $CONFIG_MIPS32 +bool 'Support for Toshiba RBTX49[23]7 Reference Board' CONFIG_TOSHIBA_RBTX4927 +bool 'Support for Victor MP-C303/304' CONFIG_VICTOR_MPC30X +if [ "$CONFIG_VICTOR_MPC30X" = "y" ]; then + tristate ' NEC VRC4173 support' CONFIG_VRC4173 +fi bool 'Support for ZAO Networks Capcella' CONFIG_ZAO_CAPCELLA dep_bool 'High Memory Support' CONFIG_HIGHMEM $CONFIG_MIPS32 @@ -127,56 +232,123 @@ define_bool CONFIG_MIPS_JAZZ y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PC_KEYB y - define_bool CONFIG_ROTTEN_IRQ y define_bool CONFIG_OLD_TIME_C y fi +if [ "$CONFIG_CASIO_E55" = "y" ]; then + define_bool CONFIG_IRQ_CPU y + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_VR41XX_TIME_C y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_ISA y + define_bool CONFIG_DUMMY_KEYB y + define_bool CONFIG_SCSI n +fi +if [ "$CONFIG_MIPS_MIRAGE" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1500 y + define_bool CONFIG_PC_KEYB y + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y + define_bool CONFIG_NONCOHERENT_IO y +fi +if [ "$CONFIG_MIPS_BOSPORUS" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1500 y + define_bool CONFIG_PC_KEYB y + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y + define_bool CONFIG_NONCOHERENT_IO y +fi if [ "$CONFIG_MIPS_PB1000" = "y" ]; then - define_bool CONFIG_MIPS_AU1000 y - define_bool CONFIG_NEW_IRQ y + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1000 y define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PC_KEYB y - define_bool CONFIG_SWAP_IO_SPACE y - define_bool CONFIG_AU1000_USB_DEVICE y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y fi if [ "$CONFIG_MIPS_PB1100" = "y" ]; then - define_bool CONFIG_MIPS_AU1000 y - define_bool CONFIG_NEW_IRQ y + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1100 y define_bool CONFIG_PCI y define_bool CONFIG_PCI_AUTO n define_bool CONFIG_NEW_PCI y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PC_KEYB y - define_bool CONFIG_SWAP_IO_SPACE y - define_bool CONFIG_AU1000_USB_DEVICE y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y fi if [ "$CONFIG_MIPS_PB1500" = "y" ]; then - define_bool CONFIG_MIPS_AU1000 y - define_bool CONFIG_NEW_IRQ y + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1500 y define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y define_bool CONFIG_PCI_AUTO y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PC_KEYB y - define_bool CONFIG_AU1000_USB_DEVICE y fi -if [ "$CONFIG_ALGOR_P4032" = "y" ]; then +if [ "$CONFIG_MIPS_DB1000" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1000 y + # CONFIG_PCI needed for USB define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO n + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_PC_KEYB y + define_bool CONFIG_SWAP_IO_SPACE y +fi +if [ "$CONFIG_MIPS_DB1500" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1500 y + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_PC_KEYB y +fi +if [ "$CONFIG_MIPS_DB1100" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1100 y + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_PC_KEYB y + define_bool CONFIG_SWAP_IO_SPACE y +fi +if [ "$CONFIG_MIPS_XXS1500" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1500 y + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_PC_KEYB y +fi +if [ "$CONFIG_MIPS_MTX1" = "y" ]; then + define_bool CONFIG_SOC_AU1X00 y + define_bool CONFIG_SOC_AU1500 y + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y define_bool CONFIG_NONCOHERENT_IO y - define_bool CONFIG_OLD_TIME_C y fi if [ "$CONFIG_MIPS_COBALT" = "y" ]; then define_bool CONFIG_COBALT_LCD y define_bool CONFIG_I8259 y define_bool CONFIG_PCI y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_NONCOHERENT_IO y fi if [ "$CONFIG_DECSTATION" = "y" ]; then + define_bool CONFIG_BOOT_ELF32 y define_bool CONFIG_IRQ_CPU y - define_bool CONFIG_NEW_IRQ y + define_int CONFIG_L1_CACHE_SHIFT 4 + define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_NONCOHERENT_IO y fi if [ "$CONFIG_MIPS_EV64120" = "y" ]; then @@ -187,13 +359,15 @@ define_bool CONFIG_OLD_TIME_C y fi if [ "$CONFIG_MIPS_EV96100" = "y" ]; then + define_bool CONFIG_BOARD_SCACHE y define_bool CONFIG_PCI y + define_bool CONFIG_MIPS_GT64120 y define_bool CONFIG_MIPS_GT96100 y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_PCI y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PCI_AUTO y - define_bool CONFIG_SWAP_IO_SPACE y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y fi if [ "$CONFIG_MIPS_IVR" = "y" ]; then define_bool CONFIG_PCI y @@ -202,18 +376,34 @@ define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PCI_AUTO y define_bool CONFIG_IT8172_CIR y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_TIME_C y fi if [ "$CONFIG_HP_LASERJET" = "y" ]; then define_bool CONFIG_IRQ_CPU y define_bool CONFIG_NEW_TIME_C y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_PCI y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PCI y #not yet define_bool CONFIG_PCI_AUTO y fi +if [ "$CONFIG_IBM_WORKPAD" = "y" ]; then + define_bool CONFIG_IRQ_CPU y + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_VR41XX_TIME_C y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_ISA y + define_bool CONFIG_DUMMY_KEYB y + define_bool CONFIG_SCSI n +fi +if [ "$CONFIG_LASAT" = "y" ]; then + define_bool CONFIG_BOARD_SCACHE y + define_bool CONFIG_R5000_CPU_SCACHE y + define_bool CONFIG_PCI y + define_bool CONFIG_MIPS_GT64120 y + define_bool CONFIG_MIPS_NILE4 y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_NEW_TIME_C y +fi if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then define_bool CONFIG_PCI y define_bool CONFIG_IT8712 y @@ -222,17 +412,19 @@ define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PCI_AUTO y define_bool CONFIG_IT8172_CIR y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_TIME_C y fi if [ "$CONFIG_MIPS_ATLAS" = "y" ]; then define_bool CONFIG_BOOT_ELF32 y define_int CONFIG_L1_CACHE_SHIFT 5 - define_bool CONFIG_NEW_IRQ y + define_bool CONFIG_MIPS_BONITO64 y + define_bool CONFIG_MIPS_GT64120 y + define_bool CONFIG_MIPS_MSC y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PCI y - define_bool CONFIG_SWAP_IO_SPACE y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y fi if [ "$CONFIG_MIPS_MAGNUM_4000" = "y" -o \ "$CONFIG_OLIVETTI_M700" = "y" ]; then @@ -250,37 +442,47 @@ define_bool CONFIG_BOOT_ELF32 y define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y define_bool CONFIG_I8259 y + define_bool CONFIG_MIPS_BONITO64 y + define_bool CONFIG_MIPS_GT64120 y + define_bool CONFIG_MIPS_MSC y define_int CONFIG_L1_CACHE_SHIFT 5 - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_NONCOHERENT_IO y - define_bool CONFIG_SWAP_IO_SPACE y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y define_bool CONFIG_PC_KEYB y define_bool CONFIG_PCI y fi if [ "$CONFIG_MIPS_SEAD" = "y" ]; then + define_bool CONFIG_BOOT_ELF32 y define_int CONFIG_L1_CACHE_SHIFT 5 - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PCI n fi if [ "$CONFIG_MOMENCO_OCELOT" = "y" ]; then + define_bool CONFIG_BOARD_SCACHE y define_bool CONFIG_PCI y define_bool CONFIG_SYSCLK_100 y - define_bool CONFIG_SWAP_IO_SPACE y - define_bool CONFIG_NEW_IRQ y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_OLD_TIME_C y fi if [ "$CONFIG_MOMENCO_OCELOT_G" = "y" ]; then define_bool CONFIG_PCI y define_bool CONFIG_SYSCLK_100 y - define_bool CONFIG_SWAP_IO_SPACE y - define_bool CONFIG_NEW_IRQ y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_OLD_TIME_C y fi +if [ "$CONFIG_MOMENCO_OCELOT_C" = "y" ]; then + define_bool CONFIG_PCI y + define_bool CONFIG_SWAP_IO_SPACE y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_NEW_TIME_C y +fi if [ "$CONFIG_DDB5074" = "y" ]; then define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y define_bool CONFIG_I8259 y @@ -290,7 +492,6 @@ define_bool CONFIG_PC_KEYB y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_PCI_AUTO y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_IRQ_CPU y define_bool CONFIG_NEW_PCI y fi @@ -298,7 +499,6 @@ define_bool CONFIG_ISA y define_bool CONFIG_PCI y define_bool CONFIG_PC_KEYB y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_IRQ_CPU y define_bool CONFIG_I8259 y define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y @@ -310,19 +510,15 @@ if [ "$CONFIG_DDB5477" = "y" ]; then define_bool CONFIG_PCI y define_bool CONFIG_NEW_TIME_C y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_IRQ_CPU y define_bool CONFIG_NEW_PCI y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PCI_AUTO y - define_bool CONFIG_DUMMY_KEYB y + define_bool CONFIG_PC_KEYB y define_bool CONFIG_I8259 y fi if [ "$CONFIG_NEC_OSPREY" = "y" ]; then define_bool CONFIG_VR4181 y - define_bool CONFIG_SERIAL y - define_bool CONFIG_SERIAL_MANY_PORTS y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_IRQ_CPU y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_NONCOHERENT_IO y @@ -330,8 +526,6 @@ define_bool CONFIG_SCSI n fi if [ "$CONFIG_NEC_EAGLE" = "y" ]; then - define_bool CONFIG_CPU_VR41XX y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_IRQ_CPU y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_VR41XX_TIME_C y @@ -344,78 +538,108 @@ define_bool CONFIG_SCSI n fi if [ "$CONFIG_NINO" = "y" ]; then - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PC_KEYB y fi if [ "$CONFIG_SGI_IP22" = "y" ]; then define_bool CONFIG_ARC32 y - define_bool CONFIG_ARC_CONSOLE y - define_bool CONFIG_ARC_MEMORY y + define_bool CONFIG_ARC_PROMLIB y define_bool CONFIG_BOARD_SCACHE y define_bool CONFIG_BOOT_ELF32 y - define_bool CONFIG_SWAP_IO_SPACE y + define_bool CONFIG_SWAP_IO_SPACE_W n + define_bool CONFIG_SWAP_IO_SPACE_L y define_bool CONFIG_IRQ_CPU y define_int CONFIG_L1_CACHE_SHIFT 5 - define_bool CONFIG_NONCOHERENT_IO y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_PC_KEYB y - define_bool CONFIG_SGI y fi if [ "$CONFIG_SGI_IP27" = "y" ]; then define_bool CONFIG_BOOT_ELF64 y define_bool CONFIG_ARC64 y + define_int CONFIG_L1_CACHE_SHIFT 7 #define_bool CONFIG_MAPPED_PCI_IO y + define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_PCI y define_bool CONFIG_QL_ISP_A64 y - define_int CONFIG_L1_CACHE_SHIFT 7 -fi -if [ "$CONFIG_SGI_IP32" = "y" ]; then - define_bool CONFIG_ARC_MEMORY y - define_bool CONFIG_ARC32 y - #define_bool CONFIG_BOARD_SCACHE y - define_bool CONFIG_BOOT_ELF32 y - define_int CONFIG_L1_CACHE_SHIFT 5 - define_bool CONFIG_NONCOHERENT_IO y - define_bool CONFIG_PC_KEYB y - define_bool CONFIG_PCI y fi -if [ "$CONFIG_SIBYTE_SB1250" = "y" ]; then - define_bool CONFIG_NEW_IRQ y +if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_DUMMY_KEYB y - define_bool CONFIG_SWAP_IO_SPACE y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y define_bool CONFIG_BOOT_ELF32 y fi if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then define_bool CONFIG_ARC32 y define_bool CONFIG_ARC_MEMORY y + define_bool CONFIG_ARC_PROMLIB y define_bool CONFIG_I8259 y define_bool CONFIG_ISA y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NONCOHERENT_IO y define_bool CONFIG_OLD_TIME_C y define_bool CONFIG_PC_KEYB y define_bool CONFIG_PCI y fi +if [ "$CONFIG_TANBAC_TB0226" = "y" ]; then + define_bool CONFIG_IRQ_CPU y + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_VR41XX_TIME_C y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_ISA n + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y + define_bool CONFIG_DUMMY_KEYB y + define_bool CONFIG_SERIAL_MANY_PORTS y +fi +if [ "$CONFIG_TANBAC_TB0229" = "y" ]; then + define_bool CONFIG_IRQ_CPU y + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_VR41XX_TIME_C y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_ISA n + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y + define_bool CONFIG_DUMMY_KEYB y + define_bool CONFIG_SERIAL_MANY_PORTS y +fi if [ "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then define_bool CONFIG_TOSHIBA_BOARDS y define_bool CONFIG_PCI y define_bool CONFIG_NEW_PCI y define_bool CONFIG_PCI_AUTO y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_NONCOHERENT_IO y - define_bool CONFIG_SWAP_IO_SPACE y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y define_bool CONFIG_PC_KEYB y fi +if [ "$CONFIG_TOSHIBA_RBTX4927" = "y" ]; then + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y + define_bool CONFIG_SWAP_IO_SPACE_W y + define_bool CONFIG_SWAP_IO_SPACE_L y + define_bool CONFIG_ISA y + define_bool CONFIG_NONCOHERENT_IO y +fi +if [ "$CONFIG_VICTOR_MPC30X" = "y" ]; then + define_bool CONFIG_IRQ_CPU y + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_VR41XX_TIME_C y + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_ISA n + define_bool CONFIG_PCI y + define_bool CONFIG_NEW_PCI y + define_bool CONFIG_PCI_AUTO y + define_bool CONFIG_DUMMY_KEYB y + define_bool CONFIG_SCSI n +fi if [ "$CONFIG_ZAO_CAPCELLA" = "y" ]; then - define_bool CONFIG_CPU_VR41XX y - define_bool CONFIG_CPU_LITTLE_ENDIAN y - define_bool CONFIG_NEW_IRQ y define_bool CONFIG_IRQ_CPU y define_bool CONFIG_NEW_TIME_C y define_bool CONFIG_VR41XX_TIME_C y @@ -454,12 +678,8 @@ RM7000 CONFIG_CPU_RM7000 \ SB1 CONFIG_CPU_SB1" R4x00 -if [ "$CONFIG_CPU_R5000" = "y" ]; then - define_bool CONFIG_BOARD_SCACHE y -fi - -if [ "$CONFIG_CPU_NEVADA" = "y" ]; then - define_bool CONFIG_BOARD_SCACHE y +if [ "$CONFIG_SMP_CAPABLE" = "y" ]; then + bool ' Multi-Processing support' CONFIG_SMP fi if [ "$CONFIG_CPU_MIPS32" = "y" ]; then @@ -477,15 +697,14 @@ fi if [ "$CONFIG_CPU_SB1" = "y" ]; then - choice 'SB1 Pass' \ - "Pass1 CONFIG_CPU_SB1_PASS_1 \ - Pass2 CONFIG_CPU_SB1_PASS_2 \ - Pass2.2 CONFIG_CPU_SB1_PASS_2_2" Pass1 + bool ' Use DMA to clear/copy pages' CONFIG_SIBYTE_DMA_PAGEOPS + # SB1 Pass-specific options if [ "$CONFIG_CPU_SB1_PASS_1" = "y" ]; then define_bool CONFIG_SB1_PASS_1_WORKAROUNDS y fi if [ "$CONFIG_CPU_SB1_PASS_2" = "y" ]; then define_bool CONFIG_SB1_PASS_2_WORKAROUNDS y + define_bool CONFIG_SB1_PASS_2_1_WORKAROUNDS y else # Avoid prefetches on Pass 2 (before 2.2) bool ' Enable prefetches' CONFIG_CPU_HAS_PREFETCH @@ -494,9 +713,7 @@ # XXXKW for now, let 2.2 use same WORKAROUNDS flag as pre-2.2 define_bool CONFIG_SB1_PASS_2_WORKAROUNDS y fi - bool ' Support for SB1 Cache Error handler' CONFIG_SB1_CACHE_ERROR - dep_bool ' Ignore recoverable cache errors' CONFIG_SB1_CERR_IGNORE_RECOVERABLE $CONFIG_SB1_CACHE_ERROR - dep_bool ' Spin instead of running handler' CONFIG_SB1_CERR_SPIN $CONFIG_SB1_CACHE_ERROR + define_bool CONFIG_VTAG_ICACHE y fi @@ -547,15 +764,51 @@ fi endmenu +# +# Choose endianess of code to generate. It's a frequent trap for users so the +# config file tries it's best to choose the right endianess for those systems +# where we know about their endianess. We only ask the user for systems +# known to be bi-endian; for those systems the defconfig file should defaults +# to the common endianess used for that system. +# mainmenu_option next_comment comment 'General setup' -if [ "$CONFIG_DECSTATION" = "y" -o \ - "$CONFIG_DDB5074" = "y" -o \ - "$CONFIG_NINO" = "y" -o \ - "$CONFIG_MIPS_COBALT" = "y" ]; then +if [ "$CONFIG_ACER_PICA_61" = "y" -o \ + "$CONFIG_CASIO_E55" = "y" -o \ + "$CONFIG_DDB5074" = "y" -o \ + "$CONFIG_DDB5476" = "y" -o \ + "$CONFIG_DDB5477" = "y" -o \ + "$CONFIG_DECSTATION" = "y" -o \ + "$CONFIG_HP_LASERJET" = "y" -o \ + "$CONFIG_IBM_WORKPAD" = "y" -o \ + "$CONFIG_LASAT" = "y" -o \ + "$CONFIG_MIPS_COBALT" = "y" -o \ + "$CONFIG_MIPS_ITE8172" = "y" -o \ + "$CONFIG_MIPS_IVR" = "y" -o \ + "$CONFIG_MIPS_PB1000" = "y" -o \ + "$CONFIG_MIPS_PB1100" = "y" -o \ + "$CONFIG_MIPS_PB1500" = "y" -o \ + "$CONFIG_NEC_OSPREY" = "y" -o \ + "$CONFIG_NEC_EAGLE" = "y" -o \ + "$CONFIG_NINO" = "y" -o \ + "$CONFIG_OLIVETTI_M700" = "y" -o \ + "$CONFIG_SNI_RM200_PCI" = "y" -o \ + "$CONFIG_VICTOR_MPC30X" = "y" -o \ + "$CONFIG_ZAO_CAPCELLA" = "y" ]; then define_bool CONFIG_CPU_LITTLE_ENDIAN y else - bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN + if [ "$CONFIG_BAGET_MIPS" = "y" -o \ + "$CONFIG_MIPS_EV64120" = "y" -o \ + "$CONFIG_MIPS_EV96100" = "y" -o \ + "$CONFIG_MOMENCO_OCELOT" = "y" -o \ + "$CONFIG_MOMENCO_OCELOT_G" = "y" -o \ + "$CONFIG_SGI_IP22" = "y" -o \ + "$CONFIG_SGI_IP27" = "y" -o \ + "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then + define_bool CONFIG_CPU_LITTLE_ENDIAN n + else + bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN + fi fi if [ "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then @@ -564,7 +817,6 @@ if [ "$CONFIG_CPU_LITTLE_ENDIAN" = "n" ]; then bool 'Include IRIX binary compatibility' CONFIG_BINFMT_IRIX - bool 'Include forward keyboard' CONFIG_FORWARD_KEYBOARD fi if [ "$CONFIG_CPU_R10000" = "y" ]; then @@ -623,11 +875,20 @@ define_bool CONFIG_BINFMT_AOUT n tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF dep_bool 'Kernel support for Linux/MIPS 32-bit binary compatibility' CONFIG_MIPS32_COMPAT $CONFIG_MIPS64 -define_bool CONFIG_BINFMT_ELF32 $CONFIG_MIPS32_COMPAT +dep_bool 'Kernel support for o32 binaries' CONFIG_MIPS32_O32 $CONFIG_MIPS32_COMPAT +dep_bool 'Kernel support for n32 binaries' CONFIG_MIPS32_N32 $CONFIG_MIPS32_COMPAT +if [ "$CONFIG_MIPS32_O32" = "y" -o \ + "$CONFIG_MIPS32_N32" = "y" ]; then + define_bool CONFIG_BINFMT_ELF32 y +else + define_bool CONFIG_BINFMT_ELF32 n +fi tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC -dep_bool 'Power Management support (EXPERIMENTAL)' CONFIG_PM $CONFIG_EXPERIMENTAL $CONFIG_MIPS_AU1000 +if [ "$CONFIG_SOC_AU1X00" = "y" ]; then + bool 'Power Management support' CONFIG_PM +fi endmenu source drivers/mtd/Config.in @@ -641,6 +902,9 @@ mainmenu_option next_comment comment 'MIPS initrd options' bool ' Embed root filesystem ramdisk into the kernel' CONFIG_EMBEDDED_RAMDISK + if [ "$CONFIG_EMBEDDED_RAMDISK" = "y" ]; then + string ' Filename of gziped ramdisk image' CONFIG_EMBEDDED_RAMDISK_IMAGE ramdisk.gz + fi endmenu fi @@ -675,7 +939,7 @@ fi endmenu -if [ "$CONFIG_PCI" = "y" ]; then +if [ "$CONFIG_PCI" = "y" -a "$CONFIG_MIPS32" = "y" ]; then source drivers/message/i2o/Config.in fi @@ -727,32 +991,6 @@ #source drivers/misc/Config.in -if [ "$CONFIG_DECSTATION" = "y" ]; then - mainmenu_option next_comment - comment 'DECStation Character devices' - - tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL - dep_bool ' DZ11 Serial Support' CONFIG_DZ $CONFIG_SERIAL - dep_bool ' Z85C30 Serial Support' CONFIG_ZS $CONFIG_SERIAL $CONFIG_TC - dep_bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE $CONFIG_SERIAL -# dep_bool 'MAXINE Access.Bus mouse (VSXXX-BB/GB) support' CONFIG_DTOP_MOUSE $CONFIG_ACCESSBUS - bool 'Enhanced Real Time Clock Support' CONFIG_RTC - endmenu -fi - -if [ "$CONFIG_SGI_IP22" = "y" ]; then - mainmenu_option next_comment - comment 'SGI Character devices' - if [ "$CONFIG_VT" = "y" ]; then - tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE - if [ "$CONFIG_SGI_NEWPORT_CONSOLE" = "y" ]; then - define_bool CONFIG_FONT_8x16 y - fi - define_bool CONFIG_DUMMY_CONSOLE y - fi - endmenu -fi - source fs/Config.in source drivers/media/Config.in @@ -761,6 +999,13 @@ mainmenu_option next_comment comment 'Console drivers' bool 'VGA text console' CONFIG_VGA_CONSOLE + if [ "$CONFIG_SGI_IP22" = "y" ]; then + tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE + if [ "$CONFIG_SGI_NEWPORT_CONSOLE" = "y" ]; then + define_bool CONFIG_FONT_8x16 y + fi + define_bool CONFIG_DUMMY_CONSOLE y + fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE source drivers/video/Config.in @@ -777,10 +1022,6 @@ fi endmenu -if [ "$CONFIG_SGI_IP22" = "y" ]; then - source drivers/sgi/Config.in -fi - source drivers/usb/Config.in source net/bluetooth/Config.in @@ -789,11 +1030,12 @@ comment 'Kernel hacking' bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE -if [ "$CONFIG_SERIAL" = "y" -o "$CONFIG_AU1000_UART" = "y" ]; then - bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG - dep_bool 'Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_REMOTE_DEBUG +bool 'Enable run-time debugging' CONFIG_RUNTIME_DEBUG +bool 'Remote GDB kernel debugging' CONFIG_KGDB +dep_bool ' Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_KGDB +if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then + bool 'Compile for Corelis Debugger' CONFIG_SB1XXX_CORELIS fi -bool 'Enable run-time debugging' CONFIG_DEBUG bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ if [ "$CONFIG_SMP" != "y" ]; then bool 'Run uncached' CONFIG_MIPS_UNCACHED diff -urN linux-2.4.21-bk37/arch/mips/ddb5074/Makefile linux-2.4.21-bk38/arch/mips/ddb5074/Makefile --- linux-2.4.21-bk37/arch/mips/ddb5074/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5074/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,18 +0,0 @@ -# -# Makefile for the NEC DDB Vrc-5074 specific kernel interface routines -# under Linux. -# -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# -# Note 2! The CFLAGS definitions are now in the main makefile... -# - -USE_STANDARD_AS_RULE := true - -O_TARGET = ddb5074.a - -obj-y := setup.o irq.o time.o prom.o pci.o int-handler.o nile4.o - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/ddb5074/int-handler.S linux-2.4.21-bk38/arch/mips/ddb5074/int-handler.S --- linux-2.4.21-bk37/arch/mips/ddb5074/int-handler.S 2001-04-13 20:26:07.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ddb5074/int-handler.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,120 +0,0 @@ -/* - * arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler - * - * Based on arch/mips/sgi/kernel/indyIRQ.S - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * Copyright (C) 2000 Geert Uytterhoeven - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include -#include -#include -#include - -/* A lot of complication here is taken away because: - * - * 1) We handle one interrupt and return, sitting in a loop and moving across - * all the pending IRQ bits in the cause register is _NOT_ the answer, the - * common case is one pending IRQ so optimize in that direction. - * - * 2) We need not check against bits in the status register IRQ mask, that - * would make this routine slow as hell. - * - * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in - * between like BSD spl() brain-damage. - * - * Furthermore, the IRQs on the INDY look basically (barring software IRQs - * which we don't use at all) like: - * - * MIPS IRQ Source - * -------- ------ - * 0 Software (ignored) - * 1 Software (ignored) - * 2 Local IRQ level zero - * 3 Local IRQ level one - * 4 8254 Timer zero - * 5 8254 Timer one - * 6 Bus Error - * 7 R4k timer (what we use) - * - * We handle the IRQ according to _our_ priority which is: - * - * Highest ---- R4k Timer - * Local IRQ zero - * Local IRQ one - * Bus Error - * 8254 Timer zero - * Lowest ---- 8254 Timer one - * - * then we just return, if multiple IRQs are pending then we will just take - * another exception, big deal. - */ - - .text - .set noreorder - .set noat - .align 5 - NESTED(ddbIRQ, PT_SIZE, sp) - SAVE_ALL - CLI - .set at - mfc0 s0, CP0_CAUSE # get irq mask - -#if 1 - mfc0 t2,CP0_STATUS # get enabled interrupts - and s0,t2 # isolate allowed ones -#endif - /* First we check for r4k counter/timer IRQ. */ - andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero - beq a0, zero, 1f - andi a0, s0, CAUSEF_IP3 # delay slot, check local level one - - /* Wheee, local level zero interrupt. */ - jal ddb_local0_irqdispatch - move a0, sp # delay slot - - j ret_from_irq - nop # delay slot - -1: - beq a0, zero, 1f - andi a0, s0, CAUSEF_IP6 # delay slot, check bus error - - /* Wheee, local level one interrupt. */ - move a0, sp - jal ddb_local1_irqdispatch - nop - - j ret_from_irq - nop - -1: - beq a0, zero, 1f - nop - - /* Wheee, an asynchronous bus error... */ - move a0, sp - jal ddb_buserror_irq - nop - - j ret_from_irq - nop - -1: - /* Here by mistake? This is possible, what can happen - * is that by the time we take the exception the IRQ - * pin goes low, so just leave if this is the case. - */ - andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) - beq a0, zero, 1f - - /* Must be one of the 8254 timers... */ - move a0, sp - jal ddb_8254timer_irq - nop -1: - j ret_from_irq - nop - END(ddbIRQ) diff -urN linux-2.4.21-bk37/arch/mips/ddb5074/irq.c linux-2.4.21-bk38/arch/mips/ddb5074/irq.c --- linux-2.4.21-bk37/arch/mips/ddb5074/irq.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5074/irq.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,226 +0,0 @@ -/* - * arch/mips/ddb5074/irq.c -- NEC DDB Vrc-5074 interrupt routines - * - * Copyright (C) 2000 Geert Uytterhoeven - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - - -extern void __init i8259_init(void); -extern void i8259_disable_irq(unsigned int irq_nr); -extern void i8259_enable_irq(unsigned int irq_nr); - -extern asmlinkage void ddbIRQ(void); -extern asmlinkage void i8259_do_irq(int irq, struct pt_regs *regs); -extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs); - - -void no_action(int cpl, void *dev_id, struct pt_regs *regs) -{ -} - - -#define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */ -#define M1543_PNP_INDEX 0x03f0 /* PnP Index Port */ -#define M1543_PNP_DATA 0x03f1 /* PnP Data Port */ - -#define M1543_PNP_ALT_CONFIG 0x0370 /* Alternative PnP Config Port */ -#define M1543_PNP_ALT_INDEX 0x0370 /* Alternative PnP Index Port */ -#define M1543_PNP_ALT_DATA 0x0371 /* Alternative PnP Data Port */ - -#define M1543_INT1_MASTER_CTRL 0x0020 /* INT_1 (master) Control Register */ -#define M1543_INT1_MASTER_MASK 0x0021 /* INT_1 (master) Mask Register */ - -#define M1543_INT1_SLAVE_CTRL 0x00a0 /* INT_1 (slave) Control Register */ -#define M1543_INT1_SLAVE_MASK 0x00a1 /* INT_1 (slave) Mask Register */ - -#define M1543_INT1_MASTER_ELCR 0x04d0 /* INT_1 (master) Edge/Level Control */ -#define M1543_INT1_SLAVE_ELCR 0x04d1 /* INT_1 (slave) Edge/Level Control */ - - -static void m1543_irq_setup(void) -{ - /* - * The ALI M1543 has 13 interrupt inputs, IRQ1..IRQ13. Not all - * the possible IO sources in the M1543 are in use by us. We will - * use the following mapping: - * - * IRQ1 - keyboard (default set by M1543) - * IRQ3 - reserved for UART B (default set by M1543) (note that - * the schematics for the DDB Vrc-5074 board seem to - * indicate that IRQ3 is connected to the DS1386 - * watchdog timer interrupt output so we might have - * a conflict) - * IRQ4 - reserved for UART A (default set by M1543) - * IRQ5 - parallel (default set by M1543) - * IRQ8 - DS1386 time of day (RTC) interrupt - * IRQ12 - mouse - */ - - /* - * Assing mouse interrupt to IRQ12 - */ - - /* Enter configuration mode */ - outb(0x51, M1543_PNP_CONFIG); - outb(0x23, M1543_PNP_CONFIG); - - /* Select logical device 7 (Keyboard) */ - outb(0x07, M1543_PNP_INDEX); - outb(0x07, M1543_PNP_DATA); - - /* Select IRQ12 */ - outb(0x72, M1543_PNP_INDEX); - outb(0x0c, M1543_PNP_DATA); - - /* Leave configration mode */ - outb(0xbb, M1543_PNP_CONFIG); - - - /* Initialize the 8259 PIC in the M1543 */ - i8259_init(); - - /* Enable the interrupt cascade */ - nile4_enable_irq(NILE4_INT_INTE); - - request_region(M1543_PNP_CONFIG, 2, "M1543 config"); - request_region(M1543_INT1_MASTER_ELCR, 2, "pic ELCR"); -} - -static void nile4_irq_setup(void) -{ - int i; - - /* Map all interrupts to CPU int #0 */ - nile4_map_irq_all(0); - - /* PCI INTA#-E# must be level triggered */ - nile4_set_pci_irq_level_or_edge(0, 1); - nile4_set_pci_irq_level_or_edge(1, 1); - nile4_set_pci_irq_level_or_edge(2, 1); - nile4_set_pci_irq_level_or_edge(3, 1); - nile4_set_pci_irq_level_or_edge(4, 1); - - /* PCI INTA#-D# must be active low, INTE# must be active high */ - nile4_set_pci_irq_polarity(0, 0); - nile4_set_pci_irq_polarity(1, 0); - nile4_set_pci_irq_polarity(2, 0); - nile4_set_pci_irq_polarity(3, 0); - nile4_set_pci_irq_polarity(4, 1); - - for (i = 0; i < 16; i++) - nile4_clear_irq(i); - - /* Enable CPU int #0 */ - nile4_enable_irq_output(0); - - request_mem_region(NILE4_BASE, NILE4_SIZE, "Nile 4"); -} - - -/* - * IRQ2 is cascade interrupt to second interrupt controller - */ -static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL }; - - -void disable_irq(unsigned int irq_nr) -{ - if (is_i8259_irq(irq_nr)) - i8259_disable_irq(irq_nr); - else - nile4_disable_irq(irq_to_nile4(irq_nr)); -} - -void enable_irq(unsigned int irq_nr) -{ - if (is_i8259_irq(irq_nr)) - i8259_enable_irq(irq_nr); - else - nile4_enable_irq(irq_to_nile4(irq_nr)); -} - -int table[16] = { 0, }; - -void ddb_local0_irqdispatch(struct pt_regs *regs) -{ - u32 mask; - int nile4_irq; -#if 1 - volatile static int nesting = 0; - if (nesting++ == 0) - ddb5074_led_d3(1); - ddb5074_led_hex(nesting < 16 ? nesting : 15); -#endif - - mask = nile4_get_irq_stat(0); - nile4_clear_irq_mask(mask); - - /* Handle the timer interrupt first */ - if (mask & (1 << NILE4_INT_GPT)) { - nile4_disable_irq(NILE4_INT_GPT); - do_IRQ(nile4_to_irq(NILE4_INT_GPT), regs); - nile4_enable_irq(NILE4_INT_GPT); - mask &= ~(1 << NILE4_INT_GPT); - } - for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1) - if (mask & 1) { - nile4_disable_irq(nile4_irq); - if (nile4_irq == NILE4_INT_INTE) { - int i8259_irq = nile4_i8259_iack(); - i8259_do_irq(i8259_irq, regs); - } else - do_IRQ(nile4_to_irq(nile4_irq), regs); - nile4_enable_irq(nile4_irq); - } -#if 1 - if (--nesting == 0) - ddb5074_led_d3(0); - ddb5074_led_hex(nesting < 16 ? nesting : 15); -#endif -} - -void ddb_local1_irqdispatch(void) -{ - printk("ddb_local1_irqdispatch called\n"); -} - -void ddb_buserror_irq(void) -{ - printk("ddb_buserror_irq called\n"); -} - -void ddb_8254timer_irq(void) -{ - printk("ddb_8254timer_irq called\n"); -} - -void __init ddb_irq_setup(void) -{ -#ifdef CONFIG_REMOTE_DEBUG - if (remote_debug) - set_debug_traps(); - breakpoint(); /* you may move this line to whereever you want :-) */ -#endif - request_region(0x20, 0x20, "pic1"); - request_region(0xa0, 0x20, "pic2"); - i8259_setup_irq(2, &irq2); - - nile4_irq_setup(); - m1543_irq_setup(); - - set_except_vector(0, ddbIRQ); -} diff -urN linux-2.4.21-bk37/arch/mips/ddb5074/nile4.c linux-2.4.21-bk38/arch/mips/ddb5074/nile4.c --- linux-2.4.21-bk37/arch/mips/ddb5074/nile4.c 2001-04-13 20:26:07.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ddb5074/nile4.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,292 +0,0 @@ -/* - * arch/mips/ddb5074/nile4.c -- NEC Vrc-5074 Nile 4 support routines - * - * Copyright (C) 2000 Geert Uytterhoeven - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include -#include - -#include - - -/* - * Physical Device Address Registers - * - * Note: 32 bit addressing only! - */ -void nile4_set_pdar(u32 pdar, u32 phys, u32 size, int width, - int on_memory_bus, int visible) -{ - u32 maskbits; - u32 widthbits; - - if (pdar > NILE4_BOOTCS || (pdar & 7)) { - printk("nile4_set_pdar: invalid pdar %d\n", pdar); - return; - } - if (pdar == NILE4_INTCS && size != 0x00200000) { - printk("nile4_set_pdar: INTCS size must be 2 MB\n"); - return; - } - switch (size) { -#if 0 /* We don't support 4 GB yet */ - case 0x100000000: /* 4 GB */ - maskbits = 4; - break; -#endif - case 0x80000000: /* 2 GB */ - maskbits = 5; - break; - case 0x40000000: /* 1 GB */ - maskbits = 6; - break; - case 0x20000000: /* 512 MB */ - maskbits = 7; - break; - case 0x10000000: /* 256 MB */ - maskbits = 8; - break; - case 0x08000000: /* 128 MB */ - maskbits = 9; - break; - case 0x04000000: /* 64 MB */ - maskbits = 10; - break; - case 0x02000000: /* 32 MB */ - maskbits = 11; - break; - case 0x01000000: /* 16 MB */ - maskbits = 12; - break; - case 0x00800000: /* 8 MB */ - maskbits = 13; - break; - case 0x00400000: /* 4 MB */ - maskbits = 14; - break; - case 0x00200000: /* 2 MB */ - maskbits = 15; - break; - case 0: /* OFF */ - maskbits = 0; - break; - default: - printk("nile4_set_pdar: unsupported size %p\n", (void *) size); - return; - } - switch (width) { - case 8: - widthbits = 0; - break; - case 16: - widthbits = 1; - break; - case 32: - widthbits = 2; - break; - case 64: - widthbits = 3; - break; - default: - printk("nile4_set_pdar: unsupported width %d\n", width); - return; - } - nile4_out32(pdar, maskbits | (on_memory_bus ? 0x10 : 0) | - (visible ? 0x20 : 0) | (widthbits << 6) | - (phys & 0xffe00000)); - nile4_out32(pdar + 4, 0); - /* - * When programming a PDAR, the register should be read immediately - * after writing it. This ensures that address decoders are properly - * configured. - */ - nile4_in32(pdar); - nile4_in32(pdar + 4); -} - - -/* - * PCI Master Registers - * - * Note: 32 bit addressing only! - */ -void nile4_set_pmr(u32 pmr, u32 type, u32 addr) -{ - if (pmr != NILE4_PCIINIT0 && pmr != NILE4_PCIINIT1) { - printk("nile4_set_pmr: invalid pmr %d\n", pmr); - return; - } - switch (type) { - case NILE4_PCICMD_IACK: /* PCI Interrupt Acknowledge */ - case NILE4_PCICMD_IO: /* PCI I/O Space */ - case NILE4_PCICMD_MEM: /* PCI Memory Space */ - case NILE4_PCICMD_CFG: /* PCI Configuration Space */ - break; - default: - printk("nile4_set_pmr: invalid type %d\n", type); - return; - } - nile4_out32(pmr, (type << 1) | 0x10 | (addr & 0xffe00000)); - nile4_out32(pmr + 4, 0); -} - - -/* - * Interrupt Programming - */ -void nile4_map_irq(int nile4_irq, int cpu_irq) -{ - u32 offset, t; - - offset = NILE4_INTCTRL; - if (nile4_irq >= 8) { - offset += 4; - nile4_irq -= 8; - } - t = nile4_in32(offset); - t &= ~(7 << (nile4_irq * 4)); - t |= cpu_irq << (nile4_irq * 4); - nile4_out32(offset, t); -} - -void nile4_map_irq_all(int cpu_irq) -{ - u32 all, t; - - all = cpu_irq; - all |= all << 4; - all |= all << 8; - all |= all << 16; - t = nile4_in32(NILE4_INTCTRL); - t &= 0x88888888; - t |= all; - nile4_out32(NILE4_INTCTRL, t); - t = nile4_in32(NILE4_INTCTRL + 4); - t &= 0x88888888; - t |= all; - nile4_out32(NILE4_INTCTRL + 4, t); -} - -void nile4_enable_irq(int nile4_irq) -{ - u32 offset, t; - - offset = NILE4_INTCTRL; - if (nile4_irq >= 8) { - offset += 4; - nile4_irq -= 8; - } - t = nile4_in32(offset); - t |= 8 << (nile4_irq * 4); - nile4_out32(offset, t); -} - -void nile4_disable_irq(int nile4_irq) -{ - u32 offset, t; - - offset = NILE4_INTCTRL; - if (nile4_irq >= 8) { - offset += 4; - nile4_irq -= 8; - } - t = nile4_in32(offset); - t &= ~(8 << (nile4_irq * 4)); - nile4_out32(offset, t); -} - -void nile4_disable_irq_all(void) -{ - nile4_out32(NILE4_INTCTRL, 0); - nile4_out32(NILE4_INTCTRL + 4, 0); -} - -u16 nile4_get_irq_stat(int cpu_irq) -{ - return nile4_in16(NILE4_INTSTAT0 + cpu_irq * 2); -} - -void nile4_enable_irq_output(int cpu_irq) -{ - u32 t; - - t = nile4_in32(NILE4_INTSTAT1 + 4); - t |= 1 << (16 + cpu_irq); - nile4_out32(NILE4_INTSTAT1, t); -} - -void nile4_disable_irq_output(int cpu_irq) -{ - u32 t; - - t = nile4_in32(NILE4_INTSTAT1 + 4); - t &= ~(1 << (16 + cpu_irq)); - nile4_out32(NILE4_INTSTAT1, t); -} - -void nile4_set_pci_irq_polarity(int pci_irq, int high) -{ - u32 t; - - t = nile4_in32(NILE4_INTPPES); - if (high) - t &= ~(1 << (pci_irq * 2)); - else - t |= 1 << (pci_irq * 2); - nile4_out32(NILE4_INTPPES, t); -} - -void nile4_set_pci_irq_level_or_edge(int pci_irq, int level) -{ - u32 t; - - t = nile4_in32(NILE4_INTPPES); - if (level) - t |= 2 << (pci_irq * 2); - else - t &= ~(2 << (pci_irq * 2)); - nile4_out32(NILE4_INTPPES, t); -} - -void nile4_clear_irq(int nile4_irq) -{ - nile4_out32(NILE4_INTCLR, 1 << nile4_irq); -} - -void nile4_clear_irq_mask(u32 mask) -{ - nile4_out32(NILE4_INTCLR, mask); -} - -u8 nile4_i8259_iack(void) -{ - u8 irq; - - /* Set window 0 for interrupt acknowledge */ - nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IACK, 0); - irq = *(volatile u8 *) NILE4_PCI_IACK_BASE; - /* Set window 0 for PCI I/O space */ - nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IO, 0); - return irq; -} - -#if 0 -void nile4_dump_irq_status(void) -{ - printk("CPUSTAT = %p:%p\n", (void *) nile4_in32(NILE4_CPUSTAT + 4), - (void *) nile4_in32(NILE4_CPUSTAT)); - printk("INTCTRL = %p:%p\n", (void *) nile4_in32(NILE4_INTCTRL + 4), - (void *) nile4_in32(NILE4_INTCTRL)); - printk("INTSTAT0 = %p:%p\n", - (void *) nile4_in32(NILE4_INTSTAT0 + 4), - (void *) nile4_in32(NILE4_INTSTAT0)); - printk("INTSTAT1 = %p:%p\n", - (void *) nile4_in32(NILE4_INTSTAT1 + 4), - (void *) nile4_in32(NILE4_INTSTAT1)); - printk("INTCLR = %p:%p\n", (void *) nile4_in32(NILE4_INTCLR + 4), - (void *) nile4_in32(NILE4_INTCLR)); - printk("INTPPES = %p:%p\n", (void *) nile4_in32(NILE4_INTPPES + 4), - (void *) nile4_in32(NILE4_INTPPES)); -} -#endif diff -urN linux-2.4.21-bk37/arch/mips/ddb5074/pci.c linux-2.4.21-bk38/arch/mips/ddb5074/pci.c --- linux-2.4.21-bk37/arch/mips/ddb5074/pci.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5074/pci.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,425 +0,0 @@ -/* - * arch/mips/ddb5074/pci.c -- NEC DDB Vrc-5074 PCI access routines - * - * Copyright (C) 2000 Geert Uytterhoeven - * Albert Dorofeev - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include -#include -#include -#include -#include -#include - -#include - - -static u32 nile4_pre_pci_access0(int slot_num) -{ - u32 pci_addr = 0; - u32 virt_addr = NILE4_PCI_CFG_BASE; - - /* Set window 1 address 8000000 - 64 bit - 2 MB (PCI config space) */ - nile4_set_pdar(NILE4_PCIW1, PHYSADDR(virt_addr), 0x00200000, 64, 0, - 0); - if (slot_num > 2) - pci_addr = 0x00040000 << slot_num; - else - virt_addr += 0x00040000 << slot_num; - nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_CFG, pci_addr); - return virt_addr; -} - -static void nile4_post_pci_access0(void) -{ - /* - * Set window 1 back to address 8000000 - 64 bit - 128 MB - * (PCI IO space) - */ - nile4_set_pdar(NILE4_PCIW1, PHYSADDR(NILE4_PCI_MEM_BASE), - 0x08000000, 64, 1, 1); - nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0); -} - - -static int nile4_pci_read_config_dword(struct pci_dev *dev, - int where, u32 * val) -{ - int slot_num, func_num; - u32 base; - - /* - * For starters let's do configuration cycle 0 only (one bus only) - */ - if (dev->bus->number) - return PCIBIOS_FUNC_NOT_SUPPORTED; - - slot_num = PCI_SLOT(dev->devfn); - func_num = PCI_FUNC(dev->devfn); - if (slot_num == 5) { - /* - * This is Nile 4 and it will crash if we access it like other - * devices - */ - *val = nile4_in32(NILE4_PCI_BASE + where); - return PCIBIOS_SUCCESSFUL; - } - base = nile4_pre_pci_access0(slot_num); - *val = - *((volatile u32 *) (base + (func_num << 8) + (where & 0xfc))); - nile4_post_pci_access0(); - return PCIBIOS_SUCCESSFUL; -} - -static int nile4_pci_write_config_dword(struct pci_dev *dev, int where, - u32 val) -{ - int slot_num, func_num; - u32 base; - - /* - * For starters let's do configuration cycle 0 only (one bus only) - */ - if (dev->bus->number) - return PCIBIOS_FUNC_NOT_SUPPORTED; - - slot_num = PCI_SLOT(dev->devfn); - func_num = PCI_FUNC(dev->devfn); - if (slot_num == 5) { - /* - * This is Nile 4 and it will crash if we access it like other - * devices - */ - nile4_out32(NILE4_PCI_BASE + where, val); - return PCIBIOS_SUCCESSFUL; - } - base = nile4_pre_pci_access0(slot_num); - *((volatile u32 *) (base + (func_num << 8) + (where & 0xfc))) = - val; - nile4_post_pci_access0(); - return PCIBIOS_SUCCESSFUL; -} - -static int nile4_pci_read_config_word(struct pci_dev *dev, int where, - u16 * val) -{ - int status; - u32 result; - - status = nile4_pci_read_config_dword(dev, where, &result); - if (status != PCIBIOS_SUCCESSFUL) - return status; - if (where & 2) - result >>= 16; - *val = result & 0xffff; - return PCIBIOS_SUCCESSFUL; -} - -static int nile4_pci_read_config_byte(struct pci_dev *dev, int where, - u8 * val) -{ - int status; - u32 result; - - status = nile4_pci_read_config_dword(dev, where, &result); - if (status != PCIBIOS_SUCCESSFUL) - return status; - if (where & 1) - result >>= 8; - if (where & 2) - result >>= 16; - *val = result & 0xff; - return PCIBIOS_SUCCESSFUL; -} - -static int nile4_pci_write_config_word(struct pci_dev *dev, int where, - u16 val) -{ - int status, shift = 0; - u32 result; - - status = nile4_pci_read_config_dword(dev, where, &result); - if (status != PCIBIOS_SUCCESSFUL) - return status; - if (where & 2) - shift += 16; - result &= ~(0xffff << shift); - result |= val << shift; - return nile4_pci_write_config_dword(dev, where, result); -} - -static int nile4_pci_write_config_byte(struct pci_dev *dev, int where, - u8 val) -{ - int status, shift = 0; - u32 result; - - status = nile4_pci_read_config_dword(dev, where, &result); - if (status != PCIBIOS_SUCCESSFUL) - return status; - if (where & 2) - shift += 16; - if (where & 1) - shift += 8; - result &= ~(0xff << shift); - result |= val << shift; - return nile4_pci_write_config_dword(dev, where, result); -} - -struct pci_ops nile4_pci_ops = { - nile4_pci_read_config_byte, - nile4_pci_read_config_word, - nile4_pci_read_config_dword, - nile4_pci_write_config_byte, - nile4_pci_write_config_word, - nile4_pci_write_config_dword -}; - -struct { - struct resource ram; - struct resource flash; - struct resource isa_io; - struct resource pci_io; - struct resource isa_mem; - struct resource pci_mem; - struct resource nile4; - struct resource boot; -} ddb5074_resources = { - { "RAM", 0x00000000, 0x03ffffff, - IORESOURCE_MEM | PCI_BASE_ADDRESS_MEM_TYPE_64}, - { "Flash ROM", 0x04000000, 0x043fffff}, - { "Nile4 ISA I/O", 0x06000000, 0x060fffff}, - { "Nile4 PCI I/O", 0x06100000, 0x07ffffff}, - { "Nile4 ISA mem", 0x08000000, 0x08ffffff, IORESOURCE_MEM}, - { "Nile4 PCI mem", 0x09000000, 0x0fffffff, IORESOURCE_MEM}, - { "Nile4 ctrl", 0x1fa00000, 0x1fbfffff, - IORESOURCE_MEM | PCI_BASE_ADDRESS_MEM_TYPE_64}, - { "Boot ROM", 0x1fc00000, 0x1fffffff} -}; - -static void __init ddb5074_pci_fixup(void) -{ - struct pci_dev *dev; - - pci_for_each_dev(dev) { - if (dev->vendor == PCI_VENDOR_ID_NEC && - dev->device == PCI_DEVICE_ID_NEC_NILE4) { - /* - * The first 64-bit PCI base register should point to - * the Nile4 control registers. Unfortunately this - * isn't the case, so we fix it ourselves. This allows - * the serial driver to find the UART. - */ - dev->resource[0] = ddb5074_resources.nile4; - request_resource(&iomem_resource, - &dev->resource[0]); - /* - * The second 64-bit PCI base register points to the - * first memory bank. Unfortunately the address is - * wrong, so we fix it (again). - */ - dev->resource[2] = ddb5074_resources.ram; - request_resource(&iomem_resource, - &dev->resource[2]); - } else if (dev->vendor == PCI_VENDOR_ID_AL - && dev->device == PCI_DEVICE_ID_AL_M7101) { - /* - * It's nice to have the LEDs on the GPIO pins - * available for debugging - */ - extern struct pci_dev *pci_pmu; - u8 t8; - - pci_pmu = dev; /* for LEDs D2 and D3 */ - /* Program the lines for LEDs D2 and D3 to output */ - nile4_pci_read_config_byte(dev, 0x7d, &t8); - t8 |= 0xc0; - nile4_pci_write_config_byte(dev, 0x7d, t8); - /* Turn LEDs D2 and D3 off */ - nile4_pci_read_config_byte(dev, 0x7e, &t8); - t8 |= 0xc0; - nile4_pci_write_config_byte(dev, 0x7e, t8); - } - } -} - -static void __init pcibios_fixup_irqs(void) -{ - struct pci_dev *dev; - int slot_num; - - pci_for_each_dev(dev) { - slot_num = PCI_SLOT(dev->devfn); - switch (slot_num) { - case 0: - dev->irq = nile4_to_irq(NILE4_INT_INTE); - break; - case 1: - dev->irq = nile4_to_irq(NILE4_INT_INTA); - break; - case 2: /* slot 1 */ - dev->irq = nile4_to_irq(NILE4_INT_INTA); - break; - case 3: /* slot 2 */ - dev->irq = nile4_to_irq(NILE4_INT_INTB); - break; - case 4: /* slot 3 */ - dev->irq = nile4_to_irq(NILE4_INT_INTC); - break; - case 5: - /* - * Fixup so the serial driver can use the UART - */ - dev->irq = nile4_to_irq(NILE4_INT_UART); - break; - case 13: - dev->irq = nile4_to_irq(NILE4_INT_INTE); - break; - default: - break; - } - } -} - -void __init pcibios_init(void) -{ - printk("PCI: Probing PCI hardware\n"); - ioport_resource.end = 0x1ffffff; /* 32 MB */ - iomem_resource.end = 0x1fffffff; /* 512 MB */ - /* `ram' and `nile4' are requested through the Nile4 pci_dev */ - request_resource(&iomem_resource, &ddb5074_resources.flash); - request_resource(&iomem_resource, &ddb5074_resources.isa_io); - request_resource(&iomem_resource, &ddb5074_resources.pci_io); - request_resource(&iomem_resource, &ddb5074_resources.isa_mem); - request_resource(&iomem_resource, &ddb5074_resources.pci_mem); - request_resource(&iomem_resource, &ddb5074_resources.boot); - - pci_scan_bus(0, &nile4_pci_ops, NULL); - ddb5074_pci_fixup(); - pci_assign_unassigned_resources(); - pcibios_fixup_irqs(); -} - -void __init pcibios_fixup_bus(struct pci_bus *bus) -{ - bus->resource[1] = &ddb5074_resources.pci_mem; -} - -char *pcibios_setup(char *str) -{ - return str; -} - -void __init pcibios_update_irq(struct pci_dev *dev, int irq) -{ - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); -} - -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; -} - -int pcibios_enable_resources(struct pci_dev *dev) -{ - u16 cmd, old_cmd; - int idx; - struct resource *r; - - /* - * Don't touch the Nile 4 - */ - if (dev->vendor == PCI_VENDOR_ID_NEC && - dev->device == PCI_DEVICE_ID_NEC_NILE4) return 0; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - for (idx = 0; idx < 6; idx++) { - r = &dev->resource[idx]; - if (!r->start && r->end) { - printk(KERN_ERR "PCI: Device %s not available because " - "of resource collisions\n", dev->slot_name); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (cmd != old_cmd) { - printk("PCI: Enabling device %s (%04x -> %04x)\n", - dev->slot_name, old_cmd, cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); - } - return 0; -} - -int pcibios_enable_device(struct pci_dev *dev) -{ - return pcibios_enable_resources(dev); -} - -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); - if (resource < 6) { - reg = PCI_BASE_ADDRESS_0 + 4 * resource; - } else if (resource == PCI_ROM_RESOURCE) { - res->flags |= PCI_ROM_ADDRESS_ENABLE; - reg = dev->rom_base_reg; - } else { - /* - * Somebody might have asked allocation of a non-standard - * resource - */ - return; - } - - pci_write_config_dword(dev, reg, new); - pci_read_config_dword(dev, reg, &check); - if ((new ^ check) & - ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : - PCI_BASE_ADDRESS_MEM_MASK)) { - printk(KERN_ERR "PCI: Error while updating region " - "%s/%d (%08x != %08x)\n", dev->slot_name, resource, - new, check); - } -} - -void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ - struct pci_dev *dev = data; - - if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; - - /* We need to avoid collisions with `mirrored' VGA ports - and other strange ISA hardware, so we always want the - addresses kilobyte aligned. */ - if (size > 0x100) { - printk(KERN_ERR "PCI: I/O Region %s/%d too large" - " (%ld bytes)\n", dev->slot_name, - dev->resource - res, size); - } - - start = (start + 1024 - 1) & ~(1024 - 1); - res->start = start; - } -} - -unsigned __init int pcibios_assign_all_busses(void) -{ - return 1; -} - -struct pci_fixup pcibios_fixups[] = { }; diff -urN linux-2.4.21-bk37/arch/mips/ddb5074/prom.c linux-2.4.21-bk38/arch/mips/ddb5074/prom.c --- linux-2.4.21-bk37/arch/mips/ddb5074/prom.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ddb5074/prom.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,41 +0,0 @@ -/* - * arch/mips/ddb5074/prom.c -- NEC DDB Vrc-5074 PROM routines - * - * Copyright (C) 2000 Geert Uytterhoeven - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include -#include -#include -#include - -#include -#include - - -char arcs_cmdline[CL_SIZE]; - -const char *get_system_type(void) -{ - return "NEC DDB Vrc-5074"; -} - -void __init prom_init(const char *s) -{ - int i = 0; - - if (s != (void *) -1) - while (*s && i < sizeof(arcs_cmdline) - 1) - arcs_cmdline[i++] = *s++; - arcs_cmdline[i] = '\0'; - - mips_machgroup = MACH_GROUP_NEC_DDB; - mips_machtype = MACH_NEC_DDB5074; - - /* 64 MB non-upgradable */ - add_memory_region(0, 64 << 20, BOOT_MEM_RAM); -} - -void __init prom_free_prom_memory(void) -{ -} diff -urN linux-2.4.21-bk37/arch/mips/ddb5074/setup.c linux-2.4.21-bk38/arch/mips/ddb5074/setup.c --- linux-2.4.21-bk37/arch/mips/ddb5074/setup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5074/setup.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,251 +0,0 @@ -/* - * arch/mips/ddb5074/setup.c -- NEC DDB Vrc-5074 setup routines - * - * Copyright (C) 2000 Geert Uytterhoeven - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#ifdef CONFIG_REMOTE_DEBUG -extern void rs_kgdb_hook(int); -extern void breakpoint(void); -#endif - -#if defined(CONFIG_SERIAL_CONSOLE) -extern void console_setup(char *); -#endif - -extern struct ide_ops std_ide_ops; -extern struct rtc_ops ddb_rtc_ops; - -static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000; - -static void ddb_machine_restart(char *command) -{ - u32 t; - - /* PCI cold reset */ - t = nile4_in32(NILE4_PCICTRL + 4); - t |= 0x40000000; - nile4_out32(NILE4_PCICTRL + 4, t); - /* CPU cold reset */ - t = nile4_in32(NILE4_CPUSTAT); - t |= 1; - nile4_out32(NILE4_CPUSTAT, t); - /* Call the PROM */ - back_to_prom(); -} - -static void ddb_machine_halt(void) -{ - printk("DDB Vrc-5074 halted.\n"); - do { - } while (1); -} - -static void ddb_machine_power_off(void) -{ - printk("DDB Vrc-5074 halted. Please turn off the power.\n"); - do { - } while (1); -} - -extern void ddb_irq_setup(void); - -void (*board_time_init) (struct irqaction * irq); - - -static void __init ddb_time_init(struct irqaction *irq) -{ - /* set the clock to 1 Hz */ - nile4_out32(NILE4_T2CTRL, 1000000); - /* enable the General-Purpose Timer */ - nile4_out32(NILE4_T2CTRL + 4, 0x00000001); - /* reset timer */ - nile4_out32(NILE4_T2CNTR, 0); - /* enable interrupt */ - nile4_enable_irq(NILE4_INT_GPT); - i8259_setup_irq(nile4_to_irq(NILE4_INT_GPT), irq); - change_cp0_status(ST0_IM, - IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4); -} - - -void __init bus_error_init(void) { /* nothing */ } - - -void __init ddb_setup(void) -{ - extern int panic_timeout; - - irq_setup = ddb_irq_setup; - set_io_port_base(NILE4_PCI_IO_BASE); - isa_slot_offset = NILE4_PCI_MEM_BASE; - request_region(0x00, 0x20, "dma1"); - request_region(0x40, 0x20, "timer"); - request_region(0x70, 0x10, "rtc"); - request_region(0x80, 0x10, "dma page reg"); - request_region(0xc0, 0x20, "dma2"); - board_time_init = ddb_time_init; - - _machine_restart = ddb_machine_restart; - _machine_halt = ddb_machine_halt; - _machine_power_off = ddb_machine_power_off; - -#ifdef CONFIG_BLK_DEV_IDE - ide_ops = &std_ide_ops; -#endif - rtc_ops = &ddb_rtc_ops; - - /* Reboot on panic */ - panic_timeout = 180; -} - - -#define USE_NILE4_SERIAL 0 - -#if USE_NILE4_SERIAL -#define ns16550_in(reg) nile4_in8((reg)*8) -#define ns16550_out(reg, val) nile4_out8((reg)*8, (val)) -#else -#define NS16550_BASE (NILE4_PCI_IO_BASE+0x03f8) -static inline u8 ns16550_in(u32 reg) -{ - return *(volatile u8 *) (NS16550_BASE + reg); -} - -static inline void ns16550_out(u32 reg, u8 val) -{ - *(volatile u8 *) (NS16550_BASE + reg) = val; -} -#endif - -#define NS16550_RBR 0 -#define NS16550_THR 0 -#define NS16550_DLL 0 -#define NS16550_IER 1 -#define NS16550_DLM 1 -#define NS16550_FCR 2 -#define NS16550_IIR 2 -#define NS16550_LCR 3 -#define NS16550_MCR 4 -#define NS16550_LSR 5 -#define NS16550_MSR 6 -#define NS16550_SCR 7 - -#define NS16550_LSR_DR 0x01 /* Data ready */ -#define NS16550_LSR_OE 0x02 /* Overrun */ -#define NS16550_LSR_PE 0x04 /* Parity error */ -#define NS16550_LSR_FE 0x08 /* Framing error */ -#define NS16550_LSR_BI 0x10 /* Break */ -#define NS16550_LSR_THRE 0x20 /* Xmit holding register empty */ -#define NS16550_LSR_TEMT 0x40 /* Xmitter empty */ -#define NS16550_LSR_ERR 0x80 /* Error */ - - -void _serinit(void) -{ -#if USE_NILE4_SERIAL - ns16550_out(NS16550_LCR, 0x80); - ns16550_out(NS16550_DLM, 0x00); - ns16550_out(NS16550_DLL, 0x36); /* 9600 baud */ - ns16550_out(NS16550_LCR, 0x00); - ns16550_out(NS16550_LCR, 0x03); - ns16550_out(NS16550_FCR, 0x47); -#else - /* done by PMON */ -#endif -} - -void _putc(char c) -{ - while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE)); - ns16550_out(NS16550_THR, c); - if (c == '\n') { - while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE)); - ns16550_out(NS16550_THR, '\r'); - } -} - -void _puts(const char *s) -{ - char c; - while ((c = *s++)) - _putc(c); -} - -char _getc(void) -{ - while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_DR)); - return ns16550_in(NS16550_RBR); -} - -int _testc(void) -{ - return (ns16550_in(NS16550_LSR) & NS16550_LSR_DR) != 0; -} - - -/* - * Hexadecimal 7-segment LED - */ -void ddb5074_led_hex(int hex) -{ - outb(hex, 0x80); -} - - -/* - * LEDs D2 and D3, connected to the GPIO pins of the PMU in the ALi M1543 - */ -struct pci_dev *pci_pmu = NULL; - -void ddb5074_led_d2(int on) -{ - u8 t; - - if (pci_pmu) { - pci_read_config_byte(pci_pmu, 0x7e, &t); - if (on) - t &= 0x7f; - else - t |= 0x80; - pci_write_config_byte(pci_pmu, 0x7e, t); - } -} - -void ddb5074_led_d3(int on) -{ - u8 t; - - if (pci_pmu) { - pci_read_config_byte(pci_pmu, 0x7e, &t); - if (on) - t &= 0xbf; - else - t |= 0x40; - pci_write_config_byte(pci_pmu, 0x7e, t); - } -} diff -urN linux-2.4.21-bk37/arch/mips/ddb5074/time.c linux-2.4.21-bk38/arch/mips/ddb5074/time.c --- linux-2.4.21-bk37/arch/mips/ddb5074/time.c 2001-04-13 20:26:07.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ddb5074/time.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,32 +0,0 @@ -/* - * arch/mips/ddb5074/time.c -- Timer routines - * - * Copyright (C) 2000 Geert Uytterhoeven - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include -#include - -static unsigned char ddb_rtc_read_data(unsigned long addr) -{ - outb_p(addr, RTC_PORT(0)); - - return inb_p(RTC_PORT(1)); -} - -static void ddb_rtc_write_data(unsigned char data, unsigned long addr) -{ - outb_p(addr, RTC_PORT(0)); - outb_p(data, RTC_PORT(1)); -} - -static int ddb_rtc_bcd_mode(void) -{ - return 1; -} - -struct rtc_ops ddb_rtc_ops = { - ddb_rtc_read_data, - ddb_rtc_write_data, - ddb_rtc_bcd_mode -}; diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/common/irq.c linux-2.4.21-bk38/arch/mips/ddb5xxx/common/irq.c --- linux-2.4.21-bk37/arch/mips/ddb5xxx/common/irq.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/common/irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -19,7 +19,7 @@ void __init init_IRQ(void) { -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void breakpoint(void); extern void set_debug_traps(void); diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5074/irq.c linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5074/irq.c --- linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5074/irq.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5074/irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -6,14 +6,15 @@ */ #include #include +#include #include #include #include #include #include +#include #include -#include #include #include #include @@ -21,14 +22,7 @@ #include -extern void __init i8259_init(void); -extern void init_i8259_irqs (void); -extern void i8259_disable_irq(unsigned int irq_nr); -extern void i8259_enable_irq(unsigned int irq_nr); - extern asmlinkage void ddbIRQ(void); -extern asmlinkage void i8259_do_irq(int irq, struct pt_regs *regs); -extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs); static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL }; @@ -142,7 +136,7 @@ void __init ddb_irq_setup(void) { -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB if (remote_debug) set_debug_traps(); breakpoint(); /* you may move this line to whereever you want :-) */ diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5074/nile4_pic.c linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5074/nile4_pic.c --- linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5074/nile4_pic.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5074/nile4_pic.c 2003-08-24 02:55:57.000000000 -0700 @@ -260,7 +260,7 @@ } -#if defined(CONFIG_LL_DEBUG) +#if defined(CONFIG_RUNTIME_DEBUG) void nile4_dump_irq_status(void) { printk(KERN_DEBUG " diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5074/pci.c linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5074/pci.c --- linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5074/pci.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5074/pci.c 2003-08-24 02:55:57.000000000 -0700 @@ -9,22 +9,24 @@ #include static struct resource extpci_io_resource = { - "pci IO space", - 0x1000, /* leave some room for ISA bus */ - DDB_PCI_IO_SIZE -1, - IORESOURCE_IO}; + "pci IO space", + 0x1000, /* leave some room for ISA bus */ + DDB_PCI_IO_SIZE - 1, + IORESOURCE_IO +}; static struct resource extpci_mem_resource = { - "pci memory space", - DDB_PCI_MEM_BASE + 0x00100000, /* leave 1 MB for RTC */ - DDB_PCI_MEM_BASE + DDB_PCI_MEM_SIZE -1, - IORESOURCE_MEM}; + "pci memory space", + DDB_PCI_MEM_BASE + 0x00100000, /* leave 1 MB for RTC */ + DDB_PCI_MEM_BASE + DDB_PCI_MEM_SIZE - 1, + IORESOURCE_MEM +}; extern struct pci_ops ddb5476_ext_pci_ops; struct pci_channel mips_pci_channels[] = { - { &ddb5476_ext_pci_ops, &extpci_io_resource, &extpci_mem_resource }, - { NULL, NULL, NULL} + {&ddb5476_ext_pci_ops, &extpci_io_resource, &extpci_mem_resource}, + {NULL, NULL, NULL} }; #define PCI_EXT_INTA 8 @@ -52,7 +54,8 @@ /* SLOT: 13 */ nile4_to_irq(PCI_EXT_INTE), }; -void __init pcibios_fixup_irqs(void) { +void __init pcibios_fixup_irqs(void) +{ struct pci_dev *dev; int slot_num; @@ -60,12 +63,12 @@ pci_for_each_dev(dev) { slot_num = PCI_SLOT(dev->devfn); db_assert(slot_num < MAX_SLOT_NUM); -printk("irq_map[%d]: %02x\n",slot_num, irq_map[slot_num]); + printk("irq_map[%d]: %02x\n", slot_num, irq_map[slot_num]); db_assert(irq_map[slot_num] != 0xff); pci_write_config_byte(dev, - PCI_INTERRUPT_LINE, - irq_map[slot_num]); + PCI_INTERRUPT_LINE, + irq_map[slot_num]); dev->irq = irq_map[slot_num]; } @@ -73,27 +76,27 @@ void __init ddb_pci_reset_bus(void) { - u32 temp; + u32 temp; - /* - * I am not sure about the "official" procedure, the following - * steps work as far as I know: - * We first set PCI cold reset bit (bit 31) in PCICTRL-H. - * Then we clear the PCI warm reset bit (bit 30) to 0 in PCICTRL-H. - * The same is true for both PCI channels. - */ - temp = ddb_in32(DDB_PCICTRL+4); - temp |= 0x80000000; - ddb_out32(DDB_PCICTRL+4, temp); - temp &= ~0xc0000000; - ddb_out32(DDB_PCICTRL+4, temp); + /* + * I am not sure about the "official" procedure, the following + * steps work as far as I know: + * We first set PCI cold reset bit (bit 31) in PCICTRL-H. + * Then we clear the PCI warm reset bit (bit 30) to 0 in PCICTRL-H. + * The same is true for both PCI channels. + */ + temp = ddb_in32(DDB_PCICTRL + 4); + temp |= 0x80000000; + ddb_out32(DDB_PCICTRL + 4, temp); + temp &= ~0xc0000000; + ddb_out32(DDB_PCICTRL + 4, temp); } unsigned __init int pcibios_assign_all_busses(void) { - /* we hope pci_auto has assigned the bus numbers to all buses */ - return 1; + /* we hope pci_auto has assigned the bus numbers to all buses */ + return 1; } void __init pcibios_fixup_resources(struct pci_dev *dev) @@ -106,25 +109,24 @@ pci_for_each_dev(dev) { if (dev->vendor == PCI_VENDOR_ID_AL && - dev->device == PCI_DEVICE_ID_AL_M7101) { - /* - * It's nice to have the LEDs on the GPIO pins - * available for debugging - */ - extern struct pci_dev *pci_pmu; - u8 t8; - - pci_pmu = dev; /* for LEDs D2 and D3 */ - /* Program the lines for LEDs D2 and D3 to output */ - pci_read_config_byte(dev, 0x7d, &t8); - t8 |= 0xc0; - pci_write_config_byte(dev, 0x7d, t8); - /* Turn LEDs D2 and D3 off */ - pci_read_config_byte(dev, 0x7e, &t8); - t8 |= 0xc0; - pci_write_config_byte(dev, 0x7e, t8); + dev->device == PCI_DEVICE_ID_AL_M7101) { + /* + * It's nice to have the LEDs on the GPIO pins + * available for debugging + */ + extern struct pci_dev *pci_pmu; + u8 t8; + + pci_pmu = dev; /* for LEDs D2 and D3 */ + /* Program the lines for LEDs D2 and D3 to output */ + pci_read_config_byte(dev, 0x7d, &t8); + t8 |= 0xc0; + pci_write_config_byte(dev, 0x7d, t8); + /* Turn LEDs D2 and D3 off */ + pci_read_config_byte(dev, 0x7e, &t8); + t8 |= 0xc0; + pci_write_config_byte(dev, 0x7e, t8); } } } - diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5074/pci_ops.c linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5074/pci_ops.c --- linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5074/pci_ops.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5074/pci_ops.c 2003-08-24 02:55:57.000000000 -0700 @@ -49,8 +49,6 @@ DDB_PCI_CONFIG_SIZE }; -static int pci_config_workaround=1; - /* * access config space */ @@ -63,12 +61,8 @@ u32 virt_addr = swap->config_base; u32 option; - if (pci_config_workaround) { - if (slot_num == 5) slot_num = 14; - } - else { - if (slot_num == 5) return DDB_BASE + DDB_PCI_BASE; - } + if (slot_num == 5) + slot_num = 14; /* minimum pdar (window) size is 2MB */ db_assert(swap->config_size >= (2 << 20)); @@ -279,64 +273,3 @@ extpci_write_config_word, extpci_write_config_dword }; - - -#if defined(CONFIG_DEBUG) -void jsun_scan_pci_bus(void) -{ - struct pci_bus bus; - struct pci_dev dev; - unsigned int devfn; - int j; - - pci_config_workaround = 0; - - bus.parent = NULL; /* we scan the top level only */ - dev.bus = &bus; - dev.sysdata = NULL; - - /* scan ext pci bus and io pci bus*/ - for (j=0; j< 1; j++) { - printk(KERN_INFO "scan ddb5476 external PCI bus:\n"); - bus.ops = &ddb5476_ext_pci_ops; - - for (devfn = 0; devfn < 0x100; devfn += 8) { - u32 temp; - u16 temp16; - u8 temp8; - int i; - - dev.devfn = devfn; - db_verify(pci_read_config_dword(&dev, 0, &temp), - == PCIBIOS_SUCCESSFUL); - if (temp == 0xffffffff) continue; - - printk(KERN_INFO "slot %d: (addr %d) \n", devfn/8, - 11+devfn/8); - - /* verify read word and byte */ - db_verify(pci_read_config_word(&dev, 2, &temp16), - == PCIBIOS_SUCCESSFUL); - db_assert(temp16 == (temp >> 16)); - db_verify(pci_read_config_byte(&dev, 3, &temp8), - == PCIBIOS_SUCCESSFUL); - db_assert(temp8 == (temp >> 24)); - db_verify(pci_read_config_byte(&dev, 1, &temp8), - == PCIBIOS_SUCCESSFUL); - db_assert(temp8 == ((temp >> 8) & 0xff)); - - for (i=0; i < 16; i++) { - if ((i%4) == 0) - printk(KERN_INFO); - db_verify(pci_read_config_dword(&dev, i*4, &temp), - == PCIBIOS_SUCCESSFUL); - printk("\t%08X", temp); - if ((i%4) == 3) - printk("\n"); - } - } - } - - pci_config_workaround = 1; -} -#endif diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5074/setup.c linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5074/setup.c --- linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5074/setup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5074/setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -31,7 +31,7 @@ #include -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void rs_kgdb_hook(int); extern void breakpoint(void); #endif @@ -81,10 +81,6 @@ extern void (*board_timer_setup) (struct irqaction * irq); -void __init bus_error_init(void) -{ -} - static void __init ddb_timer_init(struct irqaction *irq) { /* set the clock to 1 Hz */ @@ -96,7 +92,7 @@ /* enable interrupt */ setup_irq(nile4_to_irq(NILE4_INT_GPT), irq); nile4_enable_irq(nile4_to_irq(NILE4_INT_GPT)); - change_cp0_status(ST0_IM, + change_c0_status(ST0_IM, IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4); } diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5476/Makefile linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5476/Makefile --- linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5476/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5476/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -15,6 +15,6 @@ obj-y += setup.o irq.o int-handler.o pci.o pci_ops.o \ nile4_pic.o vrc5476_irq.o -obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o +obj-$(CONFIG_KGDB) += dbg_io.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5476/irq.c linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5476/irq.c --- linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5476/irq.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5476/irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -14,6 +14,7 @@ #include #include +#include #include #include diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5476/nile4_pic.c linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5476/nile4_pic.c --- linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5476/nile4_pic.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5476/nile4_pic.c 2003-08-24 02:55:57.000000000 -0700 @@ -163,7 +163,7 @@ return irq + I8259_IRQ_BASE; } -#if defined(CONFIG_LL_DEBUG) +#if defined(CONFIG_RUNTIME_DEBUG) void nile4_dump_irq_status(void) { printk(KERN_DEBUG " diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5476/pci.c linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5476/pci.c --- linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5476/pci.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5476/pci.c 2003-08-24 02:55:57.000000000 -0700 @@ -100,10 +100,6 @@ } } -#if defined(CONFIG_DEBUG) -extern void jsun_scan_pci_bus(void); -#endif - void __init ddb_pci_reset_bus(void) { u32 temp; diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5476/pci_ops.c linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5476/pci_ops.c --- linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5476/pci_ops.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5476/pci_ops.c 2003-08-24 02:55:57.000000000 -0700 @@ -49,8 +49,6 @@ DDB_PCI_CONFIG_SIZE }; -static int pci_config_workaround=1; - /* * access config space */ @@ -63,27 +61,11 @@ u32 virt_addr = swap->config_base; u32 option; - if (pci_config_workaround) { - /* [jsun] work around Vrc5476 controller itself, returnning - * slot 0 essentially makes vrc5476 invisible - */ - if (slot_num == 12) slot_num = 0; - -#if 0 - /* BUG : skip P2P bridge for now */ - if (slot_num == 5) slot_num = 0; -#endif - - } else { - /* now we have to be hornest, returning the true - * PCI config headers for vrc5476 - */ - if (slot_num == 12) { - swap->pdar_backup = ddb_in32(swap->pdar); - swap->pmr_backup = ddb_in32(swap->pmr); - return DDB_BASE + DDB_PCI_BASE; - } - } + /* + * BUG: skip host PCI controller. Its BARS are bogus. + */ + if (slot_num == 12) + slot_num = 0; /* minimum pdar (window) size is 2MB */ db_assert(swap->config_size >= (2 << 20)); @@ -294,64 +276,3 @@ extpci_write_config_word, extpci_write_config_dword }; - - -#if defined(CONFIG_DEBUG) -void jsun_scan_pci_bus(void) -{ - struct pci_bus bus; - struct pci_dev dev; - unsigned int devfn; - int j; - - pci_config_workaround = 0; - - bus.parent = NULL; /* we scan the top level only */ - dev.bus = &bus; - dev.sysdata = NULL; - - /* scan ext pci bus and io pci bus*/ - for (j=0; j< 1; j++) { - printk(KERN_INFO "scan ddb5476 external PCI bus:\n"); - bus.ops = &ddb5476_ext_pci_ops; - - for (devfn = 0; devfn < 0x100; devfn += 8) { - u32 temp; - u16 temp16; - u8 temp8; - int i; - - dev.devfn = devfn; - db_verify(pci_read_config_dword(&dev, 0, &temp), - == PCIBIOS_SUCCESSFUL); - if (temp == 0xffffffff) continue; - - printk(KERN_INFO "slot %d: (addr %d) \n", devfn/8, - 11+devfn/8); - - /* verify read word and byte */ - db_verify(pci_read_config_word(&dev, 2, &temp16), - == PCIBIOS_SUCCESSFUL); - db_assert(temp16 == (temp >> 16)); - db_verify(pci_read_config_byte(&dev, 3, &temp8), - == PCIBIOS_SUCCESSFUL); - db_assert(temp8 == (temp >> 24)); - db_verify(pci_read_config_byte(&dev, 1, &temp8), - == PCIBIOS_SUCCESSFUL); - db_assert(temp8 == ((temp >> 8) & 0xff)); - - for (i=0; i < 16; i++) { - if ((i%4) == 0) - printk(KERN_INFO); - db_verify(pci_read_config_dword(&dev, i*4, &temp), - == PCIBIOS_SUCCESSFUL); - printk("\t%08X", temp); - if ((i%4) == 3) - printk("\n"); - } - } - } - - pci_config_workaround = 1; -} -#endif diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5476/setup.c linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5476/setup.c --- linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5476/setup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5476/setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -41,7 +41,7 @@ #define TIMER_IRQ (VRC5476_IRQ_BASE + VRC5476_IRQ_GPT) #endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void breakpoint(void); #endif @@ -103,8 +103,8 @@ setup_irq(CPU_IRQ_BASE + 7, irq); /* to generate the first timer interrupt */ - count = read_32bit_cp0_register(CP0_COUNT); - write_32bit_cp0_register(CP0_COMPARE, count + 1000); + count = read_c0_count(); + write_c0_compare(count + 1000); #else @@ -140,9 +140,6 @@ }; -void __init bus_error_init(void) { /* nothing */ } - - static void ddb5476_board_init(void); extern void ddb5476_irq_setup(void); extern void (*irq_setup)(void); diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c --- linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -12,6 +12,7 @@ */ #include #include +#include #include #include @@ -81,7 +82,6 @@ asmlinkage void vrc5476_irq_dispatch(struct pt_regs *regs) { - extern unsigned int do_IRQ(int irq, struct pt_regs *regs); extern void spurious_interrupt(void); u32 mask; diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5477/Makefile linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5477/Makefile --- linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5477/Makefile 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5477/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -12,8 +12,7 @@ obj-y += int-handler.o irq.o irq_5477.o setup.o pci.o pci_ops.o lcd44780.o -obj-$(CONFIG_DEBUG) += debug.o -obj-$(CONFIG_REMOTE_DEBUG) += kgdb_io.o -obj-$(CONFIG_BLK_DEV_INITRD) += ramdisk.o +obj-$(CONFIG_RUNTIME_DEBUG) += debug.o +obj-$(CONFIG_KGDB) += kgdb_io.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5477/debug.c linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5477/debug.c --- linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5477/debug.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5477/debug.c 2003-08-24 02:55:57.000000000 -0700 @@ -56,8 +56,8 @@ void vrc5477_show_int_regs() { jsun_show_regs("interrupt registers", int_regs); - printk("CPU CAUSE = %08x\n", read_32bit_cp0_register(CP0_CAUSE)); - printk("CPU STATUS = %08x\n", read_32bit_cp0_register(CP0_STATUS)); + printk("CPU CAUSE = %08x\n", read_c0_cause()); + printk("CPU STATUS = %08x\n", read_c0_status()); } static Register pdar_regs[] = { {"DDB_SDRAM0", DDB_BASE + DDB_SDRAM0}, diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5477/int-handler.S linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5477/int-handler.S --- linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5477/int-handler.S 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5477/int-handler.S 2003-08-24 02:55:57.000000000 -0700 @@ -14,6 +14,7 @@ #include #include #include +#include /* * first level interrupt dispatcher for ocelot board - @@ -55,20 +56,20 @@ j ret_from_irq ll_cputimer_irq: - li a0, 7 + li a0, CPU_IRQ_BASE + 7 move a1, sp jal do_IRQ j ret_from_irq ll_cpu_ip0: - li a0, 0 + li a0, CPU_IRQ_BASE + 0 move a1, sp jal do_IRQ j ret_from_irq ll_cpu_ip1: - li a0, 1 + li a0, CPU_IRQ_BASE + 1 move a1, sp jal do_IRQ j ret_from_irq diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5477/irq.c linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5477/irq.c --- linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5477/irq.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5477/irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -13,9 +13,11 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -71,7 +73,6 @@ ddb_out32(pci, reg_value); } -extern void init_i8259_irqs (void); extern void vrc5477_irq_init(u32 base); extern void mips_cpu_irq_init(u32 base); extern asmlinkage void ddb5477_handle_int(void); @@ -90,8 +91,8 @@ ddb_out32(DDB_INTCTRL2, 0); ddb_out32(DDB_INTCTRL3, 0); - clear_cp0_status(0xff00); - set_cp0_status(0x0400); + clear_c0_status(0xff00); + set_c0_status(0x0400); /* setup PCI interrupt attributes */ set_pci_int_attr(PCI0, INTA, ACTIVE_LOW, LEVEL_SENSE); @@ -164,8 +165,6 @@ asmlinkage void vrc5477_irq_dispatch(struct pt_regs *regs) { - extern unsigned int do_IRQ(int irq, struct pt_regs *regs); - u32 intStatus; u32 bitmask; u32 i; @@ -176,7 +175,7 @@ db_assert(ddb_in32(DDB_NMISTAT) == 0); if (ddb_in32(DDB_INT1STAT) != 0) { -#if defined(CONFIG_DEBUG) +#if defined(CONFIG_RUNTIME_DEBUG) vrc5477_show_int_regs(); #endif panic("error interrupt has happened."); diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5477/pci.c linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5477/pci.c --- linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5477/pci.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5477/pci.c 2003-08-24 02:55:57.000000000 -0700 @@ -166,10 +166,6 @@ } } -#if defined(CONFIG_DEBUG) -extern void jsun_scan_pci_bus(void); -extern void jsun_assign_pci_resource(void); -#endif void ddb_pci_reset_bus(void) { u32 temp; @@ -204,6 +200,33 @@ { } +/* + * fixup baseboard AMD chip so that tx does not underflow. + * bcr_18 |= 0x0800 + * This sets NOUFLO bit which makes tx not start until whole pkt + * is fetched to the chip. + */ +#define PCNET32_WIO_RDP 0x10 +#define PCNET32_WIO_RAP 0x12 +#define PCNET32_WIO_RESET 0x14 +#define PCNET32_WIO_BDP 0x16 +void __init fix_amd_lance(struct pci_dev *dev) +{ + unsigned long ioaddr; + u16 temp; + + ioaddr=pci_resource_start(dev, 0); + + inw(ioaddr + PCNET32_WIO_RESET); /* reset chip */ + + /* bcr_18 |= 0x0800 */ + outw (18, ioaddr + PCNET32_WIO_RAP); + temp = inw (ioaddr + PCNET32_WIO_BDP); + temp |= 0x0800; + outw (18, ioaddr + PCNET32_WIO_RAP); + outw (temp, ioaddr + PCNET32_WIO_BDP); +} + void __init pcibios_fixup(void) { if (mips_machtype == MACH_NEC_ROCKHOPPERII) { @@ -241,6 +264,10 @@ pci_read_config_byte(dev, 0x41, &old); pci_write_config_byte(dev, 0x41, old | 0xd0); } + + if (dev->vendor == PCI_VENDOR_ID_AMD && + dev->device == PCI_DEVICE_ID_AMD_LANCE) + fix_amd_lance(dev); } } diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5477/pci_ops.c linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5477/pci_ops.c --- linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5477/pci_ops.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5477/pci_ops.c 2003-08-24 02:55:57.000000000 -0700 @@ -299,4 +299,3 @@ iopci_write_config_word, iopci_write_config_dword }; - diff -urN linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5477/setup.c linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5477/setup.c --- linux-2.4.21-bk37/arch/mips/ddb5xxx/ddb5477/setup.c 2002-11-28 15:53:09.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/ddb5xxx/ddb5477/setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -43,12 +43,10 @@ #include "lcd44780.h" -// #define USE_CPU_COUNTER_TIMER /* whether we use cpu counter */ +#define USE_CPU_COUNTER_TIMER /* whether we use cpu counter */ -#ifndef USE_CPU_COUNTER_TIMER #define SP_TIMER_BASE DDB_SPT1CTRL_L #define SP_TIMER_IRQ VRC5477_IRQ_SPT1 -#endif static int bus_frequency = CONFIG_DDB5477_BUS_FREQUENCY*1000; @@ -88,38 +86,36 @@ unsigned char c; unsigned int t1, t2; unsigned i; - unsigned preset_freq[]={ - 0, 83330000, 100000000, 124000000,133300000, 0xffffffff}; ddb_out32(SP_TIMER_BASE, 0xffffffff); ddb_out32(SP_TIMER_BASE+4, 0x1); ddb_out32(SP_TIMER_BASE+8, 0xffffffff); - c= *(volatile unsigned char*)rtc_base; - for(i=0; (i<100000000) && (c == *(volatile unsigned char*)rtc_base); i++); + /* check if rtc is running */ + c= *(volatile unsigned char*)rtc_base; + for(i=0; (c == *(volatile unsigned char*)rtc_base) && (i<100000000); i++); if (c == *(volatile unsigned char*)rtc_base) { printk("Failed to detect bus frequency. Use default 83.3MHz.\n"); return 83333000; } - /* we are now at the turn of 1/100th second */ - t1 = ddb_in32(SP_TIMER_BASE+8); - c= *(volatile unsigned char*)rtc_base; while (c == *(volatile unsigned char*)rtc_base); + /* we are now at the turn of 1/100th second, if no error. */ + t1 = ddb_in32(SP_TIMER_BASE+8); - /* we are now at the turn of another 1/100th second */ - t2 = ddb_in32(SP_TIMER_BASE+8); - ddb_out32(SP_TIMER_BASE+4, 0x0); /* disable it again */ - freq = (t1 - t2)*100; + for (i=0; i< 10; i++) { + c= *(volatile unsigned char*)rtc_base; + while (c == *(volatile unsigned char*)rtc_base); + /* we are now at the turn of another 1/100th second */ + t2 = ddb_in32(SP_TIMER_BASE+8); + } - /* find the nearest preset freq */ - for (i=0; freq > preset_freq[i+1]; i++); - if ((freq - preset_freq[i]) >= (preset_freq[i+1]-freq)) - i++; + ddb_out32(SP_TIMER_BASE+4, 0x0); /* disable it again */ - printk("DDB bus frequency detection : %d -> %d\n", freq, preset_freq[i]); - return preset_freq[i]; + freq = (t1 - t2)*10; + printk("DDB bus frequency detection : %u \n", freq); + return freq; } extern void rtc_ds1386_init(unsigned long base); @@ -143,8 +139,8 @@ } /* mips_counter_frequency is 1/2 of the cpu core freq */ - i = (read_32bit_cp0_register(CP0_CONFIG) >> 28 ) & 7; - if ((mips_cpu.cputype == CPU_R5432) && (i == 3)) + i = (read_c0_config() >> 28 ) & 7; + if ((current_cpu_data.cputype == CPU_R5432) && (i == 3)) i = 4; mips_counter_frequency = bus_frequency*(i+4)/4; } @@ -158,10 +154,6 @@ /* we are using the cpu counter for timer interrupts */ setup_irq(CPU_IRQ_BASE + 7, irq); - /* to generate the first timer interrupt */ - count = read_32bit_cp0_register(CP0_COUNT); - write_32bit_cp0_register(CP0_COMPARE, count + 1000); - #else /* if we use Special purpose timer 1 */ @@ -172,8 +164,6 @@ #endif } -void __init bus_error_init(void) { /* nothing */ } - static void ddb5477_board_init(void); extern void ddb5477_irq_setup(void); diff -urN linux-2.4.21-bk37/arch/mips/defconfig linux-2.4.21-bk38/arch/mips/defconfig --- linux-2.4.21-bk37/arch/mips/defconfig 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig 2003-08-24 02:55:57.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,28 +58,28 @@ # CONFIG_NINO is not set CONFIG_SGI_IP22=y # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_ARC32=y -CONFIG_ARC_CONSOLE=y -CONFIG_ARC_MEMORY=y +CONFIG_ARC_PROMLIB=y CONFIG_BOARD_SCACHE=y CONFIG_BOOT_ELF32=y -CONFIG_SWAP_IO_SPACE=y +# CONFIG_SWAP_IO_SPACE_W is not set +CONFIG_SWAP_IO_SPACE_L=y CONFIG_IRQ_CPU=y CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NONCOHERENT_IO=y -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y CONFIG_PC_KEYB=y -CONFIG_SGI=y # CONFIG_MIPS_AU1000 is not set # @@ -91,7 +101,6 @@ # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -104,7 +113,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set CONFIG_BINFMT_IRIX=y -CONFIG_FORWARD_KEYBOARD=y CONFIG_ARC_CONSOLE=y # CONFIG_IP22_EISA is not set CONFIG_NET=y @@ -125,9 +133,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -282,6 +291,7 @@ # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -310,6 +320,7 @@ # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # @@ -354,6 +365,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -443,6 +455,11 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards @@ -451,6 +468,7 @@ # CONFIG_WATCHDOG_NOWAYOUT is not set # CONFIG_ACQUIRE_WDT is not set # CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set # CONFIG_ALIM7101_WDT is not set # CONFIG_SC520_WDT is not set # CONFIG_PCWATCHDOG is not set @@ -461,6 +479,7 @@ # CONFIG_MIXCOMWD is not set # CONFIG_60XX_WDT is not set # CONFIG_SC1200_WDT is not set +# CONFIG_SCx200_WDT is not set # CONFIG_SOFT_WATCHDOG is not set # CONFIG_W83877F_WDT is not set # CONFIG_WDT is not set @@ -468,8 +487,12 @@ # CONFIG_MACHZ_WDT is not set CONFIG_INDYDOG=y # CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +CONFIG_SGI_DS1286=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -482,16 +505,10 @@ # CONFIG_DRM is not set # -# SGI Character devices -# -CONFIG_SGI_NEWPORT_CONSOLE=y -CONFIG_FONT_8x16=y -CONFIG_DUMMY_CONSOLE=y - -# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y # CONFIG_REISERFS_FS is not set @@ -501,11 +518,12 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set @@ -536,7 +554,7 @@ # CONFIG_QNX4FS_FS is not set # CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UDF_FS is not set # CONFIG_UDF_RW is not set @@ -550,6 +568,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set @@ -599,6 +618,9 @@ # Console drivers # # CONFIG_VGA_CONSOLE is not set +CONFIG_SGI_NEWPORT_CONSOLE=y +CONFIG_FONT_8x16=y +CONFIG_DUMMY_CONSOLE=y # CONFIG_MDA_CONSOLE is not set # @@ -609,15 +631,31 @@ # # Sound # -# CONFIG_SOUND is not set - -# -# SGI devices -# -CONFIG_SGI_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set -CONFIG_SGI_DS1286=y -# CONFIG_SGI_NEWPORT_GFX is not set +CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_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_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_HAL2=y +# 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_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set # # USB support @@ -633,12 +671,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-atlas linux-2.4.21-bk38/arch/mips/defconfig-atlas --- linux-2.4.21-bk37/arch/mips/defconfig-atlas 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-atlas 2003-08-24 02:55:57.000000000 -0700 @@ -19,17 +19,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set CONFIG_MIPS_ATLAS=y # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +46,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,21 +56,27 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BOOT_ELF32=y CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NEW_IRQ=y +CONFIG_MIPS_BONITO64=y +CONFIG_MIPS_GT64120=y +CONFIG_MIPS_MSC=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y CONFIG_PCI=y -CONFIG_SWAP_IO_SPACE=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y # CONFIG_MIPS_AU1000 is not set # @@ -96,7 +112,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set @@ -115,9 +130,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -271,6 +287,7 @@ # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -313,6 +330,7 @@ # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # @@ -357,14 +375,17 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -381,6 +402,7 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set # CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set @@ -399,6 +421,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -484,13 +507,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -506,6 +537,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -515,6 +547,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -564,6 +597,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set @@ -629,14 +663,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-bosporus linux-2.4.21-bk38/arch/mips/defconfig-bosporus --- linux-2.4.21-bk37/arch/mips/defconfig-bosporus 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-bosporus 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,932 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +CONFIG_MIPS_BOSPORUS=y +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1500=y +CONFIG_PC_KEYB=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +CONFIG_PCI_NAMES=y +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +# CONFIG_PCMCIA is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +# CONFIG_HOTPLUG_PCI_ACPI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +CONFIG_MTD_BOSPORUS=y +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +# CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_CSTM_MIPS_IXX is not set +# CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# 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_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# 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_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_FILTER=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +# CONFIG_IP_NF_FTP is not set +# CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_TFTP is not set +# CONFIG_IP_NF_IRC is not set +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +# CONFIG_IP_NF_MATCH_LIMIT is not set +# CONFIG_IP_NF_MATCH_MAC is not set +# CONFIG_IP_NF_MATCH_PKTTYPE is not set +# CONFIG_IP_NF_MATCH_MARK is not set +# CONFIG_IP_NF_MATCH_MULTIPORT is not set +# CONFIG_IP_NF_MATCH_TOS is not set +# CONFIG_IP_NF_MATCH_RECENT is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_DSCP is not set +# CONFIG_IP_NF_MATCH_AH_ESP is not set +# CONFIG_IP_NF_MATCH_LENGTH is not set +# CONFIG_IP_NF_MATCH_TTL is not set +# CONFIG_IP_NF_MATCH_TCPMSS is not set +# CONFIG_IP_NF_MATCH_HELPER is not set +# CONFIG_IP_NF_MATCH_STATE is not set +# CONFIG_IP_NF_MATCH_CONNTRACK is not set +# CONFIG_IP_NF_MATCH_UNCLEAN is not set +# CONFIG_IP_NF_MATCH_OWNER is not set +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +# CONFIG_IP_NF_TARGET_MIRROR is not set +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_NAT_LOCAL=y +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_MANGLE=m +# CONFIG_IP_NF_TARGET_TOS is not set +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_DSCP is not set +# CONFIG_IP_NF_TARGET_MARK is not set +# CONFIG_IP_NF_TARGET_LOG is not set +# CONFIG_IP_NF_TARGET_ULOG is not set +# CONFIG_IP_NF_TARGET_TCPMSS is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +CONFIG_WAN_ROUTER=m +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +CONFIG_SCSI=m + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +CONFIG_SD_EXTRA_DEVS=40 +CONFIG_CHR_DEV_ST=m +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_SR_EXTRA_DEVS=2 +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_NCR53C8XX is not set +# CONFIG_SCSI_SYM53C8XX is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM 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_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_WAVELAN is not set +# CONFIG_ARLAN is not set +# CONFIG_AIRONET4500 is not set +# CONFIG_AIRONET4500_NONCS is not set +# CONFIG_AIRONET4500_PROC is not set +# CONFIG_AIRO is not set +# CONFIG_HERMES is not set +# CONFIG_PLX_HERMES is not set +# CONFIG_PCI_HERMES is not set +CONFIG_NET_WIRELESS=y + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO 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_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_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 is not set +# CONFIG_DEVFS_MOUNT is not set +# 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_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_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_DEBUG=y +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21-bk37/arch/mips/defconfig-capcella linux-2.4.21-bk38/arch/mips/defconfig-capcella --- linux-2.4.21-bk37/arch/mips/defconfig-capcella 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-capcella 2003-08-24 02:55:57.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,17 +58,17 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set CONFIG_ZAO_CAPCELLA=y # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_CPU_VR41XX=y -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_NEW_IRQ=y CONFIG_IRQ_CPU=y CONFIG_NEW_TIME_C=y CONFIG_VR41XX_TIME_C=y @@ -118,9 +128,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -250,15 +261,6 @@ CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set # CONFIG_IDEDISK_STROKE 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 is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -272,15 +274,15 @@ # 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 is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set +CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -329,14 +331,17 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -353,6 +358,7 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set # CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set @@ -371,6 +377,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -457,6 +464,11 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards @@ -465,6 +477,7 @@ # CONFIG_WATCHDOG_NOWAYOUT is not set # CONFIG_ACQUIRE_WDT is not set # CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set # CONFIG_ALIM7101_WDT is not set # CONFIG_SC520_WDT is not set # CONFIG_PCWATCHDOG is not set @@ -475,6 +488,7 @@ # CONFIG_MIXCOMWD is not set # CONFIG_60XX_WDT is not set # CONFIG_SC1200_WDT is not set +# CONFIG_SCx200_WDT is not set # CONFIG_SOFT_WATCHDOG is not set # CONFIG_W83877F_WDT is not set # CONFIG_WDT is not set @@ -482,8 +496,11 @@ # CONFIG_MACHZ_WDT is not set # CONFIG_INDYDOG is not set # CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -499,6 +516,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y # CONFIG_REISERFS_FS is not set @@ -508,6 +526,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -557,6 +576,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set @@ -632,14 +652,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-cobalt linux-2.4.21-bk38/arch/mips/defconfig-cobalt --- linux-2.4.21-bk37/arch/mips/defconfig-cobalt 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-cobalt 2003-08-24 02:55:57.000000000 -0700 @@ -19,17 +19,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set CONFIG_MIPS_COBALT=y # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +46,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,10 +56,13 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -57,7 +70,6 @@ CONFIG_COBALT_LCD=y CONFIG_I8259=y CONFIG_PCI=y -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y # CONFIG_MIPS_AU1000 is not set @@ -81,7 +93,6 @@ # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y @@ -110,9 +121,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -238,15 +250,6 @@ CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set # CONFIG_IDEDISK_STROKE 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 is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -260,8 +263,8 @@ # 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_BLK_DEV_GENERIC is not set # CONFIG_IDEPCI_SHARE_IRQ is not set CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_OFFBOARD is not set @@ -270,30 +273,29 @@ # CONFIG_IDEDMA_ONLYDISK is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_PCI_WIP is not set -# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set -# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set -CONFIG_BLK_DEV_ADMA=y +# CONFIG_BLK_DEV_ADMA100 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_AMD74XX is not set # CONFIG_AMD74XX_OVERRIDE is not set # CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_CMD680 is not set +# CONFIG_BLK_DEV_TRIFLEX is not set # 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_PIIX is not set -# CONFIG_PIIX_TUNING 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_BLK_DEV_PDC202XX_OLD is not set # CONFIG_PDC202XX_BURST is not set -# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set @@ -306,6 +308,7 @@ # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -354,8 +357,10 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set CONFIG_TULIP=y # CONFIG_TULIP_MWI is not set @@ -364,6 +369,7 @@ # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -380,6 +386,7 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set # CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set @@ -398,6 +405,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -483,13 +491,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set CONFIG_RTC=y +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -505,6 +521,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -514,6 +531,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -563,6 +581,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set # CONFIG_ROOT_NFS is not set # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set @@ -627,14 +646,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-db1000 linux-2.4.21-bk38/arch/mips/defconfig-db1000 --- linux-2.4.21-bk37/arch/mips/defconfig-db1000 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-db1000 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,981 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +CONFIG_MIPS_DB1000=y +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1000=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +# CONFIG_PCI_AUTO is not set +CONFIG_NONCOHERENT_IO=y +CONFIG_PC_KEYB=y +CONFIG_SWAP_IO_SPACE=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +CONFIG_PCI_NAMES=y +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_CARDBUS is not set +# CONFIG_TCIC is not set +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +CONFIG_PCMCIA_AU1X00=m +# CONFIG_PCMCIA_PB1X00 is not set +CONFIG_PCMCIA_DB1X00=y +# CONFIG_PCMCIA_XXS1500 is not set +# CONFIG_PCMCIA_VRC4173 is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +# CONFIG_HOTPLUG_PCI_ACPI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +CONFIG_MTD_DB1X00=y +CONFIG_MTD_DB1X00_BOOT=y +CONFIG_MTD_DB1X00_USER=y +# CONFIG_MTD_CSTM_MIPS_IXX is not set +# CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# 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_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# 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_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_FILTER=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +CONFIG_BLK_DEV_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# 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_IDEPCI is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM 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_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +CONFIG_IRDA=y + +# +# IrDA protocols +# +CONFIG_IRLAN=m +# CONFIG_IRNET is not set +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +# CONFIG_IRTTY_SIR is not set +# CONFIG_IRPORT_SIR is not set + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_NSC_FIR is not set +# CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_OLD is not set +# CONFIG_TOSHIBA_FIR is not set +CONFIG_AU1000_FIR=m +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +# CONFIG_VLSI_FIR is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_PCMCIA_SERIAL_CS is not set +# CONFIG_SYNCLINK_CS is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO 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_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +# CONFIG_UMSDOS_FS is not set +CONFIG_VFAT_FS=y +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_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 is not set +# CONFIG_DEVFS_MOUNT is not set +# 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_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_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_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_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_AU1X00=y +# 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_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21-bk37/arch/mips/defconfig-db1100 linux-2.4.21-bk38/arch/mips/defconfig-db1100 --- linux-2.4.21-bk37/arch/mips/defconfig-db1100 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-db1100 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,1020 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +CONFIG_MIPS_DB1100=y +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1100=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_NONCOHERENT_IO=y +CONFIG_PC_KEYB=y +CONFIG_SWAP_IO_SPACE=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_CARDBUS is not set +# CONFIG_TCIC is not set +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +CONFIG_PCMCIA_AU1X00=m +# CONFIG_PCMCIA_PB1X00 is not set +CONFIG_PCMCIA_DB1X00=y +# CONFIG_PCMCIA_XXS1500 is not set +# CONFIG_PCMCIA_VRC4173 is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +# CONFIG_HOTPLUG_PCI_ACPI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +CONFIG_MTD_DB1X00=y +# CONFIG_MTD_DB1X00_BOOT is not set +CONFIG_MTD_DB1X00_USER=y +# CONFIG_MTD_CSTM_MIPS_IXX is not set +# CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# 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_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# 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_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_FILTER=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +CONFIG_BLK_DEV_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# 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_IDEPCI is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM 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_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +CONFIG_IRDA=y + +# +# IrDA protocols +# +CONFIG_IRLAN=m +# CONFIG_IRNET is not set +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +# CONFIG_IRTTY_SIR is not set +# CONFIG_IRPORT_SIR is not set + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_NSC_FIR is not set +# CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_OLD is not set +# CONFIG_TOSHIBA_FIR is not set +CONFIG_AU1000_FIR=m +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +# CONFIG_VLSI_FIR is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_PCMCIA_SERIAL_CS is not set +# CONFIG_SYNCLINK_CS is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO 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_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +# CONFIG_UMSDOS_FS is not set +CONFIG_VFAT_FS=y +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_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 is not set +# CONFIG_DEVFS_MOUNT is not set +# 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_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_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_RIVA is not set +# CONFIG_FB_CLGEN is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_E1356 is not set +CONFIG_FB_AU1100=y +# CONFIG_FB_VIRTUAL is not set +CONFIG_FBCON_ADVANCED=y +# CONFIG_FBCON_MFB is not set +# CONFIG_FBCON_CFB2 is not set +# CONFIG_FBCON_CFB4 is not set +CONFIG_FBCON_CFB8=y +CONFIG_FBCON_CFB16=y +# CONFIG_FBCON_CFB24 is not set +# CONFIG_FBCON_CFB32 is not set +# CONFIG_FBCON_AFB is not set +# CONFIG_FBCON_ILBM is not set +# CONFIG_FBCON_IPLAN2P2 is not set +# CONFIG_FBCON_IPLAN2P4 is not set +# CONFIG_FBCON_IPLAN2P8 is not set +# CONFIG_FBCON_MAC is not set +# CONFIG_FBCON_VGA_PLANES is not set +# CONFIG_FBCON_VGA is not set +# CONFIG_FBCON_HGA is not set +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +# CONFIG_FBCON_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_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_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_AU1X00=y +# 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_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21-bk37/arch/mips/defconfig-db1500 linux-2.4.21-bk38/arch/mips/defconfig-db1500 --- linux-2.4.21-bk37/arch/mips/defconfig-db1500 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-db1500 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,860 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +CONFIG_MIPS_DB1500=y +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1500=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_NONCOHERENT_IO=y +CONFIG_PC_KEYB=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_CARDBUS is not set +# CONFIG_TCIC is not set +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +CONFIG_PCMCIA_AU1X00=m +# CONFIG_PCMCIA_PB1X00 is not set +CONFIG_PCMCIA_DB1X00=y +# CONFIG_PCMCIA_XXS1500 is not set +# CONFIG_PCMCIA_VRC4173 is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +# CONFIG_HOTPLUG_PCI_ACPI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# 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_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# 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_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +CONFIG_BLK_DEV_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# 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_IDEPCI=y +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_BLK_DEV_ADMA100 is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_AMD74XX_OVERRIDE is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# 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=y +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_PDC202XX_BURST is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_CHIPSETS is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM 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_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_PCMCIA_SERIAL_CS is not set +# CONFIG_SYNCLINK_CS is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO 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_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_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 is not set +# CONFIG_DEVFS_MOUNT is not set +# 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_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_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_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_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_AU1X00=y +# 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_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21-bk37/arch/mips/defconfig-ddb5476 linux-2.4.21-bk38/arch/mips/defconfig-ddb5476 --- linux-2.4.21-bk37/arch/mips/defconfig-ddb5476 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-ddb5476 2003-08-24 02:55:57.000000000 -0700 @@ -19,17 +19,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +46,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set CONFIG_DDB5476=y # CONFIG_DDB5477 is not set @@ -46,10 +56,13 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -57,7 +70,6 @@ CONFIG_ISA=y CONFIG_PCI=y CONFIG_PC_KEYB=y -CONFIG_NEW_IRQ=y CONFIG_IRQ_CPU=y CONFIG_I8259=y CONFIG_HAVE_STD_PC_SERIAL_PORT=y @@ -113,9 +125,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -244,15 +257,6 @@ CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set # CONFIG_IDEDISK_STROKE 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 is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -266,8 +270,8 @@ # 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_BLK_DEV_GENERIC is not set # CONFIG_IDEPCI_SHARE_IRQ is not set # CONFIG_BLK_DEV_IDEDMA_PCI is not set # CONFIG_BLK_DEV_OFFBOARD is not set @@ -276,30 +280,29 @@ # CONFIG_IDEDMA_ONLYDISK is not set # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_PCI_WIP is not set -# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set -# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set -# CONFIG_BLK_DEV_ADMA is not set +# CONFIG_BLK_DEV_ADMA100 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_AMD74XX is not set # CONFIG_AMD74XX_OVERRIDE is not set # CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_CMD680 is not set +# CONFIG_BLK_DEV_TRIFLEX is not set # 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_PIIX is not set -# CONFIG_PIIX_TUNING 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_BLK_DEV_PDC202XX_OLD is not set # CONFIG_PDC202XX_BURST is not set -# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set @@ -307,10 +310,11 @@ # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set +CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -361,9 +365,11 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_AC3200 is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set CONFIG_TULIP=y # CONFIG_TULIP_MWI is not set @@ -372,6 +378,7 @@ # CONFIG_DGRS is not set # CONFIG_DM9102 is not set CONFIG_EEPRO100=y +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -388,6 +395,7 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set # CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set @@ -406,6 +414,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -501,13 +510,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -523,6 +540,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -532,6 +550,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -581,6 +600,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set @@ -632,6 +652,7 @@ # CONFIG_FB_ATY is not set # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set # CONFIG_FB_SIS is not set # CONFIG_FB_NEOMAGIC is not set CONFIG_FB_3DFX=y @@ -667,14 +688,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +CONFIG_RUNTIME_DEBUG=y +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -CONFIG_DEBUG=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-ddb5477 linux-2.4.21-bk38/arch/mips/defconfig-ddb5477 --- linux-2.4.21-bk37/arch/mips/defconfig-ddb5477 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-ddb5477 2003-08-24 02:55:57.000000000 -0700 @@ -19,17 +19,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +46,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set CONFIG_DDB5477=y @@ -47,22 +57,24 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_PCI=y CONFIG_NEW_TIME_C=y -CONFIG_NEW_IRQ=y CONFIG_IRQ_CPU=y CONFIG_NEW_PCI=y CONFIG_NONCOHERENT_IO=y CONFIG_PCI_AUTO=y -CONFIG_DUMMY_KEYB=y +CONFIG_PC_KEYB=y CONFIG_I8259=y # CONFIG_MIPS_AU1000 is not set @@ -113,9 +125,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -280,8 +293,10 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y CONFIG_PCNET32=y +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set CONFIG_TULIP=y # CONFIG_TULIP_MWI is not set @@ -290,6 +305,7 @@ # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -306,6 +322,7 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set # CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set @@ -324,6 +341,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -409,13 +427,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -431,6 +457,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y # CONFIG_REISERFS_FS is not set @@ -440,6 +467,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -489,6 +517,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set @@ -563,14 +592,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +CONFIG_RUNTIME_DEBUG=y +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -CONFIG_DEBUG=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-e55 linux-2.4.21-bk38/arch/mips/defconfig-e55 --- linux-2.4.21-bk37/arch/mips/defconfig-e55 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-e55 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,629 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +CONFIG_CASIO_E55=y +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_IRQ_CPU=y +CONFIG_NEW_TIME_C=y +CONFIG_VR41XX_TIME_C=y +CONFIG_NONCOHERENT_IO=y +CONFIG_ISA=y +CONFIG_DUMMY_KEYB=y +# CONFIG_SCSI is not set +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +CONFIG_CPU_VR41XX=y +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_ADVANCED is not set +# CONFIG_CPU_HAS_LLSC is not set +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI is not set +CONFIG_EISA=y +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# 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_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# 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_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# 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_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM 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 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +CONFIG_SERIAL_EXTENDED=y +CONFIG_SERIAL_MANY_PORTS=y +# CONFIG_SERIAL_SHARE_IRQ is not set +# CONFIG_SERIAL_DETECT_IRQ is not set +# CONFIG_SERIAL_MULTIPORT is not set +# CONFIG_HUB6 is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_INDYDOG is not set +# CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO 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_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_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 is not set +# CONFIG_DEVFS_MOUNT is not set +# 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_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_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_ROOT_NFS is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-eagle linux-2.4.21-bk38/arch/mips/defconfig-eagle --- linux-2.4.21-bk37/arch/mips/defconfig-eagle 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-eagle 2003-08-24 02:55:57.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,25 +48,28 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set # CONFIG_NEC_OSPREY is not set CONFIG_NEC_EAGLE=y +CONFIG_VRC4173=y # CONFIG_OLIVETTI_M700 is not set # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_CPU_VR41XX=y -CONFIG_NEW_IRQ=y CONFIG_IRQ_CPU=y CONFIG_NEW_TIME_C=y CONFIG_VR41XX_TIME_C=y @@ -106,9 +118,25 @@ # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set -# CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=y +# CONFIG_CARDBUS is not set +# CONFIG_TCIC is not set +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +CONFIG_PCMCIA_VRC4173=y + +# +# PCI Hotplug Support +# # CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +# CONFIG_HOTPLUG_PCI_ACPI is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y @@ -117,9 +145,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -129,6 +158,7 @@ # CONFIG_MTD_PARTITIONS is not set # CONFIG_MTD_CONCAT is not set # CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set # # User Modules And Translation Layers @@ -151,6 +181,7 @@ # CONFIG_MTD_CFI_GEOMETRY is not set CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set @@ -169,15 +200,20 @@ # CONFIG_MTD_PB1000 is not set # CONFIG_MTD_PB1500 is not set # CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +# CONFIG_MTD_DB1X00 is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set # CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set # # Self-contained MTD device drivers # # CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_MS02NV is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_MTDRAM is not set # CONFIG_MTD_BLKMTD is not set @@ -303,9 +339,43 @@ # # ATA/IDE/MFM/RLL support # -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set # CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +# CONFIG_IDEDISK_STROKE is not set +CONFIG_BLK_DEV_IDECS=y +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# 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_IDEPCI is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -354,14 +424,17 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y CONFIG_PCNET32=y +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -378,6 +451,7 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set # CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set @@ -396,6 +470,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -423,6 +498,22 @@ # CONFIG_WAN is not set # +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +# CONFIG_PCMCIA_3C589 is not set +# CONFIG_PCMCIA_3C574 is not set +CONFIG_PCMCIA_FMVJ18X=y +CONFIG_PCMCIA_PCNET=m +# CONFIG_PCMCIA_AXNET is not set +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_ARCNET_COM20020_CS is not set +# CONFIG_PCMCIA_IBMTR is not set +# CONFIG_NET_PCMCIA_RADIO is not set + +# # Amateur Radio support # # CONFIG_HAMRADIO is not set @@ -486,6 +577,11 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards @@ -494,6 +590,7 @@ # CONFIG_WATCHDOG_NOWAYOUT is not set # CONFIG_ACQUIRE_WDT is not set # CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set # CONFIG_ALIM7101_WDT is not set # CONFIG_SC520_WDT is not set # CONFIG_PCWATCHDOG is not set @@ -504,6 +601,7 @@ # CONFIG_MIXCOMWD is not set # CONFIG_60XX_WDT is not set # CONFIG_SC1200_WDT is not set +# CONFIG_SCx200_WDT is not set # CONFIG_SOFT_WATCHDOG is not set # CONFIG_W83877F_WDT is not set # CONFIG_WDT is not set @@ -511,8 +609,11 @@ # CONFIG_MACHZ_WDT is not set # CONFIG_INDYDOG is not set # CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -525,9 +626,16 @@ # CONFIG_DRM is not set # +# PCMCIA character devices +# +# CONFIG_PCMCIA_SERIAL_CS is not set +# CONFIG_SYNCLINK_CS is not set + +# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y # CONFIG_REISERFS_FS is not set @@ -537,6 +645,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -589,6 +698,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set @@ -653,7 +763,110 @@ # # USB support # -# CONFIG_USB is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_BANDWIDTH=y + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +# CONFIG_USB_HID is not set + +# +# Input core support is needed for USB HID input layer or HIDBP support +# +# CONFIG_USB_HIDINPUT is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +CONFIG_USB_PEGASUS=y +CONFIG_USB_RTL8150=y +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set # # Bluetooth support @@ -664,14 +877,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -urN linux-2.4.21-bk37/arch/mips/defconfig-ev64120 linux-2.4.21-bk38/arch/mips/defconfig-ev64120 --- linux-2.4.21-bk37/arch/mips/defconfig-ev64120 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-ev64120 2003-08-24 02:55:57.000000000 -0700 @@ -21,11 +21,18 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set CONFIG_MIPS_EV64120=y @@ -36,6 +43,8 @@ # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -43,6 +52,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -52,10 +62,13 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -86,7 +99,6 @@ # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -99,7 +111,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set CONFIG_NET=y # CONFIG_PCI_NAMES is not set # CONFIG_ISA is not set @@ -118,9 +129,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -284,14 +296,17 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -308,6 +323,7 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set # CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set @@ -326,6 +342,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -418,11 +435,18 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_DTLK is not set @@ -440,6 +464,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -449,6 +474,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -498,6 +524,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set @@ -548,14 +575,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-ev96100 linux-2.4.21-bk38/arch/mips/defconfig-ev96100 --- linux-2.4.21-bk37/arch/mips/defconfig-ev96100 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-ev96100 2003-08-24 02:55:57.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set CONFIG_MIPS_EV96100=y # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,21 +58,26 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_BOARD_SCACHE=y CONFIG_PCI=y +CONFIG_MIPS_GT64120=y CONFIG_MIPS_GT96100=y -CONFIG_NEW_IRQ=y CONFIG_NEW_PCI=y CONFIG_NONCOHERENT_IO=y CONFIG_PCI_AUTO=y -CONFIG_SWAP_IO_SPACE=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y # CONFIG_MIPS_AU1000 is not set # @@ -97,7 +112,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set @@ -116,9 +130,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -283,8 +298,10 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set CONFIG_TULIP=y # CONFIG_TULIP_MWI is not set @@ -293,6 +310,7 @@ # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -309,6 +327,7 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set # CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set @@ -327,6 +346,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -412,11 +432,18 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_DTLK is not set @@ -434,6 +461,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -443,6 +471,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -492,6 +521,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set @@ -542,14 +572,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-hp-lj linux-2.4.21-bk38/arch/mips/defconfig-hp-lj --- linux-2.4.21-bk37/arch/mips/defconfig-hp-lj 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/defconfig-hp-lj 2003-08-24 02:55:57.000000000 -0700 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,101 +11,203 @@ CONFIG_EXPERIMENTAL=y # +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# # Machine selection # # CONFIG_ACER_PICA_61 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set -# CONFIG_DDB5074 is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +CONFIG_HP_LASERJET=y +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set -CONFIG_MIPS_MALTA=y -# CONFIG_NINO is not set -# CONFIG_SIBYTE_SB1250 is not set # CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set # CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1500 is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_HP_LASERJET is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set -CONFIG_I8259=y -CONFIG_PCI=y -CONFIG_HAVE_STD_PC_SERIAL_PORT=y -CONFIG_NEW_IRQ=y +CONFIG_IRQ_CPU=y CONFIG_NEW_TIME_C=y +CONFIG_NEW_PCI=y CONFIG_NONCOHERENT_IO=y -CONFIG_SWAP_IO_SPACE=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set - -# -# Loadable module support -# -# CONFIG_MODULES is not set +CONFIG_PCI=y +# CONFIG_MIPS_AU1000 is not set # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set # CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_R6000 is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set # CONFIG_CPU_TX49XX is not set -# CONFIG_CPU_R5000 is not set +CONFIG_CPU_R5000=y # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_CPU_MIPS32=y -# CONFIG_CPU_MIPS64 is not set -CONFIG_CPU_HAS_PREFETCH=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y -# CONFIG_CPU_HAS_LLDSCD is not set +CONFIG_CPU_HAS_LLDSCD=y # CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y # # General setup # CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_KCORE_ELF=y -CONFIG_ELF_KERNEL=y -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set CONFIG_NET=y # CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set # CONFIG_HOTPLUG_PCI is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_SYSCTL is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set # # Memory Technology Devices (MTD) # -# CONFIG_MTD is not set +CONFIG_MTD=y +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=3 +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=10040000 +CONFIG_MTD_PHYSMAP_LEN=00fc0000 +CONFIG_MTD_PHYSMAP_BUSWIDTH=4 +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +# CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_CSTM_MIPS_IXX is not set +# CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NAND_IDS=y # # Parallel port support @@ -112,19 +215,27 @@ # CONFIG_PARPORT is not set # +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# # Block devices # -CONFIG_BLK_DEV_FD=y +# 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_CISS_SCSI_TAPE is not set # CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set # # Multi-device support (RAID and LVM) @@ -141,7 +252,8 @@ # # Networking options # -# CONFIG_PACKET is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set # CONFIG_NETLINK_DEV is not set # CONFIG_NETFILTER is not set # CONFIG_FILTER is not set @@ -150,7 +262,7 @@ # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_DHCP=y # CONFIG_IP_PNP_BOOTP is not set # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set @@ -168,6 +280,11 @@ # # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -185,6 +302,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Telephony Support # # CONFIG_PHONE is not set @@ -194,81 +316,85 @@ # # ATA/IDE/MFM/RLL support # -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set -# CONFIG_BLK_DEV_HD is not set +CONFIG_IDE=y # -# SCSI support +# IDE, ATA and ATAPI Block devices # -CONFIG_SCSI=y +CONFIG_BLK_DEV_IDE=y # -# SCSI support type (disk, tape, CD-ROM) +# Please see Documentation/ide.txt for help/info on IDE drives # -CONFIG_BLK_DEV_SD=y -CONFIG_SD_EXTRA_DEVS=40 -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_DEBUG_QUEUES is not set -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI low-level drivers -# -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_7000FASST is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AHA1740 is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set -# CONFIG_SCSI_MEGARAID is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set -# CONFIG_SCSI_EATA_PIO is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR53C7xx is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_NCR53C8XX is not set -# CONFIG_SCSI_SYM53C8XX is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_QLOGIC_ISP is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_DEBUG is not set +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_BLK_DEV_CMD640=y +CONFIG_BLK_DEV_CMD640_ENHANCED=y +# CONFIG_BLK_DEV_ISAPNP is not set +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_BLK_DEV_ADMA100 is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_AMD74XX_OVERRIDE is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# 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_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_PDC202XX_BURST is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_CHIPSETS is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set # # I2O device support @@ -311,16 +437,21 @@ # CONFIG_HP100 is not set # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y -CONFIG_PCNET32=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set -# CONFIG_TULIP is not set -# CONFIG_TC35815 is not set +CONFIG_TULIP=y +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -332,11 +463,13 @@ # CONFIG_8139TOO_PIO is not set # CONFIG_8139TOO_TUNE_TWISTER is not set # CONFIG_8139TOO_8129 is not set -# CONFIG_8139_NEW_RX_RESET is not set +# CONFIG_8139_OLD_RX_RESET is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set +# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -348,11 +481,14 @@ # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set +# CONFIG_E1000 is not set # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set @@ -362,7 +498,18 @@ # # Wireless LAN (non-hamradio) # -# CONFIG_NET_RADIO is not set +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_WAVELAN is not set +# CONFIG_ARLAN is not set +# CONFIG_AIRONET4500 is not set +# CONFIG_AIRONET4500_NONCS is not set +# CONFIG_AIRONET4500_PROC is not set +# CONFIG_AIRO is not set +# CONFIG_HERMES is not set +# CONFIG_PLX_HERMES is not set +# CONFIG_PCI_HERMES is not set +CONFIG_NET_WIRELESS=y # # Token Ring devices @@ -393,9 +540,13 @@ # CONFIG_ISDN is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input core support # -# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set # # Character devices @@ -405,8 +556,7 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 +# CONFIG_UNIX98_PTYS is not set # # I2C support @@ -432,14 +582,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set -CONFIG_RTC=y +# CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -452,15 +609,11 @@ # CONFIG_DRM is not set # -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# # File systems # # CONFIG_QUOTA is not set -CONFIG_AUTOFS_FS=y +# CONFIG_QFMT_V2 is not set +# CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_REISERFS_CHECK is not set @@ -469,6 +622,9 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set @@ -477,15 +633,19 @@ # CONFIG_MSDOS_FS is not set # CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS is not set -CONFIG_EFS_FS=y +# CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=3 # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set +CONFIG_RAMFS=y # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -495,7 +655,7 @@ # CONFIG_DEVFS_FS is not set # CONFIG_DEVFS_MOUNT is not set # CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y +# CONFIG_DEVPTS_FS is not set # CONFIG_QNX4FS_FS is not set # CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set @@ -512,12 +672,15 @@ # CONFIG_CODA_FS is not set # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set +CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set # CONFIG_NCPFS_PACKET_SIGNING is not set @@ -529,7 +692,6 @@ # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set # CONFIG_ZISOFS_FS is not set -# CONFIG_ZLIB_FS_INFLATE is not set # # Partition Types @@ -540,6 +702,11 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Sound # # CONFIG_SOUND is not set @@ -550,119 +717,28 @@ # CONFIG_USB is not set # -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices -# - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# -# USB Network adaptors +# Bluetooth support # -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set +# CONFIG_BLUEZ is not set # -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OMNINET is not set - -# -# USB Miscellaneous drivers +# Kernel hacking # -# CONFIG_USB_RIO500 is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +# CONFIG_CRYPTO is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set -# CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff -urN linux-2.4.21-bk37/arch/mips/defconfig-ip22 linux-2.4.21-bk38/arch/mips/defconfig-ip22 --- linux-2.4.21-bk37/arch/mips/defconfig-ip22 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-ip22 2003-08-24 02:55:57.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,28 +58,28 @@ # CONFIG_NINO is not set CONFIG_SGI_IP22=y # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_ARC32=y -CONFIG_ARC_CONSOLE=y -CONFIG_ARC_MEMORY=y +CONFIG_ARC_PROMLIB=y CONFIG_BOARD_SCACHE=y CONFIG_BOOT_ELF32=y -CONFIG_SWAP_IO_SPACE=y +# CONFIG_SWAP_IO_SPACE_W is not set +CONFIG_SWAP_IO_SPACE_L=y CONFIG_IRQ_CPU=y CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NONCOHERENT_IO=y -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y CONFIG_PC_KEYB=y -CONFIG_SGI=y # CONFIG_MIPS_AU1000 is not set # @@ -91,7 +101,6 @@ # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -104,7 +113,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set CONFIG_BINFMT_IRIX=y -CONFIG_FORWARD_KEYBOARD=y CONFIG_ARC_CONSOLE=y # CONFIG_IP22_EISA is not set CONFIG_NET=y @@ -125,9 +133,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -282,6 +291,7 @@ # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -310,6 +320,7 @@ # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # @@ -354,6 +365,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -411,7 +423,30 @@ CONFIG_VT_CONSOLE=y # CONFIG_SERIAL is not set # CONFIG_SERIAL_EXTENDED is not set -# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_IP22_SERIAL=y CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -443,6 +478,11 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards @@ -451,6 +491,7 @@ # CONFIG_WATCHDOG_NOWAYOUT is not set # CONFIG_ACQUIRE_WDT is not set # CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set # CONFIG_ALIM7101_WDT is not set # CONFIG_SC520_WDT is not set # CONFIG_PCWATCHDOG is not set @@ -461,6 +502,7 @@ # CONFIG_MIXCOMWD is not set # CONFIG_60XX_WDT is not set # CONFIG_SC1200_WDT is not set +# CONFIG_SCx200_WDT is not set # CONFIG_SOFT_WATCHDOG is not set # CONFIG_W83877F_WDT is not set # CONFIG_WDT is not set @@ -468,8 +510,12 @@ # CONFIG_MACHZ_WDT is not set CONFIG_INDYDOG=y # CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +CONFIG_SGI_DS1286=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -482,16 +528,10 @@ # CONFIG_DRM is not set # -# SGI Character devices -# -CONFIG_SGI_NEWPORT_CONSOLE=y -CONFIG_FONT_8x16=y -CONFIG_DUMMY_CONSOLE=y - -# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y # CONFIG_REISERFS_FS is not set @@ -501,11 +541,12 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set @@ -536,7 +577,7 @@ # CONFIG_QNX4FS_FS is not set # CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UDF_FS is not set # CONFIG_UDF_RW is not set @@ -550,6 +591,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set @@ -599,6 +641,9 @@ # Console drivers # # CONFIG_VGA_CONSOLE is not set +CONFIG_SGI_NEWPORT_CONSOLE=y +CONFIG_FONT_8x16=y +CONFIG_DUMMY_CONSOLE=y # CONFIG_MDA_CONSOLE is not set # @@ -609,15 +654,31 @@ # # Sound # -# CONFIG_SOUND is not set - -# -# SGI devices -# -CONFIG_SGI_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set -CONFIG_SGI_DS1286=y -# CONFIG_SGI_NEWPORT_GFX is not set +CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_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_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_HAL2=y +# 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_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set # # USB support @@ -633,12 +694,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-it8172 linux-2.4.21-bk38/arch/mips/defconfig-it8172 --- linux-2.4.21-bk37/arch/mips/defconfig-it8172 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/defconfig-it8172 2003-08-24 02:55:57.000000000 -0700 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,40 +11,65 @@ CONFIG_EXPERIMENTAL=y # +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# # Machine selection # # CONFIG_ACER_PICA_61 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set -# CONFIG_DDB5074 is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +CONFIG_MIPS_ITE8172=y +# CONFIG_IT8172_REVC is not set # CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_NINO is not set -# CONFIG_SIBYTE_SB1250 is not set # CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set # CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set -CONFIG_MIPS_ITE8172=y -# CONFIG_IT8172_REVC is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1500 is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_HP_LASERJET is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set CONFIG_PCI=y CONFIG_IT8712=y CONFIG_PC_KEYB=y @@ -51,58 +77,60 @@ CONFIG_NONCOHERENT_IO=y CONFIG_PCI_AUTO=y CONFIG_IT8172_CIR=y -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set -CONFIG_KMOD=y +# CONFIG_MIPS_AU1000 is not set # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set # CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_R6000 is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set CONFIG_CPU_NEVADA=y +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y # CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y # # General setup # CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_KCORE_ELF=y -CONFIG_ELF_KERNEL=y -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set CONFIG_NET=y CONFIG_PCI_NAMES=y +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set # CONFIG_HOTPLUG_PCI is not set CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set # # Memory Technology Devices (MTD) @@ -110,7 +138,9 @@ CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_PARTITIONS is not set +# CONFIG_MTD_CONCAT is not set # CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set # # User Modules And Translation Layers @@ -130,6 +160,7 @@ # CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set @@ -147,8 +178,16 @@ CONFIG_MTD_PHYSMAP_BUSWIDTH=4 # CONFIG_MTD_PB1000 is not set # CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +# CONFIG_MTD_DB1X00 is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set # # Self-contained MTD device drivers @@ -177,6 +216,12 @@ # CONFIG_PARPORT is not set # +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# # Block devices # # CONFIG_BLK_DEV_FD is not set @@ -184,11 +229,14 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_CISS_SCSI_TAPE is not set # CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set # # Multi-device support (RAID and LVM) @@ -233,6 +281,11 @@ # # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -250,6 +303,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Telephony Support # # CONFIG_PHONE is not set @@ -273,20 +331,13 @@ # CONFIG_BLK_DEV_HD is not set 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_IDEDISK_STROKE is not set # CONFIG_BLK_DEV_IDECS is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set # # IDE chipset support/bugfixes @@ -294,54 +345,45 @@ # 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_BLK_DEV_GENERIC is not set CONFIG_IDEPCI_SHARE_IRQ=y CONFIG_BLK_DEV_IDEDMA_PCI=y -CONFIG_BLK_DEV_ADMA=y # CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_PCI_WIP is not set -# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set +# CONFIG_BLK_DEV_ADMA100 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_AMD74XX is not set # CONFIG_AMD74XX_OVERRIDE is not set # CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set # 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_PIIX is not set CONFIG_BLK_DEV_IT8172=y -CONFIG_IT8172_TUNING=y -CONFIG_BLK_DEV_IT8172=y -CONFIG_IT8172_TUNING=y # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_PDC202XX is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_PDC202XX_BURST is not set -# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set -CONFIG_IDE_CHIPSETS=y - -# -# Note: most of these also require special kernel boot parameters -# -# CONFIG_BLK_DEV_4DRIVES is not set -# CONFIG_BLK_DEV_ALI14XX is not set -# CONFIG_BLK_DEV_DTC2278 is not set -# CONFIG_BLK_DEV_HT6560B is not set -# CONFIG_BLK_DEV_PDC4030 is not set -# CONFIG_BLK_DEV_QD65XX is not set -# CONFIG_BLK_DEV_UMC8672 is not set +# CONFIG_IDE_CHIPSETS is not set CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set # CONFIG_DMA_NONPCI is not set @@ -349,6 +391,7 @@ # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -397,17 +440,20 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set CONFIG_TULIP=y -# CONFIG_TC35815 is not set # CONFIG_TULIP_MWI is not set # CONFIG_TULIP_MMIO is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -419,11 +465,13 @@ # CONFIG_8139TOO_PIO is not set # CONFIG_8139TOO_TUNE_TWISTER is not set # CONFIG_8139TOO_8129 is not set -# CONFIG_8139_NEW_RX_RESET is not set +# CONFIG_8139_OLD_RX_RESET is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set +# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -435,11 +483,14 @@ # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set +# CONFIG_E1000 is not set # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set @@ -480,9 +531,13 @@ # CONFIG_ISDN is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input core support # -# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set # # Character devices @@ -523,14 +578,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set -CONFIG_RTC=y +# CONFIG_RTC is not set +CONFIG_MIPS_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -544,14 +606,10 @@ # CONFIG_ITE_GPIO is not set # -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -561,6 +619,9 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set @@ -574,10 +635,13 @@ # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set +CONFIG_RAMFS=y # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -605,9 +669,11 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set @@ -621,7 +687,6 @@ # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set # CONFIG_ZISOFS_FS is not set -# CONFIG_ZLIB_FS_INFLATE is not set # # Partition Types @@ -632,9 +697,15 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Sound # CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set # CONFIG_SOUND_BT878 is not set # CONFIG_SOUND_CMPCI is not set # CONFIG_SOUND_EMU10K1 is not set @@ -646,11 +717,11 @@ # CONFIG_SOUND_ESSSOLO1 is not set # CONFIG_SOUND_MAESTRO is not set # CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set # CONFIG_SOUND_ICH is not set CONFIG_SOUND_IT8172=y # CONFIG_SOUND_RME96XX is not set # CONFIG_SOUND_SONICVIBES is not set -# CONFIG_SOUND_HAL2 is not set CONFIG_SOUND_IT8172=y # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set @@ -666,123 +737,28 @@ # CONFIG_USB is not set # -# USB Controllers +# Bluetooth support # -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set +# CONFIG_BLUEZ is not set # -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set - -# -# SCSI support is needed for USB Storage -# -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices -# - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# -# USB Network adaptors -# -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OMNINET is not set - -# -# USB Miscellaneous drivers +# Kernel hacking # -# CONFIG_USB_RIO500 is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +# CONFIG_CRYPTO is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set -# CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-ivr linux-2.4.21-bk38/arch/mips/defconfig-ivr --- linux-2.4.21-bk37/arch/mips/defconfig-ivr 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/defconfig-ivr 2003-08-24 02:55:57.000000000 -0700 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -20,31 +21,51 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set CONFIG_MIPS_IVR=y # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set # CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set # CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set -# CONFIG_SIBYTE_SB1250 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set @@ -54,32 +75,33 @@ CONFIG_NONCOHERENT_IO=y CONFIG_PCI_AUTO=y CONFIG_IT8172_CIR=y -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y # CONFIG_MIPS_AU1000 is not set # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set # CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_R6000 is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set CONFIG_CPU_NEVADA=y +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y # CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y # # General setup @@ -102,8 +124,11 @@ # CONFIG_KCORE_AOUT is not set # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -136,6 +161,7 @@ # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set # # Multi-device support (RAID and LVM) @@ -231,15 +257,6 @@ CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set # CONFIG_IDEDISK_STROKE 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 is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -253,8 +270,8 @@ # 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_BLK_DEV_GENERIC is not set # CONFIG_IDEPCI_SHARE_IRQ is not set CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_OFFBOARD is not set @@ -263,32 +280,30 @@ # CONFIG_IDEDMA_ONLYDISK is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_PCI_WIP is not set -# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set -# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set -CONFIG_BLK_DEV_ADMA=y +# CONFIG_BLK_DEV_ADMA100 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_AMD74XX is not set # CONFIG_AMD74XX_OVERRIDE is not set # CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_CMD680 is not set +# CONFIG_BLK_DEV_TRIFLEX is not set # 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_PIIX is not set CONFIG_BLK_DEV_IT8172=y -CONFIG_IT8172_TUNING=y -CONFIG_BLK_DEV_IT8172=y -CONFIG_IT8172_TUNING=y # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_PDC202XX is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_PDC202XX_BURST is not set -# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set @@ -301,6 +316,7 @@ # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -349,17 +365,20 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set CONFIG_TULIP=y -# CONFIG_TC35815 is not set # CONFIG_TULIP_MWI is not set # CONFIG_TULIP_MMIO is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -371,11 +390,13 @@ # CONFIG_8139TOO_PIO is not set # CONFIG_8139TOO_TUNE_TWISTER is not set # CONFIG_8139TOO_8129 is not set -# CONFIG_8139_NEW_RX_RESET is not set +# CONFIG_8139_OLD_RX_RESET is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set +# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -387,10 +408,12 @@ # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set +# CONFIG_E1000 is not set # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -433,6 +456,17 @@ # CONFIG_ISDN is not set # +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# # Character devices # CONFIG_VT=y @@ -493,13 +527,21 @@ # CONFIG_INPUT_GAMECON is not set # CONFIG_INPUT_TURBOGRAFX is not set # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set CONFIG_RTC=y +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -512,14 +554,10 @@ # CONFIG_DRM is not set # -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -529,6 +567,9 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set @@ -546,6 +587,9 @@ # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -573,9 +617,11 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set @@ -589,7 +635,6 @@ # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set # CONFIG_ZISOFS_FS is not set -# CONFIG_ZLIB_FS_INFLATE is not set # # Partition Types @@ -600,6 +645,11 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Console drivers # # CONFIG_VGA_CONSOLE is not set @@ -626,7 +676,6 @@ # # CONFIG_USB_DEVICEFS is not set # CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_LONG_TIMEOUT is not set # # USB Host Controller Drivers @@ -642,6 +691,7 @@ # CONFIG_USB_AUDIO is not set # CONFIG_USB_EMI26 is not set # CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set # # SCSI support is needed for USB Storage @@ -654,6 +704,7 @@ # CONFIG_USB_STORAGE_DPCM is not set # CONFIG_USB_STORAGE_HP8200e is not set # CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set # CONFIG_USB_ACM is not set # CONFIG_USB_PRINTER is not set @@ -664,7 +715,10 @@ CONFIG_USB_HID=y # CONFIG_USB_HIDINPUT is not set # CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set # # USB Imaging devices @@ -690,6 +744,7 @@ # CONFIG_USB_RTL8150 is not set # CONFIG_USB_KAWETH is not set # CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set # CONFIG_USB_CDCETHER is not set # CONFIG_USB_USBNET is not set @@ -702,39 +757,15 @@ # USB Serial Converter support # # CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OMNINET is not set # # USB Miscellaneous drivers # # CONFIG_USB_RIO500 is not set # CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set # CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set # # Bluetooth support @@ -742,22 +773,23 @@ # CONFIG_BLUEZ is not set # -# Input core support -# -CONFIG_INPUT=y -CONFIG_INPUT_KEYBDEV=y -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set - -# # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-jmr3927 linux-2.4.21-bk38/arch/mips/defconfig-jmr3927 --- linux-2.4.21-bk37/arch/mips/defconfig-jmr3927 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/defconfig-jmr3927 2003-08-24 02:55:57.000000000 -0700 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,99 +11,126 @@ CONFIG_EXPERIMENTAL=y # +# Loadable module support +# +# CONFIG_MODULES is not set + +# # Machine selection # # CONFIG_ACER_PICA_61 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set -# CONFIG_DDB5074 is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_NINO is not set -# CONFIG_SIBYTE_SB1250 is not set # CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set # CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1500 is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set CONFIG_TOSHIBA_JMR3927=y -# CONFIG_HP_LASERJET is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set -CONFIG_NONCOHERENT_IO=y CONFIG_TOSHIBA_BOARDS=y CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_PCI_AUTO=y -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y -CONFIG_SWAP_IO_SPACE=y +CONFIG_NONCOHERENT_IO=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y CONFIG_PC_KEYB=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set - -# -# Loadable module support -# -# CONFIG_MODULES is not set +# CONFIG_MIPS_AU1000 is not set # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set CONFIG_CPU_TX39XX=y -# CONFIG_CPU_R6000 is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set # CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y # # General setup # # CONFIG_CPU_LITTLE_ENDIAN is not set CONFIG_RTC_DS1742=y -CONFIG_KCORE_ELF=y -CONFIG_ELF_KERNEL=y # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set CONFIG_NET=y # CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set # CONFIG_HOTPLUG_PCI is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set # # Memory Technology Devices (MTD) @@ -115,6 +143,12 @@ # CONFIG_PARPORT is not set # +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# # Block devices # # CONFIG_BLK_DEV_FD is not set @@ -122,11 +156,14 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_CISS_SCSI_TAPE is not set # CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set # # Multi-device support (RAID and LVM) @@ -171,6 +208,11 @@ # # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -188,6 +230,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Telephony Support # # CONFIG_PHONE is not set @@ -248,15 +295,18 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set -CONFIG_TC35815=y # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -268,11 +318,13 @@ # CONFIG_8139TOO_PIO is not set # CONFIG_8139TOO_TUNE_TWISTER is not set # CONFIG_8139TOO_8129 is not set -# CONFIG_8139_NEW_RX_RESET is not set +# CONFIG_8139_OLD_RX_RESET is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set +CONFIG_TC35815=y # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -284,11 +336,14 @@ # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set +# CONFIG_E1000 is not set # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set @@ -329,9 +384,13 @@ # CONFIG_ISDN is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input core support # -# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set # # Character devices @@ -350,6 +409,7 @@ # CONFIG_MOXA_INTELLIO is not set # CONFIG_MOXA_SMARTIO is not set # CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set # CONFIG_N_HDLC is not set # CONFIG_RISCOM8 is not set # CONFIG_SPECIALIX is not set @@ -358,7 +418,8 @@ # CONFIG_STALDRV is not set # CONFIG_SERIAL_TX3912 is not set # CONFIG_SERIAL_TX3912_CONSOLE is not set -# CONFIG_AU1000_UART is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set CONFIG_TXX927_SERIAL=y CONFIG_TXX927_SERIAL_CONSOLE=y # CONFIG_UNIX98_PTYS is not set @@ -387,14 +448,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -407,14 +475,10 @@ # CONFIG_DRM is not set # -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -424,6 +488,9 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set @@ -437,10 +504,13 @@ # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set +CONFIG_RAMFS=y # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -468,9 +538,11 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set @@ -484,7 +556,6 @@ # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set # CONFIG_ZISOFS_FS is not set -# CONFIG_ZLIB_FS_INFLATE is not set # # Partition Types @@ -495,6 +566,11 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Console drivers # # CONFIG_VGA_CONSOLE is not set @@ -508,15 +584,19 @@ # CONFIG_FB_RIVA is not set # CONFIG_FB_CLGEN is not set # CONFIG_FB_PM2 is not set +# CONFIG_FB_PM3 is not set # CONFIG_FB_CYBER2000 is not set # CONFIG_FB_MATROX is not set # CONFIG_FB_ATY is not set # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set # CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set +# CONFIG_FB_E1356 is not set # CONFIG_FB_VIRTUAL is not set CONFIG_FBCON_ADVANCED=y CONFIG_FBCON_MFB=y @@ -551,121 +631,28 @@ # CONFIG_USB is not set # -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set - -# -# USB Device Class drivers +# Bluetooth support # -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set +# CONFIG_BLUEZ is not set # -# SCSI support is needed for USB Storage -# -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices -# - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# -# USB Network adaptors -# -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OMNINET is not set - -# -# USB Miscellaneous drivers +# Kernel hacking # -# CONFIG_USB_RIO500 is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +# CONFIG_CRYPTO is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_DEBUG is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-lasat linux-2.4.21-bk38/arch/mips/defconfig-lasat --- linux-2.4.21-bk37/arch/mips/defconfig-lasat 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-lasat 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,742 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +CONFIG_LASAT=y +CONFIG_PICVUE=y +CONFIG_PICVUE_PROC=y +CONFIG_DS1603=y +CONFIG_LASAT_SYSCTL=y +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_BOARD_SCACHE=y +CONFIG_R5000_CPU_SCACHE=y +CONFIG_PCI=y +CONFIG_MIPS_GT64120=y +CONFIG_MIPS_NILE4=y +CONFIG_NONCOHERENT_IO=y +CONFIG_NEW_TIME_C=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +CONFIG_CPU_R5000=y +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_64BIT_PHYS_ADDR is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +# CONFIG_MTD_BLOCK is not set +CONFIG_MTD_BLOCK_RO=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +# CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_CSTM_MIPS_IXX is not set +# CONFIG_MTD_OCELOT is not set +CONFIG_MTD_LASAT=y +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# 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_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# 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_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# 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_IDEPCI=y +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_BLK_DEV_ADMA100 is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_AMD74XX_OVERRIDE is not set +CONFIG_BLK_DEV_CMD64X=y +# CONFIG_BLK_DEV_TRIFLEX is not set +# 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_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_PDC202XX_BURST is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_CHIPSETS is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM 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_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=y +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX 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_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set +# CONFIG_TLAN is not set +# CONFIG_TC35815 is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_LAN_SAA9730 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO 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_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_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 +# CONFIG_DEVFS_MOUNT is not set +# 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_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_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_ROOT_NFS is not set +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-malta linux-2.4.21-bk38/arch/mips/defconfig-malta --- linux-2.4.21-bk37/arch/mips/defconfig-malta 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-malta 2003-08-24 02:55:57.000000000 -0700 @@ -13,23 +13,34 @@ # # Loadable module support # -# CONFIG_MODULES is not set +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y # # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,10 +58,13 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -57,11 +72,14 @@ CONFIG_BOOT_ELF32=y CONFIG_HAVE_STD_PC_SERIAL_PORT=y CONFIG_I8259=y +CONFIG_MIPS_BONITO64=y +CONFIG_MIPS_GT64120=y +CONFIG_MIPS_MSC=y CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y -CONFIG_SWAP_IO_SPACE=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y CONFIG_PC_KEYB=y CONFIG_PCI=y # CONFIG_MIPS_AU1000 is not set @@ -116,9 +134,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -178,8 +197,8 @@ # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set @@ -270,6 +289,7 @@ # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -306,6 +326,7 @@ # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # @@ -350,14 +371,17 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y CONFIG_PCNET32=y +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -374,6 +398,7 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set # CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set @@ -392,6 +417,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -477,13 +503,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set CONFIG_RTC=y +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -499,6 +533,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -508,6 +543,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -556,13 +592,15 @@ # CONFIG_CODA_FS is not set # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set +CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y -# CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y # CONFIG_NFSD_TCP is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set # CONFIG_NCPFS_PACKET_SIGNING is not set @@ -607,14 +645,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-mirage linux-2.4.21-bk38/arch/mips/defconfig-mirage --- linux-2.4.21-bk37/arch/mips/defconfig-mirage 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-mirage 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,769 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +CONFIG_MIPS_MIRAGE=y +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1500=y +CONFIG_PC_KEYB=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +# CONFIG_PCMCIA is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +# CONFIG_HOTPLUG_PCI_ACPI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# 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_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# 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_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM 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_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO 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_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_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 is not set +# CONFIG_DEVFS_MOUNT is not set +# 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_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_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_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_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_AU1X00=y +# 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_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21-bk37/arch/mips/defconfig-mpc30x linux-2.4.21-bk38/arch/mips/defconfig-mpc30x --- linux-2.4.21-bk37/arch/mips/defconfig-mpc30x 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-mpc30x 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,684 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +CONFIG_VICTOR_MPC30X=y +CONFIG_VRC4173=y +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_IRQ_CPU=y +CONFIG_NEW_TIME_C=y +CONFIG_VR41XX_TIME_C=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_ISA is not set +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_DUMMY_KEYB=y +# CONFIG_SCSI is not set +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +CONFIG_CPU_VR41XX=y +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_ADVANCED is not set +# CONFIG_CPU_HAS_LLSC is not set +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# 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_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# 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_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM 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_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO 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_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_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 is not set +# CONFIG_DEVFS_MOUNT is not set +# 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_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_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_BANDWIDTH=y + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +# CONFIG_USB_HID is not set + +# +# Input core support is needed for USB HID input layer or HIDBP support +# +# CONFIG_USB_HIDINPUT is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +CONFIG_USB_PEGASUS=y +CONFIG_USB_RTL8150=y +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-mtx-1 linux-2.4.21-bk38/arch/mips/defconfig-mtx-1 --- linux-2.4.21-bk37/arch/mips/defconfig-mtx-1 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-mtx-1 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,663 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +CONFIG_MIPS_MTX1=y +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1500=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +CONFIG_PCI_NAMES=y +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +CONFIG_MTD_MTX1=y +# CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_CSTM_MIPS_IXX is not set +# CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# 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_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# 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_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM 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_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO 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_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_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 +CONFIG_DEVFS_MOUNT=y +# 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_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_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21-bk37/arch/mips/defconfig-nino linux-2.4.21-bk38/arch/mips/defconfig-nino --- linux-2.4.21-bk37/arch/mips/defconfig-nino 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/defconfig-nino 2003-08-24 02:55:57.000000000 -0700 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,95 +11,123 @@ CONFIG_EXPERIMENTAL=y # +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# # Machine selection # # CONFIG_ACER_PICA_61 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set -# CONFIG_DDB5074 is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -CONFIG_NINO=y -# CONFIG_NINO_4MB is not set -CONFIG_NINO_8MB=y -# CONFIG_NINO_16MB is not set -# CONFIG_SIBYTE_SB1250 is not set # CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set # CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set +CONFIG_NINO=y +# CONFIG_NINO_4MB is not set +CONFIG_NINO_8MB=y +# CONFIG_NINO_16MB is not set # CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1500 is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_HP_LASERJET is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y CONFIG_PC_KEYB=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set -CONFIG_KMOD=y +# CONFIG_MIPS_AU1000 is not set # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set CONFIG_CPU_R3000=y # CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_R6000 is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set # CONFIG_CPU_HAS_WB is not set +# CONFIG_CPU_HAS_SYNC is not set # # General setup # CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_KCORE_ELF=y -CONFIG_ELF_KERNEL=y -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set CONFIG_NET=y +# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set # CONFIG_HOTPLUG_PCI is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_SYSCTL is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set # # Memory Technology Devices (MTD) @@ -111,6 +140,12 @@ # CONFIG_PARPORT is not set # +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# # Block devices # # CONFIG_BLK_DEV_FD is not set @@ -118,12 +153,15 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_CISS_SCSI_TAPE is not set # CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=512 CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_STATS is not set # # MIPS initrd options @@ -170,6 +208,11 @@ # # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -187,6 +230,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Telephony Support # # CONFIG_PHONE is not set @@ -206,15 +254,6 @@ # CONFIG_SCSI is not set # -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# # Network device support # # CONFIG_NETDEVICES is not set @@ -235,9 +274,13 @@ # CONFIG_ISDN is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input core support # -# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set # # Character devices @@ -257,6 +300,7 @@ # CONFIG_MOXA_SMARTIO is not set # CONFIG_ISI is not set # CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set # CONFIG_N_HDLC is not set # CONFIG_RISCOM8 is not set # CONFIG_SPECIALIX is not set @@ -265,7 +309,8 @@ # CONFIG_STALDRV is not set CONFIG_SERIAL_TX3912=y CONFIG_SERIAL_TX3912_CONSOLE=y -# CONFIG_AU1000_UART is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set # CONFIG_TXX927_SERIAL is not set # CONFIG_UNIX98_PTYS is not set @@ -293,14 +338,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -313,14 +365,10 @@ # CONFIG_DRM is not set # -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -330,6 +378,9 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set @@ -343,10 +394,13 @@ # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set +CONFIG_RAMFS=y # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -374,9 +428,11 @@ # CONFIG_INTERMEZZO_FS is not set # CONFIG_NFS_FS is not set # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set # CONFIG_ROOT_NFS is not set # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set # CONFIG_SUNRPC is not set # CONFIG_LOCKD is not set # CONFIG_SMB_FS is not set @@ -390,7 +446,6 @@ # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set # CONFIG_ZISOFS_FS is not set -# CONFIG_ZLIB_FS_INFLATE is not set # # Partition Types @@ -401,6 +456,11 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Console drivers # # CONFIG_VGA_CONSOLE is not set @@ -412,14 +472,6 @@ CONFIG_FB=y CONFIG_DUMMY_CONSOLE=y # CONFIG_FB_CYBER2000 is not set -# CONFIG_FB_MATROX is not set -# CONFIG_FB_ATY is not set -# CONFIG_FB_RADEON is not set -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_SIS is not set -# CONFIG_FB_3DFX is not set -# CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_TRIDENT is not set CONFIG_FB_TX3912=y # CONFIG_FB_VIRTUAL is not set CONFIG_FBCON_ADVANCED=y @@ -455,121 +507,28 @@ # CONFIG_USB is not set # -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set - -# -# SCSI support is needed for USB Storage -# -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID +# Bluetooth support # +# CONFIG_BLUEZ is not set # -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices -# - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# -# USB Network adaptors -# -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OMNINET is not set - -# -# USB Miscellaneous drivers +# Kernel hacking # -# CONFIG_USB_RIO500 is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +# CONFIG_CRYPTO is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_DEBUG is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-ocelot linux-2.4.21-bk38/arch/mips/defconfig-ocelot --- linux-2.4.21-bk37/arch/mips/defconfig-ocelot 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/defconfig-ocelot 2003-08-24 02:55:57.000000000 -0700 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,102 +11,205 @@ CONFIG_EXPERIMENTAL=y # +# Loadable module support +# +# CONFIG_MODULES is not set + +# # Machine selection # # CONFIG_ACER_PICA_61 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set -# CONFIG_DDB5074 is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_NINO is not set -# CONFIG_SIBYTE_SB1250 is not set # CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set CONFIG_MOMENCO_OCELOT=y +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set # CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1500 is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_HP_LASERJET is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set +CONFIG_BOARD_SCACHE=y CONFIG_PCI=y CONFIG_SYSCLK_100=y -CONFIG_SWAP_IO_SPACE=y -CONFIG_NEW_IRQ=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y CONFIG_NONCOHERENT_IO=y CONFIG_OLD_TIME_C=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set - -# -# Loadable module support -# -# CONFIG_MODULES is not set +# CONFIG_MIPS_AU1000 is not set # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set # CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_R6000 is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set -CONFIG_CPU_RM7000=y +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +CONFIG_CPU_RM7000=y # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y # CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y # # General setup # # CONFIG_CPU_LITTLE_ENDIAN is not set -CONFIG_KCORE_ELF=y -CONFIG_ELF_KERNEL=y # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set CONFIG_NET=y CONFIG_PCI_NAMES=y +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set # CONFIG_HOTPLUG_PCI is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set # # Memory Technology Devices (MTD) # -# CONFIG_MTD is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_REDBOOT_PARTS=y +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +# CONFIG_MTD_BLOCK is not set +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +CONFIG_NFTL=y +CONFIG_NFTL_RW=y + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +# CONFIG_MTD_GEN_PROBE is not set +# CONFIG_MTD_CFI_INTELEXT is not set +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_RAM=y +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +CONFIG_MTD_OBSOLETE_CHIPS=y +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +CONFIG_MTD_JEDEC=y + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +# CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_CSTM_MIPS_IXX is not set +CONFIG_MTD_OCELOT=y +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +CONFIG_MTD_DOC2000=y +# CONFIG_MTD_DOC2001 is not set +CONFIG_MTD_DOCPROBE=y +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_DOCPROBE_HIGH is not set +# CONFIG_MTD_DOCPROBE_55AA is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set +CONFIG_MTD_NAND_IDS=y # # Parallel port support @@ -113,6 +217,12 @@ # CONFIG_PARPORT is not set # +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# # Block devices # # CONFIG_BLK_DEV_FD is not set @@ -120,11 +230,14 @@ # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_CISS_SCSI_TAPE is not set # CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set # # Multi-device support (RAID and LVM) @@ -168,6 +281,11 @@ # # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -185,6 +303,11 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# # Telephony Support # # CONFIG_PHONE is not set @@ -245,15 +368,18 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set -# CONFIG_TC35815 is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set CONFIG_EEPRO100=y +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -265,11 +391,13 @@ # CONFIG_8139TOO_PIO is not set # CONFIG_8139TOO_TUNE_TWISTER is not set # CONFIG_8139TOO_8129 is not set -# CONFIG_8139_NEW_RX_RESET is not set +# CONFIG_8139_OLD_RX_RESET is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set +# CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set @@ -281,11 +409,14 @@ # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set +# CONFIG_E1000 is not set # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set @@ -326,9 +457,13 @@ # CONFIG_ISDN is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input core support # -# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set # # Character devices @@ -365,12 +500,18 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_DTLK is not set @@ -385,14 +526,10 @@ # CONFIG_DRM is not set # -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -402,6 +539,9 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set @@ -415,10 +555,13 @@ # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set # CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set +CONFIG_RAMFS=y # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -446,9 +589,11 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set @@ -462,7 +607,6 @@ # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set # CONFIG_ZISOFS_FS is not set -# CONFIG_ZLIB_FS_INFLATE is not set # # Partition Types @@ -473,6 +617,11 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Sound # # CONFIG_SOUND is not set @@ -483,123 +632,28 @@ # CONFIG_USB is not set # -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set - -# -# SCSI support is needed for USB Storage -# -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices +# Bluetooth support # -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set +# CONFIG_BLUEZ is not set # -# USB Multimedia devices -# - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# -# USB Network adaptors -# -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OMNINET is not set - -# -# USB Miscellaneous drivers +# Kernel hacking # -# CONFIG_USB_RIO500 is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +# CONFIG_CRYPTO is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set -# CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-osprey linux-2.4.21-bk38/arch/mips/defconfig-osprey --- linux-2.4.21-bk37/arch/mips/defconfig-osprey 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/defconfig-osprey 2003-08-24 02:55:57.000000000 -0700 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -20,38 +21,55 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set # CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set CONFIG_NEC_OSPREY=y +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set -# CONFIG_SIBYTE_SB1250 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_VR4181=y -CONFIG_SERIAL=y -CONFIG_SERIAL_MANY_PORTS=y -CONFIG_NEW_IRQ=y CONFIG_IRQ_CPU=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y @@ -62,25 +80,27 @@ # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set # CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_R6000 is not set CONFIG_CPU_VR41XX=y # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_ADVANCED is not set # CONFIG_CPU_HAS_LLSC is not set # CONFIG_CPU_HAS_LLDSCD is not set # CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y # # General setup @@ -103,8 +123,11 @@ # CONFIG_KCORE_AOUT is not set # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -137,6 +160,7 @@ # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set # # Multi-device support (RAID and LVM) @@ -215,6 +239,13 @@ # CONFIG_PHONE_IXJ_PCMCIA is not set # +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# # SCSI support # # CONFIG_SCSI is not set @@ -256,10 +287,12 @@ # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set +# CONFIG_E1000 is not set # CONFIG_MYRI_SBUS is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -302,13 +335,27 @@ # CONFIG_ISDN is not set # +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# # Character devices # CONFIG_VT=y # CONFIG_VT_CONSOLE is not set CONFIG_SERIAL=y CONFIG_SERIAL_CONSOLE=y -# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_EXTENDED=y +CONFIG_SERIAL_MANY_PORTS=y +# CONFIG_SERIAL_SHARE_IRQ is not set +# CONFIG_SERIAL_DETECT_IRQ is not set +# CONFIG_SERIAL_MULTIPORT is not set +# CONFIG_HUB6 is not set # CONFIG_SERIAL_NONSTANDARD is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -337,13 +384,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -356,14 +411,10 @@ # CONFIG_DRM is not set # -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -373,6 +424,9 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set @@ -390,6 +444,9 @@ # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -417,9 +474,11 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set @@ -433,7 +492,6 @@ # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set # CONFIG_ZISOFS_FS is not set -# CONFIG_ZLIB_FS_INFLATE is not set # # Partition Types @@ -444,6 +502,11 @@ # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Console drivers # # CONFIG_VGA_CONSOLE is not set @@ -470,20 +533,23 @@ # CONFIG_BLUEZ is not set # -# Input core support -# -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set - -# # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-pb1000 linux-2.4.21-bk38/arch/mips/defconfig-pb1000 --- linux-2.4.21-bk37/arch/mips/defconfig-pb1000 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-pb1000 2003-08-24 02:55:57.000000000 -0700 @@ -21,18 +21,27 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set CONFIG_MIPS_PB1000=y CONFIG_PCI_AUTO=y # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -40,6 +49,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -49,22 +59,26 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_MIPS_AU1000=y -CONFIG_NEW_IRQ=y +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1000=y CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_NONCOHERENT_IO=y CONFIG_PC_KEYB=y -CONFIG_SWAP_IO_SPACE=y -CONFIG_AU1000_USB_DEVICE=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y +# CONFIG_MIPS_AU1000 is not set # # CPU selection @@ -88,10 +102,10 @@ CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set CONFIG_64BIT_PHYS_ADDR=y -CONFIG_CPU_ADVANCED=y +# CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y # CONFIG_CPU_HAS_LLDSCD is not set -CONFIG_CPU_HAS_WB=y +# CONFIG_CPU_HAS_WB is not set CONFIG_CPU_HAS_SYNC=y # @@ -115,8 +129,11 @@ # CONFIG_TCIC is not set # CONFIG_I82092 is not set # CONFIG_I82365 is not set -CONFIG_PCMCIA_AU1000=m +CONFIG_PCMCIA_AU1X00=m CONFIG_PCMCIA_PB1X00=y +# CONFIG_PCMCIA_DB1X00 is not set +# CONFIG_PCMCIA_XXS1500 is not set +# CONFIG_PCMCIA_VRC4173 is not set # # PCI Hotplug Support @@ -133,6 +150,8 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set @@ -145,6 +164,7 @@ CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_CONCAT is not set # CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set # # User Modules And Translation Layers @@ -163,6 +183,7 @@ # CONFIG_MTD_CFI_ADV_OPTIONS is not set # CONFIG_MTD_CFI_INTELEXT is not set CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set @@ -178,15 +199,20 @@ CONFIG_MTD_PB1000=y # CONFIG_MTD_PB1500 is not set # CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +# CONFIG_MTD_DB1X00 is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set # CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set # # Self-contained MTD device drivers # # CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_MS02NV is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_MTDRAM is not set # CONFIG_MTD_BLKMTD is not set @@ -326,15 +352,6 @@ CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set # CONFIG_IDEDISK_STROKE 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=m # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -348,15 +365,15 @@ # 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 is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set +CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -392,7 +409,8 @@ # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -CONFIG_MIPS_AU1000_ENET=y +CONFIG_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY is not set # CONFIG_SUNLANCE is not set # CONFIG_HAPPYMEAL is not set # CONFIG_SUNBMAC is not set @@ -417,6 +435,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -505,6 +524,7 @@ # CONFIG_USB_IRDA is not set # CONFIG_NSC_FIR is not set # CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_OLD is not set # CONFIG_TOSHIBA_FIR is not set CONFIG_AU1000_FIR=m # CONFIG_SMC_IRCC_FIR is not set @@ -519,11 +539,13 @@ # # Input core support # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +CONFIG_INPUT_EVDEV=y # # Character devices @@ -552,10 +574,12 @@ # CONFIG_STALDRV is not set # CONFIG_SERIAL_TX3912 is not set # CONFIG_SERIAL_TX3912_CONSOLE is not set -CONFIG_AU1000_UART=y -CONFIG_AU1000_SERIAL_CONSOLE=y -# CONFIG_AU1000_USB_TTY is not set -# CONFIG_AU1000_USB_RAW is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set # CONFIG_TXX927_SERIAL is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -575,20 +599,49 @@ # Joysticks # # CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set # -# Input core support is needed for gameports -# - -# -# Input core support is needed for joysticks +# Joysticks # +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_DTLK is not set @@ -607,13 +660,14 @@ # # CONFIG_PCMCIA_SERIAL_CS is not set # CONFIG_SYNCLINK_CS is not set -CONFIG_AU1000_GPIO=y -# CONFIG_TS_AU1000_ADS7846 is not set +CONFIG_AU1X00_GPIO=m +# CONFIG_TS_AU1X00_ADS7846 is not set # # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y # CONFIG_REISERFS_FS is not set @@ -623,6 +677,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -673,6 +728,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set @@ -724,6 +780,7 @@ # CONFIG_FB_ATY is not set # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set # CONFIG_FB_SIS is not set # CONFIG_FB_NEOMAGIC is not set # CONFIG_FB_3DFX is not set @@ -776,7 +833,7 @@ # CONFIG_SOUND_ICH is not set # CONFIG_SOUND_RME96XX is not set # CONFIG_SOUND_SONICVIBES is not set -CONFIG_SOUND_AU1000=y +CONFIG_SOUND_AU1X00=y # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set @@ -788,7 +845,104 @@ # # USB support # -# CONFIG_USB is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set # # Bluetooth support @@ -799,14 +953,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -urN linux-2.4.21-bk37/arch/mips/defconfig-pb1100 linux-2.4.21-bk38/arch/mips/defconfig-pb1100 --- linux-2.4.21-bk37/arch/mips/defconfig-pb1100 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-pb1100 2003-08-24 02:55:57.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set CONFIG_MIPS_PB1100=y # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,23 +58,27 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_MIPS_AU1000=y -CONFIG_NEW_IRQ=y +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1100=y CONFIG_PCI=y # CONFIG_PCI_AUTO is not set CONFIG_NEW_PCI=y CONFIG_NONCOHERENT_IO=y CONFIG_PC_KEYB=y -CONFIG_SWAP_IO_SPACE=y -CONFIG_AU1000_USB_DEVICE=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y +# CONFIG_MIPS_AU1000 is not set # # CPU selection @@ -88,10 +102,10 @@ CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set CONFIG_64BIT_PHYS_ADDR=y -CONFIG_CPU_ADVANCED=y +# CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y # CONFIG_CPU_HAS_LLDSCD is not set -CONFIG_CPU_HAS_WB=y +# CONFIG_CPU_HAS_WB is not set CONFIG_CPU_HAS_SYNC=y # @@ -105,26 +119,9 @@ # CONFIG_TC is not set # CONFIG_MCA is not set # CONFIG_SBUS is not set -CONFIG_HOTPLUG=y - -# -# PCMCIA/CardBus support -# -CONFIG_PCMCIA=m -# CONFIG_CARDBUS is not set -# CONFIG_TCIC is not set -# CONFIG_I82092 is not set -# CONFIG_I82365 is not set -CONFIG_PCMCIA_AU1000=m -CONFIG_PCMCIA_PB1X00=y - -# -# PCI Hotplug Support -# +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set # CONFIG_HOTPLUG_PCI is not set -# CONFIG_HOTPLUG_PCI_COMPAQ is not set -# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set -# CONFIG_HOTPLUG_PCI_ACPI is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y @@ -133,6 +130,8 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set @@ -145,6 +144,7 @@ CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_CONCAT is not set # CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set # # User Modules And Translation Layers @@ -163,6 +163,7 @@ # CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set @@ -177,16 +178,23 @@ # CONFIG_MTD_PHYSMAP is not set # CONFIG_MTD_PB1000 is not set # CONFIG_MTD_PB1500 is not set -# CONFIG_MTD_PB1100 is not set +CONFIG_MTD_PB1100=y +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set +CONFIG_MTD_PB1500_BOOT=y +CONFIG_MTD_PB1500_USER=y +# CONFIG_MTD_DB1X00 is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set # CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set # # Self-contained MTD device drivers # # CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_MS02NV is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_MTDRAM is not set # CONFIG_MTD_BLKMTD is not set @@ -252,7 +260,7 @@ # CONFIG_NETLINK_DEV is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set -# CONFIG_FILTER is not set +CONFIG_FILTER=y CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -338,16 +346,7 @@ CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set # CONFIG_IDEDISK_STROKE 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=m +# CONFIG_BLK_DEV_IDECS is not set # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -360,15 +359,15 @@ # 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 is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_IDE_MODES is not set +CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -404,7 +403,8 @@ # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -CONFIG_MIPS_AU1000_ENET=y +CONFIG_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY is not set # CONFIG_SUNLANCE is not set # CONFIG_HAPPYMEAL is not set # CONFIG_SUNBMAC is not set @@ -429,6 +429,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -463,22 +464,6 @@ # CONFIG_WAN is not set # -# PCMCIA network device support -# -CONFIG_NET_PCMCIA=y -CONFIG_PCMCIA_3C589=m -# CONFIG_PCMCIA_3C574 is not set -# CONFIG_PCMCIA_FMVJ18X is not set -# CONFIG_PCMCIA_PCNET is not set -# CONFIG_PCMCIA_AXNET is not set -# CONFIG_PCMCIA_NMCLAN is not set -# CONFIG_PCMCIA_SMC91C92 is not set -# CONFIG_PCMCIA_XIRC2PS is not set -# CONFIG_ARCNET_COM20020_CS is not set -# CONFIG_PCMCIA_IBMTR is not set -# CONFIG_NET_PCMCIA_RADIO is not set - -# # Amateur Radio support # # CONFIG_HAMRADIO is not set @@ -524,6 +509,7 @@ # CONFIG_USB_IRDA is not set # CONFIG_NSC_FIR is not set # CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_OLD is not set # CONFIG_TOSHIBA_FIR is not set CONFIG_AU1000_FIR=y # CONFIG_SMC_IRCC_FIR is not set @@ -538,11 +524,13 @@ # # Input core support # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +CONFIG_INPUT_EVDEV=y # # Character devices @@ -571,10 +559,12 @@ # CONFIG_STALDRV is not set # CONFIG_SERIAL_TX3912 is not set # CONFIG_SERIAL_TX3912_CONSOLE is not set -CONFIG_AU1000_UART=y -CONFIG_AU1000_SERIAL_CONSOLE=y -# CONFIG_AU1000_USB_TTY is not set -# CONFIG_AU1000_USB_RAW is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set # CONFIG_TXX927_SERIAL is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -594,20 +584,49 @@ # Joysticks # # CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set # -# Input core support is needed for gameports -# - -# -# Input core support is needed for joysticks +# Joysticks # +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set CONFIG_RTC=y # CONFIG_DTLK is not set @@ -620,19 +639,14 @@ # CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set - -# -# PCMCIA character devices -# -# CONFIG_PCMCIA_SERIAL_CS is not set -# CONFIG_SYNCLINK_CS is not set -# CONFIG_AU1000_GPIO is not set -# CONFIG_TS_AU1000_ADS7846 is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set # # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_REISERFS_FS=m @@ -642,6 +656,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -694,6 +709,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y CONFIG_NFSD=m # CONFIG_NFSD_V3 is not set @@ -788,13 +804,14 @@ # CONFIG_FB_ATY is not set # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set # CONFIG_FB_SIS is not set # CONFIG_FB_NEOMAGIC is not set # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set # CONFIG_FB_E1356 is not set -# CONFIG_FB_AU1100 is not set +CONFIG_FB_AU1100=y # CONFIG_FB_VIRTUAL is not set CONFIG_FBCON_ADVANCED=y # CONFIG_FBCON_MFB is not set @@ -838,7 +855,7 @@ # CONFIG_SOUND_ICH is not set # CONFIG_SOUND_RME96XX is not set # CONFIG_SOUND_SONICVIBES is not set -CONFIG_SOUND_AU1000=y +# CONFIG_SOUND_AU1X00 is not set # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set @@ -850,7 +867,104 @@ # # USB support # -# CONFIG_USB is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set # # Bluetooth support @@ -861,14 +975,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21-bk37/arch/mips/defconfig-pb1500 linux-2.4.21-bk38/arch/mips/defconfig-pb1500 --- linux-2.4.21-bk37/arch/mips/defconfig-pb1500 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-pb1500 2003-08-24 02:55:57.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set CONFIG_MIPS_PB1500=y -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,22 +58,25 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_MIPS_AU1000=y -CONFIG_NEW_IRQ=y +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1500=y CONFIG_PCI=y CONFIG_NEW_PCI=y CONFIG_PCI_AUTO=y CONFIG_NONCOHERENT_IO=y CONFIG_PC_KEYB=y -CONFIG_AU1000_USB_DEVICE=y +# CONFIG_MIPS_AU1000 is not set # # CPU selection @@ -86,11 +99,11 @@ # CONFIG_CPU_SB1 is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_VTAG_ICACHE is not set -# CONFIG_64BIT_PHYS_ADDR is not set -CONFIG_CPU_ADVANCED=y +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y # CONFIG_CPU_HAS_LLDSCD is not set -CONFIG_CPU_HAS_WB=y +# CONFIG_CPU_HAS_WB is not set CONFIG_CPU_HAS_SYNC=y # @@ -114,7 +127,11 @@ # CONFIG_TCIC is not set # CONFIG_I82092 is not set # CONFIG_I82365 is not set -# CONFIG_PCMCIA_AU1000 is not set +CONFIG_PCMCIA_AU1X00=m +CONFIG_PCMCIA_PB1X00=y +# CONFIG_PCMCIA_DB1X00 is not set +# CONFIG_PCMCIA_XXS1500 is not set +# CONFIG_PCMCIA_VRC4173 is not set # # PCI Hotplug Support @@ -131,6 +148,8 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set @@ -143,6 +162,7 @@ CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_CONCAT is not set # CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set # # User Modules And Translation Layers @@ -161,6 +181,7 @@ # CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set @@ -176,17 +197,22 @@ # CONFIG_MTD_PB1000 is not set CONFIG_MTD_PB1500=y # CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +# CONFIG_MTD_XXS1500 is not set +# CONFIG_MTD_MTX1 is not set CONFIG_MTD_PB1500_BOOT=y # CONFIG_MTD_PB1500_USER is not set +# CONFIG_MTD_DB1X00 is not set # CONFIG_MTD_CSTM_MIPS_IXX is not set # CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set # CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set # # Self-contained MTD device drivers # # CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_MS02NV is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_MTDRAM is not set # CONFIG_MTD_BLKMTD is not set @@ -338,15 +364,6 @@ CONFIG_BLK_DEV_IDEDISK=y CONFIG_IDEDISK_MULTI_MODE=y # CONFIG_IDEDISK_STROKE 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=m # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set @@ -360,8 +377,8 @@ # 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_BLK_DEV_GENERIC is not set # CONFIG_IDEPCI_SHARE_IRQ is not set CONFIG_BLK_DEV_IDEDMA_PCI=y CONFIG_BLK_DEV_OFFBOARD=y @@ -370,30 +387,29 @@ # CONFIG_IDEDMA_ONLYDISK is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_PCI_WIP is not set -# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set -# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set -CONFIG_BLK_DEV_ADMA=y +# CONFIG_BLK_DEV_ADMA100 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_AMD74XX is not set # CONFIG_AMD74XX_OVERRIDE is not set # CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_CMD680 is not set +# CONFIG_BLK_DEV_TRIFLEX is not set # 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=y # CONFIG_BLK_DEV_PIIX is not set -# CONFIG_PIIX_TUNING 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_BLK_DEV_PDC202XX_OLD is not set # CONFIG_PDC202XX_BURST is not set -# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set @@ -406,6 +422,7 @@ # CONFIG_BLK_DEV_ATARAID is not set # CONFIG_BLK_DEV_ATARAID_PDC is not set # CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -441,7 +458,8 @@ # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -CONFIG_MIPS_AU1000_ENET=y +CONFIG_MIPS_AU1X00_ENET=y +# CONFIG_BCM5222_DUAL_PHY is not set # CONFIG_SUNLANCE is not set # CONFIG_HAPPYMEAL is not set # CONFIG_SUNBMAC is not set @@ -455,14 +473,17 @@ # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_APRICOT is not set +# CONFIG_B44 is not set # CONFIG_CS89x0 is not set # CONFIG_TULIP is not set # CONFIG_DE4X5 is not set # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_LNE390 is not set # CONFIG_FEALNX is not set @@ -479,6 +500,7 @@ # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set # CONFIG_TC35815 is not set # CONFIG_VIA_RHINE is not set @@ -497,6 +519,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -599,10 +622,12 @@ # CONFIG_STALDRV is not set # CONFIG_SERIAL_TX3912 is not set # CONFIG_SERIAL_TX3912_CONSOLE is not set -CONFIG_AU1000_UART=y -CONFIG_AU1000_SERIAL_CONSOLE=y -# CONFIG_AU1000_USB_TTY is not set -# CONFIG_AU1000_USB_RAW is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set # CONFIG_TXX927_SERIAL is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -653,11 +678,18 @@ # CONFIG_INPUT_GAMECON is not set # CONFIG_INPUT_TURBOGRAFX is not set # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set CONFIG_RTC=y # CONFIG_DTLK is not set @@ -676,13 +708,14 @@ # # CONFIG_PCMCIA_SERIAL_CS is not set # CONFIG_SYNCLINK_CS is not set -# CONFIG_AU1000_GPIO is not set -# CONFIG_TS_AU1000_ADS7846 is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set # # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set CONFIG_AUTOFS_FS=m CONFIG_AUTOFS4_FS=m CONFIG_REISERFS_FS=m @@ -692,6 +725,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -744,6 +778,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set CONFIG_ROOT_NFS=y CONFIG_NFSD=m # CONFIG_NFSD_V3 is not set @@ -838,12 +873,15 @@ # CONFIG_FB_ATY is not set # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set # CONFIG_FB_SIS is not set # CONFIG_FB_NEOMAGIC is not set # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set -# CONFIG_FB_E1356 is not set +CONFIG_FB_E1356=y +CONFIG_PB1500_CRT=y +# CONFIG_PB1500_TFT is not set # CONFIG_FB_VIRTUAL is not set CONFIG_FBCON_ADVANCED=y # CONFIG_FBCON_MFB is not set @@ -887,7 +925,7 @@ # CONFIG_SOUND_ICH is not set # CONFIG_SOUND_RME96XX is not set # CONFIG_SOUND_SONICVIBES is not set -CONFIG_SOUND_AU1000=y +CONFIG_SOUND_AU1X00=y # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set @@ -907,7 +945,6 @@ # # CONFIG_USB_DEVICEFS is not set # CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_LONG_TIMEOUT is not set # # USB Host Controller Drivers @@ -945,10 +982,12 @@ # USB Human Interface Devices (HID) # CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT is not set +CONFIG_USB_HIDINPUT=y # CONFIG_USB_HIDDEV is not set # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set # # USB Imaging devices @@ -974,6 +1013,7 @@ # CONFIG_USB_RTL8150 is not set # CONFIG_USB_KAWETH is not set # CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set # CONFIG_USB_CDCETHER is not set # CONFIG_USB_USBNET is not set @@ -1005,14 +1045,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21-bk37/arch/mips/defconfig-rm200 linux-2.4.21-bk38/arch/mips/defconfig-rm200 --- linux-2.4.21-bk37/arch/mips/defconfig-rm200 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/defconfig-rm200 2003-08-24 02:55:57.000000000 -0700 @@ -3,6 +3,7 @@ # CONFIG_MIPS=y CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -20,38 +21,59 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set # CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set # CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set -# CONFIG_SIBYTE_SB1250 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set CONFIG_SNI_RM200_PCI=y +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_ARC32=y +CONFIG_ARC_MEMORY=y +CONFIG_ARC_PROMLIB=y CONFIG_I8259=y CONFIG_ISA=y -CONFIG_NEW_IRQ=y CONFIG_NONCOHERENT_IO=y CONFIG_OLD_TIME_C=y CONFIG_PC_KEYB=y @@ -61,26 +83,28 @@ # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set # CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_R6000 is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set CONFIG_CPU_R4X00=y # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y # CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y # # General setup @@ -103,8 +127,11 @@ # CONFIG_KCORE_AOUT is not set # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -137,6 +164,7 @@ # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set # # Multi-device support (RAID and LVM) @@ -259,6 +287,15 @@ # CONFIG_CD_NO_IDESCSI is not set # +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# # Character devices # CONFIG_VT=y @@ -293,11 +330,18 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set CONFIG_RTC=y # CONFIG_DTLK is not set @@ -312,14 +356,10 @@ # CONFIG_DRM is not set # -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -329,6 +369,9 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set @@ -346,6 +389,9 @@ # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -373,9 +419,11 @@ # CONFIG_INTERMEZZO_FS is not set # CONFIG_NFS_FS is not set # CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set # CONFIG_ROOT_NFS is not set # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set # CONFIG_SUNRPC is not set # CONFIG_LOCKD is not set # CONFIG_SMB_FS is not set @@ -389,7 +437,6 @@ # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set # CONFIG_ZISOFS_FS is not set -# CONFIG_ZLIB_FS_INFLATE is not set # # Partition Types @@ -409,10 +456,16 @@ CONFIG_SGI_PARTITION=y # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set # CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# # Console drivers # CONFIG_VGA_CONSOLE=y @@ -439,18 +492,23 @@ # CONFIG_BLUEZ is not set # -# Input core support -# -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set - -# # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-sb1250-swarm linux-2.4.21-bk38/arch/mips/defconfig-sb1250-swarm --- linux-2.4.21-bk37/arch/mips/defconfig-sb1250-swarm 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-sb1250-swarm 2003-08-24 02:55:57.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,27 +58,44 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set CONFIG_SIBYTE_SB1xxx_SOC=y +CONFIG_SIBYTE_SWARM=y +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_UNKNOWN is not set +CONFIG_SIBYTE_BOARD=y CONFIG_SIBYTE_SB1250=y -# CONFIG_SIMULATION is not set +CONFIG_CPU_SB1_PASS_1=y +# CONFIG_CPU_SB1_PASS_2 is not set +# CONFIG_CPU_SB1_PASS_2_2 is not set +# CONFIG_CPU_SB1_PASS_4 is not set CONFIG_SIBYTE_CFE=y # CONFIG_SIBYTE_CFE_CONSOLE is not set +# CONFIG_SIBYTE_BUS_WATCHER is not set # CONFIG_SIBYTE_SB1250_PROF is not set -# CONFIG_BCM1250_TBPROF is not set -CONFIG_SMP=y +# CONFIG_SIBYTE_TBPROF is not set # CONFIG_PCI is not set -CONFIG_SIBYTE_SWARM=y +CONFIG_SIBYTE_GENBUS_IDE=y +CONFIG_SMP_CAPABLE=y # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_DUMMY_KEYB=y -CONFIG_SWAP_IO_SPACE=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y CONFIG_BOOT_ELF32=y # CONFIG_MIPS_AU1000 is not set @@ -91,14 +118,10 @@ # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set CONFIG_CPU_SB1=y -CONFIG_CPU_SB1_PASS_1=y -# CONFIG_CPU_SB1_PASS_2 is not set -# CONFIG_CPU_SB1_PASS_2_2 is not set +CONFIG_SMP=y +# CONFIG_SIBYTE_DMA_PAGEOPS is not set CONFIG_SB1_PASS_1_WORKAROUNDS=y CONFIG_CPU_HAS_PREFETCH=y -CONFIG_SB1_CACHE_ERROR=y -CONFIG_SB1_CERR_IGNORE_RECOVERABLE=y -# CONFIG_SB1_CERR_SPIN is not set CONFIG_VTAG_ICACHE=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set @@ -112,7 +135,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set CONFIG_NET=y # CONFIG_PCI is not set # CONFIG_ISA is not set @@ -131,9 +153,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -183,8 +206,9 @@ # # Networking options # -# CONFIG_PACKET is not set -# CONFIG_NETLINK_DEV is not set +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y # CONFIG_NETFILTER is not set # CONFIG_FILTER is not set CONFIG_UNIX=y @@ -243,9 +267,43 @@ # # ATA/IDE/MFM/RLL support # -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set # CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# 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_IDE_SIBYTE=y +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set # # SCSI support @@ -294,6 +352,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -370,12 +429,12 @@ # CONFIG_STALDRV is not set # CONFIG_SERIAL_TX3912 is not set # CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set # CONFIG_TXX927_SERIAL is not set CONFIG_SIBYTE_SB1250_DUART=y CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y CONFIG_SERIAL_CONSOLE=y -CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE=1024 -# CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1 is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -403,13 +462,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -425,6 +492,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -434,6 +502,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -483,6 +552,7 @@ # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set # CONFIG_ROOT_NFS is not set # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set @@ -534,11 +604,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_SB1XXX_CORELIS is not set # CONFIG_MAGIC_SYSRQ is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-sead linux-2.4.21-bk38/arch/mips/defconfig-sead --- linux-2.4.21-bk37/arch/mips/defconfig-sead 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-sead 2003-08-24 02:55:57.000000000 -0700 @@ -19,17 +19,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +46,7 @@ CONFIG_MIPS_SEAD=y # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,16 +56,19 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_BOOT_ELF32=y CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y # CONFIG_PCI is not set @@ -111,9 +124,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set # CONFIG_BINFMT_ELF32 is not set # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -152,7 +166,7 @@ # # MIPS initrd options # -CONFIG_EMBEDDED_RAMDISK=y +# CONFIG_EMBEDDED_RAMDISK is not set # # Multi-device support (RAID and LVM) @@ -233,13 +247,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -255,6 +277,7 @@ # File systems # # CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set @@ -264,6 +287,7 @@ # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set @@ -350,14 +374,20 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set # +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# # Library routines # +# CONFIG_CRC32 is not set # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-tb0226 linux-2.4.21-bk38/arch/mips/defconfig-tb0226 --- linux-2.4.21-bk37/arch/mips/defconfig-tb0226 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-tb0226 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,807 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +CONFIG_TANBAC_TB0226=y +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_IRQ_CPU=y +CONFIG_NEW_TIME_C=y +CONFIG_VR41XX_TIME_C=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_ISA is not set +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_DUMMY_KEYB=y +CONFIG_SERIAL_MANY_PORTS=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +CONFIG_CPU_VR41XX=y +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_ADVANCED is not set +# CONFIG_CPU_HAS_LLSC is not set +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# 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_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# 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_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_SD_EXTRA_DEVS=40 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_SR_EXTRA_DEVS=2 +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_NCR53C8XX is not set +# CONFIG_SCSI_SYM53C8XX is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM 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_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX 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_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set +# CONFIG_TLAN is not set +# CONFIG_TC35815 is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_LAN_SAA9730 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_INDYDOG is not set +# CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO 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_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_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 is not set +# CONFIG_DEVFS_MOUNT is not set +# 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_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_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_BANDWIDTH=y + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +# CONFIG_USB_HID is not set + +# +# Input core support is needed for USB HID input layer or HIDBP support +# +# CONFIG_USB_HIDINPUT is not set +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-tb0229 linux-2.4.21-bk38/arch/mips/defconfig-tb0229 --- linux-2.4.21-bk37/arch/mips/defconfig-tb0229 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-tb0229 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,647 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +CONFIG_TANBAC_TB0229=y +CONFIG_TANBAC_TB0219=y +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_IRQ_CPU=y +CONFIG_NEW_TIME_C=y +CONFIG_VR41XX_TIME_C=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_ISA is not set +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_DUMMY_KEYB=y +CONFIG_SERIAL_MANY_PORTS=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +CONFIG_CPU_VR41XX=y +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_ADVANCED is not set +# CONFIG_CPU_HAS_LLSC is not set +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# 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_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# 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_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +CONFIG_NET_VENDOR_3COM=y +# CONFIG_EL1 is not set +# CONFIG_EL2 is not set +# CONFIG_ELPLUS is not set +# CONFIG_EL16 is not set +# CONFIG_ELMC is not set +# CONFIG_ELMC_II is not set +CONFIG_VORTEX=y +# CONFIG_TYPHOON is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX 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_8139CP=y +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set +# CONFIG_TLAN is not set +# CONFIG_TC35815 is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_LAN_SAA9730 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_INDYDOG is not set +# CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO 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_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_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 is not set +# CONFIG_DEVFS_MOUNT is not set +# 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_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_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-ti1500 linux-2.4.21-bk38/arch/mips/defconfig-ti1500 --- linux-2.4.21-bk37/arch/mips/defconfig-ti1500 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-ti1500 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,989 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +CONFIG_MIPS_XXS1500=y +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1500=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_NONCOHERENT_IO=y +CONFIG_PC_KEYB=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +CONFIG_PCI_NAMES=y +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_CARDBUS is not set +# CONFIG_TCIC is not set +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +CONFIG_PCMCIA_AU1X00=m +# CONFIG_PCMCIA_PB1X00 is not set +# CONFIG_PCMCIA_DB1X00 is not set +CONFIG_PCMCIA_XXS1500=y +# CONFIG_PCMCIA_VRC4173 is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +# CONFIG_HOTPLUG_PCI_ACPI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +CONFIG_MTD_XXS1500=y +# CONFIG_MTD_MTX1 is not set +# CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_CSTM_MIPS_IXX is not set +# CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# 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_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# 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_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +# CONFIG_IDEDISK_STROKE is not set +CONFIG_BLK_DEV_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# 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_IDEPCI is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MIPS_AU1X00_ENET=y +CONFIG_BCM5222_DUAL_PHY=y +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM 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_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +# CONFIG_PCMCIA_PCNET is not set +# CONFIG_PCMCIA_AXNET is not set +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_ARCNET_COM20020_CS is not set +# CONFIG_PCMCIA_IBMTR is not set +# CONFIG_NET_PCMCIA_RADIO is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +CONFIG_I2C=m +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_PROC=m + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_PCMCIA_SERIAL_CS is not set +# CONFIG_SYNCLINK_CS is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO 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_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=m +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_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 is not set +# CONFIG_DEVFS_MOUNT is not set +# 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_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_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +CONFIG_NFSD=m +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_SMB_NLS=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_RIVA is not set +# CONFIG_FB_CLGEN is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_INTEL is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_E1356 is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FBCON_ADVANCED=y +# CONFIG_FBCON_MFB is not set +# CONFIG_FBCON_CFB2 is not set +# CONFIG_FBCON_CFB4 is not set +CONFIG_FBCON_CFB8=y +CONFIG_FBCON_CFB16=y +CONFIG_FBCON_CFB24=y +# CONFIG_FBCON_CFB32 is not set +# CONFIG_FBCON_AFB is not set +# CONFIG_FBCON_ILBM is not set +# CONFIG_FBCON_IPLAN2P2 is not set +# CONFIG_FBCON_IPLAN2P4 is not set +# CONFIG_FBCON_IPLAN2P8 is not set +# CONFIG_FBCON_MAC is not set +# CONFIG_FBCON_VGA_PLANES is not set +# CONFIG_FBCON_VGA is not set +# CONFIG_FBCON_HGA is not set +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +# CONFIG_FBCON_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_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_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_AU1X00=y +# 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_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_MIDI is not set + +# +# SCSI support is needed for USB Storage +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +CONFIG_USB_HIDDEV=y +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_AX8817X is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_TIGL is not set +# CONFIG_USB_BRLVGER is not set +# CONFIG_USB_LCD is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21-bk37/arch/mips/defconfig-workpad linux-2.4.21-bk38/arch/mips/defconfig-workpad --- linux-2.4.21-bk37/arch/mips/defconfig-workpad 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-workpad 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,629 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +CONFIG_IBM_WORKPAD=y +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_IRQ_CPU=y +CONFIG_NEW_TIME_C=y +CONFIG_VR41XX_TIME_C=y +CONFIG_NONCOHERENT_IO=y +CONFIG_ISA=y +CONFIG_DUMMY_KEYB=y +# CONFIG_SCSI is not set +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +CONFIG_CPU_VR41XX=y +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_ADVANCED is not set +# CONFIG_CPU_HAS_LLSC is not set +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI is not set +CONFIG_EISA=y +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# 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_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# 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_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# 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_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM 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 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +CONFIG_SERIAL_EXTENDED=y +CONFIG_SERIAL_MANY_PORTS=y +# CONFIG_SERIAL_SHARE_IRQ is not set +# CONFIG_SERIAL_DETECT_IRQ is not set +# CONFIG_SERIAL_MULTIPORT is not set +# CONFIG_HUB6 is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_INDYDOG is not set +# CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO 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_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_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 is not set +# CONFIG_DEVFS_MOUNT is not set +# 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_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_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_ROOT_NFS is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips/defconfig-xxs1500 linux-2.4.21-bk38/arch/mips/defconfig-xxs1500 --- linux-2.4.21-bk37/arch/mips/defconfig-xxs1500 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/defconfig-xxs1500 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,897 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +CONFIG_MIPS_XXS1500=y +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_SOC_AU1X00=y +CONFIG_SOC_AU1500=y +CONFIG_PCI=y +CONFIG_NEW_PCI=y +CONFIG_PCI_AUTO=y +CONFIG_NONCOHERENT_IO=y +CONFIG_PC_KEYB=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +CONFIG_PCI_NAMES=y +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_CARDBUS is not set +# CONFIG_TCIC is not set +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +CONFIG_PCMCIA_AU1X00=m +# CONFIG_PCMCIA_PB1X00 is not set +# CONFIG_PCMCIA_DB1X00 is not set +CONFIG_PCMCIA_XXS1500=y +# CONFIG_PCMCIA_VRC4173 is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +# CONFIG_HOTPLUG_PCI_ACPI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_BOSPORUS is not set +CONFIG_MTD_XXS1500=y +# CONFIG_MTD_MTX1 is not set +# CONFIG_MTD_DB1X00 is not set +# CONFIG_MTD_CSTM_MIPS_IXX is not set +# CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# 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_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# 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_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +# CONFIG_IDEDISK_STROKE is not set +CONFIG_BLK_DEV_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set + +# +# 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_IDEPCI=y +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_OFFBOARD=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_BLK_DEV_ADMA100 is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_AMD74XX_OVERRIDE is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# 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_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_PDC202XX_BURST is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_CHIPSETS is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_BLK_DEV_ATARAID_SII is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MIPS_AU1X00_ENET=y +CONFIG_BCM5222_DUAL_PHY=y +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM 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_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX 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_8139CP is not set +CONFIG_8139TOO=y +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set +# CONFIG_TLAN is not set +# CONFIG_TC35815 is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_LAN_SAA9730 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +# CONFIG_PCMCIA_PCNET is not set +# CONFIG_PCMCIA_AXNET is not set +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_ARCNET_COM20020_CS is not set +# CONFIG_PCMCIA_IBMTR is not set +# CONFIG_NET_PCMCIA_RADIO is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +CONFIG_AU1X00_UART=y +CONFIG_AU1X00_SERIAL_CONSOLE=y +# CONFIG_AU1X00_USB_TTY is not set +# CONFIG_AU1X00_USB_RAW is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_PCMCIA_SERIAL_CS is not set +# CONFIG_SYNCLINK_CS is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V2 is not set +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO 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_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=m +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_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 is not set +# CONFIG_DEVFS_MOUNT is not set +# 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_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_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_ROOT_NFS=y +CONFIG_NFSD=m +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_SMB_NLS=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_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_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_AU1X00=y +# 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_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/Makefile linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/Makefile --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,26 +0,0 @@ -# -# Copyright 2000 RidgeRun, Inc. -# Author: RidgeRun, Inc. -# glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com -# -# Makefile for the Galileo EV64120 board. -# -# Note! Dependencies are done automagically by 'make dep', which also -# 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 - -all: ev64120.o int-handler.o - -O_TARGET := ev64120.o - -export-objs = i2o.o - -obj-y := serialGT.o int-handler.o promcon.o reset.o setup.o irq.o \ - irq-handler.o i2o.o pci_bios.o - -int-handler.o: int-handler.S - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/cntmr.c linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/cntmr.c --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/cntmr.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/cntmr.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,207 +0,0 @@ -/* cntmr.c - GT counters/timers functions */ - -/* Copyright - Galileo technology. 9/3/2000 */ - -/* -DESCRIPTION -This file contains function which serves the user with a complete interface -to the GT internal counters and timers, please advise: each counter/timer unit -can function only as a counter or a timer at current time. -Counter/timer 0 is 32 bit wide. -Counters/timers 1-3 are 24 bit wide. -*/ - -/* includes */ - -#ifdef __linux__ -#include -#include -#else -#include "cntmr.h" -#include "core.h" -#endif - -/******************************************************************** -* cntTmrStart - Starts a counter/timer with given an initiate value. -* -* INPUTS: unsigned int countNum - Selects one of the 8 counters/timers. -* unsigned int countValue - Initial value for count down. -* CNT_TMR_OP_MODES opMode - Set Mode, Counter or Timer. -* -* RETURNS: false if one of the parameters is erroneous, true otherwise. -*********************************************************************/ - -bool cntTmrStart(CNTMR_NUM countNum, unsigned int countValue, - CNT_TMR_OP_MODES opMode) -{ - unsigned int command = 1; - unsigned int value; - - if (countNum > LAST_CNTMR) - return false; - else { - GT_REG_READ(TIMER_COUNTER_CONTROL, &value); - cntTmrDisable(countNum); - GT_REG_WRITE((TIMER_COUNTER0 + (4 * countNum)), - countValue); - command = command << countNum * 2; - value = value | command; - command = command << 1; - switch (opMode) { - case TIMER: /* The Timer/Counter bit set to logic '1' */ - value = value | command; - break; - case COUNTER: /* The Timer/Counter bit set to logic '0' */ - value = value & ~command; - break; - default: - return false; - } - GT_REG_WRITE(TIMER_COUNTER_CONTROL, value); - return true; - } -} - -/******************************************************************** -* cntTmrDisable - Disables the timer/counter operation and return its -* value. -* -* INPUTS: unsigned int countNum - Selects one of the 8 counters/timers. -* RETURNS: The counter/timer value (unsigned int), if any of the arguments are -* erroneous return 0. -*********************************************************************/ - -unsigned int cntTmrDisable(CNTMR_NUM countNum) -{ - unsigned int command = 1; - unsigned int regValue; - unsigned int value; - - GT_REG_READ(TIMER_COUNTER_CONTROL, &value); - if (countNum > LAST_CNTMR) - return 0; - GT_REG_READ(TIMER_COUNTER0 + 4 * countNum, ®Value); - command = command << countNum * 2; /* Disable the timer/counter */ - value = value & ~command; - GT_REG_WRITE(TIMER_COUNTER_CONTROL, value); - return regValue; -} - -/******************************************************************** -* cntTmrRead - Reads a timer or a counter value. (This operation can be -* perform while the counter/timer is active). -* -* RETURNS: The counter/timer value. If wrong input value, return 0. -*********************************************************************/ - -unsigned int cntTmrRead(CNTMR_NUM countNum) -{ - unsigned int value; - if (countNum > LAST_CNTMR) - return 0; - else - GT_REG_READ(TIMER_COUNTER0 + countNum * 4, &value); - return value; -} - -/******************************************************************** -* cntTmrEnable - Set enable-bit of timer/counter. -* Be aware: If the counter/timer is active, this function -* will terminate with an false. -* -* INPUTS: unsigned int countNum - Selects one of the 8 counters/timers. -* RETURNS: false if one of the parameters is erroneous, true otherwise. -*********************************************************************/ - -bool cntTmrEnable(CNTMR_NUM countNum) -{ - unsigned int command = 1; - unsigned int value; - GT_REG_READ(TIMER_COUNTER_CONTROL, &value); - if (countNum > LAST_CNTMR) - return false; - else { - command = command << countNum * 2; - if ((command & value) != 0) /* ==> The counter/timer is enabled */ - return false; /* doesn't make sense to Enable an "enabled" counter */ - value = value | command; - GT_REG_WRITE(TIMER_COUNTER_CONTROL, value); - return true; - } -} - -/******************************************************************** -* cntTmrLoad - loading value for timer number countNum. -* Be aware: If this function try to load value to an enabled -* counter/timer it terminate with false. -* -* INPUTS: unsigned int countNum - Selects one of the 8 counters/timers. -* unsigned int countValue - The value for load the register. -* RETURNS: false if one of the parameters is erroneous, true otherwise. -*********************************************************************/ - -bool cntTmrLoad(unsigned int countNum, unsigned int countValue) -{ - unsigned int command = 1; - unsigned int value; - GT_REG_READ(TIMER_COUNTER_CONTROL, &value); - if (countNum > LAST_CNTMR) - return false; - else { - command = command << countNum * 2; - value = value & command; - if (value != 0) { /* ==> The counter/timer is enabled */ - return false; /* can't reload value when counter/timer is enabled */ - } else { - GT_REG_WRITE((TIMER_COUNTER0 + (4 * countNum)), - countValue); - return true; - } - - } -} - -/******************************************************************** -* cntTmrSetMode - Configurate the Mode of the channel to work as a counter -* or as a timer. (for more details on the different between -* those two modes is written in the Data Sheet). -* NOTE: This function only set the counter/timer mode and -* don't enable it. -* Be aware: If this function try to load value to an enabled -* counter/timer it terminate with false. -* -* INPUTS: unsigned int countNum - Selects one of the 8 counters/timers. -* CNT_TMR_OP_MODES opMode - TIMER or COUNTER mode. -* RETURNS: false if one of the parameters is erroneous true otherwise . -*********************************************************************/ - -bool cntTmrSetMode(CNTMR_NUM countNum, CNT_TMR_OP_MODES opMode) -{ - unsigned int command = 1; - unsigned int value; - - GT_REG_READ(TIMER_COUNTER_CONTROL, &value); - if (countNum > LAST_CNTMR) - return false; - else { - command = command << countNum * 2; - value = value & command; - if (value != 0) { /* ==> The counter/timer is enabled */ - return false; /* can't set the Mode when counter/timer is enabled */ - } else { - command = command << 1; - switch (opMode) { - case TIMER: - value = value | command; /* The Timer/Counter bit set to logic '1' */ - break; - case COUNTER: - value = value & ~command; /*The Timer/Counter bit set to logic '0' */ - break; - default: - return false; - } - GT_REG_WRITE(TIMER_COUNTER_CONTROL, value); - return true; - } - } -} diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/dma.c linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/dma.c --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/dma.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/dma.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,168 +0,0 @@ -/* DMA.C - DMA functions and definitions */ - -/* Copyright Galileo Technology. */ - -/* -DESCRIPTION -This file gives the user a complete interface to the powerful DMA engines, -including functions for controling the priority mechanism. -To fully understand the capabilities of the DMA engines please spare some -time to go trough the spec. -*/ - -/* includes */ - -#ifdef __linux__ -#include -#include -#else -#include "Core.h" -#include "DMA.h" -#endif -/******************************************************************** -* dmaCommand - Write a command to a DMA channel -* -* Inputs: DMA_ENGINE channel - choosing one of the four engine. -* unsigned int command - The command to be written to the control register. -* Returns: false if one of the parameters is erroneous else returns true. -*********************************************************************/ - -bool dmaCommand(DMA_ENGINE channel, unsigned int command) -{ - if (channel > LAST_DMA_ENGINE) - return false; - GT_REG_WRITE(CHANNEL0CONTROL + channel * 4, command); - return true; -} - -/******************************************************************** -* dmaTransfer - transfer data from sourceAddr to destAddr on DMA channel -* Inputs: -* DMA_RECORED *nextRecoredPointer: If we are using chain mode DMA transfer, -* then this pointer should point to the next recored,otherwise it should be -* NULL. -* VERY IMPORTANT !!! When using chain mode, the records must be 16 Bytes -* aligned, the function will take care of that for you, but you need to -* allocate one more record for that, meaning: if you are having 3 records , -* declare 4 (see the example bellow) and start using the second one. -* Example: -* Performing a chain mode DMA transfer(Copy a 1/4 mega of data using -* chain mode DMA): -* DMA_RECORED dmaRecoredArray[4]; -* dmaRecoredArray[1].ByteCnt = _64KB; -* dmaRecoredArray[1].DestAdd = destAddress + _64KB; -* dmaRecoredArray[1].SrcAdd = sourceAddress + _64KB; -* dmaRecoredArray[1].NextRecPtr = &dmaRecoredArray[2]; -* dmaRecoredArray[2].ByteCnt = _64KB; -* dmaRecoredArray[2].DestAdd = destAddress + 2*_64KB; -* dmaRecoredArray[2].SrcAdd = sourceAddress + 2*_64KB; -* dmaRecoredArray[2].NextRecPtr = &dmaRecoredArray[3]; -* dmaRecoredArray[3].ByteCnt = _64KB; -* dmaRecoredArray[3].DestAdd = destAddress + 3*_64KB; -* dmaRecoredArray[3].SrcAdd = sourceAddress + 3*_64KB; -* dmaRecoredArray[3].NextRecPtr = NULL; -* performCmDma(0,sourceAddress,destAddress,_64KB,PLAIN,WAIT_TO_END, -* &dmaRecoredArray[1]); -* Returns: NO_SUCH_CHANNEL if channel does not exist, CHANNEL_BUSY if channel -* is active and true if the transfer ended successfully -*********************************************************************/ - -DMA_STATUS dmaTransfer(DMA_ENGINE channel, unsigned int sourceAddr, - unsigned int destAddr, unsigned int numOfBytes, - unsigned int command, - DMA_RECORED * nextRecoredPointer) -{ - unsigned int tempData, checkBits, alignmentOffset = 0; - DMA_RECORED *next = nextRecoredPointer; - - if (channel > LAST_DMA_ENGINE) - return NO_SUCH_CHANNEL; - if (numOfBytes > 0xffff) - return GENERAL_ERROR; - if (isDmaChannelActive(channel)) - return CHANNEL_BUSY; - if (next != NULL) { /* case of chain Mode */ - alignmentOffset = ((unsigned int) next % 16); - } - checkBits = command & 0x6000000; - if (checkBits == 0) { - while (next != NULL) { - WRITE_WORD((unsigned int) next - alignmentOffset, - next->ByteCnt); - tempData = (unsigned int) next->SrcAdd; - WRITE_WORD((unsigned int) next + 4 - - alignmentOffset, tempData & 0x5fffffff); - tempData = (unsigned int) next->DestAdd; - WRITE_WORD((unsigned int) next + 8 - - alignmentOffset, tempData & 0x5fffffff); - tempData = (unsigned int) next->NextRecPtr; - WRITE_WORD((unsigned int) next + 12 - - alignmentOffset, - tempData & 0x5fffffff - - alignmentOffset); - next = (DMA_RECORED *) tempData; - if (next == nextRecoredPointer) - next = NULL; - } - } - GT_REG_WRITE(CHANNEL0_DMA_BYTE_COUNT + channel * 4, numOfBytes); - tempData = sourceAddr; - GT_REG_WRITE(CHANNEL0_DMA_SOURCE_ADDRESS + channel * 4, - tempData & 0x5fffffff); - tempData = destAddr; - GT_REG_WRITE(CHANNEL0_DMA_DESTINATION_ADDRESS + channel * 4, - tempData & 0x5fffffff); - if (nextRecoredPointer != NULL) { - tempData = - (unsigned int) nextRecoredPointer - alignmentOffset; - GT_REG_WRITE(CHANNEL0NEXT_RECORD_POINTER + 4 * channel, - tempData & 0x5fffffff); - command = command | CHANNEL_ENABLE; - } else { - command = command | CHANNEL_ENABLE | NON_CHAIN_MOD; - } - /* Activate DMA engine By writting to dmaControlRegister */ - GT_REG_WRITE(CHANNEL0CONTROL + channel * 4, command); - - return DMA_OK; -} - -/******************************************************************** -* isDmaChannelActive - check if channel is busy -* -* Inputs: channel number -* RETURNS: True if the channel is busy, false otherwise. -*********************************************************************/ - -bool isDmaChannelActive(DMA_ENGINE channel) -{ - unsigned int data; - - if (channel > LAST_DMA_ENGINE) - return false; - GT_REG_READ(CHANNEL0CONTROL + 4 * channel, &data); - if (data & DMA_ACTIVITY_STATUS) - return true; - else - return false; -} - - -/******************************************************************** -* changeDmaPriority - update the arbiter`s priority for channels 0-3 -* -* Inputs: priority for channels 0-1, priority for channels 2-3, - priority for groups and other priority options -* RETURNS: false if one of the parameters is erroneous and true else -*********************************************************************/ - -bool changeDmaPriority(PRIO_CHAN_0_1 prio_01, PRIO_CHAN_2_3 prio_23, - PRIO_GROUP prioGrp, PRIO_OPT prioOpt) -{ - unsigned int prioReg = 0; - - prioReg = (prio_01 & 0x3) + ((prio_23 & 0x3) << 2) + - ((prioGrp & 0x3) << 4) + (prioOpt << 6); - GT_REG_WRITE(ARBITER_CONTROL, prioReg); - return true; -} diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/i2o.c linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/i2o.c --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/i2o.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/i2o.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,689 +0,0 @@ -/* i2o.c - Drivers for the I2O */ - -/* Copyright - Galileo technology. */ - -/*includes*/ - -#include - -#ifdef __linux__ -#include -#include -#else -#include "Core.h" -#include "i2o.h" -#endif - -/******************************************************************** -* getInBoundMessage - When the GT is configured for I2O support -* it can receive a message from an agent on the pci bus. -* This message is a 32 bit wide and can be read by -* the CPU. -* The messaging unit contains two sets of registers -* so, actually it can receive a 64 bit message. -* -* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. -* OUTPUT: N/A. -* RETURNS: Data received from the remote agent. -*********************************************************************/ -unsigned int getInBoundMessage(I2O_MESSAGE_REG messageRegNum) -{ - unsigned int regValue; - - GT_REG_READ(INBOUND_MESSAGE_REGISTER0_CPU_SIDE + 4 * messageRegNum, - ®Value); - return (regValue); -} - - -/******************************************************************** -* checkInboundIntAndClear - When a message is received an interrupt is -* generated, to enable polling instead the use of -* an interrupt handler the user can use this fuction. -* You will need to mask the incomming interrupt for -* proper use. -* -* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. -* OUTPUT: N/A. -* RETURNS: true if the corresponding bit in the cause register is set otherwise -* false. -*********************************************************************/ -bool checkInBoundIntAndClear(I2O_MESSAGE_REG messageRegNum) -{ - unsigned int regValue; - - GT_REG_READ(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, ®Value); - /* clears bit 0 for message register 0 or bit 1 for message register 1 */ - GT_REG_WRITE(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, - BIT1 * messageRegNum); - switch (messageRegNum) { - case MESSAGE_REG_0: - if (regValue & BIT0) - return true; - break; - case MESSAGE_REG_1: - if (regValue & BIT1) - return true; - break; - } - return false; -} - -/******************************************************************** -* sendOutBoundMessage - When the GT is configured for I2O support -* it can send a message to an agent on the pci bus. -* This message is a 32 bit wide and can be read by -* the PCI agent. -* The messaging unit contains two sets of registers -* so, actually it can send a 64 bit message. -* -* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. -* unsigned int message - Message to be sent. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool sendOutBoundMessage(I2O_MESSAGE_REG messageRegNum, - unsigned int message) -{ - GT_REG_WRITE(OUTBOUND_MESSAGE_REGISTER0_CPU_SIDE + - 4 * messageRegNum, message); - return true; -} - -/******************************************************************** -* checkOutboundInt - When the CPU sends a message to the Outbound -* register it generates an interrupt which is refelcted on -* the Outbound Interrupt cause register, the interrupt can -* be cleard only by the PCI agent which read the message. -* After sending the message you can acknowledge it by -* monitoring the corresponding bit in the cause register. -* -* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. -* OUTPUT: N/A. -* RETURNS: true if the corresponding bit in the cause register is set otherwise -* false. -*********************************************************************/ -bool outBoundMessageAcknowledge(I2O_MESSAGE_REG messageRegNum) -{ - unsigned int regValue; - - GT_REG_READ(OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, ®Value); - switch (messageRegNum) { - case MESSAGE_REG_0: - if (regValue & BIT0) - return true; - break; - case MESSAGE_REG_1: - if (regValue & BIT1) - return true; - break; - } - return false; -} - -/******************************************************************** -* maskInBoundMessageInterrupt - Mask the inbound interrupt, when masking -* the interrupt you can work in polling mode -* using the checkInboundIntAndClear function. -* -* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool maskInBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum) -{ - switch (messageRegNum) { - case MESSAGE_REG_0: - SET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - BIT0); - break; - case MESSAGE_REG_1: - SET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - BIT1); - break; - } - return true; -} - -/******************************************************************** -* enableInBoundMessageInterrupt - unMask the inbound interrupt. -* -* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool enableInBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum) -{ - switch (messageRegNum) { - case MESSAGE_REG_0: - RESET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - BIT0); - break; - case MESSAGE_REG_1: - RESET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - BIT1); - break; - } - return true; -} - -/******************************************************************** -* maskOutboundMessageInterrupt - Mask the out bound interrupt, when doing so -* the PCI agent needs to poll on the interrupt -* cause register to monitor an incoming message. -* -* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool maskOutBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum) -{ - switch (messageRegNum) { - case MESSAGE_REG_0: - SET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - BIT0); - break; - case MESSAGE_REG_1: - SET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - BIT1); - break; - } - return true; -} - -/******************************************************************** -* enableOutboundMessageInterrupt - Mask the out bound interrupt, when doing so -* the PCI agent needs to poll on the interrupt -* cause register to monitor an incoming message. -* -* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool enableOutBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum) -{ - switch (messageRegNum) { - case MESSAGE_REG_0: - RESET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - BIT0); - break; - case MESSAGE_REG_1: - RESET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - BIT1); - break; - } - return true; -} - -/******************************************************************** -* initiateOutBoundDoorBellInt - Setting a bit in this register to '1' by the -* CPU generates a PCI interrupt (if it is not masked by -* the Outbound interrupt Mask register) -* Only the PCI agent which recieved the interrupt can -* clear it, only after clearing all the bits the -* interrupt will be de-asserted. -* -* INPUTS: unsigned int data - Requested interrupt bits. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool initiateOutBoundDoorBellInt(unsigned int data) -{ - GT_REG_WRITE(OUTBOUND_DOORBELL_REGISTER_CPU_SIDE, data); - return true; -} - -/******************************************************************** -* readInBoundDoorBellInt - Read the in bound door bell interrupt cause -* register. -* -* OUTPUT: N/A. -* RETURNS: The 32 bit interrupt cause register. -*********************************************************************/ -unsigned int readInBoundDoorBellInt() -{ - unsigned int regData; - GT_REG_READ(INBOUND_DOORBELL_REGISTER_CPU_SIDE, ®Data); - return regData; -} - -/******************************************************************** -* clearInBoundDoorBellInt - An interrupt generated by a PCI agent through -* the in bound door bell mechanisem can be cleared -* only by the CPU. The interrupt will be de-asserted -* only if all the bits which where set by the PCI -* agent are cleared. -* -* INPUTS: unsigned int data - Bits to be cleared. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool clearInBoundDoorBellInt(unsigned int data) -{ - GT_REG_WRITE(INBOUND_DOORBELL_REGISTER_CPU_SIDE, data); - return true; -} - -/******************************************************************** -* isInBoundDoorBellInterruptSet - Check if Inbound Doorbell Interrupt is set, -* can be used for polling mode. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true if the corresponding bit in the cause register is set otherwise -* false. -*********************************************************************/ -bool isInBoundDoorBellInterruptSet() -{ - unsigned int regData; - - GT_REG_READ(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, ®Data); - return (regData & BIT2); -} - -/******************************************************************** -* isOutBoundDoorBellInterruptSet - Check if out bound Doorbell Interrupt is -* set, can be used for acknowledging interrupt -* handling by the agent who recieived the -* interrupt. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true if the corresponding bit in the cause register is set otherwise -* false. -*********************************************************************/ -bool isOutBoundDoorBellInterruptSet() -{ - unsigned int regData; - - GT_REG_READ(OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, ®Data); - return (regData & BIT2); -} - -/******************************************************************** -* maskInboundDoorBellInterrupt - Mask the Inbound Doorbell Interrupt. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool maskInBoundDoorBellInterrupt() -{ - SET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2); - return true; -} - -/******************************************************************** -* enableInboundDoorBellInterrupt - unMask the Inbound Doorbell Interrupt. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool enableInBoundDoorBellInterrupt() -{ - RESET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2); - return true; -} - -/******************************************************************** -* maskOutboundDoorBellInterrupt - Mask the Outbound Doorbell Interrupt. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool maskOutBoundDoorBellInterrupt() -{ - SET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2); - return true; -} - -/******************************************************************** -* enableOutboundDoorBellInterrupt - unMask the Outbound Doorbell Interrupt. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool enableOutBoundDoorBellInterrupt() -{ - RESET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2); - return true; -} - -/******************************************************************** -* circularQueueEnable - Initialize the I2O messaging mechanism. -* -* INPUTS: CIRCULE_QUEUE_SIZE cirQueSize - Bits 5:1 in the: -* Queue Control Register, Offset 0x50 (0x1c50). -* Defines the queues size (refer to the data sheet -* for more information) -* unsigned int queueBaseAddr - The base address for the first queue. -* The other queues base Address will be determined as follows: -* Inbound Free = queueBaseAddr -* Inbound Post = queueBaseAddr + cirQueSize -* Outbound Post = queueBaseAddr + cirQueSize -* -* OUTPUT: N/A. -* RETURNS: true. -* -* The Circular Queue Starting Addresses as written in the spec: -* ---------------------------------------- -* | Queue | Starting Address | -* |----------------|---------------------| -* | Inbound Free | QBAR | -* | Inbound Post | QBAR + Queue Size | -* | Outbound Post | QBAR + 2*Queue Size | -* | Outbound Free | QBAR + 3*Queue Size | -* ---------------------------------------- -*********************************************************************/ -bool circularQueueEnable(CIRCULAR_QUEUE_SIZE cirQueSize, - unsigned int queueBaseAddr) -{ - unsigned int regData; - - regData = BIT0 | (cirQueSize << 1); - /* Enable Queue Operation */ - GT_REG_WRITE(QUEUE_CONTROL_REGISTER_CPU_SIDE, regData); - /* Writing The base Address for the 4 Queues */ - GT_REG_WRITE(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, queueBaseAddr); - /* Update The Inbound Free Queue Base Address, offset=0 */ - GT_REG_WRITE(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, 0); - GT_REG_WRITE(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, 0); - /* Update The Inbound Post Queue Base Address, offset=_16K*cirQueSize */ - GT_REG_WRITE(INBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE, - _16K * cirQueSize); - GT_REG_WRITE(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE, - _16K * cirQueSize); - /* Update The Outbound Post Queue Base Address, offset=2*_16K*cirQueSize */ - GT_REG_WRITE(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE, - 2 * _16K * cirQueSize); - GT_REG_WRITE(OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE, - 2 * _16K * cirQueSize); - /* Update The Outbound Free Queue Base Address, offset=3*_16K*cirQueSize */ - GT_REG_WRITE(OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, - 3 * _16K * cirQueSize); - GT_REG_WRITE(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, - 3 * _16K * cirQueSize); - return true; -} - -/******************************************************************** -* inBoundPostQueuePop - Two actions are being taken upon pop: -* 1) Getting out the data from the Queue`s head. -* 2) Increment the tail pointer in a cyclic way (The HEAD is -* incremented automaticaly by the GT) -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: Data pointed by tail. -*********************************************************************/ -unsigned int inBoundPostQueuePop() -{ - unsigned int tailAddrPointer; - unsigned int data; - unsigned int cirQueSize; - unsigned int qBar; - unsigned int inBoundPostQbase; - - /* Gets the Inbound Post TAIL pointer */ - GT_REG_READ(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE, - &tailAddrPointer); - /* Gets the Data From the pointer Address */ - READ_WORD(tailAddrPointer, &data); - /* incrementing head process: */ - /* Gets the fifo's base Address */ - GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar); - qBar = qBar & 0xfff00000; - /* Gets the fifo's size */ - GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize); - cirQueSize = 0x1f && (cirQueSize >> 1); - /* calculating The Inbound Post Queue Base Address */ - inBoundPostQbase = qBar + 1 * cirQueSize * _16K; - /* incrementing Inbound Post queue TAIL in a cyclic loop */ - tailAddrPointer = inBoundPostQbase + ((tailAddrPointer + 4) % - (_16K * cirQueSize)); - /* updating the pointer back to INBOUND_POST_TAIL_POINTER_REGISTER */ - GT_REG_WRITE(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE, - tailAddrPointer); - return data; -} - -/******************************************************************** -* isInBoundPostQueueInterruptSet - Check if in bound interrupt is set. -* can be used for polling mode. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true if the corresponding bit in the cause register is set otherwise -* false. -*********************************************************************/ -bool isInBoundPostQueueInterruptSet() -{ - unsigned int regData; - - GT_REG_READ(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, ®Data); - return (regData & BIT4); /* if set return '1' (true), else '0' (false) */ -} - -/******************************************************************** -* clearInBoundPostQueueInterrupt - Clears the Post queue interrupt. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool clearInBoundPostQueueInterrupt() -{ - GT_REG_WRITE(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, BIT4); - return true; -} - -/******************************************************************** -* maskInBoundPostQueueInterrupt - Mask the inbound interrupt, when masking -* the interrupt you can work in polling mode. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: -*********************************************************************/ -void maskInBoundPostQueueInterrupt() -{ - unsigned int regData; - - GT_REG_READ(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, ®Data); - GT_REG_WRITE(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - regData | BIT4); - -} - -/******************************************************************** -* enableInBoundPostQueueInterrupt - Enable interrupt when ever there is a new -* message from the PCI agent. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: -*********************************************************************/ -void enableInBoundPostQueueInterrupt() -{ - unsigned int regData; - - GT_REG_READ(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, ®Data); - GT_REG_WRITE(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, - regData & 0xfffffffb); -} - -/******************************************************************** -* inBoundFreeQueuePush - Two actions are being taken upon push: -* 1) Place the user`s data on the Queue`s head. -* 2) Increment the haed pointer in a cyclic way (The tail is -* decremented automaticaly by the GT) -* -* INPUTS: unsigned int data - Data to be placed in the queue. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool inBoundFreeQueuePush(unsigned int data) -{ - unsigned int headPointer; - unsigned int cirQueSize; - unsigned int qBar; - unsigned int inBoundFreeQbase; - - GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, - &headPointer); - /* placing the data in the queue */ - WRITE_WORD(headPointer, data); - /* incrementing head process: */ - /* Gets the fifo's base Address */ - GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar); - qBar = qBar & 0xfff00000; - /* Gets the fifo's size */ - GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize); - cirQueSize = 0x1f && (cirQueSize >> 1); - /* calculating The Inbound Free Queue Base Address */ - inBoundFreeQbase = qBar; - /* incrementing Inbound Free queue HEAD in a cyclic loop */ - headPointer = - inBoundFreeQbase + ((headPointer + 4) % (_16K * cirQueSize)); - /* updating the pointer back to OUTBOUND_POST_HEAD_POINTER_REGISTER */ - GT_REG_WRITE(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, - headPointer); - return true; -} - -/******************************************************************** -* isInBoundFreeQueueEmpty - Check if Inbound Free Queue Empty. -* Can be used for acknowledging the messages -* being sent by us to the PCI agent. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true if the queue is empty , otherwise false. -*********************************************************************/ -bool isInBoundFreeQueueEmpty() -{ - unsigned int inBoundFreeQueHead; - unsigned int inBoundFreeQueTail; - - GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, - &inBoundFreeQueHead); - GT_REG_READ(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, - &inBoundFreeQueTail); - if (inBoundFreeQueHead == inBoundFreeQueTail) { - return true; - } else - return false; -} - -/******************************************************************** -* outBoundPostQueuePush - Two actions are being taken upon push: -* 1) Place the user`s data on the Queue`s head. -* 2) Increment the haed pointer in a cyclic way (The tail is -* decremented automaticaly by the GT when the Agent on the -* PCI have read data from the Outbound Port). -* -* INPUTS: unsigned int data - Data to be placed in the queue`s head. -* OUTPUT: N/A. -* RETURNS: true. -*********************************************************************/ -bool outBoundPostQueuePush(unsigned int data) -{ - unsigned int headPointer; - unsigned int cirQueSize; - unsigned int qBar; - unsigned int outBoundPostQbase; - - GT_REG_READ(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE, - &headPointer); - /* placing the data in the queue (where the head point to..) */ - WRITE_WORD(headPointer, data); - /* incrementing head process: */ - /* Gets the fifo's base Address */ - GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar); - qBar = qBar & 0xfff00000; - /* Gets the fifo's size */ - GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize); - cirQueSize = 0x1f && (cirQueSize >> 1); - /* calculating The Outbound Post Queue Base Address */ - outBoundPostQbase = qBar + 2 * cirQueSize * _16K; - /* incrementing Outbound Post queue in a cyclic loop */ - headPointer = - outBoundPostQbase + ((headPointer + 4) % (_16K * cirQueSize)); - /* updating the pointer back to OUTBOUND_POST_HEAD_POINTER_REGISTER */ - GT_REG_WRITE(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE, - headPointer); - return true; -} - -/******************************************************************** -* isOutBoundPostQueueEmpty - Check if Outbound Post Queue Empty. -* Can be used for acknowledging the messages -* being sent by us to the PCI agent. -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: true if the queue is empty , otherwise false. -*********************************************************************/ -bool isOutBoundPostQueueEmpty() -{ - unsigned int outBoundPostQueHead; - unsigned int outBoundPostQueTail; - - GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, - &outBoundPostQueHead); - GT_REG_READ(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, - &outBoundPostQueTail); - if (outBoundPostQueHead == outBoundPostQueTail) { - return true; - } else - return false; -} - -/******************************************************************** -* outBoundFreeQueuePop - Two actions are being taken upon pop: -* 1) Getting out the data from the Queue`s head. -* 2) Increment the tail pointer in a cyclic way (The HEAD is -* incremented automaticaly by the GT) -* -* INPUTS: N/A. -* OUTPUT: N/A. -* RETURNS: Data pointed by tail. -*********************************************************************/ -unsigned int outBoundFreeQueuePop() -{ - unsigned int tailAddrPointer; - unsigned int data; - unsigned int cirQueSize; - unsigned int qBar; - unsigned int outBoundFreeQbase; - - /* Gets the Inbound Post TAIL pointer */ - GT_REG_READ(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, - &tailAddrPointer); - /* Gets the Data From the pointer Address */ - READ_WORD(tailAddrPointer, &data); - /* incrementing head process: */ - /* Gets the fifo's base Address */ - GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar); - qBar = qBar & 0xfff00000; - /* Gets the fifo's size */ - GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize); - cirQueSize = 0x1f && (cirQueSize >> 1); - /* calculating The Inbound Post Queue Base Address */ - outBoundFreeQbase = qBar + 3 * cirQueSize * _16K; - /* incrementing Outbound Free queue TAlL in a cyclic loop */ - tailAddrPointer = outBoundFreeQbase + ((tailAddrPointer + 4) % - (_16K * cirQueSize)); - /* updating the pointer back to OUTBOUND_FREE_TAIL_POINTER_REGISTER */ - GT_REG_WRITE(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, - tailAddrPointer); - return data; -} - - -EXPORT_SYMBOL(isInBoundDoorBellInterruptSet); -EXPORT_SYMBOL(initiateOutBoundDoorBellInt); -EXPORT_SYMBOL(clearInBoundDoorBellInt); diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/int-handler.S linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/int-handler.S --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/int-handler.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/int-handler.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,113 +0,0 @@ -/* - * int-handler.S - * - * Based on the cobalt handler. - */ -#include -#include -#include -#include -#include - -/* - * galileo_handle_int - - * We check for the timer first, then check PCI ints A and D. - * Then check for serial IRQ and fall through. - */ - .align 5 - .set reorder - .set noat - NESTED(galileo_handle_int, PT_SIZE, sp) - SAVE_ALL - CLI - .set at - mfc0 t0,CP0_CAUSE - mfc0 t2,CP0_STATUS - - and t0,t2 - - andi t1,t0,STATUSF_IP4 /* int2 hardware line (timer) */ - bnez t1,ll_galileo_irq - andi t1,t0,STATUSF_IP2 /* int0 hardware line */ - bnez t1,ll_pci_intA - andi t1,t0,STATUSF_IP5 /* int3 hardware line */ - bnez t1,ll_pci_intD - andi t1,t0,STATUSF_IP6 /* int4 hardware line */ - bnez t1,ll_serial_irq - andi t1,t0,STATUSF_IP7 /* compare int */ - bnez t1,ll_compare_irq - nop - - /* wrong alarm or masked ... */ - j spurious_interrupt - nop - END(galileo_handle_int) - - - .align 5 - .set reorder -ll_galileo_irq: - li a0,4 - move a1,sp - jal do_IRQ - nop - j ret_from_irq - nop - - .align 5 - .set reorder -ll_compare_irq: - li a0,7 - move a1,sp - jal do_IRQ - nop - j ret_from_irq - nop - - .align 5 - .set reorder -ll_pci_intA: - move a0,sp - jal pci_intA - nop - j ret_from_irq - nop - -#if 0 - .align 5 - .set reorder -ll_pci_intB: - move a0,sp - jal pci_intB - nop - j ret_from_irq - nop - - .align 5 - .set reorder -ll_pci_intC: - move a0,sp - jal pci_intC - nop - j ret_from_irq - nop -#endif - - .align 5 - .set reorder -ll_pci_intD: - move a0,sp - jal pci_intD - nop - j ret_from_irq - nop - - .align 5 - .set reorder -ll_serial_irq: - li a0,6 - move a1,sp - jal do_IRQ - nop - j ret_from_irq - nop diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/irq-handler.c linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/irq-handler.c --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/irq-handler.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/irq-handler.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,270 +0,0 @@ -/* - * Galileo Technology chip interrupt handler - * - * Modified by RidgeRun, Inc. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * These are interrupt handlers for the GT on-chip interrupts. They all come - * in to the MIPS on a single interrupt line, and have to be handled and ack'ed - * differently than other MIPS interrupts. - */ - -#if CURRENTLY_UNUSED - -struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH]; -void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr); - -/* - * hook_irq_handler - * - * Hooks IRQ handler to the system. When the system is interrupted - * the interrupt service routine is called. - * - * Inputs : - * int_cause - The interrupt cause number. In EVB64120 two parameters - * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. - * bit_num - Indicates which bit number in the cause register - * isr_ptr - Pointer to the interrupt service routine - * - * Outputs : - */ -void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr) -{ - irq_handlers[int_cause][bit_num].routine = isr_ptr; -} - - -/* - * enable_galileo_irq - * - * Enables the IRQ on Galileo Chip - * - * Inputs : - * int_cause - The interrupt cause number. In EVB64120 two parameters - * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. - * bit_num - Indicates which bit number in the cause register - * - * Outputs : - * 1 if succesful, 0 if failure - */ -int enable_galileo_irq(int int_cause, int bit_num) -{ - if (int_cause == INT_CAUSE_MAIN) - SET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, (1 << bit_num)); - else if (int_cause == INT_CAUSE_HIGH) - SET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER, - (1 << bit_num)); - else - return 0; - return 1; -} - -/* - * disable_galileo_irq - * - * Disables the IRQ on Galileo Chip - * - * Inputs : - * int_cause - The interrupt cause number. In EVB64120 two parameters - * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. - * bit_num - Indicates which bit number in the cause register - * - * Outputs : - * 1 if succesful, 0 if failure - */ -int disable_galileo_irq(int int_cause, int bit_num) -{ - if (int_cause == INT_CAUSE_MAIN) - RESET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, - (1 << bit_num)); - else if (int_cause == INT_CAUSE_HIGH) - RESET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER, - (1 << bit_num)); - else - return 0; - return 1; -} - -#endif /* UNUSED */ - -/* - * galileo_irq - - * - * Interrupt handler for interrupts coming from the Galileo chip. - * It could be timer interrupt, built in ethernet ports etc... - * - * Inputs : - * - * Outputs : - * - */ -static void galileo_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - unsigned int irq_src, int_high_src, irq_src_mask, - int_high_src_mask; - int handled; - unsigned int count; - static int counter = 0; - - GT_READ(GT_INTRCAUSE_OFS, &irq_src); - GT_READ(GT_INTRMASK_OFS, &irq_src_mask); - GT_READ(GT_HINTRCAUSE_OFS, &int_high_src); - GT_READ(GT_HINTRMASK_OFS, &int_high_src_mask); - irq_src = irq_src & irq_src_mask; - int_high_src = int_high_src & int_high_src_mask; - - handled = 0; - - /* Execute all interrupt handlers */ - /* Check for timer interrupt */ - if (irq_src & 0x00000800) { - handled = 1; - irq_src &= ~0x00000800; - // RESET_REG_BITS (INTERRUPT_CAUSE_REGISTER,BIT8); - do_timer(regs); - } - - if (irq_src) { - printk(KERN_INFO - "Other Galileo interrupt received irq_src %x\n", - irq_src); -#if CURRENTLY_UNUSED - for (count = 0; count < MAX_CAUSE_REG_WIDTH; count++) { - if (irq_src & (1 << count)) { - if (irq_handlers[INT_CAUSE_MAIN][count]. - routine) { - queue_task(&irq_handlers - [INT_CAUSE_MAIN][count], - &tq_immediate); - mark_bh(IMMEDIATE_BH); - handled = 1; - } - } - } -#endif /* UNUSED */ - } - GT_WRITE(GT_INTRCAUSE_OFS, 0); - GT_WRITE(GT_HINTRCAUSE_OFS, 0); - -#undef GALILEO_I2O -#ifdef GALILEO_I2O - /* - Future I2O support. We currently attach I2O interrupt handlers to the - Galileo interrupt (int 4) and handle them in do_IRQ. - */ - if (isInBoundDoorBellInterruptSet()) { - printk(KERN_INFO "I2O doorbell interrupt received.\n"); - handled = 1; - } - - if (isInBoundPostQueueInterruptSet()) { - printk(KERN_INFO "I2O Queue interrupt received.\n"); - handled = 1; - } - - /* - This normally would be outside of the ifdef, but since - we're handling I2O outside of this handler, this - printk shows up every time we get a valid I2O - interrupt. So turn this off for now. - */ - if (handled == 0) { - if (counter < 50) { - printk("Spurious Galileo interrupt...\n"); - counter++; - } - } -#endif -} - -/* - * galileo_time_init - - * - * Initializes timer using galileo's built in timer. - * - * - * Inputs : - * irq - number of irq to be used by the timer - * - * Outpus : - * - */ -#ifdef CONFIG_SYSCLK_100 -#define Sys_clock (100 * 1000000) // 100 MHz -#endif -#ifdef CONFIG_SYSCLK_83 -#define Sys_clock (83.333 * 1000000) // 83.333 MHz -#endif -#ifdef CONFIG_SYSCLK_75 -#define Sys_clock (75 * 1000000) // 75 MHz -#endif - -/* - * This will ignore the standard MIPS timer interrupt handler that is passed - * in as *irq (=irq0 in ../kernel/time.c). We will do our own timer interrupt - * handling. - */ -void galileo_time_init(struct irqaction *irq) -{ - extern irq_desc_t irq_desc[NR_IRQS]; - static struct irqaction timer; - - /* Disable timer first */ - GT_WRITE(GT_TC_CONTROL_OFS, 0); - /* Load timer value for 100 Hz */ - GT_WRITE(GT_TC3_OFS, Sys_clock / 100); - - /* - * Create the IRQ structure entry for the timer. Since we're too early - * in the boot process to use the "request_irq()" call, we'll hard-code - * the values to the correct interrupt line. - */ - timer.handler = &galileo_irq; - timer.flags = SA_SHIRQ; - timer.name = "timer"; - timer.dev_id = NULL; - timer.next = NULL; - timer.mask = 0; - irq_desc[TIMER].action = &timer; - - /* Enable timer ints */ - GT_WRITE(GT_TC_CONTROL_OFS, 0xc0); - /* clear Cause register first */ - GT_WRITE(GT_INTRCAUSE_OFS, 0x0); - /* Unmask timer int */ - GT_WRITE(GT_INTRMASK_OFS, 0x800); - /* Clear High int register */ - GT_WRITE(GT_HINTRCAUSE_OFS, 0x0); - /* Mask All interrupts at High cause interrupt */ - GT_WRITE(GT_HINTRMASK_OFS, 0x0); - -} - -void galileo_irq_init(void) -{ - int i, j; - -#if CURRENTLY_UNUSED - /* Reset irq handlers pointers to NULL */ - for (i = 0; i < MAX_CAUSE_REGS; i++) { - for (j = 0; j < MAX_CAUSE_REG_WIDTH; j++) { - irq_handlers[i][j].next = NULL; - irq_handlers[i][j].sync = 0; - irq_handlers[i][j].routine = NULL; - irq_handlers[i][j].data = NULL; - } - } -#endif -} diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/irq.c linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/irq.c --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/irq.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,456 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Code to handle irqs on GT64120A boards - * Derived from mips/orion and Cort - * - * Copyright (C) 2000 RidgeRun, Inc. - * Author: RidgeRun, Inc. - * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com - * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#undef IRQ_DEBUG - -#ifdef IRQ_DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - - -asmlinkage void do_IRQ(int irq, struct pt_regs *regs); - -#define MAX_AGENTS_PER_INT 21 /* Random number */ -unsigned char pci_int_irq[MAX_AGENTS_PER_INT]; -static int max_interrupts = 0; - -/* Duplicate interrupt handlers. */ -/******************************************************************** - *pci_int(A/B/C/D) - - * - *Calls all the handlers connected to PCI interrupt A/B/C/D - * - *Inputs : - * - *Outpus : - * - *********************************************************************/ -asmlinkage __inline__ void pci_intA(struct pt_regs *regs) -{ - unsigned int count = 0; - DBG(KERN_INFO "pci_intA, max_interrupts %d\n", max_interrupts); - for (count = 0; count < max_interrupts; count++) { - do_IRQ(pci_int_irq[count], regs); - } -} - -asmlinkage __inline__ void pci_intD(struct pt_regs *regs) -{ - unsigned int count = 0; - DBG(KERN_INFO "pci_intD, max_interrupts %d\n", max_interrupts); - for (count = 0; count < max_interrupts; count++) { - do_IRQ(pci_int_irq[count], regs); - } -} - - -/* Function for careful CP0 interrupt mask access */ -static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) -{ - unsigned long status = read_32bit_cp0_register(CP0_STATUS); - DBG(KERN_INFO "modify_cp0_intmask clr %x, set %x\n", clr_mask, - set_mask); - DBG(KERN_INFO "modify_cp0_intmask status %x\n", status); - status &= ~((clr_mask & 0xFF) << 8); - status |= (set_mask & 0xFF) << 8; - DBG(KERN_INFO "modify_cp0_intmask status %x\n", status); - write_32bit_cp0_register(CP0_STATUS, status); -} - -static inline void mask_irq(unsigned int irq_nr) -{ - modify_cp0_intmask(irq_nr, 0); -} - -static inline void unmask_irq(unsigned int irq_nr) -{ - modify_cp0_intmask(0, irq_nr); -} - -void disable_irq(unsigned int irq_nr) -{ - unsigned long flags; - - DBG(KERN_INFO "disable_irq, irq %d\n", irq_nr); - save_and_cli(flags); - if (irq_nr >= 8) { // All PCI interrupts are on line 5 or 2 - mask_irq(9 << 2); - } else { - mask_irq(1 << irq_nr); - } - restore_flags(flags); -} - -void enable_irq(unsigned int irq_nr) -{ - unsigned long flags; - - DBG(KERN_INFO "enable_irq, irq %d\n", irq_nr); - save_and_cli(flags); - if (irq_nr >= 8) { // All PCI interrupts are on line 5 or 2 - DBG(KERN_INFO __FUNCTION__ " pci interrupt %d\n", irq_nr); - unmask_irq(9 << 2); - } else { - DBG(KERN_INFO __FUNCTION__ " interrupt set mask %d\n", - 1 << irq_nr); - unmask_irq(1 << irq_nr); - } - restore_flags(flags); -} - -/* - * Generic no controller code - */ - -static void no_irq_enable_disable(unsigned int irq) -{ -} -static unsigned int no_irq_startup(unsigned int irq) -{ - return 0; -} - -#if 0 -static void no_irq_ack(unsigned int irq) -{ - printk(KERN_CRIT "Unexpected IRQ trap at vector %u\n", irq); -} -#endif - -struct hw_interrupt_type no_irq_type = { - typename:"none", - startup:no_irq_startup, - shutdown:no_irq_enable_disable, - enable:no_irq_enable_disable, - disable:no_irq_enable_disable, - ack:NULL, - end:no_irq_enable_disable, -}; - -// ack: no_irq_ack, re-enable later -- SKJ - - -/* - * Controller mappings for all interrupt sources: - */ -irq_desc_t irq_desc[NR_IRQS]; - -atomic_t irq_err_count; - -int get_irq_list(char *buf) -{ - int i, len = 0, j; - struct irqaction *action; - - len += sprintf(buf + len, " "); - for (j = 0; j < smp_num_cpus; j++) - len += sprintf(buf + len, "CPU%d ", j); - *(char *) (buf + len++) = '\n'; - - for (i = 0; i < NR_IRQS; i++) { - action = irq_desc[i].action; - if (!action || !action->handler) - continue; - len += sprintf(buf + len, "%3d: ", i); - len += sprintf(buf + len, "%10u ", kstat_irqs(i)); - if (irq_desc[i].handler) - len += - sprintf(buf + len, " %s ", - irq_desc[i].handler->typename); - else - len += sprintf(buf + len, " None "); - len += sprintf(buf + len, " %s", action->name); - for (action = action->next; action; action = action->next) { - len += sprintf(buf + len, ", %s", action->name); - } - len += sprintf(buf + len, "\n"); - } - len += sprintf(buf + len, "BAD: %10lu\n", atomic_read(&irq_err_count)); - return len; -} - -asmlinkage void do_IRQ(int irq, struct pt_regs *regs) -{ - struct irqaction *action; - int cpu; - -#ifdef IRQ_DEBUG - if (irq != TIMER) - DBG(KERN_INFO __FUNCTION__ " irq = %d\n", irq); - if (irq != TIMER) - DBG(KERN_INFO "cause register = %x\n", - read_32bit_cp0_register(CP0_CAUSE)); - if (irq != TIMER) - DBG(KERN_INFO "status register = %x\n", - read_32bit_cp0_register(CP0_STATUS)); -#endif - - cpu = smp_processor_id(); - irq_enter(cpu, irq); - kstat.irqs[cpu][irq]++; - - if (irq_desc[irq].handler->ack) { - irq_desc[irq].handler->ack(irq); - } - - disable_irq(irq); - - action = irq_desc[irq].action; - if (action && action->handler) { -#ifdef IRQ_DEBUG - if (irq != TIMER) - DBG(KERN_INFO - "rr: irq %d action %p and handler %p\n", irq, - action, action->handler); -#endif - if (!(action->flags & SA_INTERRUPT)) - __sti(); - do { - 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); - } - } - - enable_irq(irq); - irq_exit(cpu, irq); - - if (softirq_pending(cpu)) - do_softirq(); - - /* unmasking and bottom half handling is done magically for us. */ -} - -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; - - DBG(KERN_INFO "rr:dev %s irq %d handler %x\n", devname, irq, - handler); - if (irq >= NR_IRQS) - return -EINVAL; - - action = (struct irqaction *) - kmalloc(sizeof(struct irqaction), GFP_KERNEL); - if (!action) - return -ENOMEM; - - action->handler = handler; - action->flags = irqflags; - action->mask = 0; - action->name = devname; - action->dev_id = dev_id; - action->next = NULL; - - save_flags(flags); - cli(); - - 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); - if (irq >= 8) { - DBG(KERN_INFO "request_irq, max_interrupts %d\n", - max_interrupts); - pci_int_irq[max_interrupts++] = irq; // NOTE: Add error-handling if > max - } - enable_irq(irq); - return 0; -} - - -void free_irq(unsigned int irq, void *dev_id) -{ - struct irqaction *p, *old = NULL; - unsigned long flags; - int count, tmp, removed = 0; - - for (p = irq_desc[irq].action; p != NULL; old = p, p = p->next) { - /* Found the IRQ, is it the correct dev_id? */ - if (dev_id == p->dev_id) { - save_flags(flags); - cli(); - - // remove link from list - if (old) - old->next = p->next; - else - irq_desc[irq].action = p->next; - - restore_flags(flags); - kfree(p); - removed = 1; - break; - } - } - - /* - Remove PCI interrupts from the pci_int_irq list. Make sure - that some handler was removed before decrementing max_interrupts. - */ - if ((irq >= 8) && (removed)) { - for (count = 0; count < max_interrupts; count++) { - if (pci_int_irq[count] == irq) { - for (tmp = count; tmp < max_interrupts; - tmp++) { - pci_int_irq[tmp] = - pci_int_irq[tmp + 1]; - } - } - } - max_interrupts--; - DBG(KERN_INFO "free_irq, max_interrupts %d\n", - max_interrupts); - } -} - -unsigned long probe_irq_on(void) -{ - printk(KERN_INFO "probe_irq_on\n"); - return 0; -} - -int probe_irq_off(unsigned long irqs) -{ - printk(KERN_INFO "probe_irq_off\n"); - return 0; -} - -/******************************************************************** - *galileo_irq_setup - - * - *Initializes CPU interrupts - * - * - *Inputs : - * - *Outpus : - * - *********************************************************************/ -void galileo_irq_setup(void) -{ - extern asmlinkage void galileo_handle_int(void); - extern void galileo_irq_init(void); - - DBG(KERN_INFO "rr: galileo_irq_setup entry\n"); - - galileo_irq_init(); - - /* - * Clear all of the interrupts while we change the able around a bit. - */ - clear_cp0_status(ST0_IM); - - /* Sets the exception_handler array. */ - set_except_vector(0, galileo_handle_int); - - cli(); - - /* - * Enable timer. Other interrupts will be enabled as they are - * registered. - */ - set_cp0_status(IE_IRQ2); - - -#ifdef CONFIG_REMOTE_DEBUG - { - extern int DEBUG_CHANNEL; - serial_init(DEBUG_CHANNEL); - serial_set(DEBUG_CHANNEL, 115200); - set_debug_traps(); - breakpoint(); /* you may move this line to whereever you want :-) */ - } -#endif -} - -void init_irq_proc(void) -{ - /* Nothing, for now. */ -} - -void __init init_IRQ(void) -{ - int i; - - DBG(KERN_INFO "rr:init_IRQ\n"); - - /* Let's initialize our IRQ descriptors */ - for (i = 0; i < NR_IRQS; i++) { - irq_desc[i].status = 0; - irq_desc[i].handler = &no_irq_type; - irq_desc[i].action = NULL; - irq_desc[i].depth = 0; - irq_desc[i].lock = SPIN_LOCK_UNLOCKED; - } - - galileo_irq_setup(); -} diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/pci_bios.c linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/pci_bios.c --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/pci_bios.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/pci_bios.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,1236 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Galileo Evaluation Boards PCI support. - * - * The general-purpose functions to read/write and configure the GT64120A's - * PCI registers (function names start with pci0 or pci1) are either direct - * copies of functions written by Galileo Technology, or are modifications - * of their functions to work with Linux 2.4 vs Linux 2.2. These functions - * are Copyright - Galileo Technology. - * - * Other functions are derived from other MIPS PCI implementations, or were - * written by RidgeRun, Inc, Copyright (C) 2000 RidgeRun, Inc. - * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com - * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#undef PCI_DEBUG - -#ifdef PCI_DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -#ifdef CONFIG_PCI - -#define SELF 0 - -/* - * These functions and structures provide the BIOS scan and mapping of the PCI - * devices. - */ - -#define MAX_PCI_DEVS 10 - -struct pci_device { - u32 slot; - u32 BARtype[6]; - u32 BARsize[6]; -}; - -static void __init scan_and_initialize_pci(void); -static u32 __init scan_pci_bus(struct pci_device *pci_devices); -static void __init allocate_pci_space(struct pci_device *pci_devices); - -static void __init galileo_pcibios_fixup_bus(struct pci_bus *bus); - -/* - * The functions that actually read and write to the controller. - * Copied from or modified from Galileo Technology code. - */ -static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device); -static void pci0WriteConfigReg(unsigned int offset, - struct pci_dev *device, unsigned int data); -static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device); -static void pci1WriteConfigReg(unsigned int offset, - struct pci_dev *device, unsigned int data); - -static void pci0MapIOspace(unsigned int pci0IoBase, - unsigned int pci0IoLength); -static void pci1MapIOspace(unsigned int pci1IoBase, - unsigned int pci1IoLength); -static void pci0MapMemory0space(unsigned int pci0Mem0Base, - unsigned int pci0Mem0Length); -static void pci1MapMemory0space(unsigned int pci1Mem0Base, - unsigned int pci1Mem0Length); -static void pci0MapMemory1space(unsigned int pci0Mem1Base, - unsigned int pci0Mem1Length); -static void pci1MapMemory1space(unsigned int pci1Mem1Base, - unsigned int pci1Mem1Length); -static unsigned int pci0GetIOspaceBase(void); -static unsigned int pci0GetIOspaceSize(void); -static unsigned int pci0GetMemory0Base(void); -static unsigned int pci0GetMemory0Size(void); -static unsigned int pci0GetMemory1Base(void); -static unsigned int pci0GetMemory1Size(void); -static unsigned int pci1GetIOspaceBase(void); -static unsigned int pci1GetIOspaceSize(void); -static unsigned int pci1GetMemory0Base(void); -static unsigned int pci1GetMemory0Size(void); -static unsigned int pci1GetMemory1Base(void); -static unsigned int pci1GetMemory1Size(void); - - -/* Functions to implement "pci ops" */ -static int galileo_pcibios_read_config_word(struct pci_dev *dev, - int offset, u16 * val); -static int galileo_pcibios_read_config_byte(struct pci_dev *dev, - int offset, u8 * val); -static int galileo_pcibios_read_config_dword(struct pci_dev *dev, - int offset, u32 * val); -static int galileo_pcibios_write_config_byte(struct pci_dev *dev, - int offset, u8 val); -static int galileo_pcibios_write_config_word(struct pci_dev *dev, - int offset, u16 val); -static int galileo_pcibios_write_config_dword(struct pci_dev *dev, - int offset, u32 val); -static void galileo_pcibios_set_master(struct pci_dev *dev); - -/* - * General-purpose PCI functions. - */ - -/* - * pci0MapIOspace - Maps PCI0 IO space for the master. - * Inputs: base and length of pci0Io - */ -static void pci0MapIOspace(unsigned int pci0IoBase, unsigned int pci0IoLength) -{ - unsigned int pci0IoTop = - (unsigned int) (pci0IoBase + pci0IoLength); - - if (pci0IoLength == 0) - pci0IoTop++; - - pci0IoBase = (unsigned int) (pci0IoBase >> 21); - pci0IoTop = (unsigned int) (((pci0IoTop - 1) & 0x0fffffff) >> 21); - GT_WRITE(GT_PCI0IOLD_OFS, pci0IoBase); - GT_WRITE(GT_PCI0IOHD_OFS, pci0IoTop); -} - -/* - * pci1MapIOspace - Maps PCI1 IO space for the master. - * Inputs: base and length of pci1Io - */ - -static void pci1MapIOspace(unsigned int pci1IoBase, - unsigned int pci1IoLength) -{ - unsigned int pci1IoTop = - (unsigned int) (pci1IoBase + pci1IoLength); - - if (pci1IoLength == 0) - pci1IoTop++; - - pci1IoBase = (unsigned int) (pci1IoBase >> 21); - pci1IoTop = (unsigned int) (((pci1IoTop - 1) & 0x0fffffff) >> 21); - GT_WRITE(GT_PCI1IOLD_OFS, pci1IoBase); - GT_WRITE(GT_PCI1IOHD_OFS, pci1IoTop); -} - -/* - * pci0MapMemory0space - Maps PCI0 memory0 space for the master. - * Inputs: base and length of pci0Mem0 - */ - -static void pci0MapMemory0space(unsigned int pci0Mem0Base, - unsigned int pci0Mem0Length) -{ - unsigned int pci0Mem0Top = pci0Mem0Base + pci0Mem0Length; - - if (pci0Mem0Length == 0) - pci0Mem0Top++; - - pci0Mem0Base = pci0Mem0Base >> 21; - pci0Mem0Top = ((pci0Mem0Top - 1) & 0x0fffffff) >> 21; - GT_WRITE(GT_PCI0M0LD_OFS, pci0Mem0Base); - GT_WRITE(GT_PCI0M0HD_OFS, pci0Mem0Top); -} - -/* - * pci1MapMemory0space - Maps PCI1 memory0 space for the master. - * Inputs: base and length of pci1Mem0 - */ - -static void pci1MapMemory0space(unsigned int pci1Mem0Base, - unsigned int pci1Mem0Length) -{ - unsigned int pci1Mem0Top = pci1Mem0Base + pci1Mem0Length; - - if (pci1Mem0Length == 0) - pci1Mem0Top++; - - pci1Mem0Base = pci1Mem0Base >> 21; - pci1Mem0Top = ((pci1Mem0Top - 1) & 0x0fffffff) >> 21; - GT_WRITE(GT_PCI1M0LD_OFS, pci1Mem0Base); - GT_WRITE(GT_PCI1M0HD_OFS, pci1Mem0Top); -} - -/* - * pci0MapMemory1space - Maps PCI0 memory1 space for the master. - * Inputs: base and length of pci0Mem1 - */ - -static void pci0MapMemory1space(unsigned int pci0Mem1Base, - unsigned int pci0Mem1Length) -{ - unsigned int pci0Mem1Top = pci0Mem1Base + pci0Mem1Length; - - if (pci0Mem1Length == 0) - pci0Mem1Top++; - - pci0Mem1Base = pci0Mem1Base >> 21; - pci0Mem1Top = ((pci0Mem1Top - 1) & 0x0fffffff) >> 21; - GT_WRITE(GT_PCI0M1LD_OFS, pci0Mem1Base); - GT_WRITE(GT_PCI0M1HD_OFS, pci0Mem1Top); - -} - -/* - * pci1MapMemory1space - Maps PCI1 memory1 space for the master. - * Inputs: base and length of pci1Mem1 - */ - -static void pci1MapMemory1space(unsigned int pci1Mem1Base, - unsigned int pci1Mem1Length) -{ - unsigned int pci1Mem1Top = pci1Mem1Base + pci1Mem1Length; - - if (pci1Mem1Length == 0) - pci1Mem1Top++; - - pci1Mem1Base = pci1Mem1Base >> 21; - pci1Mem1Top = ((pci1Mem1Top - 1) & 0x0fffffff) >> 21; - GT_WRITE(GT_PCI1M1LD_OFS, pci1Mem1Base); - GT_WRITE(GT_PCI1M1HD_OFS, pci1Mem1Top); -} - -/* - * pci0GetIOspaceBase - Return PCI0 IO Base Address. - * Inputs: N/A - * Returns: PCI0 IO Base Address. - */ - -static unsigned int pci0GetIOspaceBase(void) -{ - unsigned int base; - GT_READ(GT_PCI0IOLD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci0GetIOspaceSize - Return PCI0 IO Bar Size. - * Inputs: N/A - * Returns: PCI0 IO Bar Size. - */ -static unsigned int pci0GetIOspaceSize(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI0IOLD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI0IOHD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci0GetMemory0Base - Return PCI0 Memory 0 Base Address. - * Inputs: N/A - * Returns: PCI0 Memory 0 Base Address. - */ -static unsigned int pci0GetMemory0Base(void) -{ - unsigned int base; - GT_READ(GT_PCI0M0LD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci0GetMemory0Size - Return PCI0 Memory 0 Bar Size. - * Inputs: N/A - * Returns: PCI0 Memory 0 Bar Size. - */ -static unsigned int pci0GetMemory0Size(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI0M0LD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI0M0HD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci0GetMemory1Base - Return PCI0 Memory 1 Base Address. - * Inputs: N/A - * Returns: PCI0 Memory 1 Base Address. - */ -static unsigned int pci0GetMemory1Base(void) -{ - unsigned int base; - GT_READ(GT_PCI0M1LD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci0GetMemory1Size - Return PCI0 Memory 1 Bar Size. - * Inputs: N/A - * Returns: PCI0 Memory 1 Bar Size. - */ - -static unsigned int pci0GetMemory1Size(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI0M1LD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI0M1HD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci1GetIOspaceBase - Return PCI1 IO Base Address. - * Inputs: N/A - * Returns: PCI1 IO Base Address. - */ - -static unsigned int pci1GetIOspaceBase(void) -{ - unsigned int base; - GT_READ(GT_PCI1IOLD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci1GetIOspaceSize - Return PCI1 IO Bar Size. - * Inputs: N/A - * Returns: PCI1 IO Bar Size. - */ - -static unsigned int pci1GetIOspaceSize(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI1IOLD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI1IOHD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci1GetMemory0Base - Return PCI1 Memory 0 Base Address. - * Inputs: N/A - * Returns: PCI1 Memory 0 Base Address. - */ - -static unsigned int pci1GetMemory0Base(void) -{ - unsigned int base; - GT_READ(GT_PCI1M0LD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci1GetMemory0Size - Return PCI1 Memory 0 Bar Size. - * Inputs: N/A - * Returns: PCI1 Memory 0 Bar Size. - */ - -static unsigned int pci1GetMemory0Size(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI1M1LD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI1M1HD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci1GetMemory1Base - Return PCI1 Memory 1 Base Address. - * Inputs: N/A - * Returns: PCI1 Memory 1 Base Address. - */ - -static unsigned int pci1GetMemory1Base(void) -{ - unsigned int base; - GT_READ(GT_PCI1M1LD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci1GetMemory1Size - Return PCI1 Memory 1 Bar Size. - * Inputs: N/A - * Returns: PCI1 Memory 1 Bar Size. - */ - -static unsigned int pci1GetMemory1Size(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI1M1LD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI1M1HD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - - - -/* - * pci_range_ck - - * - * Check if the pci device that are trying to access does really exists - * on the evaluation board. - * - * Inputs : - * bus - bus number (0 for PCI 0 ; 1 for PCI 1) - * dev - number of device on the specific pci bus - * - * Outpus : - * 0 - if OK , 1 - if failure - */ -static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev) -{ - //DBG(KERN_INFO "p_r_c %d %d\n",bus,dev); - if (((bus == 0) || (bus == 1)) && (dev >= 6) && (dev <= 8)) - return 0; // Bus/Device Number OK - return -1; // Bus/Device Number not OK -} - -/* - * pciXReadConfigReg - Read from a PCI configuration register - * - Make sure the GT is configured as a master before - * reading from another device on the PCI. - * - The function takes care of Big/Little endian conversion. - * INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI - * spec) - * pciDevNum: The device number needs to be addressed. - * RETURNS: data , if the data == 0xffffffff check the master abort bit in the - * cause register to make sure the data is valid - * - * Configuration Address 0xCF8: - * - * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number - * |congif|Reserved| Bus |Device|Function|Register|00| - * |Enable| |Number|Number| Number | Number | | <=field Name - * - */ -static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device) -{ - unsigned int DataForRegCf8; - unsigned int data; - - DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | - (PCI_FUNC(device->devfn) << 8) | - (offset & ~0x3)) | 0x80000000; - GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); - - /* The casual observer might wonder why the READ is duplicated here, - rather than immediately following the WRITE, and just have the - swap in the "if". That's because there is a latency problem - with trying to read immediately after setting up the address - register. The "if" check gives enough time for the address - to stabilize, so the READ can work. - */ - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - GT_READ(GT_PCI0_CFGDATA_OFS, &data); - return data; - } else { /* The PCI is working in LE Mode so swap the Data. */ - GT_READ(GT_PCI0_CFGDATA_OFS, &data); - return cpu_to_le32(data); - } -} - -static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device) -{ - unsigned int DataForRegCf8; - unsigned int data; - - DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | - (PCI_FUNC(device->devfn) << 8) | - (offset & ~0x3)) | 0x80000000; - /* The casual observer might wonder why the READ is duplicated here, - rather than immediately following the WRITE, and just have the - swap in the "if". That's because there is a latency problem - with trying to read immediately after setting up the address - register. The "if" check gives enough time for the address - to stabilize, so the READ can work. - */ - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - /* when configurating our own PCI 1 L-unit the access is through - the PCI 0 interface with reg number = reg number + 0x80 */ - DataForRegCf8 |= 0x80; - GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); - } else { /* The PCI is working in LE Mode so swap the Data. */ - GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8); - } - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - GT_READ(GT_PCI0_CFGDATA_OFS, &data); - return data; - } else { - GT_READ(GT_PCI1_CFGDATA_OFS, &data); - return cpu_to_le32(data); - } -} - - - -/* - * pciXWriteConfigReg - Write to a PCI configuration register - * - Make sure the GT is configured as a master before - * writingto another device on the PCI. - * - The function takes care of Big/Little endian conversion. - * Inputs: unsigned int regOffset: The register offset as it apears in the - * GT spec - * (or any other PCI device spec) - * pciDevNum: The device number needs to be addressed. - * - * Configuration Address 0xCF8: - * - * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number - * |congif|Reserved| Bus |Device|Function|Register|00| - * |Enable| |Number|Number| Number | Number | | <=field Name - * - */ -static void pci0WriteConfigReg(unsigned int offset, - struct pci_dev *device, unsigned int data) -{ - unsigned int DataForRegCf8; - - DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | - (PCI_FUNC(device->devfn) << 8) | - (offset & ~0x3)) | 0x80000000; - GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - GT_WRITE(GT_PCI0_CFGDATA_OFS, data); - } else { /* configuration Transaction over the pci. */ - /* The PCI is working in LE Mode so swap the Data. */ - GT_WRITE(GT_PCI0_CFGDATA_OFS, le32_to_cpu(data)); - } -} - -static void pci1WriteConfigReg(unsigned int offset, - struct pci_dev *device, unsigned int data) -{ - unsigned int DataForRegCf8; - - DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | - (PCI_FUNC(device->devfn) << 8) | - (offset & ~0x3)) | 0x80000000; - /* There is a latency problem - with trying to read immediately after setting up the address - register. The "if" check gives enough time for the address - to stabilize, so the WRITE can work. - */ - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - /* when configurating our own PCI 1 L-unit the access is through - the PCI 0 interface with reg number = reg number + 0x80 */ - DataForRegCf8 |= 0x80; - GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); - } else { /* configuration Transaction over the pci. */ - /* The PCI is working in LE Mode so swap the Data. */ - GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8); - } - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - GT_WRITE(GT_PCI0_CFGDATA_OFS, data); - } else { /* configuration Transaction over the pci. */ - GT_WRITE(GT_PCI1_CFGADDR_OFS, le32_to_cpu(data)); - } -} - - -/* - * galileo_pcibios_(read/write)_config_(dword/word/byte) - - * - * reads/write a dword/word/byte register from the configuration space - * of a device. - * - * Inputs : - * bus - bus number - * dev - device number - * offset - register offset in the configuration space - * val - value to be written / read - * - * Outputs : - * PCIBIOS_SUCCESSFUL when operation was succesfull - * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous - * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned - */ - -static int galileo_pcibios_read_config_dword(struct pci_dev *device, - int offset, u32 * val) -{ - int dev, bus; - //DBG(KERN_INFO "rcd entry \n",offset,val); - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) { - *val = 0xffffffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - if (offset & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == 0) - *val = pci0ReadConfigReg(offset, device); -// if (bus == 1) *val = pci1ReadConfigReg (offset,device); - DBG(KERN_INFO "rr: rcd dev %d offset %x %x\n", dev, offset, *val); - - /* - * This is so that the upper PCI layer will get the correct return - * value if we're not attached to anything. - */ - if ((offset == 0) && (*val == 0xffffffff)) { - return PCIBIOS_DEVICE_NOT_FOUND; - } - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_read_config_word(struct pci_dev *device, - int offset, u16 * val) -{ - int dev, bus; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) { - *val = 0xffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - if (offset & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (bus == 0) - *val = (unsigned short) (pci0ReadConfigReg(offset, device) >> - ((offset & ~0x3) * 8)); -// if (bus == 1) *val = (unsigned short) (pci1ReadConfigReg(offset,device) >> ((offset & ~0x3) * 8)); - - DBG(KERN_INFO "rr: rcw dev %d offset %x %x\n", dev, offset, *val); - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_read_config_byte(struct pci_dev *device, - int offset, u8 * val) -{ - int dev, bus; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) { - *val = 0xff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - - if (bus == 0) - *val = - (unsigned char) (pci0ReadConfigReg(offset, device) >> - ((offset & ~0x3) * 8)); -// if (bus == 1) *val = (unsigned char) (pci1ReadConfigReg(offset,device) >> ((offset & ~0x3) * 8)); - - DBG(KERN_INFO "rr: rcb dev %d offset %x %x\n", dev, offset, *val); - - /* This is so that the upper PCI layer will get the correct return value if - we're not attached to anything. */ - if ((offset == 0xe) && (*val == 0xff)) { - u32 MasterAbort; - GT_READ(GT_INTRCAUSE_OFS, &MasterAbort); - if (MasterAbort & 0x40000) { - DBG(KERN_INFO "PCI Master Abort, ICR %x\n", - MasterAbort); - GT_WRITE(GT_INTRCAUSE_OFS, - (MasterAbort & 0xfffbffff)); - return PCIBIOS_DEVICE_NOT_FOUND; - } - } - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_write_config_dword(struct pci_dev *device, - int offset, u32 val) -{ - int dev, bus; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == 0) - pci0WriteConfigReg(offset, device, val); -// if (bus == 1) pci1WriteConfigReg (offset,device,val); - - DBG(KERN_INFO "rr: wcd dev %d, offset %x, val %x\n", dev, offset, - val); - return PCIBIOS_SUCCESSFUL; -} - - -static int galileo_pcibios_write_config_word(struct pci_dev *device, - int offset, u16 val) -{ - int dev, bus; - unsigned long tmp; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == 0) - tmp = pci0ReadConfigReg(offset, device); -// if (bus == 1) tmp = pci1ReadConfigReg (offset,device); - - if ((offset % 4) == 0) - tmp = (tmp & 0xffff0000) | (val & 0xffff); - if ((offset % 4) == 2) - tmp = (tmp & 0x0000ffff) | ((val & 0xffff) << 16); - - if (bus == 0) - pci0WriteConfigReg(offset, device, tmp); -// if (bus == 1) pci1WriteConfigReg (offset,device,tmp); - DBG(KERN_INFO "rr: wcw dev %d, offset %x, val %x\n", dev, offset, - val); - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_write_config_byte(struct pci_dev *device, - int offset, u8 val) -{ - int dev, bus; - unsigned long tmp; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - if (bus == 0) - tmp = pci0ReadConfigReg(offset, device); -// if (bus == 1) tmp = pci1ReadConfigReg (offset,device); - - if ((offset % 4) == 0) - tmp = (tmp & 0xffffff00) | (val & 0xff); - if ((offset % 4) == 1) - tmp = (tmp & 0xffff00ff) | ((val & 0xff) << 8); - if ((offset % 4) == 2) - tmp = (tmp & 0xff00ffff) | ((val & 0xff) << 16); - if ((offset % 4) == 3) - tmp = (tmp & 0x00ffffff) | ((val & 0xff) << 24); - - if (bus == 0) - pci0WriteConfigReg(offset, device, tmp); -// if (bus == 1) pci1WriteConfigReg (offset,device,tmp); - DBG(KERN_INFO "rr: wcb dev %d, offset %x, val %x\n", dev, offset, - val); - - return PCIBIOS_SUCCESSFUL; -} - -static void galileo_pcibios_set_master(struct pci_dev *dev) -{ - u16 cmd; - - DBG(KERN_INFO "rr: galileo_pcibios_set_master\n"); - - galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MASTER; - galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd); - DBG("PCI: Enabling device %s (%04x)\n", dev->slot_name, cmd); -} - -/* Externally-expected functions. Do not change function names */ - -int pcibios_enable_resources(struct pci_dev *dev) -{ - u16 cmd, old_cmd; - u16 tmp; - u8 tmp1; - int idx; - struct resource *r; - - DBG(KERN_INFO "rr: pcibios_enable_resources\n"); - - galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - for (idx = 0; idx < 6; idx++) { - r = &dev->resource[idx]; - DBG(KERN_INFO - "rr: BAR %d, start %lx, end %lx, flags %lx\n", idx, - r->start, r->end, r->flags); - if (!r->start && r->end) { - printk(KERN_ERR - "PCI: Device %s not available because of resource collisions\n", - dev->slot_name); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (cmd != old_cmd) { - DBG(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", - dev->slot_name, old_cmd, cmd); - galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd); - } - - /* - Let's fix up the latency timer and cache line size here. Cache line size = - 32 bytes / sizeof dword (4) = 8. - Latency timer must be > 8. 32 is random but appears to work. - */ - galileo_pcibios_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1); - if (tmp1 != 8) { - DBG(KERN_INFO - "rr: PCI setting cache line size to 8 from %d\n", - tmp1); - galileo_pcibios_write_config_byte(dev, PCI_CACHE_LINE_SIZE, - 8); - } - galileo_pcibios_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp1); - if (tmp1 < 32) { - DBG(KERN_INFO - "rr: PCI setting latency timer to 32 from %d\n", tmp1); - galileo_pcibios_write_config_byte(dev, PCI_LATENCY_TIMER, - 32); - } - - return 0; -} - -int pcibios_enable_device(struct pci_dev *dev) -{ - DBG(KERN_INFO "rr: pcibios_enable_device\n"); - return pcibios_enable_resources(dev); -} - -void pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - u32 new, check; - int reg; - - DBG(KERN_INFO "rr: pcibios_update_resource\n"); - return; - - new = res->start | (res->flags & PCI_REGION_FLAG_MASK); - if (resource < 6) { - reg = PCI_BASE_ADDRESS_0 + 4 * resource; - } else if (resource == PCI_ROM_RESOURCE) { - res->flags |= PCI_ROM_ADDRESS_ENABLE; - reg = dev->rom_base_reg; - } else { - /* Somebody might have asked allocation of a non-standard resource */ - return; - } - - pci_write_config_dword(dev, reg, new); - pci_read_config_dword(dev, reg, &check); - if ((new ^ check) & - ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : - PCI_BASE_ADDRESS_MEM_MASK)) { - DBG(KERN_ERR "PCI: Error while updating region " - "%s/%d (%08x != %08x)\n", dev->slot_name, resource, - new, check); - } -} - -void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ - struct pci_dev *dev = data; - - DBG(KERN_INFO "pcibios_align_resource\n"); - - if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; - - /* We need to avoid collisions with `mirrored' VGA ports - and other strange ISA hardware, so we always want the - addresses kilobyte aligned. */ - if (size > 0x100) { - DBG(KERN_ERR "PCI: I/O Region %s/%d too large" - " (%ld bytes)\n", dev->slot_name, - dev->resource - res, size); - } - - start = (start + 1024 - 1) & ~(1024 - 1); - res->start = start; - } -} - -/* - * structure galileo_pci_ops - * - * This structure holds the pointers for the PCI configuration space - * access, and the fixup for the interrupts. - * This structure is registered to the operating system in boot time - */ -struct pci_ops galileo_pci_ops = { - galileo_pcibios_read_config_byte, - galileo_pcibios_read_config_word, - galileo_pcibios_read_config_dword, - galileo_pcibios_write_config_byte, - galileo_pcibios_write_config_word, - galileo_pcibios_write_config_dword -}; - -/* - * galileo_pcibios_fixup_bus - - * - * After detecting all agents over the PCI , this function is called - * in order to give an interrupt number for each PCI device starting - * from IRQ 20. It does also enables master for each device. - * - * Inputs : - * mem_start , mem_end are not relevant in MIPS architecture. - * - * Outpus : - * return always mem_start - */ -static void __init galileo_pcibios_fixup_bus(struct pci_bus *bus) -{ - unsigned int Current_IRQ = 20; - struct pci_bus *current_bus = bus; - struct pci_dev *devices; - struct list_head *devices_link; - - list_for_each(devices_link, &(current_bus->devices)) { - devices = pci_dev_b(devices_link); - if (devices != NULL) { - devices->irq = Current_IRQ++; - - /* Assign an interrupt number for the device */ - galileo_pcibios_write_config_byte(devices, - PCI_INTERRUPT_LINE, - Current_IRQ); - galileo_pcibios_set_master(devices); - - } - } - -} - -struct pci_fixup pcibios_fixups[] = { -// { PCI_FIXUP_HEADER, 0x4620, 0x11ab, galileo_pcibios_fixup }, - {0} -}; - -void __init pcibios_fixup_bus(struct pci_bus *c) -{ - DBG(KERN_INFO "rr: pcibios_fixup_bus\n"); - galileo_pcibios_fixup_bus(c); -} - -/* - * This code was derived from Galileo Technology's example - * and significantly reworked. - * - * This is very simple. It does not scan multiple function devices. It does - * not scan behind bridges. Those would be simple to implement, but we don't - * currently need this. - */ -static void __init scan_and_initialize_pci(void) -{ - struct pci_device pci_devices[MAX_PCI_DEVS]; - - if (scan_pci_bus(pci_devices)) { - allocate_pci_space(pci_devices); - } -} - -/* - * This is your basic PCI scan. It goes through each slot and checks to - * see if there's something that responds. If so, then get the size and - * type of each of the responding BARs. Save them for later. - */ - -static u32 __init scan_pci_bus(struct pci_device *pci_devices) -{ - u32 arrayCounter = 0; - u32 memType; - u32 memSize; - u32 pci_slot, bar; - u32 id; - u32 c18RegValue; - struct pci_dev device; - - DBG(KERN_INFO "rr: scan_pci_bus\n"); - - /* - According to PCI REV 2.1 MAX agents on the bus are 21. - We don't bother scanning ourselves (slot 0). - */ - for (pci_slot = 1; pci_slot < 22; pci_slot++) { - - device.devfn = PCI_DEVFN(pci_slot, 0); - id = pci0ReadConfigReg(PCI_VENDOR_ID, &device); - - /* Check for a PCI Master Abort (nothing responds in the slot) */ - GT_READ(GT_INTRCAUSE_OFS, &c18RegValue); - /* Clearing bit 18 of in the Cause Register 0xc18 by writting 0. */ - GT_WRITE(GT_INTRCAUSE_OFS, (c18RegValue & 0xfffbffff)); - if ((id != 0xffffffff) && !(c18RegValue & 0x40000)) { - DBG(KERN_INFO "rr: found device %x, slot %d\n", id, - pci_slot); - pci_devices[arrayCounter].slot = pci_slot; - for (bar = 0; bar < 6; bar++) { - memType = - pci0ReadConfigReg(PCI_BASE_ADDRESS_0 + - (bar * 4), &device); - pci_devices[arrayCounter].BARtype[bar] = - memType & 1; - pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + - (bar * 4), &device, - 0xffffffff); - memSize = - pci0ReadConfigReg(PCI_BASE_ADDRESS_0 + - (bar * 4), &device); - if (memType & 1) { /* IO space */ - pci_devices[arrayCounter]. - BARsize[bar] = - ~(memSize & 0xfffffffc) + 1; - } else { /* memory space */ - pci_devices[arrayCounter]. - BARsize[bar] = - ~(memSize & 0xfffffff0) + 1; - } - DBG(KERN_INFO - "rr: BAR %d, type %d, size %x\n", bar, - (memType & 1), - pci_devices[arrayCounter]. - BARsize[bar]); - } /* BAR counter */ - - arrayCounter++; - } - /* found a device */ - } /* slot counter */ - - DBG(KERN_INFO "rr: found %d devices\n", arrayCounter); - if (arrayCounter < MAX_PCI_DEVS) { - pci_devices[arrayCounter].slot = -1; - } - return (arrayCounter); -} - -#define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1)) -#define MAX(val1, val2) ((val1) > (val2) ? (val1) : (val2)) - -/* - * This function goes through the list of devices and allocates the BARs in - * either IO or MEM space. It does it in order of size, which will limit the - * amount of fragmentation we have in the IO and MEM spaces. - */ - -static void __init allocate_pci_space(struct pci_device *pci_devices) -{ - u32 count, maxcount, bar; - u32 maxSize, maxDevice, maxBAR; - u32 alignto; - u32 base; - u32 pci0_mem_base = pci0GetMemory0Base(); - u32 pci0_io_base = pci0GetIOspaceBase(); - struct pci_dev device; - - DBG(KERN_INFO "rr: allocate_pci_space\n"); - - DBG(KERN_INFO "pci0_io_base %x\n", pci0_io_base); - DBG(KERN_INFO "pci0_mem_base %x\n", pci0_mem_base); - - /* How many PCI devices do we have? */ - maxcount = MAX_PCI_DEVS; - for (count = 0; count < MAX_PCI_DEVS; count++) { - if (pci_devices[count].slot == -1) { - maxcount = count; - break; - } - } - -// DBG(KERN_INFO "Found %d devices\n", maxcount); - - do { - /* Find the largest size BAR we need to allocate */ - maxSize = 0; - for (count = 0; count < maxcount; count++) { - for (bar = 0; bar < 6; bar++) { - if (pci_devices[count].BARsize[bar] > - maxSize) { - maxSize = - pci_devices[count]. - BARsize[bar]; - maxDevice = count; - maxBAR = bar; - } - } - } - - /* - We've found the largest BAR. Allocate it into IO or - mem space. We don't idiot check the bases to make - sure they haven't overflowed the current size for that aperture. - - Don't bother to enable the device's IO or MEM space here. That will - be done in pci_enable_resources if the device is activated by a driver. - */ - if (maxSize) { - device.devfn = - PCI_DEVFN(pci_devices[maxDevice].slot, 0); - if (pci_devices[maxDevice].BARtype[maxBAR] == 1) { - alignto = MAX(0x1000, maxSize); - base = ALIGN(pci0_io_base, alignto); - pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + - (maxBAR * 4), &device, - base | 0x1); - pci0_io_base = base + alignto; - DBG(KERN_INFO - "Device %d BAR %d address %x\n", - pci_devices[maxDevice].slot, maxBAR, - base); - DBG(KERN_INFO "New IO base %x\n", - pci0_io_base); - } else { - alignto = MAX(0x1000, maxSize); - base = ALIGN(pci0_mem_base, alignto); - pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + - (maxBAR * 4), &device, - base); - pci0_mem_base = base + alignto; - DBG(KERN_INFO - "Device %d BAR %d address %x\n", - pci_devices[maxDevice].slot, maxBAR, - base); - DBG(KERN_INFO "New mem base %x\n", - pci0_mem_base); - } - /* - This entry is finished. Remove it from the list we'll scan. - */ - pci_devices[maxDevice].BARsize[maxBAR] = 0; - } - } while (maxSize); -} - -unsigned __init int pcibios_assign_all_busses(void) -{ - return 1; -} - -void __init pcibios_init(void) -{ - - u32 tmp; - struct pci_dev controller; - - controller.devfn = SELF; - - DBG(KERN_INFO "rr: pcibios_init\n"); - GT_READ(GT_PCI0_CMD_OFS, &tmp); - DBG(KERN_INFO "rr: PCI0 command - %x\n", tmp); - GT_READ(GT_PCI0_BARE_OFS, &tmp); - DBG(KERN_INFO "rr: BAR0 - %x\n", tmp); - - /* - * You have to enable bus mastering to configure any other - * card on the bus. - */ - tmp = pci0ReadConfigReg(PCI_COMMAND, &controller); - DBG(KERN_INFO "rr: command/status - %x\n", tmp); - tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR; - DBG(KERN_INFO "rr: new command/status - %x\n", tmp); - pci0WriteConfigReg(PCI_COMMAND, &controller, tmp); - - /* This scans the PCI bus and sets up initial values. */ - scan_and_initialize_pci(); - - /* - * Reset PCI I/O and PCI MEM values to ones supported by EVM. - */ - ioport_resource.start = 0x10000000; - ioport_resource.end = 0x11ffffff; /* 32 MB */ - iomem_resource.start = 0x12000000; - iomem_resource.end = 0x13ffffff; /* 32 MB */ - - pci_scan_bus(0, &galileo_pci_ops, NULL); - -} - -char *pcibios_setup(char *str) -{ - printk(KERN_INFO "rr: pcibios_setup\n"); - /* Nothing to do for now. */ - - return str; -} - -#endif /* CONFIG_PCI */ diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/promcon.c linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/promcon.c --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/promcon.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/promcon.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,58 +0,0 @@ -/* - * Wrap-around code for a console using the - * SGI PROM io-routines. - * - * Copyright (c) 1999 Ulf Carlsson - * - * Derived from DECstation promcon.c - * Copyright (c) 1998 Harald Koerfgen - */ -#include -#include -#include -#include -#include -#include - -static void prom_console_write(struct console *co, const char *s, - unsigned count) -{ - extern int CONSOLE_CHANNEL; // The default serial port - unsigned i; - - for (i = 0; i < count; i++) { - if (*s == 10) - serial_putc(CONSOLE_CHANNEL, 13); - serial_putc(CONSOLE_CHANNEL, *s++); - } -} - -int prom_getchar(void) -{ - return 0; -} - -static kdev_t prom_console_device(struct console *c) -{ - return MKDEV(TTY_MAJOR, 64 + c->index); -} - -static struct console sercons = { - name: "ttyS", - write: prom_console_write, - device: prom_console_device, - flags: CON_PRINTBUFFER, - index: -1, -}; - -/* - * Register console. - */ - -void gal_serial_console_init(void) -{ - // serial_init(); - //serial_set(115200); - - register_console(&sercons); -} diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/reset.c linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/reset.c --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/reset.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/reset.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,45 +0,0 @@ -/* - * 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. - * - * Copyright (C) 1997 Ralf Baechle - */ -#include -#include -#include -#include -#include -#include -#include - -void galileo_machine_restart(char *command) -{ - *(volatile char *) 0xbc000000 = 0x0f; - /* - * Ouch, we're still alive ... This time we take the silver bullet ... - * ... and find that we leave the hardware in a state in which the - * kernel in the flush locks up somewhen during of after the PCI - * detection stuff. - */ - set_cp0_status(ST0_BEV | ST0_ERL); - change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); - flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); - __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); -} - -void galileo_machine_halt(void) -{ - printk(KERN_NOTICE "You can safely turn off the power\n"); - while (1) - __asm__(".set\tmips3\n\t" - "wait\n\t" - ".set\tmips0"); - -} - -void galileo_machine_power_off(void) -{ - galileo_machine_halt(); -} diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/serialGT.c linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/serialGT.c --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/serialGT.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/serialGT.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,212 +0,0 @@ -/* - * serialGT.c - * - * BRIEF MODULE DESCRIPTION - * Low Level Serial Port control for use - * with the Galileo EVB64120A MIPS eval board and - * its on board two channel 16552 Uart. - * - * Copyright (C) 2000 RidgeRun, Inc. - * Author: RidgeRun, Inc. - * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com - * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -// Note: -// Serial CHANNELS - 0 is the bottom connector of evb64120A. -// (The one that maps to the "B" channel of the -// board's uart) -// 1 is the top connector of evb64120A. -// (The one that maps to the "A" channel of the -// board's uart) -int DEBUG_CHANNEL = 0; // See Note Above -int CONSOLE_CHANNEL = 1; // See Note Above - -#define DUART 0xBD000000 /* Base address of Uart. */ -#define CHANNELOFFSET 0x20 /* DUART+CHANNELOFFSET gets you to the ChanA - register set of the 16552 Uart device. - DUART+0 gets you to the ChanB register set. - */ -#define DUART_DELTA 0x4 -#define FIFO_ENABLE 0x07 -#define INT_ENABLE 0x04 /* default interrupt mask */ - -#define RBR 0x00 -#define THR 0x00 -#define DLL 0x00 -#define IER 0x01 -#define DLM 0x01 -#define IIR 0x02 -#define FCR 0x02 -#define LCR 0x03 -#define MCR 0x04 -#define LSR 0x05 -#define MSR 0x06 -#define SCR 0x07 - -#define LCR_DLAB 0x80 -#define XTAL 1843200 -#define LSR_THRE 0x20 -#define LSR_BI 0x10 -#define LSR_DR 0x01 -#define MCR_LOOP 0x10 -#define ACCESS_DELAY 0x10000 - -/****************************** - Routine: - Description: - ******************************/ -int inreg(int channel, int reg) -{ - int val; - val = - *((volatile unsigned char *) DUART + - (channel * CHANNELOFFSET) + (reg * DUART_DELTA)); - return val; -} - -/****************************** - Routine: - Description: - ******************************/ -void outreg(int channel, int reg, unsigned char val) -{ - *((volatile unsigned char *) DUART + (channel * CHANNELOFFSET) - + (reg * DUART_DELTA)) = val; -} - -/****************************** - Routine: - Description: - Initialize the device driver. - ******************************/ -void serial_init(int channel) -{ - /* - * Configure active port, (CHANNELOFFSET already set.) - * - * Set 8 bits, 1 stop bit, no parity. - * - * LCR<7> 0 divisor latch access bit - * LCR<6> 0 break control (1=send break) - * LCR<5> 0 stick parity (0=space, 1=mark) - * LCR<4> 0 parity even (0=odd, 1=even) - * LCR<3> 0 parity enable (1=enabled) - * LCR<2> 0 # stop bits (0=1, 1=1.5) - * LCR<1:0> 11 bits per character(00=5, 01=6, 10=7, 11=8) - */ - outreg(channel, LCR, 0x3); - - outreg(channel, FCR, FIFO_ENABLE); /* Enable the FIFO */ - - outreg(channel, IER, INT_ENABLE); /* Enable appropriate interrupts */ -} - -/****************************** - Routine: - Description: - Set the baud rate. - ******************************/ -void serial_set(int channel, unsigned long baud) -{ - unsigned char sav_lcr; - - /* - * Enable access to the divisor latches by setting DLAB in LCR. - * - */ - sav_lcr = inreg(channel, LCR); - -#if 0 - /* - * Set baud rate - */ - outreg(channel, LCR, LCR_DLAB | sav_lcr); - // outreg(DLL,(XTAL/(16*2*(baud))-2)); - outreg(channel, DLL, XTAL / (16 * baud)); - // outreg(DLM,(XTAL/(16*2*(baud))-2)>>8); - outreg(channel, DLM, (XTAL / (16 * baud)) >> 8); -#else - /* - * Note: Set baud rate, hardcoded here for rate of 115200 - * since became unsure of above "buad rate" algorithm (??). - */ - outreg(channel, LCR, 0x83); - outreg(channel, DLM, 0x00); // See note above - outreg(channel, DLL, 0x02); // See note above. - outreg(channel, LCR, 0x03); -#endif - - /* - * Restore line control register - */ - outreg(channel, LCR, sav_lcr); -} - - -/****************************** - Routine: - Description: - Transmit a character. - ******************************/ -void serial_putc(int channel, int c) -{ - while ((inreg(channel, LSR) & LSR_THRE) == 0); - outreg(channel, THR, c); -} - -/****************************** - Routine: - Description: - Read a received character if one is - available. Return -1 otherwise. - ******************************/ -int serial_getc(int channel) -{ - if (inreg(channel, LSR) & LSR_DR) { - return inreg(channel, RBR); - } - return -1; -} - -/****************************** - Routine: - Description: - Used by embedded gdb client. (example; gdb-stub.c) - ******************************/ -char getDebugChar() -{ - int val; - while ((val = serial_getc(DEBUG_CHANNEL)) == -1); // loop until we get a character in. - return (char) val; -} - -/****************************** - Routine: - Description: - Used by embedded gdb target. (example; gdb-stub.c) - ******************************/ -void putDebugChar(char c) -{ - serial_putc(DEBUG_CHANNEL, (int) c); -} diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/setup.c linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/setup.c --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev64120/setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev64120/setup.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,188 +0,0 @@ -/* - * setup.c - * - * BRIEF MODULE DESCRIPTION - * Galileo Evaluation Boards - board dependent boot routines - * - * Copyright (C) 2000 RidgeRun, Inc. - * Author: RidgeRun, Inc. - * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com - * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern struct rtc_ops no_rtc_ops; - -/* These functions are used for rebooting or halting the machine*/ -extern void galileo_machine_restart(char *command); -extern void galileo_machine_halt(void); -extern void galileo_machine_power_off(void); -/* - *This structure holds pointers to the pci configuration space accesses - *and interrupts allocating routine for device over the PCI - */ -extern struct pci_ops galileo_pci_ops; - -extern unsigned long mips_machgroup; - -char arcs_cmdline[CL_SIZE] = { "console=ttyS0,115200 " - "root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/disk2/fs.gal " - "ip=192.168.1.211:192.168.1.1:::gt::" -}; - -//struct eeprom_parameters eeprom_param; - -/* - * This function is added because arch/mips/mm/init.c needs it - * basically it does nothing - */ -void prom_free_prom_memory(void) -{ -} - -extern void (*board_time_init) (struct irqaction * irq); - -static unsigned char galileo_rtc_read_data(unsigned long addr) -{ - return 0; -} - -static void galileo_rtc_write_data(unsigned char data, unsigned long addr) -{ -} - -static int galileo_rtc_bcd_mode(void) -{ - return 0; -} - -struct rtc_ops galileo_rtc_ops = { - &galileo_rtc_read_data, - &galileo_rtc_write_data, - &galileo_rtc_bcd_mode -}; - - -void __init bus_error_init(void) { /* nothing */ } - - -/******************************************************************** - *ev64120_setup - - * - *Initializes basic routines and structures pointers, memory size (as - *given by the bios and saves the command line. - * - * - *Inputs : - * - *Outpus : - * - *********************************************************************/ -extern void galileo_time_init(); -void ev64120_setup(void) -{ - unsigned int i, j; - - //printk(KERN_INFO "ev64120_setup\n"); - - _machine_restart = galileo_machine_restart; - _machine_halt = galileo_machine_halt; - _machine_power_off = galileo_machine_power_off; - - rtc_ops = &galileo_rtc_ops; - - board_time_init = galileo_time_init; - set_io_port_base(KSEG1); - -#ifdef CONFIG_L2_L3_CACHE -#error "external cache not implemented yet" - config_register = read_32bit_cp0_register(CP0_CONFIG); - printk("\n\n\nchecking second level cache cp0_config = %08lx\n", - config_register); - if (config_register & CONF_SC) { // second/third level cache available - config_register = config_register & (1 << 12); - write_32bit_cp0_register(CP0_CONFIG, config_register); - printk - ("\n\n\nchecking second level cache cp0_config = %08lx\n", - config_register); - } -#endif - -} - -const char *get_system_type(void) -{ - return "Galileo EV64120A"; -} - -/* - * SetUpBootInfo - - * - * This function is called at very first stages of kernel startup. - * It specifies for the kernel the evaluation board that the linux - * is running on. Then it saves the eprom parameters that holds the - * command line, memory size etc... - * - * Inputs : - * argc - nothing - * argv - holds a pointer to the eprom parameters - * envp - nothing - */ - -void SetUpBootInfo(int argc, char **argv, char **envp) -{ - mips_machgroup = MACH_GROUP_GALILEO; - mips_machtype = MACH_EV64120A; -} - -void __init prom_init(int a, char **b, char **c, int *d) -{ - unsigned long free_start, free_end, start_pfn, bootmap_size; - - mips_machgroup = MACH_GROUP_GALILEO; - add_memory_region(0, 32 << 20, BOOT_MEM_RAM); -} diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev96100/Makefile linux-2.4.21-bk38/arch/mips/galileo-boards/ev96100/Makefile --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev96100/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev96100/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -12,9 +12,10 @@ USE_STANDARD_AS_RULE := true -O_TARGET:= ev96100.o +O_TARGET := ev96100.o -obj-y := init.o pci_ops.o pci_fixups.o time.o irq.o int-handler.o setup.o \ - puts.o +obj-y := init.o irq.o puts.o reset.o time.o int-handler.o \ + setup.o +obj-$(CONFIG_PCI) += pci_fixups.o pci_ops.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev96100/init.c linux-2.4.21-bk38/arch/mips/galileo-boards/ev96100/init.c --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev96100/init.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev96100/init.c 2003-08-24 02:55:57.000000000 -0700 @@ -39,7 +39,7 @@ #include #include -#include +#include /* Environment variable */ diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev96100/irq.c linux-2.4.21-bk38/arch/mips/galileo-boards/ev96100/irq.c --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev96100/irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev96100/irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -45,13 +46,10 @@ #include #include #include -#include #include #include #include -extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs); - extern void mips_timer_interrupt(int irq, struct pt_regs *regs); extern asmlinkage void ev96100IRQ(void); @@ -60,7 +58,7 @@ unsigned long flags; save_and_cli(flags); - clear_cp0_status(0x100 << irq_nr); + clear_c0_status(0x100 << irq_nr); restore_flags(flags); } @@ -69,7 +67,7 @@ unsigned long flags; save_and_cli(flags); - set_cp0_status(0x100 << irq_nr); + set_c0_status(0x100 << irq_nr); restore_flags(flags); } diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev96100/pci_fixups.c linux-2.4.21-bk38/arch/mips/galileo-boards/ev96100/pci_fixups.c --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev96100/pci_fixups.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev96100/pci_fixups.c 2003-08-24 02:55:57.000000000 -0700 @@ -27,18 +27,13 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include - -#ifdef CONFIG_PCI - #include #include #include #include #include -#include -#include +#include extern unsigned short get_gt_devid(void); @@ -93,4 +88,3 @@ { return 0; } -#endif diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev96100/pci_ops.c linux-2.4.21-bk38/arch/mips/galileo-boards/ev96100/pci_ops.c --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev96100/pci_ops.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev96100/pci_ops.c 2003-08-24 02:55:57.000000000 -0700 @@ -33,242 +33,40 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include - -#ifdef CONFIG_PCI - +#include #include #include #include -#include #include -#include -#include +#include #include #define PCI_ACCESS_READ 0 #define PCI_ACCESS_WRITE 1 -#undef DEBUG - -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - #define GT_PCI_MEM_BASE 0x12000000 #define GT_PCI_MEM_SIZE 0x02000000 #define GT_PCI_IO_BASE 0x10000000 #define GT_PCI_IO_SIZE 0x02000000 + static struct resource pci_io_resource = { "io pci IO space", 0x10000000, 0x10000000 + 0x02000000, - IORESOURCE_IO}; + IORESOURCE_IO +}; static struct resource pci_mem_resource = { "ext pci memory space", 0x12000000, 0x12000000 + 0x02000000, - IORESOURCE_MEM}; + IORESOURCE_MEM +}; -extern struct pci_ops gt96100_pci_ops; +extern struct pci_ops gt64120_pci_ops; struct pci_channel mips_pci_channels[] = { - { >96100_pci_ops, &pci_io_resource, &pci_mem_resource, 1, 0xff }, + { >64120_pci_ops, &pci_io_resource, &pci_mem_resource, 1, 0xff }, { NULL, NULL, NULL, NULL, NULL} }; - -int -static gt96100_config_access(unsigned char access_type, struct pci_dev *dev, - unsigned char where, u32 *data) -{ - unsigned char bus = dev->bus->number; - unsigned char dev_fn = dev->devfn; - u32 intr; - - - if ((bus == 0) && (dev_fn >= PCI_DEVFN(31,0))) { - return -1; /* Because of a bug in the galileo (for slot 31). */ - } - - /* Clear cause register bits */ - GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | - GT_INTRCAUSE_TARABORT0_BIT)); - - /* Setup address */ - GT_WRITE(GT_PCI0_CFGADDR_OFS, - (bus << GT_PCI0_CFGADDR_BUSNUM_SHF) | - (dev_fn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | - ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | - GT_PCI0_CFGADDR_CONFIGEN_BIT); - udelay(2); - - - if (access_type == PCI_ACCESS_WRITE) { - if (dev_fn != 0) { - *data = le32_to_cpu(*data); - } - GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); - } - else { - GT_READ(GT_PCI0_CFGDATA_OFS, *data); - if (dev_fn != 0) { - *data = le32_to_cpu(*data); - } - } - - udelay(2); - - /* Check for master or target abort */ - GT_READ(GT_INTRCAUSE_OFS, intr); - - if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) - { - //printk("config access error: %x:%x\n", dev_fn,where); - /* Error occured */ - - /* Clear bits */ - GT_WRITE( GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | - GT_INTRCAUSE_TARABORT0_BIT) ); - - if (access_type == PCI_ACCESS_READ) { - *data = 0xffffffff; - } - return -1; - } - return 0; -} - - -/* - * We can't address 8 and 16 bit words directly. Instead we have to - * read/write a 32bit word and mask/modify the data we actually want. - */ -static int -read_config_byte (struct pci_dev *dev, int where, u8 *val) -{ - u32 data = 0; - - if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) { - *val = 0xff; - return -1; - } - - *val = (data >> ((where & 3) << 3)) & 0xff; - DBG("cfg read byte: bus %d dev_fn %x where %x: val %x\n", - dev->bus->number, dev->devfn, where, *val); - - return PCIBIOS_SUCCESSFUL; -} - - -static int -read_config_word (struct pci_dev *dev, int where, u16 *val) -{ - u32 data = 0; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) { - *val = 0xffff; - return -1; - } - - *val = (data >> ((where & 3) << 3)) & 0xffff; - DBG("cfg read word: bus %d dev_fn %x where %x: val %x\n", - dev->bus->number, dev->devfn, where, *val); - - return PCIBIOS_SUCCESSFUL; -} - -static int -read_config_dword (struct pci_dev *dev, int where, u32 *val) -{ - u32 data = 0; - - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) { - *val = 0xffffffff; - return -1; - } - - *val = data; - DBG("cfg read dword: bus %d dev_fn %x where %x: val %x\n", - dev->bus->number, dev->devfn, where, *val); - - return PCIBIOS_SUCCESSFUL; -} - - -static int -write_config_byte (struct pci_dev *dev, int where, u8 val) -{ - u32 data = 0; - - if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - data = (data & ~(0xff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - DBG("cfg write byte: bus %d dev_fn %x where %x: val %x\n", - dev->bus->number, dev->devfn, where, val); - - if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &data)) - return -1; - - return PCIBIOS_SUCCESSFUL; -} - -static int -write_config_word (struct pci_dev *dev, int where, u16 val) -{ - u32 data = 0; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - data = (data & ~(0xffff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - DBG("cfg write word: bus %d dev_fn %x where %x: val %x\n", - dev->bus->number, dev->devfn, where, val); - - if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &data)) - return -1; - - - return PCIBIOS_SUCCESSFUL; -} - -static int -write_config_dword(struct pci_dev *dev, int where, u32 val) -{ - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &val)) - return -1; - DBG("cfg write dword: bus %d dev_fn %x where %x: val %x\n", - dev->bus->number, dev->devfn, where, val); - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops gt96100_pci_ops = { - read_config_byte, - read_config_word, - read_config_dword, - write_config_byte, - write_config_word, - write_config_dword -}; - -#endif /* CONFIG_PCI */ diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev96100/puts.c linux-2.4.21-bk38/arch/mips/galileo-boards/ev96100/puts.c --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev96100/puts.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev96100/puts.c 2003-08-24 02:55:57.000000000 -0700 @@ -4,7 +4,7 @@ */ #include -#include +#include //#define SERIAL_BASE EV96100_UART0_REGS_BASE @@ -22,123 +22,117 @@ #undef SLOW_DOWN static const char digits[16] = "0123456789abcdef"; -static volatile unsigned char * const com1 = (unsigned char *)SERIAL_BASE; +static volatile unsigned char *const com1 = (unsigned char *) SERIAL_BASE; #ifdef SLOW_DOWN static inline void slow_down() { - int k; - for (k=0; k<10000; k++); + int k; + for (k = 0; k < 10000; k++); } #else #define slow_down() #endif -void -putch(const unsigned char c) +void putch(const unsigned char c) { - unsigned char ch; - int i = 0; + unsigned char ch; + int i = 0; - do { - ch = com1[SERB_CMD]; - slow_down(); - i++; - if (i>TIMEOUT) { - break; - } - } while (0 == (ch & TX_BUSY)); - com1[SERB_DATA] = c; -} - -void -putchar(const unsigned char c) -{ - unsigned char ch; - int i = 0; - - do { - ch = com1[SERB_CMD]; - slow_down(); - i++; - if (i>TIMEOUT) { - break; - } - } while (0 == (ch & TX_BUSY)); - com1[SERB_DATA] = c; -} - -void -puts(unsigned char *cp) -{ - unsigned char ch; - int i = 0; - - while (*cp) { - do { - ch = com1[SERB_CMD]; - slow_down(); - i++; - if (i>TIMEOUT) { - break; - } - } while (0 == (ch & TX_BUSY)); - com1[SERB_DATA] = *cp++; - } - putch('\r'); - putch('\n'); -} - -void -fputs(unsigned char *cp) -{ - unsigned char ch; - int i = 0; - - while (*cp) { - - do { - ch = com1[SERB_CMD]; - slow_down(); - i++; - if (i>TIMEOUT) { - break; - } - } while (0 == (ch & TX_BUSY)); - com1[SERB_DATA] = *cp++; - } -} - - -void -put64(uint64_t ul) -{ - int cnt; - unsigned ch; - - cnt = 16; /* 16 nibbles in a 64 bit long */ - putch('0'); - putch('x'); - do { - cnt--; - ch = (unsigned char)(ul >> cnt * 4) & 0x0F; - putch(digits[ch]); - } while (cnt > 0); -} - -void -put32(unsigned u) -{ - int cnt; - unsigned ch; - - cnt = 8; /* 8 nibbles in a 32 bit long */ - putch('0'); - putch('x'); - do { - cnt--; - ch = (unsigned char)(u >> cnt * 4) & 0x0F; - putch(digits[ch]); - } while (cnt > 0); + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i > TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = c; +} + +void putchar(const unsigned char c) +{ + unsigned char ch; + int i = 0; + + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i > TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = c; +} + +void puts(unsigned char *cp) +{ + unsigned char ch; + int i = 0; + + while (*cp) { + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i > TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = *cp++; + } + putch('\r'); + putch('\n'); +} + +void fputs(unsigned char *cp) +{ + unsigned char ch; + int i = 0; + + while (*cp) { + + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i > TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = *cp++; + } +} + + +void put64(uint64_t ul) +{ + int cnt; + unsigned ch; + + cnt = 16; /* 16 nibbles in a 64 bit long */ + putch('0'); + putch('x'); + do { + cnt--; + ch = (unsigned char) (ul >> cnt * 4) & 0x0F; + putch(digits[ch]); + } while (cnt > 0); +} + +void put32(unsigned u) +{ + int cnt; + unsigned ch; + + cnt = 8; /* 8 nibbles in a 32 bit long */ + putch('0'); + putch('x'); + do { + cnt--; + ch = (unsigned char) (u >> cnt * 4) & 0x0F; + putch(digits[ch]); + } while (cnt > 0); } diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev96100/reset.c linux-2.4.21-bk38/arch/mips/galileo-boards/ev96100/reset.c --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev96100/reset.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev96100/reset.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,70 @@ +/* + * BRIEF MODULE DESCRIPTION + * Galileo EV96100 reset routines. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/generic/reset.c + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +static void mips_machine_restart(char *command); +static void mips_machine_halt(void); + +static void mips_machine_restart(char *command) +{ + set_c0_status(ST0_BEV | ST0_ERL); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + flush_cache_all(); + write_c0_wired(0); + __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); + while (1); +} + +static void mips_machine_halt(void) +{ + printk(KERN_NOTICE "You can safely turn off the power\n"); + while (1) + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} + +void mips_reboot_setup(void) +{ + _machine_restart = mips_machine_restart; + _machine_halt = mips_machine_halt; +} diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev96100/setup.c linux-2.4.21-bk38/arch/mips/galileo-boards/ev96100/setup.c --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev96100/setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev96100/setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -1,5 +1,4 @@ /* - * * BRIEF MODULE DESCRIPTION * Galileo EV96100 setup. * @@ -47,8 +46,7 @@ #include #include #include -#include -#include +#include #include @@ -65,17 +63,16 @@ unsigned char mac_0_1[12]; - void __init ev96100_setup(void) { - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - unsigned long status = read_32bit_cp0_register(CP0_STATUS); - unsigned long info = read_32bit_cp0_register(CP0_INFO); + unsigned int config = read_c0_config(); + unsigned int status = read_c0_status(); + unsigned int info = read_c0_info(); u32 tmp; char *argptr; - clear_cp0_status(ST0_FR); + clear_c0_status(ST0_FR); if (config & 0x8) { printk("Secondary cache is enabled\n"); @@ -164,7 +161,7 @@ GT_PCI0_CFGADDR_CONFIGEN_BIT); udelay(2); - tmp = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS)); + tmp = GT_READ(GT_PCI0_CFGDATA_OFS); tmp |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR); @@ -174,7 +171,7 @@ ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | GT_PCI0_CFGADDR_CONFIGEN_BIT); udelay(2); - *(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS) = cpu_to_le32(tmp); + GT_WRITE(GT_PCI0_CFGDATA_OFS, tmp); /* Setup address */ GT_WRITE(GT_PCI0_CFGADDR_OFS, @@ -184,7 +181,7 @@ GT_PCI0_CFGADDR_CONFIGEN_BIT); udelay(2); - tmp = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS)); + tmp = GT_READ(GT_PCI0_CFGDATA_OFS); } unsigned short get_gt_devid() @@ -199,7 +196,7 @@ GT_PCI0_CFGADDR_CONFIGEN_BIT); udelay(4); - gt_devid = le32_to_cpu(*(volatile u32 *) - (MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS)); - return (unsigned short)(gt_devid>>16); + gt_devid = GT_READ(GT_PCI0_CFGDATA_OFS); + + return gt_devid >> 16; } diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/ev96100/time.c linux-2.4.21-bk38/arch/mips/galileo-boards/ev96100/time.c --- linux-2.4.21-bk37/arch/mips/galileo-boards/ev96100/time.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/ev96100/time.c 2003-08-24 02:55:57.000000000 -0700 @@ -54,7 +54,7 @@ static inline void ack_r4ktimer(unsigned long newval) { - write_32bit_cp0_register(CP0_COMPARE, newval); + write_c0_compare(newval); } static int set_rtc_mmss(unsigned long nowtime) @@ -109,12 +109,11 @@ est_freq -= est_freq%10000; printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, (est_freq%1000000)*100/1000000); - r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset); + r4k_cur = (read_c0_count() + r4k_offset); - write_32bit_cp0_register(CP0_COMPARE, r4k_cur); + write_c0_compare(r4k_cur); - /* FIX ME */ - change_cp0_status(ST0_IM, IE_IRQ5); + change_c0_status(ST0_IM, IE_IRQ5); /* FIX ME */ } /* This is for machines which generate the exact clock. */ @@ -172,7 +171,7 @@ } /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; @@ -195,7 +194,7 @@ void do_gettimeofday(struct timeval *tv) { - unsigned int flags; + unsigned long flags; read_lock_irqsave (&xtime_lock, flags); *tv = xtime; @@ -221,7 +220,7 @@ write_lock_irq (&xtime_lock); /* This is revolting. We need to set the xtime.tv_usec correctly. - * However, the value in this location is is value at the last tick. + * However, the value in this location is value at the last tick. * Discover what correction gettimeofday would have done, and then * undo it! */ @@ -260,7 +259,7 @@ r4k_cur += r4k_offset; ack_r4ktimer(r4k_cur); - } while (((unsigned long)read_32bit_cp0_register(CP0_COUNT) + } while (((unsigned long)read_c0_count() - r4k_cur) < 0x7fffffff); return; diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/generic/Makefile linux-2.4.21-bk38/arch/mips/galileo-boards/generic/Makefile --- linux-2.4.21-bk37/arch/mips/galileo-boards/generic/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/generic/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,36 +0,0 @@ -# -# Carsten Langgaard, carstenl@mips.com -# Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. -# -# ######################################################################## -# -# This program is free software; you can distribute it and/or modify it -# under the terms of the GNU General Public License (Version 2) as -# published by the Free Software Foundation. -# -# This program is distributed in the hope it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -# -# ####################################################################### -# -# Makefile for the MIPS boards generic routines under Linux. -# -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# -# Note 2! The CFLAGS definitions are now in the main makefile... - -USE_STANDARD_AS_RULE := true - -O_TARGET:= galboards.o - -obj-y := reset.o - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/galileo-boards/generic/reset.c linux-2.4.21-bk38/arch/mips/galileo-boards/generic/reset.c --- linux-2.4.21-bk37/arch/mips/galileo-boards/generic/reset.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/galileo-boards/generic/reset.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,72 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Galileo EV96100 reset routines. - * - * Copyright 2000 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * This file was derived from Carsten Langgaard's - * arch/mips/mips-boards/generic/reset.c - * - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -static void mips_machine_restart(char *command); -static void mips_machine_halt(void); - -static void mips_machine_restart(char *command) -{ - set_cp0_status(ST0_BEV | ST0_ERL); - change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); - flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); - __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); - while (1); -} - -static void mips_machine_halt(void) -{ - printk(KERN_NOTICE "You can safely turn off the power\n"); - while (1) - __asm__(".set\tmips3\n\t" - "wait\n\t" - ".set\tmips0"); -} - -void mips_reboot_setup(void) -{ - _machine_restart = mips_machine_restart; - _machine_halt = mips_machine_halt; -} diff -urN linux-2.4.21-bk37/arch/mips/gt64120/common/Makefile linux-2.4.21-bk38/arch/mips/gt64120/common/Makefile --- linux-2.4.21-bk37/arch/mips/gt64120/common/Makefile 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/gt64120/common/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -6,13 +6,11 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true -O_TARGET:= gt64120.o +O_TARGET := gt64120.o -obj-y := gt_irq.o pci.o +obj-y += time.o +obj-$(CONFIG_PCI) += pci.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/gt64120/common/gt_irq.c linux-2.4.21-bk38/arch/mips/gt64120/common/gt_irq.c --- linux-2.4.21-bk37/arch/mips/gt64120/common/gt_irq.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/gt64120/common/gt_irq.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,250 +0,0 @@ -/* - * - * Copyright 2001 MontaVista Software Inc. - * Author: jsun@mvista.com or jsun@junsun.net - * - * arch/mips/gt64120/common/gt_irq.c - * Interrupt routines for gt64120. Currently it only handles timer irq. - * - * 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. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * These are interrupt handlers for the GT on-chip interrupts. They - * all come in to the MIPS on a single interrupt line, and have to - * be handled and ack'ed differently than other MIPS interrupts. - */ - -#if CURRENTLY_UNUSED - -struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH]; -void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr); - -/* - * Hooks IRQ handler to the system. When the system is interrupted - * the interrupt service routine is called. - * - * Inputs : - * int_cause - The interrupt cause number. In EVB64120 two parameters - * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. - * bit_num - Indicates which bit number in the cause register - * isr_ptr - Pointer to the interrupt service routine - */ -void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr) -{ - irq_handlers[int_cause][bit_num].routine = isr_ptr; -} - - -/* - * Enables the IRQ on Galileo Chip - * - * Inputs : - * int_cause - The interrupt cause number. In EVB64120 two parameters - * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. - * bit_num - Indicates which bit number in the cause register - * - * Outputs : - * 1 if succesful, 0 if failure - */ -int enable_galileo_irq(int int_cause, int bit_num) -{ - if (int_cause == INT_CAUSE_MAIN) - SET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, (1 << bit_num)); - else if (int_cause == INT_CAUSE_HIGH) - SET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER, - (1 << bit_num)); - else - return 0; - - return 1; -} - -/* - * Disables the IRQ on Galileo Chip - * - * Inputs : - * int_cause - The interrupt cause number. In EVB64120 two parameters - * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. - * bit_num - Indicates which bit number in the cause register - * - * Outputs : - * 1 if succesful, 0 if failure - */ -int disable_galileo_irq(int int_cause, int bit_num) -{ - if (int_cause == INT_CAUSE_MAIN) - RESET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, - (1 << bit_num)); - else if (int_cause == INT_CAUSE_HIGH) - RESET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER, - (1 << bit_num)); - else - return 0; - return 1; -} -#endif /* UNUSED */ - -/* - * Interrupt handler for interrupts coming from the Galileo chip. - * It could be timer interrupt, built in ethernet ports etc... - */ -static void gt64120_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - unsigned int irq_src, int_high_src, irq_src_mask, - int_high_src_mask; - int handled; - - GT_READ(GT_INTRCAUSE_OFS, &irq_src); - GT_READ(GT_INTRMASK_OFS, &irq_src_mask); - GT_READ(GT_HINTRCAUSE_OFS, &int_high_src); - GT_READ(GT_HINTRMASK_OFS, &int_high_src_mask); - irq_src = irq_src & irq_src_mask; - int_high_src = int_high_src & int_high_src_mask; - - handled = 0; - - /* Execute all interrupt handlers */ - /* Check for timer interrupt */ - if (irq_src & 0x00000800) { - handled = 1; - irq_src &= ~0x00000800; - // RESET_REG_BITS (INTERRUPT_CAUSE_REGISTER,BIT8); - do_timer(regs); - } - - if (irq_src) { - printk(KERN_INFO - "Other Galileo interrupt received irq_src %x\n", - irq_src); -#if CURRENTLY_UNUSED - for (count = 0; count < MAX_CAUSE_REG_WIDTH; count++) { - if (irq_src & (1 << count)) { - if (irq_handlers[INT_CAUSE_MAIN][count]. - routine) { - queue_task(&irq_handlers - [INT_CAUSE_MAIN][count], - &tq_immediate); - mark_bh(IMMEDIATE_BH); - handled = 1; - } - } - } -#endif /* UNUSED */ - } - GT_WRITE(GT_INTRCAUSE_OFS, 0); - GT_WRITE(GT_HINTRCAUSE_OFS, 0); - -#undef GALILEO_I2O -#ifdef GALILEO_I2O - /* - * Future I2O support. We currently attach I2O interrupt handlers to - * the Galileo interrupt (int 4) and handle them in do_IRQ. - */ - if (isInBoundDoorBellInterruptSet()) { - printk(KERN_INFO "I2O doorbell interrupt received.\n"); - handled = 1; - } - - if (isInBoundPostQueueInterruptSet()) { - printk(KERN_INFO "I2O Queue interrupt received.\n"); - handled = 1; - } - - /* - * This normally would be outside of the ifdef, but since we're - * handling I2O outside of this handler, this printk shows up every - * time we get a valid I2O interrupt. So turn this off for now. - */ - if (handled == 0) { - if (counter < 50) { - printk("Spurious Galileo interrupt...\n"); - counter++; - } - } -#endif -} - -/* - * Initializes timer using galileo's built in timer. - */ -#ifdef CONFIG_SYSCLK_100 -#define Sys_clock (100 * 1000000) // 100 MHz -#endif -#ifdef CONFIG_SYSCLK_83 -#define Sys_clock (83.333 * 1000000) // 83.333 MHz -#endif -#ifdef CONFIG_SYSCLK_75 -#define Sys_clock (75 * 1000000) // 75 MHz -#endif - -/* - * This will ignore the standard MIPS timer interrupt handler - * that is passed in as *irq (=irq0 in ../kernel/time.c). - * We will do our own timer interrupt handling. - */ -void gt64120_time_init(void) -{ - extern irq_desc_t irq_desc[NR_IRQS]; - static struct irqaction timer; - - /* Disable timer first */ - GT_WRITE(GT_TC_CONTROL_OFS, 0); - /* Load timer value for 100 Hz */ - GT_WRITE(GT_TC3_OFS, Sys_clock / 100); - - /* - * Create the IRQ structure entry for the timer. Since we're too early - * in the boot process to use the "request_irq()" call, we'll hard-code - * the values to the correct interrupt line. - */ - timer.handler = >64120_irq; - timer.flags = SA_SHIRQ | SA_INTERRUPT; - timer.name = "timer"; - timer.dev_id = NULL; - timer.next = NULL; - timer.mask = 0; - irq_desc[TIMER].action = &timer; - - enable_irq(TIMER); - - /* Enable timer ints */ - GT_WRITE(GT_TC_CONTROL_OFS, 0xc0); - /* clear Cause register first */ - GT_WRITE(GT_INTRCAUSE_OFS, 0x0); - /* Unmask timer int */ - GT_WRITE(GT_INTRMASK_OFS, 0x800); - /* Clear High int register */ - GT_WRITE(GT_HINTRCAUSE_OFS, 0x0); - /* Mask All interrupts at High cause interrupt */ - GT_WRITE(GT_HINTRMASK_OFS, 0x0); -} - -void gt64120_irq_init(void) -{ -#if CURRENTLY_UNUSED - int i, j; - - /* Reset irq handlers pointers to NULL */ - for (i = 0; i < MAX_CAUSE_REGS; i++) { - for (j = 0; j < MAX_CAUSE_REG_WIDTH; j++) { - irq_handlers[i][j].next = NULL; - irq_handlers[i][j].sync = 0; - irq_handlers[i][j].routine = NULL; - irq_handlers[i][j].data = NULL; - } - } -#endif -} diff -urN linux-2.4.21-bk37/arch/mips/gt64120/common/pci.c linux-2.4.21-bk38/arch/mips/gt64120/common/pci.c --- linux-2.4.21-bk37/arch/mips/gt64120/common/pci.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/gt64120/common/pci.c 2003-08-24 02:55:57.000000000 -0700 @@ -12,9 +12,6 @@ * written by RidgeRun, Inc, Copyright (C) 2000 RidgeRun, Inc. * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com * - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * * 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 @@ -35,440 +32,23 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include +#include #include #include #include -#include -#include -#include -#include #include -#include - -#ifdef CONFIG_PCI - #define SELF 0 /* - * These functions and structures provide the BIOS scan and mapping of the PCI - * devices. - */ - -#define MAX_PCI_DEVS 10 - -struct pci_device { - u32 slot; - u32 BARtype[6]; - u32 BARsize[6]; -}; - -static void __init scan_and_initialize_pci(void); -static u32 __init scan_pci_bus(struct pci_device *pci_devices); -static void __init allocate_pci_space(struct pci_device *pci_devices); - -/* - * The functions that actually read and write to the controller. - * - * Copied from or modified from Galileo Technology code. - */ -static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device); -static void pci0WriteConfigReg(unsigned int offset, - struct pci_dev *device, unsigned int data); -static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device); -static void pci1WriteConfigReg(unsigned int offset, - struct pci_dev *device, unsigned int data); - -static void pci0MapIOspace(unsigned int pci0IoBase, - unsigned int pci0IoLength); -static void pci1MapIOspace(unsigned int pci1IoBase, - unsigned int pci1IoLength); -static void pci0MapMemory0space(unsigned int pci0Mem0Base, - unsigned int pci0Mem0Length); -static void pci1MapMemory0space(unsigned int pci1Mem0Base, - unsigned int pci1Mem0Length); -static void pci0MapMemory1space(unsigned int pci0Mem1Base, - unsigned int pci0Mem1Length); -static void pci1MapMemory1space(unsigned int pci1Mem1Base, - unsigned int pci1Mem1Length); -static unsigned int pci0GetIOspaceBase(void); -static unsigned int pci0GetIOspaceSize(void); -static unsigned int pci0GetMemory0Base(void); -static unsigned int pci0GetMemory0Size(void); -static unsigned int pci0GetMemory1Base(void); -static unsigned int pci0GetMemory1Size(void); -static unsigned int pci1GetIOspaceBase(void); -static unsigned int pci1GetIOspaceSize(void); -static unsigned int pci1GetMemory0Base(void); -static unsigned int pci1GetMemory0Size(void); -static unsigned int pci1GetMemory1Base(void); -static unsigned int pci1GetMemory1Size(void); - - -/* Functions to implement "pci ops" */ -static int galileo_pcibios_read_config_word(struct pci_dev *dev, - int offset, u16 * val); -static int galileo_pcibios_read_config_byte(struct pci_dev *dev, - int offset, u8 * val); -static int galileo_pcibios_read_config_dword(struct pci_dev *dev, - int offset, u32 * val); -static int galileo_pcibios_write_config_byte(struct pci_dev *dev, - int offset, u8 val); -static int galileo_pcibios_write_config_word(struct pci_dev *dev, - int offset, u16 val); -static int galileo_pcibios_write_config_dword(struct pci_dev *dev, - int offset, u32 val); -static void galileo_pcibios_set_master(struct pci_dev *dev); - -/* - * General-purpose PCI functions. - */ - -/* - * pci0MapIOspace - Maps PCI0 IO space for the master. - * Inputs: base and length of pci0Io - */ - -static void pci0MapIOspace(unsigned int pci0IoBase, - unsigned int pci0IoLength) -{ - unsigned int pci0IoTop = - (unsigned int) (pci0IoBase + pci0IoLength); - - if (pci0IoLength == 0) - pci0IoTop++; - - pci0IoBase = (unsigned int) (pci0IoBase >> 21); - pci0IoTop = (unsigned int) (((pci0IoTop - 1) & 0x0fffffff) >> 21); - GT_WRITE(GT_PCI0IOLD_OFS, pci0IoBase); - GT_WRITE(GT_PCI0IOHD_OFS, pci0IoTop); -} - -/* - * pci1MapIOspace - Maps PCI1 IO space for the master. - * Inputs: base and length of pci1Io - */ - -static void pci1MapIOspace(unsigned int pci1IoBase, - unsigned int pci1IoLength) -{ - unsigned int pci1IoTop = - (unsigned int) (pci1IoBase + pci1IoLength); - - if (pci1IoLength == 0) - pci1IoTop++; - - pci1IoBase = (unsigned int) (pci1IoBase >> 21); - pci1IoTop = (unsigned int) (((pci1IoTop - 1) & 0x0fffffff) >> 21); - GT_WRITE(GT_PCI1IOLD_OFS, pci1IoBase); - GT_WRITE(GT_PCI1IOHD_OFS, pci1IoTop); -} - -/* - * pci0MapMemory0space - Maps PCI0 memory0 space for the master. - * Inputs: base and length of pci0Mem0 - */ - -static void pci0MapMemory0space(unsigned int pci0Mem0Base, - unsigned int pci0Mem0Length) -{ - unsigned int pci0Mem0Top = pci0Mem0Base + pci0Mem0Length; - - if (pci0Mem0Length == 0) - pci0Mem0Top++; - - pci0Mem0Base = pci0Mem0Base >> 21; - pci0Mem0Top = ((pci0Mem0Top - 1) & 0x0fffffff) >> 21; - GT_WRITE(GT_PCI0M0LD_OFS, pci0Mem0Base); - GT_WRITE(GT_PCI0M0HD_OFS, pci0Mem0Top); -} - -/* - * pci1MapMemory0space - Maps PCI1 memory0 space for the master. - * Inputs: base and length of pci1Mem0 - */ - -static void pci1MapMemory0space(unsigned int pci1Mem0Base, - unsigned int pci1Mem0Length) -{ - unsigned int pci1Mem0Top = pci1Mem0Base + pci1Mem0Length; - - if (pci1Mem0Length == 0) - pci1Mem0Top++; - - pci1Mem0Base = pci1Mem0Base >> 21; - pci1Mem0Top = ((pci1Mem0Top - 1) & 0x0fffffff) >> 21; - GT_WRITE(GT_PCI1M0LD_OFS, pci1Mem0Base); - GT_WRITE(GT_PCI1M0HD_OFS, pci1Mem0Top); -} - -/* - * pci0MapMemory1space - Maps PCI0 memory1 space for the master. - * Inputs: base and length of pci0Mem1 - */ - -static void pci0MapMemory1space(unsigned int pci0Mem1Base, - unsigned int pci0Mem1Length) -{ - unsigned int pci0Mem1Top = pci0Mem1Base + pci0Mem1Length; - - if (pci0Mem1Length == 0) - pci0Mem1Top++; - - pci0Mem1Base = pci0Mem1Base >> 21; - pci0Mem1Top = ((pci0Mem1Top - 1) & 0x0fffffff) >> 21; - GT_WRITE(GT_PCI0M1LD_OFS, pci0Mem1Base); - GT_WRITE(GT_PCI0M1HD_OFS, pci0Mem1Top); - -} - -/* - * pci1MapMemory1space - Maps PCI1 memory1 space for the master. - * Inputs: base and length of pci1Mem1 - */ - -static void pci1MapMemory1space(unsigned int pci1Mem1Base, - unsigned int pci1Mem1Length) -{ - unsigned int pci1Mem1Top = pci1Mem1Base + pci1Mem1Length; - - if (pci1Mem1Length == 0) - pci1Mem1Top++; - - pci1Mem1Base = pci1Mem1Base >> 21; - pci1Mem1Top = ((pci1Mem1Top - 1) & 0x0fffffff) >> 21; - GT_WRITE(GT_PCI1M1LD_OFS, pci1Mem1Base); - GT_WRITE(GT_PCI1M1HD_OFS, pci1Mem1Top); -} - -/* - * pci0GetIOspaceBase - Return PCI0 IO Base Address. - * Inputs: N/A - * Returns: PCI0 IO Base Address. - */ - -static unsigned int pci0GetIOspaceBase(void) -{ - unsigned int base; - GT_READ(GT_PCI0IOLD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci0GetIOspaceSize - Return PCI0 IO Bar Size. - * Inputs: N/A - * Returns: PCI0 IO Bar Size. - */ - -static unsigned int pci0GetIOspaceSize(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI0IOLD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI0IOHD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci0GetMemory0Base - Return PCI0 Memory 0 Base Address. - * Inputs: N/A - * Returns: PCI0 Memory 0 Base Address. - */ - -static unsigned int pci0GetMemory0Base(void) -{ - unsigned int base; - GT_READ(GT_PCI0M0LD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci0GetMemory0Size - Return PCI0 Memory 0 Bar Size. - * Inputs: N/A - * Returns: PCI0 Memory 0 Bar Size. - */ - -static unsigned int pci0GetMemory0Size(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI0M0LD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI0M0HD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci0GetMemory1Base - Return PCI0 Memory 1 Base Address. - * Inputs: N/A - * Returns: PCI0 Memory 1 Base Address. - */ - -static unsigned int pci0GetMemory1Base(void) -{ - unsigned int base; - GT_READ(GT_PCI0M1LD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci0GetMemory1Size - Return PCI0 Memory 1 Bar Size. - * Inputs: N/A - * Returns: PCI0 Memory 1 Bar Size. - */ - -static unsigned int pci0GetMemory1Size(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI0M1LD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI0M1HD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci1GetIOspaceBase - Return PCI1 IO Base Address. - * Inputs: N/A - * Returns: PCI1 IO Base Address. - */ - -static unsigned int pci1GetIOspaceBase(void) -{ - unsigned int base; - GT_READ(GT_PCI1IOLD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci1GetIOspaceSize - Return PCI1 IO Bar Size. - * Inputs: N/A - * Returns: PCI1 IO Bar Size. - */ - -static unsigned int pci1GetIOspaceSize(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI1IOLD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI1IOHD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci1GetMemory0Base - Return PCI1 Memory 0 Base Address. - * Inputs: N/A - * Returns: PCI1 Memory 0 Base Address. - */ - -static unsigned int pci1GetMemory0Base(void) -{ - unsigned int base; - GT_READ(GT_PCI1M0LD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci1GetMemory0Size - Return PCI1 Memory 0 Bar Size. - * Inputs: N/A - * Returns: PCI1 Memory 0 Bar Size. - */ - -static unsigned int pci1GetMemory0Size(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI1M1LD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI1M1HD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - -/* - * pci1GetMemory1Base - Return PCI1 Memory 1 Base Address. - * Inputs: N/A - * Returns: PCI1 Memory 1 Base Address. - */ - -static unsigned int pci1GetMemory1Base(void) -{ - unsigned int base; - GT_READ(GT_PCI1M1LD_OFS, &base); - base = base << 21; - return base; -} - -/* - * pci1GetMemory1Size - Return PCI1 Memory 1 Bar Size. - * Inputs: N/A - * Returns: PCI1 Memory 1 Bar Size. - */ - -static unsigned int pci1GetMemory1Size(void) -{ - unsigned int top, base, size; - GT_READ(GT_PCI1M1LD_OFS, &base); - base = base << 21; - GT_READ(GT_PCI1M1HD_OFS, &top); - top = (top << 21); - size = ((top - base) & 0xfffffff); - size = size | 0x1fffff; - return (size + 1); -} - - - -/* - * pci_range_ck - - * - * Check if the pci device that are trying to access does really exists - * on the evaluation board. - * - * Inputs : - * bus - bus number (0 for PCI 0 ; 1 for PCI 1) - * dev - number of device on the specific pci bus - * - * Outpus : - * 0 - if OK , 1 - if failure - */ -static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev) -{ - /* - * We don't even pretend to handle other busses than bus 0 correctly. - * Accessing device 31 crashes the CP7000 for some reason. - */ - if ((bus == 0) && (dev != 31)) - return 0; - return -1; -} - -/* * pciXReadConfigReg - Read from a PCI configuration register - * - Make sure the GT is configured as a master before + * - Make sure the GT is configured as a master before * reading from another device on the PCI. * - The function takes care of Big/Little endian conversion. * INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI * spec) - * pciDevNum: The device number needs to be addressed. - * RETURNS: data , if the data == 0xffffffff check the master abort bit in the + * pciDevNum: The device number needs to be addressed. + * RETURNS: data , if the data == 0xffffffff check the master abort bit in the * cause register to make sure the data is valid * * Configuration Address 0xCF8: @@ -496,59 +76,21 @@ * check gives enough time for the address to stabilize, so the READ * can work. */ - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - GT_READ(GT_PCI0_CFGDATA_OFS, &data); - return data; - } else { /* The PCI is working in LE Mode so swap the Data. */ - GT_READ(GT_PCI0_CFGDATA_OFS, &data); - return cpu_to_le32(data); - } + if (PCI_SLOT(device->devfn) == SELF) /* This board */ + return GT_READ(GT_PCI0_CFGDATA_OFS); + else /* PCI is little endian so swap the Data. */ + return __GT_READ(GT_PCI0_CFGDATA_OFS); } -static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device) -{ - unsigned int DataForRegCf8; - unsigned int data; - - DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | - (PCI_FUNC(device->devfn) << 8) | - (offset & ~0x3)) | 0x80000000; - /* - * The casual observer might wonder why the READ is duplicated here, - * rather than immediately following the WRITE, and just have the - * swap in the "if". That's because there is a latency problem - * with trying to read immediately after setting up the address - * register. The "if" check gives enough time for the address - * to stabilize, so the READ can work. - */ - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - /* when configurating our own PCI 1 L-unit the access is through - the PCI 0 interface with reg number = reg number + 0x80 */ - DataForRegCf8 |= 0x80; - GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); - } else { /* The PCI is working in LE Mode so swap the Data. */ - GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8); - } - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - GT_READ(GT_PCI0_CFGDATA_OFS, &data); - return data; - } else { - GT_READ(GT_PCI1_CFGDATA_OFS, &data); - return cpu_to_le32(data); - } -} - - - /* * pciXWriteConfigReg - Write to a PCI configuration register - * - Make sure the GT is configured as a master before + * - Make sure the GT is configured as a master before * writingto another device on the PCI. * - The function takes care of Big/Little endian conversion. * Inputs: unsigned int regOffset: The register offset as it apears in the - * GT spec + * GT spec * (or any other PCI device spec) - * pciDevNum: The device number needs to be addressed. + * pciDevNum: The device number needs to be addressed. * * Configuration Address 0xCF8: * @@ -566,356 +108,13 @@ (PCI_FUNC(device->devfn) << 8) | (offset & ~0x3)) | 0x80000000; GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - GT_WRITE(GT_PCI0_CFGDATA_OFS, data); - } else { /* configuration Transaction over the pci. */ - /* The PCI is working in LE Mode so swap the Data. */ - GT_WRITE(GT_PCI0_CFGDATA_OFS, le32_to_cpu(data)); - } -} - -static void pci1WriteConfigReg(unsigned int offset, - struct pci_dev *device, unsigned int data) -{ - unsigned int DataForRegCf8; - DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | - (PCI_FUNC(device->devfn) << 8) | - (offset & ~0x3)) | 0x80000000; - /* - * There is a latency problem - * with trying to read immediately after setting up the address - * register. The "if" check gives enough time for the address - * to stabilize, so the WRITE can work. - */ - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ - /* - * when configurating our own PCI 1 L-unit the access is through - * the PCI 0 interface with reg number = reg number + 0x80 - */ - DataForRegCf8 |= 0x80; - GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); - } else { /* configuration Transaction over the pci. */ - /* The PCI is working in LE Mode so swap the Data. */ - GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8); - } - if (PCI_SLOT(device->devfn) == SELF) { /* This board */ + if (PCI_SLOT(device->devfn) == SELF) /* This board */ GT_WRITE(GT_PCI0_CFGDATA_OFS, data); - } else { /* configuration Transaction over the pci. */ - GT_WRITE(GT_PCI1_CFGADDR_OFS, le32_to_cpu(data)); - } -} - - -/* - * galileo_pcibios_(read/write)_config_(dword/word/byte) - - * - * reads/write a dword/word/byte register from the configuration space - * of a device. - * - * Inputs : - * bus - bus number - * dev - device number - * offset - register offset in the configuration space - * val - value to be written / read - * - * Outputs : - * PCIBIOS_SUCCESSFUL when operation was succesfull - * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous - * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned - */ - -static int galileo_pcibios_read_config_dword(struct pci_dev *device, - int offset, u32 * val) -{ - int dev, bus; - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) { - *val = 0xffffffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - if (offset & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == 0) - *val = pci0ReadConfigReg(offset, device); - - /* This is so that the upper PCI layer will get the correct return value if - we're not attached to anything. */ - if ((offset == 0) && (*val == 0xffffffff)) { - return PCIBIOS_DEVICE_NOT_FOUND; - } - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_read_config_word(struct pci_dev *device, - int offset, u16 * val) -{ - int dev, bus; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) { - *val = 0xffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - if (offset & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (bus == 0) - *val = - (unsigned short) (pci0ReadConfigReg(offset, device) >> - ((offset & ~0x3) * 8)); - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_read_config_byte(struct pci_dev *device, - int offset, u8 * val) -{ - int dev, bus; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) { - *val = 0xff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - - if (bus == 0) - *val = - (unsigned char) (pci0ReadConfigReg(offset, device) >> - ((offset & ~0x3) * 8)); - - /* - * This is so that the upper PCI layer will get the correct return - * value if we're not attached to anything. - */ - if ((offset == 0xe) && (*val == 0xff)) { - u32 MasterAbort; - GT_READ(GT_INTRCAUSE_OFS, &MasterAbort); - if (MasterAbort & 0x40000) { - GT_WRITE(GT_INTRCAUSE_OFS, - (MasterAbort & 0xfffbffff)); - return PCIBIOS_DEVICE_NOT_FOUND; - } - } - - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_write_config_dword(struct pci_dev *device, - int offset, u32 val) -{ - int dev, bus; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == 0) - pci0WriteConfigReg(offset, device, val); -// if (bus == 1) pci1WriteConfigReg (offset,device,val); - - return PCIBIOS_SUCCESSFUL; + else /* configuration Transaction over the pci. */ + __GT_WRITE(GT_PCI0_CFGDATA_OFS, data); } - -static int galileo_pcibios_write_config_word(struct pci_dev *device, - int offset, u16 val) -{ - int dev, bus; - unsigned long tmp; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == 0) - tmp = pci0ReadConfigReg(offset, device); -// if (bus == 1) tmp = pci1ReadConfigReg (offset,device); - - if ((offset % 4) == 0) - tmp = (tmp & 0xffff0000) | (val & 0xffff); - if ((offset % 4) == 2) - tmp = (tmp & 0x0000ffff) | ((val & 0xffff) << 16); - - if (bus == 0) - pci0WriteConfigReg(offset, device, tmp); -// if (bus == 1) pci1WriteConfigReg (offset,device,tmp); - return PCIBIOS_SUCCESSFUL; -} - -static int galileo_pcibios_write_config_byte(struct pci_dev *device, - int offset, u8 val) -{ - int dev, bus; - unsigned long tmp; - - bus = device->bus->number; - dev = PCI_SLOT(device->devfn); - - if (pci_range_ck(bus, dev)) - return PCIBIOS_DEVICE_NOT_FOUND; - if (bus == 0) - tmp = pci0ReadConfigReg(offset, device); -// if (bus == 1) tmp = pci1ReadConfigReg (offset,device); - - if ((offset % 4) == 0) - tmp = (tmp & 0xffffff00) | (val & 0xff); - if ((offset % 4) == 1) - tmp = (tmp & 0xffff00ff) | ((val & 0xff) << 8); - if ((offset % 4) == 2) - tmp = (tmp & 0xff00ffff) | ((val & 0xff) << 16); - if ((offset % 4) == 3) - tmp = (tmp & 0x00ffffff) | ((val & 0xff) << 24); - - if (bus == 0) - pci0WriteConfigReg(offset, device, tmp); -// if (bus == 1) pci1WriteConfigReg (offset,device,tmp); - - return PCIBIOS_SUCCESSFUL; -} - -static void galileo_pcibios_set_master(struct pci_dev *dev) -{ - u16 cmd; - - galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MASTER; - galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd); -} - -/* Externally-expected functions. Do not change function names */ - -int pcibios_enable_resources(struct pci_dev *dev) -{ - u16 cmd, old_cmd; - u8 tmp1; - int idx; - struct resource *r; - - galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - for (idx = 0; idx < 6; idx++) { - r = &dev->resource[idx]; - if (!r->start && r->end) { - printk(KERN_ERR - "PCI: Device %s not available because of " - "resource collisions\n", dev->slot_name); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (cmd != old_cmd) { - galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd); - } - - /* - * Let's fix up the latency timer and cache line size here. Cache - * line size = 32 bytes / sizeof dword (4) = 8. - * Latency timer must be > 8. 32 is random but appears to work. - */ - galileo_pcibios_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1); - if (tmp1 != 8) { - printk(KERN_WARNING "PCI setting cache line size to 8 from " - "%d\n", tmp1); - galileo_pcibios_write_config_byte(dev, PCI_CACHE_LINE_SIZE, - 8); - } - galileo_pcibios_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp1); - if (tmp1 < 32) { - printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n", - tmp1); - galileo_pcibios_write_config_byte(dev, PCI_LATENCY_TIMER, - 32); - } - - return 0; -} - -int pcibios_enable_device(struct pci_dev *dev) -{ - return pcibios_enable_resources(dev); -} - -void pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - u32 new, check; - int reg; - - return; - - new = res->start | (res->flags & PCI_REGION_FLAG_MASK); - if (resource < 6) { - reg = PCI_BASE_ADDRESS_0 + 4 * resource; - } else if (resource == PCI_ROM_RESOURCE) { - res->flags |= PCI_ROM_ADDRESS_ENABLE; - reg = dev->rom_base_reg; - } else { - /* - * Somebody might have asked allocation of a non-standard - * resource - */ - return; - } - - pci_write_config_dword(dev, reg, new); - pci_read_config_dword(dev, reg, &check); - if ((new ^ check) & - ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : - PCI_BASE_ADDRESS_MEM_MASK)) { - printk(KERN_ERR "PCI: Error while updating region " - "%s/%d (%08x != %08x)\n", dev->slot_name, resource, - new, check); - } -} - -void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ - struct pci_dev *dev = data; - - if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; - - /* We need to avoid collisions with `mirrored' VGA ports - and other strange ISA hardware, so we always want the - addresses kilobyte aligned. */ - if (size > 0x100) { - printk(KERN_ERR "PCI: I/O Region %s/%d too large" - " (%ld bytes)\n", dev->slot_name, - dev->resource - res, size); - } - - start = (start + 1024 - 1) & ~(1024 - 1); - res->start = start; - } -} - -struct pci_ops galileo_pci_ops = { - galileo_pcibios_read_config_byte, - galileo_pcibios_read_config_word, - galileo_pcibios_read_config_dword, - galileo_pcibios_write_config_byte, - galileo_pcibios_write_config_word, - galileo_pcibios_write_config_dword -}; - struct pci_fixup pcibios_fixups[] = { {0} }; @@ -925,174 +124,7 @@ gt64120_board_pcibios_fixup_bus(c); } -/* - * This code was derived from Galileo Technology's example - * and significantly reworked. - * - * This is very simple. It does not scan multiple function devices. It does - * not scan behind bridges. Those would be simple to implement, but we don't - * currently need this. - */ - -static void __init scan_and_initialize_pci(void) -{ - struct pci_device pci_devices[MAX_PCI_DEVS]; - - if (scan_pci_bus(pci_devices)) { - allocate_pci_space(pci_devices); - } -} - -/* - * This is your basic PCI scan. It goes through each slot and checks to - * see if there's something that responds. If so, then get the size and - * type of each of the responding BARs. Save them for later. - */ - -static u32 __init scan_pci_bus(struct pci_device *pci_devices) -{ - u32 arrayCounter = 0; - u32 memType; - u32 memSize; - u32 pci_slot, bar; - u32 id; - u32 c18RegValue; - struct pci_dev device; - - /* - * According to PCI REV 2.1 MAX agents on the bus are 21. - * We don't bother scanning ourselves (slot 0). - */ - for (pci_slot = 1; pci_slot < 22; pci_slot++) { - - device.devfn = PCI_DEVFN(pci_slot, 0); - id = pci0ReadConfigReg(PCI_VENDOR_ID, &device); - - /* - * Check for a PCI Master Abort (nothing responds in the - * slot) - */ - GT_READ(GT_INTRCAUSE_OFS, &c18RegValue); - /* - * Clearing bit 18 of in the Cause Register 0xc18 by - * writting 0. - */ - GT_WRITE(GT_INTRCAUSE_OFS, (c18RegValue & 0xfffbffff)); - if ((id != 0xffffffff) && !(c18RegValue & 0x40000)) { - pci_devices[arrayCounter].slot = pci_slot; - for (bar = 0; bar < 6; bar++) { - memType = - pci0ReadConfigReg(PCI_BASE_ADDRESS_0 + - (bar * 4), &device); - pci_devices[arrayCounter].BARtype[bar] = - memType & 1; - pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + - (bar * 4), &device, - 0xffffffff); - memSize = - pci0ReadConfigReg(PCI_BASE_ADDRESS_0 + - (bar * 4), &device); - if (memType & 1) { /* IO space */ - pci_devices[arrayCounter]. - BARsize[bar] = - ~(memSize & 0xfffffffc) + 1; - } else { /* memory space */ - pci_devices[arrayCounter]. - BARsize[bar] = - ~(memSize & 0xfffffff0) + 1; - } - } /* BAR counter */ - - arrayCounter++; - } - /* found a device */ - } /* slot counter */ - - if (arrayCounter < MAX_PCI_DEVS) - pci_devices[arrayCounter].slot = -1; - - return arrayCounter; -} - -#define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1)) -#define MAX(val1, val2) ((val1) > (val2) ? (val1) : (val2)) - -/* - * This function goes through the list of devices and allocates the BARs in - * either IO or MEM space. It does it in order of size, which will limit the - * amount of fragmentation we have in the IO and MEM spaces. - */ - -static void __init allocate_pci_space(struct pci_device *pci_devices) -{ - u32 count, maxcount, bar; - u32 maxSize, maxDevice, maxBAR; - u32 alignto; - u32 base; - u32 pci0_mem_base = pci0GetMemory0Base(); - u32 pci0_io_base = pci0GetIOspaceBase(); - struct pci_dev device; - - /* How many PCI devices do we have? */ - maxcount = MAX_PCI_DEVS; - for (count = 0; count < MAX_PCI_DEVS; count++) { - if (pci_devices[count].slot == -1) { - maxcount = count; - break; - } - } - - do { - /* Find the largest size BAR we need to allocate */ - maxSize = 0; - for (count = 0; count < maxcount; count++) { - for (bar = 0; bar < 6; bar++) { - if (pci_devices[count].BARsize[bar] > - maxSize) { - maxSize = - pci_devices[count]. - BARsize[bar]; - maxDevice = count; - maxBAR = bar; - } - } - } - - /* - * We've found the largest BAR. Allocate it into IO or - * mem space. We don't idiot check the bases to make - * sure they haven't overflowed the current size for that - * aperture. - * Don't bother to enable the device's IO or MEM space here. - * That will be done in pci_enable_resources if the device is - * activated by a driver. - */ - if (maxSize) { - device.devfn = - PCI_DEVFN(pci_devices[maxDevice].slot, 0); - if (pci_devices[maxDevice].BARtype[maxBAR] == 1) { - alignto = MAX(0x1000, maxSize); - base = ALIGN(pci0_io_base, alignto); - pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + - (maxBAR * 4), &device, - base | 0x1); - pci0_io_base = base + alignto; - } else { - alignto = MAX(0x1000, maxSize); - base = ALIGN(pci0_mem_base, alignto); - pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + - (maxBAR * 4), &device, - base); - pci0_mem_base = base + alignto; - } - /* - * This entry is finished. Remove it from the list - * we'll scan. - */ - pci_devices[maxDevice].BARsize[maxBAR] = 0; - } - } while (maxSize); -} +extern struct pci_ops gt64120_pci_ops; void __init pcibios_init(void) { @@ -1101,8 +133,8 @@ controller.devfn = SELF; - GT_READ(GT_PCI0_CMD_OFS, &tmp); - GT_READ(GT_PCI0_BARE_OFS, &tmp); + tmp = GT_READ(GT_PCI0_CMD_OFS); /* Huh??? -- Ralf */ + tmp = GT_READ(GT_PCI0_BARE_OFS); /* * You have to enable bus mastering to configure any other @@ -1112,34 +144,18 @@ tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR; pci0WriteConfigReg(PCI_COMMAND, &controller, tmp); - /* This scans the PCI bus and sets up initial values. */ - scan_and_initialize_pci(); - /* * Reset PCI I/O and PCI MEM values to ones supported by EVM. */ - ioport_resource.start = GT_PCI_IO_BASE; - ioport_resource.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1; - iomem_resource.start = GT_PCI_MEM_BASE; - iomem_resource.end = GT_PCI_MEM_BASE + GT_PCI_MEM_BASE - 1; + ioport_resource.start = GT_PCI_IO_BASE; + ioport_resource.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1; + iomem_resource.start = GT_PCI_MEM_BASE; + iomem_resource.end = GT_PCI_MEM_BASE + GT_PCI_MEM_SIZE - 1; - pci_scan_bus(0, &galileo_pci_ops, NULL); -} - -/* - * for parsing "pci=" kernel boot arguments. - */ -char *pcibios_setup(char *str) -{ - printk(KERN_INFO "rr: pcibios_setup\n"); - /* Nothing to do for now. */ - - return str; + pci_scan_bus(0, >64120_pci_ops, NULL); } unsigned __init int pcibios_assign_all_busses(void) { return 1; } - -#endif /* CONFIG_PCI */ diff -urN linux-2.4.21-bk37/arch/mips/gt64120/common/time.c linux-2.4.21-bk38/arch/mips/gt64120/common/time.c --- linux-2.4.21-bk37/arch/mips/gt64120/common/time.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/gt64120/common/time.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,98 @@ +/* + * 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. + * + * Galileo Technology chip interrupt handler + */ +#include +#include +#include +#include +#include +#include +#include + +/* + * These are interrupt handlers for the GT on-chip interrupts. They all come + * in to the MIPS on a single interrupt line, and have to be handled and ack'ed + * differently than other MIPS interrupts. + */ + +static void gt64120_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned int irq_src, int_high_src, irq_src_mask, int_high_src_mask; + int handled = 0; + + irq_src = GT_READ(GT_INTRCAUSE_OFS); + irq_src_mask = GT_READ(GT_INTRMASK_OFS); + int_high_src = GT_READ(GT_HINTRCAUSE_OFS); + int_high_src_mask = GT_READ(GT_HINTRMASK_OFS); + irq_src = irq_src & irq_src_mask; + int_high_src = int_high_src & int_high_src_mask; + + if (irq_src & 0x00000800) { /* Check for timer interrupt */ + handled = 1; + irq_src &= ~0x00000800; + do_timer(regs); + } + + GT_WRITE(GT_INTRCAUSE_OFS, 0); + GT_WRITE(GT_HINTRCAUSE_OFS, 0); +} + +/* + * Initializes timer using galileo's built in timer. + */ +#ifdef CONFIG_SYSCLK_100 +#define Sys_clock (100 * 1000000) // 100 MHz +#endif +#ifdef CONFIG_SYSCLK_83 +#define Sys_clock (83.333 * 1000000) // 83.333 MHz +#endif +#ifdef CONFIG_SYSCLK_75 +#define Sys_clock (75 * 1000000) // 75 MHz +#endif + +/* + * This will ignore the standard MIPS timer interrupt handler that is passed in + * as *irq (=irq0 in ../kernel/time.c). We will do our own timer interrupt + * handling. + */ +void gt64120_time_init(void) +{ + extern irq_desc_t irq_desc[NR_IRQS]; + static struct irqaction timer; + + /* Disable timer first */ + GT_WRITE(GT_TC_CONTROL_OFS, 0); + /* Load timer value for 100 Hz */ + GT_WRITE(GT_TC3_OFS, Sys_clock / 100); + + /* + * Create the IRQ structure entry for the timer. Since we're too early + * in the boot process to use the "request_irq()" call, we'll hard-code + * the values to the correct interrupt line. + */ + timer.handler = gt64120_irq; + timer.flags = SA_SHIRQ | SA_INTERRUPT; + timer.name = "timer"; + timer.dev_id = NULL; + timer.next = NULL; + timer.mask = 0; + irq_desc[GT_TIMER].action = &timer; + + enable_irq(GT_TIMER); + + /* Enable timer ints */ + GT_WRITE(GT_TC_CONTROL_OFS, 0xc0); + /* clear Cause register first */ + GT_WRITE(GT_INTRCAUSE_OFS, 0x0); + /* Unmask timer int */ + GT_WRITE(GT_INTRMASK_OFS, 0x800); + /* Clear High int register */ + GT_WRITE(GT_HINTRCAUSE_OFS, 0x0); + /* Mask All interrupts at High cause interrupt */ + GT_WRITE(GT_HINTRMASK_OFS, 0x0); +} diff -urN linux-2.4.21-bk37/arch/mips/gt64120/ev64120/Makefile linux-2.4.21-bk38/arch/mips/gt64120/ev64120/Makefile --- linux-2.4.21-bk37/arch/mips/gt64120/ev64120/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/gt64120/ev64120/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,25 @@ +# +# Copyright 2000 RidgeRun, Inc. +# Author: RidgeRun, Inc. +# glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com +# +# Makefile for the Galileo EV64120 board. +# +# Note! Dependencies are done automagically by 'make dep', which also +# 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 + +all: ev64120.o int-handler.o + +O_TARGET := ev64120.o + +obj-y += serialGT.o int-handler.o promcon.o reset.o setup.o \ + irq.o +obj-$(CONFIG_PCI) += fixup-ev64120.o + +int-handler.o: int-handler.S + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/gt64120/ev64120/fixup-ev64120.c linux-2.4.21-bk38/arch/mips/gt64120/ev64120/fixup-ev64120.c --- linux-2.4.21-bk37/arch/mips/gt64120/ev64120/fixup-ev64120.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/gt64120/ev64120/fixup-ev64120.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,35 @@ +#include +#include + +int pci_range_ck(unsigned char bus, unsigned char dev) +{ + if (((bus == 0) || (bus == 1)) && (dev >= 6) && (dev <= 8)) + return 0; + + return -1; +} + +/* + * After detecting all agents over the PCI , this function is called + * in order to give an interrupt number for each PCI device starting + * from IRQ 20. It does also enables master for each device. + */ +void __init gt64120_board_pcibios_fixup_bus(struct pci_bus *bus) +{ + unsigned int irq = 20; + struct pci_bus *current_bus = bus; + struct pci_dev *dev; + struct list_head *devices_link; + + list_for_each(devices_link, &(current_bus->devices)) { + dev = pci_dev_b(devices_link); + if (dev != NULL) { + dev->irq = irq++; + + /* Assign an interrupt number for the device */ + pcibios_write_config_byte(bus, dev->devfn, + PCI_INTERRUPT_LINE, irq); + pcibios_set_master(dev); + } + } +} diff -urN linux-2.4.21-bk37/arch/mips/gt64120/ev64120/int-handler.S linux-2.4.21-bk38/arch/mips/gt64120/ev64120/int-handler.S --- linux-2.4.21-bk37/arch/mips/gt64120/ev64120/int-handler.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/gt64120/ev64120/int-handler.S 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,113 @@ +/* + * int-handler.S + * + * Based on the cobalt handler. + */ +#include +#include +#include +#include +#include + +/* + * galileo_handle_int - + * We check for the timer first, then check PCI ints A and D. + * Then check for serial IRQ and fall through. + */ + .align 5 + .set reorder + .set noat + NESTED(galileo_handle_int, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + mfc0 t0,CP0_CAUSE + mfc0 t2,CP0_STATUS + + and t0,t2 + + andi t1,t0,STATUSF_IP4 /* int2 hardware line (timer) */ + bnez t1,ll_gt64120_irq + andi t1,t0,STATUSF_IP2 /* int0 hardware line */ + bnez t1,ll_pci_intA + andi t1,t0,STATUSF_IP5 /* int3 hardware line */ + bnez t1,ll_pci_intD + andi t1,t0,STATUSF_IP6 /* int4 hardware line */ + bnez t1,ll_serial_irq + andi t1,t0,STATUSF_IP7 /* compare int */ + bnez t1,ll_compare_irq + nop + + /* wrong alarm or masked ... */ + j spurious_interrupt + nop + END(galileo_handle_int) + + + .align 5 + .set reorder +ll_gt64120_irq: + li a0,4 + move a1,sp + jal do_IRQ + nop + j ret_from_irq + nop + + .align 5 + .set reorder +ll_compare_irq: + li a0,7 + move a1,sp + jal do_IRQ + nop + j ret_from_irq + nop + + .align 5 + .set reorder +ll_pci_intA: + move a0,sp + jal pci_intA + nop + j ret_from_irq + nop + +#if 0 + .align 5 + .set reorder +ll_pci_intB: + move a0,sp + jal pci_intB + nop + j ret_from_irq + nop + + .align 5 + .set reorder +ll_pci_intC: + move a0,sp + jal pci_intC + nop + j ret_from_irq + nop +#endif + + .align 5 + .set reorder +ll_pci_intD: + move a0,sp + jal pci_intD + nop + j ret_from_irq + nop + + .align 5 + .set reorder +ll_serial_irq: + li a0,6 + move a1,sp + jal do_IRQ + nop + j ret_from_irq + nop diff -urN linux-2.4.21-bk37/arch/mips/gt64120/ev64120/irq.c linux-2.4.21-bk38/arch/mips/gt64120/ev64120/irq.c --- linux-2.4.21-bk37/arch/mips/gt64120/ev64120/irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/gt64120/ev64120/irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,145 @@ +/* + * BRIEF MODULE DESCRIPTION + * Code to handle irqs on GT64120A boards + * Derived from mips/orion and Cort + * + * Copyright (C) 2000 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +asmlinkage inline void pci_intA(struct pt_regs *regs) +{ + do_IRQ(GT_INTA, regs); +} + +asmlinkage inline void pci_intD(struct pt_regs *regs) +{ + do_IRQ(GT_INTD, regs); +} + +static void disable_ev64120_irq(unsigned int irq_nr) +{ + unsigned long flags; + + local_irq_save(flags); + if (irq_nr >= 8) { // All PCI interrupts are on line 5 or 2 + clear_c0_status(9 << 10); + } else { + clear_c0_status(1 << (irq_nr + 8)); + } + local_irq_restore(flags); +} + +static void enable_ev64120_irq(unsigned int irq_nr) +{ + unsigned long flags; + + local_irq_save(flags); + if (irq_nr >= 8) // All PCI interrupts are on line 5 or 2 + set_c0_status(9 << 10); + else + set_c0_status(1 << (irq_nr + 8)); + local_irq_restore(flags); +} + +static unsigned int startup_ev64120_irq(unsigned int irq) +{ + enable_ev64120_irq(irq); + return 0; /* Never anything pending */ +} + +#define shutdown_ev64120_irq disable_ev64120_irq +#define mask_and_ack_ev64120_irq disable_ev64120_irq + +static void end_ev64120_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_ev64120_irq(irq); +} + +static struct hw_interrupt_type ev64120_irq_type = { + .typename = "EV64120", + .startup = startup_ev64120_irq, + .shutdown = shutdown_ev64120_irq, + .enable = enable_ev64120_irq, + .disable = disable_ev64120_irq, + .ack = mask_and_ack_ev64120_irq, + .end = end_ev64120_irq, + .set_affinity = NULL +}; + +void gt64120_irq_setup(void) +{ + extern asmlinkage void galileo_handle_int(void); + + /* + * Clear all of the interrupts while we change the able around a bit. + */ + clear_c0_status(ST0_IM); + + /* Sets the exception_handler array. */ + set_except_vector(0, galileo_handle_int); + + cli(); + + /* + * Enable timer. Other interrupts will be enabled as they are + * registered. + */ + set_c0_status(IE_IRQ2); +} + +void __init init_IRQ(void) +{ + int i; + + /* Let's initialize our IRQ descriptors */ + for (i = 0; i < NR_IRQS; i++) { + irq_desc[i].status = 0; + irq_desc[i].handler = &no_irq_type; + irq_desc[i].action = NULL; + irq_desc[i].depth = 0; + irq_desc[i].lock = SPIN_LOCK_UNLOCKED; + } + + gt64120_irq_setup(); +} diff -urN linux-2.4.21-bk37/arch/mips/gt64120/ev64120/promcon.c linux-2.4.21-bk38/arch/mips/gt64120/ev64120/promcon.c --- linux-2.4.21-bk37/arch/mips/gt64120/ev64120/promcon.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/gt64120/ev64120/promcon.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,58 @@ +/* + * Wrap-around code for a console using the + * SGI PROM io-routines. + * + * Copyright (c) 1999 Ulf Carlsson + * + * Derived from DECstation promcon.c + * Copyright (c) 1998 Harald Koerfgen + */ +#include +#include +#include +#include +#include +#include + +static void prom_console_write(struct console *co, const char *s, + unsigned count) +{ + extern int CONSOLE_CHANNEL; // The default serial port + unsigned i; + + for (i = 0; i < count; i++) { + if (*s == 10) + serial_putc(CONSOLE_CHANNEL, 13); + serial_putc(CONSOLE_CHANNEL, *s++); + } +} + +int prom_getchar(void) +{ + return 0; +} + +static kdev_t prom_console_device(struct console *c) +{ + return MKDEV(TTY_MAJOR, 64 + c->index); +} + +static struct console sercons = { + .name = "ttyS", + .write = prom_console_write, + .device = prom_console_device, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +/* + * Register console. + */ + +void gal_serial_console_init(void) +{ + // serial_init(); + //serial_set(115200); + + register_console(&sercons); +} diff -urN linux-2.4.21-bk37/arch/mips/gt64120/ev64120/reset.c linux-2.4.21-bk38/arch/mips/gt64120/ev64120/reset.c --- linux-2.4.21-bk37/arch/mips/gt64120/ev64120/reset.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/gt64120/ev64120/reset.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,45 @@ +/* + * 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. + * + * Copyright (C) 1997 Ralf Baechle + */ +#include +#include +#include +#include +#include +#include +#include + +void galileo_machine_restart(char *command) +{ + *(volatile char *) 0xbc000000 = 0x0f; + /* + * Ouch, we're still alive ... This time we take the silver bullet ... + * ... and find that we leave the hardware in a state in which the + * kernel in the flush locks up somewhen during of after the PCI + * detection stuff. + */ + set_c0_status(ST0_BEV | ST0_ERL); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + flush_cache_all(); + write_c0_wired(0); + __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); +} + +void galileo_machine_halt(void) +{ + printk(KERN_NOTICE "You can safely turn off the power\n"); + while (1) + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); + +} + +void galileo_machine_power_off(void) +{ + galileo_machine_halt(); +} diff -urN linux-2.4.21-bk37/arch/mips/gt64120/ev64120/serialGT.c linux-2.4.21-bk38/arch/mips/gt64120/ev64120/serialGT.c --- linux-2.4.21-bk37/arch/mips/gt64120/ev64120/serialGT.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/gt64120/ev64120/serialGT.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,212 @@ +/* + * serialGT.c + * + * BRIEF MODULE DESCRIPTION + * Low Level Serial Port control for use + * with the Galileo EVB64120A MIPS eval board and + * its on board two channel 16552 Uart. + * + * Copyright (C) 2000 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +// Note: +// Serial CHANNELS - 0 is the bottom connector of evb64120A. +// (The one that maps to the "B" channel of the +// board's uart) +// 1 is the top connector of evb64120A. +// (The one that maps to the "A" channel of the +// board's uart) +int DEBUG_CHANNEL = 0; // See Note Above +int CONSOLE_CHANNEL = 1; // See Note Above + +#define DUART 0xBD000000 /* Base address of Uart. */ +#define CHANNELOFFSET 0x20 /* DUART+CHANNELOFFSET gets you to the ChanA + register set of the 16552 Uart device. + DUART+0 gets you to the ChanB register set. + */ +#define DUART_DELTA 0x4 +#define FIFO_ENABLE 0x07 +#define INT_ENABLE 0x04 /* default interrupt mask */ + +#define RBR 0x00 +#define THR 0x00 +#define DLL 0x00 +#define IER 0x01 +#define DLM 0x01 +#define IIR 0x02 +#define FCR 0x02 +#define LCR 0x03 +#define MCR 0x04 +#define LSR 0x05 +#define MSR 0x06 +#define SCR 0x07 + +#define LCR_DLAB 0x80 +#define XTAL 1843200 +#define LSR_THRE 0x20 +#define LSR_BI 0x10 +#define LSR_DR 0x01 +#define MCR_LOOP 0x10 +#define ACCESS_DELAY 0x10000 + +/****************************** + Routine: + Description: + ******************************/ +int inreg(int channel, int reg) +{ + int val; + val = + *((volatile unsigned char *) DUART + + (channel * CHANNELOFFSET) + (reg * DUART_DELTA)); + return val; +} + +/****************************** + Routine: + Description: + ******************************/ +void outreg(int channel, int reg, unsigned char val) +{ + *((volatile unsigned char *) DUART + (channel * CHANNELOFFSET) + + (reg * DUART_DELTA)) = val; +} + +/****************************** + Routine: + Description: + Initialize the device driver. + ******************************/ +void serial_init(int channel) +{ + /* + * Configure active port, (CHANNELOFFSET already set.) + * + * Set 8 bits, 1 stop bit, no parity. + * + * LCR<7> 0 divisor latch access bit + * LCR<6> 0 break control (1=send break) + * LCR<5> 0 stick parity (0=space, 1=mark) + * LCR<4> 0 parity even (0=odd, 1=even) + * LCR<3> 0 parity enable (1=enabled) + * LCR<2> 0 # stop bits (0=1, 1=1.5) + * LCR<1:0> 11 bits per character(00=5, 01=6, 10=7, 11=8) + */ + outreg(channel, LCR, 0x3); + + outreg(channel, FCR, FIFO_ENABLE); /* Enable the FIFO */ + + outreg(channel, IER, INT_ENABLE); /* Enable appropriate interrupts */ +} + +/****************************** + Routine: + Description: + Set the baud rate. + ******************************/ +void serial_set(int channel, unsigned long baud) +{ + unsigned char sav_lcr; + + /* + * Enable access to the divisor latches by setting DLAB in LCR. + * + */ + sav_lcr = inreg(channel, LCR); + +#if 0 + /* + * Set baud rate + */ + outreg(channel, LCR, LCR_DLAB | sav_lcr); + // outreg(DLL,(XTAL/(16*2*(baud))-2)); + outreg(channel, DLL, XTAL / (16 * baud)); + // outreg(DLM,(XTAL/(16*2*(baud))-2)>>8); + outreg(channel, DLM, (XTAL / (16 * baud)) >> 8); +#else + /* + * Note: Set baud rate, hardcoded here for rate of 115200 + * since became unsure of above "buad rate" algorithm (??). + */ + outreg(channel, LCR, 0x83); + outreg(channel, DLM, 0x00); // See note above + outreg(channel, DLL, 0x02); // See note above. + outreg(channel, LCR, 0x03); +#endif + + /* + * Restore line control register + */ + outreg(channel, LCR, sav_lcr); +} + + +/****************************** + Routine: + Description: + Transmit a character. + ******************************/ +void serial_putc(int channel, int c) +{ + while ((inreg(channel, LSR) & LSR_THRE) == 0); + outreg(channel, THR, c); +} + +/****************************** + Routine: + Description: + Read a received character if one is + available. Return -1 otherwise. + ******************************/ +int serial_getc(int channel) +{ + if (inreg(channel, LSR) & LSR_DR) { + return inreg(channel, RBR); + } + return -1; +} + +/****************************** + Routine: + Description: + Used by embedded gdb client. (example; gdb-stub.c) + ******************************/ +char getDebugChar() +{ + int val; + while ((val = serial_getc(DEBUG_CHANNEL)) == -1); // loop until we get a character in. + return (char) val; +} + +/****************************** + Routine: + Description: + Used by embedded gdb target. (example; gdb-stub.c) + ******************************/ +void putDebugChar(char c) +{ + serial_putc(DEBUG_CHANNEL, (int) c); +} diff -urN linux-2.4.21-bk37/arch/mips/gt64120/ev64120/setup.c linux-2.4.21-bk38/arch/mips/gt64120/ev64120/setup.c --- linux-2.4.21-bk37/arch/mips/gt64120/ev64120/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/gt64120/ev64120/setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2000 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +unsigned long gt64120_base = KSEG1ADDR(0x14000000); + +extern struct rtc_ops no_rtc_ops; + +/* These functions are used for rebooting or halting the machine*/ +extern void galileo_machine_restart(char *command); +extern void galileo_machine_halt(void); +extern void galileo_machine_power_off(void); +/* + *This structure holds pointers to the pci configuration space accesses + *and interrupts allocating routine for device over the PCI + */ +extern struct pci_ops galileo_pci_ops; + +char arcs_cmdline[CL_SIZE] = { + "console=ttyS0,115200 " + "root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/disk2/fs.gal " + "ip=192.168.1.211:192.168.1.1:::gt::" +}; + +void prom_free_prom_memory(void) +{ +} + +static unsigned char galileo_rtc_read_data(unsigned long addr) +{ + return 0; +} + +static void galileo_rtc_write_data(unsigned char data, unsigned long addr) +{ +} + +static int galileo_rtc_bcd_mode(void) +{ + return 0; +} + +struct rtc_ops galileo_rtc_ops = { + &galileo_rtc_read_data, + &galileo_rtc_write_data, + &galileo_rtc_bcd_mode +}; + + +/* + * Initializes basic routines and structures pointers, memory size (as + * given by the bios and saves the command line. + */ +extern void gt64120_time_init(void); + +void ev64120_setup(void) +{ + _machine_restart = galileo_machine_restart; + _machine_halt = galileo_machine_halt; + _machine_power_off = galileo_machine_power_off; + + rtc_ops = &galileo_rtc_ops; + + board_time_init = gt64120_time_init; + set_io_port_base(KSEG1); +} + +const char *get_system_type(void) +{ + return "Galileo EV64120A"; +} + +/* + * SetUpBootInfo - + * + * This function is called at very first stages of kernel startup. + * It specifies for the kernel the evaluation board that the linux + * is running on. Then it saves the eprom parameters that holds the + * command line, memory size etc... + * + * Inputs : + * argc - nothing + * argv - holds a pointer to the eprom parameters + * envp - nothing + */ + +void SetUpBootInfo(int argc, char **argv, char **envp) +{ + mips_machgroup = MACH_GROUP_GALILEO; + mips_machtype = MACH_EV64120A; +} + +void __init prom_init(int a, char **b, char **c, int *d) +{ + mips_machgroup = MACH_GROUP_GALILEO; + add_memory_region(0, 32 << 20, BOOT_MEM_RAM); +} diff -urN linux-2.4.21-bk37/arch/mips/gt64120/momenco_ocelot/Makefile linux-2.4.21-bk38/arch/mips/gt64120/momenco_ocelot/Makefile --- linux-2.4.21-bk37/arch/mips/gt64120/momenco_ocelot/Makefile 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/gt64120/momenco_ocelot/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -6,15 +6,13 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true O_TARGET:= momenco_ocelot.o -obj-y += int-handler.o irq.o pci.o prom.o reset.o setup.o +obj-y += int-handler.o irq.o prom.o reset.o setup.o -obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o +obj-$(CONFIG_KGDB) += dbg_io.o +obj-$(CONFIG_PCI) += fixup-ocelot.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/gt64120/momenco_ocelot/dbg_io.c linux-2.4.21-bk38/arch/mips/gt64120/momenco_ocelot/dbg_io.c --- linux-2.4.21-bk37/arch/mips/gt64120/momenco_ocelot/dbg_io.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/gt64120/momenco_ocelot/dbg_io.c 2003-08-24 02:55:57.000000000 -0700 @@ -1,6 +1,6 @@ #include -#if defined(CONFIG_REMOTE_DEBUG) +#if defined(CONFIG_KGDB) #include /* For the serial port location and base baud */ diff -urN linux-2.4.21-bk37/arch/mips/gt64120/momenco_ocelot/fixup-ocelot.c linux-2.4.21-bk38/arch/mips/gt64120/momenco_ocelot/fixup-ocelot.c --- linux-2.4.21-bk37/arch/mips/gt64120/momenco_ocelot/fixup-ocelot.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/gt64120/momenco_ocelot/fixup-ocelot.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,87 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * arch/mips/gt64120/momenco_ocelot/pci.c + * Board-specific PCI routines for gt64120 controller. + * + * 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. + */ +#include +#include +#include +#include +#include +#include + +static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev) +{ + /* + * We don't even pretend to handle other busses than bus 0 correctly. + * Accessing device 31 crashes the CP7000 for some reason. + */ + if ((bus == 0) && (dev != 31)) + return 0; + + return -1; +} + + +void __init gt64120_board_pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_bus *current_bus = bus; + struct pci_dev *devices; + struct list_head *devices_link; + u16 cmd; + + list_for_each(devices_link, &(current_bus->devices)) { + + devices = pci_dev_b(devices_link); + if (devices == NULL) + continue; + + if (PCI_SLOT(devices->devfn) == 1) { + /* + * Slot 1 is primary ether port, i82559 + * we double-check against that assumption + */ + if ((devices->vendor != 0x8086) || + (devices->device != 0x1209) ) { + panic("gt64120_board_pcibios_fixup_bus: found " + "unexpected PCI device in slot 1."); + } + devices->irq = 2; /* irq_nr is 2 for INT0 */ + } else if (PCI_SLOT(devices->devfn) == 2) { + /* + * Slot 2 is secondary ether port, i21143 + * we double-check against that assumption + */ + if ((devices->vendor != 0x1011) || + (devices->device != 0x19) ) { + panic("gt64120_board_pcibios_fixup_bus: " + "found unexpected PCI device in slot 2."); + } + devices->irq = 3; /* irq_nr is 3 for INT1 */ + } else if (PCI_SLOT(devices->devfn) == 4) { + /* PMC Slot 1 */ + devices->irq = 8; /* irq_nr is 8 for INT6 */ + } else if (PCI_SLOT(devices->devfn) == 5) { + /* PMC Slot 1 */ + devices->irq = 9; /* irq_nr is 9 for INT7 */ + } else { + /* We don't have assign interrupts for other devices. */ + devices->irq = 0xff; + } + + /* Assign an interrupt number for the device */ + bus->ops->write_byte(devices, PCI_INTERRUPT_LINE, devices->irq); + + /* enable master */ + bus->ops->read_word(devices, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER; + bus->ops->write_word(devices, PCI_COMMAND, cmd); + } +} diff -urN linux-2.4.21-bk37/arch/mips/gt64120/momenco_ocelot/int-handler.S linux-2.4.21-bk38/arch/mips/gt64120/momenco_ocelot/int-handler.S --- linux-2.4.21-bk37/arch/mips/gt64120/momenco_ocelot/int-handler.S 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/gt64120/momenco_ocelot/int-handler.S 2003-08-24 02:55:57.000000000 -0700 @@ -9,7 +9,6 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ -#include #include #include #include @@ -26,11 +25,11 @@ SAVE_ALL CLI .set at - mfc0 t0, CP0_CAUSE + mfc0 t0, CP0_CAUSE mfc0 t2, CP0_STATUS and t0, t2 - + andi t1, t0, STATUSF_IP2 /* int0 hardware line */ bnez t1, ll_pri_enet_irq andi t1, t0, STATUSF_IP3 /* int1 hardware line */ @@ -45,7 +44,7 @@ bnez t1, ll_cputimer_irq /* now look at the extended interrupts */ - mfc0 t0, CP0_CAUSE + mfc0 t0, CP0_CAUSE cfc0 t1, CP0_S1_INTCONTROL /* shift the mask 8 bits left to line up the bits */ @@ -88,7 +87,7 @@ move a1, sp jal do_IRQ j ret_from_irq - + ll_cpci_irq: li a0, 5 move a1, sp @@ -106,7 +105,7 @@ move a1, sp jal do_IRQ j ret_from_irq - + ll_pmc1_irq: li a0, 8 move a1, sp diff -urN linux-2.4.21-bk37/arch/mips/gt64120/momenco_ocelot/irq.c linux-2.4.21-bk38/arch/mips/gt64120/momenco_ocelot/irq.c --- linux-2.4.21-bk37/arch/mips/gt64120/momenco_ocelot/irq.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/gt64120/momenco_ocelot/irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -28,6 +28,7 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. * */ +#include #include #include #include @@ -60,18 +61,18 @@ /* do the low 8 bits first */ clr_mask = 0xff & clr_mask_in; set_mask = 0xff & set_mask_in; - status = read_32bit_cp0_register(CP0_STATUS); + status = read_c0_status(); status &= ~((clr_mask & 0xFF) << 8); status |= (set_mask & 0xFF) << 8; - write_32bit_cp0_register(CP0_STATUS, status); + write_c0_status(status); /* do the high 8 bits */ clr_mask = 0xff & (clr_mask_in >> 8); set_mask = 0xff & (set_mask_in >> 8); - status = read_32bit_cp0_set1_register(CP0_S1_INTCONTROL); + status = read_c0_intcontrol(); status &= ~((clr_mask & 0xFF) << 8); status |= (set_mask & 0xFF) << 8; - write_32bit_cp0_set1_register(CP0_S1_INTCONTROL, status); + write_c0_intcontrol(status); } static inline void mask_irq(unsigned int irq) @@ -135,7 +136,6 @@ extern asmlinkage void ocelot_handle_int(void); -extern void gt64120_irq_init(void); void __init init_IRQ(void) { @@ -144,7 +144,7 @@ /* * Clear all of the interrupts while we change the able around a bit. */ - clear_cp0_status(ST0_IM); + clear_c0_status(ST0_IM); __cli(); /* Sets the first-level interrupt dispatcher. */ @@ -158,9 +158,7 @@ irq_desc[i].handler = &cp7000_hpcdma_irq_type; } - gt64120_irq_init(); - -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB printk("start kgdb ...\n"); set_debug_traps(); breakpoint(); /* you may move this line to whereever you want :-) */ diff -urN linux-2.4.21-bk37/arch/mips/gt64120/momenco_ocelot/pci.c linux-2.4.21-bk38/arch/mips/gt64120/momenco_ocelot/pci.c --- linux-2.4.21-bk37/arch/mips/gt64120/momenco_ocelot/pci.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/gt64120/momenco_ocelot/pci.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,75 +0,0 @@ -/* - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * arch/mips/gt64120/momenco_ocelot/pci.c - * Board-specific PCI routines for gt64120 controller. - * - * 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. - */ -#include -#include -#include -#include -#include -#include - - -void __init gt64120_board_pcibios_fixup_bus(struct pci_bus *bus) -{ - struct pci_bus *current_bus = bus; - struct pci_dev *devices; - struct list_head *devices_link; - u16 cmd; - - list_for_each(devices_link, &(current_bus->devices)) { - - devices = pci_dev_b(devices_link); - if (devices == NULL) - continue; - - if (PCI_SLOT(devices->devfn) == 1) { - /* - * Slot 1 is primary ether port, i82559 - * we double-check against that assumption - */ - if ((devices->vendor != 0x8086) || - (devices->device != 0x1209) ) { - panic("gt64120_board_pcibios_fixup_bus: found " - "unexpected PCI device in slot 1."); - } - devices->irq = 2; /* irq_nr is 2 for INT0 */ - } else if (PCI_SLOT(devices->devfn) == 2) { - /* - * Slot 2 is secondary ether port, i21143 - * we double-check against that assumption - */ - if ((devices->vendor != 0x1011) || - (devices->device != 0x19) ) { - panic("galileo_pcibios_fixup_bus: " - "found unexpected PCI device in slot 2."); - } - devices->irq = 3; /* irq_nr is 3 for INT1 */ - } else if (PCI_SLOT(devices->devfn) == 4) { - /* PMC Slot 1 */ - devices->irq = 8; /* irq_nr is 8 for INT6 */ - } else if (PCI_SLOT(devices->devfn) == 5) { - /* PMC Slot 1 */ - devices->irq = 9; /* irq_nr is 9 for INT7 */ - } else { - /* We don't have assign interrupts for other devices. */ - devices->irq = 0xff; - } - - /* Assign an interrupt number for the device */ - bus->ops->write_byte(devices, PCI_INTERRUPT_LINE, devices->irq); - - /* enable master */ - bus->ops->read_word(devices, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MASTER; - bus->ops->write_word(devices, PCI_COMMAND, cmd); - } -} diff -urN linux-2.4.21-bk37/arch/mips/gt64120/momenco_ocelot/prom.c linux-2.4.21-bk38/arch/mips/gt64120/momenco_ocelot/prom.c --- linux-2.4.21-bk37/arch/mips/gt64120/momenco_ocelot/prom.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/gt64120/momenco_ocelot/prom.c 2003-08-24 02:55:57.000000000 -0700 @@ -15,34 +15,35 @@ #include #include -#define PLD_BASE 0xbc000000 - -#define REV 0x0 /* Board Assembly Revision */ -#define PLD1ID 0x1 /* PLD 1 ID */ -#define PLD2ID 0x2 /* PLD 2 ID */ -#define RESET_STAT 0x3 /* Reset Status Register */ -#define BOARD_STAT 0x4 /* Board Status Register */ -#define CPCI_ID 0x5 /* Compact PCI ID Register */ -#define CONTROL 0x8 /* Control Register */ -#define CPU_EEPROM 0x9 /* CPU Configuration EEPROM Register */ -#define INTMASK 0xA /* Interrupt Mask Register */ -#define INTSTAT 0xB /* Interrupt Status Register */ -#define INTSET 0xC /* Interrupt Set Register */ -#define INTCLR 0xD /* Interrupt Clear Register */ - -#define PLD_REG(x) ((uint8_t*)(PLD_BASE+(x))) +struct callvectors { + int (*open) (char*, int, int); + int (*close) (int); + int (*read) (int, void*, int); + int (*write) (int, void*, int); + off_t (*lseek) (int, off_t, int); + int (*printf) (const char*, ...); + void (*cacheflush) (void); + char* (*gets) (char*); +}; +struct callvectors* debug_vectors; char arcs_cmdline[CL_SIZE]; +extern unsigned long gt64120_base; + const char *get_system_type(void) { return "Momentum Ocelot"; } /* [jsun@junsun.net] PMON passes arguments in C main() style */ -void __init prom_init(int argc, const char **arg) +void __init prom_init(int argc, char **arg, char** env, struct callvectors *cv) { int i; + uint32_t tmp; + + /* save the PROM vectors for debugging use */ + debug_vectors = cv; /* arg[0] is "g", the rest is boot parameters */ arcs_cmdline[0] = '\0'; @@ -57,9 +58,16 @@ mips_machgroup = MACH_GROUP_MOMENCO; mips_machtype = MACH_MOMENCO_OCELOT; - /* turn off the Bit Error LED, which comes on automatically - * at power-up reset */ - *PLD_REG(INTCLR) = 0x80; + while (*env) { + if (strncmp("gtbase", *env, 6) == 0) { + gt64120_base = simple_strtol(*env + strlen("gtbase="), + NULL, 16); + break; + } + *env++; + } + + debug_vectors->printf("Booting Linux kernel...\n"); /* All the boards have at least 64MiB. If there's more, we detect and register it later */ diff -urN linux-2.4.21-bk37/arch/mips/gt64120/momenco_ocelot/setup.c linux-2.4.21-bk38/arch/mips/gt64120/momenco_ocelot/setup.c --- linux-2.4.21-bk37/arch/mips/gt64120/momenco_ocelot/setup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/gt64120/momenco_ocelot/setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -83,25 +84,9 @@ static void __init setup_l3cache(unsigned long size); -void __init momenco_ocelot_setup(void) +/* setup code for a handoff from a version 1 PMON 2000 PROM */ +void PMON_v1_setup() { - void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache); - unsigned int tmpword; - - board_time_init = gt64120_time_init; - - _machine_restart = momenco_ocelot_restart; - _machine_halt = momenco_ocelot_halt; - _machine_power_off = momenco_ocelot_power_off; - - /* - * initrd_start = (ulong)ocelot_initrd_start; - * initrd_end = (ulong)ocelot_initrd_start + (ulong)ocelot_initrd_size; - * initrd_below_start_ok = 1; - */ - rtc_ops = &no_rtc_ops; - - /* A wired TLB entry for the GT64120A and the serial port. The GT64120A is going to be hit on every IRQ anyway - there's absolutely no point in letting it be a random TLB entry, as @@ -122,12 +107,11 @@ Ocelot PLD (CS0) 0x2c000000 0xe0020000 NVRAM 0x2c800000 0xe0030000 */ - - add_temporary_entry(ENTRYLO(0x2C000000), ENTRYLO(0x2d000000), 0xe0020000, PM_64K); + add_temporary_entry(ENTRYLO(0x2C000000), ENTRYLO(0x2d000000), 0xe0020000, PM_64K); /* Relocate the CS3/BootCS region */ - GT_WRITE( GT_CS3BOOTLD_OFS, 0x2f000000 >> 21); + GT_WRITE(GT_CS3BOOTLD_OFS, 0x2f000000 >> 21); /* Relocate CS[012] */ GT_WRITE(GT_CS20LD_OFS, 0x2c000000 >> 21); @@ -142,19 +126,75 @@ GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x24000000); GT_WRITE(GT_PCI0_CFGADDR_OFS, 0x80000024); GT_WRITE(GT_PCI0_CFGDATA_OFS, 0x24000001); +} - /* Relocate PCI0 I/O and Mem0 */ - GT_WRITE(GT_PCI0IOLD_OFS, 0x20000000 >> 21); - GT_WRITE(GT_PCI0M0LD_OFS, 0x22000000 >> 21); +/* setup code for a handoff from a version 2 PMON 2000 PROM */ +void PMON_v2_setup() +{ + /* A wired TLB entry for the GT64120A and the serial port. The + GT64120A is going to be hit on every IRQ anyway - there's + absolutely no point in letting it be a random TLB entry, as + it'll just cause needless churning of the TLB. And we use + the other half for the serial port, which is just a PITA + otherwise :) - /* Relocate PCI0 Mem1 */ - GT_WRITE(GT_PCI0M1LD_OFS, 0x36000000 >> 21); + Device Physical Virtual + GT64120 Internal Regs 0xf4000000 0xe0000000 + UARTs (CS2) 0xfd000000 0xe0001000 + */ + add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xfD000000), 0xe0000000, PM_4K); + + /* Also a temporary entry to let us talk to the Ocelot PLD and NVRAM + in the CS[012] region. We can't use ioremap() yet. The NVRAM + is a ST M48T37Y, which includes NVRAM, RTC, and Watchdog functions. + + Ocelot PLD (CS0) 0xfc000000 0xe0020000 + NVRAM 0xfc800000 0xe0030000 + */ + add_temporary_entry(ENTRYLO(0xfC000000), ENTRYLO(0xfd000000), 0xe0020000, PM_64K); + + gt64120_base = 0xe0000000; +} + +void __init momenco_ocelot_setup(void) +{ + void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache); + unsigned int tmpword; + + board_time_init = gt64120_time_init; + + _machine_restart = momenco_ocelot_restart; + _machine_halt = momenco_ocelot_halt; + _machine_power_off = momenco_ocelot_power_off; + + /* + * initrd_start = (ulong)ocelot_initrd_start; + * initrd_end = (ulong)ocelot_initrd_start + (ulong)ocelot_initrd_size; + * initrd_below_start_ok = 1; + */ + rtc_ops = &no_rtc_ops; + + /* do handoff reconfiguration */ + if (gt64120_base == KSEG1ADDR(GT_DEF_BASE)) + PMON_v1_setup(); + else + PMON_v2_setup(); + + /* Turn off the Bit-Error LED */ + OCELOT_PLD_WRITE(0x80, INTCLR); /* Relocate all the PCI1 stuff, not that we use it */ GT_WRITE(GT_PCI1IOLD_OFS, 0x30000000 >> 21); GT_WRITE(GT_PCI1M0LD_OFS, 0x32000000 >> 21); GT_WRITE(GT_PCI1M1LD_OFS, 0x34000000 >> 21); + /* Relocate PCI0 I/O and Mem0 */ + GT_WRITE(GT_PCI0IOLD_OFS, 0x20000000 >> 21); + GT_WRITE(GT_PCI0M0LD_OFS, 0x22000000 >> 21); + + /* Relocate PCI0 Mem1 */ + GT_WRITE(GT_PCI0M1LD_OFS, 0x36000000 >> 21); + /* For the initial programming, we assume 512MB configuration */ /* Relocate the CPU's view of the RAM... */ GT_WRITE(GT_SCS10LD_OFS, 0); @@ -283,19 +323,19 @@ { int register i; unsigned long tmp; - + printk("Enabling L3 cache..."); /* Enable the L3 cache in the GT64120A's CPU Configuration register */ - GT_READ(0, &tmp); + tmp = GT_READ(0); GT_WRITE(0, tmp | (1<<14)); /* Enable the L3 cache in the CPU */ - set_cp0_config(1<<12 /* CONF_TE */); + set_c0_config(1<<12 /* CONF_TE */); /* Clear the cache */ - set_taglo(0); - set_taghi(0); + write_c0_taglo(0); + write_c0_taghi(0); for (i=0; i < size; i+= 4096) { __asm__ __volatile__ ( diff -urN linux-2.4.21-bk37/arch/mips/hp-lj/Makefile linux-2.4.21-bk38/arch/mips/hp-lj/Makefile --- linux-2.4.21-bk37/arch/mips/hp-lj/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/hp-lj/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -17,7 +17,7 @@ obj-y := init.o setup.o irq.o int-handler.o pci.o utils.o asic.o -obj-$(CONFIG_REMOTE_DEBUG) += gdb_hook.o +obj-$(CONFIG_KGDB) += gdb_hook.o obj-$(CONFIG_DIRECT_PRINTK) += gdb_hook.o obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o diff -urN linux-2.4.21-bk37/arch/mips/hp-lj/asic.c linux-2.4.21-bk38/arch/mips/hp-lj/asic.c --- linux-2.4.21-bk37/arch/mips/hp-lj/asic.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/hp-lj/asic.c 2003-08-24 02:55:57.000000000 -0700 @@ -20,7 +20,7 @@ const char* const GetAsicName(void) { - static const char* const Names[] = + static const char* const Names[] = { "Illegal", "Unknown", "Andros", "Harmony" }; return Names[(int)GetAsicId()]; diff -urN linux-2.4.21-bk37/arch/mips/hp-lj/gdb_hook.c linux-2.4.21-bk38/arch/mips/hp-lj/gdb_hook.c --- linux-2.4.21-bk37/arch/mips/hp-lj/gdb_hook.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/hp-lj/gdb_hook.c 2003-08-24 02:55:57.000000000 -0700 @@ -77,7 +77,7 @@ while (((SERIAL_REG(HPSR_TX_STAT_OFFSET) & HPSR_TX_STAT_READY) == 0)) ; SERIAL_REG(HPSR_DATA_OFFSET) = (unsigned int) c; - } + } return 1; } @@ -87,7 +87,7 @@ while (!(((H_HPSR_STAT) & H_SER_STAT_RX_EMPTY) == 0)); return H_HPSR_DATA_RX; - + } else if (GetAsicId() == AndrosAsic) { while ((SERIAL_REG(HPSR_RX_STAT_OFFSET) & HPSR_RX_DATA_AVAIL) == 0) ; diff -urN linux-2.4.21-bk37/arch/mips/hp-lj/init.c linux-2.4.21-bk38/arch/mips/hp-lj/init.c --- linux-2.4.21-bk37/arch/mips/hp-lj/init.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/hp-lj/init.c 2003-08-24 02:55:57.000000000 -0700 @@ -1,7 +1,7 @@ /* * init.c: PROM library initialisation code. * - * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov + * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov */ #include @@ -35,7 +35,7 @@ add_memory_region(mem_size,reserve_size, BOOT_MEM_RESERVED); printk("Main Memory: %ld bytes\n", mem_size); - printk("Reserved Memory: %ld bytes at 0x%08x\n", + printk("Reserved Memory: %ld bytes at 0x%08x\n", get_reserved_buffer_size(), (ulong)get_reserved_buffer()); printk("Detected %s ASIC\n", GetAsicName()); diff -urN linux-2.4.21-bk37/arch/mips/hp-lj/int-handler.S linux-2.4.21-bk38/arch/mips/hp-lj/int-handler.S --- linux-2.4.21-bk37/arch/mips/hp-lj/int-handler.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/hp-lj/int-handler.S 2003-08-24 02:55:57.000000000 -0700 @@ -64,7 +64,7 @@ la a1, ret_from_irq jr a1 -*/ +*/ 3: j spurious_interrupt END(hpIRQ) diff -urN linux-2.4.21-bk37/arch/mips/hp-lj/irq.c linux-2.4.21-bk38/arch/mips/hp-lj/irq.c --- linux-2.4.21-bk37/arch/mips/hp-lj/irq.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/hp-lj/irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -25,8 +25,8 @@ mips_cpu_irq_init(0); set_except_vector(0, hpIRQ); -#ifdef CONFIG_REMOTE_DEBUG - { +#ifdef CONFIG_KGDB + { extern void breakpoint(void); extern int remote_debug; @@ -36,6 +36,6 @@ } } #endif - + } diff -urN linux-2.4.21-bk37/arch/mips/hp-lj/pci-dma.c linux-2.4.21-bk38/arch/mips/hp-lj/pci-dma.c --- linux-2.4.21-bk37/arch/mips/hp-lj/pci-dma.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/hp-lj/pci-dma.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2000 Ani Joshi - * - * - * Dynamic DMA mapping support. - * - * swiped from i386, and cloned for MIPS by Geert. - * - */ - -#include -#include -#include -#include -#include - -void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, - dma_addr_t *dma_handle) -{ - void *ret; - int gfp = GFP_ATOMIC; - - if (hwdev == NULL || hwdev->dma_mask != 0xffffffff) - gfp |= GFP_DMA; - ret = (void *)__get_free_pages(gfp, get_order(size)); - if (ret != NULL) { - memset(ret, 0, size); - *dma_handle = virt_to_bus(ret); - - - // REVISIT this needs reviewal as mentioned in bug report - // currently we bump kseg0 allocates to kseg1 uncacheable space - - if ((((unsigned int) ret) & 0xe0000000) == 0x80000000) { - //flush the cache to eliminate coherency problems - // and assure dirty lines won't later get written over any dma, etc. - flush_cache_all(); - ret = (void*)((unsigned int)ret | 0x20000000); - } - - - } - return ret; -} - - -void pci_free_consistent(struct pci_dev *hwdev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - free_pages((unsigned long)vaddr, get_order(size)); -} - diff -urN linux-2.4.21-bk37/arch/mips/hp-lj/pci.c linux-2.4.21-bk38/arch/mips/hp-lj/pci.c --- linux-2.4.21-bk37/arch/mips/hp-lj/pci.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/hp-lj/pci.c 2003-08-24 02:55:57.000000000 -0700 @@ -77,7 +77,7 @@ if (where & 1) return PCIBIOS_BAD_REGISTER_NUMBER; *pci_config_address_reg = cfgaddr(dev, where); - *(volatile u16 *)(((int)pci_config_data_reg) + (where & 2)) = + *(volatile u16 *)(((int)pci_config_data_reg) + (where & 2)) = le16_to_cpu(val); //printk("pci_write_word 0x%x = 0x%x\n", where, val); return PCIBIOS_SUCCESSFUL; @@ -158,9 +158,9 @@ case AndrosAsic: pci_regs_base_offset = 0xbff80000; break; case HarmonyAsic: pci_regs_base_offset = 0xbff70000; break; default: - printk("ERROR: PCI does not support %s Asic\n", GetAsicName()); + printk("ERROR: PCI does not support %s Asic\n", GetAsicName()); while(1); - break; + break; } // set bus stat/command reg @@ -176,7 +176,7 @@ // KLUDGE (mips_io_port_base is screwed up, we've got to work around it here) // by letting both low (illegal) and high (legal) addresses appear in pci io space - ioport_resource.start = 0x0; + ioport_resource.start = 0x0; set_io_port_base(IO_PORT_LOGICAL_START + IO_PORT_VIRTUAL_OFFSET); @@ -185,7 +185,7 @@ // except that the range is outside user space // parameters: lo0, lo1, hi, pagemask // lo indicates physical page, hi indicates virtual address - add_wired_entry((IO_MEM_LOGICAL_START >> 6) | 0x17, + add_wired_entry((IO_MEM_LOGICAL_START >> 6) | 0x17, ((IO_MEM_LOGICAL_START + (16 * ONE_MEG)) >> 6) | 0x17, 0xee000000, PM_16M); @@ -203,7 +203,7 @@ int bases; printk("adjusting pci device: %s\n", dev->name); - + switch (dev->hdr_type) { case PCI_HEADER_TYPE_NORMAL: bases = 6; break; case PCI_HEADER_TYPE_BRIDGE: bases = 2; break; @@ -212,12 +212,12 @@ } for (pos=0; pos < bases; pos++) { struct resource* res = &dev->resource[pos]; - if (res->start >= IO_MEM_LOGICAL_START && + if (res->start >= IO_MEM_LOGICAL_START && res->end <= IO_MEM_LOGICAL_END) { res->start += IO_MEM_VIRTUAL_OFFSET; res->end += IO_MEM_VIRTUAL_OFFSET; } - if (res->start >= IO_PORT_LOGICAL_START && + if (res->start >= IO_PORT_LOGICAL_START && res->end <= IO_PORT_LOGICAL_END) { res->start += IO_PORT_VIRTUAL_OFFSET; res->end += IO_PORT_VIRTUAL_OFFSET; diff -urN linux-2.4.21-bk37/arch/mips/hp-lj/setup.c linux-2.4.21-bk38/arch/mips/hp-lj/setup.c --- linux-2.4.21-bk37/arch/mips/hp-lj/setup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/hp-lj/setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -20,7 +20,7 @@ #include #include "utils.h" -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB int remote_debug = 0; #endif @@ -80,8 +80,8 @@ irq->handler = andros_timer_interrupt; irq->flags |= SA_INTERRUPT | SA_SHIRQ; printk("setting up timer in hp_time_init\n"); - setup_irq(ASIC_IRQ_NUMBER, irq); - + setup_irq(ASIC_IRQ_NUMBER, irq); + // enable timer interrupt *((volatile unsigned int*)0xbfea0000) = 0x20; @@ -98,7 +98,7 @@ *((volatile unsigned int*)0xbff610a0) |= 1; // turn on timer0 - } else if (GetAsicId() == UnknownAsic) + } else if (GetAsicId() == UnknownAsic) printk("Unknown asic in hp_time_init()\n"); else printk("Unsupported asic in hp_time_init()\n"); @@ -107,7 +107,7 @@ static void hplj_restart(void) { - if (GetAsicId() == AndrosAsic) + if (GetAsicId() == AndrosAsic) *((volatile unsigned int *) 0xbfe900c0) = 0; @@ -144,7 +144,7 @@ board_timer_setup = hp_time_init; -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB { extern char CommandLine[]; remote_debug = (strstr(CommandLine, "kgdb") != NULL); diff -urN linux-2.4.21-bk37/arch/mips/hp-lj/utils.c linux-2.4.21-bk38/arch/mips/hp-lj/utils.c --- linux-2.4.21-bk37/arch/mips/hp-lj/utils.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/hp-lj/utils.c 2003-08-24 02:55:57.000000000 -0700 @@ -20,11 +20,11 @@ unsigned long cfg[10],i,total_mem=0; - for(i=0;i<10;i++) - cfg[i] = *miu_chan_cfg(i); + for(i=0;i<10;i++) + cfg[i] = *miu_chan_cfg(i); for(i=0;i<10;i++){ - if(cfg[i]==0x1fc160c2) continue; // skip empties + if(cfg[i]==0x1fc160c2) continue; // skip empties if( ( (cfg[i]>>12) & 0xf ) <= 0xb ) continue; // skip roms total_mem += mbsize[(cfg[i]>>16)&0x7] *1024*1024; } @@ -43,19 +43,19 @@ #define MIN_GEN_MEM (4 << 20) - -void reserve_buffer(const char* cl, ulong base_mem) + +void reserve_buffer(const char* cl, ulong base_mem) { char* pos = strstr(cl, "reserved_buffer="); if (pos) { - buffer_size = simple_strtol(pos+strlen("reserved_buffer="), + buffer_size = simple_strtol(pos+strlen("reserved_buffer="), 0, 10); buffer_size <<= 20; if (buffer_size + MIN_GEN_MEM > base_mem) buffer_size = base_mem - MIN_GEN_MEM; - if (buffer_size > 0) + if (buffer_size > 0) buffer_ptr = (ulong*)(base_mem - buffer_size); - else + else buffer_size = 0; } } diff -urN linux-2.4.21-bk37/arch/mips/ite-boards/generic/Makefile linux-2.4.21-bk38/arch/mips/ite-boards/generic/Makefile --- linux-2.4.21-bk37/arch/mips/ite-boards/generic/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ite-boards/generic/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -10,19 +10,16 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true all: it8172.o O_TARGET := it8172.o -obj-y := it8172_rtc.o it8172_setup.o irq.o int-handler.o pmon_prom.o time.o lpc.o puts.o reset.o +obj-y := it8172_setup.o irq.o int-handler.o pmon_prom.o time.o lpc.o puts.o reset.o obj-$(CONFIG_PCI) += it8172_pci.o -obj-$(CONFIG_IT8172_CIR) += it8172_cir.o -obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o +obj-$(CONFIG_IT8172_CIR) += it8172_cir.o +obj-$(CONFIG_KGDB) += dbg_io.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/ite-boards/generic/dbg_io.c linux-2.4.21-bk38/arch/mips/ite-boards/generic/dbg_io.c --- linux-2.4.21-bk37/arch/mips/ite-boards/generic/dbg_io.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ite-boards/generic/dbg_io.c 2003-08-24 02:55:57.000000000 -0700 @@ -1,7 +1,7 @@ #include -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB /* --- CONFIG --- */ diff -urN linux-2.4.21-bk37/arch/mips/ite-boards/generic/int-handler.S linux-2.4.21-bk38/arch/mips/ite-boards/generic/int-handler.S --- linux-2.4.21-bk37/arch/mips/ite-boards/generic/int-handler.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ite-boards/generic/int-handler.S 2003-08-24 02:55:57.000000000 -0700 @@ -26,15 +26,17 @@ andi a0, t0, CAUSEF_IP7 beq a0, zero, 1f - move a0, sp - jal local_timer_interrupt + + li a0, 127 # MIPS_CPU_TIMER_IRQ = (NR_IRQS-1) + move a1, sp + jal ll_timer_interrupt j ret_from_irq nop - + 1: andi a0, t0, CAUSEF_IP2 # the only int we expect at this time - beq a0, zero, 3f - move a0,sp + beq a0, zero, 3f + move a0,sp jal it8172_hw0_irqdispatch mfc0 t0,CP0_STATUS # disable interrupts @@ -44,12 +46,12 @@ nop nop nop - + la a1, ret_from_irq jr a1 nop - -3: + +3: move a0, sp jal mips_spurious_interrupt nop diff -urN linux-2.4.21-bk37/arch/mips/ite-boards/generic/irq.c linux-2.4.21-bk38/arch/mips/ite-boards/generic/irq.c --- linux-2.4.21-bk37/arch/mips/ite-boards/generic/irq.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ite-boards/generic/irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -7,7 +7,7 @@ * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com * - * Part of this file was derived from Carsten Langgaard's + * Part of this file was derived from Carsten Langgaard's * arch/mips/mips-boards/atlas/atlas_int.c. * * Carsten Langgaard, carstenl@mips.com @@ -33,8 +33,10 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include +#include #include #include #include @@ -64,7 +66,7 @@ #define DPRINTK(fmt, args...) #endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void breakpoint(void); #endif @@ -89,10 +91,10 @@ /* Function for careful CP0 interrupt mask access */ static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) { - unsigned long status = read_32bit_cp0_register(CP0_STATUS); + unsigned long status = read_c0_status(); status &= ~((clr_mask & 0xFF) << 8); status |= (set_mask & 0xFF) << 8; - write_32bit_cp0_register(CP0_STATUS, status); + write_c0_status(status); } static inline void mask_irq(unsigned int irq_nr) @@ -131,28 +133,28 @@ if ( (irq_nr >= IT8172_LPC_IRQ_BASE) && (irq_nr <= IT8172_SERIRQ_15)) { /* LPC interrupt */ DPRINTK("DB lpc_mask %x\n", it8172_hw0_icregs->lpc_mask); - it8172_hw0_icregs->lpc_mask |= + it8172_hw0_icregs->lpc_mask |= (1 << (irq_nr - IT8172_LPC_IRQ_BASE)); DPRINTK("DA lpc_mask %x\n", it8172_hw0_icregs->lpc_mask); } else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) { /* Local Bus interrupt */ DPRINTK("DB lb_mask %x\n", it8172_hw0_icregs->lb_mask); - it8172_hw0_icregs->lb_mask |= + it8172_hw0_icregs->lb_mask |= (1 << (irq_nr - IT8172_LB_IRQ_BASE)); DPRINTK("DA lb_mask %x\n", it8172_hw0_icregs->lb_mask); } else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) { /* PCI and other interrupts */ DPRINTK("DB pci_mask %x\n", it8172_hw0_icregs->pci_mask); - it8172_hw0_icregs->pci_mask |= + it8172_hw0_icregs->pci_mask |= (1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE)); DPRINTK("DA pci_mask %x\n", it8172_hw0_icregs->pci_mask); } else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) { /* NMI interrupts */ DPRINTK("DB nmi_mask %x\n", it8172_hw0_icregs->nmi_mask); - it8172_hw0_icregs->nmi_mask |= + it8172_hw0_icregs->nmi_mask |= (1 << (irq_nr - IT8172_NMI_IRQ_BASE)); DPRINTK("DA nmi_mask %x\n", it8172_hw0_icregs->nmi_mask); } @@ -167,28 +169,28 @@ if ( (irq_nr >= IT8172_LPC_IRQ_BASE) && (irq_nr <= IT8172_SERIRQ_15)) { /* LPC interrupt */ DPRINTK("EB before lpc_mask %x\n", it8172_hw0_icregs->lpc_mask); - it8172_hw0_icregs->lpc_mask &= + it8172_hw0_icregs->lpc_mask &= ~(1 << (irq_nr - IT8172_LPC_IRQ_BASE)); DPRINTK("EA after lpc_mask %x\n", it8172_hw0_icregs->lpc_mask); } else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) { /* Local Bus interrupt */ DPRINTK("EB lb_mask %x\n", it8172_hw0_icregs->lb_mask); - it8172_hw0_icregs->lb_mask &= + it8172_hw0_icregs->lb_mask &= ~(1 << (irq_nr - IT8172_LB_IRQ_BASE)); DPRINTK("EA lb_mask %x\n", it8172_hw0_icregs->lb_mask); } else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) { /* PCI and other interrupts */ DPRINTK("EB pci_mask %x\n", it8172_hw0_icregs->pci_mask); - it8172_hw0_icregs->pci_mask &= + it8172_hw0_icregs->pci_mask &= ~(1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE)); DPRINTK("EA pci_mask %x\n", it8172_hw0_icregs->pci_mask); } else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) { /* NMI interrupts */ DPRINTK("EB nmi_mask %x\n", it8172_hw0_icregs->nmi_mask); - it8172_hw0_icregs->nmi_mask &= + it8172_hw0_icregs->nmi_mask &= ~(1 << (irq_nr - IT8172_NMI_IRQ_BASE)); DPRINTK("EA nmi_mask %x\n", it8172_hw0_icregs->nmi_mask); } @@ -200,7 +202,7 @@ static unsigned int startup_ite_irq(unsigned int irq) { enable_it8172_irq(irq); - return 0; + return 0; } #define shutdown_ite_irq disable_it8172_irq @@ -282,15 +284,15 @@ it8172_hw0_icregs->lb_level |= 0x20; /* keyboard and mouse are edge triggered */ - it8172_hw0_icregs->lpc_trigger |= (0x2 | 0x1000); + it8172_hw0_icregs->lpc_trigger |= (0x2 | 0x1000); #if 0 // Enable this piece of code to make internal USB interrupt // edge triggered. - it8172_hw0_icregs->pci_trigger |= + it8172_hw0_icregs->pci_trigger |= (1 << (IT8172_USB_IRQ - IT8172_PCI_DEV_IRQ_BASE)); - it8172_hw0_icregs->pci_level &= + it8172_hw0_icregs->pci_level &= ~(1 << (IT8172_USB_IRQ - IT8172_PCI_DEV_IRQ_BASE)); #endif @@ -298,13 +300,13 @@ irq_desc[i].handler = &it8172_irq_type; } irq_desc[MIPS_CPU_TIMER_IRQ].handler = &cp0_irq_type; - set_cp0_status(ALLINTS_NOTIMER); + set_c0_status(ALLINTS_NOTIMER); -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB /* If local serial I/O used for debug port, enter kgdb at once */ puts("Waiting for kgdb to connect..."); set_debug_traps(); - breakpoint(); + breakpoint(); #endif } @@ -316,8 +318,8 @@ unsigned long status, cause; printk("got spurious interrupt\n"); - status = read_32bit_cp0_register(CP0_STATUS); - cause = read_32bit_cp0_register(CP0_CAUSE); + status = read_c0_status(); + cause = read_c0_cause(); printk("status %x cause %x\n", status, cause); printk("epc %x badvaddr %x \n", regs->cp0_epc, regs->cp0_badvaddr); // while(1); diff -urN linux-2.4.21-bk37/arch/mips/ite-boards/generic/it8172_pci.c linux-2.4.21-bk38/arch/mips/ite-boards/generic/it8172_pci.c --- linux-2.4.21-bk37/arch/mips/ite-boards/generic/it8172_pci.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ite-boards/generic/it8172_pci.c 2003-08-24 02:55:57.000000000 -0700 @@ -53,15 +53,15 @@ static struct resource pci_mem_resource_1; static struct resource pci_io_resource = { - "io pci IO space", - 0x14000000, + "io pci IO space", + 0x14018000, 0x17FFFFFF, IORESOURCE_IO }; static struct resource pci_mem_resource_0 = { - "ext pci memory space 0/1", - 0x0C000000, + "ext pci memory space 0/1", + 0x10101000, 0x13FFFFFF, IORESOURCE_MEM, &pci_mem_resource_0, @@ -70,7 +70,7 @@ }; static struct resource pci_mem_resource_1 = { - "ext pci memory space 2/3", + "ext pci memory space 2/3", 0x1A000000, 0x1FBFFFFF, IORESOURCE_MEM, @@ -82,7 +82,7 @@ extern struct pci_ops it8172_pci_ops; struct pci_channel mips_pci_channels[] = { - { &it8172_pci_ops, &pci_io_resource, &pci_mem_resource_0, 0, 0xff }, + { &it8172_pci_ops, &pci_io_resource, &pci_mem_resource_0, 0x10, 0xff }, { NULL, NULL, NULL, NULL, NULL} }; @@ -90,7 +90,7 @@ it8172_pcibios_config_access(unsigned char access_type, struct pci_dev *dev, unsigned char where, u32 *data) { - /* + /* * config cycles are on 4 byte boundary only */ unsigned char bus = dev->bus->number; @@ -100,13 +100,13 @@ access_type, dev, bus, dev_fn, *data); /* Setup address */ - IT_WRITE(IT_CONFADDR, (bus << IT_BUSNUM_SHF) | + IT_WRITE(IT_CONFADDR, (bus << IT_BUSNUM_SHF) | (dev_fn << IT_FUNCNUM_SHF) | (where & ~0x3)); if (access_type == PCI_ACCESS_WRITE) { IT_WRITE(IT_CONFDATA, *data); - } + } else { IT_READ(IT_CONFDATA, *data); } @@ -133,7 +133,7 @@ return -1; *val = (data >> ((where & 3) << 3)) & 0xff; - DBG("cfg read byte: bus %d dev_fn %x where %x: val %x\n", + DBG("cfg read byte: bus %d dev_fn %x where %x: val %x\n", dev->bus->number, dev->devfn, where, *val); return PCIBIOS_SUCCESSFUL; @@ -152,7 +152,7 @@ return -1; *val = (data >> ((where & 3) << 3)) & 0xffff; - DBG("cfg read word: bus %d dev_fn %x where %x: val %x\n", + DBG("cfg read word: bus %d dev_fn %x where %x: val %x\n", dev->bus->number, dev->devfn, where, *val); return PCIBIOS_SUCCESSFUL; @@ -165,12 +165,12 @@ if (where & 3) return PCIBIOS_BAD_REGISTER_NUMBER; - + if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) return -1; *val = data; - DBG("cfg read dword: bus %d dev_fn %x where %x: val %x\n", + DBG("cfg read dword: bus %d dev_fn %x where %x: val %x\n", dev->bus->number, dev->devfn, where, *val); return PCIBIOS_SUCCESSFUL; @@ -181,7 +181,7 @@ write_config_byte (struct pci_dev *dev, int where, u8 val) { u32 data = 0; - + if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) return -1; @@ -201,11 +201,11 @@ if (where & 1) return PCIBIOS_BAD_REGISTER_NUMBER; - + if (it8172_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) return -1; - data = (data & ~(0xffff << ((where & 3) << 3))) | + data = (data & ~(0xffff << ((where & 3) << 3))) | (val << ((where & 3) << 3)); if (it8172_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data)) diff -urN linux-2.4.21-bk37/arch/mips/ite-boards/generic/it8172_rtc.c linux-2.4.21-bk38/arch/mips/ite-boards/generic/it8172_rtc.c --- linux-2.4.21-bk37/arch/mips/ite-boards/generic/it8172_rtc.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ite-boards/generic/it8172_rtc.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,62 +0,0 @@ -/* - * Copyright 2000 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * RTC routines for ITE8172 MC146818-compatible rtc chip. - * - */ -#include -#include - -#define IT8172_RTC_ADR_REG (IT8172_PCI_IO_BASE + IT_RTC_BASE) -#define IT8172_RTC_DAT_REG (IT8172_RTC_ADR_REG + 1) - -static volatile char *rtc_adr_reg = KSEG1ADDR((volatile char *)IT8172_RTC_ADR_REG); -static volatile char *rtc_dat_reg = KSEG1ADDR((volatile char *)IT8172_RTC_DAT_REG); - -unsigned char it8172_rtc_read_data(unsigned long addr) -{ - unsigned char retval; - - *rtc_adr_reg = addr; - retval = *rtc_dat_reg; - return retval; -} - -void it8172_rtc_write_data(unsigned char data, unsigned long addr) -{ - *rtc_adr_reg = addr; - *rtc_dat_reg = data; -} - -static int it8172_rtc_bcd_mode(void) -{ - return 0; -} - -struct rtc_ops it8172_rtc_ops = { - &it8172_rtc_read_data, - &it8172_rtc_write_data, - &it8172_rtc_bcd_mode -}; diff -urN linux-2.4.21-bk37/arch/mips/ite-boards/generic/it8172_setup.c linux-2.4.21-bk38/arch/mips/ite-boards/generic/it8172_setup.c --- linux-2.4.21-bk37/arch/mips/ite-boards/generic/it8172_setup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ite-boards/generic/it8172_setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -32,14 +32,16 @@ #include #include #include -#include #include #include #include #include +#include +#include #include #include +#include #include #include #ifdef CONFIG_PC_KEYB @@ -51,7 +53,6 @@ char serial_console[20]; #endif -extern struct rtc_ops it8172_rtc_ops; extern struct resource ioport_resource; #ifdef CONFIG_BLK_DEV_IDE extern struct ide_ops std_ide_ops; @@ -71,11 +72,8 @@ extern void (*board_time_init)(void); extern void (*board_timer_setup)(struct irqaction *irq); -extern unsigned long (*rtc_get_time)(void); -extern int (*rtc_set_time)(unsigned long); extern void it8172_time_init(void); extern void it8172_timer_setup(struct irqaction *irq); -extern unsigned long it8172_rtc_get_time(void); #ifdef CONFIG_IT8172_REVC struct { @@ -131,22 +129,19 @@ argptr = prom_getcmdline(); strcat(argptr, " console=ttyS0,115200"); } -#endif +#endif - clear_cp0_status(ST0_FR); - rtc_ops = &it8172_rtc_ops; + clear_c0_status(ST0_FR); board_time_init = it8172_time_init; board_timer_setup = it8172_timer_setup; - rtc_get_time = it8172_rtc_get_time; - //rtc_set_time = it8172_rtc_set_time; _machine_restart = it8172_restart; _machine_halt = it8172_halt; _machine_power_off = it8172_power_off; /* - * IO/MEM resources. + * IO/MEM resources. * * revisit this area. */ @@ -173,7 +168,7 @@ dsr &= ~IT_PM_DSR_ACSB; #else dsr |= IT_PM_DSR_ACSB; -#endif +#endif #ifdef CONFIG_BLK_DEV_IT8172 dsr &= ~IT_PM_DSR_IDESB; ide_ops = &std_ide_ops; @@ -209,8 +204,8 @@ LPCSetConfig(0x4, 0x30, 0x1); LPCSetConfig(0x4, 0xf4, LPCGetConfig(0x4, 0xf4) | 0x80); - if ((LPCGetConfig(LDN_KEYBOARD, 0x30) == 0) || - (LPCGetConfig(LDN_MOUSE, 0x30) == 0)) + if ((LPCGetConfig(LDN_KEYBOARD, 0x30) == 0) || + (LPCGetConfig(LDN_MOUSE, 0x30) == 0)) printk("Error: keyboard or mouse not enabled\n"); kbd_ops = &std_kbd_ops; @@ -234,7 +229,7 @@ #endif #ifdef CONFIG_IT8172_SCR0 { - unsigned i; + unsigned i; /* Enable Smart Card Reader 0 */ /* First power it up */ IT_IO_READ16(IT_PM_DSR, i); @@ -253,7 +248,7 @@ #endif /* CONFIG_IT8172_SCR0 */ #ifdef CONFIG_IT8172_SCR1 { - unsigned i; + unsigned i; /* Enable Smart Card Reader 1 */ /* First power it up */ IT_IO_READ16(IT_PM_DSR, i); @@ -275,7 +270,7 @@ #ifdef CONFIG_PC_KEYB /* - * According to the ITE Special BIOS Note for waking up the + * According to the ITE Special BIOS Note for waking up the * keyboard controller... */ int init_8712_keyboard() diff -urN linux-2.4.21-bk37/arch/mips/ite-boards/generic/lpc.c linux-2.4.21-bk38/arch/mips/ite-boards/generic/lpc.c --- linux-2.4.21-bk37/arch/mips/ite-boards/generic/lpc.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ite-boards/generic/lpc.c 2003-08-24 02:55:57.000000000 -0700 @@ -62,7 +62,7 @@ LPCEnterMBPnP(); // Enter IT8712 MB PnP mode outb(0x07, LPC_KEY_ADDR); outb(LdnNumber, LPC_DATA_ADDR); - outb(Index, LPC_KEY_ADDR); + outb(Index, LPC_KEY_ADDR); outb(data, LPC_DATA_ADDR); LPCExitMBPnP(); } @@ -74,7 +74,7 @@ LPCEnterMBPnP(); // Enter IT8712 MB PnP mode outb(0x07, LPC_KEY_ADDR); outb(LdnNumber, LPC_DATA_ADDR); - outb(Index, LPC_KEY_ADDR); + outb(Index, LPC_KEY_ADDR); rtn = inb(LPC_DATA_ADDR); LPCExitMBPnP(); return rtn; @@ -92,7 +92,7 @@ Id2 = inb(LPC_DATA_ADDR); Id = (Id1 << 8) | Id2; LPCExitMBPnP(); - if (Id == 0x8712) + if (Id == 0x8712) return TRUE; else return FALSE; @@ -104,30 +104,30 @@ unsigned long data; bus = 0; - dev_fn = 1<<3 | 4; + dev_fn = 1<<3 | 4; /* pci cmd, SERR# Enable */ - IT_WRITE(IT_CONFADDR, + IT_WRITE(IT_CONFADDR, (bus << IT_BUSNUM_SHF) | (dev_fn << IT_FUNCNUM_SHF) | ((0x4 / 4) << IT_REGNUM_SHF)); IT_READ(IT_CONFDATA, data); data |= 0x0100; - IT_WRITE(IT_CONFADDR, + IT_WRITE(IT_CONFADDR, (bus << IT_BUSNUM_SHF) | (dev_fn << IT_FUNCNUM_SHF) | ((0x4 / 4) << IT_REGNUM_SHF)); IT_WRITE(IT_CONFDATA, data); /* setup serial irq control register */ - IT_WRITE(IT_CONFADDR, + IT_WRITE(IT_CONFADDR, (bus << IT_BUSNUM_SHF) | (dev_fn << IT_FUNCNUM_SHF) | ((0x48 / 4) << IT_REGNUM_SHF)); IT_READ(IT_CONFDATA, data); data = (data & 0xffff00ff) | 0xc400; - IT_WRITE(IT_CONFADDR, + IT_WRITE(IT_CONFADDR, (bus << IT_BUSNUM_SHF) | (dev_fn << IT_FUNCNUM_SHF) | ((0x48 / 4) << IT_REGNUM_SHF)); @@ -136,7 +136,7 @@ /* Enable I/O Space Subtractive Decode */ /* default 0x4C is 0x3f220000 */ - IT_WRITE(IT_CONFADDR, + IT_WRITE(IT_CONFADDR, (bus << IT_BUSNUM_SHF) | (dev_fn << IT_FUNCNUM_SHF) | ((0x4C / 4) << IT_REGNUM_SHF)); diff -urN linux-2.4.21-bk37/arch/mips/ite-boards/generic/pmon_prom.c linux-2.4.21-bk38/arch/mips/ite-boards/generic/pmon_prom.c --- linux-2.4.21-bk37/arch/mips/ite-boards/generic/pmon_prom.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ite-boards/generic/pmon_prom.c 2003-08-24 02:55:57.000000000 -0700 @@ -8,7 +8,7 @@ * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com * - * This file was derived from Carsten Langgaard's + * This file was derived from Carsten Langgaard's * arch/mips/mips-boards/xx files. * * Carsten Langgaard, carstenl@mips.com @@ -128,11 +128,11 @@ memsize_str = prom_getenv("memsize"); if (!memsize_str) { #ifdef CONFIG_MIPS_ITE8172 - memsize = 32; + memsize = 32; #elif defined(CONFIG_MIPS_IVR) - memsize = 64; + memsize = 64; #else - memsize = 8; + memsize = 8; #endif printk("memsize unknown: setting to %dMB\n", memsize); } else { diff -urN linux-2.4.21-bk37/arch/mips/ite-boards/generic/reset.c linux-2.4.21-bk38/arch/mips/ite-boards/generic/reset.c --- linux-2.4.21-bk37/arch/mips/ite-boards/generic/reset.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ite-boards/generic/reset.c 2003-08-24 02:55:57.000000000 -0700 @@ -38,10 +38,10 @@ void it8172_restart() { - set_cp0_status(ST0_BEV | ST0_ERL); - change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + set_c0_status(ST0_BEV | ST0_ERL); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); + write_c0_wired(0); __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); } diff -urN linux-2.4.21-bk37/arch/mips/ite-boards/generic/time.c linux-2.4.21-bk38/arch/mips/ite-boards/generic/time.c --- linux-2.4.21-bk37/arch/mips/ite-boards/generic/time.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ite-boards/generic/time.c 2003-08-24 02:55:57.000000000 -0700 @@ -2,6 +2,9 @@ * Carsten Langgaard, carstenl@mips.com * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. * + * Copyright (C) 2003 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * * ######################################################################## * * This program is free software; you can distribute it and/or modify it @@ -22,108 +25,212 @@ * Setting up the clock on the MIPS boards. * */ - -#include #include #include #include #include #include -#include +#include #include #include +#include #include #include +#define IT8172_RTC_ADR_REG (IT8172_PCI_IO_BASE + IT_RTC_BASE) +#define IT8172_RTC_DAT_REG (IT8172_RTC_ADR_REG + 1) +#define IT8172_RTC_CENTURY_REG (IT8172_PCI_IO_BASE + IT_RTC_CENTURY) + +static volatile char *rtc_adr_reg = (char*)KSEG1ADDR(IT8172_RTC_ADR_REG); +static volatile char *rtc_dat_reg = (char*)KSEG1ADDR(IT8172_RTC_DAT_REG); +static volatile char *rtc_century_reg = (char*)KSEG1ADDR(IT8172_RTC_CENTURY_REG); + +unsigned char it8172_rtc_read_data(unsigned long addr) +{ + unsigned char retval; + + *rtc_adr_reg = addr; + retval = *rtc_dat_reg; + return retval; +} + +void it8172_rtc_write_data(unsigned char data, unsigned long addr) +{ + *rtc_adr_reg = addr; + *rtc_dat_reg = data; +} + +#undef CMOS_READ +#undef CMOS_WRITE +#define CMOS_READ(addr) it8172_rtc_read_data(addr) +#define CMOS_WRITE(data, addr) it8172_rtc_write_data(data, addr) + +static unsigned char saved_control; /* remember rtc control reg */ +static inline int rtc_24h(void) { return saved_control & RTC_24H; } +static inline int rtc_dm_binary(void) { return saved_control & RTC_DM_BINARY; } + +static inline unsigned char +bin_to_hw(unsigned char c) +{ + if (rtc_dm_binary()) + return c; + else + return ((c/10) << 4) + (c%10); +} + +static inline unsigned char +hw_to_bin(unsigned char c) +{ + if (rtc_dm_binary()) + return c; + else + return (c>>4)*10 + (c &0xf); +} + +/* 0x80 bit indicates pm in 12-hour format */ +static inline unsigned char +hour_bin_to_hw(unsigned char c) +{ + if (rtc_24h()) + return bin_to_hw(c); + if (c >= 12) + return 0x80 | bin_to_hw((c==12)?12:c-12); /* 12 is 12pm */ + else + return bin_to_hw((c==0)?12:c); /* 0 is 12 AM, not 0 am */ +} + +static inline unsigned char +hour_hw_to_bin(unsigned char c) +{ + unsigned char tmp = hw_to_bin(c&0x3f); + if (rtc_24h()) + return tmp; + if (c & 0x80) + return (tmp==12)?12:tmp+12; /* 12pm is 12, not 24 */ + else + return (tmp==12)?0:tmp; /* 12am is 0 */ +} + static unsigned long r4k_offset; /* Amount to increment compare reg each time */ static unsigned long r4k_cur; /* What counter should be at next timer irq */ extern unsigned int mips_counter_frequency; -extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs); -/* +/* * Figure out the r4k offset, the amount to increment the compare - * register for each time tick. + * register for each time tick. * Use the RTC to calculate offset. */ static unsigned long __init cal_r4koff(void) { - unsigned int flags; + unsigned long flags; - __save_and_cli(flags); + local_irq_save(flags); /* Start counter exactly on falling edge of update flag */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); /* Start r4k counter. */ - write_32bit_cp0_register(CP0_COUNT, 0); + write_c0_count(0); /* Read counter exactly on falling edge of update flag */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); - mips_counter_frequency = read_32bit_cp0_register(CP0_COUNT); + mips_counter_frequency = read_c0_count(); /* restore interrupts */ - __restore_flags(flags); - + local_irq_restore(flags); + return (mips_counter_frequency / HZ); } -unsigned long it8172_rtc_get_time(void) +static unsigned long +it8172_rtc_get_time(void) { unsigned int year, mon, day, hour, min, sec; - unsigned char save_control; - - save_control = CMOS_READ(RTC_CONTROL); + unsigned int flags; - /* Freeze it. */ - CMOS_WRITE(save_control | RTC_SET, RTC_CONTROL); + /* avoid update-in-progress. */ + for (;;) { + local_irq_save(flags); + if (! (CMOS_READ(RTC_REG_A) & RTC_UIP)) + break; + /* don't hold intr closed all the time */ + local_irq_restore(flags); + } /* Read regs. */ - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - - if (!(save_control & RTC_24H)) - { - if ((hour & 0xf) == 0xc) - hour &= 0x80; - if (hour & 0x80) - hour = (hour & 0xf) + 12; + sec = hw_to_bin(CMOS_READ(RTC_SECONDS)); + min = hw_to_bin(CMOS_READ(RTC_MINUTES)); + hour = hour_hw_to_bin(CMOS_READ(RTC_HOURS)); + day = hw_to_bin(CMOS_READ(RTC_DAY_OF_MONTH)); + mon = hw_to_bin(CMOS_READ(RTC_MONTH)); + year = hw_to_bin(CMOS_READ(RTC_YEAR)) + + hw_to_bin(*rtc_century_reg) * 100; + + /* restore interrupts */ + local_irq_restore(flags); + + return mktime(year, mon, day, hour, min, sec); +} + +static int +it8172_rtc_set_time(unsigned long t) +{ + struct rtc_time tm; + unsigned int flags; + + /* convert */ + to_tm(t, &tm); + + /* avoid update-in-progress. */ + for (;;) { + local_irq_save(flags); + if (! (CMOS_READ(RTC_REG_A) & RTC_UIP)) + break; + /* don't hold intr closed all the time */ + local_irq_restore(flags); } - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); - /* Unfreeze clock. */ - CMOS_WRITE(save_control, RTC_CONTROL); + *rtc_century_reg = bin_to_hw(tm.tm_year/100); + CMOS_WRITE(bin_to_hw(tm.tm_sec), RTC_SECONDS); + CMOS_WRITE(bin_to_hw(tm.tm_min), RTC_MINUTES); + CMOS_WRITE(hour_bin_to_hw(tm.tm_hour), RTC_HOURS); + CMOS_WRITE(bin_to_hw(tm.tm_mday), RTC_DAY_OF_MONTH); + CMOS_WRITE(bin_to_hw(tm.tm_mon+1), RTC_MONTH); /* tm_mon starts from 0 */ + CMOS_WRITE(bin_to_hw(tm.tm_year%100), RTC_YEAR); - if ((year += 1900) < 1970) - year += 100; + /* restore interrupts */ + local_irq_restore(flags); - return mktime(year, mon, day, hour, min, sec); + return 0; } void __init it8172_time_init(void) { - unsigned int est_freq, flags; + unsigned long flags; + unsigned int est_freq; + + local_irq_save(flags); - __save_and_cli(flags); - /* Set Data mode - binary. */ - CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); + saved_control = CMOS_READ(RTC_CONTROL); printk("calculating r4koff... "); r4k_offset = cal_r4koff(); printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset); - est_freq = 2*r4k_offset*HZ; + est_freq = 2*r4k_offset*HZ; est_freq += 5000; /* round */ est_freq -= est_freq%10000; - printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, + printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, (est_freq%1000000)*100/1000000); - __restore_flags(flags); + + local_irq_restore(flags); + + rtc_get_time = it8172_rtc_get_time; + rtc_set_time = it8172_rtc_set_time; } #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) @@ -136,12 +243,7 @@ setup_irq(MIPS_CPU_TIMER_IRQ, irq); /* to generate the first timer interrupt */ - r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset); - write_32bit_cp0_register(CP0_COMPARE, r4k_cur); - set_cp0_status(ALLINTS); -} - -void local_timer_interrupt(struct pt_regs *regs) -{ - do_IRQ(MIPS_CPU_TIMER_IRQ, regs); + r4k_cur = (read_c0_count() + r4k_offset); + write_c0_compare(r4k_cur); + set_c0_status(ALLINTS); } diff -urN linux-2.4.21-bk37/arch/mips/ite-boards/ivr/Makefile linux-2.4.21-bk38/arch/mips/ite-boards/ivr/Makefile --- linux-2.4.21-bk37/arch/mips/ite-boards/ivr/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ite-boards/ivr/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -11,17 +11,14 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true all: ivr.o O_TARGET := ivr.o -obj-y := init.o +obj-y := init.o -obj-$(CONFIG_PCI) += pci_fixup.o +obj-$(CONFIG_PCI) += pci_fixup.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/ite-boards/ivr/README linux-2.4.21-bk38/arch/mips/ite-boards/ivr/README --- linux-2.4.21-bk37/arch/mips/ite-boards/ivr/README 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ite-boards/ivr/README 2003-08-24 02:55:57.000000000 -0700 @@ -1,3 +1,3 @@ -This is not really a board made by ITE Semi, but it's very +This is not really a board made by ITE Semi, but it's very similar to the ITE QED-4N-S01B board. The IVR board is made by Globespan and it's a reference board for the PVR chip. diff -urN linux-2.4.21-bk37/arch/mips/ite-boards/ivr/init.c linux-2.4.21-bk38/arch/mips/ite-boards/ivr/init.c --- linux-2.4.21-bk37/arch/mips/ite-boards/ivr/init.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ite-boards/ivr/init.c 2003-08-24 02:55:57.000000000 -0700 @@ -27,14 +27,12 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include #include #include #include #include #include -#include #include #include #include @@ -81,7 +79,7 @@ * make the entire physical memory visible to pci bus masters */ IT_READ(IT_MC_PCICR, pcicr); - pcicr &= ~0x1f; + pcicr &= ~0x1f; pcicr |= (mem_size - 1) >> 22; IT_WRITE(IT_MC_PCICR, pcicr); diff -urN linux-2.4.21-bk37/arch/mips/ite-boards/ivr/pci_fixup.c linux-2.4.21-bk38/arch/mips/ite-boards/ivr/pci_fixup.c --- linux-2.4.21-bk37/arch/mips/ite-boards/ivr/pci_fixup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ite-boards/ivr/pci_fixup.c 2003-08-24 02:55:57.000000000 -0700 @@ -74,8 +74,8 @@ switch (slot) { case 0x01: /* - * Internal device 1 is actually 7 different - * internal devices on the IT8172G (multi-function + * Internal device 1 is actually 7 different + * internal devices on the IT8172G (multi-function * device). */ if (func < 7) @@ -97,7 +97,7 @@ dev->irq = IT8172_PCI_INTB_IRQ; break; default: - dev->irq = 0xff; + dev->irq = 0xff; break; } @@ -118,7 +118,7 @@ dev->irq = IT8172_PCI_INTD_IRQ; break; default: - dev->irq = 0xff; + dev->irq = 0xff; break; } @@ -139,7 +139,7 @@ dev->irq = IT8172_PCI_INTD_IRQ; break; default: - dev->irq = 0xff; + dev->irq = 0xff; break; } diff -urN linux-2.4.21-bk37/arch/mips/ite-boards/qed-4n-s01b/Makefile linux-2.4.21-bk38/arch/mips/ite-boards/qed-4n-s01b/Makefile --- linux-2.4.21-bk37/arch/mips/ite-boards/qed-4n-s01b/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ite-boards/qed-4n-s01b/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -11,16 +11,12 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true O_TARGET := ite.o -obj-y := init.o +obj-y := init.o obj-$(CONFIG_PCI) += pci_fixup.o -obj-$(CONFIG_BLK_DEV_INITRD) += le_ramdisk.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/ite-boards/qed-4n-s01b/init.c linux-2.4.21-bk38/arch/mips/ite-boards/qed-4n-s01b/init.c --- linux-2.4.21-bk37/arch/mips/ite-boards/qed-4n-s01b/init.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ite-boards/qed-4n-s01b/init.c 2003-08-24 02:55:57.000000000 -0700 @@ -27,14 +27,12 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include #include #include #include #include #include -#include #include #include #include @@ -82,7 +80,7 @@ * make the entire physical memory visible to pci bus masters */ IT_READ(IT_MC_PCICR, pcicr); - pcicr &= ~0x1f; + pcicr &= ~0x1f; pcicr |= (mem_size - 1) >> 22; IT_WRITE(IT_MC_PCICR, pcicr); diff -urN linux-2.4.21-bk37/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c linux-2.4.21-bk38/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c --- linux-2.4.21-bk37/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ite-boards/qed-4n-s01b/pci_fixup.c 2003-08-24 02:55:57.000000000 -0700 @@ -75,7 +75,7 @@ switch (slot) { case 0x01: /* - * Internal device 1 is actually 7 different + * Internal device 1 is actually 7 different * internal devices on the IT8172G (a multi- * function device). */ @@ -97,7 +97,7 @@ dev->irq = IT8172_PCI_INTD_IRQ; break; default: - dev->irq = 0xff; + dev->irq = 0xff; break; } @@ -117,7 +117,7 @@ dev->irq = IT8172_PCI_INTD_IRQ; break; default: - dev->irq = 0xff; + dev->irq = 0xff; break; } @@ -137,7 +137,7 @@ dev->irq = IT8172_PCI_INTA_IRQ; break; default: - dev->irq = 0xff; + dev->irq = 0xff; break; } @@ -157,7 +157,7 @@ dev->irq = IT8172_PCI_INTB_IRQ; break; default: - dev->irq = 0xff; + dev->irq = 0xff; break; } @@ -177,7 +177,7 @@ dev->irq = IT8172_PCI_INTC_IRQ; break; default: - dev->irq = 0xff; + dev->irq = 0xff; break; } diff -urN linux-2.4.21-bk37/arch/mips/jazz/Makefile linux-2.4.21-bk38/arch/mips/jazz/Makefile --- linux-2.4.21-bk37/arch/mips/jazz/Makefile 2001-04-13 20:26:07.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jazz/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -6,17 +6,15 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $@ -.S.o: - $(CC) $(CFLAGS) -c $< -o $@ +USE_STANDARD_AS_RULE := true all: jazz.o O_TARGET := jazz.o -obj-y := int-handler.o irq.o jazzdma.o reset.o rtc-jazz.o setup.o \ - floppy-jazz.o kbd-jazz.o +export-syms := jazz-ksyms.o +obj-y := int-handler.o irq.o jazzdma.o jazz-ksyms.o reset.o \ + rtc-jazz.o setup.o floppy-jazz.o kbd-jazz.o int-handler.o: int-handler.S diff -urN linux-2.4.21-bk37/arch/mips/jazz/floppy-jazz.c linux-2.4.21-bk38/arch/mips/jazz/floppy-jazz.c --- linux-2.4.21-bk37/arch/mips/jazz/floppy-jazz.c 2000-05-13 08:29:14.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jazz/floppy-jazz.c 2003-08-24 02:55:57.000000000 -0700 @@ -1,5 +1,4 @@ -/* $Id: floppy-jazz.c,v 1.2 1998/10/18 13:18:25 tsbogend Exp $ - * +/* * 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. @@ -108,9 +107,9 @@ static void jazz_fd_dma_mem_free(unsigned long addr, unsigned long size) -{ +{ vdma_free(vdma_phys2log(PHYSADDR(addr))); - free_pages(addr, get_order(size)); + free_pages(addr, get_order(size)); } static unsigned long jazz_fd_drive_type(unsigned long n) diff -urN linux-2.4.21-bk37/arch/mips/jazz/int-handler.S linux-2.4.21-bk38/arch/mips/jazz/int-handler.S --- linux-2.4.21-bk37/arch/mips/jazz/int-handler.S 2000-05-13 08:29:14.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jazz/int-handler.S 2003-08-24 02:55:57.000000000 -0700 @@ -1,5 +1,4 @@ -/* $Id: int-handler.S,v 1.14 1999/05/01 22:40:34 ralf Exp $ - * +/* * 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. @@ -251,14 +250,14 @@ nor s1,zero,s1 jal do_IRQ - + /* * Reenable interrupt */ lhu t2,JAZZ_IO_IRQ_ENABLE or t2,s1 sh t2,JAZZ_IO_IRQ_ENABLE - + j ret_from_irq /* diff -urN linux-2.4.21-bk37/arch/mips/jazz/irq.c linux-2.4.21-bk38/arch/mips/jazz/irq.c --- linux-2.4.21-bk37/arch/mips/jazz/irq.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jazz/irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -8,11 +8,11 @@ */ #include #include -#include #include #include #include +#include #include #include @@ -20,7 +20,7 @@ /* * On systems with i8259-style interrupt controllers we assume for - * driver compatibility reasons interrupts 0 - 15 to be the i8295 + * driver compatibility reasons interrupts 0 - 15 to be the i8259 * interrupts even if the hardware uses a different interrupt numbering. */ void __init init_IRQ (void) diff -urN linux-2.4.21-bk37/arch/mips/jazz/jazz-ksyms.c linux-2.4.21-bk38/arch/mips/jazz/jazz-ksyms.c --- linux-2.4.21-bk37/arch/mips/jazz/jazz-ksyms.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/jazz/jazz-ksyms.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,16 @@ +/* + * 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. + * + * Copyright (C) 1996, 1997, 1998, 2000, 2001, 2003 by Ralf Baechle + */ +#include + +#include +#include +#include + +EXPORT_SYMBOL(vdma_alloc); +EXPORT_SYMBOL(vdma_free); +EXPORT_SYMBOL(vdma_log2phys); diff -urN linux-2.4.21-bk37/arch/mips/jazz/kbd-jazz.c linux-2.4.21-bk38/arch/mips/jazz/kbd-jazz.c --- linux-2.4.21-bk37/arch/mips/jazz/kbd-jazz.c 2000-05-13 08:29:14.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jazz/kbd-jazz.c 2003-08-24 02:55:57.000000000 -0700 @@ -1,5 +1,4 @@ -/* $Id: kbd-jazz.c,v 1.1 1998/10/28 12:38:10 ralf Exp $ - * +/* * Low-level hardware access stuff for Jazz family machines. * * This file is subject to the terms and conditions of the GNU General Public @@ -39,20 +38,20 @@ static int jazz_aux_request_irq(void (*handler)(int, void *, struct pt_regs *)) { int ret; - + ret = request_irq(JAZZ_MOUSE_IRQ, handler, 0, "PS/2 Mouse", NULL); if (ret != 0) return ret; - r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, - r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | + r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, + r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | JAZZ_IE_MOUSE); return 0; } static void jazz_aux_free_irq(void) { - r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, + r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | JAZZ_IE_MOUSE); free_irq(JAZZ_MOUSE_IRQ, NULL); diff -urN linux-2.4.21-bk37/arch/mips/jazz/reset.c linux-2.4.21-bk38/arch/mips/jazz/reset.c --- linux-2.4.21-bk37/arch/mips/jazz/reset.c 2000-05-13 08:29:14.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jazz/reset.c 2003-08-24 02:55:57.000000000 -0700 @@ -1,11 +1,6 @@ /* - * linux/arch/mips/jazz/process.c - * - * Reset a Jazz machine. - * - * $Id:$ + * Reset a Jazz machine. */ - #include #include #include @@ -27,7 +22,7 @@ void jazz_machine_restart(char *command) { while (1) { - kb_wait (); + kb_wait (); kbd_write_command (0xd1); kb_wait (); kbd_write_output (0x00); diff -urN linux-2.4.21-bk37/arch/mips/jazz/setup.c linux-2.4.21-bk38/arch/mips/jazz/setup.c --- linux-2.4.21-bk37/arch/mips/jazz/setup.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jazz/setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -28,6 +28,7 @@ #include #include #include +#include /* * Initial irq handlers. @@ -72,7 +73,7 @@ JAZZ_IE_FLOPPY); r4030_read_reg16(JAZZ_IO_IRQ_SOURCE); /* clear pending IRQs */ r4030_read_reg32(JAZZ_R4030_INVAL_ADDR); /* clear error bits */ - change_cp0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1); + change_c0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1); /* set the clock to 100 Hz */ r4030_write_reg32(JAZZ_TIMER_INTERVAL, 9); request_region(0x20, 0x20, "pic1"); @@ -80,14 +81,20 @@ i8259_setup_irq(2, &irq2); } + void __init jazz_setup(void) { + /* Map 0xe0000000 -> 0x0:800005C0, 0xe0010000 -> 0x1:30000580 */ add_wired_entry (0x02000017, 0x03c00017, 0xe0000000, PM_64K); + + /* Map 0xe2000000 -> 0x0:900005C0, 0xe3010000 -> 0x0:910005C0 */ add_wired_entry (0x02400017, 0x02440017, 0xe2000000, PM_16M); + + /* Map 0xe4000000 -> 0x0:600005C0, 0xe4100000 -> 400005C0 */ add_wired_entry (0x01800017, 0x01000017, 0xe4000000, PM_4M); irq_setup = jazz_irq_setup; - mips_io_port_base = JAZZ_PORT_BASE; + set_io_port_base(JAZZ_PORT_BASE); if (mips_machtype == MACH_MIPS_MAGNUM_4000) EISA_bus = 1; isa_slot_offset = 0xe3000000; diff -urN linux-2.4.21-bk37/arch/mips/jmr3927/common/Makefile linux-2.4.21-bk38/arch/mips/jmr3927/common/Makefile --- linux-2.4.21-bk37/arch/mips/jmr3927/common/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jmr3927/common/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -6,10 +6,7 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true O_TARGET:= tx3927.o diff -urN linux-2.4.21-bk37/arch/mips/jmr3927/common/prom.c linux-2.4.21-bk38/arch/mips/jmr3927/common/prom.c --- linux-2.4.21-bk37/arch/mips/jmr3927/common/prom.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jmr3927/common/prom.c 2003-08-24 02:55:57.000000000 -0700 @@ -6,11 +6,11 @@ * * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. - * ahennessy@mvista.com + * ahennessy@mvista.com * * Based on arch/mips/au1000/common/prom.c * - * This file was derived from Carsten Langgaard's + * This file was derived from Carsten Langgaard's * arch/mips/mips-boards/xx files. * * Carsten Langgaard, carstenl@mips.com @@ -36,8 +36,6 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include #include #include #include diff -urN linux-2.4.21-bk37/arch/mips/jmr3927/common/puts.c linux-2.4.21-bk38/arch/mips/jmr3927/common/puts.c --- linux-2.4.21-bk37/arch/mips/jmr3927/common/puts.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jmr3927/common/puts.c 2003-08-24 02:55:57.000000000 -0700 @@ -7,7 +7,7 @@ * Author: MontaVista Software, Inc. * ahennessy@mvista.com or source@mvista.com * - * Copyright (C) 2000-2001 Toshiba Corporation + * Copyright (C) 2000-2001 Toshiba Corporation * * Based on arch/mips/au1000/common/puts.c * @@ -52,7 +52,7 @@ putch(const unsigned char c) { int i = 0; - + do { slow_down(); i++; @@ -69,7 +69,7 @@ int i = 0; int dicr; char c; - + /* diable RX int. */ dicr = tx3927_sioptr(1)->dicr; tx3927_sioptr(1)->dicr = 0; diff -urN linux-2.4.21-bk37/arch/mips/jmr3927/common/rtc_ds1742.c linux-2.4.21-bk38/arch/mips/jmr3927/common/rtc_ds1742.c --- linux-2.4.21-bk37/arch/mips/jmr3927/common/rtc_ds1742.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jmr3927/common/rtc_ds1742.c 2003-08-24 02:55:57.000000000 -0700 @@ -2,13 +2,13 @@ * * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. - * ahennessy@mvista.com + * ahennessy@mvista.com * * arch/mips/jmr3927/common/rtc_ds1742.c * Based on arch/mips/ddb5xxx/common/rtc_ds1386.c * low-level RTC hookups for s for Dallas 1742 chip. * - * Copyright (C) 2000-2001 Toshiba Corporation + * Copyright (C) 2000-2001 Toshiba Corporation * * 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 @@ -82,7 +82,7 @@ } extern void to_tm(unsigned long tim, struct rtc_time * tm); -static int +static int rtc_ds1742_set_time(unsigned long t) { struct rtc_time tm; @@ -117,7 +117,7 @@ day = BIN_TO_BCD(tm.tm_mday); if (day != cmos_day) { - + CMOS_WRITE(day, RTC_DATE); } @@ -144,7 +144,7 @@ if (second != cmos_second) { CMOS_WRITE(second & RTC_SECONDS_MASK,RTC_SECONDS); } - + /* RTC_CENTURY and RTC_CONTROL share same address... */ CMOS_WRITE(cmos_century, RTC_CONTROL); diff -urN linux-2.4.21-bk37/arch/mips/jmr3927/rbhma3100/Makefile linux-2.4.21-bk38/arch/mips/jmr3927/rbhma3100/Makefile --- linux-2.4.21-bk37/arch/mips/jmr3927/rbhma3100/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jmr3927/rbhma3100/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -6,16 +6,13 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true O_TARGET:= jmr3927.o obj-y += init.o int-handler.o irq.o setup.o rtc.o pci_fixup.o pci_ops.o -obj-$(CONFIG_LL_DEBUG) += debug.o -obj-$(CONFIG_REMOTE_DEBUG) += kgdb_io.o +obj-$(CONFIG_RUNTIME_DEBUG) += debug.o +obj-$(CONFIG_KGDB) += kgdb_io.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/jmr3927/rbhma3100/init.c linux-2.4.21-bk38/arch/mips/jmr3927/rbhma3100/init.c --- linux-2.4.21-bk37/arch/mips/jmr3927/rbhma3100/init.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jmr3927/rbhma3100/init.c 2003-08-24 02:55:57.000000000 -0700 @@ -2,11 +2,11 @@ * * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. - * ahennessy@mvista.com + * ahennessy@mvista.com * * arch/mips/jmr3927/common/init.c * - * Copyright (C) 2000-2001 Toshiba Corporation + * Copyright (C) 2000-2001 Toshiba Corporation * * 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 @@ -66,7 +66,7 @@ #endif prom_argc = argc; prom_argv = argv; - prom_envp = envp; + prom_envp = envp; mips_machgroup = MACH_GROUP_TOSHIBA; diff -urN linux-2.4.21-bk37/arch/mips/jmr3927/rbhma3100/int-handler.S linux-2.4.21-bk38/arch/mips/jmr3927/rbhma3100/int-handler.S --- linux-2.4.21-bk37/arch/mips/jmr3927/rbhma3100/int-handler.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jmr3927/rbhma3100/int-handler.S 2003-08-24 02:55:57.000000000 -0700 @@ -1,7 +1,7 @@ /* * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. - * ahennessy@mvista.com + * ahennessy@mvista.com * * Based on arch/mips/tsdb/kernel/int-handler.S * diff -urN linux-2.4.21-bk37/arch/mips/jmr3927/rbhma3100/irq.c linux-2.4.21-bk38/arch/mips/jmr3927/rbhma3100/irq.c --- linux-2.4.21-bk37/arch/mips/jmr3927/rbhma3100/irq.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jmr3927/rbhma3100/irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -1,7 +1,7 @@ /* * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. - * ahennessy@mvista.com + * ahennessy@mvista.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 @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -47,7 +48,6 @@ #include #include -#include #include #include @@ -137,7 +137,7 @@ db_assert(irq < jmr3927_irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC); if (irq == JMR3927_IRQ_IRC_TMR0) { - jmr3927_tmrptr->tisr = 0; /* ack interrupt */ + jmr3927_tmrptr->tisr = 0; /* ack interrupt */ } jmr3927_irq_disable(irq); @@ -248,33 +248,33 @@ } struct tb_irq_space jmr3927_isac_irqspace = { - next: NULL, - start_irqno: JMR3927_IRQ_ISAC, + .next = NULL, + .start_irqno = JMR3927_IRQ_ISAC, nr_irqs : JMR3927_NR_IRQ_ISAC, - mask_func: mask_irq_isac, - unmask_func: unmask_irq_isac, - name: "ISAC", - space_id: 0, + .mask_func = mask_irq_isac, + .unmask_func = unmask_irq_isac, + .name = "ISAC", + .space_id = 0, can_share : 0 }; struct tb_irq_space jmr3927_ioc_irqspace = { - next: NULL, - start_irqno: JMR3927_IRQ_IOC, + .next = NULL, + .start_irqno = JMR3927_IRQ_IOC, nr_irqs : JMR3927_NR_IRQ_IOC, - mask_func: mask_irq_ioc, - unmask_func: unmask_irq_ioc, - name: "IOC", - space_id: 0, + .mask_func = mask_irq_ioc, + .unmask_func = unmask_irq_ioc, + .name = "IOC", + .space_id = 0, can_share : 1 }; struct tb_irq_space jmr3927_irc_irqspace = { - next: NULL, - start_irqno: JMR3927_IRQ_IRC, + .next = NULL, + .start_irqno = JMR3927_IRQ_IRC, nr_irqs : JMR3927_NR_IRQ_IRC, - mask_func: mask_irq_irc, - unmask_func: unmask_irq_irc, - name: "on-chip", - space_id: 0, + .mask_func = mask_irq_irc, + .unmask_func = unmask_irq_irc, + .name = "on-chip", + .space_id = 0, can_share : 0 }; @@ -287,11 +287,10 @@ regs->cp0_cause, regs->cp0_epc, regs->regs[31]); } -extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs); void jmr3927_irc_irqdispatch(struct pt_regs *regs) { int irq; - + #ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND tx_branch_likely_bug_fixup(regs); #endif @@ -437,14 +436,14 @@ #endif /* enable all CPU interrupt bits. */ - set_cp0_status(ST0_IM); /* IE bit is still 0. */ + set_c0_status(ST0_IM); /* IE bit is still 0. */ } void (*irq_setup)(void); void __init init_IRQ(void) { -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void breakpoint(void); extern void set_debug_traps(void); @@ -468,7 +467,7 @@ NULL /* no affinity stuff for UP */ }; -void +void jmr3927_irq_init(u32 irq_base) { extern irq_desc_t irq_desc[]; @@ -480,7 +479,7 @@ irq_desc[i].depth = 1; irq_desc[i].handler = &jmr3927_irq_controller; } - + jmr3927_irq_base = irq_base; } diff -urN linux-2.4.21-bk37/arch/mips/jmr3927/rbhma3100/kgdb_io.c linux-2.4.21-bk38/arch/mips/jmr3927/rbhma3100/kgdb_io.c --- linux-2.4.21-bk37/arch/mips/jmr3927/rbhma3100/kgdb_io.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jmr3927/rbhma3100/kgdb_io.c 2003-08-24 02:55:57.000000000 -0700 @@ -8,7 +8,7 @@ * * Based on arch/mips/ddb5xxx/ddb5477/kgdb_io.c * - * Copyright (C) 2000-2001 Toshiba Corporation + * Copyright (C) 2000-2001 Toshiba Corporation * * 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 @@ -52,7 +52,7 @@ int putDebugChar(unsigned char c) { int i = 0; - + if (!remoteDebugInitialized) { remoteDebugInitialized = 1; debugInit(38400); @@ -75,7 +75,7 @@ int i = 0; int dicr; char c; - + if (!remoteDebugInitialized) { remoteDebugInitialized = 1; debugInit(38400); diff -urN linux-2.4.21-bk37/arch/mips/jmr3927/rbhma3100/pci_fixup.c linux-2.4.21-bk38/arch/mips/jmr3927/rbhma3100/pci_fixup.c --- linux-2.4.21-bk37/arch/mips/jmr3927/rbhma3100/pci_fixup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jmr3927/rbhma3100/pci_fixup.c 2003-08-24 02:55:57.000000000 -0700 @@ -42,7 +42,7 @@ #ifdef DEBUG #define DBG(x...) printk(x) #else -#define DBG(x...) +#define DBG(x...) #endif void __init pcibios_fixup_resources(struct pci_dev *dev) diff -urN linux-2.4.21-bk37/arch/mips/jmr3927/rbhma3100/pci_ops.c linux-2.4.21-bk38/arch/mips/jmr3927/rbhma3100/pci_ops.c --- linux-2.4.21-bk37/arch/mips/jmr3927/rbhma3100/pci_ops.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jmr3927/rbhma3100/pci_ops.c 2003-08-24 02:55:57.000000000 -0700 @@ -1,15 +1,15 @@ /*********************************************************************** * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. - * ahennessy@mvista.com + * ahennessy@mvista.com * - * Copyright (C) 2000-2001 Toshiba Corporation + * Copyright (C) 2000-2001 Toshiba Corporation * * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c * * Define the pci_ops for JMR3927. * - * Much of the code is derived from the original DDB5074 port by + * Much of the code is derived from the original DDB5074 port by * Geert Uytterhoeven * * This program is free software; you can redistribute it and/or modify it @@ -37,7 +37,6 @@ #include #include #include -#include #include #include @@ -45,13 +44,13 @@ #include struct resource pci_io_resource = { - "pci IO space", + "pci IO space", 0x1000, /* reserve regacy I/O space */ 0x1000 + JMR3927_PCIIO_SIZE -1, IORESOURCE_IO}; struct resource pci_mem_resource = { - "pci memory space", + "pci memory space", JMR3927_PCIMEM, JMR3927_PCIMEM + JMR3927_PCIMEM_SIZE -1, IORESOURCE_MEM}; @@ -66,7 +65,7 @@ unsigned int pcibios_assign_all_busses(void) { return 1; -} +} static int mkaddr(unsigned char bus, unsigned char dev_fn, unsigned char where, int *flagsp) @@ -107,7 +106,7 @@ unsigned char bus, func_num; db_assert((where & 3) == 0); - db_assert(where < (1 << 8)); + db_assert(where < (1 << 8)); /* check if the bus is top-level */ if (dev->bus->parent != NULL) { @@ -115,7 +114,7 @@ db_assert(bus != 0); } else { bus = 0; - } + } func_num = PCI_FUNC(dev->devfn); if (mkaddr(bus, dev->devfn, where, &flags)) @@ -135,7 +134,7 @@ return PCIBIOS_BAD_REGISTER_NUMBER; db_assert((where & 3) == 0); - db_assert(where < (1 << 8)); + db_assert(where < (1 << 8)); /* check if the bus is top-level */ if (dev->bus->parent != NULL) { @@ -143,7 +142,7 @@ db_assert(bus != 0); } else { bus = 0; - } + } func_num = PCI_FUNC(dev->devfn); if (mkaddr(bus, dev->devfn, where, &flags)) @@ -163,7 +162,7 @@ return PCIBIOS_BAD_REGISTER_NUMBER; db_assert((where & 3) == 0); - db_assert(where < (1 << 8)); + db_assert(where < (1 << 8)); /* check if the bus is top-level */ if (dev->bus->parent != NULL) { @@ -171,7 +170,7 @@ db_assert(bus != 0); } else { bus = 0; - } + } func_num = PCI_FUNC(dev->devfn); if (mkaddr(bus, dev->devfn, where, &flags)) @@ -193,7 +192,7 @@ db_assert(bus != 0); } else { bus = 0; - } + } func_num = PCI_FUNC(dev->devfn); if (mkaddr(bus, dev->devfn, where, &flags)) @@ -218,7 +217,7 @@ db_assert(bus != 0); } else { bus = 0; - } + } func_num = PCI_FUNC(dev->devfn); if (mkaddr(bus, dev->devfn, where, &flags)) @@ -243,7 +242,7 @@ db_assert(bus != 0); } else { bus = 0; - } + } func_num = PCI_FUNC(dev->devfn); if (mkaddr(bus, dev->devfn, where, &flags)) @@ -276,7 +275,7 @@ addr = PHYSADDR(addr); *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)addr; - *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = + *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_MEMREAD << PCI_IPCIBE_ICMD_SHIFT) | PCI_IPCIBE_IBE_LONG; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata); @@ -289,7 +288,7 @@ addr = PHYSADDR(addr); *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = cpu_to_le32(data); *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)addr; - *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = + *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_MEMWRITE << PCI_IPCIBE_ICMD_SHIFT) | PCI_IPCIBE_IBE_LONG; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; /* clear by setting */ @@ -313,7 +312,7 @@ else if (offset == 3) byte = 0xe; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)ioaddr; - *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = + *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata); @@ -341,7 +340,7 @@ byte = 0xe; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = data; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)ioaddr; - *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = + *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | byte; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; /* clear by setting */ @@ -361,7 +360,7 @@ else if (offset == 2) byte = 0xc; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)ioaddr; - *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = + *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata); @@ -386,7 +385,7 @@ byte = 0xc; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = data; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)ioaddr; - *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = + *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | byte; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; /* clear by setting */ @@ -399,7 +398,7 @@ ioaddr = (unsigned long)addr; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)ioaddr; - *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = + *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | PCI_IPCIBE_IBE_LONG; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata); @@ -414,7 +413,7 @@ ioaddr = (unsigned long)addr; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = cpu_to_le32(data); *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)ioaddr; - *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = + *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | PCI_IPCIBE_IBE_LONG; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; /* clear by setting */ diff -urN linux-2.4.21-bk37/arch/mips/jmr3927/rbhma3100/rtc.c linux-2.4.21-bk38/arch/mips/jmr3927/rbhma3100/rtc.c --- linux-2.4.21-bk37/arch/mips/jmr3927/rbhma3100/rtc.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jmr3927/rbhma3100/rtc.c 2003-08-24 02:55:57.000000000 -0700 @@ -1,7 +1,7 @@ /* * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. - * ahennessy@mvista.com + * ahennessy@mvista.com * * RTC routines for Dallas chip. * diff -urN linux-2.4.21-bk37/arch/mips/jmr3927/rbhma3100/setup.c linux-2.4.21-bk38/arch/mips/jmr3927/rbhma3100/setup.c --- linux-2.4.21-bk37/arch/mips/jmr3927/rbhma3100/setup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/jmr3927/rbhma3100/setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -2,13 +2,13 @@ * * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. - * ahennessy@mvista.com + * ahennessy@mvista.com * * Based on arch/mips/ddb5xxx/ddb5477/setup.c * * Setup file for JMR3927. * - * Copyright (C) 2000-2001 Toshiba Corporation + * Copyright (C) 2000-2001 Toshiba Corporation * * 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 @@ -55,6 +55,7 @@ #include #include #include +#include /* Tick Timer divider */ #define JMR3927_TIMER_CCD 0 /* 1/2 */ @@ -180,11 +181,12 @@ } return res; -} +} + #if defined(CONFIG_BLK_DEV_INITRD) extern unsigned long __rd_start, __rd_end, initrd_start, initrd_end; -#endif +#endif //#undef DO_WRITE_THROUGH #define DO_WRITE_THROUGH @@ -211,19 +213,19 @@ _machine_power_off = jmr3927_machine_power_off; /* - * IO/MEM resources. + * IO/MEM resources. */ ioport_resource.start = pci_io_resource.start; ioport_resource.end = pci_io_resource.end; iomem_resource.start = pci_mem_resource.start; iomem_resource.end = pci_mem_resource.end; - + /* Reboot on panic */ panic_timeout = 180; { unsigned int conf; - conf = read_32bit_cp0_register(CP0_CONF); + conf = read_c0_conf(); } #if 1 @@ -243,15 +245,15 @@ int mips_config_wbon = 1; #endif - conf = read_32bit_cp0_register(CP0_CONF); + conf = read_c0_conf(); conf &= ~(TX39_CONF_ICE | TX39_CONF_DCE | TX39_CONF_WBON | TX39_CONF_CWFON); conf |= mips_ic_disable ? 0 : TX39_CONF_ICE; conf |= mips_dc_disable ? 0 : TX39_CONF_DCE; conf |= mips_config_wbon ? TX39_CONF_WBON : 0; conf |= mips_config_cwfon ? TX39_CONF_CWFON : 0; - write_32bit_cp0_register(CP0_CONF, conf); - write_32bit_cp0_register(CP0_TX39_CACHE, 0); + write_c0_conf(conf); + write_c0_cache(0); } #endif @@ -275,9 +277,9 @@ argptr = prom_getcmdline(); strcat(argptr, " console=ttyS1,115200"); } -#endif +#endif } - + static void tx3927_setup(void); @@ -338,7 +340,7 @@ jmr3927_led_set(0); - if (jmr3927_have_isac()) + if (jmr3927_have_isac()) jmr3927_io_led_set(0); printk("JMR-TX3927 (Rev %d) --- IOC(Rev %d) DIPSW:%d,%d,%d,%d\n", jmr3927_ioc_reg_in(JMR3927_IOC_BREV_ADDR) & JMR3927_REV_MASK, @@ -510,7 +512,7 @@ { unsigned int conf; - conf = read_32bit_cp0_register(CP0_CONF); + conf = read_c0_conf(); if (!(conf & TX39_CONF_ICE)) printk("TX3927 I-Cache disabled.\n"); if (!(conf & TX39_CONF_DCE)) diff -urN linux-2.4.21-bk37/arch/mips/kernel/Makefile linux-2.4.21-bk38/arch/mips/kernel/Makefile --- linux-2.4.21-bk37/arch/mips/kernel/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -12,11 +12,11 @@ O_TARGET := kernel.o -export-objs = irq.o pci-dma.o setup.o smp.o mips_ksyms.o old-irq.o +export-objs = irq.o mips_ksyms.o pci-dma.o setup.o smp.o -obj-y += branch.o cpu-probe.o process.o signal.o entry.o traps.o \ - ptrace.o vm86.o ioport.o reset.o semaphore.o setup.o \ - syscall.o sysmips.o ipc.o scall_o32.o unaligned.o +obj-y += branch.o cpu-probe.o irq.o process.o signal.o entry.o \ + traps.o ptrace.o reset.o semaphore.o setup.o syscall.o \ + sysmips.o ipc.o scall_o32.o unaligned.o obj-$(CONFIG_MODULES) += mips_ksyms.o @@ -39,9 +39,6 @@ obj-$(CONFIG_SMP) += smp.o -# Old style irq support, going to die in 2.5. -obj-$(CONFIG_NEW_IRQ) += irq.o -obj-$(CONFIG_ROTTEN_IRQ) += old-irq.o obj-$(CONFIG_I8259) += i8259.o obj-$(CONFIG_IRQ_CPU) += irq_cpu.o @@ -53,11 +50,9 @@ obj-$(CONFIG_BINFMT_IRIX) += irixelf.o irixioctl.o irixsig.o sysirix.o \ irixinv.o -obj-$(CONFIG_REMOTE_DEBUG) += gdb-low.o gdb-stub.o +obj-$(CONFIG_KGDB) += gdb-low.o gdb-stub.o obj-$(CONFIG_PROC_FS) += proc.o -obj-$(CONFIG_NEW_PCI) += pci.o -obj-$(CONFIG_PCI_AUTO) += pci_auto.o ifndef CONFIG_MAPPED_PCI_IO obj-y += pci-dma.o endif diff -urN linux-2.4.21-bk37/arch/mips/kernel/branch.c linux-2.4.21-bk38/arch/mips/kernel/branch.c --- linux-2.4.21-bk37/arch/mips/kernel/branch.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/kernel/branch.c 2003-08-24 02:55:57.000000000 -0700 @@ -163,10 +163,10 @@ * And now the FPA/cp1 branch instructions. */ case cop1_op: - if (!(mips_cpu.options & MIPS_CPU_FPU)) + if (!cpu_has_fpu) fcr31 = current->thread.fpu.soft.sr; else - asm("cfc1\t%0,$31":"=r" (fcr31)); + asm volatile("cfc1\t%0,$31" : "=r" (fcr31)); bit = (insn.i_format.rt >> 2); bit += (bit != 0); bit += 23; diff -urN linux-2.4.21-bk37/arch/mips/kernel/cpu-probe.c linux-2.4.21-bk38/arch/mips/kernel/cpu-probe.c --- linux-2.4.21-bk37/arch/mips/kernel/cpu-probe.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/cpu-probe.c 2003-08-24 02:55:57.000000000 -0700 @@ -3,6 +3,7 @@ #include #include #include +#include #include /* @@ -16,14 +17,14 @@ static void r3081_wait(void) { - unsigned long cfg = read_32bit_cp0_register(CP0_CONF); - write_32bit_cp0_register(CP0_CONF, cfg|CONF_HALT); + unsigned long cfg = read_c0_conf(); + write_c0_conf(cfg | R30XX_CONF_HALT); } static void r39xx_wait(void) { - unsigned long cfg = read_32bit_cp0_register(CP0_CONF); - write_32bit_cp0_register(CP0_CONF, cfg|TX39_CONF_HALT); + unsigned long cfg = read_c0_conf(); + write_c0_conf(cfg | TX39_CONF_HALT); } static void r4k_wait(void) @@ -39,23 +40,29 @@ /* using the wait instruction makes CP0 counter unusable */ __asm__(".set\tmips3\n\t" "wait\n\t" - "nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" ".set\tmips0"); + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set\tmips0"); #else - __asm__("nop\n\t" "nop\n\t"); + __asm__("nop\n\t" + "nop"); #endif } static inline void check_wait(void) { + struct cpuinfo_mips *c = ¤t_cpu_data; + printk("Checking for 'wait' instruction... "); - switch(mips_cpu.cputype) { + switch (c->cputype) { case CPU_R3081: case CPU_R3081E: cpu_wait = r3081_wait; printk(" available.\n"); break; case CPU_TX3927: - case CPU_TX39XX: cpu_wait = r39xx_wait; printk(" available.\n"); break; @@ -104,12 +111,12 @@ #ifdef CONFIG_CPU_R3000 extern unsigned long r3k_cache_size(unsigned long); unsigned long size1, size2; - unsigned long cfg = read_32bit_cp0_register(CP0_CONF); + unsigned long cfg = read_c0_conf(); size1 = r3k_cache_size(ST0_ISC); - write_32bit_cp0_register(CP0_CONF, cfg^CONF_AC); + write_c0_conf(cfg ^ R30XX_CONF_AC); size2 = r3k_cache_size(ST0_ISC); - write_32bit_cp0_register(CP0_CONF, cfg); + write_c0_conf(cfg); return size1 != size2; #else return 0; @@ -123,143 +130,138 @@ { unsigned long tmp, fpu_id; - tmp = read_32bit_cp0_register(CP0_STATUS); + tmp = read_c0_status(); __enable_fpu(); fpu_id = read_32bit_cp1_register(CP1_REVISION); - write_32bit_cp0_register(CP0_STATUS, tmp); + write_c0_status(tmp); return fpu_id; } /* * Check the CPU has an FPU the official way. */ -static inline int cpu_has_fpu(void) +static inline int __cpu_has_fpu(void) { return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE); } -/* declaration of the global struct */ -struct mips_cpu mips_cpu = { - processor_id: PRID_IMP_UNKNOWN, - fpu_id: FPIR_IMP_NONE, - cputype: CPU_UNKNOWN -}; - -/* Shortcut for assembler access to mips_cpu.options */ -int *cpuoptions = &mips_cpu.options; - #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \ | MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX) __init void cpu_probe(void) { -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) - unsigned long config0 = read_32bit_cp0_register(CP0_CONFIG); + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned long config0 = read_c0_config(); unsigned long config1; + c->processor_id = PRID_IMP_UNKNOWN; + c->fpu_id = FPIR_IMP_NONE; + c->cputype = CPU_UNKNOWN; + if (config0 & (1 << 31)) { /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */ - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC; - config1 = read_mips32_cp0_config1(); + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | + MIPS_CPU_LLSC; + config1 = read_c0_config1(); if (config1 & (1 << 3)) - mips_cpu.options |= MIPS_CPU_WATCH; + c->options |= MIPS_CPU_WATCH; if (config1 & (1 << 2)) - mips_cpu.options |= MIPS_CPU_MIPS16; + c->options |= MIPS_CPU_MIPS16; if (config1 & (1 << 1)) - mips_cpu.options |= MIPS_CPU_EJTAG; + c->options |= MIPS_CPU_EJTAG; if (config1 & 1) { - mips_cpu.options |= MIPS_CPU_FPU; -#if defined(CONFIG_CPU_MIPS64) - mips_cpu.options |= MIPS_CPU_32FPR; -#endif + c->options |= MIPS_CPU_FPU; + c->options |= MIPS_CPU_32FPR; } - mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT; + c->scache.flags = MIPS_CACHE_NOT_PRESENT; + + c->tlbsize = ((config1 >> 25) & 0x3f) + 1; } -#endif - mips_cpu.processor_id = read_32bit_cp0_register(CP0_PRID); - switch (mips_cpu.processor_id & 0xff0000) { + + c->processor_id = read_c0_prid(); + switch (c->processor_id & 0xff0000) { case PRID_COMP_LEGACY: - switch (mips_cpu.processor_id & 0xff00) { + switch (c->processor_id & 0xff00) { case PRID_IMP_R2000: - mips_cpu.cputype = CPU_R2000; - mips_cpu.isa_level = MIPS_CPU_ISA_I; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX; - if (cpu_has_fpu()) - mips_cpu.options |= MIPS_CPU_FPU; - mips_cpu.tlbsize = 64; + c->cputype = CPU_R2000; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | + MIPS_CPU_LLSC; + if (__cpu_has_fpu()) + c->options |= MIPS_CPU_FPU; + c->tlbsize = 64; break; case PRID_IMP_R3000: - if ((mips_cpu.processor_id & 0xff) == PRID_REV_R3000A) + if ((c->processor_id & 0xff) == PRID_REV_R3000A) if (cpu_has_confreg()) - mips_cpu.cputype = CPU_R3081E; + c->cputype = CPU_R3081E; else - mips_cpu.cputype = CPU_R3000A; + c->cputype = CPU_R3000A; else - mips_cpu.cputype = CPU_R3000; - mips_cpu.isa_level = MIPS_CPU_ISA_I; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX; - if (cpu_has_fpu()) - mips_cpu.options |= MIPS_CPU_FPU; - mips_cpu.tlbsize = 64; + c->cputype = CPU_R3000; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | + MIPS_CPU_LLSC; + if (__cpu_has_fpu()) + c->options |= MIPS_CPU_FPU; + c->tlbsize = 64; break; case PRID_IMP_R4000: - if ((mips_cpu.processor_id & 0xff) == PRID_REV_R4400) - mips_cpu.cputype = CPU_R4400SC; + if ((c->processor_id & 0xff) >= PRID_REV_R4400) + c->cputype = CPU_R4400SC; else - mips_cpu.cputype = CPU_R4000SC; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR | MIPS_CPU_WATCH | - MIPS_CPU_VCE; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R4000SC; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_VCE | + MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_VR41XX: - switch (mips_cpu.processor_id & 0xf0) { + switch (c->processor_id & 0xf0) { #ifndef CONFIG_VR4181 case PRID_REV_VR4111: - mips_cpu.cputype = CPU_VR4111; + c->cputype = CPU_VR4111; break; #else case PRID_REV_VR4181: - mips_cpu.cputype = CPU_VR4181; + c->cputype = CPU_VR4181; break; #endif case PRID_REV_VR4121: - mips_cpu.cputype = CPU_VR4121; + c->cputype = CPU_VR4121; break; case PRID_REV_VR4122: - if ((mips_cpu.processor_id & 0xf) < 0x3) - mips_cpu.cputype = CPU_VR4122; + if ((c->processor_id & 0xf) < 0x3) + c->cputype = CPU_VR4122; else - mips_cpu.cputype = CPU_VR4181A; + c->cputype = CPU_VR4181A; break; case PRID_REV_VR4131: - mips_cpu.cputype = CPU_VR4131; - mips_cpu.icache.ways = 2; - mips_cpu.dcache.ways = 2; + c->cputype = CPU_VR4131; break; default: printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); - mips_cpu.cputype = CPU_VR41XX; + c->cputype = CPU_VR41XX; break; } - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS; - mips_cpu.tlbsize = 32; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS; + c->tlbsize = 32; break; case PRID_IMP_R4300: - mips_cpu.cputype = CPU_R4300; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; - mips_cpu.tlbsize = 32; + c->cputype = CPU_R4300; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 32; break; case PRID_IMP_R4600: - mips_cpu.cputype = CPU_R4600; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R4600; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; + c->tlbsize = 48; break; #if 0 case PRID_IMP_R4650: @@ -269,101 +271,97 @@ * for documentation. Commented out because it shares * it's c0_prid id number with the TX3900. */ - mips_cpu.cputype = CPU_R4650; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R4650; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; + c->tlbsize = 48; break; #endif case PRID_IMP_TX39: - mips_cpu.isa_level = MIPS_CPU_ISA_I; - mips_cpu.options = MIPS_CPU_TLB; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB; - if ((mips_cpu.processor_id & 0xf0) == + if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) { - mips_cpu.cputype = CPU_TX3927; - mips_cpu.tlbsize = 64; - mips_cpu.icache.ways = 2; - mips_cpu.dcache.ways = 2; + c->cputype = CPU_TX3927; + c->tlbsize = 64; } else { - switch (mips_cpu.processor_id & 0xff) { + switch (c->processor_id & 0xff) { case PRID_REV_TX3912: - mips_cpu.cputype = CPU_TX3912; - mips_cpu.tlbsize = 32; + c->cputype = CPU_TX3912; + c->tlbsize = 32; break; case PRID_REV_TX3922: - mips_cpu.cputype = CPU_TX3922; - mips_cpu.tlbsize = 64; + c->cputype = CPU_TX3922; + c->tlbsize = 64; break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; break; } } break; case PRID_IMP_R4700: - mips_cpu.cputype = CPU_R4700; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R4700; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_TX49: - mips_cpu.cputype = CPU_TX49XX; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; - mips_cpu.tlbsize = 48; - mips_cpu.icache.ways = 4; - mips_cpu.dcache.ways = 4; + c->cputype = CPU_TX49XX; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_R5000: - mips_cpu.cputype = CPU_R5000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R5000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_R5432: - mips_cpu.cputype = CPU_R5432; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR | MIPS_CPU_WATCH; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R5432; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_R5500: - mips_cpu.cputype = CPU_R5500; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR | MIPS_CPU_WATCH; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R5500; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_NEVADA: - mips_cpu.cputype = CPU_NEVADA; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR | MIPS_CPU_DIVEC; - mips_cpu.tlbsize = 48; - mips_cpu.icache.ways = 2; - mips_cpu.dcache.ways = 2; + c->cputype = CPU_NEVADA; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_DIVEC | MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_R6000: - mips_cpu.cputype = CPU_R6000; - mips_cpu.isa_level = MIPS_CPU_ISA_II; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU; - mips_cpu.tlbsize = 32; + c->cputype = CPU_R6000; + c->isa_level = MIPS_CPU_ISA_II; + c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | + MIPS_CPU_LLSC; + c->tlbsize = 32; break; case PRID_IMP_R6000A: - mips_cpu.cputype = CPU_R6000A; - mips_cpu.isa_level = MIPS_CPU_ISA_II; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU; - mips_cpu.tlbsize = 32; + c->cputype = CPU_R6000A; + c->isa_level = MIPS_CPU_ISA_II; + c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | + MIPS_CPU_LLSC; + c->tlbsize = 32; break; case PRID_IMP_RM7000: - mips_cpu.cputype = CPU_RM7000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; + c->cputype = CPU_RM7000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; /* * Undocumented RM7000: Bit 29 in the info register of * the RM7000 v2.0 indicates if the TLB has 48 or 64 @@ -372,118 +370,139 @@ * 29 1 => 64 entry JTLB * 0 => 48 entry JTLB */ - mips_cpu.tlbsize = (get_info() & (1 << 29)) ? 64 : 48; + c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; break; case PRID_IMP_R8000: - mips_cpu.cputype = CPU_R8000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR; - mips_cpu.tlbsize = 384; /* has weird TLB: 3-way x 128 */ + c->cputype = CPU_R8000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 384; /* has weird TLB: 3-way x 128 */ break; case PRID_IMP_R10000: - mips_cpu.cputype = CPU_R10000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_COUNTER | MIPS_CPU_WATCH; - mips_cpu.tlbsize = 64; + c->cputype = CPU_R10000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_COUNTER | MIPS_CPU_WATCH | + MIPS_CPU_LLSC; + c->tlbsize = 64; break; case PRID_IMP_R12000: - mips_cpu.cputype = CPU_R12000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_COUNTER | MIPS_CPU_WATCH; - mips_cpu.tlbsize = 64; + c->cputype = CPU_R12000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_COUNTER | MIPS_CPU_WATCH | + MIPS_CPU_LLSC; + c->tlbsize = 64; break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; break; } break; -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) case PRID_COMP_MIPS: - switch (mips_cpu.processor_id & 0xff00) { + switch (c->processor_id & 0xff00) { case PRID_IMP_4KC: - mips_cpu.cputype = CPU_4KC; - mips_cpu.isa_level = MIPS_CPU_ISA_M32; + c->cputype = CPU_4KC; + c->isa_level = MIPS_CPU_ISA_M32; break; case PRID_IMP_4KEC: - mips_cpu.cputype = CPU_4KEC; - mips_cpu.isa_level = MIPS_CPU_ISA_M32; + c->cputype = CPU_4KEC; + c->isa_level = MIPS_CPU_ISA_M32; break; case PRID_IMP_4KSC: - mips_cpu.cputype = CPU_4KSC; - mips_cpu.isa_level = MIPS_CPU_ISA_M32; + c->cputype = CPU_4KSC; + c->isa_level = MIPS_CPU_ISA_M32; break; case PRID_IMP_5KC: - mips_cpu.cputype = CPU_5KC; - mips_cpu.isa_level = MIPS_CPU_ISA_M64; + c->cputype = CPU_5KC; + c->isa_level = MIPS_CPU_ISA_M64; break; case PRID_IMP_20KC: - mips_cpu.cputype = CPU_20KC; - mips_cpu.isa_level = MIPS_CPU_ISA_M64; + c->cputype = CPU_20KC; + c->isa_level = MIPS_CPU_ISA_M64; break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; break; } break; case PRID_COMP_ALCHEMY: - switch (mips_cpu.processor_id & 0xff00) { + switch (c->processor_id & 0xff00) { case PRID_IMP_AU1_REV1: case PRID_IMP_AU1_REV2: - switch ((mips_cpu.processor_id >> 24) & 0xff) { + switch ((c->processor_id >> 24) & 0xff) { case 0: - mips_cpu.cputype = CPU_AU1000; + c->cputype = CPU_AU1000; break; case 1: - mips_cpu.cputype = CPU_AU1500; + c->cputype = CPU_AU1500; break; case 2: - mips_cpu.cputype = CPU_AU1100; + c->cputype = CPU_AU1100; break; default: panic("Unknown Au Core!"); break; } - mips_cpu.isa_level = MIPS_CPU_ISA_M32; + c->isa_level = MIPS_CPU_ISA_M32; break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; break; } break; -#endif /* CONFIG_CPU_MIPS32 */ case PRID_COMP_SIBYTE: - switch (mips_cpu.processor_id & 0xff00) { + switch (c->processor_id & 0xff00) { case PRID_IMP_SB1: - mips_cpu.cputype = CPU_SB1; - mips_cpu.isa_level = MIPS_CPU_ISA_M64; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | - MIPS_CPU_MCHECK; + c->cputype = CPU_SB1; + c->isa_level = MIPS_CPU_ISA_M64; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | + MIPS_CPU_MCHECK | MIPS_CPU_EJTAG | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; #ifndef CONFIG_SB1_PASS_1_WORKAROUNDS /* FPU in pass1 is known to have issues. */ - mips_cpu.options |= MIPS_CPU_FPU; + c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; #endif break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; + break; + } + break; + + case PRID_COMP_SANDCRAFT: + switch (c->processor_id & 0xff00) { + case PRID_IMP_SR71000: + c->cputype = CPU_SR71000; + c->isa_level = MIPS_CPU_ISA_M64; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_FPU | + MIPS_CPU_COUNTER | MIPS_CPU_MCHECK; + c->scache.ways = 8; + c->tlbsize = 64; + break; + default: + c->cputype = CPU_UNKNOWN; break; } break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; } - if (mips_cpu.options & MIPS_CPU_FPU) - mips_cpu.fpu_id = cpu_get_fpu_id(); + if (c->options & MIPS_CPU_FPU) + c->fpu_id = cpu_get_fpu_id(); } __init void cpu_report(void) { - printk("CPU revision is: %08x\n", mips_cpu.processor_id); - if (mips_cpu.options & MIPS_CPU_FPU) - printk("FPU revision is: %08x\n", mips_cpu.fpu_id); + struct cpuinfo_mips *c = ¤t_cpu_data; + + printk("CPU revision is: %08x\n", c->processor_id); + if (c->options & MIPS_CPU_FPU) + printk("FPU revision is: %08x\n", c->fpu_id); } diff -urN linux-2.4.21-bk37/arch/mips/kernel/entry.S linux-2.4.21-bk38/arch/mips/kernel/entry.S --- linux-2.4.21-bk37/arch/mips/kernel/entry.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/entry.S 2003-08-24 02:55:57.000000000 -0700 @@ -28,7 +28,7 @@ .text - .align 4 + .align 5 .set push .set reorder FEXPORT(ret_from_irq) @@ -100,6 +100,9 @@ * and R4400 SC and MC versions. */ NESTED(except_vec3_generic, 0, sp) +#if R5432_CP0_INTERRUPT_WAR + mfc0 k0, CP0_INDEX +#endif mfc0 k1, CP0_CAUSE la k0, exception_handlers andi k1, k1, 0x7c @@ -114,9 +117,6 @@ .set push .set mips3 .set noat -#if defined(R5432_CP0_INTERRUPT_WAR) - mfc0 k0, CP0_INDEX -#endif mfc0 k1, CP0_CAUSE li k0, 31<<2 andi k1, k1, 0x7c @@ -232,6 +232,7 @@ BUILD_HANDLER(ov,ov,sti,silent) /* #12 */ BUILD_HANDLER(tr,tr,sti,silent) /* #13 */ BUILD_HANDLER(fpe,fpe,fpe,silent) /* #15 */ + BUILD_HANDLER(mdmx,mdmx,sti,silent) /* #22 */ BUILD_HANDLER(watch,watch,sti,silent) /* #23 */ BUILD_HANDLER(mcheck,mcheck,cli,silent) /* #24 */ BUILD_HANDLER(reserved,reserved,sti,silent) /* others */ diff -urN linux-2.4.21-bk37/arch/mips/kernel/gdb-low.S linux-2.4.21-bk38/arch/mips/kernel/gdb-low.S --- linux-2.4.21-bk37/arch/mips/kernel/gdb-low.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/gdb-low.S 2003-08-24 02:55:57.000000000 -0700 @@ -14,6 +14,16 @@ #include /* + * [jsun] We reserves about 2x GDB_FR_SIZE in stack. The lower (addressed) + * part is used to store registers and passed to exception handler. + * The upper part is reserved for "call func" feature where gdb client + * saves some of the regs, setups call frame and passes args. + * + * A trace shows about 200 bytes are used to store about half of all regs. + * The rest should be big enough for frame setup and passing args. + */ + +/* * The low level trap handler */ .align 5 @@ -38,7 +48,7 @@ nop 1: move k0,sp - subu sp,k1,GDB_FR_SIZE + subu sp,k1,GDB_FR_SIZE*2 # see comment above sw k0,GDB_FR_REG29(sp) sw v0,GDB_FR_REG2(sp) diff -urN linux-2.4.21-bk37/arch/mips/kernel/gdb-stub.c linux-2.4.21-bk38/arch/mips/kernel/gdb-stub.c --- linux-2.4.21-bk37/arch/mips/kernel/gdb-stub.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/gdb-stub.c 2003-08-24 02:55:57.000000000 -0700 @@ -11,6 +11,9 @@ * Send complaints, suggestions etc. to * * Copyright (C) 1995 Andreas Busse + * + * Copyright (C) 2003 MontaVista Software Inc + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net */ /* @@ -99,7 +102,7 @@ * the kernel running. It will promptly halt and wait * for the host gdb session to connect. It does this * since the "Kernel Hacking" option has defined - * CONFIG_REMOTE_DEBUG which in turn enables your calls + * CONFIG_KGDB which in turn enables your calls * to: * set_debug_traps(); * breakpoint(); @@ -127,6 +130,10 @@ #include #include #include +#include +#include +#include +#include #include #include @@ -135,6 +142,8 @@ #include #include +#include + /* * external low-level support routines */ @@ -148,6 +157,8 @@ */ extern void breakpoint(void); extern void breakinst(void); +extern void async_breakpoint(void); +extern void async_breakinst(void); extern void adel(void); /* @@ -163,6 +174,12 @@ void handle_exception(struct gdb_regs *regs); /* + * spin locks for smp case + */ +static spinlock_t kgdb_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t kgdb_cpulock[NR_CPUS] = { [0 ... NR_CPUS-1] = SPIN_LOCK_UNLOCKED}; + +/* * BUFMAX defines the maximum number of characters in inbound/outbound buffers * at least NUMREGBYTES*2 are needed for register packets */ @@ -171,12 +188,13 @@ static char input_buffer[BUFMAX]; static char output_buffer[BUFMAX]; static int initialized; /* !0 means we've been initialized */ +static int kgdb_started; static const char hexchars[]="0123456789abcdef"; /* Used to prevent crashes in memory access. Note that they'll crash anyway if we haven't set up fault handlers yet... */ -int kgdb_read_byte(unsigned *address, unsigned *dest); -int kgdb_write_byte(unsigned val, unsigned *dest); +int kgdb_read_byte(unsigned char *address, unsigned char *dest); +int kgdb_write_byte(unsigned char val, unsigned char *dest); /* * Convert ch from a hex digit to an int @@ -394,6 +412,17 @@ restore_flags(flags); } +void restore_debug_traps(void) +{ + struct hard_trap_info *ht; + unsigned long flags; + + save_and_cli(flags); + for (ht = hard_trap_info; ht->tt && ht->signo; ht++) + set_except_vector(ht->tt, saved_vectors[ht->tt]); + restore_flags(flags); +} + /* * Convert the MIPS hardware trap type code to a Unix signal number. */ @@ -572,12 +601,39 @@ */ static struct gdb_bp_save async_bp; -void set_async_breakpoint(unsigned int epc) +/* + * Swap the interrupted EPC with our asynchronous breakpoint routine. + * This is safer than stuffing the breakpoint in-place, since no cache + * flushes (or resulting smp_call_functions) are required. The + * assumption is that only one CPU will be handling asynchronous bp's, + * and only one can be active at a time. + */ +extern spinlock_t smp_call_lock; +void set_async_breakpoint(unsigned long *epc) { - async_bp.addr = epc; - async_bp.val = *(unsigned *)epc; - *(unsigned *)epc = BP; - __flush_cache_all(); + /* skip breaking into userland */ + if ((*epc & 0x80000000) == 0) + return; + + /* avoid deadlock if someone is make IPC */ + if (spin_is_locked(&smp_call_lock)) + return; + + async_bp.addr = *epc; + *epc = (unsigned long)async_breakpoint; +} + +void kgdb_wait(void *arg) +{ + unsigned flags; + int cpu = smp_processor_id(); + + local_irq_save(flags); + + spin_lock(&kgdb_cpulock[cpu]); + spin_unlock(&kgdb_cpulock[cpu]); + + local_irq_restore(flags); } @@ -594,31 +650,45 @@ int length; char *ptr; unsigned long *stack; + int i; -#if 0 - printk("in handle_exception()\n"); - show_gdbregs(regs); -#endif + kgdb_started = 1; /* - * First check trap type. If this is CPU_UNUSABLE and CPU_ID is 1, - * the simply switch the FPU on and return since this is no error - * condition. kernel/traps.c does the same. - * FIXME: This doesn't work yet, so we don't catch CPU_UNUSABLE - * traps for now. + * acquire the big kgdb spinlock */ - trap = (regs->cp0_cause & 0x7c) >> 2; -/* printk("trap=%d\n",trap); */ - if (trap == 11) { - if (((regs->cp0_cause >> CAUSEB_CE) & 3) == 1) { - regs->cp0_status |= ST0_CU1; - return; - } + if (!spin_trylock(&kgdb_lock)) { + /* + * some other CPU has the lock, we should go back to + * receive the gdb_wait IPC + */ + return; } /* + * If we're in async_breakpoint(), restore the real EPC from + * the breakpoint. + */ + if (regs->cp0_epc == (unsigned long)async_breakinst) { + regs->cp0_epc = async_bp.addr; + async_bp.addr = 0; + } + + /* + * acquire the CPU spinlocks + */ + for (i=0; i< smp_num_cpus; i++) + db_verify(spin_trylock(&kgdb_cpulock[i]), != 0); + + /* + * force other cpus to enter kgdb + */ + smp_call_function(kgdb_wait, NULL, 0, 0); + + /* * If we're in breakpoint() increment the PC */ + trap = (regs->cp0_cause & 0x7c) >> 2; if (trap == 9 && regs->cp0_epc == (unsigned long)breakinst) regs->cp0_epc += 4; @@ -636,16 +706,6 @@ } } - /* - * If we were interrupted asynchronously by gdb, then a - * breakpoint was set at the EPC of the interrupt so - * that we'd wind up here with an interesting stack frame. - */ - if (async_bp.addr) { - *(unsigned *)async_bp.addr = async_bp.val; - async_bp.addr = 0; - } - stack = (long *)regs->reg29; /* stack ptr */ sigval = computeSignal(trap); @@ -707,6 +767,14 @@ output_buffer[3] = 0; break; + /* + * Detach debugger; let CPU run + */ + case 'D': + putpacket(output_buffer); + goto finish_kgdb; + break; + case 'd': /* toggle debug flag */ break; @@ -726,26 +794,21 @@ /* * set the value of the CPU registers - return OK - * FIXME: Needs to be written */ case 'G': { -#if 0 - unsigned long *newsp, psr; - ptr = &input_buffer[1]; - hex2mem(ptr, (char *)registers, 16 * 4, 0); /* G & O regs */ - - /* - * See if the stack pointer has moved. If so, then copy the - * saved locals and ins to the new location. - */ - - newsp = (unsigned long *)registers[SP]; - if (sp != newsp) - sp = memcpy(newsp, sp, 16 * 4); - -#endif + hex2mem(ptr, (char *)®s->reg0, 32*4, 0); + ptr += 32*8; + hex2mem(ptr, (char *)®s->cp0_status, 6*4, 0); + ptr += 6*8; + hex2mem(ptr, (char *)®s->fpr0, 32*4, 0); + ptr += 32*8; + hex2mem(ptr, (char *)®s->cp1_fsr, 2*4, 0); + ptr += 2*8; + hex2mem(ptr, (char *)®s->frame_ptr, 2*4, 0); + ptr += 2*8; + hex2mem(ptr, (char *)®s->cp0_index, 16*4, 0); strcpy(output_buffer,"OK"); } break; @@ -794,36 +857,19 @@ ptr = &input_buffer[1]; if (hexToInt(&ptr, &addr)) regs->cp0_epc = addr; - - /* - * Need to flush the instruction cache here, as we may - * have deposited a breakpoint, and the icache probably - * has no way of knowing that a data ref to some location - * may have changed something that is in the instruction - * cache. - * NB: We flush both caches, just to be sure... - */ - - __flush_cache_all(); - return; - /* NOTREACHED */ + + goto exit_kgdb_exception; break; - - /* - * kill the program - */ - case 'k' : - break; /* do nothing */ - - /* - * Reset the whole machine (FIXME: system dependent) + * kill the program; let us try to restart the machine + * Reset the whole machine. */ + case 'k': case 'r': + machine_restart("kgdb restarts machine"); break; - /* * Step to next instruction */ @@ -833,9 +879,9 @@ * use breakpoints and continue, instead. */ single_step(regs); - __flush_cache_all(); - return; + goto exit_kgdb_exception; /* NOTREACHED */ + break; /* * Set baud rate (bBB) @@ -890,6 +936,20 @@ putpacket(output_buffer); } /* while */ + + return; + +finish_kgdb: + restore_debug_traps(); + +exit_kgdb_exception: + /* release locks so other CPUs can go */ + for (i=0; i < smp_num_cpus; i++) + spin_unlock(&kgdb_cpulock[i]); + spin_unlock(&kgdb_lock); + + __flush_cache_all(); + return; } /* @@ -903,23 +963,50 @@ if (!initialized) return; - __asm__ __volatile__(" - .globl breakinst - .set noreorder - nop -breakinst: break - nop - .set reorder - "); + __asm__ __volatile__( + ".globl breakinst\n\t" + ".set\tnoreorder\n\t" + "nop\n\t" + "breakinst:\tbreak\n\t" + "nop\n\t" + ".set\treorder" + ); +} + +/* Nothing but the break; don't pollute any registers */ +void async_breakpoint(void) +{ + __asm__ __volatile__( + ".globl async_breakinst\n\t" + ".set\tnoreorder\n\t" + "nop\n\t" + "async_breakinst:\tbreak\n\t" + "nop\n\t" + ".set\treorder" + ); } void adel(void) { - __asm__ __volatile__(" - .globl adel - la $8,0x80000001 - lw $9,0($8) - "); + __asm__ __volatile__( + ".globl\tadel\n\t" + "la\t$8,0x80000001\n\t" + "lw\t$9,0($8)\n\t" + ); +} + +/* + * malloc is needed by gdb client in "call func()", even a private one + * will make gdb happy + */ +static void *malloc(size_t size) +{ + return kmalloc(size, GFP_ATOMIC); +} + +static void free(void *where) +{ + kfree(where); } #ifdef CONFIG_GDB_CONSOLE @@ -928,6 +1015,9 @@ { char outbuf[18]; + if (!kgdb_started) + return; + outbuf[0]='O'; while(l) { @@ -951,11 +1041,11 @@ } static struct console gdb_console = { - name: "gdb", - write: gdb_console_write, - device: gdb_console_dev, - flags: CON_PRINTBUFFER, - index: -1 + .name = "gdb", + .write = gdb_console_write, + .device = gdb_console_dev, + .flags = CON_PRINTBUFFER, + .index = -1 }; __init void register_gdb_console(void) diff -urN linux-2.4.21-bk37/arch/mips/kernel/head.S linux-2.4.21-bk38/arch/mips/kernel/head.S --- linux-2.4.21-bk37/arch/mips/kernel/head.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/head.S 2003-08-24 02:55:57.000000000 -0700 @@ -91,6 +91,8 @@ nop END(except_vec_ejtag_debug) + __FINIT + /* * EJTAG debug exception handler. */ @@ -114,11 +116,15 @@ ejtag_return: mfc0 k0, CP0_DESAVE - .word 0x4200001f # DERET, return from EJTAG debug exception. + .set mips32 + deret + .set mips0 nop .set at END(ejtag_debug_handler) + __INIT + /* * NMI debug exception handler for MIPS reference boards. * The NMI debug exception entry point is 0xbfc00000, which @@ -130,6 +136,8 @@ nop END(except_vec_nmi) + __FINIT + NESTED(nmi_handler, PT_SIZE, sp) .set noat .set noreorder @@ -143,6 +151,8 @@ .set mips0 END(nmi_handler) + __INIT + /* * Kernel entry point */ diff -urN linux-2.4.21-bk37/arch/mips/kernel/i8259.c linux-2.4.21-bk38/arch/mips/kernel/i8259.c --- linux-2.4.21-bk37/arch/mips/kernel/i8259.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/i8259.c 2003-08-24 02:55:57.000000000 -0700 @@ -15,6 +15,7 @@ #include #include +#include #include void enable_8259A_irq(unsigned int irq); diff -urN linux-2.4.21-bk37/arch/mips/kernel/ioport.c linux-2.4.21-bk38/arch/mips/kernel/ioport.c --- linux-2.4.21-bk37/arch/mips/kernel/ioport.c 1997-06-26 12:33:37.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/kernel/ioport.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,34 +0,0 @@ -/* - * linux/arch/mips/kernel/ioport.c - */ -#include -#include -#include -#include -#include - -/* - * This changes the io permissions bitmap in the current task. - */ -asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on) -{ - return -ENOSYS; -} - -/* - * sys_iopl has to be used when you want to access the IO ports - * beyond the 0x3ff range: to get the full 65536 ports bitmapped - * you'd need 8kB of bitmaps/process, which is a bit excessive. - * - * Here we just change the eflags value on the stack: we allow - * only the super-user to do it. This depends on the stack-layout - * on system-call entry - see also fork() and the signal handling - * code. - */ -asmlinkage int sys_iopl(long ebx,long ecx,long edx, - long esi, long edi, long ebp, long eax, long ds, - long es, long fs, long gs, long orig_eax, - long eip,long cs,long eflags,long esp,long ss) -{ - return -ENOSYS; -} diff -urN linux-2.4.21-bk37/arch/mips/kernel/ipc.c linux-2.4.21-bk38/arch/mips/kernel/ipc.c --- linux-2.4.21-bk37/arch/mips/kernel/ipc.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/ipc.c 2003-08-24 02:55:57.000000000 -0700 @@ -93,6 +93,6 @@ return sys_shmctl (first, second, (struct shmid_ds *) ptr); default: - return -EINVAL; + return -ENOSYS; } } diff -urN linux-2.4.21-bk37/arch/mips/kernel/irixelf.c linux-2.4.21-bk38/arch/mips/kernel/irixelf.c --- linux-2.4.21-bk37/arch/mips/kernel/irixelf.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/irixelf.c 2003-08-24 02:55:57.000000000 -0700 @@ -574,7 +574,7 @@ pp = (struct prda *) v; pp->prda_sys.t_pid = current->pid; - pp->prda_sys.t_prid = read_32bit_cp0_register (CP0_PRID); + pp->prda_sys.t_prid = read_c0_prid(); pp->prda_sys.t_rpid = current->pid; /* We leave the rest set to zero */ diff -urN linux-2.4.21-bk37/arch/mips/kernel/irixinv.c linux-2.4.21-bk38/arch/mips/kernel/irixinv.c --- linux-2.4.21-bk37/arch/mips/kernel/irixinv.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/irixinv.c 2003-08-24 02:55:57.000000000 -0700 @@ -16,8 +16,7 @@ static inventory_t inventory [MAX_INVENTORY]; -void -add_to_inventory (int class, int type, int controller, int unit, int state) +void add_to_inventory (int class, int type, int controller, int unit, int state) { inventory_t *ni = &inventory [inventory_items]; @@ -33,8 +32,7 @@ inventory_items++; } -int -dump_inventory_to_user (void *userbuf, int size) +int dump_inventory_to_user (void *userbuf, int size) { inventory_t *inv = &inventory [0]; inventory_t *user = userbuf; @@ -51,13 +49,13 @@ return inventory_items * sizeof (inventory_t); } -void __init init_inventory (void) +static int __init init_inventory(void) { - /* gross hack while we put the right bits all over the kernel + /* + * gross hack while we put the right bits all over the kernel * most likely this will not let just anyone run the X server * until we put the right values all over the place */ - add_to_inventory (10, 3, 0, 0, 16400); add_to_inventory (1, 1, 150, -1, 12); add_to_inventory (1, 3, 0, 0, 8976); @@ -76,6 +74,8 @@ add_to_inventory (2, 2, 0, 2, 0); add_to_inventory (2, 2, 0, 1, 0); add_to_inventory (7, 14, 0, 0, 6); + + return 0; } module_init(init_inventory); diff -urN linux-2.4.21-bk37/arch/mips/kernel/irixsig.c linux-2.4.21-bk38/arch/mips/kernel/irixsig.c --- linux-2.4.21-bk37/arch/mips/kernel/irixsig.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/irixsig.c 2003-08-24 02:55:57.000000000 -0700 @@ -116,7 +116,8 @@ regs->regs[5] = 0; /* XXX sigcode XXX */ regs->regs[6] = regs->regs[29] = sp; regs->regs[7] = (unsigned long) ka->sa.sa_handler; - regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa.sa_restorer; + regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa_restorer; + return; segv_and_exit: @@ -407,7 +408,7 @@ * value for all invocations of sigaction. Will have to * investigate. POSIX POSIX, die die die... */ - new_ka.sa.sa_restorer = trampoline; + new_ka.sa_restorer = trampoline; } /* XXX Implement SIG_SETMASK32 for IRIX compatibility */ diff -urN linux-2.4.21-bk37/arch/mips/kernel/irq.c linux-2.4.21-bk38/arch/mips/kernel/irq.c --- linux-2.4.21-bk37/arch/mips/kernel/irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -211,7 +211,7 @@ void __global_cli(void) { - unsigned int flags; + unsigned long flags; __save_flags(flags); if (flags & ST0_IE) { diff -urN linux-2.4.21-bk37/arch/mips/kernel/irq_cpu.c linux-2.4.21-bk38/arch/mips/kernel/irq_cpu.c --- linux-2.4.21-bk37/arch/mips/kernel/irq_cpu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/irq_cpu.c 2003-08-24 02:55:57.000000000 -0700 @@ -31,13 +31,13 @@ static void mips_cpu_irq_enable(unsigned int irq) { - clear_cp0_cause( 1 << (irq - mips_cpu_irq_base + 8)); - set_cp0_status(1 << (irq - mips_cpu_irq_base + 8)); + clear_c0_cause( 1 << (irq - mips_cpu_irq_base + 8)); + set_c0_status(1 << (irq - mips_cpu_irq_base + 8)); } static void mips_cpu_irq_disable(unsigned int irq) { - clear_cp0_status(1 << (irq - mips_cpu_irq_base + 8)); + clear_c0_status(1 << (irq - mips_cpu_irq_base + 8)); } static unsigned int mips_cpu_irq_startup(unsigned int irq) @@ -51,10 +51,10 @@ static void mips_cpu_irq_ack(unsigned int irq) { - /* although we attemp to clear the IP bit in cause reigster, I think + /* although we attempt to clear the IP bit in cause register, I think * usually it is cleared by device (irq source) */ - clear_cp0_cause(1 << (irq - mips_cpu_irq_base + 8)); + clear_c0_cause(1 << (irq - mips_cpu_irq_base + 8)); /* disable this interrupt - so that we safe proceed to the handler */ mips_cpu_irq_disable(irq); @@ -62,7 +62,7 @@ static void mips_cpu_irq_end(unsigned int irq) { - if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) mips_cpu_irq_enable(irq); } diff -urN linux-2.4.21-bk37/arch/mips/kernel/mips_ksyms.c linux-2.4.21-bk38/arch/mips/kernel/mips_ksyms.c --- linux-2.4.21-bk37/arch/mips/kernel/mips_ksyms.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/mips_ksyms.c 2003-08-24 02:55:57.000000000 -0700 @@ -24,11 +24,9 @@ #include #include #include -#include -#include #include #include -#ifdef CONFIG_BLK_DEV_FD +#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE) #include #endif @@ -86,7 +84,6 @@ /* * Functions to control caches. */ -EXPORT_SYMBOL(_flush_page_to_ram); EXPORT_SYMBOL(_flush_cache_all); EXPORT_SYMBOL(invalid_pte_table); @@ -100,21 +97,6 @@ EXPORT_SYMBOL(__up); /* - * Architecture specific stuff. - */ -#ifdef CONFIG_MIPS_JAZZ -EXPORT_SYMBOL(vdma_alloc); -EXPORT_SYMBOL(vdma_free); -EXPORT_SYMBOL(vdma_log2phys); -#endif - -#ifdef CONFIG_SGI_IP22 -EXPORT_SYMBOL(hpc3c0); -EXPORT_SYMBOL(hpc3c1); -EXPORT_SYMBOL(mcmisc_regs); -#endif - -/* * Kernel hacking ... */ #include diff -urN linux-2.4.21-bk37/arch/mips/kernel/old-irq.c linux-2.4.21-bk38/arch/mips/kernel/old-irq.c --- linux-2.4.21-bk37/arch/mips/kernel/old-irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/old-irq.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,408 +0,0 @@ -/* - * 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. - * - * Code to handle x86 style IRQs plus some generic interrupt stuff. - * - * Copyright (C) 1992 Linus Torvalds - * Copyright (C) 1994 - 2001 Ralf Baechle - * - * Old rotten IRQ code. To be killed as soon as everybody had converted or - * in 2.5.0, whatever comes first. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* - * The board specific setup routine sets irq_setup to point to a board - * specific setup routine. - */ -void (*irq_setup)(void); - -/* - * Linux has a controller-independent x86 interrupt architecture. - * every controller has a 'controller-template', that is used - * by the main code to do the right thing. Each driver-visible - * interrupt source is transparently wired to the apropriate - * controller. Thus drivers need not be aware of the - * interrupt-controller. - * - * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC, - * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC. - * (IO-APICs assumed to be messaging to Pentium local-APICs) - * - * the code is designed to be easily extended with new/different - * interrupt controllers, without having to do assembly magic. - */ - -/* - * This contains the irq mask for both 8259A irq controllers, it's an - * int so we can deal with the third PIC in some systems like the RM300. - * (XXX This is broken for big endian.) - */ -static unsigned int cached_irq_mask = 0xffff; - -#define __byte(x,y) (((unsigned char *)&(y))[x]) -#define __word(x,y) (((unsigned short *)&(y))[x]) -#define __long(x,y) (((unsigned int *)&(y))[x]) - -#define cached_21 (__byte(0,cached_irq_mask)) -#define cached_A1 (__byte(1,cached_irq_mask)) - -volatile unsigned long irq_err_count; - -/* - * (un)mask_irq, disable_irq() and enable_irq() only handle (E)ISA and - * PCI devices. Other onboard hardware needs specific routines. - */ -static inline void mask_irq(unsigned int irq) -{ - cached_irq_mask |= 1 << irq; - if (irq & 8) { - outb(cached_A1, 0xa1); - } else { - outb(cached_21, 0x21); - } -} - -static inline void unmask_irq(unsigned int irq) -{ - cached_irq_mask &= ~(1 << irq); - if (irq & 8) { - outb(cached_A1, 0xa1); - } else { - outb(cached_21, 0x21); - } -} - -void i8259_disable_irq(unsigned int irq_nr) -{ - unsigned long flags; - - save_and_cli(flags); - mask_irq(irq_nr); - restore_flags(flags); -} - -void i8259_enable_irq(unsigned int irq_nr) -{ - unsigned long flags; - save_and_cli(flags); - unmask_irq(irq_nr); - restore_flags(flags); -} - -static struct irqaction *irq_action[NR_IRQS] = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; - -int get_irq_list(char *buf) -{ - int i, len = 0; - struct irqaction * action; - - for (i = 0 ; i < 32 ; i++) { - action = irq_action[i]; - if (!action) - continue; - len += sprintf(buf+len, "%2d: %8d %c %s", - i, kstat.irqs[0][i], - (action->flags & SA_INTERRUPT) ? '+' : ' ', - action->name); - for (action=action->next; action; action = action->next) { - len += sprintf(buf+len, ",%s %s", - (action->flags & SA_INTERRUPT) ? " +" : "", - action->name); - } - len += sprintf(buf+len, "\n"); - } - return len; -} - -static inline void i8259_mask_and_ack_irq(int irq) -{ - cached_irq_mask |= 1 << irq; - - if (irq & 8) { - inb(0xa1); - outb(cached_A1, 0xa1); - outb(0x62, 0x20); /* Specific EOI to cascade */ - outb(0x20, 0xa0); - } else { - inb(0x21); - outb(cached_21, 0x21); - outb(0x20, 0x20); - } -} - -asmlinkage void i8259_do_irq(int irq, struct pt_regs *regs) -{ - struct irqaction *action; - int do_random, cpu; - - cpu = smp_processor_id(); - irq_enter(cpu, irq); - - if (irq >= 16) - goto out; - - i8259_mask_and_ack_irq(irq); - - kstat.irqs[cpu][irq]++; - - action = *(irq + irq_action); - if (!action) - goto out; - - if (!(action->flags & SA_INTERRUPT)) - __sti(); - action = *(irq + irq_action); - do_random = 0; - do { - do_random |= action->flags; - action->handler(irq, action->dev_id, regs); - action = action->next; - } while (action); - if (do_random & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - __cli(); - unmask_irq (irq); - -out: - irq_exit(cpu, irq); -} - -/* - * do_IRQ handles IRQ's that have been installed without the - * SA_INTERRUPT flag: it uses the full signal-handling return - * and runs with other interrupts enabled. All relatively slow - * IRQ's should use this format: notably the keyboard/timer - * routines. - */ -asmlinkage void do_IRQ(int irq, struct pt_regs * regs) -{ - struct irqaction *action; - int do_random, cpu; - - cpu = smp_processor_id(); - irq_enter(cpu, irq); - kstat.irqs[cpu][irq]++; - - action = *(irq + irq_action); - if (action) { - if (!(action->flags & SA_INTERRUPT)) - __sti(); - action = *(irq + irq_action); - do_random = 0; - do { - do_random |= action->flags; - action->handler(irq, action->dev_id, regs); - action = action->next; - } while (action); - if (do_random & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - __cli(); - } - irq_exit(cpu, irq); - - if (softirq_pending(cpu)) - do_softirq(); - - /* unmasking and bottom half handling is done magically for us. */ -} - -int i8259_setup_irq(int irq, struct irqaction * new) -{ - int shared = 0; - struct irqaction *old, **p; - unsigned long flags; - - p = irq_action + irq; - if ((old = *p) != NULL) { - /* Can't share interrupts unless both agree to */ - if (!(old->flags & new->flags & SA_SHIRQ)) - return -EBUSY; - - /* Can't share interrupts unless both are same type */ - if ((old->flags ^ new->flags) & SA_INTERRUPT) - return -EBUSY; - - /* add new interrupt at end of irq queue */ - do { - p = &old->next; - old = *p; - } while (old); - shared = 1; - } - - if (new->flags & SA_SAMPLE_RANDOM) - rand_initialize_irq(irq); - - save_and_cli(flags); - *p = new; - - if (!shared) { - if (is_i8259_irq(irq)) - unmask_irq(irq); -#if (defined(CONFIG_DDB5074) || defined(CONFIG_DDB5476)) - else - nile4_enable_irq(irq_to_nile4(irq)); -#endif - } - restore_flags(flags); - return 0; -} - -/* - * Request_interrupt and free_interrupt ``sort of'' handle interrupts of - * non i8259 devices. They will have to be replaced by architecture - * specific variants. For now we still use this as broken as it is because - * it used to work ... - */ -int request_irq(unsigned int irq, - void (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, const char * devname, void *dev_id) -{ - int retval; - struct irqaction * action; - - if (irq >= 32) - return -EINVAL; - if (!handler) - return -EINVAL; - - action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); - if (!action) - return -ENOMEM; - - action->handler = handler; - action->flags = irqflags; - action->mask = 0; - action->name = devname; - action->next = NULL; - action->dev_id = dev_id; - - retval = i8259_setup_irq(irq, action); - - if (retval) - kfree(action); - return retval; -} - -void free_irq(unsigned int irq, void *dev_id) -{ - struct irqaction * action, **p; - unsigned long flags; - - if (irq > 31) { - printk("Trying to free IRQ%d\n",irq); - return; - } - for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) { - if (action->dev_id != dev_id) - continue; - - /* Found it - now free it */ - save_and_cli(flags); - *p = action->next; - if (!irq[irq_action]) - mask_irq(irq); - restore_flags(flags); - kfree(action); - return; - } - printk("Trying to free free IRQ%d\n",irq); -} - -unsigned long probe_irq_on (void) -{ - unsigned int i, irqs = 0; - unsigned long delay; - - /* first, enable any unassigned (E)ISA irqs */ - for (i = 15; i > 0; i--) { - if (!irq_action[i]) { - i8259_enable_irq(i); - irqs |= (1 << i); - } - } - - /* wait for spurious interrupts to mask themselves out again */ - for (delay = jiffies + HZ/10; time_before(jiffies, delay); ) - /* about 100ms delay */; - - /* now filter out any obviously spurious interrupts */ - return irqs & ~cached_irq_mask; -} - -int probe_irq_off (unsigned long irqs) -{ - unsigned int i; - -#ifdef DEBUG - printk("probe_irq_off: irqs=0x%04x irqmask=0x%04x\n", irqs, irqmask); -#endif - irqs &= cached_irq_mask; - if (!irqs) - return 0; - i = ffz(~irqs); - if (irqs != (irqs & (1 << i))) - i = -i; - return i; -} - -void __init i8259_init(void) -{ - /* Init master interrupt controller */ - outb(0x11, 0x20); /* Start init sequence */ - outb(0x00, 0x21); /* Vector base */ - outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */ - outb(0x01, 0x21); /* Select 8086 mode */ - outb(0xff, 0x21); /* Mask all */ - - /* Init slave interrupt controller */ - outb(0x11, 0xa0); /* Start init sequence */ - outb(0x08, 0xa1); /* Vector base */ - outb(0x02, 0xa1); /* edge triggered, Cascade (slave) on IRQ2 */ - outb(0x01, 0xa1); /* Select 8086 mode */ - outb(0xff, 0xa1); /* Mask all */ - - outb(cached_A1, 0xa1); - outb(cached_21, 0x21); -} - -void __init init_IRQ(void) -{ - /* i8259_init(); */ - irq_setup(); -} - -EXPORT_SYMBOL(free_irq); -EXPORT_SYMBOL(request_irq); diff -urN linux-2.4.21-bk37/arch/mips/kernel/old-time.c linux-2.4.21-bk38/arch/mips/kernel/old-time.c --- linux-2.4.21-bk37/arch/mips/kernel/old-time.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/old-time.c 2003-08-24 02:55:57.000000000 -0700 @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -94,7 +93,7 @@ } /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; @@ -414,7 +413,7 @@ * The cycle counter is only 32 bit which is good for about * a minute at current count rates of upto 150MHz or so. */ - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); timerhi += (count < timerlo); /* Wrap around */ timerlo = count; @@ -425,7 +424,7 @@ * we need only ask for the next in r4k_interval counts. On other * archs we have a real timer, so we don't want this. */ - write_32bit_cp0_register (CP0_COMPARE, + write_c0_compare( (unsigned long) (count + r4k_interval)); kstat.irqs[0][irq]++; #endif @@ -512,8 +511,8 @@ xtime.tv_usec = 0; write_unlock_irq (&xtime_lock); - if (mips_cpu.options & MIPS_CPU_COUNTER) { - write_32bit_cp0_register(CP0_COUNT, 0); + if (cpu_has_counter) { + write_c0_count(0); do_gettimeoffset = do_fast_gettimeoffset; irq0.handler = r4k_timer_interrupt; } diff -urN linux-2.4.21-bk37/arch/mips/kernel/pci-dma.c linux-2.4.21-bk38/arch/mips/kernel/pci-dma.c --- linux-2.4.21-bk37/arch/mips/kernel/pci-dma.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/pci-dma.c 2003-08-24 02:55:57.000000000 -0700 @@ -21,6 +21,7 @@ { void *ret; int gfp = GFP_ATOMIC; + struct pci_bus *bus = NULL; #ifdef CONFIG_ISA if (hwdev == NULL || hwdev->dma_mask != 0xffffffff) @@ -30,7 +31,9 @@ if (ret != NULL) { memset(ret, 0, size); - *dma_handle = bus_to_baddr(hwdev->bus->number, __pa(ret)); + if (hwdev) + bus = hwdev->bus; + *dma_handle = bus_to_baddr(bus, __pa(ret)); #ifdef CONFIG_NONCOHERENT_IO dma_cache_wback_inv((unsigned long) ret, size); ret = UNCAC_ADDR(ret); diff -urN linux-2.4.21-bk37/arch/mips/kernel/pci.c linux-2.4.21-bk38/arch/mips/kernel/pci.c --- linux-2.4.21-bk37/arch/mips/kernel/pci.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/pci.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,176 +0,0 @@ -/* - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * Modified to be mips generic, ppopov@mvista.com - * arch/mips/kernl/pci.c - * Common MIPS PCI routines. - * - * 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. - */ - -/* - * This file contains common PCI routines meant to be shared for - * all MIPS machines. - * - * Strategies: - * - * . We rely on pci_auto.c file to assign PCI resources (MEM and IO) - * TODO: this shold be optional for some machines where they do have - * a real "pcibios" that does resource assignment. - * - * . We then use pci_scan_bus() to "discover" all the resources for - * later use by Linux. - * - * . We finally reply on a board supplied function, pcibios_fixup_irq(), to - * to assign the interrupts. We may use setup-irq.c under drivers/pci - * later. - * - * . Specifically, we will *NOT* use pci_assign_unassigned_resources(), - * because we assume all PCI devices should have the resources correctly - * assigned and recorded. - * - * Limitations: - * - * . We "collapse" all IO and MEM spaces in sub-buses under a top-level bus - * into a contiguous range. - * - * . In the case of Memory space, the rnage is 1:1 mapping with CPU physical - * address space. - * - * . In the case of IO space, it starts from 0, and the beginning address - * is mapped to KSEG0ADDR(mips_io_port) in the CPU physical address. - * - * . These are the current MIPS limitations (by ioremap, etc). In the - * future, we may remove them. - * - * Credits: - * Most of the code are derived from the pci routines from PPC and Alpha, - * which were mostly writtne by - * Cort Dougan, cort@fsmlabs.com - * Matt Porter, mporter@mvista.com - * Dave Rusling david.rusling@reo.mts.dec.com - * David Mosberger davidm@cs.arizona.edu - */ -#include -#include -#include -#include -#include - -#include - -extern void pcibios_fixup(void); -extern void pcibios_fixup_irqs(void); - -struct pci_fixup pcibios_fixups[] = { - { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources }, - { 0 } -}; - -extern int pciauto_assign_resources(int busno, struct pci_channel * hose); - -void __init pcibios_init(void) -{ - struct pci_channel *p; - struct pci_bus *bus; - int busno; - -#ifdef CONFIG_PCI_AUTO - /* assign resources */ - busno=0; - for (p= mips_pci_channels; p->pci_ops != NULL; p++) { - busno = pciauto_assign_resources(busno, p) + 1; - } -#endif - - /* scan the buses */ - busno = 0; - for (p= mips_pci_channels; p->pci_ops != NULL; p++) { - bus = pci_scan_bus(busno, p->pci_ops, p); - busno = bus->subordinate+1; - } - - /* machine dependent fixups */ - pcibios_fixup(); - /* fixup irqs (board specific routines) */ - pcibios_fixup_irqs(); -} - -int pcibios_enable_device(struct pci_dev *dev) -{ - /* pciauto_assign_resources() will enable all devices found */ - return 0; -} - -unsigned long __init pci_bridge_check_io(struct pci_dev *bridge) -{ - u16 io; - - pci_read_config_word(bridge, PCI_IO_BASE, &io); - if (!io) { - pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0); - pci_read_config_word(bridge, PCI_IO_BASE, &io); - pci_write_config_word(bridge, PCI_IO_BASE, 0x0); - } - if (io) - return IORESOURCE_IO; - printk(KERN_WARNING "PCI: bridge %s does not support I/O forwarding!\n", - bridge->name); - return 0; -} - -void __init pcibios_fixup_bus(struct pci_bus *bus) -{ - /* Propogate hose info into the subordinate devices. */ - - struct pci_channel *hose = bus->sysdata; - struct pci_dev *dev = bus->self; - - if (!dev) { - /* Root bus */ - bus->resource[0] = hose->io_resource; - bus->resource[1] = hose->mem_resource; - } else { - /* This is a bridge. Do not care how it's initialized, - just link its resources to the bus ones */ - 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]->flags |= pci_bridge_check_io(dev); - bus->resource[1]->flags |= IORESOURCE_MEM; - /* For now, propogate hose limits to the bus; - we'll adjust them later. */ - bus->resource[0]->end = hose->io_resource->end; - bus->resource[1]->end = hose->mem_resource->end; - /* Turn off downstream PF memory address range by default */ - bus->resource[2]->start = 1024*1024; - bus->resource[2]->end = bus->resource[2]->start - 1; - } -} - -char *pcibios_setup(char *str) -{ - return str; -} - -void -pcibios_align_resource(void *data, struct resource *res, unsigned long size, - unsigned long align) -{ - /* this should not be called */ -} - -void -pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - /* this should not be called */ -} diff -urN linux-2.4.21-bk37/arch/mips/kernel/pci_auto.c linux-2.4.21-bk38/arch/mips/kernel/pci_auto.c --- linux-2.4.21-bk37/arch/mips/kernel/pci_auto.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/pci_auto.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,394 +0,0 @@ -/* - * PCI autoconfiguration library - * - * Author: Matt Porter - * - * Copyright 2000, 2001 MontaVista Software Inc. - * Copyright 2001 Bradley D. LaRonde - * - * 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. - */ - -/* - * Modified for MIPS by Jun Sun, jsun@mvista.com - * - * . Simplify the interface between pci_auto and the rest: a single function. - * . Assign resources from low address to upper address. - * . change most int to u32. - * - * Further modified to include it as mips generic code, ppopov@mvista.com. - * - * 2001-10-26 Bradley D. LaRonde - * - Add a top_bus argument to the "early config" functions so that - * they can set a fake parent bus pointer to convince the underlying - * pci ops to use type 1 configuration for sub busses. - * - Set bridge base and limit registers correctly. - * - Align io and memory base properly before and after bridge setup. - * - Don't fall through to pci_setup_bars for bridge. - * - Reformat the debug output to look more like lspci's output. - */ - -#include -#include -#include -#include - -#include - -#define DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -/* - * 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_channel *hose, - int top_bus, int busnr, int devfn) -{ - static struct pci_dev dev; - static struct pci_bus bus; - - dev.bus = &bus; - dev.sysdata = hose; - dev.devfn = devfn; - bus.number = busnr; - bus.ops = hose->pci_ops; - - if(busnr != top_bus) - /* Fake a parent bus structure. */ - bus.parent = &bus; - else - bus.parent = NULL; - - return &dev; -} - -#define EARLY_PCI_OP(rw, size, type) \ -int early_##rw##_config_##size(struct pci_channel *hose, \ - int top_bus, int bus, int devfn, int offset, type value) \ -{ \ - return pci_##rw##_config_##size( \ - fake_pci_dev(hose, top_bus, 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) - -static struct resource *io_resource_inuse; -static struct resource *mem_resource_inuse; - -static u32 pciauto_lower_iospc; -static u32 pciauto_upper_iospc; - -static u32 pciauto_lower_memspc; -static u32 pciauto_upper_memspc; - -void __init -pciauto_setup_bars(struct pci_channel *hose, - int top_bus, - int current_bus, - int pci_devfn) -{ - u32 bar_response, bar_size, bar_value; - u32 bar, addr_mask, bar_nr = 0; - u32 * upper_limit; - u32 * lower_limit; - int found_mem64 = 0; - - for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar+=4) { - /* Tickle the BAR and get the response */ - early_write_config_dword(hose, top_bus, - current_bus, - pci_devfn, - bar, - 0xffffffff); - early_read_config_dword(hose, top_bus, - current_bus, - pci_devfn, - bar, - &bar_response); - - /* If BAR is not implemented go to the next BAR */ - if (!bar_response) - continue; - - /* - * Workaround for a BAR that doesn't use its upper word, - * like the ALi 1535D+ PCI DC-97 Controller Modem (M5457). - * bdl - */ - if (!(bar_response & 0xffff0000)) - bar_response |= 0xffff0000; - -retry: - /* Check the BAR type and set our address mask */ - if (bar_response & PCI_BASE_ADDRESS_SPACE) { - addr_mask = PCI_BASE_ADDRESS_IO_MASK; - upper_limit = &pciauto_upper_iospc; - lower_limit = &pciauto_lower_iospc; - DBG(" I/O"); - } else { - if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == - PCI_BASE_ADDRESS_MEM_TYPE_64) - found_mem64 = 1; - - addr_mask = PCI_BASE_ADDRESS_MEM_MASK; - upper_limit = &pciauto_upper_memspc; - lower_limit = &pciauto_lower_memspc; - DBG(" Mem"); - } - - - /* Calculate requested size */ - bar_size = ~(bar_response & addr_mask) + 1; - - /* Allocate a base address */ - bar_value = ((*lower_limit - 1) & ~(bar_size - 1)) + bar_size; - - if ((bar_value + bar_size) > *upper_limit) { - if (bar_response & PCI_BASE_ADDRESS_SPACE) { - if (io_resource_inuse->child) { - io_resource_inuse = - io_resource_inuse->child; - pciauto_lower_iospc = - io_resource_inuse->start; - pciauto_upper_iospc = - io_resource_inuse->end + 1; - goto retry; - } - - } else { - if (mem_resource_inuse->child) { - mem_resource_inuse = - mem_resource_inuse->child; - pciauto_lower_memspc = - mem_resource_inuse->start; - pciauto_upper_memspc = - mem_resource_inuse->end + 1; - goto retry; - } - } - DBG(" unavailable -- skipping\n"); - continue; - } - - /* Write it out and update our limit */ - early_write_config_dword(hose, top_bus, current_bus, pci_devfn, - bar, bar_value); - - *lower_limit = bar_value + bar_size; - - /* - * If we are a 64-bit decoder then increment to the - * upper 32 bits of the bar and force it to locate - * in the lower 4GB of memory. - */ - if (found_mem64) { - bar += 4; - early_write_config_dword(hose, top_bus, - current_bus, - pci_devfn, - bar, - 0x00000000); - } - - DBG(" at 0x%.8x [size=0x%x]\n", bar_value, bar_size); - - bar_nr++; - } - -} - -void __init -pciauto_prescan_setup_bridge(struct pci_channel *hose, - int top_bus, - int current_bus, - int pci_devfn, - int sub_bus) -{ - /* Configure bus number registers */ - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_PRIMARY_BUS, current_bus); - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_SECONDARY_BUS, sub_bus + 1); - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_SUBORDINATE_BUS, 0xff); - - /* Align memory and I/O to 1MB and 4KB boundaries. */ - pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1)) - & ~(0x100000 - 1); - pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1)) - & ~(0x1000 - 1); - - /* Set base (lower limit) of address range behind bridge. */ - early_write_config_word(hose, top_bus, current_bus, pci_devfn, - PCI_MEMORY_BASE, pciauto_lower_memspc >> 16); - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_IO_BASE, (pciauto_lower_iospc & 0x0000f000) >> 8); - early_write_config_word(hose, top_bus, current_bus, pci_devfn, - PCI_IO_BASE_UPPER16, pciauto_lower_iospc >> 16); - - /* We don't support prefetchable memory for now, so disable */ - early_write_config_word(hose, top_bus, current_bus, pci_devfn, - PCI_PREF_MEMORY_BASE, 0); - early_write_config_word(hose, top_bus, current_bus, pci_devfn, - PCI_PREF_MEMORY_LIMIT, 0); -} - -void __init -pciauto_postscan_setup_bridge(struct pci_channel *hose, - int top_bus, - int current_bus, - int pci_devfn, - int sub_bus) -{ - u32 temp; - - /* Configure bus number registers */ - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_SUBORDINATE_BUS, sub_bus); - - /* Set upper limit of address range behind bridge. */ - early_write_config_word(hose, top_bus, current_bus, pci_devfn, - PCI_MEMORY_LIMIT, pciauto_lower_memspc >> 16); - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_IO_LIMIT, (pciauto_lower_iospc & 0x0000f000) >> 8); - early_write_config_word(hose, top_bus, current_bus, pci_devfn, - PCI_IO_LIMIT_UPPER16, pciauto_lower_iospc >> 16); - - /* Align memory and I/O to 1MB and 4KB boundaries. */ - pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1)) - & ~(0x100000 - 1); - pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1)) - & ~(0x1000 - 1); - - /* Enable memory and I/O accesses, enable bus master */ - early_read_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_COMMAND, &temp); - early_write_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY - | PCI_COMMAND_MASTER); -} - -#define PCIAUTO_IDE_MODE_MASK 0x05 - -int __init -pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus) -{ - int sub_bus; - u32 pci_devfn, pci_class, cmdstat, found_multi=0; - unsigned short vid, did; - unsigned char header_type; - int devfn_start = 0; - int devfn_stop = 0xff; - - sub_bus = current_bus; - - if (hose->first_devfn) - devfn_start = hose->first_devfn; - if (hose->last_devfn) - devfn_stop = hose->last_devfn; - - for (pci_devfn=devfn_start; pci_devfn> 16, vid, did); - if (pci_class & 0xff) - DBG(" (rev %.2x)", pci_class & 0xff); - DBG("\n"); - - if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) { - DBG(" Bridge: primary=%.2x, secondary=%.2x\n", - current_bus, sub_bus + 1); - pciauto_prescan_setup_bridge(hose, top_bus, current_bus, - pci_devfn, sub_bus); - DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", - sub_bus + 1, - pciauto_lower_iospc, pciauto_lower_memspc); - sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1); - DBG("Back to bus %.2x\n", current_bus); - pciauto_postscan_setup_bridge(hose, top_bus, current_bus, - pci_devfn, sub_bus); - continue; - } else if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) { - - unsigned char prg_iface; - - early_read_config_byte(hose, top_bus, current_bus, - pci_devfn, PCI_CLASS_PROG, &prg_iface); - if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) { - DBG("Skipping legacy mode IDE controller\n"); - continue; - } - } - - /* - * Found a peripheral, enable some standard - * settings - */ - early_read_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_COMMAND, &cmdstat); - early_write_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_COMMAND, cmdstat | PCI_COMMAND_IO | - PCI_COMMAND_MEMORY | - PCI_COMMAND_MASTER); - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_LATENCY_TIMER, 0x80); - - /* Allocate PCI I/O and/or memory space */ - pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn); - } - return sub_bus; -} - -int __init -pciauto_assign_resources(int busno, struct pci_channel *hose) -{ - /* setup resource limits */ - io_resource_inuse = hose->io_resource; - mem_resource_inuse = hose->mem_resource; - - pciauto_lower_iospc = io_resource_inuse->start; - pciauto_upper_iospc = io_resource_inuse->end + 1; - pciauto_lower_memspc = mem_resource_inuse->start; - pciauto_upper_memspc = mem_resource_inuse->end + 1; - DBG("Autoconfig PCI channel 0x%p\n", hose); - DBG("Scanning bus %.2x, I/O 0x%.8x:0x%.8x, Mem 0x%.8x:0x%.8x\n", - busno, pciauto_lower_iospc, pciauto_upper_iospc, - pciauto_lower_memspc, pciauto_upper_memspc); - - return pciauto_bus_scan(hose, busno, busno); -} diff -urN linux-2.4.21-bk37/arch/mips/kernel/proc.c linux-2.4.21-bk38/arch/mips/kernel/proc.c --- linux-2.4.21-bk37/arch/mips/kernel/proc.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/proc.c 2003-08-24 02:55:57.000000000 -0700 @@ -17,10 +17,6 @@ unsigned int vced_count, vcei_count; -#ifndef CONFIG_CPU_HAS_LLSC -unsigned long ll_ops, sc_ops; -#endif - static const char *cpu_name[] = { [CPU_UNKNOWN] "unknown", [CPU_R2000] "R2000", @@ -66,21 +62,21 @@ [CPU_VR41XX] "NEC Vr41xx", [CPU_R5500] "R5500", [CPU_TX49XX] "TX49xx", - [CPU_TX39XX] "TX39xx", [CPU_20KC] "MIPS 20Kc", [CPU_VR4111] "NEC VR4111", [CPU_VR4121] "NEC VR4121", [CPU_VR4122] "NEC VR4122", [CPU_VR4131] "NEC VR4131", [CPU_VR4181] "NEC VR4181", - [CPU_VR4181A] "NEC VR4181A" + [CPU_VR4181A] "NEC VR4181A", + [CPU_SR71000] "Sandcraft SR71000" }; static int show_cpuinfo(struct seq_file *m, void *v) { - unsigned int version = mips_cpu.processor_id; - unsigned int fp_vers = mips_cpu.fpu_id; + unsigned int version = current_cpu_data.processor_id; + unsigned int fp_vers = current_cpu_data.fpu_id; unsigned long n = (unsigned long) v - 1; char fmt [64]; @@ -97,9 +93,9 @@ seq_printf(m, "processor\t\t: %ld\n", n); sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n", - (mips_cpu.options & MIPS_CPU_FPU) ? " FPU V%d.%d" : ""); - seq_printf(m, fmt, cpu_name[mips_cpu.cputype <= CPU_LAST ? - mips_cpu.cputype : CPU_UNKNOWN], + cpu_has_fpu ? " FPU V%d.%d" : ""); + seq_printf(m, fmt, cpu_name[current_cpu_data.cputype <= CPU_LAST ? + current_cpu_data.cputype : CPU_UNKNOWN], (version >> 4) & 0x0f, version & 0x0f, (fp_vers >> 4) & 0x0f, fp_vers & 0x0f); seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n", @@ -107,23 +103,18 @@ (loops_per_jiffy / (5000/HZ)) % 100); seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no"); seq_printf(m, "microsecond timers\t: %s\n", - (mips_cpu.options & MIPS_CPU_COUNTER) ? "yes" : "no"); - seq_printf(m, "tlb_entries\t\t: %d\n", mips_cpu.tlbsize); + cpu_has_counter ? "yes" : "no"); + seq_printf(m, "tlb_entries\t\t: %d\n", current_cpu_data.tlbsize); seq_printf(m, "extra interrupt vector\t: %s\n", - (mips_cpu.options & MIPS_CPU_DIVEC) ? "yes" : "no"); + cpu_has_divec ? "yes" : "no"); seq_printf(m, "hardware watchpoint\t: %s\n", - watch_available ? "yes" : "no"); + cpu_has_watch ? "yes" : "no"); sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", - (mips_cpu.options & MIPS_CPU_VCE) ? "%d" : "not available"); + cpu_has_vce ? "%d" : "not available"); seq_printf(m, fmt, 'D', vced_count); seq_printf(m, fmt, 'I', vcei_count); -#ifndef CONFIG_CPU_HAS_LLSC - seq_printf(m, "ll emulations\t\t: %lu\n", ll_ops); - seq_printf(m, "sc emulations\t\t: %lu\n", sc_ops); -#endif - return 0; } @@ -145,8 +136,8 @@ } struct seq_operations cpuinfo_op = { - start: c_start, - next: c_next, - stop: c_stop, - show: show_cpuinfo, + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = show_cpuinfo, }; diff -urN linux-2.4.21-bk37/arch/mips/kernel/process.c linux-2.4.21-bk38/arch/mips/kernel/process.c --- linux-2.4.21-bk37/arch/mips/kernel/process.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/kernel/process.c 2003-08-24 02:55:57.000000000 -0700 @@ -18,9 +18,12 @@ #include #include #include +#include +#include #include #include +#include #include #include #include @@ -30,6 +33,7 @@ #include #include #include +#include ATTRIB_NORET void cpu_idle(void) { @@ -47,28 +51,25 @@ } } -struct task_struct *last_task_used_math = NULL; - asmlinkage void ret_from_fork(void); +void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) +{ + regs->cp0_status &= ~(ST0_CU0|ST0_KSU|ST0_CU1); + regs->cp0_status |= KU_USER; + current->used_math = 0; + lose_fpu(); + regs->cp0_epc = pc; + regs->regs[29] = sp; + current->thread.current_ds = USER_DS; +} + void exit_thread(void) { - /* Forget lazy fpu state */ - if (last_task_used_math == current && mips_cpu.options & MIPS_CPU_FPU) { - __enable_fpu(); - __asm__ __volatile__("cfc1\t$0,$31"); - last_task_used_math = NULL; - } } void flush_thread(void) { - /* Forget lazy fpu state */ - if (last_task_used_math == current && mips_cpu.options & MIPS_CPU_FPU) { - __enable_fpu(); - __asm__ __volatile__("cfc1\t$0,$31"); - last_task_used_math = NULL; - } } int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, @@ -80,11 +81,10 @@ childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32; - if (last_task_used_math == current) - if (mips_cpu.options & MIPS_CPU_FPU) { - __enable_fpu(); - save_fp(p); - } + if (is_fpu_owner()) { + save_fp(p); + } + /* set up new TSS. */ childregs = (struct pt_regs *) childksp - 1; *childregs = *regs; @@ -111,10 +111,10 @@ p->thread.reg31 = (unsigned long) ret_from_fork; /* - * New tasks loose permission to use the fpu. This accelerates context + * New tasks lose permission to use the fpu. This accelerates context * switching for most programs since they don't use the fpu. */ - p->thread.cp0_status = read_32bit_cp0_register(CP0_STATUS) & + p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1|KU_MASK); childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); @@ -124,29 +124,8 @@ /* Fill in the fpu structure for a core dump.. */ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r) { - /* We actually store the FPU info in the task->thread - * area. - */ - if(regs->cp0_status & ST0_CU1) { - memcpy(r, ¤t->thread.fpu, sizeof(current->thread.fpu)); - return 1; - } - return 0; /* Task didn't use the fpu at all. */ -} - -/* Fill in the user structure for a core dump.. */ -void dump_thread(struct pt_regs *regs, struct user *dump) -{ - dump->magic = CMAGIC; - dump->start_code = current->mm->start_code; - dump->start_data = current->mm->start_data; - dump->start_stack = regs->regs[29] & ~(PAGE_SIZE - 1); - dump->u_tsize = (current->mm->end_code - dump->start_code) >> PAGE_SHIFT; - dump->u_dsize = (current->mm->brk + (PAGE_SIZE - 1) - dump->start_data) >> PAGE_SHIFT; - dump->u_ssize = - (current->mm->start_stack - dump->start_stack + PAGE_SIZE - 1) >> PAGE_SHIFT; - memcpy(&dump->regs[0], regs, sizeof(struct pt_regs)); - memcpy(&dump->regs[EF_SIZE/4], ¤t->thread.fpu, sizeof(current->thread.fpu)); + memcpy(r, ¤t->thread.fpu, sizeof(current->thread.fpu)); + return 1; } /* @@ -157,21 +136,21 @@ long retval; __asm__ __volatile__( - ".set noreorder \n" - " move $6,$sp \n" - " move $4,%5 \n" - " li $2,%1 \n" - " syscall \n" - " beq $6,$sp,1f \n" - " subu $sp,32 \n" /* delay slot */ - " jalr %4 \n" - " move $4,%3 \n" /* delay slot */ - " move $4,$2 \n" - " li $2,%2 \n" - " syscall \n" - "1: addiu $sp,32 \n" - " move %0,$2 \n" - ".set reorder" + " .set noreorder \n" + " move $6, $sp \n" + " move $4, %5 \n" + " li $2, %1 \n" + " syscall \n" + " beq $6, $sp, 1f \n" + " subu $sp, 32 \n" + " jalr %4 \n" + " move $4, %3 \n" + " move $4, $2 \n" + " li $2, %2 \n" + " syscall \n" + "1: addiu $sp, 32 \n" + " move %0, $2 \n" + " .set reorder" : "=r" (retval) : "i" (__NR_clone), "i" (__NR_exit), "r" (arg), "r" (fn), "r" (flags | CLONE_VM) @@ -180,7 +159,7 @@ * at, result, argument or temporary registers ... */ : "$2", "$3", "$4", "$5", "$6", "$7", "$8", - "$9","$10","$11","$12","$13","$14","$15","$24","$25"); + "$9","$10","$11","$12","$13","$14","$15","$24","$25", "$31"); return retval; } @@ -193,6 +172,62 @@ #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) +struct mips_frame_info schedule_frame; +static struct mips_frame_info schedule_timeout_frame; +static struct mips_frame_info sleep_on_frame; +static struct mips_frame_info sleep_on_timeout_frame; +static struct mips_frame_info wait_for_completion_frame; +static int mips_frame_info_initialized; +static int __init get_frame_info(struct mips_frame_info *info, void *func) +{ + int i; + union mips_instruction *ip = (union mips_instruction *)func; + info->pc_offset = -1; + info->frame_offset = -1; + for (i = 0; i < 128; i++, ip++) { + /* if jal, jalr, jr, stop. */ + if (ip->j_format.opcode == jal_op || + (ip->r_format.opcode == spec_op && + (ip->r_format.func == jalr_op || + ip->r_format.func == jr_op))) + break; + if (ip->i_format.opcode == sw_op && + ip->i_format.rs == 29) { + /* sw $ra, offset($sp) */ + if (ip->i_format.rt == 31) { + if (info->pc_offset != -1) + break; + info->pc_offset = + ip->i_format.simmediate / sizeof(long); + } + /* sw $s8, offset($sp) */ + if (ip->i_format.rt == 30) { + if (info->frame_offset != -1) + break; + info->frame_offset = + ip->i_format.simmediate / sizeof(long); + } + } + } + if (info->pc_offset == -1 || info->frame_offset == -1) { + printk("Can't analyze prologue code at %p\n", func); + info->pc_offset = -1; + info->frame_offset = -1; + return -1; + } + + return 0; +} +void __init frame_info_init(void) +{ + mips_frame_info_initialized = + !get_frame_info(&schedule_frame, schedule) && + !get_frame_info(&schedule_timeout_frame, schedule_timeout) && + !get_frame_info(&sleep_on_frame, sleep_on) && + !get_frame_info(&sleep_on_timeout_frame, sleep_on_timeout) && + !get_frame_info(&wait_for_completion_frame, wait_for_completion); +} + /* get_wchan - a maintenance nightmare^W^Wpain in the ass ... */ unsigned long get_wchan(struct task_struct *p) { @@ -201,6 +236,8 @@ if (!p || p == current || p->state == TASK_RUNNING) return 0; + if (!mips_frame_info_initialized) + return 0; pc = thread_saved_pc(&p->thread); if (pc < first_sched || pc >= last_sched) { return pc; @@ -214,29 +251,33 @@ goto schedule_timeout_caller; if (pc >= (unsigned long)interruptible_sleep_on) goto schedule_caller; - /* Fall through */ + if (pc >= (unsigned long)wait_for_completion) + goto schedule_caller; + goto schedule_timeout_caller; schedule_caller: - pc = ((unsigned long *)p->thread.reg30)[13]; - + frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset]; + if (pc >= (unsigned long) sleep_on) + pc = ((unsigned long *)frame)[sleep_on_frame.pc_offset]; + else + pc = ((unsigned long *)frame)[wait_for_completion_frame.pc_offset]; return pc; schedule_timeout_caller: /* * The schedule_timeout frame */ - frame = ((unsigned long *)p->thread.reg30)[13]; + frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset]; /* * frame now points to sleep_on_timeout's frame */ - frame = ((unsigned long *)frame)[9]; - pc = ((unsigned long *)frame)[10]; + pc = ((unsigned long *)frame)[schedule_timeout_frame.pc_offset]; if (pc >= first_sched && pc < last_sched) { - /* schedule_timeout called by interruptible_sleep_on_timeout */ - frame = ((unsigned long *)frame)[9]; - pc = ((unsigned long *)frame)[10]; + /* schedule_timeout called by [interruptible_]sleep_on_timeout */ + frame = ((unsigned long *)frame)[schedule_timeout_frame.frame_offset]; + pc = ((unsigned long *)frame)[sleep_on_timeout_frame.pc_offset]; } return pc; diff -urN linux-2.4.21-bk37/arch/mips/kernel/ptrace.c linux-2.4.21-bk38/arch/mips/kernel/ptrace.c --- linux-2.4.21-bk37/arch/mips/kernel/ptrace.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/ptrace.c 2003-08-24 02:55:57.000000000 -0700 @@ -27,6 +27,7 @@ #include #include #include +#include /* * Called by kernel/ptrace.c when detaching.. @@ -42,7 +43,6 @@ { struct task_struct *child; int ret; - extern void save_fp(struct task_struct *); lock_kernel(); #if 0 @@ -72,7 +72,7 @@ ret = -EPERM; if (pid == 1) /* you may not mess with init */ - goto out; + goto out_tsk; if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); @@ -94,8 +94,7 @@ if (copied != sizeof(tmp)) break; ret = put_user(tmp,(unsigned long *) data); - - goto out; + break; } /* Read the word at location addr in the USER area. */ @@ -113,20 +112,7 @@ break; case FPR_BASE ... FPR_BASE + 31: if (child->used_math) { - unsigned long long *fregs - = (unsigned long long *) - &child->thread.fpu.hard.fp_regs[0]; - if(!(mips_cpu.options & MIPS_CPU_FPU)) { - fregs = (unsigned long long *) - child->thread.fpu.soft.regs; - } else - if (last_task_used_math == child) { - __enable_fpu(); - save_fp(child); - __disable_fpu(); - last_task_used_math = NULL; - regs->cp0_status &= ~ST0_CU1; - } + unsigned long long *fregs = get_fpu_regs(child); /* * The odd registers are actually the high * order bits of the values stored in the even @@ -156,17 +142,16 @@ tmp = regs->lo; break; case FPC_CSR: - if (!(mips_cpu.options & MIPS_CPU_FPU)) + if (!cpu_has_fpu) tmp = child->thread.fpu.soft.sr; else tmp = child->thread.fpu.hard.control; break; case FPC_EIR: { /* implementation / version register */ - unsigned int flags; + unsigned long flags; - if (!(mips_cpu.options & MIPS_CPU_FPU)) { + if (!cpu_has_fpu) break; - } __save_flags(flags); __enable_fpu(); @@ -177,10 +162,10 @@ default: tmp = 0; ret = -EIO; - goto out; + goto out_tsk; } ret = put_user(tmp, (unsigned long *) data); - goto out; + break; } case PTRACE_POKETEXT: /* write the word at location addr. */ @@ -190,7 +175,7 @@ == sizeof(data)) break; ret = -EIO; - goto out; + break; case PTRACE_POKEUSR: { struct pt_regs *regs; @@ -204,21 +189,8 @@ break; case FPR_BASE ... FPR_BASE + 31: { unsigned long long *fregs; - fregs = (unsigned long long *)&child->thread.fpu.hard.fp_regs[0]; - if (child->used_math) { - if (last_task_used_math == child) { - if(!(mips_cpu.options & MIPS_CPU_FPU)) { - fregs = (unsigned long long *) - child->thread.fpu.soft.regs; - } else { - __enable_fpu(); - save_fp(child); - __disable_fpu(); - last_task_used_math = NULL; - regs->cp0_status &= ~ST0_CU1; - } - } - } else { + fregs = (unsigned long long *)get_fpu_regs(child); + if (!child->used_math) { /* FP not yet used */ memset(&child->thread.fpu.hard, ~0, sizeof(child->thread.fpu.hard)); @@ -229,11 +201,6 @@ * of the values stored in the even registers - unless * we're using r2k_switch.S. */ -#ifdef CONFIG_CPU_R3000 - if (mips_cpu.options & MIPS_CPU_FPU) - *(unsigned long *)(fregs + addr) = data; - else -#endif if (addr & 1) { fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff; fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long long) data) << 32; @@ -253,7 +220,7 @@ regs->lo = data; break; case FPC_CSR: - if (!(mips_cpu.options & MIPS_CPU_FPU)) + if (!cpu_has_fpu) child->thread.fpu.soft.sr = data; else child->thread.fpu.hard.control = data; @@ -308,7 +275,7 @@ default: ret = -EIO; - goto out; + break; } out_tsk: free_task_struct(child); diff -urN linux-2.4.21-bk37/arch/mips/kernel/r2300_switch.S linux-2.4.21-bk38/arch/mips/kernel/r2300_switch.S --- linux-2.4.21-bk37/arch/mips/kernel/r2300_switch.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/kernel/r2300_switch.S 2003-08-24 02:55:57.000000000 -0700 @@ -28,6 +28,19 @@ .set mips1 .align 5 +#define PF_USEDFPU 0x00100000 /* task used FPU this quantum (SMP) */ +#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS) + +/* + * [jsun] FPU context is saved if and only if the process has used FPU in + * the current run (PF_USEDFPU). In any case, the CU1 bit for user space + * STATUS register should be 0, so that a process *always* starts its + * userland with FPU disabled after each context switch. + * + * FPU will be enabled as soon as the process accesses FPU again, through + * do_cpu() trap. + */ + /* * task_struct *resume(task_struct *prev, * task_struct *next) @@ -41,6 +54,32 @@ CPU_SAVE_NONSCRATCH(a0) sw ra, THREAD_REG31(a0) + /* + * check if we need to save FPU registers + */ + lw t0, TASK_FLAGS(a0) + li t1, PF_USEDFPU + and t2, t0, t1 + beqz t2, 1f + nor t1, zero, t1 + + /* + * clear PF_USEDFPU bit in task flags + */ + and t0, t0, t1 + sw t0, TASK_FLAGS(a0) + + /* + * clear user-saved stack CU1 bit + */ + lw t0, ST_OFF(a0) + li t1, ~ST0_CU1 + and t0, t0, t1 + sw t0, ST_OFF(a0) + + FPU_SAVE_SINGLE(a0, t0) # clobbers t0 + +1: /* * The order of restoring the registers takes care of the race * updating $28, $29 and kernelsp without disabling ints. @@ -64,59 +103,32 @@ END(resume) /* - * Do lazy fpu context switch. Saves FPU context to the process in a0 - * and loads the new context of the current process. - */ - -#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS) - -LEAF(lazy_fpu_switch) - mfc0 t0, CP0_STATUS # enable cp1 - li t3, ST0_CU1 - or t0, t3 - mtc0 t0, CP0_STATUS - - .set noreorder - beqz a0, 2f # Save floating point state - nor t3, zero, t3 - .set reorder - lw t1, ST_OFF(a0) # last thread looses fpu - and t1, t3 - sw t1, ST_OFF(a0) - FPU_SAVE_SINGLE(a0, t1) # clobbers t1 - -2: - FPU_RESTORE_SINGLE($28, t0) # clobbers t0 - jr ra - END(lazy_fpu_switch) - -/* * Save a thread's fp context. */ -LEAF(save_fp) +LEAF(_save_fp) FPU_SAVE_SINGLE(a0, t1) # clobbers t1 jr ra - END(save_fp) + END(_save_fp) /* * Restore a thread's fp context. */ -LEAF(restore_fp) +LEAF(_restore_fp) FPU_RESTORE_SINGLE(a0, t1) # clobbers t1 jr ra - END(restore_fp) + END(_restore_fp) /* * Load the FPU with signalling NANS. This bit pattern we're using has * the property that no matter wether considered as single or as double - * precission represents signaling NANS. + * precision represents signaling NANS. * * We initialize fcr31 to rounding to nearest, no exceptions. */ #define FPU_DEFAULT 0x00000000 -LEAF(init_fpu) +LEAF(_init_fpu) mfc0 t0, CP0_STATUS li t1, ST0_CU1 or t0, t1 @@ -162,4 +174,4 @@ jr ra mtc1 t0, $f31 .set reorder - END(init_fpu) + END(_init_fpu) diff -urN linux-2.4.21-bk37/arch/mips/kernel/r4k_switch.S linux-2.4.21-bk38/arch/mips/kernel/r4k_switch.S --- linux-2.4.21-bk37/arch/mips/kernel/r4k_switch.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/r4k_switch.S 2003-08-24 02:55:57.000000000 -0700 @@ -25,6 +25,19 @@ #include +#define PF_USEDFPU 0x00100000 /* task used FPU this quantum (SMP) */ +#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS) + +/* + * [jsun] FPU context is saved if and only if the process has used FPU in + * the current run (PF_USEDFPU). In any case, the CU1 bit for user space + * STATUS register should be 0, so that a process *always* starts its + * userland with FPU disabled after each context switch. + * + * FPU will be enabled as soon as the process accesses FPU again, through + * do_cpu() trap. + */ + /* * task_struct *r4xx0_resume(task_struct *prev, task_struct *next) */ @@ -39,6 +52,32 @@ CPU_SAVE_NONSCRATCH(a0) sw ra, THREAD_REG31(a0) + /* + * check if we need to save FPU registers + */ + lw t0, TASK_FLAGS(a0) + li t1, PF_USEDFPU + and t2, t0, t1 + beqz t2, 1f + nor t1, zero, t1 + + /* + * clear PF_USEDFPU bit in task flags + */ + and t0, t0, t1 + sw t0, TASK_FLAGS(a0) + + /* + * clear saved user stack CU1 bit + */ + lw t0, ST_OFF(a0) + li t1, ~ST0_CU1 + and t0, t0, t1 + sw t0, ST_OFF(a0) + + FPU_SAVE_DOUBLE(a0, t0) # clobbers t0 + +1: /* * The order of restoring the registers takes care of the race * updating $28, $29 and kernelsp without disabling ints. @@ -69,50 +108,20 @@ END(resume) /* - * Do lazy fpu context switch. Saves FPU context to the process in a0 - * and loads the new context of the current process. - */ - -#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS) - -LEAF(lazy_fpu_switch) - mfc0 t0, CP0_STATUS # enable cp1 - li t3, ST0_CU1 - or t0, t3 - mtc0 t0, CP0_STATUS - FPU_ENABLE_HAZARD - - beqz a0, 2f # Save floating point state - nor t3, zero, t3 - - lw t1, ST_OFF(a0) # last thread looses fpu - and t1, t3 - sw t1, ST_OFF(a0) - - - FPU_SAVE_DOUBLE(a0, t1) # clobbers t1 -2: - - .set reorder - FPU_RESTORE_DOUBLE($28, t0) # clobbers t0 - jr ra - END(lazy_fpu_switch) - -/* * Save a thread's fp context. */ -LEAF(save_fp) +LEAF(_save_fp) FPU_SAVE_DOUBLE(a0, t1) # clobbers t1 jr ra - END(save_fp) + END(_save_fp) /* * Restore a thread's fp context. */ -LEAF(restore_fp) +LEAF(_restore_fp) FPU_RESTORE_DOUBLE(a0, t1) # clobbers t1 jr ra - END(restore_fp) + END(_restore_fp) /* * Load the FPU with signalling NANS. This bit pattern we're using has @@ -124,7 +133,7 @@ #define FPU_DEFAULT 0x00000000 -LEAF(init_fpu) +LEAF(_init_fpu) .set mips3 mfc0 t0, CP0_STATUS li t1, ST0_CU1 @@ -156,5 +165,5 @@ jr ra dmtc1 t0, $f30 .set reorder - END(init_fpu) + END(_init_fpu) diff -urN linux-2.4.21-bk37/arch/mips/kernel/setup.c linux-2.4.21-bk38/arch/mips/kernel/setup.c --- linux-2.4.21-bk37/arch/mips/kernel/setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -7,7 +7,7 @@ * Copyright (C) 1995 Waldorf Electronics * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001 Ralf Baechle * Copyright (C) 1996 Stoned Elipot - * Copyright (C) 2000, 2001 Maciej W. Rozycki + * Copyright (C) 2000, 2001, 2002 Maciej W. Rozycki */ #include #include @@ -39,9 +39,7 @@ #include #include -#ifndef CONFIG_SMP -struct cpuinfo_mips cpu_data[1]; -#endif +struct cpuinfo_mips cpu_data[NR_CPUS]; /* * There are several bus types available for MIPS machines. "RISC PC" @@ -56,8 +54,11 @@ struct screen_info screen_info; +#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE) +#include extern struct fd_ops no_fd_ops; struct fd_ops *fd_ops; +#endif #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) extern struct ide_ops no_ide_ops; @@ -70,7 +71,6 @@ struct rtc_ops *rtc_ops; #ifdef CONFIG_PC_KEYB -extern struct kbd_ops no_kbd_ops; struct kbd_ops *kbd_ops; #endif @@ -100,15 +100,14 @@ /* - * isa_slot_offset is the address where E(ISA) busaddress 0 is is mapped + * isa_slot_offset is the address where E(ISA) busaddress 0 is mapped * for the processor. */ unsigned long isa_slot_offset; EXPORT_SYMBOL(isa_slot_offset); -extern void sgi_sysinit(void); extern void SetUpBootInfo(void); -extern void loadmmu(void); +extern void load_mmu(void); extern asmlinkage void start_kernel(void); extern void prom_init(int, char **, char **, int *); @@ -123,10 +122,6 @@ prom_init(argc, argv, envp, prom_vec); -#ifdef CONFIG_SGI_IP22 - sgi_sysinit(); -#endif - cpu_report(); /* @@ -134,11 +129,11 @@ * then flush the tlb and caches. On the r4xx0 * variants this also sets CP0_WIRED to zero. */ - loadmmu(); + load_mmu(); /* Disable coprocessors and set FPU for 16/32 FPR register model */ - clear_cp0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR); - set_cp0_status(ST0_CU0); + clear_c0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR); + set_c0_status(ST0_CU0); start_kernel(); } @@ -236,210 +231,6 @@ } } -void __init setup_arch(char **cmdline_p) -{ - void atlas_setup(void); - void baget_setup(void); - void cobalt_setup(void); - void ddb_setup(void); - void decstation_setup(void); - void deskstation_setup(void); - void jazz_setup(void); - void sni_rm200_pci_setup(void); - void ip22_setup(void); - void ev96100_setup(void); - void malta_setup(void); - void sead_setup(void); - void ikos_setup(void); - void momenco_ocelot_setup(void); - void momenco_ocelot_g_setup(void); - void nino_setup(void); - void nec_osprey_setup(void); - void nec_eagle_setup(void); - void zao_capcella_setup(void); - void jmr3927_setup(void); - void it8172_setup(void); - void swarm_setup(void); - void hp_setup(void); - - unsigned long bootmap_size; - unsigned long start_pfn, max_pfn, max_low_pfn, first_usable_pfn; -#ifdef CONFIG_BLK_DEV_INITRD - unsigned long tmp; - unsigned long* initrd_header; -#endif - - int i; - -#ifdef CONFIG_BLK_DEV_FD - fd_ops = &no_fd_ops; -#endif - -#ifdef CONFIG_BLK_DEV_IDE - ide_ops = &no_ide_ops; -#endif - -#ifdef CONFIG_PC_KEYB - kbd_ops = &no_kbd_ops; -#endif - - rtc_ops = &no_rtc_ops; - - switch(mips_machgroup) - { -#ifdef CONFIG_BAGET_MIPS - case MACH_GROUP_BAGET: - baget_setup(); - break; -#endif -#ifdef CONFIG_MIPS_COBALT - case MACH_GROUP_COBALT: - cobalt_setup(); - break; -#endif -#ifdef CONFIG_DECSTATION - case MACH_GROUP_DEC: - decstation_setup(); - break; -#endif -#ifdef CONFIG_MIPS_ATLAS - case MACH_GROUP_UNKNOWN: - atlas_setup(); - break; -#endif -#ifdef CONFIG_MIPS_JAZZ - case MACH_GROUP_JAZZ: - jazz_setup(); - break; -#endif -#ifdef CONFIG_MIPS_MALTA - case MACH_GROUP_UNKNOWN: - malta_setup(); - break; -#endif -#ifdef CONFIG_MOMENCO_OCELOT - case MACH_GROUP_MOMENCO: - momenco_ocelot_setup(); - break; -#endif -#ifdef CONFIG_MOMENCO_OCELOT_G - case MACH_GROUP_MOMENCO: - momenco_ocelot_g_setup(); - break; -#endif -#ifdef CONFIG_MIPS_SEAD - case MACH_GROUP_UNKNOWN: - sead_setup(); - break; -#endif -#ifdef CONFIG_SGI_IP22 - /* As of now this is only IP22. */ - case MACH_GROUP_SGI: - ip22_setup(); - break; -#endif -#ifdef CONFIG_SNI_RM200_PCI - case MACH_GROUP_SNI_RM: - sni_rm200_pci_setup(); - break; -#endif -#ifdef CONFIG_DDB5074 - case MACH_GROUP_NEC_DDB: - ddb_setup(); - break; -#endif -#ifdef CONFIG_DDB5476 - case MACH_GROUP_NEC_DDB: - ddb_setup(); - break; -#endif -#ifdef CONFIG_DDB5477 - case MACH_GROUP_NEC_DDB: - ddb_setup(); - break; -#endif -#ifdef CONFIG_CPU_VR41XX - case MACH_GROUP_NEC_VR41XX: - switch (mips_machtype) { -#ifdef CONFIG_NEC_OSPREY - case MACH_NEC_OSPREY: - nec_osprey_setup(); - break; -#endif -#ifdef CONFIG_NEC_EAGLE - case MACH_NEC_EAGLE: - nec_eagle_setup(); - break; -#endif -#ifdef CONFIG_ZAO_CAPCELLA - case MACH_ZAO_CAPCELLA: - zao_capcella_setup(); - break; -#endif - } - break; -#endif -#ifdef CONFIG_MIPS_EV96100 - case MACH_GROUP_GALILEO: - ev96100_setup(); - break; -#endif -#ifdef CONFIG_MIPS_EV64120 - case MACH_GROUP_GALILEO: - ev64120_setup(); - break; -#endif -#if defined(CONFIG_MIPS_IVR) || defined(CONFIG_MIPS_ITE8172) - case MACH_GROUP_ITE: - case MACH_GROUP_GLOBESPAN: - it8172_setup(); - break; -#endif -#ifdef CONFIG_NINO - case MACH_GROUP_PHILIPS: - nino_setup(); - break; -#endif -#ifdef CONFIG_MIPS_PB1000 - case MACH_GROUP_ALCHEMY: - au1000_setup(); - break; -#endif -#ifdef CONFIG_MIPS_PB1100 - case MACH_GROUP_ALCHEMY: - au1100_setup(); - break; -#endif -#ifdef CONFIG_MIPS_PB1500 - case MACH_GROUP_ALCHEMY: - au1500_setup(); - break; -#endif -#ifdef CONFIG_TOSHIBA_JMR3927 - case MACH_GROUP_TOSHIBA: - jmr3927_setup(); - break; -#endif -#ifdef CONFIG_SIBYTE_SWARM - case MACH_GROUP_SIBYTE: - swarm_setup(); - break; -#endif -#ifdef CONFIG_HP_LASERJET - case MACH_GROUP_HP_LJ: - hp_setup(); - break; -#endif - default: - panic("Unsupported architecture"); - } - - strncpy(command_line, arcs_cmdline, sizeof command_line); - command_line[sizeof command_line - 1] = 0; - strcpy(saved_command_line, command_line); - *cmdline_p = command_line; - - parse_mem_cmdline(); #define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) #define PFN_DOWN(x) ((x) >> PAGE_SHIFT) @@ -448,6 +239,16 @@ #define MAXMEM HIGHMEM_START #define MAXMEM_PFN PFN_DOWN(MAXMEM) +static inline void bootmem_init(void) +{ +#ifdef CONFIG_BLK_DEV_INITRD + unsigned long tmp; + unsigned long *initrd_header; +#endif + unsigned long bootmap_size; + unsigned long start_pfn, max_pfn, max_low_pfn, first_usable_pfn; + int i; + #ifdef CONFIG_BLK_DEV_INITRD tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8; if (tmp < (unsigned long)&_end) @@ -592,15 +393,18 @@ initrd_size); if (PHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) { printk("initrd extends beyond end of memory " - "(0x%lx > 0x%p)\ndisabling initrd\n", + "(0x%08lx > 0x%08lx)\ndisabling initrd\n", PHYSADDR(initrd_end), PFN_PHYS(max_low_pfn)); initrd_start = initrd_end = 0; } } #endif /* CONFIG_BLK_DEV_INITRD */ +} - paging_init(); +static inline void resource_init(void) +{ + int i; code_resource.start = virt_to_bus(&_ftext); code_resource.end = virt_to_bus(&_etext) - 1; @@ -612,7 +416,14 @@ */ for (i = 0; i < boot_mem_map.nr_map; i++) { struct resource *res; - unsigned long addr_pfn, end_pfn; + unsigned long start, end; + + start = boot_mem_map.map[i].addr; + end = boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1; + if (start >= MAXMEM) + continue; + if (end >= MAXMEM) + end = MAXMEM - 1; res = alloc_bootmem(sizeof(struct resource)); switch (boot_mem_map.map[i].type) { @@ -624,16 +435,10 @@ default: res->name = "reserved"; } - addr_pfn = PFN_UP(boot_mem_map.map[i].addr); - end_pfn = PFN_UP(boot_mem_map.map[i].addr+boot_mem_map.map[i].size); - if (addr_pfn > max_low_pfn) - continue; - res->start = boot_mem_map.map[i].addr; - if (end_pfn < max_low_pfn) { - res->end = res->start + boot_mem_map.map[i].size - 1; - } else { - res->end = max_low_pfn - 1; - } + + res->start = start; + res->end = end; + res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; request_resource(&iomem_resource, res); @@ -647,9 +452,257 @@ } } +#undef PFN_UP +#undef PFN_DOWN +#undef PFN_PHYS + +#undef MAXMEM +#undef MAXMEM_PFN + + +void __init setup_arch(char **cmdline_p) +{ + void atlas_setup(void); + void baget_setup(void); + void cobalt_setup(void); + void lasat_setup(void); + void ddb_setup(void); + void decstation_setup(void); + void deskstation_setup(void); + void jazz_setup(void); + void sni_rm200_pci_setup(void); + void ip22_setup(void); + void ev96100_setup(void); + void malta_setup(void); + void sead_setup(void); + void ikos_setup(void); + void momenco_ocelot_setup(void); + void momenco_ocelot_g_setup(void); + void momenco_ocelot_c_setup(void); + void nino_setup(void); + void nec_osprey_setup(void); + void nec_eagle_setup(void); + void zao_capcella_setup(void); + void victor_mpc30x_setup(void); + void ibm_workpad_setup(void); + void casio_e55_setup(void); + void tanbac_tb0226_setup(void); + void jmr3927_setup(void); + void tx4927_setup(void); + void it8172_setup(void); + void swarm_setup(void); + void hp_setup(void); + void au1x00_setup(void); + void frame_info_init(void); + + frame_info_init(); +#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE) + fd_ops = &no_fd_ops; +#endif + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &no_ide_ops; +#endif + + rtc_ops = &no_rtc_ops; + + switch(mips_machgroup) + { +#ifdef CONFIG_BAGET_MIPS + case MACH_GROUP_BAGET: + baget_setup(); + break; +#endif +#ifdef CONFIG_MIPS_COBALT + case MACH_GROUP_COBALT: + cobalt_setup(); + break; +#endif +#ifdef CONFIG_DECSTATION + case MACH_GROUP_DEC: + decstation_setup(); + break; +#endif +#ifdef CONFIG_MIPS_ATLAS + case MACH_GROUP_UNKNOWN: + atlas_setup(); + break; +#endif +#ifdef CONFIG_MIPS_JAZZ + case MACH_GROUP_JAZZ: + jazz_setup(); + break; +#endif +#ifdef CONFIG_MIPS_MALTA + case MACH_GROUP_UNKNOWN: + malta_setup(); + break; +#endif +#ifdef CONFIG_MOMENCO_OCELOT + case MACH_GROUP_MOMENCO: + momenco_ocelot_setup(); + break; +#endif +#ifdef CONFIG_MOMENCO_OCELOT_G + case MACH_GROUP_MOMENCO: + momenco_ocelot_g_setup(); + break; +#endif +#ifdef CONFIG_MOMENCO_OCELOT_C + case MACH_GROUP_MOMENCO: + momenco_ocelot_c_setup(); + break; +#endif +#ifdef CONFIG_MIPS_SEAD + case MACH_GROUP_UNKNOWN: + sead_setup(); + break; +#endif +#ifdef CONFIG_SGI_IP22 + /* As of now this is only IP22. */ + case MACH_GROUP_SGI: + ip22_setup(); + break; +#endif +#ifdef CONFIG_SNI_RM200_PCI + case MACH_GROUP_SNI_RM: + sni_rm200_pci_setup(); + break; +#endif +#ifdef CONFIG_DDB5074 + case MACH_GROUP_NEC_DDB: + ddb_setup(); + break; +#endif +#ifdef CONFIG_DDB5476 + case MACH_GROUP_NEC_DDB: + ddb_setup(); + break; +#endif +#ifdef CONFIG_DDB5477 + case MACH_GROUP_NEC_DDB: + ddb_setup(); + break; +#endif +#ifdef CONFIG_CPU_VR41XX + case MACH_GROUP_NEC_VR41XX: + switch (mips_machtype) { +#ifdef CONFIG_NEC_OSPREY + case MACH_NEC_OSPREY: + nec_osprey_setup(); + break; +#endif +#ifdef CONFIG_NEC_EAGLE + case MACH_NEC_EAGLE: + nec_eagle_setup(); + break; +#endif +#ifdef CONFIG_ZAO_CAPCELLA + case MACH_ZAO_CAPCELLA: + zao_capcella_setup(); + break; +#endif +#ifdef CONFIG_VICTOR_MPC30X + case MACH_VICTOR_MPC30X: + victor_mpc30x_setup(); + break; +#endif +#ifdef CONFIG_IBM_WORKPAD + case MACH_IBM_WORKPAD: + ibm_workpad_setup(); + break; +#endif +#ifdef CONFIG_CASIO_E55 + case MACH_CASIO_E55: + casio_e55_setup(); + break; +#endif +#ifdef CONFIG_TANBAC_TB0226 + case MACH_TANBAC_TB0226: + tanbac_tb0226_setup(); + break; +#endif +#ifdef CONFIG_TANBAC_TB0229 + case MACH_TANBAC_TB0229: + tanbac_tb0229_setup(); + break; +#endif + } + break; +#endif +#ifdef CONFIG_MIPS_EV96100 + case MACH_GROUP_GALILEO: + ev96100_setup(); + break; +#endif +#ifdef CONFIG_MIPS_EV64120 + case MACH_GROUP_GALILEO: + ev64120_setup(); + break; +#endif +#if defined(CONFIG_MIPS_IVR) || defined(CONFIG_MIPS_ITE8172) + case MACH_GROUP_ITE: + case MACH_GROUP_GLOBESPAN: + it8172_setup(); + break; +#endif +#ifdef CONFIG_NINO + case MACH_GROUP_PHILIPS: + nino_setup(); + break; +#endif +#ifdef CONFIG_LASAT + case MACH_GROUP_LASAT: + lasat_setup(); + break; +#endif +#ifdef CONFIG_SOC_AU1X00 + case MACH_GROUP_ALCHEMY: + au1x00_setup(); + break; +#endif +#ifdef CONFIG_TOSHIBA_JMR3927 + case MACH_GROUP_TOSHIBA: + jmr3927_setup(); + break; +#endif +#ifdef CONFIG_TOSHIBA_RBTX4927 + case MACH_GROUP_TOSHIBA: + tx4927_setup(); + break; +#endif +#ifdef CONFIG_SIBYTE_BOARD + case MACH_GROUP_SIBYTE: + swarm_setup(); + break; +#endif +#ifdef CONFIG_HP_LASERJET + case MACH_GROUP_HP_LJ: + hp_setup(); + break; +#endif + default: + panic("Unsupported architecture"); + } + + strncpy(command_line, arcs_cmdline, sizeof command_line); + command_line[sizeof command_line - 1] = 0; + strcpy(saved_command_line, command_line); + *cmdline_p = command_line; + + parse_mem_cmdline(); + + bootmem_init(); + + paging_init(); + + resource_init(); +} + static int __init fpu_disable(char *s) { - mips_cpu.options &= ~MIPS_CPU_FPU; + cpu_data[0].options &= ~MIPS_CPU_FPU; + return 1; } __setup("nofpu", fpu_disable); diff -urN linux-2.4.21-bk37/arch/mips/kernel/signal.c linux-2.4.21-bk38/arch/mips/kernel/signal.c --- linux-2.4.21-bk37/arch/mips/kernel/signal.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/signal.c 2003-08-24 02:55:57.000000000 -0700 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -34,9 +35,6 @@ extern asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); -extern asmlinkage int (*save_fp_context)(struct sigcontext *sc); -extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc); - extern asmlinkage void syscall_trace(void); int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) @@ -150,7 +148,6 @@ err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler); err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); err |= __get_user(mask, &act->sa_mask.sig[0]); - err |= __get_user(new_ka.sa.sa_restorer, &act->sa_restorer); if (err) return -EFAULT; @@ -168,7 +165,6 @@ err |= __put_user(0, &oact->sa_mask.sig[1]); err |= __put_user(0, &oact->sa_mask.sig[2]); err |= __put_user(0, &oact->sa_mask.sig[3]); - err |= __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer); if (err) return -EFAULT; } @@ -185,59 +181,8 @@ return do_sigaltstack(uss, uoss, usp); } -static inline int restore_thread_fp_context(struct sigcontext *sc) -{ - u64 *pfreg = ¤t->thread.fpu.soft.regs[0]; - int err = 0; - - /* - * Copy all 32 64-bit values, for two reasons. First, the R3000 and - * R4000/MIPS32 kernels use the thread FP register storage differently, - * such that a full copy is essentially necessary to support both. - */ - -#define restore_fpr(i) \ - do { err |= __get_user(pfreg[i], &sc->sc_fpregs[i]); } while(0) - - restore_fpr( 0); restore_fpr( 1); restore_fpr( 2); restore_fpr( 3); - restore_fpr( 4); restore_fpr( 5); restore_fpr( 6); restore_fpr( 7); - restore_fpr( 8); restore_fpr( 9); restore_fpr(10); restore_fpr(11); - restore_fpr(12); restore_fpr(13); restore_fpr(14); restore_fpr(15); - restore_fpr(16); restore_fpr(17); restore_fpr(18); restore_fpr(19); - restore_fpr(20); restore_fpr(21); restore_fpr(22); restore_fpr(23); - restore_fpr(24); restore_fpr(25); restore_fpr(26); restore_fpr(27); - restore_fpr(28); restore_fpr(29); restore_fpr(30); restore_fpr(31); - - err |= __get_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr); - - return err; -} - -static inline int save_thread_fp_context(struct sigcontext *sc) -{ - u64 *pfreg = ¤t->thread.fpu.soft.regs[0]; - int err = 0; - -#define save_fpr(i) \ - do { err |= __put_user(pfreg[i], &sc->sc_fpregs[i]); } while(0) - - save_fpr( 0); save_fpr( 1); save_fpr( 2); save_fpr( 3); - save_fpr( 4); save_fpr( 5); save_fpr( 6); save_fpr( 7); - save_fpr( 8); save_fpr( 9); save_fpr(10); save_fpr(11); - save_fpr(12); save_fpr(13); save_fpr(14); save_fpr(15); - save_fpr(16); save_fpr(17); save_fpr(18); save_fpr(19); - save_fpr(20); save_fpr(21); save_fpr(22); save_fpr(23); - save_fpr(24); save_fpr(25); save_fpr(26); save_fpr(27); - save_fpr(28); save_fpr(29); save_fpr(30); save_fpr(31); - - err |= __put_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr); - - return err; -} - static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) { - int owned_fp; int err = 0; u64 reg; @@ -265,25 +210,17 @@ restore_gp_reg(31); #undef restore_gp_reg - err |= __get_user(owned_fp, &sc->sc_ownedfp); err |= __get_user(current->used_math, &sc->sc_used_math); - if (owned_fp) { - err |= restore_fp_context(sc); - goto out; - } - - if (current == last_task_used_math) { - /* Signal handler acquired FPU - give it back */ - last_task_used_math = NULL; - regs->cp0_status &= ~ST0_CU1; - } if (current->used_math) { - /* Undo possible contamination of thread state */ - err |= restore_thread_fp_context(sc); + /* restore fpu context if we have used it before */ + own_fpu(); + err |= restore_fp_context(sc); + } else { + /* signal handler may have used FPU. Give it up. */ + lose_fpu(); } -out: return err; } @@ -380,7 +317,6 @@ static int inline setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) { - int owned_fp; int err = 0; u64 reg; @@ -408,25 +344,20 @@ err |= __put_user(regs->cp0_cause, &sc->sc_cause); err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); - owned_fp = (current == last_task_used_math); - err |= __put_user(owned_fp, &sc->sc_ownedfp); err |= __put_user(current->used_math, &sc->sc_used_math); if (!current->used_math) goto out; - /* There exists FP thread state that may be trashed by signal */ - if (owned_fp) { - /* fp is active. Save context from FPU */ - err |= save_fp_context(sc); - goto out; - } - - /* - * Someone else has FPU. - * Copy Thread context into signal context + /* + * Save FPU state to signal context. Signal handler will "inherit" + * current FPU state. */ - err |= save_thread_fp_context(sc); + if (!is_fpu_owner()) { + own_fpu(); + restore_fp(current); + } + err |= save_fp_context(sc); out: return err; @@ -467,23 +398,15 @@ if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto give_sigsegv; - /* Set up to return from userspace. If provided, use a stub already - in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) - regs->regs[31] = (unsigned long) ka->sa.sa_restorer; - else { - /* - * Set up the return code ... - * - * li v0, __NR_sigreturn - * syscall - */ - err |= __put_user(0x24020000 + __NR_sigreturn, - frame->sf_code + 0); - err |= __put_user(0x0000000c , - frame->sf_code + 1); - flush_cache_sigtramp((unsigned long) frame->sf_code); - } + /* + * Set up the return code ... + * + * li v0, __NR_sigreturn + * syscall + */ + err |= __put_user(0x24020000 + __NR_sigreturn, frame->sf_code + 0); + err |= __put_user(0x0000000c , frame->sf_code + 1); + flush_cache_sigtramp((unsigned long) frame->sf_code); err |= setup_sigcontext(regs, &frame->sf_sc); err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); @@ -530,23 +453,15 @@ if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto give_sigsegv; - /* Set up to return from userspace. If provided, use a stub already - in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) - regs->regs[31] = (unsigned long) ka->sa.sa_restorer; - else { - /* - * Set up the return code ... - * - * li v0, __NR_rt_sigreturn - * syscall - */ - err |= __put_user(0x24020000 + __NR_rt_sigreturn, - frame->rs_code + 0); - err |= __put_user(0x0000000c , - frame->rs_code + 1); - flush_cache_sigtramp((unsigned long) frame->rs_code); - } + /* + * Set up the return code ... + * + * li v0, __NR_rt_sigreturn + * syscall + */ + err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0); + err |= __put_user(0x0000000c , frame->rs_code + 1); + flush_cache_sigtramp((unsigned long) frame->rs_code); /* Create siginfo. */ err |= copy_siginfo_to_user(&frame->rs_info, info); diff -urN linux-2.4.21-bk37/arch/mips/kernel/smp.c linux-2.4.21-bk38/arch/mips/kernel/smp.c --- linux-2.4.21-bk37/arch/mips/kernel/smp.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/smp.c 2003-08-24 02:55:57.000000000 -0700 @@ -43,9 +43,7 @@ spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; int smp_threads_ready; /* Not used */ atomic_t smp_commenced = ATOMIC_INIT(0); -struct cpuinfo_mips cpu_data[NR_CPUS]; -// static atomic_t cpus_booted = ATOMIC_INIT(0); atomic_t cpus_booted = ATOMIC_INIT(0); int smp_num_cpus = 1; /* Number that came online. */ @@ -83,10 +81,6 @@ void prom_smp_finish(void); -static void smp_tune_scheduling(void) -{ -} - void __init smp_callin(void) { #if 0 @@ -104,6 +98,7 @@ { unsigned int cpu = smp_processor_id(); + cpu_probe(); prom_init_secondary(); per_cpu_trap_init(); @@ -138,7 +133,7 @@ core_send_ipi(cpu, SMP_RESCHEDULE_YOURSELF); } -static spinlock_t call_lock = SPIN_LOCK_UNLOCKED; +spinlock_t smp_call_lock = SPIN_LOCK_UNLOCKED; struct call_data_struct *call_data; @@ -170,7 +165,7 @@ if (wait) atomic_set(&data.finished, 0); - spin_lock(&call_lock); + spin_lock(&smp_call_lock); call_data = &data; /* Send a message to all other CPUs and wait for them to respond */ @@ -186,7 +181,7 @@ if (wait) while (atomic_read(&data.finished) != cpus) barrier(); - spin_unlock(&call_lock); + spin_unlock(&smp_call_lock); return 0; } @@ -224,7 +219,7 @@ */ clear_bit(smp_processor_id(), &cpu_online_map); /* May need to service _machine_restart IPI */ - __sti(); + local_irq_enable(); /* XXXKW wait if available? */ for (;;); } @@ -282,7 +277,7 @@ int i; for (i = 0; i < smp_num_cpus; i++) if (smp_processor_id() != i) - CPU_CONTEXT(i, mm) = 0; + cpu_context(i, mm) = 0; } local_flush_tlb_mm(mm); } @@ -314,7 +309,7 @@ int i; for (i = 0; i < smp_num_cpus; i++) if (smp_processor_id() != i) - CPU_CONTEXT(i, mm) = 0; + cpu_context(i, mm) = 0; } local_flush_tlb_range(mm, start, end); } @@ -338,7 +333,7 @@ int i; for (i = 0; i < smp_num_cpus; i++) if (smp_processor_id() != i) - CPU_CONTEXT(i, vma->vm_mm) = 0; + cpu_context(i, vma->vm_mm) = 0; } local_flush_tlb_page(vma, page); } diff -urN linux-2.4.21-bk37/arch/mips/kernel/syscall.c linux-2.4.21-bk38/arch/mips/kernel/syscall.c --- linux-2.4.21-bk37/arch/mips/kernel/syscall.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/syscall.c 2003-08-24 02:55:57.000000000 -0700 @@ -55,9 +55,11 @@ return res; } -#define COLOUR_ALIGN(addr,pgoff) \ - ((((addr)+SHMLBA-1)&~(SHMLBA-1)) + \ - (((pgoff)< #include #include +#include #include #include #include #include +#include #include #include @@ -28,9 +31,14 @@ #include #include -/* This is for machines which generate the exact clock. */ -#define USECS_PER_JIFFY (1000000/HZ) -#define USECS_PER_JIFFY_FRAC ((u32)((1000000ULL << 32) / HZ)) +/* + * The integer part of the number of usecs per jiffy is taken from tick, + * but the fractional part is not recorded, so we calculate it using the + * initial value of HZ. This aids systems where tick isn't really an + * integer (e.g. for HZ = 128). + */ +#define USECS_PER_JIFFY tick +#define USECS_PER_JIFFY_FRAC ((unsigned long)(u32)((1000000ULL << 32) / HZ)) /* * forward reference @@ -38,11 +46,14 @@ extern rwlock_t xtime_lock; extern volatile unsigned long wall_jiffies; +spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; + /* * whether we emulate local_timer_interrupts for SMP machines. */ int emulate_local_timer_interrupt; + /* * By default we provide the null RTC ops */ @@ -58,6 +69,85 @@ unsigned long (*rtc_get_time)(void) = null_rtc_get_time; int (*rtc_set_time)(unsigned long) = null_rtc_set_time; +int (*rtc_set_mmss)(unsigned long); + + +/* usecs per counter cycle, shifted to left by 32 bits */ +static unsigned int sll32_usecs_per_cycle; + +/* how many counter cycles in a jiffy */ +static unsigned long cycles_per_jiffy; + +/* Cycle counter value at the previous timer interrupt.. */ +static unsigned int timerhi, timerlo; + +/* expirelo is the count value for next CPU timer interrupt */ +static unsigned int expirelo; + + +/* + * Null timer ack for systems not needing one (e.g. i8254). + */ +static void null_timer_ack(void) { /* nothing */ } + +/* + * Null high precision timer functions for systems lacking one. + */ +static unsigned int null_hpt_read(void) +{ + return 0; +} + +static void null_hpt_init(unsigned int count) { /* nothing */ } + + +/* + * Timer ack for a R4k-compatible timer of a known frequency. + */ +static void c0_fixed_timer_ack(void) +{ + unsigned int count; + + /* Ack this timer interrupt and set the next one. */ + expirelo += cycles_per_jiffy; + write_c0_compare(expirelo); + + /* Check to see if we have missed any timer interrupts. */ + count = read_c0_count(); + if ((count - expirelo) < 0x7fffffff) { + /* missed_timer_count++; */ + expirelo = count + cycles_per_jiffy; + write_c0_compare(expirelo); + } +} + +/* + * High precision timer functions for a R4k-compatible timer. + */ +static unsigned int c0_hpt_read(void) +{ + return read_c0_count(); +} + +/* For unknown frequency. */ +static void c0_hpt_init(unsigned int count) +{ + write_c0_count(read_c0_count() - count); +} + +/* For a known frequency. Used as an interrupt source. */ +static void c0_fixed_hpt_init(unsigned int count) +{ + expirelo = cycles_per_jiffy; + count = read_c0_count() - count; + write_c0_count(0); + write_c0_compare(cycles_per_jiffy); + write_c0_count(count); +} + +void (*mips_timer_ack)(void); +unsigned int (*mips_hpt_read)(void); +void (*mips_hpt_init)(unsigned int); /* @@ -65,22 +155,23 @@ */ void do_gettimeofday(struct timeval *tv) { - unsigned long flags; + unsigned long flags, lost; + + read_lock_irqsave(&xtime_lock, flags); - read_lock_irqsave (&xtime_lock, flags); *tv = xtime; tv->tv_usec += do_gettimeoffset(); - /* - * xtime is atomically updated in timer_bh. jiffies - wall_jiffies - * is nonzero if the timer bottom half hasnt executed yet. + * xtime is atomically updated in timer_bh. jiffies - wall_jiffies + * is nonzero if the timer bottom half hasn't executed yet. */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; + lost = jiffies - wall_jiffies; + if (lost) + tv->tv_usec += lost * USECS_PER_JIFFY; - read_unlock_irqrestore (&xtime_lock, flags); + read_unlock_irqrestore(&xtime_lock, flags); - if (tv->tv_usec >= 1000000) { + while (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; tv->tv_sec++; } @@ -88,27 +179,29 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq (&xtime_lock); + write_lock_irq(&xtime_lock); - /* This is revolting. We need to set the xtime.tv_usec - * correctly. However, the value in this location is - * is value at the last tick. - * Discover what correction gettimeofday - * would have done, and then undo it! + /* + * This is revolting. We need to set "xtime" correctly. However, + * the value in this location is the value at the most recent update + * of wall time. Discover what correction gettimeofday() would have + * made, and then undo it! */ tv->tv_usec -= do_gettimeoffset(); + tv->tv_usec -= (jiffies - wall_jiffies) * USECS_PER_JIFFY; - if (tv->tv_usec < 0) { + while (tv->tv_usec < 0) { tv->tv_usec += 1000000; tv->tv_sec--; } + xtime = *tv; time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq (&xtime_lock); + write_unlock_irq(&xtime_lock); } @@ -119,76 +212,61 @@ * If the exact CPU counter frequency is known, use fixed_rate_gettimeoffset. * Otherwise use calibrate_gettimeoffset() * - * If the CPU does not have counter register all, you can either supply - * your own gettimeoffset() routine, or use null_gettimeoffset() routines, - * which gives the same resolution as HZ. + * If the CPU does not have the counter register, you can either supply + * your own gettimeoffset() routine, or use null_gettimeoffset(), which + * gives the same resolution as HZ. */ +static unsigned long null_gettimeoffset(void) +{ + return 0; +} -/* This is for machines which generate the exact clock. */ -#define USECS_PER_JIFFY (1000000/HZ) - -/* usecs per counter cycle, shifted to left by 32 bits */ -static unsigned int sll32_usecs_per_cycle=0; - -/* how many counter cycles in a jiffy */ -static unsigned long cycles_per_jiffy=0; - -/* Cycle counter value at the previous timer interrupt.. */ -static unsigned int timerhi, timerlo; - -/* last time when xtime and rtc are sync'ed up */ -static long last_rtc_update; -/* the function pointer to one of the gettimeoffset funcs*/ +/* The function pointer to one of the gettimeoffset funcs. */ unsigned long (*do_gettimeoffset)(void) = null_gettimeoffset; -unsigned long null_gettimeoffset(void) -{ - return 0; -} -unsigned long fixed_rate_gettimeoffset(void) +static unsigned long fixed_rate_gettimeoffset(void) { u32 count; unsigned long res; /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = mips_hpt_read(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; - __asm__("multu\t%1,%2\n\t" - "mfhi\t%0" - :"=r" (res) - :"r" (count), - "r" (sll32_usecs_per_cycle)); + __asm__("multu %1,%2" + : "=h" (res) + : "r" (count), "r" (sll32_usecs_per_cycle) + : "lo", "accum"); /* * Due to possible jiffies inconsistencies, we need to check * the result so that we'll get a timer that is monotonic. */ if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY-1; + res = USECS_PER_JIFFY - 1; return res; } + /* - * Cached "1/(clocks per usec)*2^32" value. + * Cached "1/(clocks per usec) * 2^32" value. * It has to be recalculated once each jiffy. */ static unsigned long cached_quotient; /* Last jiffy when calibrate_divXX_gettimeoffset() was called. */ -static unsigned long last_jiffies = 0; - +static unsigned long last_jiffies; /* - * This is copied from dec/time.c:do_ioasic_gettimeoffset() by Mercij. + * This is moved from dec/time.c:do_ioasic_gettimeoffset() by Maciej. */ -unsigned long calibrate_div32_gettimeoffset(void) +static unsigned long calibrate_div32_gettimeoffset(void) { u32 count; unsigned long res, tmp; @@ -204,20 +282,21 @@ unsigned long r0; do_div64_32(r0, timerhi, timerlo, tmp); do_div64_32(quotient, USECS_PER_JIFFY, - USECS_PER_JIFFY_FRAC, r0); + USECS_PER_JIFFY_FRAC, r0); cached_quotient = quotient; } } /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = mips_hpt_read(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; - __asm__("multu %2,%3" - : "=l" (tmp), "=h" (res) - : "r" (count), "r" (quotient)); + __asm__("multu %1,%2" + : "=h" (res) + : "r" (count), "r" (quotient) + : "lo", "accum"); /* * Due to possible jiffies inconsistencies, we need to check @@ -229,7 +308,7 @@ return res; } -unsigned long calibrate_div64_gettimeoffset(void) +static unsigned long calibrate_div64_gettimeoffset(void) { u32 count; unsigned long res, tmp; @@ -239,54 +318,56 @@ quotient = cached_quotient; - if (tmp && last_jiffies != tmp) { + if (last_jiffies != tmp) { last_jiffies = tmp; - __asm__(".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "lwu\t%0,%2\n\t" - "dsll32\t$1,%1,0\n\t" - "or\t$1,$1,%0\n\t" - "ddivu\t$0,$1,%3\n\t" - "mflo\t$1\n\t" - "dsll32\t%0,%4,0\n\t" - "nop\n\t" - "ddivu\t$0,%0,$1\n\t" - "mflo\t%0\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=&r" (quotient) - :"r" (timerhi), - "m" (timerlo), - "r" (tmp), - "r" (USECS_PER_JIFFY)); - cached_quotient = quotient; + if (last_jiffies) { + unsigned long r0; + __asm__(".set push\n\t" + ".set mips3\n\t" + "lwu %0,%3\n\t" + "dsll32 %1,%2,0\n\t" + "or %1,%1,%0\n\t" + "ddivu $0,%1,%4\n\t" + "dsll32 %0,%5,0\n\t" + "or %0,%0,%6\n\t" + "mflo %1\n\t" + "ddivu $0,%0,%1\n\t" + "mflo %0\n\t" + ".set pop" + : "=&r" (quotient), "=&r" (r0) + : "r" (timerhi), "m" (timerlo), + "r" (tmp), "r" (USECS_PER_JIFFY), + "r" (USECS_PER_JIFFY_FRAC) + : "hi", "lo", "accum"); + cached_quotient = quotient; + } } /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = mips_hpt_read(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; - __asm__("multu\t%1,%2\n\t" - "mfhi\t%0" - :"=r" (res) - :"r" (count), - "r" (quotient)); + __asm__("multu %1,%2" + : "=h" (res) + : "r" (count), "r" (quotient) + : "lo", "accum"); /* * Due to possible jiffies inconsistencies, we need to check * the result so that we'll get a timer that is monotonic. */ if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY-1; + res = USECS_PER_JIFFY - 1; return res; } +/* last time when xtime and rtc are sync'ed up */ +static long last_rtc_update; + /* * local_timer_interrupt() does profiling and process accounting * on a per-CPU basis. @@ -311,8 +392,8 @@ * put them into the last histogram slot, so if * present, they will show up as a sharp peak. */ - if (pc > prof_len-1) - pc = prof_len-1; + if (pc > prof_len - 1) + pc = prof_len - 1; atomic_inc((atomic_t *)&prof_buffer[pc]); } } @@ -324,31 +405,19 @@ } /* - * high-level timer interrupt service routines. This function + * High-level timer interrupt service routines. This function * is set as irqaction->handler and is invoked through do_IRQ. */ void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - if (mips_cpu.options & MIPS_CPU_COUNTER) { - unsigned int count; + unsigned int count; - /* - * The cycle counter is only 32 bit which is good for about - * a minute at current count rates of upto 150MHz or so. - */ - count = read_32bit_cp0_register(CP0_COUNT); - timerhi += (count < timerlo); /* Wrap around */ - timerlo = count; + count = mips_hpt_read(); + mips_timer_ack(); - /* - * set up for next timer interrupt - no harm if the machine - * is using another timer interrupt source. - * Note that writing to COMPARE register clears the interrupt - */ - write_32bit_cp0_register (CP0_COMPARE, - count + cycles_per_jiffy); - - } + /* Update timerhi/timerlo for intra-jiffy calibration. */ + timerhi += count < timerlo; /* Wrap around */ + timerlo = count; /* * call the generic timer interrupt handling @@ -360,27 +429,28 @@ * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be * called as close as possible to 500 ms before the new second starts. */ - read_lock (&xtime_lock); + read_lock(&xtime_lock); if ((time_status & STA_UNSYNC) == 0 && xtime.tv_sec > last_rtc_update + 660 && xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 && xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) { - if (rtc_set_time(xtime.tv_sec) == 0) { + if (rtc_set_mmss(xtime.tv_sec) == 0) { last_rtc_update = xtime.tv_sec; } else { - last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ + last_rtc_update = xtime.tv_sec - 600; } } - read_unlock (&xtime_lock); + read_unlock(&xtime_lock); /* - * If jiffies has overflowed in this timer_interrupt we must + * If jiffies has overflown in this timer_interrupt, we must * update the timer[hi]/[lo] to make fast gettimeoffset funcs * quotient calc still valid. -arca */ if (!jiffies) { timerhi = timerlo = 0; + mips_hpt_init(count); } #if !defined(CONFIG_SMP) @@ -391,7 +461,7 @@ * In SMP mode, local_timer_interrupt() is invoked by appropriate * low-level local timer interrupt handler. */ - local_timer_interrupt(0, NULL, regs); + local_timer_interrupt(irq, dev_id, regs); #else /* CONFIG_SMP */ @@ -458,18 +528,15 @@ * c) enable the timer interrupt */ -void (*board_time_init)(void) = NULL; -void (*board_timer_setup)(struct irqaction *irq) = NULL; +void (*board_time_init)(void); +void (*board_timer_setup)(struct irqaction *irq); -unsigned int mips_counter_frequency = 0; +unsigned int mips_counter_frequency; static struct irqaction timer_irqaction = { - timer_interrupt, - SA_INTERRUPT, - 0, - "timer", - NULL, - NULL + .handler = timer_interrupt, + .flags = SA_INTERRUPT, + .name = "timer", }; void __init time_init(void) @@ -477,55 +544,76 @@ if (board_time_init) board_time_init(); + if (!rtc_set_mmss) + rtc_set_mmss = rtc_set_time; + xtime.tv_sec = rtc_get_time(); xtime.tv_usec = 0; - /* choose appropriate gettimeoffset routine */ - if (!(mips_cpu.options & MIPS_CPU_COUNTER)) { - /* no cpu counter - sorry */ - do_gettimeoffset = null_gettimeoffset; - } else if (mips_counter_frequency != 0) { - /* we have cpu counter and know counter frequency! */ - do_gettimeoffset = fixed_rate_gettimeoffset; - } else if ((mips_cpu.isa_level == MIPS_CPU_ISA_M32) || - (mips_cpu.isa_level == MIPS_CPU_ISA_I) || - (mips_cpu.isa_level == MIPS_CPU_ISA_II) ) { - /* we need to calibrate the counter but we don't have - * 64-bit division. */ - do_gettimeoffset = calibrate_div32_gettimeoffset; + /* Choose appropriate high precision timer routines. */ + if (!cpu_has_counter && !mips_hpt_read) { + /* No high precision timer -- sorry. */ + mips_hpt_read = null_hpt_read; + mips_hpt_init = null_hpt_init; + } else if (!mips_counter_frequency) { + /* A high precision timer of unknown frequency. */ + if (!mips_hpt_read) { + /* No external high precision timer -- use R4k. */ + mips_hpt_read = c0_hpt_read; + mips_hpt_init = c0_hpt_init; + } + + if ((current_cpu_data.isa_level == MIPS_CPU_ISA_M32) || + (current_cpu_data.isa_level == MIPS_CPU_ISA_I) || + (current_cpu_data.isa_level == MIPS_CPU_ISA_II)) + /* + * We need to calibrate the counter but we don't have + * 64-bit division. + */ + do_gettimeoffset = calibrate_div32_gettimeoffset; + else + /* + * We need to calibrate the counter but we *do* have + * 64-bit division. + */ + do_gettimeoffset = calibrate_div64_gettimeoffset; } else { - /* we need to calibrate the counter but we *do* have - * 64-bit division. */ - do_gettimeoffset = calibrate_div64_gettimeoffset; - } + /* We know counter frequency! */ + if (!mips_hpt_read) { + /* No external high precision timer -- use R4k. */ + mips_hpt_read = c0_hpt_read; + mips_hpt_init = c0_fixed_hpt_init; + + if (!mips_timer_ack) + /* R4k timer interrupt ack. */ + mips_timer_ack = c0_fixed_timer_ack; + } - /* caclulate cache parameters */ - if (mips_counter_frequency) { - u32 count; + do_gettimeoffset = fixed_rate_gettimeoffset; + /* Calculate cache parameters. */ cycles_per_jiffy = mips_counter_frequency / HZ; - /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */ - /* any better way to do this? */ + /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */ + /* Any better way to do this? */ sll32_usecs_per_cycle = mips_counter_frequency / 100000; sll32_usecs_per_cycle = 0xffffffff / sll32_usecs_per_cycle; sll32_usecs_per_cycle *= 10; - - /* - * For those using cpu counter as timer, this sets up the - * first interrupt - */ - count = read_32bit_cp0_register(CP0_COUNT); - write_32bit_cp0_register (CP0_COMPARE, - count + cycles_per_jiffy); } + if (!mips_timer_ack) + /* No timer interrupt ack (e.g. i8254). */ + mips_timer_ack = null_timer_ack; + + /* This sets up the high precision timer for the first interrupt. */ + mips_hpt_init(mips_hpt_read()); + /* * Call board specific timer interrupt setup. * * this pointer must be setup in machine setup routine. * - * Even if the machine choose to use low-level timer interrupt, + * Even if a machine chooses to use a low-level timer interrupt, * it still needs to setup the timer_irqaction. * In that case, it might be better to set timer_irqaction.handler * to be NULL function so that we are sure the high-level code @@ -538,15 +626,15 @@ #define STARTOFTIME 1970 #define SECDAY 86400L #define SECYR (SECDAY * 365) -#define leapyear(year) ((year) % 4 == 0) -#define days_in_year(a) (leapyear(a) ? 366 : 365) -#define days_in_month(a) (month_days[(a) - 1]) +#define leapyear(y) ((!((y) % 4) && ((y) % 100)) || !((y) % 400)) +#define days_in_year(y) (leapyear(y) ? 366 : 365) +#define days_in_month(m) (month_days[(m) - 1]) static int month_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; -void to_tm(unsigned long tim, struct rtc_time * tm) +void to_tm(unsigned long tim, struct rtc_time *tm) { long hms, day, gday; int i; @@ -561,16 +649,16 @@ /* Number of years in days */ for (i = STARTOFTIME; day >= days_in_year(i); i++) - day -= days_in_year(i); + day -= days_in_year(i); tm->tm_year = i; /* Number of months in days left */ if (leapyear(tm->tm_year)) - days_in_month(FEBRUARY) = 29; + days_in_month(FEBRUARY) = 29; for (i = 1; day >= days_in_month(i); i++) - day -= days_in_month(i); + day -= days_in_month(i); days_in_month(FEBRUARY) = 28; - tm->tm_mon = i-1; /* tm_mon starts from 0 to 11 */ + tm->tm_mon = i - 1; /* tm_mon starts from 0 to 11 */ /* Days are what is left over (+1) from all that. */ tm->tm_mday = day + 1; @@ -578,5 +666,10 @@ /* * Determine the day of week */ - tm->tm_wday = (gday + 4) % 7; /* 1970/1/1 was Thursday */ + tm->tm_wday = (gday + 4) % 7; /* 1970/1/1 was Thursday */ } + +EXPORT_SYMBOL(rtc_lock); +EXPORT_SYMBOL(to_tm); +EXPORT_SYMBOL(rtc_set_time); +EXPORT_SYMBOL(rtc_get_time); diff -urN linux-2.4.21-bk37/arch/mips/kernel/traps.c linux-2.4.21-bk38/arch/mips/kernel/traps.c --- linux-2.4.21-bk37/arch/mips/kernel/traps.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/traps.c 2003-08-24 02:55:57.000000000 -0700 @@ -4,13 +4,12 @@ * for more details. * * Copyright (C) 1994 - 1999, 2000, 01 Ralf Baechle - * Modified for R3000 by Paul M. Antoine, 1995, 1996 - * Complete output from die() by Ulf Carlsson, 1998 + * Copyright (C) 1995, 1996 Paul M. Antoine + * Copyright (C) 1998 Ulf Carlsson * Copyright (C) 1999 Silicon Graphics, Inc. - * * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000, 01 MIPS Technologies, Inc. - * Copyright (C) 2002 Maciej W. Rozycki + * Copyright (C) 2002, 2003 Maciej W. Rozycki */ #include #include @@ -24,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -32,21 +32,13 @@ #include #include #include +#include #include #include #include #include #include -/* - * Machine specific interrupt handlers - */ -extern asmlinkage void acer_pica_61_handle_int(void); -extern asmlinkage void decstation_handle_int(void); -extern asmlinkage void deskstation_rpc44_handle_int(void); -extern asmlinkage void deskstation_tyne_handle_int(void); -extern asmlinkage void mips_magnum_4000_handle_int(void); - extern asmlinkage void handle_mod(void); extern asmlinkage void handle_tlbl(void); extern asmlinkage void handle_tlbs(void); @@ -61,6 +53,7 @@ extern asmlinkage void handle_ov(void); extern asmlinkage void handle_tr(void); extern asmlinkage void handle_fpe(void); +extern asmlinkage void handle_mdmx(void); extern asmlinkage void handle_watch(void); extern asmlinkage void handle_mcheck(void); extern asmlinkage void handle_reserved(void); @@ -68,9 +61,8 @@ extern int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx); -char watch_available = 0; - -int (*be_board_handler)(struct pt_regs *regs, int is_fixup); +void (*board_be_init)(void); +int (*board_be_handler)(struct pt_regs *regs, int is_fixup); int kstack_depth_to_print = 24; @@ -81,107 +73,6 @@ #define MODULE_RANGE (8*1024*1024) /* - * This stuff is needed for the userland ll-sc emulation for R2300 - */ - -#define OPCODE 0xfc000000 -#define BASE 0x03e00000 -#define RT 0x001f0000 -#define OFFSET 0x0000ffff -#define LL 0xc0000000 -#define SC 0xe0000000 - -/* - * The ll_bit is cleared by r*_switch.S - */ - -unsigned long ll_bit; -#ifdef CONFIG_PROC_FS -extern unsigned long ll_ops; -extern unsigned long sc_ops; -#endif - -static struct task_struct *ll_task = NULL; - -static inline void simulate_ll(struct pt_regs *regp, unsigned int opcode) -{ - unsigned long value, *vaddr; - long offset; - int signal = 0; - - /* - * analyse the ll instruction that just caused a ri exception - * and put the referenced address to addr. - */ - - /* sign extend offset */ - offset = opcode & OFFSET; - offset <<= 16; - offset >>= 16; - - vaddr = (unsigned long *)((long)(regp->regs[(opcode & BASE) >> 21]) + offset); - -#ifdef CONFIG_PROC_FS - ll_ops++; -#endif - - if ((unsigned long)vaddr & 3) - signal = SIGBUS; - else if (get_user(value, vaddr)) - signal = SIGSEGV; - else { - if (ll_task == NULL || ll_task == current) { - ll_bit = 1; - } else { - ll_bit = 0; - } - ll_task = current; - regp->regs[(opcode & RT) >> 16] = value; - } - if (compute_return_epc(regp)) - return; - if (signal) - send_sig(signal, current, 1); -} - -static inline void simulate_sc(struct pt_regs *regp, unsigned int opcode) -{ - unsigned long *vaddr, reg; - long offset; - int signal = 0; - - /* - * analyse the sc instruction that just caused a ri exception - * and put the referenced address to addr. - */ - - /* sign extend offset */ - offset = opcode & OFFSET; - offset <<= 16; - offset >>= 16; - - vaddr = (unsigned long *)((long)(regp->regs[(opcode & BASE) >> 21]) + offset); - reg = (opcode & RT) >> 16; - -#ifdef CONFIG_PROC_FS - sc_ops++; -#endif - - if ((unsigned long)vaddr & 3) - signal = SIGBUS; - else if (ll_bit == 0 || ll_task != current) - regp->regs[reg] = 0; - else if (put_user(regp->regs[reg], vaddr)) - signal = SIGSEGV; - else - regp->regs[reg] = 1; - if (compute_return_epc(regp)) - return; - if (signal) - send_sig(signal, current, 1); -} - -/* * If the address is either in the .text section of the * kernel, or in the vmalloc'ed module regions, it *may* * be the address of a calling routine @@ -320,7 +211,7 @@ } } -void show_regs(struct pt_regs * regs) +void show_regs(struct pt_regs *regs) { /* * Saved main processor registers @@ -330,10 +221,10 @@ regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11], - regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]); + regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]); printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19], - regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]); + regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]); printk("$24: %08lx %08lx %08lx %08lx %08lx %08lx\n", regs->regs[24], regs->regs[25], regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]); @@ -433,7 +324,7 @@ spin_lock_irqsave(&modlist_lock, flags); for (mp = module_list; mp != NULL; mp = mp->next) { if (!mod_member_present(mp, archdata_end) || - !mod_archdata_member_present(mp, struct archdata, + !mod_archdata_member_present(mp, struct archdata, dbe_table_end)) continue; ap = (struct archdata *)(mp->archdata_start); @@ -464,8 +355,8 @@ if (fixup) action = MIPS_BE_FIXUP; - if (be_board_handler) - action = be_board_handler(regs, fixup != 0); + if (board_be_handler) + action = board_be_handler(regs, fixup != 0); switch (action) { case MIPS_BE_DISCARD: @@ -492,12 +383,151 @@ force_sig(SIGBUS, current); } -asmlinkage void do_ov(struct pt_regs *regs) +static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode) { - siginfo_t info; + unsigned int *epc; + + epc = (unsigned int *) regs->cp0_epc + + ((regs->cp0_cause & CAUSEF_BD) != 0); + if (!get_user(*opcode, epc)) + return 0; + + force_sig(SIGSEGV, current); + return 1; +} + +/* + * ll/sc emulation + */ + +#define OPCODE 0xfc000000 +#define BASE 0x03e00000 +#define RT 0x001f0000 +#define OFFSET 0x0000ffff +#define LL 0xc0000000 +#define SC 0xe0000000 + +/* + * The ll_bit is cleared by r*_switch.S + */ + +unsigned long ll_bit; - if (compute_return_epc(regs)) +static struct task_struct *ll_task = NULL; + +static inline void simulate_ll(struct pt_regs *regs, unsigned int opcode) +{ + unsigned long value, *vaddr; + long offset; + int signal = 0; + + /* + * analyse the ll instruction that just caused a ri exception + * and put the referenced address to addr. + */ + + /* sign extend offset */ + offset = opcode & OFFSET; + offset <<= 16; + offset >>= 16; + + vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset); + + if ((unsigned long)vaddr & 3) { + signal = SIGBUS; + goto sig; + } + if (get_user(value, vaddr)) { + signal = SIGSEGV; + goto sig; + } + + if (ll_task == NULL || ll_task == current) { + ll_bit = 1; + } else { + ll_bit = 0; + } + ll_task = current; + + regs->regs[(opcode & RT) >> 16] = value; + + compute_return_epc(regs); + return; + +sig: + force_sig(signal, current); +} + +static inline void simulate_sc(struct pt_regs *regs, unsigned int opcode) +{ + unsigned long *vaddr, reg; + long offset; + int signal = 0; + + /* + * analyse the sc instruction that just caused a ri exception + * and put the referenced address to addr. + */ + + /* sign extend offset */ + offset = opcode & OFFSET; + offset <<= 16; + offset >>= 16; + + vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset); + reg = (opcode & RT) >> 16; + + if ((unsigned long)vaddr & 3) { + signal = SIGBUS; + goto sig; + } + if (ll_bit == 0 || ll_task != current) { + regs->regs[reg] = 0; + compute_return_epc(regs); return; + } + + if (put_user(regs->regs[reg], vaddr)) { + signal = SIGSEGV; + goto sig; + } + + regs->regs[reg] = 1; + + compute_return_epc(regs); + return; + +sig: + force_sig(signal, current); +} + +/* + * ll uses the opcode of lwc0 and sc uses the opcode of swc0. That is both + * opcodes are supposed to result in coprocessor unusable exceptions if + * executed on ll/sc-less processors. That's the theory. In practice a + * few processors such as NEC's VR4100 throw reserved instruction exceptions + * instead, so we're doing the emulation thing in both exception handlers. + */ +static inline int simulate_llsc(struct pt_regs *regs) +{ + unsigned int opcode; + + if (unlikely(get_insn_opcode(regs, &opcode))) + return -EFAULT; + + if ((opcode & OPCODE) == LL) { + simulate_ll(regs, opcode); + return 0; + } + if ((opcode & OPCODE) == SC) { + simulate_sc(regs, opcode); + return 0; + } +} + +asmlinkage void do_ov(struct pt_regs *regs) +{ + siginfo_t info; info.si_code = FPE_INTOVF; info.si_signo = SIGFPE; @@ -541,36 +571,14 @@ /* If something went wrong, signal */ if (sig) - { - /* - * Return EPC is not calculated in the FPU emulator, - * if a signal is being send. So we calculate it here. - */ - compute_return_epc(regs); force_sig(sig, current); - } return; } - if (compute_return_epc(regs)) - return; force_sig(SIGFPE, current); } -static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode) -{ - unsigned long *epc; - - epc = (unsigned long *) regs->cp0_epc + - ((regs->cp0_cause & CAUSEF_BD) != 0); - if (!get_user(*opcode, epc)) - return 0; - - force_sig(SIGSEGV, current); - return 1; -} - asmlinkage void do_bp(struct pt_regs *regs) { unsigned int opcode, bcode; @@ -611,8 +619,8 @@ asmlinkage void do_tr(struct pt_regs *regs) { - siginfo_t info; unsigned int opcode, tcode = 0; + siginfo_t info; if (get_insn_opcode(regs, &opcode)) return; @@ -644,109 +652,67 @@ } } -/* - * userland emulation for R2300 CPUs - * needed for the multithreading part of glibc - * - * this implementation can handle only sychronization between 2 or more - * user contexts and is not SMP safe. - */ asmlinkage void do_ri(struct pt_regs *regs) { die_if_kernel("Reserved instruction in kernel code", regs); -#ifndef CONFIG_CPU_HAS_LLSC - -#ifdef CONFIG_SMP -#error "ll/sc emulation is not SMP safe" -#endif - - { - unsigned int opcode; - - if (!get_insn_opcode(regs, &opcode)) { - if ((opcode & OPCODE) == LL) { - simulate_ll(regs, opcode); - return; - } - if ((opcode & OPCODE) == SC) { - simulate_sc(regs, opcode); + if (!cpu_has_llsc) + if (!simulate_llsc(regs)) return; - } - } - } -#endif /* CONFIG_CPU_HAS_LLSC */ - if (compute_return_epc(regs)) - return; force_sig(SIGILL, current); } asmlinkage void do_cpu(struct pt_regs *regs) { unsigned int cpid; - void fpu_emulator_init_fpu(void); - int sig; - - cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; - if (cpid != 1) - goto bad_cid; - if (!(mips_cpu.options & MIPS_CPU_FPU)) - goto fp_emul; + die_if_kernel("do_cpu invoked from kernel context!", regs); - regs->cp0_status |= ST0_CU1; - if (last_task_used_math == current) - return; + cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; - if (current->used_math) { /* Using the FPU again. */ - lazy_fpu_switch(last_task_used_math); - } else { /* First time FPU user. */ - if (last_task_used_math != NULL) - save_fp(last_task_used_math); - init_fpu(); - current->used_math = 1; - } - last_task_used_math = current; + switch (cpid) { + case 0: + if (cpu_has_llsc) + break; - return; + if (!simulate_llsc(regs)) + return; + break; -fp_emul: - if (last_task_used_math != current) { - if (!current->used_math) { - fpu_emulator_init_fpu(); + case 1: + own_fpu(); + if (current->used_math) { /* Using the FPU again. */ + restore_fp(current); + } else { /* First time FPU user. */ + init_fpu(); current->used_math = 1; } - } - sig = fpu_emulator_cop1Handler(0, regs, ¤t->thread.fpu.soft); - last_task_used_math = current; - if (sig) { - /* - * Return EPC is not calculated in the FPU emulator, if - * a signal is being send. So we calculate it here. - */ - compute_return_epc(regs); - force_sig(sig, current); - } - return; -bad_cid: -#ifndef CONFIG_CPU_HAS_LLSC - switch (mips_cpu.cputype) { - case CPU_TX3927: - case CPU_TX39XX: - do_ri(regs); + if (!cpu_has_fpu) { + int sig = fpu_emulator_cop1Handler(0, regs, + ¤t->thread.fpu.soft); + if (sig) + force_sig(sig, current); + } + return; + + case 2: + case 3: + break; } -#endif - compute_return_epc(regs); + force_sig(SIGILL, current); } -asmlinkage void do_watch(struct pt_regs *regs) +asmlinkage void do_mdmx(struct pt_regs *regs) { - extern void dump_tlb_all(void); + force_sig(SIGILL, current); +} +asmlinkage void do_watch(struct pt_regs *regs) +{ /* * We use the watch exception where available to detect stack * overflows. @@ -777,15 +743,8 @@ * hard/software error. */ show_regs(regs); - panic("Caught reserved exception - should not happen."); -} - -static inline void watch_init(void) -{ - if (mips_cpu.options & MIPS_CPU_WATCH ) { - set_except_vector(23, handle_watch); - watch_available = 1; - } + panic("Caught reserved exception %ld - should not happen.", + (regs->cp0_cause & 0x7f) >> 2); } /* @@ -794,14 +753,12 @@ */ static inline void parity_protection_init(void) { - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_5KC: - /* Set the PE bit (bit 31) in the CP0_ECC register. */ + /* Set the PE bit (bit 31) in the c0_ecc register. */ printk(KERN_INFO "Enable the cache parity protection for " "MIPS 5KC CPUs.\n"); - write_32bit_cp0_register(CP0_ECC, - read_32bit_cp0_register(CP0_ECC) - | 0x80000000); + write_c0_ecc(read_c0_ecc() | 0x80000000); break; default: break; @@ -813,13 +770,12 @@ unsigned int reg_val; /* For the moment, report the problem and hang. */ - reg_val = read_32bit_cp0_register(CP0_ERROREPC); printk("Cache error exception:\n"); - printk("cp0_errorepc == %08x\n", reg_val); - reg_val = read_32bit_cp0_register(CP0_CACHEERR); - printk("cp0_cacheerr == %08x\n", reg_val); + printk("cp0_errorepc == %08lx\n", read_c0_errorepc()); + reg_val = read_c0_cacheerr(); + printk("c0_cacheerr == %08x\n", reg_val); - printk("Decoded CP0_CACHEERR: %s cache fault in %s reference.\n", + printk("Decoded c0_cacheerr: %s cache fault in %s reference.\n", reg_val & (1<<30) ? "secondary" : "primary", reg_val & (1<<31) ? "data" : "insn"); printk("Error bits: %s%s%s%s%s%s%s\n", @@ -832,13 +788,13 @@ reg_val & (1<<22) ? "E0 " : ""); printk("IDX: 0x%08x\n", reg_val & ((1<<22)-1)); - if (reg_val&(1<<22)) - printk("DErrAddr0: 0x%08x\n", - read_32bit_cp0_set1_register(CP0_S1_DERRADDR0)); - - if (reg_val&(1<<23)) - printk("DErrAddr1: 0x%08x\n", - read_32bit_cp0_set1_register(CP0_S1_DERRADDR1)); +#if defined(CONFIG_CPU_MIPS32) || defined (CONFIG_CPU_MIPS64) + if (reg_val & (1<<22)) + printk("DErrAddr0: 0x%08lx\n", read_c0_derraddr0()); + + if (reg_val & (1<<23)) + printk("DErrAddr1: 0x%08lx\n", read_c0_derraddr1()); +#endif panic("Can't handle the cache error!"); } @@ -849,31 +805,32 @@ */ void ejtag_exception_handler(struct pt_regs *regs) { - unsigned int depc, old_epc, debug; + unsigned long depc, old_epc; + unsigned int debug; - printk("SDBBP EJTAG debug exception - not handled yet, just ignored!\n"); - depc = read_32bit_cp0_register(CP0_DEPC); - debug = read_32bit_cp0_register(CP0_DEBUG); - printk("DEPC = %08x, DEBUG = %08x\n", depc, debug); - if (debug & 0x80000000) { - /* - * In branch delay slot. - * We cheat a little bit here and use EPC to calculate the - * debug return address (DEPC). EPC is restored after the - * calculation. - */ - old_epc = regs->cp0_epc; - regs->cp0_epc = depc; - __compute_return_epc(regs); - depc = regs->cp0_epc; - regs->cp0_epc = old_epc; - } else - depc += 4; - write_32bit_cp0_register(CP0_DEPC, depc); + printk("SDBBP EJTAG debug exception - not handled yet, just ignored!\n"); + depc = read_c0_depc(); + debug = read_c0_debug(); + printk("c0_depc = %08lx, DEBUG = %08x\n", depc, debug); + if (debug & 0x80000000) { + /* + * In branch delay slot. + * We cheat a little bit here and use EPC to calculate the + * debug return address (DEPC). EPC is restored after the + * calculation. + */ + old_epc = regs->cp0_epc; + regs->cp0_epc = depc; + __compute_return_epc(regs); + depc = regs->cp0_epc; + regs->cp0_epc = old_epc; + } else + depc += 4; + write_c0_depc(depc); #if 0 printk("\n\n----- Enable EJTAG single stepping ----\n\n"); - write_32bit_cp0_register(CP0_DEBUG, debug | 0x100); + write_c0_debug(debug | 0x100); #endif } @@ -882,9 +839,9 @@ */ void nmi_exception_handler(struct pt_regs *regs) { - printk("NMI taken!!!!\n"); - die("NMI", regs); - while(1) ; /* We die here. */ + printk("NMI taken!!!!\n"); + die("NMI", regs); + while(1) ; } unsigned long exception_handlers[32]; @@ -900,7 +857,7 @@ unsigned long old_handler = exception_handlers[n]; exception_handlers[n] = handler; - if (n == 0 && mips_cpu.options & MIPS_CPU_DIVEC) { + if (n == 0 && cpu_has_divec) { *(volatile u32 *)(KSEG0+0x200) = 0x08000000 | (0x03ffffff & (handler >> 2)); flush_icache_range(KSEG0+0x200, KSEG0 + 0x204); @@ -910,6 +867,7 @@ asmlinkage int (*save_fp_context)(struct sigcontext *sc); asmlinkage int (*restore_fp_context)(struct sigcontext *sc); + extern asmlinkage int _save_fp_context(struct sigcontext *sc); extern asmlinkage int _restore_fp_context(struct sigcontext *sc); @@ -921,33 +879,40 @@ unsigned int cpu = smp_processor_id(); /* Some firmware leaves the BEV flag set, clear it. */ - clear_cp0_status(ST0_BEV); + clear_c0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_BEV); + + if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV) + set_c0_status(ST0_XX); /* * Some MIPS CPUs have a dedicated interrupt vector which reduces the * interrupt processing overhead. Use it where available. */ - if (mips_cpu.options & MIPS_CPU_DIVEC) - set_cp0_cause(CAUSEF_IV); + if (cpu_has_divec) + set_c0_cause(CAUSEF_IV); cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; - set_context(cpu << 23); + write_c0_context(cpu << 23); + + atomic_inc(&init_mm.mm_count); + current->active_mm = &init_mm; + if (current->mm) + BUG(); + enter_lazy_tlb(&init_mm, current, cpu); } void __init trap_init(void) { - extern char except_vec1_generic, except_vec2_generic; + extern char except_vec1_generic; extern char except_vec3_generic, except_vec3_r4000; - extern char except_vec4; extern char except_vec_ejtag_debug; + extern char except_vec4; unsigned long i; per_cpu_trap_init(); /* Copy the generic exception handler code to it's final destination. */ memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80); - memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80); - memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80); /* * Setup default vectors @@ -959,23 +924,22 @@ * Copy the EJTAG debug exception vector handler code to it's final * destination. */ - if (mips_cpu.options & MIPS_CPU_EJTAG) + if (cpu_has_ejtag) memcpy((void *)(KSEG0 + 0x300), &except_vec_ejtag_debug, 0x80); /* * Only some CPUs have the watch exceptions or a dedicated * interrupt vector. */ - watch_init(); + if (cpu_has_watch) + set_except_vector(23, handle_watch); /* * Some MIPS CPUs have a dedicated interrupt vector which reduces the * interrupt processing overhead. Use it where available. */ - if (mips_cpu.options & MIPS_CPU_DIVEC) { + if (cpu_has_divec) memcpy((void *)(KSEG0 + 0x200), &except_vec4, 8); - set_cp0_cause(CAUSEF_IV); - } /* * Some CPUs can enable/disable for cache parity detection, but does @@ -988,7 +952,8 @@ * by external hardware. Therefore these two exceptions * may have board specific handlers. */ - bus_error_init(); + if (board_be_init) + board_be_init(); set_except_vector(1, handle_mod); set_except_vector(2, handle_tlbl); @@ -1005,46 +970,23 @@ set_except_vector(11, handle_cpu); set_except_vector(12, handle_ov); set_except_vector(13, handle_tr); + set_except_vector(22, handle_mdmx); - if ((mips_cpu.options & MIPS_CPU_FPU) && - !(mips_cpu.options & MIPS_CPU_NOFPUEX)) + if (cpu_has_fpu && !cpu_has_nofpuex) set_except_vector(15, handle_fpe); - if (mips_cpu.options & MIPS_CPU_MCHECK) + + if (cpu_has_mcheck) set_except_vector(24, handle_mcheck); - /* - * Handling the following exceptions depends mostly of the cpu type - */ - if ((mips_cpu.options & MIPS_CPU_4KEX) - && (mips_cpu.options & MIPS_CPU_4KTLB)) { - /* Cache error vector already set above. */ - - if (mips_cpu.options & MIPS_CPU_VCE) { - memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, - 0x80); - } - } else switch (mips_cpu.cputype) { - case CPU_SB1: - /* - * XXX - This should be folded in to the "cleaner" handling, - * above - */ + if (cpu_has_vce) memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, 0x80); -#ifdef CONFIG_SB1_CACHE_ERROR - { - /* Special cache error handler for SB1 */ - extern char except_vec2_sb1; - memcpy((void *)(KSEG0 + 0x100), &except_vec2_sb1, 0x80); - memcpy((void *)(KSEG1 + 0x100), &except_vec2_sb1, 0x80); - } -#endif + else if (cpu_has_4kex) + memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80); + else + memcpy((void *)(KSEG0 + 0x080), &except_vec3_generic, 0x80); - /* Enable timer interrupt and scd mapped interrupt */ - clear_cp0_status(0xf000); - set_cp0_status(0xc00); - break; - case CPU_R6000: - case CPU_R6000A: + if (current_cpu_data.cputype == CPU_R6000 || + current_cpu_data.cputype == CPU_R6000A) { /* * The R6000 is the only R-series CPU that features a machine * check exception (similar to the R4000 cache error) and @@ -1055,29 +997,9 @@ */ //set_except_vector(14, handle_mc); //set_except_vector(15, handle_ndc); - case CPU_R2000: - case CPU_R3000: - case CPU_R3000A: - case CPU_R3041: - case CPU_R3051: - case CPU_R3052: - case CPU_R3081: - case CPU_R3081E: - case CPU_TX3912: - case CPU_TX3922: - case CPU_TX3927: - case CPU_TX39XX: - memcpy((void *)(KSEG0 + 0x80), &except_vec3_generic, 0x80); - break; - - case CPU_UNKNOWN: - default: - panic("Unknown CPU type"); } - flush_icache_range(KSEG0, KSEG0 + 0x400); - - if (mips_cpu.options & MIPS_CPU_FPU) { + if (cpu_has_fpu) { save_fp_context = _save_fp_context; restore_fp_context = _restore_fp_context; } else { @@ -1085,10 +1007,9 @@ restore_fp_context = fpu_emulator_restore_context; } - if (mips_cpu.isa_level == MIPS_CPU_ISA_IV) - set_cp0_status(ST0_XX); + flush_icache_range(KSEG0, KSEG0 + 0x400); - atomic_inc(&init_mm.mm_count); /* XXX UP? */ + atomic_inc(&init_mm.mm_count); /* XXX UP? */ current->active_mm = &init_mm; /* XXX Must be done for all CPUs */ diff -urN linux-2.4.21-bk37/arch/mips/kernel/unaligned.c linux-2.4.21-bk38/arch/mips/kernel/unaligned.c --- linux-2.4.21-bk37/arch/mips/kernel/unaligned.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/kernel/unaligned.c 2003-08-24 02:55:57.000000000 -0700 @@ -5,7 +5,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996, 1998, 2002 by Ralf Baechle + * Copyright (C) 1996, 1998, 1999, 2002 by Ralf Baechle * Copyright (C) 1999 Silicon Graphics, Inc. * * This file contains exception handler for address error exception with the @@ -88,22 +88,21 @@ #define STR(x) __STR(x) #define __STR(x) #x -/* - * User code may only access USEG; kernel code may access the - * entire address space. - */ -#define check_axs(pc,a,s) \ - if ((long)(~(pc) & ((a) | ((a)+(s)))) < 0) \ - goto sigbus; +#ifdef CONFIG_PROC_FS +unsigned long unaligned_instructions; +#endif static inline int emulate_load_store_insn(struct pt_regs *regs, - unsigned long addr, unsigned long pc) + void *addr, unsigned long pc, + unsigned long **regptr, unsigned long *newvalue) { union mips_instruction insn; unsigned long value, fixup; unsigned int res; regs->regs[0] = 0; + *regptr=NULL; + /* * This load never faults. */ @@ -143,8 +142,10 @@ * The remaining opcodes are the ones that are really of interest. */ case lh_op: - check_axs(pc, addr, 2); - __asm__(".set\tnoat\n" + if (verify_area(VERIFY_READ, addr, 2)) + goto sigbus; + + __asm__ __volatile__ (".set\tnoat\n" #ifdef __BIG_ENDIAN "1:\tlb\t%0, 0(%2)\n" "2:\tlbu\t$1, 1(%2)\n\t" @@ -169,12 +170,15 @@ : "r" (addr), "i" (-EFAULT)); if (res) goto fault; - regs->regs[insn.i_format.rt] = value; - return 0; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; case lw_op: - check_axs(pc, addr, 4); - __asm__( + if (verify_area(VERIFY_READ, addr, 4)) + goto sigbus; + + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN "1:\tlwl\t%0, (%2)\n" "2:\tlwr\t%0, 3(%2)\n\t" @@ -196,12 +200,15 @@ : "r" (addr), "i" (-EFAULT)); if (res) goto fault; - regs->regs[insn.i_format.rt] = value; - return 0; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; case lhu_op: - check_axs(pc, addr, 2); - __asm__( + if (verify_area(VERIFY_READ, addr, 2)) + goto sigbus; + + __asm__ __volatile__ ( ".set\tnoat\n" #ifdef __BIG_ENDIAN "1:\tlbu\t%0, 0(%2)\n" @@ -227,18 +234,102 @@ : "r" (addr), "i" (-EFAULT)); if (res) goto fault; - regs->regs[insn.i_format.rt] = value; - return 0; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; case lwu_op: +#ifdef CONFIG_MIPS64 + /* + * A 32-bit kernel might be running on a 64-bit processor. But + * if we're on a 32-bit processor and an i-cache incoherency + * or race makes us see a 64-bit instruction here the sdl/sdr + * would blow up, so for now we don't handle unaligned 64-bit + * instructions on 32-bit kernels. + */ + if (verify_area(VERIFY_READ, addr, 4)) + goto sigbus; + + __asm__ __volatile__ ( +#ifdef __BIG_ENDIAN + "1:\tlwl\t%0, (%2)\n" + "2:\tlwr\t%0, 3(%2)\n\t" +#endif +#ifdef __LITTLE_ENDIAN + "1:\tlwl\t%0, 3(%2)\n" + "2:\tlwr\t%0, (%2)\n\t" +#endif + "dsll\t%0, %0, 32\n\t" + "dsrl\t%0, %0, 32\n\t" + "li\t%1, 0\n" + "3:\t.section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" + ".section\t__ex_table,\"a\"\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" + ".previous" + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; +#endif /* CONFIG_MIPS64 */ + + /* Cannot handle 64-bit instructions in 32-bit kernel */ + goto sigill; + case ld_op: +#ifdef CONFIG_MIPS64 + /* + * A 32-bit kernel might be running on a 64-bit processor. But + * if we're on a 32-bit processor and an i-cache incoherency + * or race makes us see a 64-bit instruction here the sdl/sdr + * would blow up, so for now we don't handle unaligned 64-bit + * instructions on 32-bit kernels. + */ + if (verify_area(VERIFY_READ, addr, 8)) + goto sigbus; + + __asm__ __volatile__ ( +#ifdef __BIG_ENDIAN + "1:\tldl\t%0, (%2)\n" + "2:\tldr\t%0, 7(%2)\n\t" +#endif +#ifdef __LITTLE_ENDIAN + "1:\tldl\t%0, 7(%2)\n" + "2:\tldr\t%0, (%2)\n\t" +#endif + "li\t%1, 0\n" + "3:\t.section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" + ".section\t__ex_table,\"a\"\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" + ".previous" + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; +#endif /* CONFIG_MIPS64 */ + /* Cannot handle 64-bit instructions in 32-bit kernel */ goto sigill; case sh_op: - check_axs(pc, addr, 2); + if (verify_area(VERIFY_WRITE, addr, 2)) + goto sigbus; + value = regs->regs[insn.i_format.rt]; - __asm__( + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN ".set\tnoat\n" "1:\tsb\t%1, 1(%2)\n\t" @@ -267,12 +358,14 @@ : "r" (value), "r" (addr), "i" (-EFAULT)); if (res) goto fault; - return 0; + break; case sw_op: - check_axs(pc, addr, 4); + if (verify_area(VERIFY_WRITE, addr, 4)) + goto sigbus; + value = regs->regs[insn.i_format.rt]; - __asm__( + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN "1:\tswl\t%1,(%2)\n" "2:\tswr\t%1, 3(%2)\n\t" @@ -295,9 +388,47 @@ : "r" (value), "r" (addr), "i" (-EFAULT)); if (res) goto fault; - return 0; + break; case sd_op: +#ifdef CONFIG_MIPS64 + /* + * A 32-bit kernel might be running on a 64-bit processor. But + * if we're on a 32-bit processor and an i-cache incoherency + * or race makes us see a 64-bit instruction here the sdl/sdr + * would blow up, so for now we don't handle unaligned 64-bit + * instructions on 32-bit kernels. + */ + if (verify_area(VERIFY_WRITE, addr, 8)) + goto sigbus; + + value = regs->regs[insn.i_format.rt]; + __asm__ __volatile__ ( +#ifdef __BIG_ENDIAN + "1:\tsdl\t%1,(%2)\n" + "2:\tsdr\t%1, 7(%2)\n\t" +#endif +#ifdef __LITTLE_ENDIAN + "1:\tsdl\t%1, 7(%2)\n" + "2:\tsdr\t%1, (%2)\n\t" +#endif + "li\t%0, 0\n" + "3:\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%0, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" + ".section\t__ex_table,\"a\"\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" + ".previous" + : "=r" (res) + : "r" (value), "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + break; +#endif /* CONFIG_MIPS64 */ + /* Cannot handle 64-bit instructions in 32-bit kernel */ goto sigill; @@ -328,6 +459,11 @@ */ goto sigill; } + +#ifdef CONFIG_PROC_FS + unaligned_instructions++; +#endif + return 0; fault: @@ -356,23 +492,21 @@ sigill: die_if_kernel("Unhandled kernel unaligned access or invalid instruction", regs); send_sig(SIGILL, current, 1); + return 0; } -#ifdef CONFIG_PROC_FS -unsigned long unaligned_instructions; -#endif - asmlinkage void do_ade(struct pt_regs *regs) { - unsigned long pc; + unsigned long *regptr, newval; extern int do_dsemulret(struct pt_regs *); + mm_segment_t seg; + unsigned long pc; /* - * Address errors may be deliberately induced - * by the FPU emulator to take retake control - * of the CPU after executing the instruction - * in the delay slot of an emulated branch. + * Address errors may be deliberately induced by the FPU emulator to + * retake control of the CPU after executing the instruction in the + * delay slot of an emulated branch. */ /* Terminate if exception was recognized as a delay slot return */ if (do_dsemulret(regs)) @@ -382,13 +516,12 @@ /* * Did we catch a fault trying to load an instruction? - * This also catches attempts to activate MIPS16 code on - * CPUs which don't support it. + * Or are we running in MIPS16 mode? */ - if (regs->cp0_badvaddr == regs->cp0_epc) + if ((regs->cp0_badvaddr == regs->cp0_epc) || (regs->cp0_epc & 0x1)) goto sigbus; - pc = regs->cp0_epc + ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0); + pc = exception_epc(regs); if ((current->thread.mflags & MF_FIXADE) == 0) goto sigbus; @@ -396,12 +529,20 @@ * Do branch emulation only if we didn't forward the exception. * This is all so but ugly ... */ - if (!emulate_load_store_insn(regs, regs->cp0_badvaddr, pc)) + seg = get_fs(); + if (!user_mode(regs)) + set_fs(KERNEL_DS); + if (!emulate_load_store_insn(regs, (void *)regs->cp0_badvaddr, pc, + ®ptr, &newval)) { compute_return_epc(regs); - -#ifdef CONFIG_PROC_FS - unaligned_instructions++; -#endif + /* + * Now that branch is evaluated, update the dest + * register if necessary + */ + if (regptr) + *regptr = newval; + } + set_fs(seg); return; @@ -412,6 +553,4 @@ /* * XXX On return from the signal handler we should advance the epc */ - - return; } diff -urN linux-2.4.21-bk37/arch/mips/kernel/vm86.c linux-2.4.21-bk38/arch/mips/kernel/vm86.c --- linux-2.4.21-bk37/arch/mips/kernel/vm86.c 1997-06-26 12:33:37.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/kernel/vm86.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,13 +0,0 @@ -/* - * arch/mips/vm86.c - * - * Copyright (C) 1994 Waldorf GMBH, - * written by Ralf Baechle - */ -#include -#include - -asmlinkage int sys_vm86(void *v86) -{ - return -ENOSYS; -} diff -urN linux-2.4.21-bk37/arch/mips/lasat/Makefile linux-2.4.21-bk38/arch/mips/lasat/Makefile --- linux-2.4.21-bk37/arch/mips/lasat/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,22 @@ +# +# Makefile for the LASAT specific kernel interface routines under Linux. +# +USE_STANDARD_AS_RULE := 1 + +O_TARGET := lasatkern.o +obj-y := reset.o setup.o prom.o lasat_board.o \ + crc32.o at93c.o interrupt.o lasatIRQ.o + +obj-$(CONFIG_LASAT_SYSCTL) += sysctl.o + +obj-$(CONFIG_DS1603) += ds1603.o + +obj-$(CONFIG_PICVUE) += picvue.o +obj-$(CONFIG_PICVUE_PROC) += picvue_proc.o + +obj-$(CONFIG_PCI) += pci.o + +include $(TOPDIR)/Rules.make + +clean: + make -C image clean diff -urN linux-2.4.21-bk37/arch/mips/lasat/at93c.c linux-2.4.21-bk38/arch/mips/lasat/at93c.c --- linux-2.4.21-bk37/arch/mips/lasat/at93c.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/at93c.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,148 @@ +/* + * Atmel AT93C46 serial eeprom driver + * + * Brian Murphy + * + */ +#include +#include +#include +#include +#include + +#include "at93c.h" + +#define AT93C_ADDR_SHIFT 7 +#define AT93C_ADDR_MAX ((1 << AT93C_ADDR_SHIFT) - 1) +#define AT93C_RCMD (0x6 << AT93C_ADDR_SHIFT) +#define AT93C_WCMD (0x5 << AT93C_ADDR_SHIFT) +#define AT93C_WENCMD 0x260 +#define AT93C_WDSCMD 0x200 + +struct at93c_defs *at93c; + +static void at93c_reg_write(u32 val) +{ + *at93c->reg = val; +} + +static u32 at93c_reg_read(void) +{ + u32 tmp = *at93c->reg; + return tmp; +} + +static u32 at93c_datareg_read(void) +{ + u32 tmp = *at93c->rdata_reg; + return tmp; +} + +static void at93c_cycle_clk(u32 data) +{ + at93c_reg_write(data | at93c->clk); + lasat_ndelay(250); + at93c_reg_write(data & ~at93c->clk); + lasat_ndelay(250); +} + +static void at93c_write_databit(u8 bit) +{ + u32 data = at93c_reg_read(); + if (bit) + data |= 1 << at93c->wdata_shift; + else + data &= ~(1 << at93c->wdata_shift); + + at93c_reg_write(data); + lasat_ndelay(100); + at93c_cycle_clk(data); +} + +static unsigned int at93c_read_databit(void) +{ + u32 data; + + at93c_cycle_clk(at93c_reg_read()); + data = (at93c_datareg_read() >> at93c->rdata_shift) & 1; + return data; +} + +static u8 at93c_read_byte(void) +{ + int i; + u8 data = 0; + + for (i = 0; i<=7; i++) { + data <<= 1; + data |= at93c_read_databit(); + } + return data; +} + +static void at93c_write_bits(u32 data, int size) +{ + int i; + int shift = size - 1; + u32 mask = (1 << shift); + + for (i = 0; i < size; i++) { + at93c_write_databit((data & mask) >> shift); + data <<= 1; + } +} + +static void at93c_init_op(void) +{ + at93c_reg_write((at93c_reg_read() | at93c->cs) & ~at93c->clk & ~(1 << at93c->rdata_shift)); + lasat_ndelay(50); +} + +static void at93c_end_op(void) +{ + at93c_reg_write(at93c_reg_read() & ~at93c->cs); + lasat_ndelay(250); +} + +static void at93c_wait(void) +{ + at93c_init_op(); + while (!at93c_read_databit()) + ; + at93c_end_op(); +}; + +static void at93c_disable_wp(void) +{ + at93c_init_op(); + at93c_write_bits(AT93C_WENCMD, 10); + at93c_end_op(); +} + +static void at93c_enable_wp(void) +{ + at93c_init_op(); + at93c_write_bits(AT93C_WDSCMD, 10); + at93c_end_op(); +} + +u8 at93c_read(u8 addr) +{ + u8 byte; + at93c_init_op(); + at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_RCMD, 10); + byte = at93c_read_byte(); + at93c_end_op(); + return byte; +} + +void at93c_write(u8 addr, u8 data) +{ + at93c_disable_wp(); + at93c_init_op(); + at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_WCMD, 10); + at93c_write_bits(data, 8); + at93c_end_op(); + at93c_wait(); + at93c_enable_wp(); +} diff -urN linux-2.4.21-bk37/arch/mips/lasat/at93c.h linux-2.4.21-bk38/arch/mips/lasat/at93c.h --- linux-2.4.21-bk37/arch/mips/lasat/at93c.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/at93c.h 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,18 @@ +/* + * Atmel AT93C46 serial eeprom driver + * + * Brian Murphy + * + */ + +extern struct at93c_defs { + volatile u32 *reg; + volatile u32 *rdata_reg; + int rdata_shift; + int wdata_shift; + u32 cs; + u32 clk; +} *at93c; + +u8 at93c_read(u8 addr); +void at93c_write(u8 addr, u8 data); diff -urN linux-2.4.21-bk37/arch/mips/lasat/crc32.c linux-2.4.21-bk38/arch/mips/lasat/crc32.c --- linux-2.4.21-bk37/arch/mips/lasat/crc32.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/crc32.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,87 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#undef DYNAMIC_CRC_TABLE + +#define local static + +/* ======================================================================== + * Table of CRC-32's of all single-byte values (made by make_crc_table) + */ +const unsigned long crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; +/* ========================================================================= */ +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); + +/* ========================================================================= */ +unsigned long crc32(unsigned long crc, const unsigned char * buf, unsigned int len) +{ + if (buf == 0) return 0L; + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + return crc ^ 0xffffffffL; +} diff -urN linux-2.4.21-bk37/arch/mips/lasat/ds1603.c linux-2.4.21-bk38/arch/mips/lasat/ds1603.c --- linux-2.4.21-bk37/arch/mips/lasat/ds1603.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/ds1603.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,174 @@ +/* + * Dallas Semiconductors 1603 RTC driver + * + * Brian Murphy + * + */ +#include +#include +#include +#include + +#include "ds1603.h" + +#define READ_TIME_CMD 0x81 +#define SET_TIME_CMD 0x80 +#define TRIMMER_SET_CMD 0xC0 +#define TRIMMER_VALUE_MASK 0x38 +#define TRIMMER_SHIFT 3 + +struct ds_defs *ds1603 = NULL; + +/* HW specific register functions */ +static void rtc_reg_write(unsigned long val) +{ + *ds1603->reg = val; +} + +static unsigned long rtc_reg_read(void) +{ + unsigned long tmp = *ds1603->reg; + return tmp; +} + +static unsigned long rtc_datareg_read(void) +{ + unsigned long tmp = *ds1603->data_reg; + return tmp; +} + +static void rtc_nrst_high(void) +{ + rtc_reg_write(rtc_reg_read() | ds1603->rst); +} + +static void rtc_nrst_low(void) +{ + rtc_reg_write(rtc_reg_read() & ~ds1603->rst); +} + +static void rtc_cycle_clock(unsigned long data) +{ + data |= ds1603->clk; + rtc_reg_write(data); + ndelay(250); + if (ds1603->data_reversed) + data &= ~ds1603->data; + else + data |= ds1603->data; + data &= ~ds1603->clk; + rtc_reg_write(data); + ndelay(250 + ds1603->huge_delay); +} + +static void rtc_write_databit(unsigned int bit) +{ + unsigned long data = rtc_reg_read(); + if (ds1603->data_reversed) + bit = !bit; + if (bit) + data |= ds1603->data; + else + data &= ~ds1603->data; + + rtc_reg_write(data); + ndelay(50 + ds1603->huge_delay); + rtc_cycle_clock(data); +} + +static unsigned int rtc_read_databit(void) +{ + unsigned int data; + + data = (rtc_datareg_read() & (1 << ds1603->data_read_shift)) + >> ds1603->data_read_shift; + rtc_cycle_clock(rtc_reg_read()); + return data; +} + +static void rtc_write_byte(unsigned int byte) +{ + int i; + + for (i = 0; i<=7; i++) { + rtc_write_databit(byte & 1L); + byte >>= 1; + } +} + +static void rtc_write_word(unsigned long word) +{ + int i; + + for (i = 0; i<=31; i++) { + rtc_write_databit(word & 1L); + word >>= 1; + } +} + +static unsigned long rtc_read_word(void) +{ + int i; + unsigned long word = 0; + unsigned long shift = 0; + + for (i = 0; i<=31; i++) { + word |= rtc_read_databit() << shift; + shift++; + } + return word; +} + +static void rtc_init_op(void) +{ + rtc_nrst_high(); + + rtc_reg_write(rtc_reg_read() & ~ds1603->clk); + + ndelay(50); +} + +static void rtc_end_op(void) +{ + rtc_nrst_low(); + ndelay(1000); +} + +/* interface */ +unsigned long ds1603_read(void) +{ + unsigned long word; + rtc_init_op(); + rtc_write_byte(READ_TIME_CMD); + word = rtc_read_word(); + rtc_end_op(); + return word; +} + +int ds1603_set(unsigned long time) +{ + rtc_init_op(); + rtc_write_byte(SET_TIME_CMD); + rtc_write_word(time); + rtc_end_op(); + + return 0; +} + +void ds1603_set_trimmer(unsigned int trimval) +{ + rtc_init_op(); + rtc_write_byte(((trimval << TRIMMER_SHIFT) & TRIMMER_VALUE_MASK) + | (TRIMMER_SET_CMD)); + rtc_end_op(); +} + +void ds1603_disable(void) +{ + ds1603_set_trimmer(TRIMMER_DISABLE_RTC); +} + +void ds1603_enable(void) +{ + ds1603_set_trimmer(TRIMMER_DEFAULT); +} diff -urN linux-2.4.21-bk37/arch/mips/lasat/ds1603.h linux-2.4.21-bk38/arch/mips/lasat/ds1603.h --- linux-2.4.21-bk37/arch/mips/lasat/ds1603.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/ds1603.h 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,33 @@ +/* + * Dallas Semiconductors 1603 RTC driver + * + * Brian Murphy + * + */ +#ifndef __DS1603_H +#define __DS1603_H + +struct ds_defs { + volatile u32 *reg; + volatile u32 *data_reg; + u32 rst; + u32 clk; + u32 data; + u32 data_read_shift; + char data_reversed; + u32 huge_delay; +}; + +extern struct ds_defs *ds1603; + +unsigned long ds1603_read(void); +int ds1603_set(unsigned long); +void ds1603_set_trimmer(unsigned int); +void ds1603_enable(void); +void ds1603_disable(void); +void ds1603_init(struct ds_defs *); + +#define TRIMMER_DEFAULT 3 +#define TRIMMER_DISABLE_RTC 0 + +#endif diff -urN linux-2.4.21-bk37/arch/mips/lasat/image/Makefile linux-2.4.21-bk38/arch/mips/lasat/image/Makefile --- linux-2.4.21-bk37/arch/mips/lasat/image/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/image/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,59 @@ +# +# MAKEFILE FOR THE MIPS LINUX BOOTLOADER AND ROM DEBUGGER +# +# i-data Networks +# +# Author: Thomas Horsten +# + +ifndef Version + Version = "$(USER)-test" +endif + +MKLASATIMG = mklasatimg +MKLASATIMG_ARCH = mq2,mqpro,sp100,sp200 +ifdef CONFIG_LASAT_SERVICE +MKLASATIMG_FLAG = -s +else +MKLASATIMG_FLAG = -k +endif + +KERNEL_IMAGE = $(TOPDIR)/vmlinux +KERNEL_START = $(shell $(NM) $(KERNEL_IMAGE) | grep _ftext | cut -f1 -d\ ) +KERNEL_ENTRY = $(shell $(NM) $(KERNEL_IMAGE) | grep kernel_entry | cut -f1 -d\ ) + +LDSCRIPT= -Tromscript.normal + +AFLAGS_head.o = -D_kernel_start=0x$(KERNEL_START) \ + -D_kernel_entry=0x$(KERNEL_ENTRY) \ + -D VERSION="\"$(Version)\"" \ + -D TIMESTAMP=$(shell date +%s) + +head.o: $(KERNEL_IMAGE) + +OBJECTS= head.o kImage.o + +rom.sw: rom.bin + $(MKLASATIMG) -o rom.sw $(MKLASATIMG_FLAG) rom.bin -m $(MKLASATIMG_ARCH) + +rom.bin: rom + $(OBJCOPY) -O binary -S rom rom.bin + +# Rule to make the bootloader +rom: $(OBJECTS) + $(LD) $(LDFLAGS) $(LDSCRIPT) -o rom $(OBJECTS) + +%.o: %.gz + $(LD) -r -o $@ -b binary $< + +%.gz: %.bin + gzip -cf -9 $< > $@ + +kImage.bin: $(KERNEL_IMAGE) + $(OBJCOPY) -O binary -S $(TOPDIR)/vmlinux kImage.bin + +clean: + rm -f rom rom.bin rom.sw kImage.bin + +USE_STANDARD_AS_RULE = 1 +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/lasat/image/head.S linux-2.4.21-bk38/arch/mips/lasat/image/head.S --- linux-2.4.21-bk37/arch/mips/lasat/image/head.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/image/head.S 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,31 @@ +#include + + .text + .section .text.start, "ax" + .set noreorder + .set mips3 + + /* Magic words identifying a software image */ + .word LASAT_K_MAGIC0_VAL + .word LASAT_K_MAGIC1_VAL + + /* Image header version */ + .word 0x00000002 + + /* image start and size */ + .word _image_start + .word _image_size + + /* start of kernel and entrypoint in uncompressed image */ + .word _kernel_start + .word _kernel_entry + + /* Here we have room for future flags */ + + .org 0x40 +reldate: + .word TIMESTAMP + + .org 0x50 +release: + .string VERSION diff -urN linux-2.4.21-bk37/arch/mips/lasat/image/romscript.normal linux-2.4.21-bk38/arch/mips/lasat/image/romscript.normal --- linux-2.4.21-bk37/arch/mips/lasat/image/romscript.normal 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/image/romscript.normal 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,22 @@ +OUTPUT_ARCH(mips) + +SECTIONS +{ + .text : + { + *(.text.start) + } + + /* Data in ROM */ + + .data ALIGN(0x10) : + { + *(.data) + } + _image_start = ADDR(.data); + _image_size = SIZEOF(.data); + + .other : { + *(.*) + } +} diff -urN linux-2.4.21-bk37/arch/mips/lasat/interrupt.c linux-2.4.21-bk38/arch/mips/lasat/interrupt.c --- linux-2.4.21-bk37/arch/mips/lasat/interrupt.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/interrupt.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,192 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Routines for generic manipulation of the interrupts found on the + * Lasat boards. + * + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static volatile int *lasat_int_status = NULL; +static volatile int *lasat_int_mask = NULL; +static volatile int lasat_int_mask_shift; + +extern asmlinkage void mipsIRQ(void); + +#if 0 +#define DEBUG_INT(x...) printk(x) +#else +#define DEBUG_INT(x...) +#endif + +void disable_lasat_irq(unsigned int irq_nr) +{ + unsigned long flags; + DEBUG_INT("disable_lasat_irq: %d", irq_nr); + + local_irq_save(flags); + *lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift; + local_irq_restore(flags); +} + +void enable_lasat_irq(unsigned int irq_nr) +{ + unsigned long flags; + DEBUG_INT("enable_lasat_irq: %d", irq_nr); + + local_irq_save(flags); + *lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift; + local_irq_restore(flags); +} + +static unsigned int startup_lasat_irq(unsigned int irq) +{ + enable_lasat_irq(irq); + return 0; /* never anything pending */ +} + +#define shutdown_lasat_irq disable_lasat_irq + +#define mask_and_ack_lasat_irq disable_lasat_irq + +static void end_lasat_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_lasat_irq(irq); +} + +static struct hw_interrupt_type lasat_irq_type = { + "Lasat", + startup_lasat_irq, + shutdown_lasat_irq, + enable_lasat_irq, + disable_lasat_irq, + mask_and_ack_lasat_irq, + end_lasat_irq, + NULL +}; + +static inline int ls1bit32(unsigned int x) +{ + int b = 31, s; + + s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s; + s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s; + s = 4; if (x << 4 == 0) s = 0; b -= s; x <<= s; + s = 2; if (x << 2 == 0) s = 0; b -= s; x <<= s; + s = 1; if (x << 1 == 0) s = 0; b -= s; + + return b; +} + +static unsigned long (* get_int_status)(void); + +static unsigned long get_int_status_100(void) +{ + return (*lasat_int_status & *lasat_int_mask); +} + +static unsigned long get_int_status_200(void) +{ + unsigned long int_status; + + int_status = *lasat_int_status; + int_status &= (int_status >> LASATINT_MASK_SHIFT_200) & 0xffff; + return int_status; +} + +void lasat_hw0_irqdispatch(struct pt_regs *regs) +{ + struct irqaction *action; + unsigned long int_status; + int irq, cpu = smp_processor_id(); + + int_status = get_int_status(); + + /* if int_status == 0, then the interrupt has already been cleared */ + if (int_status == 0) + return; + + irq = ls1bit32(int_status); + action = irq_desc[irq].action; + + DEBUG_INT("lasat_hw0_irqdispatch: irq=%d\n", irq); + + /* if action == NULL, then we don't have a handler for the irq */ + if (action == NULL) { + printk("No handler for hw0 irq: %i\n", irq); + atomic_inc(&irq_err_count); + return; + } + + irq_enter(cpu, irq); + kstat.irqs[0][irq]++; + action->handler(irq, action->dev_id, regs); + irq_exit(cpu, irq); + + return; +} + +void __init init_IRQ(void) +{ + int i; + + init_generic_irq(); + + switch (mips_machtype) { + case MACH_LASAT_100: + lasat_int_status = (void *)LASAT_INT_STATUS_REG_100; + lasat_int_mask = (void *)LASAT_INT_MASK_REG_100; + lasat_int_mask_shift = LASATINT_MASK_SHIFT_100; + get_int_status = get_int_status_100; + *lasat_int_mask = 0; + break; + case MACH_LASAT_200: + lasat_int_status = (void *)LASAT_INT_STATUS_REG_200; + lasat_int_mask = (void *)LASAT_INT_MASK_REG_200; + lasat_int_mask_shift = LASATINT_MASK_SHIFT_200; + get_int_status = get_int_status_200; + *lasat_int_mask &= 0xffff; + break; + default: + panic("init_IRQ: mips_machtype incorrect"); + } + + /* Now safe to set the exception vector. */ + set_except_vector(0, mipsIRQ); + + for (i = 0; i <= LASATINT_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &lasat_irq_type; + } +} diff -urN linux-2.4.21-bk37/arch/mips/lasat/lasatIRQ.S linux-2.4.21-bk38/arch/mips/lasat/lasatIRQ.S --- linux-2.4.21-bk37/arch/mips/lasat/lasatIRQ.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/lasatIRQ.S 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,75 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Interrupt exception dispatch code. + * + */ +#include + +#include +#include +#include +#include + + .text + .set noreorder + .set noat + .align 5 + NESTED(mipsIRQ, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + + mfc0 s0, CP0_CAUSE # get irq mask + + /* First we check for r4k counter/timer IRQ. */ + andi a0, s0, CAUSEF_IP7 + beq a0, zero, 1f + andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt + + /* Wheee, a timer interrupt. */ + move a0, sp + jal lasat_timer_interrupt + nop + + j ret_from_irq + nop + +1: + /* Wheee, combined hardware level zero interrupt. */ + jal lasat_hw0_irqdispatch + move a0, sp # delay slot + + j ret_from_irq + nop # delay slot + +1: + /* + * Here by mistake? This is possible, what can happen is that by the + * time we take the exception the IRQ pin goes low, so just leave if + * this is the case. + */ + move a1,s0 + mfc0 a1, CP0_EPC + + j ret_from_irq + nop + END(mipsIRQ) diff -urN linux-2.4.21-bk37/arch/mips/lasat/lasat_board.c linux-2.4.21-bk38/arch/mips/lasat/lasat_board.c --- linux-2.4.21-bk37/arch/mips/lasat/lasat_board.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/lasat_board.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,279 @@ +/* + * lasat_board.c + * + * Thomas Horsten + * Copyright (C) 2000 LASAT Networks A/S. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Routines specific to the LASAT boards + */ +#include +#include +#include +#include +#include +#include +#include +#include "at93c.h" +/* New model description table */ +#include "lasat_models.h" +struct lasat_info lasat_board_info; + +unsigned long crc32(unsigned long, unsigned char *, int); +void update_bcastaddr(void); + +int EEPROMRead(unsigned int pos, unsigned char *data, int len) +{ + int i; + + for (i=0; i 0x200000) { + ls[LASAT_MTD_CONFIG] = 0x100000; + ls[LASAT_MTD_FS] = 0x500000; + } + } else { + lasat_board_info.li_flash_base = KSEG1ADDR(0x10000000); + + if (lasat_board_info.li_flash_size < 0x1000000) { + lb[LASAT_MTD_BOOTLOADER] = KSEG1ADDR(0x10000000); + ls[LASAT_MTD_CONFIG] = 0x100000; + if (lasat_board_info.li_flash_size >= 0x400000) { + ls[LASAT_MTD_FS] = lasat_board_info.li_flash_size - 0x300000; + } + } + } + + for (i = 1; i < LASAT_MTD_LAST; i++) + lb[i] = lb[i-1] + ls[i-1]; +} + +int lasat_init_board_info(void) +{ + int c; + unsigned long crc; + unsigned long cfg0, cfg1; + const product_info_t *ppi; + int i_n_base_models = N_BASE_MODELS; + const char * const * i_txt_base_models = txt_base_models; + int i_n_prids = N_PRIDS; + + memset(&lasat_board_info, 0, sizeof(lasat_board_info)); + + /* First read the EEPROM info */ + EEPROMRead(0, (unsigned char *)&lasat_board_info.li_eeprom_info, + sizeof(struct lasat_eeprom_struct)); + + /* Check the CRC */ + crc = crc32(0x0, (unsigned char *)(&lasat_board_info.li_eeprom_info), + sizeof(struct lasat_eeprom_struct) - 4); + + if (crc != lasat_board_info.li_eeprom_info.crc32) { + prom_printf("WARNING...\nWARNING...\nEEPROM CRC does not match calculated, attempting to soldier on...\n"); + } + + if (lasat_board_info.li_eeprom_info.version != LASAT_EEPROM_VERSION) + { + prom_printf("WARNING...\nWARNING...\nEEPROM version %d, wanted version %d, attempting to soldier on...\n", + (unsigned int)lasat_board_info.li_eeprom_info.version, + LASAT_EEPROM_VERSION); + } + + cfg0 = lasat_board_info.li_eeprom_info.cfg[0]; + cfg1 = lasat_board_info.li_eeprom_info.cfg[1]; + + if ( LASAT_W0_DSCTYPE(cfg0) != 1) { + prom_printf("WARNING...\nWARNING...\nInvalid configuration read from EEPROM, attempting to soldier on..."); + } + /* We have a valid configuration */ + + switch (LASAT_W0_SDRAMBANKSZ(cfg0)) { + case 0: + lasat_board_info.li_memsize = 0x0800000; + break; + case 1: + lasat_board_info.li_memsize = 0x1000000; + break; + case 2: + lasat_board_info.li_memsize = 0x2000000; + break; + case 3: + lasat_board_info.li_memsize = 0x4000000; + break; + case 4: + lasat_board_info.li_memsize = 0x8000000; + break; + default: + lasat_board_info.li_memsize = 0; + } + + switch (LASAT_W0_SDRAMBANKS(cfg0)) { + case 0: + break; + case 1: + lasat_board_info.li_memsize *= 2; + break; + default: + break; + } + + switch (LASAT_W0_BUSSPEED(cfg0)) { + case 0x0: + lasat_board_info.li_bus_hz = 60000000; + break; + case 0x1: + lasat_board_info.li_bus_hz = 66000000; + break; + case 0x2: + lasat_board_info.li_bus_hz = 66666667; + break; + case 0x3: + lasat_board_info.li_bus_hz = 80000000; + break; + case 0x4: + lasat_board_info.li_bus_hz = 83333333; + break; + case 0x5: + lasat_board_info.li_bus_hz = 100000000; + break; + } + + switch (LASAT_W0_CPUCLK(cfg0)) { + case 0x0: + lasat_board_info.li_cpu_hz = + lasat_board_info.li_bus_hz; + break; + case 0x1: + lasat_board_info.li_cpu_hz = + lasat_board_info.li_bus_hz + + (lasat_board_info.li_bus_hz >> 1); + break; + case 0x2: + lasat_board_info.li_cpu_hz = + lasat_board_info.li_bus_hz + + lasat_board_info.li_bus_hz; + break; + case 0x3: + lasat_board_info.li_cpu_hz = + lasat_board_info.li_bus_hz + + lasat_board_info.li_bus_hz + + (lasat_board_info.li_bus_hz >> 1); + break; + case 0x4: + lasat_board_info.li_cpu_hz = + lasat_board_info.li_bus_hz + + lasat_board_info.li_bus_hz + + lasat_board_info.li_bus_hz; + break; + } + + /* Flash size */ + switch (LASAT_W1_FLASHSIZE(cfg1)) { + case 0: + lasat_board_info.li_flash_size = 0x200000; + break; + case 1: + lasat_board_info.li_flash_size = 0x400000; + break; + case 2: + lasat_board_info.li_flash_size = 0x800000; + break; + case 3: + lasat_board_info.li_flash_size = 0x1000000; + break; + case 4: + lasat_board_info.li_flash_size = 0x2000000; + break; + } + + init_flash_sizes(); + + lasat_board_info.li_bmid = LASAT_W0_BMID(cfg0); + lasat_board_info.li_prid = lasat_board_info.li_eeprom_info.prid; + if (lasat_board_info.li_prid == 0xffff || lasat_board_info.li_prid == 0) + lasat_board_info.li_prid = lasat_board_info.li_bmid; + + /* Base model stuff */ + if (lasat_board_info.li_bmid > i_n_base_models) + lasat_board_info.li_bmid = i_n_base_models; + strcpy(lasat_board_info.li_bmstr, i_txt_base_models[lasat_board_info.li_bmid]); + + /* Product ID dependent values */ + c = lasat_board_info.li_prid; + if (c >= i_n_prids) { + strcpy(lasat_board_info.li_namestr, "Unknown Model"); + strcpy(lasat_board_info.li_typestr, "Unknown Type"); + } else { + ppi = &vendor_info_table[0].vi_product_info[c]; + strcpy(lasat_board_info.li_namestr, ppi->pi_name); + if (ppi->pi_type) + strcpy(lasat_board_info.li_typestr, ppi->pi_type); + else + sprintf(lasat_board_info.li_typestr, "%d",10*c); + } + +#if defined(CONFIG_INET) && defined(CONFIG_SYSCTL) + update_bcastaddr(); +#endif + + return 0; +} + +void lasat_write_eeprom_info(void) +{ + unsigned long crc; + + /* Generate the CRC */ + crc = crc32(0x0, (unsigned char *)(&lasat_board_info.li_eeprom_info), + sizeof(struct lasat_eeprom_struct) - 4); + lasat_board_info.li_eeprom_info.crc32 = crc; + + /* Write the EEPROM info */ + EEPROMWrite(0, (unsigned char *)&lasat_board_info.li_eeprom_info, + sizeof(struct lasat_eeprom_struct)); +} + diff -urN linux-2.4.21-bk37/arch/mips/lasat/lasat_models.h linux-2.4.21-bk38/arch/mips/lasat/lasat_models.h --- linux-2.4.21-bk37/arch/mips/lasat/lasat_models.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/lasat_models.h 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,63 @@ +/* + * Model description tables + */ + +typedef struct product_info_t { + const char *pi_name; + const char *pi_type; +} product_info_t; + +typedef struct vendor_info_t { + const char *vi_name; + const product_info_t *vi_product_info; +} vendor_info_t; + +/* + * Base models + */ +static const char * const txt_base_models[] = { + "MQ 2", "MQ Pro", "SP 25", "SP 50", "SP 100", "SP 5000", "SP 7000", "SP 1000", "Unknown" +}; +#define N_BASE_MODELS (sizeof(txt_base_models)/sizeof(char*)-1) + +/* + * Eicon Networks + */ +static const char txt_en_mq[] = "Masquerade"; +static const char txt_en_sp[] = "Safepipe"; + +static const product_info_t product_info_eicon[] = { + { txt_en_mq, "II" }, /* 0 */ + { txt_en_mq, "Pro" }, /* 1 */ + { txt_en_sp, "25" }, /* 2 */ + { txt_en_sp, "50" }, /* 3 */ + { txt_en_sp, "100" }, /* 4 */ + { txt_en_sp, "5000" }, /* 5 */ + { txt_en_sp, "7000" }, /* 6 */ + { txt_en_sp, "30" }, /* 7 */ + { txt_en_sp, "5100" }, /* 8 */ + { txt_en_sp, "7100" }, /* 9 */ + { txt_en_sp, "1110" }, /* 10 */ + { txt_en_sp, "3020" }, /* 11 */ + { txt_en_sp, "3030" }, /* 12 */ + { txt_en_sp, "5020" }, /* 13 */ + { txt_en_sp, "5030" }, /* 14 */ + { txt_en_sp, "1120" }, /* 15 */ + { txt_en_sp, "1130" }, /* 16 */ + { txt_en_sp, "6010" }, /* 17 */ + { txt_en_sp, "6110" }, /* 18 */ + { txt_en_sp, "6210" }, /* 19 */ + { txt_en_sp, "1020" }, /* 20 */ + { txt_en_sp, "1040" }, /* 21 */ + { txt_en_sp, "1050" }, /* 22 */ + { txt_en_sp, "1060" }, /* 23 */ +}; +#define N_PRIDS (sizeof(product_info_eicon)/sizeof(product_info_t)) + +/* + * The vendor table + */ +static vendor_info_t const vendor_info_table[] = { + { "Eicon Networks", product_info_eicon }, +}; +#define N_VENDORS (sizeof(vendor_info_table)/sizeof(vendor_info_t)) diff -urN linux-2.4.21-bk37/arch/mips/lasat/pci.c linux-2.4.21-bk38/arch/mips/lasat/pci.c --- linux-2.4.21-bk37/arch/mips/lasat/pci.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/pci.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include + +extern struct pci_ops nile4_pci_ops; +extern struct pci_ops gt64120_pci_ops; + +void __init pcibios_init(void) +{ + struct pci_ops *pci_ops; + + switch (mips_machtype) { + case MACH_LASAT_100: + pci_ops = >64120_pci_ops; + break; + case MACH_LASAT_200: + pci_ops = &nile4_pci_ops; + break; + default: + panic("pcibios_init: mips_machtype incorrect"); + } + + pci_scan_bus(0, pci_ops, NULL); +} + +void __init pcibios_fixup_bus(struct pci_bus *b) +{ +} + +unsigned __init int pcibios_assign_all_busses(void) +{ + return 1; +} + +struct pci_fixup pcibios_fixups[] = { + { 0 } +}; diff -urN linux-2.4.21-bk37/arch/mips/lasat/picvue.c linux-2.4.21-bk38/arch/mips/lasat/picvue.c --- linux-2.4.21-bk37/arch/mips/lasat/picvue.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/picvue.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,241 @@ +/* + * Picvue PVC160206 display driver + * + * Brian Murphy + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "picvue.h" + +#define PVC_BUSY 0x80 +#define PVC_NLINES 2 +#define PVC_DISPMEM 80 +#define PVC_LINELEN PVC_DISPMEM / PVC_NLINES + +struct pvc_defs *picvue = NULL; + +DECLARE_MUTEX(pvc_sem); + +static void pvc_reg_write(u32 val) +{ + *picvue->reg = val; +} + +static u32 pvc_reg_read(void) +{ + u32 tmp = *picvue->reg; + return tmp; +} + +static void pvc_write_byte(u32 data, u8 byte) +{ + data |= picvue->e; + pvc_reg_write(data); + data &= ~picvue->data_mask; + data |= byte << picvue->data_shift; + pvc_reg_write(data); + ndelay(220); + pvc_reg_write(data & ~picvue->e); + ndelay(220); +} + +static u8 pvc_read_byte(u32 data) +{ + u8 byte; + + data |= picvue->e; + pvc_reg_write(data); + ndelay(220); + byte = (pvc_reg_read() & picvue->data_mask) >> picvue->data_shift; + data &= ~picvue->e; + pvc_reg_write(data); + ndelay(220); + return byte; +} + +static u8 pvc_read_data(void) +{ + u32 data = pvc_reg_read(); + u8 byte; + data |= picvue->rw; + data &= ~picvue->rs; + pvc_reg_write(data); + ndelay(40); + byte = pvc_read_byte(data); + data |= picvue->rs; + pvc_reg_write(data); + return byte; +} + +#define TIMEOUT 1000 +static int pvc_wait(void) +{ + int i = TIMEOUT; + int err = 0; + + while ((pvc_read_data() & PVC_BUSY) && i) + i--; + if (i == 0) + err = -ETIME; + + return err; +} + +#define MODE_INST 0 +#define MODE_DATA 1 +static void pvc_write(u8 byte, int mode) +{ + u32 data = pvc_reg_read(); + data &= ~picvue->rw; + if (mode == MODE_DATA) + data |= picvue->rs; + else + data &= ~picvue->rs; + pvc_reg_write(data); + ndelay(40); + pvc_write_byte(data, byte); + if (mode == MODE_DATA) + data &= ~picvue->rs; + else + data |= picvue->rs; + pvc_reg_write(data); + pvc_wait(); +} + +void pvc_write_string(const unsigned char *str, u8 addr, int line) +{ + int i = 0; + + if (line > 0 && (PVC_NLINES > 1)) + addr += 0x40 * line; + pvc_write(0x80 | addr, MODE_INST); + + while (*str != 0 && i < PVC_LINELEN) { + pvc_write(*str++, MODE_DATA); + i++; + } +} + +void pvc_write_string_centered(const unsigned char *str, int line) +{ + int len = strlen(str); + u8 addr; + + if (len > PVC_VISIBLE_CHARS) + addr = 0; + else + addr = (PVC_VISIBLE_CHARS - strlen(str))/2; + + pvc_write_string(str, addr, line); +} + +void pvc_dump_string(const unsigned char *str) +{ + int len = strlen(str); + + pvc_clear(); + pvc_write_string(str, 0, 0); + if (len > PVC_VISIBLE_CHARS) + pvc_write_string(&str[PVC_VISIBLE_CHARS], 0, 1); +} + +#define BM_SIZE 8 +#define MAX_PROGRAMMABLE_CHARS 8 +int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE]) +{ + int i; + int addr; + + if (charnum > MAX_PROGRAMMABLE_CHARS) + return -ENOENT; + + addr = charnum * 8; + pvc_write(0x40 | addr, MODE_INST); + + for (i=0; i + * + */ +#include + +struct pvc_defs { + volatile u32 *reg; + u32 data_shift; + u32 data_mask; + u32 e; + u32 rw; + u32 rs; +}; + +extern struct pvc_defs *picvue; + +#define PVC_NLINES 2 +#define PVC_DISPMEM 80 +#define PVC_LINELEN PVC_DISPMEM / PVC_NLINES +#define PVC_VISIBLE_CHARS 16 + +void pvc_write_string(const unsigned char *str, u8 addr, int line); +void pvc_write_string_centered(const unsigned char *str, int line); +void pvc_dump_string(const unsigned char *str); + +#define BM_SIZE 8 +#define MAX_PROGRAMMABLE_CHARS 8 +int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE]); + +void pvc_dispcnt(u8 cmd); +#define DISP_OFF 0 +#define DISP_ON (1 << 2) +#define CUR_ON (1 << 1) +#define CUR_BLINK (1 << 0) + +void pvc_move(u8 cmd); +#define DISPLAY (1 << 3) +#define CURSOR 0 +#define RIGHT (1 << 2) +#define LEFT 0 + +void pvc_clear(void); +void pvc_home(void); + +extern struct semaphore pvc_sem; diff -urN linux-2.4.21-bk37/arch/mips/lasat/picvue_proc.c linux-2.4.21-bk38/arch/mips/lasat/picvue_proc.c --- linux-2.4.21-bk37/arch/mips/lasat/picvue_proc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/picvue_proc.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,186 @@ +/* + * Picvue PVC160206 display driver + * + * Brian Murphy + * + */ +#include +#include +#include +#include + +#include +#include + +#include + +#include "picvue.h" + +static char pvc_lines[PVC_NLINES][PVC_LINELEN+1]; +static int pvc_linedata[PVC_NLINES]; +static struct proc_dir_entry *pvc_display_dir; +static char *pvc_linename[PVC_NLINES] = {"line1", "line2"}; +#define DISPLAY_DIR_NAME "display" +static int scroll_dir = 0, scroll_interval = 0; + +static struct timer_list timer; + +static void pvc_display(unsigned long data) { + int i; + + pvc_clear(); + for (i=0; i PVC_NLINES) { + printk("proc_read_line: invalid lineno %d\n", lineno); + return 0; + } + + down(&pvc_sem); + page += sprintf(page, "%s\n", pvc_lines[lineno]); + up(&pvc_sem); + + return page - origpage; +} + +static int pvc_proc_write_line(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int origcount = count; + int lineno = *(int *)data; + + if (lineno < 0 || lineno > PVC_NLINES) { + printk("proc_write_line: invalid lineno %d\n", lineno); + return origcount; + } + + if (count > PVC_LINELEN) + count = PVC_LINELEN; + + if (buffer[count-1] == '\n') + count--; + + down(&pvc_sem); + strncpy(pvc_lines[lineno], buffer, count); + pvc_lines[lineno][count] = '\0'; + up(&pvc_sem); + + tasklet_schedule(&pvc_display_tasklet); + + return origcount; +} + +static int pvc_proc_write_scroll(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int origcount = count; + int cmd = simple_strtol(buffer, NULL, 10); + + down(&pvc_sem); + if (scroll_interval != 0) + del_timer(&timer); + + if (cmd == 0) { + scroll_dir = 0; + scroll_interval = 0; + } else { + if (cmd < 0) { + scroll_dir = -1; + scroll_interval = -cmd; + } else { + scroll_dir = 1; + scroll_interval = cmd; + } + add_timer(&timer); + } + up(&pvc_sem); + + return origcount; +} + +static int pvc_proc_read_scroll(char *page, char **start, + off_t off, int count, + int *eof, void *data) +{ + char *origpage = page; + + down(&pvc_sem); + page += sprintf(page, "%d\n", scroll_dir * scroll_interval); + up(&pvc_sem); + + return page - origpage; +} + + +void pvc_proc_timerfunc(unsigned long data) +{ + if (scroll_dir < 0) + pvc_move(DISPLAY|RIGHT); + else if (scroll_dir > 0) + pvc_move(DISPLAY|LEFT); + + timer.expires = jiffies + scroll_interval; + add_timer(&timer); +} + +static void pvc_proc_cleanup(void) +{ + int i; + for (i=0; iread_proc = pvc_proc_read_line; + proc_entry->write_proc = pvc_proc_write_line; + proc_entry->data = &pvc_linedata[i]; + } + proc_entry = create_proc_entry("scroll", 0644, pvc_display_dir); + if (proc_entry == NULL) + goto error; + proc_entry->write_proc = pvc_proc_write_scroll; + proc_entry->read_proc = pvc_proc_read_scroll; + + init_timer(&timer); + timer.function = pvc_proc_timerfunc; + + return 0; +error: + pvc_proc_cleanup(); + return -ENOMEM; +} + +module_init(pvc_proc_init); +module_exit(pvc_proc_cleanup); +MODULE_LICENSE("GPL"); diff -urN linux-2.4.21-bk37/arch/mips/lasat/prom.c linux-2.4.21-bk38/arch/mips/lasat/prom.c --- linux-2.4.21-bk37/arch/mips/lasat/prom.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/prom.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,140 @@ +/* + * PROM interface routines. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "at93c.h" +#include +#include "prom.h" + +#define RESET_VECTOR 0xbfc00000 +#define PROM_JUMP_TABLE_ENTRY(n) (*((u32 *)(RESET_VECTOR + 0x20) + n)) +#define PROM_DISPLAY_ADDR PROM_JUMP_TABLE_ENTRY(0) +#define PROM_PUTC_ADDR PROM_JUMP_TABLE_ENTRY(1) +#define PROM_MONITOR_ADDR PROM_JUMP_TABLE_ENTRY(2) + +static void null_prom_printf(const char * fmt, ...) +{ +} + +static void null_prom_display(const char *string, int pos, int clear) +{ +} + +static void null_prom_monitor(void) +{ +} + +static void null_prom_putc(char c) +{ +} + +/* these are functions provided by the bootloader */ +static void (* prom_putc)(char c) = null_prom_putc; +void (* prom_printf)(const char * fmt, ...) = null_prom_printf; +void (* prom_display)(const char *string, int pos, int clear) = + null_prom_display; +void (* prom_monitor)(void) = null_prom_monitor; + +unsigned int lasat_ndelay_divider; + +#define PROM_PRINTFBUF_SIZE 256 +static char prom_printfbuf[PROM_PRINTFBUF_SIZE]; + +static void real_prom_printf(const char * fmt, ...) +{ + va_list ap; + int len; + char *c = prom_printfbuf; + int i; + + va_start(ap, fmt); + len = vsnprintf(prom_printfbuf, PROM_PRINTFBUF_SIZE, fmt, ap); + va_end(ap); + + /* output overflowed the buffer */ + if (len < 0 || len > PROM_PRINTFBUF_SIZE) + len = PROM_PRINTFBUF_SIZE; + + for (i=0; i < len; i++) { + if (*c == '\n') + prom_putc('\r'); + prom_putc(*c++); + } +} + +static void setup_prom_vectors(void) +{ + u32 version = *(u32 *)(RESET_VECTOR + 0x90); + + if (version == 306) { + prom_display = (void *)PROM_DISPLAY_ADDR; + prom_putc = (void *)PROM_PUTC_ADDR; + prom_printf = real_prom_printf; + prom_monitor = (void *)PROM_MONITOR_ADDR; + } + prom_printf("prom vectors set up\n"); +} + +char arcs_cmdline[CL_SIZE]; + +static struct at93c_defs at93c_defs[N_MACHTYPES] = { + {(void *)AT93C_REG_100, (void *)AT93C_RDATA_REG_100, AT93C_RDATA_SHIFT_100, + AT93C_WDATA_SHIFT_100, AT93C_CS_M_100, AT93C_CLK_M_100}, + {(void *)AT93C_REG_200, (void *)AT93C_RDATA_REG_200, AT93C_RDATA_SHIFT_200, + AT93C_WDATA_SHIFT_200, AT93C_CS_M_200, AT93C_CLK_M_200}, +}; + +void __init prom_init(int argc, char **argv, char **envp, int *prom_vec) +{ + setup_prom_vectors(); + + if (current_cpu_data.cputype == CPU_R5000) { + mips_machtype = MACH_LASAT_200; + lasat_ndelay_divider = 8; + } else { + mips_machtype = MACH_LASAT_100; + lasat_ndelay_divider = 20; + } + + at93c = &at93c_defs[mips_machtype]; + + lasat_init_board_info(); /* Read info from EEPROM */ + + mips_machgroup = MACH_GROUP_LASAT; + + /* Get the command line */ + if (argc>0) { + strncpy(arcs_cmdline, argv[0], CL_SIZE-1); + arcs_cmdline[CL_SIZE-1] = '\0'; + } + + /* Set the I/O base address */ + set_io_port_base(KSEG1); + + /* Set memory regions */ + ioport_resource.start = 0; /* Should be KSEGx ??? */ + ioport_resource.end = 0xffffffff; /* Should be ??? */ + + add_memory_region(0, lasat_board_info.li_memsize, BOOT_MEM_RAM); +} + +void prom_free_prom_memory(void) +{ +} + +const char *get_system_type(void) +{ + return lasat_board_info.li_bmstr; +} diff -urN linux-2.4.21-bk37/arch/mips/lasat/prom.h linux-2.4.21-bk38/arch/mips/lasat/prom.h --- linux-2.4.21-bk37/arch/mips/lasat/prom.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/prom.h 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,6 @@ +#ifndef PROM_H +#define PROM_H +extern void (* prom_display)(const char *string, int pos, int clear); +extern void (* prom_monitor)(void); +extern void (* prom_printf)(const char * fmt, ...); +#endif diff -urN linux-2.4.21-bk37/arch/mips/lasat/reset.c linux-2.4.21-bk38/arch/mips/lasat/reset.c --- linux-2.4.21-bk37/arch/mips/lasat/reset.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/reset.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,73 @@ +/* + * + * Thomas Horsten + * Copyright (C) 2000 LASAT Networks A/S. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Reset the LASAT board. + * + */ + +#include +#include +#include +#include +#include "picvue.h" +#include "prom.h" + +static void lasat_machine_restart(char *command); +static void lasat_machine_halt(void); + +/* Used to set machine to boot in service mode via /proc interface */ +int lasat_boot_to_service = 0; + +static void lasat_machine_restart(char *command) +{ + local_irq_disable(); + + if (lasat_boot_to_service) { + printk("machine_restart: Rebooting to service mode\n"); + *(volatile unsigned int *)0xa0000024 = 0xdeadbeef; + *(volatile unsigned int *)0xa00000fc = 0xfedeabba; + } + *lasat_misc->reset_reg = 0xbedead; + for (;;) ; +} + +#define MESSAGE "System halted" +static void lasat_machine_halt(void) +{ + local_irq_disable(); + + /* Disable interrupts and loop forever */ + printk(KERN_NOTICE MESSAGE "\n"); +#ifdef CONFIG_PICVUE + pvc_clear(); + pvc_write_string(MESSAGE, 0, 0); +#endif + prom_monitor(); + for (;;) ; +} + +void lasat_reboot_setup(void) +{ + _machine_restart = lasat_machine_restart; + _machine_halt = lasat_machine_halt; + _machine_power_off = lasat_machine_halt; +} diff -urN linux-2.4.21-bk37/arch/mips/lasat/setup.c linux-2.4.21-bk38/arch/mips/lasat/setup.c --- linux-2.4.21-bk37/arch/mips/lasat/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,223 @@ +/* + * setup.c + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999 MIPS Technologies, Inc. All rights reserved. + * + * Thomas Horsten + * Copyright (C) 2000 LASAT Networks A/S. + * + * Brian Murphy + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Lasat specific setup. + */ +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#if CONFIG_PICVUE +#include +#endif + +#include "ds1603.h" +#include "at93c.h" +#include +#include +#include + +#include "prom.h" + +int lasat_command_line = 0; +void lasatint_init(void); + +#ifdef CONFIG_BLK_DEV_IDE +extern struct ide_ops std_ide_ops; +extern struct ide_ops *ide_ops; +#endif + +extern char arcs_cmdline[CL_SIZE]; + +extern void lasat_reboot_setup(void); +extern void pcisetup(void); +extern void edhac_init(void *, void *, void *); +extern void addrflt_init(void); + +struct lasat_misc lasat_misc_info[N_MACHTYPES] = { + {(void *)KSEG1ADDR(0x1c840000), (void *)KSEG1ADDR(0x1c800000), 2}, + {(void *)KSEG1ADDR(0x11080000), (void *)KSEG1ADDR(0x11000000), 6} +}; + +struct lasat_misc *lasat_misc = NULL; + +#ifdef CONFIG_DS1603 +static struct ds_defs ds_defs[N_MACHTYPES] = { + { (void *)DS1603_REG_100, (void *)DS1603_REG_100, + DS1603_RST_100, DS1603_CLK_100, DS1603_DATA_100, + DS1603_DATA_SHIFT_100, 0, 0 }, + { (void *)DS1603_REG_200, (void *)DS1603_DATA_REG_200, + DS1603_RST_200, DS1603_CLK_200, DS1603_DATA_200, + DS1603_DATA_READ_SHIFT_200, 1, 2000 } +}; +#endif + +#ifdef CONFIG_PICVUE +#include "picvue.h" +static struct pvc_defs pvc_defs[N_MACHTYPES] = { + { (void *)PVC_REG_100, PVC_DATA_SHIFT_100, PVC_DATA_M_100, + PVC_E_100, PVC_RW_100, PVC_RS_100 }, + { (void *)PVC_REG_200, PVC_DATA_SHIFT_200, PVC_DATA_M_200, + PVC_E_200, PVC_RW_200, PVC_RS_200 } +}; +#endif + +static int lasat_panic_display(struct notifier_block *this, + unsigned long event, void *ptr) +{ +#ifdef CONFIG_PICVUE + unsigned char *string = ptr; + if (string == NULL) + string = "Kernel Panic"; + pvc_dump_string(string); +#endif + return NOTIFY_DONE; +} + +static int lasat_panic_prom_monitor(struct notifier_block *this, + unsigned long event, void *ptr) +{ + prom_monitor(); + return NOTIFY_DONE; +} + +static struct notifier_block lasat_panic_block[] = +{ + { lasat_panic_display, NULL, INT_MAX }, + { lasat_panic_prom_monitor, NULL, INT_MIN } +}; + +#ifdef CONFIG_BLK_DEV_IDE +static int lasat_ide_default_irq(ide_ioreg_t base) { + return 0; +} + +static ide_ioreg_t lasat_ide_default_io_base(int index) { + return 0; +} +#endif + +static void lasat_time_init(void) +{ + mips_counter_frequency = lasat_board_info.li_cpu_hz / 2; +} + +static void lasat_timer_setup(struct irqaction *irq) +{ + + write_c0_compare( + read_c0_count() + + mips_counter_frequency / HZ); + change_c0_status(ST0_IM, IE_IRQ0 | IE_IRQ5); +} + +#define MIPS_CPU_TIMER_IRQ 7 +asmlinkage void lasat_timer_interrupt(struct pt_regs *regs) +{ + ll_timer_interrupt(MIPS_CPU_TIMER_IRQ, regs); +} + +void __init serial_init(void) +{ +#ifdef CONFIG_SERIAL + struct serial_struct s; + + memset(&s, 0, sizeof(s)); + + s.flags = STD_COM_FLAGS; + s.io_type = SERIAL_IO_MEM; + + if (mips_machtype == MACH_LASAT_100) { + s.baud_base = LASAT_BASE_BAUD_100; + s.irq = LASATINT_UART_100; + s.iomem_reg_shift = LASAT_UART_REGS_SHIFT_100; + s.iomem_base = (u8 *)KSEG1ADDR(LASAT_UART_REGS_BASE_100); + } else { + s.baud_base = LASAT_BASE_BAUD_200; + s.irq = LASATINT_UART_200; + s.iomem_reg_shift = LASAT_UART_REGS_SHIFT_200; + s.iomem_base = (u8 *)KSEG1ADDR(LASAT_UART_REGS_BASE_200); + } + + if (early_serial_setup(&s) != 0) + printk(KERN_ERR "Serial setup failed!\n"); +#endif +} + +void __init lasat_setup(void) +{ + int i; + lasat_misc = &lasat_misc_info[mips_machtype]; +#ifdef CONFIG_PICVUE + picvue = &pvc_defs[mips_machtype]; +#endif + + /* Set up panic notifier */ + for (i = 0; i < sizeof(lasat_panic_block) / sizeof(struct notifier_block); i++) + notifier_chain_register(&panic_notifier_list, &lasat_panic_block[i]); + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &std_ide_ops; + ide_ops->ide_default_irq = &lasat_ide_default_irq; + ide_ops->ide_default_io_base = &lasat_ide_default_io_base; +#endif + + lasat_reboot_setup(); + + board_time_init = lasat_time_init; + board_timer_setup = lasat_timer_setup; + +#ifdef CONFIG_DS1603 + ds1603 = &ds_defs[mips_machtype]; + rtc_get_time = ds1603_read; + rtc_set_time = ds1603_set; +#endif + + serial_init(); + + /* Switch from prom exception handler to normal mode */ + change_c0_status(ST0_BEV,0); + + prom_printf("Lasat specific initialization complete\n"); +} + + diff -urN linux-2.4.21-bk37/arch/mips/lasat/sysctl.c linux-2.4.21-bk38/arch/mips/lasat/sysctl.c --- linux-2.4.21-bk37/arch/mips/lasat/sysctl.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/sysctl.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,359 @@ +/* + * sysctl.c + * + * Thomas Horsten + * Copyright (C) 2000 LASAT Networks A/S. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Routines specific to the LASAT boards + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sysctl.h" +#include "ds1603.h" + +static DECLARE_MUTEX(lasat_info_sem); + +/* Strategy function to write EEPROM after changing string entry */ +int sysctl_lasatstring(ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, void **context) +{ + int r; + down(&lasat_info_sem); + r = sysctl_string(table, name, + nlen, oldval, oldlenp, newval, newlen, context); + if (r < 0) { + up(&lasat_info_sem); + return r; + } + if (newval && newlen) { + lasat_write_eeprom_info(); + } + up(&lasat_info_sem); + return 1; +} + + +/* And the same for proc */ +int proc_dolasatstring(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + int r; + down(&lasat_info_sem); + r = proc_dostring(table, write, filp, buffer, lenp); + if ( (!write) || r) { + up(&lasat_info_sem); + return r; + } + lasat_write_eeprom_info(); + up(&lasat_info_sem); + return 0; +} + +/* proc function to write EEPROM after changing int entry */ +int proc_dolasatint(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + int r; + down(&lasat_info_sem); + r = proc_dointvec(table, write, filp, buffer, lenp); + if ( (!write) || r) { + up(&lasat_info_sem); + return r; + } + lasat_write_eeprom_info(); + up(&lasat_info_sem); + return 0; +} + +static int rtctmp; + +#ifdef CONFIG_DS1603 +/* proc function to read/write RealTime Clock */ +int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + int r; + down(&lasat_info_sem); + if (!write) { + rtctmp = ds1603_read(); + /* check for time < 0 and set to 0 */ + if (rtctmp < 0) + rtctmp = 0; + } + r = proc_dointvec(table, write, filp, buffer, lenp); + if ( (!write) || r) { + up(&lasat_info_sem); + return r; + } + ds1603_set(rtctmp); + up(&lasat_info_sem); + return 0; +} +#endif + +/* Sysctl for setting the IP addresses */ +int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, void **context) +{ + int r; + down(&lasat_info_sem); + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen, context); + if (r < 0) { + up(&lasat_info_sem); + return r; + } + if (newval && newlen) { + lasat_write_eeprom_info(); + } + up(&lasat_info_sem); + return 1; +} + +#if CONFIG_DS1603 +/* Same for RTC */ +int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, void **context) +{ + int r; + down(&lasat_info_sem); + rtctmp = ds1603_read(); + if (rtctmp < 0) + rtctmp = 0; + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen, context); + if (r < 0) { + up(&lasat_info_sem); + return r; + } + if (newval && newlen) { + ds1603_set(rtctmp); + } + up(&lasat_info_sem); + return 1; +} +#endif + +#ifdef CONFIG_INET +static char lasat_bcastaddr[16]; + +void update_bcastaddr(void) +{ + unsigned int ip; + + ip = lasat_board_info.li_eeprom_info.ipaddr | + ~lasat_board_info.li_eeprom_info.netmask; + + sprintf(lasat_bcastaddr, "%d.%d.%d.%d", + (ip ) & 0xff, + (ip >> 8) & 0xff, + (ip >> 16) & 0xff, + (ip >> 24) & 0xff); +} + +static char proc_lasat_ipbuf[32]; +/* Parsing of IP address */ +int proc_lasat_ip(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + int len; + unsigned int ip; + char *p, c; + + if (!table->data || !table->maxlen || !*lenp || + (filp->f_pos && !write)) { + *lenp = 0; + return 0; + } + + down(&lasat_info_sem); + if (write) { + len = 0; + p = buffer; + while (len < *lenp) { + if(get_user(c, p++)) { + up(&lasat_info_sem); + return -EFAULT; + } + if (c == 0 || c == '\n') + break; + len++; + } + if (len >= sizeof(proc_lasat_ipbuf)-1) + len = sizeof(proc_lasat_ipbuf) - 1; + if (copy_from_user(proc_lasat_ipbuf, buffer, len)) + { + up(&lasat_info_sem); + return -EFAULT; + } + proc_lasat_ipbuf[len] = 0; + filp->f_pos += *lenp; + /* Now see if we can convert it to a valid IP */ + ip = in_aton(proc_lasat_ipbuf); + *(unsigned int *)(table->data) = ip; + lasat_write_eeprom_info(); + } else { + ip = *(unsigned int *)(table->data); + sprintf(proc_lasat_ipbuf, "%d.%d.%d.%d", + (ip ) & 0xff, + (ip >> 8) & 0xff, + (ip >> 16) & 0xff, + (ip >> 24) & 0xff); + len = strlen(proc_lasat_ipbuf); + if (len > *lenp) + len = *lenp; + if (len) + if(copy_to_user(buffer, proc_lasat_ipbuf, len)) { + up(&lasat_info_sem); + return -EFAULT; + } + if (len < *lenp) { + if(put_user('\n', ((char *) buffer) + len)) { + up(&lasat_info_sem); + return -EFAULT; + } + len++; + } + *lenp = len; + filp->f_pos += len; + } + update_bcastaddr(); + up(&lasat_info_sem); + return 0; +} +#endif /* defined(CONFIG_INET) */ + +static int sysctl_lasat_eeprom_value(ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, + void **context) +{ + int r; + + down(&lasat_info_sem); + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen, context); + if (r < 0) { + up(&lasat_info_sem); + return r; + } + + if (newval && newlen) + { + if (name && *name == LASAT_PRID) + lasat_board_info.li_eeprom_info.prid = *(int*)newval; + + lasat_write_eeprom_info(); + lasat_init_board_info(); + } + up(&lasat_info_sem); + + return 0; +} + +int proc_lasat_eeprom_value(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + int r; + down(&lasat_info_sem); + r = proc_dointvec(table, write, filp, buffer, lenp); + if ( (!write) || r) { + up(&lasat_info_sem); + return r; + } + if (filp && filp->f_dentry) + { + if (!strcmp(filp->f_dentry->d_name.name, "prid")) + lasat_board_info.li_eeprom_info.prid = lasat_board_info.li_prid; + if (!strcmp(filp->f_dentry->d_name.name, "debugaccess")) + lasat_board_info.li_eeprom_info.debugaccess = lasat_board_info.li_debugaccess; + } + lasat_write_eeprom_info(); + up(&lasat_info_sem); + return 0; +} + +extern int lasat_boot_to_service; + +#ifdef CONFIG_SYSCTL + +static ctl_table lasat_table[] = { + {LASAT_CPU_HZ, "cpu-hz", &lasat_board_info.li_cpu_hz, sizeof(int), + 0444, NULL, &proc_dointvec, &sysctl_intvec}, + {LASAT_BUS_HZ, "bus-hz", &lasat_board_info.li_bus_hz, sizeof(int), + 0444, NULL, &proc_dointvec, &sysctl_intvec}, + {LASAT_MODEL, "bmid", &lasat_board_info.li_bmid, sizeof(int), + 0444, NULL, &proc_dointvec, &sysctl_intvec}, + {LASAT_PRID, "prid", &lasat_board_info.li_prid, sizeof(int), + 0644, NULL, &proc_lasat_eeprom_value, &sysctl_lasat_eeprom_value}, +#ifdef CONFIG_INET + {LASAT_IPADDR, "ipaddr", &lasat_board_info.li_eeprom_info.ipaddr, sizeof(int), + 0644, NULL, &proc_lasat_ip, &sysctl_lasat_intvec}, + {LASAT_NETMASK, "netmask", &lasat_board_info.li_eeprom_info.netmask, sizeof(int), + 0644, NULL, &proc_lasat_ip, &sysctl_lasat_intvec}, + {LASAT_BCAST, "bcastaddr", &lasat_bcastaddr, + sizeof(lasat_bcastaddr), 0600, NULL, + &proc_dostring, &sysctl_string}, +#endif + {LASAT_PASSWORD, "passwd_hash", &lasat_board_info.li_eeprom_info.passwd_hash, sizeof(lasat_board_info.li_eeprom_info.passwd_hash), + 0600, NULL, &proc_dolasatstring, &sysctl_lasatstring}, + {LASAT_SBOOT, "boot-service", &lasat_boot_to_service, sizeof(int), + 0644, NULL, &proc_dointvec, &sysctl_intvec}, +#if CONFIG_DS1603 + {LASAT_RTC, "rtc", &rtctmp, sizeof(int), + 0644, NULL, &proc_dolasatrtc, &sysctl_lasat_rtc}, +#endif + {LASAT_NAMESTR, "namestr", &lasat_board_info.li_namestr, sizeof(lasat_board_info.li_namestr), + 0444, NULL, &proc_dostring, &sysctl_string}, + {LASAT_TYPESTR, "typestr", &lasat_board_info.li_typestr, sizeof(lasat_board_info.li_typestr), + 0444, NULL, &proc_dostring, &sysctl_string}, + {0} +}; + +#define CTL_LASAT 1 // CTL_ANY ??? +static ctl_table lasat_root_table[] = { + { CTL_LASAT, "lasat", NULL, 0, 0555, lasat_table }, + { 0 } +}; + +static int __init lasat_register_sysctl(void) +{ + struct ctl_table_header *lasat_table_header; + + lasat_table_header = + register_sysctl_table(lasat_root_table, 0); + + return 0; +} + +__initcall(lasat_register_sysctl); +#endif /* CONFIG_SYSCTL */ diff -urN linux-2.4.21-bk37/arch/mips/lasat/sysctl.h linux-2.4.21-bk38/arch/mips/lasat/sysctl.h --- linux-2.4.21-bk37/arch/mips/lasat/sysctl.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lasat/sysctl.h 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,24 @@ +/* + * LASAT sysctl values + */ + +#ifndef _LASAT_SYSCTL_H +#define _LASAT_SYSCTL_H + +/* /proc/sys/lasat */ +enum { + LASAT_CPU_HZ=1, + LASAT_BUS_HZ, + LASAT_MODEL, + LASAT_PRID, + LASAT_IPADDR, + LASAT_NETMASK, + LASAT_BCAST, + LASAT_PASSWORD, + LASAT_SBOOT, + LASAT_RTC, + LASAT_NAMESTR, + LASAT_TYPESTR, +}; + +#endif /* _LASAT_SYSCTL_H */ diff -urN linux-2.4.21-bk37/arch/mips/ld.script.in linux-2.4.21-bk38/arch/mips/ld.script.in --- linux-2.4.21-bk37/arch/mips/ld.script.in 2001-07-02 13:56:40.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ld.script.in 2003-08-24 02:55:57.000000000 -0700 @@ -81,8 +81,8 @@ . = ALIGN(4096); __rd_start = .; *(.initrd) - __rd_end = .; . = ALIGN(4096); + __rd_end = .; CONSTRUCTORS } diff -urN linux-2.4.21-bk37/arch/mips/lib/Makefile linux-2.4.21-bk38/arch/mips/lib/Makefile --- linux-2.4.21-bk37/arch/mips/lib/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lib/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -7,9 +7,9 @@ L_TARGET = lib.a obj-y += csum_partial.o csum_partial_copy.o \ - rtc-std.o rtc-no.o memcpy.o memset.o \ - watch.o strlen_user.o strncpy_user.o \ - strnlen_user.o + promlib.o rtc-std.o rtc-no.o memcpy.o \ + memset.o watch.o strlen_user.o \ + strncpy_user.o strnlen_user.o ifeq ($(CONFIG_CPU_R3000)$(CONFIG_CPU_TX39XX),y) obj-y += r3k_dump_tlb.o @@ -18,7 +18,7 @@ endif obj-$(CONFIG_BLK_DEV_FD) += floppy-no.o floppy-std.o -obj-$(CONFIG_IDE) += ide-std.o ide-no.o -obj-$(CONFIG_PC_KEYB) += kbd-std.o kbd-no.o +obj-$(subst m,y,$(CONFIG_IDE)) += ide-std.o ide-no.o # needed for ide module +obj-$(CONFIG_PC_KEYB) += kbd-std.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/lib/dump_tlb.c linux-2.4.21-bk38/arch/mips/lib/dump_tlb.c --- linux-2.4.21-bk37/arch/mips/lib/dump_tlb.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/lib/dump_tlb.c 2003-08-24 02:55:57.000000000 -0700 @@ -41,11 +41,11 @@ unsigned long long entrylo0, entrylo1; unsigned long entryhi; - asid = get_entryhi() & 0xff; + asid = read_c0_entryhi() & 0xff; printk("\n"); for(i=first;i<=last;i++) { - write_32bit_cp0_register(CP0_INDEX, i); + write_c0_index(i); __asm__ __volatile__( ".set\tmips3\n\t" ".set\tnoreorder\n\t" @@ -54,10 +54,10 @@ "nop;nop;nop;nop\n\t" ".set\treorder\n\t" ".set\tmips0\n\t"); - pagemask = read_32bit_cp0_register(CP0_PAGEMASK); - entryhi = read_32bit_cp0_register(CP0_ENTRYHI); - entrylo0 = get_entrylo0(); - entrylo1 = get_entrylo1(); + pagemask = read_c0_pagemask(); + entryhi = read_c0_entryhi(); + entrylo0 = read_c0_entrylo0(); + entrylo1 = read_c0_entrylo1(); /* Unused entries have a virtual address in KSEG0. */ if ((entryhi & 0xf0000000) != 0x80000000 @@ -86,21 +86,21 @@ } } - set_entryhi(asid); + write_c0_entryhi(asid); } void dump_tlb_all(void) { - dump_tlb(0, mips_cpu.tlbsize - 1); + dump_tlb(0, current_cpu_data.tlbsize - 1); } void dump_tlb_wired(void) { int wired; - wired = read_32bit_cp0_register(CP0_WIRED); + wired = read_c0_wired(); printk("Wired: %d", wired); - dump_tlb(0, read_32bit_cp0_register(CP0_WIRED)); + dump_tlb(0, read_c0_wired()); } #define BARRIER \ @@ -112,19 +112,19 @@ void dump_tlb_addr(unsigned long addr) { - unsigned int flags, oldpid; + unsigned long flags, oldpid; int index; - __save_and_cli(flags); - oldpid = get_entryhi() & 0xff; + local_irq_save(flags); + oldpid = read_c0_entryhi() & 0xff; BARRIER; - set_entryhi((addr & PAGE_MASK) | oldpid); + write_c0_entryhi((addr & PAGE_MASK) | oldpid); BARRIER; tlb_probe(); BARRIER; - index = get_index(); - set_entryhi(oldpid); - __restore_flags(flags); + index = read_c0_index(); + write_c0_entryhi(oldpid); + local_irq_restore(flags); if (index < 0) { printk("No entry for address 0x%08lx in TLB\n", addr); @@ -138,7 +138,7 @@ void dump_tlb_nonwired(void) { - dump_tlb(read_32bit_cp0_register(CP0_WIRED), mips_cpu.tlbsize - 1); + dump_tlb(read_c0_wired(), current_cpu_data.tlbsize - 1); } void @@ -153,8 +153,8 @@ addr = (unsigned int) address; printk("Addr == %08x\n", addr); - printk("task == %08p\n", t); - printk("task->mm == %08p\n", t->mm); + printk("task == %8p\n", t); + printk("task->mm == %8p\n", t->mm); //printk("tasks->mm.pgd == %08x\n", (unsigned int) t->mm->pgd); if (addr > KSEG0) @@ -177,9 +177,9 @@ page = *pte; #ifdef CONFIG_64BIT_PHYS_ADDR - printk("page == %08Lx\n", (unsigned long long) pte_val(page)); + printk("page == %08Lx\n", pte_val(page)); #else - printk("page == %08lx\n", (unsigned int) pte_val(page)); + printk("page == %08lx\n", pte_val(page)); #endif val = pte_val(page); @@ -225,9 +225,7 @@ for(i=0;i<8;i++) { - printk("*%08lx == %08lx, ", - (unsigned long)p, (unsigned long)*p++); - printk("*%08lx == %08lx\n", - (unsigned long)p, (unsigned long)*p++); + printk("*%8p = %08lx, ", p, *p); p++; + printk("*%8p = %08lx\n", p, *p); p++; } } diff -urN linux-2.4.21-bk37/arch/mips/lib/ide-no.c linux-2.4.21-bk38/arch/mips/lib/ide-no.c --- linux-2.4.21-bk37/arch/mips/lib/ide-no.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lib/ide-no.c 2003-08-24 02:55:57.000000000 -0700 @@ -29,42 +29,8 @@ { } -static int no_ide_request_irq(unsigned int irq, - void (*handler)(int,void *, struct pt_regs *), - unsigned long flags, const char *device, - void *dev_id) -{ - panic("no_no_ide_request_irq called - shouldn't happen"); -} - -static void no_ide_free_irq(unsigned int irq, void *dev_id) -{ - panic("no_ide_free_irq called - shouldn't happen"); -} - -static int no_ide_check_region(ide_ioreg_t from, unsigned int extent) -{ - panic("no_ide_check_region called - shouldn't happen"); -} - -static void no_ide_request_region(ide_ioreg_t from, unsigned int extent, - const char *name) -{ - panic("no_ide_request_region called - shouldn't happen"); -} - -static void no_ide_release_region(ide_ioreg_t from, unsigned int extent) -{ - panic("no_ide_release_region called - shouldn't happen"); -} - struct ide_ops no_ide_ops = { &no_ide_default_irq, &no_ide_default_io_base, - &no_ide_init_hwif_ports, - &no_ide_request_irq, - &no_ide_free_irq, - &no_ide_check_region, - &no_ide_request_region, - &no_ide_release_region + &no_ide_init_hwif_ports }; diff -urN linux-2.4.21-bk37/arch/mips/lib/ide-std.c linux-2.4.21-bk38/arch/mips/lib/ide-std.c --- linux-2.4.21-bk37/arch/mips/lib/ide-std.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lib/ide-std.c 2003-08-24 02:55:57.000000000 -0700 @@ -62,42 +62,8 @@ hw->io_ports[IDE_IRQ_OFFSET] = 0; } -static int std_ide_request_irq(unsigned int irq, - void (*handler)(int,void *, struct pt_regs *), - unsigned long flags, const char *device, - void *dev_id) -{ - return request_irq(irq, handler, flags, device, dev_id); -} - -static void std_ide_free_irq(unsigned int irq, void *dev_id) -{ - free_irq(irq, dev_id); -} - -static int std_ide_check_region(ide_ioreg_t from, unsigned int extent) -{ - return check_region(from, extent); -} - -static void std_ide_request_region(ide_ioreg_t from, unsigned int extent, - const char *name) -{ - request_region(from, extent, name); -} - -static void std_ide_release_region(ide_ioreg_t from, unsigned int extent) -{ - release_region(from, extent); -} - struct ide_ops std_ide_ops = { &std_ide_default_irq, &std_ide_default_io_base, - &std_ide_init_hwif_ports, - &std_ide_request_irq, - &std_ide_free_irq, - &std_ide_check_region, - &std_ide_request_region, - &std_ide_release_region + &std_ide_init_hwif_ports }; diff -urN linux-2.4.21-bk37/arch/mips/lib/kbd-no.c linux-2.4.21-bk38/arch/mips/lib/kbd-no.c --- linux-2.4.21-bk37/arch/mips/lib/kbd-no.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/lib/kbd-no.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,62 +0,0 @@ -/* - * 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. - * - * Stub keyboard and psaux routines to keep Linux from crashing on machines - * without a keyboard. - * - * Copyright (C) 1998 by Ralf Baechle - */ -#include -#include - -static void no_kbd_request_region(void) -{ - /* No I/O ports are being used on the Indy. */ -} - -static int no_kbd_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - return -ENODEV; -} - -static int no_aux_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - return -ENODEV; -} - -static void no_aux_free_irq(void) -{ -} - -static unsigned char no_kbd_read_input(void) -{ - return 0; -} - -static void no_kbd_write_output(unsigned char val) -{ -} - -static void no_kbd_write_command(unsigned char val) -{ -} - -static unsigned char no_kbd_read_status(void) -{ - return 0; -} - -struct kbd_ops no_kbd_ops = { - no_kbd_request_region, - no_kbd_request_irq, - - no_aux_request_irq, - no_aux_free_irq, - - no_kbd_read_input, - no_kbd_write_output, - no_kbd_write_command, - no_kbd_read_status -}; diff -urN linux-2.4.21-bk37/arch/mips/lib/memcpy.S linux-2.4.21-bk38/arch/mips/lib/memcpy.S --- linux-2.4.21-bk37/arch/mips/lib/memcpy.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lib/memcpy.S 2003-08-24 02:55:57.000000000 -0700 @@ -77,11 +77,13 @@ .previous /* - * In the mips (not mips64) tree, so we can't use doubles + * Only on the 64-bit kernel we can made use of 64-bit registers. */ -#undef USE_DOUBLE +#ifdef CONFIG_MIPS64 +#define USE_DOUBLE +#endif -#if defined(USE_DOUBLE) +#ifdef USE_DOUBLE #define LOAD ld #define LOADL ldl @@ -99,6 +101,24 @@ #define NBYTES 8 #define LOG_NBYTES 3 +/* + * As we are sharing code base with the mips32 tree (which use the o32 ABI + * register definitions). We need to redefine the register definitions from + * the n64 ABI register naming to the o32 ABI register naming. + */ +#undef t0 +#undef t1 +#undef t2 +#undef t3 +#define t0 $8 +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 + #else #define LOAD lw @@ -246,7 +266,7 @@ beq rem, len, copy_bytes nop 1: -EXC( LOAD t0, 0(src), l_exc) +EXC( LOAD t0, 0(src), l_exc) ADD src, src, NBYTES SUB len, len, NBYTES EXC( STORE t0, 0(dst), s_exc_p1u) @@ -320,10 +340,10 @@ EXC( LDFIRST t3, FIRST(3)(src), l_exc_copy) EXC( LDREST t2, REST(2)(src), l_exc_copy) EXC( LDREST t3, REST(3)(src), l_exc_copy) - PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed) + PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed) ADD src, src, 4*NBYTES #ifdef CONFIG_CPU_SB1 - nop # improves slotting + nop # improves slotting #endif EXC( STORE t0, UNIT(0)(dst), s_exc_p4u) EXC( STORE t1, UNIT(1)(dst), s_exc_p3u) @@ -337,8 +357,9 @@ beqz len, done and rem, len, NBYTES-1 # rem = len % NBYTES beq rem, len, copy_bytes + nop 1: -EXC( LDFIRST t0, FIRST(0)(src), l_exc) +EXC( LDFIRST t0, FIRST(0)(src), l_exc) EXC( LDREST t0, REST(0)(src), l_exc_copy) ADD src, src, NBYTES SUB len, len, NBYTES @@ -385,7 +406,7 @@ * * Assumes src < THREAD_BUADDR($28) */ - lw t0, THREAD_BUADDR($28) + LOAD t0, THREAD_BUADDR($28) 1: EXC( lb t1, 0(src), l_exc) ADD src, src, 1 @@ -393,16 +414,16 @@ bne src, t0, 1b ADD dst, dst, 1 l_exc: - lw t0, THREAD_BUADDR($28) # t0 is just past last good address + LOAD t0, THREAD_BUADDR($28) # t0 is just past last good address nop - subu len, AT, t0 # len number of uncopied bytes + SUB len, AT, t0 # len number of uncopied bytes /* * Here's where we rely on src and dst being incremented in tandem, * See (3) above. * dst += (fault addr - src) to put dst at first byte to clear */ - addu dst, t0 # compute start address in a1 - subu dst, src + ADD dst, t0 # compute start address in a1 + SUB dst, src /* * Clear len bytes starting at dst. Can't call __bzero because it * might modify len. An inefficient loop for these rare times... @@ -440,8 +461,8 @@ .align 5 LEAF(memmove) - addu t0, a0, a2 - addu t1, a1, a2 + ADD t0, a0, a2 + ADD t1, a1, a2 sltu t0, a1, t0 # dst + len <= src -> memcpy sltu t1, a0, t1 # dst >= src + len -> memcpy and t0, t1 @@ -455,16 +476,16 @@ sltu t0, a1, a0 beqz t0, r_end_bytes_up # src >= dst nop - addu a0, a2 # dst = dst + len - addu a1, a2 # src = src + len + ADD a0, a2 # dst = dst + len + ADD a1, a2 # src = src + len r_end_bytes: lb t0, -1(a1) - subu a2, a2, 0x1 + SUB a2, a2, 0x1 sb t0, -1(a0) - subu a1, a1, 0x1 + SUB a1, a1, 0x1 bnez a2, r_end_bytes - subu a0, a0, 0x1 + SUB a0, a0, 0x1 r_out: jr ra @@ -472,11 +493,11 @@ r_end_bytes_up: lb t0, (a1) - subu a2, a2, 0x1 + SUB a2, a2, 0x1 sb t0, (a0) - addu a1, a1, 0x1 + ADD a1, a1, 0x1 bnez a2, r_end_bytes_up - addu a0, a0, 0x1 + ADD a0, a0, 0x1 jr ra move a2, zero diff -urN linux-2.4.21-bk37/arch/mips/lib/promlib.c linux-2.4.21-bk38/arch/mips/lib/promlib.c --- linux-2.4.21-bk37/arch/mips/lib/promlib.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/lib/promlib.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,24 @@ +#include +#include + +extern void prom_putchar(char); + +void prom_printf(char *fmt, ...) +{ + va_list args; + char ppbuf[1024]; + char *bptr; + + va_start(args, fmt); + vsprintf(ppbuf, fmt, args); + + bptr = ppbuf; + + while (*bptr != 0) { + if (*bptr == '\n') + prom_putchar('\r'); + + prom_putchar(*bptr++); + } + va_end(args); +} diff -urN linux-2.4.21-bk37/arch/mips/lib/r3k_dump_tlb.c linux-2.4.21-bk38/arch/mips/lib/r3k_dump_tlb.c --- linux-2.4.21-bk37/arch/mips/lib/r3k_dump_tlb.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/lib/r3k_dump_tlb.c 2003-08-24 02:55:57.000000000 -0700 @@ -26,18 +26,18 @@ unsigned int asid; unsigned long entryhi, entrylo0; - asid = get_entryhi() & 0xfc0; + asid = read_c0_entryhi() & 0xfc0; for(i=first;i<=last;i++) { - write_32bit_cp0_register(CP0_INDEX, i<<8); + write_c0_index(i<<8); __asm__ __volatile__( ".set\tnoreorder\n\t" "tlbr\n\t" "nop\n\t" ".set\treorder"); - entryhi = read_32bit_cp0_register(CP0_ENTRYHI); - entrylo0 = read_32bit_cp0_register(CP0_ENTRYLO0); + entryhi = read_c0_entryhi(); + entrylo0 = read_c0_entrylo0(); /* Unused entries have a virtual address of KSEG0. */ if ((entryhi & 0xffffe000) != 0x80000000 @@ -60,19 +60,19 @@ } printk("\n"); - set_entryhi(asid); + write_c0_entryhi(asid); } void dump_tlb_all(void) { - dump_tlb(0, mips_cpu.tlbsize - 1); + dump_tlb(0, current_cpu_data.tlbsize - 1); } void dump_tlb_wired(void) { - int wired = r3k_have_wired_reg ? get_wired() : 8; + int wired = r3k_have_wired_reg ? read_c0_wired() : 8; printk("Wired: %d", wired); dump_tlb(0, wired - 1); @@ -81,16 +81,16 @@ void dump_tlb_addr(unsigned long addr) { - unsigned int flags, oldpid; + unsigned long flags, oldpid; int index; - __save_and_cli(flags); - oldpid = get_entryhi() & 0xff; - set_entryhi((addr & PAGE_MASK) | oldpid); + local_irq_save(flags); + oldpid = read_c0_entryhi() & 0xff; + write_c0_entryhi((addr & PAGE_MASK) | oldpid); tlb_probe(); - index = get_index(); - set_entryhi(oldpid); - __restore_flags(flags); + index = read_c0_index(); + write_c0_entryhi(oldpid); + local_irq_restore(flags); if (index < 0) { printk("No entry for address 0x%08lx in TLB\n", addr); @@ -104,8 +104,8 @@ void dump_tlb_nonwired(void) { - int wired = r3k_have_wired_reg ? get_wired() : 8; - dump_tlb(wired, mips_cpu.tlbsize - 1); + int wired = r3k_have_wired_reg ? read_c0_wired() : 8; + dump_tlb(wired, current_cpu_data.tlbsize - 1); } void diff -urN linux-2.4.21-bk37/arch/mips/lib/rtc-no.c linux-2.4.21-bk38/arch/mips/lib/rtc-no.c --- linux-2.4.21-bk37/arch/mips/lib/rtc-no.c 2001-07-02 13:56:40.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/lib/rtc-no.c 2003-08-24 02:55:57.000000000 -0700 @@ -24,7 +24,7 @@ } struct rtc_ops no_rtc_ops = { - rtc_read_data: (void *) &shouldnt_happen, - rtc_write_data: (void *) &shouldnt_happen, - rtc_bcd_mode: (void *) &shouldnt_happen + .rtc_read_data = (void *) &shouldnt_happen, + .rtc_write_data = (void *) &shouldnt_happen, + .rtc_bcd_mode = (void *) &shouldnt_happen }; diff -urN linux-2.4.21-bk37/arch/mips/math-emu/cp1emu.c linux-2.4.21-bk38/arch/mips/math-emu/cp1emu.c --- linux-2.4.21-bk37/arch/mips/math-emu/cp1emu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/math-emu/cp1emu.c 2003-08-24 02:55:57.000000000 -0700 @@ -200,7 +200,7 @@ vaddr_t emulpc, contpc; unsigned int cond; - if (get_user(ir, (mips_instruction *) REG_TO_VA xcp->cp0_epc)) { + if (get_user(ir, (mips_instruction *) xcp->cp0_epc)) { fpuemuprivate.stats.errors++; return SIGBUS; } @@ -1284,21 +1284,14 @@ struct mips_fpu_soft_struct *ctx) { gpreg_t oldepc, prevepc; - mips_instruction insn, *insnp; + mips_instruction insn; int sig = 0; oldepc = xcp->cp0_epc; do { prevepc = xcp->cp0_epc; - /* - * This is a braindead way to do it but the only sane way I - * found to keep the 64-bit egcs 1.1.2 from crashing. - */ - insnp = (mips_instruction *) REG_TO_VA xcp->cp0_epc; - - if (verify_area(VERIFY_READ, insnp, 4) || - __get_user(insn, insnp)) { + if (get_user(insn, (mips_instruction *) xcp->cp0_epc)) { fpuemuprivate.stats.errors++; return SIGBUS; } @@ -1313,7 +1306,7 @@ sig = cop1Emulate(xcp, ctx); } - if (mips_cpu.options & MIPS_CPU_FPU) + if (cpu_has_fpu) break; if (sig) break; diff -urN linux-2.4.21-bk37/arch/mips/math-emu/dp_cmp.c linux-2.4.21-bk38/arch/mips/math-emu/dp_cmp.c --- linux-2.4.21-bk37/arch/mips/math-emu/dp_cmp.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/math-emu/dp_cmp.c 2003-08-24 02:55:57.000000000 -0700 @@ -44,7 +44,7 @@ if (cmp & IEEE754_CUN) return 1; if (cmp & (IEEE754_CLT | IEEE754_CGT)) { - if (sig && SETCX(IEEE754_INVALID_OPERATION)) + if (sig && SETANDTESTCX(IEEE754_INVALID_OPERATION)) return ieee754si_xcpt(0, "fcmpf", x); } return 0; diff -urN linux-2.4.21-bk37/arch/mips/math-emu/dp_fint.c linux-2.4.21-bk38/arch/mips/math-emu/dp_fint.c --- linux-2.4.21-bk37/arch/mips/math-emu/dp_fint.c 2001-04-13 20:26:07.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/math-emu/dp_fint.c 2003-08-24 02:55:57.000000000 -0700 @@ -33,6 +33,8 @@ CLEARCX; + xc = ( 0 ? xc : xc ); + if (x == 0) return ieee754dp_zero(0); if (x == 1 || x == -1) diff -urN linux-2.4.21-bk37/arch/mips/math-emu/dp_flong.c linux-2.4.21-bk38/arch/mips/math-emu/dp_flong.c --- linux-2.4.21-bk37/arch/mips/math-emu/dp_flong.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/math-emu/dp_flong.c 2003-08-24 02:55:57.000000000 -0700 @@ -33,6 +33,8 @@ CLEARCX; + xc = ( 0 ? xc : xc ); + if (x == 0) return ieee754dp_zero(0); if (x == 1 || x == -1) diff -urN linux-2.4.21-bk37/arch/mips/math-emu/ieee754dp.c linux-2.4.21-bk38/arch/mips/math-emu/ieee754dp.c --- linux-2.4.21-bk37/arch/mips/math-emu/ieee754dp.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/math-emu/ieee754dp.c 2003-08-24 02:55:57.000000000 -0700 @@ -69,7 +69,7 @@ if (!ieee754dp_issnan(r)) /* QNAN does not cause invalid op !! */ return r; - if (!SETCX(IEEE754_INVALID_OPERATION)) { + if (!SETANDTESTCX(IEEE754_INVALID_OPERATION)) { /* not enabled convert to a quiet NaN */ DPMANT(r) &= (~DP_MBIT(DP_MBITS-1)); if (ieee754dp_isnan(r)) diff -urN linux-2.4.21-bk37/arch/mips/math-emu/ieee754int.h linux-2.4.21-bk38/arch/mips/math-emu/ieee754int.h --- linux-2.4.21-bk37/arch/mips/math-emu/ieee754int.h 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/math-emu/ieee754int.h 2003-08-24 02:55:57.000000000 -0700 @@ -61,7 +61,10 @@ (ieee754_csr.cx = 0) #define SETCX(x) \ - (ieee754_csr.cx |= (x),ieee754_csr.sx |= (x),ieee754_csr.mx & (x)) + (ieee754_csr.cx |= (x),ieee754_csr.sx |= (x)) + +#define SETANDTESTCX(x) \ + (SETCX(x),ieee754_csr.mx & (x)) #define TSTX() \ (ieee754_csr.cx & ieee754_csr.mx) diff -urN linux-2.4.21-bk37/arch/mips/math-emu/ieee754sp.c linux-2.4.21-bk38/arch/mips/math-emu/ieee754sp.c --- linux-2.4.21-bk37/arch/mips/math-emu/ieee754sp.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/math-emu/ieee754sp.c 2003-08-24 02:55:57.000000000 -0700 @@ -70,7 +70,7 @@ if (!ieee754sp_issnan(r)) /* QNAN does not cause invalid op !! */ return r; - if (!SETCX(IEEE754_INVALID_OPERATION)) { + if (!SETANDTESTCX(IEEE754_INVALID_OPERATION)) { /* not enabled convert to a quiet NaN */ SPMANT(r) &= (~SP_MBIT(SP_MBITS-1)); if (ieee754sp_isnan(r)) diff -urN linux-2.4.21-bk37/arch/mips/math-emu/ieee754xcpt.c linux-2.4.21-bk38/arch/mips/math-emu/ieee754xcpt.c --- linux-2.4.21-bk37/arch/mips/math-emu/ieee754xcpt.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/math-emu/ieee754xcpt.c 2003-08-24 02:55:57.000000000 -0700 @@ -29,6 +29,7 @@ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. *************************************************************************/ +#include #include "ieee754.h" /* @@ -42,7 +43,7 @@ void ieee754_xcpt(struct ieee754xctx *xcp) { - printk("floating point exception in \"%s\", type=%s\n", + printk(KERN_DEBUG "floating point exception in \"%s\", type=%s\n", xcp->op, rtnames[xcp->rt]); } diff -urN linux-2.4.21-bk37/arch/mips/math-emu/kernel_linkage.c linux-2.4.21-bk38/arch/mips/math-emu/kernel_linkage.c --- linux-2.4.21-bk37/arch/mips/math-emu/kernel_linkage.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/math-emu/kernel_linkage.c 2003-08-24 02:55:57.000000000 -0700 @@ -90,3 +90,40 @@ return err; } +#ifdef CONFIG_MIPS64 +/* + * This is the o32 version + */ + +int fpu_emulator_save_context32(struct sigcontext32 *sc) +{ + int i; + int err = 0; + + for (i = 0; i < 32; i+=2) { + err |= + __put_user(current->thread.fpu.soft.regs[i], + &sc->sc_fpregs[i]); + } + err |= __put_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr); + err |= __put_user(fpuemuprivate.eir, &sc->sc_fpc_eir); + + return err; +} + +int fpu_emulator_restore_context32(struct sigcontext32 *sc) +{ + int i; + int err = 0; + + for (i = 0; i < 32; i+=2) { + err |= + __get_user(current->thread.fpu.soft.regs[i], + &sc->sc_fpregs[i]); + } + err |= __get_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr); + err |= __get_user(fpuemuprivate.eir, &sc->sc_fpc_eir); + + return err; +} +#endif diff -urN linux-2.4.21-bk37/arch/mips/math-emu/sp_cmp.c linux-2.4.21-bk38/arch/mips/math-emu/sp_cmp.c --- linux-2.4.21-bk37/arch/mips/math-emu/sp_cmp.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/math-emu/sp_cmp.c 2003-08-24 02:55:57.000000000 -0700 @@ -44,7 +44,7 @@ if (cmp & IEEE754_CUN) return 1; if (cmp & (IEEE754_CLT | IEEE754_CGT)) { - if (sig && SETCX(IEEE754_INVALID_OPERATION)) + if (sig && SETANDTESTCX(IEEE754_INVALID_OPERATION)) return ieee754si_xcpt(0, "fcmpf", x); } return 0; diff -urN linux-2.4.21-bk37/arch/mips/math-emu/sp_fint.c linux-2.4.21-bk38/arch/mips/math-emu/sp_fint.c --- linux-2.4.21-bk37/arch/mips/math-emu/sp_fint.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/math-emu/sp_fint.c 2003-08-24 02:55:57.000000000 -0700 @@ -33,6 +33,8 @@ CLEARCX; + xc = ( 0 ? xc : xc ); + if (x == 0) return ieee754sp_zero(0); if (x == 1 || x == -1) diff -urN linux-2.4.21-bk37/arch/mips/math-emu/sp_flong.c linux-2.4.21-bk38/arch/mips/math-emu/sp_flong.c --- linux-2.4.21-bk37/arch/mips/math-emu/sp_flong.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/math-emu/sp_flong.c 2003-08-24 02:55:57.000000000 -0700 @@ -33,6 +33,8 @@ CLEARCX; + xc = ( 0 ? xc : xc ); + if (x == 0) return ieee754sp_zero(0); if (x == 1 || x == -1) diff -urN linux-2.4.21-bk37/arch/mips/math-emu/sp_sqrt.c linux-2.4.21-bk38/arch/mips/math-emu/sp_sqrt.c --- linux-2.4.21-bk37/arch/mips/math-emu/sp_sqrt.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/math-emu/sp_sqrt.c 2003-08-24 02:55:57.000000000 -0700 @@ -29,7 +29,6 @@ ieee754sp ieee754sp_sqrt(ieee754sp x) { - int sign = (int) 0x80000000; int ix, s, q, m, t, i; unsigned int r; COMPXSP; diff -urN linux-2.4.21-bk37/arch/mips/math-emu/sp_sub.c linux-2.4.21-bk38/arch/mips/math-emu/sp_sub.c --- linux-2.4.21-bk37/arch/mips/math-emu/sp_sub.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/math-emu/sp_sub.c 2003-08-24 02:55:57.000000000 -0700 @@ -167,12 +167,12 @@ xe = xe; xs = ys; } - if (xm == 0) + if (xm == 0) { if (ieee754_csr.rm == IEEE754_RD) return ieee754sp_zero(1); /* round negative inf. => sign = -1 */ else return ieee754sp_zero(0); /* other round modes => sign = 1 */ - + } /* normalize to rounding precision */ while ((xm >> (SP_MBITS + 3)) == 0) { diff -urN linux-2.4.21-bk37/arch/mips/mips-boards/atlas/atlas_int.c linux-2.4.21-bk38/arch/mips/mips-boards/atlas/atlas_int.c --- linux-2.4.21-bk37/arch/mips/mips-boards/atlas/atlas_int.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mips-boards/atlas/atlas_int.c 2003-08-24 02:55:57.000000000 -0700 @@ -40,7 +40,6 @@ = (struct atlas_ictrl_regs *)ATLAS_ICTRL_REGS_BASE; extern asmlinkage void mipsIRQ(void); -extern void do_IRQ(int irq, struct pt_regs *regs); #if 0 #define DEBUG_INT(x...) printk(x) @@ -130,7 +129,7 @@ return; } -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void breakpoint(void); extern int remote_debug; #endif @@ -155,7 +154,7 @@ irq_desc[i].handler = &atlas_irq_type; } -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB if (remote_debug) { set_debug_traps(); breakpoint(); diff -urN linux-2.4.21-bk37/arch/mips/mips-boards/atlas/atlas_setup.c linux-2.4.21-bk38/arch/mips/mips-boards/atlas/atlas_setup.c --- linux-2.4.21-bk37/arch/mips/mips-boards/atlas/atlas_setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mips-boards/atlas/atlas_setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include @@ -38,7 +38,7 @@ char serial_console[20]; #endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void rs_kgdb_hook(int); extern void saa9730_kgdb_hook(void); extern void breakpoint(void); @@ -54,17 +54,13 @@ return "MIPS Atlas"; } -void __init bus_error_init(void) -{ -} - extern void mips_time_init(void); extern void mips_timer_setup(struct irqaction *irq); extern unsigned long mips_rtc_get_time(void); void __init atlas_setup(void) { -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB int rs_putDebugChar(char); char rs_getDebugChar(void); int saa9730_putDebugChar(char); @@ -90,7 +86,7 @@ } #endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) { int line; @@ -122,7 +118,7 @@ argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "nofpu")) != NULL) - mips_cpu.options &= ~MIPS_CPU_FPU; + cpu_data[0].options &= ~MIPS_CPU_FPU; rtc_ops = &atlas_rtc_ops; board_time_init = mips_time_init; diff -urN linux-2.4.21-bk37/arch/mips/mips-boards/generic/Makefile linux-2.4.21-bk38/arch/mips/mips-boards/generic/Makefile --- linux-2.4.21-bk37/arch/mips/mips-boards/generic/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mips-boards/generic/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -32,6 +32,6 @@ obj-$(CONFIG_MIPS_ATLAS) += time.o obj-$(CONFIG_MIPS_MALTA) += time.o obj-$(CONFIG_PCI) += pci.o -obj-$(CONFIG_REMOTE_DEBUG) += gdb_hook.o +obj-$(CONFIG_KGDB) += gdb_hook.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/mips-boards/generic/init.c linux-2.4.21-bk38/arch/mips/mips-boards/generic/init.c --- linux-2.4.21-bk37/arch/mips/mips-boards/generic/init.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mips-boards/generic/init.c 2003-08-24 02:55:57.000000000 -0700 @@ -25,14 +25,15 @@ #include #include #include -#include -#include +#include #include #include +#ifdef CONFIG_MIPS_MALTA +#include +#endif /* Environment variable */ -typedef struct -{ +typedef struct { char *name; char *val; } t_env_var; @@ -50,6 +51,11 @@ unsigned int mips_revision_corid; +/* + * Algorithmics Bonito64 system controller register base. + */ +char * const _bonito = (char *)KSEG1ADDR(BONITO_REG_BASE); + char *prom_getenv(char *envname) { /* @@ -62,21 +68,21 @@ i = strlen(envname); - while(prom_envp(index)) { + while (prom_envp(index)) { if(strncmp(envname, prom_envp(index), i) == 0) { return(prom_envp(index+1)); } index += 2; } - return(NULL); + return NULL; } static inline unsigned char str2hexnum(unsigned char c) { - if(c >= '0' && c <= '9') + if (c >= '0' && c <= '9') return c - '0'; - if(c >= 'a' && c <= 'f') + if (c >= 'a' && c <= 'f') return c - 'a' + 10; return 0; /* foo */ } @@ -85,7 +91,7 @@ { int i; - for(i = 0; i < 6; i++) { + for (i = 0; i < 6; i++) { unsigned char num; if((*str == '.') || (*str == ':')) @@ -138,14 +144,14 @@ * Setup the North bridge to do Master byte-lane swapping * when running in bigendian. */ -#if defined(__MIPSEL__) +#ifdef CONFIG_CPU_LITTLE_ENDIAN GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT | GT_PCI0_CMD_SBYTESWAP_BIT); #else GT_WRITE(GT_PCI0_CMD_OFS, 0); #endif -#if defined(CONFIG_MIPS_MALTA) +#ifdef CONFIG_MIPS_MALTA set_io_port_base(MALTA_GT_PORT_BASE); #else set_io_port_base(KSEG1); @@ -165,7 +171,7 @@ * Setup the North bridge to do Master byte-lane swapping * when running in bigendian. */ -#if defined(__MIPSEL__) +#ifdef CONFIG_CPU_LITTLE_ENDIAN BONITO_BONGENCFG = BONITO_BONGENCFG & ~(BONITO_BONGENCFG_MSTRBYTESWAP | BONITO_BONGENCFG_BYTESWAP); @@ -175,16 +181,18 @@ BONITO_BONGENCFG_BYTESWAP; #endif -#if defined(CONFIG_MIPS_MALTA) - set_io_port_base(MALTA_BONITO_PORT_BASE); +#ifdef CONFIG_MIPS_MALTA + set_io_port_base(MALTA_BONITO_PORT_BASE); #else - set_io_port_base(KSEG1); + set_io_port_base(KSEG1); #endif break; case MIPS_REVISION_CORID_CORE_MSC: - set_io_port_base(MALTA_MSC_PORT_BASE); -#if defined(__MIPSEL__) +#ifdef CONFIG_MIPS_MALTA + set_io_port_base(MALTA_MSC_PORT_BASE); +#endif +#ifdef CONFIG_CPU_LITTLE_ENDIAN MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP); #else MSC_WRITE(MSC01_PCI_SWAP, @@ -199,7 +207,6 @@ while(1); /* We die here... */ } #endif - setup_prom_printf(0); prom_printf("\nLINUX started...\n"); prom_init_cmdline(); prom_meminit(); diff -urN linux-2.4.21-bk37/arch/mips/mips-boards/generic/memory.c linux-2.4.21-bk38/arch/mips/mips-boards/generic/memory.c --- linux-2.4.21-bk37/arch/mips/mips-boards/generic/memory.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mips-boards/generic/memory.c 2003-08-24 02:55:57.000000000 -0700 @@ -168,7 +168,7 @@ + boot_mem_map.map[i].size) { ClearPageReserved(virt_to_page(__va(addr))); set_page_count(virt_to_page(__va(addr)), 1); - free_page(__va(addr)); + free_page((unsigned long)__va(addr)); addr += PAGE_SIZE; freed += PAGE_SIZE; } diff -urN linux-2.4.21-bk37/arch/mips/mips-boards/generic/pci.c linux-2.4.21-bk38/arch/mips/mips-boards/generic/pci.c --- linux-2.4.21-bk37/arch/mips/mips-boards/generic/pci.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mips-boards/generic/pci.c 2003-08-24 02:55:57.000000000 -0700 @@ -1,6 +1,6 @@ /* * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as @@ -16,442 +16,31 @@ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * * MIPS boards specific PCI support. - * */ #include - -#ifdef CONFIG_PCI - #include #include #include #include #include -#include +#include #include #ifdef CONFIG_MIPS_MALTA #include #endif #include -#define PCI_ACCESS_READ 0 -#define PCI_ACCESS_WRITE 1 - -/* - * PCI configuration cycle AD bus definition - */ -/* Type 0 */ -#define PCI_CFG_TYPE0_REG_SHF 0 -#define PCI_CFG_TYPE0_FUNC_SHF 8 - -/* Type 1 */ -#define PCI_CFG_TYPE1_REG_SHF 0 -#define PCI_CFG_TYPE1_FUNC_SHF 8 -#define PCI_CFG_TYPE1_DEV_SHF 11 -#define PCI_CFG_TYPE1_BUS_SHF 16 - -static int -mips_pcibios_config_access(unsigned char access_type, struct pci_dev *dev, - unsigned char where, u32 *data) -{ - unsigned char bus = dev->bus->number; - unsigned char dev_fn = dev->devfn; - unsigned char type; - u32 intr, dummy; - u64 pci_addr; - - switch(mips_revision_corid) { - case MIPS_REVISION_CORID_QED_RM5261: - case MIPS_REVISION_CORID_CORE_LV: - case MIPS_REVISION_CORID_CORE_FPGA: - /* Galileo GT64120 system controller. */ - - if ((bus == 0) && (dev_fn >= PCI_DEVFN(31,0))) - return -1; /* Because of a bug in the galileo (for slot 31). */ - - /* Clear cause register bits */ - GT_READ(GT_INTRCAUSE_OFS, intr); - GT_WRITE(GT_INTRCAUSE_OFS, intr & - ~(GT_INTRCAUSE_MASABORT0_BIT | - GT_INTRCAUSE_TARABORT0_BIT)); - - /* Setup address */ - GT_WRITE(GT_PCI0_CFGADDR_OFS, - (bus << GT_PCI0_CFGADDR_BUSNUM_SHF) | - (dev_fn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | - ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | - GT_PCI0_CFGADDR_CONFIGEN_BIT); - - if (access_type == PCI_ACCESS_WRITE) { - if (bus == 0 && dev_fn == 0) { - /* - * The Galileo system controller is acting - * differently than other devices. - */ - GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); - } else { - GT_PCI_WRITE(GT_PCI0_CFGDATA_OFS, *data); - } - } else { - if (bus == 0 && dev_fn == 0) { - /* - * The Galileo system controller is acting - * differently than other devices. - */ - GT_READ(GT_PCI0_CFGDATA_OFS, *data); - } else { - GT_PCI_READ(GT_PCI0_CFGDATA_OFS, *data); - } - } - - /* Check for master or target abort */ - GT_READ(GT_INTRCAUSE_OFS, intr); - - if (intr & (GT_INTRCAUSE_MASABORT0_BIT | - GT_INTRCAUSE_TARABORT0_BIT)) - { - /* Error occured */ - - /* Clear bits */ - GT_READ(GT_INTRCAUSE_OFS, intr); - GT_WRITE(GT_INTRCAUSE_OFS, intr & - ~(GT_INTRCAUSE_MASABORT0_BIT | - GT_INTRCAUSE_TARABORT0_BIT)); - - return -1; - } - - break; - - case MIPS_REVISION_CORID_BONITO64: - case MIPS_REVISION_CORID_CORE_20K: - /* Algorithmics Bonito64 system controller. */ - - if ((bus == 0) && (PCI_SLOT(dev_fn) == 0)) { - return -1; - } - - /* Clear cause register bits */ - BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | - BONITO_PCICMD_MTABORT_CLR); - - /* - * Setup pattern to be used as PCI "address" for - * Type 0 cycle - */ - if (bus == 0) { - /* IDSEL */ - pci_addr = (u64)1 << (PCI_SLOT(dev_fn) + 10); - } else { - /* Bus number */ - pci_addr = bus << PCI_CFG_TYPE1_BUS_SHF; - - /* Device number */ - pci_addr |= PCI_SLOT(dev_fn) << PCI_CFG_TYPE1_DEV_SHF; - } - - /* Function (same for Type 0/1) */ - pci_addr |= PCI_FUNC(dev_fn) << PCI_CFG_TYPE0_FUNC_SHF; - - /* Register number (same for Type 0/1) */ - pci_addr |= (where & ~0x3) << PCI_CFG_TYPE0_REG_SHF; - - if (bus == 0) { - /* Type 0 */ - BONITO_PCIMAP_CFG = pci_addr >> 16; - } else { - /* Type 1 */ - BONITO_PCIMAP_CFG = (pci_addr >> 16) | 0x10000; - } - - /* Flush Bonito register block */ - dummy = BONITO_PCIMAP_CFG; - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "sync\n\t" - ".set\tat\n\t" - ".set\treorder"); - - /* Perform access */ - if (access_type == PCI_ACCESS_WRITE) { - *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE + - (pci_addr & 0xffff))) = *(u32 *)data; - - /* Wait till done */ - while (BONITO_PCIMSTAT & 0xF) - ; - } else { - *(u32 *)data = - *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE + - (pci_addr & 0xffff))); - } - - /* Detect Master/Target abort */ - if (BONITO_PCICMD & (BONITO_PCICMD_MABORT_CLR | - BONITO_PCICMD_MTABORT_CLR) ) - { - /* Error occurred */ - - /* Clear bits */ - BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | - BONITO_PCICMD_MTABORT_CLR); - - return -1; - } - break; - - case MIPS_REVISION_CORID_CORE_MSC: - /* MIPS system controller. */ - - if ((bus == 0) && (PCI_SLOT(dev_fn) == 0)) { - return -1; - } - - /* Clear status register bits. */ - MSC_WRITE(MSC01_PCI_INTSTAT, - (MSC01_PCI_INTCFG_MA_BIT | - MSC01_PCI_INTCFG_TA_BIT)); - - /* Setup address */ - if (bus == 0) - type = 0; /* Type 0 */ - else - type = 1; /* Type 1 */ - - MSC_WRITE(MSC01_PCI_CFGADDR, - ((bus << MSC01_PCI_CFGADDR_BNUM_SHF) | - (PCI_SLOT(dev_fn) << MSC01_PCI_CFGADDR_DNUM_SHF) | - (PCI_FUNC(dev_fn) << MSC01_PCI_CFGADDR_FNUM_SHF) | - ((where /4 ) << MSC01_PCI_CFGADDR_RNUM_SHF) | - (type))); - - /* Perform access */ - if (access_type == PCI_ACCESS_WRITE) { - MSC_WRITE(MSC01_PCI_CFGDATA, *data); - } else { - MSC_READ(MSC01_PCI_CFGDATA, *data); - } - - /* Detect Master/Target abort */ - MSC_READ(MSC01_PCI_INTSTAT, intr); - if (intr & (MSC01_PCI_INTCFG_MA_BIT | - MSC01_PCI_INTCFG_TA_BIT)) - { - /* Error occurred */ - - /* Clear bits */ - MSC_READ(MSC01_PCI_INTSTAT, intr); - MSC_WRITE(MSC01_PCI_INTSTAT, - (MSC01_PCI_INTCFG_MA_BIT | - MSC01_PCI_INTCFG_TA_BIT)); - - return -1; - } - break; - default: - printk("Unknown Core card, don't know the system controller.\n"); - return -1; - } - - return 0; -} - - -/* - * We can't address 8 and 16 bit words directly. Instead we have to - * read/write a 32bit word and mask/modify the data we actually want. - */ -static int -mips_pcibios_read_config_byte (struct pci_dev *dev, int where, u8 *val) -{ - u32 data = 0; - - if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - *val = (data >> ((where & 3) << 3)) & 0xff; - - return PCIBIOS_SUCCESSFUL; -} - - -static int -mips_pcibios_read_config_word (struct pci_dev *dev, int where, u16 *val) -{ - u32 data = 0; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - *val = (data >> ((where & 3) << 3)) & 0xffff; +extern struct pci_ops bonito64_pci_ops; +extern struct pci_ops gt64120_pci_ops; +extern struct pci_ops msc_pci_ops; - return PCIBIOS_SUCCESSFUL; -} - -static int -mips_pcibios_read_config_dword (struct pci_dev *dev, int where, u32 *val) -{ - u32 data = 0; - - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - *val = data; - - return PCIBIOS_SUCCESSFUL; -} - - -static int -mips_pcibios_write_config_byte (struct pci_dev *dev, int where, u8 val) -{ - u32 data = 0; - - if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - data = (data & ~(0xff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - - if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data)) - return -1; - - return PCIBIOS_SUCCESSFUL; -} - -static int -mips_pcibios_write_config_word (struct pci_dev *dev, int where, u16 val) -{ - u32 data = 0; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - data = (data & ~(0xffff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - - if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data)) - return -1; - - - return PCIBIOS_SUCCESSFUL; -} - -static int -mips_pcibios_write_config_dword(struct pci_dev *dev, int where, u32 val) -{ - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &val)) - return -1; - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops mips_pci_ops = { - mips_pcibios_read_config_byte, - mips_pcibios_read_config_word, - mips_pcibios_read_config_dword, - mips_pcibios_write_config_byte, - mips_pcibios_write_config_word, - mips_pcibios_write_config_dword -}; - -int mips_pcibios_iack(void) -{ - int irq; - u32 dummy; - - /* - * Determine highest priority pending interrupt by performing - * a PCI Interrupt Acknowledge cycle. - */ - switch(mips_revision_corid) { - case MIPS_REVISION_CORID_QED_RM5261: - case MIPS_REVISION_CORID_CORE_LV: - case MIPS_REVISION_CORID_CORE_FPGA: - case MIPS_REVISION_CORID_CORE_MSC: - if (mips_revision_corid == MIPS_REVISION_CORID_CORE_MSC) - MSC_READ(MSC01_PCI_IACK, irq); - else - GT_READ(GT_PCI0_IACK_OFS, irq); - irq &= 0xff; - break; - case MIPS_REVISION_CORID_BONITO64: - case MIPS_REVISION_CORID_CORE_20K: - /* The following will generate a PCI IACK cycle on the - * Bonito controller. It's a little bit kludgy, but it - * was the easiest way to implement it in hardware at - * the given time. - */ - BONITO_PCIMAP_CFG = 0x20000; - - /* Flush Bonito register block */ - dummy = BONITO_PCIMAP_CFG; - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "sync\n\t" - ".set\tat\n\t" - ".set\treorder"); - - irq = *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE)); - irq &= 0xff; - BONITO_PCIMAP_CFG = 0; - break; - default: - printk("Unknown Core card, don't know the system controller.\n"); - return -1; - } - return irq; -} - -void __init pcibios_init(void) +static void __init malta_fixup(void) { #ifdef CONFIG_MIPS_MALTA struct pci_dev *pdev; unsigned char reg_val; -#endif - printk("PCI: Probing PCI hardware on host bus 0.\n"); - pci_scan_bus(0, &mips_pci_ops, NULL); - - switch(mips_revision_corid) { - case MIPS_REVISION_CORID_QED_RM5261: - case MIPS_REVISION_CORID_CORE_LV: - case MIPS_REVISION_CORID_CORE_FPGA: - /* - * Due to a bug in the Galileo system controller, we need - * to setup the PCI BAR for the Galileo internal registers. - * This should be done in the bios/bootprom and will be - * fixed in a later revision of YAMON (the MIPS boards - * boot prom). - */ - GT_WRITE(GT_PCI0_CFGADDR_OFS, - (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */ - (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */ - (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/ - ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/ - GT_PCI0_CFGADDR_CONFIGEN_BIT ); - - /* Perform the write */ - GT_WRITE( GT_PCI0_CFGDATA_OFS, PHYSADDR(MIPS_GT_BASE)); - break; - } - -#ifdef CONFIG_MIPS_MALTA pci_for_each_dev(pdev) { if ((pdev->vendor == PCI_VENDOR_ID_INTEL) && (pdev->device == PCI_DEVICE_ID_INTEL_82371AB) @@ -497,57 +86,61 @@ #endif } -int __init -pcibios_enable_device(struct pci_dev *dev) +void __init pcibios_init(void) { - /* Not needed, since we enable all devices at startup. */ - return 0; -} + printk("PCI: Probing PCI hardware on host bus 0.\n"); -void __init -pcibios_align_resource(void *data, struct resource *res, unsigned long size, - unsigned long align) -{ -} + switch (mips_revision_corid) { + case MIPS_REVISION_CORID_QED_RM5261: + case MIPS_REVISION_CORID_CORE_LV: + case MIPS_REVISION_CORID_CORE_FPGA: + /* + * Due to a bug in the Galileo system controller, we need + * to setup the PCI BAR for the Galileo internal registers. + * This should be done in the bios/bootprom and will be + * fixed in a later revision of YAMON (the MIPS boards + * boot prom). + */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */ + (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */ + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/ + ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/ + GT_PCI0_CFGADDR_CONFIGEN_BIT ); -char * __init -pcibios_setup(char *str) -{ - /* Nothing to do for now. */ + /* Perform the write */ + GT_WRITE( GT_PCI0_CFGDATA_OFS, PHYSADDR(GT64120_BASE)); + + pci_scan_bus(0, >64120_pci_ops, NULL); + break; + + case MIPS_REVISION_CORID_BONITO64: + case MIPS_REVISION_CORID_CORE_20K: + pci_scan_bus(0, &bonito64_pci_ops, NULL); + break; + + case MIPS_REVISION_CORID_CORE_MSC: + pci_scan_bus(0, &msc_pci_ops, NULL); + break; + } - return str; + malta_fixup(); } struct pci_fixup pcibios_fixups[] = { { 0 } }; -void __init -pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - unsigned long where, size; - u32 reg; - - where = PCI_BASE_ADDRESS_0 + (resource * 4); - size = res->end - res->start; - pci_read_config_dword(dev, where, ®); - reg = (reg & size) | (((u32)(res->start - root->start)) & ~size); - pci_write_config_dword(dev, where, reg); -} - /* * Called after each bus is probed, but before its children * are examined. */ -void __init pcibios_fixup_bus(struct pci_bus *b) +void __devinit pcibios_fixup_bus(struct pci_bus *b) { pci_read_bridge_bases(b); } -unsigned __init int pcibios_assign_all_busses(void) +unsigned int pcibios_assign_all_busses(void) { return 1; } - -#endif /* CONFIG_PCI */ diff -urN linux-2.4.21-bk37/arch/mips/mips-boards/generic/printf.c linux-2.4.21-bk38/arch/mips/mips-boards/generic/printf.c --- linux-2.4.21-bk37/arch/mips/mips-boards/generic/printf.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mips-boards/generic/printf.c 2003-08-24 02:55:57.000000000 -0700 @@ -2,8 +2,6 @@ * Carsten Langgaard, carstenl@mips.com * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. * - * ######################################################################## - * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. @@ -17,101 +15,84 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * - * ######################################################################## - * * Putting things on the screen/serial line using YAMONs facilities. - * */ #include #include #include -#include #include -#include +#include #include -#include +#ifdef CONFIG_MIPS_ATLAS + +#include -#if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_SEAD) /* * Atlas registers are memory mapped on 64-bit aligned boundaries and * only word access are allowed. * When reading the UART 8 bit registers only the LSB are valid. */ -unsigned int atlas_serial_in(struct async_struct *info, int offset) +static inline unsigned int serial_in(int offset) { - return (*(volatile unsigned int *)(info->port + mips_io_port_base + offset*8) & 0xff); + return (*(volatile unsigned int *)(mips_io_port_base + ATLAS_UART_REGS_BASE + offset*8) & 0xff); } -void atlas_serial_out(struct async_struct *info, int offset, int value) +static inline void serial_out(int offset, int value) { - *(volatile unsigned int *)(info->port + mips_io_port_base + offset*8) = value; + *(volatile unsigned int *)(mips_io_port_base + ATLAS_UART_REGS_BASE + offset*8) = value; } -#define serial_in atlas_serial_in -#define serial_out atlas_serial_out +#elif defined(CONFIG_MIPS_SEAD) -#else +#include -static unsigned int serial_in(struct async_struct *info, int offset) +/* + * SEAD registers are just like Atlas registers. + */ +static inline unsigned int serial_in(int offset) { - return inb(info->port + offset); + return (*(volatile unsigned int *)(mips_io_port_base + SEAD_UART0_REGS_BASE + offset*8) & 0xff); } -static void serial_out(struct async_struct *info, int offset, - int value) +static inline void serial_out(int offset, int value) { - outb(value, info->port + offset); + *(volatile unsigned int *)(mips_io_port_base + SEAD_UART0_REGS_BASE + offset*8) = value; } -#endif - -static struct serial_state rs_table[] = { - SERIAL_PORT_DFNS /* Defined in serial.h */ -}; - -/* - * Hooks to fake "prom" console I/O before devices - * are fully initialized. - */ -static struct async_struct prom_port_info = {0}; -void __init setup_prom_printf(int tty_no) { - struct serial_state *ser = &rs_table[tty_no]; +#else - prom_port_info.state = ser; - prom_port_info.magic = SERIAL_MAGIC; - prom_port_info.port = ser->port; - prom_port_info.flags = ser->flags; +static inline unsigned int serial_in(int offset) +{ + return inb(0x3f8 + offset); +} - /* No setup of UART - assume YAMON left in sane state */ +static inline void serial_out(int offset, int value) +{ + outb(value, 0x3f8 + offset); } +#endif int putPromChar(char c) { - if (!prom_port_info.state) { /* need to init device first */ - return 0; - } - - while ((serial_in(&prom_port_info, UART_LSR) & UART_LSR_THRE) == 0) + while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0) ; - serial_out(&prom_port_info, UART_TX, c); + serial_out(UART_TX, c); return 1; } char getPromChar(void) { - if (!prom_port_info.state) { /* need to init device first */ - return 0; - } - - while (!(serial_in(&prom_port_info, UART_LSR) & 1)) + while (!(serial_in(UART_LSR) & 1)) ; - return(serial_in(&prom_port_info, UART_RX)); + return serial_in(UART_RX); } +static spinlock_t con_lock = SPIN_LOCK_UNLOCKED; + static char buf[1024]; void __init prom_printf(char *fmt, ...) @@ -123,8 +104,7 @@ int putPromChar(char); - /* Low level, brute force, not SMP safe... */ - save_and_cli(flags); + spin_lock_irqsave(con_lock, flags); va_start(args, fmt); l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */ va_end(args); @@ -133,8 +113,9 @@ for (p = buf; p < buf_end; p++) { /* Crude cr/nl handling is better than none */ - if(*p == '\n')putPromChar('\r'); + if (*p == '\n') + putPromChar('\r'); putPromChar(*p); } - restore_flags(flags); + spin_unlock_irqrestore(con_lock, flags); } diff -urN linux-2.4.21-bk37/arch/mips/mips-boards/generic/time.c linux-2.4.21-bk38/arch/mips/mips-boards/generic/time.c --- linux-2.4.21-bk37/arch/mips/mips-boards/generic/time.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mips-boards/generic/time.c 2003-08-24 02:55:57.000000000 -0700 @@ -65,7 +65,7 @@ static inline void ack_r4ktimer(unsigned int newval) { - write_32bit_cp0_register(CP0_COMPARE, newval); + write_c0_compare(newval); } void mips_timer_interrupt(struct pt_regs *regs) @@ -87,25 +87,25 @@ */ static unsigned int __init cal_r4koff(void) { - unsigned int flags; + unsigned long flags; - __save_and_cli(flags); + local_irq_save(flags); /* Start counter exactly on falling edge of update flag */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); /* Start r4k counter. */ - write_32bit_cp0_register(CP0_COUNT, 0); + write_c0_count(0); /* Read counter exactly on falling edge of update flag */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); - mips_counter_frequency = read_32bit_cp0_register(CP0_COUNT); + mips_counter_frequency = read_c0_count(); /* restore interrupts */ - __restore_flags(flags); + local_irq_restore(flags); return (mips_counter_frequency / HZ); } @@ -147,9 +147,10 @@ void __init mips_time_init(void) { - unsigned int est_freq, flags; + unsigned long flags; + unsigned int est_freq; - __save_and_cli(flags); + local_irq_save(flags); /* Set Data mode - binary. */ CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); @@ -158,7 +159,7 @@ r4k_offset = cal_r4koff(); printk("%08x(%d)\n", r4k_offset, r4k_offset); - if ((read_32bit_cp0_register(CP0_PRID) & 0xffff00) == + if ((read_c0_prid() & 0xffff00) == (PRID_COMP_MIPS | PRID_IMP_20KC)) est_freq = r4k_offset*HZ; else @@ -169,7 +170,7 @@ printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, (est_freq%1000000)*100/1000000); - __restore_flags(flags); + local_irq_restore(flags); } void __init mips_timer_setup(struct irqaction *irq) @@ -179,7 +180,7 @@ setup_irq(MIPS_CPU_TIMER_IRQ, irq); /* to generate the first timer interrupt */ - r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset); - write_32bit_cp0_register(CP0_COMPARE, r4k_cur); - set_cp0_status(ALLINTS); + r4k_cur = (read_c0_count() + r4k_offset); + write_c0_compare(r4k_cur); + set_c0_status(ALLINTS); } diff -urN linux-2.4.21-bk37/arch/mips/mips-boards/malta/malta_int.c linux-2.4.21-bk38/arch/mips/mips-boards/malta/malta_int.c --- linux-2.4.21-bk37/arch/mips/mips-boards/malta/malta_int.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mips-boards/malta/malta_int.c 2003-08-24 02:55:57.000000000 -0700 @@ -23,28 +23,83 @@ */ #include #include +#include #include #include #include #include #include -#include +#include #include #include #include #include -#include +#include #include #include extern asmlinkage void mipsIRQ(void); -extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs); -extern void init_i8259_irqs (void); extern int mips_pcibios_iack(void); +#ifdef CONFIG_KGDB +extern void breakpoint(void); +extern void set_debug_traps(void); +extern int remote_debug; +#endif + static spinlock_t mips_irq_lock = SPIN_LOCK_UNLOCKED; +/* + * Algorithmics Bonito64 system controller register base. + */ +static char * const _bonito = (char *)KSEG1ADDR(BONITO_REG_BASE); + +static inline int mips_pcibios_iack(void) +{ + int irq; + u32 dummy; + + /* + * Determine highest priority pending interrupt by performing + * a PCI Interrupt Acknowledge cycle. + */ + switch(mips_revision_corid) { + case MIPS_REVISION_CORID_QED_RM5261: + case MIPS_REVISION_CORID_CORE_LV: + case MIPS_REVISION_CORID_CORE_FPGA: + case MIPS_REVISION_CORID_CORE_MSC: + if (mips_revision_corid == MIPS_REVISION_CORID_CORE_MSC) + MSC_READ(MSC01_PCI_IACK, irq); + else + irq = GT_READ(GT_PCI0_IACK_OFS); + irq &= 0xff; + break; + case MIPS_REVISION_CORID_BONITO64: + case MIPS_REVISION_CORID_CORE_20K: + /* The following will generate a PCI IACK cycle on the + * Bonito controller. It's a little bit kludgy, but it + * was the easiest way to implement it in hardware at + * the given time. + */ + BONITO_PCIMAP_CFG = 0x20000; + + /* Flush Bonito register block */ + dummy = BONITO_PCIMAP_CFG; + iob(); /* sync */ + + irq = *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE)); + iob(); /* sync */ + irq &= 0xff; + BONITO_PCIMAP_CFG = 0; + break; + default: + printk("Unknown Core card, don't know the system controller.\n"); + return -1; + } + return irq; +} + static inline int get_int(int *irq) { unsigned long flags; @@ -91,6 +146,9 @@ { unsigned int data,datahi; + /* Mask out corehi interrupt. */ + clear_c0_status(IE_IRQ3); + printk("CoreHI interrupt, shouldn't happen, so we die here!!!\n"); printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\nbadVaddr : %08lx\n" , regs->cp0_epc, regs->cp0_status, regs->cp0_cause, regs->cp0_badvaddr); @@ -100,10 +158,10 @@ case MIPS_REVISION_CORID_QED_RM5261: case MIPS_REVISION_CORID_CORE_LV: case MIPS_REVISION_CORID_CORE_FPGA: - GT_READ(GT_INTRCAUSE_OFS, data); + data = GT_READ(GT_INTRCAUSE_OFS); printk("GT_INTRCAUSE = %08x\n", data); - GT_READ(0x70, data); - GT_READ(0x78, datahi); + data = GT_READ(0x70); + datahi = GT_READ(0x78); printk("GT_CPU_ERR_ADDR = %0x2%08x\n", datahi,data); break; case MIPS_REVISION_CORID_BONITO64: @@ -125,7 +183,6 @@ /* We die here*/ die("CoreHi interrupt", regs); - while (1) ; } void __init init_IRQ(void) @@ -134,7 +191,7 @@ init_generic_irq(); init_i8259_irqs(); -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB if (remote_debug) { set_debug_traps(); breakpoint(); diff -urN linux-2.4.21-bk37/arch/mips/mips-boards/malta/malta_setup.c linux-2.4.21-bk38/arch/mips/mips-boards/malta/malta_setup.c --- linux-2.4.21-bk37/arch/mips/mips-boards/malta/malta_setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mips-boards/malta/malta_setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -50,11 +50,9 @@ char serial_console[20]; #endif -#ifdef CONFIG_REMOTE_DEBUG -extern void set_debug_traps(void); +#ifdef CONFIG_KGDB extern void rs_kgdb_hook(int); -extern void breakpoint(void); -static int remote_debug = 0; +int remote_debug = 0; #endif extern struct ide_ops std_ide_ops; @@ -64,9 +62,6 @@ extern void mips_reboot_setup(void); -extern void (*board_time_init)(void); -extern void (*board_timer_setup)(struct irqaction *irq); -extern unsigned long (*rtc_get_time)(void); extern void mips_time_init(void); extern void mips_timer_setup(struct irqaction *irq); extern unsigned long mips_rtc_get_time(void); @@ -85,17 +80,13 @@ return "MIPS Malta"; } -void __init bus_error_init(void) -{ -} - void __init malta_setup(void) { -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB int rs_putDebugChar(char); char rs_getDebugChar(void); - extern int (*putDebugChar)(char); - extern char (*getDebugChar)(void); + extern int (*generic_putDebugChar)(char); + extern char (*generic_getDebugChar)(void); #endif char *argptr; int i; @@ -117,7 +108,7 @@ } #endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) { int line; @@ -130,8 +121,8 @@ line ? 1 : 0); rs_kgdb_hook(line); - putDebugChar = rs_putDebugChar; - getDebugChar = rs_getDebugChar; + generic_putDebugChar = rs_putDebugChar; + generic_getDebugChar = rs_getDebugChar; prom_printf("KGDB: Using serial line /dev/ttyS%d for session, " "please connect your debugger\n", line ? 1 : 0); @@ -143,7 +134,7 @@ argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "nofpu")) != NULL) - mips_cpu.options &= ~MIPS_CPU_FPU; + cpu_data[0].options &= ~MIPS_CPU_FPU; rtc_ops = &malta_rtc_ops; diff -urN linux-2.4.21-bk37/arch/mips/mips-boards/sead/sead_int.c linux-2.4.21-bk38/arch/mips/mips-boards/sead/sead_int.c --- linux-2.4.21-bk37/arch/mips/mips-boards/sead/sead_int.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mips-boards/sead/sead_int.c 2003-08-24 02:55:57.000000000 -0700 @@ -25,34 +25,33 @@ */ #include #include +#include #include #include #include #include -#include #include #include extern asmlinkage void mipsIRQ(void); -extern void do_IRQ(int irq, struct pt_regs *regs); void disable_sead_irq(unsigned int irq_nr) { if (irq_nr == SEADINT_UART0) - clear_cp0_status(0x00000400); + clear_c0_status(0x00000400); else if (irq_nr == SEADINT_UART1) - clear_cp0_status(0x00000800); + clear_c0_status(0x00000800); } void enable_sead_irq(unsigned int irq_nr) { if (irq_nr == SEADINT_UART0) - set_cp0_status(0x00000400); + set_c0_status(0x00000400); else if (irq_nr == SEADINT_UART1) - set_cp0_status(0x00000800); + set_c0_status(0x00000800); } static unsigned int startup_sead_irq(unsigned int irq) @@ -99,14 +98,14 @@ /* * Mask out all interrupt */ - clear_cp0_status(0x0000ff00); + clear_c0_status(0x0000ff00); /* Now safe to set the exception vector. */ set_except_vector(0, mipsIRQ); init_generic_irq(); - for (i = 0; i <= SEADINT_END; i++) { + for (i = 0; i < SEADINT_END; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; diff -urN linux-2.4.21-bk37/arch/mips/mips-boards/sead/sead_setup.c linux-2.4.21-bk38/arch/mips/mips-boards/sead/sead_setup.c --- linux-2.4.21-bk37/arch/mips/mips-boards/sead/sead_setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mips-boards/sead/sead_setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -45,10 +45,6 @@ return "MIPS SEAD"; } -void __init bus_error_init(void) -{ -} - void __init sead_setup(void) { char *argptr; @@ -72,7 +68,7 @@ argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "nofpu")) != NULL) - mips_cpu.options &= ~MIPS_CPU_FPU; + cpu_data[0].options &= ~MIPS_CPU_FPU; board_time_init = mips_time_init; board_timer_setup = mips_timer_setup; diff -urN linux-2.4.21-bk37/arch/mips/mips-boards/sead/sead_time.c linux-2.4.21-bk38/arch/mips/mips-boards/sead/sead_time.c --- linux-2.4.21-bk37/arch/mips/mips-boards/sead/sead_time.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mips-boards/sead/sead_time.c 2003-08-24 02:55:57.000000000 -0700 @@ -59,7 +59,7 @@ static inline void ack_r4ktimer(unsigned long newval) { - write_32bit_cp0_register(CP0_COMPARE, newval); + write_c0_compare(newval); } /* @@ -87,7 +87,7 @@ r4k_cur += r4k_offset; ack_r4ktimer(r4k_cur); - } while (((unsigned long)read_32bit_cp0_register(CP0_COUNT) + } while (((unsigned long)read_c0_count() - r4k_cur) < 0x7fffffff); irq_exit(cpu, irq); @@ -111,18 +111,19 @@ void __init mips_time_init(void) { - unsigned int est_freq, flags; + unsigned long flags; + unsigned int est_freq; - __save_and_cli(flags); + local_irq_save(flags); /* Start r4k counter. */ - write_32bit_cp0_register(CP0_COUNT, 0); + write_c0_count(0); printk("calculating r4koff... "); r4k_offset = cal_r4koff(); printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset); - if ((read_32bit_cp0_register(CP0_PRID) & 0xffff00) == + if ((read_c0_prid() & 0xffff00) == (PRID_COMP_MIPS | PRID_IMP_20KC)) est_freq = r4k_offset*HZ; else @@ -133,7 +134,7 @@ printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, (est_freq%1000000)*100/1000000); - __restore_flags(flags); + local_irq_restore(flags); } void __init mips_timer_setup(struct irqaction *irq) @@ -143,7 +144,7 @@ setup_irq(MIPS_CPU_TIMER_IRQ, irq); /* to generate the first timer interrupt */ - r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset); - write_32bit_cp0_register(CP0_COMPARE, r4k_cur); - set_cp0_status(ALLINTS); + r4k_cur = (read_c0_count() + r4k_offset); + write_c0_compare(r4k_cur); + set_c0_status(ALLINTS); } diff -urN linux-2.4.21-bk37/arch/mips/mm/Makefile linux-2.4.21-bk38/arch/mips/mm/Makefile --- linux-2.4.21-bk37/arch/mips/mm/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -10,28 +10,29 @@ O_TARGET := mm.o -export-objs += ioremap.o loadmmu.o umap.o -obj-y += extable.o init.o ioremap.o fault.o loadmmu.o +export-objs += cache.o ioremap.o loadmmu.o remap.o +obj-y += cache.o extable.o init.o ioremap.o fault.o \ + loadmmu.o -obj-$(CONFIG_CPU_R3000) += pg-r3k.o c-r3k.o c-tx39.o tlb-r3k.o \ - tlbex-r3k.o +obj-$(CONFIG_CPU_R3000) += pg-r3k.o c-r3k.o tlb-r3k.o tlbex-r3k.o obj-$(CONFIG_CPU_TX39XX) += pg-r3k.o c-tx39.o tlb-r3k.o tlbex-r3k.o -obj-$(CONFIG_CPU_TX49XX) += pg-r4k.o c-tx49.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_TX49XX) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o obj-$(CONFIG_CPU_R4300) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o obj-$(CONFIG_CPU_R4X00) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o obj-$(CONFIG_CPU_VR41XX) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o -obj-$(CONFIG_CPU_R5000) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o \ - r5k-sc.o -obj-$(CONFIG_CPU_NEVADA) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o \ - r5k-sc.o -obj-$(CONFIG_CPU_R5432) += pg-r5432.o c-r5432.o tlb-r4k.o tlbex-r4k.o -obj-$(CONFIG_CPU_RM7000) += pg-rm7k.o c-rm7k.o tlb-r4k.o tlbex-r4k.o -obj-$(CONFIG_CPU_R10000) += pg-andes.o c-andes.o tlb-r4k.o tlbex-r4k.o -obj-$(CONFIG_CPU_MIPS32) += pg-mips32.o c-mips32.o tlb-r4k.o tlbex-r4k.o -obj-$(CONFIG_CPU_MIPS64) += pg-mips32.o c-mips32.o tlb-r4k.o tlbex-r4k.o -obj-$(CONFIG_CPU_SB1) += pg-sb1.o c-sb1.o tlb-sb1.o tlbex-r4k.o +obj-$(CONFIG_CPU_R5000) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_NEVADA) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_R5432) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_RM7000) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_R10000) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_MIPS32) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-mips32.o +obj-$(CONFIG_CPU_MIPS64) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_SB1) += pg-sb1.o c-sb1.o tlb-sb1.o tlbex-r4k.o \ + cex-sb1.o cerr-sb1.o -obj-$(CONFIG_SGI_IP22) += umap.o -obj-$(CONFIG_BAGET_MIPS) += umap.o +obj-$(CONFIG_64BIT_PHYS_ADDR) += remap.o +obj-$(CONFIG_CPU_RM7000) += sc-rm7k.o +obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o +obj-$(CONFIG_SGI_IP22) += sc-ip22.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/mm/c-andes.c linux-2.4.21-bk38/arch/mips/mm/c-andes.c --- linux-2.4.21-bk37/arch/mips/mm/c-andes.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/c-andes.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,129 +0,0 @@ -/* - * 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. - * - * Copyright (C) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 1999 Silicon Graphics, Inc. - * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com) - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int scache_lsz64; - -static void andes_flush_cache_all(void) -{ -} - -static void andes_flush_cache_mm(struct mm_struct *mm) -{ -} - -static void andes_flush_cache_range(struct mm_struct *mm, unsigned long start, - unsigned long end) -{ -} - -static void andes_flush_cache_page(struct vm_area_struct *vma, - unsigned long page) -{ -} - -static void andes_flush_page_to_ram(struct page *page) -{ -} - -/* Cache operations. These are only used with the virtual memory system, - not for non-coherent I/O so it's ok to ignore the secondary caches. */ -static void -andes_flush_cache_l1(void) -{ - blast_dcache32(); blast_icache64(); -} - -/* - * This is only used during initialization time. vmalloc() also calls - * this, but that will be changed pretty soon. - */ -static void -andes_flush_cache_l2(void) -{ - switch (sc_lsize()) { - case 64: - blast_scache64(); - break; - case 128: - blast_scache128(); - break; - default: - printk("Unknown L2 line size\n"); - while(1); - } -} - -static void andes___flush_cache_all(void) -{ - andes_flush_cache_l1(); - andes_flush_cache_l2(); -} - -void -andes_flush_icache_page(unsigned long page) -{ - if (scache_lsz64) - blast_scache64_page(page); - else - blast_scache128_page(page); -} - -static void -andes_flush_cache_sigtramp(unsigned long addr) -{ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -void __init ld_mmu_andes(void) -{ - printk("Primary instruction cache %dkb, linesize %d bytes\n", - icache_size >> 10, ic_lsize); - printk("Primary data cache %dkb, linesize %d bytes\n", - dcache_size >> 10, dc_lsize); - printk("Secondary cache sized at %ldK, linesize %ld\n", - scache_size() >> 10, sc_lsize()); - - _clear_page = andes_clear_page; - _copy_page = andes_copy_page; - - _flush_cache_all = andes_flush_cache_all; - ___flush_cache_all = andes___flush_cache_all; - _flush_cache_mm = andes_flush_cache_mm; - _flush_cache_page = andes_flush_cache_page; - _flush_page_to_ram = andes_flush_page_to_ram; - _flush_cache_l1 = andes_flush_cache_l1; - _flush_cache_l2 = andes_flush_cache_l2; - _flush_cache_sigtramp = andes_flush_cache_sigtramp; - - switch (sc_lsize()) { - case 64: - scache_lsz64 = 1; - break; - case 128: - scache_lsz64 = 0; - break; - default: - printk("Unknown L2 line size\n"); - while(1); - } - - flush_cache_l1(); -} diff -urN linux-2.4.21-bk37/arch/mips/mm/c-mips32.c linux-2.4.21-bk38/arch/mips/mm/c-mips32.c --- linux-2.4.21-bk37/arch/mips/mm/c-mips32.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/c-mips32.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,671 +0,0 @@ -/* - * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * MIPS32 CPU variant specific MMU/Cache routines. - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/* CP0 hazard avoidance. */ -#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ - "nop; nop; nop; nop; nop; nop;\n\t" \ - ".set reorder\n\t") - -/* Primary cache parameters. */ -int icache_size, dcache_size; /* Size in bytes */ -int ic_lsize, dc_lsize; /* LineSize in bytes */ - -/* Secondary cache (if present) parameters. */ -unsigned int scache_size, sc_lsize; /* Again, in bytes */ - -#include -#include - -#undef DEBUG_CACHE - -/* - * Dummy cache handling routines for machines without boardcaches - */ -static void no_sc_noop(void) {} - -static struct bcache_ops no_sc_ops = { - (void *)no_sc_noop, (void *)no_sc_noop, - (void *)no_sc_noop, (void *)no_sc_noop -}; - -struct bcache_ops *bcops = &no_sc_ops; - -static inline void mips32_flush_cache_all_sc(void) -{ - unsigned long flags; - - __save_and_cli(flags); - blast_dcache(); blast_icache(); blast_scache(); - __restore_flags(flags); -} - -static inline void mips32_flush_cache_all_pc(void) -{ - unsigned long flags; - - __save_and_cli(flags); - blast_dcache(); blast_icache(); - __restore_flags(flags); -} - -static void -mips32_flush_cache_range_sc(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - unsigned long flags; - - if(mm->context == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if(mm->context != current->mm->context) { - mips32_flush_cache_all_sc(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - __save_and_cli(flags); - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache_page(start); - start += PAGE_SIZE; - } - __restore_flags(flags); - } - } -} - -static void mips32_flush_cache_range_pc(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if(mm->context != 0) { - unsigned long flags; - -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - __save_and_cli(flags); - blast_dcache(); blast_icache(); - __restore_flags(flags); - } -} - -/* - * On architectures like the Sparc, we could get rid of lines in - * the cache created only by a certain context, but on the MIPS - * (and actually certain Sparc's) we cannot. - */ -static void mips32_flush_cache_mm_sc(struct mm_struct *mm) -{ - if(mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - mips32_flush_cache_all_sc(); - } -} - -static void mips32_flush_cache_mm_pc(struct mm_struct *mm) -{ - if(mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - mips32_flush_cache_all_pc(); - } -} - -static void mips32_flush_cache_page_sc(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - __save_and_cli(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache_page_indexed(page); - blast_scache_page_indexed(page); - } else - blast_scache_page(page); -out: - __restore_flags(flags); -} - -static void mips32_flush_cache_page_pc(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - __save_and_cli(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since Mips32 caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm == current->active_mm) { - blast_dcache_page(page); - } else { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache_page_indexed(page); - } -out: - __restore_flags(flags); -} - -/* If the addresses passed to these routines are valid, they are - * either: - * - * 1) In KSEG0, so we can do a direct flush of the page. - * 2) In KSEG2, and since every process can translate those - * addresses all the time in kernel mode we can do a direct - * flush. - * 3) In KSEG1, no flush necessary. - */ -static void mips32_flush_page_to_ram_sc(struct page *page) -{ - blast_scache_page((unsigned long)page_address(page)); -} - -static void mips32_flush_page_to_ram_pc(struct page *page) -{ - blast_dcache_page((unsigned long)page_address(page)); -} - -static void -mips32_flush_icache_page_s(struct vm_area_struct *vma, struct page *page) -{ - /* - * We did an scache flush therefore PI is already clean. - */ -} - -static void -mips32_flush_icache_range(unsigned long start, unsigned long end) -{ - flush_cache_all(); -} - -static void -mips32_flush_icache_page(struct vm_area_struct *vma, struct page *page) -{ - int address; - - if (!(vma->vm_flags & VM_EXEC)) - return; - - address = KSEG0 + ((unsigned long)page_address(page) & PAGE_MASK & (dcache_size - 1)); - blast_icache_page_indexed(address); -} - -/* - * Writeback and invalidate the primary cache dcache before DMA. - */ -static void -mips32_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= dcache_size) { - flush_cache_all(); - } else { - __save_and_cli(flags); - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - __restore_flags(flags); - } - bc_wback_inv(addr, size); -} - -static void -mips32_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= scache_size) { - flush_cache_all(); - return; - } - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} - -static void -mips32_dma_cache_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= dcache_size) { - flush_cache_all(); - } else { - __save_and_cli(flags); - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - __restore_flags(flags); - } - - bc_inv(addr, size); -} - -static void -mips32_dma_cache_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= scache_size) { - flush_cache_all(); - return; - } - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} - -static void -mips32_dma_cache_wback(unsigned long addr, unsigned long size) -{ - panic("mips32_dma_cache called - should not happen."); -} - -/* - * While we're protected against bad userland addresses we don't care - * very much about what happens in that case. Usually a segmentation - * fault will dump the process later on anyway ... - */ -static void mips32_flush_cache_sigtramp(unsigned long addr) -{ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -static void mips32_flush_icache_all(void) -{ - if (mips_cpu.cputype == CPU_20KC) { - blast_icache(); - } -} - -/* Detect and size the various caches. */ -static void __init probe_icache(unsigned long config) -{ - unsigned long config1; - unsigned int lsize; - - if (!(config & (1 << 31))) { - /* - * Not a MIPS32 complainant CPU. - * Config 1 register not supported, we assume R4k style. - */ - icache_size = 1 << (12 + ((config >> 9) & 7)); - ic_lsize = 16 << ((config >> 5) & 1); - mips_cpu.icache.linesz = ic_lsize; - - /* - * We cannot infer associativity - assume direct map - * unless probe template indicates otherwise - */ - if(!mips_cpu.icache.ways) mips_cpu.icache.ways = 1; - mips_cpu.icache.sets = - (icache_size / ic_lsize) / mips_cpu.icache.ways; - } else { - config1 = read_mips32_cp0_config1(); - - if ((lsize = ((config1 >> 19) & 7))) - mips_cpu.icache.linesz = 2 << lsize; - else - mips_cpu.icache.linesz = lsize; - mips_cpu.icache.sets = 64 << ((config1 >> 22) & 7); - mips_cpu.icache.ways = 1 + ((config1 >> 16) & 7); - - ic_lsize = mips_cpu.icache.linesz; - icache_size = mips_cpu.icache.sets * mips_cpu.icache.ways * - ic_lsize; - } - printk("Primary instruction cache %dkb, linesize %d bytes (%d ways)\n", - icache_size >> 10, ic_lsize, mips_cpu.icache.ways); -} - -static void __init probe_dcache(unsigned long config) -{ - unsigned long config1; - unsigned int lsize; - - if (!(config & (1 << 31))) { - /* - * Not a MIPS32 complainant CPU. - * Config 1 register not supported, we assume R4k style. - */ - dcache_size = 1 << (12 + ((config >> 6) & 7)); - dc_lsize = 16 << ((config >> 4) & 1); - mips_cpu.dcache.linesz = dc_lsize; - /* - * We cannot infer associativity - assume direct map - * unless probe template indicates otherwise - */ - if(!mips_cpu.dcache.ways) mips_cpu.dcache.ways = 1; - mips_cpu.dcache.sets = - (dcache_size / dc_lsize) / mips_cpu.dcache.ways; - } else { - config1 = read_mips32_cp0_config1(); - - if ((lsize = ((config1 >> 10) & 7))) - mips_cpu.dcache.linesz = 2 << lsize; - else - mips_cpu.dcache.linesz= lsize; - mips_cpu.dcache.sets = 64 << ((config1 >> 13) & 7); - mips_cpu.dcache.ways = 1 + ((config1 >> 7) & 7); - - dc_lsize = mips_cpu.dcache.linesz; - dcache_size = - mips_cpu.dcache.sets * mips_cpu.dcache.ways - * dc_lsize; - } - printk("Primary data cache %dkb, linesize %d bytes (%d ways)\n", - dcache_size >> 10, dc_lsize, mips_cpu.dcache.ways); -} - - -/* If you even _breathe_ on this function, look at the gcc output - * and make sure it does not pop things on and off the stack for - * the cache sizing loop that executes in KSEG1 space or else - * you will crash and burn badly. You have been warned. - */ -static int __init probe_scache(unsigned long config) -{ - extern unsigned long stext; - unsigned long flags, addr, begin, end, pow2; - int tmp; - - if (mips_cpu.scache.flags == MIPS_CACHE_NOT_PRESENT) - return 0; - - tmp = ((config >> 17) & 1); - if(tmp) - return 0; - tmp = ((config >> 22) & 3); - switch(tmp) { - case 0: - sc_lsize = 16; - break; - case 1: - sc_lsize = 32; - break; - case 2: - sc_lsize = 64; - break; - case 3: - sc_lsize = 128; - break; - } - - begin = (unsigned long) &stext; - begin &= ~((4 * 1024 * 1024) - 1); - end = begin + (4 * 1024 * 1024); - - /* This is such a bitch, you'd think they would make it - * easy to do this. Away you daemons of stupidity! - */ - __save_and_cli(flags); - - /* Fill each size-multiple cache line with a valid tag. */ - pow2 = (64 * 1024); - for(addr = begin; addr < end; addr = (begin + pow2)) { - unsigned long *p = (unsigned long *) addr; - __asm__ __volatile__("nop" : : "r" (*p)); /* whee... */ - pow2 <<= 1; - } - - /* Load first line with zero (therefore invalid) tag. */ - set_taglo(0); - set_taghi(0); - __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */ - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 8, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 9, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 11, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (begin)); - - /* Now search for the wrap around point. */ - pow2 = (128 * 1024); - tmp = 0; - for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) { - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 7, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (addr)); - __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */ - if(!get_taglo()) - break; - pow2 <<= 1; - } - __restore_flags(flags); - addr -= begin; - printk("Secondary cache sized at %dK linesize %d bytes.\n", - (int) (addr >> 10), sc_lsize); - scache_size = addr; - return 1; -} - -static void __init setup_noscache_funcs(void) -{ - _clear_page = (void *)mips32_clear_page_dc; - _copy_page = (void *)mips32_copy_page_dc; - _flush_cache_all = mips32_flush_cache_all_pc; - ___flush_cache_all = mips32_flush_cache_all_pc; - _flush_cache_mm = mips32_flush_cache_mm_pc; - _flush_cache_range = mips32_flush_cache_range_pc; - _flush_cache_page = mips32_flush_cache_page_pc; - _flush_page_to_ram = mips32_flush_page_to_ram_pc; - - _flush_icache_page = mips32_flush_icache_page; - - _dma_cache_wback_inv = mips32_dma_cache_wback_inv_pc; - _dma_cache_wback = mips32_dma_cache_wback; - _dma_cache_inv = mips32_dma_cache_inv_pc; -} - -static void __init setup_scache_funcs(void) -{ - _flush_cache_all = mips32_flush_cache_all_sc; - ___flush_cache_all = mips32_flush_cache_all_sc; - _flush_cache_mm = mips32_flush_cache_mm_sc; - _flush_cache_range = mips32_flush_cache_range_sc; - _flush_cache_page = mips32_flush_cache_page_sc; - _flush_page_to_ram = mips32_flush_page_to_ram_sc; - _clear_page = (void *)mips32_clear_page_sc; - _copy_page = (void *)mips32_copy_page_sc; - - _flush_icache_page = mips32_flush_icache_page_s; - - _dma_cache_wback_inv = mips32_dma_cache_wback_inv_sc; - _dma_cache_wback = mips32_dma_cache_wback; - _dma_cache_inv = mips32_dma_cache_inv_sc; -} - -typedef int (*probe_func_t)(unsigned long); - -static inline void __init setup_scache(unsigned int config) -{ - probe_func_t probe_scache_kseg1; - int sc_present = 0; - - /* Maybe the cpu knows about a l2 cache? */ - probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); - sc_present = probe_scache_kseg1(config); - - if (sc_present) { - mips_cpu.scache.linesz = sc_lsize; - /* - * We cannot infer associativity - assume direct map - * unless probe template indicates otherwise - */ - if(!mips_cpu.scache.ways) mips_cpu.scache.ways = 1; - mips_cpu.scache.sets = - (scache_size / sc_lsize) / mips_cpu.scache.ways; - - setup_scache_funcs(); - return; - } - - setup_noscache_funcs(); -} - -void __init ld_mmu_mips32(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - - change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); - - probe_icache(config); - probe_dcache(config); - setup_scache(config); - - _flush_cache_sigtramp = mips32_flush_cache_sigtramp; - _flush_icache_range = mips32_flush_icache_range; /* Ouch */ - _flush_icache_all = mips32_flush_icache_all; - - __flush_cache_all(); -} diff -urN linux-2.4.21-bk37/arch/mips/mm/c-r3k.c linux-2.4.21-bk38/arch/mips/mm/c-r3k.c --- linux-2.4.21-bk37/arch/mips/mm/c-r3k.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/c-r3k.c 2003-08-24 02:55:57.000000000 -0700 @@ -7,6 +7,7 @@ * Tx39XX R4k style caches added. HK * Copyright (C) 1998, 1999, 2000 Harald Koerfgen * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov + * Copyright (C) 2001 Maciej W. Rozycki */ #include #include @@ -22,6 +23,9 @@ #include #include +void r3k_clear_page(void * page); +void r3k_copy_page(void * to, void * from); + static unsigned long icache_size, dcache_size; /* Size in bytes */ static unsigned long icache_lsize, dcache_lsize; /* Size in bytes */ @@ -34,14 +38,14 @@ p = (volatile unsigned long *) KSEG0; - flags = read_32bit_cp0_register(CP0_STATUS); + flags = read_c0_status(); /* isolate cache space */ - write_32bit_cp0_register(CP0_STATUS, (ca_flags|flags)&~ST0_IEC); + write_c0_status((ca_flags|flags)&~ST0_IEC); *p = 0xa5a55a5a; dummy = *p; - status = read_32bit_cp0_register(CP0_STATUS); + status = read_c0_status(); if (dummy != 0xa5a55a5a || (status & ST0_CM)) { size = 0; @@ -57,7 +61,7 @@ size = 0; } - write_32bit_cp0_register(CP0_STATUS, flags); + write_c0_status(flags); return size * sizeof(*p); } @@ -69,24 +73,24 @@ p = (volatile unsigned long *) KSEG0; - flags = read_32bit_cp0_register(CP0_STATUS); + flags = read_c0_status(); /* isolate cache space */ - write_32bit_cp0_register(CP0_STATUS, (ca_flags|flags)&~ST0_IEC); + write_c0_status((ca_flags|flags)&~ST0_IEC); for (i = 0; i < 128; i++) *(p + i) = 0; *(volatile unsigned char *)p = 0; for (lsize = 1; lsize < 128; lsize <<= 1) { *(p + lsize); - status = read_32bit_cp0_register(CP0_STATUS); + status = read_c0_status(); if (!(status & ST0_CM)) break; } for (i = 0; i < 128; i += lsize) *(volatile unsigned char *)(p + i) = 0; - write_32bit_cp0_register(CP0_STATUS, flags); + write_c0_status(flags); return lsize * sizeof(*p); } @@ -97,7 +101,6 @@ if (dcache_size) dcache_lsize = r3k_cache_lsize(ST0_ISC); - icache_size = r3k_cache_size(ST0_ISC|ST0_SWC); if (icache_size) icache_lsize = r3k_cache_lsize(ST0_ISC|ST0_SWC); @@ -115,10 +118,10 @@ } p = (char *)start; - flags = read_32bit_cp0_register(CP0_STATUS); + flags = read_c0_status(); /* isolate cache space */ - write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|ST0_SWC|flags)&~ST0_IEC); + write_c0_status((ST0_ISC|ST0_SWC|flags)&~ST0_IEC); for (i = 0; i < size; i += 0x080) { asm ( "sb\t$0, 0x000(%0)\n\t" @@ -157,7 +160,7 @@ p += 0x080; } - write_32bit_cp0_register(CP0_STATUS, flags); + write_c0_status(flags); } static void r3k_flush_dcache_range(unsigned long start, unsigned long end) @@ -172,10 +175,10 @@ } p = (char *)start; - flags = read_32bit_cp0_register(CP0_STATUS); + flags = read_c0_status(); /* isolate cache space */ - write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|flags)&~ST0_IEC); + write_c0_status((ST0_ISC|flags)&~ST0_IEC); for (i = 0; i < size; i += 0x080) { asm ( "sb\t$0, 0x000(%0)\n\t" @@ -214,7 +217,7 @@ p += 0x080; } - write_32bit_cp0_register(CP0_STATUS,flags); + write_c0_status(flags); } static inline unsigned long get_phys_page (unsigned long addr, @@ -241,6 +244,7 @@ static inline void r3k___flush_cache_all(void) { + r3k_flush_dcache_range(KSEG0, KSEG0 + dcache_size); r3k_flush_icache_range(KSEG0, KSEG0 + icache_size); } @@ -258,11 +262,8 @@ { } -static void r3k_flush_page_to_ram(struct page * page) +static void r3k_flush_data_cache_page(unsigned long addr) { - /* - * Nothing to be done - */ } static void r3k_flush_icache_page(struct vm_area_struct *vma, struct page *page) @@ -270,14 +271,14 @@ struct mm_struct *mm = vma->vm_mm; unsigned long physpage; - if (mm->context == 0) + if (cpu_context(smp_processor_id(), mm) == 0) return; if (!(vma->vm_flags & VM_EXEC)) return; #ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); + printk("cpage[%d,%08lx]", cpu_context(smp_processor_id(), mm), page); #endif physpage = (unsigned long) page_address(page); @@ -293,22 +294,22 @@ printk("csigtramp[%08lx]", addr); #endif - flags = read_32bit_cp0_register(CP0_STATUS); + flags = read_c0_status(); - write_32bit_cp0_register(CP0_STATUS, flags&~ST0_IEC); + write_c0_status(flags&~ST0_IEC); /* Fill the TLB to avoid an exception with caches isolated. */ asm ( "lw\t$0, 0x000(%0)\n\t" "lw\t$0, 0x004(%0)\n\t" : : "r" (addr) ); - write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|ST0_SWC|flags)&~ST0_IEC); + write_c0_status((ST0_ISC|ST0_SWC|flags)&~ST0_IEC); asm ( "sb\t$0, 0x000(%0)\n\t" "sb\t$0, 0x004(%0)\n\t" : : "r" (addr) ); - write_32bit_cp0_register(CP0_STATUS, flags); + write_c0_status(flags); } static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size) @@ -331,16 +332,16 @@ _flush_cache_mm = r3k_flush_cache_mm; _flush_cache_range = r3k_flush_cache_range; _flush_cache_page = r3k_flush_cache_page; - _flush_cache_sigtramp = r3k_flush_cache_sigtramp; - _flush_page_to_ram = r3k_flush_page_to_ram; _flush_icache_page = r3k_flush_icache_page; _flush_icache_range = r3k_flush_icache_range; - _dma_cache_wback_inv = r3k_dma_cache_wback_inv; + _flush_cache_sigtramp = r3k_flush_cache_sigtramp; + _flush_data_cache_page = r3k_flush_data_cache_page; - printk("Primary instruction cache %dkb, linesize %d bytes\n", - (int) (icache_size >> 10), (int) icache_lsize); - printk("Primary data cache %dkb, linesize %d bytes\n", - (int) (dcache_size >> 10), (int) dcache_lsize); + _dma_cache_wback_inv = r3k_dma_cache_wback_inv; + printk("Primary instruction cache %ldkB, linesize %ld bytes.\n", + icache_size >> 10, icache_lsize); + printk("Primary data cache %ldkB, linesize %ld bytes.\n", + dcache_size >> 10, dcache_lsize); } diff -urN linux-2.4.21-bk37/arch/mips/mm/c-r4k.c linux-2.4.21-bk38/arch/mips/mm/c-r4k.c --- linux-2.4.21-bk37/arch/mips/mm/c-r4k.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/c-r4k.c 2003-08-24 02:55:57.000000000 -0700 @@ -3,44 +3,51 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * r4xx0.c: R4000 processor variant specific MMU/Cache routines. - * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org - * - * To do: - * - * - this code is a overbloated pig - * - many of the bug workarounds are not efficient at all, but at - * least they are functional ... + * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ #include #include #include #include #include +#include +#include #include +#include #include -#include #include #include #include +#include #include #include #include -/* Primary cache parameters. */ -static int icache_size, dcache_size; /* Size in bytes */ -static int ic_lsize, dc_lsize; /* LineSize in bytes */ - -/* Secondary cache (if present) parameters. */ -static unsigned int scache_size, sc_lsize; /* Again, in bytes */ - -#include -#include +static unsigned long icache_size, dcache_size, scache_size; -#undef DEBUG_CACHE +extern void andes_clear_page(void * page); +extern void r4k_clear_page32_d16(void * page); +extern void r4k_clear_page32_d32(void * page); +extern void r4k_clear_page_d16(void * page); +extern void r4k_clear_page_d32(void * page); +extern void r4k_clear_page_r4600_v1(void * page); +extern void r4k_clear_page_r4600_v2(void * page); +extern void r4k_clear_page_s16(void * page); +extern void r4k_clear_page_s32(void * page); +extern void r4k_clear_page_s64(void * page); +extern void r4k_clear_page_s128(void * page); +extern void andes_copy_page(void * to, void * from); +extern void r4k_copy_page_d16(void * to, void * from); +extern void r4k_copy_page_d32(void * to, void * from); +extern void r4k_copy_page_r4600_v1(void * to, void * from); +extern void r4k_copy_page_r4600_v2(void * to, void * from); +extern void r4k_copy_page_s16(void * to, void * from); +extern void r4k_copy_page_s32(void * to, void * from); +extern void r4k_copy_page_s64(void * to, void * from); +extern void r4k_copy_page_s128(void * to, void * from); /* * Dummy cache handling routines for machines without boardcaches @@ -48,884 +55,386 @@ static void no_sc_noop(void) {} static struct bcache_ops no_sc_ops = { - (void *)no_sc_noop, (void *)no_sc_noop, - (void *)no_sc_noop, (void *)no_sc_noop + .bc_enable = (void *)no_sc_noop, + .bc_disable = (void *)no_sc_noop, + .bc_wback_inv = (void *)no_sc_noop, + .bc_inv = (void *)no_sc_noop }; struct bcache_ops *bcops = &no_sc_ops; -/* - * On processors with QED R4600 style two set assosicative cache - * this is the bit which selects the way in the cache for the - * indexed cachops. - */ -#define icache_waybit (icache_size >> 1) -#define dcache_waybit (dcache_size >> 1) +#define R4600_HIT_CACHEOP_WAR_IMPL \ +do { \ + if (R4600_V2_HIT_CACHEOP_WAR && \ + (read_c0_prid() & 0xfff0) == 0x2020) { /* R4600 V2.0 */\ + *(volatile unsigned long *)KSEG1; \ + } \ + if (R4600_V1_HIT_CACHEOP_WAR) \ + __asm__ __volatile__("nop;nop;nop;nop"); \ +} while (0) -/* - * If you think for one second that this stuff coming up is a lot - * of bulky code eating too many kernel cache lines. Think _again_. - * - * Consider: - * 1) Taken branches have a 3 cycle penalty on R4k - * 2) The branch itself is a real dead cycle on even R4600/R5000. - * 3) Only one of the following variants of each type is even used by - * the kernel based upon the cache parameters we detect at boot time. - * - * QED. - */ - -static inline void r4k_flush_cache_all_s16d16i16(void) +static void r4k_blast_dcache_page(unsigned long addr) { - blast_dcache16(); blast_icache16(); blast_scache16(); -} + static void *l = &&init; + unsigned long dc_lsize; -static inline void r4k_flush_cache_all_s32d16i16(void) -{ - blast_dcache16(); blast_icache16(); blast_scache32(); -} + goto *l; -static inline void r4k_flush_cache_all_s64d16i16(void) -{ - blast_dcache16(); blast_icache16(); blast_scache64(); -} +dc_16: + blast_dcache16_page(addr); + return; -static inline void r4k_flush_cache_all_s128d16i16(void) -{ - blast_dcache16(); blast_icache16(); blast_scache128(); -} +dc_32: + R4600_HIT_CACHEOP_WAR_IMPL; + blast_dcache32_page(addr); + return; -static inline void r4k_flush_cache_all_s32d32i32(void) -{ - blast_dcache32(); blast_icache32(); blast_scache32(); -} +init: + dc_lsize = current_cpu_data.dcache.linesz; -static inline void r4k_flush_cache_all_s64d32i32(void) -{ - blast_dcache32(); blast_icache32(); blast_scache64(); + if (dc_lsize == 16) + l = &&dc_16; + else if (dc_lsize == 32) + l = &&dc_32; + goto *l; } -static inline void r4k_flush_cache_all_s128d32i32(void) +static void r4k_blast_dcache_page_indexed(unsigned long addr) { - blast_dcache32(); blast_icache32(); blast_scache128(); -} + static void *l = &&init; + unsigned long dc_lsize; -static inline void r4k_flush_cache_all_d16i16(void) -{ - blast_dcache16(); blast_icache16(); -} + goto *l; -static inline void r4k_flush_cache_all_d32i32(void) -{ - blast_dcache32(); blast_icache32(); -} +dc_16: + blast_dcache16_page_indexed(addr); + return; -static void -r4k_flush_cache_range_s16d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; +dc_32: + blast_dcache32_page_indexed(addr); + return; - if (mm->context == 0) - return; +init: + dc_lsize = current_cpu_data.dcache.linesz; - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if (vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s16d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while (start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache16_page(start); - start += PAGE_SIZE; - } - } - } + if (dc_lsize == 16) + l = &&dc_16; + else if (dc_lsize == 32) + l = &&dc_32; + goto *l; } -static void -r4k_flush_cache_range_s32d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) +static void r4k_blast_dcache(void) { - struct vm_area_struct *vma; + static void *l = &&init; + unsigned long dc_lsize; - if (mm->context == 0) - return; + goto *l; - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if (vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s32d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache32_page(start); - start += PAGE_SIZE; - } - } - } -} +dc_16: + blast_dcache16(); + return; -static void r4k_flush_cache_range_s64d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; +dc_32: + blast_dcache32(); + return; - if (mm->context == 0) - return; +init: + dc_lsize = current_cpu_data.dcache.linesz; - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s64d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache64_page(start); - start += PAGE_SIZE; - } - } - } + if (dc_lsize == 16) + l = &&dc_16; + else if (dc_lsize == 32) + l = &&dc_32; + goto *l; } -static void r4k_flush_cache_range_s128d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - - if (mm->context == 0) - return; +/* force code alignment (used for TX49XX_ICACHE_INDEX_INV_WAR) */ +#define JUMP_TO_ALIGN(order) \ + __asm__ __volatile__( \ + "b\t1f\n\t" \ + ".align\t" #order "\n\t" \ + "1:\n\t" \ + ) +#define CACHE32_UNROLL32_ALIGN JUMP_TO_ALIGN(10) /* 32 * 32 = 1024 */ +#define CACHE32_UNROLL32_ALIGN2 JUMP_TO_ALIGN(11) - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if (vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s128d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache128_page(start); - start += PAGE_SIZE; - } - } - } -} - -static void r4k_flush_cache_range_s32d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) +static inline void tx49_blast_icache32(void) { - struct vm_area_struct *vma; - - if (mm->context == 0) - return; + unsigned long start = KSEG0; + unsigned long end = start + current_cpu_data.icache.waysize; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if (vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s32d32i32(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache32_page(start); - start += PAGE_SIZE; - } - } - } + CACHE32_UNROLL32_ALIGN2; + /* I'm in even chunk. blast odd chunks */ + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start + 0x400; addr < end; addr += 0x400 * 2) + cache32_unroll32(addr|ws,Index_Invalidate_I); + CACHE32_UNROLL32_ALIGN; + /* I'm in odd chunk. blast even chunks */ + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400 * 2) + cache32_unroll32(addr|ws,Index_Invalidate_I); } -static void r4k_flush_cache_range_s64d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) +static inline void tx49_blast_icache32_page_indexed(unsigned long page) { - struct vm_area_struct *vma; + unsigned long start = page; + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; - if (mm->context == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if (vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s64d32i32(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache64_page(start); - start += PAGE_SIZE; - } - } - } + CACHE32_UNROLL32_ALIGN2; + /* I'm in even chunk. blast odd chunks */ + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start + 0x400; addr < end; addr += 0x400 * 2) + cache32_unroll32(addr|ws,Index_Invalidate_I); + CACHE32_UNROLL32_ALIGN; + /* I'm in odd chunk. blast even chunks */ + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400 * 2) + cache32_unroll32(addr|ws,Index_Invalidate_I); } -static void r4k_flush_cache_range_s128d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) +static void r4k_blast_icache_page(unsigned long addr) { - struct vm_area_struct *vma; + unsigned long ic_lsize = current_cpu_data.icache.linesz; + static void *l = &&init; - if (mm->context == 0) - return; + goto *l; - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if (vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s128d32i32(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache128_page(start); - start += PAGE_SIZE; - } - } - } -} +ic_16: + blast_icache16_page(addr); + return; -static void r4k_flush_cache_range_d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - blast_dcache16(); blast_icache16(); - } -} +ic_32: + blast_icache32_page(addr); + return; -static void r4k_flush_cache_range_d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - blast_dcache32(); blast_icache32(); - } -} +ic_64: + blast_icache64_page(addr); + return; -/* - * On architectures like the Sparc, we could get rid of lines in - * the cache created only by a certain context, but on the MIPS - * (and actually certain Sparc's) we cannot. - */ -static void r4k_flush_cache_mm_s16d16i16(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s16d16i16(); - } +init: + if (ic_lsize == 16) + l = &&ic_16; + else if (ic_lsize == 32) + l = &&ic_32; + else if (ic_lsize == 64) + l = &&ic_64; + goto *l; } -static void r4k_flush_cache_mm_s32d16i16(struct mm_struct *mm) +static void r4k_blast_icache_page_indexed(unsigned long addr) { - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s32d16i16(); - } -} + unsigned long ic_lsize = current_cpu_data.icache.linesz; + static void *l = &&init; -static void r4k_flush_cache_mm_s64d16i16(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s64d16i16(); - } -} + goto *l; -static void r4k_flush_cache_mm_s128d16i16(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s128d16i16(); - } -} +ic_16: + blast_icache16_page_indexed(addr); + return; -static void r4k_flush_cache_mm_s32d32i32(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s32d32i32(); - } -} +ic_32: + blast_icache32_page_indexed(addr); + return; -static void r4k_flush_cache_mm_s64d32i32(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s64d32i32(); - } -} +ic_64: + blast_icache64_page_indexed(addr); + return; -static void r4k_flush_cache_mm_s128d32i32(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s128d32i32(); - } -} +ic_32_tx49: + tx49_blast_icache32_page_indexed(addr); + return; -static void r4k_flush_cache_mm_d16i16(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_d16i16(); - } -} - -static void r4k_flush_cache_mm_d32i32(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_d32i32(); - } +init: + if (ic_lsize == 16) + l = &&ic_16; + else if (ic_lsize == 32) + if (TX49XX_ICACHE_INDEX_INV_WAR) + l = &&ic_32_tx49; + else + l = &&ic_32; + else if (ic_lsize == 64) + l = &&ic_64; + goto *l; } -static void r4k_flush_cache_page_s16d16i16(struct vm_area_struct *vma, - unsigned long page) +static void r4k_blast_icache(void) { - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; + unsigned long ic_lsize = current_cpu_data.icache.linesz; + static void *l = &&init; - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; + goto *l; -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); +ic_16: + blast_icache16(); + return; - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; +ic_32: + blast_icache32(); + return; - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache16_page_indexed(page); - } else - blast_scache16_page(page); -out: -} +ic_64: + blast_icache64(); + return; -static void r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); +ic_32_tx49: + tx49_blast_icache32(); + return; - /* If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache32_page_indexed(page); - } else - blast_scache32_page(page); -out: -} - -static void r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache64_page_indexed(page); - } else - blast_scache64_page(page); -out: +init: + if (ic_lsize == 16) + l = &&ic_16; + else if (ic_lsize == 32) + if (TX49XX_ICACHE_INDEX_INV_WAR) + l = &&ic_32_tx49; + else + l = &&ic_32; + else if (ic_lsize == 64) + l = &&ic_64; + goto *l; } -static void r4k_flush_cache_page_s128d16i16(struct vm_area_struct *vma, - unsigned long page) +static void r4k_blast_scache_page(unsigned long addr) { - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; + unsigned long sc_lsize = current_cpu_data.scache.linesz; + static void *l = &&init; - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; + goto *l; -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); +sc_16: + blast_scache16_page(addr); + return; - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; +sc_32: + blast_scache32_page(addr); + return; - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache128_page_indexed(page); - } else - blast_scache128_page(page); -out: -} - -static void r4k_flush_cache_page_s32d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); +sc_64: + blast_scache64_page(addr); + return; - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; +sc_128: + blast_scache128_page(addr); + return; - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache32_page_indexed(page); - blast_scache32_page_indexed(page); - } else - blast_scache32_page(page); -out: +init: + if (sc_lsize == 16) + l = &&sc_16; + else if (sc_lsize == 32) + l = &&sc_32; + else if (sc_lsize == 64) + l = &&sc_64; + else if (sc_lsize == 128) + l = &&sc_128; + goto *l; } -static void r4k_flush_cache_page_s64d32i32(struct vm_area_struct *vma, - unsigned long page) +static void r4k_blast_scache(void) { - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; + unsigned long sc_lsize = current_cpu_data.scache.linesz; + static void *l = &&init; - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache32_page_indexed(page); - blast_scache64_page_indexed(page); - } else - blast_scache64_page(page); -out: -} + goto *l; -static void r4k_flush_cache_page_s128d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; +sc_16: + blast_scache16(); + return; - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; +sc_32: + blast_scache32(); + return; -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); +sc_64: + blast_scache64(); + return; - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; +sc_128: + blast_scache128(); + return; - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache32_page_indexed(page); - blast_scache128_page_indexed(page); - } else - blast_scache128_page(page); -out: +init: + if (sc_lsize == 16) + l = &&sc_16; + else if (sc_lsize == 32) + l = &&sc_32; + else if (sc_lsize == 64) + l = &&sc_64; + else if (sc_lsize == 128) + l = &&sc_128; + goto *l; } -static void r4k_flush_cache_page_d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) +static void r4k_flush_cache_all(void) +{ + if (!cpu_has_dc_aliases) return; -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); + r4k_blast_dcache(); + r4k_blast_icache(); +} - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; +static void r4k___flush_cache_all(void) +{ + r4k_blast_dcache(); + r4k_blast_icache(); - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm == current->active_mm) { - blast_dcache16_page(page); - } else { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache16_page_indexed(page); + switch (current_cpu_data.cputype) { + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400SC: + case CPU_R4400MC: + case CPU_R10000: + case CPU_R12000: + r4k_blast_scache(); } -out: } -static void r4k_flush_cache_page_d32i32(struct vm_area_struct *vma, - unsigned long page) +static void r4k_flush_cache_range(struct mm_struct *mm, + unsigned long start, unsigned long end) { - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; + if (!cpu_has_dc_aliases) + return; - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) + if (cpu_context(smp_processor_id(), mm) != 0) { + r4k_blast_dcache(); + r4k_blast_icache(); + } +} + +static void r4k_flush_cache_mm(struct mm_struct *mm) +{ + if (!cpu_has_dc_aliases) return; -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); + if (!cpu_context(smp_processor_id(), mm)) + return; - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_PRESENT)) - goto out; + r4k_blast_dcache(); + r4k_blast_icache(); /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. + * Kludge alert. For obscure reasons R4000SC and R4400SC go nuts if we + * only flush the primary caches but R10000 and R12000 behave sane ... */ - if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache32_page(page); - } else { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache32_page_indexed(page); - } -out: + if (current_cpu_data.cputype == CPU_R4000SC || + current_cpu_data.cputype == CPU_R4000MC || + current_cpu_data.cputype == CPU_R4400SC || + current_cpu_data.cputype == CPU_R4400MC) + r4k_blast_scache(); } -static void r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma, - unsigned long page) +static void r4k_flush_cache_page(struct vm_area_struct *vma, + unsigned long page) { + int exec = vma->vm_flags & VM_EXEC; struct mm_struct *mm = vma->vm_mm; pgd_t *pgdp; pmd_t *pmdp; @@ -935,12 +444,9 @@ * If ownes no valid ASID yet, cannot possibly have gotten * this page into the cache. */ - if (mm->context == 0) + if (cpu_context(smp_processor_id(), mm) == 0) return; -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif page &= PAGE_MASK; pgdp = pgd_offset(mm, page); pmdp = pmd_offset(pgdp, page); @@ -951,7 +457,7 @@ * in the cache. */ if (!(pte_val(*ptep) & _PAGE_PRESENT)) - goto out; + return; /* * Doing flushes for another ASID than the current one is @@ -960,195 +466,215 @@ * in that case, which doesn't overly flush the cache too much. */ if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache32_page(page); - } else { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache32_page_indexed(page); - blast_dcache32_page_indexed(page ^ dcache_waybit); - } -out: -} - -/* If the addresses passed to these routines are valid, they are - * either: - * - * 1) In KSEG0, so we can do a direct flush of the page. - * 2) In KSEG2, and since every process can translate those - * addresses all the time in kernel mode we can do a direct - * flush. - * 3) In KSEG1, no flush necessary. - */ -static void r4k_flush_page_to_ram_s16(struct page *page) -{ - blast_scache16_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_s32(struct page *page) -{ - blast_scache32_page((unsigned long)page_address(page)); -} + if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) + r4k_blast_dcache_page(page); + if (exec) + r4k_blast_icache_page(page); -static void r4k_flush_page_to_ram_s64(struct page *page) -{ - blast_scache64_page((unsigned long)page_address(page)); -} + return; + } -static void r4k_flush_page_to_ram_s128(struct page *page) -{ - blast_scache128_page((unsigned long)page_address(page)); -} + /* + * Do indexed flush, too much work to get the (possible) TLB refills + * to work correctly. + */ + page = (KSEG0 + (page & (dcache_size - 1))); + if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) + r4k_blast_dcache_page_indexed(page); + if (exec) { + if (cpu_has_vtag_icache) { + int cpu = smp_processor_id(); -static void r4k_flush_page_to_ram_d16(struct page *page) -{ - blast_dcache16_page((unsigned long)page_address(page)); + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); + } else + r4k_blast_icache_page_indexed(page); + } } -static void r4k_flush_page_to_ram_d32(struct page *page) +static void r4k_flush_data_cache_page(unsigned long addr) { - blast_dcache32_page((unsigned long)page_address(page)); + r4k_blast_dcache_page(addr); } -static void r4k_flush_page_to_ram_d32_r4600(struct page *page) +static void r4k_flush_icache_range(unsigned long start, unsigned long end) { -#ifdef R4600_V1_HIT_DCACHE_WAR - unsigned long flags; + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + unsigned long addr, aend; - __save_and_cli(flags); - __asm__ __volatile__("nop;nop;nop;nop"); -#endif - blast_dcache32_page((unsigned long)page_address(page)); -#ifdef R4600_V1_HIT_DCACHE_WAR - __restore_flags(flags); -#endif -} + if (!cpu_has_ic_fills_f_dc) { + if (end - start > dcache_size) + r4k_blast_dcache(); + else { + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); -static void -r4k_flush_icache_page_s(struct vm_area_struct *vma, struct page *page) -{ - /* - * We did an scache flush therefore PI is already clean. - */ -} + while (1) { + /* Hit_Writeback_Inv_D */ + protected_writeback_dcache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } + } + } -static void -r4k_flush_icache_range(unsigned long start, unsigned long end) -{ - flush_cache_all(); + if (end - start > icache_size) + r4k_blast_icache(); + else { + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); + while (1) { + /* Hit_Invalidate_I */ + protected_flush_icache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } + } } /* * Ok, this seriously sucks. We use them to flush a user page but don't * know the virtual address, so we have to blast away the whole icache - * which is significantly more expensive than the real thing. + * which is significantly more expensive than the real thing. Otoh we at + * least know the kernel address of the page so we can flush it + * selectivly. */ -static void -r4k_flush_icache_page_p(struct vm_area_struct *vma, struct page *page) +static void r4k_flush_icache_page(struct vm_area_struct *vma, + struct page *page) { + /* + * If there's no context yet, or the page isn't executable, no icache + * flush is needed. + */ if (!(vma->vm_flags & VM_EXEC)) return; - flush_cache_all(); + /* + * Tricky ... Because we don't know the virtual address we've got the + * choice of either invalidating the entire primary and secondary + * caches or invalidating the secondary caches also. With the subset + * enforcment on R4000SC, R4400SC, R10000 and R12000 invalidating the + * secondary cache will result in any entries in the primary caches + * also getting invalidated which hopefully is a bit more economical. + */ + if (cpu_has_subset_pcaches) { + unsigned long addr = (unsigned long) page_address(page); + r4k_blast_scache_page(addr); + + return; + } + + if (!cpu_has_ic_fills_f_dc) { + unsigned long addr = (unsigned long) page_address(page); + r4k_blast_dcache_page(addr); + } + + /* + * We're not sure of the virtual address(es) involved here, so + * we have to flush the entire I-cache. + */ + if (cpu_has_vtag_icache) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); + } else + r4k_blast_icache(); } -static void -r4k_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size) +#ifdef CONFIG_NONCOHERENT_IO + +static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) { unsigned long end, a; - unsigned int flags; + if (cpu_has_subset_pcaches) { + unsigned long sc_lsize = current_cpu_data.scache.linesz; + + if (size >= scache_size) { + r4k_blast_scache(); + return; + } + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } + return; + } + + /* + * Either no secondary cache or the available caches don't have the + * subset property so we have to flush the primary caches + * explicitly + */ if (size >= dcache_size) { - flush_cache_all(); + r4k_blast_dcache(); } else { -#ifdef R4600_V2_HIT_CACHEOP_WAR - /* Workaround for R4600 bug. See comment in . */ - __save_and_cli(flags); - *(volatile unsigned long *)KSEG1; -#endif + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + R4600_HIT_CACHEOP_WAR_IMPL; a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) + break; a += dc_lsize; } -#ifdef R4600_V2_HIT_CACHEOP_WAR - __restore_flags(flags); -#endif } + bc_wback_inv(addr, size); } -static void -r4k_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size) +static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) { unsigned long end, a; - if (size >= scache_size) { - flush_cache_all(); - return; - } + if (cpu_has_subset_pcaches) { + unsigned long sc_lsize = current_cpu_data.scache.linesz; - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} + if (size >= scache_size) { + r4k_blast_scache(); + return; + } -static void -r4k_dma_cache_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } + return; + } if (size >= dcache_size) { - flush_cache_all(); + r4k_blast_dcache(); } else { -#ifdef R4600_V2_HIT_CACHEOP_WAR - /* Workaround for R4600 bug. See comment above. */ - __save_and_cli(flags); - *(volatile unsigned long *)KSEG1; -#endif + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + R4600_HIT_CACHEOP_WAR_IMPL; a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) + break; a += dc_lsize; } -#ifdef R4600_V2_HIT_CACHEOP_WAR - __restore_flags(flags); -#endif } bc_inv(addr, size); } - -static void -r4k_dma_cache_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= scache_size) { - flush_cache_all(); - return; - } - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} +#endif /* CONFIG_NONCOHERENT_IO */ /* * While we're protected against bad userland addresses we don't care @@ -1157,170 +683,357 @@ */ static void r4k_flush_cache_sigtramp(unsigned long addr) { -#ifdef R4600_V1_HIT_DCACHE_WAR - unsigned long flags; + unsigned long ic_lsize = current_cpu_data.icache.linesz; + unsigned long dc_lsize = current_cpu_data.dcache.linesz; - __save_and_cli(flags); - __asm__ __volatile__("nop;nop;nop;nop"); -#endif + R4600_HIT_CACHEOP_WAR_IMPL; protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); protected_flush_icache_line(addr & ~(ic_lsize - 1)); -#ifdef R4600_V1_HIT_DCACHE_WAR - __restore_flags(flags); -#endif + if (MIPS4K_ICACHE_REFILL_WAR) { + __asm__ __volatile__ ( + ".set push\n\t" + ".set noat\n\t" + ".set mips3\n\t" +#if CONFIG_MIPS32 + "la $at,1f\n\t" +#endif +#if CONFIG_MIPS64 + "dla $at,1f\n\t" +#endif + "cache %0,($at)\n\t" + "nop; nop; nop\n" + "1:\n\t" + ".set pop" + : + : "i" (Hit_Invalidate_I)); + } + if (MIPS_CACHE_SYNC_WAR) + __asm__ __volatile__ ("sync"); +} + +static void r4k_flush_icache_all(void) +{ + if (cpu_has_vtag_icache) + r4k_blast_icache(); +} + +static inline void rm7k_erratum31(void) +{ + const unsigned long ic_lsize = 32; + unsigned long addr; + + /* RM7000 erratum #31. The icache is screwed at startup. */ + write_c0_taglo(0); + write_c0_taghi(0); + + for (addr = KSEG0; addr <= KSEG0 + 4096; addr += ic_lsize) { + __asm__ __volatile__ ( + ".set noreorder\n\t" + ".set mips3\n\t" + "cache\t%1, 0(%0)\n\t" + "cache\t%1, 0x1000(%0)\n\t" + "cache\t%1, 0x2000(%0)\n\t" + "cache\t%1, 0x3000(%0)\n\t" + "cache\t%2, 0(%0)\n\t" + "cache\t%2, 0x1000(%0)\n\t" + "cache\t%2, 0x2000(%0)\n\t" + "cache\t%2, 0x3000(%0)\n\t" + "cache\t%1, 0(%0)\n\t" + "cache\t%1, 0x1000(%0)\n\t" + "cache\t%1, 0x2000(%0)\n\t" + "cache\t%1, 0x3000(%0)\n\t" + ".set\tmips0\n\t" + ".set\treorder\n\t" + : + : "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill)); + } } -static void r4600v20k_flush_cache_sigtramp(unsigned long addr) +static char *way_string[] = { NULL, "direct mapped", "2-way", "3-way", "4-way", + "5-way", "6-way", "7-way", "8-way" +}; + +static void __init probe_pcache(void) { - unsigned int flags; + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int config = read_c0_config(); + unsigned int prid = read_c0_prid(); + unsigned long config1; + unsigned int lsize; -#ifdef R4600_V2_HIT_CACHEOP_WAR - __save_and_cli(flags); + switch (c->cputype) { + case CPU_R4600: /* QED style two way caches? */ + case CPU_R4700: + case CPU_R5000: + case CPU_NEVADA: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 2; + c->icache.waybit = ffs(icache_size/2) - 1; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 2; + c->dcache.waybit= ffs(dcache_size/2) - 1; + break; - /* Clear internal cache refill buffer */ - *(volatile unsigned int *)KSEG1; -#endif + case CPU_R5432: + case CPU_R5500: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 2; + c->icache.waybit= 0; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 2; + c->dcache.waybit = 0; + break; - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); + case CPU_TX49XX: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 4; + c->icache.waybit= 0; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 4; + c->dcache.waybit = 0; + break; -#ifdef R4600_V2_HIT_CACHEOP_WAR - __restore_flags(flags); -#endif -} + case CPU_R4000PC: + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400PC: + case CPU_R4400SC: + case CPU_R4400MC: + case CPU_R4300: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 1; + c->icache.waybit = 0; /* doesn't matter */ + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 1; + c->dcache.waybit = 0; /* does not matter */ + break; -/* Detect and size the various r4k caches. */ -static void __init probe_icache(unsigned long config) -{ - switch (mips_cpu.cputype) { - case CPU_VR41XX: - case CPU_VR4111: - case CPU_VR4121: - case CPU_VR4122: - case CPU_VR4131: - case CPU_VR4181: - case CPU_VR4181A: - icache_size = 1 << (10 + ((config >> 9) & 7)); - break; - default: - icache_size = 1 << (12 + ((config >> 9) & 7)); - break; - } - ic_lsize = 16 << ((config >> 5) & 1); - - printk("Primary instruction cache %dkb, linesize %d bytes.\n", - icache_size >> 10, ic_lsize); -} - -static void __init probe_dcache(unsigned long config) -{ - switch (mips_cpu.cputype) { - case CPU_VR41XX: - case CPU_VR4111: - case CPU_VR4121: - case CPU_VR4122: - case CPU_VR4131: - case CPU_VR4181: - case CPU_VR4181A: - dcache_size = 1 << (10 + ((config >> 6) & 7)); - break; - default: - dcache_size = 1 << (12 + ((config >> 6) & 7)); - break; - } - dc_lsize = 16 << ((config >> 4) & 1); - - printk("Primary data cache %dkb, linesize %d bytes.\n", - dcache_size >> 10, dc_lsize); -} + case CPU_R10000: + case CPU_R12000: + icache_size = 1 << (12 + ((config & R10K_CONF_IC) >> 29)); + c->icache.linesz = 64; + c->icache.ways = 2; + c->icache.waybit = 0; + + dcache_size = 1 << (12 + ((config & R10K_CONF_DC) >> 26)); + c->dcache.linesz = 32; + c->dcache.ways = 2; + c->dcache.waybit = 0; + break; + + case CPU_VR4131: + icache_size = 1 << (10 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 2; + c->icache.waybit = ffs(icache_size/2) - 1; + + dcache_size = 1 << (10 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 2; + c->dcache.waybit = ffs(dcache_size/2) - 1; + break; + + case CPU_VR41XX: + case CPU_VR4111: + case CPU_VR4121: + case CPU_VR4122: + case CPU_VR4181: + case CPU_VR4181A: + icache_size = 1 << (10 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 1; + c->icache.waybit = 0; /* doesn't matter */ + + dcache_size = 1 << (10 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 1; + c->dcache.waybit = 0; /* does not matter */ + break; + + case CPU_RM7000: + rm7k_erratum31(); + + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 4; + c->icache.waybit = ffs(icache_size / c->icache.ways) - 1; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 4; + c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1; + break; + + default: + if (!(config & MIPS_CONF_M)) + panic("Don't know how to probe P-caches on this cpu."); + + /* + * So we seem to be a MIPS32 or MIPS64 CPU + * So let's probe the I-cache ... + */ + config1 = read_c0_config1(); + + if ((lsize = ((config1 >> 19) & 7))) + c->icache.linesz = 2 << lsize; + else + c->icache.linesz = lsize; + c->icache.sets = 64 << ((config1 >> 22) & 7); + c->icache.ways = 1 + ((config1 >> 16) & 7); + + icache_size = c->icache.sets * + c->icache.ways * + c->icache.linesz; + c->icache.waybit = ffs(icache_size/c->icache.ways) - 1; + + /* + * Now probe the MIPS32 / MIPS64 data cache. + */ + c->dcache.flags = 0; + + if ((lsize = ((config1 >> 10) & 7))) + c->dcache.linesz = 2 << lsize; + else + c->dcache.linesz= lsize; + c->dcache.sets = 64 << ((config1 >> 13) & 7); + c->dcache.ways = 1 + ((config1 >> 7) & 7); + + dcache_size = c->dcache.sets * + c->dcache.ways * + c->dcache.linesz; + c->dcache.waybit = ffs(dcache_size/c->dcache.ways) - 1; + break; + } + + /* + * Processor configuration sanity check for the R4000SC erratum + * #5. With page sizes larger than 32kB there is no possibility + * to get a VCE exception anymore so we don't care about this + * misconfiguration. The case is rather theoretical anyway; + * presumably no vendor is shipping his hardware in the "bad" + * configuration. + */ + if ((prid & 0xff00) == PRID_IMP_R4000 && (prid & 0xff) < 0x40 && + !(config & CONF_SC) && c->icache.linesz != 16 && + PAGE_SIZE <= 0x8000) + panic("Improper R4000SC processor configuration detected"); + + /* compute a couple of other cache variables */ + c->icache.waysize = icache_size / c->icache.ways; + c->dcache.waysize = dcache_size / c->dcache.ways; + + c->icache.sets = icache_size / (c->icache.linesz * c->icache.ways); + c->dcache.sets = dcache_size / (c->dcache.linesz * c->dcache.ways); + + /* + * R10000 and R12000 P-caches are odd in a positive way. They're 32kB + * 2-way virtually indexed so normally would suffer from aliases. So + * normally they'd suffer from aliases but magic in the hardware deals + * with that for us so we don't need to take care ourselves. + */ + if (c->cputype != CPU_R10000 && c->cputype != CPU_R12000) + if (c->dcache.waysize > PAGE_SIZE) + c->dcache.flags |= MIPS_CACHE_ALIASES; + + if (config & 0x8) /* VI bit */ + c->icache.flags |= MIPS_CACHE_VTAG; + + switch (c->cputype) { + case CPU_20KC: + /* + * Some older 20Kc chips doesn't have the 'VI' bit in + * the config register. + */ + c->icache.flags |= MIPS_CACHE_VTAG; + break; + + case CPU_AU1500: + c->icache.flags |= MIPS_CACHE_IC_F_DC; + break; + } + + printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n", + icache_size >> 10, + cpu_has_vtag_icache ? "virtually tagged" : "physically tagged", + way_string[c->icache.ways], c->icache.linesz); + printk("Primary data cache %ldkB %s, linesize %d bytes.\n", + dcache_size >> 10, way_string[c->dcache.ways], c->dcache.linesz); +} -/* If you even _breathe_ on this function, look at the gcc output - * and make sure it does not pop things on and off the stack for - * the cache sizing loop that executes in KSEG1 space or else - * you will crash and burn badly. You have been warned. +/* + * If you even _breathe_ on this function, look at the gcc output and make sure + * it does not pop things on and off the stack for the cache sizing loop that + * executes in KSEG1 space or else you will crash and burn badly. You have + * been warned. */ -static int __init probe_scache(unsigned long config) +static int __init probe_scache(void) { extern unsigned long stext; unsigned long flags, addr, begin, end, pow2; + unsigned int config = read_c0_config(); + struct cpuinfo_mips *c = ¤t_cpu_data; int tmp; - tmp = ((config >> 17) & 1); - if(tmp) + if (config & CONF_SC) return 0; - tmp = ((config >> 22) & 3); - switch(tmp) { - case 0: - sc_lsize = 16; - break; - case 1: - sc_lsize = 32; - break; - case 2: - sc_lsize = 64; - break; - case 3: - sc_lsize = 128; - break; - } begin = (unsigned long) &stext; begin &= ~((4 * 1024 * 1024) - 1); end = begin + (4 * 1024 * 1024); - /* This is such a bitch, you'd think they would make it - * easy to do this. Away you daemons of stupidity! + /* + * This is such a bitch, you'd think they would make it easy to do + * this. Away you daemons of stupidity! */ - __save_and_cli(flags); + local_irq_save(flags); /* Fill each size-multiple cache line with a valid tag. */ pow2 = (64 * 1024); - for(addr = begin; addr < end; addr = (begin + pow2)) { + for (addr = begin; addr < end; addr = (begin + pow2)) { unsigned long *p = (unsigned long *) addr; __asm__ __volatile__("nop" : : "r" (*p)); /* whee... */ pow2 <<= 1; } /* Load first line with zero (therefore invalid) tag. */ - set_taglo(0); - set_taghi(0); + write_c0_taglo(0); + write_c0_taghi(0); __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */ - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 8, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 9, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 11, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (begin)); + cache_op(Index_Store_Tag_I, begin); + cache_op(Index_Store_Tag_D, begin); + cache_op(Index_Store_Tag_SD, begin); /* Now search for the wrap around point. */ pow2 = (128 * 1024); tmp = 0; - for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) { - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 7, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (addr)); + for (addr = begin + (128 * 1024); addr < end; addr = begin + pow2) { + cache_op(Index_Load_Tag_SD, addr); __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */ - if(!get_taglo()) + if (!read_c0_taglo()) break; pow2 <<= 1; } - __restore_flags(flags); + local_irq_restore(flags); addr -= begin; - printk("Secondary cache sized at %dK linesize %d bytes.\n", - (int) (addr >> 10), sc_lsize); + scache_size = addr; + c->scache.linesz = 16 << ((config & R4K_CONF_SB) >> 22); + c->scache.ways = 1; + c->dcache.waybit = 0; /* does not matter */ + return 1; } @@ -1328,183 +1041,210 @@ { unsigned int prid; - switch(dc_lsize) { + switch (current_cpu_data.dcache.linesz) { case 16: - _clear_page = r4k_clear_page_d16; + if (cpu_has_64bits) + _clear_page = r4k_clear_page_d16; + else + _clear_page = r4k_clear_page32_d16; _copy_page = r4k_copy_page_d16; - _flush_cache_all = r4k_flush_cache_all_d16i16; - _flush_cache_mm = r4k_flush_cache_mm_d16i16; - _flush_cache_range = r4k_flush_cache_range_d16i16; - _flush_cache_page = r4k_flush_cache_page_d16i16; - _flush_page_to_ram = r4k_flush_page_to_ram_d16; + break; case 32: - prid = read_32bit_cp0_register(CP0_PRID) & 0xfff0; + prid = read_c0_prid() & 0xfff0; if (prid == 0x2010) { /* R4600 V1.7 */ _clear_page = r4k_clear_page_r4600_v1; _copy_page = r4k_copy_page_r4600_v1; - _flush_page_to_ram = r4k_flush_page_to_ram_d32_r4600; } else if (prid == 0x2020) { /* R4600 V2.0 */ _clear_page = r4k_clear_page_r4600_v2; _copy_page = r4k_copy_page_r4600_v2; - _flush_page_to_ram = r4k_flush_page_to_ram_d32; } else { - _clear_page = r4k_clear_page_d32; + if (cpu_has_64bits) + _clear_page = r4k_clear_page_d32; + else + _clear_page = r4k_clear_page32_d32; _copy_page = r4k_copy_page_d32; - _flush_page_to_ram = r4k_flush_page_to_ram_d32; } - _flush_cache_all = r4k_flush_cache_all_d32i32; - _flush_cache_mm = r4k_flush_cache_mm_d32i32; - _flush_cache_range = r4k_flush_cache_range_d32i32; - _flush_cache_page = r4k_flush_cache_page_d32i32; break; } - ___flush_cache_all = _flush_cache_all; - - _flush_icache_page = r4k_flush_icache_page_p; - - _dma_cache_wback_inv = r4k_dma_cache_wback_inv_pc; - _dma_cache_wback = r4k_dma_cache_wback_inv_pc; - _dma_cache_inv = r4k_dma_cache_inv_pc; } static void __init setup_scache_funcs(void) { - switch(sc_lsize) { + struct cpuinfo_mips *c = ¤t_cpu_data; + + if (c->dcache.linesz > c->scache.linesz) + panic("Invalid primary cache configuration detected"); + + if (c->cputype == CPU_R10000 || c->cputype == CPU_R12000) { + _clear_page = andes_clear_page; + _copy_page = andes_copy_page; + return; + } + + switch (c->scache.linesz) { case 16: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s16d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s16d16i16; - _flush_cache_range = r4k_flush_cache_range_s16d16i16; - _flush_cache_page = r4k_flush_cache_page_s16d16i16; - break; - case 32: - panic("Invalid cache configuration detected"); - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s16; _clear_page = r4k_clear_page_s16; _copy_page = r4k_copy_page_s16; break; case 32: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s32d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s32d16i16; - _flush_cache_range = r4k_flush_cache_range_s32d16i16; - _flush_cache_page = r4k_flush_cache_page_s32d16i16; - break; - case 32: - _flush_cache_all = r4k_flush_cache_all_s32d32i32; - _flush_cache_mm = r4k_flush_cache_mm_s32d32i32; - _flush_cache_range = r4k_flush_cache_range_s32d32i32; - _flush_cache_page = r4k_flush_cache_page_s32d32i32; - break; - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s32; _clear_page = r4k_clear_page_s32; _copy_page = r4k_copy_page_s32; break; case 64: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s64d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s64d16i16; - _flush_cache_range = r4k_flush_cache_range_s64d16i16; - _flush_cache_page = r4k_flush_cache_page_s64d16i16; - break; - case 32: - _flush_cache_all = r4k_flush_cache_all_s64d32i32; - _flush_cache_mm = r4k_flush_cache_mm_s64d32i32; - _flush_cache_range = r4k_flush_cache_range_s64d32i32; - _flush_cache_page = r4k_flush_cache_page_s64d32i32; - break; - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s64; _clear_page = r4k_clear_page_s64; _copy_page = r4k_copy_page_s64; break; case 128: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s128d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s128d16i16; - _flush_cache_range = r4k_flush_cache_range_s128d16i16; - _flush_cache_page = r4k_flush_cache_page_s128d16i16; - break; - case 32: - _flush_cache_all = r4k_flush_cache_all_s128d32i32; - _flush_cache_mm = r4k_flush_cache_mm_s128d32i32; - _flush_cache_range = r4k_flush_cache_range_s128d32i32; - _flush_cache_page = r4k_flush_cache_page_s128d32i32; - break; - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s128; _clear_page = r4k_clear_page_s128; _copy_page = r4k_copy_page_s128; break; } - ___flush_cache_all = _flush_cache_all; - _flush_icache_page = r4k_flush_icache_page_s; - _dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc; - _dma_cache_wback = r4k_dma_cache_wback_inv_sc; - _dma_cache_inv = r4k_dma_cache_inv_sc; } typedef int (*probe_func_t)(unsigned long); +extern int r5k_sc_init(void); +extern int rm7k_sc_init(void); -static inline void __init setup_scache(unsigned int config) +static void __init setup_scache(void) { + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int config = read_c0_config(); probe_func_t probe_scache_kseg1; int sc_present = 0; - /* Maybe the cpu knows about a l2 cache? */ - probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); - sc_present = probe_scache_kseg1(config); + /* + * Do the probing thing on R4000SC and R4400SC processors. Other + * processors don't have a S-cache that would be relevant to the + * Linux memory managment. + */ + switch (c->cputype) { + case CPU_R4000PC: + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400PC: + case CPU_R4400SC: + case CPU_R4400MC: + probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); + sc_present = probe_scache_kseg1(config); + break; - if (!sc_present) { - setup_noscache_funcs(); - return; - } + case CPU_R10000: + case CPU_R12000: + scache_size = 0x80000 << ((config & R10K_CONF_SS) >> 16); + c->scache.linesz = 64 << ((config >> 13) & 1); + c->scache.ways = 2; + c->scache.waybit= 0; + sc_present = 1; + break; - switch(mips_cpu.cputype) { case CPU_R5000: case CPU_NEVADA: - setup_noscache_funcs(); -#if defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_NEVADA) - r5k_sc_init(); + setup_noscache_funcs(); +#ifdef CONFIG_R5000_CPU_SCACHE + r5k_sc_init(); #endif - break; + return; + + case CPU_RM7000: + setup_noscache_funcs(); +#ifdef CONFIG_RM7000_CPU_SCACHE + rm7k_sc_init(); +#endif + return; + default: - setup_scache_funcs(); + sc_present = 0; + } + + if (!sc_present) { + setup_noscache_funcs(); + return; } + if ((c->isa_level == MIPS_CPU_ISA_M32 || + c->isa_level == MIPS_CPU_ISA_M64) && + !(c->scache.flags & MIPS_CACHE_NOT_PRESENT)) + panic("Dunno how to handle MIPS32 / MIPS64 second level cache"); + + /* compute a couple of other cache variables */ + c->scache.waysize = scache_size / c->scache.ways; + + c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways); + printk("Unified secondary cache %ldkB %s, linesize %d bytes.\n", + scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); + + c->options |= MIPS_CPU_SUBSET_CACHES; + setup_scache_funcs(); } -void __init ld_mmu_r4xx0(void) +static inline void coherency_setup(void) { - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); + change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); - change_cp0_config(CONF_CM_CMASK | CONF_CU, CONF_CM_DEFAULT); + /* + * c0_status.cu=0 specifies that updates by the sc instruction use + * the coherency mode specified by the TLB; 1 means cachable + * coherent update on write will be used. Not all processors have + * this bit and; some wire it to zero, others like Toshiba had the + * silly idea of putting something else there ... + */ + switch (current_cpu_data.cputype) { + case CPU_R4000PC: + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400PC: + case CPU_R4400SC: + case CPU_R4400MC: + clear_c0_config(CONF_CU); + break; + } - probe_icache(config); - probe_dcache(config); - setup_scache(config); +} - switch(mips_cpu.cputype) { - case CPU_R4600: /* QED style two way caches? */ - case CPU_R4700: - case CPU_R5000: - case CPU_NEVADA: - _flush_cache_page = r4k_flush_cache_page_d32i32_r4600; - } +void __init ld_mmu_r4xx0(void) +{ + extern char except_vec2_generic; + struct cpuinfo_mips *c = ¤t_cpu_data; - _flush_cache_sigtramp = r4k_flush_cache_sigtramp; - _flush_icache_range = r4k_flush_icache_range; /* Ouch */ - if ((read_32bit_cp0_register(CP0_PRID) & 0xfff0) == 0x2020) { - _flush_cache_sigtramp = r4600v20k_flush_cache_sigtramp; - } + /* Default cache error handler for R4000 and R5000 family */ + memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80); + memcpy((void *)(KSEG1 + 0x100), &except_vec2_generic, 0x80); + + probe_pcache(); + setup_scache(); + coherency_setup(); + + if (c->dcache.sets * c->dcache.ways > PAGE_SIZE) + c->dcache.flags |= MIPS_CACHE_ALIASES; + + /* + * Some MIPS32 and MIPS64 processors have physically indexed caches. + * This code supports virtually indexed processors and will be + * unnecessarily inefficient on physically indexed processors. + */ + shm_align_mask = max_t( unsigned long, + c->dcache.sets * c->dcache.linesz - 1, + PAGE_SIZE - 1); + + _flush_cache_all = r4k_flush_cache_all; + ___flush_cache_all = r4k___flush_cache_all; + _flush_cache_mm = r4k_flush_cache_mm; + _flush_cache_page = r4k_flush_cache_page; + _flush_icache_page = r4k_flush_icache_page; + _flush_cache_range = r4k_flush_cache_range; + + _flush_cache_sigtramp = r4k_flush_cache_sigtramp; + _flush_icache_all = r4k_flush_icache_all; + _flush_data_cache_page = r4k_flush_data_cache_page; + _flush_icache_range = r4k_flush_icache_range; + +#ifdef CONFIG_NONCOHERENT_IO + _dma_cache_wback_inv = r4k_dma_cache_wback_inv; + _dma_cache_wback = r4k_dma_cache_wback_inv; + _dma_cache_inv = r4k_dma_cache_inv; +#endif __flush_cache_all(); } diff -urN linux-2.4.21-bk37/arch/mips/mm/c-r5432.c linux-2.4.21-bk38/arch/mips/mm/c-r5432.c --- linux-2.4.21-bk37/arch/mips/mm/c-r5432.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/c-r5432.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,480 +0,0 @@ -/* - * 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. - * - * r5432.c: NEC Vr5432 processor. We cannot use r4xx0.c because of - * its unique way-selection method for indexed operations. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 2000 Jun Sun (jsun@mvista.com) - * - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* CP0 hazard avoidance. */ -#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ - "nop; nop; nop; nop; nop; nop;\n\t" \ - ".set reorder\n\t") - -#include -#include - -#undef DEBUG_CACHE - -/* Primary cache parameters. */ -static int icache_size, dcache_size; /* Size in bytes */ -static int ic_lsize, dc_lsize; /* LineSize in bytes */ - - -/* -------------------------------------------------------------------- */ -/* #include */ - -static inline void flush_icache_line_indexed(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - "cache %1, 1(%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Index_Invalidate_I)); -} - -static inline void flush_dcache_line_indexed(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - "cache %1, 1(%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Index_Writeback_Inv_D)); -} - -static inline void flush_icache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Invalidate_I)); -} - -static inline void flush_dcache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Writeback_Inv_D)); -} - -static inline void invalidate_dcache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Invalidate_D)); -} - - -/* - * The next two are for badland addresses like signal trampolines. - */ -static inline void protected_flush_icache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n" - "1:\tcache %1,(%0)\n" - "2:\t.set mips0\n\t" - ".set reorder\n\t" - ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,2b\n\t" - ".previous" - : - : "r" (addr), - "i" (Hit_Invalidate_I)); -} - -static inline void protected_writeback_dcache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n" - "1:\tcache %1,(%0)\n" - "2:\t.set mips0\n\t" - ".set reorder\n\t" - ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,2b\n\t" - ".previous" - : - : "r" (addr), - "i" (Hit_Writeback_D)); -} - - -#define cache32_unroll32(base,op) \ - __asm__ __volatile__(" \ - .set noreorder; \ - .set mips3; \ - cache %1, 0x000(%0); cache %1, 0x020(%0); \ - cache %1, 0x040(%0); cache %1, 0x060(%0); \ - cache %1, 0x080(%0); cache %1, 0x0a0(%0); \ - cache %1, 0x0c0(%0); cache %1, 0x0e0(%0); \ - cache %1, 0x100(%0); cache %1, 0x120(%0); \ - cache %1, 0x140(%0); cache %1, 0x160(%0); \ - cache %1, 0x180(%0); cache %1, 0x1a0(%0); \ - cache %1, 0x1c0(%0); cache %1, 0x1e0(%0); \ - cache %1, 0x200(%0); cache %1, 0x220(%0); \ - cache %1, 0x240(%0); cache %1, 0x260(%0); \ - cache %1, 0x280(%0); cache %1, 0x2a0(%0); \ - cache %1, 0x2c0(%0); cache %1, 0x2e0(%0); \ - cache %1, 0x300(%0); cache %1, 0x320(%0); \ - cache %1, 0x340(%0); cache %1, 0x360(%0); \ - cache %1, 0x380(%0); cache %1, 0x3a0(%0); \ - cache %1, 0x3c0(%0); cache %1, 0x3e0(%0); \ - .set mips0; \ - .set reorder" \ - : \ - : "r" (base), \ - "i" (op)); - -static inline void blast_dcache32(void) -{ - unsigned long start = KSEG0; - unsigned long end = (start + dcache_size/2); - - while(start < end) { - cache32_unroll32(start,Index_Writeback_Inv_D); - cache32_unroll32(start+1,Index_Writeback_Inv_D); - start += 0x400; - } -} - -static inline void blast_dcache32_page(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache32_unroll32(start,Hit_Writeback_Inv_D); - start += 0x400; - } -} - -static inline void blast_dcache32_page_indexed(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache32_unroll32(start,Index_Writeback_Inv_D); - cache32_unroll32(start+1,Index_Writeback_Inv_D); - start += 0x400; - } -} - -static inline void blast_icache32(void) -{ - unsigned long start = KSEG0; - unsigned long end = (start + icache_size/2); - - while(start < end) { - cache32_unroll32(start,Index_Invalidate_I); - cache32_unroll32(start+1,Index_Invalidate_I); - start += 0x400; - } -} - -static inline void blast_icache32_page(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache32_unroll32(start,Hit_Invalidate_I); - start += 0x400; - } -} - -static inline void blast_icache32_page_indexed(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache32_unroll32(start,Index_Invalidate_I); - cache32_unroll32(start+1,Index_Invalidate_I); - start += 0x400; - } -} - -/* -------------------------------------------------------------------- */ - -/* - * If you think for one second that this stuff coming up is a lot - * of bulky code eating too many kernel cache lines. Think _again_. - * - * Consider: - * 1) Taken branches have a 3 cycle penalty on R4k - * 2) The branch itself is a real dead cycle on even R4600/R5000. - * 3) Only one of the following variants of each type is even used by - * the kernel based upon the cache parameters we detect at boot time. - * - * QED. - */ - -static inline void r5432_flush_cache_all_d32i32(void) -{ - blast_dcache32(); blast_icache32(); -} - -static void r5432_flush_cache_range_d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - blast_dcache32(); blast_icache32(); - } -} - -/* - * On architectures like the Sparc, we could get rid of lines in - * the cache created only by a certain context, but on the MIPS - * (and actually certain Sparc's) we cannot. - */ -static void r5432_flush_cache_mm_d32i32(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r5432_flush_cache_all_d32i32(); - } -} - -static void r5432_flush_cache_page_d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_PRESENT)) - return; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache32_page(page); - } else { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache32_page_indexed(page); - } -} - - -/* If the addresses passed to these routines are valid, they are - * either: - * - * 1) In KSEG0, so we can do a direct flush of the page. - * 2) In KSEG2, and since every process can translate those - * addresses all the time in kernel mode we can do a direct - * flush. - * 3) In KSEG1, no flush necessary. - */ -static void r5432_flush_page_to_ram_d32(struct page *page) -{ - blast_dcache32_page((unsigned long)page_address(page)); -} - -static void -r5432_flush_icache_range(unsigned long start, unsigned long end) -{ - r5432_flush_cache_all_d32i32(); -} - -/* - * Ok, this seriously sucks. We use them to flush a user page but don't - * know the virtual address, so we have to blast away the whole icache - * which is significantly more expensive than the real thing. - */ -static void -r5432_flush_icache_page_i32(struct vm_area_struct *vma, struct page *page) -{ - if (!(vma->vm_flags & VM_EXEC)) - return; - - r5432_flush_cache_all_d32i32(); -} - -/* - * Writeback and invalidate the primary cache dcache before DMA. - */ -static void -r5432_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= dcache_size) { - flush_cache_all(); - } else { - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - } - bc_wback_inv(addr, size); -} - -static void -r5432_dma_cache_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= dcache_size) { - flush_cache_all(); - } else { - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - } - - bc_inv(addr, size); -} - -static void -r5432_dma_cache_wback(unsigned long addr, unsigned long size) -{ - panic("r5432_dma_cache called - should not happen."); -} - -/* - * While we're protected against bad userland addresses we don't care - * very much about what happens in that case. Usually a segmentation - * fault will dump the process later on anyway ... - */ -static void r5432_flush_cache_sigtramp(unsigned long addr) -{ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -/* Detect and size the various r4k caches. */ -static void __init probe_icache(unsigned long config) -{ - icache_size = 1 << (12 + ((config >> 9) & 7)); - ic_lsize = 16 << ((config >> 5) & 1); - - printk("Primary instruction cache %dkb, linesize %d bytes.\n", - icache_size >> 10, ic_lsize); -} - -static void __init probe_dcache(unsigned long config) -{ - dcache_size = 1 << (12 + ((config >> 6) & 7)); - dc_lsize = 16 << ((config >> 4) & 1); - - printk("Primary data cache %dkb, linesize %d bytes.\n", - dcache_size >> 10, dc_lsize); -} - - -void __init ld_mmu_r5432(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - - change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); - - probe_icache(config); - probe_dcache(config); - - _clear_page = r5432_clear_page_d32; - _copy_page = r5432_copy_page_d32; - _flush_cache_all = r5432_flush_cache_all_d32i32; - ___flush_cache_all = r5432_flush_cache_all_d32i32; - _flush_page_to_ram = r5432_flush_page_to_ram_d32; - _flush_cache_mm = r5432_flush_cache_mm_d32i32; - _flush_cache_range = r5432_flush_cache_range_d32i32; - _flush_cache_page = r5432_flush_cache_page_d32i32; - _flush_icache_page = r5432_flush_icache_page_i32; - _dma_cache_wback_inv = r5432_dma_cache_wback_inv_pc; - _dma_cache_wback = r5432_dma_cache_wback; - _dma_cache_inv = r5432_dma_cache_inv_pc; - - _flush_cache_sigtramp = r5432_flush_cache_sigtramp; - _flush_icache_range = r5432_flush_icache_range; /* Ouch */ - - __flush_cache_all(); -} diff -urN linux-2.4.21-bk37/arch/mips/mm/c-rm7k.c linux-2.4.21-bk38/arch/mips/mm/c-rm7k.c --- linux-2.4.21-bk37/arch/mips/mm/c-rm7k.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/c-rm7k.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,347 +0,0 @@ -/* - * 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. - * - * r4xx0.c: R4000 processor variant specific MMU/Cache routines. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998 Ralf Baechle ralf@gnu.org - * - * To do: - * - * - this code is a overbloated pig - * - many of the bug workarounds are not efficient at all, but at - * least they are functional ... - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* CP0 hazard avoidance. */ -#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ - "nop; nop; nop; nop; nop; nop;\n\t" \ - ".set reorder\n\t") - -/* Primary cache parameters. */ -static int icache_size, dcache_size; /* Size in bytes */ - -#define ic_lsize 32 /* Fixed to 32 byte on RM7000 */ -#define dc_lsize 32 /* Fixed to 32 byte on RM7000 */ -#define sc_lsize 32 /* Fixed to 32 byte on RM7000 */ -#define tc_pagesize (32*128) - -/* Secondary cache parameters. */ -#define scache_size (256*1024) /* Fixed to 256KiB on RM7000 */ - -#include -#include - -int rm7k_tcache_enabled = 0; - -/* - * Not added to asm/r4kcache.h because it seems to be RM7000-specific. - */ -#define Page_Invalidate_T 0x16 - -static inline void invalidate_tcache_page(unsigned long addr) -{ - __asm__ __volatile__( - ".set\tnoreorder\t\t\t# invalidate_tcache_page\n\t" - ".set\tmips3\n\t" - "cache\t%1, (%0)\n\t" - ".set\tmips0\n\t" - ".set\treorder" - : - : "r" (addr), - "i" (Page_Invalidate_T)); -} - -static void __flush_cache_all_d32i32(void) -{ - blast_dcache32(); - blast_icache32(); -} - -static inline void rm7k_flush_cache_all_d32i32(void) -{ - /* Yes! Caches that don't suck ... */ -} - -static void rm7k_flush_cache_range_d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - /* RM7000 caches are sane ... */ -} - -static void rm7k_flush_cache_mm_d32i32(struct mm_struct *mm) -{ - /* RM7000 caches are sane ... */ -} - -static void rm7k_flush_cache_page_d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - /* RM7000 caches are sane ... */ -} - -static void rm7k_flush_page_to_ram_d32i32(struct page * page) -{ - /* Yes! Caches that don't suck! */ -} - -static void rm7k_flush_icache_range(unsigned long start, unsigned long end) -{ - /* - * FIXME: This is overdoing things and harms performance. - */ - __flush_cache_all_d32i32(); -} - -static void rm7k_flush_icache_page(struct vm_area_struct *vma, - struct page *page) -{ - /* - * FIXME: We should not flush the entire cache but establish some - * temporary mapping and use hit_invalidate operation to flush out - * the line from the cache. - */ - __flush_cache_all_d32i32(); -} - - -/* - * Writeback and invalidate the primary cache dcache before DMA. - * (XXX These need to be fixed ...) - */ -static void -rm7k_dma_cache_wback_inv(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } - - if (!rm7k_tcache_enabled) - return; - - a = addr & ~(tc_pagesize - 1); - end = (addr + size) & ~(tc_pagesize - 1); - while(1) { - invalidate_tcache_page(a); /* Page_Invalidate_T */ - if (a == end) break; - a += tc_pagesize; - } -} - -static void -rm7k_dma_cache_inv(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - invalidate_dcache_line(a); /* Hit_Invalidate_D */ - invalidate_scache_line(a); /* Hit_Invalidate_SD */ - if (a == end) break; - a += sc_lsize; - } - - if (!rm7k_tcache_enabled) - return; - - a = addr & ~(tc_pagesize - 1); - end = (addr + size) & ~(tc_pagesize - 1); - while(1) { - invalidate_tcache_page(a); /* Page_Invalidate_T */ - if (a == end) break; - a += tc_pagesize; - } -} - -static void -rm7k_dma_cache_wback(unsigned long addr, unsigned long size) -{ - panic("rm7k_dma_cache_wback called - should not happen."); -} - -/* - * While we're protected against bad userland addresses we don't care - * very much about what happens in that case. Usually a segmentation - * fault will dump the process later on anyway ... - */ -static void rm7k_flush_cache_sigtramp(unsigned long addr) -{ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -/* Detect and size the caches. */ -static inline void probe_icache(unsigned long config) -{ - icache_size = 1 << (12 + ((config >> 9) & 7)); - - printk(KERN_INFO "Primary instruction cache %dKiB.\n", icache_size >> 10); -} - -static inline void probe_dcache(unsigned long config) -{ - dcache_size = 1 << (12 + ((config >> 6) & 7)); - - printk(KERN_INFO "Primary data cache %dKiB.\n", dcache_size >> 10); -} - - -/* - * This function is executed in the uncached segment KSEG1. - * It must not touch the stack, because the stack pointer still points - * into KSEG0. - * - * Three options: - * - Write it in assembly and guarantee that we don't use the stack. - * - Disable caching for KSEG0 before calling it. - * - Pray that GCC doesn't randomly start using the stack. - * - * This being Linux, we obviously take the least sane of those options - - * following DaveM's lead in r4xx0.c - * - * It seems we get our kicks from relying on unguaranteed behaviour in GCC - */ -static __init void setup_scache(void) -{ - int register i; - - set_cp0_config(1<<3 /* CONF_SE */); - - set_taglo(0); - set_taghi(0); - - for (i=0; i> 31) & 1) - return; - - printk(KERN_INFO "Secondary cache %dKiB, linesize %d bytes.\n", - (scache_size >> 10), sc_lsize); - - if ((config >> 3) & 1) - return; - - printk(KERN_INFO "Enabling secondary cache..."); - func(); - printk("Done\n"); -} - -static inline void probe_tcache(unsigned long config) -{ - if ((config >> 17) & 1) - return; - - /* We can't enable the L3 cache yet. There may be board-specific - * magic necessary to turn it on, and blindly asking the CPU to - * start using it would may give cache errors. - * - * Also, board-specific knowledge may allow us to use the - * CACHE Flash_Invalidate_T instruction if the tag RAM supports - * it, and may specify the size of the L3 cache so we don't have - * to probe it. - */ - printk(KERN_INFO "Tertiary cache present, %s enabled\n", - config&(1<<12) ? "already" : "not (yet)"); - - if ((config >> 12) & 1) - rm7k_tcache_enabled = 1; -} - -void __init ld_mmu_rm7k(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - unsigned long addr; - - change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); - - /* RM7000 erratum #31. The icache is screwed at startup. */ - set_taglo(0); - set_taghi(0); - for (addr = KSEG0; addr <= KSEG0 + 4096; addr += ic_lsize) { - __asm__ __volatile__ ( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache\t%1, 0(%0)\n\t" - "cache\t%1, 0x1000(%0)\n\t" - "cache\t%1, 0x2000(%0)\n\t" - "cache\t%1, 0x3000(%0)\n\t" - "cache\t%2, 0(%0)\n\t" - "cache\t%2, 0x1000(%0)\n\t" - "cache\t%2, 0x2000(%0)\n\t" - "cache\t%2, 0x3000(%0)\n\t" - "cache\t%1, 0(%0)\n\t" - "cache\t%1, 0x1000(%0)\n\t" - "cache\t%1, 0x2000(%0)\n\t" - "cache\t%1, 0x3000(%0)\n\t" - ".set\tmips0\n\t" - ".set\treorder\n\t" - : - : "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill)); - } - - change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); - - probe_icache(config); - probe_dcache(config); - probe_scache(config); - probe_tcache(config); - - _clear_page = rm7k_clear_page; - _copy_page = rm7k_copy_page; - - _flush_cache_all = rm7k_flush_cache_all_d32i32; - ___flush_cache_all = __flush_cache_all_d32i32; - _flush_cache_mm = rm7k_flush_cache_mm_d32i32; - _flush_cache_range = rm7k_flush_cache_range_d32i32; - _flush_cache_page = rm7k_flush_cache_page_d32i32; - _flush_page_to_ram = rm7k_flush_page_to_ram_d32i32; - _flush_cache_sigtramp = rm7k_flush_cache_sigtramp; - _flush_icache_range = rm7k_flush_icache_range; - _flush_icache_page = rm7k_flush_icache_page; - - _dma_cache_wback_inv = rm7k_dma_cache_wback_inv; - _dma_cache_wback = rm7k_dma_cache_wback; - _dma_cache_inv = rm7k_dma_cache_inv; - - __flush_cache_all_d32i32(); -} diff -urN linux-2.4.21-bk37/arch/mips/mm/c-sb1.c linux-2.4.21-bk38/arch/mips/mm/c-sb1.c --- linux-2.4.21-bk37/arch/mips/mm/c-sb1.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/c-sb1.c 2003-08-24 02:55:57.000000000 -0700 @@ -25,21 +25,34 @@ #include #include +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS +extern void sb1_dma_init(void); +extern void sb1_clear_page_dma(void * page); +extern void sb1_copy_page_dma(void * to, void * from); +#else +extern void sb1_clear_page(void * page); +extern void sb1_copy_page(void * to, void * from); +#endif + /* These are probed at ld_mmu time */ -static unsigned int icache_size; -static unsigned int dcache_size; +static unsigned long icache_size; +static unsigned long dcache_size; -static unsigned int icache_line_size; -static unsigned int dcache_line_size; +static unsigned long icache_line_size; +static unsigned long dcache_line_size; static unsigned int icache_index_mask; +static unsigned int dcache_index_mask; -static unsigned int icache_assoc; -static unsigned int dcache_assoc; +static unsigned long icache_assoc; +static unsigned long dcache_assoc; static unsigned int icache_sets; static unsigned int dcache_sets; +static unsigned int icache_range_cutoff; +static unsigned int dcache_range_cutoff; + void pgd_init(unsigned long page) { unsigned long *p = (unsigned long *) page; @@ -70,59 +83,223 @@ * to flush it */ -static void sb1_flush_cache_all(void) -{ -} - -static void local_sb1___flush_cache_all(void) +/* + * Writeback and invalidate the entire dcache + */ +static inline void __sb1_writeback_inv_dcache_all(void) { - /* - * Haven't worried too much about speed here; given that we're flushing - * the icache, the time to invalidate is dwarfed by the time it's going - * to take to refill it. Register usage: - * - * $1 - moving cache index - * $2 - set count - */ __asm__ __volatile__ ( ".set push \n" ".set noreorder \n" ".set noat \n" ".set mips4 \n" - " move $1, %2 \n" /* Start at index 0 */ - "1: cache %3, 0($1) \n" /* WB/Invalidate this index */ + " move $1, $0 \n" /* Start at index 0 */ + "1: cache %2, 0($1) \n" /* Invalidate this index */ + " cache %2, (1<<13)($1)\n" /* Invalidate this index */ + " cache %2, (2<<13)($1)\n" /* Invalidate this index */ + " cache %2, (3<<13)($1)\n" /* Invalidate this index */ " addiu %1, %1, -1 \n" /* Decrement loop count */ " bnez %1, 1b \n" /* loop test */ - " addu $1, $1, %0 \n" /* Next address */ + " addu $1, $1, %0 \n" /* Next address */ ".set pop \n" : - : "r" (dcache_line_size), "r" (dcache_sets * dcache_assoc), - "r" (KSEG0), "i" (Index_Writeback_Inv_D)); + : "r" (dcache_line_size), "r" (dcache_sets), + "i" (Index_Writeback_Inv_D)); +} +/* + * Writeback and invalidate a range of the dcache. The addresses are + * virtual, and since we're using index ops and bit 12 is part of both + * the virtual frame and physical index, we have to clear both sets + * (bit 12 set and cleared). + */ +static inline void __sb1_writeback_inv_dcache_range(unsigned long start, + unsigned long end) +{ + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips4 \n" + " and $1, %0, %3 \n" /* mask non-index bits */ + "1: cache %4, (0<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-WB-inval this address */ + " xori $1, $1, 1<<12 \n" /* flip bit 12 (va/pa alias) */ + " cache %4, (0<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-WB-inval this address */ + " addu %0, %0, %2 \n" /* next line */ + " bne %0, %1, 1b \n" /* loop test */ + " and $1, %0, %3 \n" /* mask non-index bits */ + " sync \n" + " .set pop \n" + : + : "r" (start & ~(dcache_line_size - 1)), + "r" ((end + dcache_line_size - 1) & ~(dcache_line_size - 1)), + "r" (dcache_line_size), + "r" (dcache_index_mask), + "i" (Index_Writeback_Inv_D)); +} + +/* + * Writeback and invalidate a range of the dcache. With physical + * addresseses, we don't have to worry about possible bit 12 aliasing. + * XXXKW is it worth turning on KX and using hit ops with xkphys? + */ +static inline void __sb1_writeback_inv_dcache_phys_range(unsigned long start, + unsigned long end) +{ + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips4 \n" + " and $1, %0, %3 \n" /* mask non-index bits */ + "1: cache %4, (0<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-WB-inval this address */ + " addu %0, %0, %2 \n" /* next line */ + " bne %0, %1, 1b \n" /* loop test */ + " and $1, %0, %3 \n" /* mask non-index bits */ + " sync \n" + " .set pop \n" + : + : "r" (start & ~(dcache_line_size - 1)), + "r" ((end + dcache_line_size - 1) & ~(dcache_line_size - 1)), + "r" (dcache_line_size), + "r" (dcache_index_mask), + "i" (Index_Writeback_Inv_D)); +} + + +/* + * Invalidate the entire icache + */ +static inline void __sb1_flush_icache_all(void) +{ __asm__ __volatile__ ( ".set push \n" ".set noreorder \n" - ".set mips2 \n" - "sync \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS /* Bug 1384 */ - "sync \n" + ".set noat \n" + ".set mips4 \n" + " move $1, $0 \n" /* Start at index 0 */ + "1: cache %2, 0($1) \n" /* Invalidate this index */ + " cache %2, (1<<13)($1)\n" /* Invalidate this index */ + " cache %2, (2<<13)($1)\n" /* Invalidate this index */ + " cache %2, (3<<13)($1)\n" /* Invalidate this index */ + " addiu %1, %1, -1 \n" /* Decrement loop count */ + " bnez %1, 1b \n" /* loop test */ + " addu $1, $1, %0 \n" /* Next address */ + " bnezl $0, 2f \n" /* Force mispredict */ + " nop \n" + "2: sync \n" + ".set pop \n" + : + : "r" (icache_line_size), "r" (icache_sets), + "i" (Index_Invalidate_I)); +} + +/* + * Flush the icache for a given physical page. Need to writeback the + * dcache first, then invalidate the icache. If the page isn't + * executable, nothing is required. + */ +static void local_sb1_flush_cache_page(struct vm_area_struct *vma, + unsigned long addr) +{ + int cpu = smp_processor_id(); + +#ifndef CONFIG_SMP + if (!(vma->vm_flags & VM_EXEC)) + return; +#endif + + __sb1_writeback_inv_dcache_range(addr, addr + PAGE_SIZE); + + /* + * Bumping the ASID is probably cheaper than the flush ... + */ + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); +} + +#ifdef CONFIG_SMP +struct flush_cache_page_args { + struct vm_area_struct *vma; + unsigned long addr; +}; + +static void sb1_flush_cache_page_ipi(void *info) +{ + struct flush_cache_page_args *args = info; + + local_sb1_flush_cache_page(args->vma, args->addr); +} + +/* Dirty dcache could be on another CPU, so do the IPIs */ +static void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr) +{ + struct flush_cache_page_args args; + + if (!(vma->vm_flags & VM_EXEC)) + return; + + args.vma = vma; + args.addr = addr; + smp_call_function(sb1_flush_cache_page_ipi, (void *) &args, 1, 1); + local_sb1_flush_cache_page(vma, addr); +} +#else +void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr); +asm("sb1_flush_cache_page = local_sb1_flush_cache_page"); #endif - ".set pop \n"); +/* + * Invalidate a range of the icache. The addresses are virtual, and + * the cache is virtually indexed and tagged. However, we don't + * necessarily have the right ASID context, so use index ops instead + * of hit ops. + */ +static inline void __sb1_flush_icache_range(unsigned long start, + unsigned long end) +{ __asm__ __volatile__ ( ".set push \n" ".set noreorder \n" ".set noat \n" ".set mips4 \n" - " move $1, %2 \n" /* Start at index 0 */ - "1: cache %3, 0($1) \n" /* Invalidate this index */ - " addiu %1, %1, -1 \n" /* Decrement loop count */ - " bnez %1, 1b \n" /* loop test */ - " addu $1, $1, %0 \n" /* Next address */ + " and $1, %0, %3 \n" /* mask non-index bits */ + "1: cache %4, (0<<13)($1) \n" /* Index-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-inval this address */ + " addu %0, %0, %2 \n" /* next line */ + " bne %0, %1, 1b \n" /* loop test */ + " and $1, %0, %3 \n" /* mask non-index bits */ + " bnezl $0, 2f \n" /* Force mispredict */ + " nop \n" + "2: sync \n" ".set pop \n" : - : "r" (icache_line_size), "r" (icache_sets * icache_assoc), - "r" (KSEG0), "i" (Index_Invalidate_I)); + : "r" (start & ~(icache_line_size - 1)), + "r" ((end + icache_line_size - 1) & ~(icache_line_size - 1)), + "r" (icache_line_size), + "r" (icache_index_mask), + "i" (Index_Invalidate_I)); +} + + +/* + * Invalidate all caches on this CPU + */ +static void local_sb1___flush_cache_all(void) +{ + __sb1_writeback_inv_dcache_all(); + __sb1_flush_icache_all(); } #ifdef CONFIG_SMP @@ -139,80 +316,28 @@ asm("sb1___flush_cache_all = local_sb1___flush_cache_all"); #endif - /* * When flushing a range in the icache, we have to first writeback * the dcache for the same range, so new ifetches will see any * data that was dirty in the dcache. * - * The start/end arguments are expected to be Kseg addresses. + * The start/end arguments are Kseg addresses (possibly mapped Kseg). */ -static void local_sb1_flush_icache_range(unsigned long start, unsigned long end) +static void local_sb1_flush_icache_range(unsigned long start, + unsigned long end) { -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - unsigned long flags; - local_irq_save(flags); -#endif - - __asm__ __volatile__ ( - ".set push \n" - ".set noreorder \n" - ".set noat \n" - ".set mips4 \n" - " move $1, %0 \n" - "1: \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - ".align 3 \n" - " lw $0, 0($1) \n" /* Bug 1370, 1368 */ - " sync \n" -#endif - " cache %3, 0($1) \n" /* Hit-WB{,-inval} this address */ - " bne $1, %1, 1b \n" /* loop test */ - " addu $1, $1, %2 \n" /* next line */ - ".set pop \n" - : - : "r" (start & ~(dcache_line_size - 1)), - "r" ((end - 1) & ~(dcache_line_size - 1)), - "r" (dcache_line_size), -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - "i" (Hit_Writeback_Inv_D) -#else - "i" (Hit_Writeback_D) -#endif - ); - __asm__ __volatile__ ( - ".set push \n" - ".set noreorder \n" - ".set mips2 \n" - "sync \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS /* Bug 1384 */ - "sync \n" -#endif - ".set pop \n"); -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - local_irq_restore(flags); -#endif - - __asm__ __volatile__ ( - ".set push \n" - ".set noreorder \n" - ".set noat \n" - ".set mips4 \n" - " move $1, %0 \n" - ".align 3 \n" - "1: cache %3, (0<<13)($1) \n" /* Index-inval this address */ - " cache %3, (1<<13)($1) \n" /* Index-inval this address */ - " cache %3, (2<<13)($1) \n" /* Index-inval this address */ - " cache %3, (3<<13)($1) \n" /* Index-inval this address */ - " bne $1, %1, 1b \n" /* loop test */ - " addu $1, $1, %2 \n" /* next line */ - ".set pop \n" - : - : "r" (start & ~(icache_line_size - 1)), - "r" ((end - 1) & ~(icache_line_size - 1)), - "r" (icache_line_size), - "i" (Index_Invalidate_I)); + /* Just wb-inv the whole dcache if the range is big enough */ + if ((end - start) > dcache_range_cutoff) + __sb1_writeback_inv_dcache_all(); + else + __sb1_writeback_inv_dcache_range(start, end); + + /* Just flush the whole icache if the range is big enough */ + if ((end - start) > icache_range_cutoff) + __sb1_flush_icache_all(); + else + __sb1_flush_icache_range(start, end); } #ifdef CONFIG_SMP @@ -243,186 +368,123 @@ #endif /* - * If there's no context yet, or the page isn't executable, no icache flush - * is needed + * Flush the icache for a given physical page. Need to writeback the + * dcache first, then invalidate the icache. If the page isn't + * executable, nothing is required. */ -static void sb1_flush_icache_page(struct vm_area_struct *vma, +static void local_sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page) { + unsigned long start; + int cpu = smp_processor_id(); + +#ifndef CONFIG_SMP if (!(vma->vm_flags & VM_EXEC)) return; +#endif + /* Need to writeback any dirty data for that page, we have the PA */ + start = (unsigned long)(page-mem_map) << PAGE_SHIFT; + __sb1_writeback_inv_dcache_phys_range(start, start + PAGE_SIZE); /* - * We're not sure of the virtual address(es) involved here, so - * conservatively flush the entire caches on all processors - * (ouch). + * If there's a context, bump the ASID (cheaper than a flush, + * since we don't know VAs!) */ - sb1___flush_cache_all(); + if (cpu_context(cpu, vma->vm_mm) != 0) { + drop_mmu_context(vma->vm_mm, cpu); + } } -static inline void protected_flush_icache_line(unsigned long addr) +#ifdef CONFIG_SMP +struct flush_icache_page_args { + struct vm_area_struct *vma; + struct page *page; +}; + +static void sb1_flush_icache_page_ipi(void *info) { - __asm__ __volatile__( - " .set push \n" - " .set noreorder \n" - " .set mips4 \n" - "1: cache %1, (%0) \n" - "2: .set pop \n" - " .section __ex_table,\"a\"\n" - " .word 1b, 2b \n" - " .previous" - : - : "r" (addr), - "i" (Hit_Invalidate_I)); + struct flush_icache_page_args *args = info; + local_sb1_flush_icache_page(args->vma, args->page); } -static inline void protected_writeback_dcache_line(unsigned long addr) +/* Dirty dcache could be on another CPU, so do the IPIs */ +static void sb1_flush_icache_page(struct vm_area_struct *vma, + struct page *page) { -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - /* Have to be sure the TLB entry exists for the cache op, - so we have to be sure that nothing happens in between the - lw and the cache op - */ - unsigned long flags; - local_irq_save(flags); -#endif - __asm__ __volatile__( - " .set push \n" - " .set noreorder \n" - " .set mips4 \n" - "1: \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - " lw $0, (%0) \n" - " sync \n" -#endif - " cache %1, 0(%0) \n" /* Hit-WB{-inval} this address */ - /* XXX: should be able to do this after both dcache cache - ops, but there's no guarantee that this will be inlined, - and the pass1 restriction checker can't detect syncs - following cache ops except in the following basic block. - */ - " sync \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS /* Bug 1384 */ - " sync \n" -#endif - "2: .set pop \n" - " .section __ex_table,\"a\"\n" - " .word 1b, 2b \n" - " .previous" - : - : "r" (addr), -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - "i" (Hit_Writeback_Inv_D) + struct flush_icache_page_args args; + + if (!(vma->vm_flags & VM_EXEC)) + return; + args.vma = vma; + args.page = page; + smp_call_function(sb1_flush_icache_page_ipi, (void *) &args, 1, 1); + local_sb1_flush_icache_page(vma, page); +} #else - "i" (Hit_Writeback_D) -#endif - ); -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - local_irq_restore(flags); +void sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page); +asm("sb1_flush_icache_page = local_sb1_flush_icache_page"); #endif -} /* * A signal trampoline must fit into a single cacheline. */ static void local_sb1_flush_cache_sigtramp(unsigned long addr) { - unsigned long daddr, iaddr; - - daddr = addr & ~(dcache_line_size - 1); - protected_writeback_dcache_line(daddr); - iaddr = addr & ~(icache_line_size - 1); - protected_flush_icache_line(iaddr); + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips4 \n" + " cache %2, (0<<13)(%0) \n" /* Index-inval this address */ + " cache %2, (1<<13)(%0) \n" /* Index-inval this address */ + " cache %2, (2<<13)(%0) \n" /* Index-inval this address */ + " cache %2, (3<<13)(%0) \n" /* Index-inval this address */ + " xori $1, %0, 1<<12 \n" /* Flip index bit 12 */ + " cache %2, (0<<13)($1) \n" /* Index-inval this address */ + " cache %2, (1<<13)($1) \n" /* Index-inval this address */ + " cache %2, (2<<13)($1) \n" /* Index-inval this address */ + " cache %2, (3<<13)($1) \n" /* Index-inval this address */ + " cache %3, (0<<13)(%1) \n" /* Index-inval this address */ + " cache %3, (1<<13)(%1) \n" /* Index-inval this address */ + " cache %3, (2<<13)(%1) \n" /* Index-inval this address */ + " cache %3, (3<<13)(%1) \n" /* Index-inval this address */ + " bnezl $0, 1f \n" /* Force mispredict */ + " nop \n" + "1: \n" + " .set pop \n" + : + : "r" (addr & dcache_index_mask), "r" (addr & icache_index_mask), + "i" (Index_Writeback_Inv_D), "i" (Index_Invalidate_I)); } #ifdef CONFIG_SMP - static void sb1_flush_cache_sigtramp_ipi(void *info) { unsigned long iaddr = (unsigned long) info; - - iaddr = iaddr & ~(icache_line_size - 1); - protected_flush_icache_line(iaddr); + local_sb1_flush_cache_sigtramp(iaddr); } static void sb1_flush_cache_sigtramp(unsigned long addr) { - unsigned long tmp; - - /* - * Flush the local dcache, then load the instruction back into a - * register. That will make sure that any remote CPU also has - * written back it's data cache to memory. - */ local_sb1_flush_cache_sigtramp(addr); - __get_user(tmp, (unsigned long *)addr); - smp_call_function(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1); } - #else void sb1_flush_cache_sigtramp(unsigned long addr); asm("sb1_flush_cache_sigtramp = local_sb1_flush_cache_sigtramp"); #endif -static void sb1_flush_icache_all(void) -{ - /* - * Haven't worried too much about speed here; given that we're flushing - * the icache, the time to invalidate is dwarfed by the time it's going - * to take to refill it. Register usage: - * - * $1 - moving cache index - * $2 - set count - */ - __asm__ __volatile__ ( - ".set push \n" - ".set noreorder \n" - ".set noat \n" - ".set mips4 \n" - " move $1, %2 \n" /* Start at index 0 */ - "1: cache %3, 0($1) \n" /* Invalidate this index */ - " addiu %1, %1, -1 \n" /* Decrement loop count */ - " bnez %1, 1b \n" /* loop test */ - " addu $1, $1, %0 \n" /* Next address */ - ".set pop \n" - : - : "r" (icache_line_size), "r" (icache_sets * icache_assoc), - "r" (KSEG0), "i" (Index_Invalidate_I)); -} /* * Anything that just flushes dcache state can be ignored, as we're always * coherent in dcache space. This is just a dummy function that all the * nop'ed routines point to */ - static void sb1_nop(void) { } /* - * This only needs to make sure stores done up to this - * point are visible to other agents outside the CPU. Given - * the coherent nature of the ZBbus, all that's required here is - * a sync to make sure the data gets out to the caches and is - * visible to an arbitrary A Phase from an external agent - * - * Actually, I'm not even sure that's necessary; the semantics - * of this function aren't clear. If it's supposed to serve as - * a memory barrier, this is needed. If it's only meant to - * prevent data from being invisible to non-cpu memory accessors - * for some indefinite period of time (e.g. in a non-coherent - * dcache) then this function would be a complete nop. - */ -static void sb1_flush_page_to_ram(struct page *page) -{ - __asm__ __volatile__( - " sync \n" /* Short pipe */ - :::"memory"); -} - -/* * Cache set values (from the mips64 spec) * 0 - 64 * 1 - 128 @@ -481,7 +543,7 @@ { u32 config1; - config1 = read_mips32_cp0_config1(); + config1 = read_c0_config1(); icache_line_size = decode_cache_line_size((config1 >> 19) & 0x7); dcache_line_size = decode_cache_line_size((config1 >> 10) & 0x7); icache_sets = decode_cache_sets((config1 >> 22) & 0x7); @@ -490,7 +552,17 @@ dcache_assoc = ((config1 >> 7) & 0x7) + 1; icache_size = icache_line_size * icache_sets * icache_assoc; dcache_size = dcache_line_size * dcache_sets * dcache_assoc; + /* Need to remove non-index bits for index ops */ icache_index_mask = (icache_sets - 1) * icache_line_size; + dcache_index_mask = (dcache_sets - 1) * dcache_line_size; + /* + * These are for choosing range (index ops) versus all. + * icache flushes all ways for each set, so drop icache_assoc. + * dcache flushes all ways and each setting of bit 12 for each + * index, so drop dcache_assoc and halve the dcache_sets. + */ + icache_range_cutoff = icache_sets * icache_line_size; + dcache_range_cutoff = (dcache_sets / 2) * icache_line_size; } /* @@ -500,25 +572,57 @@ */ void ld_mmu_sb1(void) { + extern char except_vec2_sb1; + unsigned long temp; + + /* Special cache error handler for SB1 */ + memcpy((void *)(KSEG0 + 0x100), &except_vec2_sb1, 0x80); + memcpy((void *)(KSEG1 + 0x100), &except_vec2_sb1, 0x80); + probe_cache_sizes(); +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS + _clear_page = sb1_clear_page_dma; + _copy_page = sb1_copy_page_dma; + sb1_dma_init(); +#else _clear_page = sb1_clear_page; _copy_page = sb1_copy_page; +#endif - _flush_cache_all = sb1_flush_cache_all; - ___flush_cache_all = sb1___flush_cache_all; - _flush_cache_mm = (void (*)(struct mm_struct *))sb1_nop; + /* + * None of these are needed for the SB1 - the Dcache is + * physically indexed and tagged, so no virtual aliasing can + * occur + */ _flush_cache_range = (void *) sb1_nop; - _flush_page_to_ram = sb1_flush_page_to_ram; - _flush_icache_page = sb1_flush_icache_page; - _flush_icache_range = sb1_flush_icache_range; + _flush_cache_page = sb1_flush_cache_page; + _flush_cache_mm = (void (*)(struct mm_struct *))sb1_nop; + _flush_cache_all = sb1_nop; - /* None of these are needed for the sb1 */ - _flush_cache_page = (void *) sb1_nop; + /* These routines are for Icache coherence with the Dcache */ + _flush_icache_range = sb1_flush_icache_range; + _flush_icache_page = sb1_flush_icache_page; + _flush_icache_all = __sb1_flush_icache_all; /* local only */ _flush_cache_sigtramp = sb1_flush_cache_sigtramp; - _flush_icache_all = sb1_flush_icache_all; + _flush_data_cache_page = (void *) sb1_nop; - change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); + /* Full flush */ + ___flush_cache_all = sb1___flush_cache_all; + + change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); + /* + * This is the only way to force the update of K0 to complete + * before subsequent instruction fetch. + */ + __asm__ __volatile__ ( + " .set push \n" + " .set mips4 \n" + " la %0, 1f \n" + " mtc0 %0, $14 \n" + " eret \n" + "1: .set pop \n" + : "=r" (temp)); flush_cache_all(); } diff -urN linux-2.4.21-bk37/arch/mips/mm/c-tx39.c linux-2.4.21-bk38/arch/mips/mm/c-tx39.c --- linux-2.4.21-bk37/arch/mips/mm/c-tx39.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/c-tx39.c 2003-08-24 02:55:57.000000000 -0700 @@ -25,18 +25,24 @@ /* For R3000 cores with R4000 style caches */ static unsigned long icache_size, dcache_size; /* Size in bytes */ -extern long scache_size; - -#define icache_lsize mips_cpu.icache.linesz -#define dcache_lsize mips_cpu.dcache.linesz #include +extern void r3k_clear_page(void * page); +extern void r3k_copy_page(void * to, void * from); + extern int r3k_have_wired_reg; /* in r3k-tlb.c */ -static void tx39h_flush_page_to_ram(struct page * page) -{ -} +/* This sequence is required to ensure icache is disabled immediately */ +#define TX39_STOP_STREAMING() \ +__asm__ __volatile__( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + "b 1f\n\t" \ + "nop\n\t" \ + "1:\n\t" \ + ".set pop" \ + ) /* TX39H-style cache flush routines. */ static void tx39h_flush_icache_all(void) @@ -46,8 +52,10 @@ unsigned long flags, config; /* disable icache (set ICE#) */ - __save_and_cli(flags); - config = read_32bit_cp0_register(CP0_CONF); + local_irq_save(flags); + config = read_c0_conf(); + write_c0_conf(config & ~TX39_CONF_ICE); + TX39_STOP_STREAMING(); /* invalidate icache */ while (start < end) { @@ -55,46 +63,103 @@ start += 0x200; } - write_32bit_cp0_register(CP0_CONF, config); - __restore_flags(flags); + write_c0_conf(config); + local_irq_restore(flags); } static void tx39h_dma_cache_wback_inv(unsigned long addr, unsigned long size) { unsigned long end, a; + unsigned long dc_lsize = current_cpu_data.dcache.linesz; iob(); - a = addr & ~(dcache_lsize - 1); - end = (addr + size) & ~(dcache_lsize - 1); + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); while (1) { invalidate_dcache_line(a); /* Hit_Invalidate_D */ if (a == end) break; - a += dcache_lsize; + a += dc_lsize; } } /* TX39H2,TX39H3 */ -static inline void tx39_flush_cache_all(void) +static inline void tx39_blast_dcache_page(unsigned long addr) +{ + if (current_cpu_data.cputype != CPU_TX3912) + blast_dcache16_page(addr); +} + +static inline void tx39_blast_dcache_page_indexed(unsigned long addr) +{ + blast_dcache16_page_indexed(addr); +} + +static inline void tx39_blast_dcache(void) +{ + blast_dcache16(); +} + +static inline void tx39_blast_icache_page(unsigned long addr) +{ + unsigned long flags, config; + /* disable icache (set ICE#) */ + local_irq_save(flags); + config = read_c0_conf(); + write_c0_conf(config & ~TX39_CONF_ICE); + TX39_STOP_STREAMING(); + blast_icache16_page(addr); + write_c0_conf(config); + local_irq_restore(flags); +} + +static inline void tx39_blast_icache_page_indexed(unsigned long addr) { unsigned long flags, config; + /* disable icache (set ICE#) */ + local_irq_save(flags); + config = read_c0_conf(); + write_c0_conf(config & ~TX39_CONF_ICE); + TX39_STOP_STREAMING(); + blast_icache16_page_indexed(addr); + write_c0_conf(config); + local_irq_restore(flags); +} - __save_and_cli(flags); - blast_dcache16_wayLSB(); +static inline void tx39_blast_icache(void) +{ + unsigned long flags, config; /* disable icache (set ICE#) */ - config = read_32bit_cp0_register(CP0_CONF); - write_32bit_cp0_register(CP0_CONF, config&~TX39_CONF_ICE); - blast_icache16_wayLSB(); - write_32bit_cp0_register(CP0_CONF, config); - __restore_flags(flags); + local_irq_save(flags); + config = read_c0_conf(); + write_c0_conf(config & ~TX39_CONF_ICE); + TX39_STOP_STREAMING(); + blast_icache16(); + write_c0_conf(config); + local_irq_restore(flags); +} + +static inline void tx39_flush_cache_all(void) +{ + if (!cpu_has_dc_aliases) + return; + + tx39_blast_dcache(); + tx39_blast_icache(); +} + +static inline void tx39___flush_cache_all(void) +{ + tx39_blast_dcache(); + tx39_blast_icache(); } static void tx39_flush_cache_mm(struct mm_struct *mm) { - if(mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif + if (!cpu_has_dc_aliases) + return; + + if (cpu_context(smp_processor_id(), mm) != 0) { tx39_flush_cache_all(); } } @@ -103,28 +168,20 @@ unsigned long start, unsigned long end) { - if(mm->context != 0) { - unsigned long flags, config; + if (!cpu_has_dc_aliases) + return; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - __save_and_cli(flags); - blast_dcache16_wayLSB(); - /* disable icache (set ICE#) */ - config = read_32bit_cp0_register(CP0_CONF); - write_32bit_cp0_register(CP0_CONF, config&~TX39_CONF_ICE); - blast_icache16_wayLSB(); - write_32bit_cp0_register(CP0_CONF, config); - __restore_flags(flags); + if (cpu_context(smp_processor_id(), mm) != 0) { + tx39_blast_dcache(); + tx39_blast_icache(); } } static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page) { + int exec = vma->vm_flags & VM_EXEC; struct mm_struct *mm = vma->vm_mm; - unsigned long flags; pgd_t *pgdp; pmd_t *pmdp; pte_t *ptep; @@ -133,13 +190,9 @@ * If ownes no valid ASID yet, cannot possibly have gotten * this page into the cache. */ - if(mm->context == 0) + if (cpu_context(smp_processor_id(), mm) == 0) return; -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - __save_and_cli(flags); page &= PAGE_MASK; pgdp = pgd_offset(mm, page); pmdp = pmd_offset(pgdp, page); @@ -149,8 +202,8 @@ * If the page isn't marked valid, the page cannot possibly be * in the cache. */ - if(!(pte_val(*ptep) & _PAGE_PRESENT)) - goto out; + if (!(pte_val(*ptep) & _PAGE_PRESENT)) + return; /* * Doing flushes for another ASID than the current one is @@ -158,51 +211,121 @@ * for every cache flush operation. So we do indexed flushes * in that case, which doesn't overly flush the cache too much. */ - if((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache16_page(page); - } else { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache16_page_indexed_wayLSB(page); + if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { + if (cpu_has_dc_aliases || exec) + tx39_blast_dcache_page(page); + if (exec) + tx39_blast_icache_page(page); + + return; } -out: - __restore_flags(flags); + + /* + * Do indexed flush, too much work to get the (possible) TLB refills + * to work correctly. + */ + page = (KSEG0 + (page & (dcache_size - 1))); + if (cpu_has_dc_aliases || exec) + tx39_blast_dcache_page_indexed(page); + if (exec) + tx39_blast_icache_page_indexed(page); } -static void tx39_flush_page_to_ram(struct page * page) +static void tx39_flush_data_cache_page(unsigned long addr) { - blast_dcache16_page((unsigned long)page_address(page)); + tx39_blast_dcache_page(addr); } static void tx39_flush_icache_range(unsigned long start, unsigned long end) { - flush_cache_all(); + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + unsigned long addr, aend; + + if (end - start > dcache_size) + tx39_blast_dcache(); + else { + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); + + while (1) { + /* Hit_Writeback_Inv_D */ + protected_writeback_dcache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } + } + + if (end - start > icache_size) + tx39_blast_icache(); + else { + unsigned long flags, config; + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); + /* disable icache (set ICE#) */ + local_irq_save(flags); + config = read_c0_conf(); + write_c0_conf(config & ~TX39_CONF_ICE); + TX39_STOP_STREAMING(); + while (1) { + /* Hit_Invalidate_I */ + protected_flush_icache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } + write_c0_conf(config); + local_irq_restore(flags); + } } +/* + * Ok, this seriously sucks. We use them to flush a user page but don't + * know the virtual address, so we have to blast away the whole icache + * which is significantly more expensive than the real thing. Otoh we at + * least know the kernel address of the page so we can flush it + * selectivly. + */ static void tx39_flush_icache_page(struct vm_area_struct *vma, struct page *page) { + unsigned long addr; + /* + * If there's no context yet, or the page isn't executable, no icache + * flush is needed. + */ if (!(vma->vm_flags & VM_EXEC)) return; - flush_cache_all(); + addr = (unsigned long) page_address(page); + tx39_blast_dcache_page(addr); + + /* + * We're not sure of the virtual address(es) involved here, so + * we have to flush the entire I-cache. + */ + tx39_blast_icache(); } static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size) { unsigned long end, a; - if (size >= dcache_size) { - flush_cache_all(); + if (((size | addr) & (PAGE_SIZE - 1)) == 0) { + end = addr + size; + do { + tx39_blast_dcache_page(addr); + addr += PAGE_SIZE; + } while(addr != end); + } else if (size > dcache_size) { + tx39_blast_dcache(); } else { - a = addr & ~(dcache_lsize - 1); - end = (addr + size) & ~(dcache_lsize - 1); + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); while (1) { flush_dcache_line(a); /* Hit_Writeback_Inv_D */ if (a == end) break; - a += dcache_lsize; + a += dc_lsize; } } } @@ -211,59 +334,75 @@ { unsigned long end, a; - if (size >= dcache_size) { - flush_cache_all(); + if (((size | addr) & (PAGE_SIZE - 1)) == 0) { + end = addr + size; + do { + tx39_blast_dcache_page(addr); + addr += PAGE_SIZE; + } while(addr != end); + } else if (size > dcache_size) { + tx39_blast_dcache(); } else { - a = addr & ~(dcache_lsize - 1); - end = (addr + size) & ~(dcache_lsize - 1); + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); while (1) { invalidate_dcache_line(a); /* Hit_Invalidate_D */ if (a == end) break; - a += dcache_lsize; + a += dc_lsize; } } } -static void tx39_dma_cache_wback(unsigned long addr, unsigned long size) -{ - panic("tx39_dma_cache called - should not happen."); -} - static void tx39_flush_cache_sigtramp(unsigned long addr) { + unsigned long ic_lsize = current_cpu_data.icache.linesz; + unsigned long dc_lsize = current_cpu_data.dcache.linesz; unsigned long config; - unsigned int flags; + unsigned long flags; - __save_and_cli(flags); - protected_writeback_dcache_line(addr & ~(dcache_lsize - 1)); + protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); /* disable icache (set ICE#) */ - config = read_32bit_cp0_register(CP0_CONF); - write_32bit_cp0_register(CP0_CONF, config&~TX39_CONF_ICE); - protected_flush_icache_line(addr & ~(icache_lsize - 1)); - write_32bit_cp0_register(CP0_CONF, config); - __restore_flags(flags); + local_irq_save(flags); + config = read_c0_conf(); + write_c0_conf(config & ~TX39_CONF_ICE); + TX39_STOP_STREAMING(); + protected_flush_icache_line(addr & ~(ic_lsize - 1)); + write_c0_conf(config); + local_irq_restore(flags); } static __init void tx39_probe_cache(void) { unsigned long config; - config = read_32bit_cp0_register(CP0_CONF); + config = read_c0_conf(); - icache_size = 1 << (10 + ((config >> 19) & 3)); - dcache_size = 1 << (10 + ((config >> 16) & 3)); + icache_size = 1 << (10 + ((config & TX39_CONF_ICS_MASK) >> + TX39_CONF_ICS_SHIFT)); + dcache_size = 1 << (10 + ((config & TX39_CONF_DCS_MASK) >> + TX39_CONF_DCS_SHIFT)); - icache_lsize = 16; - switch (mips_cpu.cputype) { + current_cpu_data.icache.linesz = 16; + switch (current_cpu_data.cputype) { case CPU_TX3912: - dcache_lsize = 4; + current_cpu_data.icache.ways = 1; + current_cpu_data.dcache.ways = 1; + current_cpu_data.dcache.linesz = 4; break; - case CPU_TX3922: + case CPU_TX3927: - case CPU_TX39XX: + current_cpu_data.icache.ways = 2; + current_cpu_data.dcache.ways = 2; + current_cpu_data.dcache.linesz = 16; + break; + + case CPU_TX3922: default: - dcache_lsize = 16; + current_cpu_data.icache.ways = 1; + current_cpu_data.dcache.ways = 1; + current_cpu_data.dcache.linesz = 16; break; } } @@ -275,13 +414,13 @@ _clear_page = r3k_clear_page; _copy_page = r3k_copy_page; - config = read_32bit_cp0_register(CP0_CONF); + config = read_c0_conf(); config &= ~TX39_CONF_WBON; - write_32bit_cp0_register(CP0_CONF, config); + write_c0_conf(config); tx39_probe_cache(); - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_TX3912: /* TX39/H core (writethru direct-map cache) */ _flush_cache_all = tx39h_flush_icache_all; @@ -289,12 +428,16 @@ _flush_cache_mm = (void *) tx39h_flush_icache_all; _flush_cache_range = (void *) tx39h_flush_icache_all; _flush_cache_page = (void *) tx39h_flush_icache_all; - _flush_cache_sigtramp = (void *) tx39h_flush_icache_all; - _flush_page_to_ram = tx39h_flush_page_to_ram; _flush_icache_page = (void *) tx39h_flush_icache_all; _flush_icache_range = (void *) tx39h_flush_icache_all; - _dma_cache_wback_inv = tx39h_dma_cache_wback_inv; + _flush_cache_sigtramp = (void *) tx39h_flush_icache_all; + _flush_data_cache_page = (void *) tx39h_flush_icache_all; + + _dma_cache_wback_inv = tx39h_dma_cache_wback_inv; + + shm_align_mask = PAGE_SIZE - 1; + break; case CPU_TX3922: @@ -302,37 +445,47 @@ default: /* TX39/H2,H3 core (writeback 2way-set-associative cache) */ r3k_have_wired_reg = 1; - set_wired (0); /* set 8 on reset... */ + write_c0_wired(0); /* set 8 on reset... */ /* board-dependent init code may set WBON */ _flush_cache_all = tx39_flush_cache_all; - ___flush_cache_all = tx39_flush_cache_all; + ___flush_cache_all = tx39___flush_cache_all; _flush_cache_mm = tx39_flush_cache_mm; _flush_cache_range = tx39_flush_cache_range; _flush_cache_page = tx39_flush_cache_page; - _flush_cache_sigtramp = tx39_flush_cache_sigtramp; - _flush_page_to_ram = tx39_flush_page_to_ram; _flush_icache_page = tx39_flush_icache_page; _flush_icache_range = tx39_flush_icache_range; + _flush_cache_sigtramp = tx39_flush_cache_sigtramp; + _flush_data_cache_page = tx39_flush_data_cache_page; + _dma_cache_wback_inv = tx39_dma_cache_wback_inv; - _dma_cache_wback = tx39_dma_cache_wback; + _dma_cache_wback = tx39_dma_cache_wback_inv; _dma_cache_inv = tx39_dma_cache_inv; + shm_align_mask = max_t(unsigned long, + (dcache_size / current_cpu_data.dcache.ways) - 1, + PAGE_SIZE - 1); + break; } - if (mips_cpu.icache.ways == 0) - mips_cpu.icache.ways = 1; - if (mips_cpu.dcache.ways == 0) - mips_cpu.dcache.ways = 1; - mips_cpu.icache.sets = - icache_size / mips_cpu.icache.ways / mips_cpu.icache.linesz; - mips_cpu.dcache.sets = - dcache_size / mips_cpu.dcache.ways / mips_cpu.dcache.linesz; - - printk("Primary instruction cache %dkb, linesize %d bytes\n", - (int) (icache_size >> 10), (int) icache_lsize); - printk("Primary data cache %dkb, linesize %d bytes\n", - (int) (dcache_size >> 10), (int) dcache_lsize); + current_cpu_data.icache.waysize = icache_size / current_cpu_data.icache.ways; + current_cpu_data.dcache.waysize = dcache_size / current_cpu_data.dcache.ways; + + current_cpu_data.icache.sets = + current_cpu_data.icache.waysize / current_cpu_data.icache.linesz; + current_cpu_data.dcache.sets = + current_cpu_data.dcache.waysize / current_cpu_data.dcache.linesz; + + if (current_cpu_data.dcache.waysize > PAGE_SIZE) + current_cpu_data.dcache.flags |= MIPS_CACHE_ALIASES; + + current_cpu_data.icache.waybit = 0; + current_cpu_data.dcache.waybit = 0; + + printk("Primary instruction cache %ldkb, linesize %d bytes\n", + icache_size >> 10, current_cpu_data.icache.linesz); + printk("Primary data cache %ldkb, linesize %d bytes\n", + dcache_size >> 10, current_cpu_data.dcache.linesz); } diff -urN linux-2.4.21-bk37/arch/mips/mm/c-tx49.c linux-2.4.21-bk38/arch/mips/mm/c-tx49.c --- linux-2.4.21-bk37/arch/mips/mm/c-tx49.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/c-tx49.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,435 +0,0 @@ -/* - * 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. - * - * r49xx.c: TX49 processor variant specific MMU/Cache routines. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org - * - * Modified for R4300/TX49xx (Jun/2001) - * Copyright (C) 1999-2001 Toshiba Corporation - * - * To do: - * - * - this code is a overbloated pig - * - many of the bug workarounds are not efficient at all, but at - * least they are functional ... - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* Primary cache parameters. */ -static int icache_size, dcache_size; /* Size in bytes */ -#define ic_lsize mips_cpu.icache.linesz -#define dc_lsize mips_cpu.dcache.linesz -static unsigned long scache_size; - -#include -#include - -#undef DEBUG_CACHE - -/* TX49 does can not flush the line contains the CACHE insn itself... */ -/* r4k_xxx routines are completely same as those in r4xx0.c */ - -/* - * If you think for one second that this stuff coming up is a lot - * of bulky code eating too many kernel cache lines. Think _again_. - * - * Consider: - * 1) Taken branches have a 3 cycle penalty on R4k - * 2) The branch itself is a real dead cycle on even R4600/R5000. - * 3) Only one of the following variants of each type is even used by - * the kernel based upon the cache parameters we detect at boot time. - * - * QED. - */ - -static inline void r49_flush_cache_all_d16i32(void) -{ - unsigned long flags, config; - - __save_and_cli(flags); - blast_dcache16_wayLSB(); - /* disable icache (set ICE#) */ - config = read_32bit_cp0_register(CP0_CONFIG); - write_32bit_cp0_register(CP0_CONFIG, config|TX49_CONF_IC); - blast_icache32_wayLSB(); - write_32bit_cp0_register(CP0_CONFIG, config); - __restore_flags(flags); -} - -static inline void r49_flush_cache_all_d32i32(void) -{ - unsigned long flags, config; - - __save_and_cli(flags); - blast_dcache32_wayLSB(); - /* disable icache (set ICE#) */ - config = read_32bit_cp0_register(CP0_CONFIG); - write_32bit_cp0_register(CP0_CONFIG, config|TX49_CONF_IC); - blast_icache32_wayLSB(); - write_32bit_cp0_register(CP0_CONFIG, config); - __restore_flags(flags); -} - -static void r49_flush_cache_range_d16i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if (mm->context != 0) { - unsigned long flags, config; - -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - __save_and_cli(flags); - blast_dcache16_wayLSB(); - /* disable icache (set ICE#) */ - config = read_32bit_cp0_register(CP0_CONFIG); - write_32bit_cp0_register(CP0_CONFIG, config|TX49_CONF_IC); - blast_icache32_wayLSB(); - write_32bit_cp0_register(CP0_CONFIG, config); - __restore_flags(flags); - } -} - -static void r49_flush_cache_range_d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if (mm->context != 0) { - unsigned long flags, config; - -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - __save_and_cli(flags); - blast_dcache32_wayLSB(); - /* disable icache (set ICE#) */ - config = read_32bit_cp0_register(CP0_CONFIG); - write_32bit_cp0_register(CP0_CONFIG, config|TX49_CONF_IC); - blast_icache32_wayLSB(); - write_32bit_cp0_register(CP0_CONFIG, config); - __restore_flags(flags); - } -} - -/* - * On architectures like the Sparc, we could get rid of lines in - * the cache created only by a certain context, but on the MIPS - * (and actually certain Sparc's) we cannot. - */ -static void r49_flush_cache_mm_d16i32(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r49_flush_cache_all_d16i32(); - } -} - -static void r49_flush_cache_mm_d32i32(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r49_flush_cache_all_d32i32(); - } -} - -static void r49_flush_cache_page_d16i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - __save_and_cli(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_PRESENT)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache16_page(page); - } else { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache16_page_indexed_wayLSB(page); - } -out: - __restore_flags(flags); -} - -static void r49_flush_cache_page_d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - __save_and_cli(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_PRESENT)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache32_page(page); - } else { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache32_page_indexed_wayLSB(page); - } -out: - __restore_flags(flags); -} - -/* If the addresses passed to these routines are valid, they are - * either: - * - * 1) In KSEG0, so we can do a direct flush of the page. - * 2) In KSEG2, and since every process can translate those - * addresses all the time in kernel mode we can do a direct - * flush. - * 3) In KSEG1, no flush necessary. - */ -static void r4k_flush_page_to_ram_d16(struct page *page) -{ - blast_dcache16_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_d32(struct page *page) -{ - blast_dcache32_page((unsigned long)page_address(page)); -} - -static void -r4k_flush_icache_range(unsigned long start, unsigned long end) -{ - flush_cache_all(); -} - -/* - * Ok, this seriously sucks. We use them to flush a user page but don't - * know the virtual address, so we have to blast away the whole icache - * which is significantly more expensive than the real thing. - */ -static void -r4k_flush_icache_page(struct vm_area_struct *vma, struct page *page) -{ - if (!(vma->vm_flags & VM_EXEC)) - return; - - flush_cache_all(); -} - -/* - * Writeback and invalidate the primary cache dcache before DMA. - */ -static void -r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= dcache_size) { - flush_cache_all(); - } else { - __save_and_cli(flags); - - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - __restore_flags(flags); - } -} - -static void -r4k_dma_cache_inv(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= dcache_size) { - flush_cache_all(); - } else { - __save_and_cli(flags); - - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - __restore_flags(flags); - } -} - -static void -r4k_dma_cache_wback(unsigned long addr, unsigned long size) -{ - panic("r4k_dma_cache called - should not happen."); -} - -/* - * While we're protected against bad userland addresses we don't care - * very much about what happens in that case. Usually a segmentation - * fault will dump the process later on anyway ... - */ -static void r4k_flush_cache_sigtramp(unsigned long addr) -{ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -/* Detect and size the various r4k caches. */ -static void __init probe_icache(unsigned long config) -{ - icache_size = 1 << (12 + ((config >> 9) & 7)); - ic_lsize = 16 << ((config >> 5) & 1); - - printk("Primary instruction cache %dkb, linesize %d bytes.\n", - icache_size >> 10, ic_lsize); -} - -static void __init probe_dcache(unsigned long config) -{ - dcache_size = 1 << (12 + ((config >> 6) & 7)); - dc_lsize = 16 << ((config >> 4) & 1); - - printk("Primary data cache %dkb, linesize %d bytes.\n", - dcache_size >> 10, dc_lsize); -} - -int mips_configk0 = -1; /* board-specific setup routine can override this */ -void __init ld_mmu_tx49(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - - if (mips_configk0 != -1) - change_cp0_config(CONF_CM_CMASK, mips_configk0); - else - change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); - - probe_icache(config); - probe_dcache(config); - if (mips_cpu.icache.ways == 0) - mips_cpu.icache.ways = 1; - if (mips_cpu.dcache.ways == 0) - mips_cpu.dcache.ways = 1; - mips_cpu.icache.sets = - icache_size / mips_cpu.icache.ways / mips_cpu.icache.linesz; - mips_cpu.dcache.sets = - dcache_size / mips_cpu.dcache.ways / mips_cpu.dcache.linesz; - - switch(dc_lsize) { - case 16: - _clear_page = r4k_clear_page_d16; - _copy_page = r4k_copy_page_d16; - _flush_page_to_ram = r4k_flush_page_to_ram_d16; - _flush_cache_all = r49_flush_cache_all_d16i32; - _flush_cache_mm = r49_flush_cache_mm_d16i32; - _flush_cache_range = r49_flush_cache_range_d16i32; - _flush_cache_page = r49_flush_cache_page_d16i32; - break; - case 32: - _clear_page = r4k_clear_page_d32; - _copy_page = r4k_copy_page_d32; - _flush_page_to_ram = r4k_flush_page_to_ram_d32; - _flush_cache_all = r49_flush_cache_all_d32i32; - _flush_cache_mm = r49_flush_cache_mm_d32i32; - _flush_cache_range = r49_flush_cache_range_d32i32; - _flush_cache_page = r49_flush_cache_page_d32i32; - break; - } - ___flush_cache_all = _flush_cache_all; - - _flush_icache_page = r4k_flush_icache_page; - - _dma_cache_wback_inv = r4k_dma_cache_wback_inv; - _dma_cache_wback = r4k_dma_cache_wback; - _dma_cache_inv = r4k_dma_cache_inv; - - _flush_cache_sigtramp = r4k_flush_cache_sigtramp; - _flush_icache_range = r4k_flush_icache_range; /* Ouch */ - - __flush_cache_all(); -} diff -urN linux-2.4.21-bk37/arch/mips/mm/cache.c linux-2.4.21-bk38/arch/mips/mm/cache.c --- linux-2.4.21-bk37/arch/mips/mm/cache.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/cache.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,67 @@ +/* + * 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. + * + * Copyright (C) 1994 - 2003 by Ralf Baechle + */ +#include +#include +#include +#include + +#include + +asmlinkage int sys_cacheflush(void *addr, int bytes, int cache) +{ + /* This should flush more selectivly ... */ + __flush_cache_all(); + + return 0; +} + +void flush_dcache_page(struct page *page) +{ + unsigned long addr; + + if (!cpu_has_dc_aliases) + return; + + if (page->mapping && page->mapping->i_mmap == NULL && + page->mapping->i_mmap_shared == NULL) { + SetPageDcacheDirty(page); + + return; + } + + /* + * We could delay the flush for the !page->mapping case too. But that + * case is for exec env/arg pages and those are 99% certainly going to + * get faulted into the tlb (and thus flushed) anyways. + */ + addr = (unsigned long) page_address(page); + flush_data_cache_page(addr); +} + +void __update_cache(struct vm_area_struct *vma, unsigned long address, + pte_t pte) +{ + unsigned long addr; + struct page *page; + + if (!cpu_has_dc_aliases) + return; + + page = pte_page(pte); + if (VALID_PAGE(page) && page->mapping && + (page->flags & (1UL << PG_dcache_dirty))) { + if (pages_do_alias((unsigned long) page_address(page), address & PAGE_MASK)) { + addr = (unsigned long) page_address(page); + flush_data_cache_page(addr); + } + + ClearPageDcacheDirty(page); + } +} + +EXPORT_SYMBOL(flush_dcache_page); diff -urN linux-2.4.21-bk37/arch/mips/mm/cerr-sb1.c linux-2.4.21-bk38/arch/mips/mm/cerr-sb1.c --- linux-2.4.21-bk37/arch/mips/mm/cerr-sb1.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/cerr-sb1.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,542 @@ +/* + * Copyright (C) 2001 Broadcom Corporation + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include + +#ifndef CONFIG_SIBYTE_BUS_WATCHER +#include +#include +#include +#include +#endif + +/* SB1 definitions */ + +/* XXX should come from config1 XXX */ +#define SB1_CACHE_INDEX_MASK 0x1fe0 + +#define CP0_ERRCTL_RECOVERABLE (1 << 31) +#define CP0_ERRCTL_DCACHE (1 << 30) +#define CP0_ERRCTL_ICACHE (1 << 29) +#define CP0_ERRCTL_MULTIBUS (1 << 23) +#define CP0_ERRCTL_MC_TLB (1 << 15) +#define CP0_ERRCTL_MC_TIMEOUT (1 << 14) + +#define CP0_CERRI_TAG_PARITY (1 << 29) +#define CP0_CERRI_DATA_PARITY (1 << 28) +#define CP0_CERRI_EXTERNAL (1 << 26) + +#define CP0_CERRI_IDX_VALID(c) (!((c) & CP0_CERRI_EXTERNAL)) +#define CP0_CERRI_DATA (CP0_CERRI_DATA_PARITY) + +#define CP0_CERRD_MULTIPLE (1 << 31) +#define CP0_CERRD_TAG_STATE (1 << 30) +#define CP0_CERRD_TAG_ADDRESS (1 << 29) +#define CP0_CERRD_DATA_SBE (1 << 28) +#define CP0_CERRD_DATA_DBE (1 << 27) +#define CP0_CERRD_EXTERNAL (1 << 26) +#define CP0_CERRD_LOAD (1 << 25) +#define CP0_CERRD_STORE (1 << 24) +#define CP0_CERRD_FILLWB (1 << 23) +#define CP0_CERRD_COHERENCY (1 << 22) +#define CP0_CERRD_DUPTAG (1 << 21) + +#define CP0_CERRD_DPA_VALID(c) (!((c) & CP0_CERRD_EXTERNAL)) +#define CP0_CERRD_IDX_VALID(c) \ + (((c) & (CP0_CERRD_LOAD | CP0_CERRD_STORE)) ? (!((c) & CP0_CERRD_EXTERNAL)) : 0) +#define CP0_CERRD_CAUSES \ + (CP0_CERRD_LOAD | CP0_CERRD_STORE | CP0_CERRD_FILLWB | CP0_CERRD_COHERENCY | CP0_CERRD_DUPTAG) +#define CP0_CERRD_TYPES \ + (CP0_CERRD_TAG_STATE | CP0_CERRD_TAG_ADDRESS | CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE | CP0_CERRD_EXTERNAL) +#define CP0_CERRD_DATA (CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE) + +static uint32_t extract_ic(unsigned short addr, int data); +static uint32_t extract_dc(unsigned short addr, int data); + +static inline void breakout_errctl(unsigned int val) +{ + if (val & CP0_ERRCTL_RECOVERABLE) + prom_printf(" recoverable"); + if (val & CP0_ERRCTL_DCACHE) + prom_printf(" dcache"); + if (val & CP0_ERRCTL_ICACHE) + prom_printf(" icache"); + if (val & CP0_ERRCTL_MULTIBUS) + prom_printf(" multiple-buserr"); + prom_printf("\n"); +} + +static inline void breakout_cerri(unsigned int val) +{ + if (val & CP0_CERRI_TAG_PARITY) + prom_printf(" tag-parity"); + if (val & CP0_CERRI_DATA_PARITY) + prom_printf(" data-parity"); + if (val & CP0_CERRI_EXTERNAL) + prom_printf(" external"); + prom_printf("\n"); +} + +static inline void breakout_cerrd(unsigned int val) +{ + switch (val & CP0_CERRD_CAUSES) { + case CP0_CERRD_LOAD: + prom_printf(" load,"); + break; + case CP0_CERRD_STORE: + prom_printf(" store,"); + break; + case CP0_CERRD_FILLWB: + prom_printf(" fill/wb,"); + break; + case CP0_CERRD_COHERENCY: + prom_printf(" coherency,"); + break; + case CP0_CERRD_DUPTAG: + prom_printf(" duptags,"); + break; + default: + prom_printf(" NO CAUSE,"); + break; + } + if (!(val & CP0_CERRD_TYPES)) + prom_printf(" NO TYPE"); + else { + if (val & CP0_CERRD_MULTIPLE) + prom_printf(" multi-err"); + if (val & CP0_CERRD_TAG_STATE) + prom_printf(" tag-state"); + if (val & CP0_CERRD_TAG_ADDRESS) + prom_printf(" tag-address"); + if (val & CP0_CERRD_DATA_SBE) + prom_printf(" data-SBE"); + if (val & CP0_CERRD_DATA_DBE) + prom_printf(" data-DBE"); + if (val & CP0_CERRD_EXTERNAL) + prom_printf(" external"); + } + prom_printf("\n"); +} + +#ifndef CONFIG_SIBYTE_BUS_WATCHER + +static void check_bus_watcher(void) +{ + uint32_t status, l2_err, memio_err; + + /* Destructive read, clears register and interrupt */ + status = csr_in32(IO_SPACE_BASE | A_SCD_BUS_ERR_STATUS); + /* Bit 31 is always on, but there's no #define for that */ + if (status & ~(1UL << 31)) { + l2_err = csr_in32(IO_SPACE_BASE | A_BUS_L2_ERRORS); + memio_err = csr_in32(IO_SPACE_BASE | A_BUS_MEM_IO_ERRORS); + prom_printf("Bus watcher error counters: %08x %08x\n", l2_err, memio_err); + prom_printf("\nLast recorded signature:\n"); + prom_printf("Request %02x from %d, answered by %d with Dcode %d\n", + (unsigned int)(G_SCD_BERR_TID(status) & 0x3f), + (int)(G_SCD_BERR_TID(status) >> 6), + (int)G_SCD_BERR_RID(status), + (int)G_SCD_BERR_DCODE(status)); + } else { + prom_printf("Bus watcher indicates no error\n"); + } +} +#else +extern void check_bus_watcher(void); +#endif + +asmlinkage void sb1_cache_error(void) +{ + uint64_t cerr_dpa; + uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res; + + prom_printf("Cache error exception on CPU %x:\n", + (read_c0_prid() >> 25) & 0x7); + + __asm__ __volatile__ ( + " .set push\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " mfc0 %0, $26\n\t" + " mfc0 %1, $27\n\t" + " mfc0 %2, $27, 1\n\t" + " dmfc0 $1, $27, 3\n\t" + " dsrl32 %3, $1, 0 \n\t" + " sll %4, $1, 0 \n\t" + " mfc0 %5, $30\n\t" + " .set pop" + : "=r" (errctl), "=r" (cerr_i), "=r" (cerr_d), + "=r" (dpahi), "=r" (dpalo), "=r" (eepc)); + + cerr_dpa = (((uint64_t)dpahi) << 32) | dpalo; + prom_printf(" cp0_errorepc == %08x\n", eepc); + prom_printf(" cp0_errctl == %08x", errctl); + breakout_errctl(errctl); + if (errctl & CP0_ERRCTL_ICACHE) { + prom_printf(" cp0_cerr_i == %08x", cerr_i); + breakout_cerri(cerr_i); + if (CP0_CERRI_IDX_VALID(cerr_i)) { + if ((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK)) + prom_printf(" cerr_i idx doesn't match eepc\n"); + else { + res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK, + (cerr_i & CP0_CERRI_DATA) != 0); + if (!(res & cerr_i)) + prom_printf("...didn't see indicated icache problem\n"); + } + } + } + if (errctl & CP0_ERRCTL_DCACHE) { + prom_printf(" cp0_cerr_d == %08x", cerr_d); + breakout_cerrd(cerr_d); + if (CP0_CERRD_DPA_VALID(cerr_d)) { + prom_printf(" cp0_cerr_dpa == %010llx\n", cerr_dpa); + if (!CP0_CERRD_IDX_VALID(cerr_d)) { + res = extract_dc(cerr_dpa & SB1_CACHE_INDEX_MASK, + (cerr_d & CP0_CERRD_DATA) != 0); + if (!(res & cerr_d)) + prom_printf("...didn't see indicated dcache problem\n"); + } else { + if ((cerr_dpa & SB1_CACHE_INDEX_MASK) != (cerr_d & SB1_CACHE_INDEX_MASK)) + prom_printf(" cerr_d idx doesn't match cerr_dpa\n"); + else { + res = extract_dc(cerr_d & SB1_CACHE_INDEX_MASK, + (cerr_d & CP0_CERRD_DATA) != 0); + if (!(res & cerr_d)) + prom_printf("...didn't see indicated problem\n"); + } + } + } + } + + check_bus_watcher(); + + while (1); + /* + * This tends to make things get really ugly; let's just stall instead. + * panic("Can't handle the cache error!"); + */ +} + + +/* Parity lookup table. */ +static const uint8_t parity[256] = { + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0 +}; + +/* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */ +static const uint64_t mask_72_64[8] = { + 0x0738C808099264FFL, + 0x38C808099264FF07L, + 0xC808099264FF0738L, + 0x08099264FF0738C8L, + 0x099264FF0738C808L, + 0x9264FF0738C80809L, + 0x64FF0738C8080992L, + 0xFF0738C808099264L +}; + +/* Calculate the parity on a range of bits */ +static char range_parity(uint64_t dword, int max, int min) +{ + char parity = 0; + int i; + dword >>= min; + for (i=max-min; i>=0; i--) { + if (dword & 0x1) + parity = !parity; + dword >>= 1; + } + return parity; +} + +/* Calculate the 4-bit even byte-parity for an instruction */ +static unsigned char inst_parity(uint32_t word) +{ + int i, j; + char parity = 0; + for (j=0; j<4; j++) { + char byte_parity = 0; + for (i=0; i<8; i++) { + if (word & 0x80000000) + byte_parity = !byte_parity; + word <<= 1; + } + parity <<= 1; + parity |= byte_parity; + } + return parity; +} + +static uint32_t extract_ic(unsigned short addr, int data) +{ + unsigned short way; + int valid; + uint64_t taglo, va, tlo_tmp; + uint32_t taghi, taglolo, taglohi; + uint8_t lru; + int res = 0; + + prom_printf("Icache index 0x%04x ", addr); + for (way = 0; way < 4; way++) { + /* Index-load-tag-I */ + __asm__ __volatile__ ( + " .set push \n\t" + " .set noreorder \n\t" + " .set mips64 \n\t" + " .set noat \n\t" + " cache 4, 0(%3) \n\t" + " mfc0 %0, $29 \n\t" + " dmfc0 $1, $28 \n\t" + " dsrl32 %1, $1, 0 \n\t" + " sll %2, $1, 0 \n\t" + " .set pop" + : "=r" (taghi), "=r" (taglohi), "=r" (taglolo) + : "r" ((way << 13) | addr)); + + taglo = ((unsigned long long)taglohi << 32) | taglolo; + if (way == 0) { + lru = (taghi >> 14) & 0xff; + prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", + ((addr >> 5) & 0x3), /* bank */ + ((addr >> 7) & 0x3f), /* index */ + (lru & 0x3), + ((lru >> 2) & 0x3), + ((lru >> 4) & 0x3), + ((lru >> 6) & 0x3)); + } + va = (taglo & 0xC0000FFFFFFFE000) | addr; + if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3)) + va |= 0x3FFFF00000000000; + valid = ((taghi >> 29) & 1); + if (valid) { + tlo_tmp = taglo & 0xfff3ff; + if (((taglo >> 10) & 1) ^ range_parity(tlo_tmp, 23, 0)) { + prom_printf(" ** bad parity in VTag0/G/ASID\n"); + res |= CP0_CERRI_TAG_PARITY; + } + if (((taglo >> 11) & 1) ^ range_parity(taglo, 63, 24)) { + prom_printf(" ** bad parity in R/VTag1\n"); + res |= CP0_CERRI_TAG_PARITY; + } + } + if (valid ^ ((taghi >> 27) & 1)) { + prom_printf(" ** bad parity for valid bit\n"); + res |= CP0_CERRI_TAG_PARITY; + } + prom_printf(" %d [VA %016llx] [Vld? %d] raw tags: %08X-%016llX\n", + way, va, valid, taghi, taglo); + + if (data) { + uint32_t datahi, insta, instb; + uint8_t predecode; + int offset; + + /* (hit all banks and ways) */ + for (offset = 0; offset < 4; offset++) { + /* Index-load-data-I */ + __asm__ __volatile__ ( + " .set push\n\t" + " .set noreorder\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " cache 6, 0(%3) \n\t" + " mfc0 %0, $29, 1\n\t" + " dmfc0 $1, $28, 1\n\t" + " dsrl32 %1, $1, 0 \n\t" + " sll %2, $1, 0 \n\t" + " .set pop \n" + : "=r" (datahi), "=r" (insta), "=r" (instb) + : "r" ((way << 13) | addr | (offset << 3))); + predecode = (datahi >> 8) & 0xff; + if (((datahi >> 16) & 1) != (uint32_t)range_parity(predecode, 7, 0)) { + prom_printf(" ** bad parity in predecode\n"); + res |= CP0_CERRI_DATA_PARITY; + } + /* XXXKW should/could check predecode bits themselves */ + if (((datahi >> 4) & 0xf) ^ inst_parity(insta)) { + prom_printf(" ** bad parity in instruction a\n"); + res |= CP0_CERRI_DATA_PARITY; + } + if ((datahi & 0xf) ^ inst_parity(instb)) { + prom_printf(" ** bad parity in instruction b\n"); + res |= CP0_CERRI_DATA_PARITY; + } + prom_printf(" %05X-%08X%08X", datahi, insta, instb); + } + prom_printf("\n"); + } + } + return res; +} + +/* Compute the ECC for a data doubleword */ +static uint8_t dc_ecc(uint64_t dword) +{ + uint64_t t; + uint32_t w; + uint8_t p; + int i; + + p = 0; + for (i = 7; i >= 0; i--) + { + p <<= 1; + t = dword & mask_72_64[i]; + w = (uint32_t)(t >> 32); + p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF] + ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]); + w = (uint32_t)(t & 0xFFFFFFFF); + p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF] + ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]); + } + return p; +} + +struct dc_state { + unsigned char val; + char *name; +}; + +static struct dc_state dc_states[] = { + { 0x00, "INVALID" }, + { 0x0f, "COH-SHD" }, + { 0x13, "NCO-E-C" }, + { 0x19, "NCO-E-D" }, + { 0x16, "COH-E-C" }, + { 0x1c, "COH-E-D" }, + { 0xff, "*ERROR*" } +}; + +#define DC_TAG_VALID(state) \ + (((state) == 0xf) || ((state) == 0x13) || ((state) == 0x19) || ((state == 0x16)) || ((state) == 0x1c)) + +static char *dc_state_str(unsigned char state) +{ + struct dc_state *dsc = dc_states; + while (dsc->val != 0xff) { + if (dsc->val == state) + break; + dsc++; + } + return dsc->name; +} + +static uint32_t extract_dc(unsigned short addr, int data) +{ + int valid, way; + unsigned char state; + uint64_t taglo, pa; + uint32_t taghi, taglolo, taglohi; + uint8_t ecc, lru; + int res = 0; + + prom_printf("Dcache index 0x%04x ", addr); + for (way = 0; way < 4; way++) { + __asm__ __volatile__ ( + " .set push\n\t" + " .set noreorder\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " cache 5, 0(%3)\n\t" /* Index-load-tag-D */ + " mfc0 %0, $29, 2\n\t" + " dmfc0 $1, $28, 2\n\t" + " dsrl32 %1, $1, 0\n\t" + " sll %2, $1, 0\n\t" + " .set pop" + : "=r" (taghi), "=r" (taglohi), "=r" (taglolo) + : "r" ((way << 13) | addr)); + + taglo = ((unsigned long long)taglohi << 32) | taglolo; + pa = (taglo & 0xFFFFFFE000) | addr; + if (way == 0) { + lru = (taghi >> 14) & 0xff; + prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", + ((addr >> 11) & 0x2) | ((addr >> 5) & 1), /* bank */ + ((addr >> 6) & 0x3f), /* index */ + (lru & 0x3), + ((lru >> 2) & 0x3), + ((lru >> 4) & 0x3), + ((lru >> 6) & 0x3)); + } + state = (taghi >> 25) & 0x1f; + valid = DC_TAG_VALID(state); + prom_printf(" %d [PA %010llx] [state %s (%02x)] raw tags: %08X-%016llX\n", + way, pa, dc_state_str(state), state, taghi, taglo); + if (valid) { + if (((taglo >> 11) & 1) ^ range_parity(taglo, 39, 26)) { + prom_printf(" ** bad parity in PTag1\n"); + res |= CP0_CERRD_TAG_ADDRESS; + } + if (((taglo >> 10) & 1) ^ range_parity(taglo, 25, 13)) { + prom_printf(" ** bad parity in PTag0\n"); + res |= CP0_CERRD_TAG_ADDRESS; + } + } else { + res |= CP0_CERRD_TAG_STATE; + } + + if (data) { + uint64_t datalo; + uint32_t datalohi, datalolo, datahi; + int offset; + + for (offset = 0; offset < 4; offset++) { + /* Index-load-data-D */ + __asm__ __volatile__ ( + " .set push\n\t" + " .set noreorder\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " cache 7, 0(%3)\n\t" /* Index-load-data-D */ + " mfc0 %0, $29, 3\n\t" + " dmfc0 $1, $28, 3\n\t" + " dsrl32 %1, $1, 0 \n\t" + " sll %2, $1, 0 \n\t" + " .set pop" + : "=r" (datahi), "=r" (datalohi), "=r" (datalolo) + : "r" ((way << 13) | addr | (offset << 3))); + datalo = ((unsigned long long)datalohi << 32) | datalolo; + ecc = dc_ecc(datalo); + if (ecc != datahi) { + int bits = 0; + prom_printf(" ** bad ECC (%02x %02x) ->", + datahi, ecc); + ecc ^= datahi; + while (ecc) { + if (ecc & 1) bits++; + ecc >>= 1; + } + res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE; + } + prom_printf(" %02X-%016llX", datahi, datalo); + } + prom_printf("\n"); + } + } + return res; +} diff -urN linux-2.4.21-bk37/arch/mips/mm/cex-sb1.S linux-2.4.21-bk38/arch/mips/mm/cex-sb1.S --- linux-2.4.21-bk37/arch/mips/mm/cex-sb1.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/cex-sb1.S 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2001,2002,2003 Broadcom Corporation + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include +#include + +#include +#include +#include +#include +#include + + .text + .set noat + .set mips4 + + __INIT + + /* Cache Error handler for SB1 */ + LEAF(except_vec2_sb1) + mfc0 k1, $26 + # check if error was recoverable + bltz k1, leave_cerr +#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS + # look for signature of spurious CErr + lui k0, 0x4000 + bne k0, k1, 1f + .word 0x401Bd801 # mfc0 k1, $27, 1 + lui k0, 0xffe0 + and k1, k0, k1 + lui k0, 0x0200 + beq k0, k1, leave_cerr +1: +#endif + j handle_vec2_sb1 + +leave_cerr: + # clear/unlock the registers + mtc0 zero, $26 + mtc0 zero, $27 + .word 0x4080d801 # mtc0 zero, $27, 1 + .word 0x4080d803 # mtc0 zero, $27, 3 + eret + END(except_vec2_sb1) + + __FINIT + + LEAF(handle_vec2_sb1) + mfc0 k0,CP0_CONFIG + li k1,~CONF_CM_CMASK + and k0,k0,k1 + ori k0,k0,CONF_CM_UNCACHED + mtc0 k0,CP0_CONFIG + + SSNOP + SSNOP + SSNOP + SSNOP + bnezl $0, 1f +1: + mfc0 k0, CP0_STATUS + sll k0, k0, 3 # check CU0 (kernel?) + bltz k0, 2f + GET_SAVED_SP + move sp, k0 # want Kseg SP (so uncached) +2: + j sb1_cache_error + + END(handle_vec2_sb1) diff -urN linux-2.4.21-bk37/arch/mips/mm/fault.c linux-2.4.21-bk38/arch/mips/mm/fault.c --- linux-2.4.21-bk37/arch/mips/mm/fault.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/fault.c 2003-08-24 02:55:57.000000000 -0700 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -159,7 +160,6 @@ bad_area: up_read(&mm->mmap_sem); -bad_area_nosemaphore: /* User mode accesses just cause a SIGSEGV */ if (user_mode(regs)) { tsk->thread.cp0_badvaddr = address; @@ -246,26 +246,31 @@ /* * Synchronize this task's top level page-table * with the 'reference' page table. + * + * Do _not_ use "tsk" here. We might be inside + * an interrupt in the middle of a task switch.. */ - int offset = pgd_index(address); + int offset = __pgd_offset(address); pgd_t *pgd, *pgd_k; pmd_t *pmd, *pmd_k; + pte_t *pte_k; - pgd = tsk->active_mm->pgd + offset; + pgd = (pgd_t *) pgd_current[smp_processor_id()] + offset; pgd_k = init_mm.pgd + offset; - if (!pgd_present(*pgd)) { - if (!pgd_present(*pgd_k)) - goto bad_area_nosemaphore; - set_pgd(pgd, *pgd_k); - return; - } + if (!pgd_present(*pgd_k)) + goto no_context; + set_pgd(pgd, *pgd_k); pmd = pmd_offset(pgd, address); pmd_k = pmd_offset(pgd_k, address); - - if (pmd_present(*pmd) || !pmd_present(*pmd_k)) - goto bad_area_nosemaphore; + if (!pmd_present(*pmd_k)) + goto no_context; set_pmd(pmd, *pmd_k); + + pte_k = pte_offset(pmd_k, address); + if (!pte_present(*pte_k)) + goto no_context; + return; } } diff -urN linux-2.4.21-bk37/arch/mips/mm/init.c linux-2.4.21-bk38/arch/mips/mm/init.c --- linux-2.4.21-bk37/arch/mips/mm/init.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/init.c 2003-08-24 02:55:57.000000000 -0700 @@ -43,17 +43,6 @@ static unsigned long totalram_pages; static unsigned long totalhigh_pages; -extern void prom_free_prom_memory(void); - - -asmlinkage int sys_cacheflush(void *addr, int bytes, int cache) -{ - /* This should flush more selectivly ... */ - __flush_cache_all(); - - return 0; -} - /* * We have upto 8 empty zeroed pages so we can map one of the right colour * when needed. This is necessary only on R4000 / R4400 SC and MC versions @@ -67,7 +56,8 @@ { unsigned long order, size; struct page *page; - if(mips_cpu.options & MIPS_CPU_VCE) + + if (cpu_has_vce) order = 3; else order = 0; @@ -161,6 +151,7 @@ extern char _ftext, _etext, _fdata, _edata; extern char __init_begin, __init_end; +#ifdef CONFIG_HIGHMEM static void __init fixrange_init (unsigned long start, unsigned long end, pgd_t *pgd_base) { @@ -189,22 +180,25 @@ j = 0; } } +#endif void __init pagetable_init(void) { +#ifdef CONFIG_HIGHMEM unsigned long vaddr; pgd_t *pgd, *pgd_base; pmd_t *pmd; pte_t *pte; +#endif /* Initialize the entire pgd. */ pgd_init((unsigned long)swapper_pg_dir); pgd_init((unsigned long)swapper_pg_dir + sizeof(pgd_t ) * USER_PTRS_PER_PGD); +#ifdef CONFIG_HIGHMEM pgd_base = swapper_pg_dir; -#ifdef CONFIG_HIGHMEM /* * Fixed mappings: */ @@ -360,7 +354,7 @@ #endif extern char __init_begin, __init_end; -extern void prom_free_prom_memory(void); +extern void prom_free_prom_memory(void) __init; void free_initmem(void) { diff -urN linux-2.4.21-bk37/arch/mips/mm/ioremap.c linux-2.4.21-bk38/arch/mips/mm/ioremap.c --- linux-2.4.21-bk37/arch/mips/mm/ioremap.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/ioremap.c 2003-08-24 02:55:57.000000000 -0700 @@ -94,6 +94,17 @@ } /* + * Allow physical addresses to be fixed up to help 36 bit + * peripherals. + */ +static phys_t def_fixup_bigphys_addr(phys_t phys_addr, phys_t size) +{ + return phys_addr; +} + +phys_t (*fixup_bigphys_addr)(phys_t phys_addr, phys_t size) = def_fixup_bigphys_addr; + +/* * Generic mapping function (not visible outside): */ @@ -107,7 +118,7 @@ * caller shouldn't need to know that small detail. */ -#define IS_LOW512(addr) (!((phys_t)(addr) & ~0x1fffffffUL)) +#define IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL)) void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags) { @@ -116,6 +127,8 @@ phys_t last_addr; void * addr; + phys_addr = fixup_bigphys_addr(phys_addr, size); + /* Don't allow wraparound or zero size */ last_addr = phys_addr + size - 1; if (!size || last_addr < phys_addr) diff -urN linux-2.4.21-bk37/arch/mips/mm/loadmmu.c linux-2.4.21-bk38/arch/mips/mm/loadmmu.c --- linux-2.4.21-bk37/arch/mips/mm/loadmmu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/loadmmu.c 2003-08-24 02:55:57.000000000 -0700 @@ -1,7 +1,11 @@ /* - * loadmmu.c: Setup cpu/cache specific function ptrs at boot time. + * 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. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999 Silicon Graphics, Inc. * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. */ @@ -27,13 +31,13 @@ void (*___flush_cache_all)(void); void (*_flush_cache_mm)(struct mm_struct *mm); void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start, - unsigned long end); + unsigned long end); void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page); -void (*_flush_cache_sigtramp)(unsigned long addr); void (*_flush_icache_range)(unsigned long start, unsigned long end); void (*_flush_icache_page)(struct vm_area_struct *vma, struct page *page); -void (*_flush_page_to_ram)(struct page * page); +void (*_flush_cache_sigtramp)(unsigned long addr); +void (*_flush_data_cache_page)(unsigned long addr); void (*_flush_icache_all)(void); #ifdef CONFIG_NONCOHERENT_IO @@ -49,49 +53,31 @@ #endif /* CONFIG_NONCOHERENT_IO */ - extern void ld_mmu_r23000(void); extern void ld_mmu_r4xx0(void); extern void ld_mmu_tx39(void); -extern void ld_mmu_tx49(void); -extern void ld_mmu_r5432(void); extern void ld_mmu_r6000(void); -extern void ld_mmu_rm7k(void); extern void ld_mmu_tfp(void); extern void ld_mmu_andes(void); extern void ld_mmu_sb1(void); -extern void ld_mmu_mips32(void); +extern void sb1_tlb_init(void); extern void r3k_tlb_init(void); extern void r4k_tlb_init(void); extern void sb1_tlb_init(void); -void __init loadmmu(void) +void __init load_mmu(void) { - if (mips_cpu.options & MIPS_CPU_4KTLB) { -#if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_VR41XX) || \ - defined(CONFIG_CPU_R4300) || defined(CONFIG_CPU_R5000) || \ - defined(CONFIG_CPU_NEVADA) + if (cpu_has_4ktlb) { +#if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_VR41XX) || \ + defined(CONFIG_CPU_R4300) || defined(CONFIG_CPU_R5000) || \ + defined(CONFIG_CPU_NEVADA) || defined(CONFIG_CPU_R5432) || \ + defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_MIPS32) || \ + defined(CONFIG_CPU_MIPS64) || defined(CONFIG_CPU_TX49XX) || \ + defined(CONFIG_CPU_RM7000) ld_mmu_r4xx0(); r4k_tlb_init(); #endif -#if defined(CONFIG_CPU_RM7000) - ld_mmu_rm7k(); - r4k_tlb_init(); -#endif -#if defined(CONFIG_CPU_R5432) || defined(CONFIG_CPU_R5500) - ld_mmu_r5432(); - r4k_tlb_init(); -#endif -#if defined(CONFIG_CPU_TX49XX) - ld_mmu_tx49(); - r4k_tlb_init(); -#endif - -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) - ld_mmu_mips32(); - r4k_tlb_init(); -#endif - } else switch(mips_cpu.cputype) { + } else switch (current_cpu_data.cputype) { #ifdef CONFIG_CPU_R3000 case CPU_R2000: case CPU_R3000: @@ -100,19 +86,11 @@ ld_mmu_r23000(); r3k_tlb_init(); break; - case CPU_TX3912: - case CPU_TX3922: - case CPU_TX3927: - case CPU_TX39XX: - ld_mmu_tx39(); - r3k_tlb_init(); - break; #endif #ifdef CONFIG_CPU_TX39XX case CPU_TX3912: case CPU_TX3922: case CPU_TX3927: - case CPU_TX39XX: ld_mmu_tx39(); r3k_tlb_init(); break; @@ -120,8 +98,8 @@ #ifdef CONFIG_CPU_R10000 case CPU_R10000: case CPU_R12000: - ld_mmu_andes(); - r4k_tlb_init(); + ld_mmu_r4xx0(); + andes_tlb_init(); break; #endif #ifdef CONFIG_CPU_SB1 @@ -130,6 +108,11 @@ sb1_tlb_init(); break; #endif + + case CPU_R8000: + panic("R8000 is unsupported"); + break; + default: panic("Yeee, unsupported mmu/cache architecture."); } diff -urN linux-2.4.21-bk37/arch/mips/mm/pg-andes.S linux-2.4.21-bk38/arch/mips/mm/pg-andes.S --- linux-2.4.21-bk37/arch/mips/mm/pg-andes.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/mm/pg-andes.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,66 +0,0 @@ -/* - * 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. - * - * r4xx0.c: R4000 processor variant specific MMU/Cache routines. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org - */ -#include -#include -#include - - .text - .set mips4 - .set noat - -/* - * This is suboptimal for 32-bit kernels; we assume that R10000 is only used - * with 64-bit kernels. The prefetch offsets have been experimentally tuned - * an Origin 200. - */ - -LEAF(andes_clear_page) - LONG_ADDIU AT, a0, _PAGE_SIZE -1: pref 7, 512(a0) - LONG_S zero, 0*SZREG(a0) - LONG_S zero, 1*SZREG(a0) - LONG_S zero, 2*SZREG(a0) - LONG_S zero, 3*SZREG(a0) - LONG_ADDIU a0, a0, 8*SZREG - LONG_S zero, -4*SZREG(a0) - LONG_S zero, -3*SZREG(a0) - LONG_S zero, -2*SZREG(a0) - LONG_S zero, -1*SZREG(a0) - bne AT, a0, 1b - j ra - .end andes_clear_page - END(andes_clear_page) - -LEAF(andes_copy_page) - LONG_ADDIU AT, a0, _PAGE_SIZE -1: pref 0, 2*128(a1) - pref 1, 2*128(a0) - LONG_L a3, 0*SZREG(a1) - LONG_L a2, 1*SZREG8(a1) - LONG_L v1, 2*SZREG(a1) - LONG_L v0, 3*SZREG(a1) - LONG_S a3, 0*SZREG(a0) - LONG_S a2, 1*SZREG(a0) - LONG_S v1, 2*SZREG(a0) - LONG_S v0, 3*SZREG(a0) - LONG_ADDIU a0, a0, 8*SZREG - LONG_ADDIU a1, a1, 8*SZREG - LONG_L a3, -4*SZREG(a1) - LONG_L a2, -3*SZREG(a1) - LONG_L v1, -2*SZREG(a1) - LONG_L v0, -1*SZREG(a1) - LONG_S a3, -4*SZREG(a0) - LONG_S a2, -3*SZREG(a0) - LONG_S v1, -2*SZREG(a0) - LONG_S v0, -1*SZREG(a0) - bne AT, a0,1b - j ra - END(andes_copy_page) diff -urN linux-2.4.21-bk37/arch/mips/mm/pg-mips32.c linux-2.4.21-bk38/arch/mips/mm/pg-mips32.c --- linux-2.4.21-bk37/arch/mips/mm/pg-mips32.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/mm/pg-mips32.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,140 +0,0 @@ -/* - * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * MIPS32 CPU variant specific MMU/Cache routines. - */ -#include -#include - -#include -#include -#include - -extern int dc_lsize, ic_lsize, sc_lsize; - -/* - * Zero an entire page. - */ - -void mips32_clear_page_dc(unsigned long page) -{ - unsigned long i; - - if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) { - for (i=page; i -#include - -#include - -void r5432_clear_page_d32(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "addiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "addiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) - : "memory"); -} - -/* - * This is still inefficient. We only can do better if we know the - * virtual address where the copy will be accessed. - */ - -void r5432_copy_page_d32(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "addiu\t$1,%0,%8\n" - "1:\tcache\t%9,(%0)\n\t" - "lw\t%2,(%1)\n\t" - "lw\t%3,4(%1)\n\t" - "lw\t%4,8(%1)\n\t" - "lw\t%5,12(%1)\n\t" - "sw\t%2,(%0)\n\t" - "sw\t%3,4(%0)\n\t" - "sw\t%4,8(%0)\n\t" - "sw\t%5,12(%0)\n\t" - "lw\t%2,16(%1)\n\t" - "lw\t%3,20(%1)\n\t" - "lw\t%4,24(%1)\n\t" - "lw\t%5,28(%1)\n\t" - "sw\t%2,16(%0)\n\t" - "sw\t%3,20(%0)\n\t" - "sw\t%4,24(%0)\n\t" - "sw\t%5,28(%0)\n\t" - "cache\t%9,32(%0)\n\t" - "addiu\t%0,64\n\t" - "addiu\t%1,64\n\t" - "lw\t%2,-32(%1)\n\t" - "lw\t%3,-28(%1)\n\t" - "lw\t%4,-24(%1)\n\t" - "lw\t%5,-20(%1)\n\t" - "sw\t%2,-32(%0)\n\t" - "sw\t%3,-28(%0)\n\t" - "sw\t%4,-24(%0)\n\t" - "sw\t%5,-20(%0)\n\t" - "lw\t%2,-16(%1)\n\t" - "lw\t%3,-12(%1)\n\t" - "lw\t%4,-8(%1)\n\t" - "lw\t%5,-4(%1)\n\t" - "sw\t%2,-16(%0)\n\t" - "sw\t%3,-12(%0)\n\t" - "sw\t%4,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t%5,-4(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - -void pgd_init(unsigned long page) -{ - unsigned long *p = (unsigned long *) page; - int i; - - for(i = 0; i < USER_PTRS_PER_PGD; i+=8) { - p[i + 0] = (unsigned long) invalid_pte_table; - p[i + 1] = (unsigned long) invalid_pte_table; - p[i + 2] = (unsigned long) invalid_pte_table; - p[i + 3] = (unsigned long) invalid_pte_table; - p[i + 4] = (unsigned long) invalid_pte_table; - p[i + 5] = (unsigned long) invalid_pte_table; - p[i + 6] = (unsigned long) invalid_pte_table; - p[i + 7] = (unsigned long) invalid_pte_table; - } -} diff -urN linux-2.4.21-bk37/arch/mips/mm/pg-rm7k.c linux-2.4.21-bk38/arch/mips/mm/pg-rm7k.c --- linux-2.4.21-bk37/arch/mips/mm/pg-rm7k.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/mm/pg-rm7k.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,120 +0,0 @@ -/* - * 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. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998 Ralf Baechle ralf@gnu.org - */ -#include -#include - -#include - -/* - * Zero an entire page. Note that while the RM7000 has a second level cache - * it doesn't have a Create_Dirty_Excl_SD operation. - */ -void rm7k_clear_page(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "addiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "addiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) - : "memory"); -} - -/* - * Copy an entire page. Note that while the RM7000 has a second level cache - * it doesn't have a Create_Dirty_Excl_SD operation. - */ -void rm7k_copy_page(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "addiu\t$1,%0,%8\n" - "1:\tcache\t%9,(%0)\n\t" - "lw\t%2,(%1)\n\t" - "lw\t%3,4(%1)\n\t" - "lw\t%4,8(%1)\n\t" - "lw\t%5,12(%1)\n\t" - "sw\t%2,(%0)\n\t" - "sw\t%3,4(%0)\n\t" - "sw\t%4,8(%0)\n\t" - "sw\t%5,12(%0)\n\t" - "lw\t%2,16(%1)\n\t" - "lw\t%3,20(%1)\n\t" - "lw\t%4,24(%1)\n\t" - "lw\t%5,28(%1)\n\t" - "sw\t%2,16(%0)\n\t" - "sw\t%3,20(%0)\n\t" - "sw\t%4,24(%0)\n\t" - "sw\t%5,28(%0)\n\t" - "cache\t%9,32(%0)\n\t" - "addiu\t%0,64\n\t" - "addiu\t%1,64\n\t" - "lw\t%2,-32(%1)\n\t" - "lw\t%3,-28(%1)\n\t" - "lw\t%4,-24(%1)\n\t" - "lw\t%5,-20(%1)\n\t" - "sw\t%2,-32(%0)\n\t" - "sw\t%3,-28(%0)\n\t" - "sw\t%4,-24(%0)\n\t" - "sw\t%5,-20(%0)\n\t" - "lw\t%2,-16(%1)\n\t" - "lw\t%3,-12(%1)\n\t" - "lw\t%4,-8(%1)\n\t" - "lw\t%5,-4(%1)\n\t" - "sw\t%2,-16(%0)\n\t" - "sw\t%3,-12(%0)\n\t" - "sw\t%4,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t%5,-4(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - : "0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - -void pgd_init(unsigned long page) -{ - unsigned long *p = (unsigned long *) page; - int i; - - for (i = 0; i < USER_PTRS_PER_PGD; i+=8) { - p[i + 0] = (unsigned long) invalid_pte_table; - p[i + 1] = (unsigned long) invalid_pte_table; - p[i + 2] = (unsigned long) invalid_pte_table; - p[i + 3] = (unsigned long) invalid_pte_table; - p[i + 4] = (unsigned long) invalid_pte_table; - p[i + 5] = (unsigned long) invalid_pte_table; - p[i + 6] = (unsigned long) invalid_pte_table; - p[i + 7] = (unsigned long) invalid_pte_table; - } -} diff -urN linux-2.4.21-bk37/arch/mips/mm/pg-sb1.c linux-2.4.21-bk38/arch/mips/mm/pg-sb1.c --- linux-2.4.21-bk37/arch/mips/mm/pg-sb1.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/pg-sb1.c 2003-08-24 02:55:57.000000000 -0700 @@ -1,9 +1,10 @@ /* * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 2000 Sibyte + * Copyright (C) 2000 SiByte, Inc. * - * Written by Justin Carlson (carlson@sibyte.com) + * Written by Justin Carlson of SiByte, Inc. + * and Kip Walker of Broadcom Corp. * * * This program is free software; you can redistribute it and/or @@ -20,8 +21,16 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + #include -#include +#include +#include + +#include +#include +#include +#include +#include #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS #define SB1_PREF_LOAD_STREAMED_HINT "0" @@ -34,13 +43,15 @@ /* These are the functions hooked by the memory management function pointers */ void sb1_clear_page(void *page) { - /* JDCXXX - This should be bottlenecked by the write buffer, but these - things tend to be mildly unpredictable...should check this on the - performance model */ - - /* We prefetch 4 lines ahead. We're also "cheating" slightly here... - since we know we're on an SB1, we force the assembler to take - 64-bit operands to speed things up */ + /* + * JDCXXX - This should be bottlenecked by the write buffer, but these + * things tend to be mildly unpredictable...should check this on the + * performance model + * + * We prefetch 4 lines ahead. We're also "cheating" slightly here... + * since we know we're on an SB1, we force the assembler to take + * 64-bit operands to speed things up + */ __asm__ __volatile__( ".set push \n" ".set noreorder \n" @@ -63,22 +74,20 @@ " bne $1, %0, 1b \n" " addiu %0, %0, 32 \n" /* Next cacheline (This instruction better be short piped!) */ ".set pop \n" - :"=r" (page) - :"0" (page), - "I" (PAGE_SIZE-32) - :"$1","memory"); + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE-32) + : "memory"); } void sb1_copy_page(void *to, void *from) { - - /* This should be optimized in assembly...can't use ld/sd, though, + /* + * This should be optimized in assembly...can't use ld/sd, though, * because the top 32 bits could be nuked if we took an interrupt * during the routine. And this is not a good place to be cli()'ing - */ - - /* The pref's used here are using "streaming" hints, which cause the + * + * The pref's used here are using "streaming" hints, which cause the * copied data to be kicked out of the cache sooner. A page copy often * ends up copying a lot more data than is commonly used, so this seems * to make sense in terms of reducing cache pollution, but I've no real @@ -125,19 +134,82 @@ " bne $1, %0, 1b \n" " addiu %0, %0, 32 \n" /* Next cacheline */ ".set pop \n" - :"=r" (to), - "=r" (from) - : - "0" (from), - "1" (to), - "I" (PAGE_SIZE-32) - :"$1","$2","$3","$4","$5","$6","$7","$8","$9","memory"); + : "=r" (to), "=r" (from) + : "0" (from), "1" (to), "I" (PAGE_SIZE-32) + : "$2","$3","$4","$5","$6","$7","$8","$9","memory"); +} + + +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS + /* - unsigned long *src = from; - unsigned long *dest = to; - unsigned long *target = (unsigned long *) (((unsigned long)src) + PAGE_SIZE); - while (src != target) { - *dest++ = *src++; - } -*/ + * Pad descriptors to cacheline, since each is exclusively owned by a + * particular CPU. + */ +typedef struct dmadscr_s { + uint64_t dscr_a; + uint64_t dscr_b; + uint64_t pad_a; + uint64_t pad_b; +} dmadscr_t; + +static dmadscr_t page_descr[NR_CPUS] __attribute__((aligned(SMP_CACHE_BYTES))); + +void sb1_dma_init(void) +{ + int cpu = smp_processor_id(); + uint64_t base_val = PHYSADDR(&page_descr[cpu]) | V_DM_DSCR_BASE_RINGSZ(1); + + out64(base_val, + IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); + out64(base_val | M_DM_DSCR_BASE_RESET, + IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); + out64(base_val | M_DM_DSCR_BASE_ENABL, + IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); +} + +void sb1_clear_page_dma(void *page) +{ + int cpu = smp_processor_id(); + + /* if the page is above Kseg0, use old way */ + if (KSEGX(page) != K0BASE) + return sb1_clear_page(page); + + page_descr[cpu].dscr_a = PHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT; + page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE); + out64(1, IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)); + + /* + * Don't really want to do it this way, but there's no + * reliable way to delay completion detection. + */ + while (!(in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & M_DM_DSCR_BASE_INTERRUPT)) + ; + in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); } + +void sb1_copy_page_dma(void *to, void *from) +{ + unsigned long from_phys = PHYSADDR(from); + unsigned long to_phys = PHYSADDR(to); + int cpu = smp_processor_id(); + + /* if either page is above Kseg0, use old way */ + if ((KSEGX(to) != K0BASE) || (KSEGX(from) != K0BASE)) + return sb1_copy_page(to, from); + + page_descr[cpu].dscr_a = PHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT; + page_descr[cpu].dscr_b = PHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE); + out64(1, IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)); + + /* + * Don't really want to do it this way, but there's no + * reliable way to delay completion detection. + */ + while (!(in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & M_DM_DSCR_BASE_INTERRUPT)) + ; + in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); +} + +#endif diff -urN linux-2.4.21-bk37/arch/mips/mm/r5k-sc.c linux-2.4.21-bk38/arch/mips/mm/r5k-sc.c --- linux-2.4.21-bk37/arch/mips/mm/r5k-sc.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/r5k-sc.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,115 +0,0 @@ -/* - * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), - * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* Secondary cache size in bytes, if present. */ -static unsigned long scache_size; - -#define SC_LINE 32 -#define SC_PAGE (128*SC_LINE) - -#define cache_op(base,op) \ -__asm__ __volatile__(" \ - .set noreorder; \ - .set mips3; \ - cache %1, (%0); \ - .set mips0; \ - .set reorder" \ - : \ - : "r" (base), \ - "i" (op)); - -static inline void blast_r5000_scache(void) -{ - unsigned long start = KSEG0; - unsigned long end = KSEG0 + scache_size; - - while(start < end) { - cache_op(start, R5K_Page_Invalidate_S); - start += SC_PAGE; - } -} - -static void r5k_dma_cache_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= scache_size) { - blast_r5000_scache(); - return; - } - - /* On the R5000 secondary cache we cannot - * invalidate less than a page at a time. - * The secondary cache is physically indexed, write-through. - */ - a = addr & ~(SC_PAGE - 1); - end = (addr + size - 1) & ~(SC_PAGE - 1); - while (a <= end) { - cache_op(a, R5K_Page_Invalidate_S); - a += SC_PAGE; - } -} - -static void r5k_sc_enable(void) -{ - unsigned long flags; - - __save_and_cli(flags); - change_cp0_config(CONF_SE, CONF_SE); - blast_r5000_scache(); - __restore_flags(flags); -} - -static void r5k_sc_disable(void) -{ - unsigned long flags; - - __save_and_cli(flags); - blast_r5000_scache(); - change_cp0_config(CONF_SE, 0); - __restore_flags(flags); -} - -static inline int __init r5k_sc_probe(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - - if(config & CONF_SC) - return(0); - - scache_size = (512*1024) << ((config >> 20)&3); - - printk("R5000 SCACHE size %ldK, linesize 32 bytes.\n", - scache_size >> 10); - - return 1; -} - -struct bcache_ops r5k_sc_ops = { - r5k_sc_enable, - r5k_sc_disable, - r5k_dma_cache_inv_sc, - r5k_dma_cache_inv_sc -}; - -void __init r5k_sc_init(void) -{ - if (r5k_sc_probe()) { - r5k_sc_enable(); - bcops = &r5k_sc_ops; - } -} diff -urN linux-2.4.21-bk37/arch/mips/mm/remap.c linux-2.4.21-bk38/arch/mips/mm/remap.c --- linux-2.4.21-bk37/arch/mips/mm/remap.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/remap.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,115 @@ +/* + * arch/mips/mm/remap.c + * A copy of mm/memory.c with modifications to handle 64 bit + * physical addresses. + */ + +/* + * maps a range of physical memory into the requested pages. the old + * mappings are removed. any references to nonexistent pages results + * in null mappings (currently treated as "copy-on-access") + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * Return indicates whether a page was freed so caller can adjust rss + */ +static inline void forget_pte(pte_t page) +{ + if (!pte_none(page)) { + printk("forget_pte: old mapping existed!\n"); + BUG(); + } +} + +static inline void remap_pte_range(pte_t * pte, unsigned long address, unsigned long size, + phys_t phys_addr, pgprot_t prot) +{ + unsigned long end; + + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + do { + struct page *page; + pte_t oldpage; + oldpage = ptep_get_and_clear(pte); + + page = virt_to_page(__va(phys_addr)); + if ((!VALID_PAGE(page)) || PageReserved(page)) + set_pte(pte, mk_pte_phys(phys_addr, prot)); + forget_pte(oldpage); + address += PAGE_SIZE; + phys_addr += PAGE_SIZE; + pte++; + } while (address && (address < end)); +} + +static inline int remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size, + phys_t phys_addr, pgprot_t prot) +{ + unsigned long end; + + address &= ~PGDIR_MASK; + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + phys_addr -= address; + do { + pte_t * pte = pte_alloc(mm, pmd, address); + if (!pte) + return -ENOMEM; + remap_pte_range(pte, address, end - address, address + phys_addr, prot); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address && (address < end)); + return 0; +} + +extern phys_t (*fixup_bigphys_addr)(phys_t phys_addr, phys_t size); +/* Note: this is only safe if the mm semaphore is held when called. */ +int remap_page_range_high(unsigned long from, phys_t phys_addr, unsigned long size, pgprot_t prot) +{ + int error = 0; + pgd_t * dir; + unsigned long beg = from; + unsigned long end = from + size; + struct mm_struct *mm = current->mm; + + phys_addr = fixup_bigphys_addr(phys_addr, size); + phys_addr -= from; + dir = pgd_offset(mm, from); + flush_cache_range(mm, beg, end); + if (from >= end) + BUG(); + + spin_lock(&mm->page_table_lock); + do { + pmd_t *pmd = pmd_alloc(mm, dir, from); + error = -ENOMEM; + if (!pmd) + break; + error = remap_pmd_range(mm, pmd, from, end - from, phys_addr + from, prot); + if (error) + break; + from = (from + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } while (from && (from < end)); + spin_unlock(&mm->page_table_lock); + flush_tlb_range(mm, beg, end); + return error; +} diff -urN linux-2.4.21-bk37/arch/mips/mm/sc-ip22.c linux-2.4.21-bk38/arch/mips/mm/sc-ip22.c --- linux-2.4.21-bk37/arch/mips/mm/sc-ip22.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/sc-ip22.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,177 @@ +/* + * sc-ip22.c: Indy cache management functions. + * + * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), + * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Secondary cache size in bytes, if present. */ +static unsigned long scache_size; + +#undef DEBUG_CACHE + +#define SC_SIZE 0x00080000 +#define SC_LINE 32 +#define CI_MASK (SC_SIZE - SC_LINE) +#define SC_INDEX(n) ((n) & CI_MASK) + +static inline void indy_sc_wipe(unsigned long first, unsigned long last) +{ + unsigned long tmp; + + __asm__ __volatile__( + ".set\tpush\t\t\t# indy_sc_wipe\n\t" + ".set\tnoreorder\n\t" + ".set\tmips3\n\t" + ".set\tnoat\n\t" + "mfc0\t%2, $12\n\t" + "li\t$1, 0x80\t\t\t# Go 64 bit\n\t" + "mtc0\t$1, $12\n\t" + + "dli\t$1, 0x9000000080000000\n\t" + "or\t%0, $1\t\t\t# first line to flush\n\t" + "or\t%1, $1\t\t\t# last line to flush\n\t" + ".set\tat\n\t" + + "1:\tsw\t$0, 0(%0)\n\t" + "bne\t%0, %1, 1b\n\t" + " daddu\t%0, 32\n\t" + + "mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t" + "nop; nop; nop; nop;\n\t" + ".set\tpop" + : "=r" (first), "=r" (last), "=&r" (tmp) + : "0" (first), "1" (last)); +} + +static void indy_sc_wback_invalidate(unsigned long addr, unsigned long size) +{ + unsigned long first_line, last_line; + unsigned long flags; + +#ifdef DEBUG_CACHE + printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size); +#endif + + if (!size) + return; + + /* Which lines to flush? */ + first_line = SC_INDEX(addr); + last_line = SC_INDEX(addr + size - 1); + + local_irq_save(flags); + if (first_line <= last_line) { + indy_sc_wipe(first_line, last_line); + goto out; + } + + indy_sc_wipe(first_line, SC_SIZE - SC_LINE); + indy_sc_wipe(0, last_line); +out: + local_irq_restore(flags); +} + +static void indy_sc_enable(void) +{ + unsigned long addr, tmp1, tmp2; + + /* This is really cool... */ +#ifdef DEBUG_CACHE + printk("Enabling R4600 SCACHE\n"); +#endif + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tnoreorder\n\t" + ".set\tmips3\n\t" + "mfc0\t%2, $12\n\t" + "nop; nop; nop; nop;\n\t" + "li\t%1, 0x80\n\t" + "mtc0\t%1, $12\n\t" + "nop; nop; nop; nop;\n\t" + "li\t%0, 0x1\n\t" + "dsll\t%0, 31\n\t" + "lui\t%1, 0x9000\n\t" + "dsll32\t%1, 0\n\t" + "or\t%0, %1, %0\n\t" + "sb\t$0, 0(%0)\n\t" + "mtc0\t$0, $12\n\t" + "nop; nop; nop; nop;\n\t" + "mtc0\t%2, $12\n\t" + "nop; nop; nop; nop;\n\t" + ".set\tpop" + : "=r" (tmp1), "=r" (tmp2), "=r" (addr)); +} + +static void indy_sc_disable(void) +{ + unsigned long tmp1, tmp2, tmp3; + +#ifdef DEBUG_CACHE + printk("Disabling R4600 SCACHE\n"); +#endif + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tnoreorder\n\t" + ".set\tmips3\n\t" + "li\t%0, 0x1\n\t" + "dsll\t%0, 31\n\t" + "lui\t%1, 0x9000\n\t" + "dsll32\t%1, 0\n\t" + "or\t%0, %1, %0\n\t" + "mfc0\t%2, $12\n\t" + "nop; nop; nop; nop\n\t" + "li\t%1, 0x80\n\t" + "mtc0\t%1, $12\n\t" + "nop; nop; nop; nop\n\t" + "sh\t$0, 0(%0)\n\t" + "mtc0\t$0, $12\n\t" + "nop; nop; nop; nop\n\t" + "mtc0\t%2, $12\n\t" + "nop; nop; nop; nop\n\t" + ".set\tpop" + : "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)); +} + +static inline int __init indy_sc_probe(void) +{ + unsigned int size = ip22_eeprom_read(&sgimc->eeprom, 17); + if (size == 0) + return 0; + + size <<= PAGE_SHIFT; + printk(KERN_INFO "R4600/R5000 SCACHE size %dK, linesize 32 bytes.\n", + size >> 10); + scache_size = size; + + return 1; +} + +/* XXX Check with wje if the Indy caches can differenciate between + writeback + invalidate and just invalidate. */ +struct bcache_ops indy_sc_ops = { + .bc_enable = indy_sc_enable, + .bc_disable = indy_sc_disable, + .bc_wback_inv = indy_sc_wback_invalidate, + .bc_inv = indy_sc_wback_invalidate +}; + +void __init indy_sc_init(void) +{ + if (indy_sc_probe()) { + indy_sc_enable(); + bcops = &indy_sc_ops; + } +} diff -urN linux-2.4.21-bk37/arch/mips/mm/sc-r5k.c linux-2.4.21-bk38/arch/mips/mm/sc-r5k.c --- linux-2.4.21-bk37/arch/mips/mm/sc-r5k.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/sc-r5k.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,115 @@ +/* + * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), + * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Secondary cache size in bytes, if present. */ +static unsigned long scache_size; + +#define SC_LINE 32 +#define SC_PAGE (128*SC_LINE) + +#define cache_op(base,op) \ +__asm__ __volatile__(" \ + .set noreorder; \ + .set mips3; \ + cache %1, (%0); \ + .set mips0; \ + .set reorder" \ + : \ + : "r" (base), \ + "i" (op)); + +static inline void blast_r5000_scache(void) +{ + unsigned long start = KSEG0; + unsigned long end = KSEG0 + scache_size; + + while(start < end) { + cache_op(start, R5K_Page_Invalidate_S); + start += SC_PAGE; + } +} + +static void r5k_dma_cache_inv_sc(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + + if (size >= scache_size) { + blast_r5000_scache(); + return; + } + + /* On the R5000 secondary cache we cannot + * invalidate less than a page at a time. + * The secondary cache is physically indexed, write-through. + */ + a = addr & ~(SC_PAGE - 1); + end = (addr + size - 1) & ~(SC_PAGE - 1); + while (a <= end) { + cache_op(a, R5K_Page_Invalidate_S); + a += SC_PAGE; + } +} + +static void r5k_sc_enable(void) +{ + unsigned long flags; + + local_irq_save(flags); + change_c0_config(R5K_CONF_SE, R5K_CONF_SE); + blast_r5000_scache(); + local_irq_restore(flags); +} + +static void r5k_sc_disable(void) +{ + unsigned long flags; + + local_irq_save(flags); + blast_r5000_scache(); + change_c0_config(R5K_CONF_SE, 0); + local_irq_restore(flags); +} + +static inline int __init r5k_sc_probe(void) +{ + unsigned long config = read_c0_config(); + + if (config & CONF_SC) + return(0); + + scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20); + + printk("R5000 SCACHE size %ldkB, linesize 32 bytes.\n", + scache_size >> 10); + + return 1; +} + +static struct bcache_ops r5k_sc_ops = { + .bc_enable = r5k_sc_enable, + .bc_disable = r5k_sc_disable, + .bc_wback_inv = r5k_dma_cache_inv_sc, + .bc_inv = r5k_dma_cache_inv_sc +}; + +void __init r5k_sc_init(void) +{ + if (r5k_sc_probe()) { + r5k_sc_enable(); + bcops = &r5k_sc_ops; + } +} diff -urN linux-2.4.21-bk37/arch/mips/mm/sc-rm7k.c linux-2.4.21-bk38/arch/mips/mm/sc-rm7k.c --- linux-2.4.21-bk37/arch/mips/mm/sc-rm7k.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/sc-rm7k.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,193 @@ +/* + * sc-rm7k.c: RM7000 cache management functions. + * + * Copyright (C) 1997, 2001, 2003 Ralf Baechle (ralf@gnu.org), + */ +#include +#include +#include + +#include +#include +#include +#include +#include + +/* Primary cache parameters. */ +#define sc_lsize 32 +#define tc_pagesize (32*128) + +static unsigned long scache_way_size = 32; /* HACKKKKK!!! */ + +/* Secondary cache parameters. */ +#define scache_size (256*1024) /* Fixed to 256KiB on RM7000 */ + +extern unsigned long icache_way_size, dcache_way_size; + +#include + +int rm7k_tcache_enabled; + +/* + * Writeback and invalidate the primary cache dcache before DMA. + * (XXX These need to be fixed ...) + */ +static void rm7k_sc_wback_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + +#ifdef DEBUG_CACHE + printk("rm7k_sc_wback_inv[%08lx,%08lx]", addr, size); +#endif + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } + + if (!rm7k_tcache_enabled) + return; + + a = addr & ~(tc_pagesize - 1); + end = (addr + size - 1) & ~(tc_pagesize - 1); + while(1) { + invalidate_tcache_page(a); /* Page_Invalidate_T */ + if (a == end) + break; + a += tc_pagesize; + } +} + +static void rm7k_sc_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + +#ifdef DEBUG_CACHE + printk("rm7k_sc_inv[%08lx,%08lx]", addr, size); +#endif + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + invalidate_scache_line(a); /* Hit_Invalidate_SD */ + if (a == end) + break; + a += sc_lsize; + } + + if (!rm7k_tcache_enabled) + return; + + a = addr & ~(tc_pagesize - 1); + end = (addr + size - 1) & ~(tc_pagesize - 1); + while(1) { + invalidate_tcache_page(a); /* Page_Invalidate_T */ + if (a == end) + break; + a += tc_pagesize; + } +} + +/* + * This function is executed in the uncached segment KSEG1. + * It must not touch the stack, because the stack pointer still points + * into KSEG0. + * + * Three options: + * - Write it in assembly and guarantee that we don't use the stack. + * - Disable caching for KSEG0 before calling it. + * - Pray that GCC doesn't randomly start using the stack. + * + * This being Linux, we obviously take the least sane of those options - + * following DaveM's lead in c-r4k.c + * + * It seems we get our kicks from relying on unguaranteed behaviour in GCC + */ +static __init void rm7k_sc_enable(void) +{ + int i; + + set_c0_config(1<<3); /* CONF_SE */ + + write_c0_taglo(0); + write_c0_taghi(0); + + for (i=0; i> 31) & 1) + return 0; + + printk(KERN_INFO "Secondary cache size %ldK, linesize 32 bytes.\n", + (scache_size >> 10), sc_lsize); + + if ((config >> 3) & 1) + return; + + printk(KERN_INFO "Enabling secondary cache..."); + func(); + printk(" done\n"); + + /* + * While we're at it let's deal with the tertiary cache. + */ + if ((config >> 17) & 1) + return 1; + + /* + * We can't enable the L3 cache yet. There may be board-specific + * magic necessary to turn it on, and blindly asking the CPU to + * start using it would may give cache errors. + * + * Also, board-specific knowledge may allow us to use the + * CACHE Flash_Invalidate_T instruction if the tag RAM supports + * it, and may specify the size of the L3 cache so we don't have + * to probe it. + */ + printk(KERN_INFO "Tertiary cache present, %s enabled\n", + config&(1<<12) ? "already" : "not (yet)"); + + if ((config >> 12) & 1) + rm7k_tcache_enabled = 1; + + return 1; +} + +struct bcache_ops rm7k_sc_ops = { + .bc_enable = rm7k_sc_enable, + .bc_disable = rm7k_sc_disable, + .bc_wback_inv = rm7k_sc_wback_inv, + .bc_inv = rm7k_sc_inv +}; + +void __init rm7k_sc_init(void) +{ + if (rm7k_sc_probe()) { + rm7k_sc_enable(); + bcops = &rm7k_sc_ops; + } +} diff -urN linux-2.4.21-bk37/arch/mips/mm/tlb-r3k.c linux-2.4.21-bk38/arch/mips/mm/tlb-r3k.c --- linux-2.4.21-bk37/arch/mips/mm/tlb-r3k.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/tlb-r3k.c 2003-08-24 02:55:57.000000000 -0700 @@ -7,6 +7,8 @@ * Tx39XX R4k style caches added. HK * Copyright (C) 1998, 1999, 2000 Harald Koerfgen * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov + * Copyright (C) 2002 Ralf Baechle + * Copyright (C) 2002 Maciej W. Rozycki */ #include #include @@ -23,11 +25,19 @@ #include #include +#undef DEBUG_TLB + extern char except_vec0_r2300; -#undef DEBUG_TLB +/* CP0 hazard avoidance. */ +#define BARRIER \ + __asm__ __volatile__( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + "nop\n\t" \ + ".set pop\n\t") -int r3k_have_wired_reg = 0; /* should be in mips_cpu? */ +int r3k_have_wired_reg; /* should be in cpu_data? */ /* TLB operations. */ void local_flush_tlb_all(void) @@ -40,117 +50,109 @@ printk("[tlball]"); #endif - save_and_cli(flags); - old_ctx = (get_entryhi() & 0xfc0); - write_32bit_cp0_register(CP0_ENTRYLO0, 0); -#ifdef CONFIG_CPU_TX39XX - entry = r3k_have_wired_reg ? get_wired() : 8; -#else - entry = 8; -#endif - for (; entry < mips_cpu.tlbsize; entry++) { - write_32bit_cp0_register(CP0_INDEX, entry << 8); - write_32bit_cp0_register(CP0_ENTRYHI, ((entry | 0x80000) << 12)); - __asm__ __volatile__("tlbwi"); + local_irq_save(flags); + old_ctx = read_c0_entryhi() & ASID_MASK; + write_c0_entrylo0(0); + entry = r3k_have_wired_reg ? read_c0_wired() : 8; + for (; entry < current_cpu_data.tlbsize; entry++) { + write_c0_index(entry << 8); + write_c0_entryhi((entry | 0x80000) << 12); + BARRIER; + tlb_write_indexed(); } - set_entryhi(old_ctx); - restore_flags(flags); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); } void local_flush_tlb_mm(struct mm_struct *mm) { - if (mm->context != 0) { - unsigned long flags; + int cpu = smp_processor_id(); + if (cpu_context(cpu, mm) != 0) { #ifdef DEBUG_TLB - printk("[tlbmm<%lu>]", (unsigned long) mm->context); + printk("[tlbmm<%lu>]", (unsigned long)cpu_context(cpu, mm)); #endif - save_and_cli(flags); - get_new_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xfc0); - restore_flags(flags); + drop_mmu_context(mm, cpu); } } void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, - unsigned long end) + unsigned long end) { - if (mm->context != 0) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, mm) != 0) { unsigned long flags; int size; #ifdef DEBUG_TLB printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", - (mm->context & 0xfc0), start, end); + cpu_asid(cpu, mm), start, end); #endif - save_and_cli(flags); + local_irq_save(flags); size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - if (size <= mips_cpu.tlbsize) { - int oldpid = (get_entryhi() & 0xfc0); - int newpid = (mm->context & 0xfc0); + if (size <= current_cpu_data.tlbsize) { + int oldpid = read_c0_entryhi() & ASID_MASK; + int newpid = cpu_asid(cpu, mm); start &= PAGE_MASK; - end += (PAGE_SIZE - 1); + end += PAGE_SIZE - 1; end &= PAGE_MASK; while (start < end) { int idx; - set_entryhi(start | newpid); - start += PAGE_SIZE; + write_c0_entryhi(start | newpid); + start += PAGE_SIZE; /* BARRIER */ tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entryhi(KSEG0); - if (idx < 0) + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entryhi(KSEG0); + if (idx < 0) /* BARRIER */ continue; tlb_write_indexed(); } - set_entryhi(oldpid); + write_c0_entryhi(oldpid); } else { - get_new_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xfc0); + drop_mmu_context(mm, cpu); } - restore_flags(flags); + local_irq_restore(flags); } } void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) { - if (!vma || vma->vm_mm->context != 0) { + int cpu = smp_processor_id(); + + if (!vma || cpu_context(cpu, vma->vm_mm) != 0) { unsigned long flags; int oldpid, newpid, idx; #ifdef DEBUG_TLB - printk("[tlbpage<%lu,0x%08lx>]", vma->vm_mm->context, page); + printk("[tlbpage<%lu,0x%08lx>]", cpu_context(cpu, vma->vm_mm), page); #endif - newpid = (vma->vm_mm->context & 0xfc0); + newpid = cpu_asid(cpu, vma->vm_mm); page &= PAGE_MASK; - save_and_cli(flags); - oldpid = (get_entryhi() & 0xfc0); - set_entryhi(page | newpid); + local_irq_save(flags); + oldpid = read_c0_entryhi() & ASID_MASK; + write_c0_entryhi(page | newpid); + BARRIER; tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entryhi(KSEG0); - if (idx < 0) + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entryhi(KSEG0); + if (idx < 0) /* BARRIER */ goto finish; tlb_write_indexed(); finish: - set_entryhi(oldpid); - restore_flags(flags); + write_c0_entryhi(oldpid); + local_irq_restore(flags); } } -void update_mmu_cache(struct vm_area_struct * vma, unsigned long address, - pte_t pte) +void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) { unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; int idx, pid; /* @@ -159,92 +161,86 @@ if (current->active_mm != vma->vm_mm) return; - pid = get_entryhi() & 0xfc0; + pid = read_c0_entryhi() & ASID_MASK; #ifdef DEBUG_TLB - if ((pid != (vma->vm_mm->context & 0xfc0)) || (vma->vm_mm->context == 0)) { + if ((pid != cpu_asid(cpu, vma->vm_mm)) || (cpu_context(cpu, vma->vm_mm) == 0)) { printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%lu tlbpid=%d\n", - (vma->vm_mm->context & 0xfc0), pid); + (cpu_context(cpu, vma->vm_mm)), pid); } #endif - save_and_cli(flags); + local_irq_save(flags); address &= PAGE_MASK; - set_entryhi(address | (pid)); - pgdp = pgd_offset(vma->vm_mm, address); + write_c0_entryhi(address | pid); + BARRIER; tlb_probe(); - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - set_entrylo0(pte_val(*ptep)); - set_entryhi(address | (pid)); - if (idx < 0) { + idx = read_c0_index(); + write_c0_entrylo0(pte_val(pte)); + write_c0_entryhi(address | pid); + if (idx < 0) { /* BARRIER */ tlb_write_random(); -#if 0 - printk("[MISS]"); -#endif } else { tlb_write_indexed(); -#if 0 - printk("[HIT]"); -#endif } - set_entryhi(pid); - restore_flags(flags); + write_c0_entryhi(pid); + local_irq_restore(flags); } void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, - unsigned long entryhi, unsigned long pagemask) + unsigned long entryhi, unsigned long pagemask) { unsigned long flags; unsigned long old_ctx; static unsigned long wired = 0; -#ifdef CONFIG_CPU_TX39XX - if (r3k_have_wired_reg) { + if (r3k_have_wired_reg) { /* TX39XX */ unsigned long old_pagemask; unsigned long w; #ifdef DEBUG_TLB - printk("[tlbwired]"); - printk("ently lo0 %8x, hi %8x\n, pagemask %8x\n", + printk("[tlbwired]\n", entrylo0, entryhi, pagemask); #endif - save_and_cli(flags); + + local_irq_save(flags); /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - old_pagemask = get_pagemask(); - w = get_wired(); - set_wired (w + 1); - if (get_wired() != w + 1) { + old_ctx = read_c0_entryhi() & ASID_MASK; + old_pagemask = read_c0_pagemask(); + w = read_c0_wired(); + write_c0_wired(w + 1); + if (read_c0_wired() != w + 1) { printk("[tlbwired] No WIRED reg?\n"); return; } - set_index (w << 8); - set_pagemask (pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); + write_c0_index(w << 8); + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + BARRIER; tlb_write_indexed(); - set_entryhi(old_ctx); - set_pagemask (old_pagemask); + write_c0_entryhi(old_ctx); + write_c0_pagemask(old_pagemask); local_flush_tlb_all(); - restore_flags(flags); - return; - } + local_irq_restore(flags); + + } else if (wired < 8) { +#ifdef DEBUG_TLB + printk("[tlbwired]\n", + entrylo0, entryhi); #endif - if (wired < 8) { - __save_and_cli(flags); - old_ctx = get_entryhi() & 0xfc0; - set_entrylo0(entrylo0); - set_entryhi(entryhi); - set_index(wired); - wired++; + local_irq_save(flags); + old_ctx = read_c0_entryhi() & ASID_MASK; + write_c0_entrylo0(entrylo0); + write_c0_entryhi(entryhi); + write_c0_index(wired); + wired++; /* BARRIER */ tlb_write_indexed(); - set_entryhi(old_ctx); - local_flush_tlb_all(); - __restore_flags(flags); + write_c0_entryhi(old_ctx); + local_flush_tlb_all(); + local_irq_restore(flags); } } diff -urN linux-2.4.21-bk37/arch/mips/mm/tlb-r4k.c linux-2.4.21-bk38/arch/mips/mm/tlb-r4k.c --- linux-2.4.21-bk37/arch/mips/mm/tlb-r4k.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/tlb-r4k.c 2003-08-24 02:55:57.000000000 -0700 @@ -44,66 +44,64 @@ printk("[tlball]"); #endif - __save_and_cli(flags); + local_irq_save(flags); /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - set_entrylo0(0); - set_entrylo1(0); + old_ctx = (read_c0_entryhi() & 0xff); + write_c0_entrylo0(0); + write_c0_entrylo1(0); BARRIER; - entry = get_wired(); + entry = read_c0_wired(); /* Blast 'em all away. */ - while (entry < mips_cpu.tlbsize) { + while (entry < current_cpu_data.tlbsize) { /* * Make sure all entries differ. If they're not different * MIPS32 will take revenge ... */ - set_entryhi(KSEG0 + entry*0x2000); - set_index(entry); + write_c0_entryhi(KSEG0 + entry*0x2000); + write_c0_index(entry); BARRIER; tlb_write_indexed(); BARRIER; entry++; } BARRIER; - set_entryhi(old_ctx); - __restore_flags(flags); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); } void local_flush_tlb_mm(struct mm_struct *mm) { - if (mm->context != 0) { - unsigned long flags; + int cpu = smp_processor_id(); + if (cpu_context(cpu, mm) != 0) { #ifdef DEBUG_TLB - printk("[tlbmm<%d>]", mm->context); + printk("[tlbmm<%d>]", cpu_context(cpu, mm)); #endif - __save_and_cli(flags); - get_new_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xff); - __restore_flags(flags); + drop_mmu_context(mm,cpu); } } void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end) { - if (mm->context != 0) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, mm) != 0) { unsigned long flags; int size; #ifdef DEBUG_TLB - printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff), - start, end); + printk("[tlbrange<%02x,%08lx,%08lx>]", + cpu_asid(cpu, mm), start, end); #endif - __save_and_cli(flags); + local_irq_save(flags); size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; size = (size + 1) >> 1; - if (size <= mips_cpu.tlbsize/2) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (mm->context & 0xff); + if (size <= current_cpu_data.tlbsize/2) { + int oldpid = read_c0_entryhi() & ASID_MASK; + int newpid = cpu_asid(cpu, mm); start &= (PAGE_MASK << 1); end += ((PAGE_SIZE << 1) - 1); @@ -111,63 +109,64 @@ while (start < end) { int idx; - set_entryhi(start | newpid); + write_c0_entryhi(start | newpid); start += (PAGE_SIZE << 1); BARRIER; tlb_probe(); BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); if (idx < 0) continue; /* Make sure all entries differ. */ - set_entryhi(KSEG0 + idx*0x2000); + write_c0_entryhi(KSEG0 + idx*0x2000); BARRIER; tlb_write_indexed(); BARRIER; } - set_entryhi(oldpid); + write_c0_entryhi(oldpid); } else { - get_new_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xff); + drop_mmu_context(mm, cpu); } - __restore_flags(flags); + local_irq_restore(flags); } } void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) { - if (!vma || vma->vm_mm->context != 0) { + int cpu = smp_processor_id(); + + if (!vma || cpu_context(cpu, vma->vm_mm) != 0) { unsigned long flags; int oldpid, newpid, idx; #ifdef DEBUG_TLB - printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); + printk("[tlbpage<%d,%08lx>]", cpu_context(cpu, vma->vm_mm), + page); #endif - newpid = (vma->vm_mm->context & 0xff); + newpid = cpu_asid(cpu, vma->vm_mm); page &= (PAGE_MASK << 1); - __save_and_cli(flags); - oldpid = (get_entryhi() & 0xff); - set_entryhi(page | newpid); + local_irq_save(flags); + oldpid = (read_c0_entryhi() & 0xff); + write_c0_entryhi(page | newpid); BARRIER; tlb_probe(); BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); if(idx < 0) goto finish; /* Make sure all entries differ. */ - set_entryhi(KSEG0+idx*0x2000); + write_c0_entryhi(KSEG0+idx*0x2000); BARRIER; tlb_write_indexed(); finish: BARRIER; - set_entryhi(oldpid); - __restore_flags(flags); + write_c0_entryhi(oldpid); + local_irq_restore(flags); } } @@ -175,8 +174,7 @@ * updates the TLB with the new pte(s), and another which also checks * for the R4k "end of page" hardware bug and does the needy. */ -void update_mmu_cache(struct vm_area_struct * vma, unsigned long address, - pte_t pte) +void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) { unsigned long flags; pgd_t *pgdp; @@ -190,29 +188,36 @@ if (current->active_mm != vma->vm_mm) return; - pid = get_entryhi() & 0xff; + pid = read_c0_entryhi() & ASID_MASK; #ifdef DEBUG_TLB - if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n", - (int) (vma->vm_mm->context & 0xff), pid); + if ((pid != cpu_asid(cpu, vma->vm_mm)) || + (cpu_context(vma->vm_mm) == 0)) { + printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d " + "tlbpid=%d\n", (int) (cpu_asid(cpu, vma->vm_mm)), pid); } #endif - __save_and_cli(flags); + local_irq_save(flags); address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); + write_c0_entryhi(address | pid); pgdp = pgd_offset(vma->vm_mm, address); BARRIER; tlb_probe(); BARRIER; pmdp = pmd_offset(pgdp, address); - idx = get_index(); + idx = read_c0_index(); ptep = pte_offset(pmdp, address); BARRIER; - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); +#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) + write_c0_entrylo0(ptep->pte_high); + ptep++; + write_c0_entrylo1(ptep->pte_high); +#else + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); +#endif + write_c0_entryhi(address | pid); BARRIER; if (idx < 0) { tlb_write_random(); @@ -220,9 +225,9 @@ tlb_write_indexed(); } BARRIER; - set_entryhi(pid); + write_c0_entryhi(pid); BARRIER; - __restore_flags(flags); + local_irq_restore(flags); } #if 0 @@ -235,23 +240,23 @@ pte_t *ptep; int idx; - __save_and_cli(flags); + local_irq_save(flags); address &= (PAGE_MASK << 1); - set_entryhi(address | (get_entryhi() & 0xff)); + write_c0_entryhi(address | (read_c0_entryhi() & 0xff)); pgdp = pgd_offset(vma->vm_mm, address); tlb_probe(); pmdp = pmd_offset(pgdp, address); - idx = get_index(); + idx = read_c0_index(); ptep = pte_offset(pmdp, address); - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); BARRIER; if (idx < 0) tlb_write_random(); else tlb_write_indexed(); BARRIER; - __restore_flags(flags); + local_irq_restore(flags); } #endif @@ -263,27 +268,27 @@ unsigned long old_pagemask; unsigned long old_ctx; - __save_and_cli(flags); + local_irq_save(flags); /* Save old context and create impossible VPN2 value */ - old_ctx = get_entryhi() & 0xff; - old_pagemask = get_pagemask(); - wired = get_wired(); - set_wired(wired + 1); - set_index(wired); - BARRIER; - set_pagemask(pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); - set_entrylo1(entrylo1); + old_ctx = read_c0_entryhi() & 0xff; + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); + write_c0_wired(wired + 1); + write_c0_index(wired); + BARRIER; + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); BARRIER; tlb_write_indexed(); BARRIER; - set_entryhi(old_ctx); + write_c0_entryhi(old_ctx); BARRIER; - set_pagemask(old_pagemask); + write_c0_pagemask(old_pagemask); local_flush_tlb_all(); - __restore_flags(flags); + local_irq_restore(flags); } /* @@ -303,58 +308,60 @@ unsigned long old_pagemask; unsigned long old_ctx; - __save_and_cli(flags); + local_irq_save(flags); /* Save old context and create impossible VPN2 value */ - old_ctx = get_entryhi() & 0xff; - old_pagemask = get_pagemask(); - wired = get_wired(); + old_ctx = read_c0_entryhi() & 0xff; + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); if (--temp_tlb_entry < wired) { printk(KERN_WARNING "No TLB space left for add_temporary_entry\n"); ret = -ENOSPC; goto out; } - set_index(temp_tlb_entry); + write_c0_index(temp_tlb_entry); BARRIER; - set_pagemask(pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); - set_entrylo1(entrylo1); + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); BARRIER; tlb_write_indexed(); BARRIER; - set_entryhi(old_ctx); + write_c0_entryhi(old_ctx); BARRIER; - set_pagemask(old_pagemask); + write_c0_pagemask(old_pagemask); out: - __restore_flags(flags); + local_irq_restore(flags); return ret; } static void __init probe_tlb(unsigned long config) { - unsigned int prid, config1; + unsigned int reg; - prid = read_32bit_cp0_register(CP0_PRID) & 0xff00; - if (prid == PRID_IMP_RM7000 || !(config & (1 << 31))) + reg = read_c0_prid() & 0xff00; + if (reg == PRID_IMP_RM7000 || !(config & (1 << 31))) /* - * Not a MIPS32 complianant CPU. Config 1 register not + * Not a MIPS32 compliant CPU. Config 1 register not * supported, we assume R4k style. Cpu probing already figured * out the number of tlb entries. */ return; - config1 = read_mips32_cp0_config1(); +#if defined(CONFIG_CPU_MIPS32) || defined (CONFIG_CPU_MIPS64) + reg = read_c0_config1(); if (!((config >> 7) & 3)) panic("No MMU present"); else - mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1; + current_cpu_data.tlbsize = ((reg >> 25) & 0x3f) + 1; +#endif } void __init r4k_tlb_init(void) { - u32 config = read_32bit_cp0_register(CP0_CONFIG); + u32 config = read_c0_config(); /* * You should never change this register: @@ -364,16 +371,15 @@ * be set for 4kb pages. */ probe_tlb(config); - set_pagemask(PM_4K); - write_32bit_cp0_register(CP0_WIRED, 0); - temp_tlb_entry = mips_cpu.tlbsize - 1; + write_c0_pagemask(PM_4K); + write_c0_wired(0); + temp_tlb_entry = current_cpu_data.tlbsize - 1; local_flush_tlb_all(); - if ((mips_cpu.options & MIPS_CPU_4KEX) - && (mips_cpu.options & MIPS_CPU_4KTLB)) { - if (mips_cpu.cputype == CPU_NEVADA) + if (cpu_has_4kex && cpu_has_4ktlb) { + if (current_cpu_data.cputype == CPU_NEVADA) memcpy((void *)KSEG0, &except_vec0_nevada, 0x80); - else if (mips_cpu.cputype == CPU_R4600) + else if (current_cpu_data.cputype == CPU_R4600) memcpy((void *)KSEG0, &except_vec0_r4600, 0x80); else memcpy((void *)KSEG0, &except_vec0_r4000, 0x80); diff -urN linux-2.4.21-bk37/arch/mips/mm/tlb-sb1.c linux-2.4.21-bk38/arch/mips/mm/tlb-sb1.c --- linux-2.4.21-bk37/arch/mips/mm/tlb-sb1.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/tlb-sb1.c 2003-08-24 02:55:57.000000000 -0700 @@ -22,7 +22,7 @@ #include #include -extern char except_vec0_r4000[]; +extern char except_vec0_sb1[]; /* Dump the current entry* and pagemask registers */ static inline void dump_cur_tlb_regs(void) @@ -35,7 +35,6 @@ ".set noreorder \n" ".set mips64 \n" ".set noat \n" - " tlbr \n" " dmfc0 $1, $10 \n" " dsrl32 %0, $1, 0 \n" " sll %1, $1, 0 \n" @@ -47,13 +46,11 @@ " sll %5, $1, 0 \n" " mfc0 %6, $5 \n" ".set pop \n" - : "=r" (entryhihi), - "=r" (entryhilo), - "=r" (entrylo0hi), - "=r" (entrylo0lo), - "=r" (entrylo1hi), - "=r" (entrylo1lo), - "=r" (pagemask)); + : "=r" (entryhihi), "=r" (entryhilo), + "=r" (entrylo0hi), "=r" (entrylo0lo), + "=r" (entrylo1hi), "=r" (entrylo1lo), + "=r" (pagemask)); + printk("%08X%08X %08X%08X %08X%08X %08X", entryhihi, entryhilo, entrylo0hi, entrylo0lo, @@ -66,29 +63,25 @@ unsigned long old_ctx; unsigned long flags; int entry; - __save_and_cli(flags); - old_ctx = get_entryhi(); + local_irq_save(flags); + old_ctx = read_c0_entryhi(); printk("Current TLB registers state:\n" " EntryHi EntryLo0 EntryLo1 PageMask Index\n" "--------------------------------------------------------------------\n"); dump_cur_tlb_regs(); - printk(" %08X\n", read_32bit_cp0_register(CP0_INDEX)); + printk(" %08X\n", read_c0_index()); printk("\n\nFull TLB Dump:\n" "Idx EntryHi EntryLo0 EntryLo1 PageMask\n" "--------------------------------------------------------------\n"); - for (entry = 0; entry < mips_cpu.tlbsize; entry++) { - set_index(entry); + for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { + write_c0_index(entry); printk("\n%02i ", entry); - __asm__ __volatile__ ( - ".set push \n" - ".set mips64 \n" - " tlbr \n" - ".set pop \n"); + tlb_read(); dump_cur_tlb_regs(); } printk("\n"); - set_entryhi(old_ctx); - __restore_flags(flags); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); } void local_flush_tlb_all(void) @@ -97,18 +90,18 @@ unsigned long old_ctx; int entry; - __save_and_cli(flags); + local_irq_save(flags); /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - set_entrylo0(0); - set_entrylo1(0); - for (entry = 0; entry < mips_cpu.tlbsize; entry++) { - set_entryhi(KSEG0 + (PAGE_SIZE << 1) * entry); - set_index(entry); + old_ctx = read_c0_entryhi() & ASID_MASK; + write_c0_entrylo0(0); + write_c0_entrylo1(0); + for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { + write_c0_entryhi(KSEG0 + (PAGE_SIZE << 1) * entry); + write_c0_index(entry); tlb_write_indexed(); } - set_entryhi(old_ctx); - __restore_flags(flags); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); } @@ -126,15 +119,15 @@ long inc = 1<<24; /* 16MB */ /* Save old context and create impossible VPN2 value */ - set_entrylo0(0); - set_entrylo1(0); - for (entry = 0; entry < mips_cpu.tlbsize; entry++) { + write_c0_entrylo0(0); + write_c0_entrylo1(0); + for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { do { addr += inc; - set_entryhi(addr); + write_c0_entryhi(addr); tlb_probe(); - } while ((int)(get_index()) >= 0); - set_index(entry); + } while ((int)(read_c0_index()) >= 0); + write_c0_index(entry); tlb_write_indexed(); } /* Now that we know we're safe from collisions, we can safely flush @@ -149,79 +142,66 @@ unsigned long flags; int cpu; - __save_and_cli(flags); + local_irq_save(flags); cpu = smp_processor_id(); - if(CPU_CONTEXT(cpu, mm) != 0) { + if (cpu_context(cpu, mm) != 0) { int size; size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; size = (size + 1) >> 1; - if(size <= (mips_cpu.tlbsize/2)) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (CPU_CONTEXT(cpu, mm) & 0xff); + if (size <= (current_cpu_data.tlbsize/2)) { + int oldpid = read_c0_entryhi() & ASID_MASK; + int newpid = cpu_asid(cpu, mm); start &= (PAGE_MASK << 1); end += ((PAGE_SIZE << 1) - 1); end &= (PAGE_MASK << 1); - while(start < end) { + while (start < end) { int idx; - set_entryhi(start | newpid); + write_c0_entryhi(start | newpid); start += (PAGE_SIZE << 1); tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0 + (idx << (PAGE_SHIFT+1))); - if(idx < 0) + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + write_c0_entryhi(KSEG0 + (idx << (PAGE_SHIFT+1))); + if (idx < 0) continue; tlb_write_indexed(); } - set_entryhi(oldpid); + write_c0_entryhi(oldpid); } else { - get_new_mmu_context(mm, cpu); - if (mm == current->active_mm) - set_entryhi(CPU_CONTEXT(cpu, mm) & 0xff); + drop_mmu_context(mm, cpu); } } - __restore_flags(flags); + local_irq_restore(flags); } void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) { unsigned long flags; - -#ifdef CONFIG_SMP - /* - * This variable is eliminated from CPU_CONTEXT() if SMP isn't defined, - * so conditional it to get rid of silly "unused variable" compiler - * complaints - */ int cpu = smp_processor_id(); -#endif - __save_and_cli(flags); - if (CPU_CONTEXT(cpu, vma->vm_mm) != 0) { + local_irq_save(flags); + if (cpu_context(cpu, vma->vm_mm) != 0) { int oldpid, newpid, idx; -#ifdef DEBUG_TLB - printk("[tlbpage<%d,%08lx>]", CPU_CONTEXT(cpu, vma->vm_mm), page); -#endif - newpid = (CPU_CONTEXT(cpu, vma->vm_mm) & 0xff); + newpid = cpu_asid(cpu, vma->vm_mm); page &= (PAGE_MASK << 1); - oldpid = (get_entryhi() & 0xff); - set_entryhi (page | newpid); + oldpid = read_c0_entryhi() & ASID_MASK; + write_c0_entryhi(page | newpid); tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - if(idx < 0) + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + if (idx < 0) goto finish; /* Make sure all entries differ. */ - set_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1))); + write_c0_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1))); tlb_write_indexed(); finish: - set_entryhi(oldpid); + write_c0_entryhi(oldpid); } - __restore_flags(flags); + local_irq_restore(flags); } @@ -229,23 +209,16 @@ these entries, we just bump the asid. */ void local_flush_tlb_mm(struct mm_struct *mm) { - unsigned long flags; - int cpu; - __save_and_cli(flags); - cpu = smp_processor_id(); - if (CPU_CONTEXT(cpu, mm) != 0) { - get_new_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) { - set_entryhi(CPU_CONTEXT(cpu, mm) & 0xff); - } + int cpu = smp_processor_id(); + + if (cpu_context(cpu, mm) != 0) { + drop_mmu_context(mm, cpu); } - __restore_flags(flags); } /* Stolen from mips32 routines */ -void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, - pte_t pte) +void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) { unsigned long flags; pgd_t *pgdp; @@ -259,35 +232,24 @@ if (current->active_mm != vma->vm_mm) return; - __save_and_cli(flags); - - - pid = get_entryhi() & 0xff; - -#ifdef DEBUG_TLB - if((pid != (CPU_CONTEXT(cpu, vma->vm_mm) & 0xff)) || (CPU_CONTEXT(cpu, vma->vm_mm) == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n", - (int) (CPU_CONTEXT(cpu, vma->vm_mm) & 0xff), pid); - } -#endif + local_irq_save(flags); + pid = read_c0_entryhi() & ASID_MASK; address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); + write_c0_entryhi(address | (pid)); pgdp = pgd_offset(vma->vm_mm, address); tlb_probe(); pmdp = pmd_offset(pgdp, address); - idx = get_index(); + idx = read_c0_index(); ptep = pte_offset(pmdp, address); - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); - if(idx < 0) { + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); + if (idx < 0) { tlb_write_random(); } else { tlb_write_indexed(); } - set_entryhi(pid); - __restore_flags(flags); + local_irq_restore(flags); } /* @@ -297,10 +259,7 @@ */ void sb1_tlb_init(void) { - u32 config1; - - config1 = read_mips32_cp0_config1(); - mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1; + write_c0_pagemask(PM_4K); /* * We don't know what state the firmware left the TLB's in, so this is @@ -309,6 +268,6 @@ */ sb1_sanitize_tlb(); - memcpy((void *)KSEG0, except_vec0_r4000, 0x80); + memcpy((void *)KSEG0, except_vec0_sb1, 0x80); flush_icache_range(KSEG0, KSEG0 + 0x80); } diff -urN linux-2.4.21-bk37/arch/mips/mm/tlbex-mips32.S linux-2.4.21-bk38/arch/mips/mm/tlbex-mips32.S --- linux-2.4.21-bk37/arch/mips/mm/tlbex-mips32.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/tlbex-mips32.S 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,329 @@ +/* + * TLB exception handling code for MIPS32 CPUs. + * + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse + * + * Multi-cpu abstraction and reworking: + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + * + * Pete Popov, ppopov@pacbell.net + * Added 36 bit phys address support. + * Copyright (C) 2002 MontaVista Software, Inc. + */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TLB_OPTIMIZE /* If you are paranoid, disable this. */ + +#ifdef CONFIG_64BIT_PHYS_ADDR + +/* We really only support 36 bit physical addresses on MIPS32 */ +#define PTE_L lw +#define PTE_S sw +#define PTE_SRL srl +#define P_MTC0 mtc0 +#define PTE_HALF 4 /* pte_high contains pre-shifted, ready to go entry */ +#define PTE_SIZE 8 +#define PTEP_INDX_MSK 0xff0 +#define PTE_INDX_MSK 0xff8 +#define PTE_INDX_SHIFT 9 +#define CONVERT_PTE(pte) +#define PTE_MAKEWRITE_HIGH(pte, ptr) \ + lw pte, 4(ptr); \ + ori pte, (_PAGE_VALID | _PAGE_DIRTY); \ + sw pte, 4(ptr); \ + lw pte, 0(ptr); + +#define PTE_MAKEVALID_HIGH(pte, ptr) \ + lw pte, 4(ptr); \ + ori pte, pte, _PAGE_VALID; \ + sw pte, 4(ptr); \ + lw pte, 0(ptr); + +#else + +#define PTE_L lw +#define PTE_S sw +#define PTE_SRL srl +#define P_MTC0 mtc0 +#define PTE_HALF 0 +#define PTE_SIZE 4 +#define PTEP_INDX_MSK 0xff8 +#define PTE_INDX_MSK 0xffc +#define PTE_INDX_SHIFT 10 +#define CONVERT_PTE(pte) srl pte, pte, 6 +#define PTE_MAKEWRITE_HIGH(pte, ptr) +#define PTE_MAKEVALID_HIGH(pte, ptr) + +#endif /* CONFIG_64BIT_PHYS_ADDR */ + + __INIT + +#ifdef CONFIG_64BIT_PHYS_ADDR +#define GET_PTE_OFF(reg) +#else +#define GET_PTE_OFF(reg) srl reg, reg, 1 +#endif + +/* + * These handlers much be written in a relocatable manner + * because based upon the cpu type an arbitrary one of the + * following pieces of code will be copied to the KSEG0 + * vector location. + */ + /* TLB refill, EXL == 0, MIPS32 version */ + .set noreorder + .set noat + LEAF(except_vec0_r4000) + .set mips3 +#ifdef CONFIG_SMP + mfc0 k1, CP0_CONTEXT + la k0, pgd_current + srl k1, 23 + sll k1, 2 # log2(sizeof(pgd_t) + addu k1, k0, k1 + lw k1, (k1) +#else + lw k1, pgd_current # get pgd pointer +#endif + nop + mfc0 k0, CP0_BADVADDR # Get faulting address + srl k0, k0, PGDIR_SHIFT # get pgd only bits + + sll k0, k0, 2 + addu k1, k1, k0 # add in pgd offset + mfc0 k0, CP0_CONTEXT # get context reg + lw k1, (k1) + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 # add in offset + + PTE_L k0, PTE_HALF(k1) # get even pte + CONVERT_PTE(k0) + P_MTC0 k0, CP0_ENTRYLO0 # load it + PTE_L k1, (PTE_HALF+PTE_SIZE)(k1) # get odd pte + CONVERT_PTE(k1) + P_MTC0 k1, CP0_ENTRYLO1 # load it + b 1f + tlbwr # write random tlb entry +1: + nop + eret # return from trap + END(except_vec0_r4000) + +/* + * These are here to avoid putting ifdefs in tlb-r4k.c + */ + .set noreorder + .set noat + LEAF(except_vec0_nevada) + .set mips3 + PANIC("Nevada Exception Vec 0 called") + END(except_vec0_nevada) + + .set noreorder + .set noat + LEAF(except_vec0_r4600) + .set mips3 + PANIC("R4600 Exception Vec 0 called") + END(except_vec0_r4600) + + __FINIT + +/* + * ABUSE of CPP macros 101. + * + * After this macro runs, the pte faulted on is + * in register PTE, a ptr into the table in which + * the pte belongs is in PTR. + */ + +#ifdef CONFIG_SMP +#define GET_PGD(scratch, ptr) \ + mfc0 ptr, CP0_CONTEXT; \ + la scratch, pgd_current;\ + srl ptr, 23; \ + sll ptr, 2; \ + addu ptr, scratch, ptr; \ + lw ptr, (ptr); +#else +#define GET_PGD(scratch, ptr) \ + lw ptr, pgd_current; +#endif + +#define LOAD_PTE(pte, ptr) \ + GET_PGD(pte, ptr) \ + mfc0 pte, CP0_BADVADDR; \ + srl pte, pte, PGDIR_SHIFT; \ + sll pte, pte, 2; \ + addu ptr, ptr, pte; \ + mfc0 pte, CP0_BADVADDR; \ + lw ptr, (ptr); \ + srl pte, pte, PTE_INDX_SHIFT; \ + and pte, pte, PTE_INDX_MSK; \ + addu ptr, ptr, pte; \ + PTE_L pte, (ptr); + + /* This places the even/odd pte pair in the page + * table at PTR into ENTRYLO0 and ENTRYLO1 using + * TMP as a scratch register. + */ +#define PTE_RELOAD(ptr, tmp) \ + ori ptr, ptr, PTE_SIZE; \ + xori ptr, ptr, PTE_SIZE; \ + PTE_L tmp, (PTE_HALF+PTE_SIZE)(ptr); \ + CONVERT_PTE(tmp); \ + P_MTC0 tmp, CP0_ENTRYLO1; \ + PTE_L ptr, PTE_HALF(ptr); \ + CONVERT_PTE(ptr); \ + P_MTC0 ptr, CP0_ENTRYLO0; + +#define DO_FAULT(write) \ + .set noat; \ + SAVE_ALL; \ + mfc0 a2, CP0_BADVADDR; \ + STI; \ + .set at; \ + move a0, sp; \ + jal do_page_fault; \ + li a1, write; \ + j ret_from_exception; \ + nop; \ + .set noat; + + /* Check is PTE is present, if not then jump to LABEL. + * PTR points to the page table where this PTE is located, + * when the macro is done executing PTE will be restored + * with it's original value. + */ +#define PTE_PRESENT(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + bnez pte, label; \ + PTE_L pte, (ptr); + + /* Make PTE valid, store result in PTR. */ +#define PTE_MAKEVALID(pte, ptr) \ + ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ + PTE_S pte, (ptr); + + /* Check if PTE can be written to, if not branch to LABEL. + * Regardless restore PTE with value from PTR when done. + */ +#define PTE_WRITABLE(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + bnez pte, label; \ + PTE_L pte, (ptr); + + /* Make PTE writable, update software status bits as well, + * then store at PTR. + */ +#define PTE_MAKEWRITE(pte, ptr) \ + ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ + _PAGE_VALID | _PAGE_DIRTY); \ + PTE_S pte, (ptr); + + .set noreorder + +#define R5K_HAZARD nop + + .align 5 + NESTED(handle_tlbl, PT_SIZE, sp) + .set noat +invalid_tlbl: +#ifdef TLB_OPTIMIZE + /* Test present bit in entry. */ + LOAD_PTE(k0, k1) + R5K_HAZARD + tlbp + PTE_PRESENT(k0, k1, nopage_tlbl) + PTE_MAKEVALID_HIGH(k0, k1) + PTE_MAKEVALID(k0, k1) + PTE_RELOAD(k1, k0) + nop + b 1f + tlbwi +1: + nop + .set mips3 + eret + .set mips0 +#endif + +nopage_tlbl: + DO_FAULT(0) + END(handle_tlbl) + + .align 5 + NESTED(handle_tlbs, PT_SIZE, sp) + .set noat +#ifdef TLB_OPTIMIZE + .set mips3 + li k0,0 + LOAD_PTE(k0, k1) + R5K_HAZARD + tlbp # find faulting entry + PTE_WRITABLE(k0, k1, nopage_tlbs) + PTE_MAKEWRITE(k0, k1) + PTE_MAKEWRITE_HIGH(k0, k1) + PTE_RELOAD(k1, k0) + nop + b 1f + tlbwi +1: + nop + .set mips3 + eret + .set mips0 +#endif + +nopage_tlbs: + DO_FAULT(1) + END(handle_tlbs) + + .align 5 + NESTED(handle_mod, PT_SIZE, sp) + .set noat +#ifdef TLB_OPTIMIZE + .set mips3 + LOAD_PTE(k0, k1) + R5K_HAZARD + tlbp # find faulting entry + andi k0, k0, _PAGE_WRITE + beqz k0, nowrite_mod + PTE_L k0, (k1) + + /* Present and writable bits set, set accessed and dirty bits. */ + PTE_MAKEWRITE(k0, k1) + PTE_MAKEWRITE_HIGH(k0, k1) + /* Now reload the entry into the tlb. */ + PTE_RELOAD(k1, k0) + nop + b 1f + tlbwi +1: + nop + .set mips3 + eret + .set mips0 +#endif + +nowrite_mod: + DO_FAULT(1) + END(handle_mod) + diff -urN linux-2.4.21-bk37/arch/mips/mm/tlbex-r4k.S linux-2.4.21-bk38/arch/mips/mm/tlbex-r4k.S --- linux-2.4.21-bk37/arch/mips/mm/tlbex-r4k.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/tlbex-r4k.S 2003-08-24 02:55:57.000000000 -0700 @@ -23,6 +23,7 @@ #include #include #include +#include #define TLB_OPTIMIZE /* If you are paranoid, disable this. */ @@ -46,6 +47,100 @@ #define PTE_INDX_SHIFT 10 #endif +/* + * ABUSE of CPP macros 101. + * + * After this macro runs, the pte faulted on is + * in register PTE, a ptr into the table in which + * the pte belongs is in PTR. + */ + +#ifdef CONFIG_SMP +#define GET_PGD(scratch, ptr) \ + mfc0 ptr, CP0_CONTEXT; \ + la scratch, pgd_current;\ + srl ptr, 23; \ + sll ptr, 2; \ + addu ptr, scratch, ptr; \ + lw ptr, (ptr); +#else +#define GET_PGD(scratch, ptr) \ + lw ptr, pgd_current; +#endif + +#define LOAD_PTE(pte, ptr) \ + GET_PGD(pte, ptr) \ + mfc0 pte, CP0_BADVADDR; \ + srl pte, pte, _PGDIR_SHIFT; \ + sll pte, pte, 2; \ + addu ptr, ptr, pte; \ + mfc0 pte, CP0_BADVADDR; \ + lw ptr, (ptr); \ + srl pte, pte, PTE_INDX_SHIFT; \ + and pte, pte, PTE_INDX_MSK; \ + addu ptr, ptr, pte; \ + PTE_L pte, (ptr); + + /* This places the even/odd pte pair in the page + * table at PTR into ENTRYLO0 and ENTRYLO1 using + * TMP as a scratch register. + */ +#define PTE_RELOAD(ptr, tmp) \ + ori ptr, ptr, PTE_SIZE; \ + xori ptr, ptr, PTE_SIZE; \ + PTE_L tmp, PTE_SIZE(ptr); \ + PTE_L ptr, 0(ptr); \ + PTE_SRL tmp, tmp, 6; \ + P_MTC0 tmp, CP0_ENTRYLO1; \ + PTE_SRL ptr, ptr, 6; \ + P_MTC0 ptr, CP0_ENTRYLO0; + +#define DO_FAULT(write) \ + .set noat; \ + SAVE_ALL; \ + mfc0 a2, CP0_BADVADDR; \ + KMODE; \ + .set at; \ + move a0, sp; \ + jal do_page_fault; \ + li a1, write; \ + j ret_from_exception; \ + nop; \ + .set noat; + + /* Check is PTE is present, if not then jump to LABEL. + * PTR points to the page table where this PTE is located, + * when the macro is done executing PTE will be restored + * with it's original value. + */ +#define PTE_PRESENT(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + bnez pte, label; \ + PTE_L pte, (ptr); + + /* Make PTE valid, store result in PTR. */ +#define PTE_MAKEVALID(pte, ptr) \ + ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ + PTE_S pte, (ptr); + + /* Check if PTE can be written to, if not branch to LABEL. + * Regardless restore PTE with value from PTR when done. + */ +#define PTE_WRITABLE(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + bnez pte, label; \ + PTE_L pte, (ptr); + + /* Make PTE writable, update software status bits as well, + * then store at PTR. + */ +#define PTE_MAKEWRITE(pte, ptr) \ + ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ + _PAGE_VALID | _PAGE_DIRTY); \ + PTE_S pte, (ptr); + __INIT #ifdef CONFIG_64BIT_PHYS_ADDR @@ -67,16 +162,7 @@ .set noat LEAF(except_vec0_r4000) .set mips3 -#ifdef CONFIG_SMP - mfc0 k1, CP0_CONTEXT - la k0, pgd_current - srl k1, 23 - sll k1, 2 # log2(sizeof(pgd_t) - addu k1, k0, k1 - lw k1, (k1) -#else - lw k1, pgd_current # get pgd pointer -#endif + GET_PGD(k0, k1) # get pgd pointer mfc0 k0, CP0_BADVADDR # Get faulting address srl k0, k0, _PGDIR_SHIFT # get pgd only bits @@ -103,16 +189,14 @@ /* TLB refill, EXL == 0, R4600 version */ LEAF(except_vec0_r4600) .set mips3 + GET_PGD(k0, k1) # get pgd pointer mfc0 k0, CP0_BADVADDR srl k0, k0, _PGDIR_SHIFT - lw k1, pgd_current # get pgd pointer sll k0, k0, 2 # log2(sizeof(pgd_t) addu k1, k1, k0 mfc0 k0, CP0_CONTEXT lw k1, (k1) -#ifndef CONFIG_64BIT_PHYS_ADDR - srl k0, k0, 1 -#endif + GET_PTE_OFF(k0) # get pte offset and k0, k0, PTEP_INDX_MSK addu k1, k1, k0 PTE_L k0, 0(k1) @@ -148,9 +232,7 @@ addu k1, k1, k0 # add in pgd offset lw k1, (k1) mfc0 k0, CP0_CONTEXT # get context reg -#ifndef CONFIG_64BIT_PHYS_ADDR - srl k0, k0, 1 # get pte offset -#endif + GET_PTE_OFF(k0) # get pte offset and k0, k0, PTEP_INDX_MSK addu k1, k1, k0 # add in offset PTE_L k0, 0(k1) # get even pte @@ -166,12 +248,41 @@ eret # return from trap END(except_vec0_nevada) + /* TLB refill, EXL == 0, SB1 with M3 errata handling version */ + LEAF(except_vec0_sb1) +#if BCM1250_M3_WAR + mfc0 k0, CP0_BADVADDR + mfc0 k1, CP0_ENTRYHI + xor k0, k1 + srl k0, k0, PAGE_SHIFT+1 + bnez k0, 1f +#endif + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR # Get faulting address + srl k0, k0, _PGDIR_SHIFT # get pgd only bits + sll k0, k0, 2 + addu k1, k1, k0 # add in pgd offset + mfc0 k0, CP0_CONTEXT # get context reg + lw k1, (k1) + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 # add in offset + PTE_L k0, 0(k1) # get even pte + PTE_L k1, PTE_SIZE(k1) # get odd pte + PTE_SRL k0, k0, 6 # convert to entrylo0 + P_MTC0 k0, CP0_ENTRYLO0 # load it + PTE_SRL k1, k1, 6 # convert to entrylo1 + P_MTC0 k1, CP0_ENTRYLO1 # load it + tlbwr # write random tlb entry +1: eret # return from trap + END(except_vec0_sb1) + /* TLB refill, EXL == 0, R4[40]00/R5000 badvaddr hwbug version */ LEAF(except_vec0_r45k_bvahwbug) .set mips3 + GET_PGD(k0, k1) # get pgd pointer mfc0 k0, CP0_BADVADDR srl k0, k0, _PGDIR_SHIFT - lw k1, pgd_current # get pgd pointer sll k0, k0, 2 # log2(sizeof(pgd_t) addu k1, k1, k0 mfc0 k0, CP0_CONTEXT @@ -201,9 +312,9 @@ /* TLB refill, EXL == 0, R4000 MP badvaddr hwbug version */ LEAF(except_vec0_r4k_mphwbug) .set mips3 + GET_PGD(k0, k1) # get pgd pointer mfc0 k0, CP0_BADVADDR srl k0, k0, _PGDIR_SHIFT - lw k1, pgd_current # get pgd pointer sll k0, k0, 2 # log2(sizeof(pgd_t) addu k1, k1, k0 mfc0 k0, CP0_CONTEXT @@ -233,9 +344,9 @@ /* TLB refill, EXL == 0, R4000 UP 250MHZ entrylo[01] hwbug version */ LEAF(except_vec0_r4k_250MHZhwbug) .set mips3 + GET_PGD(k0, k1) # get pgd pointer mfc0 k0, CP0_BADVADDR srl k0, k0, _PGDIR_SHIFT - lw k1, pgd_current # get pgd pointer sll k0, k0, 2 # log2(sizeof(pgd_t) addu k1, k1, k0 mfc0 k0, CP0_CONTEXT @@ -264,9 +375,9 @@ /* TLB refill, EXL == 0, R4000 MP 250MHZ entrylo[01]+badvaddr bug version */ LEAF(except_vec0_r4k_MP250MHZhwbug) .set mips3 + GET_PGD(k0, k1) # get pgd pointer mfc0 k0, CP0_BADVADDR srl k0, k0, _PGDIR_SHIFT - lw k1, pgd_current # get pgd pointer sll k0, k0, 2 # log2(sizeof(pgd_t) addu k1, k1, k0 mfc0 k0, CP0_CONTEXT @@ -295,104 +406,8 @@ END(except_vec0_r4k_MP250MHZhwbug) #endif - - __FINIT -/* - * ABUSE of CPP macros 101. - * - * After this macro runs, the pte faulted on is - * in register PTE, a ptr into the table in which - * the pte belongs is in PTR. - */ - -#ifdef CONFIG_SMP -#define GET_PGD(scratch, ptr) \ - mfc0 ptr, CP0_CONTEXT; \ - la scratch, pgd_current;\ - srl ptr, 23; \ - sll ptr, 2; \ - addu ptr, scratch, ptr; \ - lw ptr, (ptr); -#else -#define GET_PGD(scratch, ptr) \ - lw ptr, pgd_current; -#endif - -#define LOAD_PTE(pte, ptr) \ - GET_PGD(pte, ptr) \ - mfc0 pte, CP0_BADVADDR; \ - srl pte, pte, _PGDIR_SHIFT; \ - sll pte, pte, 2; \ - addu ptr, ptr, pte; \ - mfc0 pte, CP0_BADVADDR; \ - lw ptr, (ptr); \ - srl pte, pte, PTE_INDX_SHIFT; \ - and pte, pte, PTE_INDX_MSK; \ - addu ptr, ptr, pte; \ - PTE_L pte, (ptr); - - /* This places the even/odd pte pair in the page - * table at PTR into ENTRYLO0 and ENTRYLO1 using - * TMP as a scratch register. - */ -#define PTE_RELOAD(ptr, tmp) \ - ori ptr, ptr, PTE_SIZE; \ - xori ptr, ptr, PTE_SIZE; \ - PTE_L tmp, PTE_SIZE(ptr); \ - PTE_L ptr, 0(ptr); \ - PTE_SRL tmp, tmp, 6; \ - P_MTC0 tmp, CP0_ENTRYLO1; \ - PTE_SRL ptr, ptr, 6; \ - P_MTC0 ptr, CP0_ENTRYLO0; - -#define DO_FAULT(write) \ - .set noat; \ - SAVE_ALL; \ - mfc0 a2, CP0_BADVADDR; \ - KMODE; \ - .set at; \ - move a0, sp; \ - jal do_page_fault; \ - li a1, write; \ - j ret_from_exception; \ - nop; \ - .set noat; - - /* Check is PTE is present, if not then jump to LABEL. - * PTR points to the page table where this PTE is located, - * when the macro is done executing PTE will be restored - * with it's original value. - */ -#define PTE_PRESENT(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - bnez pte, label; \ - PTE_L pte, (ptr); - - /* Make PTE valid, store result in PTR. */ -#define PTE_MAKEVALID(pte, ptr) \ - ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ - PTE_S pte, (ptr); - - /* Check if PTE can be written to, if not branch to LABEL. - * Regardless restore PTE with value from PTR when done. - */ -#define PTE_WRITABLE(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - bnez pte, label; \ - PTE_L pte, (ptr); - - /* Make PTE writable, update software status bits as well, - * then store at PTR. - */ -#define PTE_MAKEWRITE(pte, ptr) \ - ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ - _PAGE_VALID | _PAGE_DIRTY); \ - PTE_S pte, (ptr); - .set noreorder /* @@ -424,6 +439,18 @@ .align 5 NESTED(handle_tlbl, PT_SIZE, sp) .set noat +#if BCM1250_M3_WAR + mfc0 k0, CP0_BADVADDR + mfc0 k1, CP0_ENTRYHI + xor k0, k1 + srl k0, k0, PAGE_SHIFT+1 + beqz k0, 1f + nop + .set mips3 + eret + .set mips0 +1: +#endif invalid_tlbl: #ifdef TLB_OPTIMIZE /* Test present bit in entry. */ diff -urN linux-2.4.21-bk37/arch/mips/mm/umap.c linux-2.4.21-bk38/arch/mips/mm/umap.c --- linux-2.4.21-bk37/arch/mips/mm/umap.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/mm/umap.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,218 +0,0 @@ -/* - * (C) Copyright 1994 Linus Torvalds - * - * Changes: - * - * Modified from Linus source to removing active mappings from any - * task. This is required for implementing the virtual graphics - * interface for direct rendering on the SGI - miguel. - * - * Added a routine to map a vmalloc()ed area into user space, this one - * is required by the /dev/shmiq driver - miguel. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static inline void -remove_mapping_pte_range (pmd_t *pmd, unsigned long address, unsigned long size) -{ - pte_t *pte; - unsigned long end; - - if (pmd_none (*pmd)) - return; - if (pmd_bad (*pmd)){ - printk ("remove_graphics_pte_range: bad pmd (%08lx)\n", pmd_val (*pmd)); - pmd_clear (pmd); - return; - } - pte = pte_offset (pmd, address); - address &= ~PMD_MASK; - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; - do { - pte_t entry = *pte; - if (pte_present (entry)) - set_pte (pte, pte_modify (entry, PAGE_NONE)); - address += PAGE_SIZE; - pte++; - } while (address < end); - -} - -static inline void -remove_mapping_pmd_range (pgd_t *pgd, unsigned long address, unsigned long size) -{ - pmd_t *pmd; - unsigned long end; - - if (pgd_none (*pgd)) - return; - - if (pgd_bad (*pgd)){ - printk ("remove_graphics_pmd_range: bad pgd (%08lx)\n", pgd_val (*pgd)); - pgd_clear (pgd); - return; - } - pmd = pmd_offset (pgd, address); - address &= ~PGDIR_MASK; - end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - do { - remove_mapping_pte_range (pmd, address, end - address); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address < end); - -} - -/* - * This routine is called from the page fault handler to remove a - * range of active mappings at this point - */ -void -remove_mapping (struct task_struct *task, unsigned long start, unsigned long end) -{ - unsigned long beg = start; - pgd_t *dir; - - down_write (&task->mm->mmap_sem); - dir = pgd_offset (task->mm, start); - flush_cache_range (task->mm, beg, end); - while (start < end){ - remove_mapping_pmd_range (dir, start, end - start); - start = (start + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } - local_flush_tlb_range (task->mm, beg, end); - up_write (&task->mm->mmap_sem); -} - -EXPORT_SYMBOL(remove_mapping); - -void *vmalloc_uncached (unsigned long size) -{ - return __vmalloc (size, GFP_KERNEL | __GFP_HIGHMEM, - PAGE_KERNEL_UNCACHED); -} - -static inline void free_pte(pte_t page) -{ - if (pte_present(page)) { - struct page *ptpage = pte_page(page); - if ((!VALID_PAGE(ptpage)) || PageReserved(ptpage)) - return; - __free_page(ptpage); - if (current->mm->rss <= 0) - return; - current->mm->rss--; - return; - } - swap_free(pte_to_swp_entry(page)); -} - -static inline void forget_pte(pte_t page) -{ - if (!pte_none(page)) { - printk("forget_pte: old mapping existed!\n"); - free_pte(page); - } -} - -/* - * maps a range of vmalloc()ed memory into the requested pages. the old - * mappings are removed. - */ -static inline void -vmap_pte_range (pte_t *pte, unsigned long address, unsigned long size, unsigned long vaddr) -{ - unsigned long end; - pgd_t *vdir; - pmd_t *vpmd; - pte_t *vpte; - - address &= ~PMD_MASK; - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; - do { - pte_t oldpage = *pte; - struct page * page; - pte_clear(pte); - - vdir = pgd_offset_k (vaddr); - vpmd = pmd_offset (vdir, vaddr); - vpte = pte_offset (vpmd, vaddr); - page = pte_page (*vpte); - - set_pte(pte, mk_pte(page, PAGE_USERIO)); - forget_pte(oldpage); - address += PAGE_SIZE; - vaddr += PAGE_SIZE; - pte++; - } while (address < end); -} - -static inline int -vmap_pmd_range (pmd_t *pmd, unsigned long address, unsigned long size, unsigned long vaddr) -{ - unsigned long end; - - address &= ~PGDIR_MASK; - end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - vaddr -= address; - do { - pte_t * pte = pte_alloc(current->mm, pmd, address); - if (!pte) - return -ENOMEM; - vmap_pte_range(pte, address, end - address, address + vaddr); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address < end); - return 0; -} - -int -vmap_page_range (unsigned long from, unsigned long size, unsigned long vaddr) -{ - int error = 0; - pgd_t * dir; - unsigned long beg = from; - unsigned long end = from + size; - - vaddr -= from; - dir = pgd_offset(current->mm, from); - flush_cache_range(current->mm, beg, end); - while (from < end) { - pmd_t *pmd = pmd_alloc(current->mm, dir, from); - error = -ENOMEM; - if (!pmd) - break; - error = vmap_pmd_range(pmd, from, end - from, vaddr + from); - if (error) - break; - from = (from + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } - local_flush_tlb_range(current->mm, beg, end); - return error; -} diff -urN linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/Makefile linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/Makefile --- linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,18 @@ +# +# Makefile for Momentum Computer's Ocelot-C and -CS boards. +# +# Note! Dependencies are done automagically by 'make dep', which also +# 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:= ocelot_c.o + +obj-y += mv-irq.o cpci-irq.o uart-irq.o int-handler.o irq.o +obj-y += pci-irq.o pci.o prom.o reset.o setup.o + +obj-$(CONFIG_KGDB) += dbg_io.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/cpci-irq.c linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/cpci-irq.c --- linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/cpci-irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/cpci-irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,154 @@ +/* + * Copyright 2002 Momentum Computer + * Author: mdharm@momenco.com + * + * arch/mips/momentum/ocelot_c/cpci-irq.c + * Interrupt routines for cpci. Interrupt numbers are assigned from + * CPCI_IRQ_BASE to CPCI_IRQ_BASE+8 (8 interrupt sources). + * + * Note that the high-level software will need to be careful about using + * these interrupts. If this board is asserting a cPCI interrupt, it will + * also see the asserted interrupt. Care must be taken to avoid an + * interrupt flood. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ocelot_c_fpga.h" + +#define CPCI_IRQ_BASE 8 + +static inline int ls1bit8(unsigned int x) +{ + int b = 7, s; + + s = 4; if (((unsigned char)(x << 4)) == 0) s = 0; b -= s; x <<= s; + s = 2; if (((unsigned char)(x << 2)) == 0) s = 0; b -= s; x <<= s; + s = 1; if (((unsigned char)(x << 1)) == 0) s = 0; b -= s; + + return b; +} + +/* mask off an interrupt -- 0 is enable, 1 is disable */ +static inline void mask_cpci_irq(unsigned int irq) +{ + uint32_t value; + + value = OCELOT_FPGA_READ(INTMASK); + value |= 1 << (irq - CPCI_IRQ_BASE); + OCELOT_FPGA_WRITE(value, INTMASK); + + /* read the value back to assure that it's really been written */ + value = OCELOT_FPGA_READ(INTMASK); +} + +/* unmask an interrupt -- 0 is enable, 1 is disable */ +static inline void unmask_cpci_irq(unsigned int irq) +{ + uint32_t value; + + value = OCELOT_FPGA_READ(INTMASK); + value &= ~(1 << (irq - CPCI_IRQ_BASE)); + OCELOT_FPGA_WRITE(value, INTMASK); + + /* read the value back to assure that it's really been written */ + value = OCELOT_FPGA_READ(INTMASK); +} + +/* + * Enables the IRQ in the FPGA + */ +static void enable_cpci_irq(unsigned int irq) +{ + unmask_cpci_irq(irq); +} + +/* + * Initialize the IRQ in the FPGA + */ +static unsigned int startup_cpci_irq(unsigned int irq) +{ + unmask_cpci_irq(irq); + return 0; +} + +/* + * Disables the IRQ in the FPGA + */ +static void disable_cpci_irq(unsigned int irq) +{ + mask_cpci_irq(irq); +} + +/* + * Masks and ACKs an IRQ + */ +static void mask_and_ack_cpci_irq(unsigned int irq) +{ + mask_cpci_irq(irq); +} + +/* + * End IRQ processing + */ +static void end_cpci_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + unmask_cpci_irq(irq); +} + +/* + * Interrupt handler for interrupts coming from the FPGA chip. + * It could be built in ethernet ports etc... + */ +void ll_cpci_irq(struct pt_regs *regs) +{ + unsigned int irq_src, irq_mask; + + /* read the interrupt status registers */ + irq_src = OCELOT_FPGA_READ(INTSTAT); + irq_mask = OCELOT_FPGA_READ(INTMASK); + + /* mask for just the interrupts we want */ + irq_src &= ~irq_mask; + + do_IRQ(ls1bit8(irq_src) + CPCI_IRQ_BASE, regs); +} + +#define shutdown_cpci_irq disable_cpci_irq + +struct hw_interrupt_type cpci_irq_type = { + "CPCI/FPGA", + startup_cpci_irq, + shutdown_cpci_irq, + enable_cpci_irq, + disable_cpci_irq, + mask_and_ack_cpci_irq, + end_cpci_irq, + NULL +}; + +void cpci_irq_init(void) +{ + int i; + + /* Reset irq handlers pointers to NULL */ + for (i = CPCI_IRQ_BASE; i < (CPCI_IRQ_BASE + 8); i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 2; + irq_desc[i].handler = &cpci_irq_type; + } +} diff -urN linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/dbg_io.c linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/dbg_io.c --- linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/dbg_io.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/dbg_io.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,126 @@ +#include + +#if defined(CONFIG_KGDB) + +#include /* For the serial port location and base baud */ + +/* --- CONFIG --- */ + +typedef unsigned char uint8; +typedef unsigned int uint32; + +/* --- END OF CONFIG --- */ + +#define UART16550_BAUD_2400 2400 +#define UART16550_BAUD_4800 4800 +#define UART16550_BAUD_9600 9600 +#define UART16550_BAUD_19200 19200 +#define UART16550_BAUD_38400 38400 +#define UART16550_BAUD_57600 57600 +#define UART16550_BAUD_115200 115200 + +#define UART16550_PARITY_NONE 0 +#define UART16550_PARITY_ODD 0x08 +#define UART16550_PARITY_EVEN 0x18 +#define UART16550_PARITY_MARK 0x28 +#define UART16550_PARITY_SPACE 0x38 + +#define UART16550_DATA_5BIT 0x0 +#define UART16550_DATA_6BIT 0x1 +#define UART16550_DATA_7BIT 0x2 +#define UART16550_DATA_8BIT 0x3 + +#define UART16550_STOP_1BIT 0x0 +#define UART16550_STOP_2BIT 0x4 + +/* ----------------------------------------------------- */ + +/* === CONFIG === */ + +/* [jsun] we use the second serial port for kdb */ +#define BASE OCELOT_SERIAL1_BASE +#define MAX_BAUD OCELOT_BASE_BAUD + +/* === END OF CONFIG === */ + +#define REG_OFFSET 4 + +/* register offset */ +#define OFS_RCV_BUFFER 0 +#define OFS_TRANS_HOLD 0 +#define OFS_SEND_BUFFER 0 +#define OFS_INTR_ENABLE (1*REG_OFFSET) +#define OFS_INTR_ID (2*REG_OFFSET) +#define OFS_DATA_FORMAT (3*REG_OFFSET) +#define OFS_LINE_CONTROL (3*REG_OFFSET) +#define OFS_MODEM_CONTROL (4*REG_OFFSET) +#define OFS_RS232_OUTPUT (4*REG_OFFSET) +#define OFS_LINE_STATUS (5*REG_OFFSET) +#define OFS_MODEM_STATUS (6*REG_OFFSET) +#define OFS_RS232_INPUT (6*REG_OFFSET) +#define OFS_SCRATCH_PAD (7*REG_OFFSET) + +#define OFS_DIVISOR_LSB (0*REG_OFFSET) +#define OFS_DIVISOR_MSB (1*REG_OFFSET) + + +/* memory-mapped read/write of the port */ +#define UART16550_READ(y) (*((volatile uint8*)(BASE + y))) +#define UART16550_WRITE(y, z) ((*((volatile uint8*)(BASE + y))) = z) + +void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) +{ + /* disable interrupts */ + UART16550_WRITE(OFS_INTR_ENABLE, 0); + + /* set up buad rate */ + { + uint32 divisor; + + /* set DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x80); + + /* set divisor */ + divisor = MAX_BAUD / baud; + UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff); + UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8); + + /* clear DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x0); + } + + /* set data format */ + UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop); +} + +static int remoteDebugInitialized = 0; + +uint8 getDebugChar(void) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(UART16550_BAUD_38400, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); + } + + while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0); + return UART16550_READ(OFS_RCV_BUFFER); +} + + +int putDebugChar(uint8 byte) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(UART16550_BAUD_38400, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); + } + + while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0); + UART16550_WRITE(OFS_SEND_BUFFER, byte); + return 1; +} + +#endif diff -urN linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/int-handler.S linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/int-handler.S --- linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/int-handler.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/int-handler.S 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,104 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm + * + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * First-level interrupt dispatcher for Ocelot-CS 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. + */ +#define __ASSEMBLY__ +#include +#include +#include +#include +#include +#include +#include "ocelot_c_fpga.h" + +/* + * First level interrupt dispatcher for Ocelot-CS board + */ + .align 5 + NESTED(ocelot_handle_int, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + mfc0 t0, CP0_CAUSE + mfc0 t2, CP0_STATUS + + and t0, t2 + + andi t1, t0, STATUSF_IP0 /* sw0 software interrupt */ + bnez t1, ll_sw0_irq + andi t1, t0, STATUSF_IP1 /* sw1 software interrupt */ + bnez t1, ll_sw1_irq + andi t1, t0, STATUSF_IP2 /* int0 hardware line */ + bnez t1, ll_scsi_irq + andi t1, t0, STATUSF_IP3 /* int1 hardware line */ + bnez t1, ll_uart_decode_irq + andi t1, t0, STATUSF_IP4 /* int2 hardware line */ + bnez t1, ll_pmc_irq + andi t1, t0, STATUSF_IP5 /* int3 hardware line */ + bnez t1, ll_cpci_decode_irq + andi t1, t0, STATUSF_IP6 /* int4 hardware line */ + bnez t1, ll_mv64340_decode_irq + andi t1, t0, STATUSF_IP7 /* cpu timer */ + bnez t1, ll_cputimer_irq + + .set reorder + + /* wrong alarm or masked ... */ + j spurious_interrupt + nop + END(ocelot_handle_int) + + .align 5 +ll_sw0_irq: + li a0, 0 + move a1, sp + jal do_IRQ + j ret_from_irq +ll_sw1_irq: + li a0, 1 + move a1, sp + jal do_IRQ + j ret_from_irq +ll_scsi_irq: + li a0, 2 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_uart_decode_irq: + move a0, sp + jal ll_uart_irq + j ret_from_irq + +ll_pmc_irq: + li a0, 4 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_cpci_decode_irq: + move a0, sp + jal ll_cpci_irq + j ret_from_irq + +ll_mv64340_decode_irq: + move a0, sp + jal ll_mv64340_irq + j ret_from_irq + +ll_cputimer_irq: + li a0, 7 + move a1, sp + jal do_IRQ + j ret_from_irq + diff -urN linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/irq.c linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/irq.c --- linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2000 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED; + +/* Function for careful CP0 interrupt mask access */ +static inline void modify_cp0_intmask(unsigned clr_mask_in, unsigned set_mask_in) +{ + unsigned long status; + unsigned clr_mask; + unsigned set_mask; + + /* do the low 8 bits first */ + clr_mask = 0xff & clr_mask_in; + set_mask = 0xff & set_mask_in; + status = read_c0_status(); + status &= ~((clr_mask & 0xFF) << 8); + status |= (set_mask & 0xFF) << 8; + write_c0_status(status); +} + +static inline void mask_irq(unsigned int irq) +{ + modify_cp0_intmask(irq, 0); +} + +static inline void unmask_irq(unsigned int irq) +{ + modify_cp0_intmask(0, irq); +} + +static void enable_cp7000_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&irq_lock, flags); + unmask_irq(1 << irq); + spin_unlock_irqrestore(&irq_lock, flags); +} + +static unsigned int startup_cp7000_irq(unsigned int irq) +{ + enable_cp7000_irq(irq); + + return 0; /* never anything pending */ +} + +static void disable_cp7000_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&irq_lock, flags); + mask_irq(1 << irq); + spin_unlock_irqrestore(&irq_lock, flags); +} + +#define shutdown_cp7000_irq disable_cp7000_irq + +static void mask_and_ack_cp7000_irq(unsigned int irq) +{ + mask_irq(1 << irq); +} + +static void end_cp7000_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + unmask_irq(1 << irq); +} + +static struct hw_interrupt_type cp7000_hpcdma_irq_type = { +#ifdef CONFIG_CPU_SR71000 + "SR71000", +#else + "RM7000", +#endif + startup_cp7000_irq, + shutdown_cp7000_irq, + enable_cp7000_irq, + disable_cp7000_irq, + mask_and_ack_cp7000_irq, + end_cp7000_irq, + NULL +}; + +extern asmlinkage void ocelot_handle_int(void); +extern void mv64340_irq_init(void); +extern void uart_irq_init(void); +extern void cpci_irq_init(void); + +static struct irqaction cascade_fpga = + { no_action, SA_INTERRUPT, 0, "cascade via FPGA", NULL, NULL }; +static struct irqaction cascade_mv64340 = + { no_action, SA_INTERRUPT, 0, "cascade via MV64340", NULL, NULL }; + +void __init init_IRQ(void) +{ + int i; + + /* + * Clear all of the interrupts while we change the able around a bit. + * int-handler is not on bootstrap + */ + clear_c0_status(ST0_IM | ST0_BEV); + __cli(); + + /* Sets the first-level interrupt dispatcher. */ + set_except_vector(0, ocelot_handle_int); + init_generic_irq(); + + /* set up handler for first 8 IRQs as the CPU */ + for (i = 0; i < 8; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &cp7000_hpcdma_irq_type; + } + + /* set up the cascading interrupts */ + setup_irq(3, &cascade_fpga); + setup_irq(5, &cascade_fpga); + setup_irq(6, &cascade_mv64340); + + mv64340_irq_init(); + uart_irq_init(); + cpci_irq_init(); + +#ifdef CONFIG_KGDB + printk("start kgdb ...\n"); + set_debug_traps(); + breakpoint(); /* you may move this line to whereever you want :-) */ +#endif +#ifdef CONFIG_GDB_CONSOLE + register_gdb_console(); +#endif +} diff -urN linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/mv-irq.c linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/mv-irq.c --- linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/mv-irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/mv-irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,164 @@ +/* + * Copyright 2002 Momentum Computer + * Author: mdharm@momenco.com + * + * arch/mips/momentum/ocelot_c/mv-irq.c + * Interrupt routines for mv64340. Interrupt numbers are assigned from + * MV64340_IRQ_BASE to MV64340_IRQ_BASE+64. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MV64340_IRQ_BASE 16 + +static inline int ls1bit32(unsigned int x) +{ + int b = 31, s; + + s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s; + s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s; + s = 4; if (x << 4 == 0) s = 0; b -= s; x <<= s; + s = 2; if (x << 2 == 0) s = 0; b -= s; x <<= s; + s = 1; if (x << 1 == 0) s = 0; b -= s; + + return b; +} + +/* mask off an interrupt -- 1 is enable, 0 is disable */ +static inline void mask_mv64340_irq(unsigned int irq) +{ + uint32_t value; + + if (irq < (MV64340_IRQ_BASE + 32)) { + MV_READ(MV64340_INTERRUPT0_MASK_0_LOW, &value); + value &= ~(1 << (irq - MV64340_IRQ_BASE)); + MV_WRITE(MV64340_INTERRUPT0_MASK_0_LOW, value); + } else { + MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH, &value); + value &= ~(1 << (irq - (MV64340_IRQ_BASE - 32))); + MV_WRITE(MV64340_INTERRUPT0_MASK_0_HIGH, value); + } +} + +/* unmask an interrupt -- 1 is enable, 0 is disable */ +static inline void unmask_mv64340_irq(unsigned int irq) +{ + uint32_t value; + + if (irq < (MV64340_IRQ_BASE + 32)) { + MV_READ(MV64340_INTERRUPT0_MASK_0_LOW, &value); + value |= 1 << (irq - MV64340_IRQ_BASE); + MV_WRITE(MV64340_INTERRUPT0_MASK_0_LOW, value); + } else { + MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH, &value); + value |= 1 << (irq - (MV64340_IRQ_BASE - 32)); + MV_WRITE(MV64340_INTERRUPT0_MASK_0_HIGH, value); + } +} + +/* + * Enables the IRQ on Marvell Chip + */ +static void enable_mv64340_irq(unsigned int irq) +{ + unmask_mv64340_irq(irq); +} + +/* + * Initialize the IRQ on Marvell Chip + */ +static unsigned int startup_mv64340_irq(unsigned int irq) +{ + unmask_mv64340_irq(irq); + return 0; +} + +/* + * Disables the IRQ on Marvell Chip + */ +static void disable_mv64340_irq(unsigned int irq) +{ + mask_mv64340_irq(irq); +} + +/* + * Masks and ACKs an IRQ + */ +static void mask_and_ack_mv64340_irq(unsigned int irq) +{ + mask_mv64340_irq(irq); +} + +/* + * End IRQ processing + */ +static void end_mv64340_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + unmask_mv64340_irq(irq); +} + +/* + * Interrupt handler for interrupts coming from the Marvell chip. + * It could be built in ethernet ports etc... + */ +void ll_mv64340_irq(struct pt_regs *regs) +{ + unsigned int irq_src_low, irq_src_high; + unsigned int irq_mask_low, irq_mask_high; + + /* read the interrupt status registers */ + MV_READ(MV64340_INTERRUPT0_MASK_0_LOW, &irq_mask_low); + MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH, &irq_mask_high); + MV_READ(MV64340_MAIN_INTERRUPT_CAUSE_LOW, &irq_src_low); + MV_READ(MV64340_MAIN_INTERRUPT_CAUSE_HIGH, &irq_src_high); + + /* mask for just the interrupts we want */ + irq_src_low &= irq_mask_low; + irq_src_high &= irq_mask_high; + + if (irq_src_low) + do_IRQ(ls1bit32(irq_src_low) + MV64340_IRQ_BASE, regs); + else + do_IRQ(ls1bit32(irq_src_high) + MV64340_IRQ_BASE + 32, regs); +} + +#define shutdown_mv64340_irq disable_mv64340_irq + +struct hw_interrupt_type mv64340_irq_type = { + "MV-64340", + startup_mv64340_irq, + shutdown_mv64340_irq, + enable_mv64340_irq, + disable_mv64340_irq, + mask_and_ack_mv64340_irq, + end_mv64340_irq, + NULL +}; + +void mv64340_irq_init(void) +{ + int i; + + /* Reset irq handlers pointers to NULL */ + for (i = MV64340_IRQ_BASE; i < (MV64340_IRQ_BASE + 64); i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 2; + irq_desc[i].handler = &mv64340_irq_type; + } +} diff -urN linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h --- linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,50 @@ +/* + * Ocelot-C Board Register Definitions + * + * (C) 2002 Momentum Computer Inc. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef __OCELOT_C_FPGA_H__ +#define __OCELOT_C_FPGA_H__ + +#define OCELOT_C_CS0_ADDR (0xfc000000) + +#define OCELOT_C_REG_BOARDREV 0x0 +#define OCELOT_C_REG_FPGA_REV 0x1 +#define OCELOT_C_REG_FPGA_TYPE 0x2 +#define OCELOT_C_REG_RESET_STATUS 0x3 +#define OCELOT_C_REG_BOARD_STATUS 0x4 +#define OCELOT_C_REG_CPCI_ID 0x5 +#define OCELOT_C_REG_SET 0x6 +#define OCELOT_C_REG_CLR 0x7 +#define OCELOT_C_REG_EEPROM_MODE 0x9 +#define OCELOT_C_REG_INTMASK 0xa +#define OCELOT_C_REG_INTSTAT 0xb +#define OCELOT_C_REG_UART_INTMASK 0xc +#define OCELOT_C_REG_UART_INTSTAT 0xd +#define OCELOT_C_REG_INTSET 0xe +#define OCELOT_C_REG_INTCLR 0xf + +#define OCELOT_FPGA_WRITE(x, y) writeb(x, OCELOT_C_CS0_ADDR + OCELOT_C_REG_##y) +#define OCELOT_FPGA_READ(x) readb(OCELOT_C_CS0_ADDR + OCELOT_C_REG_##x) + +#endif diff -urN linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/pci-irq.c linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/pci-irq.c --- linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/pci-irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/pci-irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,73 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm + * + * Based on work for the Linux port to the Ocelot board, which is + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * arch/mips/momentum/ocelot_g/pci.c + * Board-specific PCI routines for mv64340 controller. + * + * 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. + */ +#include +#include +#include +#include +#include +#include + + +void __init mv64340_board_pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_bus *current_bus = bus; + struct pci_dev *devices; + struct list_head *devices_link; + u16 cmd; + + /* loop over all known devices on this bus */ + list_for_each(devices_link, &(current_bus->devices)) { + + devices = pci_dev_b(devices_link); + if (devices == NULL) + continue; + + if ((current_bus->number == 0) && + (PCI_SLOT(devices->devfn) == 1) && + (PCI_FUNC(devices->devfn) == 0)) { + /* LSI 53C10101R SCSI (A) */ + devices->irq = 2; + } else if ((current_bus->number == 0) && + (PCI_SLOT(devices->devfn) == 1) && + (PCI_FUNC(devices->devfn) == 1)) { + /* LSI 53C10101R SCSI (B) */ + devices->irq = 2; + } else if ((current_bus->number == 1) && + (PCI_SLOT(devices->devfn) == 1)) { + /* Intel 21555 bridge */ + devices->irq = 12; + } else if ((current_bus->number == 1) && + (PCI_SLOT(devices->devfn) == 2)) { + /* PMC Slot */ + devices->irq = 4; + } else { + /* We don't have assign interrupts for other devices. */ + devices->irq = 0xff; + } + + /* Assign an interrupt number for the device */ + bus->ops->write_byte(devices, PCI_INTERRUPT_LINE, devices->irq); + + /* enable master for everything but the MV-64340 */ + if (((current_bus->number != 0) && (current_bus->number != 1)) + || (PCI_SLOT(devices->devfn) != 0)) { + bus->ops->read_word(devices, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER; + bus->ops->write_word(devices, PCI_COMMAND, cmd); + } + } +} diff -urN linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/pci.c linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/pci.c --- linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/pci.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/pci.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,363 @@ +/* + * Copyright 2002 Momentum Computer + * Author: Matthew Dharm + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef CONFIG_PCI + +/* + * These functions and structures provide the BIOS scan and mapping of the PCI + * devices. + */ + +#define MAX_PCI_DEVS 10 + +void mv64340_board_pcibios_fixup_bus(struct pci_bus* c); + +/* Functions to implement "pci ops" */ +static int marvell_pcibios_read_config_word(struct pci_dev *dev, + int offset, u16 * val); +static int marvell_pcibios_read_config_byte(struct pci_dev *dev, + int offset, u8 * val); +static int marvell_pcibios_read_config_dword(struct pci_dev *dev, + int offset, u32 * val); +static int marvell_pcibios_write_config_byte(struct pci_dev *dev, + int offset, u8 val); +static int marvell_pcibios_write_config_word(struct pci_dev *dev, + int offset, u16 val); +static int marvell_pcibios_write_config_dword(struct pci_dev *dev, + int offset, u32 val); + +/* + * General-purpose PCI functions. + */ + + +/* + * pci_range_ck - + * + * Check if the pci device that are trying to access does really exists + * on the evaluation board. + * + * Inputs : + * bus - bus number (0 for PCI 0 ; 1 for PCI 1) + * dev - number of device on the specific pci bus + * + * Outpus : + * 0 - if OK , 1 - if failure + */ +static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev) +{ + /* Accessing device 31 crashes the MV-64340. */ + if (dev < 5) + return 0; + return -1; +} + +/* + * marvell_pcibios_(read/write)_config_(dword/word/byte) - + * + * reads/write a dword/word/byte register from the configuration space + * of a device. + * + * Note that bus 0 and bus 1 are local, and we assume all other busses are + * bridged from bus 1. This is a safe assumption, since any other + * configuration will require major modifications to the CP7000G + * + * Inputs : + * bus - bus number + * dev - device number + * offset - register offset in the configuration space + * val - value to be written / read + * + * Outputs : + * PCIBIOS_SUCCESSFUL when operation was succesfull + * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous + * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned + */ + +static int marvell_pcibios_read_config_dword(struct pci_dev *device, + int offset, u32* val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* read the data */ + MV_READ(data_reg, val); + + return PCIBIOS_SUCCESSFUL; +} + + +static int marvell_pcibios_read_config_word(struct pci_dev *device, + int offset, u16* val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* read the data */ + MV_READ_16(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +static int marvell_pcibios_read_config_byte(struct pci_dev *device, + int offset, u8* val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* write the data */ + MV_READ_8(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +static int marvell_pcibios_write_config_dword(struct pci_dev *device, + int offset, u32 val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* write the data */ + MV_WRITE(data_reg, val); + + return PCIBIOS_SUCCESSFUL; +} + + +static int marvell_pcibios_write_config_word(struct pci_dev *device, + int offset, u16 val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* write the data */ + MV_WRITE_16(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +static int marvell_pcibios_write_config_byte(struct pci_dev *device, + int offset, u8 val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* write the data */ + MV_WRITE_8(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops marvell_pci_ops = { + marvell_pcibios_read_config_byte, + marvell_pcibios_read_config_word, + marvell_pcibios_read_config_dword, + marvell_pcibios_write_config_byte, + marvell_pcibios_write_config_word, + marvell_pcibios_write_config_dword +}; + +struct pci_fixup pcibios_fixups[] = { + {0} +}; + +void __init pcibios_fixup_bus(struct pci_bus *c) +{ + mv64340_board_pcibios_fixup_bus(c); +} + +void __init pcibios_init(void) +{ + /* Reset PCI I/O and PCI MEM values */ + ioport_resource.start = 0xe0000000; + ioport_resource.end = 0xe0000000 + 0x20000000 - 1; + iomem_resource.start = 0xc0000000; + iomem_resource.end = 0xc0000000 + 0x20000000 - 1; + + pci_scan_bus(0, &marvell_pci_ops, NULL); + pci_scan_bus(1, &marvell_pci_ops, NULL); +} + +unsigned __init int pcibios_assign_all_busses(void) +{ + return 1; +} + +#endif /* CONFIG_PCI */ diff -urN linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/prom.c linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/prom.c --- linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/prom.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/prom.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,151 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm + * + * Based on Ocelot Linux port, which is + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * 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. + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "ocelot_c_fpga.h" + +struct callvectors { + int (*open) (char*, int, int); + int (*close) (int); + int (*read) (int, void*, int); + int (*write) (int, void*, int); + off_t (*lseek) (int, off_t, int); + int (*printf) (const char*, ...); + void (*cacheflush) (void); + char* (*gets) (char*); +}; + +struct callvectors* debug_vectors; +char arcs_cmdline[CL_SIZE]; + +extern unsigned long mv64340_base; +extern unsigned long cpu_clock; + +#ifdef CONFIG_MV64340_ETH +extern unsigned char prom_mac_addr_base[6]; +#endif + +const char *get_system_type(void) +{ +#ifdef CONFIG_CPU_SR71000 + return "Momentum Ocelot-CS"; +#else + return "Momentum Ocelot-C"; +#endif +} + +#ifdef CONFIG_MV64340_ETH +static void burn_clocks(void) +{ + int i; + + /* this loop should burn at least 1us -- this should be plenty */ + for (i = 0; i < 0x10000; i++) + ; +} + +static u8 exchange_bit(u8 val, u8 cs) +{ + /* place the data */ + OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); + burn_clocks(); + + /* turn the clock on */ + OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); + burn_clocks(); + + /* turn the clock off and read-strobe */ + OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); + + /* return the data */ + return ((OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1); +} + +void get_mac(char dest[6]) +{ + u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int i,j; + + for (i = 0; i < 12; i++) + exchange_bit(read_opcode[i], 1); + + for (j = 0; j < 6; j++) { + dest[j] = 0; + for (i = 0; i < 8; i++) { + dest[j] <<= 1; + dest[j] |= exchange_bit(0, 1); + } + } + + /* turn off CS */ + exchange_bit(0,0); +} +#endif + +/* [jsun@junsun.net] PMON passes arguments in C main() style */ +void __init prom_init(int argc, char **arg, char** env, struct callvectors *cv) +{ + int i; + + /* save the PROM vectors for debugging use */ + debug_vectors = cv; + + /* arg[0] is "g", the rest is boot parameters */ + arcs_cmdline[0] = '\0'; + for (i = 1; i < argc; i++) { + if (strlen(arcs_cmdline) + strlen(arg[i] + 1) + >= sizeof(arcs_cmdline)) + break; + strcat(arcs_cmdline, arg[i]); + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_MOMENCO; + mips_machtype = MACH_MOMENCO_OCELOT_C; + + while (*env) { + if (strncmp("gtbase", *env, strlen("gtbase")) == 0) { + mv64340_base = simple_strtol(*env + strlen("gtbase="), + NULL, 16); + } + if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) { + cpu_clock = simple_strtol(*env + strlen("cpuclock="), + NULL, 10); + } + env++; + } + +#ifdef CONFIG_MV64340_ETH + /* get the base MAC address for on-board ethernet ports */ + get_mac(prom_mac_addr_base); +#endif + + debug_vectors->printf("Booting Linux kernel...\n"); +} + +void __init prom_free_prom_memory(void) +{ +} + +void __init prom_fixup_mem_map(unsigned long start, unsigned long end) +{ +} diff -urN linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/reset.c linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/reset.c --- linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/reset.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/reset.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,50 @@ +/* + * 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. + * + * Copyright (C) 1997, 2001 Ralf Baechle + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * Copyright (C) 2002 Momentum Computer Inc. + * Author: Matthew Dharm + */ +#include +#include +#include +#include +#include +#include +#include +#include + +void momenco_ocelot_restart(char *command) +{ + /* base address of timekeeper portion of part */ + void *nvram = (void*) 0xfc807000; + + /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */ + writeb(0x84, nvram + 0xff7); + + /* wait for the watchdog to go off */ + mdelay(100+(1000/16)); + + /* if the watchdog fails for some reason, let people know */ + printk(KERN_NOTICE "Watchdog reset failed\n"); +} + +void momenco_ocelot_halt(void) +{ + printk(KERN_NOTICE "\n** You can safely turn off the power\n"); + while (1) + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} + +void momenco_ocelot_power_off(void) +{ + momenco_ocelot_halt(); +} diff -urN linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/setup.c linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/setup.c --- linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,330 @@ +/* + * setup.c + * + * BRIEF MODULE DESCRIPTION + * Momentum Computer Ocelot-C and -CS board dependent boot routines + * + * Copyright (C) 1996, 1997, 2001 Ralf Baechle + * Copyright (C) 2000 RidgeRun, Inc. + * Copyright (C) 2001 Red Hat, Inc. + * Copyright (C) 2002 Momentum Computer + * + * Author: Matthew Dharm, Momentum Computer + * mdharm@momenco.com + * + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ocelot_c_fpga.h" + +unsigned long mv64340_base; +unsigned long cpu_clock; + +/* These functions are used for rebooting or halting the machine*/ +extern void momenco_ocelot_restart(char *command); +extern void momenco_ocelot_halt(void); +extern void momenco_ocelot_power_off(void); + +void momenco_time_init(void); + +static char reset_reason; + +#define ENTRYLO(x) ((pte_val(mk_pte_phys((x), PAGE_KERNEL_UNCACHED)) >> 6)|1) + +/* setup code for a handoff from a version 2 PMON 2000 PROM */ +void PMON_v2_setup(void) +{ + /* Some wired TLB entries for the MV64340 and perhiperals. The + MV64340 is going to be hit on every IRQ anyway - there's + absolutely no point in letting it be a random TLB entry, as + it'll just cause needless churning of the TLB. And we use + the other half for the serial port, which is just a PITA + otherwise :) + + Device Physical Virtual + MV64340 Internal Regs 0xf4000000 0xf4000000 + Ocelot-C[S] PLD (CS0) 0xfc000000 0xfc000000 + NVRAM (CS1) 0xfc800000 0xfc800000 + UARTs (CS2) 0xfd000000 0xfd000000 + Internal SRAM 0xfe000000 0xfe000000 + M-Systems DOC (CS3) 0xff000000 0xff000000 + */ + + /* marvell and extra space */ + add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K); + /* fpga, rtc, and uart */ + add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), 0xfc000000, PM_16M); + /* m-sys and internal SRAM */ + add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfe000000, PM_16M); + + mv64340_base = 0xf4000000; +} + +#define CONV_BCD_TO_BIN(val) (((val) & 0xf) + (((val) >> 4) * 10)) +#define CONV_BIN_TO_BCD(val) (((val) % 10) + (((val) / 10) << 4)) + +unsigned long m48t37y_get_time(void) +{ + unsigned char* rtc_base = (unsigned char*)0xfc800000; + unsigned int year, month, day, hour, min, sec; + + /* stop the update */ + rtc_base[0x7ff8] = 0x40; + + year = CONV_BCD_TO_BIN(rtc_base[0x7fff]); + year += CONV_BCD_TO_BIN(rtc_base[0x7ff1]) * 100; + + month = CONV_BCD_TO_BIN(rtc_base[0x7ffe]); + + day = CONV_BCD_TO_BIN(rtc_base[0x7ffd]); + + hour = CONV_BCD_TO_BIN(rtc_base[0x7ffb]); + min = CONV_BCD_TO_BIN(rtc_base[0x7ffa]); + sec = CONV_BCD_TO_BIN(rtc_base[0x7ff9]); + + /* start the update */ + rtc_base[0x7ff8] = 0x00; + + return mktime(year, month, day, hour, min, sec); +} + +int m48t37y_set_time(unsigned long sec) +{ + unsigned char* rtc_base = (unsigned char*)0xfc800000; + struct rtc_time tm; + + /* convert to a more useful format -- note months count from 0 */ + to_tm(sec, &tm); + tm.tm_mon += 1; + + /* enable writing */ + rtc_base[0x7ff8] = 0x80; + + /* year */ + rtc_base[0x7fff] = CONV_BIN_TO_BCD(tm.tm_year % 100); + rtc_base[0x7ff1] = CONV_BIN_TO_BCD(tm.tm_year / 100); + + /* month */ + rtc_base[0x7ffe] = CONV_BIN_TO_BCD(tm.tm_mon); + + /* day */ + rtc_base[0x7ffd] = CONV_BIN_TO_BCD(tm.tm_mday); + + /* hour/min/sec */ + rtc_base[0x7ffb] = CONV_BIN_TO_BCD(tm.tm_hour); + rtc_base[0x7ffa] = CONV_BIN_TO_BCD(tm.tm_min); + rtc_base[0x7ff9] = CONV_BIN_TO_BCD(tm.tm_sec); + + /* day of week -- not really used, but let's keep it up-to-date */ + rtc_base[0x7ffc] = CONV_BIN_TO_BCD(tm.tm_wday + 1); + + /* disable writing */ + rtc_base[0x7ff8] = 0x00; + + return 0; +} + +void momenco_timer_setup(struct irqaction *irq) +{ + setup_irq(7, irq); +} + +void momenco_time_init(void) +{ +#ifdef CONFIG_CPU_SR71000 + mips_counter_frequency = cpu_clock; +#elif defined(CONFIG_CPU_RM7000) + mips_counter_frequency = cpu_clock / 2; +#else +#error Unknown CPU for this board +#endif + board_timer_setup = momenco_timer_setup; + + rtc_get_time = m48t37y_get_time; + rtc_set_time = m48t37y_set_time; +} + +void __init momenco_ocelot_c_setup(void) +{ + unsigned int tmpword; + + board_time_init = momenco_time_init; + + _machine_restart = momenco_ocelot_restart; + _machine_halt = momenco_ocelot_halt; + _machine_power_off = momenco_ocelot_power_off; + + /* + * initrd_start = (ulong)ocelot_initrd_start; + * initrd_end = (ulong)ocelot_initrd_start + (ulong)ocelot_initrd_size; + * initrd_below_start_ok = 1; + */ + + /* do handoff reconfiguration */ + PMON_v2_setup(); + + /* shut down ethernet ports, just to be sure our memory doesn't get + * corrupted by random ethernet traffic. + */ + MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8); + MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8); + MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8); + MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8); + do {} + while (MV_READ_DATA(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff); + do {} + while (MV_READ_DATA(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff); + do {} + while (MV_READ_DATA(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff); + do {} + while (MV_READ_DATA(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff); + MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0), MV_READ_DATA(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1); + MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1), MV_READ_DATA(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1); + + /* Turn off the Bit-Error LED */ + OCELOT_FPGA_WRITE(0x80, CLR); + + tmpword = OCELOT_FPGA_READ(BOARDREV); +#ifdef CONFIG_CPU_SR71000 + if (tmpword < 26) + printk("Momenco Ocelot-CS: Board Assembly Rev. %c\n", + 'A'+tmpword); + else + printk("Momenco Ocelot-CS: Board Assembly Revision #0x%x\n", + tmpword); +#else + if (tmpword < 26) + printk("Momenco Ocelot-C: Board Assembly Rev. %c\n", + 'A'+tmpword); + else + printk("Momenco Ocelot-C: Board Assembly Revision #0x%x\n", + tmpword); +#endif + + tmpword = OCELOT_FPGA_READ(FPGA_REV); + printk("FPGA Rev: %d.%d\n", tmpword>>4, tmpword&15); + tmpword = OCELOT_FPGA_READ(RESET_STATUS); + printk("Reset reason: 0x%x\n", tmpword); + switch (tmpword) { + case 0x1: + printk(" - Power-up reset\n"); + break; + case 0x2: + printk(" - Push-button reset\n"); + break; + case 0x4: + printk(" - cPCI bus reset\n"); + break; + case 0x8: + printk(" - Watchdog reset\n"); + break; + case 0x10: + printk(" - Software reset\n"); + break; + default: + printk(" - Unknown reset cause\n"); + } + reset_reason = tmpword; + OCELOT_FPGA_WRITE(0xff, RESET_STATUS); + + tmpword = OCELOT_FPGA_READ(CPCI_ID); + printk("cPCI ID register: 0x%02x\n", tmpword); + printk(" - Slot number: %d\n", tmpword & 0x1f); + printk(" - PCI bus present: %s\n", tmpword & 0x40 ? "yes" : "no"); + printk(" - System Slot: %s\n", tmpword & 0x20 ? "yes" : "no"); + + tmpword = OCELOT_FPGA_READ(BOARD_STATUS); + printk("Board Status register: 0x%02x\n", tmpword); + printk(" - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent"); + printk(" - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent"); + printk(" - L3 Cache size: %d MiB\n", (1<<((tmpword&12) >> 2))&~1); + printk(" - SDRAM size: %d MiB\n", 1<<(6+(tmpword&3))); + + switch(tmpword &3) { + case 3: + /* 512MiB */ + add_memory_region(0x0, 0x200<<20, BOOT_MEM_RAM); + break; + case 2: + /* 256MiB */ + add_memory_region(0x0, 0x100<<20, BOOT_MEM_RAM); + break; + case 1: + /* 128MiB */ + add_memory_region(0x0, 0x80<<20, BOOT_MEM_RAM); + break; + case 0: + /* 1GiB -- needs CONFIG_HIGHMEM */ + add_memory_region(0x0, 0x400<<20, BOOT_MEM_RAM); + break; + } +} + +/* This needs to be one of the first initcalls, because no I/O port access + can work before this */ +static int io_base_ioremap(void) +{ + /* we're mapping PCI accesses from 0xc0000000 to 0xf0000000 */ + void *io_remap_range = ioremap(0xc0000000, 0x30000000); + + if (!io_remap_range) { + panic("Could not ioremap I/O port range"); + } + printk("io_remap_range set at 0x%08x\n", (uint32_t)io_remap_range); + set_io_port_base(io_remap_range - 0xc0000000); + + return 0; +} + +module_init(io_base_ioremap); diff -urN linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/uart-irq.c linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/uart-irq.c --- linux-2.4.21-bk37/arch/mips/momentum/ocelot_c/uart-irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/momentum/ocelot_c/uart-irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,148 @@ +/* + * Copyright 2002 Momentum Computer + * Author: mdharm@momenco.com + * + * arch/mips/momentum/ocelot_c/uart-irq.c + * Interrupt routines for UARTs. Interrupt numbers are assigned from + * 80 to 81 (2 interrupt sources). + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ocelot_c_fpga.h" + +static inline int ls1bit8(unsigned int x) +{ + int b = 7, s; + + s = 4; if (((unsigned char)(x << 4)) == 0) s = 0; b -= s; x <<= s; + s = 2; if (((unsigned char)(x << 2)) == 0) s = 0; b -= s; x <<= s; + s = 1; if (((unsigned char)(x << 1)) == 0) s = 0; b -= s; + + return b; +} + +/* mask off an interrupt -- 0 is enable, 1 is disable */ +static inline void mask_uart_irq(unsigned int irq) +{ + uint8_t value; + + value = OCELOT_FPGA_READ(UART_INTMASK); + value |= 1 << (irq - 74); + OCELOT_FPGA_WRITE(value, UART_INTMASK); + + /* read the value back to assure that it's really been written */ + value = OCELOT_FPGA_READ(UART_INTMASK); +} + +/* unmask an interrupt -- 0 is enable, 1 is disable */ +static inline void unmask_uart_irq(unsigned int irq) +{ + uint8_t value; + + value = OCELOT_FPGA_READ(UART_INTMASK); + value &= ~(1 << (irq - 74)); + OCELOT_FPGA_WRITE(value, UART_INTMASK); + + /* read the value back to assure that it's really been written */ + value = OCELOT_FPGA_READ(UART_INTMASK); +} + +/* + * Enables the IRQ in the FPGA + */ +static void enable_uart_irq(unsigned int irq) +{ + unmask_uart_irq(irq); +} + +/* + * Initialize the IRQ in the FPGA + */ +static unsigned int startup_uart_irq(unsigned int irq) +{ + unmask_uart_irq(irq); + return 0; +} + +/* + * Disables the IRQ in the FPGA + */ +static void disable_uart_irq(unsigned int irq) +{ + mask_uart_irq(irq); +} + +/* + * Masks and ACKs an IRQ + */ +static void mask_and_ack_uart_irq(unsigned int irq) +{ + mask_uart_irq(irq); +} + +/* + * End IRQ processing + */ +static void end_uart_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + unmask_uart_irq(irq); +} + +/* + * Interrupt handler for interrupts coming from the FPGA chip. + */ +void ll_uart_irq(struct pt_regs *regs) +{ + unsigned int irq_src, irq_mask; + + /* read the interrupt status registers */ + irq_src = OCELOT_FPGA_READ(UART_INTSTAT); + irq_mask = OCELOT_FPGA_READ(UART_INTMASK); + + /* mask for just the interrupts we want */ + irq_src &= ~irq_mask; + + do_IRQ(ls1bit8(irq_src) + 74, regs); +} + +#define shutdown_uart_irq disable_uart_irq + +struct hw_interrupt_type uart_irq_type = { + "UART/FPGA", + startup_uart_irq, + shutdown_uart_irq, + enable_uart_irq, + disable_uart_irq, + mask_and_ack_uart_irq, + end_uart_irq, + NULL +}; + +void uart_irq_init(void) +{ + /* Reset irq handlers pointers to NULL */ + irq_desc[80].status = IRQ_DISABLED; + irq_desc[80].action = 0; + irq_desc[80].depth = 2; + irq_desc[80].handler = &uart_irq_type; + + irq_desc[81].status = IRQ_DISABLED; + irq_desc[81].action = 0; + irq_desc[81].depth = 2; + irq_desc[81].handler = &uart_irq_type; +} diff -urN linux-2.4.21-bk37/arch/mips/momentum/ocelot_g/Makefile linux-2.4.21-bk38/arch/mips/momentum/ocelot_g/Makefile --- linux-2.4.21-bk37/arch/mips/momentum/ocelot_g/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/momentum/ocelot_g/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -6,15 +6,12 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true O_TARGET:= ocelot_g.o -obj-y += gt-irq.o pci-irq.o pci.o int-handler.o irq.o prom.o reset.o setup.o - -obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o +obj-y += gt-irq.o pci-irq.o int-handler.o irq.o prom.o reset.o setup.o +obj-$(CONFIG_KGDB) += dbg_io.o +obj-$(CONFIG_PCI) += pci.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/momentum/ocelot_g/dbg_io.c linux-2.4.21-bk38/arch/mips/momentum/ocelot_g/dbg_io.c --- linux-2.4.21-bk37/arch/mips/momentum/ocelot_g/dbg_io.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/momentum/ocelot_g/dbg_io.c 2003-08-24 02:55:57.000000000 -0700 @@ -1,6 +1,6 @@ #include -#if defined(CONFIG_REMOTE_DEBUG) +#if defined(CONFIG_KGDB) #include /* For the serial port location and base baud */ diff -urN linux-2.4.21-bk37/arch/mips/momentum/ocelot_g/irq.c linux-2.4.21-bk38/arch/mips/momentum/ocelot_g/irq.c --- linux-2.4.21-bk37/arch/mips/momentum/ocelot_g/irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/momentum/ocelot_g/irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -60,18 +60,18 @@ /* do the low 8 bits first */ clr_mask = 0xff & clr_mask_in; set_mask = 0xff & set_mask_in; - status = read_32bit_cp0_register(CP0_STATUS); + status = read_c0_status(); status &= ~((clr_mask & 0xFF) << 8); status |= (set_mask & 0xFF) << 8; - write_32bit_cp0_register(CP0_STATUS, status); + write_c0_status(status); /* do the high 8 bits */ clr_mask = 0xff & (clr_mask_in >> 8); set_mask = 0xff & (set_mask_in >> 8); - status = read_32bit_cp0_set1_register(CP0_S1_INTCONTROL); + status = read_c0_intcontrol(); status &= ~((clr_mask & 0xFF) << 8); status |= (set_mask & 0xFF) << 8; - write_32bit_cp0_set1_register(CP0_S1_INTCONTROL, status); + write_c0_intrcontrol(status); } static inline void mask_irq(unsigned int irq) @@ -145,7 +145,7 @@ * Clear all of the interrupts while we change the able around a bit. * int-handler is not on bootstrap */ - clear_cp0_status(ST0_IM | ST0_BEV); + clear_c0_status(ST0_IM | ST0_BEV); __cli(); /* Sets the first-level interrupt dispatcher. */ @@ -161,7 +161,7 @@ gt64240_irq_init(); -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB printk("start kgdb ...\n"); set_debug_traps(); breakpoint(); /* you may move this line to whereever you want :-) */ diff -urN linux-2.4.21-bk37/arch/mips/momentum/ocelot_g/ocelot_pld.h linux-2.4.21-bk38/arch/mips/momentum/ocelot_g/ocelot_pld.h --- linux-2.4.21-bk37/arch/mips/momentum/ocelot_g/ocelot_pld.h 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/momentum/ocelot_g/ocelot_pld.h 2003-08-24 02:55:57.000000000 -0700 @@ -8,11 +8,7 @@ #ifndef __MOMENCO_OCELOT_PLD_H__ #define __MOMENCO_OCELOT_PLD_H__ -#if 0 -#define OCELOT_CS0_ADDR (0xe0020000) -#else #define OCELOT_CS0_ADDR (0xfc000000) -#endif #define OCELOT_REG_BOARDREV (0) #define OCELOT_REG_PLD1_ID (1) diff -urN linux-2.4.21-bk37/arch/mips/momentum/ocelot_g/pci.c linux-2.4.21-bk38/arch/mips/momentum/ocelot_g/pci.c --- linux-2.4.21-bk37/arch/mips/momentum/ocelot_g/pci.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/momentum/ocelot_g/pci.c 2003-08-24 02:55:57.000000000 -0700 @@ -34,8 +34,6 @@ #include -#ifdef CONFIG_PCI - #define SELF 0 #define MASTER_ABORT_BIT 0x100 @@ -61,7 +59,6 @@ int offset, u16 val); static int galileo_pcibios_write_config_dword(struct pci_dev *dev, int offset, u32 val); -static void galileo_pcibios_set_master(struct pci_dev *dev); /* * General-purpose PCI functions. @@ -345,128 +342,6 @@ return PCIBIOS_SUCCESSFUL; } -static void galileo_pcibios_set_master(struct pci_dev *dev) -{ - u16 cmd; - - galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MASTER; - galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd); -} - -/* Externally-expected functions. Do not change function names */ - -int pcibios_enable_resources(struct pci_dev *dev) -{ - u16 cmd, old_cmd; - u8 tmp1; - int idx; - struct resource *r; - - galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - for (idx = 0; idx < 6; idx++) { - r = &dev->resource[idx]; - if (!r->start && r->end) { - printk(KERN_ERR - "PCI: Device %s not available because of " - "resource collisions\n", dev->slot_name); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (cmd != old_cmd) { - galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd); - } - - /* - * Let's fix up the latency timer and cache line size here. Cache - * line size = 32 bytes / sizeof dword (4) = 8. - * Latency timer must be > 8. 32 is random but appears to work. - */ - galileo_pcibios_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1); - if (tmp1 != 8) { - printk(KERN_WARNING "PCI setting cache line size to 8 from " - "%d\n", tmp1); - galileo_pcibios_write_config_byte(dev, PCI_CACHE_LINE_SIZE, - 8); - } - galileo_pcibios_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp1); - if (tmp1 < 32) { - printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n", - tmp1); - galileo_pcibios_write_config_byte(dev, PCI_LATENCY_TIMER, - 32); - } - - return 0; -} - -int pcibios_enable_device(struct pci_dev *dev) -{ - return pcibios_enable_resources(dev); -} - -void pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - u32 new, check; - int reg; - - return; - -#if 0 - new = res->start | (res->flags & PCI_REGION_FLAG_MASK); - if (resource < 6) { - reg = PCI_BASE_ADDRESS_0 + 4 * resource; - } else if (resource == PCI_ROM_RESOURCE) { - res->flags |= PCI_ROM_ADDRESS_ENABLE; - reg = dev->rom_base_reg; - } else { - /* - * Somebody might have asked allocation of a non-standard - * resource - */ - return; - } - - pci_write_config_dword(dev, reg, new); - pci_read_config_dword(dev, reg, &check); - if ((new ^ check) & - ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : - PCI_BASE_ADDRESS_MEM_MASK)) { - printk(KERN_ERR "PCI: Error while updating region " - "%s/%d (%08x != %08x)\n", dev->slot_name, resource, - new, check); - } -#endif -} - -void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ - struct pci_dev *dev = data; - - if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; - - /* We need to avoid collisions with `mirrored' VGA ports - and other strange ISA hardware, so we always want the - addresses kilobyte aligned. */ - if (size > 0x100) { - printk(KERN_ERR "PCI: I/O Region %s/%d too large" - " (%ld bytes)\n", dev->slot_name, - dev->resource - res, size); - } - - start = (start + 1024 - 1) & ~(1024 - 1); - res->start = start; - } -} - struct pci_ops galileo_pci_ops = { galileo_pcibios_read_config_byte, galileo_pcibios_read_config_word, @@ -534,9 +409,6 @@ GT_WRITE(PCI_1P2P_CONFIGURATION, regData); } -#define PCI0_STATUS_COMMAND_REG 0x4 -#define PCI1_STATUS_COMMAND_REG 0x84 - void __init pcibios_init(void) { /* Reset PCI I/O and PCI MEM values */ @@ -549,20 +421,7 @@ pci_scan_bus(1, &galileo_pci_ops, NULL); } -/* - * for parsing "pci=" kernel boot arguments. - */ -char *pcibios_setup(char *str) -{ - printk(KERN_INFO "rr: pcibios_setup\n"); - /* Nothing to do for now. */ - - return str; -} - unsigned __init int pcibios_assign_all_busses(void) { return 1; } - -#endif /* CONFIG_PCI */ diff -urN linux-2.4.21-bk37/arch/mips/momentum/ocelot_g/setup.c linux-2.4.21-bk38/arch/mips/momentum/ocelot_g/setup.c --- linux-2.4.21-bk37/arch/mips/momentum/ocelot_g/setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/momentum/ocelot_g/setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -70,6 +70,10 @@ extern struct rtc_ops no_rtc_ops; +#ifdef CONFIG_GALILLEO_GT64240_ETH +extern unsigned char prom_mac_addr_base[6]; +#endif + unsigned long gt64240_base; /* These functions are used for rebooting or halting the machine*/ @@ -86,8 +90,6 @@ static void __init setup_l3cache(unsigned long size); -void __init bus_error_init(void) { /* nothing */ } - /* setup code for a handoff from a version 2 PMON 2000 PROM */ void PMON_v2_setup(void) { @@ -139,6 +141,11 @@ /* do handoff reconfiguration */ PMON_v2_setup(); +#ifdef CONFIG_GALILLEO_GT64240_ETH + /* get the mac addr */ + memcpy(prom_mac_addr_base, (void*)0xfc807cf2, 6); +#endif + /* Turn off the Bit-Error LED */ OCELOT_PLD_WRITE(0x80, INTCLR); @@ -213,11 +220,11 @@ GT_WRITE(0, tmp | (1<<14)); /* Enable the L3 cache in the CPU */ - set_cp0_config(1<<12 /* CONF_TE */); + set_c0_config(1<<12 /* CONF_TE */); /* Clear the cache */ - set_taglo(0); - set_taghi(0); + write_c0_taglo(0); + write_c0_taghi(0); for (i=0; i < size; i+= 4096) { __asm__ __volatile__ ( diff -urN linux-2.4.21-bk37/arch/mips/pci/Makefile linux-2.4.21-bk38/arch/mips/pci/Makefile --- linux-2.4.21-bk37/arch/mips/pci/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/pci/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,21 @@ +# +# Makefile for the Linux/MIPS kernel. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +O_TARGET := pci-core.o + +export-objs = pci.o + +obj-$(CONFIG_MIPS_BONITO64) += ops-bonito64.o +obj-$(CONFIG_MIPS_GT64120) += ops-gt64120.o +obj-$(CONFIG_MIPS_MSC) += ops-msc.o +obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o +obj-$(CONFIG_SNI_RM200_PCI) += ops-sni.o +obj-y += pci.o +obj-$(CONFIG_PCI_AUTO) += pci_auto.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/pci/ops-bonito64.c linux-2.4.21-bk38/arch/mips/pci/ops-bonito64.c --- linux-2.4.21-bk37/arch/mips/pci/ops-bonito64.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/pci/ops-bonito64.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,224 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#include +#include +#include +#include + +#include + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +/* + * PCI configuration cycle AD bus definition + */ +/* Type 0 */ +#define PCI_CFG_TYPE0_REG_SHF 0 +#define PCI_CFG_TYPE0_FUNC_SHF 8 + +/* Type 1 */ +#define PCI_CFG_TYPE1_REG_SHF 0 +#define PCI_CFG_TYPE1_FUNC_SHF 8 +#define PCI_CFG_TYPE1_DEV_SHF 11 +#define PCI_CFG_TYPE1_BUS_SHF 16 + +static int bonito64_config_access(unsigned char access_type, + struct pci_dev *dev, unsigned char where, u32 *data) +{ + unsigned char bus = dev->bus->number; + unsigned char dev_fn = dev->devfn; + unsigned char type; + u32 intr, dummy; + u64 pci_addr; + + if ((bus == 0) && (PCI_SLOT(dev_fn) == 0)) + return -1; + + /* Clear cause register bits */ + BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | BONITO_PCICMD_MTABORT_CLR); + + /* + * Setup pattern to be used as PCI "address" for Type 0 cycle + */ + if (bus == 0) { + /* IDSEL */ + pci_addr = (u64)1 << (PCI_SLOT(dev_fn) + 10); + } else { + /* Bus number */ + pci_addr = bus << PCI_CFG_TYPE1_BUS_SHF; + + /* Device number */ + pci_addr |= PCI_SLOT(dev_fn) << PCI_CFG_TYPE1_DEV_SHF; + } + + /* Function (same for Type 0/1) */ + pci_addr |= PCI_FUNC(dev_fn) << PCI_CFG_TYPE0_FUNC_SHF; + + /* Register number (same for Type 0/1) */ + pci_addr |= (where & ~0x3) << PCI_CFG_TYPE0_REG_SHF; + + if (bus == 0) { + /* Type 0 */ + BONITO_PCIMAP_CFG = pci_addr >> 16; + } else { + /* Type 1 */ + BONITO_PCIMAP_CFG = (pci_addr >> 16) | 0x10000; + } + + /* Flush Bonito register block */ + dummy = BONITO_PCIMAP_CFG; + iob(); /* sync */ + + /* Perform access */ + if (access_type == PCI_ACCESS_WRITE) { + *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE + + (pci_addr & 0xffff))) = *(u32 *)data; + + /* Wait till done */ + while (BONITO_PCIMSTAT & 0xF) + ; + } else { + *(u32 *)data = + *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE + + (pci_addr & 0xffff))); + } + + /* Detect Master/Target abort */ + if (BONITO_PCICMD & (BONITO_PCICMD_MABORT_CLR | + BONITO_PCICMD_MTABORT_CLR)) { + /* Error occurred */ + + /* Clear bits */ + BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | + BONITO_PCICMD_MTABORT_CLR); + + return -1; + } + + return 0; +} + + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int bonito64_read_config_byte (struct pci_dev *dev, int where, + u8 *val) +{ + u32 data = 0; + + if (bonito64_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + *val = (data >> ((where & 3) << 3)) & 0xff; + + return PCIBIOS_SUCCESSFUL; +} + +static int bonito64_read_config_word (struct pci_dev *dev, int where, + u16 *val) +{ + u32 data = 0; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (bonito64_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + *val = (data >> ((where & 3) << 3)) & 0xffff; + + return PCIBIOS_SUCCESSFUL; +} + +static int bonito64_read_config_dword (struct pci_dev *dev, int where, + u32 *val) +{ + u32 data = 0; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (bonito64_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + *val = data; + + return PCIBIOS_SUCCESSFUL; +} + +static int bonito64_write_config_byte (struct pci_dev *dev, int where, + u8 val) +{ + u32 data = 0; + + if (bonito64_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (bonito64_config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +static int bonito64_write_config_word (struct pci_dev *dev, int where, + u16 val) +{ + u32 data = 0; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (bonito64_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (bonito64_config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return -1; + + + return PCIBIOS_SUCCESSFUL; +} + +static int bonito64_write_config_dword(struct pci_dev *dev, int where, + u32 val) +{ + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (bonito64_config_access(PCI_ACCESS_WRITE, dev, where, &val)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops bonito64_pci_ops = { + bonito64_read_config_byte, + bonito64_read_config_word, + bonito64_read_config_dword, + bonito64_write_config_byte, + bonito64_write_config_word, + bonito64_write_config_dword +}; diff -urN linux-2.4.21-bk37/arch/mips/pci/ops-gt64120.c linux-2.4.21-bk38/arch/mips/pci/ops-gt64120.c --- linux-2.4.21-bk37/arch/mips/pci/ops-gt64120.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/pci/ops-gt64120.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,204 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#include +#include +#include + +#include + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +/* + * PCI configuration cycle AD bus definition + */ +/* Type 0 */ +#define PCI_CFG_TYPE0_REG_SHF 0 +#define PCI_CFG_TYPE0_FUNC_SHF 8 + +/* Type 1 */ +#define PCI_CFG_TYPE1_REG_SHF 0 +#define PCI_CFG_TYPE1_FUNC_SHF 8 +#define PCI_CFG_TYPE1_DEV_SHF 11 +#define PCI_CFG_TYPE1_BUS_SHF 16 + +#define GT_ERR_BITS (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT) + +static int gt64120_config_access(unsigned int access_type, + struct pci_dev *dev, unsigned char where, u32 *data) +{ + unsigned char bus = dev->bus->number; + unsigned char dev_fn = dev->devfn; + u32 intr, ret; + + /* + * Because of a bug in the galileo (for slot 31) and support for the + * 2nd bus of the Galileo is broken anyway ... + */ + if ((bus == 0) && (dev_fn >= PCI_DEVFN(31,0))) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* Clear cause register bits */ + intr = GT_READ(GT_INTRCAUSE_OFS); + GT_WRITE(GT_INTRCAUSE_OFS, intr & ~GT_ERR_BITS); + + /* Setup address */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (bus << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (dev_fn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + (where & ~0x3) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + + if (access_type == PCI_ACCESS_WRITE) { + if (bus == 0 && PCI_SLOT(dev_fn) == 0) { + /* + * The Galileo system controller is acting + * differently than other devices. + */ + GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); + } else + __GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); + } else { + if (bus == 0 && PCI_SLOT(dev_fn) == 0) { + /* + * The Galileo system controller is acting + * differently than other devices. + */ + ret = GT_READ(GT_PCI0_CFGDATA_OFS); + } else + ret = __GT_READ(GT_PCI0_CFGDATA_OFS); + } + + /* Check for master or target abort */ + intr = GT_READ(GT_INTRCAUSE_OFS); + + if (intr & GT_ERR_BITS) { /* Error occured */ + + /* Clear bits */ + intr = GT_READ(GT_INTRCAUSE_OFS); + GT_WRITE(GT_INTRCAUSE_OFS, intr & ~GT_ERR_BITS); + + return PCIBIOS_DEVICE_NOT_FOUND; + } + + *data = ret; + + return 0; +} + + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int gt64120_read_config_byte (struct pci_dev *dev, int where, u8 *val) +{ + u32 data; + + if (gt64120_config_access(PCI_ACCESS_READ, dev, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + *val = data >> ((where & 3) << 3); + + return PCIBIOS_SUCCESSFUL; +} + +static int gt64120_read_config_word (struct pci_dev *dev, int where, u16 *val) +{ + u32 data; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (gt64120_config_access(PCI_ACCESS_READ, dev, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + *val = data >> ((where & 3) << 3); + + return PCIBIOS_SUCCESSFUL; +} + +static int gt64120_read_config_dword (struct pci_dev *dev, int where, u32 *val) +{ + u32 data; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (gt64120_config_access(PCI_ACCESS_READ, dev, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + *val = data; + + return PCIBIOS_SUCCESSFUL; +} + +static int gt64120_write_config_byte (struct pci_dev *dev, int where, u8 val) +{ + u32 data = 0; + + if (gt64120_config_access(PCI_ACCESS_READ, dev, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (gt64120_config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + return PCIBIOS_SUCCESSFUL; +} + +static int gt64120_write_config_word (struct pci_dev *dev, int where, u16 val) +{ + u32 data = 0; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (gt64120_config_access(PCI_ACCESS_READ, dev, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (gt64120_config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + return PCIBIOS_SUCCESSFUL; +} + +static int gt64120_write_config_dword(struct pci_dev *dev, int where, u32 val) +{ + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (gt64120_config_access(PCI_ACCESS_WRITE, dev, where, &val)) + return PCIBIOS_DEVICE_NOT_FOUND; + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops gt64120_pci_ops = { + gt64120_read_config_byte, + gt64120_read_config_word, + gt64120_read_config_dword, + gt64120_write_config_byte, + gt64120_write_config_word, + gt64120_write_config_dword +}; diff -urN linux-2.4.21-bk37/arch/mips/pci/ops-msc.c linux-2.4.21-bk38/arch/mips/pci/ops-msc.c --- linux-2.4.21-bk37/arch/mips/pci/ops-msc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/pci/ops-msc.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,201 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#include +#include +#include +#include + +#include + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +/* + * PCI configuration cycle AD bus definition + */ +/* Type 0 */ +#define PCI_CFG_TYPE0_REG_SHF 0 +#define PCI_CFG_TYPE0_FUNC_SHF 8 + +/* Type 1 */ +#define PCI_CFG_TYPE1_REG_SHF 0 +#define PCI_CFG_TYPE1_FUNC_SHF 8 +#define PCI_CFG_TYPE1_DEV_SHF 11 +#define PCI_CFG_TYPE1_BUS_SHF 16 + +static int msc_config_access(unsigned char access_type, + struct pci_dev *dev, unsigned char where, u32 *data) +{ + unsigned char bus = dev->bus->number; + unsigned char dev_fn = dev->devfn; + unsigned char type; + u32 intr, dummy; + u64 pci_addr; + + if ((bus == 0) && (PCI_SLOT(dev_fn) == 0)) + return -1; + + /* Clear status register bits. */ + MSC_WRITE(MSC01_PCI_INTSTAT, + (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT)); + + /* Setup address */ + if (bus == 0) + type = 0; /* Type 0 */ + else + type = 1; /* Type 1 */ + + MSC_WRITE(MSC01_PCI_CFGADDR, + ((bus << MSC01_PCI_CFGADDR_BNUM_SHF) | + (PCI_SLOT(dev_fn) << MSC01_PCI_CFGADDR_DNUM_SHF) | + (PCI_FUNC(dev_fn) << MSC01_PCI_CFGADDR_FNUM_SHF) | + ((where /4 ) << MSC01_PCI_CFGADDR_RNUM_SHF) | + (type))); + + /* Perform access */ + if (access_type == PCI_ACCESS_WRITE) { + MSC_WRITE(MSC01_PCI_CFGDATA, *data); + } else { + MSC_READ(MSC01_PCI_CFGDATA, *data); + } + + /* Detect Master/Target abort */ + MSC_READ(MSC01_PCI_INTSTAT, intr); + if (intr & (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT)) { + /* Error occurred */ + + /* Clear bits */ + MSC_READ(MSC01_PCI_INTSTAT, intr); + MSC_WRITE(MSC01_PCI_INTSTAT, + (MSC01_PCI_INTCFG_MA_BIT | + MSC01_PCI_INTCFG_TA_BIT)); + + return -1; + } + + return 0; +} + + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int msc_read_config_byte (struct pci_dev *dev, int where, + u8 *val) +{ + u32 data = 0; + + if (msc_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + *val = (data >> ((where & 3) << 3)) & 0xff; + + return PCIBIOS_SUCCESSFUL; +} + +static int msc_read_config_word (struct pci_dev *dev, int where, + u16 *val) +{ + u32 data = 0; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (msc_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + *val = (data >> ((where & 3) << 3)) & 0xffff; + + return PCIBIOS_SUCCESSFUL; +} + +static int msc_read_config_dword (struct pci_dev *dev, int where, + u32 *val) +{ + u32 data = 0; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (msc_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + *val = data; + + return PCIBIOS_SUCCESSFUL; +} + +static int msc_write_config_byte (struct pci_dev *dev, int where, + u8 val) +{ + u32 data = 0; + + if (msc_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (msc_config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +static int msc_write_config_word (struct pci_dev *dev, int where, + u16 val) +{ + u32 data = 0; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (msc_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (msc_config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return -1; + + + return PCIBIOS_SUCCESSFUL; +} + +static int msc_write_config_dword(struct pci_dev *dev, int where, + u32 val) +{ + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (msc_config_access(PCI_ACCESS_WRITE, dev, where, &val)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops msc_pci_ops = { + msc_read_config_byte, + msc_read_config_word, + msc_read_config_dword, + msc_write_config_byte, + msc_write_config_word, + msc_write_config_dword +}; diff -urN linux-2.4.21-bk37/arch/mips/pci/ops-nile4.c linux-2.4.21-bk38/arch/mips/pci/ops-nile4.c --- linux-2.4.21-bk37/arch/mips/pci/ops-nile4.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/pci/ops-nile4.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,213 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +#define LO(reg) (reg / 4) +#define HI(reg) (reg / 4 + 1) + +static volatile unsigned long * const vrc_pciregs = (void *)Vrc5074_BASE; + +static spinlock_t nile4_pci_lock; + +static int nile4_pcibios_config_access(unsigned char access_type, + struct pci_dev *dev, unsigned char reg, u32 *data) +{ + unsigned char bus = dev->bus->number; + unsigned char dev_fn = dev->devfn; + u32 adr, mask, err; + + if ((bus == 0) && (PCI_SLOT(dev_fn) > 8)) + /* The addressing scheme chosen leaves room for just + * 8 devices on the first bus (besides the PCI + * controller itself) */ + return PCIBIOS_DEVICE_NOT_FOUND; + + if ((bus == 0) && (dev_fn == PCI_DEVFN(0,0))) { + /* Access controller registers directly */ + if (access_type == PCI_ACCESS_WRITE) { + vrc_pciregs[(0x200+reg) >> 2] = *data; + } else { + *data = vrc_pciregs[(0x200+reg) >> 2]; + } + return PCIBIOS_SUCCESSFUL; + } + + /* Temporarily map PCI Window 1 to config space */ + mask = vrc_pciregs[LO(NILE4_PCIINIT1)]; + vrc_pciregs[LO(NILE4_PCIINIT1)] = 0x0000001a | (bus ? 0x200 : 0); + + /* Clear PCI Error register. This also clears the Error Type + * bits in the Control register */ + vrc_pciregs[LO(NILE4_PCIERR)] = 0; + vrc_pciregs[HI(NILE4_PCIERR)] = 0; + + /* Setup address */ + if (bus == 0) + adr = KSEG1ADDR(PCI_WINDOW1) + + ((1 << (PCI_SLOT(dev_fn) + 15)) | + (PCI_FUNC(dev_fn) << 8) | (reg & ~3)); + else + adr = KSEG1ADDR(PCI_WINDOW1) | (bus << 16) | (dev_fn << 8) | + (reg & ~3); + + if (access_type == PCI_ACCESS_WRITE) + *(u32 *)adr = *data; + else + *data = *(u32 *)adr; + + /* Check for master or target abort */ + err = (vrc_pciregs[HI(NILE4_PCICTRL)] >> 5) & 0x7; + + /* Restore PCI Window 1 */ + vrc_pciregs[LO(NILE4_PCIINIT1)] = mask; + + if (err) + return PCIBIOS_DEVICE_NOT_FOUND; + + return PCIBIOS_SUCCESSFUL; +} + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int nile4_pcibios_read_config_byte(struct pci_dev *dev, int reg, u8 *val) +{ + unsigned long flags; + u32 data = 0; + int err; + + spin_lock_irqsave(&nile4_pci_lock, flags); + err = nile4_pcibios_config_access(PCI_ACCESS_READ, dev, reg, &data); + spin_unlock_irqrestore(&nile4_pci_lock, flags); + + if (err) + return err; + + *val = (data >> ((reg & 3) << 3)) & 0xff; + + return PCIBIOS_SUCCESSFUL; +} + +static int nile4_pcibios_read_config_word(struct pci_dev *dev, int reg, u16 *val) +{ + unsigned long flags; + u32 data = 0; + int err; + + if (reg & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + spin_lock_irqsave(&nile4_pci_lock, flags); + err = nile4_pcibios_config_access(PCI_ACCESS_READ, dev, reg, &data); + spin_unlock_irqrestore(&nile4_pci_lock, flags); + + if (err) + return err; + + *val = (data >> ((reg & 3) << 3)) & 0xffff; + + return PCIBIOS_SUCCESSFUL; +} + +static int nile4_pcibios_read_config_dword(struct pci_dev *dev, int reg, u32 *val) +{ + unsigned long flags; + u32 data = 0; + int err; + + if (reg & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + spin_lock_irqsave(&nile4_pci_lock, flags); + err = nile4_pcibios_config_access(PCI_ACCESS_READ, dev, reg, &data); + spin_unlock_irqrestore(&nile4_pci_lock, flags); + + if (err) + return err; + + *val = data; + + return PCIBIOS_SUCCESSFUL; +} + + +static int nile4_pcibios_write_config_byte(struct pci_dev *dev, int reg, u8 val) +{ + unsigned long flags; + u32 data = 0; + int err; + + spin_lock_irqsave(&nile4_pci_lock, flags); + err = nile4_pcibios_config_access(PCI_ACCESS_READ, dev, reg, &data); + if (err) + goto out; + + data = (data & ~(0xff << ((reg & 3) << 3))) | (val << ((reg & 3) << 3)); + err = nile4_pcibios_config_access(PCI_ACCESS_WRITE, dev, reg, &data); + +out: + spin_unlock_irqrestore(&nile4_pci_lock, flags); + return err; +} + +static int nile4_pcibios_write_config_word(struct pci_dev *dev, int reg, u16 val) +{ + unsigned long flags; + u32 data = 0; + int err; + + if (reg & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + spin_lock_irqsave(&nile4_pci_lock, flags); + err = nile4_pcibios_config_access(PCI_ACCESS_READ, dev, reg, &data); + if (err) + goto out; + + data = (data & ~(0xffff << ((reg & 3) << 3))) | (val << ((reg&3) << 3)); + err = nile4_pcibios_config_access(PCI_ACCESS_WRITE, dev, reg, &data); + +out: + spin_unlock_irqrestore(&nile4_pci_lock, flags); + return err; +} + +static int nile4_pcibios_write_config_dword(struct pci_dev *dev, int reg, u32 val) +{ + unsigned long flags; + u32 data = 0; + int err; + + if (reg & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + spin_lock_irqsave(&nile4_pci_lock, flags); + err = nile4_pcibios_config_access(PCI_ACCESS_WRITE, dev, reg, &val); + spin_unlock_irqrestore(&nile4_pci_lock, flags); + + if (err) + return -1; + else + return PCIBIOS_SUCCESSFUL; +out: + return err; +} + +struct pci_ops nile4_pci_ops = { + nile4_pcibios_read_config_byte, + nile4_pcibios_read_config_word, + nile4_pcibios_read_config_dword, + nile4_pcibios_write_config_byte, + nile4_pcibios_write_config_word, + nile4_pcibios_write_config_dword +}; diff -urN linux-2.4.21-bk37/arch/mips/pci/ops-sni.c linux-2.4.21-bk38/arch/mips/pci/ops-sni.c --- linux-2.4.21-bk37/arch/mips/pci/ops-sni.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/pci/ops-sni.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,113 @@ +/* + * 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. + * + * SNI specific PCI support for RM200/RM300. + * + * Copyright (C) 1997 - 2000, 2003 Ralf Baechle + */ +#include +#include +#include +#include +#include +#include +#include + +#define mkaddr(dev, where) \ +do { \ + if ((dev)->bus->number == 0) \ + return -1; \ + *(volatile u32 *)PCIMT_CONFIG_ADDRESS = \ + ((dev->bus->number & 0xff) << 0x10) | \ + ((dev->devfn & 0xff) << 0x08) | \ + (where & 0xfc); \ +} while(0) + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int pcimt_read_config_byte (struct pci_dev *dev, + int where, unsigned char *val) +{ + u32 res; + + mkaddr(dev, where); + res = *(volatile u32 *)PCIMT_CONFIG_DATA; + res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xff; + *val = res; + + return PCIBIOS_SUCCESSFUL; +} + +static int pcimt_read_config_word (struct pci_dev *dev, + int where, unsigned short *val) +{ + u32 res; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + mkaddr(dev, where); + res = *(volatile u32 *)PCIMT_CONFIG_DATA; + res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xffff; + *val = res; + + return PCIBIOS_SUCCESSFUL; +} + +static int pcimt_read_config_dword (struct pci_dev *dev, + int where, unsigned int *val) +{ + u32 res; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + mkaddr(dev, where); + res = *(volatile u32 *)PCIMT_CONFIG_DATA; + res = le32_to_cpu(res); + *val = res; + + return PCIBIOS_SUCCESSFUL; +} + +static int pcimt_write_config_byte (struct pci_dev *dev, + int where, unsigned char val) +{ + mkaddr(dev, where); + *(volatile u8 *)(PCIMT_CONFIG_DATA + (where & 3)) = val; + + return PCIBIOS_SUCCESSFUL; +} + +static int pcimt_write_config_word (struct pci_dev *dev, + int where, unsigned short val) +{ + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + mkaddr(dev, where); + *(volatile u16 *)(PCIMT_CONFIG_DATA + (where & 3)) = le16_to_cpu(val); + + return PCIBIOS_SUCCESSFUL; +} + +static int pcimt_write_config_dword (struct pci_dev *dev, + int where, unsigned int val) +{ + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + mkaddr(dev, where); + *(volatile u32 *)PCIMT_CONFIG_DATA = le32_to_cpu(val); + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops sni_pci_ops = { + pcimt_read_config_byte, + pcimt_read_config_word, + pcimt_read_config_dword, + pcimt_write_config_byte, + pcimt_write_config_word, + pcimt_write_config_dword +}; diff -urN linux-2.4.21-bk37/arch/mips/pci/pci.c linux-2.4.21-bk38/arch/mips/pci/pci.c --- linux-2.4.21-bk37/arch/mips/pci/pci.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/pci/pci.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,272 @@ +/* + * 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. + */ +#include +#include +#include +#include +#include + +#include + +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); + if (resource < 6) { + reg = PCI_BASE_ADDRESS_0 + 4*resource; + } else if (resource == PCI_ROM_RESOURCE) { + res->flags |= PCI_ROM_ADDRESS_ENABLE; + new |= PCI_ROM_ADDRESS_ENABLE; + reg = dev->rom_base_reg; + } else { + /* Somebody might have asked allocation of a non-standard resource */ + return; + } + + pci_write_config_dword(dev, reg, new); + pci_read_config_dword(dev, reg, &check); + if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) { + printk(KERN_ERR "PCI: Error while updating region " + "%s/%d (%08x != %08x)\n", dev->slot_name, resource, + new, check); + } +} + +/* + * We need to avoid collisions with `mirrored' VGA ports + * and other strange ISA hardware, so we always want the + * addresses to be allocated in the 0x000-0x0ff region + * modulo 0x400. + * + * Why? Because some silly external IO cards only decode + * the low 10 bits of the IO address. The 0x00-0xff region + * is reserved for motherboard devices that decode all 16 + * bits, so it's ok to allocate at, say, 0x2800-0x28ff, + * but we want to try to avoid allocating at 0x2900-0x2bff + * which might have be mirrored at 0x0100-0x03ff.. + */ +void +pcibios_align_resource(void *data, struct resource *res, + unsigned long size, unsigned long align) +{ + if (res->flags & IORESOURCE_IO) { + unsigned long start = res->start; + + if (start & 0x300) { + start = (start + 0x3ff) & ~0x3ff; + res->start = start; + } + } +} + +/* + * If we set up a device for bus mastering, we need to check the latency + * timer as certain crappy BIOSes forget to set it properly. + */ +unsigned int pcibios_max_latency = 255; + +void pcibios_set_master(struct pci_dev *dev) +{ + u8 lat; + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); + if (lat < 16) + lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; + else if (lat > pcibios_max_latency) + lat = pcibios_max_latency; + else + return; + printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); +} + +char * __devinit pcibios_setup(char *str) +{ + return str; +} + +static int pcibios_enable_resources(struct pci_dev *dev, int mask) +{ + u16 cmd, old_cmd; + int idx; + struct resource *r; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for(idx=0; idx<6; idx++) { + /* Only set up the requested stuff */ + if (!(mask & (1<resource[idx]; + if (!r->start && r->end) { + printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (dev->resource[PCI_ROM_RESOURCE].start) + cmd |= PCI_COMMAND_MEMORY; + if (cmd != old_cmd) { + printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + return 0; +} + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + return pcibios_enable_resources(dev, mask); +} + +#ifdef CONFIG_NEW_PCI +/* + * Named PCI new and about to die before it's old :-) + * + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * Modified to be mips generic, ppopov@mvista.com + */ + +/* + * This file contains common PCI routines meant to be shared for + * all MIPS machines. + * + * Strategies: + * + * . We rely on pci_auto.c file to assign PCI resources (MEM and IO) + * TODO: this shold be optional for some machines where they do have + * a real "pcibios" that does resource assignment. + * + * . We then use pci_scan_bus() to "discover" all the resources for + * later use by Linux. + * + * . We finally reply on a board supplied function, pcibios_fixup_irq(), to + * to assign the interrupts. We may use setup-irq.c under drivers/pci + * later. + * + * . Specifically, we will *NOT* use pci_assign_unassigned_resources(), + * because we assume all PCI devices should have the resources correctly + * assigned and recorded. + * + * Limitations: + * + * . We "collapse" all IO and MEM spaces in sub-buses under a top-level bus + * into a contiguous range. + * + * . In the case of Memory space, the rnage is 1:1 mapping with CPU physical + * address space. + * + * . In the case of IO space, it starts from 0, and the beginning address + * is mapped to KSEG0ADDR(mips_io_port) in the CPU physical address. + * + * . These are the current MIPS limitations (by ioremap, etc). In the + * future, we may remove them. + * + * Credits: + * Most of the code are derived from the pci routines from PPC and Alpha, + * which were mostly writtne by + * Cort Dougan, cort@fsmlabs.com + * Matt Porter, mporter@mvista.com + * Dave Rusling david.rusling@reo.mts.dec.com + * David Mosberger davidm@cs.arizona.edu + */ + +extern void pcibios_fixup(void); +extern void pcibios_fixup_irqs(void); + +struct pci_fixup pcibios_fixups[] = { + { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources }, + { 0 } +}; + +extern int pciauto_assign_resources(int busno, struct pci_channel * hose); + +void __init pcibios_init(void) +{ + struct pci_channel *p; + struct pci_bus *bus; + int busno; + +#ifdef CONFIG_PCI_AUTO + /* assign resources */ + busno=0; + for (p= mips_pci_channels; p->pci_ops != NULL; p++) { + busno = pciauto_assign_resources(busno, p) + 1; + } +#endif + + /* scan the buses */ + busno = 0; + for (p= mips_pci_channels; p->pci_ops != NULL; p++) { + bus = pci_scan_bus(busno, p->pci_ops, p); + busno = bus->subordinate+1; + } + + /* machine dependent fixups */ + pcibios_fixup(); + /* fixup irqs (board specific routines) */ + pcibios_fixup_irqs(); +} + +unsigned long __init pci_bridge_check_io(struct pci_dev *bridge) +{ + u16 io; + + pci_read_config_word(bridge, PCI_IO_BASE, &io); + if (!io) { + pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0); + pci_read_config_word(bridge, PCI_IO_BASE, &io); + pci_write_config_word(bridge, PCI_IO_BASE, 0x0); + } + if (io) + return IORESOURCE_IO; + printk(KERN_WARNING "PCI: bridge %s does not support I/O forwarding!\n", + bridge->name); + return 0; +} + +void __init pcibios_fixup_bus(struct pci_bus *bus) +{ + /* Propogate hose info into the subordinate devices. */ + + struct pci_channel *hose = bus->sysdata; + struct pci_dev *dev = bus->self; + + if (!dev) { + /* Root bus */ + bus->resource[0] = hose->io_resource; + bus->resource[1] = hose->mem_resource; + } else { + /* This is a bridge. Do not care how it's initialized, + just link its resources to the bus ones */ + 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]->flags |= pci_bridge_check_io(dev); + bus->resource[1]->flags |= IORESOURCE_MEM; + /* For now, propogate hose limits to the bus; + we'll adjust them later. */ + bus->resource[0]->end = hose->io_resource->end; + bus->resource[1]->end = hose->mem_resource->end; + /* Turn off downstream PF memory address range by default */ + bus->resource[2]->start = 1024*1024; + bus->resource[2]->end = bus->resource[2]->start - 1; + } +} +#endif diff -urN linux-2.4.21-bk37/arch/mips/pci/pci_auto.c linux-2.4.21-bk38/arch/mips/pci/pci_auto.c --- linux-2.4.21-bk37/arch/mips/pci/pci_auto.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/pci/pci_auto.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,508 @@ +/* + * PCI autoconfiguration library + * + * Author: Matt Porter + * + * Copyright 2000, 2001, 2002, 2003 MontaVista Software Inc. + * Copyright 2001 Bradley D. LaRonde + * + * 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. + */ + +/* + * Modified for MIPS by Jun Sun, jsun@mvista.com + * + * . Simplify the interface between pci_auto and the rest: a single function. + * . Assign resources from low address to upper address. + * . change most int to u32. + * + * Further modified to include it as mips generic code, ppopov@mvista.com. + * + * 2001-10-26 Bradley D. LaRonde + * - Add a top_bus argument to the "early config" functions so that + * they can set a fake parent bus pointer to convince the underlying + * pci ops to use type 1 configuration for sub busses. + * - Set bridge base and limit registers correctly. + * - Align io and memory base properly before and after bridge setup. + * - Don't fall through to pci_setup_bars for bridge. + * - Reformat the debug output to look more like lspci's output. + * + * 2003-04-09 Yoichi Yuasa, Alice Hennessy, Jun Sun + * - Add cardbus bridge support, mostly copied from PPC + */ + +#include +#include +#include +#include + +#include + +#define DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +/* + * 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_channel *hose, + int top_bus, int busnr, int devfn) +{ + static struct pci_dev dev; + static struct pci_bus bus; + + dev.bus = &bus; + dev.sysdata = hose; + dev.devfn = devfn; + bus.number = busnr; + bus.ops = hose->pci_ops; + + if(busnr != top_bus) + /* Fake a parent bus structure. */ + bus.parent = &bus; + else + bus.parent = NULL; + + return &dev; +} + +#define EARLY_PCI_OP(rw, size, type) \ +int early_##rw##_config_##size(struct pci_channel *hose, \ + int top_bus, int bus, int devfn, int offset, type value) \ +{ \ + return pci_##rw##_config_##size( \ + fake_pci_dev(hose, top_bus, 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) + +static struct resource *io_resource_inuse; +static struct resource *mem_resource_inuse; + +static u32 pciauto_lower_iospc; +static u32 pciauto_upper_iospc; + +static u32 pciauto_lower_memspc; +static u32 pciauto_upper_memspc; + +void __init +pciauto_setup_bars(struct pci_channel *hose, + int top_bus, + int current_bus, + int pci_devfn, + int bar_limit) +{ + u32 bar_response, bar_size, bar_value; + u32 bar, addr_mask, bar_nr = 0; + u32 * upper_limit; + u32 * lower_limit; + int found_mem64 = 0; + + for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4) { + /* Tickle the BAR and get the response */ + early_write_config_dword(hose, top_bus, + current_bus, + pci_devfn, + bar, + 0xffffffff); + early_read_config_dword(hose, top_bus, + current_bus, + pci_devfn, + bar, + &bar_response); + + /* If BAR is not implemented go to the next BAR */ + if (!bar_response) + continue; + + /* + * Workaround for a BAR that doesn't use its upper word, + * like the ALi 1535D+ PCI DC-97 Controller Modem (M5457). + * bdl + */ + if (!(bar_response & 0xffff0000)) + bar_response |= 0xffff0000; + +retry: + /* Check the BAR type and set our address mask */ + if (bar_response & PCI_BASE_ADDRESS_SPACE) { + addr_mask = PCI_BASE_ADDRESS_IO_MASK; + upper_limit = &pciauto_upper_iospc; + lower_limit = &pciauto_lower_iospc; + DBG(" I/O"); + } else { + if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == + PCI_BASE_ADDRESS_MEM_TYPE_64) + found_mem64 = 1; + + addr_mask = PCI_BASE_ADDRESS_MEM_MASK; + upper_limit = &pciauto_upper_memspc; + lower_limit = &pciauto_lower_memspc; + DBG(" Mem"); + } + + + /* Calculate requested size */ + bar_size = ~(bar_response & addr_mask) + 1; + + /* Allocate a base address */ + bar_value = ((*lower_limit - 1) & ~(bar_size - 1)) + bar_size; + + if ((bar_value + bar_size) > *upper_limit) { + if (bar_response & PCI_BASE_ADDRESS_SPACE) { + if (io_resource_inuse->child) { + io_resource_inuse = + io_resource_inuse->child; + pciauto_lower_iospc = + io_resource_inuse->start; + pciauto_upper_iospc = + io_resource_inuse->end + 1; + goto retry; + } + + } else { + if (mem_resource_inuse->child) { + mem_resource_inuse = + mem_resource_inuse->child; + pciauto_lower_memspc = + mem_resource_inuse->start; + pciauto_upper_memspc = + mem_resource_inuse->end + 1; + goto retry; + } + } + DBG(" unavailable -- skipping\n"); + continue; + } + + /* Write it out and update our limit */ + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + bar, bar_value); + + *lower_limit = bar_value + bar_size; + + /* + * If we are a 64-bit decoder then increment to the + * upper 32 bits of the bar and force it to locate + * in the lower 4GB of memory. + */ + if (found_mem64) { + bar += 4; + early_write_config_dword(hose, top_bus, + current_bus, + pci_devfn, + bar, + 0x00000000); + } + + DBG(" at 0x%.8x [size=0x%x]\n", bar_value, bar_size); + + bar_nr++; + } + +} + +void __init +pciauto_prescan_setup_bridge(struct pci_channel *hose, + int top_bus, + int current_bus, + int pci_devfn, + int sub_bus) +{ + /* Configure bus number registers */ + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_PRIMARY_BUS, current_bus); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SECONDARY_BUS, sub_bus + 1); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SUBORDINATE_BUS, 0xff); + + /* Align memory and I/O to 1MB and 4KB boundaries. */ + pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1)) + & ~(0x100000 - 1); + pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1)) + & ~(0x1000 - 1); + + /* Set base (lower limit) of address range behind bridge. */ + early_write_config_word(hose, top_bus, current_bus, pci_devfn, + PCI_MEMORY_BASE, pciauto_lower_memspc >> 16); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_IO_BASE, (pciauto_lower_iospc & 0x0000f000) >> 8); + early_write_config_word(hose, top_bus, current_bus, pci_devfn, + PCI_IO_BASE_UPPER16, pciauto_lower_iospc >> 16); + + /* We don't support prefetchable memory for now, so disable */ + early_write_config_word(hose, top_bus, current_bus, pci_devfn, + PCI_PREF_MEMORY_BASE, 0); + early_write_config_word(hose, top_bus, current_bus, pci_devfn, + PCI_PREF_MEMORY_LIMIT, 0); +} + +void __init +pciauto_postscan_setup_bridge(struct pci_channel *hose, + int top_bus, + int current_bus, + int pci_devfn, + int sub_bus) +{ + u32 temp; + + /* + * [jsun] we always bump up baselines a little, so that if there + * nothing behind P2P bridge, we don't wind up overlapping IO/MEM + * spaces. + */ + pciauto_lower_memspc += 1; + pciauto_lower_iospc += 1; + + /* Configure bus number registers */ + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SUBORDINATE_BUS, sub_bus); + + /* Set upper limit of address range behind bridge. */ + early_write_config_word(hose, top_bus, current_bus, pci_devfn, + PCI_MEMORY_LIMIT, pciauto_lower_memspc >> 16); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_IO_LIMIT, (pciauto_lower_iospc & 0x0000f000) >> 8); + early_write_config_word(hose, top_bus, current_bus, pci_devfn, + PCI_IO_LIMIT_UPPER16, pciauto_lower_iospc >> 16); + + /* Align memory and I/O to 1MB and 4KB boundaries. */ + pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1)) + & ~(0x100000 - 1); + pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1)) + & ~(0x1000 - 1); + + /* Enable memory and I/O accesses, enable bus master */ + early_read_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_COMMAND, &temp); + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY + | PCI_COMMAND_MASTER); +} + +void __init +pciauto_prescan_setup_cardbus_bridge(struct pci_channel *hose, + int top_bus, + int current_bus, + int pci_devfn, + int sub_bus) +{ + /* Configure bus number registers */ + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_PRIMARY_BUS, current_bus); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SECONDARY_BUS, sub_bus + 1); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SUBORDINATE_BUS, 0xff); + + /* Align memory and I/O to 4KB and 4 byte boundaries. */ + pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1)) + & ~(0x1000 - 1); + pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1)) + & ~(0x4 - 1); + + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_CB_MEMORY_BASE_0, pciauto_lower_memspc); + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_CB_IO_BASE_0, pciauto_lower_iospc); +} + +void __init +pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose, + int top_bus, + int current_bus, + int pci_devfn, + int sub_bus) +{ + u32 temp; + + /* + * Configure subordinate bus number. The PCI subsystem + * bus scan will renumber buses (reserving three additional + * for this PCI<->CardBus bridge for the case where a CardBus + * adapter contains a P2P or CB2CB bridge. + */ + + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SUBORDINATE_BUS, sub_bus); + + /* + * Reserve an additional 4MB for mem space and 16KB for + * I/O space. This should cover any additional space + * requirement of unusual CardBus devices with + * additional bridges that can consume more address space. + * + * Although pcmcia-cs currently will reprogram bridge + * windows, the goal is to add an option to leave them + * alone and use the bridge window ranges as the regions + * that are searched for free resources upon hot-insertion + * of a device. This will allow a PCI<->CardBus bridge + * configured by this routine to happily live behind a + * P2P bridge in a system. + */ + pciauto_lower_memspc += 0x00400000; + pciauto_lower_iospc += 0x00004000; + + /* Align memory and I/O to 4KB and 4 byte boundaries. */ + pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1)) + & ~(0x1000 - 1); + pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1)) + & ~(0x4 - 1); + /* Set up memory and I/O filter limits, assume 32-bit I/O space */ + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_CB_MEMORY_LIMIT_0, pciauto_lower_memspc - 1); + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_CB_IO_LIMIT_0, pciauto_lower_iospc - 1); + + /* Enable memory and I/O accesses, enable bus master */ + early_read_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_COMMAND, &temp); + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY + | PCI_COMMAND_MASTER); +} + +#define PCIAUTO_IDE_MODE_MASK 0x05 + +int __init +pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus) +{ + int sub_bus; + u32 pci_devfn, pci_class, cmdstat, found_multi=0; + unsigned short vid, did; + unsigned char header_type; + int devfn_start = 0; + int devfn_stop = 0xff; + + sub_bus = current_bus; + + if (hose->first_devfn) + devfn_start = hose->first_devfn; + if (hose->last_devfn) + devfn_stop = hose->last_devfn; + + for (pci_devfn=devfn_start; pci_devfn> 16, vid, did); + if (pci_class & 0xff) + DBG(" (rev %.2x)", pci_class & 0xff); + DBG("\n"); + + if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) { + DBG(" Bridge: primary=%.2x, secondary=%.2x\n", + current_bus, sub_bus + 1); + pciauto_setup_bars(hose, top_bus, current_bus, + pci_devfn, PCI_BASE_ADDRESS_1); + pciauto_prescan_setup_bridge(hose, top_bus, current_bus, + pci_devfn, sub_bus); + DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", + sub_bus + 1, + pciauto_lower_iospc, pciauto_lower_memspc); + sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1); + DBG("Back to bus %.2x\n", current_bus); + pciauto_postscan_setup_bridge(hose, top_bus, current_bus, + pci_devfn, sub_bus); + continue; + } else if ((pci_class >> 16) == PCI_CLASS_BRIDGE_CARDBUS) { + DBG(" CARDBUS Bridge: primary=%.2x, secondary=%.2x\n", + current_bus, sub_bus + 1); + DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn)); + /* Place CardBus Socket/ExCA registers */ + pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_0); + + pciauto_prescan_setup_cardbus_bridge(hose, top_bus, + current_bus, pci_devfn, sub_bus); + + DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", + sub_bus + 1, + pciauto_lower_iospc, pciauto_lower_memspc); + sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1); + DBG("Back to bus %.2x, sub_bus is %x\n", current_bus, sub_bus); + pciauto_postscan_setup_cardbus_bridge(hose, top_bus, + current_bus, pci_devfn, sub_bus); + continue; + } else if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) { + + unsigned char prg_iface; + + early_read_config_byte(hose, top_bus, current_bus, + pci_devfn, PCI_CLASS_PROG, &prg_iface); + if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) { + DBG("Skipping legacy mode IDE controller\n"); + continue; + } + } + + /* + * Found a peripheral, enable some standard + * settings + */ + early_read_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_COMMAND, &cmdstat); + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_COMMAND, cmdstat | PCI_COMMAND_IO | + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_LATENCY_TIMER, 0x80); + + /* Allocate PCI I/O and/or memory space */ + pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_5); + } + return sub_bus; +} + +int __init +pciauto_assign_resources(int busno, struct pci_channel *hose) +{ + /* setup resource limits */ + io_resource_inuse = hose->io_resource; + mem_resource_inuse = hose->mem_resource; + + pciauto_lower_iospc = io_resource_inuse->start; + pciauto_upper_iospc = io_resource_inuse->end + 1; + pciauto_lower_memspc = mem_resource_inuse->start; + pciauto_upper_memspc = mem_resource_inuse->end + 1; + DBG("Autoconfig PCI channel 0x%p\n", hose); + DBG("Scanning bus %.2x, I/O 0x%.8x:0x%.8x, Mem 0x%.8x:0x%.8x\n", + busno, pciauto_lower_iospc, pciauto_upper_iospc, + pciauto_lower_memspc, pciauto_upper_memspc); + + return pciauto_bus_scan(hose, busno, busno); +} diff -urN linux-2.4.21-bk37/arch/mips/philips/nino/Makefile linux-2.4.21-bk38/arch/mips/philips/nino/Makefile --- linux-2.4.21-bk37/arch/mips/philips/nino/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/philips/nino/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -6,10 +6,7 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(AFLAGS) $< -o $@ -.S.o: - $(CC) $(AFLAGS) -c $< -o $@ +USE_STANDARD_AS_RULE := true O_TARGET := nino.o diff -urN linux-2.4.21-bk37/arch/mips/philips/nino/irq.c linux-2.4.21-bk38/arch/mips/philips/nino/irq.c --- linux-2.4.21-bk37/arch/mips/philips/nino/irq.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/philips/nino/irq.c 2003-08-24 02:55:57.000000000 -0700 @@ -9,7 +9,9 @@ * * Interrupt service routines for Philips Nino */ +#include #include +#include #include #include #include @@ -18,8 +20,6 @@ #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) -extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs); - static void enable_irq6(unsigned int irq) { if(irq == 0) { @@ -112,7 +112,7 @@ static void enable_irq4(unsigned int irq) { - set_cp0_status(STATUSF_IP4); + set_c0_status(STATUSF_IP4); if (irq == 2) { outl(inl(TX3912_INT2_CLEAR) | TX3912_INT2_UARTA_TX_BITS, TX3912_INT2_CLEAR); @@ -130,7 +130,7 @@ static void disable_irq4(unsigned int irq) { - clear_cp0_status(STATUSF_IP4); + clear_c0_status(STATUSF_IP4); } #define shutdown_irq4 disable_irq4 @@ -198,7 +198,7 @@ unsigned int i; /* Disable all hardware interrupts */ - change_cp0_status(ST0_IM, 0x00); + change_c0_status(ST0_IM, 0x00); /* Clear interrupts */ outl(0xffffffff, TX3912_INT1_CLEAR); @@ -243,14 +243,14 @@ TX3912_INT6_ENABLE); /* Enable all interrupts */ - change_cp0_status(ST0_IM, ALLINTS); + change_c0_status(ST0_IM, ALLINTS); } void (*irq_setup)(void); void __init init_IRQ(void) { -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void breakpoint(void); extern void set_debug_traps(void); diff -urN linux-2.4.21-bk37/arch/mips/philips/nino/power.c linux-2.4.21-bk38/arch/mips/philips/nino/power.c --- linux-2.4.21-bk37/arch/mips/philips/nino/power.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/philips/nino/power.c 2003-08-24 02:55:57.000000000 -0700 @@ -19,7 +19,7 @@ outl(inl(TX3912_POWER_CTRL) | TX3912_POWER_CTRL_STOPCPU, TX3912_POWER_CTRL); - /* + /* * We wait until an interrupt happens... */ diff -urN linux-2.4.21-bk37/arch/mips/philips/nino/prom.c linux-2.4.21-bk38/arch/mips/philips/nino/prom.c --- linux-2.4.21-bk37/arch/mips/philips/nino/prom.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/philips/nino/prom.c 2003-08-24 02:55:57.000000000 -0700 @@ -6,7 +6,7 @@ * 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. - * + * * Early initialization code for the Philips Nino */ #include @@ -60,8 +60,8 @@ * memory and mark it as reserved. */ free_end = (mem_size - tx3912fb_size) & PAGE_MASK; - add_memory_region(0, free_end, BOOT_MEM_RAM); - add_memory_region(free_end, (mem_size - free_end), BOOT_MEM_RESERVED); + add_memory_region(0, free_end, BOOT_MEM_RAM); + add_memory_region(free_end, (mem_size - free_end), BOOT_MEM_RESERVED); /* * Calculate physical and virtual addresses for @@ -71,7 +71,7 @@ tx3912fb_vaddr = KSEG1ADDR(free_end); } #else - add_memory_region(0, mem_size, BOOT_MEM_RAM); + add_memory_region(0, mem_size, BOOT_MEM_RAM); #endif } diff -urN linux-2.4.21-bk37/arch/mips/philips/nino/setup.c linux-2.4.21-bk38/arch/mips/philips/nino/setup.c --- linux-2.4.21-bk37/arch/mips/philips/nino/setup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/philips/nino/setup.c 2003-08-24 02:55:57.000000000 -0700 @@ -9,6 +9,7 @@ * * Interrupt and exception initialization for Philips Nino */ +#include #include #include #include @@ -18,6 +19,7 @@ #include #include #include +#include #include static void nino_machine_restart(char *command) @@ -80,6 +82,7 @@ setup_irq(0, irq); } + void __init nino_setup(void) { extern void nino_irq_setup(void); diff -urN linux-2.4.21-bk37/arch/mips/ramdisk/Makefile linux-2.4.21-bk38/arch/mips/ramdisk/Makefile --- linux-2.4.21-bk37/arch/mips/ramdisk/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/ramdisk/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -7,9 +7,9 @@ # O_FORMAT = $(shell $(OBJDUMP) -i | head -2 | grep elf32) -ramdisk.o: ramdisk.gz ld.script +img = $(CONFIG_EMBEDDED_RAMDISK_IMAGE) +ramdisk.o: $(subst ",,$(img)) ld.script echo "O_FORMAT: " $(O_FORMAT) - $(LD) -T ld.script -b binary --oformat $(O_FORMAT) -o $@ ramdisk.gz + $(LD) -T ld.script -b binary --oformat $(O_FORMAT) -o $@ $(img) include $(TOPDIR)/Rules.make - diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip22/Makefile linux-2.4.21-bk38/arch/mips/sgi-ip22/Makefile --- linux-2.4.21-bk37/arch/mips/sgi-ip22/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip22/Makefile 2003-08-24 02:55:57.000000000 -0700 @@ -2,11 +2,9 @@ # Makefile for the SGI specific kernel interface routines # under Linux. # -# Note! Dependencies are done automagically by 'make dep', which also +# Note: Dependencies are done automagically by 'make dep', which also # removes any old dependencies. DON'T put your own dependencies here # unless it's something special (ie not a .c file). -# -# Note 2! The CFLAGS definitions are now in the main makefile... USE_STANDARD_AS_RULE := true @@ -14,11 +12,13 @@ all: ip22-kern.o ip22-irq.o -obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-irq.o ip22-time.o ip22-berr.o \ - ip22-gio.o ip22-rtc.o ip22-reset.o ip22-system.o ip22-setup.o +obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-irq.o ip22-berr.o \ + ip22-time.o ip22-rtc.o ip22-nvram.o ip22-reset.o \ + ip22-setup.o ip22-ksyms.o + +obj-$(CONFIG_IP22_EISA) += ip22-eisa.o -obj-$(CONFIG_BOARD_SCACHE) += ip22-sc.o -obj-$(CONFIG_IP22_EISA) += ip22-eisa.o +export-objs := ip22-ksyms.o ip22-irq.o: ip22-irq.S diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-berr.c linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-berr.c --- linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-berr.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-berr.c 2003-08-24 02:55:57.000000000 -0700 @@ -1,7 +1,7 @@ /* * ip22-berr.c: Bus error handling. * - * Copyright (C) 2002 Ladislav Michl + * Copyright (C) 2002, 2003 Ladislav Michl (ladis@linux-mips.org) */ #include @@ -12,25 +12,70 @@ #include #include #include -#include -#include +#include +#include +#include +#include -unsigned int cpu_err_stat; /* Status reg for CPU */ -unsigned int gio_err_stat; /* Status reg for GIO */ -unsigned int cpu_err_addr; /* Error address reg for CPU */ -unsigned int gio_err_addr; /* Error address reg for GIO */ -volatile int nofault; +static unsigned int cpu_err_stat; /* Status reg for CPU */ +static unsigned int gio_err_stat; /* Status reg for GIO */ +static unsigned int cpu_err_addr; /* Error address reg for CPU */ +static unsigned int gio_err_addr; /* Error address reg for GIO */ +static unsigned int extio_stat; +static unsigned int hpc3_berr_stat; /* Bus error interrupt status */ static void save_and_clear_buserr(void) { - /* save memory controler's error status registers */ - cpu_err_addr = mcmisc_regs->cerr; - cpu_err_stat = mcmisc_regs->cstat; - gio_err_addr = mcmisc_regs->gerr; - gio_err_stat = mcmisc_regs->gstat; + /* save status registers */ + cpu_err_addr = sgimc->cerr; + cpu_err_stat = sgimc->cstat; + gio_err_addr = sgimc->gerr; + gio_err_stat = sgimc->gstat; + extio_stat = ip22_is_fullhouse() ? sgioc->extio : (sgint->errstat << 4); + hpc3_berr_stat = hpc3c0->bestat; - mcmisc_regs->cstat = mcmisc_regs->gstat = 0; + sgimc->cstat = sgimc->gstat = 0; +} + +#define GIO_ERRMASK 0xff00 +#define CPU_ERRMASK 0x3f00 + +static void print_buserr(void) +{ + if (extio_stat & EXTIO_MC_BUSERR) + printk(KERN_ERR "MC Bus Error\n"); + if (extio_stat & EXTIO_HPC3_BUSERR) + printk(KERN_ERR "HPC3 Bus Error 0x%x:\n", + hpc3_berr_stat, + (hpc3_berr_stat & HPC3_BESTAT_PIDMASK) >> + HPC3_BESTAT_PIDSHIFT, + (hpc3_berr_stat & HPC3_BESTAT_CTYPE) ? "PIO" : "DMA", + hpc3_berr_stat & HPC3_BESTAT_BLMASK); + if (extio_stat & EXTIO_EISA_BUSERR) + printk(KERN_ERR "EISA Bus Error\n"); + if (cpu_err_stat & CPU_ERRMASK) + printk(KERN_ERR "CPU error 0x%x<%s%s%s%s%s%s> @ 0x%08x\n", + cpu_err_stat, + cpu_err_stat & SGIMC_CSTAT_RD ? "RD " : "", + cpu_err_stat & SGIMC_CSTAT_PAR ? "PAR " : "", + cpu_err_stat & SGIMC_CSTAT_ADDR ? "ADDR " : "", + cpu_err_stat & SGIMC_CSTAT_SYSAD_PAR ? "SYSAD " : "", + cpu_err_stat & SGIMC_CSTAT_SYSCMD_PAR ? "SYSCMD " : "", + cpu_err_stat & SGIMC_CSTAT_BAD_DATA ? "BAD_DATA " : "", + cpu_err_addr); + if (gio_err_stat & GIO_ERRMASK) + printk(KERN_ERR "GIO error 0x%x:<%s%s%s%s%s%s%s%s> @ 0x08%x\n", + gio_err_stat, + gio_err_stat & SGIMC_GSTAT_RD ? "RD " : "", + gio_err_stat & SGIMC_GSTAT_WR ? "WR " : "", + gio_err_stat & SGIMC_GSTAT_TIME ? "TIME " : "", + gio_err_stat & SGIMC_GSTAT_PROM ? "PROM " : "", + gio_err_stat & SGIMC_GSTAT_ADDR ? "ADDR " : "", + gio_err_stat & SGIMC_GSTAT_BC ? "BC " : "", + gio_err_stat & SGIMC_GSTAT_PIO_RD ? "PIO_RD " : "", + gio_err_stat & SGIMC_GSTAT_PIO_WR ? "PIO_WR " : "", + gio_err_addr); } /* @@ -40,39 +85,30 @@ * and then clear the interrupt when this happens. */ -void be_ip22_interrupt(int irq, struct pt_regs *regs) +void ip22_be_interrupt(int irq, struct pt_regs *regs) { + const int field = 2 * sizeof(unsigned long); + save_and_clear_buserr(); - printk(KERN_ALERT "Bus error, epc == %08lx, ra == %08lx\n", - regs->cp0_epc, regs->regs[31]); + print_buserr(); + printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n", + (regs->cp0_cause & 4) ? "Data" : "Instruction", + field, regs->cp0_epc, field, regs->regs[31]); + /* Assume it would be too dangerous to continue ... */ die_if_kernel("Oops", regs); force_sig(SIGBUS, current); } -int be_ip22_handler(struct pt_regs *regs, int is_fixup) +static int ip22_be_handler(struct pt_regs *regs, int is_fixup) { save_and_clear_buserr(); - if (nofault) { - nofault = 0; - compute_return_epc(regs); - return MIPS_BE_DISCARD; - } - return MIPS_BE_FIXUP; -} - -int ip22_baddr(unsigned int *val, unsigned long addr) -{ - nofault = 1; - *val = *(volatile unsigned int *) addr; - __asm__ __volatile__("nop;nop;nop;nop"); - if (nofault) { - nofault = 0; - return 0; - } - return -EFAULT; + if (is_fixup) + return MIPS_BE_FIXUP; + print_buserr(); + return MIPS_BE_FATAL; } -void __init bus_error_init(void) +void __init ip22_be_init(void) { - be_board_handler = be_ip22_handler; + board_be_handler = ip22_be_handler; } diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-eisa.c linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-eisa.c --- linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-eisa.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-eisa.c 2003-08-24 02:55:57.000000000 -0700 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -30,10 +31,10 @@ #include #include #include -#include - -extern int EISA_bus; -extern void do_IRQ(int irq, struct pt_regs *regs); +#include +#include +#include +#include #define EISA_MAX_SLOTS 4 #define EISA_MAX_IRQ 16 @@ -92,7 +93,7 @@ if (eisa_irq >= EISA_MAX_IRQ) { /* Oops, Bad Stuff Happened... */ - printk("eisa_irq %d out of bound\n", eisa_irq); + printk(KERN_ERR "eisa_irq %d out of bound\n", eisa_irq); EISA_WRITE_8(EISA_INT2_CTRL, 0x20); EISA_WRITE_8(EISA_INT1_CTRL, 0x20); @@ -153,14 +154,13 @@ } static struct hw_interrupt_type ip22_eisa1_irq_type = { - "IP22 EISA", - startup_eisa1_irq, - shutdown_eisa1_irq, - enable_eisa1_irq, - disable_eisa1_irq, - mask_and_ack_eisa1_irq, - end_eisa1_irq, - NULL + .typename = "IP22 EISA", + .startup = startup_eisa1_irq, + .shutdown = shutdown_eisa1_irq, + .enable = enable_eisa1_irq, + .disable = disable_eisa1_irq, + .ack = mask_and_ack_eisa1_irq, + .end = end_eisa1_irq, }; static void enable_eisa2_irq(unsigned int irq) @@ -217,22 +217,23 @@ } static struct hw_interrupt_type ip22_eisa2_irq_type = { - "IP22 EISA", - startup_eisa2_irq, - shutdown_eisa2_irq, - enable_eisa2_irq, - disable_eisa2_irq, - mask_and_ack_eisa2_irq, - end_eisa2_irq, - NULL + .typename = "IP22 EISA", + .startup = startup_eisa2_irq, + .shutdown = shutdown_eisa2_irq, + .enable = enable_eisa2_irq, + .disable = disable_eisa2_irq, + .ack = mask_and_ack_eisa2_irq, + .end = end_eisa2_irq, }; static struct irqaction eisa_action = { - ip22_eisa_intr, 0, 0, "EISA", NULL, NULL + .handler = ip22_eisa_intr, + .name = "EISA", }; static struct irqaction cascade_action = { - no_action, 0, 0, "EISA cascade", NULL, NULL + .handler = no_action, + .name = "EISA cascade", }; int __init ip22_eisa_init(void) @@ -240,20 +241,26 @@ int i, c; char *str; u8 *slot_addr; + + if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) { + printk(KERN_INFO "EISA: bus not present.\n"); + return 1; + } - printk("EISA: Probing bus...\n"); + printk(KERN_INFO "EISA: Probing bus...\n"); for (c = 0, i = 1; i <= EISA_MAX_SLOTS; i++) { slot_addr = (u8 *) EISA_TO_KSEG1((0x1000 * i) + EISA_VENDOR_ID_OFFSET); if ((str = decode_eisa_sig(slot_addr))) { - printk("EISA: slot %d : %s detected.\n", i, str); + printk(KERN_INFO "EISA: slot %d : %s detected.\n", + i, str); c++; } } - printk("EISA: Detected %d card%s.\n", c, c < 2 ? "" : "s"); + printk(KERN_INFO "EISA: Detected %d card%s.\n", c, c < 2 ? "" : "s"); #ifdef CONFIG_ISA - printk("ISA support compiled in.\n"); + printk(KERN_INFO "ISA support compiled in.\n"); #endif /* Warning : BlackMagicAhead(tm). diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-gio.c linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-gio.c --- linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-gio.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-gio.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,153 +0,0 @@ -/* - * ip22-gio.c: Support for GIO64 bus (inspired by PCI code) - * - * Copyright (C) 2002 Ladislav Michl - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#define GIO_PIO_MAP_BASE 0x1f000000L -#define GIO_PIO_MAP_SIZE (16 * 1024*1024) - -#define GIO_ADDR_GFX 0x1f000000L -#define GIO_ADDR_GIO1 0x1f400000L -#define GIO_ADDR_GIO2 0x1f600000L - -#define GIO_GFX_MAP_SIZE (4 * 1024*1024) -#define GIO_GIO1_MAP_SIZE (2 * 1024*1024) -#define GIO_GIO2_MAP_SIZE (4 * 1024*1024) - -#define GIO_NO_DEVICE 0x80 - -static struct gio_dev gio_slot[GIO_NUM_SLOTS] = { - { - 0, - 0, - 0, - GIO_NO_DEVICE, - GIO_SLOT_GFX, - GIO_ADDR_GFX, - GIO_GFX_MAP_SIZE, - NULL, - "GFX" - }, - { - 0, - 0, - 0, - GIO_NO_DEVICE, - GIO_SLOT_GIO1, - GIO_ADDR_GIO1, - GIO_GIO1_MAP_SIZE, - NULL, - "EXP0" - }, - { - 0, - 0, - 0, - GIO_NO_DEVICE, - GIO_SLOT_GIO2, - GIO_ADDR_GIO2, - GIO_GIO2_MAP_SIZE, - NULL, - "EXP1" - } -}; - -static int gio_read_proc(char *buf, char **start, off_t off, - int count, int *eof, void *data) -{ - int i; - char *p = buf; - - p += sprintf(p, "GIO devices found:\n"); - for (i = 0; i < GIO_NUM_SLOTS; i++) { - if (gio_slot[i].flags & GIO_NO_DEVICE) - continue; - p += sprintf(p, " Slot %s, DeviceId 0x%02x\n", - gio_slot[i].slot_name, gio_slot[i].device); - p += sprintf(p, " BaseAddr 0x%08lx, MapSize 0x%08x\n", - gio_slot[i].base_addr, gio_slot[i].map_size); - } - - return p - buf; -} - -void create_gio_proc_entry(void) -{ - create_proc_read_entry("gio", 0, NULL, gio_read_proc, NULL); -} - -/** - * gio_find_device - begin or continue searching for a GIO device by device id - * @device: GIO device id to match, or %GIO_ANY_ID to match all device ids - * @from: Previous GIO device found in search, or %NULL for new search. - * - * Iterates through the list of known GIO devices. If a GIO device is found - * with a matching @device, a pointer to its device structure is returned. - * Otherwise, %NULL is returned. - * A new search is initiated by passing %NULL to the @from argument. - * Otherwise if @from is not %NULL, searches continue from next device. - */ -struct gio_dev * -gio_find_device(unsigned char device, const struct gio_dev *from) -{ - int i; - - for (i = (from) ? from->slot_number : 0; i < GIO_NUM_SLOTS; i++) - if (!(gio_slot[i].flags & GIO_NO_DEVICE) && - (device == GIO_ANY_ID || device == gio_slot[i].device)) - return &gio_slot[i]; - - return NULL; -} - -#define GIO_IDCODE(x) (x & 0x7f) -#define GIO_ALL_BITS_VALID 0x80 -#define GIO_REV(x) ((x >> 8) & 0xff) -#define GIO_GIO_SIZE_64 0x10000 -#define GIO_ROM_PRESENT 0x20000 -#define GIO_VENDOR_CODE(x) ((x >> 18) & 0x3fff) - -extern int ip22_baddr(unsigned int *val, unsigned long addr); - -/** - * sgigio_init - scan the GIO space and figure out what hardware is actually - * present. - */ -void __init sgigio_init(void) -{ - unsigned int i, id, found = 0; - - printk("GIO: Scanning for GIO cards...\n"); - for (i = 0; i < GIO_NUM_SLOTS; i++) { - if (ip22_baddr(&id, KSEG1ADDR(gio_slot[i].base_addr))) - continue; - - found = 1; - gio_slot[i].device = GIO_IDCODE(id); - if (id & GIO_ALL_BITS_VALID) { - gio_slot[i].revision = GIO_REV(id); - gio_slot[i].vendor = GIO_VENDOR_CODE(id); - gio_slot[i].flags = - (id & GIO_GIO_SIZE_64) ? GIO_IFACE_64 : 0 | - (id & GIO_ROM_PRESENT) ? GIO_HAS_ROM : 0; - } else - gio_slot[i].flags = GIO_VALID_ID_ONLY; - - printk("GIO: Card 0x%02x @ 0x%08lx\n", gio_slot[i].device, - gio_slot[i].base_addr); - } - - if (!found) - printk("GIO: No GIO cards present.\n"); -} diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-hpc.c linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-hpc.c --- linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-hpc.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-hpc.c 2003-08-24 02:55:57.000000000 -0700 @@ -4,89 +4,50 @@ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1998 Ralf Baechle */ + #include #include #include -#include -#include -#include -#include - -#if 0 -#define HPC_DEBUG(args...) printk(args) -#else -#define HPC_DEBUG(args...) -#endif +#include +#include +#include struct hpc3_regs *hpc3c0, *hpc3c1; -struct hpc3_miscregs *hpc3mregs; +struct sgioc_regs *sgioc; /* We need software copies of these because they are write only. */ -u32 sgi_hpc_write1, sgi_hpc_write2; - -/* Machine specific identifier knobs. */ -int sgi_has_ioc2 = 0; -int sgi_guiness = 0; -int sgi_boardid; +u8 sgi_ioc_reset, sgi_ioc_write; extern char *system_type; void __init sgihpc_init(void) { - unsigned int sid, crev, brev; - - hpc3c0 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP0_PBASE); - hpc3c1 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP1_PBASE); - hpc3mregs = (struct hpc3_miscregs *) (KSEG1 + HPC3_MREGS_PBASE); - sid = hpc3mregs->sysid; - - sid &= 0xff; - crev = (sid & 0xe0) >> 5; - brev = (sid & 0x1e) >> 1; - - HPC_DEBUG("sgihpc_init: crev<%2x> brev<%2x>\n", crev, brev); - HPC_DEBUG("sgihpc_init: "); - - /* This test works now thanks to William J. Earl */ - if ((sid & 1) == 0 ) { - HPC_DEBUG("GUINESS "); - sgi_guiness = 1; - mips_machtype = MACH_SGI_INDY; - system_type = "SGI Indy"; - } else { - HPC_DEBUG("FULLHOUSE "); - mips_machtype = MACH_SGI_INDIGO2; - sgi_guiness = 0; + hpc3c0 = (struct hpc3_regs *)(KSEG1 + HPC3_CHIP0_BASE); + hpc3c1 = (struct hpc3_regs *)(KSEG1 + HPC3_CHIP1_BASE); + /* IOC lives in PBUS PIO channel 6 */ + sgioc = (struct sgioc_regs *)hpc3c0->pbus_extregs[6]; + + hpc3c0->pbus_piocfg[6][0] |= HPC3_PIOCFG_DS16; + if (ip22_is_fullhouse()) { + /* Full House comes with INT2 which lives in PBUS PIO + * channel 4 */ + sgint = (struct sgint_regs *)hpc3c0->pbus_extregs[4]; system_type = "SGI Indigo2"; - } - sgi_boardid = brev; - - HPC_DEBUG("sgi_boardid<%d> ", sgi_boardid); - - if(crev == 1) { - if((sid & 1) || (brev >= 2)) { - HPC_DEBUG("IOC2 "); - sgi_has_ioc2 = 1; - } else { - HPC_DEBUG("IOC1 revision 1 "); - } } else { - HPC_DEBUG("IOC1 revision 0 "); + /* Guiness comes with INT3 which is part of IOC */ + sgint = &sgioc->int3; + system_type = "SGI Indy"; } - HPC_DEBUG("\n"); - - sgi_hpc_write1 = (HPC3_WRITE1_PRESET | HPC3_WRITE1_KMRESET | - HPC3_WRITE1_ERESET | HPC3_WRITE1_LC0OFF); - - sgi_hpc_write2 = (HPC3_WRITE2_EASEL | HPC3_WRITE2_NTHRESH | - HPC3_WRITE2_TPSPEED | HPC3_WRITE2_EPSEL | - HPC3_WRITE2_U0AMODE | HPC3_WRITE2_U1AMODE); - - if(!sgi_guiness) - sgi_hpc_write1 |= HPC3_WRITE1_GRESET; - hpc3mregs->write1 = sgi_hpc_write1; - hpc3mregs->write2 = sgi_hpc_write2; + + sgi_ioc_reset = (SGIOC_RESET_PPORT | SGIOC_RESET_KBDMOUSE | + SGIOC_RESET_EISA | SGIOC_RESET_ISDN | + SGIOC_RESET_LC0OFF); + + sgi_ioc_write = (SGIOC_WRITE_EASEL | SGIOC_WRITE_NTHRESH | + SGIOC_WRITE_TPSPEED | SGIOC_WRITE_EPSEL | + SGIOC_WRITE_U0AMODE | SGIOC_WRITE_U1AMODE); - hpc3c0->pbus_piocfgs[0][6] |= HPC3_PIOPCFG_HW; + sgioc->reset = sgi_ioc_reset; + sgioc->write = sgi_ioc_write; } diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-int.c linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-int.c --- linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-int.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-int.c 2003-08-24 02:55:57.000000000 -0700 @@ -7,7 +7,7 @@ * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) * - Indigo2 changes * - Interrupt handling fixes - * Copyright (C) 2001 Ladislav Michl (ladis@psi.cz) + * Copyright (C) 2001, 2003 Ladislav Michl (ladis@linux-mips.org) */ #include @@ -21,17 +21,16 @@ #include #include -#include -#include +#include +#include +#include /* #define DEBUG_SGINT */ -#undef I_REALLY_NEED_THIS_IRQ -struct sgi_int2_regs *sgi_i2regs; -struct sgi_int3_regs *sgi_i3regs; -struct sgi_ioc_ints *ioc_icontrol; -struct sgi_ioc_timers *ioc_timers; -volatile unsigned char *ioc_tclear; +/* So far nothing hangs here */ +#undef USE_LIO3_IRQ + +struct sgint_regs *sgint; static char lc0msk_to_irqnr[256]; static char lc1msk_to_irqnr[256]; @@ -39,8 +38,7 @@ static char lc3msk_to_irqnr[256]; extern asmlinkage void indyIRQ(void); -extern void do_IRQ(int irq, struct pt_regs *regs); -extern int ip22_eisa_init (void); +extern int ip22_eisa_init(void); static void enable_local0_irq(unsigned int irq) { @@ -50,7 +48,7 @@ /* don't allow mappable interrupt to be enabled from setup_irq, * we have our own way to do so */ if (irq != SGI_MAP_0_IRQ) - ioc_icontrol->imask0 |= (1 << (irq - SGINT_LOCAL0)); + sgint->imask0 |= (1 << (irq - SGINT_LOCAL0)); restore_flags(flags); } @@ -65,7 +63,7 @@ unsigned long flags; save_and_cli(flags); - ioc_icontrol->imask0 &= ~(1 << (irq - SGINT_LOCAL0)); + sgint->imask0 &= ~(1 << (irq - SGINT_LOCAL0)); restore_flags(flags); } @@ -79,14 +77,13 @@ } static struct hw_interrupt_type ip22_local0_irq_type = { - "IP22 local 0", - startup_local0_irq, - shutdown_local0_irq, - enable_local0_irq, - disable_local0_irq, - mask_and_ack_local0_irq, - end_local0_irq, - NULL + .typename = "IP22 local 0", + .startup = startup_local0_irq, + .shutdown = shutdown_local0_irq, + .enable = enable_local0_irq, + .disable = disable_local0_irq, + .ack = mask_and_ack_local0_irq, + .end = end_local0_irq, }; static void enable_local1_irq(unsigned int irq) @@ -97,7 +94,7 @@ /* don't allow mappable interrupt to be enabled from setup_irq, * we have our own way to do so */ if (irq != SGI_MAP_1_IRQ) - ioc_icontrol->imask1 |= (1 << (irq - SGINT_LOCAL1)); + sgint->imask1 |= (1 << (irq - SGINT_LOCAL1)); restore_flags(flags); } @@ -112,7 +109,7 @@ unsigned long flags; save_and_cli(flags); - ioc_icontrol->imask1 &= ~(1 << (irq - SGINT_LOCAL1)); + sgint->imask1 &= ~(1 << (irq - SGINT_LOCAL1)); restore_flags(flags); } @@ -126,14 +123,13 @@ } static struct hw_interrupt_type ip22_local1_irq_type = { - "IP22 local 1", - startup_local1_irq, - shutdown_local1_irq, - enable_local1_irq, - disable_local1_irq, - mask_and_ack_local1_irq, - end_local1_irq, - NULL + .typename = "IP22 local 1", + .startup = startup_local1_irq, + .shutdown = shutdown_local1_irq, + .enable = enable_local1_irq, + .disable = disable_local1_irq, + .ack = mask_and_ack_local1_irq, + .end = end_local1_irq, }; static void enable_local2_irq(unsigned int irq) @@ -141,8 +137,8 @@ unsigned long flags; save_and_cli(flags); - ioc_icontrol->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); - ioc_icontrol->cmeimask0 |= (1 << (irq - SGINT_LOCAL2)); + sgint->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); + sgint->cmeimask0 |= (1 << (irq - SGINT_LOCAL2)); restore_flags(flags); } @@ -157,9 +153,9 @@ unsigned long flags; save_and_cli(flags); - ioc_icontrol->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2)); - if (!ioc_icontrol->cmeimask0) - ioc_icontrol->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); + sgint->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2)); + if (!sgint->cmeimask0) + sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); restore_flags(flags); } @@ -173,28 +169,23 @@ } static struct hw_interrupt_type ip22_local2_irq_type = { - "IP22 local 2", - startup_local2_irq, - shutdown_local2_irq, - enable_local2_irq, - disable_local2_irq, - mask_and_ack_local2_irq, - end_local2_irq, - NULL + .typename = "IP22 local 2", + .startup = startup_local2_irq, + .shutdown = shutdown_local2_irq, + .enable = enable_local2_irq, + .disable = disable_local2_irq, + .ack = mask_and_ack_local2_irq, + .end = end_local2_irq, }; static void enable_local3_irq(unsigned int irq) { -#ifdef I_REALLY_NEED_THIS_IRQ unsigned long flags; save_and_cli(flags); - ioc_icontrol->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); - ioc_icontrol->cmeimask1 |= (1 << (irq - SGINT_LOCAL3)); + sgint->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); + sgint->cmeimask1 |= (1 << (irq - SGINT_LOCAL3)); restore_flags(flags); -#else - panic("Who need local 3 irq? see ip22-int.c"); -#endif } static unsigned int startup_local3_irq(unsigned int irq) @@ -208,9 +199,9 @@ unsigned long flags; save_and_cli(flags); - ioc_icontrol->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3)); - if (!ioc_icontrol->cmeimask1) - ioc_icontrol->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); + sgint->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3)); + if (!sgint->cmeimask1) + sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); restore_flags(flags); } @@ -224,30 +215,26 @@ } static struct hw_interrupt_type ip22_local3_irq_type = { - "IP22 local 3", - startup_local3_irq, - shutdown_local3_irq, - enable_local3_irq, - disable_local3_irq, - mask_and_ack_local3_irq, - end_local3_irq, - NULL + .typename = "IP22 local 3", + .startup = startup_local3_irq, + .shutdown = shutdown_local3_irq, + .enable = enable_local3_irq, + .disable = disable_local3_irq, + .ack = mask_and_ack_local3_irq, + .end = end_local3_irq, }; void indy_local0_irqdispatch(struct pt_regs *regs) { - unsigned char mask = ioc_icontrol->istat0; - unsigned char mask2 = 0; + u8 mask = sgint->istat0 & sgint->imask0; + u8 mask2; int irq; - mask &= ioc_icontrol->imask0; - if (mask & ISTAT0_LIO2) { - mask2 = ioc_icontrol->vmeistat; - mask2 &= ioc_icontrol->cmeimask0; + if (mask & SGINT_ISTAT0_LIO2) { + mask2 = sgint->vmeistat & sgint->cmeimask0; irq = lc2msk_to_irqnr[mask2]; - } else { + } else irq = lc0msk_to_irqnr[mask]; - } /* if irq == 0, then the interrupt has already been cleared */ if (irq) @@ -257,21 +244,15 @@ void indy_local1_irqdispatch(struct pt_regs *regs) { - unsigned char mask = ioc_icontrol->istat1; - unsigned char mask2 = 0; + u8 mask = sgint->istat1 & sgint->imask1; + u8 mask2; int irq; - mask &= ioc_icontrol->imask1; - if (mask & ISTAT1_LIO3) { -#ifndef I_REALLY_NEED_THIS_IRQ - printk("Whee: Got an LIO3 irq, winging it...\n"); -#endif - mask2 = ioc_icontrol->vmeistat; - mask2 &= ioc_icontrol->cmeimask1; + if (mask & SGINT_ISTAT1_LIO3) { + mask2 = sgint->vmeistat & sgint->cmeimask1; irq = lc3msk_to_irqnr[mask2]; - } else { + } else irq = lc1msk_to_irqnr[mask]; - } /* if irq == 0, then the interrupt has already been cleared */ if (irq) @@ -279,7 +260,7 @@ return; } -extern void be_ip22_interrupt(int irq, struct pt_regs *regs); +extern void ip22_be_interrupt(int irq, struct pt_regs *regs); void indy_buserror_irq(struct pt_regs *regs) { @@ -288,21 +269,43 @@ irq_enter(cpu, irq); kstat.irqs[cpu][irq]++; - be_ip22_interrupt(irq, regs); + ip22_be_interrupt(irq, regs); irq_exit(cpu, irq); } -static struct irqaction local0_cascade = - { no_action, SA_INTERRUPT, 0, "local0 cascade", NULL, NULL }; -static struct irqaction local1_cascade = - { no_action, SA_INTERRUPT, 0, "local1 cascade", NULL, NULL }; -static struct irqaction buserr = - { no_action, SA_INTERRUPT, 0, "Bus Error", NULL, NULL }; -static struct irqaction map0_cascade = - { no_action, SA_INTERRUPT, 0, "mappable0 cascade", NULL, NULL }; -#ifdef I_REALLY_NEED_THIS_IRQ -static struct irqaction map1_cascade = - { no_action, SA_INTERRUPT, 0, "mappable1 cascade", NULL, NULL }; +static struct irqaction local0_cascade = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "local0 cascade", +}; + +static struct irqaction local1_cascade = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "local1 cascade", +}; + +static struct irqaction buserr = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "Bus Error", +}; + +static struct irqaction map0_cascade = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "mapable0 cascade", +}; + +#ifdef USE_LIO3_IRQ +static struct irqaction map1_cascade = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "mapable1 cascade", +}; +#define SGI_INTERRUPTS SGINT_END +#else +#define SGI_INTERRUPTS SGINT_LOCAL3 #endif extern void mips_cpu_irq_init(unsigned int irq_base); @@ -311,9 +314,6 @@ { int i; - sgi_i2regs = (struct sgi_int2_regs *) (KSEG1 + SGI_INT2_BASE); - sgi_i3regs = (struct sgi_int3_regs *) (KSEG1 + SGI_INT3_BASE); - /* Init local mask --> irq tables. */ for (i = 0; i < 256; i++) { if (i & 0x80) { @@ -364,22 +364,11 @@ } } - /* Indy uses an INT3, Indigo2 uses an INT2 */ - if (sgi_guiness) { - ioc_icontrol = &sgi_i3regs->ints; - ioc_timers = &sgi_i3regs->timers; - ioc_tclear = &sgi_i3regs->tclear; - } else { - ioc_icontrol = &sgi_i2regs->ints; - ioc_timers = &sgi_i2regs->timers; - ioc_tclear = &sgi_i2regs->tclear; - } - /* Mask out all interrupts. */ - ioc_icontrol->imask0 = 0; - ioc_icontrol->imask1 = 0; - ioc_icontrol->cmeimask0 = 0; - ioc_icontrol->cmeimask1 = 0; + sgint->imask0 = 0; + sgint->imask1 = 0; + sgint->cmeimask0 = 0; + sgint->cmeimask1 = 0; set_except_vector(0, indyIRQ); @@ -387,7 +376,7 @@ /* init CPU irqs */ mips_cpu_irq_init(SGINT_CPU); - for (i = SGINT_LOCAL0; i < SGINT_END; i++) { + for (i = SGINT_LOCAL0; i < SGI_INTERRUPTS; i++) { hw_irq_controller *handler; if (i < SGINT_LOCAL1) @@ -412,11 +401,12 @@ /* cascade in cascade. i love Indy ;-) */ setup_irq(SGI_MAP_0_IRQ, &map0_cascade); -#ifdef I_REALLY_NEED_THIS_IRQ +#ifdef USE_LIO3_IRQ setup_irq(SGI_MAP_1_IRQ, &map1_cascade); #endif + #ifdef CONFIG_IP22_EISA - if (!sgi_guiness) /* Only Indigo-2 have EISA stuff */ + if (ip22_is_fullhouse()) /* Only Indigo-2 have EISA stuff */ ip22_eisa_init (); #endif } diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-ksyms.c linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-ksyms.c --- linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-ksyms.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-ksyms.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,21 @@ +/* + * ip22-ksyms.c: IP22 specific exports + */ + +#include + +#include +#include +#include +#include + +EXPORT_SYMBOL(sgimc); +EXPORT_SYMBOL(hpc3c0); +EXPORT_SYMBOL(hpc3c1); +EXPORT_SYMBOL(sgioc); + +extern void (*indy_volume_button)(int); +EXPORT_SYMBOL(indy_volume_button); + +EXPORT_SYMBOL(ip22_eeprom_read); +EXPORT_SYMBOL(ip22_nvram_read); diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-mc.c linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-mc.c --- linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-mc.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-mc.c 2003-08-24 02:55:57.000000000 -0700 @@ -1,89 +1,115 @@ /* - * ip22-mc.c: Routines for manipulating the INDY memory controller. + * ip22-mc.c: Routines for manipulating SGI Memory Controller. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes + * Copyright (C) 2003 Ladislav Michl (ladis@linux-mips.org) */ #include #include #include +#include #include #include -#include -#include +#include +#include +#include -/* #define DEBUG_SGIMC */ +struct sgimc_regs *sgimc; -#ifdef DEBUG_SGIMC -extern void prom_printf(char *fmt, ...); -#endif - -struct sgimc_misc_ctrl *mcmisc_regs; -struct sgimc_dma_ctrl *dmactrlregs; -u32 *rpsscounter; - -#ifdef DEBUG_SGIMC -static inline char *mconfig_string(unsigned long val) +static inline unsigned long get_bank_addr(unsigned int memconfig) { - switch(val & SGIMC_MCONFIG_RMASK) { - case SGIMC_MCONFIG_FOURMB: - return "4MB"; - - case SGIMC_MCONFIG_EIGHTMB: - return "8MB"; + return ((memconfig & SGIMC_MCONFIG_BASEADDR) << + ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 24 : 22)); +} - case SGIMC_MCONFIG_SXTEENMB: - return "16MB"; +static inline unsigned long get_bank_size(unsigned int memconfig) +{ + return ((memconfig & SGIMC_MCONFIG_RMASK) + 0x0100) << + ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 16 : 14); +} - case SGIMC_MCONFIG_TTWOMB: - return "32MB"; +static inline unsigned int get_bank_config(int bank) +{ + unsigned int res = bank > 1 ? sgimc->mconfig1 : sgimc->mconfig0; + return bank % 2 ? res & 0xffff : res >> 16; +} - case SGIMC_MCONFIG_SFOURMB: - return "64MB"; +struct mem { + unsigned long addr; + unsigned long size; +}; - case SGIMC_MCONFIG_OTEIGHTMB: - return "128MB"; +/* + * Detect installed memory, do some sanity checks and notify kernel about it + */ +static void probe_memory(void) +{ + int i, j, found, cnt = 0; + struct mem bank[4]; + struct mem space[2] = {{SGIMC_SEG0_BADDR, 0}, {SGIMC_SEG1_BADDR, 0}}; + + printk(KERN_INFO "MC: Probing memory configuration:\n"); + for (i = 0; i < ARRAY_SIZE(bank); i++) { + unsigned int tmp = get_bank_config(i); + if (!(tmp & SGIMC_MCONFIG_BVALID)) + continue; + + bank[cnt].size = get_bank_size(tmp); + bank[cnt].addr = get_bank_addr(tmp); + printk(KERN_INFO " bank%d: %3ldM @ %08lx\n", + i, bank[cnt].size / 1024 / 1024, bank[cnt].addr); + cnt++; + } - default: - return "wheee, unknown"; + /* And you thought bubble sort is dead algorithm... */ + do { + unsigned long addr, size; + + found = 0; + for (i = 1; i < cnt; i++) + if (bank[i-1].addr > bank[i].addr) { + addr = bank[i].addr; + size = bank[i].size; + bank[i].addr = bank[i-1].addr; + bank[i].size = bank[i-1].size; + bank[i-1].addr = addr; + bank[i-1].size = size; + found = 1; + } + } while (found); + + /* Figure out how are memory banks mapped into spaces */ + for (i = 0; i < cnt; i++) { + found = 0; + for (j = 0; j < ARRAY_SIZE(space) && !found; j++) + if (space[j].addr + space[j].size == bank[i].addr) { + space[j].size += bank[i].size; + found = 1; + } + /* There is either hole or overlapping memory */ + if (!found) + printk(KERN_CRIT "MC: Memory configuration mismatch " + "(%08lx), expect Bus Error soon\n", + bank[i].addr); } + + for (i = 0; i < ARRAY_SIZE(space); i++) + if (space[i].size) + add_memory_region(space[i].addr, space[i].size, + BOOT_MEM_RAM); } -#endif void __init sgimc_init(void) { - unsigned long tmpreg; + u32 tmp; - mcmisc_regs = (struct sgimc_misc_ctrl *)(KSEG1+0x1fa00000); - rpsscounter = (unsigned int *)(KSEG1+0x1fa01004); - dmactrlregs = (struct sgimc_dma_ctrl *)(KSEG1+0x1fa02000); + sgimc = (struct sgimc_regs *)(KSEG1 + SGIMC_BASE); printk(KERN_INFO "MC: SGI memory controller Revision %d\n", - (int) mcmisc_regs->systemid & SGIMC_SYSID_MASKREV); - -#if 0 /* XXX Until I figure out what this bit really indicates XXX */ - /* XXX Is this systemid bit reliable? */ - if(mcmisc_regs->systemid & SGIMC_SYSID_EPRESENT) { - EISA_bus = 1; - printk("with EISA\n"); - } else { - EISA_bus = 0; - printk("no EISA\n"); - } -#endif - -#ifdef DEBUG_SGIMC - prom_printf("sgimc_init: memconfig0<%s> mconfig1<%s>\n", - mconfig_string(mcmisc_regs->mconfig0), - mconfig_string(mcmisc_regs->mconfig1)); - - prom_printf("mcdump: cpuctrl0<%08lx> cpuctrl1<%08lx>\n", - mcmisc_regs->cpuctrl0, mcmisc_regs->cpuctrl1); - prom_printf("mcdump: divider<%08lx>, gioparm<%04x>\n", - mcmisc_regs->divider, mcmisc_regs->gioparm); -#endif + (int) sgimc->systemid & SGIMC_SYSID_MASKREV); /* Place the MC into a known state. This must be done before * interrupts are first enabled etc. @@ -93,32 +119,32 @@ * still running (which might be the case after a * soft reboot). */ - tmpreg = mcmisc_regs->cpuctrl0; - tmpreg &= ~SGIMC_CCTRL0_WDOG; - mcmisc_regs->cpuctrl0 = tmpreg; + tmp = sgimc->cpuctrl0; + tmp &= ~SGIMC_CCTRL0_WDOG; + sgimc->cpuctrl0 = tmp; /* Step 1: The CPU/GIO error status registers will not latch * up a new error status until the register has been * cleared by the cpu. These status registers are * cleared by writing any value to them. */ - mcmisc_regs->cstat = mcmisc_regs->gstat = 0; + sgimc->cstat = sgimc->gstat = 0; /* Step 2: Enable all parity checking in cpu control register * zero. */ - tmpreg = mcmisc_regs->cpuctrl0; - tmpreg |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM | - SGIMC_CCTRL0_R4KNOCHKPARR); - mcmisc_regs->cpuctrl0 = tmpreg; + tmp = sgimc->cpuctrl0; + tmp |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM | + SGIMC_CCTRL0_R4KNOCHKPARR); + sgimc->cpuctrl0 = tmp; /* Step 3: Setup the MC write buffer depth, this is controlled * in cpu control register 1 in the lower 4 bits. */ - tmpreg = mcmisc_regs->cpuctrl1; - tmpreg &= ~0xf; - tmpreg |= 0xd; - mcmisc_regs->cpuctrl1 = tmpreg; + tmp = sgimc->cpuctrl1; + tmp &= ~0xf; + tmp |= 0xd; + sgimc->cpuctrl1 = tmp; /* Step 4: Initialize the RPSS divider register to run as fast * as it can correctly operate. The register is laid @@ -134,38 +160,42 @@ * registers value increases at each 'tick'. Thus, * for IP22 we get INCREMENT=1, DIVIDER=1 == 0x101 */ - mcmisc_regs->divider = 0x101; + sgimc->divider = 0x101; /* Step 5: Initialize GIO64 arbitrator configuration register. * - * NOTE: If you dork with startup code the HPC init code in - * sgihpc_init() must run before us because of how we - * need to know Guiness vs. FullHouse and the board - * revision on this machine. You have been warned. + * NOTE: HPC init code in sgihpc_init() must run before us because + * we need to know Guiness vs. FullHouse and the board + * revision on this machine. You have been warned. */ /* First the basic invariants across all GIO64 implementations. */ - tmpreg = SGIMC_GIOPARM_HPC64; /* All 1st HPC's interface at 64bits. */ - tmpreg |= SGIMC_GIOPARM_ONEBUS; /* Only one physical GIO bus exists. */ + tmp = SGIMC_GIOPAR_HPC64; /* All 1st HPC's interface at 64bits */ + tmp |= SGIMC_GIOPAR_ONEBUS; /* Only one physical GIO bus exists */ - if(sgi_guiness) { - /* Guiness specific settings. */ - tmpreg |= SGIMC_GIOPARM_EISA64; /* MC talks to EISA at 64bits */ - tmpreg |= SGIMC_GIOPARM_MASTEREISA; /* EISA bus can act as master */ - } else { + if (ip22_is_fullhouse()) { /* Fullhouse specific settings. */ - if(sgi_boardid < 2) { - tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC at 64bits */ - tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp0 pipelines */ - tmpreg |= SGIMC_GIOPARM_MASTEREXP1;/* exp1 masters */ - tmpreg |= SGIMC_GIOPARM_RTIMEEXP0; /* exp0 is realtime */ + if (SGIOC_SYSID_BOARDREV(sgioc->sysid) < 2) { + tmp |= SGIMC_GIOPAR_HPC264; /* 2nd HPC at 64bits */ + tmp |= SGIMC_GIOPAR_PLINEEXP0; /* exp0 pipelines */ + tmp |= SGIMC_GIOPAR_MASTEREXP1; /* exp1 masters */ + tmp |= SGIMC_GIOPAR_RTIMEEXP0; /* exp0 is realtime */ } else { - tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC 64bits */ - tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp[01] pipelined */ - tmpreg |= SGIMC_GIOPARM_PLINEEXP1; - tmpreg |= SGIMC_GIOPARM_MASTEREISA;/* EISA masters */ - tmpreg |= SGIMC_GIOPARM_GFX64; /* GFX at 64 bits */ + tmp |= SGIMC_GIOPAR_HPC264; /* 2nd HPC 64bits */ + tmp |= SGIMC_GIOPAR_PLINEEXP0; /* exp[01] pipelined */ + tmp |= SGIMC_GIOPAR_PLINEEXP1; + tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA masters */ + tmp |= SGIMC_GIOPAR_GFX64; /* GFX at 64 bits */ } + } else { + /* Guiness specific settings. */ + tmp |= SGIMC_GIOPAR_EISA64; /* MC talks to EISA at 64bits */ + tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA bus can act as master */ } - mcmisc_regs->gioparm = tmpreg; /* poof */ + sgimc->giopar = tmp; /* poof */ + + probe_memory(); } + +void __init prom_meminit(void) {} +void __init prom_free_prom_memory (void) {} diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-nvram.c linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-nvram.c --- linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-nvram.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-nvram.c 2003-08-24 02:55:57.000000000 -0700 @@ -0,0 +1,114 @@ +/* + * ip22-nvram.c: NVRAM and serial EEPROM handling. + * + * Copyright (C) 2003 Ladislav Michl (ladis@linux-mips.org) + */ + +#include +#include + +/* Control opcode for serial eeprom */ +#define EEPROM_READ 0xc000 /* serial memory read */ +#define EEPROM_WEN 0x9800 /* write enable before prog modes */ +#define EEPROM_WRITE 0xa000 /* serial memory write */ +#define EEPROM_WRALL 0x8800 /* write all registers */ +#define EEPROM_WDS 0x8000 /* disable all programming */ +#define EEPROM_PRREAD 0xc000 /* read protect register */ +#define EEPROM_PREN 0x9800 /* enable protect register mode */ +#define EEPROM_PRCLEAR 0xffff /* clear protect register */ +#define EEPROM_PRWRITE 0xa000 /* write protect register */ +#define EEPROM_PRDS 0x8000 /* disable protect register, forever */ + +#define EEPROM_EPROT 0x01 /* Protect register enable */ +#define EEPROM_CSEL 0x02 /* Chip select */ +#define EEPROM_ECLK 0x04 /* EEPROM clock */ +#define EEPROM_DATO 0x08 /* Data out */ +#define EEPROM_DATI 0x10 /* Data in */ + +/* We need to use this functions early... */ +#define delay() ({ \ + int x; \ + for (x=0; x<100000; x++) __asm__ __volatile__(""); }) + +#define eeprom_cs_on(ptr) ({ \ + *ptr &= ~EEPROM_DATO; \ + *ptr &= ~EEPROM_ECLK; \ + *ptr &= ~EEPROM_EPROT; \ + delay(); \ + *ptr |= EEPROM_CSEL; \ + *ptr |= EEPROM_ECLK; }) + + +#define eeprom_cs_off(ptr) ({ \ + *ptr &= ~EEPROM_ECLK; \ + *ptr &= ~EEPROM_CSEL; \ + *ptr |= EEPROM_EPROT; \ + *ptr |= EEPROM_ECLK; }) + +#define BITS_IN_COMMAND 11 +/* + * clock in the nvram command and the register number. For the + * national semiconductor nv ram chip the op code is 3 bits and + * the address is 6/8 bits. + */ +static inline void eeprom_cmd(volatile unsigned int *ctrl, unsigned cmd, + unsigned reg) +{ + unsigned short ser_cmd; + int i; + + ser_cmd = cmd | (reg << (16 - BITS_IN_COMMAND)); + for (i = 0; i < BITS_IN_COMMAND; i++) { + if (ser_cmd & (1<<15)) /* if high order bit set */ + *ctrl |= EEPROM_DATO; + else + *ctrl &= ~EEPROM_DATO; + *ctrl &= ~EEPROM_ECLK; + *ctrl |= EEPROM_ECLK; + ser_cmd <<= 1; + } + *ctrl &= ~EEPROM_DATO; /* see data sheet timing diagram */ +} + +unsigned short ip22_eeprom_read(volatile unsigned int *ctrl, int reg) +{ + unsigned short res = 0; + int i; + + *ctrl &= ~EEPROM_EPROT; + eeprom_cs_on(ctrl); + eeprom_cmd(ctrl, EEPROM_READ, reg); + + /* clock the data ouf of serial mem */ + for (i = 0; i < 16; i++) { + *ctrl &= ~EEPROM_ECLK; + delay(); + *ctrl |= EEPROM_ECLK; + delay(); + res <<= 1; + if (*ctrl & EEPROM_DATI) + res |= 1; + } + + eeprom_cs_off(ctrl); + + return res; +} + +/* + * Read specified register from main NVRAM + */ +unsigned short ip22_nvram_read(int reg) +{ + if (ip22_is_fullhouse()) + /* IP22 (Indigo2 aka FullHouse) stores env variables into + * 93CS56 Microwire Bus EEPROM 2048 Bit (128x16) */ + return ip22_eeprom_read(&hpc3c0->eeprom, reg); + else { + unsigned short tmp; + /* IP24 (Indy aka Guiness) uses DS1386 8K version */ + reg <<= 1; + tmp = hpc3c0->bbram[reg++] & 0xff; + return (tmp << 8) | (hpc3c0->bbram[reg] & 0xff); + } +} diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-reset.c linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-reset.c --- linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-reset.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-reset.c 2003-08-24 02:55:58.000000000 -0700 @@ -3,20 +3,24 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1997, 1998, 2001 by Ralf Baechle + * Copyright (C) 1997, 1998, 2001, 2003 by Ralf Baechle */ +#include #include #include #include #include + #include #include #include #include #include #include -#include -#include +#include +#include +#include +#include /* * Just powerdown if init hasn't done after POWERDOWN_TIMEOUT seconds. @@ -31,49 +35,50 @@ #define POWERDOWN_FREQ (HZ / 4) #define PANIC_FREQ (HZ / 8) -static unsigned char sgi_volume; - static struct timer_list power_timer, blink_timer, debounce_timer, volume_timer; -static int shuting_down = 0, has_paniced = 0, setup_done = 0; + +#define MACHINE_PANICED 1 +#define MACHINE_SHUTTING_DOWN 2 +static int machine_state = 0; static void sgi_machine_restart(char *command) __attribute__((noreturn)); static void sgi_machine_halt(void) __attribute__((noreturn)); static void sgi_machine_power_off(void) __attribute__((noreturn)); -/* XXX How to pass the reboot command to the firmware??? */ static void sgi_machine_restart(char *command) { - if (shuting_down) + if (machine_state & MACHINE_SHUTTING_DOWN) sgi_machine_power_off(); - ArcReboot(); + sgimc->cpuctrl0 |= SGIMC_CCTRL0_SYSINIT; + while (1); } static void sgi_machine_halt(void) { - if (shuting_down) + if (machine_state & MACHINE_SHUTTING_DOWN) sgi_machine_power_off(); ArcEnterInteractiveMode(); } static void sgi_machine_power_off(void) { - unsigned char val; + unsigned int tmp; cli(); /* Disable watchdog */ - val = CMOS_READ(RTC_CMD); - CMOS_WRITE(val|RTC_WAM, RTC_CMD); - CMOS_WRITE(0, RTC_WSEC); - CMOS_WRITE(0, RTC_WHSEC); + tmp = hpc3c0->rtcregs[RTC_CMD] & 0xff; + hpc3c0->rtcregs[RTC_CMD] = tmp | RTC_WAM; + hpc3c0->rtcregs[RTC_WSEC] = 0; + hpc3c0->rtcregs[RTC_WHSEC] = 0; - while(1) { - hpc3mregs->panel=0xfe; + while (1) { + sgioc->panel = ~SGIOC_PANEL_POWERON; /* Good bye cruel world ... */ /* If we're still running, we probably got sent an alarm interrupt. Read the flag to clear it. */ - val = CMOS_READ(RTC_HOURS_ALARM); + tmp = hpc3c0->rtcregs[RTC_HOURS_ALARM]; } } @@ -85,8 +90,8 @@ static void blink_timeout(unsigned long data) { /* XXX fix this for fullhouse */ - sgi_hpc_write1 ^= (HPC3_WRITE1_LC0OFF|HPC3_WRITE1_LC1OFF); - hpc3mregs->write1 = sgi_hpc_write1; + sgi_ioc_reset ^= (SGIOC_RESET_LC0OFF|SGIOC_RESET_LC1OFF); + sgioc->reset = sgi_ioc_reset; mod_timer(&blink_timer, jiffies+data); } @@ -94,32 +99,35 @@ static void debounce(unsigned long data) { del_timer(&debounce_timer); - if (ioc_icontrol->istat1 & 2) { /* Interrupt still being sent. */ + if (sgint->istat1 & SGINT_ISTAT1_PWR) { + /* Interrupt still being sent. */ debounce_timer.expires = jiffies + 5; /* 0.05s */ add_timer(&debounce_timer); - hpc3mregs->panel = 0xf3; + sgioc->panel = SGIOC_PANEL_POWERON | SGIOC_PANEL_POWERINTR | + SGIOC_PANEL_VOLDNINTR | SGIOC_PANEL_VOLDNHOLD | + SGIOC_PANEL_VOLUPINTR | SGIOC_PANEL_VOLUPHOLD; return; } - if (has_paniced) - ArcReboot(); + if (machine_state & MACHINE_PANICED) + sgimc->cpuctrl0 |= SGIMC_CCTRL0_SYSINIT; enable_irq(SGI_PANEL_IRQ); } static inline void power_button(void) { - if (has_paniced) + if (machine_state & MACHINE_PANICED) return; - if (shuting_down || kill_proc(1, SIGINT, 1)) { + if ((machine_state & MACHINE_SHUTTING_DOWN) || kill_proc(1,SIGINT,1)) { /* No init process or button pressed twice. */ sgi_machine_power_off(); } - shuting_down = 1; + machine_state |= MACHINE_SHUTTING_DOWN; blink_timer.data = POWERDOWN_FREQ; blink_timeout(POWERDOWN_FREQ); @@ -129,47 +137,29 @@ add_timer(&power_timer); } -void inline sgi_volume_set(unsigned char volume) -{ - sgi_volume = volume; - - hpc3c0->pbus_extregs[2][0] = sgi_volume; - hpc3c0->pbus_extregs[2][1] = sgi_volume; -} - -void inline sgi_volume_get(unsigned char *volume) -{ - *volume = sgi_volume; -} +void (*indy_volume_button)(int) = NULL; static inline void volume_up_button(unsigned long data) { del_timer(&volume_timer); - if (sgi_volume < 0xff) - sgi_volume++; + if (indy_volume_button) + indy_volume_button(1); - hpc3c0->pbus_extregs[2][0] = sgi_volume; - hpc3c0->pbus_extregs[2][1] = sgi_volume; - - if (ioc_icontrol->istat1 & 2) { + if (sgint->istat1 & SGINT_ISTAT1_PWR) { volume_timer.expires = jiffies + 1; add_timer(&volume_timer); } - } static inline void volume_down_button(unsigned long data) { del_timer(&volume_timer); - if (sgi_volume > 0) - sgi_volume--; - - hpc3c0->pbus_extregs[2][0] = sgi_volume; - hpc3c0->pbus_extregs[2][1] = sgi_volume; + if (indy_volume_button) + indy_volume_button(-1); - if (ioc_icontrol->istat1 & 2) { + if (sgint->istat1 & SGINT_ISTAT1_PWR) { volume_timer.expires = jiffies + 1; add_timer(&volume_timer); } @@ -179,10 +169,11 @@ { unsigned int buttons; - buttons = hpc3mregs->panel; - hpc3mregs->panel = 0x03; /* power_interrupt | power_supply_on */ + buttons = sgioc->panel; + sgioc->panel = SGIOC_PANEL_POWERON | SGIOC_PANEL_POWERINTR; - if (ioc_icontrol->istat1 & 2) { /* Wait until interrupt goes away */ + if (sgint->istat1 & SGINT_ISTAT1_PWR) { + /* Wait until interrupt goes away */ disable_irq(SGI_PANEL_IRQ); init_timer(&debounce_timer); debounce_timer.function = debounce; @@ -190,15 +181,25 @@ add_timer(&debounce_timer); } - if (!(buttons & 0x02)) /* Power button was pressed */ + /* Power button was pressed + * ioc.ps page 22: "The Panel Register is called Power Control by Full + * House. Only lowest 2 bits are used. Guiness uses upper four bits + * for volume control". This is not true, all bits are pulled high + * on fullhouse */ + if (ip22_is_fullhouse() || !(buttons & SGIOC_PANEL_POWERINTR)) { power_button(); - if (!(buttons & 0x40)) { /* Volume up button was pressed */ + return; + } + /* TODO: mute/unmute */ + /* Volume up button was pressed */ + if (!(buttons & SGIOC_PANEL_VOLUPINTR)) { init_timer(&volume_timer); volume_timer.function = volume_up_button; volume_timer.expires = jiffies + 1; add_timer(&volume_timer); } - if (!(buttons & 0x10)) { /* Volume down button was pressed */ + /* Volume down button was pressed */ + if (!(buttons & SGIOC_PANEL_VOLDNINTR)) { init_timer(&volume_timer); volume_timer.function = volume_down_button; volume_timer.expires = jiffies + 1; @@ -209,9 +210,9 @@ static int panic_event(struct notifier_block *this, unsigned long event, void *ptr) { - if (has_paniced) + if (machine_state & MACHINE_PANICED) return NOTIFY_DONE; - has_paniced = 1; + machine_state |= MACHINE_PANICED; blink_timer.data = PANIC_FREQ; blink_timeout(PANIC_FREQ); @@ -220,17 +221,11 @@ } static struct notifier_block panic_block = { - panic_event, - NULL, - 0 + .notifier_call = panic_event, }; -void indy_reboot_setup(void) +static int __init reboot_setup(void) { - if (setup_done) - return; - setup_done = 1; - _machine_restart = sgi_machine_restart; _machine_halt = sgi_machine_halt; _machine_power_off = sgi_machine_power_off; @@ -239,4 +234,8 @@ init_timer(&blink_timer); blink_timer.function = blink_timeout; notifier_chain_register(&panic_notifier_list, &panic_block); + + return 0; } + +module_init(reboot_setup); diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-rtc.c linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-rtc.c --- linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-rtc.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-rtc.c 2003-08-24 02:55:58.000000000 -0700 @@ -8,29 +8,25 @@ * Copyright (C) 1998, 2001 by Ralf Baechle */ #include -#include +#include -static unsigned char indy_rtc_read_data(unsigned long addr) +static unsigned char ip22_rtc_read_data(unsigned long addr) { - volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS; - - return rtcregs[addr]; + return hpc3c0->rtcregs[addr]; } -static void indy_rtc_write_data(unsigned char data, unsigned long addr) +static void ip22_rtc_write_data(unsigned char data, unsigned long addr) { - volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS; - - rtcregs[addr] = data; + hpc3c0->rtcregs[addr] = data; } -static int indy_rtc_bcd_mode(void) +static int ip22_rtc_bcd_mode(void) { return 0; } -struct rtc_ops indy_rtc_ops = { - &indy_rtc_read_data, - &indy_rtc_write_data, - &indy_rtc_bcd_mode +struct rtc_ops ip22_rtc_ops = { + &ip22_rtc_read_data, + &ip22_rtc_write_data, + &ip22_rtc_bcd_mode }; diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-sc.c linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-sc.c --- linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-sc.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-sc.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,225 +0,0 @@ -/* - * ip22-sc.c: Indy cache management functions. - * - * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), - * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Secondary cache size in bytes, if present. */ -static unsigned long scache_size; - -#undef DEBUG_CACHE - -#define SC_SIZE 0x00080000 -#define SC_LINE 32 -#define CI_MASK (SC_SIZE - SC_LINE) -#define SC_INDEX(n) ((n) & CI_MASK) - -static inline void indy_sc_wipe(unsigned long first, unsigned long last) -{ - unsigned long tmp; - - __asm__ __volatile__( - ".set\tpush\t\t\t# indy_sc_wipe\n\t" - ".set\tnoreorder\n\t" - ".set\tmips3\n\t" - ".set\tnoat\n\t" - "mfc0\t%2, $12\n\t" - "li\t$1, 0x80\t\t\t# Go 64 bit\n\t" - "mtc0\t$1, $12\n\t" - - "dli\t$1, 0x9000000080000000\n\t" - "or\t%0, $1\t\t\t# first line to flush\n\t" - "or\t%1, $1\t\t\t# last line to flush\n\t" - ".set\tat\n\t" - - "1:\tsw\t$0, 0(%0)\n\t" - "bne\t%0, %1, 1b\n\t" - " daddu\t%0, 32\n\t" - - "mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t" - "nop; nop; nop; nop;\n\t" - ".set\tpop" - : "=r" (first), "=r" (last), "=&r" (tmp) - : "0" (first), "1" (last)); -} - -static void indy_sc_wback_invalidate(unsigned long addr, unsigned long size) -{ - unsigned long first_line, last_line; - unsigned int flags; - -#ifdef DEBUG_CACHE - printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size); -#endif - - if (!size) - return; - - /* Which lines to flush? */ - first_line = SC_INDEX(addr); - last_line = SC_INDEX(addr + size - 1); - - __save_and_cli(flags); - if (first_line <= last_line) { - indy_sc_wipe(first_line, last_line); - goto out; - } - - indy_sc_wipe(first_line, SC_SIZE - SC_LINE); - indy_sc_wipe(0, last_line); -out: - __restore_flags(flags); -} - -static void indy_sc_enable(void) -{ - unsigned long addr, tmp1, tmp2; - - /* This is really cool... */ -#ifdef DEBUG_CACHE - printk("Enabling R4600 SCACHE\n"); -#endif - __asm__ __volatile__( - ".set\tpush\n\t" - ".set\tnoreorder\n\t" - ".set\tmips3\n\t" - "mfc0\t%2, $12\n\t" - "nop; nop; nop; nop;\n\t" - "li\t%1, 0x80\n\t" - "mtc0\t%1, $12\n\t" - "nop; nop; nop; nop;\n\t" - "li\t%0, 0x1\n\t" - "dsll\t%0, 31\n\t" - "lui\t%1, 0x9000\n\t" - "dsll32\t%1, 0\n\t" - "or\t%0, %1, %0\n\t" - "sb\t$0, 0(%0)\n\t" - "mtc0\t$0, $12\n\t" - "nop; nop; nop; nop;\n\t" - "mtc0\t%2, $12\n\t" - "nop; nop; nop; nop;\n\t" - ".set\tpop" - : "=r" (tmp1), "=r" (tmp2), "=r" (addr)); -} - -static void indy_sc_disable(void) -{ - unsigned long tmp1, tmp2, tmp3; - -#ifdef DEBUG_CACHE - printk("Disabling R4600 SCACHE\n"); -#endif - __asm__ __volatile__( - ".set\tpush\n\t" - ".set\tnoreorder\n\t" - ".set\tmips3\n\t" - "li\t%0, 0x1\n\t" - "dsll\t%0, 31\n\t" - "lui\t%1, 0x9000\n\t" - "dsll32\t%1, 0\n\t" - "or\t%0, %1, %0\n\t" - "mfc0\t%2, $12\n\t" - "nop; nop; nop; nop\n\t" - "li\t%1, 0x80\n\t" - "mtc0\t%1, $12\n\t" - "nop; nop; nop; nop\n\t" - "sh\t$0, 0(%0)\n\t" - "mtc0\t$0, $12\n\t" - "nop; nop; nop; nop\n\t" - "mtc0\t%2, $12\n\t" - "nop; nop; nop; nop\n\t" - ".set\tpop" - : "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)); -} - -static inline int __init indy_sc_probe(void) -{ - volatile unsigned int *cpu_control; - unsigned short cmd = 0xc220; - unsigned long data = 0; - int i, n; - -#ifdef __MIPSEB__ - cpu_control = (volatile unsigned int *) KSEG1ADDR(0x1fa00034); -#else - cpu_control = (volatile unsigned int *) KSEG1ADDR(0x1fa00030); -#endif -#define DEASSERT(bit) (*(cpu_control) &= (~(bit))) -#define ASSERT(bit) (*(cpu_control) |= (bit)) -#define DELAY for(n = 0; n < 100000; n++) __asm__ __volatile__("") - DEASSERT(SGIMC_EEPROM_PRE); - DEASSERT(SGIMC_EEPROM_SDATAO); - DEASSERT(SGIMC_EEPROM_SECLOCK); - DEASSERT(SGIMC_EEPROM_PRE); - DELAY; - ASSERT(SGIMC_EEPROM_CSEL); ASSERT(SGIMC_EEPROM_SECLOCK); - for(i = 0; i < 11; i++) { - if(cmd & (1<<15)) - ASSERT(SGIMC_EEPROM_SDATAO); - else - DEASSERT(SGIMC_EEPROM_SDATAO); - DEASSERT(SGIMC_EEPROM_SECLOCK); - ASSERT(SGIMC_EEPROM_SECLOCK); - cmd <<= 1; - } - DEASSERT(SGIMC_EEPROM_SDATAO); - for(i = 0; i < (sizeof(unsigned short) * 8); i++) { - unsigned int tmp; - - DEASSERT(SGIMC_EEPROM_SECLOCK); - DELAY; - ASSERT(SGIMC_EEPROM_SECLOCK); - DELAY; - data <<= 1; - tmp = *cpu_control; - if(tmp & SGIMC_EEPROM_SDATAI) - data |= 1; - } - DEASSERT(SGIMC_EEPROM_SECLOCK); - DEASSERT(SGIMC_EEPROM_CSEL); - ASSERT(SGIMC_EEPROM_PRE); - ASSERT(SGIMC_EEPROM_SECLOCK); - - data <<= PAGE_SHIFT; - if (data == 0) - return 0; - - scache_size = data; - - printk("R4600/R5000 SCACHE size %ldK, linesize 32 bytes.\n", - scache_size >> 10); - - return 1; -} - -/* XXX Check with wje if the Indy caches can differenciate between - writeback + invalidate and just invalidate. */ -struct bcache_ops indy_sc_ops = { - indy_sc_enable, - indy_sc_disable, - indy_sc_wback_invalidate, - indy_sc_wback_invalidate -}; - -void __init indy_sc_init(void) -{ - if (indy_sc_probe()) { - indy_sc_enable(); - bcops = &indy_sc_ops; - } -} diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-setup.c linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-setup.c --- linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-setup.c 2003-08-24 02:55:58.000000000 -0700 @@ -22,39 +22,27 @@ #include #include #include -#include -#include -#include -#include #include #include #include #include +#include +#include +#include +#include -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void rs_kgdb_hook(int); extern void breakpoint(void); static int remote_debug = 0; #endif -#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_ARC_CONSOLE) -extern void console_setup(char *); -#endif - -extern void sgitime_init(void); +extern struct rtc_ops ip22_rtc_ops; -extern struct hpc3_miscregs *hpc3mregs; -extern struct rtc_ops indy_rtc_ops; -extern void indy_reboot_setup(void); -extern void sgi_volume_set(unsigned char); -extern void create_gio_proc_entry(void); - -#define sgi_kh ((struct hpc_keyb *) &(hpc3mregs->kbdmouse0)) +unsigned long sgi_gfxaddr; #define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */ -unsigned long sgi_gfxaddr; - static void sgi_request_region(void) { /* No I/O ports are being used on the Indy. */ @@ -62,19 +50,6 @@ static int sgi_request_irq(void (*handler)(int, void *, struct pt_regs *)) { - /* Dirty hack, this get's called as a callback from the keyboard - * driver. We piggyback the initialization of the front panel - * button handling on it even though they're technically not - * related with the keyboard driver in any way. Doing it from - * ip22_setup wouldn't work since kmalloc isn't initialized yet. - */ - indy_reboot_setup(); - - /* Ehm, well... once David used hack above, let's add yet another. - * Register GIO bus proc entry here. - */ - create_gio_proc_entry(); - return request_irq(SGI_KEYBD_IRQ, handler, 0, "keyboard", NULL); } @@ -91,54 +66,62 @@ static unsigned char sgi_read_input(void) { - return sgi_kh->data; + return sgioc->kbdmouse.data; } static void sgi_write_output(unsigned char val) { - int status; + unsigned char status; do { - status = sgi_kh->command; + status = sgioc->kbdmouse.command; } while (status & KBD_STAT_IBF); - sgi_kh->data = val; + sgioc->kbdmouse.data = val; } static void sgi_write_command(unsigned char val) { - int status; + unsigned char status; do { - status = sgi_kh->command; + status = sgioc->kbdmouse.command; } while (status & KBD_STAT_IBF); - sgi_kh->command = val; + sgioc->kbdmouse.command = val; } static unsigned char sgi_read_status(void) { - return sgi_kh->command; + return sgioc->kbdmouse.command; } -struct kbd_ops sgi_kbd_ops = { - sgi_request_region, - sgi_request_irq, +struct kbd_ops ip22_kbd_ops = { + .kbd_request_region = sgi_request_region, + .kbd_request_irq = sgi_request_irq, - sgi_aux_request_irq, - sgi_aux_free_irq, + .aux_request_irq = sgi_aux_request_irq, + .aux_free_irq = sgi_aux_free_irq, - sgi_read_input, - sgi_write_output, - sgi_write_command, - sgi_read_status + .kbd_read_input = sgi_read_input, + .kbd_write_output = sgi_write_output, + .kbd_write_command = sgi_write_command, + .kbd_read_status = sgi_read_status, }; +extern void ip22_be_init(void) __init; +extern void ip22_time_init(void) __init; + +extern int console_setup(char *) __init; + void __init ip22_setup(void) { char *ctype; -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB char *kgdb_ttyd; #endif - sgitime_init(); + + board_be_init = ip22_be_init; + ip22_time_init(); + /* Init the INDY HPC I/O controller. Need to call this before * fucking with the memory controller because it needs to know the * boardID and whether this is a Guiness or a FullHouse machine. @@ -152,7 +135,6 @@ /* Now enable boardcaches, if any. */ indy_sc_init(); #endif - conswitchp = NULL; /* Set the IO space to some sane value */ set_io_port_base (KSEG1ADDR (0x00080000)); @@ -162,81 +144,72 @@ * line and "d2" for the second serial line. */ ctype = ArcGetEnvironmentVariable("console"); - if (*ctype == 'd') { -#ifdef CONFIG_SERIAL_CONSOLE - if(*(ctype + 1) == '2') + if (ctype && *ctype == 'd') { + if (*(ctype + 1) == '2') console_setup("ttyS1"); else console_setup("ttyS0"); -#endif - } else { -#ifdef CONFIG_ARC_CONSOLE - prom_flags &= PROM_FLAG_USE_AS_CONSOLE; - console_setup("ttyS0"); -#endif + } else if (!ctype || *ctype != 'g') { + /* Use ARC if we don't want serial ('d') or Newport ('g'). */ + prom_flags |= PROM_FLAG_USE_AS_CONSOLE; + console_setup("arc"); } -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB kgdb_ttyd = prom_getcmdline(); if ((kgdb_ttyd = strstr(kgdb_ttyd, "kgdb=ttyd")) != NULL) { int line; kgdb_ttyd += strlen("kgdb=ttyd"); if (*kgdb_ttyd != '1' && *kgdb_ttyd != '2') - printk("KGDB: Uknown serial line /dev/ttyd%c, " - "falling back to /dev/ttyd1\n", *kgdb_ttyd); + printk(KERN_INFO "KGDB: Uknown serial line /dev/ttyd%c" + ", falling back to /dev/ttyd1\n", *kgdb_ttyd); line = *kgdb_ttyd == '2' ? 0 : 1; - printk("KGDB: Using serial line /dev/ttyd%d for session\n", - line ? 1 : 2); + printk(KERN_INFO "KGDB: Using serial line /dev/ttyd%d for " + "session\n", line ? 1 : 2); rs_kgdb_hook(line); - printk("KGDB: Using serial line /dev/ttyd%d for session, " - "please connect your debugger\n", line ? 1 : 2); + printk(KERN_INFO "KGDB: Using serial line /dev/ttyd%d for " + "session, please connect your debugger\n", line ? 1:2); remote_debug = 1; /* Breakpoints and stuff are in sgi_irq_setup() */ } #endif - sgi_volume_set(simple_strtoul(ArcGetEnvironmentVariable("volume"), NULL, 10)); - #ifdef CONFIG_VT + conswitchp = &dummy_con; #ifdef CONFIG_SGI_NEWPORT_CONSOLE - { + if (ctype && *ctype == 'g'){ unsigned long *gfxinfo; - long (*__vec)(void) = (void *) *(long *)((PROMBLOCK)->pvector + 0x20); + long (*__vec)(void) = + (void *) *(long *)((PROMBLOCK)->pvector + 0x20); gfxinfo = (unsigned long *)__vec(); sgi_gfxaddr = ((gfxinfo[1] >= 0xa0000000 && gfxinfo[1] <= 0xc0000000) ? gfxinfo[1] - 0xa0000000 : 0); + + /* newport addresses? */ + if (sgi_gfxaddr == 0x1f0f0000 || sgi_gfxaddr == 0x1f4f0000) { + conswitchp = &newport_con; + + screen_info = (struct screen_info) { + .orig_x = 0, + .orig_y = 0, + .orig_video_page = 0, + .orig_video_mode = 0, + .orig_video_cols = 160, + .orig_video_ega_bx = 0, + .orig_video_lines = 64, + .orig_video_isVGA = 0, + .orig_video_points = 16, + }; + } } - /* newport addresses? */ - if (sgi_gfxaddr == 0x1f0f0000 || sgi_gfxaddr == 0x1f4f0000) { - conswitchp = &newport_con; - - screen_info = (struct screen_info) { - 0, 0, /* orig-x, orig-y */ - 0, /* unused */ - 0, /* orig_video_page */ - 0, /* orig_video_mode */ - 160, /* orig_video_cols */ - 0, 0, 0, /* unused, ega_bx, unused */ - 64, /* orig_video_lines */ - 0, /* orig_video_isVGA */ - 16 /* orig_video_points */ - }; - } else { - conswitchp = &dummy_con; - } -#else -#ifdef CONFIG_DUMMY_CONSOLE - conswitchp = &dummy_con; -#endif #endif #endif - - rtc_ops = &indy_rtc_ops; - kbd_ops = &sgi_kbd_ops; + rtc_ops = &ip22_rtc_ops; + kbd_ops = &ip22_kbd_ops; #ifdef CONFIG_PSMOUSE aux_device_present = 0xaa; #endif diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-system.c linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-system.c --- linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-system.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-system.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,134 +0,0 @@ -/* - * ip22-system.c: Probe the system type using ARCS prom interface library. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - */ -#include -#include -#include -#include - -#include -#include -#include - -enum sgi_mach sgimach; - -struct smatch { - char *name; - int type; -}; - -static struct smatch sgi_cputable[] = { - { "MIPS-R2000", CPU_R2000 }, - { "MIPS-R3000", CPU_R3000 }, - { "MIPS-R3000A", CPU_R3000A }, - { "MIPS-R4000", CPU_R4000SC }, - { "MIPS-R4400", CPU_R4400SC }, - { "MIPS-R4600", CPU_R4600 }, - { "MIPS-R8000", CPU_R8000 }, - { "MIPS-R5000", CPU_R5000 }, - { "MIPS-R5000A", CPU_R5000A }, - { "MIPS-R10000", CPU_R10000 } -}; - -static int __init string_to_cpu(char *s) -{ - ULONG cnt; - char c; - int i; - - for(i = 0; i < (sizeof(sgi_cputable) / sizeof(struct smatch)); i++) { - if(!strcmp(s, sgi_cputable[i].name)) - return sgi_cputable[i].type; - } - prom_printf("\nYeee, could not determine MIPS cpu type <%s>\n", s); - prom_printf("press a key to reboot\n"); - ArcRead(0, &c, 1, &cnt); - ArcEnterInteractiveMode(); - return 0; -} - -/* - * We' call this early before loadmmu(). If we do the other way around - * the firmware will crash and burn. - */ -void __init sgi_sysinit(void) -{ - pcomponent *p, *toplev, *cpup = 0; - int cputype = -1; - ULONG cnt; - char c; - - - /* The root component tells us what machine architecture we - * have here. - */ - p = ArcGetChild(PROM_NULL_COMPONENT); - - /* Now scan for cpu(s). */ - printk(KERN_INFO); - toplev = p = ArcGetChild(p); - while(p) { - int ncpus = 0; - - if(p->type == Cpu) { - if(++ncpus > 1) { - prom_printf("\nYeee, SGI MP not ready yet\n"); - prom_printf("press a key to reboot\n"); - ArcRead(0, &c, 1, &cnt); - ArcEnterInteractiveMode(); - } - printk("CPU: %s ", (char *)p->iname); - cpup = p; - cputype = string_to_cpu((char *)cpup->iname); - } - p = ArcGetPeer(p); - } - if (cputype == -1) { - prom_printf("\nYeee, could not find cpu ARCS component\n"); - prom_printf("press a key to reboot\n"); - ArcRead(0, &c, 1, &cnt); - ArcEnterInteractiveMode(); - } - p = ArcGetChild(cpup); - while(p) { - switch(p->class) { - case processor: - switch(p->type) { - case Fpu: - printk("FPU<%s> ", (char *)p->iname); - break; - - default: - break; - }; - break; - - case cache: - switch(p->type) { - case picache: - printk("ICACHE "); - break; - - case pdcache: - printk("DCACHE "); - break; - - case sccache: - printk("SCACHE "); - break; - - default: - break; - - }; - break; - - default: - break; - }; - p = ArcGetPeer(p); - } - printk("\n"); -} diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-time.c linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-time.c --- linux-2.4.21-bk37/arch/mips/sgi-ip22/ip22-time.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip22/ip22-time.c 2003-08-24 02:55:58.000000000 -0700 @@ -8,6 +8,8 @@ * * Copyright (C) 2001 by Ladislav Michl */ + +#include #include #include #include @@ -17,11 +19,12 @@ #include #include #include +#include #include #include -#include -#include -#include +#include +#include +#include /* * note that mktime uses month from 1 to 12 while to_tm @@ -29,20 +32,20 @@ */ static unsigned long indy_rtc_get_time(void) { - unsigned char yrs, mon, day, hrs, min, sec; - unsigned char save_control; + unsigned int yrs, mon, day, hrs, min, sec; + unsigned int save_control; - save_control = CMOS_READ(RTC_CMD); - CMOS_WRITE((save_control|RTC_TE), RTC_CMD); + save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff; + hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE; - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hrs = CMOS_READ(RTC_HOURS) & 0x1f; - day = CMOS_READ(RTC_DATE); - mon = CMOS_READ(RTC_MONTH) & 0x1f; - yrs = CMOS_READ(RTC_YEAR); + sec = hpc3c0->rtcregs[RTC_SECONDS] & 0xff; + min = hpc3c0->rtcregs[RTC_MINUTES] & 0xff; + hrs = hpc3c0->rtcregs[RTC_HOURS] & 0x1f; + day = hpc3c0->rtcregs[RTC_DATE] & 0xff; + mon = hpc3c0->rtcregs[RTC_MONTH] & 0x1f; + yrs = hpc3c0->rtcregs[RTC_YEAR] & 0xff; - CMOS_WRITE(save_control, RTC_CMD); + hpc3c0->rtcregs[RTC_CMD] = save_control; BCD_TO_BIN(sec); BCD_TO_BIN(min); @@ -56,13 +59,13 @@ if ((yrs += 40) < 70) yrs += 100; - return mktime((int)yrs + 1900, mon, day, hrs, min, sec); + return mktime(yrs + 1900, mon, day, hrs, min, sec); } static int indy_rtc_set_time(unsigned long tim) { struct rtc_time tm; - unsigned char save_control; + unsigned int save_control; to_tm(tim, &tm); @@ -78,53 +81,54 @@ BIN_TO_BCD(tm.tm_mon); BIN_TO_BCD(tm.tm_year); - save_control = CMOS_READ(RTC_CMD); - CMOS_WRITE((save_control|RTC_TE), RTC_CMD); + save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff; + hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE; - CMOS_WRITE(tm.tm_year, RTC_YEAR); - CMOS_WRITE(tm.tm_mon, RTC_MONTH); - CMOS_WRITE(tm.tm_mday, RTC_DATE); - CMOS_WRITE(tm.tm_hour, RTC_HOURS); - CMOS_WRITE(tm.tm_min, RTC_MINUTES); - CMOS_WRITE(tm.tm_sec, RTC_SECONDS); - CMOS_WRITE(0, RTC_HUNDREDTH_SECOND); + hpc3c0->rtcregs[RTC_YEAR] = tm.tm_year; + hpc3c0->rtcregs[RTC_MONTH] = tm.tm_mon; + hpc3c0->rtcregs[RTC_DATE] = tm.tm_mday; + hpc3c0->rtcregs[RTC_HOURS] = tm.tm_hour; + hpc3c0->rtcregs[RTC_MINUTES] = tm.tm_min; + hpc3c0->rtcregs[RTC_SECONDS] = tm.tm_sec; + hpc3c0->rtcregs[RTC_HUNDREDTH_SECOND] = 0; - CMOS_WRITE(save_control, RTC_CMD); + hpc3c0->rtcregs[RTC_CMD] = save_control; return 0; } -static unsigned long dosample(volatile unsigned char *tcwp, - volatile unsigned char *tc2p) +static unsigned long dosample(void) { u32 ct0, ct1; volatile u8 msb, lsb; /* Start the counter. */ - *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MRGEN); - *tc2p = (SGINT_TCSAMP_COUNTER & 0xff); - *tc2p = (SGINT_TCSAMP_COUNTER >> 8); + sgint->tcword = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | + SGINT_TCWORD_MRGEN); + sgint->tcnt2 = SGINT_TCSAMP_COUNTER & 0xff; + sgint->tcnt2 = SGINT_TCSAMP_COUNTER >> 8; /* Get initial counter invariant */ - ct0 = read_32bit_cp0_register(CP0_COUNT); + ct0 = read_c0_count(); /* Latch and spin until top byte of counter2 is zero */ do { - *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CLAT); - lsb = *tc2p; - msb = *tc2p; - ct1 = read_32bit_cp0_register(CP0_COUNT); - } while(msb); + sgint->tcword = SGINT_TCWORD_CNT2 | SGINT_TCWORD_CLAT; + lsb = sgint->tcnt2; + msb = sgint->tcnt2; + ct1 = read_c0_count(); + } while (msb); /* Stop the counter. */ - *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MSWST); - + sgint->tcword = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | + SGINT_TCWORD_MSWST); /* * Return the difference, this is how far the r4k counter increments * for every 1/HZ seconds. We round off the nearest 1 MHz of master - * clock (= 1000000 / 100 / 2 = 5000 count). + * clock (= 1000000 / HZ / 2). */ - return ((ct1 - ct0) / 5000) * 5000; + //return (ct1 - ct0 + (500000/HZ/2)) / (500000/HZ) * (500000/HZ); + return (ct1 - ct0) / (500000/HZ) * (500000/HZ); } /* @@ -132,62 +136,48 @@ */ void indy_time_init(void) { - struct sgi_ioc_timers *p; - volatile unsigned char *tcwp, *tc2p; unsigned long r4k_ticks[3]; unsigned long r4k_tick; - /* Figure out the r4k offset, the algorithm is very simple - * and works in _all_ cases as long as the 8254 counter - * register itself works ok (as an interrupt driving timer - * it does not because of bug, this is why we are using - * the onchip r4k counter/compare register to serve this - * purpose, but for r4k_offset calculation it will work - * ok for us). There are other very complicated ways - * of performing this calculation but this one works just - * fine so I am not going to futz around. ;-) + /* + * Figure out the r4k offset, the algorithm is very simple and works in + * _all_ cases as long as the 8254 counter register itself works ok (as + * an interrupt driving timer it does not because of bug, this is why + * we are using the onchip r4k counter/compare register to serve this + * purpose, but for r4k_offset calculation it will work ok for us). + * There are other very complicated ways of performing this calculation + * but this one works just fine so I am not going to futz around. ;-) */ - p = ioc_timers; - tcwp = &p->tcword; - tc2p = &p->tcnt2; - printk(KERN_INFO "Calibrating system timer... "); - dosample(tcwp, tc2p); /* Prime cache. */ - dosample(tcwp, tc2p); /* Prime cache. */ + dosample(); /* Prime cache. */ + dosample(); /* Prime cache. */ /* Zero is NOT an option. */ do { - r4k_ticks[0] = dosample (tcwp, tc2p); + r4k_ticks[0] = dosample(); } while (!r4k_ticks[0]); do { - r4k_ticks[1] = dosample (tcwp, tc2p); + r4k_ticks[1] = dosample(); } while (!r4k_ticks[1]); if (r4k_ticks[0] != r4k_ticks[1]) { - printk ("warning: timer counts differ, retrying..."); - r4k_ticks[2] = dosample (tcwp, tc2p); + printk("warning: timer counts differ, retrying... "); + r4k_ticks[2] = dosample(); if (r4k_ticks[2] == r4k_ticks[0] || r4k_ticks[2] == r4k_ticks[1]) r4k_tick = r4k_ticks[2]; else { - printk ("disagreement, using average..."); + printk("disagreement, using average... "); r4k_tick = (r4k_ticks[0] + r4k_ticks[1] + r4k_ticks[2]) / 3; } } else r4k_tick = r4k_ticks[0]; - printk("%d [%d.%02d MHz CPU]\n", (int) r4k_tick, - (int) (r4k_tick / 5000), (int) (r4k_tick % 5000) / 50); + printk("%d [%d.%04d MHz CPU]\n", (int) r4k_tick, + (int) (r4k_tick / (500000 / HZ)), + (int) (r4k_tick % (500000 / HZ))); mips_counter_frequency = r4k_tick * HZ; - - /* HACK ALERT! This get's called after traps initialization - * We piggyback the initialization of GIO bus here even though - * it is technically not related with the timer in any way. - * Doing it from ip22_setup wouldn't work since traps aren't - * initialized yet. - */ - sgigio_init(); } /* Generic SGI handler for (spurious) 8254 interrupts */ @@ -195,12 +185,12 @@ { int cpu = smp_processor_id(); int irq = SGI_8254_0_IRQ; - long cnt; + ULONG cnt; char c; irq_enter(cpu, irq); kstat.irqs[cpu][irq]++; - printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n"); + printk(KERN_ALERT "Oops, got 8254 interrupt.\n"); ArcRead(0, &c, 1, &cnt); ArcEnterInteractiveMode(); irq_exit(cpu, irq); @@ -224,21 +214,14 @@ static void indy_timer_setup(struct irqaction *irq) { - unsigned long count; - /* over-write the handler, we use our own way */ irq->handler = no_action; - /* set time for first interrupt */ - count = read_32bit_cp0_register(CP0_COUNT); - count += mips_counter_frequency / HZ; - write_32bit_cp0_register(CP0_COMPARE, count); - /* setup irqaction */ setup_irq(SGI_TIMER_IRQ, irq); } -void sgitime_init(void) +void __init ip22_time_init(void) { /* setup hookup functions */ rtc_get_time = indy_rtc_get_time; diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip27/Makefile linux-2.4.21-bk38/arch/mips/sgi-ip27/Makefile --- linux-2.4.21-bk37/arch/mips/sgi-ip27/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip27/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -6,8 +6,6 @@ O_TARGET = ip27.o -export-objs = ip27-rtc.o - obj-y := ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \ ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-pci.o \ ip27-reset.o ip27-setup.o ip27-timer.o diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip27/ip27-berr.c linux-2.4.21-bk38/arch/mips/sgi-ip27/ip27-berr.c --- linux-2.4.21-bk37/arch/mips/sgi-ip27/ip27-berr.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip27/ip27-berr.c 2003-08-24 02:55:58.000000000 -0700 @@ -17,9 +17,7 @@ #include #include #include - -extern void dump_tlb_addr(unsigned long addr); -extern void dump_tlb_all(void); +#include static void dump_hub_information(unsigned long errst0, unsigned long errst1) { @@ -54,7 +52,7 @@ ? : "invalid"); } -int be_ip27_handler(struct pt_regs *regs, int is_fixup) +int ip27_be_handler(struct pt_regs *regs, int is_fixup) { unsigned long errst0, errst1; int data = regs->cp0_cause & 4; @@ -76,13 +74,13 @@ force_sig(SIGBUS, current); } -void __init bus_error_init(void) +void __init ip27_be_init(void) { /* XXX Initialize all the Hub & Bridge error handling here. */ int cpu = LOCAL_HUB_L(PI_CPU_NUM); int cpuoff = cpu << 8; - be_board_handler = be_ip27_handler; + board_be_handler = ip27_be_handler; LOCAL_HUB_S(PI_ERR_INT_PEND, cpu ? PI_ERR_CLEAR_ALL_B : PI_ERR_CLEAR_ALL_A); diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip27/ip27-console.c linux-2.4.21-bk38/arch/mips/sgi-ip27/ip27-console.c --- linux-2.4.21-bk37/arch/mips/sgi-ip27/ip27-console.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip27/ip27-console.c 2003-08-24 02:55:58.000000000 -0700 @@ -3,25 +3,35 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001 Ralf Baechle + * Copyright (C) 2001, 2002 Ralf Baechle */ #include #include #include #include +#include +#include #include #include #include #include #include -void prom_putchar(char c) +#define IOC3_BAUD (22000000 / (3*16)) +#define IOC3_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) + +static inline struct ioc3_uartregs *console_uart(void) { struct ioc3 *ioc3; - struct ioc3_uartregs *uart; - ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base; - uart = &ioc3->sregs.uarta; + ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(get_nasid())->memory_base; + + return &ioc3->sregs.uarta; +} + +void prom_putchar(char c) +{ + struct ioc3_uartregs *uart = console_uart(); while ((uart->iu_lsr & 0x20) == 0); uart->iu_thr = c; @@ -32,27 +42,24 @@ return 0; } -static void -ip27prom_console_write(struct console *con, const char *s, unsigned n) +static void inline ioc3_console_probe(void) { - prom_printf("%s", s); -} + struct serial_struct req; -static kdev_t -ip27prom_console_dev(struct console *c) -{ - return MKDEV(TTY_MAJOR, 64 + c->index); -} + /* Register to interrupt zero because we share the interrupt with + the serial driver which we don't properly support yet. */ + memset(&req, 0, sizeof(req)); + req.irq = 0; + req.flags = IOC3_COM_FLAGS; + req.io_type = SERIAL_IO_MEM; + req.iomem_reg_shift = 0; + req.baud_base = IOC3_BAUD; -static struct console ip27_prom_console = { - name: "prom", - write: ip27prom_console_write, - device: ip27prom_console_dev, - flags: CON_PRINTBUFFER, - index: -1, -}; + req.iomem_base = (unsigned char *) console_uart(); + register_serial(&req); +} __init void ip27_setup_console(void) { - register_console(&ip27_prom_console); + ioc3_console_probe(); } diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip27/ip27-init.c linux-2.4.21-bk38/arch/mips/sgi-ip27/ip27-init.c --- linux-2.4.21-bk37/arch/mips/sgi-ip27/ip27-init.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip27/ip27-init.c 2003-08-24 02:55:58.000000000 -0700 @@ -193,7 +193,6 @@ void init_topology_matrix(void); void dump_topology(void); - master_nasid = get_nasid(); fine_mode = is_fine_dirmode(); @@ -203,7 +202,7 @@ */ CPUMASK_CLRALL(boot_cpumask); maxcpus = cpu_node_probe(&boot_cpumask, &numnodes); - printk("Discovered %d cpus on %d nodes\n", maxcpus, numnodes); + printk(KERN_INFO "Discovered %d cpus on %d nodes\n", maxcpus, numnodes); init_topology_matrix(); dump_topology(); @@ -333,8 +332,7 @@ memcpy((void *)(KSEG0 + 0x100), (void *) KSEG0, 0x80); memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x100); - flush_cache_l1(); - flush_cache_l2(); + __flush_cache_all(); } #endif } @@ -364,7 +362,7 @@ #if 0 intr_init(); #endif - clear_cp0_status(ST0_IM); + clear_c0_status(ST0_IM); per_hub_init(cnode); cpu_time_init(); if (smp_processor_id()) /* master can't do this early, no kmalloc */ @@ -374,13 +372,8 @@ #if 0 install_tlbintr(cpu); #endif - set_cp0_status(SRB_DEV0 | SRB_DEV1); + set_c0_status(SRB_DEV0 | SRB_DEV1); if (is_slave) { - clear_cp0_status(ST0_BEV); - if (mips_cpu.isa_level == MIPS_CPU_ISA_IV) - set_cp0_status(ST0_XX); - set_cp0_status(ST0_KX|ST0_SX|ST0_UX); - sti(); load_mmu(); atomic_inc(&numstarted); } else { @@ -422,9 +415,15 @@ static volatile cpumask_t boot_barrier; +extern atomic_t cpus_booted; + void __init start_secondary(void) { + unsigned int cpu = smp_processor_id(); + extern atomic_t smp_commenced; + CPUMASK_CLRB(boot_barrier, getcpuid()); /* needs atomicity */ + cpu_probe(); per_cpu_init(); per_cpu_trap_init(); #if 0 @@ -433,9 +432,33 @@ init_mfhi_war(); #endif local_flush_tlb_all(); - flush_cache_l1(); - flush_cache_l2(); - start_secondary(); + __flush_cache_all(); + + local_irq_enable(); +#if 0 + /* + * Get our bogomips. + */ + calibrate_delay(); + smp_store_cpu_info(cpuid); + prom_smp_finish(); +#endif + printk("Slave cpu booted successfully\n"); + CPUMASK_SETB(cpu_online_map, cpu); + atomic_inc(&cpus_booted); + + while (!atomic_read(&smp_commenced)); + return cpu_idle(); +} + +static int __init fork_by_hand(void) +{ + struct pt_regs regs; + /* + * don't care about the epc and regs settings since + * we'll never reschedule the forked task. + */ + return do_fork(CLONE_VM|CLONE_PID, 0, ®s, 0); } __init void allowboot(void) @@ -457,68 +480,79 @@ boot_barrier = boot_cpumask; /* Launch slaves. */ for (cpu = 0; cpu < maxcpus; cpu++) { + struct task_struct *idle; + if (cpu == mycpuid) { alloc_cpupda(cpu, num_cpus); num_cpus++; /* We're already started, clear our bit */ + CPUMASK_SETB(cpu_online_map, cpu); CPUMASK_CLRB(boot_barrier, cpu); continue; } /* Skip holes in CPU space */ - if (CPUMASK_TSTB(boot_cpumask, cpu)) { - struct task_struct *p; + if (!CPUMASK_TSTB(boot_cpumask, cpu)) + continue; - /* - * The following code is purely to make sure - * Linux can schedule processes on this slave. - */ - kernel_thread(0, NULL, CLONE_PID); - p = init_task.prev_task; - sprintf(p->comm, "%s%d", "Idle", num_cpus); - init_tasks[num_cpus] = p; - alloc_cpupda(cpu, num_cpus); - del_from_runqueue(p); - p->processor = num_cpus; - p->cpus_runnable = 1 << num_cpus; /* we schedule the first task manually */ - unhash_process(p); - /* Attach to the address space of init_task. */ - atomic_inc(&init_mm.mm_count); - p->active_mm = &init_mm; - - /* - * Launch a slave into smp_bootstrap(). - * It doesn't take an argument, and we - * set sp to the kernel stack of the newly - * created idle process, gp to the proc struct - * (so that current-> works). - */ - LAUNCH_SLAVE(cputonasid(num_cpus),cputoslice(num_cpus), - (launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap), - 0, (void *)((unsigned long)p + - KERNEL_STACK_SIZE - 32), (void *)p); - - /* - * Now optimistically set the mapping arrays. We - * need to wait here, verify the cpu booted up, then - * fire up the next cpu. - */ - __cpu_number_map[cpu] = num_cpus; - __cpu_logical_map[num_cpus] = cpu; - CPUMASK_SETB(cpu_online_map, cpu); - num_cpus++; - /* - * Wait this cpu to start up and initialize its hub, - * and discover the io devices it will control. - * - * XXX: We really want to fire up launch all the CPUs - * at once. We have to preserve the order of the - * devices on the bridges first though. - */ - while(atomic_read(&numstarted) != num_cpus); - } - } + /* + * We can't use kernel_thread since we must avoid to + * reschedule the child. + */ + if (fork_by_hand() < 0) + panic("failed fork for CPU %d", num_cpus); + + /* + * We remove it from the pidhash and the runqueue + * once we got the process: + */ + idle = init_task.prev_task; + if (!idle) + panic("No idle process for CPU %d", num_cpus); + + idle->processor = num_cpus; + idle->cpus_runnable = 1 << cpu; /* we schedule the first task manually */ + + alloc_cpupda(cpu, num_cpus); + + idle->thread.reg31 = (unsigned long) start_secondary; + del_from_runqueue(idle); + unhash_process(idle); + init_tasks[num_cpus] = idle; + + /* + * Launch a slave into smp_bootstrap(). + * It doesn't take an argument, and we + * set sp to the kernel stack of the newly + * created idle process, gp to the proc struct + * (so that current-> works). + */ + LAUNCH_SLAVE(cputonasid(num_cpus),cputoslice(num_cpus), + (launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap), + 0, (void *)((unsigned long)idle + + KERNEL_STACK_SIZE - 32), (void *)idle); + + /* + * Now optimistically set the mapping arrays. We + * need to wait here, verify the cpu booted up, then + * fire up the next cpu. + */ + __cpu_number_map[cpu] = num_cpus; + __cpu_logical_map[num_cpus] = cpu; + CPUMASK_SETB(cpu_online_map, cpu); + num_cpus++; + + /* + * Wait this cpu to start up and initialize its hub, + * and discover the io devices it will control. + * + * XXX: We really want to fire up launch all the CPUs + * at once. We have to preserve the order of the + * devices on the bridges first though. + */ + while (atomic_read(&numstarted) != num_cpus); + } #ifdef LATER Wait logic goes here. @@ -545,7 +579,7 @@ init_new_context(current, &init_mm); current->processor = 0; init_idle(); - smp_tune_scheduling(); + /* smp_tune_scheduling(); XXX */ allowboot(); } diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip27/ip27-irq.c linux-2.4.21-bk38/arch/mips/sgi-ip27/ip27-irq.c --- linux-2.4.21-bk37/arch/mips/sgi-ip27/ip27-irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip27/ip27-irq.c 2003-08-24 02:55:58.000000000 -0700 @@ -7,6 +7,7 @@ */ #include #include +#include #include #include #include @@ -25,7 +26,6 @@ #include #include #include -#include #include #include @@ -68,7 +68,6 @@ */ extern asmlinkage void ip27_irq(void); -extern void do_IRQ(int irq, struct pt_regs *regs); extern int irq_to_bus[], irq_to_slot[], bus_to_cpu[]; int intr_connect_level(int cpu, int bit); diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip27/ip27-pci.c linux-2.4.21-bk38/arch/mips/sgi-ip27/ip27-pci.c --- linux-2.4.21-bk37/arch/mips/sgi-ip27/ip27-pci.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip27/ip27-pci.c 2003-08-24 02:55:58.000000000 -0700 @@ -70,20 +70,20 @@ return PCIBIOS_SUCCESSFUL; \ } while (0) -static int -pci_conf0_read_config_byte(struct pci_dev *dev, int where, u8 *value) +static int pci_conf0_read_config_byte(struct pci_dev *dev, int where, + u8 *value) { CF0_READ_PCI_CFG(dev,where,value,3,0xff); } -static int -pci_conf0_read_config_word(struct pci_dev *dev, int where, u16 *value) +static int pci_conf0_read_config_word(struct pci_dev *dev, int where, + u16 *value) { CF0_READ_PCI_CFG(dev,where,value,2,0xffff); } -static int -pci_conf0_read_config_dword(struct pci_dev *dev, int where, u32 *value) +static int pci_conf0_read_config_dword(struct pci_dev *dev, int where, + u32 *value) { CF0_READ_PCI_CFG(dev,where,value,0,0xffffffff); } @@ -115,20 +115,20 @@ return PCIBIOS_SUCCESSFUL; \ } while (0) -static int -pci_conf0_write_config_byte(struct pci_dev *dev, int where, u8 value) +static int pci_conf0_write_config_byte(struct pci_dev *dev, int where, + u8 value) { CF0_WRITE_PCI_CFG(dev,where,value,3,0xff); } -static int -pci_conf0_write_config_word(struct pci_dev *dev, int where, u16 value) +static int pci_conf0_write_config_word(struct pci_dev *dev, int where, + u16 value) { CF0_WRITE_PCI_CFG(dev,where,value,2,0xffff); } -static int -pci_conf0_write_config_dword(struct pci_dev *dev, int where, u32 value) +static int pci_conf0_write_config_dword(struct pci_dev *dev, int where, + u32 value) { CF0_WRITE_PCI_CFG(dev,where,value,0,0xffffffff); } @@ -157,14 +157,12 @@ } } -static inline u8 -bridge_swizzle(u8 pin, u8 slot) +static inline u8 bridge_swizzle(u8 pin, u8 slot) { return (((pin-1) + slot) % 4) + 1; } -static u8 __init -pci_swizzle(struct pci_dev *dev, u8 *pinp) +static u8 __devinit pci_swizzle(struct pci_dev *dev, u8 *pinp) { u8 pin = *pinp; @@ -186,8 +184,7 @@ * A given PCI device, in general, should be able to intr any of the cpus * on any one of the hubs connected to its xbow. */ -static int __init -pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int __devinit pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { if ((dev->bus->number >= MAX_PCI_BUSSES) || (pin != 1) @@ -208,35 +205,18 @@ return lastirq - 1; } -void __init -pcibios_update_irq(struct pci_dev *dev, int irq) +void __init pcibios_update_irq(struct pci_dev *dev, int irq) { pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); } -void __init -pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - unsigned long where, size; - u32 reg; - - where = PCI_BASE_ADDRESS_0 + (resource * 4); - size = res->end - res->start; - pci_read_config_dword(dev, where, ®); - reg = (reg & size) | (((u32)(res->start - root->start)) & ~size); - pci_write_config_dword(dev, where, reg); -} - -void __init -pcibios_fixup_bus(struct pci_bus *b) +void __devinit pcibios_fixup_bus(struct pci_bus *b) { pci_fixup_irqs(pci_swizzle, pci_map_irq); } -void __init -pcibios_fixup_pbus_ranges(struct pci_bus * bus, - struct pbus_set_ranges_data * ranges) +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; @@ -244,32 +224,11 @@ ranges->mem_end -= bus->resource[1]->start; } -int __init -pcibios_enable_device(struct pci_dev *dev) +unsigned int pcibios_assign_all_busses(void) { - /* Not needed, since we enable all devices at startup. */ return 0; } -void __init -pcibios_align_resource(void *data, struct resource *res, unsigned long size, - unsigned long align) -{ -} - -unsigned __init int pcibios_assign_all_busses(void) -{ - return 0; -} - -char * __init -pcibios_setup(char *str) -{ - /* Nothing to do for now. */ - - return str; -} - /* * Device might live on a subordinate PCI bus. XXX Walk up the chain of buses * to find the slot number in sense of the bridge device register. @@ -277,8 +236,7 @@ * settings. */ -static void __init -pci_disable_swapping(struct pci_dev *dev) +static void __init pci_disable_swapping(struct pci_dev *dev) { unsigned int bus_id = (unsigned) dev->bus->number; bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id], @@ -290,8 +248,7 @@ bridge->b_widget.w_tflush; /* Flush */ } -static void __init -pci_enable_swapping(struct pci_dev *dev) +static void __init pci_enable_swapping(struct pci_dev *dev) { unsigned int bus_id = (unsigned) dev->bus->number; bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id], @@ -303,8 +260,7 @@ bridge->b_widget.w_tflush; /* Flush */ } -static void __init -pci_fixup_ioc3(struct pci_dev *d) +static void __init pci_fixup_ioc3(struct pci_dev *d) { unsigned long bus_id = (unsigned) d->bus->number; @@ -316,8 +272,7 @@ pci_disable_swapping(d); } -static void __init -pci_fixup_isp1020(struct pci_dev *d) +static void __init pci_fixup_isp1020(struct pci_dev *d) { unsigned short command; @@ -341,8 +296,7 @@ pci_enable_swapping(d); } -static void __init -pci_fixup_isp2x00(struct pci_dev *d) +static void __init pci_fixup_isp2x00(struct pci_dev *d) { unsigned int bus_id = (unsigned) d->bus->number; bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id], diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip27/ip27-rtc.c linux-2.4.21-bk38/arch/mips/sgi-ip27/ip27-rtc.c --- linux-2.4.21-bk37/arch/mips/sgi-ip27/ip27-rtc.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip27/ip27-rtc.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,334 +0,0 @@ -/* - * Driver for the SGS-Thomson M48T35 Timekeeper RAM chip - * - * Real Time Clock interface for Linux - * - * TODO: Implement periodic interrupts. - * - * Copyright (C) 2000 Silicon Graphics, Inc. - * Written by Ulf Carlsson (ulfc@engr.sgi.com) - * - * Based on code written by Paul Gortmaker. - * - * This driver allows use of the real time clock (built into - * nearly all computers) from user space. It exports the /dev/rtc - * interface supporting various ioctl() and also the /proc/rtc - * pseudo-file for status information. - * - * 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. - * - */ - -#define RTC_VERSION "1.09b" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -static int rtc_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); - -static int rtc_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data); - -static void get_rtc_time(struct rtc_time *rtc_tm); - -/* - * Bits in rtc_status. (6 bits of room for future expansion) - */ - -#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ -#define RTC_TIMER_ON 0x02 /* missed irq timer active */ - -static unsigned char rtc_status; /* bitmapped status byte. */ -static spinlock_t rtc_status_lock = SPIN_LOCK_UNLOCKED; -static unsigned long rtc_freq; /* Current periodic IRQ rate */ -static struct m48t35_rtc *rtc; - -/* - * If this driver ever becomes modularised, it will be really nice - * to make the epoch retain its value across module reload... - */ - -static unsigned long epoch = 1970; /* year corresponding to 0x00 */ - -static const unsigned char days_in_mo[] = -{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - -static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) -{ - - struct rtc_time wtime; - - switch (cmd) { - case RTC_RD_TIME: /* Read the time/date from RTC */ - { - get_rtc_time(&wtime); - break; - } - case RTC_SET_TIME: /* Set the RTC */ - { - struct rtc_time rtc_tm; - unsigned char mon, day, hrs, min, sec, leap_yr; - unsigned int yrs; - unsigned long flags; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, - sizeof(struct rtc_time))) - return -EFAULT; - - yrs = rtc_tm.tm_year + 1900; - mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ - day = rtc_tm.tm_mday; - hrs = rtc_tm.tm_hour; - min = rtc_tm.tm_min; - sec = rtc_tm.tm_sec; - - if (yrs < 1970) - return -EINVAL; - - leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); - - if ((mon > 12) || (day == 0)) - return -EINVAL; - - if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) - return -EINVAL; - - if ((hrs >= 24) || (min >= 60) || (sec >= 60)) - return -EINVAL; - - if ((yrs -= epoch) > 255) /* They are unsigned */ - return -EINVAL; - - save_flags(flags); - cli(); - if (yrs > 169) { - restore_flags(flags); - return -EINVAL; - } - if (yrs >= 100) - yrs -= 100; - - BIN_TO_BCD(sec); - BIN_TO_BCD(min); - BIN_TO_BCD(hrs); - BIN_TO_BCD(day); - BIN_TO_BCD(mon); - BIN_TO_BCD(yrs); - - rtc->control &= ~M48T35_RTC_SET; - rtc->year = yrs; - rtc->month = mon; - rtc->date = day; - rtc->hour = hrs; - rtc->min = min; - rtc->sec = sec; - rtc->control &= ~M48T35_RTC_SET; - - restore_flags(flags); - return 0; - } - default: - return -EINVAL; - } - return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; -} - -/* - * We enforce only one user at a time here with the open/close. - * Also clear the previous interrupt data on an open, and clean - * up things on a close. - */ - -static int rtc_open(struct inode *inode, struct file *file) -{ - spin_lock(rtc_status_lock); - - if (rtc_status & RTC_IS_OPEN) { - spin_unlock(rtc_status_lock); - return -EBUSY; - } - - rtc_status |= RTC_IS_OPEN; - spin_unlock(rtc_status_lock); - - return 0; -} - -static int rtc_release(struct inode *inode, struct file *file) -{ - /* - * Turn off all interrupts once the device is no longer - * in use, and clear the data. - */ - - spin_lock(rtc_status_lock); - rtc_status &= ~RTC_IS_OPEN; - spin_unlock(rtc_status_lock); - - return 0; -} - -/* - * The various file operations we support. - */ - -static struct file_operations rtc_fops = { - owner: THIS_MODULE, - ioctl: rtc_ioctl, - open: rtc_open, - release: rtc_release, -}; - -static struct miscdevice rtc_dev= -{ - RTC_MINOR, - "rtc", - &rtc_fops -}; - -static int __init rtc_init(void) -{ - unsigned long flags; - nasid_t nid; - - nid = get_nasid(); - rtc = (struct m48t35_rtc *) - KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0; - - printk(KERN_INFO "Real Time Clock Driver v%s\n", RTC_VERSION); - if (misc_register(&rtc_dev)) - return -ENODEV; - create_proc_read_entry ("rtc", 0, NULL, rtc_read_proc, NULL); - - save_flags(flags); - cli(); - restore_flags(flags); - rtc_freq = 1024; - return 0; -} - -static void __exit rtc_exit (void) -{ - /* interrupts and timer disabled at this point by rtc_release */ - - remove_proc_entry ("rtc", NULL); - misc_deregister(&rtc_dev); -} - -module_init(rtc_init); -module_exit(rtc_exit); -EXPORT_NO_SYMBOLS; - -/* - * Info exported via "/proc/rtc". - */ - -static int rtc_get_status(char *buf) -{ - char *p; - struct rtc_time tm; - - /* - * Just emulate the standard /proc/rtc - */ - - p = buf; - - get_rtc_time(&tm); - - /* - * There is no way to tell if the luser has the RTC set for local - * time or for Universal Standard Time (GMT). Probably local though. - */ - p += sprintf(p, - "rtc_time\t: %02d:%02d:%02d\n" - "rtc_date\t: %04d-%02d-%02d\n" - "rtc_epoch\t: %04lu\n" - "24hr\t\t: yes\n", - tm.tm_hour, tm.tm_min, tm.tm_sec, - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch); - - return p - buf; -} - -static int rtc_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len = rtc_get_status(page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - return len; -} - -static void get_rtc_time(struct rtc_time *rtc_tm) -{ - - unsigned long flags; - - /* - * Do we need to wait for the last update to finish? - */ - - /* - * Only the values that we read from the RTC are set. We leave - * tm_wday, tm_yday and tm_isdst untouched. Even though the - * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated - * by the RTC when initially set to a non-zero value. - */ - save_flags(flags); - cli(); - rtc->control |= M48T35_RTC_READ; - rtc_tm->tm_sec = rtc->sec; - rtc_tm->tm_min = rtc->min; - rtc_tm->tm_hour = rtc->hour; - rtc_tm->tm_mday = rtc->date; - rtc_tm->tm_mon = rtc->month; - rtc_tm->tm_year = rtc->year; - rtc->control &= ~M48T35_RTC_READ; - restore_flags(flags); - - BCD_TO_BIN(rtc_tm->tm_sec); - BCD_TO_BIN(rtc_tm->tm_min); - BCD_TO_BIN(rtc_tm->tm_hour); - BCD_TO_BIN(rtc_tm->tm_mday); - BCD_TO_BIN(rtc_tm->tm_mon); - BCD_TO_BIN(rtc_tm->tm_year); - - /* - * Account for differences between how the RTC uses the values - * and how they are defined in a struct rtc_time; - */ - if ((rtc_tm->tm_year += (epoch - 1900)) <= 69) - rtc_tm->tm_year += 100; - - rtc_tm->tm_mon--; -} diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip27/ip27-setup.c linux-2.4.21-bk38/arch/mips/sgi-ip27/ip27-setup.c --- linux-2.4.21-bk37/arch/mips/sgi-ip27/ip27-setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip27/ip27-setup.c 2003-08-24 02:55:58.000000000 -0700 @@ -29,6 +29,7 @@ #include #include #include +#include /* Check against user dumbness. */ #ifdef CONFIG_VT @@ -42,6 +43,8 @@ #define DBG(x...) #endif +extern void ip27_be_init(void) __init; + /* * get_nasid() returns the physical node id number of the caller. */ @@ -276,6 +279,7 @@ extern void ip27_setup_console(void); extern void ip27_time_init(void); +extern void ip27_reboot_setup(void); void __init ip27_setup(void) { @@ -283,6 +287,7 @@ hubreg_t p, e; ip27_setup_console(); + ip27_reboot_setup(); num_bridges = 0; /* @@ -309,6 +314,8 @@ ioc3_eth_init(); per_cpu_init(); - mips_io_port_base = IO_BASE; + set_io_port_base(IO_BASE); + + board_be_init = ip27_be_init; board_time_init = ip27_time_init; } diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip27/ip27-timer.c linux-2.4.21-bk38/arch/mips/sgi-ip27/ip27-timer.c --- linux-2.4.21-bk37/arch/mips/sgi-ip27/ip27-timer.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip27/ip27-timer.c 2003-08-24 02:55:58.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copytight (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) + * Copytight (C) 1999, 2000, 2002 Ralf Baechle (ralf@gnu.org) * Copytight (C) 1999, 2000 Silicon Graphics, Inc. */ #include @@ -55,6 +55,7 @@ rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0); + spin_lock(&rtc_lock); rtc->control |= M48T35_RTC_READ; cmos_minutes = rtc->min; BCD_TO_BIN(cmos_minutes); @@ -84,15 +85,18 @@ cmos_minutes, real_minutes); retval = -1; } + spin_unlock(&rtc_lock); return retval; } +#define IP27_TIMER_IRQ 9 /* XXX Assign number */ + void rt_timer_interrupt(struct pt_regs *regs) { int cpu = smp_processor_id(); int cpuA = ((cputoslice(cpu)) == 0); - int irq = 9; /* XXX Assign number */ + int irq = IP27_TIMER_IRQ; irq_enter(cpu, irq); write_lock(&xtime_lock); @@ -157,7 +161,7 @@ static __init unsigned long get_m48t35_time(void) { - unsigned int year, month, date, hour, min, sec; + unsigned int year, month, date, hour, min, sec; struct m48t35_rtc *rtc; nasid_t nid; @@ -165,6 +169,7 @@ rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0); + spin_lock(&rtc_lock); rtc->control |= M48T35_RTC_READ; sec = rtc->sec; min = rtc->min; @@ -173,17 +178,27 @@ month = rtc->month; year = rtc->year; rtc->control &= ~M48T35_RTC_READ; + spin_unlock(&rtc_lock); + + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(date); + BCD_TO_BIN(month); + BCD_TO_BIN(year); + + year += 1970; - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hour); - BCD_TO_BIN(date); - BCD_TO_BIN(month); - BCD_TO_BIN(year); + return mktime(year, month, date, hour, min, sec); +} - year += 1970; +static void ip27_timer_setup(struct irqaction *irq) +{ + /* over-write the handler, we use our own way */ + irq->handler = no_action; - return mktime(year, month, date, hour, min, sec); + /* setup irqaction */ +// setup_irq(IP27_TIMER_IRQ, irq); /* XXX Can't do this yet. */ } void __init ip27_time_init(void) @@ -192,6 +207,9 @@ xtime.tv_usec = 0; do_gettimeoffset = ip27_do_gettimeoffset; + + // board_time_init = ip27_time_init; + board_timer_setup = ip27_timer_setup; } void __init cpu_time_init(void) @@ -212,7 +230,7 @@ printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed); - set_cp0_status(SRB_TIMOCLK); + set_c0_status(SRB_TIMOCLK); } void __init hub_rtc_init(cnodeid_t cnode) diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip32/Makefile linux-2.4.21-bk38/arch/mips/sgi-ip32/Makefile --- linux-2.4.21-bk37/arch/mips/sgi-ip32/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip32/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,22 +0,0 @@ -# -# Makefile for the SGI specific kernel interface routines -# under Linux. -# -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# -# Note 2! The CFLAGS definitions are now in the main makefile... - -USE_STANDARD_AS_RULE := true - -O_TARGET := ip32-kern.a - -all: ip32-kern.a ip32-irq-glue.o - -obj-y += ip32-berr.o ip32-rtc.o ip32-setup.o ip32-irq.o ip32-irq-glue.o \ - ip32-timer.o crime.o ip32-reset.o - -obj-$(CONFIG_PCI) += ip32-pci.o - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip32/crime.c linux-2.4.21-bk38/arch/mips/sgi-ip32/crime.c --- linux-2.4.21-bk37/arch/mips/sgi-ip32/crime.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip32/crime.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,49 +0,0 @@ -/* - * 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. - * - * Copyright (C) 2001 Keith M Wesolowski - */ -#include -#include -#include -#include -#include - -void __init crime_init (void) -{ - u64 id = crime_read_64 (CRIME_ID); - u64 rev = id & CRIME_ID_REV; - - id = (id & CRIME_ID_IDBITS) >> 4; - - printk ("CRIME id %1lx rev %ld detected at %016lx\n", id, rev, - (unsigned long) CRIME_BASE); -} - -/* XXX Like on Sun, these give us various useful information to printk. */ -void crime_memerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs) -{ - u64 memerr = crime_read_64 (CRIME_MEM_ERROR_STAT); - u64 addr = crime_read_64 (CRIME_MEM_ERROR_ADDR); - memerr &= CRIME_MEM_ERROR_STAT_MASK; - - printk ("CRIME memory error at physaddr 0x%08lx status %08lx\n", - addr << 2, memerr); - - crime_write_64 (CRIME_MEM_ERROR_STAT, 0); -} - -void crime_cpuerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs) -{ - u64 cpuerr = crime_read_64 (CRIME_CPU_ERROR_STAT); - u64 addr = crime_read_64 (CRIME_CPU_ERROR_ADDR); - cpuerr &= CRIME_CPU_ERROR_MASK; - addr <<= 2UL; - - printk ("CRIME CPU interface error detected at %09lx status %08lx\n", - addr, cpuerr); - - crime_write_64 (CRIME_CPU_ERROR_STAT, 0); -} diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip32/ip32-berr.c linux-2.4.21-bk38/arch/mips/sgi-ip32/ip32-berr.c --- linux-2.4.21-bk37/arch/mips/sgi-ip32/ip32-berr.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip32/ip32-berr.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,36 +0,0 @@ -/* - * 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. - * - * Copyright (C) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle - * Copyright (C) 1999, 2000 by Silicon Graphics - * Copyright (C) 2002 Maciej W. Rozycki - */ -#include -#include -#include -#include -#include -#include - -int -be_ip32_handler(struct pt_regs *regs, int is_fixup) -{ - int data = regs->cp0_cause & 4; - - if (is_fixup) - return MIPS_BE_FIXUP; - - printk("Got %cbe at 0x%lx\n", data ? 'd' : 'i', regs->cp0_epc); - show_regs(regs); - dump_tlb_all(); - while(1); - force_sig(SIGBUS, current); -} - -void __init -bus_error_init(void) -{ - be_board_handler = be_ip32_handler; -} diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip32/ip32-irq-glue.S linux-2.4.21-bk38/arch/mips/sgi-ip32/ip32-irq-glue.S --- linux-2.4.21-bk37/arch/mips/sgi-ip32/ip32-irq-glue.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip32/ip32-irq-glue.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,87 +0,0 @@ -/* - * Low level interrupt handler for the SGI O2 aka IP32 aka Moosehead - * - * 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. - * - * Copyright (C) 2000 Harald Koerfgen - * Copyright (C) 2001 Keith M Wesolowski - */ -#include -#include -#include -#include -#include -#include - - .text - .set noreorder - .set noat - .align 5 - NESTED(ip32_handle_int, PT_SIZE, ra) - .set noat - SAVE_ALL - CLI # TEST: interrupts should be off - .set at - .set noreorder - - mfc0 s0,CP0_CAUSE - - andi t1, s0, IE_IRQ0 - bnez t1, handle_irq0 - andi t1, s0, IE_IRQ1 - bnez t1, handle_irq1 - andi t1, s0, IE_IRQ2 - bnez t1, handle_irq2 - andi t1, s0, IE_IRQ3 - bnez t1, handle_irq3 - andi t1, s0, IE_IRQ4 - bnez t1, handle_irq4 - andi t1, s0, IE_IRQ5 - bnez t1, handle_irq5 - nop - - /* Either someone has triggered the "software interrupts" - * or we lost an interrupt somehow. Ignore it. - */ - j ret_from_irq - nop - -handle_irq0: - jal ip32_irq0 - move a0, sp - j ret_from_irq - nop - -handle_irq1: - jal ip32_irq1 - move a0, sp - j ret_from_irq - nop - -handle_irq2: - jal ip32_irq2 - move a0, sp - j ret_from_irq - nop - -handle_irq3: - jal ip32_irq3 - move a0, sp - j ret_from_irq - nop - -handle_irq4: - jal ip32_irq4 - move a0, sp - j ret_from_irq - nop - -handle_irq5: - jal ip32_irq5 - move a0, sp - j ret_from_irq - nop - - END(ip32_handle_int) diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip32/ip32-irq.c linux-2.4.21-bk38/arch/mips/sgi-ip32/ip32-irq.c --- linux-2.4.21-bk37/arch/mips/sgi-ip32/ip32-irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip32/ip32-irq.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,584 +0,0 @@ -/* - * Code to handle IP32 IRQs - * - * 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. - * - * Copyright (C) 2000 Harald Koerfgen - * Copyright (C) 2001 Keith M Wesolowski - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#undef DEBUG_IRQ -#ifdef DEBUG_IRQ -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -/* O2 irq map - * - * IP0 -> software (ignored) - * IP1 -> software (ignored) - * IP2 -> (irq0) C crime 1.1 all interrupts; crime 1.5 ??? - * IP3 -> (irq1) X unknown - * IP4 -> (irq2) X unknown - * IP5 -> (irq3) X unknown - * IP6 -> (irq4) X unknown - * IP7 -> (irq5) 0 CPU count/compare timer (system timer) - * - * crime: (C) - * - * CRIME_INT_STAT 31:0: - * - * 0 -> 1 Video in 1 - * 1 -> 2 Video in 2 - * 2 -> 3 Video out - * 3 -> 4 Mace ethernet - * 4 -> S SuperIO sub-interrupt - * 5 -> M Miscellaneous sub-interrupt - * 6 -> A Audio sub-interrupt - * 7 -> 8 PCI bridge errors - * 8 -> 9 PCI SCSI aic7xxx 0 - * 9 -> 10 PCI SCSI aic7xxx 1 - * 10 -> 11 PCI slot 0 - * 11 -> 12 unused (PCI slot 1) - * 12 -> 13 unused (PCI slot 2) - * 13 -> 14 unused (PCI shared 0) - * 14 -> 15 unused (PCI shared 1) - * 15 -> 16 unused (PCI shared 2) - * 16 -> 17 GBE0 (E) - * 17 -> 18 GBE1 (E) - * 18 -> 19 GBE2 (E) - * 19 -> 20 GBE3 (E) - * 20 -> 21 CPU errors - * 21 -> 22 Memory errors - * 22 -> 23 RE empty edge (E) - * 23 -> 24 RE full edge (E) - * 24 -> 25 RE idle edge (E) - * 25 -> 26 RE empty level - * 26 -> 27 RE full level - * 27 -> 28 RE idle level - * 28 -> 29 unused (software 0) (E) - * 29 -> 30 unused (software 1) (E) - * 30 -> 31 unused (software 2) - crime 1.5 CPU SysCorError (E) - * 31 -> 32 VICE - * - * S, M, A: Use the MACE ISA interrupt register - * MACE_ISA_INT_STAT 31:0 - * - * 0-7 -> 33-40 Audio - * 8 -> 41 RTC - * 9 -> 42 Keyboard - * 10 -> X Keyboard polled - * 11 -> 44 Mouse - * 12 -> X Mouse polled - * 13-15 -> 46-48 Count/compare timers - * 16-19 -> 49-52 Parallel (16 E) - * 20-25 -> 53-58 Serial 1 (22 E) - * 26-31 -> 59-64 Serial 2 (28 E) - * - * Note that this means IRQs 5-7, 43, and 45 do not exist. This is a - * different IRQ map than IRIX uses, but that's OK as Linux irq handling - * is quite different anyway. - */ - -/* Some initial interrupts to set up */ -extern void crime_memerr_intr (unsigned int irq, void *dev_id, - struct pt_regs *regs); -extern void crime_cpuerr_intr (unsigned int irq, void *dev_id, - struct pt_regs *regs); - -struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT, - 0, "CRIME memory error", NULL, - NULL }; -struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT, - 0, "CRIME CPU error", NULL, - NULL }; - -extern void ip32_handle_int (void); -asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs); - -/* - * For interrupts wired from a single device to the CPU. Only the clock - * uses this it seems, which is IRQ 0 and IP7. - */ - -static void enable_cpu_irq(unsigned int irq) -{ - set_cp0_status(STATUSF_IP7); -} - -static unsigned int startup_cpu_irq(unsigned int irq) -{ - enable_cpu_irq(irq); - return 0; -} - -static void disable_cpu_irq(unsigned int irq) -{ - clear_cp0_status(STATUSF_IP7); -} - -static void end_cpu_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_cpu_irq (irq); -} - -#define shutdown_cpu_irq disable_cpu_irq -#define mask_and_ack_cpu_irq disable_cpu_irq - -static struct hw_interrupt_type ip32_cpu_interrupt = { - "IP32 CPU", - startup_cpu_irq, - shutdown_cpu_irq, - enable_cpu_irq, - disable_cpu_irq, - mask_and_ack_cpu_irq, - end_cpu_irq, - NULL -}; - -/* - * This is for pure CRIME interrupts - ie not MACE. The advantage? - * We get to split the register in half and do faster lookups. - */ - -static void enable_crime_irq(unsigned int irq) -{ - u64 crime_mask; - unsigned long flags; - - save_and_cli(flags); - crime_mask = crime_read_64(CRIME_INT_MASK); - crime_mask |= 1 << (irq - 1); - crime_write_64(CRIME_INT_MASK, crime_mask); - restore_flags(flags); -} - -static unsigned int startup_crime_irq(unsigned int irq) -{ - enable_crime_irq(irq); - return 0; /* This is probably not right; we could have pending irqs */ -} - -static void disable_crime_irq(unsigned int irq) -{ - u64 crime_mask; - unsigned long flags; - - save_and_cli(flags); - crime_mask = crime_read_64(CRIME_INT_MASK); - crime_mask &= ~(1 << (irq - 1)); - crime_write_64(CRIME_INT_MASK, crime_mask); - restore_flags(flags); -} - -static void mask_and_ack_crime_irq (unsigned int irq) -{ - u64 crime_mask; - unsigned long flags; - - /* Edge triggered interrupts must be cleared. */ - if ((irq >= CRIME_GBE0_IRQ && irq <= CRIME_GBE3_IRQ) - || (irq >= CRIME_RE_EMPTY_E_IRQ && irq <= CRIME_RE_IDLE_E_IRQ) - || (irq >= CRIME_SOFT0_IRQ && irq <= CRIME_SOFT2_IRQ)) { - save_and_cli(flags); - crime_mask = crime_read_64(CRIME_HARD_INT); - crime_mask &= ~(1 << (irq - 1)); - crime_write_64(CRIME_HARD_INT, crime_mask); - restore_flags(flags); - } - disable_crime_irq(irq); -} - -static void end_crime_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_crime_irq (irq); -} - -#define shutdown_crime_irq disable_crime_irq - -static struct hw_interrupt_type ip32_crime_interrupt = { - "IP32 CRIME", - startup_crime_irq, - shutdown_crime_irq, - enable_crime_irq, - disable_crime_irq, - mask_and_ack_crime_irq, - end_crime_irq, - NULL -}; - -/* - * This is for MACE PCI interrupts. We can decrease bus traffic by masking - * as close to the source as possible. This also means we can take the - * next chunk of the CRIME register in one piece. - */ - -static void enable_macepci_irq(unsigned int irq) -{ - u32 mace_mask; - u64 crime_mask; - unsigned long flags; - - save_and_cli(flags); - mace_mask = mace_read_32(MACEPCI_CONTROL); - mace_mask |= MACEPCI_CONTROL_INT(irq - 9); - mace_write_32(MACEPCI_CONTROL, mace_mask); - /* - * In case the CRIME interrupt isn't enabled, we must enable it; - * however, we never disable interrupts at that level. - */ - crime_mask = crime_read_64(CRIME_INT_MASK); - crime_mask |= 1 << (irq - 1); - crime_write_64(CRIME_INT_MASK, crime_mask); - restore_flags(flags); -} - -static unsigned int startup_macepci_irq(unsigned int irq) -{ - enable_macepci_irq (irq); - - return 0; /* XXX */ -} - -static void disable_macepci_irq(unsigned int irq) -{ - u32 mace_mask; - unsigned long flags; - - save_and_cli(flags); - mace_mask = mace_read_32(MACEPCI_CONTROL); - mace_mask &= ~MACEPCI_CONTROL_INT(irq - 9); - mace_write_32(MACEPCI_CONTROL, mace_mask); - restore_flags(flags); -} - -static void end_macepci_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_macepci_irq (irq); -} - -#define shutdown_macepci_irq disable_macepci_irq -#define mask_and_ack_macepci_irq disable_macepci_irq - -static struct hw_interrupt_type ip32_macepci_interrupt = { - "IP32 MACE PCI", - startup_macepci_irq, - shutdown_macepci_irq, - enable_macepci_irq, - disable_macepci_irq, - mask_and_ack_macepci_irq, - end_macepci_irq, - NULL -}; - -/* This is used for MACE ISA interrupts. That means bits 4-6 in the - * CRIME register. - */ - -static void enable_maceisa_irq (unsigned int irq) -{ - u64 crime_mask; - u32 mace_mask; - unsigned int crime_int = 0; - unsigned long flags; - - DBG ("maceisa enable: %u\n", irq); - - switch (irq) { - case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ: - crime_int = MACE_AUDIO_INT; - break; - case MACEISA_RTC_IRQ ... MACEISA_TIMER2_IRQ: - crime_int = MACE_MISC_INT; - break; - case MACEISA_PARALLEL_IRQ ... MACEISA_SERIAL2_RDMAOR_IRQ: - crime_int = MACE_SUPERIO_INT; - break; - } - DBG ("crime_int %016lx enabled\n", crime_int); - save_and_cli(flags); - crime_mask = crime_read_64(CRIME_INT_MASK); - crime_mask |= crime_int; - crime_write_64(CRIME_INT_MASK, crime_mask); - mace_mask = mace_read_32(MACEISA_INT_MASK); - mace_mask |= 1 << (irq - 33); - mace_write_32(MACEISA_INT_MASK, mace_mask); - restore_flags(flags); -} - -static unsigned int startup_maceisa_irq (unsigned int irq) -{ - enable_maceisa_irq(irq); - return 0; -} - -static void disable_maceisa_irq(unsigned int irq) -{ - u32 mace_mask; - unsigned long flags; - - save_and_cli (flags); - mace_mask = mace_read_32(MACEISA_INT_MASK); - mace_mask &= ~(1 << (irq - 33)); - mace_write_32(MACEISA_INT_MASK, mace_mask); - restore_flags(flags); -} - -static void mask_and_ack_maceisa_irq(unsigned int irq) -{ - u32 mace_mask; - unsigned long flags; - - switch (irq) { - case MACEISA_PARALLEL_IRQ: - case MACEISA_SERIAL1_TDMAPR_IRQ: - case MACEISA_SERIAL2_TDMAPR_IRQ: - save_and_cli(flags); - mace_mask = mace_read_32(MACEISA_INT_STAT); - mace_mask &= ~(1 << (irq - 33)); - mace_write_32(MACEISA_INT_STAT, mace_mask); - restore_flags(flags); - break; - } - disable_maceisa_irq(irq); -} - -static void end_maceisa_irq(unsigned irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_maceisa_irq (irq); -} - -#define shutdown_maceisa_irq disable_maceisa_irq - -static struct hw_interrupt_type ip32_maceisa_interrupt = { - "IP32 MACE ISA", - startup_maceisa_irq, - shutdown_maceisa_irq, - enable_maceisa_irq, - disable_maceisa_irq, - mask_and_ack_maceisa_irq, - end_maceisa_irq, - NULL -}; - -/* This is used for regular non-ISA, non-PCI MACE interrupts. That means - * bits 0-3 and 7 in the CRIME register. - */ - -static void enable_mace_irq(unsigned int irq) -{ - u64 crime_mask; - unsigned long flags; - - save_and_cli (flags); - crime_mask = crime_read_64 (CRIME_INT_MASK); - crime_mask |= 1 << (irq - 1); - crime_write_64 (CRIME_INT_MASK, crime_mask); - restore_flags (flags); -} - -static unsigned int startup_mace_irq(unsigned int irq) -{ - enable_mace_irq(irq); - return 0; -} - -static void disable_mace_irq(unsigned int irq) -{ - u64 crime_mask; - unsigned long flags; - - save_and_cli (flags); - crime_mask = crime_read_64 (CRIME_INT_MASK); - crime_mask &= ~(1 << (irq - 1)); - crime_write_64 (CRIME_INT_MASK, crime_mask); - restore_flags(flags); -} - -static void end_mace_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_mace_irq (irq); -} - -#define shutdown_mace_irq disable_mace_irq -#define mask_and_ack_mace_irq disable_mace_irq - -static struct hw_interrupt_type ip32_mace_interrupt = { - "IP32 MACE", - startup_mace_irq, - shutdown_mace_irq, - enable_mace_irq, - disable_mace_irq, - mask_and_ack_mace_irq, - end_mace_irq, - NULL -}; - -static void ip32_unknown_interrupt (struct pt_regs *regs) -{ - u64 crime; - u32 mace; - - printk ("Unknown interrupt occurred!\n"); - printk ("cp0_status: %08x\tcp0_cause: %08x\n", - read_32bit_cp0_register (CP0_STATUS), - read_32bit_cp0_register (CP0_CAUSE)); - crime = crime_read_64 (CRIME_INT_MASK); - printk ("CRIME interrupt mask: %016lx\n", crime); - crime = crime_read_64 (CRIME_INT_STAT); - printk ("CRIME interrupt status: %016lx\n", crime); - crime = crime_read_64 (CRIME_HARD_INT); - printk ("CRIME hardware interrupt register: %016lx\n", crime); - mace = mace_read_32 (MACEISA_INT_MASK); - printk ("MACE ISA interrupt mask: %08x\n", mace); - mace = mace_read_32 (MACEISA_INT_STAT); - printk ("MACE ISA interrupt status: %08x\n", mace); - mace = mace_read_32 (MACEPCI_CONTROL); - printk ("MACE PCI control register: %08x\n", mace); - - printk("Register dump:\n"); - show_regs(regs); - - printk("Please mail this report to linux-mips@oss.sgi.com\n"); - printk("Spinning..."); - while(1) ; -} - -/* CRIME 1.1 appears to deliver all interrupts to this one pin. */ -void ip32_irq0(struct pt_regs *regs) -{ - u64 crime_int; - u64 crime_mask; - int irq = 0; - unsigned long flags; - - save_and_cli (flags); - /* disable crime interrupts */ - crime_mask = crime_read_64(CRIME_INT_MASK); - crime_write_64(CRIME_INT_MASK, 0); - - crime_int = crime_read_64(CRIME_INT_STAT); - - if (crime_int & CRIME_MACE_INT_MASK) { - crime_int &= CRIME_MACE_INT_MASK; - irq = ffs (crime_int); - } else if (crime_int & CRIME_MACEISA_INT_MASK) { - u32 mace_int; - mace_int = mace_read_32 (MACEISA_INT_STAT); - if (mace_int == 0) - irq = 0; - else - irq = ffs (mace_int) + 32; - } else if (crime_int & CRIME_MACEPCI_INT_MASK) { - crime_int &= CRIME_MACEPCI_INT_MASK; - crime_int >>= 8; - irq = ffs (crime_int) + 8; - } else if (crime_int & 0xffff0000) { - crime_int >>= 16; - irq = ffs (crime_int) + 16; - } - if (irq == 0) - ip32_unknown_interrupt(regs); - DBG("*irq %u*\n", irq); - do_IRQ(irq, regs); - - /* enable crime interrupts */ - crime_write_64(CRIME_INT_MASK, crime_mask); - restore_flags (flags); -} - -void ip32_irq1(struct pt_regs *regs) -{ - ip32_unknown_interrupt (regs); -} - -void ip32_irq2(struct pt_regs *regs) -{ - ip32_unknown_interrupt (regs); -} - -void ip32_irq3(struct pt_regs *regs) -{ - ip32_unknown_interrupt (regs); -} - -void ip32_irq4(struct pt_regs *regs) -{ - ip32_unknown_interrupt (regs); -} - -void ip32_irq5(struct pt_regs *regs) -{ - do_IRQ (CLOCK_IRQ, regs); -} - -void __init init_IRQ(void) -{ - unsigned int irq; - int i; - - /* Install our interrupt handler, then clear and disable all - * CRIME and MACE interrupts. - */ - crime_write_64(CRIME_INT_MASK, 0); - crime_write_64(CRIME_HARD_INT, 0); - crime_write_64(CRIME_SOFT_INT, 0); - mace_write_32(MACEISA_INT_STAT, 0); - mace_write_32(MACEISA_INT_MASK, 0); - set_except_vector(0, ip32_handle_int); - - for (i = 0; i < NR_IRQS; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].handler = &no_irq_type; - } - - for (irq = 0; irq <= IP32_IRQ_MAX; irq++) { - hw_irq_controller *controller; - - if (irq == CLOCK_IRQ) - controller = &ip32_cpu_interrupt; - else if (irq <= MACE_PCI_BRIDGE_IRQ && irq >= MACE_VID_IN1_IRQ) - controller = &ip32_mace_interrupt; - else if (irq <= MACEPCI_SHARED2_IRQ && irq >= MACEPCI_SCSI0_IRQ) - controller = &ip32_macepci_interrupt; - else if (irq <= CRIME_VICE_IRQ && irq >= CRIME_GBE0_IRQ) - controller = &ip32_crime_interrupt; - else - controller = &ip32_maceisa_interrupt; - - irq_desc[irq].status = IRQ_DISABLED; - irq_desc[irq].action = 0; - irq_desc[irq].depth = 0; - irq_desc[irq].handler = controller; - } - setup_irq(CRIME_MEMERR_IRQ, &memerr_irq); - setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq); -} diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip32/ip32-pci.c linux-2.4.21-bk38/arch/mips/sgi-ip32/ip32-pci.c --- linux-2.4.21-bk37/arch/mips/sgi-ip32/ip32-pci.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip32/ip32-pci.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,460 +0,0 @@ -/* - * 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. - * - * Copyright (C) 2000, 2001 Keith M Wesolowski - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#undef DEBUG_MACE_PCI - -/* - * O2 has up to 5 PCI devices connected into the MACE bridge. The device - * map looks like this: - * - * 0 aic7xxx 0 - * 1 aic7xxx 1 - * 2 expansion slot - * 3 N/C - * 4 N/C - */ - -#define chkslot(dev) \ -do { \ - if ((dev)->bus->number > 0 || PCI_SLOT ((dev)->devfn) < 1 \ - || PCI_SLOT ((dev)->devfn) > 3) \ - return PCIBIOS_DEVICE_NOT_FOUND; \ -} while (0) - -#define mkaddr(dev, where) \ -((((dev)->devfn & 0xffUL) << 8) | ((where) & 0xfcUL)) - -void macepci_error (int irq, void *dev, struct pt_regs *regs); - -static int macepci_read_config_byte (struct pci_dev *dev, int where, - u8 *val) -{ - *val = 0xff; - chkslot (dev); - mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where)); - *val = mace_read_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL)); - - return PCIBIOS_SUCCESSFUL; -} - -static int macepci_read_config_word (struct pci_dev *dev, int where, - u16 *val) -{ - *val = 0xffff; - chkslot (dev); - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where)); - *val = mace_read_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL)); - - return PCIBIOS_SUCCESSFUL; -} - -static int macepci_read_config_dword (struct pci_dev *dev, int where, - u32 *val) -{ - *val = 0xffffffff; - chkslot (dev); - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where)); - *val = mace_read_32 (MACEPCI_CONFIG_DATA); - - return PCIBIOS_SUCCESSFUL; -} - -static int macepci_write_config_byte (struct pci_dev *dev, int where, - u8 val) -{ - chkslot (dev); - mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where)); - mace_write_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL), val); - - return PCIBIOS_SUCCESSFUL; -} - -static int macepci_write_config_word (struct pci_dev *dev, int where, - u16 val) -{ - chkslot (dev); - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where)); - mace_write_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL), val); - - return PCIBIOS_SUCCESSFUL; -} - -static int macepci_write_config_dword (struct pci_dev *dev, int where, - u32 val) -{ - chkslot (dev); - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where)); - mace_write_32 (MACEPCI_CONFIG_DATA, val); - - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops macepci_ops = { - macepci_read_config_byte, - macepci_read_config_word, - macepci_read_config_dword, - macepci_write_config_byte, - macepci_write_config_word, - macepci_write_config_dword -}; - -struct pci_fixup pcibios_fixups[] = { { 0 } }; - -void __init pcibios_init (void) -{ - struct pci_dev *dev; - u32 start, size; - u16 cmd; - u32 base_io = 0x3000; /* The first i/o address to assign after SCSI */ - u32 base_mem = 0x80100000; /* Likewise */ - u32 rev = mace_read_32 (MACEPCI_REV); - int i; - - printk ("MACE: PCI rev %d detected at %016lx\n", rev, - (u64) MACE_BASE + MACE_PCI); - - /* These are *bus* addresses */ - ioport_resource.start = 0; - ioport_resource.end = 0xffffffffUL; - iomem_resource.start = 0x80000000UL; - iomem_resource.end = 0xffffffffUL; - - /* Clear any outstanding errors and enable interrupts */ - mace_write_32 (MACEPCI_ERROR_ADDR, 0); - mace_write_32 (MACEPCI_ERROR_FLAGS, 0); - mace_write_32 (MACEPCI_CONTROL, 0xff008500); - crime_write_64 (CRIME_HARD_INT, 0UL); - crime_write_64 (CRIME_SOFT_INT, 0UL); - crime_write_64 (CRIME_INT_STAT, 0x000000000000ff00UL); - - if (request_irq (MACE_PCI_BRIDGE_IRQ, macepci_error, 0, - "MACE PCI error", NULL)) - panic("PCI bridge can't get interrupt; can't happen."); - - pci_scan_bus (0, &macepci_ops, NULL); - -#ifdef DEBUG_MACE_PCI - pci_for_each_dev (dev) { - printk ("Device: %d/%d/%d ARCS-assigned bus resource map\n", - dev->bus->number, PCI_SLOT (dev->devfn), - PCI_FUNC (dev->devfn)); - for (i=0; i < DEVICE_COUNT_RESOURCE; i++) { - if (dev->resource[i].start == 0) - continue; - printk ("%d: %016lx - %016lx (flags %04lx)\n", - i, dev->resource[i].start, - dev->resource[i].end, dev->resource[i].flags); - } - } -#endif - /* - * Assign sane resources to and enable all devices. The requirement - * for the SCSI controllers is well-known: a 256-byte I/O region - * which we must assign, and a 1-page memory region which is - * assigned by the system firmware. - */ - pci_for_each_dev (dev) { - switch (PCI_SLOT (dev->devfn)) { - case 1: /* SCSI bus 0 */ - dev->resource[0].start = 0x1000UL; - dev->resource[0].end = 0x10ffUL; - break; - case 2: /* SCSI bus 1 */ - dev->resource[0].start = 0x2000UL; - dev->resource[0].end = 0x20ffUL; - break; - default: /* Slots - I guess we have only 1 */ - for (i=0; i < 6; i++) { - size = dev->resource[i].end - - dev->resource[i].start; - if (!size - || !(dev->resource[i].flags - & (IORESOURCE_IO|IORESOURCE_MEM))) { - dev->resource[i].start - = dev->resource[i].end = 0UL; - continue; - } - if (dev->resource[i].flags & IORESOURCE_IO) { - dev->resource[i].start = base_io; - base_io += PAGE_ALIGN (size); - } else { - dev->resource[i].start = base_mem; - base_mem += 0x100000UL; - } - dev->resource[i].end = - dev->resource[i].start + size; - } - break; - } - for (i=0; i < 6; i++) { - if (dev->resource[i].start == 0) - continue; - start = dev->resource[i].start; - if (dev->resource[i].flags & IORESOURCE_IO) - start |= 1; - pci_write_config_dword (dev, - PCI_BASE_ADDRESS_0 + (i << 2), (u32) start); - } - pci_write_config_byte (dev, PCI_CACHE_LINE_SIZE, 0x20); - pci_write_config_byte (dev, PCI_LATENCY_TIMER, 0x30); - pci_read_config_word (dev, PCI_COMMAND, &cmd); - cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_SPECIAL | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY); - pci_write_config_word (dev, PCI_COMMAND, cmd); - pci_set_master (dev); - } - /* - * Fixup O2 PCI slot. Bad hack. - */ -/* devtag = pci_make_tag(0, 0, 3, 0); - - slot = macepci_conf_read(0, devtag, PCI_COMMAND_STATUS_REG); - slot |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE; - macepci_conf_write(0, devtag, PCI_COMMAND_STATUS_REG, slot); - - slot = macepci_conf_read(0, devtag, PCI_MAPREG_START); - if (slot == 0xffffffe1) - macepci_conf_write(0, devtag, PCI_MAPREG_START, 0x00001000); - - slot = macepci_conf_read(0, devtag, PCI_MAPREG_START + (2 << 2)); - if ((slot & 0xffff0000) == 0) { - slot += 0x00010000; - macepci_conf_write(0, devtag, PCI_MAPREG_START + (2 << 2), - 0x00000000); - } - */ -#ifdef DEBUG_MACE_PCI - printk ("Triggering PCI bridge interrupt...\n"); - mace_write_32 (MACEPCI_ERROR_FLAGS, MACEPCI_ERROR_INTERRUPT_TEST); - - pci_for_each_dev (dev) { - printk ("Device: %d/%d/%d final bus resource map\n", - dev->bus->number, PCI_SLOT (dev->devfn), - PCI_FUNC (dev->devfn)); - for (i=0; i < DEVICE_COUNT_RESOURCE; i++) { - if (dev->resource[i].start == 0) - continue; - printk ("%d: %016lx - %016lx (flags %04lx)\n", - i, dev->resource[i].start, - dev->resource[i].end, dev->resource[i].flags); - } - } -#endif -} - -/* - * Given a PCI slot number (a la PCI_SLOT(...)) and the interrupt pin of - * the device (1-4 => A-D), tell what irq to use. Note that we don't - * in theory have slots 4 and 5, and we never normally use the shared - * irqs. I suppose a device without a pin A will thank us for doing it - * right if there exists such a broken piece of crap. - */ -static int __init macepci_map_irq (struct pci_dev *dev, u8 slot, u8 pin) -{ - chkslot (dev); - if (pin == 0) - pin = 1; - switch (slot) { - case 1: - return MACEPCI_SCSI0_IRQ; - case 2: - return MACEPCI_SCSI1_IRQ; - case 3: - switch (pin) { - case 2: - return MACEPCI_SHARED0_IRQ; - case 3: - return MACEPCI_SHARED1_IRQ; - case 4: - return MACEPCI_SHARED2_IRQ; - case 1: - default: - return MACEPCI_SLOT0_IRQ; - } - case 4: - switch (pin) { - case 2: - return MACEPCI_SHARED2_IRQ; - case 3: - return MACEPCI_SHARED0_IRQ; - case 4: - return MACEPCI_SHARED1_IRQ; - case 1: - default: - return MACEPCI_SLOT1_IRQ; - } - return MACEPCI_SLOT1_IRQ; - case 5: - switch (pin) { - case 2: - return MACEPCI_SHARED1_IRQ; - case 3: - return MACEPCI_SHARED2_IRQ; - case 4: - return MACEPCI_SHARED0_IRQ; - case 1: - default: - return MACEPCI_SLOT2_IRQ; - } - default: - return 0; - } -} - -/* - * It's not entirely clear what this does in a system with no bridges. - * In any case, bridges are not supported by Linux in O2. - */ -static u8 __init macepci_swizzle (struct pci_dev *dev, u8 *pinp) -{ - if (PCI_SLOT (dev->devfn) == 2) - *pinp = 2; - else - *pinp = 1; - return PCI_SLOT (dev->devfn); -} - -/* All devices are enabled during initialization. */ -int pcibios_enable_device (struct pci_dev *dev) -{ - return PCIBIOS_SUCCESSFUL; -} - -char * __init pcibios_setup (char *str) -{ - return str; -} - -void __init pcibios_align_resource (void *data, struct resource *res, - unsigned long size, unsigned long align) -{ -} - -void __init pcibios_update_resource (struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ -} - -void __init pcibios_update_irq (struct pci_dev *dev, int irq) -{ - pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq); -} - -void __init pcibios_fixup_bus (struct pci_bus *b) -{ - pci_fixup_irqs (macepci_swizzle, macepci_map_irq); -} - -/* XXX anybody know what this is supposed to do? */ -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; -} - -/* - * Handle errors from the bridge. This includes master and target aborts, - * various command and address errors, and the interrupt test. This gets - * registered on the bridge error irq. It's conceivable that some of these - * conditions warrant a panic. Anybody care to say which ones? - */ -void macepci_error (int irq, void *dev, struct pt_regs *regs) { - u32 flags, error_addr; - char space; - - flags = mace_read_32 (MACEPCI_ERROR_FLAGS); - error_addr = mace_read_32 (MACEPCI_ERROR_ADDR); - - if (flags & MACEPCI_ERROR_MEMORY_ADDR) - space = 'M'; - else if (flags & MACEPCI_ERROR_CONFIG_ADDR) - space = 'C'; - else space = 'X'; - - if (flags & MACEPCI_ERROR_MASTER_ABORT) { - printk ("MACEPCI: Master abort at 0x%08x (%c)\n", error_addr, - space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_MASTER_ABORT); - } - if (flags & MACEPCI_ERROR_TARGET_ABORT) { - printk ("MACEPCI: Target abort at 0x%08x (%c)\n", error_addr, - space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_TARGET_ABORT); - } - if (flags & MACEPCI_ERROR_DATA_PARITY_ERR) { - printk ("MACEPCI: Data parity error at 0x%08x (%c)\n", - error_addr, space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_DATA_PARITY_ERR); - } - if (flags & MACEPCI_ERROR_RETRY_ERR) { - printk ("MACEPCI: Retry error at 0x%08x (%c)\n", error_addr, - space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_RETRY_ERR); - } - if (flags & MACEPCI_ERROR_ILLEGAL_CMD) { - printk ("MACEPCI: Illegal command at 0x%08x (%c)\n", - error_addr, space); - mace_write_32 (MACEPCI_ERROR_FLAGS, - flags & ~MACEPCI_ERROR_ILLEGAL_CMD); - } - if (flags & MACEPCI_ERROR_SYSTEM_ERR) { - printk ("MACEPCI: System error at 0x%08x (%c)\n", - error_addr, space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_SYSTEM_ERR); - } - if (flags & MACEPCI_ERROR_PARITY_ERR) { - printk ("MACEPCI: Parity error at 0x%08x (%c)\n", error_addr, - space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_PARITY_ERR); - } - if (flags & MACEPCI_ERROR_OVERRUN) { - printk ("MACEPCI: Overrun error at 0x%08x (%c)\n", - error_addr, space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_OVERRUN); - } - if (flags & MACEPCI_ERROR_SIG_TABORT) { - printk ("MACEPCI: Signaled target abort (clearing)\n"); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_SIG_TABORT); - } - if (flags & MACEPCI_ERROR_INTERRUPT_TEST) { - printk ("MACEPCI: Interrupt test triggered (clearing)\n"); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_INTERRUPT_TEST); - } -} -unsigned __init int pcibios_assign_all_busses(void) -{ - return 0; -} diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip32/ip32-reset.c linux-2.4.21-bk38/arch/mips/sgi-ip32/ip32-reset.c --- linux-2.4.21-bk37/arch/mips/sgi-ip32/ip32-reset.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip32/ip32-reset.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,34 +0,0 @@ -/* - * 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. - * - * Copyright (C) 2001 Keith M Wesolowski - * Copyright (C) 2001 Paul Mundt - */ -#include - -#include -#include - -static void ip32_machine_restart(char *cmd) -{ - ArcReboot(); -} - -static inline void ip32_machine_halt(void) -{ - ArcEnterInteractiveMode(); -} - -static void ip32_machine_power_off(void) -{ - ip32_machine_halt(); -} - -void __init ip32_reboot_setup(void) -{ - _machine_restart = ip32_machine_restart; - _machine_halt = ip32_machine_halt; - _machine_power_off = ip32_machine_power_off; -} diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip32/ip32-rtc.c linux-2.4.21-bk38/arch/mips/sgi-ip32/ip32-rtc.c --- linux-2.4.21-bk37/arch/mips/sgi-ip32/ip32-rtc.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip32/ip32-rtc.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,32 +0,0 @@ -/* - * RTC routines for IP32 style attached Dallas chip. - * - * 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. - * - * Copyright (C) 2000 Harald Koerfgen - */ -#include -#include - -static unsigned char ip32_rtc_read_data(unsigned long addr) -{ - return (unsigned char) mace_read_8 (MACEISA_RTC_BASE + (addr << 8)); -} - -static void ip32_rtc_write_data(unsigned char data, unsigned long addr) -{ - mace_write_8 (MACEISA_RTC_BASE + (addr << 8), data); -} - -static int ip32_rtc_bcd_mode(void) -{ - return 0; -} - -struct rtc_ops ip32_rtc_ops = { - &ip32_rtc_read_data, - &ip32_rtc_write_data, - &ip32_rtc_bcd_mode -}; diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip32/ip32-setup.c linux-2.4.21-bk38/arch/mips/sgi-ip32/ip32-setup.c --- linux-2.4.21-bk37/arch/mips/sgi-ip32/ip32-setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip32/ip32-setup.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,102 +0,0 @@ -/* - * IP32 basic setup - * - * 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. - * - * Copyright (C) 2000 Harald Koerfgen - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -extern struct rtc_ops ip32_rtc_ops; -extern u32 cc_interval; - -#ifdef CONFIG_SGI_O2MACE_ETH - -/* - * This is taken care of in here 'cause they say using Arc later on is - * problematic - */ -extern char o2meth_eaddr[8]; -static inline unsigned char str2hexnum(unsigned char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - return 0; /* foo */ -} - -static inline void str2eaddr(unsigned char *ea, unsigned char *str) -{ - int i; - - for (i = 0; i < 6; i++) { - unsigned char num; - - if(*str == ':') - str++; - num = str2hexnum(*str++) << 4; - num |= (str2hexnum(*str++)); - ea[i] = num; - } -} -#endif - -extern void ip32_time_init(void); - -void __init ip32_setup(void) -{ -#ifdef CONFIG_SERIAL_CONSOLE - char *ctype; -#endif - TLBMISS_HANDLER_SETUP (); - - mips_io_port_base = UNCACHEDADDR(MACEPCI_HI_IO);; - -#ifdef CONFIG_SERIAL_CONSOLE - ctype = ArcGetEnvironmentVariable("console"); - if (*ctype == 'd') { - if (ctype[1] == '2') - console_setup ("ttyS1"); - else - console_setup ("ttyS0"); - } -#endif -#ifdef CONFIG_SGI_O2MACE_ETH - { - char *mac=ArcGetEnvironmentVariable("eaddr"); - str2eaddr(o2meth_eaddr, mac); - } -#endif - -#ifdef CONFIG_VT - conswitchp = &dummy_con; -#endif - - rtc_ops = &ip32_rtc_ops; - board_time_init = ip32_time_init; - - crime_init (); -} - -int __init page_is_ram (unsigned long pagenr) -{ - /* XXX: to do? */ - return 1; -} diff -urN linux-2.4.21-bk37/arch/mips/sgi-ip32/ip32-timer.c linux-2.4.21-bk38/arch/mips/sgi-ip32/ip32-timer.c --- linux-2.4.21-bk37/arch/mips/sgi-ip32/ip32-timer.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sgi-ip32/ip32-timer.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,238 +0,0 @@ -/* - * IP32 timer calibration - * - * 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. - * - * Copyright (C) 2001 Keith M Wesolowski - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern volatile unsigned long wall_jiffies; -extern rwlock_t xtime_lock; - -u32 cc_interval; - -/* Cycle counter value at the previous timer interrupt.. */ -static unsigned int timerhi, timerlo; - -/* An arbitrary time; this can be decreased if reliability looks good */ -#define WAIT_MS 10 -#define PER_MHZ (1000000 / 2 / HZ) -/* - * Change this if you have some constant time drift - */ -#define USECS_PER_JIFFY (1000000/HZ) - - -void __init ip32_timer_setup (struct irqaction *irq) -{ - u64 crime_time; - u32 cc_tick; - - printk("Calibrating system timer... "); - - crime_time = crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK; - cc_tick = read_32bit_cp0_register (CP0_COUNT); - - while ((crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK) - crime_time - < WAIT_MS * 1000000 / CRIME_NS_PER_TICK) - ; - cc_tick = read_32bit_cp0_register (CP0_COUNT) - cc_tick; - cc_interval = cc_tick / HZ * (1000 / WAIT_MS); - /* The round-off seems unnecessary; in testing, the error of the - * above procedure is < 100 ticks, which means it gets filtered - * out by the HZ adjustment. - */ - cc_interval = (cc_interval / PER_MHZ) * PER_MHZ; - - printk("%d MHz CPU detected\n", (int) (cc_interval / PER_MHZ)); - - setup_irq (CLOCK_IRQ, irq); -} - -struct irqaction irq0 = { NULL, SA_INTERRUPT, 0, - "timer", NULL, NULL}; - -void cc_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) -{ - u32 count; - - /* - * The cycle counter is only 32 bit which is good for about - * a minute at current count rates of upto 150MHz or so. - */ - count = read_32bit_cp0_register(CP0_COUNT); - timerhi += (count < timerlo); /* Wrap around */ - timerlo = count; - - write_32bit_cp0_register (CP0_COMPARE, - (u32) (count + cc_interval)); - kstat.irqs[0][irq]++; - do_timer (regs); - - if (!jiffies) - { - /* - * If jiffies has overflowed in this timer_interrupt we must - * update the timer[hi]/[lo] to make do_fast_gettimeoffset() - * quotient calc still valid. -arca - */ - timerhi = timerlo = 0; - } -} - -/* - * On MIPS only R4000 and better have a cycle counter. - * - * FIXME: Does playing with the RP bit in c0_status interfere with this code? - */ -static unsigned long do_gettimeoffset(void) -{ - u32 count; - unsigned long res, tmp; - - /* Last jiffy when do_fast_gettimeoffset() was called. */ - static unsigned long last_jiffies; - u32 quotient; - - /* - * Cached "1/(clocks per usec)*2^32" value. - * It has to be recalculated once each jiffy. - */ - static u32 cached_quotient; - - tmp = jiffies; - - quotient = cached_quotient; - - if (tmp && last_jiffies != tmp) { - last_jiffies = tmp; - __asm__(".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "lwu\t%0,%2\n\t" - "dsll32\t$1,%1,0\n\t" - "or\t$1,$1,%0\n\t" - "ddivu\t$0,$1,%3\n\t" - "mflo\t$1\n\t" - "dsll32\t%0,%4,0\n\t" - "nop\n\t" - "ddivu\t$0,%0,$1\n\t" - "mflo\t%0\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=&r" (quotient) - :"r" (timerhi), - "m" (timerlo), - "r" (tmp), - "r" (USECS_PER_JIFFY) - :"$1"); - cached_quotient = quotient; - } - - /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); - - /* .. relative to previous jiffy (32 bits is enough) */ - count -= timerlo; - - __asm__("multu\t%1,%2\n\t" - "mfhi\t%0" - :"=r" (res) - :"r" (count), - "r" (quotient)); - - /* - * Due to possible jiffies inconsistencies, we need to check - * the result so that we'll get a timer that is monotonic. - */ - if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY-1; - - return res; -} - -void __init ip32_time_init(void) -{ - unsigned int epoch = 0, year, mon, day, hour, min, sec; - int i; - - /* The Linux interpretation of the CMOS clock register contents: - * When the Update-In-Progress (UIP) flag goes from 1 to 0, the - * RTC registers show the second which has precisely just started. - * Let's hope other operating systems interpret the RTC the same way. - */ - /* read RTC exactly on falling edge of update flag */ - for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */ - if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) - break; - for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */ - if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) - break; - do { /* Isn't this overkill ? UIP above should guarantee consistency */ - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); - } while (sec != CMOS_READ(RTC_SECONDS)); - if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hour); - BCD_TO_BIN(day); - BCD_TO_BIN(mon); - BCD_TO_BIN(year); - } - - /* Attempt to guess the epoch. This is the same heuristic as in - * rtc.c so no stupid things will happen to timekeeping. Who knows, - * maybe Ultrix also uses 1952 as epoch ... - */ - if (year > 10 && year < 44) - epoch = 1980; - else if (year < 96) - epoch = 1952; - year += epoch; - - write_lock_irq (&xtime_lock); - xtime.tv_sec = mktime(year, mon, day, hour, min, sec); - xtime.tv_usec = 0; - write_unlock_irq (&xtime_lock); - - write_32bit_cp0_register(CP0_COUNT, 0); - irq0.handler = cc_timer_interrupt; - - ip32_timer_setup (&irq0); - -#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) - /* Set ourselves up for future interrupts */ - write_32bit_cp0_register(CP0_COMPARE, - read_32bit_cp0_register(CP0_COUNT) - + cc_interval); - change_cp0_status(ST0_IM, ALLINTS); - sti (); -} diff -urN linux-2.4.21-bk37/arch/mips/sibyte/cfe/Makefile linux-2.4.21-bk38/arch/mips/sibyte/cfe/Makefile --- linux-2.4.21-bk37/arch/mips/sibyte/cfe/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/cfe/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -4,5 +4,6 @@ obj-y = cfe_api.o setup.o obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_SIBYTE_CFE_CONSOLE) += console.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/sibyte/cfe/cfe_api.c linux-2.4.21-bk38/arch/mips/sibyte/cfe/cfe_api.c --- linux-2.4.21-bk37/arch/mips/sibyte/cfe/cfe_api.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/cfe/cfe_api.c 2003-08-24 02:55:58.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2000, 2001, 2002 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -17,6 +17,7 @@ */ /* ********************************************************************* + * * Broadcom Common Firmware Environment (CFE) * * Device Function stubs File: cfe_api.c @@ -25,196 +26,218 @@ * call the standard "iocb" interface entry point to CFE). * There should be one routine here per iocb function call. * - * Author: Mitch Lichtenberg (mpl@broadcom.com) + * Authors: Mitch Lichtenberg, Chris Demetriou * ********************************************************************* */ - -#include "cfe_xiocb.h" #include "cfe_api.h" +#include "cfe_api_int.h" -static long cfe_console_handle = -1; -static int (*cfe_dispfunc)(long handle,cfe_xiocb_t *xiocb) = 0; -static cfe_xuint_t cfe_handle = 0; +/* Cast from a native pointer to a cfe_xptr_t and back. */ +#define XPTR_FROM_NATIVE(n) ((cfe_xptr_t) (intptr_t) (n)) +#define NATIVE_FROM_XPTR(x) ((void *) (intptr_t) (x)) + +#ifdef CFE_API_IMPL_NAMESPACE +#define cfe_iocb_dispatch(a) __cfe_iocb_dispatch(a) +#endif +int cfe_iocb_dispatch(cfe_xiocb_t * xiocb); +#if defined(CFE_API_common) || defined(CFE_API_ALL) /* - * This macro makes a "signed 64-bit pointer" - basically extending a regular - * pointer to its 64-bit compatibility space equivalent. + * Declare the dispatch function with args of "intptr_t". + * This makes sure whatever model we're compiling in + * puts the pointers in a single register. For example, + * combining -mlong64 and -mips1 or -mips2 would lead to + * trouble, since the handle and IOCB pointer will be + * passed in two registers each, and CFE expects one. */ -#define BIGPTR(x) (long long) (long) (x) -typedef unsigned long intptr_t; +static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb) = 0; +static cfe_xuint_t cfe_handle = 0; -int cfe_init(cfe_xuint_t handle) +int cfe_init(cfe_xuint_t handle, cfe_xuint_t ept) { - if ((*((unsigned int *) (int) CFE_APISEAL) == CFE_EPTSEAL) || - (*((unsigned int *) (int) CFE_APISEAL_RE) == CFE_EPTSEAL) || - (*((unsigned int *) (int) CFE_APISEAL_OLD) == CFE_EPTSEAL)) { - cfe_dispfunc = (cfe_xptr_t) (int) CFE_APIENTRY; - if (handle) cfe_handle = handle; - return 0; - } else { - return -1; - } + cfe_dispfunc = NATIVE_FROM_XPTR(ept); + cfe_handle = handle; + return 0; } -int cfe_iocb_dispatch(cfe_xiocb_t *xiocb); -int cfe_iocb_dispatch(cfe_xiocb_t *xiocb) +int cfe_iocb_dispatch(cfe_xiocb_t * xiocb) { - if (!cfe_dispfunc) return -1; - return (*cfe_dispfunc)(cfe_handle,xiocb); + if (!cfe_dispfunc) + return -1; + return (*cfe_dispfunc) ((intptr_t) cfe_handle, (intptr_t) xiocb); } +#endif /* CFE_API_common || CFE_API_ALL */ -static int cfe_strlen(char *name) +#if defined(CFE_API_close) || defined(CFE_API_ALL) +int cfe_close(int handle) { - int count = 0; + cfe_xiocb_t xiocb; - while (*name) { - count++; - name++; - } + xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = handle; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = 0; + + cfe_iocb_dispatch(&xiocb); + + return xiocb.xiocb_status; - return count; } +#endif /* CFE_API_close || CFE_API_ALL */ -int cfe_open(char *name) +#if defined(CFE_API_cpu_start) || defined(CFE_API_ALL) +int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN; + xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL; xiocb.xiocb_status = 0; xiocb.xiocb_handle = 0; xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_buffer_t); - xiocb.plist.xiocb_buffer.buf_offset = 0; - xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(name); - xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name); + xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t); + xiocb.plist.xiocb_cpuctl.cpu_number = cpu; + xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START; + xiocb.plist.xiocb_cpuctl.gp_val = gp; + xiocb.plist.xiocb_cpuctl.sp_val = sp; + xiocb.plist.xiocb_cpuctl.a1_val = a1; + xiocb.plist.xiocb_cpuctl.start_addr = (long) fn; cfe_iocb_dispatch(&xiocb); - return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.xiocb_handle; + return xiocb.xiocb_status; } +#endif /* CFE_API_cpu_start || CFE_API_ALL */ -int cfe_close(int handle) +#if defined(CFE_API_cpu_stop) || defined(CFE_API_ALL) +int cfe_cpu_stop(int cpu) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE; + xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL; xiocb.xiocb_status = 0; - xiocb.xiocb_handle = handle; + xiocb.xiocb_handle = 0; xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = 0; + xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t); + xiocb.plist.xiocb_cpuctl.cpu_number = cpu; + xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP; cfe_iocb_dispatch(&xiocb); - return (xiocb.xiocb_status); - + return xiocb.xiocb_status; } +#endif /* CFE_API_cpu_stop || CFE_API_ALL */ -int cfe_readblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length) +#if defined(CFE_API_enumenv) || defined(CFE_API_ALL) +int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_DEV_READ; + xiocb.xiocb_fcode = CFE_CMD_ENV_SET; xiocb.xiocb_status = 0; - xiocb.xiocb_handle = handle; + xiocb.xiocb_handle = 0; xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_buffer_t); - xiocb.plist.xiocb_buffer.buf_offset = offset; - xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(buffer); - xiocb.plist.xiocb_buffer.buf_length = length; + xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); + xiocb.plist.xiocb_envbuf.enum_idx = idx; + xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); + xiocb.plist.xiocb_envbuf.name_length = namelen; + xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val); + xiocb.plist.xiocb_envbuf.val_length = vallen; cfe_iocb_dispatch(&xiocb); - return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.plist.xiocb_buffer.buf_retlen; -} - -int cfe_read(int handle,unsigned char *buffer,int length) -{ - return cfe_readblk(handle,0,buffer,length); + return xiocb.xiocb_status; } +#endif /* CFE_API_enumenv || CFE_API_ALL */ - -int cfe_writeblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length) +#if defined(CFE_API_enummem) || defined(CFE_API_ALL) +int +cfe_enummem(int idx, int flags, cfe_xuint_t * start, cfe_xuint_t * length, + cfe_xuint_t * type) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE; + xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM; xiocb.xiocb_status = 0; - xiocb.xiocb_handle = handle; - xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_buffer_t); - xiocb.plist.xiocb_buffer.buf_offset = offset; - xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(buffer); - xiocb.plist.xiocb_buffer.buf_length = length; + xiocb.xiocb_handle = 0; + xiocb.xiocb_flags = flags; + xiocb.xiocb_psize = sizeof(xiocb_meminfo_t); + xiocb.plist.xiocb_meminfo.mi_idx = idx; cfe_iocb_dispatch(&xiocb); - return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.plist.xiocb_buffer.buf_retlen; -} + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; -int cfe_write(int handle,unsigned char *buffer,int length) -{ - return cfe_writeblk(handle,0,buffer,length); -} + *start = xiocb.plist.xiocb_meminfo.mi_addr; + *length = xiocb.plist.xiocb_meminfo.mi_size; + *type = xiocb.plist.xiocb_meminfo.mi_type; + return 0; +} +#endif /* CFE_API_enummem || CFE_API_ALL */ -int cfe_ioctl(int handle,unsigned int ioctlnum,unsigned char *buffer,int length,int *retlen) +#if defined(CFE_API_exit) || defined(CFE_API_ALL) +int cfe_exit(int warm, int status) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL; + xiocb.xiocb_fcode = CFE_CMD_FW_RESTART; xiocb.xiocb_status = 0; - xiocb.xiocb_handle = handle; - xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_buffer_t); - xiocb.plist.xiocb_buffer.buf_ioctlcmd = (cfe_xint_t) ioctlnum; - xiocb.plist.xiocb_buffer.buf_ptr = BIGPTR(buffer); - xiocb.plist.xiocb_buffer.buf_length = length; + xiocb.xiocb_handle = 0; + xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0; + xiocb.xiocb_psize = sizeof(xiocb_exitstat_t); + xiocb.plist.xiocb_exitstat.status = status; cfe_iocb_dispatch(&xiocb); - if (retlen) *retlen = xiocb.plist.xiocb_buffer.buf_retlen; return xiocb.xiocb_status; } +#endif /* CFE_API_exit || CFE_API_ALL */ -int cfe_inpstat(int handle) +#if defined(CFE_API_flushcache) || defined(CFE_API_ALL) +int cfe_flushcache(int flg) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT; + xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE; xiocb.xiocb_status = 0; - xiocb.xiocb_handle = handle; - xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_inpstat_t); - xiocb.plist.xiocb_inpstat.inp_status = 0; + xiocb.xiocb_handle = 0; + xiocb.xiocb_flags = flg; + xiocb.xiocb_psize = 0; cfe_iocb_dispatch(&xiocb); - if (xiocb.xiocb_status < 0) return xiocb.xiocb_status; - - return xiocb.plist.xiocb_inpstat.inp_status; - + return xiocb.xiocb_status; } +#endif /* CFE_API_flushcache || CFE_API_ALL */ -long long cfe_getticks(void) +#if defined(CFE_API_getdevinfo) || defined(CFE_API_ALL) +int cfe_getdevinfo(char *name) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME; + xiocb.xiocb_fcode = CFE_CMD_DEV_GETINFO; xiocb.xiocb_status = 0; xiocb.xiocb_handle = 0; xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_time_t); - xiocb.plist.xiocb_time.ticks = 0; + xiocb.xiocb_psize = sizeof(xiocb_buffer_t); + xiocb.plist.xiocb_buffer.buf_offset = 0; + xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name); + xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name); cfe_iocb_dispatch(&xiocb); - return xiocb.plist.xiocb_time.ticks; - + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + return xiocb.plist.xiocb_buffer.buf_devflags; } +#endif /* CFE_API_getdevinfo || CFE_API_ALL */ -int cfe_getenv(char *name,char *dest,int destlen) +#if defined(CFE_API_getenv) || defined(CFE_API_ALL) +int cfe_getenv(char *name, char *dest, int destlen) { cfe_xiocb_t xiocb; @@ -226,179 +249,254 @@ xiocb.xiocb_flags = 0; xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); xiocb.plist.xiocb_envbuf.enum_idx = 0; - xiocb.plist.xiocb_envbuf.name_ptr = BIGPTR(name); + xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name); - xiocb.plist.xiocb_envbuf.val_ptr = BIGPTR(dest); + xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(dest); xiocb.plist.xiocb_envbuf.val_length = destlen; cfe_iocb_dispatch(&xiocb); return xiocb.xiocb_status; } +#endif /* CFE_API_getenv || CFE_API_ALL */ -int cfe_setenv(char *name,char *val) +#if defined(CFE_API_getfwinfo) || defined(CFE_API_ALL) +int cfe_getfwinfo(cfe_fwinfo_t * info) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_ENV_SET; + xiocb.xiocb_fcode = CFE_CMD_FW_GETINFO; xiocb.xiocb_status = 0; xiocb.xiocb_handle = 0; xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); - xiocb.plist.xiocb_envbuf.enum_idx = 0; - xiocb.plist.xiocb_envbuf.name_ptr = BIGPTR(name); - xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name); - xiocb.plist.xiocb_envbuf.val_ptr = BIGPTR(val); - xiocb.plist.xiocb_envbuf.val_length = cfe_strlen(val); + xiocb.xiocb_psize = sizeof(xiocb_fwinfo_t); cfe_iocb_dispatch(&xiocb); - return xiocb.xiocb_status; + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + + info->fwi_version = xiocb.plist.xiocb_fwinfo.fwi_version; + info->fwi_totalmem = xiocb.plist.xiocb_fwinfo.fwi_totalmem; + info->fwi_flags = xiocb.plist.xiocb_fwinfo.fwi_flags; + info->fwi_boardid = xiocb.plist.xiocb_fwinfo.fwi_boardid; + info->fwi_bootarea_va = xiocb.plist.xiocb_fwinfo.fwi_bootarea_va; + info->fwi_bootarea_pa = xiocb.plist.xiocb_fwinfo.fwi_bootarea_pa; + info->fwi_bootarea_size = + xiocb.plist.xiocb_fwinfo.fwi_bootarea_size; +#if 0 + info->fwi_reserved1 = xiocb.plist.xiocb_fwinfo.fwi_reserved1; + info->fwi_reserved2 = xiocb.plist.xiocb_fwinfo.fwi_reserved2; + info->fwi_reserved3 = xiocb.plist.xiocb_fwinfo.fwi_reserved3; +#endif + + return 0; } +#endif /* CFE_API_getfwinfo || CFE_API_ALL */ -int cfe_enummem(long idx, unsigned long long *addr, unsigned long long *size, long *type) +#if defined(CFE_API_getstdhandle) || defined(CFE_API_ALL) +int cfe_getstdhandle(int flg) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM; + + xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE; xiocb.xiocb_status = 0; xiocb.xiocb_handle = 0; - xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_meminfo_t); - xiocb.plist.xiocb_meminfo.mi_idx = idx; + xiocb.xiocb_flags = flg; + xiocb.xiocb_psize = 0; cfe_iocb_dispatch(&xiocb); - (*addr) = xiocb.plist.xiocb_meminfo.mi_addr; - (*size) = xiocb.plist.xiocb_meminfo.mi_size; - (*type) = xiocb.plist.xiocb_meminfo.mi_type; - - return xiocb.xiocb_status; -} - - -int cfe_enumenv(int idx,char *name,int namelen,char *val,int vallen) + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + return xiocb.xiocb_handle; +} +#endif /* CFE_API_getstdhandle || CFE_API_ALL */ + +#if defined(CFE_API_getticks) || defined(CFE_API_ALL) +int64_t +#ifdef CFE_API_IMPL_NAMESPACE +__cfe_getticks(void) +#else +cfe_getticks(void) +#endif { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_ENV_SET; + xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME; xiocb.xiocb_status = 0; xiocb.xiocb_handle = 0; xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); - xiocb.plist.xiocb_envbuf.enum_idx = idx; - xiocb.plist.xiocb_envbuf.name_ptr = BIGPTR(name); - xiocb.plist.xiocb_envbuf.name_length = namelen; - xiocb.plist.xiocb_envbuf.val_ptr = BIGPTR(val); - xiocb.plist.xiocb_envbuf.val_length = vallen; + xiocb.xiocb_psize = sizeof(xiocb_time_t); + xiocb.plist.xiocb_time.ticks = 0; cfe_iocb_dispatch(&xiocb); - return xiocb.xiocb_status; + return xiocb.plist.xiocb_time.ticks; + } +#endif /* CFE_API_getticks || CFE_API_ALL */ -int cfe_exit(int warm, int status) +#if defined(CFE_API_inpstat) || defined(CFE_API_ALL) +int cfe_inpstat(int handle) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_FW_RESTART; + xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT; xiocb.xiocb_status = 0; - xiocb.xiocb_handle = 0; - xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0; - xiocb.xiocb_psize = sizeof(xiocb_exitstat_t); - xiocb.plist.xiocb_exitstat.status = (cfe_xint_t) status; + xiocb.xiocb_handle = handle; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_inpstat_t); + xiocb.plist.xiocb_inpstat.inp_status = 0; cfe_iocb_dispatch(&xiocb); - return (xiocb.xiocb_status); + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + return xiocb.plist.xiocb_inpstat.inp_status; } +#endif /* CFE_API_inpstat || CFE_API_ALL */ -int cfe_flushcache(int flg) +#if defined(CFE_API_ioctl) || defined(CFE_API_ALL) +int +cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer, + int length, int *retlen, cfe_xuint_t offset) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE; + xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL; xiocb.xiocb_status = 0; - xiocb.xiocb_handle = 0; - xiocb.xiocb_flags = flg; - xiocb.xiocb_psize = 0; + xiocb.xiocb_handle = handle; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_buffer_t); + xiocb.plist.xiocb_buffer.buf_offset = offset; + xiocb.plist.xiocb_buffer.buf_ioctlcmd = ioctlnum; + xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); + xiocb.plist.xiocb_buffer.buf_length = length; cfe_iocb_dispatch(&xiocb); + if (retlen) + *retlen = xiocb.plist.xiocb_buffer.buf_retlen; return xiocb.xiocb_status; } +#endif /* CFE_API_ioctl || CFE_API_ALL */ -int cfe_getstdhandle(int flg) +#if defined(CFE_API_open) || defined(CFE_API_ALL) +int cfe_open(char *name) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE; + xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN; xiocb.xiocb_status = 0; xiocb.xiocb_handle = 0; - xiocb.xiocb_flags = flg; - xiocb.xiocb_psize = 0; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_buffer_t); + xiocb.plist.xiocb_buffer.buf_offset = 0; + xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name); + xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name); cfe_iocb_dispatch(&xiocb); - return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.xiocb_handle; + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + return xiocb.xiocb_handle; +} +#endif /* CFE_API_open || CFE_API_ALL */ +#if defined(CFE_API_read) || defined(CFE_API_ALL) +int cfe_read(int handle, unsigned char *buffer, int length) +{ + return cfe_readblk(handle, 0, buffer, length); } +#endif /* CFE_API_read || CFE_API_ALL */ -int cfe_start_cpu(int cpu, void (*fn)(void), long sp, long gp, long a1) +#if defined(CFE_API_readblk) || defined(CFE_API_ALL) +int +cfe_readblk(int handle, cfe_xint_t offset, unsigned char *buffer, + int length) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL; + xiocb.xiocb_fcode = CFE_CMD_DEV_READ; xiocb.xiocb_status = 0; - xiocb.xiocb_handle = 0; - xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t); - xiocb.plist.xiocb_cpuctl.cpu_number = cpu; - xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START; - xiocb.plist.xiocb_cpuctl.gp_val = gp; - xiocb.plist.xiocb_cpuctl.sp_val = sp; - xiocb.plist.xiocb_cpuctl.a1_val = a1; - xiocb.plist.xiocb_cpuctl.start_addr = (long)fn; + xiocb.xiocb_handle = handle; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_buffer_t); + xiocb.plist.xiocb_buffer.buf_offset = offset; + xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); + xiocb.plist.xiocb_buffer.buf_length = length; cfe_iocb_dispatch(&xiocb); - return xiocb.xiocb_status; + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + return xiocb.plist.xiocb_buffer.buf_retlen; } +#endif /* CFE_API_readblk || CFE_API_ALL */ - -int cfe_stop_cpu(int cpu) +#if defined(CFE_API_setenv) || defined(CFE_API_ALL) +int cfe_setenv(char *name, char *val) { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL; + xiocb.xiocb_fcode = CFE_CMD_ENV_SET; xiocb.xiocb_status = 0; xiocb.xiocb_handle = 0; - xiocb.xiocb_flags = 0; - xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t); - xiocb.plist.xiocb_cpuctl.cpu_number = cpu; - xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); + xiocb.plist.xiocb_envbuf.enum_idx = 0; + xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); + xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name); + xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val); + xiocb.plist.xiocb_envbuf.val_length = cfe_strlen(val); cfe_iocb_dispatch(&xiocb); return xiocb.xiocb_status; } +#endif /* CFE_API_setenv || CFE_API_ALL */ -void cfe_open_console() +#if (defined(CFE_API_strlen) || defined(CFE_API_ALL)) \ + && !defined(CFE_API_STRLEN_CUSTOM) +int cfe_strlen(char *name) { - cfe_console_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE); + int count = 0; + + while (*name++) + count++; + + return count; } +#endif /* CFE_API_strlen || CFE_API_ALL */ -void cfe_console_print(const char *str, int len) +#if defined(CFE_API_write) || defined(CFE_API_ALL) +int cfe_write(int handle, unsigned char *buffer, int length) { - int res; - - if (cfe_console_handle != -1) { - do { - res = cfe_writeblk(cfe_console_handle, 0, str, len); - if (res < 0) - break; - str += res; - len -= res; - } while (len); - } + return cfe_writeblk(handle, 0, buffer, length); } +#endif /* CFE_API_write || CFE_API_ALL */ +#if defined(CFE_API_writeblk) || defined(CFE_API_ALL) +int +cfe_writeblk(int handle, cfe_xint_t offset, unsigned char *buffer, + int length) +{ + cfe_xiocb_t xiocb; + + xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = handle; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_buffer_t); + xiocb.plist.xiocb_buffer.buf_offset = offset; + xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); + xiocb.plist.xiocb_buffer.buf_length = length; + + cfe_iocb_dispatch(&xiocb); + + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + return xiocb.plist.xiocb_buffer.buf_retlen; +} +#endif /* CFE_API_writeblk || CFE_API_ALL */ diff -urN linux-2.4.21-bk37/arch/mips/sibyte/cfe/cfe_api.h linux-2.4.21-bk38/arch/mips/sibyte/cfe/cfe_api.h --- linux-2.4.21-bk37/arch/mips/sibyte/cfe/cfe_api.h 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/cfe/cfe_api.h 2003-08-24 02:55:58.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2000, 2001, 2002 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -17,55 +17,169 @@ */ /* ********************************************************************* + * * Broadcom Common Firmware Environment (CFE) * * Device function prototypes File: cfe_api.h * - * This module contains prototypes for cfe_devfuncs.c, a set - * of wrapper routines to the IOCB interface. This file, - * along with cfe_api.c, can be incorporated into programs - * that need to call CFE. + * This file contains declarations for doing callbacks to + * cfe from an application. It should be the only header + * needed by the application to use this library * - * Author: Mitch Lichtenberg (mpl@broadcom.com) + * Authors: Mitch Lichtenberg, Chris Demetriou * ********************************************************************* */ -#include +#ifndef CFE_API_H +#define CFE_API_H + +/* + * Apply customizations here for different OSes. These need to: + * * typedef uint64_t, int64_t, intptr_t, uintptr_t. + * * define cfe_strlen() if use of an existing function is desired. + * * define CFE_API_IMPL_NAMESPACE if API functions are to use + * names in the implementation namespace. + * Also, optionally, if the build environment does not do so automatically, + * CFE_API_* can be defined here as desired. + */ +/* Begin customization. */ +#include +#include + +typedef long intptr_t; + +#define cfe_strlen strlen + +#define CFE_API_ALL +#define CFE_API_STRLEN_CUSTOM +/* End customization. */ + + +/* ********************************************************************* + * Constants + ********************************************************************* */ +/* Seal indicating CFE's presence, passed to user program. */ #define CFE_EPTSEAL 0x43464531 -#ifdef CONFIG_MIPS_UNCACHED -#define CFE_APIENTRY 0xBFC00500 -#define CFE_APISEAL 0xBFC004E0 -#define CFE_APISEAL_RE 0xBFC004E8 -#define CFE_APISEAL_OLD 0xBFC00508 + +#define CFE_MI_RESERVED 0 /* memory is reserved, do not use */ +#define CFE_MI_AVAILABLE 1 /* memory is available */ + +#define CFE_FLG_WARMSTART 0x00000001 +#define CFE_FLG_FULL_ARENA 0x00000001 +#define CFE_FLG_ENV_PERMANENT 0x00000001 + +#define CFE_CPU_CMD_START 1 +#define CFE_CPU_CMD_STOP 0 + +#define CFE_STDHANDLE_CONSOLE 0 + +#define CFE_DEV_NETWORK 1 +#define CFE_DEV_DISK 2 +#define CFE_DEV_FLASH 3 +#define CFE_DEV_SERIAL 4 +#define CFE_DEV_CPU 5 +#define CFE_DEV_NVRAM 6 +#define CFE_DEV_CLOCK 7 +#define CFE_DEV_OTHER 8 +#define CFE_DEV_MASK 0x0F + +#define CFE_CACHE_FLUSH_D 1 +#define CFE_CACHE_INVAL_I 2 +#define CFE_CACHE_INVAL_D 4 +#define CFE_CACHE_INVAL_L2 8 + +#define CFE_FWI_64BIT 0x00000001 +#define CFE_FWI_32BIT 0x00000002 +#define CFE_FWI_RELOC 0x00000004 +#define CFE_FWI_UNCACHED 0x00000008 +#define CFE_FWI_MULTICPU 0x00000010 +#define CFE_FWI_FUNCSIM 0x00000020 +#define CFE_FWI_RTLSIM 0x00000040 + +typedef struct { + int64_t fwi_version; /* major, minor, eco version */ + int64_t fwi_totalmem; /* total installed mem */ + int64_t fwi_flags; /* various flags */ + int64_t fwi_boardid; /* board ID */ + int64_t fwi_bootarea_va; /* VA of boot area */ + int64_t fwi_bootarea_pa; /* PA of boot area */ + int64_t fwi_bootarea_size; /* size of boot area */ +} cfe_fwinfo_t; + + +/* + * cfe_strlen is handled specially: If already defined, it has been + * overridden in this environment with a standard strlen-like function. + */ +#ifdef cfe_strlen +# define CFE_API_STRLEN_CUSTOM #else -#define CFE_APIENTRY 0x9FC00500 -#define CFE_APISEAL 0x9FC004E0 -#define CFE_APISEAL_RE 0x9FC004E8 -#define CFE_APISEAL_OLD 0x9FC00508 +# ifdef CFE_API_IMPL_NAMESPACE +# define cfe_strlen(a) __cfe_strlen(a) +# endif +int cfe_strlen(char *name); #endif -#ifndef __ASSEMBLER__ -int cfe_init(cfe_xuint_t handle); -int cfe_open(char *name); +/* + * Defines and prototypes for functions which take no arguments. + */ +#ifdef CFE_API_IMPL_NAMESPACE +int64_t __cfe_getticks(void); +#define cfe_getticks() __cfe_getticks() +#else +int64_t cfe_getticks(void); +#endif + +/* + * Defines and prototypes for the rest of the functions. + */ +#ifdef CFE_API_IMPL_NAMESPACE +#define cfe_close(a) __cfe_close(a) +#define cfe_cpu_start(a,b,c,d,e) __cfe_cpu_start(a,b,c,d,e) +#define cfe_cpu_stop(a) __cfe_cpu_stop(a) +#define cfe_enumenv(a,b,d,e,f) __cfe_enumenv(a,b,d,e,f) +#define cfe_enummem(a,b,c,d,e) __cfe_enummem(a,b,c,d,e) +#define cfe_exit(a,b) __cfe_exit(a,b) +#define cfe_flushcache(a) __cfe_cacheflush(a) +#define cfe_getdevinfo(a) __cfe_getdevinfo(a) +#define cfe_getenv(a,b,c) __cfe_getenv(a,b,c) +#define cfe_getfwinfo(a) __cfe_getfwinfo(a) +#define cfe_getstdhandle(a) __cfe_getstdhandle(a) +#define cfe_init(a,b) __cfe_init(a,b) +#define cfe_inpstat(a) __cfe_inpstat(a) +#define cfe_ioctl(a,b,c,d,e,f) __cfe_ioctl(a,b,c,d,e,f) +#define cfe_open(a) __cfe_open(a) +#define cfe_read(a,b,c) __cfe_read(a,b,c) +#define cfe_readblk(a,b,c,d) __cfe_readblk(a,b,c,d) +#define cfe_setenv(a,b) __cfe_setenv(a,b) +#define cfe_write(a,b,c) __cfe_write(a,b,c) +#define cfe_writeblk(a,b,c,d) __cfe_writeblk(a,b,c,d) +#endif /* CFE_API_IMPL_NAMESPACE */ + int cfe_close(int handle); -int cfe_readblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length); -int cfe_read(int handle,unsigned char *buffer,int length); -int cfe_writeblk(int handle,cfe_xint_t offset,unsigned char *buffer,int length); -int cfe_write(int handle,unsigned char *buffer,int length); -int cfe_ioctl(int handle,unsigned int ioctlnum,unsigned char *buffer,int length,int *retlen); -int cfe_inpstat(int handle); -int cfe_enumenv(int idx,char *name,int namelen,char *val,int vallen); -int cfe_enummem(long idx, unsigned long long *addr, unsigned long long *size, long *type); -int cfe_setenv(char *name,char *val); -int cfe_getenv(char *name,char *dest,int destlen); -long long cfe_getticks(void); +int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1); +int cfe_cpu_stop(int cpu); +int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen); +int cfe_enummem(int idx, int flags, uint64_t * start, uint64_t * length, + uint64_t * type); int cfe_exit(int warm, int status); int cfe_flushcache(int flg); +int cfe_getdevinfo(char *name); +int cfe_getenv(char *name, char *dest, int destlen); +int cfe_getfwinfo(cfe_fwinfo_t * info); int cfe_getstdhandle(int flg); -int cfe_start_cpu(int cpu, void (*fn)(void), long sp, long gp, long a1); -int cfe_stop_cpu(int cpu); +int cfe_init(uint64_t handle, uint64_t ept); +int cfe_inpstat(int handle); +int cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer, + int length, int *retlen, uint64_t offset); +int cfe_open(char *name); +int cfe_read(int handle, unsigned char *buffer, int length); +int cfe_readblk(int handle, int64_t offset, unsigned char *buffer, + int length); +int cfe_setenv(char *name, char *val); +int cfe_write(int handle, unsigned char *buffer, int length); +int cfe_writeblk(int handle, int64_t offset, unsigned char *buffer, + int length); -void cfe_open_console(void); -void cfe_console_print(const char *, int); -#endif +#endif /* CFE_API_H */ diff -urN linux-2.4.21-bk37/arch/mips/sibyte/cfe/cfe_api_int.h linux-2.4.21-bk38/arch/mips/sibyte/cfe/cfe_api_int.h --- linux-2.4.21-bk37/arch/mips/sibyte/cfe/cfe_api_int.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/cfe/cfe_api_int.h 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2000, 2001, 2002 Broadcom Corporation + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* ********************************************************************* + * + * Broadcom Common Firmware Environment (CFE) + * + * Device function prototypes File: cfe_api_int.h + * + * This header defines all internal types and macros for the + * library. This is stuff that's not exported to an app + * using the library. + * + * Authors: Mitch Lichtenberg, Chris Demetriou + * + ********************************************************************* */ + +#ifndef CFE_API_INT_H +#define CFE_API_INT_H + +/* ********************************************************************* + * Constants + ********************************************************************* */ + +#define CFE_CMD_FW_GETINFO 0 +#define CFE_CMD_FW_RESTART 1 +#define CFE_CMD_FW_BOOT 2 +#define CFE_CMD_FW_CPUCTL 3 +#define CFE_CMD_FW_GETTIME 4 +#define CFE_CMD_FW_MEMENUM 5 +#define CFE_CMD_FW_FLUSHCACHE 6 + +#define CFE_CMD_DEV_GETHANDLE 9 +#define CFE_CMD_DEV_ENUM 10 +#define CFE_CMD_DEV_OPEN 11 +#define CFE_CMD_DEV_INPSTAT 12 +#define CFE_CMD_DEV_READ 13 +#define CFE_CMD_DEV_WRITE 14 +#define CFE_CMD_DEV_IOCTL 15 +#define CFE_CMD_DEV_CLOSE 16 +#define CFE_CMD_DEV_GETINFO 17 + +#define CFE_CMD_ENV_ENUM 20 +#define CFE_CMD_ENV_GET 22 +#define CFE_CMD_ENV_SET 23 +#define CFE_CMD_ENV_DEL 24 + +#define CFE_CMD_MAX 32 + +#define CFE_CMD_VENDOR_USE 0x8000 /* codes above this are for customer use */ + +/* ********************************************************************* + * Structures + ********************************************************************* */ + +typedef uint64_t cfe_xuint_t; +typedef int64_t cfe_xint_t; +typedef int64_t cfe_xptr_t; + +typedef struct xiocb_buffer_s { + cfe_xuint_t buf_offset; /* offset on device (bytes) */ + cfe_xptr_t buf_ptr; /* pointer to a buffer */ + cfe_xuint_t buf_length; /* length of this buffer */ + cfe_xuint_t buf_retlen; /* returned length (for read ops) */ + cfe_xuint_t buf_ioctlcmd; /* IOCTL command (used only for IOCTLs) */ +} xiocb_buffer_t; + +#define buf_devflags buf_ioctlcmd /* returned device info flags */ + +typedef struct xiocb_inpstat_s { + cfe_xuint_t inp_status; /* 1 means input available */ +} xiocb_inpstat_t; + +typedef struct xiocb_envbuf_s { + cfe_xint_t enum_idx; /* 0-based enumeration index */ + cfe_xptr_t name_ptr; /* name string buffer */ + cfe_xint_t name_length; /* size of name buffer */ + cfe_xptr_t val_ptr; /* value string buffer */ + cfe_xint_t val_length; /* size of value string buffer */ +} xiocb_envbuf_t; + +typedef struct xiocb_cpuctl_s { + cfe_xuint_t cpu_number; /* cpu number to control */ + cfe_xuint_t cpu_command; /* command to issue to CPU */ + cfe_xuint_t start_addr; /* CPU start address */ + cfe_xuint_t gp_val; /* starting GP value */ + cfe_xuint_t sp_val; /* starting SP value */ + cfe_xuint_t a1_val; /* starting A1 value */ +} xiocb_cpuctl_t; + +typedef struct xiocb_time_s { + cfe_xint_t ticks; /* current time in ticks */ +} xiocb_time_t; + +typedef struct xiocb_exitstat_s { + cfe_xint_t status; +} xiocb_exitstat_t; + +typedef struct xiocb_meminfo_s { + cfe_xint_t mi_idx; /* 0-based enumeration index */ + cfe_xint_t mi_type; /* type of memory block */ + cfe_xuint_t mi_addr; /* physical start address */ + cfe_xuint_t mi_size; /* block size */ +} xiocb_meminfo_t; + +typedef struct xiocb_fwinfo_s { + cfe_xint_t fwi_version; /* major, minor, eco version */ + cfe_xint_t fwi_totalmem; /* total installed mem */ + cfe_xint_t fwi_flags; /* various flags */ + cfe_xint_t fwi_boardid; /* board ID */ + cfe_xint_t fwi_bootarea_va; /* VA of boot area */ + cfe_xint_t fwi_bootarea_pa; /* PA of boot area */ + cfe_xint_t fwi_bootarea_size; /* size of boot area */ + cfe_xint_t fwi_reserved1; + cfe_xint_t fwi_reserved2; + cfe_xint_t fwi_reserved3; +} xiocb_fwinfo_t; + +typedef struct cfe_xiocb_s { + cfe_xuint_t xiocb_fcode; /* IOCB function code */ + cfe_xint_t xiocb_status; /* return status */ + cfe_xint_t xiocb_handle; /* file/device handle */ + cfe_xuint_t xiocb_flags; /* flags for this IOCB */ + cfe_xuint_t xiocb_psize; /* size of parameter list */ + union { + xiocb_buffer_t xiocb_buffer; /* buffer parameters */ + xiocb_inpstat_t xiocb_inpstat; /* input status parameters */ + xiocb_envbuf_t xiocb_envbuf; /* environment function parameters */ + xiocb_cpuctl_t xiocb_cpuctl; /* CPU control parameters */ + xiocb_time_t xiocb_time; /* timer parameters */ + xiocb_meminfo_t xiocb_meminfo; /* memory arena info parameters */ + xiocb_fwinfo_t xiocb_fwinfo; /* firmware information */ + xiocb_exitstat_t xiocb_exitstat; /* Exit Status */ + } plist; +} cfe_xiocb_t; + +#endif /* CFE_API_INT_H */ diff -urN linux-2.4.21-bk37/arch/mips/sibyte/cfe/cfe_error.h linux-2.4.21-bk38/arch/mips/sibyte/cfe/cfe_error.h --- linux-2.4.21-bk37/arch/mips/sibyte/cfe/cfe_error.h 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/cfe/cfe_error.h 2003-08-24 02:55:58.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2000, 2001, 2002 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -17,19 +17,18 @@ */ /* ********************************************************************* + * * Broadcom Common Firmware Environment (CFE) - * + * * Error codes File: cfe_error.h - * + * * CFE's global error code list is here. - * - * Author: Mitch Lichtenberg (mpl@broadcom.com) - * + * + * Author: Mitch Lichtenberg + * ********************************************************************* */ - - #define CFE_OK 0 #define CFE_ERR -1 /* generic error */ #define CFE_ERR_INV_COMMAND -2 @@ -74,3 +73,13 @@ #define CFE_ERR_WRONGDEVTYPE -32 #define CFE_ERR_BBCHECKSUM -33 #define CFE_ERR_BOOTPROGCHKSUM -34 + +#define CFE_ERR_LDRNOTAVAIL -35 + +#define CFE_ERR_NOTREADY -36 + +#define CFE_ERR_GETMEM -37 +#define CFE_ERR_SETMEM -38 + +#define CFE_ERR_NOTCONN -39 +#define CFE_ERR_ADDRINUSE -40 diff -urN linux-2.4.21-bk37/arch/mips/sibyte/cfe/cfe_xiocb.h linux-2.4.21-bk38/arch/mips/sibyte/cfe/cfe_xiocb.h --- linux-2.4.21-bk37/arch/mips/sibyte/cfe/cfe_xiocb.h 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/cfe/cfe_xiocb.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2000, 2001 Broadcom Corporation - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* ********************************************************************* - * Broadcom Common Firmware Environment (CFE) - * - * IOCB definitions File: cfe_iocb.h - * - * This module describes CFE's IOCB structure, the main - * data structure used to communicate API requests with CFE. - * - * Author: Mitch Lichtenberg (mpl@broadcom.com) - * - ********************************************************************* */ - -/* ********************************************************************* - * Constants - ********************************************************************* */ - -#define CFE_CMD_FW_GETINFO 0 -#define CFE_CMD_FW_RESTART 1 -#define CFE_CMD_FW_BOOT 2 -#define CFE_CMD_FW_CPUCTL 3 -#define CFE_CMD_FW_GETTIME 4 -#define CFE_CMD_FW_MEMENUM 5 -#define CFE_CMD_FW_FLUSHCACHE 6 - -#define CFE_CMD_DEV_GETHANDLE 9 -#define CFE_CMD_DEV_ENUM 10 -#define CFE_CMD_DEV_OPEN 11 -#define CFE_CMD_DEV_INPSTAT 12 -#define CFE_CMD_DEV_READ 13 -#define CFE_CMD_DEV_WRITE 14 -#define CFE_CMD_DEV_IOCTL 15 -#define CFE_CMD_DEV_CLOSE 16 -#define CFE_CMD_DEV_GETINFO 17 - -#define CFE_CMD_ENV_ENUM 20 -#define CFE_CMD_ENV_GET 22 -#define CFE_CMD_ENV_SET 23 -#define CFE_CMD_ENV_DEL 24 - -#define CFE_CMD_MAX 32 - -#define CFE_MI_RESERVED 0 /* memory is reserved, do not use */ -#define CFE_MI_AVAILABLE 1 /* memory is available */ - -#define CFE_FLG_WARMSTART 0x00000001 - -#define CFE_FLG_ENV_PERMANENT 0x00000001 - -#define CFE_CPU_CMD_START 1 -#define CFE_CPU_CMD_STOP 0 - -#define CFE_STDHANDLE_CONSOLE 0 - -#define CFE_DEV_NETWORK 1 -#define CFE_DEV_DISK 2 -#define CFE_DEV_FLASH 3 -#define CFE_DEV_SERIAL 4 -#define CFE_DEV_CPU 5 -#define CFE_DEV_NVRAM 6 -#define CFE_DEV_OTHER 7 -#define CFE_DEV_MASK 0x0F - -#define CFE_CACHE_FLUSH_D 1 -#define CFE_CACHE_INVAL_I 2 -#define CFE_CACHE_INVAL_D 4 -#define CFE_CACHE_INVAL_L2 8 - -/* ********************************************************************* - * Structures - ********************************************************************* */ - -typedef unsigned long long cfe_xuint_t; -typedef long long cfe_xint_t; -typedef long long cfe_xptr_t; - -typedef struct xiocb_buffer_s { - cfe_xuint_t buf_offset; /* offset on device (bytes) */ - cfe_xptr_t buf_ptr; /* pointer to a buffer */ - cfe_xuint_t buf_length; /* length of this buffer */ - cfe_xuint_t buf_retlen; /* returned length (for read ops) */ - cfe_xuint_t buf_ioctlcmd; /* IOCTL command (used only for IOCTLs) */ -} xiocb_buffer_t; - -#define buf_devflags buf_ioctlcmd /* returned device info flags */ - -typedef struct xiocb_inpstat_s { - cfe_xuint_t inp_status; /* 1 means input available */ -} xiocb_inpstat_t; - -typedef struct xiocb_envbuf_s { - cfe_xint_t enum_idx; /* 0-based enumeration index */ - cfe_xptr_t name_ptr; /* name string buffer */ - cfe_xint_t name_length; /* size of name buffer */ - cfe_xptr_t val_ptr; /* value string buffer */ - cfe_xint_t val_length; /* size of value string buffer */ -} xiocb_envbuf_t; - -typedef struct xiocb_cpuctl_s { - cfe_xuint_t cpu_number; /* cpu number to control */ - cfe_xuint_t cpu_command; /* command to issue to CPU */ - cfe_xuint_t start_addr; /* CPU start address */ - cfe_xuint_t gp_val; /* starting GP value */ - cfe_xuint_t sp_val; /* starting SP value */ - cfe_xuint_t a1_val; /* starting A1 value */ -} xiocb_cpuctl_t; - -typedef struct xiocb_time_s { - cfe_xint_t ticks; /* current time in ticks */ -} xiocb_time_t; - -typedef struct xiocb_exitstat_s { - cfe_xint_t status; -} xiocb_exitstat_t; - -typedef struct xiocb_meminfo_s { - cfe_xint_t mi_idx; /* 0-based enumeration index */ - cfe_xint_t mi_type; /* type of memory block */ - cfe_xuint_t mi_addr; /* physical start address */ - cfe_xuint_t mi_size; /* block size */ -} xiocb_meminfo_t; - -#define CFE_FWI_64BIT 0x00000001 -#define CFE_FWI_32BIT 0x00000002 -#define CFE_FWI_RELOC 0x00000004 -#define CFE_FWI_UNCACHED 0x00000008 -#define CFE_FWI_MULTICPU 0x00000010 -#define CFE_FWI_FUNCSIM 0x00000020 -#define CFE_FWI_RTLSIM 0x00000040 - -typedef struct xiocb_fwinfo_s { - cfe_xint_t fwi_version; /* major, minor, eco version */ - cfe_xint_t fwi_totalmem; /* total installed mem */ - cfe_xint_t fwi_flags; /* various flags */ - cfe_xint_t fwi_boardid; /* board ID */ - cfe_xint_t fwi_bootarea_va; /* VA of boot area */ - cfe_xint_t fwi_bootarea_pa; /* PA of boot area */ - cfe_xint_t fwi_bootarea_size; /* size of boot area */ - cfe_xint_t fwi_reserved1; - cfe_xint_t fwi_reserved2; - cfe_xint_t fwi_reserved3; -} xiocb_fwinfo_t,cfe_fwinfo_t; - -typedef struct cfe_xiocb_s { - cfe_xuint_t xiocb_fcode; /* IOCB function code */ - cfe_xint_t xiocb_status; /* return status */ - cfe_xint_t xiocb_handle; /* file/device handle */ - cfe_xuint_t xiocb_flags; /* flags for this IOCB */ - cfe_xuint_t xiocb_psize; /* size of parameter list */ - union { - xiocb_buffer_t xiocb_buffer; /* buffer parameters */ - xiocb_inpstat_t xiocb_inpstat; /* input status parameters */ - xiocb_envbuf_t xiocb_envbuf; /* environment function parameters */ - xiocb_cpuctl_t xiocb_cpuctl; /* CPU control parameters */ - xiocb_time_t xiocb_time; /* timer parameters */ - xiocb_meminfo_t xiocb_meminfo; /* memory arena info parameters */ - xiocb_fwinfo_t xiocb_fwinfo; /* firmware information */ - xiocb_exitstat_t xiocb_exitstat; /* Exit status */ - } plist; -} cfe_xiocb_t; diff -urN linux-2.4.21-bk37/arch/mips/sibyte/cfe/console.c linux-2.4.21-bk38/arch/mips/sibyte/cfe/console.c --- linux-2.4.21-bk37/arch/mips/sibyte/cfe/console.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/cfe/console.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,87 @@ +#include +#include +#include +#include + +#include + +#include "cfe_api.h" +#include "cfe_error.h" + +extern int cfe_cons_handle; +static kdev_t cfe_consdev; + +static void cfe_console_write(struct console *cons, const char *str, + unsigned int count) +{ + int i, last, written; + + for (i=0,last=0; i@" * e.g. initrd=3abfd@80010000. This is set up by the loader. @@ -205,21 +217,21 @@ if (!*tmp) { goto fail; } - initrd_size = simple_strtol(str, &endptr, 16); + initrd_size = simple_strtoul(str, &endptr, 16); if (*endptr) { *(tmp-1) = '@'; goto fail; } *(tmp-1) = '@'; - initrd_start = simple_strtol(tmp, &endptr, 16); + initrd_start = simple_strtoul(tmp, &endptr, 16); if (*endptr) { goto fail; } initrd_end = initrd_start + initrd_size; - printk("Found initrd of %lx@%lx\n", initrd_size, initrd_start); + prom_printf("Found initrd of %lx@%lx\n", initrd_size, initrd_start); return 1; fail: - printk("Bad initrd argument. Disabling initrd\n"); + prom_printf("Bad initrd argument. Disabling initrd\n"); initrd_start = 0; initrd_end = 0; return 1; @@ -232,21 +244,56 @@ */ __init int prom_init(int argc, char **argv, char **envp, int *prom_vec) { + uint64_t cfe_ept, cfe_handle; + unsigned int cfe_eptseal; +#ifdef CONFIG_KGDB + char *arg; +#endif + _machine_restart = (void (*)(char *))cfe_linux_exit; _machine_halt = cfe_linux_exit; _machine_power_off = cfe_linux_exit; /* - * This should go away. Detect if we're booting - * straight from cfe without a loader. If we - * are, then we've got a prom vector in a0. Otherwise, - * argc (and argv and envp, for that matter) will be 0) + * Check if a loader was used; if NOT, the 4 arguments are + * what CFE gives us (handle, 0, EPT and EPTSEAL) */ if (argc < 0) { - prom_vec = (int *)argc; + cfe_handle = (uint64_t)(long)argc; + cfe_ept = (long)envp; + cfe_eptseal = (uint32_t)(unsigned long)prom_vec; + } else { + if ((int32_t)(long)prom_vec < 0) { + /* + * Old loader; all it gives us is the handle, + * so use the "known" entrypoint and assume + * the seal. + */ + cfe_handle = (uint64_t)(long)prom_vec; + cfe_ept = (uint64_t)((int32_t)0x9fc00500); + cfe_eptseal = CFE_EPTSEAL; + } else { + /* + * Newer loaders bundle the handle/ept/eptseal + * Note: prom_vec is in the loader's useg + * which is still alive in the TLB. + */ + cfe_handle = (uint64_t)((int32_t *)prom_vec)[0]; + cfe_ept = (uint64_t)((int32_t *)prom_vec)[2]; + cfe_eptseal = (unsigned int)((uint32_t *)prom_vec)[3]; + } } - cfe_init((long)prom_vec); - cfe_open_console(); + if (cfe_eptseal != CFE_EPTSEAL) { + /* too early for panic to do any good */ + prom_printf("CFE's entrypoint seal doesn't match. Spinning."); + while (1) ; + } + cfe_init(cfe_handle, cfe_ept); + /* + * Get the handle for (at least) prom_putchar, possibly for + * boot console + */ + cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE); if (cfe_getenv("LINUX_CMDLINE", arcs_cmdline, CL_SIZE) < 0) { if (argc < 0) { /* @@ -254,15 +301,28 @@ * command line */ strcpy(arcs_cmdline, "root=/dev/ram0 "); -#ifdef CONFIG_SIBYTE_PTSWARM - strcat(arcs_cmdline, "console=ttyS0,115200 "); -#endif } else { /* The loader should have set the command line */ - panic("LINUX_CMDLINE not defined in cfe."); + /* too early for panic to do any good */ + prom_printf("LINUX_CMDLINE not defined in cfe."); + while (1) ; } } +#ifdef CONFIG_KGDB + if ((arg = strstr(arcs_cmdline,"kgdb=duart")) != NULL) + kgdb_port = (arg[10] == '0') ? 0 : 1; + else + kgdb_port = 1; +#endif + +#ifdef SIBYTE_DEFAULT_CONSOLE + /* Force default console from board header (allowing override) */ + if (!strstr(arcs_cmdline,"console=")) { + strcat(arcs_cmdline, "console=" SIBYTE_DEFAULT_CONSOLE); + } +#endif + #ifdef CONFIG_BLK_DEV_INITRD { char *ptr; @@ -311,77 +371,10 @@ return 0; } -#ifdef CONFIG_SIBYTE_CFE_CONSOLE - -static void cfe_console_write(struct console *cons, const char *str, - unsigned int count) -{ - int i, last; - - for (i=0,last=0; i -#include - -/* SB1 definitions */ - -/* XXX should come from config1 XXX */ -#define SB1_CACHE_INDEX_MASK 0x1fe0 - -#define CP0_ERRCTL_RECOVERABLE (1 << 31) -#define CP0_ERRCTL_DCACHE (1 << 30) -#define CP0_ERRCTL_ICACHE (1 << 29) -#define CP0_ERRCTL_MULTIBUS (1 << 23) -#define CP0_ERRCTL_MC_TLB (1 << 15) -#define CP0_ERRCTL_MC_TIMEOUT (1 << 14) - -#define CP0_CERRI_TAG_PARITY (1 << 29) -#define CP0_CERRI_DATA_PARITY (1 << 28) -#define CP0_CERRI_EXTERNAL (1 << 26) - -#define CP0_CERRI_IDX_VALID(c) (!((c) & CP0_CERRI_EXTERNAL)) -#define CP0_CERRI_DATA (CP0_CERRI_DATA_PARITY) - -#define CP0_CERRD_MULTIPLE (1 << 31) -#define CP0_CERRD_TAG_STATE (1 << 30) -#define CP0_CERRD_TAG_ADDRESS (1 << 29) -#define CP0_CERRD_DATA_SBE (1 << 28) -#define CP0_CERRD_DATA_DBE (1 << 27) -#define CP0_CERRD_EXTERNAL (1 << 26) -#define CP0_CERRD_LOAD (1 << 25) -#define CP0_CERRD_STORE (1 << 24) -#define CP0_CERRD_FILLWB (1 << 23) -#define CP0_CERRD_COHERENCY (1 << 22) -#define CP0_CERRD_DUPTAG (1 << 21) - -#define CP0_CERRD_DPA_VALID(c) (!((c) & CP0_CERRD_EXTERNAL)) -#define CP0_CERRD_IDX_VALID(c) \ - (((c) & (CP0_CERRD_LOAD | CP0_CERRD_STORE)) ? (!((c) & CP0_CERRD_EXTERNAL)) : 0) -#define CP0_CERRD_CAUSES \ - (CP0_CERRD_LOAD | CP0_CERRD_STORE | CP0_CERRD_FILLWB | CP0_CERRD_COHERENCY | CP0_CERRD_DUPTAG) -#define CP0_CERRD_TYPES \ - (CP0_CERRD_TAG_STATE | CP0_CERRD_TAG_ADDRESS | CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE | CP0_CERRD_EXTERNAL) -#define CP0_CERRD_DATA (CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE) - -static uint32_t extract_ic(unsigned short addr, int data); -static uint32_t extract_dc(unsigned short addr, int data); - -spinlock_t in_cacheerr = SPIN_LOCK_UNLOCKED; - -static inline void breakout_errctl(unsigned int val) -{ - if (val & CP0_ERRCTL_RECOVERABLE) - printk(" recoverable"); - if (val & CP0_ERRCTL_DCACHE) - printk(" dcache"); - if (val & CP0_ERRCTL_ICACHE) - printk(" icache"); - if (val & CP0_ERRCTL_MULTIBUS) - printk(" multiple-buserr"); - printk("\n"); -} - -static inline void breakout_cerri(unsigned int val) -{ - if (val & CP0_CERRI_TAG_PARITY) - printk(" tag-parity"); - if (val & CP0_CERRI_DATA_PARITY) - printk(" data-parity"); - if (val & CP0_CERRI_EXTERNAL) - printk(" external"); - printk("\n"); -} - -static inline void breakout_cerrd(unsigned int val) -{ - switch (val & CP0_CERRD_CAUSES) { - case CP0_CERRD_LOAD: - printk(" load,"); - break; - case CP0_CERRD_STORE: - printk(" store,"); - break; - case CP0_CERRD_FILLWB: - printk(" fill/wb,"); - break; - case CP0_CERRD_COHERENCY: - printk(" coherency,"); - break; - case CP0_CERRD_DUPTAG: - printk(" duptags,"); - break; - default: - printk(" NO CAUSE,"); - break; - } - if (!(val & CP0_CERRD_TYPES)) - printk(" NO TYPE"); - else { - if (val & CP0_CERRD_MULTIPLE) - printk(" multi-err"); - if (val & CP0_CERRD_TAG_STATE) - printk(" tag-state"); - if (val & CP0_CERRD_TAG_ADDRESS) - printk(" tag-address"); - if (val & CP0_CERRD_DATA_SBE) - printk(" data-SBE"); - if (val & CP0_CERRD_DATA_DBE) - printk(" data-DBE"); - if (val & CP0_CERRD_EXTERNAL) - printk(" external"); - } - printk("\n"); -} - -asmlinkage void sb1_cache_error(void) -{ - uint64_t cerr_dpa; - uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res; - - /* Prevent re-entrance in the SMP case */ - spin_lock(&in_cacheerr); - printk("Cache error exception on CPU %x:\n", - (read_32bit_cp0_register(CP0_PRID) >> 25) & 0x7); - __asm__ __volatile__ ( - ".set push\n\t" - ".set mips64\n\t" - ".set noat\n\t" - "mfc0 %0, $26, 0\n\t" - "mfc0 %1, $27, 0\n\t" - "mfc0 %2, $27, 1\n\t" - "dmfc0 $1, $27, 3\n\t" - "dsrl32 %3, $1, 0 \n\t" - "sll %4, $1, 0 \n\t" - "mfc0 %5, $30\n\t" - ".set pop\n" - : "=r" (errctl), "=r" (cerr_i), "=r" (cerr_d), - "=r" (dpahi), "=r" (dpalo), "=r" (eepc)); - cerr_dpa = (((uint64_t)dpahi) << 32) | dpalo; - printk(" cp0_errorepc == %08x\n", eepc); - printk(" cp0_errctl == %08x", errctl); - breakout_errctl(errctl); - if (errctl & CP0_ERRCTL_ICACHE) { - printk(" cp0_cerr_i == %08x", cerr_i); - breakout_cerri(cerr_i); - if (CP0_CERRI_IDX_VALID(cerr_i)) { - if ((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK)) - printk(" cerr_i idx doesn't match eepc\n"); - else { - res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK, - (cerr_i & CP0_CERRI_DATA) != 0); - if (!(res & cerr_i)) - printk("...didn't see indicated icache problem\n"); - } - } - } - if (errctl & CP0_ERRCTL_DCACHE) { - printk(" cp0_cerr_d == %08x", cerr_d); - breakout_cerrd(cerr_d); - if (CP0_CERRD_DPA_VALID(cerr_d)) { - printk(" cp0_cerr_dpa == %010llx\n", cerr_dpa); - if (!CP0_CERRD_IDX_VALID(cerr_d)) { - res = extract_dc(cerr_dpa & SB1_CACHE_INDEX_MASK, - (cerr_d & CP0_CERRD_DATA) != 0); - if (!(res & cerr_d)) - printk("...didn't see indicated dcache problem\n"); - } else { - if ((cerr_dpa & SB1_CACHE_INDEX_MASK) != (cerr_d & SB1_CACHE_INDEX_MASK)) - printk(" cerr_d idx doesn't match cerr_dpa\n"); - else { - res = extract_dc(cerr_d & SB1_CACHE_INDEX_MASK, - (cerr_d & CP0_CERRD_DATA) != 0); - if (!(res & cerr_d)) - printk("...didn't see indicated problem\n"); - } - } - } - } - - while (1); - /* - * This tends to make things get really ugly; let's just stall instead. - * panic("Can't handle the cache error!"); - */ -} - - -/* Parity lookup table. */ -static const uint8_t parity[256] = { - 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, - 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, - 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, - 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, - 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, - 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, - 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, - 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0 -}; - -/* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */ -static const uint64_t mask_72_64[8] = { - 0x0738C808099264FFL, - 0x38C808099264FF07L, - 0xC808099264FF0738L, - 0x08099264FF0738C8L, - 0x099264FF0738C808L, - 0x9264FF0738C80809L, - 0x64FF0738C8080992L, - 0xFF0738C808099264L -}; - -/* Calculate the parity on a range of bits */ -static char range_parity(uint64_t dword, int max, int min) -{ - char parity = 0; - int i; - dword >>= min; - for (i=max-min; i>=0; i--) { - if (dword & 0x1) - parity = !parity; - dword >>= 1; - } - return parity; -} - -/* Calculate the 4-bit even byte-parity for an instruction */ -static unsigned char inst_parity(uint32_t word) -{ - int i, j; - char parity = 0; - for (j=0; j<4; j++) { - char byte_parity = 0; - for (i=0; i<8; i++) { - if (word & 0x80000000) - byte_parity = !byte_parity; - word <<= 1; - } - parity <<= 1; - parity |= byte_parity; - } - return parity; -} - -static uint32_t extract_ic(unsigned short addr, int data) -{ - unsigned short way; - int valid; - uint64_t taglo, va, tlo_tmp; - uint32_t taghi, taglolo, taglohi; - uint8_t lru; - int res = 0; - - printk("Icache index 0x%04x ", addr); - for (way = 0; way < 4; way++) { - /* Index-load-tag-I */ - __asm__ __volatile__ ( - ".set push \n\t" - ".set noreorder \n\t" - ".set mips64 \n\t" - ".set noat \n\t" - "cache 4, 0(%3) \n\t" - "mfc0 %0, $29, 0\n\t" - "dmfc0 $1, $28, 0\n\t" - "dsrl32 %1, $1, 0 \n\t" - "sll %2, $1, 0 \n\t" - ".set pop \n" - : "=r" (taghi), "=r" (taglohi), - "=r" (taglolo) - : "r" ((way << 13) | addr)); - taglo = ((unsigned long long)taglohi << 32) | taglolo; - if (way == 0) { - lru = (taghi >> 14) & 0xff; - printk("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", - ((addr >> 5) & 0x3), /* bank */ - ((addr >> 7) & 0x3f), /* index */ - (lru & 0x3), - ((lru >> 2) & 0x3), - ((lru >> 4) & 0x3), - ((lru >> 6) & 0x3)); - } - va = (taglo & 0xC0000FFFFFFFE000) | addr; - if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3)) - va |= 0x3FFFF00000000000; - valid = ((taghi >> 29) & 1); - if (valid) { - tlo_tmp = taglo & 0xfff3ff; - if (((taglo >> 10) & 1) ^ range_parity(tlo_tmp, 23, 0)) { - printk(" ** bad parity in VTag0/G/ASID\n"); - res |= CP0_CERRI_TAG_PARITY; - } - if (((taglo >> 11) & 1) ^ range_parity(taglo, 63, 24)) { - printk(" ** bad parity in R/VTag1\n"); - res |= CP0_CERRI_TAG_PARITY; - } - } - if (valid ^ ((taghi >> 27) & 1)) { - printk(" ** bad parity for valid bit\n"); - res |= CP0_CERRI_TAG_PARITY; - } - printk(" %d [VA %016llx] [Vld? %d] raw tags: %08X-%016llX\n", - way, va, valid, taghi, taglo); - - if (data) { - uint32_t datahi, insta, instb; - uint8_t predecode; - int offset; - - /* (hit all banks and ways) */ - for (offset = 0; offset < 4; offset++) { - /* Index-load-data-I */ - __asm__ __volatile__ ( - ".set push \n\t" - ".set noreorder \n\t" - ".set mips64 \n\t" - ".set noat \n\t" - "cache 6, 0(%3) \n\t" - "mfc0 %0, $29, 1\n\t" - "dmfc0 $1, $28, 1\n\t" - "dsrl32 %1, $1, 0 \n\t" - "sll %2, $1, 0 \n\t" - ".set pop \n" - : "=r" (datahi), "=r" (insta), - "=r" (instb) - : "r" ((way << 13) | addr | (offset << 3))); - predecode = (datahi >> 8) & 0xff; - if (((datahi >> 16) & 1) != (uint32_t)range_parity(predecode, 7, 0)) { - printk(" ** bad parity in predecode\n"); - res |= CP0_CERRI_DATA_PARITY; - } - /* XXXKW should/could check predecode bits themselves */ - if (((datahi >> 4) & 0xf) ^ inst_parity(insta)) { - printk(" ** bad parity in instruction a\n"); - res |= CP0_CERRI_DATA_PARITY; - } - if ((datahi & 0xf) ^ inst_parity(instb)) { - printk(" ** bad parity in instruction b\n"); - res |= CP0_CERRI_DATA_PARITY; - } - printk(" %05X-%08X%08X", datahi, insta, instb); - } - printk("\n"); - } - } - return res; -} - -/* Compute the ECC for a data doubleword */ -static uint8_t dc_ecc(uint64_t dword) -{ - uint64_t t; - uint32_t w; - uint8_t p; - int i; - - p = 0; - for (i = 7; i >= 0; i--) - { - p <<= 1; - t = dword & mask_72_64[i]; - w = (uint32_t)(t >> 32); - p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF] - ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]); - w = (uint32_t)(t & 0xFFFFFFFF); - p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF] - ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]); - } - return p; -} - -struct dc_state { - unsigned char val; - char *name; -}; - -static struct dc_state dc_states[] = { - { 0x00, "INVALID" }, - { 0x0f, "COH-SHD" }, - { 0x13, "NCO-E-C" }, - { 0x19, "NCO-E-D" }, - { 0x16, "COH-E-C" }, - { 0x1c, "COH-E-D" }, - { 0xff, "*ERROR*" } -}; - -#define DC_TAG_VALID(state) \ - (((state) == 0xf) || ((state) == 0x13) || ((state) == 0x19) || ((state == 0x16)) || ((state) == 0x1c)) - -static char *dc_state_str(unsigned char state) -{ - struct dc_state *dsc = dc_states; - while (dsc->val != 0xff) { - if (dsc->val == state) - break; - dsc++; - } - return dsc->name; -} - -static uint32_t extract_dc(unsigned short addr, int data) -{ - int valid, way; - unsigned char state; - uint64_t taglo, pa; - uint32_t taghi, taglolo, taglohi; - uint8_t ecc, lru; - int res = 0; - - printk("Dcache index 0x%04x ", addr); - for (way = 0; way < 4; way++) { - /* Index-load-tag-D */ - __asm__ __volatile__ ( - ".set push \n\t" - ".set noreorder \n\t" - ".set mips64 \n\t" - ".set noat \n\t" - "cache 5, 0(%3) \n\t" - "mfc0 %0, $29, 2\n\t" - "dmfc0 $1, $28, 2\n\t" - "dsrl32 %1, $1, 0 \n\t" - "sll %2, $1, 0 \n\t" - ".set pop \n" - : "=r" (taghi), "=r" (taglohi), - "=r" (taglolo) - : "r" ((way << 13) | addr)); - - taglo = ((unsigned long long)taglohi << 32) | taglolo; - pa = (taglo & 0xFFFFFFE000) | addr; - if (way == 0) { - lru = (taghi >> 14) & 0xff; - printk("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", - ((addr >> 11) & 0x2) | ((addr >> 5) & 1), /* bank */ - ((addr >> 6) & 0x3f), /* index */ - (lru & 0x3), - ((lru >> 2) & 0x3), - ((lru >> 4) & 0x3), - ((lru >> 6) & 0x3)); - } - state = (taghi >> 25) & 0x1f; - valid = DC_TAG_VALID(state); - printk(" %d [PA %010llx] [state %s (%02x)] raw tags: %08X-%016llX\n", - way, pa, dc_state_str(state), state, taghi, taglo); - if (valid) { - if (((taglo >> 11) & 1) ^ range_parity(taglo, 39, 26)) { - printk(" ** bad parity in PTag1\n"); - res |= CP0_CERRD_TAG_ADDRESS; - } - if (((taglo >> 10) & 1) ^ range_parity(taglo, 25, 13)) { - printk(" ** bad parity in PTag0\n"); - res |= CP0_CERRD_TAG_ADDRESS; - } - } else { - res |= CP0_CERRD_TAG_STATE; - } - - if (data) { - uint64_t datalo; - uint32_t datalohi, datalolo, datahi; - int offset; - - for (offset = 0; offset < 4; offset++) { - /* Index-load-data-D */ - __asm__ __volatile__ ( - ".set push \n\t" - ".set noreorder \n\t" - ".set mips64 \n\t" - ".set noat \n\t" - "cache 7, 0(%3) \n\t" - "mfc0 %0, $29, 3\n\t" - "dmfc0 $1, $28, 3\n\t" - "dsrl32 %1, $1, 0 \n\t" - "sll %2, $1, 0 \n\t" - ".set pop \n" - : "=r" (datahi), "=r" (datalohi), - "=r" (datalolo) - : "r" ((way << 13) | addr | (offset << 3))); - datalo = ((unsigned long long)datalohi << 32) | datalolo; - ecc = dc_ecc(datalo); - if (ecc != datahi) { - int bits = 0; - printk(" ** bad ECC (%02x %02x) ->", - datahi, ecc); - ecc ^= datahi; - while (ecc) { - if (ecc & 1) bits++; - ecc >>= 1; - } - res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE; - } - printk(" %02X-%016llX", datahi, datalo); - } - printk("\n"); - } - } - return res; -} diff -urN linux-2.4.21-bk37/arch/mips/sibyte/sb1250/Makefile linux-2.4.21-bk38/arch/mips/sibyte/sb1250/Makefile --- linux-2.4.21-bk37/arch/mips/sibyte/sb1250/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/sb1250/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -4,10 +4,11 @@ obj-y := setup.o irq.o irq_handler.o time.o -obj-$(CONFIG_PCI) += pci.o -obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_BCM1250_TBPROF) += bcm1250_tbprof.o -obj-$(CONFIG_MIPS32) += lib_hssubr.o -obj-$(CONFIG_SIBYTE_STANDALONE) += prom.o +obj-$(CONFIG_PCI) += pci.o +obj-$(CONFIG_BLK_DEV_IDE) += ide.o +obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_SIBYTE_TBPROF) += bcm1250_tbprof.o +obj-$(CONFIG_SIBYTE_STANDALONE) += prom.o +obj-$(CONFIG_SIBYTE_BUS_WATCHER) += bus_watcher.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/sibyte/sb1250/bcm1250_tbprof.c linux-2.4.21-bk38/arch/mips/sibyte/sb1250/bcm1250_tbprof.c --- linux-2.4.21-bk37/arch/mips/sibyte/sb1250/bcm1250_tbprof.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/sb1250/bcm1250_tbprof.c 2003-08-24 02:55:58.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001 Broadcom Corporation + * Copyright (C) 2001, 2002, 2003 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -30,15 +30,18 @@ #include #include #include +#include #include #include #include #include -#include "bcm1250_tbprof.h" +#include -#define DEVNAME "sb1250_tbprof" +#define DEVNAME "bcm1250_tbprof" -static struct sbprof_tb *sbp; +static struct sbprof_tb sbp; + +#define TB_FULL (sbp.next_tb_sample == MAX_TB_SAMPLES) /************************************************************************ * Support for ZBbus sampling using the trace buffer @@ -53,13 +56,12 @@ * ************************************************************************/ -/* 100 samples per second on a 500 Mhz 1250 */ -#define TB_PERIOD 2500000ULL +static u_int64_t tb_period; static void arm_tb(void) { - unsigned long long scdperfcnt; - unsigned long long next = (1ULL << 40) - TB_PERIOD; + u_int64_t scdperfcnt; + u_int64_t next = (1ULL << 40) - tb_period; /* Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to trigger start of trace. XXX vary sampling period */ out64(0, KSEG1 + A_SCD_PERF_CNT_1); @@ -75,17 +77,22 @@ out64(next, KSEG1 + A_SCD_PERF_CNT_1); /* Reset the trace buffer */ out64(M_SCD_TRACE_CFG_RESET, KSEG1 + A_SCD_TRACE_CFG); - out64(M_SCD_TRACE_CFG_FREEZE_FULL, KSEG1 + A_SCD_TRACE_CFG); - sbp->tb_armed = 1; + out64(M_SCD_TRACE_CFG_FREEZE_FULL +#if 0 && defined(M_SCD_TRACE_CFG_FORCECNT) + /* XXXKW may want to expose control to the data-collector */ + | M_SCD_TRACE_CFG_FORCECNT +#endif + , KSEG1 + A_SCD_TRACE_CFG); + sbp.tb_armed = 1; } static void sbprof_tb_intr(int irq, void *dev_id, struct pt_regs *regs) { int i; DBG(printk(DEVNAME ": tb_intr\n")); - if (sbp->next_tb_sample < MAX_TB_SAMPLES) { + if (sbp.next_tb_sample < MAX_TB_SAMPLES) { /* XXX should use XKPHYS to make writes bypass L2 */ - unsigned long long *p = sbp->sbprof_tbbuf[sbp->next_tb_sample++]; + u_int64_t *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++]; /* Read out trace */ out64(M_SCD_TRACE_CFG_START_READ, KSEG1 + A_SCD_TRACE_CFG); __asm__ __volatile__ ("sync" : : : "memory"); @@ -100,11 +107,11 @@ p[i-5] = in64(KSEG1 + A_SCD_TRACE_READ); // read t0 hi p[i-6] = in64(KSEG1 + A_SCD_TRACE_READ); // read t0 lo } - if (!sbp->tb_enable) { + if (!sbp.tb_enable) { DBG(printk(DEVNAME ": tb_intr shutdown\n")); out64(M_SCD_TRACE_CFG_RESET, KSEG1 + A_SCD_TRACE_CFG); - sbp->tb_armed = 0; - wake_up(&sbp->tb_sync); + sbp.tb_armed = 0; + wake_up(&sbp.tb_sync); } else { arm_tb(); // knock down current interrupt and get another one later } @@ -112,36 +119,51 @@ /* No more trace buffer samples */ DBG(printk(DEVNAME ": tb_intr full\n")); out64(M_SCD_TRACE_CFG_RESET, KSEG1 + A_SCD_TRACE_CFG); - sbp->tb_armed = 0; - if (!sbp->tb_enable) { - wake_up(&sbp->tb_sync); + sbp.tb_armed = 0; + if (!sbp.tb_enable) { + wake_up(&sbp.tb_sync); } + wake_up(&sbp.tb_read); } } static void sbprof_pc_intr(int irq, void *dev_id, struct pt_regs *regs) { - panic(DEVNAME ": pc_intr"); + printk(DEVNAME ": unexpected pc_intr"); } static int sbprof_zbprof_start(struct file *filp) { - if (sbp->tb_enable) + u_int64_t scdperfcnt; + + if (sbp.tb_enable) return -EBUSY; DBG(printk(DEVNAME ": starting\n")); - sbp->tb_enable = 1; - sbp->next_tb_sample = 0; + sbp.tb_enable = 1; + sbp.next_tb_sample = 0; filp->f_pos = 0; if (request_irq - (K_INT_TRACE_FREEZE, sbprof_tb_intr, 0, "sbprof_tb trace freeze", sbp)) { + (K_INT_TRACE_FREEZE, sbprof_tb_intr, 0, DEVNAME " trace freeze", &sbp)) { return -EBUSY; } + /* Make sure there isn't a perf-cnt interrupt waiting */ + scdperfcnt = in64(KSEG1 + A_SCD_PERF_CNT_CFG); + /* Disable and clear counters, override SRC_1 */ + out64((scdperfcnt & ~(M_SPC_CFG_SRC1 | M_SPC_CFG_ENABLE)) | + M_SPC_CFG_ENABLE | + M_SPC_CFG_CLEAR | + V_SPC_CFG_SRC1(1), + KSEG1 + A_SCD_PERF_CNT_CFG); + + /* We grab this interrupt to prevent others from trying to use + it, even though we don't want to service the interrupts + (they only feed into the trace-on-interrupt mechanism) */ if (request_irq - (K_INT_PERF_CNT, sbprof_pc_intr, 0, "sbprof_tb scd perfcnt", sbp)) { - free_irq(K_INT_TRACE_FREEZE, sbp); + (K_INT_PERF_CNT, sbprof_pc_intr, 0, DEVNAME " scd perfcnt", &sbp)) { + free_irq(K_INT_TRACE_FREEZE, &sbp); return -EBUSY; } @@ -206,18 +228,18 @@ { DBG(printk(DEVNAME ": stopping\n")); - if (sbp->tb_enable) { - sbp->tb_enable = 0; + if (sbp.tb_enable) { + sbp.tb_enable = 0; /* XXXKW there is a window here where the intr handler may run, see the disable, and do the wake_up before this sleep happens. */ - if (sbp->tb_armed) { + if (sbp.tb_armed) { DBG(printk(DEVNAME ": wait for disarm\n")); - interruptible_sleep_on(&sbp->tb_sync); + interruptible_sleep_on(&sbp.tb_sync); DBG(printk(DEVNAME ": disarm complete\n")); } - free_irq(K_INT_TRACE_FREEZE, sbp); - free_irq(K_INT_PERF_CNT, sbp); + free_irq(K_INT_TRACE_FREEZE, &sbp); + free_irq(K_INT_PERF_CNT, &sbp); } DBG(printk(DEVNAME ": done stopping\n")); @@ -233,24 +255,19 @@ if (minor != 0) { return -ENODEV; } - if (sbp != NULL) { + if (sbp.open) { return -EBUSY; } - /* XXXKW spinlock? */ - sbp = kmalloc(sizeof(struct sbprof_tb), GFP_KERNEL); - if (!sbp) { - return -ENOMEM; - } - memset(sbp, 0, sizeof(struct sbprof_tb)); - sbp->sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES); - if (!sbp->sbprof_tbbuf) { - kfree(sbp); - sbp = NULL; + memset(&sbp, 0, sizeof(struct sbprof_tb)); + sbp.sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES); + if (!sbp.sbprof_tbbuf) { return -ENOMEM; } - memset(sbp->sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES); - init_waitqueue_head(&sbp->tb_sync); + memset(sbp.sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES); + init_waitqueue_head(&sbp.tb_sync); + init_waitqueue_head(&sbp.tb_read); + sbp.open = 1; return 0; } @@ -260,23 +277,22 @@ int minor; minor = MINOR(inode->i_rdev); - if (minor != 0 || sbp == NULL) { + if (minor != 0 || !sbp.open) { return -ENODEV; } - if (sbp->tb_armed || sbp->tb_enable) { + if (sbp.tb_armed || sbp.tb_enable) { sbprof_zbprof_stop(); } - vfree(sbp->sbprof_tbbuf); - kfree(sbp); - sbp = NULL; + vfree(sbp.sbprof_tbbuf); + sbp.open = 0; return 0; } static ssize_t sbprof_tb_read(struct file *filp, char *buf, - size_t size, loff_t *offp) + size_t size, loff_t *offp) { int cur_sample, sample_off, cur_count, sample_left; char *src; @@ -288,9 +304,9 @@ cur_sample = cur_off / TB_SAMPLE_SIZE; sample_off = cur_off % TB_SAMPLE_SIZE; sample_left = TB_SAMPLE_SIZE - sample_off; - while (size && (cur_sample < sbp->next_tb_sample)) { + while (size && (cur_sample < sbp.next_tb_sample)) { cur_count = size < sample_left ? size : sample_left; - src = (char *)(((long)sbp->sbprof_tbbuf[cur_sample])+sample_off); + src = (char *)(((long)sbp.sbprof_tbbuf[cur_sample])+sample_off); copy_to_user(dest, src, cur_count); DBG(printk(DEVNAME ": read from sample %d, %d bytes\n", cur_sample, cur_count)); size -= cur_count; @@ -311,17 +327,12 @@ return count; } -#define SBPROF_ZBSTART _IOW('s', 0, int) -#define SBPROF_ZBSTOP _IOW('s', 1, int) -#define SBPROF_ZBFULL _IOW('s', 2, int) - static int sbprof_tb_ioctl(struct inode *inode, - struct file *filp, - unsigned int command, - unsigned long arg) + struct file *filp, + unsigned int command, + unsigned long arg) { int error = 0; - int full; switch (command) { case SBPROF_ZBSTART: @@ -330,9 +341,10 @@ case SBPROF_ZBSTOP: error = sbprof_zbprof_stop(); break; - case SBPROF_ZBFULL: - full = (sbp->next_tb_sample == MAX_TB_SAMPLES); - return put_user(full, (int *) arg); + case SBPROF_ZBWAITFULL: + interruptible_sleep_on(&sbp.tb_read); + /* XXXKW check if interrupted? */ + return put_user(TB_FULL, (int *) arg); default: error = -EINVAL; break; @@ -342,12 +354,12 @@ } static struct file_operations sbprof_tb_fops = { - owner: THIS_MODULE, - open: sbprof_tb_open, - release: sbprof_tb_release, - read: sbprof_tb_read, - ioctl: sbprof_tb_ioctl, - mmap: NULL, + .owner = THIS_MODULE, + .open = sbprof_tb_open, + .release = sbprof_tb_release, + .read = sbprof_tb_read, + .ioctl = sbprof_tb_ioctl, + .mmap = NULL, }; static devfs_handle_t devfs_handle; @@ -363,8 +375,9 @@ DEVFS_FL_DEFAULT, SBPROF_TB_MAJOR, 0, S_IFCHR | S_IRUGO | S_IWUGO, &sbprof_tb_fops, NULL); - sbp = NULL; - printk(KERN_INFO DEVNAME ": initialized\n"); + sbp.open = 0; + tb_period = zbbus_mhz * 10000LL; + printk(KERN_INFO DEVNAME ": initialized - tb_period = %lld\n", tb_period); return 0; } diff -urN linux-2.4.21-bk37/arch/mips/sibyte/sb1250/bcm1250_tbprof.h linux-2.4.21-bk38/arch/mips/sibyte/sb1250/bcm1250_tbprof.h --- linux-2.4.21-bk37/arch/mips/sibyte/sb1250/bcm1250_tbprof.h 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/sb1250/bcm1250_tbprof.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2001 Broadcom Corporation - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef BCM1250_TBPROF_H - -#if SBPROF_TB_DEBUG -#define DBG(a) a -#else -#define DBG(a) -#endif - -#define SBPROF_TB_MAJOR 240 - -typedef u_int64_t tb_sample_t[6*256]; - -struct sbprof_tb { - tb_sample_t *sbprof_tbbuf; - int next_tb_sample; - - volatile int tb_enable; - volatile int tb_armed; - - wait_queue_head_t tb_sync; -}; - -#define MAX_SAMPLE_BYTES (24*1024*1024) -#define MAX_TBSAMPLE_BYTES (12*1024*1024) - -#define MAX_SAMPLES (MAX_SAMPLE_BYTES/sizeof(u_int32_t)) -#define TB_SAMPLE_SIZE (sizeof(tb_sample_t)) -#define MAX_TB_SAMPLES (MAX_TBSAMPLE_BYTES/TB_SAMPLE_SIZE) - -/*************************************************************************** - * Routines for gathering ZBbus profiles using trace buffer - ***************************************************************************/ - -/* Requires: Already called zclk_timer_init with a value that won't - saturate 40 bits. No subsequent use of SCD performance counters - or trace buffer. - Effect: Starts gathering random ZBbus profiles using trace buffer. */ -static int sbprof_zbprof_start(struct file *filp); - -/* Effect: Stops collection of ZBbus profiles */ -static int sbprof_zbprof_stop(void); - - -/*************************************************************************** - * Routines for using 40-bit SCD cycle counter - * - * Client responsible for either handling interrupts or making sure - * the cycles counter never saturates, e.g., by doing - * zclk_timer_init(0) at least every 2^40 - 1 ZCLKs. - ***************************************************************************/ - -/* Configures SCD counter 0 to count ZCLKs starting from val; - Configures SCD counters1,2,3 to count nothing. - Must not be called while gathering ZBbus profiles. - -unsigned long long val; */ -#define zclk_timer_init(val) \ - __asm__ __volatile__ (".set push;" \ - ".set mips64;" \ - "la $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \ - "sd %0, 0x10($8);" /* write val to counter0 */ \ - "sd %1, 0($8);" /* config counter0 for zclks*/ \ - ".set pop" \ - : /* no outputs */ \ - /* enable, counter0 */ \ - : /* inputs */ "r"(val), "r" ((1ULL << 33) | 1ULL) \ - : /* modifies */ "$8" ) - - -/* Reads SCD counter 0 and puts result in value - unsigned long long val; */ -#define zclk_get(val) \ - __asm__ __volatile__ (".set push;" \ - ".set mips64;" \ - "la $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \ - "ld %0, 0x10($8);" /* write val to counter0 */ \ - ".set pop" \ - : /* outputs */ "=r"(val) \ - : /* inputs */ \ - : /* modifies */ "$8" ) - -#endif diff -urN linux-2.4.21-bk37/arch/mips/sibyte/sb1250/bus_watcher.c linux-2.4.21-bk38/arch/mips/sibyte/sb1250/bus_watcher.c --- linux-2.4.21-bk37/arch/mips/sibyte/sb1250/bus_watcher.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/sb1250/bus_watcher.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2002,2003 Broadcom Corporation + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * The Bus Watcher monitors internal bus transactions and maintains + * counts of transactions with error status, logging details and + * causing one of several interrupts. This driver provides a handler + * for those interrupts which aggregates the counts (to avoid + * saturating the 8-bit counters) and provides a presence in + * /proc/bus_watcher if PROC_FS is on. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +struct bw_stats_struct { + uint64_t status; + uint32_t l2_err; + uint32_t memio_err; + int status_printed; + unsigned long l2_cor_d; + unsigned long l2_bad_d; + unsigned long l2_cor_t; + unsigned long l2_bad_t; + unsigned long mem_cor_d; + unsigned long mem_bad_d; + unsigned long bus_error; +} bw_stats; + + +static void print_summary(uint32_t status, uint32_t l2_err, + uint32_t memio_err) +{ + printk("Bus watcher error counters: %08x %08x\n", l2_err, memio_err); + printk("\nLast recorded signature:\n"); + printk("Request %02x from %d, answered by %d with Dcode %d\n", + (unsigned int)(G_SCD_BERR_TID(status) & 0x3f), + (int)(G_SCD_BERR_TID(status) >> 6), + (int)G_SCD_BERR_RID(status), + (int)G_SCD_BERR_DCODE(status)); +} + +/* + * check_bus_watcher is exported for use in situations where we want + * to see the most recent status of the bus watcher, which might have + * already been destructively read out of the registers. + * + * notes: this is currently used by the cache error handler + * should provide locking against the interrupt handler + */ +void check_bus_watcher(void) +{ + u32 status, l2_err, memio_err; + +#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS + /* Destructive read, clears register and interrupt */ + status = csr_in32(IO_SPACE_BASE | A_SCD_BUS_ERR_STATUS); +#else + /* Use non-destructive register */ + status = csr_in32(IO_SPACE_BASE | A_SCD_BUS_ERR_STATUS_DEBUG); +#endif + if (!(status & 0x7fffffff)) { + printk("Using last values reaped by bus watcher driver\n"); + status = bw_stats.status; + l2_err = bw_stats.l2_err; + memio_err = bw_stats.memio_err; + } else { + l2_err = csr_in32(IO_SPACE_BASE | A_BUS_L2_ERRORS); + memio_err = csr_in32(IO_SPACE_BASE | A_BUS_MEM_IO_ERRORS); + } + if (status & ~(1UL << 31)) + print_summary(status, l2_err, memio_err); + else + printk("Bus watcher indicates no error\n"); +} + +static int bw_print_buffer(char *page, struct bw_stats_struct *stats) +{ + int len; + + len = sprintf(page, "SiByte Bus Watcher statistics\n"); + len += sprintf(page+len, "-----------------------------\n"); + len += sprintf(page+len, "L2-d-cor %8ld\nL2-d-bad %8ld\n", + stats->l2_cor_d, stats->l2_bad_d); + len += sprintf(page+len, "L2-t-cor %8ld\nL2-t-bad %8ld\n", + stats->l2_cor_t, stats->l2_bad_t); + len += sprintf(page+len, "MC-d-cor %8ld\nMC-d-bad %8ld\n", + stats->mem_cor_d, stats->mem_bad_d); + len += sprintf(page+len, "IO-err %8ld\n", stats->bus_error); + len += sprintf(page+len, "\nLast recorded signature:\n"); + len += sprintf(page+len, "Request %02x from %d, answered by %d with Dcode %d\n", + (unsigned int)(G_SCD_BERR_TID(stats->status) & 0x3f), + (int)(G_SCD_BERR_TID(stats->status) >> 6), + (int)G_SCD_BERR_RID(stats->status), + (int)G_SCD_BERR_DCODE(stats->status)); + /* XXXKW indicate multiple errors between printings, or stats + collection (or both)? */ + if (stats->status & M_SCD_BERR_MULTERRS) + len += sprintf(page+len, "Multiple errors observed since last check.\n"); + if (stats->status_printed) { + len += sprintf(page+len, "(no change since last printing)\n"); + } else { + stats->status_printed = 1; + } + + return len; +} + +#ifdef CONFIG_PROC_FS + +/* For simplicity, I want to assume a single read is required each + time */ +static int bw_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len; + + if (off == 0) { + len = bw_print_buffer(page, data); + *start = page; + } else { + len = 0; + *eof = 1; + } + return len; +} + +static void create_proc_decoder(struct bw_stats_struct *stats) +{ + struct proc_dir_entry *ent; + + ent = create_proc_read_entry("bus_watcher", S_IWUSR | S_IRUGO, NULL, + bw_read_proc, stats); + if (!ent) { + printk(KERN_INFO "Unable to initialize bus_watcher /proc entry\n"); + return; + } +} + +#endif /* CONFIG_PROC_FS */ + +/* + * sibyte_bw_int - handle bus watcher interrupts and accumulate counts + * + * notes: possible re-entry due to multiple sources + * should check/indicate saturation + */ +static void sibyte_bw_int(int irq, void *data, struct pt_regs *regs) +{ + struct bw_stats_struct *stats = data; + unsigned long cntr; +#ifndef CONFIG_PROC_FS + char bw_buf[1024]; +#endif + + /* Destructive read, clears register and interrupt */ + stats->status = csr_in32(IO_SPACE_BASE | A_SCD_BUS_ERR_STATUS); + stats->status_printed = 0; + + stats->l2_err = cntr = csr_in32(IO_SPACE_BASE | A_BUS_L2_ERRORS); + stats->l2_cor_d += G_SCD_L2ECC_CORR_D(cntr); + stats->l2_bad_d += G_SCD_L2ECC_BAD_D(cntr); + stats->l2_cor_t += G_SCD_L2ECC_CORR_T(cntr); + stats->l2_bad_t += G_SCD_L2ECC_BAD_T(cntr); + csr_out32(0, IO_SPACE_BASE | A_BUS_L2_ERRORS); + + stats->memio_err = cntr = csr_in32(IO_SPACE_BASE | A_BUS_MEM_IO_ERRORS); + stats->mem_cor_d += G_SCD_MEM_ECC_CORR(cntr); + stats->mem_bad_d += G_SCD_MEM_ECC_BAD(cntr); + stats->bus_error += G_SCD_MEM_BUSERR(cntr); + csr_out32(0, IO_SPACE_BASE | A_BUS_MEM_IO_ERRORS); + +#ifndef CONFIG_PROC_FS + bw_print_buffer(bw_buf, stats); + printk(bw_buf); +#endif +} + +int __init sibyte_bus_watcher(void) +{ + memset(&bw_stats, 0, sizeof(struct bw_stats_struct)); + bw_stats.status_printed = 1; + + if (request_irq(K_INT_BAD_ECC, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) { + printk("Failed to register bus watcher BAD_ECC irq\n"); + return -1; + } + if (request_irq(K_INT_COR_ECC, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) { + free_irq(K_INT_BAD_ECC, &bw_stats); + printk("Failed to register bus watcher COR_ECC irq\n"); + return -1; + } + if (request_irq(K_INT_IO_BUS, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) { + free_irq(K_INT_BAD_ECC, &bw_stats); + free_irq(K_INT_COR_ECC, &bw_stats); + printk("Failed to register bus watcher IO_BUS irq\n"); + return -1; + } + +#ifdef CONFIG_PROC_FS + create_proc_decoder(&bw_stats); +#endif + + return 0; +} + +__initcall(sibyte_bus_watcher); diff -urN linux-2.4.21-bk37/arch/mips/sibyte/sb1250/ide.c linux-2.4.21-bk38/arch/mips/sibyte/sb1250/ide.c --- linux-2.4.21-bk37/arch/mips/sibyte/sb1250/ide.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/sb1250/ide.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2001, 2002, 2003 Broadcom Corporation + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* Derived loosely from ide-pmac.c, so: + * + * Copyright (C) 1998 Paul Mackerras. + * Copyright (C) 1995-1998 Mark Lord + */ +#include +#include + +#include + +extern struct ide_ops std_ide_ops; + +#ifdef CONFIG_PCMCIA_SIBYTE +extern ide_ack_intr_t sb_pcmcia_ack_intr; +#define SIBYTE_CS_REG(pcaddr) (IO_SPACE_BASE + PCMCIA_PHYS - mips_io_port_base + pcaddr) +#define SB_PC_PORT 0xff00 +#endif + +/* + * We are limiting the number of PCI-IDE devices to leave room for + * GenBus IDE (and possibly PCMCIA/CF?) + */ +static int sibyte_ide_default_irq(ide_ioreg_t base) +{ + return 0; +} + +static ide_ioreg_t sibyte_ide_default_io_base(int index) +{ + return 0; +} + +static void sibyte_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq) +{ +#ifdef CONFIG_PCMCIA_SIBYTE + if (data_port == SB_PC_PORT) { + data_port = SIBYTE_CS_REG(0); + ctrl_port = SIBYTE_CS_REG(6); + hw->ack_intr = sb_pcmcia_ack_intr; + } +#endif + std_ide_ops.ide_init_hwif_ports(hw, data_port, ctrl_port, irq); +} + +struct ide_ops sibyte_ide_ops = { + &sibyte_ide_default_irq, + &sibyte_ide_default_io_base, + &sibyte_ide_init_hwif_ports +}; + +/* + * I/O operations. The FPGA for SiByte generic bus IDE deals with + * byte-swapping for us, so we can't share the I/O macros with other + * IDE (e.g. PCI-IDE) devices. + */ + +static inline void sibyte_outb(u8 val, unsigned long port) { + *(volatile u8 *)(mips_io_port_base + (port)) = val; +} + +static inline void sibyte_outw(u16 val, unsigned long port) { + *(volatile u16 *)(mips_io_port_base + (port)) = val; +} + +static inline void sibyte_outl(u32 val, unsigned long port) { + *(volatile u32 *)(mips_io_port_base + (port)) = val; +} + +static inline unsigned char sibyte_inb(unsigned long port) +{ + return (*(volatile u8 *)(mips_io_port_base + (port))); +} + +static inline unsigned short sibyte_inw(unsigned long port) +{ + return (*(volatile u16 *)(mips_io_port_base + (port))); +} + +static inline unsigned int sibyte_inl(unsigned long port) +{ + return (*(volatile u32 *)(mips_io_port_base + (port))); +} + + +static inline void sibyte_outsb(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + sibyte_outb(*(u8 *)addr, port); + addr++; + } +} + +static inline void sibyte_insb(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + *(u8 *)addr = sibyte_inb(port); + addr++; + } +} + +static inline void sibyte_outsw(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + sibyte_outw(*(u16 *)addr, port); + addr += 2; + } +} + +static inline void sibyte_insw(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + *(u16 *)addr = sibyte_inw(port); + addr += 2; + } +} + +static inline void sibyte_outsl(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + sibyte_outl(*(u32 *)addr, port); + addr += 4; + } +} + +static inline void sibyte_insl(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + *(u32 *)addr = sibyte_inl(port); + addr += 4; + } +} + +void sibyte_set_ideops(ide_hwif_t *hwif) +{ + hwif->INB = sibyte_inb; + hwif->INW = sibyte_inw; + hwif->INL = sibyte_inl; + hwif->OUTB = sibyte_outb; + hwif->OUTW = sibyte_outw; + hwif->OUTL = sibyte_outl; + hwif->INSW = sibyte_insw; + hwif->INSL = sibyte_insl; + hwif->OUTSW = sibyte_outsw; + hwif->OUTSL = sibyte_outsl; +} diff -urN linux-2.4.21-bk37/arch/mips/sibyte/sb1250/irq.c linux-2.4.21-bk38/arch/mips/sibyte/sb1250/irq.c --- linux-2.4.21-bk37/arch/mips/sibyte/sb1250/irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/sb1250/irq.c 2003-08-24 02:55:58.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -50,21 +51,37 @@ static void disable_sb1250_irq(unsigned int irq); static unsigned int startup_sb1250_irq(unsigned int irq); static void ack_sb1250_irq(unsigned int irq); +#ifdef CONFIG_SMP +static void sb1250_set_affinity(unsigned int irq, unsigned long mask); +#endif + +#ifdef CONFIG_SIBYTE_HAS_LDT +extern unsigned long ldt_eoi_space; +#endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB +#include extern void breakpoint(void); -extern void set_debug_traps(void); +static int kgdb_irq; +#ifdef CONFIG_GDB_CONSOLE +extern void register_gdb_console(void); +#endif /* kgdb is on when configured. Pass "nokgdb" kernel arg to turn it off */ static int kgdb_flag = 1; static int __init nokgdb(char *str) { kgdb_flag = 0; + return 1; } __setup("nokgdb", nokgdb); -#endif -#define NR_IRQS 64 +/* Default to UART1 */ +int kgdb_port = 1; +#ifdef CONFIG_SIBYTE_SB1250_DUART +extern char sb1250_duart_present[]; +#endif +#endif static struct hw_interrupt_type sb1250_irq_type = { "SB1250-IMR", @@ -74,9 +91,16 @@ disable_sb1250_irq, ack_sb1250_irq, end_sb1250_irq, +#ifdef CONFIG_SMP + sb1250_set_affinity +#else NULL +#endif }; +/* Store the CPU id (not the logical number) */ +int sb1250_irq_owner[SB1250_NR_IRQS]; + spinlock_t sb1250_imr_lock = SPIN_LOCK_UNLOCKED; void sb1250_mask_irq(int cpu, int irq) @@ -85,9 +109,9 @@ u64 cur_ints; spin_lock_irqsave(&sb1250_imr_lock, flags); - cur_ints = in64(KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); + cur_ints = __in64(KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); cur_ints |= (((u64) 1) << irq); - out64(cur_ints, KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); + __out64(cur_ints, KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); spin_unlock_irqrestore(&sb1250_imr_lock, flags); } @@ -97,12 +121,61 @@ u64 cur_ints; spin_lock_irqsave(&sb1250_imr_lock, flags); - cur_ints = in64(KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); + cur_ints = __in64(KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); cur_ints &= ~(((u64) 1) << irq); - out64(cur_ints, KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); + __out64(cur_ints, KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); spin_unlock_irqrestore(&sb1250_imr_lock, flags); } +#ifdef CONFIG_SMP +static void sb1250_set_affinity(unsigned int irq, unsigned long mask) +{ + int i = 0, old_cpu, cpu, int_on; + u64 cur_ints; + irq_desc_t *desc = irq_desc + irq; + unsigned long flags; + + while (mask) { + if (mask & 1) { + mask >>= 1; + break; + } + mask >>= 1; + i++; + } + + if (mask) { + printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq); + return; + } + + /* Convert logical CPU to physical CPU */ + cpu = cpu_logical_map(i); + + /* Protect against other affinity changers and IMR manipulation */ + spin_lock_irqsave(&desc->lock, flags); + spin_lock(&sb1250_imr_lock); + + /* Swizzle each CPU's IMR (but leave the IP selection alone) */ + old_cpu = sb1250_irq_owner[irq]; + cur_ints = __in64(KSEG1 + A_IMR_MAPPER(old_cpu) + R_IMR_INTERRUPT_MASK); + int_on = !(cur_ints & (((u64) 1) << irq)); + if (int_on) { + /* If it was on, mask it */ + cur_ints |= (((u64) 1) << irq); + __out64(cur_ints, KSEG1 + A_IMR_MAPPER(old_cpu) + R_IMR_INTERRUPT_MASK); + } + sb1250_irq_owner[irq] = cpu; + if (int_on) { + /* unmask for the new CPU */ + cur_ints = __in64(KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); + cur_ints &= ~(((u64) 1) << irq); + __out64(cur_ints, KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); + } + spin_unlock(&sb1250_imr_lock); + spin_unlock_irqrestore(&desc->lock, flags); +} +#endif /* Defined in arch/mips/sibyte/sb1250/irq_handler.S */ @@ -112,7 +185,7 @@ static unsigned int startup_sb1250_irq(unsigned int irq) { - sb1250_unmask_irq(0, irq); + sb1250_unmask_irq(sb1250_irq_owner[irq], irq); return 0; /* never anything pending */ } @@ -120,36 +193,58 @@ static void disable_sb1250_irq(unsigned int irq) { - sb1250_mask_irq(0, irq); + sb1250_mask_irq(sb1250_irq_owner[irq], irq); } static void enable_sb1250_irq(unsigned int irq) { - sb1250_unmask_irq(0, irq); + sb1250_unmask_irq(sb1250_irq_owner[irq], irq); } static void ack_sb1250_irq(unsigned int irq) { +#ifdef CONFIG_SIBYTE_HAS_LDT u64 pending; /* - * If the interrupt was an LDT interrupt, now is the time - * to clear it. + * If the interrupt was an HT interrupt, now is the time to + * clear it. NOTE: we assume the HT bridge was set up to + * deliver the interrupts to all CPUs (which makes affinity + * changing easier for us) */ - pending = in64(KSEG1 + A_IMR_REGISTER(0,R_IMR_LDT_INTERRUPT)); + pending = in64(KSEG1 + A_IMR_REGISTER(sb1250_irq_owner[irq], + R_IMR_LDT_INTERRUPT)); pending &= ((u64)1 << (irq)); - if (pending) - out64(pending, KSEG1+A_IMR_REGISTER(0,R_IMR_LDT_INTERRUPT_CLR)); - - sb1250_mask_irq(0, irq); + if (pending) { + int i; + for (i=0; i= NR_IRQS) + if (irq >= SB1250_NR_IRQS) return -EINVAL; spin_lock_irqsave(&desc->lock,flags); @@ -198,6 +298,7 @@ desc->depth = 0; } spin_unlock_irqrestore(&desc->lock,flags); + return 0; } /* @@ -235,7 +336,7 @@ STATUSF_IP1 | STATUSF_IP0; /* Default everything to IP2 */ - for (i = 0; i < NR_IRQS; i++) { /* was I0 */ + for (i = 0; i < SB1250_NR_IRQS; i++) { /* was I0 */ out64(IMR_IP2_VAL, KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + @@ -273,44 +374,49 @@ /* * Note that the timer interrupts are also mapped, but this is - * done in sb1250_time_init() + * done in sb1250_time_init(). Also, the profiling driver + * does its own management of IP7. */ -#ifdef CONFIG_BCM1250_PROF - imask |= STATUSF_IP7; -#endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB imask |= STATUSF_IP6; #endif /* Enable necessary IPs, disable the rest */ - change_cp0_status(ST0_IM, imask); + change_c0_status(ST0_IM, imask); set_except_vector(0, sb1250_irq_handler); -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB if (kgdb_flag) { + kgdb_irq = K_INT_UART_0 + kgdb_port; + +#ifdef CONFIG_SIBYTE_SB1250_DUART + sb1250_duart_present[kgdb_port] = 0; +#endif /* Setup uart 1 settings, mapper */ - out64(M_DUART_IMR_BRK, KSEG1 + A_DUART + R_DUART_IMR_B); + out64(M_DUART_IMR_BRK, IO_SPACE_BASE + A_DUART_IMRREG(kgdb_port)); + sb1250_steal_irq(kgdb_irq); out64(IMR_IP6_VAL, - KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + (K_INT_UART_1<<3)); - tmp = in64(KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)); - tmp &= ~(1< -extern void set_async_breakpoint(unsigned int epc); - -#define duart_out(reg, val) out64(val, KSEG1 + A_DUART_CHANREG(1,reg)) -#define duart_in(reg) in64(KSEG1 + A_DUART_CHANREG(1,reg)) +#define duart_out(reg, val) csr_out32(val, KSEG1 + A_DUART_CHANREG(kgdb_port,reg)) +#define duart_in(reg) csr_in32(KSEG1 + A_DUART_CHANREG(kgdb_port,reg)) void sb1250_kgdb_interrupt(struct pt_regs *regs) { @@ -319,10 +425,11 @@ * host to stop the break, since we would see another * interrupt on the end-of-break too) */ + kstat.irqs[smp_processor_id()][kgdb_irq]++; mdelay(500); duart_out(R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT | M_DUART_RX_EN | M_DUART_TX_EN); - if (!user_mode(regs)) - set_async_breakpoint(regs->cp0_epc); + set_async_breakpoint(®s->cp0_epc); } -#endif /* CONFIG_REMOTE_DEBUG */ + +#endif /* CONFIG_KGDB */ diff -urN linux-2.4.21-bk37/arch/mips/sibyte/sb1250/irq_handler.S linux-2.4.21-bk38/arch/mips/sibyte/sb1250/irq_handler.S --- linux-2.4.21-bk37/arch/mips/sibyte/sb1250/irq_handler.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/sb1250/irq_handler.S 2003-08-24 02:55:58.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -77,15 +77,11 @@ mfc0 a0, CP0_EPC jal sbprof_cpu_intr addu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */ - /* Re-enable interrupts here so that events due to sbprof_cpu_intr - get charged to ret_from_irq (via a recursive interrupt) - rather than the restart pc. */ - mfc0 t0, CP0_STATUS - or t0, ST0_IE j ret_from_irq - mtc0 t0, CP0_STATUS # delay slot + nop 0: #endif + /* Timer interrupt is routed to IP[4] */ andi t1, s0, CAUSEF_IP4 beqz t1, 1f @@ -100,7 +96,7 @@ /* Mailbox interrupt is routed to IP[3] */ andi t1, s0, CAUSEF_IP3 beqz t1, 2f - nop + nop jal sb1250_mailbox_interrupt move a0, sp j ret_from_irq @@ -108,7 +104,7 @@ 2: #endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB /* KGDB (uart 1) interrupt is routed to IP[6] */ andi t1, s0, CAUSEF_IP6 beqz t1, 1f @@ -127,8 +123,14 @@ /* * Default...we've hit an IP[2] interrupt, which means we've got to * check the 1250 interrupt registers to figure out what to do + * Need to detect which CPU we're on, now that smp_affinity is supported. */ la v0, KSEG1 + A_IMR_CPU0_BASE +#ifdef CONFIG_SMP + lw t1, TASK_PROCESSOR($28) + sll t1, IMR_REGISTER_SPACING_SHIFT + addu v0, t1 +#endif ld s0, R_IMR_INTERRUPT_STATUS_BASE(v0) /* read IP[2] status */ beqz s0, 4f /* No interrupts. Return */ diff -urN linux-2.4.21-bk37/arch/mips/sibyte/sb1250/lib_hssubr.S linux-2.4.21-bk38/arch/mips/sibyte/sb1250/lib_hssubr.S --- linux-2.4.21-bk37/arch/mips/sibyte/sb1250/lib_hssubr.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/sb1250/lib_hssubr.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2000, 2001 Broadcom Corporation - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -#include -#include -#include -#include - - .set mips64 - -#define HAZARD SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP ; SSNOP - - -/* ********************************************************************* - * hs_read8 - read 8-bit bytes - ********************************************************************* */ - - -LEAF(hs_read8) - mfc0 t2, CP0_STATUS - or t1, t2, ST0_KX - mtc0 t1, CP0_STATUS - HAZARD - - dli v0, PHYS_TO_XKSEG_UNCACHED(0) - dsll a0, a0, 32 - dsrl a0, a0, 32 - or a0, a0,v0 - lb v0, (a0) - and v0, 0xFF - - mtc0 t2, CP0_STATUS - HAZARD - j ra -END(hs_read8) - -/* ********************************************************************* - * hs_read16 - read 16-bit shorts - ********************************************************************* */ - -LEAF(hs_read16) - mfc0 t2, CP0_STATUS - or t1, t2, ST0_KX - mtc0 t1, CP0_STATUS - HAZARD - - dli v0, PHYS_TO_XKSEG_UNCACHED(0) - dsll a0, a0, 32 - dsrl a0, a0, 32 - or a0, a0, v0 - lh v0, (a0) - and v0, 0xFFFF - - mtc0 t2, CP0_STATUS - HAZARD - j ra -END(hs_read16) - -/* ********************************************************************* - * hs_read32 - read 32-bit ints - ********************************************************************* */ - -LEAF(hs_read32) - mfc0 t2, CP0_STATUS - or t1, t2, ST0_KX - mtc0 t1, CP0_STATUS - HAZARD - - dli v0, PHYS_TO_XKSEG_UNCACHED(0) - dsll a0, a0, 32 - dsrl a0, a0, 32 - or a0, a0, v0 - lw v0, (a0) - and v0, 0xFFFFFFFF - - mtc0 t2, CP0_STATUS - HAZARD - j ra -END(hs_read32) - -/* ********************************************************************* - * hs_read64 - read 64-bit longs - ********************************************************************* */ - -LEAF(hs_read64) - mfc0 t2, CP0_STATUS - or t1, t2, ST0_KX - mtc0 t1, CP0_STATUS - HAZARD - - dli v0, PHYS_TO_XKSEG_UNCACHED(0) - dsll a0, a0, 32 - dsrl a0, a0, 32 - or a0, a0, v0 - ld v0, (a0) - - mtc0 t2, CP0_STATUS - HAZARD - j ra -END(hs_read64) - -/* ********************************************************************* - * hs_write8 - write 8-bit bytes - ********************************************************************* */ - -LEAF(hs_write8) - mfc0 t2, CP0_STATUS - or t1, t2, ST0_KX - mtc0 t1, CP0_STATUS - HAZARD - - dli v0, PHYS_TO_XKSEG_UNCACHED(0) - dsll a0, a0, 32 - dsrl a0, a0, 32 - or a0, a0, v0 - sb a1, (a0) - - mtc0 t2, CP0_STATUS - HAZARD - j ra -END(hs_write8) - -/* ********************************************************************* - * hs_write16 - write 16-bit shorts - ********************************************************************* */ - -LEAF(hs_write16) - mfc0 t2, CP0_STATUS - or t1, t2, ST0_KX - mtc0 t1, CP0_STATUS - HAZARD - - dli v0, PHYS_TO_XKSEG_UNCACHED(0) - dsll a0, a0, 32 - dsrl a0, a0, 32 - or a0, a0, v0 - sh a1, (a0) - - mtc0 t2, CP0_STATUS - HAZARD - j ra -END(hs_write16) - -/* ********************************************************************* - * hs_write32 - write 32-bit longs - ********************************************************************* */ - -LEAF(hs_write32) - mfc0 t2, CP0_STATUS - or t1, t2, ST0_KX - mtc0 t1, CP0_STATUS - HAZARD - - dli v0, PHYS_TO_XKSEG_UNCACHED(0) - dsll a0, a0, 32 - dsrl a0, a0, 32 - or a0, a0, v0 - sw a1, (a0) - - mtc0 t2, CP0_STATUS - HAZARD - j ra -END(hs_write32) - -/* ********************************************************************* - * hs_write64 - write 64-bit longs - ********************************************************************* */ - -LEAF(hs_write64) - mfc0 t2, CP0_STATUS - or t1, t2, ST0_KX - mtc0 t1, CP0_STATUS - HAZARD - - dli v0, PHYS_TO_XKSEG_UNCACHED(0) - dsll a0, a0, 32 - dsrl a0, a0, 32 - or a0, a0, v0 - sd a1, (a0) - - mtc0 t2, CP0_STATUS - HAZARD - j ra -END(hs_write64) diff -urN linux-2.4.21-bk37/arch/mips/sibyte/sb1250/lib_hssubr.h linux-2.4.21-bk38/arch/mips/sibyte/sb1250/lib_hssubr.h --- linux-2.4.21-bk37/arch/mips/sibyte/sb1250/lib_hssubr.h 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/sb1250/lib_hssubr.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2000, 2001 Broadcom Corporation - * Copyright (C) 2002 Ralf Baechle - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -#ifndef _LIB_HSSUBR_H -#define _LIB_HSSUBR_H - -#include -#include - -typedef long hsaddr_t; - -#ifdef CONFIG_MIPS64 - -static inline void hs_write8(hsaddr_t a, uint8_t b) -{ - *(volatile uint8_t *) a = PHYS_TO_XKSEG_UNCACHED(b); -} - -static inline void hs_write16(hsaddr_t a, uint16_t b) -{ - *(volatile uint16_t *) a = PHYS_TO_XKSEG_UNCACHED(b); -} - -static inline void hs_write32(hsaddr_t a, uint32_t b) -{ - *(volatile uint32_t *) a = PHYS_TO_XKSEG_UNCACHED(b); -} - -static inline void hs_write64(hsaddr_t a, uint64_t b) -{ - *(volatile uint32_t *) a = PHYS_TO_XKSEG_UNCACHED(b); -} - -static inline uint8_t hs_read8(hsaddr_t a) -{ - return *(volatile uint8_t *) a; -} - -static inline uint16_t hs_read16(hsaddr_t a) -{ - return *(volatile uint16_t *) a; -} - -static inline uint32_t hs_read32(hsaddr_t a) -{ - return *(volatile uint32_t *) a; -} - -static inline uint64_t hs_read64(hsaddr_t a) -{ - return *(volatile uint64_t *) a; -} - -#else /* just CONFIG_MIPS32 */ - -extern void hs_write8(hsaddr_t a, uint8_t b); -extern void hs_write16(hsaddr_t a, uint16_t b); -extern void hs_write32(hsaddr_t a, uint32_t b); -extern void hs_write64(hsaddr_t a, uint64_t b); -extern uint8_t hs_read8(hsaddr_t a); -extern uint16_t hs_read16(hsaddr_t a); -extern uint32_t hs_read32(hsaddr_t a); -extern uint64_t hs_read64(hsaddr_t a); -#endif - -#endif /* _LIB_HSSUBR_H */ diff -urN linux-2.4.21-bk37/arch/mips/sibyte/sb1250/pci.c linux-2.4.21-bk38/arch/mips/sibyte/sb1250/pci.c --- linux-2.4.21-bk37/arch/mips/sibyte/sb1250/pci.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/sb1250/pci.c 2003-08-24 02:55:58.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001 Broadcom Corporation + * Copyright (C) 2001,2002 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -24,17 +24,10 @@ * configuration space, and set up the translation for I/O * space accesses. * - * To access configuration space, we call some assembly-level - * stubs that flip the KX bit on and off in the status - * register, and do XKSEG addressed memory accesses there. - * It's slow (7 SSNOPs to guarantee that KX is set!) but - * fortunately, config space accesses are rare. - * - * We could use the ioremap functionality for the confguration - * space as well as I/O space, but I'm not sure of the - * implications of setting aside 16MB of KSEG2 for something - * that is used so rarely (how much space in the page tables?) - * + * To access configuration space, we use ioremap. In the 32-bit + * kernel, this consumes either 4 or 8 page table pages, and 16MB of + * kernel mapped memory. Hopefully neither of these should be a huge + * problem. */ #include #include @@ -48,56 +41,74 @@ #include #include -#include "lib_hssubr.h" - /* - * This macro calculates the offset into config space where - * a given bus, device/function, and offset live on the sb1250 + * Macros for calculating offsets into config space given a device + * structure or dev/fun/reg */ - #define CFGOFFSET(bus,devfn,where) (((bus)<<16)+((devfn)<<8)+(where)) +#define CFGADDR(dev,where) CFGOFFSET((dev)->bus->number,(dev)->devfn,where) + +static void *cfg_space; + +#define PCI_BUS_ENABLED 1 +#define LDT_BUS_ENABLED 2 +#define PCI_DEVICE_MODE 4 +static int sb1250_bus_status = 0; + +#define PCI_BRIDGE_DEVICE 0 +#define LDT_BRIDGE_DEVICE 1 + +#ifdef CONFIG_SIBYTE_HAS_LDT /* - * Using the above offset, this macro calcuates the physical address in the - * config space. + * HT's level-sensitive interrupts require EOI, which is generated + * through a 4MB memory-mapped region */ -#define CFGADDR(dev,where) (A_PHYS_LDTPCI_CFG_MATCH_BITS + \ - CFGOFFSET(dev->bus->number,dev->devfn,where)) +unsigned long ldt_eoi_space; +#endif /* * Read/write 32-bit values in config space. */ static inline u32 READCFG32(u32 addr) { - hs_read32(addr & ~3); + return *(u32 *)(cfg_space + (addr&~3)); } static inline void WRITECFG32(u32 addr, u32 data) { - return hs_write32(addr & ~3,(data)); + *(u32 *)(cfg_space + (addr & ~3)) = data; } /* - * This variable is the KSEG2 (kernel virtual) mapping of the ISA/PCI I/O - * space area. We map 64K here and the offsets from this address get treated - * with "match bytes" policy to make everything look little-endian. So, you - * need to also set CONFIG_SWAP_IO_SPACE, but this is the combination that - * works correctly with most of Linux's drivers. + * Some checks before doing config cycles: + * In PCI Device Mode, hide everything on bus 0 except the LDT host + * bridge. Otherwise, access is controlled by bridge MasterEn bits. */ +static int +sb1250_pci_can_access(struct pci_dev *dev) +{ + u32 devno; -#define PCI_BUS_ENABLED 1 -#define LDT_BUS_ENABLED 2 - -static int sb1250_bus_status = 0; - -#define MATCH_BITS 0x20000000 /* really belongs in an include file */ + if (!(sb1250_bus_status & (PCI_BUS_ENABLED | PCI_DEVICE_MODE))) + return 0; -#define LDT_BRIDGE_START ((A_PCI_TYPE01_HEADER|MATCH_BITS)+0x00) -#define LDT_BRIDGE_END ((A_PCI_TYPE01_HEADER|MATCH_BITS)+0x20) + if (dev->bus->number == 0) { + devno = PCI_SLOT(dev->devfn); + if (devno == LDT_BRIDGE_DEVICE) + return (sb1250_bus_status & LDT_BUS_ENABLED) != 0; + else if (sb1250_bus_status & PCI_DEVICE_MODE) + return 0; + else + return 1; + } else + return 1; +} /* * Read/write access functions for various sizes of values - * in config space. + * in config space. Return all 1's for disallowed accesses + * for a kludgy but adequate simulation of master aborts. */ static int @@ -106,23 +117,16 @@ u32 data = 0; u32 cfgaddr = CFGADDR(dev, where); - data = READCFG32(cfgaddr); - - /* - * If the LDT was not configured, make it look like the bridge - * header is not there. - */ - if (!(sb1250_bus_status & LDT_BUS_ENABLED) && - (cfgaddr >= LDT_BRIDGE_START) && (cfgaddr < LDT_BRIDGE_END)) { + if (sb1250_pci_can_access(dev)) + data = READCFG32(cfgaddr); + else data = 0xFFFFFFFF; - } *val = (data >> ((where & 3) << 3)) & 0xff; return PCIBIOS_SUCCESSFUL; } - static int sb1250_pci_read_config_word(struct pci_dev *dev, int where, u16 * val) { @@ -132,16 +136,10 @@ if (where & 1) return PCIBIOS_BAD_REGISTER_NUMBER; - data = READCFG32(cfgaddr); - - /* - * If the LDT was not configured, make it look like the bridge - * header is not there. - */ - if (!(sb1250_bus_status & LDT_BUS_ENABLED) && - (cfgaddr >= LDT_BRIDGE_START) && (cfgaddr < LDT_BRIDGE_END)) { + if (sb1250_pci_can_access(dev)) + data = READCFG32(cfgaddr); + else data = 0xFFFFFFFF; - } *val = (data >> ((where & 3) << 3)) & 0xffff; @@ -157,16 +155,10 @@ if (where & 3) return PCIBIOS_BAD_REGISTER_NUMBER; - data = READCFG32(cfgaddr); - - /* - * If the LDT was not configured, make it look like the bridge - * header is not there. - */ - if (!(sb1250_bus_status & LDT_BUS_ENABLED) && - (cfgaddr >= LDT_BRIDGE_START) && (cfgaddr < LDT_BRIDGE_END)) { + if (sb1250_pci_can_access(dev)) + data = READCFG32(cfgaddr); + else data = 0xFFFFFFFF; - } *val = data; @@ -180,12 +172,14 @@ u32 data = 0; u32 cfgaddr = CFGADDR(dev, where); - data = READCFG32(cfgaddr); + if (sb1250_pci_can_access(dev)) { + data = READCFG32(cfgaddr); - data = (data & ~(0xff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); - WRITECFG32(cfgaddr, data); + WRITECFG32(cfgaddr, data); + } return PCIBIOS_SUCCESSFUL; } @@ -199,12 +193,14 @@ if (where & 1) return PCIBIOS_BAD_REGISTER_NUMBER; - data = READCFG32(cfgaddr); + if (sb1250_pci_can_access(dev)) { + data = READCFG32(cfgaddr); - data = (data & ~(0xffff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); - WRITECFG32(cfgaddr, data); + WRITECFG32(cfgaddr, data); + } return PCIBIOS_SUCCESSFUL; } @@ -217,7 +213,8 @@ if (where & 3) return PCIBIOS_BAD_REGISTER_NUMBER; - WRITECFG32(cfgaddr, val); + if (sb1250_pci_can_access(dev)) + WRITECFG32(cfgaddr, val); return PCIBIOS_SUCCESSFUL; } @@ -237,48 +234,60 @@ uint32_t cmdreg; uint64_t reg; + cfg_space = ioremap(A_PHYS_LDTPCI_CFG_MATCH_BITS, 16*1024*1024); + /* * See if the PCI bus has been configured by the firmware. */ - - cmdreg = READCFG32((A_PCI_TYPE00_HEADER | MATCH_BITS) + - PCI_COMMAND); - - if (!(cmdreg & PCI_COMMAND_MASTER)) { - printk - ("PCI: Skipping PCI probe. Bus is not initialized.\n"); - return; - } - reg = *((volatile uint64_t *) KSEG1ADDR(A_SCD_SYSTEM_CFG)); if (!(reg & M_SYS_PCI_HOST)) { - printk("PCI: Skipping PCI probe. Processor is in PCI device mode.\n"); - return; + sb1250_bus_status |= PCI_DEVICE_MODE; + } else { + cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), + PCI_COMMAND)); + if (!(cmdreg & PCI_COMMAND_MASTER)) { + printk + ("PCI: Skipping PCI probe. Bus is not initialized.\n"); + iounmap(cfg_space); + return; + } + sb1250_bus_status |= PCI_BUS_ENABLED; } - sb1250_bus_status |= PCI_BUS_ENABLED; - /* - * Establish a mapping from KSEG2 (kernel virtual) to PCI I/O space - * Use "match bytes", even though this exposes endianness. - * big-endian Linuxes will have CONFIG_SWAP_IO_SPACE set. + * Establish mappings in KSEG2 (kernel virtual) to PCI I/O + * space. Use "match bytes" policy to make everything look + * little-endian. So, you need to also set + * CONFIG_SWAP_IO_SPACE, but this is the combination that + * works correctly with most of Linux's drivers. + * XXX ehs: Should this happen in PCI Device mode? */ - set_io_port_base(ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES, 65536)); + set_io_port_base((unsigned long) + ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES, 65536)); isa_slot_offset = (unsigned long) ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES_32, 1024*1024); +#ifdef CONFIG_SIBYTE_HAS_LDT /* * Also check the LDT bridge's enable, just in case we didn't * initialize that one. */ - cmdreg = READCFG32((A_PCI_TYPE01_HEADER | MATCH_BITS) + - PCI_COMMAND); - + cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(LDT_BRIDGE_DEVICE, 0), + PCI_COMMAND)); if (cmdreg & PCI_COMMAND_MASTER) { sb1250_bus_status |= LDT_BUS_ENABLED; + + /* + * Need bits 23:16 to convey vector number. Note that + * this consumes 4MB of kernel-mapped memory + * (Kseg2/Kseg3) for 32-bit kernel. + */ + ldt_eoi_space = (unsigned long) + ioremap(A_PHYS_LDT_SPECIAL_MATCH_BYTES, 4*1024*1024); } +#endif /* Probe for PCI hardware */ @@ -290,41 +299,10 @@ #endif } -int pcibios_enable_device(struct pci_dev *dev) -{ - /* Not needed, since we enable all devices at startup. */ - return 0; -} - -void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ -} - -char *__init pcibios_setup(char *str) -{ - /* Nothing to do for now. */ - - return str; -} - struct pci_fixup pcibios_fixups[] = { {0} }; -void pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - unsigned long where, size; - u32 reg; - - where = PCI_BASE_ADDRESS_0 + (resource * 4); - size = res->end - res->start; - pci_read_config_dword(dev, where, ®); - reg = (reg & size) | (((u32) (res->start - root->start)) & ~size); - pci_write_config_dword(dev, where, reg); -} - /* * Called after each bus is probed, but before its children * are examined. diff -urN linux-2.4.21-bk37/arch/mips/sibyte/sb1250/prom.c linux-2.4.21-bk38/arch/mips/sibyte/sb1250/prom.c --- linux-2.4.21-bk37/arch/mips/sibyte/sb1250/prom.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/sb1250/prom.c 2003-08-24 02:55:58.000000000 -0700 @@ -117,3 +117,7 @@ phys_t addr = pagenr << PAGE_SHIFT; return (addr < (CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024)); } + +void prom_putchar(char c) +{ +} diff -urN linux-2.4.21-bk37/arch/mips/sibyte/sb1250/setup.c linux-2.4.21-bk38/arch/mips/sibyte/sb1250/setup.c --- linux-2.4.21-bk37/arch/mips/sibyte/sb1250/setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/sb1250/setup.c 2003-08-24 02:55:58.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -16,39 +16,195 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include +#include +#include + +#include +#include +#include #include #include #include #include -/* Setup code likely to be common to all BCM1250 platforms */ +unsigned int sb1_pass; +unsigned int soc_pass; +unsigned int soc_type; +unsigned int periph_rev; +unsigned int zbbus_mhz; + +static char *soc_str; +static char *pass_str; +static unsigned int war_pass; /* XXXKW don't overload PASS defines? */ + +static inline int setup_bcm1250(void); +static inline int setup_bcm112x(void); + +/* Setup code likely to be common to all SiByte platforms */ + +static inline int sys_rev_decode(void) +{ + int ret = 0; + + war_pass = soc_pass; + switch (soc_type) { + case K_SYS_SOC_TYPE_BCM1250: + case K_SYS_SOC_TYPE_BCM1250_ALT: + case K_SYS_SOC_TYPE_BCM1250_ALT2: + soc_str = "BCM1250"; + ret = setup_bcm1250(); + break; + case K_SYS_SOC_TYPE_BCM1120: + soc_str = "BCM1120"; + ret = setup_bcm112x(); + break; + case K_SYS_SOC_TYPE_BCM1125: + soc_str = "BCM1125"; + ret = setup_bcm112x(); + break; + case K_SYS_SOC_TYPE_BCM1125H: + soc_str = "BCM1125H"; + ret = setup_bcm112x(); + break; + default: + prom_printf("Unknown SOC type %x\n", soc_type); + ret = 1; + break; + } + return ret; +} + +static inline int setup_bcm1250(void) +{ + int ret = 0; + + switch (soc_pass) { + case K_SYS_REVISION_BCM1250_PASS1: + periph_rev = 1; + pass_str = "Pass 1"; + break; + case K_SYS_REVISION_BCM1250_A10: + periph_rev = 2; + pass_str = "A8/A10"; + /* XXXKW different war_pass? */ + war_pass = K_SYS_REVISION_BCM1250_PASS2; + break; + case K_SYS_REVISION_BCM1250_PASS2_2: + periph_rev = 2; + pass_str = "B1"; + break; + case K_SYS_REVISION_BCM1250_B2: + periph_rev = 2; + pass_str = "B2"; + war_pass = K_SYS_REVISION_BCM1250_PASS2_2; + break; + case K_SYS_REVISION_BCM1250_PASS3: + periph_rev = 3; + pass_str = "C0"; + break; + case K_SYS_REVISION_BCM1250_C1: + periph_rev = 3; + pass_str = "C1"; + break; + default: + if (soc_pass < K_SYS_REVISION_BCM1250_PASS2_2) { + periph_rev = 2; + pass_str = "A0-A6"; + war_pass = K_SYS_REVISION_BCM1250_PASS2; + } else { + prom_printf("Unknown BCM1250 rev %x\n", soc_pass); + ret = 1; + } + break; + } + return ret; +} + +static inline int setup_bcm112x(void) +{ + int ret = 0; -unsigned int sb1250_pass; + switch (soc_pass) { + case 0: + /* Early build didn't have revid set */ + periph_rev = 3; + pass_str = "A1"; + war_pass = K_SYS_REVISION_BCM112x_A1; + break; + case K_SYS_REVISION_BCM112x_A1: + periph_rev = 3; + pass_str = "A1"; + break; + case K_SYS_REVISION_BCM112x_A2: + periph_rev = 3; + pass_str = "A2"; + break; + default: + prom_printf("Unknown %s rev %x\n", soc_str, soc_pass); + ret = 1; + } + return ret; +} void sb1250_setup(void) { + uint64_t sys_rev; + int plldiv; int bad_config = 0; - sb1250_pass = G_SYS_REVISION(in64(IO_SPACE_BASE | A_SCD_SYSTEM_REVISION)); - /* sb1250_pass is more specific than "1", "2" etc. There are - many revision numbers corresponding to "Pass 2". */ - switch(sb1250_pass) { - case 1: + sb1_pass = read_c0_prid() & 0xff; + sys_rev = in64(IO_SPACE_BASE | A_SCD_SYSTEM_REVISION); + soc_type = SYS_SOC_TYPE(sys_rev); + soc_pass = G_SYS_REVISION(sys_rev); + + if (sys_rev_decode()) { + prom_printf("Restart after failure to identify SiByte chip\n"); + machine_restart(NULL); + } + + plldiv = G_SYS_PLL_DIV(in64(IO_SPACE_BASE | A_SCD_SYSTEM_CFG)); + zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25); #ifndef CONFIG_SB1_PASS_1_WORKAROUNDS - printk("@@@@ This is a pass 1 board, and the kernel doesn't have the proper workarounds compiled in. @@@@"); + out64(0, KSEG1 + A_SCD_ZBBUS_CYCLE_COUNT); +#endif + + prom_printf("Broadcom SiByte %s %s @ %d MHz (SB1 rev %d)\n", + soc_str, pass_str, zbbus_mhz * 2, sb1_pass); + prom_printf("Board type: %s\n", get_system_type()); + + switch(war_pass) { + case K_SYS_REVISION_BCM1250_PASS1: +#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS + prom_printf("@@@@ This is a BCM1250 A0-A2 (Pass 1) board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n"); bad_config = 1; #endif break; - default: -#if defined(CONFIG_CPU_HAS_PREFETCH) || !defined(CONFIG_SB1_PASS_2_WORKAROUNDS) - printk("@@@@ This is a pass 2 board, and the kernel doesn't have the proper workarounds compiled in. @@@@"); - printk("@@@@ Prefetches are enabled in this kernel, but are buggy on this board. @@@@"); + case K_SYS_REVISION_BCM1250_PASS2: + /* Pass 2 - easiest as default for now - so many numbers */ +#if !defined(CONFIG_SB1_PASS_2_WORKAROUNDS) || !defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) + prom_printf("@@@@ This is a BCM1250 A3-A10 board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n"); + bad_config = 1; +#endif +#ifdef CONFIG_CPU_HAS_PREFETCH + prom_printf("@@@@ Prefetches may be enabled in this kernel, but are buggy on this board. @@@@\n"); bad_config = 1; #endif break; + case K_SYS_REVISION_BCM1250_PASS2_2: +#ifndef CONFIG_SB1_PASS_2_WORKAROUNDS + prom_printf("@@@@ This is a BCM1250 B1/B2. board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n"); + bad_config = 1; +#endif +#if defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) || !defined(CONFIG_CPU_HAS_PREFETCH) + prom_printf("@@@@ This is a BCM1250 B1/B2, but the kernel is conservatively configured for an 'A' stepping. @@@@\n"); +#endif + break; + default: + break; } - /* XXXKW this is too early for panic/printk to actually do much! */ if (bad_config) { - panic("Invalid configuration for this pass."); + prom_printf("Invalid configuration for this chip.\n"); + machine_restart(NULL); } } diff -urN linux-2.4.21-bk37/arch/mips/sibyte/sb1250/smp.c linux-2.4.21-bk38/arch/mips/sibyte/sb1250/smp.c --- linux-2.4.21-bk37/arch/mips/sibyte/sb1250/smp.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/sb1250/smp.c 2003-08-24 02:55:58.000000000 -0700 @@ -108,6 +108,9 @@ CPUMASK_SETB(cpu_online_map, 0); atomic_set(&cpus_booted, 1); /* Master CPU is already booted... */ init_idle(); + __cpu_number_map[0] = 0; + __cpu_logical_map[0] = 0; + /* smp_tune_scheduling(); XXX */ /* * This loop attempts to compensate for "holes" in the CPU @@ -128,9 +131,6 @@ p->processor = i; p->cpus_runnable = 1 << i; /* we schedule the first task manually */ - /* Attach to the address space of init_task. */ - atomic_inc(&init_mm.mm_count); - p->active_mm = &init_mm; init_tasks[i] = p; del_from_runqueue(p); @@ -144,6 +144,8 @@ (unsigned long)p); } while (!retval && (cur_cpu < NR_CPUS)); if (retval) { + __cpu_number_map[cur_cpu] = i; + __cpu_logical_map[i] = cur_cpu; i++; } else { panic("CPU discovery disaster"); diff -urN linux-2.4.21-bk37/arch/mips/sibyte/sb1250/time.c linux-2.4.21-bk38/arch/mips/sibyte/sb1250/time.c --- linux-2.4.21-bk37/arch/mips/sibyte/sb1250/time.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/sb1250/time.c 2003-08-24 02:55:58.000000000 -0700 @@ -52,6 +52,7 @@ void sb1250_time_init(void) { int cpu = smp_processor_id(); + int irq = K_INT_TIMER_0+cpu; /* Only have 4 general purpose timers */ if (cpu > 3) { @@ -63,11 +64,11 @@ do_gettimeoffset = sb1250_gettimeoffset; } - sb1250_mask_irq(cpu, K_INT_TIMER_0 + cpu); + sb1250_mask_irq(cpu, irq); /* Map the timer interrupt to ip[4] of this cpu */ out64(IMR_IP4_VAL, KSEG1 + A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) - + ((K_INT_TIMER_0 + cpu)<<3)); + + (irq<<3)); /* the general purpose timer ticks at 1 Mhz independent if the rest of the system */ /* Disable the timer and set up the count */ @@ -84,8 +85,8 @@ out64(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS, KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); - sb1250_unmask_irq(cpu, K_INT_TIMER_0 + cpu); - sb1250_steal_irq(K_INT_TIMER_0 + cpu); + sb1250_unmask_irq(cpu, irq); + sb1250_steal_irq(irq); /* * This interrupt is "special" in that it doesn't use the request_irq * way to hook the irq line. The timer interrupt is initialized early @@ -99,8 +100,9 @@ void sb1250_timer_interrupt(struct pt_regs *regs) { int cpu = smp_processor_id(); + int irq = K_INT_TIMER_0+cpu; - kstat.irqs[cpu][K_INT_TIMER_0+cpu]++; + kstat.irqs[cpu][irq]++; /* Reset the timer */ out64(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS, KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); @@ -109,13 +111,13 @@ * CPU 0 handles the global timer interrupt job */ if (cpu == 0) { - ll_timer_interrupt(0, regs); + ll_timer_interrupt(irq, regs); } /* * every CPU should do profiling and process accouting */ - ll_local_timer_interrupt(0, regs); + ll_local_timer_interrupt(irq, regs); } /* diff -urN linux-2.4.21-bk37/arch/mips/sibyte/swarm/Makefile linux-2.4.21-bk38/arch/mips/sibyte/swarm/Makefile --- linux-2.4.21-bk37/arch/mips/sibyte/swarm/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/swarm/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -2,27 +2,12 @@ all: sbswarm.a -OBJS-y = setup.o cmdline.o rtc_xicor1241.o +OBJS-y = setup.o cmdline.o rtc_xicor1241.o rtc_m41t81.o -OBJS-$(CONFIG_L3DEMO) += procl3switch.o l3procbootstrap.o l3proc.o -OBJS-$(CONFIG_REMOTE_DEBUG) += dbg_io.o - -#XMITTER=1 - -ifdef XMITTER -l3proc.bin: xmitter - ln xmitter l3proc.bin -else -l3proc.bin: l3proc - ln l3proc l3proc.bin -endif - -l3proc.o: l3proc.bin - mips-linux-ld -Tl3proc.lds -bbinary -o l3proc.o l3proc.bin +OBJS-$(CONFIG_KGDB) += dbg_io.o sbswarm.a: $(OBJS-y) $(AR) rcs sbswarm.a $^ - rm -f l3proc.o l3proc.bin include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/sibyte/swarm/dbg_io.c linux-2.4.21-bk38/arch/mips/sibyte/swarm/dbg_io.c --- linux-2.4.21-bk37/arch/mips/sibyte/swarm/dbg_io.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/sibyte/swarm/dbg_io.c 2003-08-24 02:55:58.000000000 -0700 @@ -1,5 +1,5 @@ /* - * kgdb debug routines for swarm board. + * kgdb debug routines for SiByte boards. * * Copyright (C) 2001 MontaVista Software Inc. * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net @@ -35,12 +35,10 @@ static int duart_initialized = 0; /* 0: need to be init'ed by kgdb */ /* -------------------- END OF CONFIG --------------------- */ +extern int kgdb_port; - -#define duart_out(reg, val) out64(val, KSEG1 + A_DUART_CHANREG(1,reg)) -#define duart_in(reg) in64(KSEG1 + A_DUART_CHANREG(1,reg)) - -extern void set_async_breakpoint(unsigned int epc); +#define duart_out(reg, val) csr_out32(val, KSEG1 + A_DUART_CHANREG(kgdb_port,reg)) +#define duart_in(reg) csr_in32(KSEG1 + A_DUART_CHANREG(kgdb_port,reg)) void putDebugChar(unsigned char c); unsigned char getDebugChar(void); diff -urN linux-2.4.21-bk37/arch/mips/sibyte/swarm/rtc_m41t81.c linux-2.4.21-bk38/arch/mips/sibyte/swarm/rtc_m41t81.c --- linux-2.4.21-bk37/arch/mips/sibyte/swarm/rtc_m41t81.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/swarm/rtc_m41t81.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * Copyright (C) 2002 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * 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. + * + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include + + +/* M41T81 definitions */ + +/* + * Register bits + */ + +#define M41T81REG_SC_ST 0x80 /* stop bit */ +#define M41T81REG_HR_CB 0x40 /* century bit */ +#define M41T81REG_HR_CEB 0x80 /* century enable bit */ +#define M41T81REG_CTL_S 0x20 /* sign bit */ +#define M41T81REG_CTL_FT 0x40 /* frequency test bit */ +#define M41T81REG_CTL_OUT 0x80 /* output level */ +#define M41T81REG_WD_RB0 0x01 /* watchdog resolution bit 0 */ +#define M41T81REG_WD_RB1 0x02 /* watchdog resolution bit 1 */ +#define M41T81REG_WD_BMB0 0x04 /* watchdog multiplier bit 0 */ +#define M41T81REG_WD_BMB1 0x08 /* watchdog multiplier bit 1 */ +#define M41T81REG_WD_BMB2 0x10 /* watchdog multiplier bit 2 */ +#define M41T81REG_WD_BMB3 0x20 /* watchdog multiplier bit 3 */ +#define M41T81REG_WD_BMB4 0x40 /* watchdog multiplier bit 4 */ +#define M41T81REG_AMO_ABE 0x20 /* alarm in "battery back-up mode" enable bit */ +#define M41T81REG_AMO_SQWE 0x40 /* square wave enable */ +#define M41T81REG_AMO_AFE 0x80 /* alarm flag enable flag */ +#define M41T81REG_ADT_RPT5 0x40 /* alarm repeat mode bit 5 */ +#define M41T81REG_ADT_RPT4 0x80 /* alarm repeat mode bit 4 */ +#define M41T81REG_AHR_RPT3 0x80 /* alarm repeat mode bit 3 */ +#define M41T81REG_AHR_HT 0x40 /* halt update bit */ +#define M41T81REG_AMN_RPT2 0x80 /* alarm repeat mode bit 2 */ +#define M41T81REG_ASC_RPT1 0x80 /* alarm repeat mode bit 1 */ +#define M41T81REG_FLG_AF 0x40 /* alarm flag (read only) */ +#define M41T81REG_FLG_WDF 0x80 /* watchdog flag (read only) */ +#define M41T81REG_SQW_RS0 0x10 /* sqw frequency bit 0 */ +#define M41T81REG_SQW_RS1 0x20 /* sqw frequency bit 1 */ +#define M41T81REG_SQW_RS2 0x40 /* sqw frequency bit 2 */ +#define M41T81REG_SQW_RS3 0x80 /* sqw frequency bit 3 */ + + +/* + * Register numbers + */ + +#define M41T81REG_TSC 0x00 /* tenths/hundredths of second */ +#define M41T81REG_SC 0x01 /* seconds */ +#define M41T81REG_MN 0x02 /* minute */ +#define M41T81REG_HR 0x03 /* hour/century */ +#define M41T81REG_DY 0x04 /* day of week */ +#define M41T81REG_DT 0x05 /* date of month */ +#define M41T81REG_MO 0x06 /* month */ +#define M41T81REG_YR 0x07 /* year */ +#define M41T81REG_CTL 0x08 /* control */ +#define M41T81REG_WD 0x09 /* watchdog */ +#define M41T81REG_AMO 0x0A /* alarm: month */ +#define M41T81REG_ADT 0x0B /* alarm: date */ +#define M41T81REG_AHR 0x0C /* alarm: hour */ +#define M41T81REG_AMN 0x0D /* alarm: minute */ +#define M41T81REG_ASC 0x0E /* alarm: second */ +#define M41T81REG_FLG 0x0F /* flags */ +#define M41T81REG_SQW 0x13 /* square wave register */ + +#define M41T81_CCR_ADDRESS 0x68 +#define SMB_CSR(reg) (KSEG1 | A_SMB_REGISTER(1, reg)) + +static int m41t81_read(uint8_t addr) +{ + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + out64(addr & 0xff, SMB_CSR(R_SMB_CMD)); + out64((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR1BYTE), SMB_CSR(R_SMB_START)); + + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + out64((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE), SMB_CSR(R_SMB_START)); + + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + if (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { + /* Clear error bit by writing a 1 */ + out64(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); + return -1; + } + + return (in64(SMB_CSR(R_SMB_DATA)) & 0xff); +} + +static int m41t81_write(uint8_t addr, int b) +{ + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + out64((addr & 0xFF), SMB_CSR(R_SMB_CMD)); + out64((b & 0xff), SMB_CSR(R_SMB_DATA)); + out64(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR2BYTE, + SMB_CSR(R_SMB_START)); + + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + if (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { + /* Clear error bit by writing a 1 */ + out64(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); + return -1; + } + + /* read the same byte again to make sure it is written */ + out64(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE, + SMB_CSR(R_SMB_START)); + + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + return 0; +} + +#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10) +#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10) + +int m41t81_set_time(unsigned long t) +{ + struct rtc_time tm; + + to_tm(t, &tm); + + /* + * Note the write order matters as it ensures the correctness. + * When we write sec, 10th sec is clear. It is reasonable to + * believe we should finish writing min within a second. + */ + + BIN_TO_BCD(tm.tm_sec); + m41t81_write(M41T81REG_SC, tm.tm_sec); + + BIN_TO_BCD(tm.tm_min); + m41t81_write(M41T81REG_MN, tm.tm_min); + + BIN_TO_BCD(tm.tm_hour); + tm.tm_hour = (tm.tm_hour & 0x3f) | (m41t81_read(M41T81REG_HR) & 0xc0); + m41t81_write(M41T81REG_HR, tm.tm_hour); + + /* tm_wday starts from 0 to 6 */ + if (tm.tm_wday == 0) tm.tm_wday = 7; + BIN_TO_BCD(tm.tm_wday); + m41t81_write(M41T81REG_DY, tm.tm_wday); + + BIN_TO_BCD(tm.tm_mday); + m41t81_write(M41T81REG_DT, tm.tm_mday); + + /* tm_mon starts from 0, *ick* */ + tm.tm_mon ++; + BIN_TO_BCD(tm.tm_mon); + m41t81_write(M41T81REG_MO, tm.tm_mon); + + /* we don't do century, everything is beyond 2000 */ + tm.tm_year %= 100; + BIN_TO_BCD(tm.tm_year); + m41t81_write(M41T81REG_YR, tm.tm_year); + + return 0; +} + +unsigned long m41t81_get_time(void) +{ + unsigned int year, mon, day, hour, min, sec; + + /* + * min is valid if two reads of sec are the same. + */ + for (;;) { + sec = m41t81_read(M41T81REG_SC); + min = m41t81_read(M41T81REG_MN); + if (sec == m41t81_read(M41T81REG_SC)) break; + } + hour = m41t81_read(M41T81REG_HR) & 0x3f; + day = m41t81_read(M41T81REG_DT); + mon = m41t81_read(M41T81REG_MO); + year = m41t81_read(M41T81REG_YR); + + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + + year += 2000; + + return mktime(year, mon, day, hour, min, sec); +} + +int m41t81_probe(void) +{ + unsigned int tmp; + + /* enable chip if it is not enabled yet */ + tmp = m41t81_read(M41T81REG_SC); + m41t81_write(M41T81REG_SC, tmp & 0x7f); + + return (m41t81_read(M41T81REG_SC) != -1); +} diff -urN linux-2.4.21-bk37/arch/mips/sibyte/swarm/rtc_xicor1241.c linux-2.4.21-bk38/arch/mips/sibyte/swarm/rtc_xicor1241.c --- linux-2.4.21-bk37/arch/mips/sibyte/swarm/rtc_xicor1241.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/swarm/rtc_xicor1241.c 2003-08-24 02:55:58.000000000 -0700 @@ -181,15 +181,14 @@ hour = (hour & 0xf) + 0x12; } - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hour); - day = xicor_read(X1241REG_DT); mon = xicor_read(X1241REG_MO); year = xicor_read(X1241REG_YR); y2k = xicor_read(X1241REG_Y2K); + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); BCD_TO_BIN(day); BCD_TO_BIN(mon); BCD_TO_BIN(year); @@ -200,3 +199,7 @@ return mktime(year, mon, day, hour, min, sec); } +int xicor_probe(void) +{ + return (xicor_read(X1241REG_SC) != -1); +} diff -urN linux-2.4.21-bk37/arch/mips/sibyte/swarm/setup.c linux-2.4.21-bk38/arch/mips/sibyte/swarm/setup.c --- linux-2.4.21-bk37/arch/mips/sibyte/swarm/setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sibyte/swarm/setup.c 2003-08-24 02:55:58.000000000 -0700 @@ -31,40 +31,36 @@ #include #include #include +#include #include #include +#include #include #include #include #include -#include +#include extern struct rtc_ops *rtc_ops; extern struct rtc_ops swarm_rtc_ops; #ifdef CONFIG_BLK_DEV_IDE -extern struct ide_ops std_ide_ops; -#ifdef CONFIG_BLK_DEV_IDE_SIBYTE extern struct ide_ops sibyte_ide_ops; #endif -#endif - -#ifdef CONFIG_L3DEMO -extern void *l3info; -#endif -static unsigned char *led_ptr; -#define LED_BASE_ADDR (A_IO_EXT_REG(R_IO_EXT_REG(R_IO_EXT_START_ADDR, LEDS_CS))) -#define setled(index, c) led_ptr[(3-((index)&3)) << 3] = (c) +extern void sb1250_setup(void); -const char *get_system_type(void) -{ - return "SiByte Swarm"; -} +extern int xicor_probe(void); +extern int xicor_set_time(unsigned long); +extern unsigned long xicor_get_time(void); +extern int m41t81_probe(void); +extern int m41t81_set_time(unsigned long); +extern unsigned long m41t81_get_time(void); -void __init bus_error_init(void) +const char *get_system_type(void) { + return "SiByte " SIBYTE_BOARD_NAME; } void __init swarm_timer_setup(struct irqaction *irq) @@ -78,9 +74,20 @@ sb1250_time_init(); } -extern int xicor_set_time(unsigned long); -extern unsigned long xicor_get_time(void); -extern void sb1250_setup(void); +int swarm_be_handler(struct pt_regs *regs, int is_fixup) +{ + if (!is_fixup && (regs->cp0_cause & 4)) { + /* Data bus error - print PA */ +#ifdef CONFIG_MIPS64 + printk("DBE physical address: %010lx\n", + __read_64bit_c0_register($26, 1)); +#else + printk("DBE physical address: %010llx\n", + __read_64bit_c0_split($26, 1)); +#endif + } + return (is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL); +} void __init swarm_setup(void) { @@ -90,16 +97,21 @@ panic_timeout = 5; /* For debug. */ - board_timer_setup = swarm_timer_setup; + board_timer_setup = swarm_timer_setup; + board_be_handler = swarm_be_handler; - rtc_get_time = xicor_get_time; - rtc_set_time = xicor_set_time; - -#ifdef CONFIG_L3DEMO - if (l3info != NULL) { - printk("\n"); + if (xicor_probe()) { + printk("swarm setup: Xicor 1241 RTC detected.\n"); + rtc_get_time = xicor_get_time; + rtc_set_time = xicor_set_time; } -#endif + + if (m41t81_probe()) { + printk("swarm setup: M41T81 RTC detected.\n"); + rtc_get_time = m41t81_get_time; + rtc_set_time = m41t81_set_time; + } + printk("This kernel optimized for " #ifdef CONFIG_SIMULATION "simulation" @@ -115,23 +127,8 @@ " CFE\n"); #ifdef CONFIG_BLK_DEV_IDE -#ifdef CONFIG_BLK_DEV_IDE_SIBYTE ide_ops = &sibyte_ide_ops; -#else - ide_ops = &std_ide_ops; #endif -#endif - - /* Set up the LED base address */ -#ifdef __MIPSEL__ - /* Pass1 workaround (bug 1624) */ - if (sb1250_pass == K_SYS_REVISION_PASS1) - led_ptr = (unsigned char *) - ((unsigned long)(KSEG1 | (G_IO_START_ADDR(csr_in32(4+(KSEG1|LED_BASE_ADDR))) << S_IO_ADDRBASE))+0x20); - else -#endif - led_ptr = (unsigned char *) - ((unsigned long)(KSEG1 | (G_IO_START_ADDR(csr_in32(KSEG1|LED_BASE_ADDR)) << S_IO_ADDRBASE))+0x20); #ifdef CONFIG_VT #ifdef CONFIG_DUMMY_CONSOLE @@ -152,60 +149,25 @@ #endif } +#ifdef LEDS_PHYS + +#ifdef CONFIG_SIBYTE_CARMEL +/* XXXKW need to detect Monterey/LittleSur/etc */ +#undef LEDS_PHYS +#define LEDS_PHYS MLEDS_PHYS +#endif + +#define setled(index, c) \ + ((unsigned char *)(LEDS_PHYS|IO_SPACE_BASE|0x20))[(3-(index))<<3] = (c) void setleds(char *str) { int i; for (i = 0; i < 4; i++) { if (!str[i]) { - for (; i < 4; i++) { - setled(' ', str[i]); - } + setled(i, ' '); } else { setled(i, str[i]); } } } - -#include - -static struct timer_list led_timer; -static unsigned char default_led_msg[] = - "Today: the CSWARM. Tomorrow: the WORLD!!!! "; -static unsigned char *led_msg = default_led_msg; -static unsigned char *led_msg_ptr = default_led_msg; - -void set_led_msg(char *new_msg) -{ - led_msg = new_msg; - led_msg_ptr = new_msg; - setleds(" "); -} - -static void move_leds(unsigned long arg) -{ - int i; - unsigned char *tmp = led_msg_ptr; - for (i = 0; i < 4; i++) { - setled(i, *tmp); - tmp++; - if (!*tmp) { - tmp = led_msg; - } - } - led_msg_ptr++; - if (!*led_msg_ptr) { - led_msg_ptr = led_msg; - } - del_timer(&led_timer); - led_timer.expires = jiffies + (HZ/8); - add_timer(&led_timer); -} - -void hack_leds(void) -{ - init_timer(&led_timer); - led_timer.expires = jiffies + (HZ/8); - led_timer.data = 0; - led_timer.function = move_leds; - add_timer(&led_timer); -} +#endif diff -urN linux-2.4.21-bk37/arch/mips/sni/Makefile linux-2.4.21-bk38/arch/mips/sni/Makefile --- linux-2.4.21-bk37/arch/mips/sni/Makefile 2001-04-13 20:26:07.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/sni/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -6,16 +6,16 @@ # unless it's something special (ie not a .c file). # -.S.s: - $(CPP) $(CFLAGS) $< -o $*.s -.S.o: - $(CC) $(CFLAGS) -c $< -o $*.o +USE_STANDARD_AS_RULE := true all: sni.o int-handler.o O_TARGET := sni.o -obj-y := int-handler.o io.o irq.o pci.o pcimt_scache.o reset.o setup.o +obj-y += int-handler.o io.o irq.o pcimt_scache.o reset.o \ + setup.o + +obj-$(CONFIG_PCI) += pci.o int-handler.o: int-handler.S diff -urN linux-2.4.21-bk37/arch/mips/sni/int-handler.S linux-2.4.21-bk38/arch/mips/sni/int-handler.S --- linux-2.4.21-bk37/arch/mips/sni/int-handler.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/sni/int-handler.S 2003-08-24 02:55:58.000000000 -0700 @@ -47,7 +47,7 @@ bnez t1, _hwint0 nop - j restore_all # spurious interrupt + j ret_from_irq # spurious interrupt nop ############################################################################## diff -urN linux-2.4.21-bk37/arch/mips/sni/irq.c linux-2.4.21-bk38/arch/mips/sni/irq.c --- linux-2.4.21-bk37/arch/mips/sni/irq.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/sni/irq.c 2003-08-24 02:55:58.000000000 -0700 @@ -9,16 +9,17 @@ #include #include #include +#include #include #include +#include #include #include spinlock_t pciasic_lock = SPIN_LOCK_UNLOCKED; extern asmlinkage void sni_rm200_pci_handle_int(void); -extern void do_IRQ(int irq, struct pt_regs *regs); static void enable_pciasic_irq(unsigned int irq); diff -urN linux-2.4.21-bk37/arch/mips/sni/pci.c linux-2.4.21-bk38/arch/mips/sni/pci.c --- linux-2.4.21-bk37/arch/mips/sni/pci.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/sni/pci.c 2003-08-24 02:55:58.000000000 -0700 @@ -15,18 +15,6 @@ #include #include -#ifdef CONFIG_PCI - -#define mkaddr(dev, where) \ -do { \ - if ((dev)->bus->number == 0) \ - return -1; \ - *(volatile u32 *)PCIMT_CONFIG_ADDRESS = \ - ((dev->bus->number & 0xff) << 0x10) | \ - ((dev->devfn & 0xff) << 0x08) | \ - (where & 0xfc); \ -} while(0) - #if 0 /* To do: Bring this uptodate ... */ static void pcimt_pcibios_fixup (void) @@ -40,7 +28,7 @@ */ if (dev->devfn == PCI_DEVFN(1, 0)) { /* Evil hack ... */ - set_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NO_WA); + set_c0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NO_WA); dev->irq = PCIMT_IRQ_SCSI; continue; } @@ -65,125 +53,12 @@ } #endif -/* - * We can't address 8 and 16 bit words directly. Instead we have to - * read/write a 32bit word and mask/modify the data we actually want. - */ -static int pcimt_read_config_byte (struct pci_dev *dev, - int where, unsigned char *val) -{ - u32 res; - - mkaddr(dev, where); - res = *(volatile u32 *)PCIMT_CONFIG_DATA; - res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xff; - *val = res; - - return PCIBIOS_SUCCESSFUL; -} - -static int pcimt_read_config_word (struct pci_dev *dev, - int where, unsigned short *val) -{ - u32 res; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - mkaddr(dev, where); - res = *(volatile u32 *)PCIMT_CONFIG_DATA; - res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xffff; - *val = res; - - return PCIBIOS_SUCCESSFUL; -} - -static int pcimt_read_config_dword (struct pci_dev *dev, - int where, unsigned int *val) -{ - u32 res; - - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - mkaddr(dev, where); - res = *(volatile u32 *)PCIMT_CONFIG_DATA; - res = le32_to_cpu(res); - *val = res; - - return PCIBIOS_SUCCESSFUL; -} - -static int pcimt_write_config_byte (struct pci_dev *dev, - int where, unsigned char val) -{ - mkaddr(dev, where); - *(volatile u8 *)(PCIMT_CONFIG_DATA + (where & 3)) = val; - - return PCIBIOS_SUCCESSFUL; -} - -static int pcimt_write_config_word (struct pci_dev *dev, - int where, unsigned short val) -{ - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - mkaddr(dev, where); - *(volatile u16 *)(PCIMT_CONFIG_DATA + (where & 3)) = le16_to_cpu(val); - - return PCIBIOS_SUCCESSFUL; -} - -static int pcimt_write_config_dword (struct pci_dev *dev, - int where, unsigned int val) -{ - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - mkaddr(dev, where); - *(volatile u32 *)PCIMT_CONFIG_DATA = le32_to_cpu(val); - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops sni_pci_ops = { - pcimt_read_config_byte, - pcimt_read_config_word, - pcimt_read_config_dword, - pcimt_write_config_byte, - pcimt_write_config_word, - pcimt_write_config_dword -}; - void __init pcibios_fixup_bus(struct pci_bus *b) { } -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); - if (resource < 6) { - reg = PCI_BASE_ADDRESS_0 + 4*resource; - } else if (resource == PCI_ROM_RESOURCE) { - res->flags |= PCI_ROM_ADDRESS_ENABLE; - new |= PCI_ROM_ADDRESS_ENABLE; - reg = dev->rom_base_reg; - } else { - /* Somebody might have asked allocation of a non-standard resource */ - return; - } - - pci_write_config_dword(dev, reg, new); - pci_read_config_dword(dev, reg, &check); - if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) { - printk(KERN_ERR "PCI: Error while updating region " - "%s/%d (%08x != %08x)\n", dev->slot_name, resource, - new, check); - } -} +extern struct pci_ops sni_pci_ops; void __init pcibios_init(void) { @@ -192,33 +67,11 @@ pci_scan_bus(0, ops, NULL); } -int __init pcibios_enable_device(struct pci_dev *dev) -{ - /* Not needed, since we enable all devices at startup. */ - return 0; -} - -void __init -pcibios_align_resource(void *data, struct resource *res, unsigned long size, - unsigned long align) -{ -} - unsigned __init int pcibios_assign_all_busses(void) { return 0; } -char * __init -pcibios_setup(char *str) -{ - /* Nothing to do for now. */ - - return str; -} - struct pci_fixup pcibios_fixups[] = { { 0 } }; - -#endif /* CONFIG_PCI */ diff -urN linux-2.4.21-bk37/arch/mips/sni/setup.c linux-2.4.21-bk38/arch/mips/sni/setup.c --- linux-2.4.21-bk37/arch/mips/sni/setup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/sni/setup.c 2003-08-24 02:55:58.000000000 -0700 @@ -31,6 +31,7 @@ #include #include #include +#include extern void sni_machine_restart(char *command); extern void sni_machine_halt(void); @@ -49,6 +50,7 @@ setup_irq(0, irq); } + extern unsigned char sni_map_isa_cache; /* diff -urN linux-2.4.21-bk37/arch/mips/tools/offset.c linux-2.4.21-bk38/arch/mips/tools/offset.c --- linux-2.4.21-bk37/arch/mips/tools/offset.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/tools/offset.c 2003-08-24 02:55:58.000000000 -0700 @@ -8,6 +8,7 @@ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. */ +#include #include #include #include @@ -151,12 +152,19 @@ offset("#define SC_MDLO ", struct sigcontext, sc_mdlo); offset("#define SC_PC ", struct sigcontext, sc_pc); offset("#define SC_STATUS ", struct sigcontext, sc_status); - offset("#define SC_OWNEDFP ", struct sigcontext, sc_ownedfp); offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr); offset("#define SC_FPC_EIR ", struct sigcontext, sc_fpc_eir); offset("#define SC_CAUSE ", struct sigcontext, sc_cause); offset("#define SC_BADVADDR ", struct sigcontext, sc_badvaddr); linefeed; + +#ifdef CONFIG_MIPS64 + text("/* Linux 32-bit sigcontext offsets. */"); + offset("#define SC32_FPREGS ", struct sigcontext32, sc_fpregs); + offset("#define SC32_FPC_CSR ", struct sigcontext32, sc_fpc_csr); + offset("#define SC32_FPC_EIR ", struct sigcontext32, sc_fpc_eir); + linefeed; +#endif } void output_signal_defined(void) diff -urN linux-2.4.21-bk37/arch/mips/tx4927/common/Makefile linux-2.4.21-bk38/arch/mips/tx4927/common/Makefile --- linux-2.4.21-bk37/arch/mips/tx4927/common/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/tx4927/common/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,20 @@ +# +# Makefile for common code for Toshiba TX4927 based systems +# +# Note! Dependencies are done automagically by 'make dep', which also +# 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:= tx4927.o + +obj-y := tx4927_prom.o +obj-y += tx4927_setup.o +obj-y += tx4927_irq.o +obj-y += tx4927_irq_handler.o + +obj-$(CONFIG_KGDB) += tx4927_dbgio.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/tx4927/common/tx4927_dbgio.c linux-2.4.21-bk38/arch/mips/tx4927/common/tx4927_dbgio.c --- linux-2.4.21-bk37/arch/mips/tx4927/common/tx4927_dbgio.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/tx4927/common/tx4927_dbgio.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,47 @@ +/* + * linux/arch/mips/tx4927/common/tx4927_dbgio.c + * + * kgdb interface for gdb + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +u8 getDebugChar(void) +{ + extern u8 txx9_sio_kdbg_rd(void); + return (txx9_sio_kdbg_rd()); +} + + +int putDebugChar(u8 byte) +{ + extern int txx9_sio_kdbg_wr( u8 ch ); + return (txx9_sio_kdbg_wr(byte)); +} diff -urN linux-2.4.21-bk37/arch/mips/tx4927/common/tx4927_irq.c linux-2.4.21-bk38/arch/mips/tx4927/common/tx4927_irq.c --- linux-2.4.21-bk37/arch/mips/tx4927/common/tx4927_irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/tx4927/common/tx4927_irq.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,708 @@ +/* + * Common tx4927 irq handler + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * DEBUG + */ +#define TX4927_IRQ_CHECK_CP0 +#define TX4927_IRQ_CHECK_PIC + +#undef TX4927_IRQ_DEBUG + +#ifdef TX4927_IRQ_DEBUG +#define TX4927_IRQ_NONE 0x00000000 + +#define TX4927_IRQ_INFO ( 1 << 0 ) +#define TX4927_IRQ_WARN ( 1 << 1 ) +#define TX4927_IRQ_EROR ( 1 << 2 ) + +#define TX4927_IRQ_INIT ( 1 << 5 ) +#define TX4927_IRQ_NEST1 ( 1 << 6 ) +#define TX4927_IRQ_NEST2 ( 1 << 7 ) +#define TX4927_IRQ_NEST3 ( 1 << 8 ) +#define TX4927_IRQ_NEST4 ( 1 << 9 ) + +#define TX4927_IRQ_CP0_INIT ( 1 << 10 ) +#define TX4927_IRQ_CP0_STARTUP ( 1 << 11 ) +#define TX4927_IRQ_CP0_SHUTDOWN ( 1 << 12 ) +#define TX4927_IRQ_CP0_ENABLE ( 1 << 13 ) +#define TX4927_IRQ_CP0_DISABLE ( 1 << 14 ) +#define TX4927_IRQ_CP0_MASK ( 1 << 15 ) +#define TX4927_IRQ_CP0_ENDIRQ ( 1 << 16 ) + +#define TX4927_IRQ_PIC_INIT ( 1 << 20 ) +#define TX4927_IRQ_PIC_STARTUP ( 1 << 21 ) +#define TX4927_IRQ_PIC_SHUTDOWN ( 1 << 22 ) +#define TX4927_IRQ_PIC_ENABLE ( 1 << 23 ) +#define TX4927_IRQ_PIC_DISABLE ( 1 << 24 ) +#define TX4927_IRQ_PIC_MASK ( 1 << 25 ) +#define TX4927_IRQ_PIC_ENDIRQ ( 1 << 26 ) + +#define TX4927_IRQ_ALL 0xffffffff +#endif + +#ifdef TX4927_IRQ_DEBUG +static const u32 tx4927_irq_debug_flag = (TX4927_IRQ_NONE + | TX4927_IRQ_INFO + | TX4927_IRQ_WARN | TX4927_IRQ_EROR +// | TX4927_IRQ_CP0_INIT +// | TX4927_IRQ_CP0_STARTUP +// | TX4927_IRQ_CP0_SHUTDOWN +// | TX4927_IRQ_CP0_ENABLE +// | TX4927_IRQ_CP0_DISABLE +// | TX4927_IRQ_CP0_MASK +// | TX4927_IRQ_CP0_ENDIRQ +// | TX4927_IRQ_PIC_INIT +// | TX4927_IRQ_PIC_STARTUP +// | TX4927_IRQ_PIC_SHUTDOWN +// | TX4927_IRQ_PIC_ENABLE +// | TX4927_IRQ_PIC_DISABLE +// | TX4927_IRQ_PIC_MASK +// | TX4927_IRQ_PIC_ENDIRQ +// | TX4927_IRQ_INIT +// | TX4927_IRQ_NEST1 +// | TX4927_IRQ_NEST2 +// | TX4927_IRQ_NEST3 +// | TX4927_IRQ_NEST4 + ); +#endif + +#ifdef TX4927_IRQ_DEBUG +#define TX4927_IRQ_DPRINTK(flag,str...) \ + if ( (tx4927_irq_debug_flag) & (flag) ) \ + { \ + char tmp[100]; \ + sprintf( tmp, str ); \ + printk( "%s(%s:%u)::%s", __FUNCTION__, __FILE__, __LINE__, tmp ); \ + } +#else +#define TX4927_IRQ_DPRINTK(flag,str...) +#endif + +/* + * Forwad definitions for all pic's + */ + +static unsigned int tx4927_irq_cp0_startup(unsigned int irq); +static void tx4927_irq_cp0_shutdown(unsigned int irq); +static void tx4927_irq_cp0_enable(unsigned int irq); +static void tx4927_irq_cp0_disable(unsigned int irq); +static void tx4927_irq_cp0_mask_and_ack(unsigned int irq); +static void tx4927_irq_cp0_end(unsigned int irq); + +static unsigned int tx4927_irq_pic_startup(unsigned int irq); +static void tx4927_irq_pic_shutdown(unsigned int irq); +static void tx4927_irq_pic_enable(unsigned int irq); +static void tx4927_irq_pic_disable(unsigned int irq); +static void tx4927_irq_pic_mask_and_ack(unsigned int irq); +static void tx4927_irq_pic_end(unsigned int irq); + +/* + * Kernel structs for all pic's + */ + +static spinlock_t tx4927_cp0_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t tx4927_pic_lock = SPIN_LOCK_UNLOCKED; + +#define TX4927_CP0_NAME "TX4927-CP0" +static struct hw_interrupt_type tx4927_irq_cp0_type = { + typename: TX4927_CP0_NAME, + startup: tx4927_irq_cp0_startup, + shutdown: tx4927_irq_cp0_shutdown, + enable: tx4927_irq_cp0_enable, + disable: tx4927_irq_cp0_disable, + ack: tx4927_irq_cp0_mask_and_ack, + end: tx4927_irq_cp0_end, + set_affinity: NULL +}; + +#define TX4927_PIC_NAME "TX4927-PIC" +static struct hw_interrupt_type tx4927_irq_pic_type = { + typename: TX4927_PIC_NAME, + startup: tx4927_irq_pic_startup, + shutdown: tx4927_irq_pic_shutdown, + enable: tx4927_irq_pic_enable, + disable: tx4927_irq_pic_disable, + ack: tx4927_irq_pic_mask_and_ack, + end: tx4927_irq_pic_end, + set_affinity: NULL +}; + +#define TX4927_PIC_ACTION(s) { no_action, 0, 0, s, NULL, NULL } +static struct irqaction tx4927_irq_pic_action = +TX4927_PIC_ACTION(TX4927_PIC_NAME); + +#define CCP0_STATUS 12 +#define CCP0_CAUSE 13 + +/* + * Functions for cp0 + */ + +#define tx4927_irq_cp0_mask(irq) ( 1 << ( irq-TX4927_IRQ_CP0_BEG+8 ) ) + +static void tx4927_irq_cp0_modify(unsigned cp0_reg, unsigned clr_bits, + unsigned set_bits) +{ + unsigned long val = 0; + + switch (cp0_reg) { + case CCP0_STATUS: + val = read_c0_status(); + break; + + case CCP0_CAUSE: + val = read_c0_cause(); + break; + + } + + val &= (~clr_bits); + val |= (set_bits); + + switch (cp0_reg) { + case CCP0_STATUS:{ + write_c0_status(val); + break; + } + case CCP0_CAUSE:{ + write_c0_cause(val); + break; + } + } + + return; +} + +static void __init tx4927_irq_cp0_init(void) +{ + int i; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_INIT, "beg=%d end=%d\n", + TX4927_IRQ_CP0_BEG, TX4927_IRQ_CP0_END); + + for (i = TX4927_IRQ_CP0_BEG; i <= TX4927_IRQ_CP0_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &tx4927_irq_cp0_type; + } + + return; +} + +static unsigned int tx4927_irq_cp0_startup(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_STARTUP, "irq=%d \n", irq); + +#ifdef TX4927_IRQ_CHECK_CP0 + { + if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + tx4927_irq_cp0_enable(irq); + + return (0); +} + +static void tx4927_irq_cp0_shutdown(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_SHUTDOWN, "irq=%d \n", irq); + +#ifdef TX4927_IRQ_CHECK_CP0 + { + if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + tx4927_irq_cp0_disable(irq); + + return; +} + +static void tx4927_irq_cp0_enable(unsigned int irq) +{ + unsigned long flags; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_ENABLE, "irq=%d \n", irq); + +#ifdef TX4927_IRQ_CHECK_CP0 + { + if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + spin_lock_irqsave(&tx4927_cp0_lock, flags); + + tx4927_irq_cp0_modify(CCP0_STATUS, 0, tx4927_irq_cp0_mask(irq)); + + spin_unlock_irqrestore(&tx4927_cp0_lock, flags); + + return; +} + +static void tx4927_irq_cp0_disable(unsigned int irq) +{ + unsigned long flags; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_DISABLE, "irq=%d \n", irq); + +#ifdef TX4927_IRQ_CHECK_CP0 + { + if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + spin_lock_irqsave(&tx4927_cp0_lock, flags); + + tx4927_irq_cp0_modify(CCP0_STATUS, tx4927_irq_cp0_mask(irq), 0); + + spin_unlock_irqrestore(&tx4927_cp0_lock, flags); + + return; +} + +static void tx4927_irq_cp0_mask_and_ack(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_MASK, "irq=%d \n", irq); + +#ifdef TX4927_IRQ_CHECK_CP0 + { + if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + tx4927_irq_cp0_disable(irq); + + return; +} + +static void tx4927_irq_cp0_end(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_ENDIRQ, "irq=%d \n", irq); + +#ifdef TX4927_IRQ_CHECK_CP0 + { + if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + tx4927_irq_cp0_enable(irq); + } + + return; +} + +/* + * Functions for pic + */ + +u32 tx4927_irq_pic_addr(int irq) +{ + /* MVMCP -- need to formulize this */ + irq -= TX4927_IRQ_PIC_BEG; + switch (irq) { + case 17: + case 16: + case 1: + case 0: + return (0xff1ff610); + + case 19: + case 18: + case 3: + case 2: + return (0xff1ff614); + + case 21: + case 20: + case 5: + case 4: + return (0xff1ff618); + + case 23: + case 22: + case 7: + case 6: + return (0xff1ff61c); + + case 25: + case 24: + case 9: + case 8: + return (0xff1ff620); + + case 27: + case 26: + case 11: + case 10: + return (0xff1ff624); + + case 29: + case 28: + case 13: + case 12: + return (0xff1ff628); + + case 31: + case 30: + case 15: + case 14: + return (0xff1ff62c); + + } + return (0); +} + +u32 tx4927_irq_pic_mask(int irq) +{ + /* MVMCP -- need to formulize this */ + irq -= TX4927_IRQ_PIC_BEG; + switch (irq) { + case 31: + case 29: + case 27: + case 25: + case 23: + case 21: + case 19: + case 17:{ + return (0x07000000); + } + case 30: + case 28: + case 26: + case 24: + case 22: + case 20: + case 18: + case 16:{ + return (0x00070000); + } + case 15: + case 13: + case 11: + case 9: + case 7: + case 5: + case 3: + case 1:{ + return (0x00000700); + } + case 14: + case 12: + case 10: + case 8: + case 6: + case 4: + case 2: + case 0:{ + return (0x00000007); + } + } + return (0x00000000); +} + +static void tx4927_irq_pic_modify(unsigned pic_reg, unsigned clr_bits, + unsigned set_bits) +{ + unsigned long val = 0; + + val = TX4927_RD(pic_reg); + val &= (~clr_bits); + val |= (set_bits); + TX4927_WR(pic_reg, val); + + return; +} + +static void __init tx4927_irq_pic_init(void) +{ + unsigned long flags; + int i; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_INIT, "beg=%d end=%d\n", + TX4927_IRQ_PIC_BEG, TX4927_IRQ_PIC_END); + + for (i = TX4927_IRQ_PIC_BEG; i <= TX4927_IRQ_PIC_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 2; + irq_desc[i].handler = &tx4927_irq_pic_type; + } + + setup_irq(TX4927_IRQ_NEST_PIC_ON_CP0, &tx4927_irq_pic_action); + + spin_lock_irqsave(&tx4927_pic_lock, flags); + + TX4927_WR(0xff1ff640, 0x6); /* irq level mask -- only accept hightest */ + TX4927_WR(0xff1ff600, TX4927_RD(0xff1ff600) | 0x1); /* irq enable */ + + spin_unlock_irqrestore(&tx4927_pic_lock, flags); + + return; +} + +static unsigned int tx4927_irq_pic_startup(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_STARTUP, "irq=%d\n", irq); + +#ifdef TX4927_IRQ_CHECK_PIC + { + if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + tx4927_irq_pic_enable(irq); + + return (0); +} + +static void tx4927_irq_pic_shutdown(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_SHUTDOWN, "irq=%d\n", irq); + +#ifdef TX4927_IRQ_CHECK_PIC + { + if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + tx4927_irq_pic_disable(irq); + + return; +} + +static void tx4927_irq_pic_enable(unsigned int irq) +{ + unsigned long flags; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_ENABLE, "irq=%d\n", irq); + +#ifdef TX4927_IRQ_CHECK_PIC + { + if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + spin_lock_irqsave(&tx4927_pic_lock, flags); + + tx4927_irq_pic_modify(tx4927_irq_pic_addr(irq), 0, + tx4927_irq_pic_mask(irq)); + + spin_unlock_irqrestore(&tx4927_pic_lock, flags); + + return; +} + +static void tx4927_irq_pic_disable(unsigned int irq) +{ + unsigned long flags; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_DISABLE, "irq=%d\n", irq); + +#ifdef TX4927_IRQ_CHECK_PIC + { + if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + spin_lock_irqsave(&tx4927_pic_lock, flags); + + tx4927_irq_pic_modify(tx4927_irq_pic_addr(irq), + tx4927_irq_pic_mask(irq), 0); + + spin_unlock_irqrestore(&tx4927_pic_lock, flags); + + return; +} + +static void tx4927_irq_pic_mask_and_ack(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_MASK, "irq=%d\n", irq); + +#ifdef TX4927_IRQ_CHECK_PIC + { + if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + tx4927_irq_pic_disable(irq); + + return; +} + +static void tx4927_irq_pic_end(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_ENDIRQ, "irq=%d\n", irq); + +#ifdef TX4927_IRQ_CHECK_PIC + { + if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + tx4927_irq_pic_enable(irq); + } + + return; +} + +/* + * Main init functions + */ +void __init tx4927_irq_init(void) +{ + extern asmlinkage void tx4927_irq_handler(void); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "-\n"); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_cp0_init()\n"); + tx4927_irq_cp0_init(); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_pic_init()\n"); + tx4927_irq_pic_init(); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, + "=Calling set_except_vector(tx4927_irq_handler)\n"); + set_except_vector(0, tx4927_irq_handler); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "+\n"); + + return; +} + +int tx4927_irq_nested(void) +{ + int sw_irq = 0; + u32 level2; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST1, "-\n"); + + level2 = TX4927_RD(0xff1ff6a0); + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST2, "=level2a=0x%x\n", level2); + + if ((level2 & 0x10000) == 0) { + level2 &= 0x1f; + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST3, "=level2b=0x%x\n", level2); + + sw_irq = TX4927_IRQ_PIC_BEG + level2; + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST3, "=sw_irq=%d\n", sw_irq); + + if (sw_irq == 27) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST4, "=irq-%d\n", + sw_irq); + +#ifdef CONFIG_TOSHIBA_RBTX4927 + { + extern int toshiba_rbtx4927_irq_nested(int sw_irq); + + sw_irq = toshiba_rbtx4927_irq_nested(sw_irq); + } +#endif + + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST4, "=irq+%d\n", + sw_irq); + } + } + + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST2, "=sw_irq=%d\n", sw_irq); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST1, "+\n"); + + return (sw_irq); +} diff -urN linux-2.4.21-bk37/arch/mips/tx4927/common/tx4927_irq_handler.S linux-2.4.21-bk38/arch/mips/tx4927/common/tx4927_irq_handler.S --- linux-2.4.21-bk37/arch/mips/tx4927/common/tx4927_irq_handler.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/tx4927/common/tx4927_irq_handler.S 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,104 @@ +/* + * linux/arch/mips/tx4927/common/tx4927_irq_handler.S + * + * Primary interrupt handler for tx4927 based systems + * + * Author: MontaVista Software, Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include + + .align 5 + NESTED(tx4927_irq_handler, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + + mfc0 t0, CP0_CAUSE + mfc0 t1, CP0_STATUS + and t0, t1 + + andi t1, t0, STATUSF_IP7 /* cpu timer */ + bnez t1, ll_ip7 + + /* IP6..IP3 multiplexed -- do not use */ + + andi t1, t0, STATUSF_IP2 /* tx4927 pic */ + bnez t1, ll_ip2 + + andi t1, t0, STATUSF_IP0 /* user line 0 */ + bnez t1, ll_ip0 + + andi t1, t0, STATUSF_IP1 /* user line 1 */ + bnez t1, ll_ip1 + + .set reorder + + /* wrong alarm or masked ... */ + j spurious_interrupt + nop + END(tx4927_irq_handler) + + .align 5 + + +ll_ip7: + li a0, TX4927_IRQ_CPU_TIMER + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_ip2: + jal tx4927_irq_nested + nop + beqz v0, goto_spurious_interrupt + nop + move a0, v0 + move a1, sp + jal do_IRQ + j ret_from_irq + +goto_spurious_interrupt: + j spurious_interrupt + nop + +ll_ip1: + li a0, TX4927_IRQ_USER1 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_ip0: + li a0, TX4927_IRQ_USER0 + move a1, sp + jal do_IRQ + j ret_from_irq diff -urN linux-2.4.21-bk37/arch/mips/tx4927/common/tx4927_prom.c linux-2.4.21-bk38/arch/mips/tx4927/common/tx4927_prom.c --- linux-2.4.21-bk37/arch/mips/tx4927/common/tx4927_prom.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/tx4927/common/tx4927_prom.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,146 @@ +/* + * linux/arch/mips/tx4927/common/tx4927_prom.c + * + * common tx4927 memory interface + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include +#include +#include + +static unsigned int __init tx4927_process_sdccr(u64 * addr) +{ + u64 val; + unsigned int sdccr_ce; + unsigned int sdccr_bs; + unsigned int sdccr_rs; + unsigned int sdccr_cs; + unsigned int sdccr_mw; + unsigned int bs = 0; + unsigned int rs = 0; + unsigned int cs = 0; + unsigned int mw = 0; + unsigned int msize = 0; + + val = (*((vu64 *) (addr))); + + /* MVMCP -- need #defs for these bits masks */ + sdccr_ce = ((val & (1 << 10)) >> 10); + sdccr_bs = ((val & (1 << 8)) >> 8); + sdccr_rs = ((val & (3 << 5)) >> 5); + sdccr_cs = ((val & (3 << 2)) >> 2); + sdccr_mw = ((val & (1 << 0)) >> 0); + + if (sdccr_ce) { + switch (sdccr_bs) { + case 0:{ + bs = 2; + break; + } + case 1:{ + bs = 4; + break; + } + } + switch (sdccr_rs) { + case 0:{ + rs = 2048; + break; + } + case 1:{ + rs = 4096; + break; + } + case 2:{ + rs = 8192; + break; + } + case 3:{ + rs = 0; + break; + } + } + switch (sdccr_cs) { + case 0:{ + cs = 256; + break; + } + case 1:{ + cs = 512; + break; + } + case 2:{ + cs = 1024; + break; + } + case 3:{ + cs = 2048; + break; + } + } + switch (sdccr_mw) { + case 0:{ + mw = 8; + break; + } /* 8 bytes = 64 bits */ + case 1:{ + mw = 4; + break; + } /* 4 bytes = 32 bits */ + } + } + + /* bytes per chip MB per chip num chips */ + msize = (((rs * cs * mw) / (1024 * 1024)) * bs); + + return (msize); +} + + +unsigned int __init tx4927_get_mem_size(void) +{ + unsigned int c0; + unsigned int c1; + unsigned int c2; + unsigned int c3; + unsigned int total; + + /* MVMCP -- need #defs for these registers */ + c0 = tx4927_process_sdccr((u64 *) 0xff1f8000); + c1 = tx4927_process_sdccr((u64 *) 0xff1f8008); + c2 = tx4927_process_sdccr((u64 *) 0xff1f8010); + c3 = tx4927_process_sdccr((u64 *) 0xff1f8018); + total = c0 + c1 + c2 + c3; + + return (total); +} diff -urN linux-2.4.21-bk37/arch/mips/tx4927/common/tx4927_setup.c linux-2.4.21-bk38/arch/mips/tx4927/common/tx4927_setup.c --- linux-2.4.21-bk37/arch/mips/tx4927/common/tx4927_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/tx4927/common/tx4927_setup.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,251 @@ +/* + * linux/arch/mips/tx4927/common/tx4927_setup.c + * + * common tx4927 setup stuff + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#undef DEBUG + +void __init tx4927_setup(void); +void __init tx4927_time_init(void); +void __init tx4927_timer_setup(struct irqaction *irq); +void dump_cp0(char *key); + + +void (*__wbflush) (void); + +static void tx4927_write_buffer_flush(void) +{ + __asm__ __volatile__ + ("sync\n\t" "nop\n\t" "loop: bc0f loop\n\t" "nop\n\t"); +} + + +void __init tx4927_setup(void) +{ + board_time_init = tx4927_time_init; + board_timer_setup = tx4927_timer_setup; + __wbflush = tx4927_write_buffer_flush; + +#ifdef CONFIG_TOSHIBA_RBTX4927 + { + extern void toshiba_rbtx4927_setup(void); + toshiba_rbtx4927_setup(); + } +#endif + + return; +} + + +void __init tx4927_time_init(void) +{ + +#ifdef CONFIG_TOSHIBA_RBTX4927 + { + extern void toshiba_rbtx4927_time_init(void); + toshiba_rbtx4927_time_init(); + } +#endif + +#ifdef CONFIG_KGDB + { + printk("Calling breakpoint() -- start remote kgdb\n"); + set_debug_traps(); + breakpoint(); + printk("Calling breakpoint() -- done\n"); + } +#endif + + return; +} + + +void __init tx4927_timer_setup(struct irqaction *irq) +{ + u32 count; + u32 c1; + u32 c2; + + setup_irq(TX4927_IRQ_CPU_TIMER, irq); + + /* to generate the first timer interrupt */ + c1 = read_c0_count(); + count = c1 + (mips_counter_frequency / HZ); + write_c0_compare(count); + c2 = read_c0_count(); + +#ifdef CONFIG_TOSHIBA_RBTX4927 + { + extern void toshiba_rbtx4927_timer_setup(struct irqaction + *irq); + toshiba_rbtx4927_timer_setup(irq); + } +#endif + + return; +} + + +#ifdef DEBUG +void print_cp0(char *key, int num, char *name, u32 val) +{ + printk("%s cp0:%02d:%s=0x%08x\n", key, num, name, val); + return; +} + +indent: Standard input:25: Error:Unexpected end of file + +void +dump_cp0(char *key) +{ + if (key == NULL) + key = ""; + + print_cp0(key, 0, "INDEX ", read_c0_index()); + print_cp0(key, 2, "ENTRYLO1", read_c0_entrylo0()); + print_cp0(key, 3, "ENTRYLO2", read_c0_entrylo1()); + print_cp0(key, 4, "CONTEXT ", read_c0_context()); + print_cp0(key, 5, "PAGEMASK", read_c0_pagemask()); + print_cp0(key, 6, "WIRED ", read_c0_wired()); + //print_cp0(key, 8, "BADVADDR", read_c0_badvaddr()); + print_cp0(key, 9, "COUNT ", read_c0_count()); + print_cp0(key, 10, "ENTRYHI ", read_c0_entryhi()); + print_cp0(key, 11, "COMPARE ", read_c0_compare()); + print_cp0(key, 12, "STATUS ", read_c0_status()); + print_cp0(key, 13, "CAUSE ", read_c0_cause() & 0xffff87ff); + print_cp0(key, 16, "CONFIG ", read_c0_config()); + return; +} + +void print_pic(char *key, u32 reg, char *name) +{ + printk("%s pic:0x%08x:%s=0x%08x\n", key, reg, name, + TX4927_RD(reg)); + return; +} + + +void dump_pic(char *key) +{ + if (key == NULL) + key = ""; + + print_pic(key, 0xff1ff600, "IRDEN "); + print_pic(key, 0xff1ff604, "IRDM0 "); + print_pic(key, 0xff1ff608, "IRDM1 "); + + print_pic(key, 0xff1ff610, "IRLVL0 "); + print_pic(key, 0xff1ff614, "IRLVL1 "); + print_pic(key, 0xff1ff618, "IRLVL2 "); + print_pic(key, 0xff1ff61c, "IRLVL3 "); + print_pic(key, 0xff1ff620, "IRLVL4 "); + print_pic(key, 0xff1ff624, "IRLVL5 "); + print_pic(key, 0xff1ff628, "IRLVL6 "); + print_pic(key, 0xff1ff62c, "IRLVL7 "); + + print_pic(key, 0xff1ff640, "IRMSK "); + print_pic(key, 0xff1ff660, "IREDC "); + print_pic(key, 0xff1ff680, "IRPND "); + print_pic(key, 0xff1ff6a0, "IRCS "); + + print_pic(key, 0xff1ff514, "IRFLAG1 "); /* don't read IRLAG0 -- it hangs system */ + + print_pic(key, 0xff1ff518, "IRPOL "); + print_pic(key, 0xff1ff51c, "IRRCNT "); + print_pic(key, 0xff1ff520, "IRMASKINT"); + print_pic(key, 0xff1ff524, "IRMASKEXT"); + + return; +} + + +void print_addr(char *hdr, char *key, u32 addr) +{ + printk("%s %s:0x%08x=0x%08x\n", hdr, key, addr, TX4927_RD(addr)); + return; +} + + +void dump_180(char *key) +{ + u32 i; + + for (i = 0x80000180; i < 0x80000180 + 0x80; i += 4) { + print_addr("180", key, i); + } + return; +} + + +void dump_eh0(char *key) +{ + int i; + extern unsigned long exception_handlers[]; + + for (i = (int) exception_handlers; + i < (int) (exception_handlers + 20); i += 4) { + print_addr("eh0", key, i); + } + + return; +} + +void pk0(void) +{ + volatile u32 val; + + __asm__ __volatile__("ori %0, $26, 0":"=r"(val) + ); + printk("k0=[0x%08x]\n", val); +} +#endif diff -urN linux-2.4.21-bk37/arch/mips/tx4927/toshiba_rbtx4927/Makefile linux-2.4.21-bk38/arch/mips/tx4927/toshiba_rbtx4927/Makefile --- linux-2.4.21-bk37/arch/mips/tx4927/toshiba_rbtx4927/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/tx4927/toshiba_rbtx4927/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,20 @@ +# +# Makefile for Toshbia's RBTX4927 board +# +# Note! Dependencies are done automagically by 'make dep', which also +# 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:= toshiba_rbtx4927.o + +obj-y += toshiba_rbtx4927_prom.o +obj-y += toshiba_rbtx4927_setup.o +obj-y += toshiba_rbtx4927_irq.o + +obj-$(CONFIG_PCI) += toshiba_rbtx4927_pci_fixup.o +obj-$(CONFIG_PCI) += toshiba_rbtx4927_pci_ops.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c linux-2.4.21-bk38/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c --- linux-2.4.21-bk37/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,796 @@ +/* + * linux/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c + * + * Toshiba RBTX4927 specific interrupt handlers + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +/* +IRQ Device +00 RBTX4927-ISA/00 +01 RBTX4927-ISA/01 PS2/Keyboard +02 RBTX4927-ISA/02 Cascade RBTX4927-ISA (irqs 8-15) +03 RBTX4927-ISA/03 +04 RBTX4927-ISA/04 +05 RBTX4927-ISA/05 +06 RBTX4927-ISA/06 +07 RBTX4927-ISA/07 +08 RBTX4927-ISA/08 +09 RBTX4927-ISA/09 +10 RBTX4927-ISA/10 +11 RBTX4927-ISA/11 +12 RBTX4927-ISA/12 PS2/Mouse (not supported at this time) +13 RBTX4927-ISA/13 +14 RBTX4927-ISA/14 IDE +15 RBTX4927-ISA/15 + +16 TX4927-CP0/00 Software 0 +17 TX4927-CP0/01 Software 1 +18 TX4927-CP0/02 Cascade TX4927-CP0 +19 TX4927-CP0/03 Multiplexed -- do not use +20 TX4927-CP0/04 Multiplexed -- do not use +21 TX4927-CP0/05 Multiplexed -- do not use +22 TX4927-CP0/06 Multiplexed -- do not use +23 TX4927-CP0/07 CPU TIMER + +24 TX4927-PIC/00 +25 TX4927-PIC/01 +26 TX4927-PIC/02 +27 TX4927-PIC/03 Cascade RBTX4927-IOC +28 TX4927-PIC/04 +29 TX4927-PIC/05 RBTX4927 RTL-8019AS ethernet +30 TX4927-PIC/06 +31 TX4927-PIC/07 +32 TX4927-PIC/08 TX4927 SerialIO Channel 0 +33 TX4927-PIC/09 TX4927 SerialIO Channel 1 +34 TX4927-PIC/10 +35 TX4927-PIC/11 +36 TX4927-PIC/12 +37 TX4927-PIC/13 +38 TX4927-PIC/14 +39 TX4927-PIC/15 +40 TX4927-PIC/16 TX4927 PCI PCI-C +41 TX4927-PIC/17 +42 TX4927-PIC/18 +43 TX4927-PIC/19 +44 TX4927-PIC/20 +45 TX4927-PIC/21 +46 TX4927-PIC/22 TX4927 PCI PCI-ERR +47 TX4927-PIC/23 TX4927 PCI PCI-PMA (not used) +48 TX4927-PIC/24 +49 TX4927-PIC/25 +50 TX4927-PIC/26 +51 TX4927-PIC/27 +52 TX4927-PIC/28 +53 TX4927-PIC/29 +54 TX4927-PIC/30 +55 TX4927-PIC/31 + +56 RBTX4927-IOC/00 FPCIB0 PCI-D PJ4/A PJ5/B SB/C PJ6/D PJ7/A (SouthBridge/NotUsed) [RTL-8139=PJ4] +57 RBTX4927-IOC/01 FPCIB0 PCI-C PJ4/D PJ5/A SB/B PJ6/C PJ7/D (SouthBridge/NotUsed) [RTL-8139=PJ5] +58 RBTX4927-IOC/02 FPCIB0 PCI-B PJ4/C PJ5/D SB/A PJ6/B PJ7/C (SouthBridge/IDE/pin=1,INTR) [RTL-8139=NotSupported] +59 RBTX4927-IOC/03 FPCIB0 PCI-A PJ4/B PJ5/C SB/D PJ6/A PJ7/B (SouthBridge/USB/pin=4) [RTL-8139=PJ6] +60 RBTX4927-IOC/04 +61 RBTX4927-IOC/05 +62 RBTX4927-IOC/06 +63 RBTX4927-IOC/07 + +NOTES: +SouthBridge/INTR is mapped to SouthBridge/A=PCI-B/#58 +SouthBridge/ISA/pin=0 no pci irq used by this device +SouthBridge/IDE/pin=1 no pci irq used by this device, using INTR via ISA IRQ14 +SouthBridge/USB/pin=4 using pci irq SouthBridge/D=PCI-A=#59 +SouthBridge/PMC/pin=0 no pci irq used by this device +SuperIO/PS2/Keyboard, using INTR via ISA IRQ1 +SuperIO/PS2/Mouse, using INTR via ISA IRQ12 (mouse not currently supported) +JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthBridge, JP4, JP5, JP6 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_RTC_DS1742 +#include +#endif +#ifdef CONFIG_TOSHIBA_FPCIB0 +#include +#endif +#include + + +#undef TOSHIBA_RBTX4927_IRQ_DEBUG + +#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG +#define TOSHIBA_RBTX4927_IRQ_NONE 0x00000000 + +#define TOSHIBA_RBTX4927_IRQ_INFO ( 1 << 0 ) +#define TOSHIBA_RBTX4927_IRQ_WARN ( 1 << 1 ) +#define TOSHIBA_RBTX4927_IRQ_EROR ( 1 << 2 ) + +#define TOSHIBA_RBTX4927_IRQ_IOC_INIT ( 1 << 10 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_STARTUP ( 1 << 11 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN ( 1 << 12 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_ENABLE ( 1 << 13 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_DISABLE ( 1 << 14 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_MASK ( 1 << 15 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ ( 1 << 16 ) + +#define TOSHIBA_RBTX4927_IRQ_ISA_INIT ( 1 << 20 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_STARTUP ( 1 << 21 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN ( 1 << 22 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_ENABLE ( 1 << 23 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_DISABLE ( 1 << 24 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_MASK ( 1 << 25 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_ENDIRQ ( 1 << 26 ) + +#define TOSHIBA_RBTX4927_SETUP_ALL 0xffffffff +#endif + + +#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG +static const u32 toshiba_rbtx4927_irq_debug_flag = + (TOSHIBA_RBTX4927_IRQ_NONE | TOSHIBA_RBTX4927_IRQ_INFO | + TOSHIBA_RBTX4927_IRQ_WARN | TOSHIBA_RBTX4927_IRQ_EROR +// | TOSHIBA_RBTX4927_IRQ_IOC_INIT +// | TOSHIBA_RBTX4927_IRQ_IOC_STARTUP +// | TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN +// | TOSHIBA_RBTX4927_IRQ_IOC_ENABLE +// | TOSHIBA_RBTX4927_IRQ_IOC_DISABLE +// | TOSHIBA_RBTX4927_IRQ_IOC_MASK +// | TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ +// | TOSHIBA_RBTX4927_IRQ_ISA_INIT +// | TOSHIBA_RBTX4927_IRQ_ISA_STARTUP +// | TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN +// | TOSHIBA_RBTX4927_IRQ_ISA_ENABLE +// | TOSHIBA_RBTX4927_IRQ_ISA_DISABLE +// | TOSHIBA_RBTX4927_IRQ_ISA_MASK +// | TOSHIBA_RBTX4927_IRQ_ISA_ENDIRQ + ); +#endif + + +#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG +#define TOSHIBA_RBTX4927_IRQ_DPRINTK(flag,str...) \ + if ( (toshiba_rbtx4927_irq_debug_flag) & (flag) ) \ + { \ + char tmp[100]; \ + sprintf( tmp, str ); \ + printk( "%s(%s:%u)::%s", __FUNCTION__, __FILE__, __LINE__, tmp ); \ + } +#else +#define TOSHIBA_RBTX4927_IRQ_DPRINTK(flag,str...) +#endif + + + + +#define TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG 0 +#define TOSHIBA_RBTX4927_IRQ_IOC_RAW_END 7 + +#define TOSHIBA_RBTX4927_IRQ_IOC_BEG ((TX4927_IRQ_PIC_END+1)+TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG) /* 56 */ +#define TOSHIBA_RBTX4927_IRQ_IOC_END ((TX4927_IRQ_PIC_END+1)+TOSHIBA_RBTX4927_IRQ_IOC_RAW_END) /* 63 */ + + +#define TOSHIBA_RBTX4927_IRQ_ISA_BEG MI8259_IRQ_ISA_BEG +#define TOSHIBA_RBTX4927_IRQ_ISA_END MI8259_IRQ_ISA_END +#define TOSHIBA_RBTX4927_IRQ_ISA_MID ((TOSHIBA_RBTX4927_IRQ_ISA_BEG+TOSHIBA_RBTX4927_IRQ_ISA_END+1)/2) + + +#define TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC TX4927_IRQ_NEST_EXT_ON_PIC +#define TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC (TOSHIBA_RBTX4927_IRQ_IOC_BEG+2) +#define TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_ISA (TOSHIBA_RBTX4927_IRQ_ISA_BEG+2) + +extern int tx4927_using_backplane; + +#ifdef CONFIG_TOSHIBA_FPCIB0 +extern void enable_8259A_irq(unsigned int irq); +extern void disable_8259A_irq(unsigned int irq); +extern void mask_and_ack_8259A(unsigned int irq); +#endif + +static unsigned int toshiba_rbtx4927_irq_ioc_startup(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_shutdown(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_mask_and_ack(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq); + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static unsigned int toshiba_rbtx4927_irq_isa_startup(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_shutdown(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_enable(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_disable(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_mask_and_ack(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_end(unsigned int irq); +#endif + +static spinlock_t toshiba_rbtx4927_ioc_lock = SPIN_LOCK_UNLOCKED; + + +#define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC" +static struct hw_interrupt_type toshiba_rbtx4927_irq_ioc_type = { + typename:TOSHIBA_RBTX4927_IOC_NAME, + startup:toshiba_rbtx4927_irq_ioc_startup, + shutdown:toshiba_rbtx4927_irq_ioc_shutdown, + enable:toshiba_rbtx4927_irq_ioc_enable, + disable:toshiba_rbtx4927_irq_ioc_disable, + ack:toshiba_rbtx4927_irq_ioc_mask_and_ack, + end:toshiba_rbtx4927_irq_ioc_end, + set_affinity:NULL +}; +#define TOSHIBA_RBTX4927_IOC_INTR_ENAB 0xbc002000 +#define TOSHIBA_RBTX4927_IOC_INTR_STAT 0xbc002006 + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +#define TOSHIBA_RBTX4927_ISA_NAME "RBTX4927-ISA" +static struct hw_interrupt_type toshiba_rbtx4927_irq_isa_type = { + typename:TOSHIBA_RBTX4927_ISA_NAME, + startup:toshiba_rbtx4927_irq_isa_startup, + shutdown:toshiba_rbtx4927_irq_isa_shutdown, + enable:toshiba_rbtx4927_irq_isa_enable, + disable:toshiba_rbtx4927_irq_isa_disable, + ack:toshiba_rbtx4927_irq_isa_mask_and_ack, + end:toshiba_rbtx4927_irq_isa_end, + set_affinity:NULL +}; +#endif + + +u32 bit2num(u32 num) +{ + u32 i; + + for (i = 0; i < (sizeof(num) * 8); i++) { + if (num & (1 << i)) { + return (i); + } + } + return (0); +} + +int toshiba_rbtx4927_irq_nested(int sw_irq) +{ + u32 level3; + + level3 = reg_rd08(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f; + if (level3) { + sw_irq = TOSHIBA_RBTX4927_IRQ_IOC_BEG + bit2num(level3); + if (sw_irq != TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC) { + goto RETURN; + } + } +#ifdef CONFIG_TOSHIBA_FPCIB0 + { + u32 level4; + u32 level5; + + if (tx4927_using_backplane) { + outb(0x0A, 0x20); + level4 = inb(0x20) & 0xff; + if (level4) { + sw_irq = + TOSHIBA_RBTX4927_IRQ_ISA_BEG + + bit2num(level4); + if (sw_irq != + TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_ISA) { + goto RETURN; + } + } + + outb(0x0A, 0xA0); + level5 = inb(0xA0) & 0xff; + if (level5) { + sw_irq = + TOSHIBA_RBTX4927_IRQ_ISA_MID + + bit2num(level5); + goto RETURN; + } + } + } +#endif + + RETURN: + return (sw_irq); +} + +//#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, 0, 0, s, NULL, NULL } +#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, SA_SHIRQ, 0, s, NULL, NULL } +static struct irqaction toshiba_rbtx4927_irq_ioc_action = +TOSHIBA_RBTX4927_PIC_ACTION(TOSHIBA_RBTX4927_IOC_NAME); +#ifdef CONFIG_TOSHIBA_FPCIB0 +static struct irqaction toshiba_rbtx4927_irq_isa_master = +TOSHIBA_RBTX4927_PIC_ACTION(TOSHIBA_RBTX4927_ISA_NAME "/M"); +static struct irqaction toshiba_rbtx4927_irq_isa_slave = +TOSHIBA_RBTX4927_PIC_ACTION(TOSHIBA_RBTX4927_ISA_NAME "/S"); +#endif + + +/**********************************************************************************/ +/* Functions for ioc */ +/**********************************************************************************/ + + +static void __init toshiba_rbtx4927_irq_ioc_init(void) +{ + int i; + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_INIT, + "beg=%d end=%d\n", + TOSHIBA_RBTX4927_IRQ_IOC_BEG, + TOSHIBA_RBTX4927_IRQ_IOC_END); + + for (i = TOSHIBA_RBTX4927_IRQ_IOC_BEG; + i <= TOSHIBA_RBTX4927_IRQ_IOC_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 3; + irq_desc[i].handler = &toshiba_rbtx4927_irq_ioc_type; + } + + setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC, + &toshiba_rbtx4927_irq_ioc_action); + + return; +} + +static unsigned int toshiba_rbtx4927_irq_ioc_startup(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_STARTUP, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_ioc_enable(irq); + + return (0); +} + + +static void toshiba_rbtx4927_irq_ioc_shutdown(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_ioc_disable(irq); + + return; +} + + +static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq) +{ + unsigned long flags; + volatile unsigned char v; + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_ENABLE, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + spin_lock_irqsave(&toshiba_rbtx4927_ioc_lock, flags); + + v = TX4927_RD08(TOSHIBA_RBTX4927_IOC_INTR_ENAB); + v |= (1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); + TOSHIBA_RBTX4927_WR08(TOSHIBA_RBTX4927_IOC_INTR_ENAB, v); + + spin_unlock_irqrestore(&toshiba_rbtx4927_ioc_lock, flags); + + return; +} + + +static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq) +{ + unsigned long flags; + volatile unsigned char v; + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_DISABLE, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + spin_lock_irqsave(&toshiba_rbtx4927_ioc_lock, flags); + + v = TX4927_RD08(TOSHIBA_RBTX4927_IOC_INTR_ENAB); + v &= ~(1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); + TOSHIBA_RBTX4927_WR08(TOSHIBA_RBTX4927_IOC_INTR_ENAB, v); + + spin_unlock_irqrestore(&toshiba_rbtx4927_ioc_lock, flags); + + return; +} + + +static void toshiba_rbtx4927_irq_ioc_mask_and_ack(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_MASK, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_ioc_disable(irq); + + return; +} + + +static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + toshiba_rbtx4927_irq_ioc_enable(irq); + } + + return; +} + + +/**********************************************************************************/ +/* Functions for isa */ +/**********************************************************************************/ + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void __init toshiba_rbtx4927_irq_isa_init(void) +{ + int i; + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_INIT, + "beg=%d end=%d\n", + TOSHIBA_RBTX4927_IRQ_ISA_BEG, + TOSHIBA_RBTX4927_IRQ_ISA_END); + + for (i = TOSHIBA_RBTX4927_IRQ_ISA_BEG; + i <= TOSHIBA_RBTX4927_IRQ_ISA_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = + ((i < TOSHIBA_RBTX4927_IRQ_ISA_MID) ? (4) : (5)); + irq_desc[i].handler = &toshiba_rbtx4927_irq_isa_type; + } + + setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC, + &toshiba_rbtx4927_irq_isa_master); + setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_ISA, + &toshiba_rbtx4927_irq_isa_slave); + + /* make sure we are looking at IRR (not ISR) */ + outb(0x0A, 0x20); + outb(0x0A, 0xA0); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static unsigned int toshiba_rbtx4927_irq_isa_startup(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_STARTUP, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_isa_enable(irq); + + return (0); +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_shutdown(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_isa_disable(irq); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_enable(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_ENABLE, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + enable_8259A_irq(irq); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_disable(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_DISABLE, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + disable_8259A_irq(irq); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_mask_and_ack(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_MASK, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + mask_and_ack_8259A(irq); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_end(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_ENDIRQ, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + toshiba_rbtx4927_irq_isa_enable(irq); + } + + return; +} +#endif + + +void __init init_IRQ(void) +{ + extern void tx4927_irq_init(void); + + cli(); + + tx4927_irq_init(); + toshiba_rbtx4927_irq_ioc_init(); +#ifdef CONFIG_TOSHIBA_FPCIB0 + { + if (tx4927_using_backplane) { + toshiba_rbtx4927_irq_isa_init(); + } + } +#endif + +#ifdef CONFIG_PCI + { + extern void toshiba_rbtx4927_pci_irq_init(void); + toshiba_rbtx4927_pci_irq_init(); + } +#endif + + wbflush(); + + return; +} + +void toshiba_rbtx4927_irq_dump(char *key) +{ +#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG + { + u32 i, j = 0; + for (i = 0; i < NR_IRQS; i++) { + if (strcmp(irq_desc[i].handler->typename, "none") + == 0) + continue; + + if ((i >= 1) + && (irq_desc[i - 1].handler->typename == + irq_desc[i].handler->typename)) { + j++; + } else { + j = 0; + } + TOSHIBA_RBTX4927_IRQ_DPRINTK + (TOSHIBA_RBTX4927_IRQ_INFO, + "%s irq=0x%02x/%3d s=0x%08x h=0x%08x a=0x%08x ah=0x%08x d=%1d n=%s/%02d\n", + key, i, i, irq_desc[i].status, + (u32) irq_desc[i].handler, + (u32) irq_desc[i].action, + (u32) (irq_desc[i].action ? irq_desc[i]. + action->handler : 0), + irq_desc[i].depth, + irq_desc[i].handler->typename, j); + } + } +#endif + return; +} + +void toshiba_rbtx4927_irq_dump_pics(char *s) +{ + u32 level0_m; + u32 level0_s; + u32 level1_m; + u32 level1_s; + u32 level2; + u32 level2_p; + u32 level2_s; + u32 level3_m; + u32 level3_s; + u32 level4_m; + u32 level4_s; + u32 level5_m; + u32 level5_s; + + if (s == NULL) + s = "null"; + + level0_m = (read_c0_status() & 0x0000ff00) >> 8; + level0_s = (read_c0_cause() & 0x0000ff00) >> 8; + + level1_m = level0_m; + level1_s = level0_s & 0x87; + + level2 = TX4927_RD(0xff1ff6a0); + level2_p = (((level2 & 0x10000)) ? 0 : 1); + level2_s = (((level2 & 0x1f) == 0x1f) ? 0 : (level2 & 0x1f)); + + level3_m = reg_rd08(TOSHIBA_RBTX4927_IOC_INTR_ENAB) & 0x1f; + level3_s = reg_rd08(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f; + + level4_m = inb(0x21); + outb(0x0A, 0x20); + level4_s = inb(0x20); + + level5_m = inb(0xa1); + outb(0x0A, 0xa0); + level5_s = inb(0xa0); + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "dump_raw_pic() "); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "cp0:m=0x%02x/s=0x%02x ", level0_m, + level0_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "cp0:m=0x%02x/s=0x%02x ", level1_m, + level1_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "pic:e=0x%02x/s=0x%02x ", level2_p, + level2_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "ioc:m=0x%02x/s=0x%02x ", level3_m, + level3_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "sbm:m=0x%02x/s=0x%02x ", level4_m, + level4_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "sbs:m=0x%02x/s=0x%02x ", level5_m, + level5_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, "[%s]\n", + s); + + return; +} diff -urN linux-2.4.21-bk37/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_fixup.c linux-2.4.21-bk38/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_fixup.c --- linux-2.4.21-bk37/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_fixup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_fixup.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,329 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Board specific pci fixups for the Toshiba rbtx4927 + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include + +#include +#include + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ + /* will need to fixup IO resources */ +} + +void __init pcibios_fixup(void) +{ + /* nothing to do here */ +} + +/* look up table for backplane pci irq for slots 17-20 by pin # */ +static unsigned char backplane_pci_irq[4][4] = { + /* PJ6 SLOT: 17, PIN: 1 */ {TX4927_IRQ_IOC_PCIA, + /* PJ6 SLOT: 17, PIN: 2 */ + TX4927_IRQ_IOC_PCIB, + /* PJ6 SLOT: 17, PIN: 3 */ + TX4927_IRQ_IOC_PCIC, + /* PJ6 SLOT: 17, PIN: 4 */ + TX4927_IRQ_IOC_PCID}, + /* SB SLOT: 18, PIN: 1 */ {TX4927_IRQ_IOC_PCIB, + /* SB SLOT: 18, PIN: 2 */ + TX4927_IRQ_IOC_PCIC, + /* SB SLOT: 18, PIN: 3 */ + TX4927_IRQ_IOC_PCID, + /* SB SLOT: 18, PIN: 4 */ + TX4927_IRQ_IOC_PCIA}, + /* PJ5 SLOT: 19, PIN: 1 */ {TX4927_IRQ_IOC_PCIC, + /* PJ5 SLOT: 19, PIN: 2 */ + TX4927_IRQ_IOC_PCID, + /* PJ5 SLOT: 19, PIN: 3 */ + TX4927_IRQ_IOC_PCIA, + /* PJ5 SLOT: 19, PIN: 4 */ + TX4927_IRQ_IOC_PCIB}, + /* PJ4 SLOT: 20, PIN: 1 */ {TX4927_IRQ_IOC_PCID, + /* PJ4 SLOT: 20, PIN: 2 */ + TX4927_IRQ_IOC_PCIA, + /* PJ4 SLOT: 20, PIN: 3 */ + TX4927_IRQ_IOC_PCIB, + /* PJ4 SLOT: 20, PIN: 4 */ + TX4927_IRQ_IOC_PCIC} +}; + +int pci_get_irq(struct pci_dev *dev, int pin) +{ + unsigned char irq = pin; + + DBG("pci_get_irq: pin is %d\n", pin); + /* IRQ rotation */ + irq--; /* 0-3 */ + if (dev->bus->parent == NULL && + PCI_SLOT(dev->devfn) == TX4927_PCIC_IDSEL_AD_TO_SLOT(23)) { + printk("Onboard PCI_SLOT(dev->devfn) is %d\n", + PCI_SLOT(dev->devfn)); + /* IDSEL=A23 is tx4927 onboard pci slot */ + irq = (irq + PCI_SLOT(dev->devfn)) % 4; + irq++; /* 1-4 */ + DBG("irq is now %d\n", irq); + + switch (irq) { + case 1: + irq = TX4927_IRQ_IOC_PCIA; + break; + case 2: + irq = TX4927_IRQ_IOC_PCIB; + break; + case 3: + irq = TX4927_IRQ_IOC_PCIC; + break; + case 4: + irq = TX4927_IRQ_IOC_PCID; + break; + } + } else { + /* PCI Backplane */ + DBG("PCI Backplane PCI_SLOT(dev->devfn) is %d\n", + PCI_SLOT(dev->devfn)); + irq = backplane_pci_irq[PCI_SLOT(dev->devfn) - 17][irq]; + } + DBG("assigned irq %d\n", irq); + return irq; +} + + +#ifdef TX4927_SUPPORT_PCI_66 +extern int tx4927_pci66; +extern void tx4927_pci66_setup(void); +#endif +extern void tx4927_pci_setup(void); + +#ifdef TX4927_SUPPORT_PCI_66 +int tx4927_pci66_check(void) +{ + struct pci_dev *dev; + unsigned short stat; + int cap66 = 1; + + if (tx4927_pci66 < 0) + return 0; + + /* check 66MHz capability */ + pci_for_each_dev(dev) { + if (cap66) { + pci_read_config_word(dev, PCI_STATUS, &stat); + if (!(stat & PCI_STATUS_66MHZ)) { + printk(KERN_INFO + "PCI: %02x:%02x not 66MHz capable.\n", + dev->bus->number, dev->devfn); + cap66 = 0; + } + } + } + return cap66; +} +#endif + +#ifdef DEBUG +void do_it(u32 offset, u32 reg) +{ + volatile u32 a1; + volatile u32 a2; + volatile u32 v1; + volatile u32 v2; + + a1 = 0xff1f0000 + offset + reg; + a2 = a1 + 4; + + v1 = *(volatile u32 *) a1; + v2 = *(volatile u32 *) a2; + + if (v1) + printk("TX4927 0x%08x 0x%08x\n", a1, v1); + if (v2) + printk("TX4927 0x%08x 0x%08x\n", a2, v2); +} + +void do_it1(u32 base, u32 r) +{ + do_it(base, r); +} + +void do_it2(u32 base, u32 start, u32 stop) +{ + u32 r; + + for (r = start; r <= stop; r += 8) { + do_it(base, r); + } +} +void dump_config(void) +{ + unsigned long id; + unsigned long j; + struct pci_dev *dev; + + printk("----------------------pci\n"); + pci_for_each_dev(dev) { + for (j = 0; j < 64; j++) { + pci_read_config_dword(dev, j * 4, &id); + if (id == 0) + continue; + printk + ("dev 0x%02x 0x%02x:0x%02x -- 0x%02x-0x%02x 0x%08x\n", + dev->devfn, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn), (j * 4) + 3, (j * 4), + id); + } + printk("dev 0x%02x \n", dev->devfn); + } + printk("----------------------sdram\n"); + do_it2(0x8000, 0x00, 0x18); + do_it1(0x8000, 0x40); + do_it1(0x8000, 0x58); + printk("----------------------ebus\n"); + do_it2(0x9000, 0x00, 0x38); + printk("----------------------ecc\n"); + do_it2(0xa000, 0x00, 0x08); + printk("----------------------dmac\n"); + do_it2(0xb000, 0x00, 0xf8); + /* b1xx */ + printk("----------------------pci\n"); + /* d */ + printk("----------------------cfg\n"); + do_it2(0xe000, 0x00, 0x20); + do_it1(0xe000, 0x30); + do_it1(0xe000, 0x48); + printk("----------------------timers\n"); + do_it2(0xf000, 0x00, 0xf0); + do_it2(0xf100, 0x00, 0xf0); + do_it2(0xf200, 0x00, 0xf0); + printk("----------------------serial\n"); + do_it2(0xf300, 0x00, 0x20); + do_it2(0xf400, 0x00, 0x20); + printk("----------------------parallel\n"); + do_it2(0xf500, 0x00, 0x0c); + printk("----------------------pic\n"); + do_it2(0xf500, 0x10, 0x24); + do_it2(0xf600, 0x00, 0x2c); + do_it1(0xf600, 0x40); + do_it1(0xf600, 0x60); + do_it1(0xf600, 0x80); + do_it1(0xf600, 0xa0); + printk("----------------------aclink\n"); + do_it2(0xf700, 0x00, 0xfc); + printk("----------------------done\n"); +} +#endif + + +void __init pcibios_fixup_irqs(void) +{ + unsigned char pin; + unsigned char irq; + struct pci_dev *dev; + unsigned int id; + +#ifdef TX4927_SUPPORT_PCI_66 + { + if (tx4927_pci66_check()) { + tx4927_pci66_setup(); + tx4927_pci_setup(); /* Reinitialize PCIC */ + } + } +#endif + + pci_for_each_dev(dev) { + DBG("FIXUP:\n"); + DBG(" devfn=0x%02x (0x%02x:0x%02x)\n", + dev->devfn, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn)); + + pci_read_config_dword(dev, PCI_VENDOR_ID, &id); + DBG(" id=0x%08x\n", id); + + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); + DBG(" line=0x%02x/%d\n", irq, irq); + + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + DBG(" pin=%d\n", pin); + +#ifdef DEBUG + { + unsigned int tmp; + pci_read_config_dword(dev, 0x10, &tmp); + DBG(" bar0:0x10=0x%08x\n", tmp); + pci_read_config_dword(dev, 0x14, &tmp); + DBG(" bar1:0x14=0x%08x\n", tmp); + pci_read_config_dword(dev, 0x1c, &tmp); + DBG(" bar2:0x1c=0x%08x\n", tmp); + pci_read_config_dword(dev, 0x20, &tmp); + DBG(" bar3:0x20=0x%08x\n", tmp); + pci_read_config_dword(dev, 0x24, &tmp); + DBG(" bar4:0x24=0x%08x\n", tmp); + } +#endif + + irq = 0; + + if (id == 0x91301055) { /* ide */ + irq = 14; + } + + if (pin == 0) { + DBG(" auto irq (now=%d) -- skipping pin=0\n", irq); + } else if (irq) { + DBG(" auto irq (now=%d) -- skipping hardcoded irq\n", irq); + } else { + DBG(" auto irq (was=%d)\n", irq); + irq = pci_get_irq(dev, pin); + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + irq); + dev->irq = irq; + DBG(" auto irq (now=%d)\n", irq); + } + + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); + printk(KERN_INFO + "PCI: 0x%02x:0x%02x(0x%02x,0x%02x) IRQ=%d\n", + dev->bus->number, dev->devfn, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn), irq); + + } + +} diff -urN linux-2.4.21-bk37/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_ops.c linux-2.4.21-bk38/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_ops.c --- linux-2.4.21-bk37/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_ops.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_ops.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,317 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c + * + * Define the pci_ops for the Toshiba rbtx4927 + * + * Much of the code is derived from the original DDB5074 port by + * Geert Uytterhoeven + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include + +#include +#include +#include +#include + +/* initialize in setup */ +struct resource pci_io_resource = { + "pci IO space", + (PCIBIOS_MIN_IO), + ((PCIBIOS_MIN_IO) + (TX4927_PCIIO_SIZE)) - 1, + IORESOURCE_IO +}; + +/* initialize in setup */ +struct resource pci_mem_resource = { + "pci memory space", + TX4927_PCIMEM, + TX4927_PCIMEM + TX4927_PCIMEM_SIZE - 1, + IORESOURCE_MEM +}; + +extern struct pci_ops tx4927_pci_ops; + +struct pci_channel mips_pci_channels[] = { + /* h/w only supports devices 0x00 to 0x14 */ + {&tx4927_pci_ops, &pci_io_resource, &pci_mem_resource, + PCI_DEVFN(0x00, 0), PCI_DEVFN(0x14, 7)}, + {NULL, NULL, NULL, 0, 0} +}; + +unsigned int pcibios_assign_all_busses(void) +{ + return 1; +} + +static int +mkaddr(unsigned char bus, unsigned char dev_fn, unsigned char where, + int *flagsp) +{ + if (bus > 0) { + /* Type 1 configuration */ + tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | + ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1; + } else { + if (dev_fn >= PCI_DEVFN(TX4927_PCIC_MAX_DEVNU, 0)) + return -1; + + /* Type 0 configuration */ + tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | + ((dev_fn & 0xff) << 0x08) | (where & 0xfc); + } + /* clear M_ABORT and Disable M_ABORT Int. */ + tx4927_pcicptr->pcistatus = + (tx4927_pcicptr->pcistatus & 0x0000ffff) | + (PCI_STATUS_REC_MASTER_ABORT << 16); + tx4927_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT; + return 0; +} + +static int check_abort(int flags) +{ + int code = PCIBIOS_SUCCESSFUL; + if (tx4927_pcicptr-> + pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) { + tx4927_pcicptr->pcistatus = + (tx4927_pcicptr-> + pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT + << 16); + tx4927_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT; + code = PCIBIOS_DEVICE_NOT_FOUND; + // printk("returning PCIBIOS_DEVICE_NOT_FOUND\n"); + } + return code; +} + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int tx4927_pcibios_read_config_byte(struct pci_dev *dev, + int where, unsigned char *val) +{ + int flags, retval; + unsigned char bus, func_num; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; +#ifdef __BIG_ENDIAN + *val = + *(volatile u8 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | ((where & 3) ^ 3)); +#else + *val = + *(volatile u8 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | (where & 3)); +#endif + retval = check_abort(flags); + if (retval == PCIBIOS_DEVICE_NOT_FOUND) + *val = 0xff; +//printk("CFG R1 0x%02x 0x%02x 0x%08x\n", dev->devfn, where, *val ); + return retval; +} + +static int tx4927_pcibios_read_config_word(struct pci_dev *dev, + int where, unsigned short *val) +{ + int flags, retval; + unsigned char bus, func_num; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; +#ifdef __BIG_ENDIAN + *val = + *(volatile u16 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | ((where & 3) ^ 2)); +#else + *val = + *(volatile u16 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | (where & 3)); +#endif + retval = check_abort(flags); + if (retval == PCIBIOS_DEVICE_NOT_FOUND) + *val = 0xffff; +//printk("CFG R2 0x%02x 0x%02x 0x%08x\n", dev->devfn, where, *val ); + return retval; +} + +static int tx4927_pcibios_read_config_dword(struct pci_dev *dev, + int where, unsigned int *val) +{ + int flags, retval; + unsigned char bus, func_num; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; + *val = tx4927_pcicptr->g2pcfgdata; + retval = check_abort(flags); + if (retval == PCIBIOS_DEVICE_NOT_FOUND) + *val = 0xffffffff; + +//printk("CFG R4 0x%02x 0x%02x 0x%08x\n", dev->devfn, where, *val ); + return retval; +} + +static int tx4927_pcibios_write_config_byte(struct pci_dev *dev, + int where, unsigned char val) +{ + int flags; + unsigned char bus, func_num; + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; +#ifdef __BIG_ENDIAN + *(volatile u8 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | ((where & 3) ^ 3)) = val; +#else + *(volatile u8 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | (where & 3)) = val; +#endif +//printk("CFG W1 0x%02x 0x%02x 0x%08x\n", dev->devfn, where, val ); + return check_abort(flags); +} + +static int tx4927_pcibios_write_config_word(struct pci_dev *dev, + int where, unsigned short val) +{ + int flags; + unsigned char bus, func_num; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; +#ifdef __BIG_ENDIAN + *(volatile u16 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | ((where & 3) ^ 2)) = val; +#else + *(volatile u16 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | (where & 3)) = val; +#endif +//printk("CFG W2 0x%02x 0x%02x 0x%08x\n", dev->devfn, where, val ); + return check_abort(flags); +} + +static int tx4927_pcibios_write_config_dword(struct pci_dev *dev, + int where, unsigned int val) +{ + int flags; + unsigned char bus, func_num; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; + tx4927_pcicptr->g2pcfgdata = val; +//printk("CFG W4 0x%02x 0x%02x 0x%08x\n", dev->devfn, where, val ); + return check_abort(flags); +} + +struct pci_ops tx4927_pci_ops = { + tx4927_pcibios_read_config_byte, + tx4927_pcibios_read_config_word, + tx4927_pcibios_read_config_dword, + tx4927_pcibios_write_config_byte, + tx4927_pcibios_write_config_word, + tx4927_pcibios_write_config_dword +}; diff -urN linux-2.4.21-bk37/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c linux-2.4.21-bk38/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c --- linux-2.4.21-bk37/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,96 @@ +/* + * rbtx4927 specific prom routines + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifndef COMMAND_LINE_SIZE +#define COMMAND_LINE_SIZE CL_SIZE +#endif + +char arcs_cmdline[COMMAND_LINE_SIZE] = "console=ttyS0,38400 ip=any root=nfs rw"; + +void __init prom_init_cmdline(int argc, char **argv) +{ + int i; /* Always ignore the "-c" at argv[0] */ + + /* ignore all built-in args if any f/w args given */ + if (argc > 1) { + *arcs_cmdline = '\0'; + } + + for (i = 1; i < argc; i++) { + if (i != 1) { + strcat(arcs_cmdline, " "); + } + strcat(arcs_cmdline, argv[i]); + } +} + +void __init prom_init(int argc, char **argv, char **envp, int *pvec) +{ + extern int tx4927_get_mem_size(void); + int msize; + char* toshiba_name_list[] = GROUP_TOSHIBA_NAMES; + extern char* toshiba_name; + + prom_init_cmdline(argc, argv); + + mips_machgroup = MACH_GROUP_TOSHIBA; + + if ((read_c0_prid() & 0xff) == PRID_REV_TX4927) + mips_machtype = MACH_TOSHIBA_RBTX4927; + else + mips_machtype = MACH_TOSHIBA_RBTX4937; + + toshiba_name = toshiba_name_list[mips_machtype]; + + msize = tx4927_get_mem_size(); + add_memory_region(0, msize << 20, BOOT_MEM_RAM); +} + +void __init prom_free_prom_memory(void) +{ +} + + +void __init prom_fixup_mem_map(unsigned long start, unsigned long end) +{ +} + +const char *get_system_type(void) +{ + return "Toshiba RBTX4927/RBTX4937"; +} diff -urN linux-2.4.21-bk37/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c linux-2.4.21-bk38/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c --- linux-2.4.21-bk37/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,1219 @@ +/* + * Toshiba rbtx4927 specific setup + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * Copyright (C) 1996, 1997, 2001 Ralf Baechle + * Copyright (C) 2000 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * Copyright 2002 MontaVista Software Inc. + * Author: Michael Pruznick, michael_pruznick@mvista.com + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_RTC_DS1742 +#include +#endif +#ifdef CONFIG_TOSHIBA_FPCIB0 +#include +#endif +#include +#ifdef CONFIG_PCI +#include +#include +#include +#include +#include +#include +#endif +#ifdef CONFIG_PC_KEYB +#include +#endif +#ifdef CONFIG_BLK_DEV_IDEPCI +#include +#include +#include +extern struct ide_ops std_ide_ops; +#endif + +#undef TOSHIBA_RBTX4927_SETUP_DEBUG + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG +#define TOSHIBA_RBTX4927_SETUP_NONE 0x00000000 + +#define TOSHIBA_RBTX4927_SETUP_INFO ( 1 << 0 ) +#define TOSHIBA_RBTX4927_SETUP_WARN ( 1 << 1 ) +#define TOSHIBA_RBTX4927_SETUP_EROR ( 1 << 2 ) + +#define TOSHIBA_RBTX4927_SETUP_EFWFU ( 1 << 3 ) +#define TOSHIBA_RBTX4927_SETUP_SETUP ( 1 << 4 ) +#define TOSHIBA_RBTX4927_SETUP_TIME_INIT ( 1 << 5 ) +#define TOSHIBA_RBTX4927_SETUP_TIMER_SETUP ( 1 << 6 ) +#define TOSHIBA_RBTX4927_SETUP_PCIBIOS ( 1 << 7 ) +#define TOSHIBA_RBTX4927_SETUP_PCI1 ( 1 << 8 ) +#define TOSHIBA_RBTX4927_SETUP_PCI2 ( 1 << 9 ) +#define TOSHIBA_RBTX4927_SETUP_PCI66 ( 1 << 10 ) + +#define TOSHIBA_RBTX4927_SETUP_ALL 0xffffffff +#endif + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG +static const u32 toshiba_rbtx4927_setup_debug_flag = + (TOSHIBA_RBTX4927_SETUP_NONE | TOSHIBA_RBTX4927_SETUP_INFO | + TOSHIBA_RBTX4927_SETUP_WARN | TOSHIBA_RBTX4927_SETUP_EROR | + TOSHIBA_RBTX4927_SETUP_EFWFU | TOSHIBA_RBTX4927_SETUP_SETUP | + TOSHIBA_RBTX4927_SETUP_TIME_INIT | TOSHIBA_RBTX4927_SETUP_TIMER_SETUP + | TOSHIBA_RBTX4927_SETUP_PCIBIOS | TOSHIBA_RBTX4927_SETUP_PCI1 | + TOSHIBA_RBTX4927_SETUP_PCI2 | TOSHIBA_RBTX4927_SETUP_PCI66); +#endif + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG +#define TOSHIBA_RBTX4927_SETUP_DPRINTK(flag,str...) \ + if ( (toshiba_rbtx4927_setup_debug_flag) & (flag) ) \ + { \ + char tmp[100]; \ + sprintf( tmp, str ); \ + printk( "%s(%s:%u)::%s", __FUNCTION__, __FILE__, __LINE__, tmp ); \ + } +#else +#define TOSHIBA_RBTX4927_SETUP_DPRINTK(flag,str...) +#endif + +/* These functions are used for rebooting or halting the machine*/ +extern void toshiba_rbtx4927_restart(char *command); +extern void toshiba_rbtx4927_halt(void); +extern void toshiba_rbtx4927_power_off(void); + +int tx4927_using_backplane = 0; + +extern void gt64120_time_init(void); +extern void toshiba_rbtx4927_irq_setup(void); + +#ifdef CONFIG_PCI +#define CONFIG_TX4927BUG_WORKAROUND +#undef TX4927_SUPPORT_COMMAND_IO +#undef TX4927_SUPPORT_PCI_66 +int tx4927_cpu_clock = 100000000; /* 100MHz */ +unsigned long mips_pci_io_base; +unsigned long mips_pci_io_size; +unsigned long mips_pci_mem_base; +unsigned long mips_pci_mem_size; +/* for legacy I/O, PCI I/O PCI Bus address must be 0 */ +unsigned long mips_pci_io_pciaddr = 0; +unsigned long mips_memory_upper; +static int tx4927_ccfg_toeon = 1; +static int tx4927_pcic_trdyto = 0; /* default: disabled */ +unsigned long tx4927_ce_base[8]; +void tx4927_pci_setup(void); +void tx4927_reset_pci_pcic(void); +#ifdef TX4927_SUPPORT_PCI_66 +void tx4927_pci66_setup(void); +extern int tx4927_pci66_check(void); +#endif +int tx4927_pci66 = 0; /* 0:auto */ +#endif + +char *toshiba_name = ""; + +#ifdef CONFIG_PCI +void tx4927_dump_pcic_settings(void) +{ + printk("%s pcic settings:",toshiba_name); + { + int i; + unsigned long *preg = (unsigned long *) tx4927_pcicptr; + for (i = 0; i < sizeof(struct tx4927_pcic_reg); i += 4) { + if (i % 32 == 0) + printk("\n%04x:", i); + if (preg == &tx4927_pcicptr->g2pintack + || preg == &tx4927_pcicptr->g2pspc +#ifdef CONFIG_TX4927BUG_WORKAROUND + || preg == &tx4927_pcicptr->g2pcfgadrs + || preg == &tx4927_pcicptr->g2pcfgdata +#endif + ) { + printk(" XXXXXXXX"); + preg++; + continue; + } + printk(" %08lx", *preg++); + if (preg == &tx4927_pcicptr->g2pcfgadrs) + break; + } + printk("\n"); + } +} + +static void tx4927_pcierr_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +{ + extern void tx4927_dump_pcic_settings(void); + +#ifdef CONFIG_BLK_DEV_IDEPCI + /* ignore MasterAbort for ide probing... */ + if (irq == TX4927_IRQ_IRC_PCIERR && + ((tx4927_pcicptr->pcistatus >> 16) & 0xf900) == + PCI_STATUS_REC_MASTER_ABORT) { + tx4927_pcicptr->pcistatus = + (tx4927_pcicptr-> + pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT + << 16); + + return; + } +#endif + printk("PCI error interrupt (irq 0x%x).\n", irq); + printk("pcistat:%04x, g2pstatus:%08lx, pcicstatus:%08lx\n", + (unsigned short) (tx4927_pcicptr->pcistatus >> 16), + tx4927_pcicptr->g2pstatus, tx4927_pcicptr->pcicstatus); + printk("ccfg:%08lx, tear:%02lx_%08lx\n", + (unsigned long) tx4927_ccfgptr->ccfg, + (unsigned long) (tx4927_ccfgptr->tear >> 32), + (unsigned long) tx4927_ccfgptr->tear); + show_regs(regs); + //tx4927_dump_pcic_settings(); + panic("PCI error at PC:%08lx.", regs->cp0_epc); +} + +static struct irqaction pcic_action = { + tx4927_pcierr_interrupt, 0, 0, "PCI-C", NULL, NULL +}; + +static struct irqaction pcierr_action = { + tx4927_pcierr_interrupt, 0, 0, "PCI-ERR", NULL, NULL +}; + + +void __init toshiba_rbtx4927_pci_irq_init(void) +{ + setup_irq(TX4927_IRQ_IRC_PCIC, &pcic_action); + setup_irq(TX4927_IRQ_IRC_PCIERR, &pcierr_action); +} + +void tx4927_reset_pci_pcic(void) +{ + /* Reset PCI Bus */ + *tx4927_pcireset_ptr = 1; + /* Reset PCIC */ + tx4927_ccfgptr->clkctr |= TX4927_CLKCTR_PCIRST; + udelay(10000); + /* clear PCIC reset */ + tx4927_ccfgptr->clkctr &= ~TX4927_CLKCTR_PCIRST; + *tx4927_pcireset_ptr = 0; +} +#endif /* CONFIG_PCI */ + +#ifdef CONFIG_PCI +#ifdef TX4927_SUPPORT_PCI_66 +void tx4927_pci66_setup(void) +{ + int pciclk, pciclkin = 1; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI66, + "-\n"); + + if (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) + return; + + tx4927_reset_pci_pcic(); + + /* Assert M66EN */ + tx4927_ccfgptr->ccfg |= TX4927_CCFG_PCI66; + /* set PCICLK 66MHz */ + if (tx4927_ccfgptr->pcfg & TX4927_PCFG_PCICLKEN_ALL) { + unsigned int pcidivmode = 0; + pcidivmode = + (unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIDIVMODE_MASK; + if (tx4927_cpu_clock >= 170000000) { + /* CPU 200MHz */ + pcidivmode = TX4927_CCFG_PCIDIVMODE_3; + pciclk = tx4927_cpu_clock / 3; + } else { + /* CPU 166MHz */ + pcidivmode = TX4927_CCFG_PCIDIVMODE_2_5; + pciclk = tx4927_cpu_clock * 2 / 5; + } + tx4927_ccfgptr->ccfg = + (tx4927_ccfgptr->ccfg & ~TX4927_CCFG_PCIDIVMODE_MASK) + | pcidivmode; + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCI66, + ":PCICLK: ccfg:0x%08lx\n", + (unsigned long) tx4927_ccfgptr->ccfg); + } else { + int pciclk_setting = *tx4927_pci_clk_ptr; + pciclkin = 0; + pciclk = 66666666; + pciclk_setting &= ~TX4927_PCI_CLK_MASK; + pciclk_setting |= TX4927_PCI_CLK_66; + *tx4927_pci_clk_ptr = pciclk_setting; + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCI66, + "PCICLK: pci_clk:%02x\n", *tx4927_pci_clk_ptr); + } + + udelay(10000); + + /* clear PCIC reset */ + tx4927_ccfgptr->clkctr &= ~TX4927_CLKCTR_PCIRST; + /* clear PCI reset */ + *tx4927_pcireset_ptr = 0; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI66, + "+\n"); +} +#endif /* TX4927_SUPPORT_PCI_66 */ + +void print_pci_status(void) +{ + printk("PCI STATUS %lx\n", tx4927_pcicptr->pcistatus); + printk("PCIC STATUS %lx\n", tx4927_pcicptr->pcicstatus); +} + +static struct pci_dev *fake_pci_dev(struct pci_channel *hose, + int top_bus, int busnr, int devfn) +{ + static struct pci_dev dev; + static struct pci_bus bus; + + dev.bus = &bus; + dev.sysdata = hose; + dev.devfn = devfn; + bus.number = busnr; + bus.ops = hose->pci_ops; + + if (busnr != top_bus) + /* Fake a parent bus structure. */ + bus.parent = &bus; + else + bus.parent = NULL; + + return &dev; +} + +#define EARLY_PCI_OP(rw, size, type) \ +static int early_##rw##_config_##size(struct pci_channel *hose, \ + int top_bus, int bus, int devfn, int offset, type value) \ +{ \ + return pci_##rw##_config_##size( \ + fake_pci_dev(hose, top_bus, bus, devfn), \ + offset, value); \ +} + +EARLY_PCI_OP(read, byte, u8 *) +EARLY_PCI_OP(read, dword, u32 *) +EARLY_PCI_OP(write, byte, u8) +EARLY_PCI_OP(write, dword, u32) + +static int __init tx4927_pcibios_init(int busno, struct pci_channel *hose) +{ + u32 pci_devfn; + int devfn_start = 0; + int devfn_stop = 0xff; + unsigned int id; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCIBIOS, + "-\n"); + + if (hose->first_devfn) + devfn_start = hose->first_devfn; + if (hose->last_devfn) + devfn_stop = hose->last_devfn; + + for (pci_devfn = devfn_start; pci_devfn < devfn_stop; pci_devfn++) { + early_read_config_dword(hose, busno, busno, pci_devfn, + PCI_VENDOR_ID, &id); + + if (id == 0xffffffff) { + continue; + } + + if (id == 0x94601055) { + u8 v08_64; + u32 v32_b0; + u8 v08_e1; +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG + char *s = " sb/isa --"; +#endif + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s beg\n", + s); + + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x64, &v08_64); + early_read_config_dword(hose, busno, busno, + pci_devfn, 0xb0, &v32_b0); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0xe1, &v08_e1); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x64 = 0x%02x\n", s, v08_64); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0xb0 = 0x%02x\n", s, v32_b0); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0xe1 = 0x%02x\n", s, v08_e1); + + /* serial irq control */ + v08_64 = 0xd0; + + /* serial irq pin */ + v32_b0 |= 0x00010000; + + /* ide irq on isa14 */ + v08_e1 &= 0xf0; + v08_e1 |= 0x0d; + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x64 = 0x%02x\n", s, v08_64); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0xb0 = 0x%02x\n", s, v32_b0); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0xe1 = 0x%02x\n", s, v08_e1); + + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x64, v08_64); + early_write_config_dword(hose, busno, busno, + pci_devfn, 0xb0, v32_b0); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0xe1, v08_e1); + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG + { + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x64, + &v08_64); + early_read_config_dword(hose, busno, busno, + pci_devfn, 0xb0, + &v32_b0); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0xe1, + &v08_e1); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x64 = 0x%02x\n", s, v08_64); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0xb0 = 0x%02x\n", s, v32_b0); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0xe1 = 0x%02x\n", s, v08_e1); + } +#endif + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s end\n", + s); + } + + if (id == 0x91301055) { + u8 v08_04; + u8 v08_09; + u8 v08_41; + u8 v08_43; + u8 v08_5c; +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG + char *s = " sb/ide --"; +#endif + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s beg\n", + s); + + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x04, &v08_04); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x09, &v08_09); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x41, &v08_41); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x43, &v08_43); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x5c, &v08_5c); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x04 = 0x%02x\n", s, v08_04); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x09 = 0x%02x\n", s, v08_09); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x41 = 0x%02x\n", s, v08_41); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x43 = 0x%02x\n", s, v08_43); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x5c = 0x%02x\n", s, v08_5c); + + /* enable ide master/io */ + v08_04 |= (PCI_COMMAND_MASTER | PCI_COMMAND_IO); + + /* enable ide native mode */ + v08_09 |= 0x05; + + /* enable primary ide */ + v08_41 |= 0x80; + + /* enable secondary ide */ + v08_43 |= 0x80; + + /* + * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! + * + * This line of code is intended to provide the user with a work + * around solution to the anomalies cited in SMSC's anomaly sheet + * entitled, "SLC90E66 Functional Rev.J_0.1 Anomalies"". + * + * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! + */ + v08_5c |= 0x01; + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x04 = 0x%02x\n", s, v08_04); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x09 = 0x%02x\n", s, v08_09); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x41 = 0x%02x\n", s, v08_41); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x43 = 0x%02x\n", s, v08_43); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x5c = 0x%02x\n", s, v08_5c); + + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x5c, v08_5c); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x04, v08_04); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x09, v08_09); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x41, v08_41); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x43, v08_43); + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG + { + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x04, + &v08_04); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x09, + &v08_09); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x41, + &v08_41); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x43, + &v08_43); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x5c, + &v08_5c); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x04 = 0x%02x\n", s, v08_04); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x09 = 0x%02x\n", s, v08_09); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x41 = 0x%02x\n", s, v08_41); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x43 = 0x%02x\n", s, v08_43); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x5c = 0x%02x\n", s, v08_5c); + } +#endif + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s end\n", + s); + } + + } + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCIBIOS, + "+\n"); + + return (busno); +} + +extern struct resource pci_io_resource; +extern struct resource pci_mem_resource; + +void tx4927_pci_setup(void) +{ + static int called = 0; + extern unsigned int tx4927_get_mem_size(void); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, "-\n"); + +#ifndef TX4927_SUPPORT_PCI_66 + if (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) + printk("PCI 66 current unsupported\n"); +#endif + + mips_memory_upper = tx4927_get_mem_size() << 20; + mips_memory_upper += KSEG0; + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_memory_upper\n", + mips_memory_upper); + mips_pci_io_base = TX4927_PCIIO; + mips_pci_io_size = TX4927_PCIIO_SIZE; + mips_pci_mem_base = TX4927_PCIMEM; + mips_pci_mem_size = TX4927_PCIMEM_SIZE; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_pci_io_base\n", + mips_pci_io_base); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_pci_io_size\n", + mips_pci_io_size); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_pci_mem_base\n", + mips_pci_mem_base); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_pci_mem_size\n", + mips_pci_mem_size); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=pci_io_resource.start\n", + pci_io_resource.start); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=pci_io_resource.end\n", + pci_io_resource.end); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=pci_mem_resource.start\n", + pci_mem_resource.start); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=pci_mem_resource.end\n", + pci_mem_resource.end); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_io_port_base", + mips_io_port_base); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "setup pci_io_resource to 0x%08lx 0x%08lx\n", + pci_io_resource.start, + pci_io_resource.end); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "setup pci_mem_resource to 0x%08lx 0x%08lx\n", + pci_mem_resource.start, + pci_mem_resource.end); + + if (!called) { + printk + ("TX4927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", + (unsigned short) (tx4927_pcicptr->pciid >> 16), + (unsigned short) (tx4927_pcicptr->pciid & 0xffff), + (unsigned short) (tx4927_pcicptr->pciccrev & 0xff), + (!(tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIXARB)) ? "External" : + "Internal"); + called = 1; + } + printk("%s PCIC --%s PCICLK:",toshiba_name, + (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) ? " PCI66" : ""); + if (tx4927_ccfgptr->pcfg & TX4927_PCFG_PCICLKEN_ALL) { + int pciclk = 0; + switch ((unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIDIVMODE_MASK) { + case TX4927_CCFG_PCIDIVMODE_2_5: + pciclk = tx4927_cpu_clock * 2 / 5; + break; + case TX4927_CCFG_PCIDIVMODE_3: + pciclk = tx4927_cpu_clock / 3; + break; + case TX4927_CCFG_PCIDIVMODE_5: + pciclk = tx4927_cpu_clock / 5; + break; + case TX4927_CCFG_PCIDIVMODE_6: + pciclk = tx4927_cpu_clock / 6; + break; + } + printk("Internal(%dMHz)", pciclk / 1000000); + } else { + int pciclk = 0; + int pciclk_setting = *tx4927_pci_clk_ptr; + switch (pciclk_setting & TX4927_PCI_CLK_MASK) { + case TX4927_PCI_CLK_33: + pciclk = 33333333; + break; + case TX4927_PCI_CLK_25: + pciclk = 25000000; + break; + case TX4927_PCI_CLK_66: + pciclk = 66666666; + break; + case TX4927_PCI_CLK_50: + pciclk = 50000000; + break; + } + printk("External(%dMHz)", pciclk / 1000000); + } + printk("\n"); + + + + /* GB->PCI mappings */ + tx4927_pcicptr->g2piomask = (mips_pci_io_size - 1) >> 4; + tx4927_pcicptr->g2piogbase = mips_pci_io_base | +#ifdef __BIG_ENDIAN + TX4927_PCIC_G2PIOGBASE_ECHG +#else + TX4927_PCIC_G2PIOGBASE_BSDIS +#endif + ; + + tx4927_pcicptr->g2piopbase = 0; + + tx4927_pcicptr->g2pmmask[0] = (mips_pci_mem_size - 1) >> 4; + tx4927_pcicptr->g2pmgbase[0] = mips_pci_mem_base | +#ifdef __BIG_ENDIAN + TX4927_PCIC_G2PMnGBASE_ECHG +#else + TX4927_PCIC_G2PMnGBASE_BSDIS +#endif + ; + tx4927_pcicptr->g2pmpbase[0] = mips_pci_mem_base; + + tx4927_pcicptr->g2pmmask[1] = 0; + tx4927_pcicptr->g2pmgbase[1] = 0; + tx4927_pcicptr->g2pmpbase[1] = 0; + tx4927_pcicptr->g2pmmask[2] = 0; + tx4927_pcicptr->g2pmgbase[2] = 0; + tx4927_pcicptr->g2pmpbase[2] = 0; + + + /* PCI->GB mappings (I/O 256B) */ + tx4927_pcicptr->p2giopbase = 0; /* 256B */ + + +#ifdef TX4927_SUPPORT_COMMAND_IO + tx4927_pcicptr->p2giogbase = 0 | TX4927_PCIC_P2GIOGBASE_TIOEN | +#ifdef __BIG_ENDIAN + TX4927_PCIC_P2GIOGBASE_TECHG +#else + TX4927_PCIC_P2GIOGBASE_TBSDIS +#endif + ; +#else + tx4927_pcicptr->p2giogbase = 0; +#endif + + /* PCI->GB mappings (MEM 512MB) M0 gets all of memory */ + tx4927_pcicptr->p2gm0plbase = 0; + tx4927_pcicptr->p2gm0pubase = 0; + tx4927_pcicptr->p2gmgbase[0] = 0 | TX4927_PCIC_P2GMnGBASE_TMEMEN | +#ifdef __BIG_ENDIAN + TX4927_PCIC_P2GMnGBASE_TECHG +#else + TX4927_PCIC_P2GMnGBASE_TBSDIS +#endif + ; + + /* PCI->GB mappings (MEM 16MB) -not used */ + tx4927_pcicptr->p2gm1plbase = 0xffffffff; +#ifdef CONFIG_TX4927BUG_WORKAROUND + /* + * TX4927-PCIC-BUG: P2GM1PUBASE must be 0 + * if P2GM0PUBASE was 0. + */ + tx4927_pcicptr->p2gm1pubase = 0; +#else + tx4927_pcicptr->p2gm1pubase = 0xffffffff; +#endif + tx4927_pcicptr->p2gmgbase[1] = 0; + + /* PCI->GB mappings (MEM 1MB) -not used */ + tx4927_pcicptr->p2gm2pbase = 0xffffffff; + tx4927_pcicptr->p2gmgbase[2] = 0; + + + /* Enable Initiator Memory 0 Space, I/O Space, Config */ + tx4927_pcicptr->pciccfg &= TX4927_PCIC_PCICCFG_LBWC_MASK; + tx4927_pcicptr->pciccfg |= + TX4927_PCIC_PCICCFG_IMSE0 | TX4927_PCIC_PCICCFG_IISE | + TX4927_PCIC_PCICCFG_ICAE | TX4927_PCIC_PCICCFG_ATR; + + + /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */ + tx4927_pcicptr->pcicfg1 = 0; + + if (tx4927_pcic_trdyto >= 0) { + tx4927_pcicptr->g2ptocnt &= ~0xff; + tx4927_pcicptr->g2ptocnt |= (tx4927_pcic_trdyto & 0xff); + //printk("%s PCIC -- TRDYTO:%02lx\n",toshiba_name, + // tx4927_pcicptr->g2ptocnt & 0xff); + } + + /* Clear All Local Bus Status */ + tx4927_pcicptr->pcicstatus = TX4927_PCIC_PCICSTATUS_ALL; + /* Enable All Local Bus Interrupts */ + tx4927_pcicptr->pcicmask = TX4927_PCIC_PCICSTATUS_ALL; + /* Clear All Initiator Status */ + tx4927_pcicptr->g2pstatus = TX4927_PCIC_G2PSTATUS_ALL; + /* Enable All Initiator Interrupts */ + tx4927_pcicptr->g2pmask = TX4927_PCIC_G2PSTATUS_ALL; + /* Clear All PCI Status Error */ + tx4927_pcicptr->pcistatus = + (tx4927_pcicptr->pcistatus & 0x0000ffff) | + (TX4927_PCIC_PCISTATUS_ALL << 16); + /* Enable All PCI Status Error Interrupts */ + tx4927_pcicptr->pcimask = TX4927_PCIC_PCISTATUS_ALL; + + /* PCIC Int => IRC IRQ16 */ + tx4927_pcicptr->pcicfg2 = + (tx4927_pcicptr->pcicfg2 & 0xffffff00) | TX4927_IR_PCIC; + + if (!(tx4927_ccfgptr->ccfg & TX4927_CCFG_PCIXARB)) { + /* XXX */ + } else { + /* Reset Bus Arbiter */ + tx4927_pcicptr->pbacfg = TX4927_PCIC_PBACFG_RPBA; + /* Enable Bus Arbiter */ + tx4927_pcicptr->pbacfg = TX4927_PCIC_PBACFG_PBAEN; + } + + tx4927_pcicptr->pcistatus = PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY | +#ifdef TX4927_SUPPORT_COMMAND_IO + PCI_COMMAND_IO | +#endif + PCI_COMMAND_PARITY | PCI_COMMAND_SERR; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + ":pci setup complete:\n"); + //tx4927_dump_pcic_settings(); + + { + struct pci_channel *p; + int busno; + + busno = 0; + for (p = mips_pci_channels; p->pci_ops != NULL; p++) { + busno = tx4927_pcibios_init(busno, p) + 1; + } + } + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, "+\n"); +} + +#endif /* CONFIG_PCI */ + +void toshiba_rbtx4927_restart(char *command) +{ + printk(KERN_NOTICE "System Rebooting...\n"); + + /* enable the s/w reset register */ + reg_wr08(RBTX4927_SW_RESET_ENABLE, RBTX4927_SW_RESET_ENABLE_SET); + + /* wait for enable to be seen */ + while ((reg_rd08(RBTX4927_SW_RESET_ENABLE) & + RBTX4927_SW_RESET_ENABLE_SET) == 0x00); + + /* do a s/w reset */ + reg_wr08(RBTX4927_SW_RESET_DO, RBTX4927_SW_RESET_DO_SET); + + /* do something passive while waiting for reset */ + cli(); + while (1) + asm_wait(); + + /* no return */ +} + +void toshiba_rbtx4927_halt(void) +{ + printk(KERN_NOTICE "System Halted\n"); + cli(); + while (1) { + asm_wait(); + } + /* no return */ +} + +void toshiba_rbtx4927_power_off(void) +{ + toshiba_rbtx4927_halt(); + /* no return */ +} + +void __init toshiba_rbtx4927_setup(void) +{ + vu32 cp0_config; + + printk("CPU is %s\n", toshiba_name); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + "-\n"); + + /* f/w leaves this on at startup */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Clearing STO_ERL.\n"); + clear_c0_status(ST0_ERL); + + /* enable caches -- HCP5 does this, pmon does not */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Enabling TX49_CONF_IC,TX49_CONF_DC.\n"); + cp0_config = read_c0_config(); + cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC); + write_c0_config(cp0_config); + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG + { + extern void dump_cp0(char *); + dump_cp0("toshiba_rbtx4927_early_fw_fixup"); + } +#endif + + /* setup irq stuff */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Setting up tx4927 pic.\n"); + TX4927_WR(0xff1ff604, 0x00000400); /* irq trigger */ + TX4927_WR(0xff1ff608, 0x00000000); /* irq trigger */ + + /* setup serial stuff */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Setting up tx4927 sio.\n"); + TX4927_WR(0xff1ff314, 0x00000000); /* h/w flow control off */ + TX4927_WR(0xff1ff414, 0x00000000); /* h/w flow control off */ + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + "+\n"); + + + + set_io_port_base(KSEG1 + TBTX4927_ISA_IO_OFFSET); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":mips_io_port_base=0x%08lx\n", + mips_io_port_base); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Resource\n"); + ioport_resource.start = 0; + ioport_resource.end = 0xffffffff; + iomem_resource.start = 0; + iomem_resource.end = 0xffffffff; + + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":ResetRoutines\n"); + _machine_restart = toshiba_rbtx4927_restart; + _machine_halt = toshiba_rbtx4927_halt; + _machine_power_off = toshiba_rbtx4927_power_off; + + +#ifdef CONFIG_BLK_DEV_IDEPCI + { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":ide_ops=&std_ide_ops(modified)\n"); + ide_ops = &std_ide_ops; + } +#else + { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":ide_ops=\n"); + } +#endif + +#ifdef CONFIG_FB + { + conswitchp = &dummy_con; + } +#endif + + + + +#ifdef CONFIG_PCI + + /* PCIC */ + /* + * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz. + * PCIDIVMODE[12:11]'s initial value are given by S9[4:3] (ON:0, OFF:1). + * CPU 166MHz: PCI 66MHz : PCIDIVMODE: 00 (1/2.5) + * CPU 200MHz: PCI 66MHz : PCIDIVMODE: 01 (1/3) + * CPU 166MHz: PCI 33MHz : PCIDIVMODE: 10 (1/5) + * CPU 200MHz: PCI 33MHz : PCIDIVMODE: 11 (1/6) + * i.e. S9[3]: ON (83MHz), OFF (100MHz) + */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1, + "ccfg is %lx, DIV is %x\n", + (unsigned long) tx4927_ccfgptr-> + ccfg, TX4927_CCFG_PCIDIVMODE_MASK); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1, + "PCI66 mode is %lx, PCI mode is %lx, pci arb is %lx\n", + (unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCI66, + (unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIMIDE, + (unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIXARB); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1, + "PCIDIVMODE is %lx\n", + (unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIDIVMODE_MASK); + + switch ((unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIDIVMODE_MASK) { + case TX4927_CCFG_PCIDIVMODE_2_5: + case TX4927_CCFG_PCIDIVMODE_5: + tx4927_cpu_clock = 166000000; /* 166MHz */ + break; + default: + tx4927_cpu_clock = 200000000; /* 200MHz */ + } + + /* CCFG */ + /* enable Timeout BusError */ + if (tx4927_ccfg_toeon) + tx4927_ccfgptr->ccfg |= TX4927_CCFG_TOE; + + /* SDRAMC fixup */ +#ifdef CONFIG_TX4927BUG_WORKAROUND + /* + * TX4927-BUG: INF 01-01-18/ BUG 01-01-22 + * G-bus timeout error detection is incorrect + */ + if (tx4927_ccfg_toeon) + tx4927_sdramcptr->tr |= 0x02000000; /* RCD:3tck */ +#endif + +#ifdef TX4927_SUPPORT_PCI_66 + tx4927_pci66_setup(); +#endif + + tx4927_pci_setup(); + + + { + u32 id = 0; + early_read_config_dword(&mips_pci_channels[0], 0, 0, 0x90, + PCI_VENDOR_ID, &id); + if (id == 0x94601055) { + tx4927_using_backplane = 1; + printk("backplane board IS installed\n"); + } else { + printk("backplane board NOT installed\n"); + } + } +#endif + + + /* this is only done if backplane board installed, so must wait for pci */ +#ifdef CONFIG_PC_KEYB + { + if (tx4927_using_backplane) { + extern struct kbd_ops std_kbd_ops; + kbd_ops = &std_kbd_ops; + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":kbd_ops=&std_kbd_ops\n"); + } else { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":kbd_ops=\n"); + } + } +#else + { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":kbd_ops=\n"); + } +#endif + + /* this is on ISA bus behind PCI bus, so need PCI up first */ +#ifdef CONFIG_TOSHIBA_FPCIB0 + { + if (tx4927_using_backplane) { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":fpcibo=yes\n"); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":smsc_fdc37m81x_init()\n"); + smsc_fdc37m81x_init(0x3f0); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":smsc_fdc37m81x_config_beg()\n"); + smsc_fdc37m81x_config_beg(); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":smsc_fdc37m81x_config_set(KBD)\n"); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_DNUM, + SMSC_FDC37M81X_KBD); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT, 1); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT2, 12); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_ACTIVE, + 1); + + smsc_fdc37m81x_config_end(); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":smsc_fdc37m81x_config_end()\n"); + } else { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":fpcibo=not_found\n"); + } + } +#else + { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, ":fpcibo=no\n"); + } +#endif + + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + "+\n"); +} + +void __init +toshiba_rbtx4927_time_init(void) +{ +#ifdef CONFIG_RTC_DS1742 + u32 c1; + u32 c2; +#endif + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "-\n"); + +#ifdef CONFIG_RTC_DS1742 + + rtc_get_time = rtc_ds1742_get_time; + rtc_set_time = rtc_ds1742_set_time; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":rtc_ds1742_init()-\n"); + rtc_ds1742_init(0xbc010000); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":rtc_ds1742_init()+\n"); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":Calibrate mips_counter_frequency-\n"); + rtc_ds1742_wait(); + + /* get the count */ + c1 = read_c0_count(); + + /* wait for the seconds to change again */ + rtc_ds1742_wait(); + + /* get the count again */ + c2 = read_c0_count(); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":Calibrate mips_counter_frequency+\n"); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":c1=%12u\n", c1); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":c2=%12u\n", c2); + + /* this diff is as close as we are going to get to counter ticks per sec */ + mips_counter_frequency = abs(c2 - c1); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":f1=%12u\n", mips_counter_frequency); + + /* round to 1/10th of a MHz */ + mips_counter_frequency /= (100 * 1000); + mips_counter_frequency *= (100 * 1000); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":f2=%12u\n", mips_counter_frequency); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_INFO, + ":mips_counter_frequency=%uHz (%uMHz)\n", + mips_counter_frequency, + mips_counter_frequency / 1000000); +#else + mips_counter_frequency = 100000000; +#endif + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "+\n"); + +} + +void __init toshiba_rbtx4927_timer_setup(struct irqaction *irq) +{ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP, + "-\n"); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP, + "+\n"); +} diff -urN linux-2.4.21-bk37/arch/mips/vr4181/common/irq.c linux-2.4.21-bk38/arch/mips/vr4181/common/irq.c --- linux-2.4.21-bk37/arch/mips/vr4181/common/irq.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/vr4181/common/irq.c 2003-08-24 02:55:58.000000000 -0700 @@ -7,7 +7,7 @@ * * Credits to Bradley D. LaRonde and Michael Klar for writing the original * irq.c file which was derived from the common irq.c file. - * + * * 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. @@ -180,9 +180,9 @@ extern int setup_irq(unsigned int irq, struct irqaction *irqaction); extern void mips_cpu_irq_init(u32 irq_base); -static struct irqaction cascade = +static struct irqaction cascade = { no_action, SA_INTERRUPT, 0, "cascade", NULL, NULL }; -static struct irqaction reserved = +static struct irqaction reserved = { no_action, SA_INTERRUPT, 0, "cascade", NULL, NULL }; void __init init_IRQ(void) @@ -216,7 +216,7 @@ /* Default all ICU IRQs to off ... */ *VR4181_MSYSINT1REG = 0; *VR4181_MSYSINT2REG = 0; - + /* We initialize the level 2 ICU registers to all bits disabled. */ *VR4181_MPIUINTREG = 0; *VR4181_MAIUINTREG = 0; @@ -229,7 +229,7 @@ setup_irq(VR4181_IRQ_INT0, &cascade); setup_irq(VR4181_IRQ_GIU, &cascade); - /* + /* * RTC interrupts are interesting. They have two destinations. * One is at sys irq controller, and the other is at CPU IP3 and IP4. * RTC timer is used as system timer. @@ -239,7 +239,7 @@ setup_irq(VR4181_IRQ_RTCL1, &reserved); setup_irq(VR4181_IRQ_RTCL2, &reserved); -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB printk("Setting debug traps - please connect the remote debugger.\n"); set_debug_traps(); diff -urN linux-2.4.21-bk37/arch/mips/vr4181/common/serial.c linux-2.4.21-bk38/arch/mips/vr4181/common/serial.c --- linux-2.4.21-bk37/arch/mips/vr4181/common/serial.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/vr4181/common/serial.c 2003-08-24 02:55:58.000000000 -0700 @@ -14,7 +14,7 @@ /* * [jsun, 010925] - * You need to make sure rs_table has at least one element in + * You need to make sure rs_table has at least one element in * drivers/char/serial.c file. There is no good way to do it right * now. A workaround is to include CONFIG_SERIAL_MANY_PORTS in your * configure file, which would gives you 64 ports and wastes 11K ram. diff -urN linux-2.4.21-bk37/arch/mips/vr4181/common/time.c linux-2.4.21-bk38/arch/mips/vr4181/common/time.c --- linux-2.4.21-bk37/arch/mips/vr4181/common/time.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/vr4181/common/time.c 2003-08-24 02:55:58.000000000 -0700 @@ -2,7 +2,7 @@ * Copyright 2001 MontaVista Software Inc. * Author: jsun@mvista.com or jsun@junsun.net * - * rtc and time ops for vr4181. Part of code is drived from + * rtc and time ops for vr4181. Part of code is drived from * linux-vr, originally written by Bradley D. LaRonde & Michael Klar. * * This program is free software; you can redistribute it and/or modify it @@ -29,10 +29,10 @@ * RTC ops */ -spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; +extern spinlock_t rtc_lock; /* per VR41xx docs, bad data can be read if between 2 counts */ -static inline unsigned short +static inline unsigned short read_time_reg(volatile unsigned short *reg) { unsigned short value; @@ -43,7 +43,7 @@ return value; } -static unsigned long +static unsigned long vr4181_rtc_get_time(void) { unsigned short regh, regm, regl; @@ -60,7 +60,7 @@ return ((regh << 17) | (regm << 1) | (regl >> 15)); } -static int +static int vr4181_rtc_set_time(unsigned long timeval) { unsigned short intreg; @@ -82,13 +82,13 @@ } -/* +/* * timer interrupt routine (wrapper) * * we need our own interrupt routine because we need to clear * RTC1 interrupt. */ -static void +static void vr4181_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* Clear the interrupt. */ @@ -115,7 +115,7 @@ extern int setup_irq(unsigned int irq, struct irqaction *irqaction); -static void +static void vr4181_timer_setup(struct irqaction *irq) { /* over-write the handler to be our own one */ diff -urN linux-2.4.21-bk37/arch/mips/vr4181/osprey/Makefile linux-2.4.21-bk38/arch/mips/vr4181/osprey/Makefile --- linux-2.4.21-bk37/arch/mips/vr4181/osprey/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/vr4181/osprey/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -12,6 +12,6 @@ obj-y := setup.o prom.o reset.o -obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o +obj-$(CONFIG_KGDB) += dbg_io.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/vr4181/osprey/prom.c linux-2.4.21-bk38/arch/mips/vr4181/osprey/prom.c --- linux-2.4.21-bk37/arch/mips/vr4181/osprey/prom.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/vr4181/osprey/prom.c 2003-08-24 02:55:58.000000000 -0700 @@ -26,7 +26,7 @@ return "NEC_Vr41xx Osprey"; } -/* +/* * [jsun] right now we assume it is the nec debug monitor, which does * not pass any arguments. */ diff -urN linux-2.4.21-bk37/arch/mips/vr4181/osprey/reset.c linux-2.4.21-bk38/arch/mips/vr4181/osprey/reset.c --- linux-2.4.21-bk37/arch/mips/vr4181/osprey/reset.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/vr4181/osprey/reset.c 2003-08-24 02:55:58.000000000 -0700 @@ -18,10 +18,10 @@ void nec_osprey_restart(char *command) { - set_cp0_status(ST0_ERL); - change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + set_c0_status(ST0_ERL); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); + write_c0_wired(0); __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); } diff -urN linux-2.4.21-bk37/arch/mips/vr4181/osprey/setup.c linux-2.4.21-bk38/arch/mips/vr4181/osprey/setup.c --- linux-2.4.21-bk37/arch/mips/vr4181/osprey/setup.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips/vr4181/osprey/setup.c 2003-08-24 02:55:58.000000000 -0700 @@ -43,7 +43,7 @@ #ifdef CONFIG_FB conswitchp = &dummy_con; #endif - + _machine_restart = nec_osprey_restart; _machine_halt = nec_osprey_halt; _machine_power_off = nec_osprey_power_off; @@ -64,7 +64,7 @@ // *VR4181_GPMD0REG = 0x00c0; // *VR4181_GPINTEN = 1<<6; - /* [jsun] I believe this will get the interrupt type right + /* [jsun] I believe this will get the interrupt type right * for the ether port. */ *VR4181_GPINTTYPL = 0x3000; diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/casio-e55/Makefile linux-2.4.21-bk38/arch/mips/vr41xx/casio-e55/Makefile --- linux-2.4.21-bk37/arch/mips/vr41xx/casio-e55/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/casio-e55/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,17 @@ +# +# Makefile for the CASIO CASSIOPEIA E-55/65 specific parts of the kernel +# +# Note! Dependencies are done automagically by 'make dep', which also +# 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 := e55.o + +all: e55.o + +obj-y := init.o setup.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/casio-e55/ide-e55.c linux-2.4.21-bk38/arch/mips/vr41xx/casio-e55/ide-e55.c --- linux-2.4.21-bk37/arch/mips/vr41xx/casio-e55/ide-e55.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/casio-e55/ide-e55.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,99 @@ +/* + * 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. + * + * IDE routines for typical pc-like standard configurations + * for the CASIO CASSIOPEIA E-55/65. + * + * Copyright (C) 1998, 1999, 2001 by Ralf Baechle + */ +/* + * Changes: + * Yoichi Yuasa Sun, 24 Feb 2002 + * - Added CASIO CASSIOPEIA E-55/65 support. + */ +#include +#include +#include +#include +#include +#include + +static int e55_ide_default_irq(ide_ioreg_t base) +{ + return 40; +} + +static ide_ioreg_t e55_ide_default_io_base(int index) +{ + switch (index) { + case 0: return 0xc1f0; + case 1: return 0xc170; + case 2: return 0xc1e8; + case 3: return 0xc168; + case 4: return 0xc1e0; + case 5: return 0xc160; + } + return 0; +} + +static void e55_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; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206; + } + if (irq != NULL) + *irq = 0; + hw->io_ports[IDE_IRQ_OFFSET] = 0; +} + +static int e55_ide_request_irq(unsigned int irq, + void (*handler)(int,void *, struct pt_regs *), + unsigned long flags, const char *device, + void *dev_id) +{ + return request_irq(irq, handler, flags, device, dev_id); +} + +static void e55_ide_free_irq(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); +} + +static int e55_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void e55_ide_request_region(ide_ioreg_t from, unsigned int extent, + const char *name) +{ + request_region(from, extent, name); +} + +static void e55_ide_release_region(ide_ioreg_t from, unsigned int extent) +{ + release_region(from, extent); +} + +struct ide_ops e55_ide_ops = { + &e55_ide_default_irq, + &e55_ide_default_io_base, + &e55_ide_init_hwif_ports, + &e55_ide_request_irq, + &e55_ide_free_irq, + &e55_ide_check_region, + &e55_ide_request_region, + &e55_ide_release_region +}; diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/casio-e55/init.c linux-2.4.21-bk38/arch/mips/vr41xx/casio-e55/init.c --- linux-2.4.21-bk37/arch/mips/vr41xx/casio-e55/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/casio-e55/init.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,49 @@ +/* + * FILE NAME + * arch/mips/vr41xx/casio-e55/init.c + * + * BRIEF MODULE DESCRIPTION + * Initialisation code for the CASIO CASSIOPEIA E-55/65. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * 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. + */ +#include +#include +#include +#include + +#include + +char arcs_cmdline[CL_SIZE]; + +const char *get_system_type(void) +{ + return "CASIO CASSIOPEIA E-11/15/55/65"; +} + +void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) +{ + int i; + + /* + * collect args and prepare cmd_line + */ + for (i = 1; i < argc; i++) { + strcat(arcs_cmdline, argv[i]); + if (i < (argc - 1)) + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_NEC_VR41XX; + mips_machtype = MACH_CASIO_E55; +} + +void __init prom_free_prom_memory (void) +{ +} diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/casio-e55/setup.c linux-2.4.21-bk38/arch/mips/vr41xx/casio-e55/setup.c --- linux-2.4.21-bk37/arch/mips/vr41xx/casio-e55/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/casio-e55/setup.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,65 @@ +/* + * FILE NAME + * arch/mips/vr41xx/casio-e55/setup.c + * + * BRIEF MODULE DESCRIPTION + * Setup for the CASIO CASSIOPEIA E-11/15/55/65. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * 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. + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +void __init casio_e55_setup(void) +{ + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; + iomem_resource.start = IO_MEM_RESOURCE_START; + iomem_resource.end = IO_MEM_RESOURCE_END; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + _machine_restart = vr41xx_restart; + _machine_halt = vr41xx_halt; + _machine_power_off = vr41xx_power_off; + + board_time_init = vr41xx_time_init; + board_timer_setup = vr41xx_timer_setup; + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + +#if defined(CONFIG_IDE) || defined(CONFIG_IDE_MODULE) + ide_ops = &vr41xx_ide_ops; +#endif + + vr41xx_bcu_init(); + + vr41xx_cmu_init(0); + + vr41xx_siu_init(SIU_RS232C, 0); +} diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/common/Makefile linux-2.4.21-bk38/arch/mips/vr41xx/common/Makefile --- linux-2.4.21-bk37/arch/mips/vr41xx/common/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/common/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -14,8 +14,12 @@ obj-y := bcu.o cmu.o giu.o icu.o int-handler.o reset.o +export-objs := vrc4173.o + obj-$(CONFIG_PCI) += pciu.o obj-$(CONFIG_SERIAL) += serial.o obj-$(CONFIG_VR41XX_TIME_C) += time.o +obj-$(CONFIG_VRC4173) += vrc4173.o +obj-$(subst m,y,$(CONFIG_IDE)) += ide.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/common/bcu.c linux-2.4.21-bk38/arch/mips/vr41xx/common/bcu.c --- linux-2.4.21-bk37/arch/mips/vr41xx/common/bcu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/common/bcu.c 2003-08-24 02:55:58.000000000 -0700 @@ -69,7 +69,7 @@ static inline u16 read_clkspeed(void) { - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: return readw(VR4111_CLKSPEEDREG); case CPU_VR4122: return readw(VR4122_CLKSPEEDREG); @@ -86,7 +86,7 @@ { unsigned long pclock = 0; - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: pclock = 18432000 * 64; @@ -110,7 +110,7 @@ static inline unsigned long calculate_vtclock(u16 clkspeed, unsigned long pclock) { - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: /* The NEC VR4111 doesn't have the VTClock. */ break; @@ -151,7 +151,7 @@ { unsigned long tclock = 0; - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: if (!(clkspeed & DIV2B)) tclock = pclock / 2; @@ -182,8 +182,8 @@ /* * VR4131 Revision 2.0 and 2.1 use a value of (tclock / 2). */ - if ((mips_cpu.processor_id == PRID_VR4131_REV2_0) || - (mips_cpu.processor_id == PRID_VR4131_REV2_1)) + if ((current_cpu_data.processor_id == PRID_VR4131_REV2_0) || + (current_cpu_data.processor_id == PRID_VR4131_REV2_1)) tclock /= 2; else tclock /= 4; diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/common/cmu.c linux-2.4.21-bk38/arch/mips/vr41xx/common/cmu.c --- linux-2.4.21-bk37/arch/mips/vr41xx/common/cmu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/common/cmu.c 2003-08-24 02:55:58.000000000 -0700 @@ -66,7 +66,7 @@ void __init vr41xx_cmu_init(u16 mask) { - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: vr41xx_cmu_base = VR4111_CMUCLKMSK; diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/common/giu.c linux-2.4.21-bk38/arch/mips/vr41xx/common/giu.c --- linux-2.4.21-bk37/arch/mips/vr41xx/common/giu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/common/giu.c 2003-08-24 02:55:58.000000000 -0700 @@ -89,7 +89,7 @@ return res; } -void vr41xx_enable_giuint(u8 pin) +void vr41xx_enable_giuint(int pin) { if (pin < 16) set_giuint(GIUINTENL, (u16)1 << pin); @@ -97,7 +97,7 @@ set_giuint(GIUINTENH, (u16)1 << (pin - 16)); } -void vr41xx_disable_giuint(u8 pin) +void vr41xx_disable_giuint(int pin) { if (pin < 16) clear_giuint(GIUINTENL, (u16)1 << pin); @@ -105,15 +105,15 @@ clear_giuint(GIUINTENH, (u16)1 << (pin - 16)); } -void vr41xx_clear_giuint(u8 pin) +void vr41xx_clear_giuint(int pin) { if (pin < 16) - write_giuint(GIUINTSTATL, (u16)1 << pin); + write_giuint((u16)1 << pin, GIUINTSTATL); else - write_giuint(GIUINTSTATH, (u16)1 << (pin - 16)); + write_giuint((u16)1 << (pin - 16), GIUINTSTATH); } -void vr41xx_set_irq_trigger(u8 pin, u8 trigger, u8 hold) +void vr41xx_set_irq_trigger(int pin, int trigger, int hold) { u16 mask; @@ -146,7 +146,7 @@ vr41xx_clear_giuint(pin); } -void vr41xx_set_irq_level(u8 pin, u8 level) +void vr41xx_set_irq_level(int pin, int level) { u16 mask; @@ -167,7 +167,6 @@ vr41xx_clear_giuint(pin); } -#define GIUINT_CASCADE_IRQ 16 #define GIUINT_NR_IRQS 32 enum { @@ -212,8 +211,6 @@ return retval; } -extern unsigned int do_IRQ(int irq, struct pt_regs *regs); - unsigned int giuint_do_IRQ(int pin, struct pt_regs *regs) { struct vr41xx_giuint_cascade *cascade; @@ -242,7 +239,7 @@ { int i; - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: vr41xx_giu_base = VR4111_GIUIOSELL; diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/common/icu.c linux-2.4.21-bk38/arch/mips/vr41xx/common/icu.c --- linux-2.4.21-bk37/arch/mips/vr41xx/common/icu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/common/icu.c 2003-08-24 02:55:58.000000000 -0700 @@ -54,21 +54,10 @@ #include #include -#define MIPS_CPU_IRQ_BASE 0 -#define SYSINT1_IRQ_BASE 8 -#define SYSINT1_IRQ_LAST 23 -#define SYSINT2_IRQ_BASE 24 -#define SYSINT2_IRQ_LAST 39 -#define GIUINT_IRQ_BASE GIU_IRQ(0) -#define GIUINT_IRQ_LAST GIU_IRQ(31) - -#define ICU_CASCADE_IRQ (MIPS_CPU_IRQ_BASE + 2) - extern asmlinkage void vr41xx_handle_interrupt(void); extern void __init init_generic_irq(void); extern void mips_cpu_irq_init(u32 irq_base); -extern unsigned int do_IRQ(int irq, struct pt_regs *regs); extern void vr41xx_giuint_init(void); extern unsigned int giuint_do_IRQ(int pin, struct pt_regs *regs); @@ -224,15 +213,11 @@ /*=======================================================================*/ -extern void vr41xx_enable_giuint(u8 pin); -extern void vr41xx_disable_giuint(u8 pin); -extern void vr41xx_clear_giuint(u8 pin); - static void enable_giuint_irq(unsigned int irq) { - u8 pin; + int pin; - pin = irq - GIUINT_IRQ_BASE; + pin = irq - GIU_IRQ_BASE; if (pin < 16) set_icu1(MGIUINTLREG, (u16)1 << pin); else @@ -243,9 +228,9 @@ static void disable_giuint_irq(unsigned int irq) { - u8 pin; + int pin; - pin = irq - GIUINT_IRQ_BASE; + pin = irq - GIU_IRQ_BASE; vr41xx_disable_giuint(pin); if (pin < 16) @@ -256,7 +241,7 @@ static unsigned int startup_giuint_irq(unsigned int irq) { - vr41xx_clear_giuint(irq - GIUINT_IRQ_BASE); + vr41xx_clear_giuint(irq - GIU_IRQ_BASE); enable_giuint_irq(irq); @@ -269,7 +254,7 @@ { disable_giuint_irq(irq); - vr41xx_clear_giuint(irq - GIUINT_IRQ_BASE); + vr41xx_clear_giuint(irq - GIU_IRQ_BASE); } static void end_giuint_irq(unsigned int irq) @@ -297,7 +282,7 @@ { int i; - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: vr41xx_icu1_base = VR4111_SYSINT1REG; @@ -319,12 +304,12 @@ write_icu2(0, MSYSINT2REG); write_icu2(0, MGIUINTHREG); - for (i = SYSINT1_IRQ_BASE; i <= GIUINT_IRQ_LAST; i++) { + for (i = SYSINT1_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { if (i >= SYSINT1_IRQ_BASE && i <= SYSINT1_IRQ_LAST) irq_desc[i].handler = &sysint1_irq_type; else if (i >= SYSINT2_IRQ_BASE && i <= SYSINT2_IRQ_LAST) irq_desc[i].handler = &sysint2_irq_type; - else if (i >= GIUINT_IRQ_BASE && i <= GIUINT_IRQ_LAST) + else if (i >= GIU_IRQ_BASE && i <= GIU_IRQ_LAST) irq_desc[i].handler = &giuint_irq_type; } @@ -343,7 +328,7 @@ set_except_vector(0, vr41xx_handle_interrupt); -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB printk("Setting debug traps - please connect the remote debugger.\n"); set_debug_traps(); breakpoint(); diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/common/ide.c linux-2.4.21-bk38/arch/mips/vr41xx/common/ide.c --- linux-2.4.21-bk37/arch/mips/vr41xx/common/ide.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/common/ide.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,50 @@ +/* + * 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. + * + * IDE routines for NEC VR4100 series standard configurations. + * + * Copyright (C) 1998, 1999, 2001 by Ralf Baechle + * Copyright (C) 2003 Yoichi Yuasa + */ +#include +#include + +#include + +static int vr41xx_ide_default_irq(ide_ioreg_t base) +{ + return 0; +} + +static ide_ioreg_t vr41xx_ide_default_io_base(int index) +{ + return 0; +} + +static void vr41xx_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; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206; + } + if (irq != NULL) + *irq = 0; + hw->io_ports[IDE_IRQ_OFFSET] = 0; +} + +struct ide_ops vr41xx_ide_ops = { + .ide_default_irq = &vr41xx_ide_default_irq, + .ide_default_io_base = &vr41xx_ide_default_io_base, + .ide_init_hwif_ports = &vr41xx_ide_init_hwif_ports +}; diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/common/pciu.c linux-2.4.21-bk38/arch/mips/vr41xx/common/pciu.c --- linux-2.4.21-bk37/arch/mips/vr41xx/common/pciu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/common/pciu.c 2003-08-24 02:55:58.000000000 -0700 @@ -262,7 +262,7 @@ /* Clear bus error */ n = readl(BUSERRADREG); - if (mips_cpu.cputype == CPU_VR4122) { + if (current_cpu_data.cputype == CPU_VR4122) { writel(0UL, PCITRDYVREG); pciu_write_config_dword(PCI_CACHE_LINE_SIZE, 0x0000f804); } else { diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/common/reset.c linux-2.4.21-bk38/arch/mips/vr41xx/common/reset.c --- linux-2.4.21-bk37/arch/mips/vr41xx/common/reset.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/common/reset.c 2003-08-24 02:55:58.000000000 -0700 @@ -18,10 +18,10 @@ void vr41xx_restart(char *command) { - change_cp0_status((ST0_BEV | ST0_ERL), (ST0_BEV | ST0_ERL)); - change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + change_c0_status((ST0_BEV | ST0_ERL), (ST0_BEV | ST0_ERL)); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); + write_c0_wired(0); __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); } diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/common/serial.c linux-2.4.21-bk38/arch/mips/vr41xx/common/serial.c --- linux-2.4.21-bk37/arch/mips/vr41xx/common/serial.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/common/serial.c 2003-08-24 02:55:58.000000000 -0700 @@ -67,7 +67,6 @@ #define SIU_BASE_BAUD 1152000 #define SIU_CLOCK 0x0102 -#define SIU_IRQ 17 /* VR4122 and VR4131 DSIU Registers */ #define DSIURB KSEG1ADDR(0x0f000820) @@ -77,7 +76,6 @@ #define DSIU_BASE_BAUD 1152000 #define DSIU_CLOCK 0x0802 -#define DSIU_IRQ 29 int vr41xx_serial_ports = 0; @@ -101,7 +99,7 @@ val |= USE_IRDA | SIU_USES_IRDA; } - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: writew(val, VR4111_SIUIRSEL); @@ -128,7 +126,7 @@ s.baud_base = SIU_BASE_BAUD; s.irq = SIU_IRQ; s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: s.iomem_base = (unsigned char *)VR4111_SIURB; @@ -155,7 +153,8 @@ { struct serial_struct s; - if (mips_cpu.cputype != CPU_VR4122 && mips_cpu.cputype != CPU_VR4131) + if (current_cpu_data.cputype != CPU_VR4122 && + current_cpu_data.cputype != CPU_VR4131) return; memset(&s, 0, sizeof(s)); diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/common/time.c linux-2.4.21-bk38/arch/mips/vr41xx/common/time.c --- linux-2.4.21-bk37/arch/mips/vr41xx/common/time.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/common/time.c 2003-08-24 02:55:58.000000000 -0700 @@ -48,8 +48,7 @@ #include #include #include - -#define MIPS_COUNTER_TIMER_IRQ 7 +#include #define VR4111_ETIMELREG KSEG1ADDR(0x0b0000c0) #define VR4122_ETIMELREG KSEG1ADDR(0x0f000100) @@ -63,7 +62,7 @@ void vr41xx_time_init(void) { - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_VR4111: case CPU_VR4121: vr41xx_rtc_base = VR4111_ETIMELREG; @@ -87,8 +86,8 @@ { u32 count; - setup_irq(MIPS_COUNTER_TIMER_IRQ, irq); + setup_irq(MIPS_COUNTER_IRQ, irq); - count = read_32bit_cp0_register(CP0_COUNT); - write_32bit_cp0_register (CP0_COMPARE, count + (mips_counter_frequency / HZ)); + count = read_c0_count(); + write_c0_compare(count + (mips_counter_frequency / HZ)); } diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/common/vrc4173.c linux-2.4.21-bk38/arch/mips/vr41xx/common/vrc4173.c --- linux-2.4.21-bk37/arch/mips/vr41xx/common/vrc4173.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/common/vrc4173.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,279 @@ +/* + * FILE NAME + * drivers/char/vrc4173.c + * + * BRIEF MODULE DESCRIPTION + * NEC VRC4173 driver for NEC VR4122/VR4131. + * + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@mvista.com + * + * Copyright 2001,2002 MontaVista Software Inc. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +MODULE_DESCRIPTION("NEC VRC4173 driver for NEC VR4122/4131"); +MODULE_AUTHOR("Yoichi Yuasa "); +MODULE_LICENSE("GPL"); + +#define VRC4173_CMUCLKMSK 0x040 +#define VRC4173_CMUSRST 0x042 + +#define VRC4173_SELECTREG 0x09e + +#define VRC4173_SYSINT1REG 0x060 +#define VRC4173_MSYSINT1REG 0x06c + +static struct pci_device_id vrc4173_table[] __devinitdata = { + {PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_VRC4173, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0, } +}; + +unsigned long vrc4173_io_offset = 0; + +EXPORT_SYMBOL(vrc4173_io_offset); + +static u16 vrc4173_cmuclkmsk; +static int vrc4173_initialized; + +void vrc4173_clock_supply(u16 mask) +{ + if (vrc4173_initialized) { + vrc4173_cmuclkmsk |= mask; + vrc4173_outw(vrc4173_cmuclkmsk, VRC4173_CMUCLKMSK); + } +} + +void vrc4173_clock_mask(u16 mask) +{ + if (vrc4173_initialized) { + vrc4173_cmuclkmsk &= ~mask; + vrc4173_outw(vrc4173_cmuclkmsk, VRC4173_CMUCLKMSK); + } +} + +static inline void vrc4173_cmu_init(void) +{ + vrc4173_cmuclkmsk = vrc4173_inw(VRC4173_CMUCLKMSK); +} + +EXPORT_SYMBOL(vrc4173_clock_supply); +EXPORT_SYMBOL(vrc4173_clock_mask); + +void vrc4173_select_function(int func) +{ + u16 val; + + if (vrc4173_initialized) { + val = vrc4173_inw(VRC4173_SELECTREG); + switch(func) { + case PS2CH1_SELECT: + val |= 0x0004; + break; + case PS2CH2_SELECT: + val |= 0x0002; + break; + case TOUCHPANEL_SELECT: + val &= 0x0007; + break; + case KIU8_SELECT: + val &= 0x000e; + break; + case KIU10_SELECT: + val &= 0x000c; + break; + case KIU12_SELECT: + val &= 0x0008; + break; + case GPIO_SELECT: + val |= 0x0008; + break; + } + vrc4173_outw(val, VRC4173_SELECTREG); + } +} + +EXPORT_SYMBOL(vrc4173_select_function); + +static void enable_vrc4173_irq(unsigned int irq) +{ + u16 val; + + val = vrc4173_inw(VRC4173_MSYSINT1REG); + val |= (u16)1 << (irq - VRC4173_IRQ_BASE); + vrc4173_outw(val, VRC4173_MSYSINT1REG); +} + +static void disable_vrc4173_irq(unsigned int irq) +{ + u16 val; + + val = vrc4173_inw(VRC4173_MSYSINT1REG); + val &= ~((u16)1 << (irq - VRC4173_IRQ_BASE)); + vrc4173_outw(val, VRC4173_MSYSINT1REG); +} + +static unsigned int startup_vrc4173_irq(unsigned int irq) +{ + enable_vrc4173_irq(irq); + return 0; /* never anything pending */ +} + +#define shutdown_vrc4173_irq disable_vrc4173_irq +#define ack_vrc4173_irq disable_vrc4173_irq + +static void end_vrc4173_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + enable_vrc4173_irq(irq); +} + +static struct hw_interrupt_type vrc4173_irq_type = { + "VRC4173", + startup_vrc4173_irq, + shutdown_vrc4173_irq, + enable_vrc4173_irq, + disable_vrc4173_irq, + ack_vrc4173_irq, + end_vrc4173_irq, + NULL +}; + +static int vrc4173_get_irq_number(int irq) +{ + u16 status, mask; + int i; + + status = vrc4173_inw(VRC4173_SYSINT1REG); + mask = vrc4173_inw(VRC4173_MSYSINT1REG); + + status &= mask; + if (status) { + for (i = 0; i < 16; i++) + if (status & (0x0001 << i)) + return VRC4173_IRQ_BASE + i; + } + + return -EINVAL; +} + +static inline void vrc4173_icu_init(int cascade_irq) +{ + int i; + + if (cascade_irq < GIU_IRQ(0) || cascade_irq > GIU_IRQ(15)) + return; + + vrc4173_outw(0, VRC4173_MSYSINT1REG); + + vr41xx_set_irq_trigger(cascade_irq - GIU_IRQ(0), TRIGGER_LEVEL, SIGNAL_THROUGH); + vr41xx_set_irq_level(cascade_irq - GIU_IRQ(0), LEVEL_LOW); + + for (i = VRC4173_IRQ_BASE; i <= VRC4173_IRQ_LAST; i++) + irq_desc[i].handler = &vrc4173_irq_type; +} + +static int __devinit vrc4173_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + unsigned long start, flags; + int err; + + if ((err = pci_enable_device(pdev)) < 0) { + printk(KERN_ERR "vrc4173: failed to enable device -- err=%d\n", err); + return err; + } + + pci_set_master(pdev); + + start = pci_resource_start(pdev, 0); + if (!start) { + printk(KERN_ERR "vrc4173:No PCI I/O resources, aborting\n"); + return -ENODEV; + } + + if (!start || (((flags = pci_resource_flags(pdev, 0)) & IORESOURCE_IO) == 0)) { + printk(KERN_ERR "vrc4173: No PCI I/O resources, aborting\n"); + return -ENODEV; + } + + if ((err = pci_request_regions(pdev, "NEC VRC4173")) < 0) { + printk(KERN_ERR "vrc4173: PCI resources are busy, aborting\n"); + return err; + } + + set_vrc4173_io_offset(start); + + vrc4173_cmu_init(); + + vrc4173_icu_init(pdev->irq); + + if ((err = vr41xx_cascade_irq(pdev->irq, vrc4173_get_irq_number)) < 0) { + printk(KERN_ERR + "vrc4173: IRQ resource %d is busy, aborting\n", pdev->irq); + return err; + } + + printk(KERN_INFO + "NEC VRC4173 at 0x%#08lx, IRQ is cascaded to %d\n", start, pdev->irq); + + return 0; +} + +static struct pci_driver vrc4173_driver = { + name: "NEC VRC4173", + probe: vrc4173_probe, + remove: NULL, + id_table: vrc4173_table, +}; + +static int __devinit vrc4173_init(void) +{ + int err; + + if ((err = pci_module_init(&vrc4173_driver)) < 0) + return err; + + vrc4173_initialized = 1; + + return 0; +} + +static void __devexit vrc4173_exit(void) +{ + vrc4173_initialized = 0; + + pci_unregister_driver(&vrc4173_driver); +} + +module_init(vrc4173_init); +module_exit(vrc4173_exit); diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/ibm-workpad/Makefile linux-2.4.21-bk38/arch/mips/vr41xx/ibm-workpad/Makefile --- linux-2.4.21-bk37/arch/mips/vr41xx/ibm-workpad/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/ibm-workpad/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,17 @@ +# +# Makefile for the IBM WorkPad z50 specific parts of the kernel +# +# Note! Dependencies are done automagically by 'make dep', which also +# 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 := workpad.o + +all: workpad.o + +obj-y := init.o setup.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/ibm-workpad/ide-workpad.c linux-2.4.21-bk38/arch/mips/vr41xx/ibm-workpad/ide-workpad.c --- linux-2.4.21-bk37/arch/mips/vr41xx/ibm-workpad/ide-workpad.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/ibm-workpad/ide-workpad.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,98 @@ +/* + * 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. + * + * IDE routines for typical pc-like standard configurations for the IBM WorkPad z50. + * + * Copyright (C) 1998, 1999, 2001 by Ralf Baechle + */ +/* + * Changes: + * Yoichi Yuasa Sun, 24 Feb 2002 + * - Added IBM WorkPad z50 support. + */ +#include +#include +#include +#include +#include +#include + +static int workpad_ide_default_irq(ide_ioreg_t base) +{ + return 49; +} + +static ide_ioreg_t workpad_ide_default_io_base(int index) +{ + switch (index) { + case 0: return 0x1f0; + case 1: return 0x170; + case 2: return 0x1e8; + case 3: return 0x168; + case 4: return 0x1e0; + case 5: return 0x160; + } + return 0; +} + +static void workpad_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; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206; + } + if (irq != NULL) + *irq = 0; + hw->io_ports[IDE_IRQ_OFFSET] = 0; +} + +static int workpad_ide_request_irq(unsigned int irq, + void (*handler)(int,void *, struct pt_regs *), + unsigned long flags, const char *device, + void *dev_id) +{ + return request_irq(irq, handler, SA_SHIRQ, device, dev_id); +} + +static void workpad_ide_free_irq(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); +} + +static int workpad_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void workpad_ide_request_region(ide_ioreg_t from, unsigned int extent, + const char *name) +{ + request_region(from, extent, name); +} + +static void workpad_ide_release_region(ide_ioreg_t from, unsigned int extent) +{ + release_region(from, extent); +} + +struct ide_ops workpad_ide_ops = { + &workpad_ide_default_irq, + &workpad_ide_default_io_base, + &workpad_ide_init_hwif_ports, + &workpad_ide_request_irq, + &workpad_ide_free_irq, + &workpad_ide_check_region, + &workpad_ide_request_region, + &workpad_ide_release_region +}; diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/ibm-workpad/init.c linux-2.4.21-bk38/arch/mips/vr41xx/ibm-workpad/init.c --- linux-2.4.21-bk37/arch/mips/vr41xx/ibm-workpad/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/ibm-workpad/init.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,49 @@ +/* + * FILE NAME + * arch/mips/vr41xx/ibm-workpad/init.c + * + * BRIEF MODULE DESCRIPTION + * Initialisation code for the IBM WorkPad z50. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * 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. + */ +#include +#include +#include +#include + +#include + +char arcs_cmdline[CL_SIZE]; + +const char *get_system_type(void) +{ + return "IBM WorkPad z50"; +} + +void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) +{ + int i; + + /* + * collect args and prepare cmd_line + */ + for (i = 1; i < argc; i++) { + strcat(arcs_cmdline, argv[i]); + if (i < (argc - 1)) + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_NEC_VR41XX; + mips_machtype = MACH_IBM_WORKPAD; +} + +void __init prom_free_prom_memory (void) +{ +} diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/ibm-workpad/setup.c linux-2.4.21-bk38/arch/mips/vr41xx/ibm-workpad/setup.c --- linux-2.4.21-bk37/arch/mips/vr41xx/ibm-workpad/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/ibm-workpad/setup.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,65 @@ +/* + * FILE NAME + * arch/mips/vr41xx/workpad/setup.c + * + * BRIEF MODULE DESCRIPTION + * Setup for the IBM WorkPad z50. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * 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. + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +void __init ibm_workpad_setup(void) +{ + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; + iomem_resource.start = IO_MEM_RESOURCE_START; + iomem_resource.end = IO_MEM_RESOURCE_END; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + _machine_restart = vr41xx_restart; + _machine_halt = vr41xx_halt; + _machine_power_off = vr41xx_power_off; + + board_time_init = vr41xx_time_init; + board_timer_setup = vr41xx_timer_setup; + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + +#if defined(CONFIG_IDE) || defined(CONFIG_IDE_MODULE) + ide_ops = &vr41xx_ide_ops; +#endif + + vr41xx_bcu_init(); + + vr41xx_cmu_init(0); + + vr41xx_siu_init(SIU_RS232C, 0); +} diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/nec-eagle/Makefile linux-2.4.21-bk38/arch/mips/vr41xx/nec-eagle/Makefile --- linux-2.4.21-bk37/arch/mips/vr41xx/nec-eagle/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/nec-eagle/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -19,7 +19,6 @@ obj-y := init.o irq.o setup.o -obj-$(CONFIG_IDE) += ide-eagle.o -obj-$(CONFIG_PCI) += pci_fixup.o +obj-$(CONFIG_PCI) += pci_fixup.o vrc4173.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/nec-eagle/init.c linux-2.4.21-bk38/arch/mips/vr41xx/nec-eagle/init.c --- linux-2.4.21-bk37/arch/mips/vr41xx/nec-eagle/init.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/nec-eagle/init.c 2003-08-24 02:55:58.000000000 -0700 @@ -52,10 +52,6 @@ return "NEC Eagle/Hawk"; } -void __init bus_error_init(void) -{ -} - void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) { int i; diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/nec-eagle/irq.c linux-2.4.21-bk38/arch/mips/vr41xx/nec-eagle/irq.c --- linux-2.4.21-bk37/arch/mips/vr41xx/nec-eagle/irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/nec-eagle/irq.c 2003-08-24 02:55:58.000000000 -0700 @@ -164,9 +164,6 @@ writeb(0, NEC_EAGLE_SDBINTMSK); writeb(0, NEC_EAGLE_PCIINTMSKREG); - vr41xx_set_irq_trigger(VRC4173_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH); - vr41xx_set_irq_level(VRC4173_PIN, LEVEL_LOW); - vr41xx_set_irq_trigger(PCISLOT_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH); vr41xx_set_irq_level(PCISLOT_PIN, LEVEL_HIGH); diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/nec-eagle/pci_fixup.c linux-2.4.21-bk38/arch/mips/vr41xx/nec-eagle/pci_fixup.c --- linux-2.4.21-bk37/arch/mips/vr41xx/nec-eagle/pci_fixup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/nec-eagle/pci_fixup.c 2003-08-24 02:55:58.000000000 -0700 @@ -47,9 +47,7 @@ #include #include -#ifdef CONFIG_VRC4173 #include -#endif void __init pcibios_fixup_resources(struct pci_dev *dev) { @@ -119,41 +117,44 @@ break; } break; -#ifdef CONFIG_VRC4173 case 12: - dev->irq = VRC4173_CARDU1_IRQ; + dev->irq = VRC4173_PCMCIA1_IRQ; break; case 13: - dev->irq = VRC4173_CARDU2_IRQ; + dev->irq = VRC4173_PCMCIA2_IRQ; break; - case 24: - dev->irq = VRC4173_CARDU1_IRQ; - break; - case 25: - dev->irq = VRC4173_CARDU2_IRQ; - break; -#endif case 28: dev->irq = LANINTA_IRQ; break; case 29: - dev->irq = PCISLOT_IRQ; + switch (pin) { + case 1: + dev->irq = PCISLOT_IRQ; + break; + case 2: + dev->irq = CP_INTB_IRQ; + break; + case 3: + dev->irq = CP_INTC_IRQ; + break; + case 4: + dev->irq = CP_INTD_IRQ; + break; + } break; -#ifdef CONFIG_VRC4173 case 30: switch (func) { case 0: - dev->irq = VRC4173_IRQ; + dev->irq = VRC4173_CASCADE_IRQ; break; case 1: - dev->irq = VRC4173_AC97U_IRQ; + dev->irq = VRC4173_AC97_IRQ; break; case 2: - dev->irq = VRC4173_USBU_IRQ; + dev->irq = VRC4173_USB_IRQ; break; } break; -#endif } pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/nec-eagle/setup.c linux-2.4.21-bk38/arch/mips/vr41xx/nec-eagle/setup.c --- linux-2.4.21-bk37/arch/mips/vr41xx/nec-eagle/setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/nec-eagle/setup.c 2003-08-24 02:55:58.000000000 -0700 @@ -55,13 +55,12 @@ extern void * __rd_start, * __rd_end; #endif -#ifdef CONFIG_BLK_DEV_IDE -extern struct ide_ops eagle_ide_ops; -#endif - extern void eagle_irq_init(void); #ifdef CONFIG_PCI + +extern void vrc4173_preinit(void); + static struct resource vr41xx_pci_io_resource = { "PCI I/O space", VR41XX_PCI_IO_START, @@ -135,22 +134,22 @@ conswitchp = &dummy_con; #endif -#ifdef CONFIG_BLK_DEV_IDE - ide_ops = &eagle_ide_ops; +#if defined(CONFIG_IDE) || defined(CONFIG_IDE_MODULE) + ide_ops = &vr41xx_ide_ops; #endif vr41xx_bcu_init(); vr41xx_cmu_init(0); +#ifdef CONFIG_SERIAL vr41xx_dsiu_init(); vr41xx_siu_init(SIU_RS232C, 0); +#endif #ifdef CONFIG_PCI vr41xx_pciu_init(&pci_address_map); -#endif -#ifdef CONFIG_VRC4173 - vrc4173_init(); + vrc4173_preinit(); #endif } diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/nec-eagle/vrc4173.c linux-2.4.21-bk38/arch/mips/vr41xx/nec-eagle/vrc4173.c --- linux-2.4.21-bk37/arch/mips/vr41xx/nec-eagle/vrc4173.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/nec-eagle/vrc4173.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,126 @@ +/* + * FILE NAME + * arch/mips/vr41xx/nec-eagle/vrc4173.c + * + * BRIEF MODULE DESCRIPTION + * Pre-setup for NEC VRC4173. + * + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@mvista.com + * + * Copyright 2001,2002 MontaVista Software Inc. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include + +#ifdef CONFIG_PCI +#include +#include +#include + +#include +#include +#include + +#define PCI_CONFIG_ADDR KSEG1ADDR(0x0f000c18) +#define PCI_CONFIG_DATA KSEG1ADDR(0x0f000c14) + +static inline void config_writeb(u8 reg, u8 val) +{ + u32 data; + int shift; + + writel((1UL << 0x1e) | (reg & 0xfc), PCI_CONFIG_ADDR); + data = readl(PCI_CONFIG_DATA); + + shift = (reg & 3) << 3; + data &= ~(0xff << shift); + data |= (((u32)val) << shift); + + writel(data, PCI_CONFIG_DATA); +} + +static inline u16 config_readw(u8 reg) +{ + u32 data; + + writel(((1UL << 30) | (reg & 0xfc)) , PCI_CONFIG_ADDR); + data = readl(PCI_CONFIG_DATA); + + return (u16)(data >> ((reg & 2) << 3)); +} + +static inline u32 config_readl(u8 reg) +{ + writel(((1UL << 30) | (reg & 0xfc)) , PCI_CONFIG_ADDR); + + return readl(PCI_CONFIG_DATA); +} + +static inline void config_writel(u8 reg, u32 val) +{ + writel((1UL << 0x1e) | (reg & 0xfc), PCI_CONFIG_ADDR); + writel(val, PCI_CONFIG_DATA); +} + +void __init vrc4173_preinit(void) +{ + u32 cmdsts, base; + u16 cmu_mask; + + + if ((config_readw(PCI_VENDOR_ID) == PCI_VENDOR_ID_NEC) && + (config_readw(PCI_DEVICE_ID) == PCI_DEVICE_ID_NEC_VRC4173)) { + /* + * Initialized NEC VRC4173 Bus Control Unit + */ + cmdsts = config_readl(PCI_COMMAND); + config_writel(PCI_COMMAND, + cmdsts | + PCI_COMMAND_IO | + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER); + + config_writeb(PCI_LATENCY_TIMER, 0x80); + + config_writel(PCI_BASE_ADDRESS_0, VR41XX_PCI_IO_START); + base = config_readl(PCI_BASE_ADDRESS_0); + base &= PCI_BASE_ADDRESS_IO_MASK; + config_writeb(0x40, 0x01); + + /* CARDU1 IDSEL = AD12, CARDU2 IDSEL = AD13 */ + config_writeb(0x41, 0); + + cmu_mask = 0x1000; + outw(cmu_mask, base + 0x040); + cmu_mask |= 0x0800; + outw(cmu_mask, base + 0x040); + + outw(0x000f, base + 0x042); /* Soft reset of CMU */ + cmu_mask |= 0x05e0; + outw(cmu_mask, base + 0x040); + cmu_mask = inw(base + 0x040); /* dummy read */ + outw(0x0000, base + 0x042); + } +} + +#endif diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/tanbac-tb0226/Makefile linux-2.4.21-bk38/arch/mips/vr41xx/tanbac-tb0226/Makefile --- linux-2.4.21-bk37/arch/mips/vr41xx/tanbac-tb0226/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/tanbac-tb0226/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,19 @@ +# +# Makefile for the TANBAC TB0226 specific parts of the kernel +# +# Note! Dependencies are done automagically by 'make dep', which also +# 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 := tb0226.o + +all: tb0226.o + +obj-y := init.o setup.o + +obj-$(CONFIG_PCI) += pci_fixup.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/tanbac-tb0226/init.c linux-2.4.21-bk38/arch/mips/vr41xx/tanbac-tb0226/init.c --- linux-2.4.21-bk37/arch/mips/vr41xx/tanbac-tb0226/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/tanbac-tb0226/init.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,64 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0226/init.c + * + * BRIEF MODULE DESCRIPTION + * Initialisation code for the TANBAC TB0226. + * + * Copyright 2002,2003 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * 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. + */ +#include +#include +#include +#include + +#include +#include +#include +#include + +char arcs_cmdline[CL_SIZE]; + +const char *get_system_type(void) +{ + return "TANBAC TB0226"; +} + +void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) +{ + u32 config; + int i; + + /* + * collect args and prepare cmd_line + */ + for (i = 1; i < argc; i++) { + strcat(arcs_cmdline, argv[i]); + if (i < (argc - 1)) + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_NEC_VR41XX; + mips_machtype = MACH_TANBAC_TB0226; + + switch (current_cpu_data.processor_id) { + case PRID_VR4131_REV1_2: + config = read_c0_config(); + config &= ~0x00000030UL; + config |= 0x00410000UL; + write_c0_config(config); + break; + default: + break; + } +} + +void __init prom_free_prom_memory (void) +{ +} diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/tanbac-tb0226/pci_fixup.c linux-2.4.21-bk38/arch/mips/vr41xx/tanbac-tb0226/pci_fixup.c --- linux-2.4.21-bk37/arch/mips/vr41xx/tanbac-tb0226/pci_fixup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/tanbac-tb0226/pci_fixup.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,87 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0226/pci_fixup.c + * + * BRIEF MODULE DESCRIPTION + * The TANBAC TB0226 specific PCI fixups. + * + * Copyright 2002,2003 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * 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. + */ +#include +#include +#include + +#include + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ +} + +void __init pcibios_fixup(void) +{ +} + +void __init pcibios_fixup_irqs(void) +{ + struct pci_dev *dev; + u8 slot, pin; + + pci_for_each_dev(dev) { + slot = PCI_SLOT(dev->devfn); + dev->irq = 0; + + switch (slot) { + case 12: + vr41xx_set_irq_trigger(GD82559_1_PIN, TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(GD82559_1_PIN, LEVEL_LOW); + dev->irq = GD82559_1_IRQ; + break; + case 13: + vr41xx_set_irq_trigger(GD82559_2_PIN, TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(GD82559_2_PIN, LEVEL_LOW); + dev->irq = GD82559_2_IRQ; + break; + case 14: + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + switch (pin) { + case 1: + vr41xx_set_irq_trigger(UPD720100_INTA_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(UPD720100_INTA_PIN, LEVEL_LOW); + dev->irq = UPD720100_INTA_IRQ; + break; + case 2: + vr41xx_set_irq_trigger(UPD720100_INTB_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(UPD720100_INTB_PIN, LEVEL_LOW); + dev->irq = UPD720100_INTB_IRQ; + break; + case 3: + vr41xx_set_irq_trigger(UPD720100_INTC_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(UPD720100_INTC_PIN, LEVEL_LOW); + dev->irq = UPD720100_INTC_IRQ; + break; + } + break; + } + + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +} + +unsigned int pcibios_assign_all_busses(void) +{ + return 0; +} diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/tanbac-tb0226/setup.c linux-2.4.21-bk38/arch/mips/vr41xx/tanbac-tb0226/setup.c --- linux-2.4.21-bk37/arch/mips/vr41xx/tanbac-tb0226/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/tanbac-tb0226/setup.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,112 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0226/setup.c + * + * BRIEF MODULE DESCRIPTION + * Setup for the TANBAC TB0226. + * + * Copyright 2002,2003 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * 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. + */ +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +#ifdef CONFIG_PCI +static struct resource vr41xx_pci_io_resource = { + "PCI I/O space", + VR41XX_PCI_IO_START, + VR41XX_PCI_IO_END, + IORESOURCE_IO +}; + +static struct resource vr41xx_pci_mem_resource = { + "PCI memory space", + VR41XX_PCI_MEM_START, + VR41XX_PCI_MEM_END, + IORESOURCE_MEM +}; + +extern struct pci_ops vr41xx_pci_ops; + +struct pci_channel mips_pci_channels[] = { + {&vr41xx_pci_ops, &vr41xx_pci_io_resource, &vr41xx_pci_mem_resource, 0, 256}, + {NULL, NULL, NULL, 0, 0} +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem1 = { + VR41XX_PCI_MEM1_BASE, + VR41XX_PCI_MEM1_MASK, + IO_MEM1_RESOURCE_START +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem2 = { + VR41XX_PCI_MEM2_BASE, + VR41XX_PCI_MEM2_MASK, + IO_MEM2_RESOURCE_START +}; + +struct vr41xx_pci_address_space vr41xx_pci_io = { + VR41XX_PCI_IO_BASE, + VR41XX_PCI_IO_MASK, + IO_PORT_RESOURCE_START +}; + +static struct vr41xx_pci_address_map pci_address_map = { + &vr41xx_pci_mem1, + &vr41xx_pci_mem2, + &vr41xx_pci_io +}; +#endif + +void __init tanbac_tb0226_setup(void) +{ + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; + iomem_resource.start = IO_MEM1_RESOURCE_START; + iomem_resource.end = IO_MEM2_RESOURCE_END; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + _machine_restart = vr41xx_restart; + _machine_halt = vr41xx_halt; + _machine_power_off = vr41xx_power_off; + + board_time_init = vr41xx_time_init; + board_timer_setup = vr41xx_timer_setup; + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + + vr41xx_bcu_init(); + + vr41xx_cmu_init(0); + + vr41xx_siu_init(SIU_RS232C, 0); + +#ifdef CONFIG_PCI + vr41xx_pciu_init(&pci_address_map); +#endif +} diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/tanbac-tb0229/Makefile linux-2.4.21-bk38/arch/mips/vr41xx/tanbac-tb0229/Makefile --- linux-2.4.21-bk37/arch/mips/vr41xx/tanbac-tb0229/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/tanbac-tb0229/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,19 @@ +# +# Makefile for the TANBAC TB0229(VR4131DIMM) specific parts of the kernel +# +# Note! Dependencies are done automagically by 'make dep', which also +# 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 := tb0229.o + +all: tb0229.o + +obj-y := init.o setup.o reboot.o + +obj-$(CONFIG_PCI) += pci_fixup.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/tanbac-tb0229/init.c linux-2.4.21-bk38/arch/mips/vr41xx/tanbac-tb0229/init.c --- linux-2.4.21-bk37/arch/mips/vr41xx/tanbac-tb0229/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/tanbac-tb0229/init.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,69 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0229/init.c + * + * BRIEF MODULE DESCRIPTION + * Initialisation code for the TANBAC TB0229(VR4131DIMM) + * + * Copyright 2002,2003 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * Modified for TANBAC TB0229: + * Copyright 2003 Megasolution Inc. + * matsu@megasolution.jp + * + * 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. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +char arcs_cmdline[CL_SIZE]; + +const char *get_system_type(void) +{ + return "TANBAC TB0229"; +} + +void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) +{ + u32 config; + int i; + + /* + * collect args and prepare cmd_line + */ + for (i = 1; i < argc; i++) { + strcat(arcs_cmdline, argv[i]); + if (i < (argc - 1)) + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_NEC_VR41XX; + mips_machtype = MACH_TANBAC_TB0229; + + switch (current_cpu_data.processor_id) { + case PRID_VR4131_REV1_2: + config = read_c0_config(); + config &= ~0x00000030UL; + config |= 0x00410000UL; + write_c0_config(config); + break; + default: + break; + } +} + +void __init prom_free_prom_memory (void) +{ +} diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/tanbac-tb0229/pci_fixup.c linux-2.4.21-bk38/arch/mips/vr41xx/tanbac-tb0229/pci_fixup.c --- linux-2.4.21-bk37/arch/mips/vr41xx/tanbac-tb0229/pci_fixup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/tanbac-tb0229/pci_fixup.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,71 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0229/pci_fixup.c + * + * BRIEF MODULE DESCRIPTION + * The TANBAC TB0229(VR4131DIMM) specific PCI fixups. + * + * Copyright 2003 Megasolution Inc. + * matsu@megasolution.jp + * + * 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. + */ +#include +#include +#include + +#include + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ +} + +void __init pcibios_fixup(void) +{ +} + +void __init pcibios_fixup_irqs(void) +{ +#ifdef CONFIG_TANBAC_TB0219 + struct pci_dev *dev; + u8 slot; + + pci_for_each_dev(dev) { + slot = PCI_SLOT(dev->devfn); + dev->irq = 0; + + switch (slot) { + case 12: + vr41xx_set_irq_trigger(TB0219_PCI_SLOT1_PIN , TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT1_PIN, LEVEL_LOW); + dev->irq = TB0219_PCI_SLOT1_IRQ; + break; + case 13: + vr41xx_set_irq_trigger(TB0219_PCI_SLOT2_PIN , TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT2_PIN, LEVEL_LOW); + dev->irq = TB0219_PCI_SLOT2_IRQ; + break; + case 14: + vr41xx_set_irq_trigger(TB0219_PCI_SLOT3_PIN , TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT3_PIN, LEVEL_LOW); + dev->irq = TB0219_PCI_SLOT3_IRQ; + break; + default: + break; + } + + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +#endif +} + +unsigned int pcibios_assign_all_busses(void) +{ + return 0; +} diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/tanbac-tb0229/reboot.c linux-2.4.21-bk38/arch/mips/vr41xx/tanbac-tb0229/reboot.c --- linux-2.4.21-bk37/arch/mips/vr41xx/tanbac-tb0229/reboot.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/tanbac-tb0229/reboot.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,30 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0229/reboot.c + * + * BRIEF MODULE DESCRIPTION + * Depending on TANBAC TB0229(VR4131DIMM) of reboot system call. + * + * Copyright 2003 Megasolution Inc. + * matsu@megasolution.jp + * + * 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. + */ +#include +#include + +#define tb0229_hard_reset() writew(0, TB0219_RESET_REGS) + +void tanbac_tb0229_restart(char *command) +{ +#ifdef CONFIG_TANBAC_TB0219 + local_irq_disable(); + tb0229_hard_reset(); + while (1); +#else + vr41xx_restart(command); +#endif +} diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/tanbac-tb0229/setup.c linux-2.4.21-bk38/arch/mips/vr41xx/tanbac-tb0229/setup.c --- linux-2.4.21-bk37/arch/mips/vr41xx/tanbac-tb0229/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/tanbac-tb0229/setup.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,126 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0229/setup.c + * + * BRIEF MODULE DESCRIPTION + * Setup for the TANBAC TB0229 (VR4131DIMM) + * + * Copyright 2002,2003 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * Modified for TANBAC TB0229: + * Copyright 2003 Megasolution Inc. + * matsu@megasolution.jp + * + * 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. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_BLK_DEV_INITRD +extern void * __rd_start, * __rd_end; +#endif + +#ifdef CONFIG_PCI +static struct resource vr41xx_pci_io_resource = { + .name = "PCI I/O space", + .start = VR41XX_PCI_IO_START, + .end = VR41XX_PCI_IO_END, + .flags = IORESOURCE_IO, +}; + +static struct resource vr41xx_pci_mem_resource = { + .name = "PCI memory space", + .start = VR41XX_PCI_MEM_START, + .end = VR41XX_PCI_MEM_END, + .flags = IORESOURCE_MEM, +}; + +extern struct pci_ops vr41xx_pci_ops; + +struct pci_channel mips_pci_channels[] = { + { .pci_ops = &vr41xx_pci_ops, + .io_resource = &vr41xx_pci_io_resource, + .mem_resource = &vr41xx_pci_mem_resource, + .first_devfn = 0, + .last_devfn = 256, }, + { .pci_ops = NULL, + .io_resource = NULL, + .mem_resource = NULL, + .first_devfn = 0, + .last_devfn = 0, } +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem1 = { + .internal_base = VR41XX_PCI_MEM1_BASE, + .address_mask = VR41XX_PCI_MEM1_MASK, + .pci_base = IO_MEM1_RESOURCE_START, +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem2 = { + .internal_base = VR41XX_PCI_MEM2_BASE, + .address_mask = VR41XX_PCI_MEM2_MASK, + .pci_base = IO_MEM2_RESOURCE_START, +}; + +struct vr41xx_pci_address_space vr41xx_pci_io = { + .internal_base = VR41XX_PCI_IO_BASE, + .address_mask = VR41XX_PCI_IO_MASK, + .pci_base = IO_PORT_RESOURCE_START, +}; + +static struct vr41xx_pci_address_map pci_address_map = { + .mem1 = &vr41xx_pci_mem1, + .mem2 = &vr41xx_pci_mem2, + .io = &vr41xx_pci_io, +}; +#endif + +void __init tanbac_tb0229_setup(void) +{ + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; + iomem_resource.start = IO_MEM1_RESOURCE_START; + iomem_resource.end = IO_MEM2_RESOURCE_END; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + _machine_restart = tanbac_tb0229_restart; + _machine_halt = vr41xx_halt; + _machine_power_off = vr41xx_power_off; + + board_time_init = vr41xx_time_init; + board_timer_setup = vr41xx_timer_setup; + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + + vr41xx_bcu_init(); + + vr41xx_cmu_init(0); + + vr41xx_siu_init(SIU_RS232C, 0); + vr41xx_dsiu_init(); + +#ifdef CONFIG_PCI + vr41xx_pciu_init(&pci_address_map); +#endif +} + diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/victor-mpc30x/Makefile linux-2.4.21-bk38/arch/mips/vr41xx/victor-mpc30x/Makefile --- linux-2.4.21-bk37/arch/mips/vr41xx/victor-mpc30x/Makefile 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/victor-mpc30x/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,19 @@ +# +# Makefile for the Victor MP-C303/304 specific parts of the kernel +# +# Note! Dependencies are done automagically by 'make dep', which also +# 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 := mpc30x.o + +all: mpc30x.o + +obj-y := init.o setup.o + +obj-$(CONFIG_PCI) += pci_fixup.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/victor-mpc30x/ide-mpc30x.c linux-2.4.21-bk38/arch/mips/vr41xx/victor-mpc30x/ide-mpc30x.c --- linux-2.4.21-bk37/arch/mips/vr41xx/victor-mpc30x/ide-mpc30x.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/victor-mpc30x/ide-mpc30x.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,91 @@ +/* + * 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. + * + * IDE routines for typical pc-like standard configurations + * for the ZAO Networks Capcella. + * + * Copyright (C) 1998, 1999, 2001 by Ralf Baechle + */ +/* + * Changes: + * Yoichi Yuasa Fri, 23 Aug 2002 + * - Added Victor MP-C303/304 support. + */ +#include +#include +#include +#include +#include +#include + +static int mpc30x_ide_default_irq(ide_ioreg_t base) +{ + return 0; +} + +static ide_ioreg_t mpc30x_ide_default_io_base(int index) +{ + return 0; +} + +static void mpc30x_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; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206; + } + if (irq != NULL) + *irq = 0; + hw->io_ports[IDE_IRQ_OFFSET] = 0; +} + +static int mpc30x_ide_request_irq(unsigned int irq, + void (*handler)(int,void *, struct pt_regs *), + unsigned long flags, const char *device, + void *dev_id) +{ + return request_irq(irq, handler, flags, device, dev_id); +} + +static void mpc30x_ide_free_irq(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); +} + +static int mpc30x_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void mpc30x_ide_request_region(ide_ioreg_t from, unsigned int extent, + const char *name) +{ + request_region(from, extent, name); +} + +static void mpc30x_ide_release_region(ide_ioreg_t from, unsigned int extent) +{ + release_region(from, extent); +} + +struct ide_ops mpc30x_ide_ops = { + &mpc30x_ide_default_irq, + &mpc30x_ide_default_io_base, + &mpc30x_ide_init_hwif_ports, + &mpc30x_ide_request_irq, + &mpc30x_ide_free_irq, + &mpc30x_ide_check_region, + &mpc30x_ide_request_region, + &mpc30x_ide_release_region +}; diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/victor-mpc30x/init.c linux-2.4.21-bk38/arch/mips/vr41xx/victor-mpc30x/init.c --- linux-2.4.21-bk37/arch/mips/vr41xx/victor-mpc30x/init.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/victor-mpc30x/init.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,54 @@ +/* + * FILE NAME + * arch/mips/vr41xx/victor-mpc30x/init.c + * + * BRIEF MODULE DESCRIPTION + * Initialisation code for the Victor MP-C303/304. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * 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. + */ +#include +#include +#include +#include + +#include +#include +#include +#include + +char arcs_cmdline[CL_SIZE]; + +const char *get_system_type(void) +{ + return "Victor MP-C303/304"; +} + +void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) +{ + int i; + + /* + * collect args and prepare cmd_line + */ + for (i = 1; i < argc; i++) { + strcat(arcs_cmdline, argv[i]); + if (i < (argc - 1)) + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_NEC_VR41XX; + mips_machtype = MACH_VICTOR_MPC30X; + + add_memory_region(0, 32 << 20, BOOT_MEM_RAM); +} + +void __init prom_free_prom_memory (void) +{ +} diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/victor-mpc30x/pci_fixup.c linux-2.4.21-bk38/arch/mips/vr41xx/victor-mpc30x/pci_fixup.c --- linux-2.4.21-bk37/arch/mips/vr41xx/victor-mpc30x/pci_fixup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/victor-mpc30x/pci_fixup.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,73 @@ +/* + * FILE NAME + * arch/mips/vr41xx/victor-mpc30x/pci_fixup.c + * + * BRIEF MODULE DESCRIPTION + * The Victor MP-C303/304 specific PCI fixups. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * 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. + */ +#include +#include +#include + +#include +#include + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ +} + +void __init pcibios_fixup(void) +{ +} + +void __init pcibios_fixup_irqs(void) +{ + struct pci_dev *dev; + u8 slot, func; + + pci_for_each_dev(dev) { + slot = PCI_SLOT(dev->devfn); + func = PCI_FUNC(dev->devfn); + dev->irq = 0; + + switch (slot) { + case 12: /* NEC VRC4173 CARDU1 */ + dev->irq = VRC4173_PCMCIA1_IRQ; + break; + case 13: /* NEC VRC4173 CARDU2 */ + dev->irq = VRC4173_PCMCIA2_IRQ; + break; + case 29: /* mediaQ MQ-200 */ + dev->irq = MQ200_IRQ; + break; + case 30: + switch (func) { + case 0: /* NEC VRC4173 */ + dev->irq = VRC4173_CASCADE_IRQ; + break; + case 1: /* NEC VRC4173 AC97U */ + dev->irq = VRC4173_AC97_IRQ; + break; + case 2: /* NEC VRC4173 USBU */ + dev->irq = VRC4173_USB_IRQ; + break; + } + break; + } + + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +} + +unsigned int pcibios_assign_all_busses(void) +{ + return 0; +} diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/victor-mpc30x/setup.c linux-2.4.21-bk38/arch/mips/vr41xx/victor-mpc30x/setup.c --- linux-2.4.21-bk37/arch/mips/vr41xx/victor-mpc30x/setup.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/victor-mpc30x/setup.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,117 @@ +/* + * FILE NAME + * arch/mips/vr41xx/victor-mpc30x/setup.c + * + * BRIEF MODULE DESCRIPTION + * Setup for the Victor MP-C303/304. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * 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. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +#ifdef CONFIG_PCI +static struct resource vr41xx_pci_io_resource = { + "PCI I/O space", + VR41XX_PCI_IO_START, + VR41XX_PCI_IO_END, + IORESOURCE_IO +}; + +static struct resource vr41xx_pci_mem_resource = { + "PCI memory space", + VR41XX_PCI_MEM_START, + VR41XX_PCI_MEM_END, + IORESOURCE_MEM +}; + +extern struct pci_ops vr41xx_pci_ops; + +struct pci_channel mips_pci_channels[] = { + {&vr41xx_pci_ops, &vr41xx_pci_io_resource, &vr41xx_pci_mem_resource, 0, 256}, + {NULL, NULL, NULL, 0, 0} +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem1 = { + VR41XX_PCI_MEM1_BASE, + VR41XX_PCI_MEM1_MASK, + IO_MEM1_RESOURCE_START +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem2 = { + VR41XX_PCI_MEM2_BASE, + VR41XX_PCI_MEM2_MASK, + IO_MEM2_RESOURCE_START +}; + +struct vr41xx_pci_address_space vr41xx_pci_io = { + VR41XX_PCI_IO_BASE, + VR41XX_PCI_IO_MASK, + IO_PORT_RESOURCE_START +}; + +static struct vr41xx_pci_address_map pci_address_map = { + &vr41xx_pci_mem1, + &vr41xx_pci_mem2, + &vr41xx_pci_io +}; +#endif + +void __init victor_mpc30x_setup(void) +{ + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; + iomem_resource.start = IO_MEM1_RESOURCE_START; + iomem_resource.end = IO_MEM2_RESOURCE_END; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + _machine_restart = vr41xx_restart; + _machine_halt = vr41xx_halt; + _machine_power_off = vr41xx_power_off; + + board_time_init = vr41xx_time_init; + board_timer_setup = vr41xx_timer_setup; + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + +#if defined(CONFIG_IDE) || defined(CONFIG_IDE_MODULE) + ide_ops = &vr41xx_ide_ops; +#endif + + vr41xx_bcu_init(); + + vr41xx_cmu_init(0); + + vr41xx_siu_init(SIU_RS232C, 0); + +#ifdef CONFIG_PCI + vr41xx_pciu_init(&pci_address_map); +#endif +} diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/zao-capcella/Makefile linux-2.4.21-bk38/arch/mips/vr41xx/zao-capcella/Makefile --- linux-2.4.21-bk37/arch/mips/vr41xx/zao-capcella/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/zao-capcella/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -14,7 +14,6 @@ obj-y := init.o setup.o -obj-$(CONFIG_IDE) += ide-capcella.o obj-$(CONFIG_PCI) += pci_fixup.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/zao-capcella/init.c linux-2.4.21-bk38/arch/mips/vr41xx/zao-capcella/init.c --- linux-2.4.21-bk37/arch/mips/vr41xx/zao-capcella/init.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/zao-capcella/init.c 2003-08-24 02:55:58.000000000 -0700 @@ -30,10 +30,6 @@ return "ZAO Networks Capcella"; } -void __init bus_error_init(void) -{ -} - void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) { u32 config; @@ -51,12 +47,12 @@ mips_machgroup = MACH_GROUP_NEC_VR41XX; mips_machtype = MACH_ZAO_CAPCELLA; - switch (mips_cpu.processor_id) { + switch (current_cpu_data.processor_id) { case PRID_VR4131_REV1_2: - config = read_32bit_cp0_register(CP0_CONFIG); + config = read_c0_config(); config &= ~0x00000030UL; config |= 0x00410000UL; - write_32bit_cp0_register(CP0_CONFIG, config); + write_c0_config(config); break; default: break; diff -urN linux-2.4.21-bk37/arch/mips/vr41xx/zao-capcella/setup.c linux-2.4.21-bk38/arch/mips/vr41xx/zao-capcella/setup.c --- linux-2.4.21-bk37/arch/mips/vr41xx/zao-capcella/setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips/vr41xx/zao-capcella/setup.c 2003-08-24 02:55:58.000000000 -0700 @@ -29,10 +29,6 @@ extern void * __rd_start, * __rd_end; #endif -#ifdef CONFIG_BLK_DEV_IDE -extern struct ide_ops capcella_ide_ops; -#endif - #ifdef CONFIG_PCI static struct resource vr41xx_pci_io_resource = { "PCI I/O space", @@ -105,8 +101,8 @@ conswitchp = &dummy_con; #endif -#ifdef CONFIG_BLK_DEV_IDE - ide_ops = &capcella_ide_ops; +#if defined(CONFIG_IDE) || defined(CONFIG_IDE_MODULE) + ide_ops = &vr41xx_ide_ops; #endif vr41xx_bcu_init(); @@ -114,6 +110,7 @@ vr41xx_cmu_init(0x0102); vr41xx_siu_init(SIU_RS232C, 0); + vr41xx_dsiu_init(); #ifdef CONFIG_PCI vr41xx_pciu_init(&pci_address_map); diff -urN linux-2.4.21-bk37/arch/mips64/Makefile linux-2.4.21-bk38/arch/mips64/Makefile --- linux-2.4.21-bk37/arch/mips64/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -39,9 +39,14 @@ LINKFLAGS += -G 0 -static # -N MODFLAGS += -mlong-calls -ifdef CONFIG_REMOTE_DEBUG +ifdef CONFIG_KGDB GCCFLAGS += -g +ifdef CONFIG_SB1XXX_CORELIS +GCCFLAGS += -mno-sched-prolog -fno-omit-frame-pointer endif +endif + +check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) # # CPU-dependent compiler/assembler options for optimization. @@ -58,6 +63,10 @@ ifdef CONFIG_CPU_NEVADA GCCFLAGS += -mcpu=r8000 -mips3 -mmad endif +ifdef CONFIG_CPU_RM7000 +GCCFLAGS += $(call check_gcc, -march=rm7000, -mcpu=r5000) \ + -mips2 -Wa,--trap +endif ifdef CONFIG_CPU_R8000 GCCFLAGS += -mcpu=r8000 -mips4 endif @@ -65,7 +74,10 @@ GCCFLAGS += -mcpu=r8000 -mips4 endif ifdef CONFIG_CPU_SB1 -GCCFLAGS += -mcpu=r8000 -mips4 +GCCFLAGS += $(call check_gcc, -mcpu=sb1, -mcpu=r5000) -mips4 +ifdef CONFIG_SB1_PASS_1_WORKAROUNDS +MODFLAGS += -msb1-pass1-workarounds +endif endif ifdef CONFIG_CPU_MIPS64 #CFLAGS += -mips64 # Should be used then we get a MIPS64 compiler @@ -78,12 +90,42 @@ CORE_FILES += arch/mips/math-emu/fpu_emulator.o SUBDIRS += arch/mips/math-emu +# +# ramdisk/initrd support +# You need a compressed ramdisk image, named ramdisk.gz in +# arch/mips/ramdisk +# +ifdef CONFIG_EMBEDDED_RAMDISK +CORE_FILES += arch/mips/ramdisk/ramdisk.o +SUBDIRS += arch/mips/ramdisk +endif + # # Board-dependent options and extra files # # +# DECstation family +# +ifdef CONFIG_DECSTATION +CORE_FILES += arch/mips/dec/dec.o +SUBDIRS += arch/mips/dec arch/mips/dec/prom +LIBS += arch/mips/dec/prom/rexlib.a +LOADADDR := 0x80040000 +endif + +# +# Galileo EV64120 Board +# +ifdef CONFIG_MIPS_EV64120 +LIBS += arch/mips/gt64120/common/gt64120.o \ + arch/mips/gt64120/ev64120/ev64120.o +SUBDIRS += arch/mips/gt64120/common arch/mips/gt64120/ev64120 +LOADADDR := 0x80100000 +endif + +# # MIPS Atlas board # ifdef CONFIG_MIPS_ATLAS @@ -114,6 +156,45 @@ endif # +# Momentum Ocelot board +# +ifdef CONFIG_MOMENCO_OCELOT +# The Ocelot setup.o must be linked early - it does the ioremap() for the +# mips_io_port_base. +CORE_FILES += arch/mips/gt64120/common/gt64120.o \ + arch/mips/gt64120/momenco_ocelot/momenco_ocelot.o +SUBDIRS += arch/mips/gt64120/common arch/mips/gt64120/momenco_ocelot +LOADADDR := 0x80100000 +endif + +# +# Momentum Ocelot-G board +# +ifdef CONFIG_MOMENCO_OCELOT_G +# The Ocelot-G setup.o must be linked early - it does the ioremap() for the +# mips_io_port_base. +CORE_FILES += arch/mips/momentum/ocelot_g/ocelot_g.o +SUBDIRS += arch/mips/momentum/ocelot_g +LOADADDR := 0x80100000 +endif + +# +# Momentum Ocelot-C and -CS boards +# +ifdef CONFIG_MOMENCO_OCELOT_C +# The Ocelot-C[S] setup.o must be linked early - it does the ioremap() for the +# mips_io_port_base. +CORE_FILES += arch/mips/momentum/ocelot_c/ocelot_c.o +SUBDIRS += arch/mips/momentum/ocelot_c +LOADADDR := 0x80100000 +endif + +ifdef CONFIG_PCI +CORE_FILES += arch/mips/pci/pci-core.o +SUBDIRS += arch/mips/pci +endif + +# # SGI IP22 (Indy/Indigo2) # ifdef CONFIG_SGI_IP22 @@ -149,38 +230,34 @@ endif # -# SGI-IP32 (O2) -# -ifdef CONFIG_SGI_IP32 -CORE_FILES += arch/mips/sgi-ip32/ip32-kern.a -LIBS += arch/mips/arc/arclib.a -SUBDIRS += arch/mips/sgi-ip32 arch/mips/arc -# -# Set LOADADDR to >= 0x????????? if you want to leave space for symmon, -# 0x80002000 for production kernels. Note that the value must be -# 16kb aligned or the handling of the current variable will break. -# -LOADADDR := 0x80002000 -endif - -# -# Sibyte SB1250 SOC +# Sibyte SB1250 SOC and Broadcom (SiByte) BCM112x SOCs # -ifdef CONFIG_SIBYTE_SB1250 +ifneq ($(CONFIG_SIBYTE_SB1250)$(CONFIG_SIBYTE_BCM112X),) # This is a LIB so that it links at the end, and initcalls are later # the sequence; but it is built as an object so that modules don't get # removed (as happens, even if they have __initcall/module_init) LIBS += arch/mips/sibyte/sb1250/sb1250.o SUBDIRS += arch/mips/sibyte/sb1250 +ifdef CONFIG_MIPS_UNCACHED +LOADADDR := 0xa0100000 +else +LOADADDR := 0x80100000 +endif endif # -# Sibyte SWARM board +# Sibyte boards: +# +# BCM91250A (SWARM), +# BCM91250E (Sentosa), +# BCM91120C (CRhine), +# BCM91120x (Carmel), +# BCM91125C (CRhone), +# BCM91125E (Rhone). # -ifdef CONFIG_SIBYTE_SWARM +ifdef CONFIG_SIBYTE_BOARD LIBS += arch/mips/sibyte/swarm/sbswarm.a SUBDIRS += arch/mips/sibyte/swarm -LOADADDR := 0x80100000 endif # @@ -192,21 +269,12 @@ endif # -# SB1 Cache Error handler -# -ifdef CONFIG_SB1_CACHE_ERROR -LIBS += arch/mips/sibyte/sb1/sb1kern.a -SUBDIRS += arch/mips/sibyte/sb1 -endif - - -# # Some machines like the Indy need 32-bit ELF binaries for booting purposes. # Other need ECOFF, so we build a 32-bit ELF binary for them which we then # convert to ECOFF using elf2ecoff. # ifdef CONFIG_BOOT_ELF32 -GCCFLAGS += -Wa,-32 +GCCFLAGS += -Wa,-32 $(shell if $(CC) -Wa,-mgp64 -c -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "-Wa,-mgp64"; fi) LINKFLAGS += -T arch/mips64/ld.script.elf32 endif # @@ -214,17 +282,27 @@ # ELF files from 32-bit files by conversion. # ifdef CONFIG_BOOT_ELF64 -GCCFLAGS += -Wa,-32 +GCCFLAGS += -Wa,-32 $(shell if $(CC) -Wa,-mgp64 -c -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "-Wa,-mgp64"; fi) LINKFLAGS += -T arch/mips64/ld.script.elf32 #AS += -64 #LD += -m elf64bmip #LINKFLAGS += -T arch/mips64/ld.script.elf64 endif +ifdef CONFIG_CPU_LITTLE_ENDIAN +32bit-bfd = elf32-tradlittlemips +64bit-bfd = elf64-tradlittlemips +else +32bit-bfd = elf32-tradbigmips +64bit-bfd = elf64-tradbigmips +endif + AFLAGS += $(GCCFLAGS) CFLAGS += $(GCCFLAGS) +LD += --oformat $(32bit-bfd) + LINKFLAGS += -Ttext $(LOADADDR) @@ -236,31 +314,20 @@ MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot -ifdef CONFIG_CPU_LITTLE_ENDIAN -64bit-bfd = elf64-littlemips -else -64bit-bfd = elf64-bigmips -endif - vmlinux: arch/mips64/ld.script.elf32 arch/mips64/ld.script.elf32: arch/mips64/ld.script.elf32.S $(CPP) -C -P -I$(HPATH) -imacros $(HPATH)/asm-mips64/sn/mapped_kernel.h -Umips arch/mips64/ld.script.elf32.S > arch/mips64/ld.script.elf32 ifdef CONFIG_MAPPED_KERNEL vmlinux.64: vmlinux - $(OBJCOPY) -O $(64bit-bfd) --change-addresses=0xbfffffff40000000 $< $@ + $(OBJCOPY) -O $(64bit-bfd) --remove-section=.reginfo --change-addresses=0xbfffffff40000000 $< $@ else vmlinux.64: vmlinux - $(OBJCOPY) -O $(64bit-bfd) --change-addresses=0xa7ffffff80000000 $< $@ + $(OBJCOPY) -O $(64bit-bfd) --remove-section=.reginfo --change-addresses=0xa800000080000000 $< $@ endif -zImage: vmlinux - @$(MAKEBOOT) zImage - -compressed: zImage - -zdisk: vmlinux - @$(MAKEBOOT) zdisk +vmlinux.ecoff: vmlinux + @$(MAKEBOOT) $@ archclean: @$(MAKEBOOT) clean @@ -270,6 +337,7 @@ archmrproper: @$(MAKEBOOT) mrproper $(MAKE) -C arch/mips/tools mrproper + $(RM) $(TOPDIR)/include/asm-$(ARCH)/offset.h archdep: if [ ! -f $(TOPDIR)/include/asm-$(ARCH)/offset.h ]; then \ diff -urN linux-2.4.21-bk37/arch/mips64/boot/Makefile linux-2.4.21-bk38/arch/mips64/boot/Makefile --- linux-2.4.21-bk37/arch/mips64/boot/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips64/boot/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -22,11 +22,11 @@ vmlinux.ecoff: $(CONFIGURE) elf2ecoff $(TOPDIR)/vmlinux ./elf2ecoff $(TOPDIR)/vmlinux vmlinux.ecoff $(E2EFLAGS) -elf2ecoff: elf2ecoff.c - $(HOSTCC) -o $@ $^ +elf2ecoff: $(TOPDIR)/arch/mips/boot/elf2ecoff.c + $(HOSTCC) -I$(TOPDIR)/arch/mips/boot -I- -o $@ $^ -addinitrd: addinitrd.c - $(HOSTCC) -o $@ $^ +addinitrd: $(TOPDIR)/arch/mips/boot/addinitrd.c + $(HOSTCC) -I$(TOPDIR)/arch/mips/boot -I- -o $@ $^ # Don't build dependencies, this may die if $(CC) isn't gcc dep: diff -urN linux-2.4.21-bk37/arch/mips64/defconfig linux-2.4.21-bk38/arch/mips64/defconfig --- linux-2.4.21-bk37/arch/mips64/defconfig 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/defconfig 2003-08-24 02:55:58.000000000 -0700 @@ -19,17 +19,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +46,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -52,20 +62,24 @@ # CONFIG_MAPPED_KERNEL is not set # CONFIG_REPLICATE_KTEXT is not set # CONFIG_REPLICATE_EXHANDLERS is not set -CONFIG_SMP=y -# CONFIG_SGI_IP32 is not set +CONFIG_SMP_CAPABLE=y # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BOOT_ELF64=y CONFIG_ARC64=y +CONFIG_L1_CACHE_SHIFT=7 +CONFIG_NEW_TIME_C=y CONFIG_PCI=y CONFIG_QL_ISP_A64=y -CONFIG_L1_CACHE_SHIFT=7 # CONFIG_MIPS_AU1000 is not set # @@ -87,6 +101,7 @@ CONFIG_CPU_R10000=y # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_SMP=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -99,7 +114,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set # CONFIG_MIPS_INSANE_LARGE is not set CONFIG_NET=y CONFIG_PCI_NAMES=y @@ -119,6 +133,8 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y CONFIG_MIPS32_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set @@ -261,6 +277,7 @@ # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -297,16 +314,7 @@ # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set - -# -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set +# CONFIG_SCSI_NSP32 is not set # # Network device support @@ -351,6 +359,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -433,13 +442,22 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +CONFIG_SGI_IP27_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -467,8 +485,8 @@ # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set @@ -578,9 +596,9 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # diff -urN linux-2.4.21-bk37/arch/mips64/defconfig-atlas linux-2.4.21-bk38/arch/mips64/defconfig-atlas --- linux-2.4.21-bk37/arch/mips64/defconfig-atlas 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/defconfig-atlas 2003-08-24 02:55:58.000000000 -0700 @@ -19,17 +19,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set CONFIG_MIPS_ATLAS=y # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +46,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,21 +56,27 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BOOT_ELF32=y CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NEW_IRQ=y +CONFIG_MIPS_BONITO64=y +CONFIG_MIPS_GT64120=y +CONFIG_MIPS_MSC=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y CONFIG_PCI=y -CONFIG_SWAP_IO_SPACE=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y # CONFIG_MIPS_AU1000 is not set # @@ -82,7 +98,6 @@ # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -95,7 +110,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set CONFIG_NET=y CONFIG_PCI_NAMES=y # CONFIG_ISA is not set @@ -114,6 +128,8 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y CONFIG_MIPS32_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set @@ -269,6 +285,7 @@ # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -305,19 +322,10 @@ # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# # Network device support # CONFIG_NETDEVICES=y @@ -360,6 +368,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -445,13 +454,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set CONFIG_RTC=y +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -575,9 +592,9 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set diff -urN linux-2.4.21-bk37/arch/mips64/defconfig-decstation linux-2.4.21-bk38/arch/mips64/defconfig-decstation --- linux-2.4.21-bk37/arch/mips64/defconfig-decstation 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/defconfig-decstation 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,626 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +# CONFIG_MIPS32 is not set +CONFIG_MIPS64=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +CONFIG_DECSTATION=y +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_BOOT_ELF32=y +CONFIG_IRQ_CPU=y +CONFIG_L1_CACHE_SHIFT=4 +CONFIG_NONCOHERENT_IO=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +CONFIG_CPU_R4X00=y +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_64BIT_PHYS_ADDR is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +CONFIG_TC=y +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +CONFIG_MIPS32_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set +CONFIG_BINFMT_ELF32=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# 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_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# 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_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_SD_EXTRA_DEVS=40 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +CONFIG_SCSI_DECNCR=y +# CONFIG_SCSI_DECSII is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM 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_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set +CONFIG_DECLANCE=y + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_SERIAL_DEC=y +CONFIG_SERIAL_DEC_CONSOLE=y +# CONFIG_DZ is not set +CONFIG_ZS=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO 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_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_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 is not set +# CONFIG_DEVFS_MOUNT is not set +# 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_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_INTERMEZZO_FS is not set +# CONFIG_NFS_FS is not set +# CONFIG_NFS_V3 is not set +# CONFIG_ROOT_NFS is not set +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +CONFIG_OSF_PARTITION=y +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +CONFIG_ULTRIX_PARTITION=y +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Library routines +# +# CONFIG_ZLIB_INFLATE is not set +# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips64/defconfig-ip22 linux-2.4.21-bk38/arch/mips64/defconfig-ip22 --- linux-2.4.21-bk37/arch/mips64/defconfig-ip22 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/defconfig-ip22 2003-08-24 02:55:58.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,28 +58,28 @@ # CONFIG_NINO is not set CONFIG_SGI_IP22=y # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_ARC32=y -CONFIG_ARC_CONSOLE=y -CONFIG_ARC_MEMORY=y +CONFIG_ARC_PROMLIB=y CONFIG_BOARD_SCACHE=y CONFIG_BOOT_ELF32=y -CONFIG_SWAP_IO_SPACE=y +# CONFIG_SWAP_IO_SPACE_W is not set +CONFIG_SWAP_IO_SPACE_L=y CONFIG_IRQ_CPU=y CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NONCOHERENT_IO=y -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y CONFIG_PC_KEYB=y -CONFIG_SGI=y # CONFIG_MIPS_AU1000 is not set # @@ -91,7 +101,6 @@ # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -104,7 +113,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set CONFIG_ARC_CONSOLE=y # CONFIG_IP22_EISA is not set CONFIG_NET=y @@ -125,9 +133,10 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y CONFIG_MIPS32_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set # # Memory Technology Devices (MTD) @@ -282,6 +291,7 @@ # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -310,6 +320,7 @@ # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # @@ -354,6 +365,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -411,7 +423,30 @@ CONFIG_VT_CONSOLE=y # CONFIG_SERIAL is not set # CONFIG_SERIAL_EXTENDED is not set -# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_ESPSERIAL is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +# CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set +# CONFIG_TXX927_SERIAL is not set +CONFIG_IP22_SERIAL=y CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -439,6 +474,11 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards @@ -447,6 +487,7 @@ # CONFIG_WATCHDOG_NOWAYOUT is not set # CONFIG_ACQUIRE_WDT is not set # CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set # CONFIG_ALIM7101_WDT is not set # CONFIG_SC520_WDT is not set # CONFIG_PCWATCHDOG is not set @@ -457,6 +498,7 @@ # CONFIG_MIXCOMWD is not set # CONFIG_60XX_WDT is not set # CONFIG_SC1200_WDT is not set +# CONFIG_SCx200_WDT is not set # CONFIG_SOFT_WATCHDOG is not set # CONFIG_W83877F_WDT is not set # CONFIG_WDT is not set @@ -464,8 +506,12 @@ # CONFIG_MACHZ_WDT is not set CONFIG_INDYDOG=y # CONFIG_AMD7XX_TCO is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +CONFIG_SGI_DS1286=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -478,13 +524,6 @@ # CONFIG_DRM is not set # -# SGI Character devices -# -CONFIG_SGI_NEWPORT_CONSOLE=y -CONFIG_FONT_8x16=y -CONFIG_DUMMY_CONSOLE=y - -# # File systems # # CONFIG_QUOTA is not set @@ -500,8 +539,8 @@ # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set @@ -532,7 +571,7 @@ # CONFIG_QNX4FS_FS is not set # CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UDF_FS is not set # CONFIG_UDF_RW is not set @@ -595,6 +634,9 @@ # Console drivers # # CONFIG_VGA_CONSOLE is not set +CONFIG_SGI_NEWPORT_CONSOLE=y +CONFIG_FONT_8x16=y +CONFIG_DUMMY_CONSOLE=y # CONFIG_MDA_CONSOLE is not set # @@ -605,15 +647,31 @@ # # Sound # -# CONFIG_SOUND is not set - -# -# SGI devices -# -CONFIG_SGI_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set -CONFIG_SGI_DS1286=y -# CONFIG_SGI_NEWPORT_GFX is not set +CONFIG_SOUND=y +# CONFIG_SOUND_ALI5455 is not set +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_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_MAESTRO3 is not set +# CONFIG_SOUND_FORTE is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_HAL2=y +# 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_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set # # USB support @@ -629,7 +687,9 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set diff -urN linux-2.4.21-bk37/arch/mips64/defconfig-ip27 linux-2.4.21-bk38/arch/mips64/defconfig-ip27 --- linux-2.4.21-bk37/arch/mips64/defconfig-ip27 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/defconfig-ip27 2003-08-24 02:55:58.000000000 -0700 @@ -19,17 +19,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +46,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -52,20 +62,24 @@ # CONFIG_MAPPED_KERNEL is not set # CONFIG_REPLICATE_KTEXT is not set # CONFIG_REPLICATE_EXHANDLERS is not set -CONFIG_SMP=y -# CONFIG_SGI_IP32 is not set +CONFIG_SMP_CAPABLE=y # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BOOT_ELF64=y CONFIG_ARC64=y +CONFIG_L1_CACHE_SHIFT=7 +CONFIG_NEW_TIME_C=y CONFIG_PCI=y CONFIG_QL_ISP_A64=y -CONFIG_L1_CACHE_SHIFT=7 # CONFIG_MIPS_AU1000 is not set # @@ -87,6 +101,7 @@ CONFIG_CPU_R10000=y # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set +CONFIG_SMP=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y @@ -99,7 +114,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set # CONFIG_MIPS_INSANE_LARGE is not set CONFIG_NET=y CONFIG_PCI_NAMES=y @@ -119,6 +133,8 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y CONFIG_MIPS32_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set @@ -261,6 +277,7 @@ # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -297,16 +314,7 @@ # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set - -# -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set +# CONFIG_SCSI_NSP32 is not set # # Network device support @@ -351,6 +359,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -433,13 +442,22 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set +CONFIG_SGI_IP27_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -467,8 +485,8 @@ # CONFIG_BEFS_FS is not set # CONFIG_BEFS_DEBUG is not set # CONFIG_BFS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set @@ -578,9 +596,9 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # diff -urN linux-2.4.21-bk37/arch/mips64/defconfig-ip32 linux-2.4.21-bk38/arch/mips64/defconfig-ip32 --- linux-2.4.21-bk37/arch/mips64/defconfig-ip32 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/defconfig-ip32 1969-12-31 16:00:00.000000000 -0800 @@ -1,609 +0,0 @@ -# -# Automatically generated make config: don't edit -# -CONFIG_MIPS=y -# CONFIG_MIPS32 is not set -CONFIG_MIPS64=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# -# Loadable module support -# -# CONFIG_MODULES is not set - -# -# Machine selection -# -# CONFIG_ACER_PICA_61 is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1100 is not set -# CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set -# CONFIG_BAGET_MIPS is not set -# CONFIG_MIPS_COBALT is not set -# CONFIG_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set -# CONFIG_MIPS_EV96100 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_HP_LASERJET is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MAGNUM_4000 is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set -# CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_G is not set -# CONFIG_DDB5074 is not set -# CONFIG_DDB5476 is not set -# CONFIG_DDB5477 is not set -# CONFIG_NEC_OSPREY is not set -# CONFIG_NEC_EAGLE is not set -# CONFIG_OLIVETTI_M700 is not set -# CONFIG_NINO is not set -# CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP27 is not set -CONFIG_SGI_IP32=y -# CONFIG_SIBYTE_SB1xxx_SOC is not set -# CONFIG_SNI_RM200_PCI is not set -# CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_ZAO_CAPCELLA is not set -# CONFIG_HIGHMEM is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_ARC_MEMORY=y -CONFIG_ARC32=y -CONFIG_BOOT_ELF32=y -CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NONCOHERENT_IO=y -CONFIG_PC_KEYB=y -CONFIG_PCI=y -# CONFIG_MIPS_AU1000 is not set - -# -# CPU selection -# -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set -# CONFIG_CPU_R3000 is not set -# CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_VR41XX is not set -# CONFIG_CPU_R4300 is not set -# CONFIG_CPU_R4X00 is not set -# CONFIG_CPU_TX49XX is not set -CONFIG_CPU_R5000=y -# CONFIG_CPU_R5432 is not set -# CONFIG_CPU_R6000 is not set -# CONFIG_CPU_NEVADA is not set -# CONFIG_CPU_R8000 is not set -# CONFIG_CPU_R10000 is not set -# CONFIG_CPU_RM7000 is not set -# CONFIG_CPU_SB1 is not set -CONFIG_BOARD_SCACHE=y -# CONFIG_64BIT_PHYS_ADDR is not set -# CONFIG_CPU_ADVANCED is not set -CONFIG_CPU_HAS_LLSC=y -CONFIG_CPU_HAS_LLDSCD=y -# CONFIG_CPU_HAS_WB is not set -CONFIG_CPU_HAS_SYNC=y - -# -# General setup -# -# CONFIG_CPU_LITTLE_ENDIAN is not set -# CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set -CONFIG_ARC_CONSOLE=y -CONFIG_NET=y -CONFIG_PCI_NAMES=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set -# CONFIG_TC is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set -# CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -# CONFIG_HOTPLUG_PCI is not set -CONFIG_SYSVIPC=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_SYSCTL=y -CONFIG_KCORE_ELF=y -# CONFIG_KCORE_AOUT is not set -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -CONFIG_MIPS32_COMPAT=y -CONFIG_BINFMT_ELF32=y -CONFIG_BINFMT_MISC=y -# CONFIG_PM is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# 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_CISS_SCSI_TAPE is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_BLK_STATS is not set - -# -# 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_MD_MULTIPATH is not set -# CONFIG_BLK_DEV_LVM is not set - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set -CONFIG_UNIX=y -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set -# CONFIG_VLAN_8021Q is not set - -# -# -# -# CONFIG_IPX is not set -# CONFIG_ATALK is not set - -# -# Appletalk devices -# -# CONFIG_DEV_APPLETALK is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# ATA/IDE/MFM/RLL support -# -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI support -# -CONFIG_SCSI=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_SD_EXTRA_DEVS=40 -CONFIG_CHR_DEV_ST=y -CONFIG_CHR_DEV_OSST=y -CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_SR_EXTRA_DEVS=2 -CONFIG_CHR_DEV_SG=y - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -CONFIG_SCSI_DEBUG_QUEUES=y -CONFIG_SCSI_MULTI_LUN=y -CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_LOGGING=y - -# -# SCSI low-level drivers -# -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_7000FASST is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AHA1740 is not set -# CONFIG_SCSI_AACRAID is not set -CONFIG_SCSI_AIC7XXX=y -CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 -CONFIG_AIC7XXX_RESET_DELAY_MS=15000 -# CONFIG_AIC7XXX_PROBE_EISA_VL is not set -# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set -# CONFIG_SCSI_MEGARAID is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set -# CONFIG_SCSI_EATA_PIO is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR53C7xx is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_NCR53C8XX is not set -# CONFIG_SCSI_SYM53C8XX is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_QLOGIC_ISP is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_DEBUG is not set - -# -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_ETHERTAP is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_SGI_O2MACE_ETH=y -# CONFIG_SUNLANCE is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNGEM 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_HP100 is not set -# CONFIG_NET_ISA is not set -# CONFIG_NET_PCI is not set -# CONFIG_NET_POCKET is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_MYRI_SBUS is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set -# CONFIG_SHAPER is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Input core support -# -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set - -# -# Character devices -# -# CONFIG_VT is not set -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -# CONFIG_SERIAL_EXTENDED is not set -# CONFIG_SERIAL_NONSTANDARD is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# Mice -# -# CONFIG_BUSMOUSE is not set -CONFIG_MOUSE=y -CONFIG_PSMOUSE=y -# CONFIG_82C710_MOUSE is not set -# CONFIG_PC110_PAD is not set -# CONFIG_MK712_MOUSE is not set - -# -# Joysticks -# -# CONFIG_INPUT_GAMEPORT is not set - -# -# Input core support is needed for gameports -# - -# -# Input core support is needed for joysticks -# -# CONFIG_QIC02_TAPE is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_FTAPE is not set -# CONFIG_AGP is not set -# CONFIG_DRM is not set - -# -# File systems -# -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO 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_BEFS_FS is not set -# CONFIG_BEFS_DEBUG is not set -# CONFIG_BFS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -# CONFIG_CRAMFS is not set -CONFIG_TMPFS=y -CONFIG_RAMFS=y -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set -# CONFIG_JFS_FS is not set -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_STATISTICS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_VXFS_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 is not set -# CONFIG_DEVFS_MOUNT is not set -# 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_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_INTERMEZZO_FS is not set -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -CONFIG_ROOT_NFS=y -# CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set -# CONFIG_NFSD_TCP is not set -CONFIG_SUNRPC=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -# 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_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set -# CONFIG_ZISOFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -# CONFIG_MSDOS_PARTITION is not set -# CONFIG_LDM_PARTITION is not set -CONFIG_SGI_PARTITION=y -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_EFI_PARTITION is not set -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -# CONFIG_USB is not set - -# -# Bluetooth support -# -# CONFIG_BLUEZ is not set - -# -# Kernel hacking -# -CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set -# CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set -CONFIG_MAGIC_SYSRQ=y -CONFIG_MIPS_UNCACHED=y - -# -# Library routines -# -# CONFIG_ZLIB_INFLATE is not set -# CONFIG_ZLIB_DEFLATE is not set diff -urN linux-2.4.21-bk37/arch/mips64/defconfig-malta linux-2.4.21-bk38/arch/mips64/defconfig-malta --- linux-2.4.21-bk37/arch/mips64/defconfig-malta 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/defconfig-malta 2003-08-24 02:55:58.000000000 -0700 @@ -13,23 +13,34 @@ # # Loadable module support # -# CONFIG_MODULES is not set +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y # # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,10 +58,13 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -57,11 +72,14 @@ CONFIG_BOOT_ELF32=y CONFIG_HAVE_STD_PC_SERIAL_PORT=y CONFIG_I8259=y +CONFIG_MIPS_BONITO64=y +CONFIG_MIPS_GT64120=y +CONFIG_MIPS_MSC=y CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y -CONFIG_SWAP_IO_SPACE=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y CONFIG_PC_KEYB=y CONFIG_PCI=y # CONFIG_MIPS_AU1000 is not set @@ -114,6 +132,8 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y CONFIG_MIPS32_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set @@ -176,8 +196,8 @@ # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set @@ -268,6 +288,7 @@ # CONFIG_SCSI_AHA1740 is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set @@ -304,19 +325,10 @@ # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# # Network device support # CONFIG_NETDEVICES=y @@ -359,6 +371,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -444,13 +457,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set CONFIG_RTC=y +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -523,13 +544,14 @@ # CONFIG_CODA_FS is not set # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set +CONFIG_NFS_V3=y CONFIG_ROOT_NFS=y -# CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y # CONFIG_NFSD_TCP is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set # CONFIG_NCPFS_PACKET_SIGNING is not set @@ -574,9 +596,9 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set diff -urN linux-2.4.21-bk37/arch/mips64/defconfig-sb1250-swarm linux-2.4.21-bk38/arch/mips64/defconfig-sb1250-swarm --- linux-2.4.21-bk37/arch/mips64/defconfig-sb1250-swarm 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/defconfig-sb1250-swarm 2003-08-24 02:55:58.000000000 -0700 @@ -21,17 +21,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -39,6 +48,7 @@ # CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -48,27 +58,44 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set CONFIG_SIBYTE_SB1xxx_SOC=y +CONFIG_SIBYTE_SWARM=y +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_UNKNOWN is not set +CONFIG_SIBYTE_BOARD=y CONFIG_SIBYTE_SB1250=y -# CONFIG_SIMULATION is not set +CONFIG_CPU_SB1_PASS_1=y +# CONFIG_CPU_SB1_PASS_2 is not set +# CONFIG_CPU_SB1_PASS_2_2 is not set +# CONFIG_CPU_SB1_PASS_4 is not set CONFIG_SIBYTE_CFE=y # CONFIG_SIBYTE_CFE_CONSOLE is not set +# CONFIG_SIBYTE_BUS_WATCHER is not set # CONFIG_SIBYTE_SB1250_PROF is not set -# CONFIG_BCM1250_TBPROF is not set -CONFIG_SMP=y +# CONFIG_SIBYTE_TBPROF is not set # CONFIG_PCI is not set -CONFIG_SIBYTE_SWARM=y +CONFIG_SIBYTE_GENBUS_IDE=y +CONFIG_SMP_CAPABLE=y # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_DUMMY_KEYB=y -CONFIG_SWAP_IO_SPACE=y +CONFIG_SWAP_IO_SPACE_W=y +CONFIG_SWAP_IO_SPACE_L=y CONFIG_BOOT_ELF32=y # CONFIG_MIPS_AU1000 is not set @@ -91,14 +118,10 @@ # CONFIG_CPU_R10000 is not set # CONFIG_CPU_RM7000 is not set CONFIG_CPU_SB1=y -CONFIG_CPU_SB1_PASS_1=y -# CONFIG_CPU_SB1_PASS_2 is not set -# CONFIG_CPU_SB1_PASS_2_2 is not set +CONFIG_SMP=y +# CONFIG_SIBYTE_DMA_PAGEOPS is not set CONFIG_SB1_PASS_1_WORKAROUNDS=y CONFIG_CPU_HAS_PREFETCH=y -CONFIG_SB1_CACHE_ERROR=y -CONFIG_SB1_CERR_IGNORE_RECOVERABLE=y -# CONFIG_SB1_CERR_SPIN is not set CONFIG_VTAG_ICACHE=y # CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set @@ -112,7 +135,6 @@ # # CONFIG_CPU_LITTLE_ENDIAN is not set # CONFIG_BINFMT_IRIX is not set -# CONFIG_FORWARD_KEYBOARD is not set CONFIG_NET=y # CONFIG_PCI is not set # CONFIG_ISA is not set @@ -130,8 +152,10 @@ # CONFIG_KCORE_AOUT is not set # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y -# CONFIG_MIPS32_COMPAT is not set -# CONFIG_BINFMT_ELF32 is not set +CONFIG_MIPS32_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set +CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set @@ -183,8 +207,9 @@ # # Networking options # -# CONFIG_PACKET is not set -# CONFIG_NETLINK_DEV is not set +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y # CONFIG_NETFILTER is not set # CONFIG_FILTER is not set CONFIG_UNIX=y @@ -294,6 +319,7 @@ # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_FDDI is not set @@ -370,12 +396,12 @@ # CONFIG_STALDRV is not set # CONFIG_SERIAL_TX3912 is not set # CONFIG_SERIAL_TX3912_CONSOLE is not set +# CONFIG_SERIAL_TXX9 is not set +# CONFIG_SERIAL_TXX9_CONSOLE is not set # CONFIG_TXX927_SERIAL is not set CONFIG_SIBYTE_SB1250_DUART=y CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y CONFIG_SERIAL_CONSOLE=y -CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE=1024 -# CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1 is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -403,13 +429,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -534,7 +568,10 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set +# CONFIG_GDB_CONSOLE is not set +# CONFIG_SB1XXX_CORELIS is not set # CONFIG_MAGIC_SYSRQ is not set # diff -urN linux-2.4.21-bk37/arch/mips64/defconfig-sead linux-2.4.21-bk38/arch/mips64/defconfig-sead --- linux-2.4.21-bk37/arch/mips64/defconfig-sead 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/defconfig-sead 2003-08-24 02:55:58.000000000 -0700 @@ -19,17 +19,26 @@ # Machine selection # # CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set # CONFIG_MIPS_PB1000 is not set # CONFIG_MIPS_PB1100 is not set # CONFIG_MIPS_PB1500 is not set -# CONFIG_ALGOR_P4032 is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_MIPS_MTX1 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set # CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set # CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MAGNUM_4000 is not set @@ -37,6 +46,7 @@ CONFIG_MIPS_SEAD=y # CONFIG_MOMENCO_OCELOT is not set # CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set @@ -46,16 +56,19 @@ # CONFIG_NINO is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set # CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set # CONFIG_HIGHMEM is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_BOOT_ELF32=y CONFIG_L1_CACHE_SHIFT=5 -CONFIG_NEW_IRQ=y CONFIG_NEW_TIME_C=y CONFIG_NONCOHERENT_IO=y # CONFIG_PCI is not set @@ -109,6 +122,8 @@ # CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y CONFIG_MIPS32_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set # CONFIG_PM is not set @@ -231,13 +246,21 @@ # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_PM768 is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_MIPS_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -348,9 +371,9 @@ # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_KGDB is not set # CONFIG_GDB_CONSOLE is not set -# CONFIG_DEBUG is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_MIPS_UNCACHED is not set diff -urN linux-2.4.21-bk37/arch/mips64/kernel/Makefile linux-2.4.21-bk38/arch/mips64/kernel/Makefile --- linux-2.4.21-bk37/arch/mips64/kernel/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -12,25 +12,30 @@ O_TARGET := kernel.o -export-objs = irq.o mips64_ksyms.o pci-dma.o setup.o smp.o +export-objs = irq.o mips64_ksyms.o pci-dma.o setup.o smp.o time.o obj-y := branch.o cpu-probe.o entry.o irq.o proc.o process.o \ ptrace.o r4k_cache.o r4k_fpu.o r4k_genex.o r4k_switch.o \ reset.o scall_64.o semaphore.o setup.o signal.o syscall.o \ - time.o traps.o unaligned.o + traps.o unaligned.o obj-$(CONFIG_I8259) += i8259.o obj-$(CONFIG_IRQ_CPU) += irq_cpu.o +obj-$(CONFIG_NEW_TIME_C) += time.o obj-$(CONFIG_MODULES) += mips64_ksyms.o -obj-$(CONFIG_MIPS32_COMPAT) += linux32.o scall_o32.o signal32.o ioctl32.o -obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o +obj-$(CONFIG_MIPS32_COMPAT) += linux32.o signal32.o ioctl32.o +obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall_n32.o signal_n32.o +obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall_o32.o obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_KGDB) += gdb-low.o gdb-stub.o + ifndef CONFIG_MAPPED_PCI_IO obj-y += pci-dma.o endif -AFLAGS_r4k_genex.o := -P +CFLAGS_cpu-probe.o = $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi) +AFLAGS_r4k_genex.o = -P include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips64/kernel/binfmt_elf32.c linux-2.4.21-bk38/arch/mips64/kernel/binfmt_elf32.c --- linux-2.4.21-bk37/arch/mips64/kernel/binfmt_elf32.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/binfmt_elf32.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,118 +0,0 @@ -/* - * Support for 32-bit Linux/MIPS ELF binaries. - * - * Copyright (C) 1999, 2001 Ralf Baechle - * Copyright (C) 1999, 2001 Silicon Graphics, Inc. - * - * Heavily inspired by the 32-bit Sparc compat code which is - * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com) - * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz) - */ - -#define ELF_ARCH EM_MIPS -#define ELF_CLASS ELFCLASS32 -#ifdef __MIPSEB__ -#define ELF_DATA ELFDATA2MSB; -#else /* __MIPSEL__ */ -#define ELF_DATA ELFDATA2LSB; -#endif - -/* ELF register definitions */ -#define ELF_NGREG 45 -#define ELF_NFPREG 33 - -typedef unsigned int elf_greg_t; -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; - -typedef double elf_fpreg_t; -typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; - -/* - * This is used to ensure we don't load something for the wrong architecture. - */ -#define elf_check_arch(hdr) \ -({ \ - int __res = 1; \ - struct elfhdr *__h = (hdr); \ - \ - if (__h->e_machine != EM_MIPS) \ - __res = 0; \ - if (__h->e_ident[EI_CLASS] != ELFCLASS32) \ - __res = 0; \ - if ((__h->e_flags & EF_MIPS_ABI2) != 0) \ - __res = 0; \ - if (((__h->e_flags & EF_MIPS_ABI) != 0) && \ - ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32)) \ - __res = 0; \ - \ - __res; \ -}) - -#define TASK32_SIZE 0x80000000UL -#undef ELF_ET_DYN_BASE -#define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) - -#include -#include -#include -#include - -struct timeval32 -{ - int tv_sec, tv_usec; -}; - -#define elf_prstatus elf_prstatus32 -struct elf_prstatus32 -{ - struct elf_siginfo pr_info; /* Info associated with signal */ - short pr_cursig; /* Current signal */ - unsigned int pr_sigpend; /* Set of pending signals */ - unsigned int pr_sighold; /* Set of held signals */ - pid_t pr_pid; - pid_t pr_ppid; - pid_t pr_pgrp; - pid_t pr_sid; - struct timeval32 pr_utime; /* User time */ - struct timeval32 pr_stime; /* System time */ - struct timeval32 pr_cutime; /* Cumulative user time */ - struct timeval32 pr_cstime; /* Cumulative system time */ - elf_gregset_t pr_reg; /* GP registers */ - int pr_fpvalid; /* True if math co-processor being used. */ -}; - -#define elf_prpsinfo elf_prpsinfo32 -struct elf_prpsinfo32 -{ - char pr_state; /* numeric process state */ - char pr_sname; /* char for pr_state */ - char pr_zomb; /* zombie */ - char pr_nice; /* nice val */ - unsigned int pr_flag; /* flags */ - u16 pr_uid; - u16 pr_gid; - pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; - /* Lots missing */ - char pr_fname[16]; /* filename of executable */ - char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ -}; - -#define elf_addr_t u32 -#define elf_caddr_t u32 -#define init_elf_binfmt init_elf32_binfmt -#undef CONFIG_BINFMT_ELF -#ifdef CONFIG_BINFMT_ELF32 -#define CONFIG_BINFMT_ELF CONFIG_BINFMT_ELF32 -#endif -#undef CONFIG_BINFMT_ELF_MODULE -#ifdef CONFIG_BINFMT_ELF32_MODULE -#define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE -#endif - -MODULE_DESCRIPTION("Binary format loader for compatibility with 32bit Linux/MIPS binaries"); -MODULE_AUTHOR("Ralf Baechle (ralf@oss.sgi.com)"); - -#undef MODULE_DESCRIPTION -#undef MODULE_AUTHOR - -#include "../../../fs/binfmt_elf.c" diff -urN linux-2.4.21-bk37/arch/mips64/kernel/binfmt_elfn32.c linux-2.4.21-bk38/arch/mips64/kernel/binfmt_elfn32.c --- linux-2.4.21-bk37/arch/mips64/kernel/binfmt_elfn32.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/binfmt_elfn32.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,119 @@ +/* + * Support for n32 Linux/MIPS ELF binaries. + * + * Copyright (C) 1999, 2001 Ralf Baechle + * Copyright (C) 1999, 2001 Silicon Graphics, Inc. + * + * Heavily inspired by the 32-bit Sparc compat code which is + * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com) + * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz) + */ + +#define ELF_ARCH EM_MIPS +#define ELF_CLASS ELFCLASS32 +#ifdef __MIPSEB__ +#define ELF_DATA ELFDATA2MSB; +#else /* __MIPSEL__ */ +#define ELF_DATA ELFDATA2LSB; +#endif + +/* ELF register definitions */ +#define ELF_NGREG 45 +#define ELF_NFPREG 33 + +typedef unsigned long elf_greg_t; +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef double elf_fpreg_t; +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(hdr) \ +({ \ + int __res = 1; \ + struct elfhdr *__h = (hdr); \ + \ + if (__h->e_machine != EM_MIPS) \ + __res = 0; \ + if (__h->e_ident[EI_CLASS] != ELFCLASS32) \ + __res = 0; \ + if (((__h->e_flags & EF_MIPS_ABI2) == 0) || \ + ((__h->e_flags & EF_MIPS_ABI) != 0)) \ + __res = 0; \ + \ + __res; \ +}) + +#define TASK32_SIZE 0x7fff8000UL +#undef ELF_ET_DYN_BASE +#define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) + +#include +#include +#include +#include + +struct timeval32 +{ + int tv_sec, tv_usec; +}; + +#define elf_prstatus elf_prstatus32 +struct elf_prstatus32 +{ + struct elf_siginfo pr_info; /* Info associated with signal */ + short pr_cursig; /* Current signal */ + unsigned int pr_sigpend; /* Set of pending signals */ + unsigned int pr_sighold; /* Set of held signals */ + pid_t pr_pid; + pid_t pr_ppid; + pid_t pr_pgrp; + pid_t pr_sid; + struct timeval32 pr_utime; /* User time */ + struct timeval32 pr_stime; /* System time */ + struct timeval32 pr_cutime; /* Cumulative user time */ + struct timeval32 pr_cstime; /* Cumulative system time */ + elf_gregset_t pr_reg; /* GP registers */ + int pr_fpvalid; /* True if math co-processor being used. */ +}; + +#define elf_prpsinfo elf_prpsinfo32 +struct elf_prpsinfo32 +{ + char pr_state; /* numeric process state */ + char pr_sname; /* char for pr_state */ + char pr_zomb; /* zombie */ + char pr_nice; /* nice val */ + unsigned int pr_flag; /* flags */ + __kernel_uid_t pr_uid; + __kernel_gid_t pr_gid; + pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; + /* Lots missing */ + char pr_fname[16]; /* filename of executable */ + char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ +}; + +#define elf_addr_t u32 +#define elf_caddr_t u32 +#define init_elf_binfmt init_elfn32_binfmt + +#define ELF_CORE_EFLAGS EF_MIPS_ABI2 + +#undef CONFIG_BINFMT_ELF +#ifdef CONFIG_BINFMT_ELF32 +#define CONFIG_BINFMT_ELF CONFIG_BINFMT_ELF32 +#endif +#undef CONFIG_BINFMT_ELF_MODULE +#ifdef CONFIG_BINFMT_ELF32_MODULE +#define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE +#endif + +MODULE_DESCRIPTION("Binary format loader for compatibility with n32 Linux/MIPS binaries"); +MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)"); + +#undef MODULE_DESCRIPTION +#undef MODULE_AUTHOR + +#include "../../../fs/binfmt_elf.c" diff -urN linux-2.4.21-bk37/arch/mips64/kernel/binfmt_elfo32.c linux-2.4.21-bk38/arch/mips64/kernel/binfmt_elfo32.c --- linux-2.4.21-bk37/arch/mips64/kernel/binfmt_elfo32.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/binfmt_elfo32.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,140 @@ +/* + * Support for o32 Linux/MIPS ELF binaries. + * + * Copyright (C) 1999, 2001 Ralf Baechle + * Copyright (C) 1999, 2001 Silicon Graphics, Inc. + * + * Heavily inspired by the 32-bit Sparc compat code which is + * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com) + * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz) + */ + +#define ELF_ARCH EM_MIPS +#define ELF_CLASS ELFCLASS32 +#ifdef __MIPSEB__ +#define ELF_DATA ELFDATA2MSB; +#else /* __MIPSEL__ */ +#define ELF_DATA ELFDATA2LSB; +#endif + +/* ELF register definitions */ +#define ELF_NGREG 45 +#define ELF_NFPREG 33 + +typedef unsigned int elf_greg_t; +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef double elf_fpreg_t; +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(hdr) \ +({ \ + int __res = 1; \ + struct elfhdr *__h = (hdr); \ + \ + if (__h->e_machine != EM_MIPS) \ + __res = 0; \ + if (__h->e_ident[EI_CLASS] != ELFCLASS32) \ + __res = 0; \ + if ((__h->e_flags & EF_MIPS_ABI2) != 0) \ + __res = 0; \ + if (((__h->e_flags & EF_MIPS_ABI) != 0) && \ + ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32)) \ + __res = 0; \ + \ + __res; \ +}) + +#define TASK32_SIZE 0x7fff8000UL +#undef ELF_ET_DYN_BASE +#define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) + +#include +#include +#include +#include + +struct timeval32 +{ + int tv_sec, tv_usec; +}; + +#define elf_prstatus elf_prstatus32 +struct elf_prstatus32 +{ + struct elf_siginfo pr_info; /* Info associated with signal */ + short pr_cursig; /* Current signal */ + unsigned int pr_sigpend; /* Set of pending signals */ + unsigned int pr_sighold; /* Set of held signals */ + pid_t pr_pid; + pid_t pr_ppid; + pid_t pr_pgrp; + pid_t pr_sid; + struct timeval32 pr_utime; /* User time */ + struct timeval32 pr_stime; /* System time */ + struct timeval32 pr_cutime; /* Cumulative user time */ + struct timeval32 pr_cstime; /* Cumulative system time */ + elf_gregset_t pr_reg; /* GP registers */ + int pr_fpvalid; /* True if math co-processor being used. */ +}; + +#define elf_prpsinfo elf_prpsinfo32 +struct elf_prpsinfo32 +{ + char pr_state; /* numeric process state */ + char pr_sname; /* char for pr_state */ + char pr_zomb; /* zombie */ + char pr_nice; /* nice val */ + unsigned int pr_flag; /* flags */ + __kernel_uid_t pr_uid; + __kernel_gid_t pr_gid; + pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; + /* Lots missing */ + char pr_fname[16]; /* filename of executable */ + char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ +}; + +#define elf_addr_t u32 +#define elf_caddr_t u32 +#define init_elf_binfmt init_elf32_binfmt + + +#undef ELF_CORE_COPY_REGS +#define ELF_CORE_COPY_REGS(_dest,_regs) elf32_core_copy_regs(_dest,_regs); + +void elf32_core_copy_regs(elf_gregset_t _dest, struct pt_regs *_regs) +{ + int i; + + memset(_dest, 0, sizeof(elf_gregset_t)); + + /* XXXKW the 6 is from EF_REG0 in gdb/gdb/mips-linux-tdep.c, include/asm-mips/reg.h */ + for (i=6; i<38; i++) + _dest[i] = (elf_greg_t) _regs->regs[i-6]; + _dest[i++] = (elf_greg_t) _regs->lo; + _dest[i++] = (elf_greg_t) _regs->hi; + _dest[i++] = (elf_greg_t) _regs->cp0_epc; + _dest[i++] = (elf_greg_t) _regs->cp0_badvaddr; + _dest[i++] = (elf_greg_t) _regs->cp0_status; + _dest[i++] = (elf_greg_t) _regs->cp0_cause; +} + +#undef CONFIG_BINFMT_ELF +#ifdef CONFIG_BINFMT_ELF32 +#define CONFIG_BINFMT_ELF CONFIG_BINFMT_ELF32 +#endif +#undef CONFIG_BINFMT_ELF_MODULE +#ifdef CONFIG_BINFMT_ELF32_MODULE +#define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE +#endif + +MODULE_DESCRIPTION("Binary format loader for compatibility with o32 Linux/MIPS binaries"); +MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)"); + +#undef MODULE_DESCRIPTION +#undef MODULE_AUTHOR + +#include "../../../fs/binfmt_elf.c" diff -urN linux-2.4.21-bk37/arch/mips64/kernel/branch.c linux-2.4.21-bk38/arch/mips64/kernel/branch.c --- linux-2.4.21-bk37/arch/mips64/kernel/branch.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips64/kernel/branch.c 2003-08-24 02:55:58.000000000 -0700 @@ -164,10 +164,10 @@ * And now the FPA/cp1 branch instructions. */ case cop1_op: - if (!(mips_cpu.options & MIPS_CPU_FPU)) + if (!cpu_has_fpu) fcr31 = current->thread.fpu.soft.sr; else - asm("cfc1\t%0,$31":"=r" (fcr31)); + asm volatile("cfc1\t%0,$31" : "=r" (fcr31)); bit = (insn.i_format.rt >> 2); bit += (bit != 0); bit += 23; diff -urN linux-2.4.21-bk37/arch/mips64/kernel/cpu-probe.c linux-2.4.21-bk38/arch/mips64/kernel/cpu-probe.c --- linux-2.4.21-bk37/arch/mips64/kernel/cpu-probe.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/cpu-probe.c 2003-08-24 02:55:58.000000000 -0700 @@ -1,9 +1,27 @@ +/* + * arch/mips64/kernel/cpu-probe.c + * + * Processor capabilities determination functions. + * + * Copyright (C) xxxx the Anonymous + * Copyright (C) 2003 Maciej W. Rozycki + * + * 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. + */ + #include #include +#include #include + #include #include +#include #include +#include /* * Not all of the MIPS CPUs have the "wait" instruction available. Moreover, @@ -16,14 +34,14 @@ static void r3081_wait(void) { - unsigned long cfg = read_32bit_cp0_register(CP0_CONF); - write_32bit_cp0_register(CP0_CONF, cfg|CONF_HALT); + unsigned long cfg = read_c0_conf(); + write_c0_conf(cfg | R30XX_CONF_HALT); } static void r39xx_wait(void) { - unsigned long cfg = read_32bit_cp0_register(CP0_CONF); - write_32bit_cp0_register(CP0_CONF, cfg|TX39_CONF_HALT); + unsigned long cfg = read_c0_conf(); + write_c0_conf(cfg | TX39_CONF_HALT); } static void r4k_wait(void) @@ -39,23 +57,29 @@ /* using the wait instruction makes CP0 counter unusable */ __asm__(".set\tmips3\n\t" "wait\n\t" - "nop\n\t" "nop\n\t" "nop\n\t" "nop\n\t" ".set\tmips0"); + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set\tmips0"); #else - __asm__("nop\n\t" "nop\n\t"); + __asm__("nop\n\t" + "nop"); #endif } static inline void check_wait(void) { + struct cpuinfo_mips *c = ¤t_cpu_data; + printk("Checking for 'wait' instruction... "); - switch(mips_cpu.cputype) { + switch (c->cputype) { case CPU_R3081: case CPU_R3081E: cpu_wait = r3081_wait; printk(" available.\n"); break; case CPU_TX3927: - case CPU_TX39XX: cpu_wait = r39xx_wait; printk(" available.\n"); break; @@ -89,9 +113,229 @@ } } +static inline void check_mult_sh(void) +{ + unsigned long flags; + int m1, m2; + long p, s, v; + + printk("Checking for the multiply/shift bug... "); + + local_irq_save(flags); + /* + * The following code leads to a wrong result of dsll32 when + * executed on R4000 rev. 2.2 or 3.0. + * + * See "MIPS R4000PC/SC Errata, Processor Revision 2.2 and + * 3.0" by MIPS Technologies, Inc., errata #16 and #28 for + * details. I got no permission to duplicate them here, + * sigh... --macro + */ + asm volatile( + ".set push\n\t" + ".set noat\n\t" + ".set noreorder\n\t" + ".set nomacro\n\t" + "mult %1, %2\n\t" + "dsll32 %0, %3, %4\n\t" + "mflo $0\n\t" + ".set pop" + : "=r" (v) + : "r" (5), "r" (8), "r" (5), "I" (0) + : "hi", "lo", "accum"); + local_irq_restore(flags); + + if (v == 5L << 32) { + printk("no.\n"); + return; + } + + printk("yes, workaround... "); + local_irq_save(flags); + /* + * We want the multiply and the shift to be isolated from the + * rest of the code to disable gcc optimizations. Hence the + * asm statements that execute nothing, but make gcc not know + * what the values of m1, m2 and s are and what v and p are + * used for. + * + * We have to use single integers for m1 and m2 and a double + * one for p to be sure the mulsidi3 gcc's RTL multiplication + * instruction has the workaround applied. Older versions of + * gcc have correct mulsi3, but other multiplication variants + * lack the workaround. + */ + asm volatile( + "" + : "=r" (m1), "=r" (m2), "=r" (s) + : "0" (5), "1" (8), "2" (5)); + p = m1 * m2; + v = s << 32; + asm volatile( + "" + : "=r" (v) + : "0" (v), "r" (p)); + local_irq_restore(flags); + + if (v == 5L << 32) { + printk("yes.\n"); + return; + } + + printk("no.\n"); + panic("Reliable operation impossible!\n" +#ifndef CONFIG_CPU_R4000 + "Configure for R4000 to enable the workaround." +#else + "Please report to ." +#endif + ); +} + +static volatile int daddi_ov __initdata = 0; + +asmlinkage void __init do_daddi_ov(struct pt_regs *regs) +{ + daddi_ov = 1; + regs->cp0_epc += 4; +} + +static inline void check_daddi(void) +{ + extern asmlinkage void handle_daddi_ov(void); + unsigned long flags; + void *handler; + long v; + + printk("Checking for the daddi bug... "); + + local_irq_save(flags); + handler = set_except_vector(12, handle_daddi_ov); + /* + * The following code fails to trigger an overflow exception + * when executed on R4000 rev. 2.2 or 3.0. + * + * See "MIPS R4000PC/SC Errata, Processor Revision 2.2 and + * 3.0" by MIPS Technologies, Inc., erratum #23 for details. + * I got no permission to duplicate it here, sigh... --macro + */ + asm volatile( + ".set push\n\t" + ".set noat\n\t" + ".set noreorder\n\t" + ".set nomacro\n\t" +#ifdef HAVE_AS_SET_DADDI + ".set daddi\n\t" +#endif + "daddi %0, %1, %2\n\t" + ".set pop" + : "=r" (v) + : "r" (0x7fffffffffffedcd), "I" (0x1234)); + set_except_vector(12, handler); + local_irq_restore(flags); + + if (daddi_ov) { + printk("no.\n"); + return; + } + + printk("yes, workaround... "); + + local_irq_save(flags); + handler = set_except_vector(12, handle_daddi_ov); + asm volatile( + "daddi %0, %1, %2" + : "=r" (v) + : "r" (0x7fffffffffffedcd), "I" (0x1234)); + set_except_vector(12, handler); + local_irq_restore(flags); + + if (daddi_ov) { + printk("yes.\n"); + return; + } + + printk("no.\n"); + panic("Reliable operation impossible!\n" +#if !defined(CONFIG_CPU_R4000) && !defined(CONFIG_CPU_R4400) + "Configure for R4000 or R4400 to enable the workaround." +#else + "Please report to ." +#endif + ); +} + +static inline void check_daddiu(void) +{ + long v, w; + + printk("Checking for the daddiu bug... "); + + /* + * The following code leads to a wrong result of daddiu when + * executed on R4400 rev. 1.0. + * + * See "MIPS R4400PC/SC Errata, Processor Revision 1.0" by + * MIPS Technologies, Inc., erratum #7 for details. + * + * According to "MIPS R4000PC/SC Errata, Processor Revision + * 2.2 and 3.0" by MIPS Technologies, Inc., erratum #41 this + * problem affects R4000 rev. 2.2 and 3.0, too. Testing + * failed to trigger it so far. + * + * I got no permission to duplicate the errata here, sigh... + * --macro + */ + asm volatile( + ".set push\n\t" + ".set noat\n\t" + ".set noreorder\n\t" + ".set nomacro\n\t" +#ifdef HAVE_AS_SET_DADDI + ".set daddi\n\t" +#endif + "daddiu %0, %2, %3\n\t" + "addiu %1, $0, %3\n\t" + "daddu %1, %2\n\t" + ".set pop" + : "=&r" (v), "=&r" (w) + : "r" (0x7fffffffffffedcd), "I" (0x1234)); + + if (v == w) { + printk("no.\n"); + return; + } + + printk("yes, workaround... "); + + asm volatile( + "daddiu %0, %2, %3\n\t" + "addiu %1, $0, %3\n\t" + "daddu %1, %2" + : "=&r" (v), "=&r" (w) + : "r" (0x7fffffffffffedcd), "I" (0x1234)); + + if (v == w) { + printk("yes.\n"); + return; + } + + printk("no.\n"); + panic("Reliable operation impossible!\n" +#if !defined(CONFIG_CPU_R4000) && !defined(CONFIG_CPU_R4400) + "Configure for R4000 or R4400 to enable the workaround." +#else + "Please report to ." +#endif + ); +} + void __init check_bugs(void) { check_wait(); + check_mult_sh(); + check_daddi(); + check_daddiu(); } /* @@ -104,12 +348,12 @@ #ifdef CONFIG_CPU_R3000 extern unsigned long r3k_cache_size(unsigned long); unsigned long size1, size2; - unsigned long cfg = read_32bit_cp0_register(CP0_CONF); + unsigned long cfg = read_c0_conf(); size1 = r3k_cache_size(ST0_ISC); - write_32bit_cp0_register(CP0_CONF, cfg^CONF_AC); + write_c0_conf(cfg ^ R30XX_CONF_AC); size2 = r3k_cache_size(ST0_ISC); - write_32bit_cp0_register(CP0_CONF, cfg); + write_c0_conf(cfg); return size1 != size2; #else return 0; @@ -123,143 +367,138 @@ { unsigned long tmp, fpu_id; - tmp = read_32bit_cp0_register(CP0_STATUS); + tmp = read_c0_status(); __enable_fpu(); fpu_id = read_32bit_cp1_register(CP1_REVISION); - write_32bit_cp0_register(CP0_STATUS, tmp); + write_c0_status(tmp); return fpu_id; } /* * Check the CPU has an FPU the official way. */ -static inline int cpu_has_fpu(void) +static inline int __cpu_has_fpu(void) { return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE); } -/* declaration of the global struct */ -struct mips_cpu mips_cpu = { - processor_id: PRID_IMP_UNKNOWN, - fpu_id: FPIR_IMP_NONE, - cputype: CPU_UNKNOWN -}; - -/* Shortcut for assembler access to mips_cpu.options */ -int *cpuoptions = &mips_cpu.options; - #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \ | MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX) __init void cpu_probe(void) { -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) - unsigned long config0 = read_32bit_cp0_register(CP0_CONFIG); + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned long config0 = read_c0_config(); unsigned long config1; + c->processor_id = PRID_IMP_UNKNOWN; + c->fpu_id = FPIR_IMP_NONE; + c->cputype = CPU_UNKNOWN; + if (config0 & (1 << 31)) { /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */ - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC; - config1 = read_mips32_cp0_config1(); + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | + MIPS_CPU_LLSC; + config1 = read_c0_config1(); if (config1 & (1 << 3)) - mips_cpu.options |= MIPS_CPU_WATCH; + c->options |= MIPS_CPU_WATCH; if (config1 & (1 << 2)) - mips_cpu.options |= MIPS_CPU_MIPS16; + c->options |= MIPS_CPU_MIPS16; if (config1 & (1 << 1)) - mips_cpu.options |= MIPS_CPU_EJTAG; + c->options |= MIPS_CPU_EJTAG; if (config1 & 1) { - mips_cpu.options |= MIPS_CPU_FPU; -#if defined(CONFIG_CPU_MIPS64) - mips_cpu.options |= MIPS_CPU_32FPR; -#endif + c->options |= MIPS_CPU_FPU; + c->options |= MIPS_CPU_32FPR; } - mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT; + c->scache.flags = MIPS_CACHE_NOT_PRESENT; + + c->tlbsize = ((config1 >> 25) & 0x3f) + 1; } -#endif - mips_cpu.processor_id = read_32bit_cp0_register(CP0_PRID); - switch (mips_cpu.processor_id & 0xff0000) { + + c->processor_id = read_c0_prid(); + switch (c->processor_id & 0xff0000) { case PRID_COMP_LEGACY: - switch (mips_cpu.processor_id & 0xff00) { + switch (c->processor_id & 0xff00) { case PRID_IMP_R2000: - mips_cpu.cputype = CPU_R2000; - mips_cpu.isa_level = MIPS_CPU_ISA_I; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX; - if (cpu_has_fpu()) - mips_cpu.options |= MIPS_CPU_FPU; - mips_cpu.tlbsize = 64; + c->cputype = CPU_R2000; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | + MIPS_CPU_LLSC; + if (__cpu_has_fpu()) + c->options |= MIPS_CPU_FPU; + c->tlbsize = 64; break; case PRID_IMP_R3000: - if ((mips_cpu.processor_id & 0xff) == PRID_REV_R3000A) + if ((c->processor_id & 0xff) == PRID_REV_R3000A) if (cpu_has_confreg()) - mips_cpu.cputype = CPU_R3081E; + c->cputype = CPU_R3081E; else - mips_cpu.cputype = CPU_R3000A; + c->cputype = CPU_R3000A; else - mips_cpu.cputype = CPU_R3000; - mips_cpu.isa_level = MIPS_CPU_ISA_I; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX; - if (cpu_has_fpu()) - mips_cpu.options |= MIPS_CPU_FPU; - mips_cpu.tlbsize = 64; + c->cputype = CPU_R3000; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | + MIPS_CPU_LLSC; + if (__cpu_has_fpu()) + c->options |= MIPS_CPU_FPU; + c->tlbsize = 64; break; case PRID_IMP_R4000: - if ((mips_cpu.processor_id & 0xff) == PRID_REV_R4400) - mips_cpu.cputype = CPU_R4400SC; + if ((c->processor_id & 0xff) >= PRID_REV_R4400) + c->cputype = CPU_R4400SC; else - mips_cpu.cputype = CPU_R4000SC; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR | MIPS_CPU_WATCH | - MIPS_CPU_VCE; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R4000SC; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_VCE | + MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_VR41XX: - switch (mips_cpu.processor_id & 0xf0) { + switch (c->processor_id & 0xf0) { #ifndef CONFIG_VR4181 case PRID_REV_VR4111: - mips_cpu.cputype = CPU_VR4111; + c->cputype = CPU_VR4111; break; #else case PRID_REV_VR4181: - mips_cpu.cputype = CPU_VR4181; + c->cputype = CPU_VR4181; break; #endif case PRID_REV_VR4121: - mips_cpu.cputype = CPU_VR4121; + c->cputype = CPU_VR4121; break; case PRID_REV_VR4122: - if ((mips_cpu.processor_id & 0xf) < 0x3) - mips_cpu.cputype = CPU_VR4122; + if ((c->processor_id & 0xf) < 0x3) + c->cputype = CPU_VR4122; else - mips_cpu.cputype = CPU_VR4181A; + c->cputype = CPU_VR4181A; break; case PRID_REV_VR4131: - mips_cpu.cputype = CPU_VR4131; - mips_cpu.icache.ways = 2; - mips_cpu.dcache.ways = 2; + c->cputype = CPU_VR4131; break; default: printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); - mips_cpu.cputype = CPU_VR41XX; + c->cputype = CPU_VR41XX; break; } - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS; - mips_cpu.tlbsize = 32; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS; + c->tlbsize = 32; break; case PRID_IMP_R4300: - mips_cpu.cputype = CPU_R4300; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; - mips_cpu.tlbsize = 32; + c->cputype = CPU_R4300; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 32; break; case PRID_IMP_R4600: - mips_cpu.cputype = CPU_R4600; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R4600; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; + c->tlbsize = 48; break; #if 0 case PRID_IMP_R4650: @@ -269,101 +508,97 @@ * for documentation. Commented out because it shares * it's c0_prid id number with the TX3900. */ - mips_cpu.cputype = CPU_R4650; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R4650; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; + c->tlbsize = 48; break; #endif case PRID_IMP_TX39: - mips_cpu.isa_level = MIPS_CPU_ISA_I; - mips_cpu.options = MIPS_CPU_TLB; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB; - if ((mips_cpu.processor_id & 0xf0) == + if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) { - mips_cpu.cputype = CPU_TX3927; - mips_cpu.tlbsize = 64; - mips_cpu.icache.ways = 2; - mips_cpu.dcache.ways = 2; + c->cputype = CPU_TX3927; + c->tlbsize = 64; } else { - switch (mips_cpu.processor_id & 0xff) { + switch (c->processor_id & 0xff) { case PRID_REV_TX3912: - mips_cpu.cputype = CPU_TX3912; - mips_cpu.tlbsize = 32; + c->cputype = CPU_TX3912; + c->tlbsize = 32; break; case PRID_REV_TX3922: - mips_cpu.cputype = CPU_TX3922; - mips_cpu.tlbsize = 64; + c->cputype = CPU_TX3922; + c->tlbsize = 64; break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; break; } } break; case PRID_IMP_R4700: - mips_cpu.cputype = CPU_R4700; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R4700; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_TX49: - mips_cpu.cputype = CPU_TX49XX; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; - mips_cpu.tlbsize = 48; - mips_cpu.icache.ways = 4; - mips_cpu.dcache.ways = 4; + c->cputype = CPU_TX49XX; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_R5000: - mips_cpu.cputype = CPU_R5000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R5000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_R5432: - mips_cpu.cputype = CPU_R5432; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR | MIPS_CPU_WATCH; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R5432; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_R5500: - mips_cpu.cputype = CPU_R5500; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR | MIPS_CPU_WATCH; - mips_cpu.tlbsize = 48; + c->cputype = CPU_R5500; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_NEVADA: - mips_cpu.cputype = CPU_NEVADA; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR | MIPS_CPU_DIVEC; - mips_cpu.tlbsize = 48; - mips_cpu.icache.ways = 2; - mips_cpu.dcache.ways = 2; + c->cputype = CPU_NEVADA; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_DIVEC | MIPS_CPU_LLSC; + c->tlbsize = 48; break; case PRID_IMP_R6000: - mips_cpu.cputype = CPU_R6000; - mips_cpu.isa_level = MIPS_CPU_ISA_II; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU; - mips_cpu.tlbsize = 32; + c->cputype = CPU_R6000; + c->isa_level = MIPS_CPU_ISA_II; + c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | + MIPS_CPU_LLSC; + c->tlbsize = 32; break; case PRID_IMP_R6000A: - mips_cpu.cputype = CPU_R6000A; - mips_cpu.isa_level = MIPS_CPU_ISA_II; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU; - mips_cpu.tlbsize = 32; + c->cputype = CPU_R6000A; + c->isa_level = MIPS_CPU_ISA_II; + c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | + MIPS_CPU_LLSC; + c->tlbsize = 32; break; case PRID_IMP_RM7000: - mips_cpu.cputype = CPU_RM7000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | - MIPS_CPU_32FPR; + c->cputype = CPU_RM7000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; /* * Undocumented RM7000: Bit 29 in the info register of * the RM7000 v2.0 indicates if the TLB has 48 or 64 @@ -372,118 +607,139 @@ * 29 1 => 64 entry JTLB * 0 => 48 entry JTLB */ - mips_cpu.tlbsize = (get_info() & (1 << 29)) ? 64 : 48; + c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; break; case PRID_IMP_R8000: - mips_cpu.cputype = CPU_R8000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR; - mips_cpu.tlbsize = 384; /* has weird TLB: 3-way x 128 */ + c->cputype = CPU_R8000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 384; /* has weird TLB: 3-way x 128 */ break; case PRID_IMP_R10000: - mips_cpu.cputype = CPU_R10000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_COUNTER | MIPS_CPU_WATCH; - mips_cpu.tlbsize = 64; + c->cputype = CPU_R10000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_COUNTER | MIPS_CPU_WATCH | + MIPS_CPU_LLSC; + c->tlbsize = 64; break; case PRID_IMP_R12000: - mips_cpu.cputype = CPU_R12000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_COUNTER | MIPS_CPU_WATCH; - mips_cpu.tlbsize = 64; + c->cputype = CPU_R12000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_COUNTER | MIPS_CPU_WATCH | + MIPS_CPU_LLSC; + c->tlbsize = 64; break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; break; } break; -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) case PRID_COMP_MIPS: - switch (mips_cpu.processor_id & 0xff00) { + switch (c->processor_id & 0xff00) { case PRID_IMP_4KC: - mips_cpu.cputype = CPU_4KC; - mips_cpu.isa_level = MIPS_CPU_ISA_M32; + c->cputype = CPU_4KC; + c->isa_level = MIPS_CPU_ISA_M32; break; case PRID_IMP_4KEC: - mips_cpu.cputype = CPU_4KEC; - mips_cpu.isa_level = MIPS_CPU_ISA_M32; + c->cputype = CPU_4KEC; + c->isa_level = MIPS_CPU_ISA_M32; break; case PRID_IMP_4KSC: - mips_cpu.cputype = CPU_4KSC; - mips_cpu.isa_level = MIPS_CPU_ISA_M32; + c->cputype = CPU_4KSC; + c->isa_level = MIPS_CPU_ISA_M32; break; case PRID_IMP_5KC: - mips_cpu.cputype = CPU_5KC; - mips_cpu.isa_level = MIPS_CPU_ISA_M64; + c->cputype = CPU_5KC; + c->isa_level = MIPS_CPU_ISA_M64; break; case PRID_IMP_20KC: - mips_cpu.cputype = CPU_20KC; - mips_cpu.isa_level = MIPS_CPU_ISA_M64; + c->cputype = CPU_20KC; + c->isa_level = MIPS_CPU_ISA_M64; break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; break; } break; case PRID_COMP_ALCHEMY: - switch (mips_cpu.processor_id & 0xff00) { + switch (c->processor_id & 0xff00) { case PRID_IMP_AU1_REV1: case PRID_IMP_AU1_REV2: - switch ((mips_cpu.processor_id >> 24) & 0xff) { + switch ((c->processor_id >> 24) & 0xff) { case 0: - mips_cpu.cputype = CPU_AU1000; + c->cputype = CPU_AU1000; break; case 1: - mips_cpu.cputype = CPU_AU1500; + c->cputype = CPU_AU1500; break; case 2: - mips_cpu.cputype = CPU_AU1100; + c->cputype = CPU_AU1100; break; default: panic("Unknown Au Core!"); break; } - mips_cpu.isa_level = MIPS_CPU_ISA_M32; + c->isa_level = MIPS_CPU_ISA_M32; break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; break; } break; -#endif /* CONFIG_CPU_MIPS32 */ case PRID_COMP_SIBYTE: - switch (mips_cpu.processor_id & 0xff00) { + switch (c->processor_id & 0xff00) { case PRID_IMP_SB1: - mips_cpu.cputype = CPU_SB1; - mips_cpu.isa_level = MIPS_CPU_ISA_M64; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | - MIPS_CPU_MCHECK; + c->cputype = CPU_SB1; + c->isa_level = MIPS_CPU_ISA_M64; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | + MIPS_CPU_MCHECK | MIPS_CPU_EJTAG | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; #ifndef CONFIG_SB1_PASS_1_WORKAROUNDS /* FPU in pass1 is known to have issues. */ - mips_cpu.options |= MIPS_CPU_FPU; + c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; #endif break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; + break; + } + break; + + case PRID_COMP_SANDCRAFT: + switch (c->processor_id & 0xff00) { + case PRID_IMP_SR71000: + c->cputype = CPU_SR71000; + c->isa_level = MIPS_CPU_ISA_M64; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_FPU | + MIPS_CPU_COUNTER | MIPS_CPU_MCHECK; + c->scache.ways = 8; + c->tlbsize = 64; + break; + default: + c->cputype = CPU_UNKNOWN; break; } break; default: - mips_cpu.cputype = CPU_UNKNOWN; + c->cputype = CPU_UNKNOWN; } - if (mips_cpu.options & MIPS_CPU_FPU) - mips_cpu.fpu_id = cpu_get_fpu_id(); + if (c->options & MIPS_CPU_FPU) + c->fpu_id = cpu_get_fpu_id(); } __init void cpu_report(void) { - printk("CPU revision is: %08x\n", mips_cpu.processor_id); - if (mips_cpu.options & MIPS_CPU_FPU) - printk("FPU revision is: %08x\n", mips_cpu.fpu_id); + struct cpuinfo_mips *c = ¤t_cpu_data; + + printk("CPU revision is: %08x\n", c->processor_id); + if (c->options & MIPS_CPU_FPU) + printk("FPU revision is: %08x\n", c->fpu_id); } diff -urN linux-2.4.21-bk37/arch/mips64/kernel/entry.S linux-2.4.21-bk38/arch/mips64/kernel/entry.S --- linux-2.4.21-bk37/arch/mips64/kernel/entry.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/entry.S 2003-08-24 02:55:58.000000000 -0700 @@ -18,7 +18,7 @@ #define KU_USER 0x10 .text - .align 4 + .align 5 FEXPORT(ret_from_fork) move a0, v0 # prev jal schedule_tail diff -urN linux-2.4.21-bk37/arch/mips64/kernel/gdb-low.S linux-2.4.21-bk38/arch/mips64/kernel/gdb-low.S --- linux-2.4.21-bk37/arch/mips64/kernel/gdb-low.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/gdb-low.S 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,357 @@ +/* + * gdb-low.S contains the low-level trap handler for the GDB stub. + * + * Copyright (C) 1995 Andreas Busse + */ +#include +#include + +#include +#include +#include +#include +#include +#include + +/* + * [jsun] We reserves about 2x GDB_FR_SIZE in stack. The lower (addressed) + * part is used to store registers and passed to exception handler. + * The upper part is reserved for "call func" feature where gdb client + * saves some of the regs, setups call frame and passes args. + * + * A trace shows about 200 bytes are used to store about half of all regs. + * The rest should be big enough for frame setup and passing args. + */ + +/* + * The low level trap handler + */ + .align 5 + NESTED(trap_low, GDB_FR_SIZE, sp) + .set noat + .set noreorder + + mfc0 k0,CP0_STATUS + sll k0,3 /* extract cu0 bit */ + bltz k0,1f + move k1,sp + + /* + * Called from user mode, go somewhere else. + */ + lui k1,%hi(saved_vectors) + mfc0 k0,CP0_CAUSE + andi k0,k0,0x7c + add k1,k1,k0 + lw k0,%lo(saved_vectors)(k1) + jr k0 + nop +1: + move k0,sp + subu sp,k1,GDB_FR_SIZE*2 # see comment above + sd k0,GDB_FR_REG29(sp) + sd v0,GDB_FR_REG2(sp) + +/* + * First save the CP0 and special registers + */ + + mfc0 v0,CP0_STATUS + sd v0,GDB_FR_STATUS(sp) + mfc0 v0,CP0_CAUSE + sd v0,GDB_FR_CAUSE(sp) + dmfc0 v0,CP0_EPC + sd v0,GDB_FR_EPC(sp) + dmfc0 v0,CP0_BADVADDR + sd v0,GDB_FR_BADVADDR(sp) + mfhi v0 + sd v0,GDB_FR_HI(sp) + mflo v0 + sd v0,GDB_FR_LO(sp) + +/* + * Now the integer registers + */ + + sd zero,GDB_FR_REG0(sp) /* I know... */ + sd $1,GDB_FR_REG1(sp) + /* v0 already saved */ + sd v1,GDB_FR_REG3(sp) + sd a0,GDB_FR_REG4(sp) + sd a1,GDB_FR_REG5(sp) + sd a2,GDB_FR_REG6(sp) + sd a3,GDB_FR_REG7(sp) + sd a4,GDB_FR_REG8(sp) + sd a5,GDB_FR_REG9(sp) + sd a6,GDB_FR_REG10(sp) + sd a7,GDB_FR_REG11(sp) + sd t0,GDB_FR_REG12(sp) + sd t1,GDB_FR_REG13(sp) + sd t2,GDB_FR_REG14(sp) + sd t3,GDB_FR_REG15(sp) + sd s0,GDB_FR_REG16(sp) + sd s1,GDB_FR_REG17(sp) + sd s2,GDB_FR_REG18(sp) + sd s3,GDB_FR_REG19(sp) + sd s4,GDB_FR_REG20(sp) + sd s5,GDB_FR_REG21(sp) + sd s6,GDB_FR_REG22(sp) + sd s7,GDB_FR_REG23(sp) + sd t8,GDB_FR_REG24(sp) + sd t9,GDB_FR_REG25(sp) + sd k0,GDB_FR_REG26(sp) + sd k1,GDB_FR_REG27(sp) + sd gp,GDB_FR_REG28(sp) + /* sp already saved */ + sd fp,GDB_FR_REG30(sp) + sd ra,GDB_FR_REG31(sp) + + CLI /* disable interrupts */ + +/* + * Followed by the floating point registers + */ + mfc0 v0,CP0_STATUS /* FPU enabled? */ + srl v0,v0,16 + andi v0,v0,(ST0_CU1 >> 16) + + beqz v0,2f /* disabled, skip */ + nop + + sdc1 $0,GDB_FR_FPR0(sp) + sdc1 $1,GDB_FR_FPR1(sp) + sdc1 $2,GDB_FR_FPR2(sp) + sdc1 $3,GDB_FR_FPR3(sp) + sdc1 $4,GDB_FR_FPR4(sp) + sdc1 $5,GDB_FR_FPR5(sp) + sdc1 $6,GDB_FR_FPR6(sp) + sdc1 $7,GDB_FR_FPR7(sp) + sdc1 $8,GDB_FR_FPR8(sp) + sdc1 $9,GDB_FR_FPR9(sp) + sdc1 $10,GDB_FR_FPR10(sp) + sdc1 $11,GDB_FR_FPR11(sp) + sdc1 $12,GDB_FR_FPR12(sp) + sdc1 $13,GDB_FR_FPR13(sp) + sdc1 $14,GDB_FR_FPR14(sp) + sdc1 $15,GDB_FR_FPR15(sp) + sdc1 $16,GDB_FR_FPR16(sp) + sdc1 $17,GDB_FR_FPR17(sp) + sdc1 $18,GDB_FR_FPR18(sp) + sdc1 $19,GDB_FR_FPR19(sp) + sdc1 $20,GDB_FR_FPR20(sp) + sdc1 $21,GDB_FR_FPR21(sp) + sdc1 $22,GDB_FR_FPR22(sp) + sdc1 $23,GDB_FR_FPR23(sp) + sdc1 $24,GDB_FR_FPR24(sp) + sdc1 $25,GDB_FR_FPR25(sp) + sdc1 $26,GDB_FR_FPR26(sp) + sdc1 $27,GDB_FR_FPR27(sp) + sdc1 $28,GDB_FR_FPR28(sp) + sdc1 $29,GDB_FR_FPR29(sp) + sdc1 $30,GDB_FR_FPR30(sp) + sdc1 $31,GDB_FR_FPR31(sp) + +/* + * FPU control registers + */ + + cfc1 v0,CP1_STATUS + sd v0,GDB_FR_FSR(sp) + cfc1 v0,CP1_REVISION + sd v0,GDB_FR_FIR(sp) + +/* + * Current stack frame ptr + */ + +2: + sd sp,GDB_FR_FRP(sp) + +/* + * CP0 registers (R4000/R4400 unused registers skipped) + */ + + mfc0 v0,CP0_INDEX + sd v0,GDB_FR_CP0_INDEX(sp) + mfc0 v0,CP0_RANDOM + sd v0,GDB_FR_CP0_RANDOM(sp) + dmfc0 v0,CP0_ENTRYLO0 + sd v0,GDB_FR_CP0_ENTRYLO0(sp) + dmfc0 v0,CP0_ENTRYLO1 + sd v0,GDB_FR_CP0_ENTRYLO1(sp) + dmfc0 v0,CP0_CONTEXT + sd v0,GDB_FR_CP0_CONTEXT(sp) + mfc0 v0,CP0_PAGEMASK + sd v0,GDB_FR_CP0_PAGEMASK(sp) + mfc0 v0,CP0_WIRED + sd v0,GDB_FR_CP0_WIRED(sp) + dmfc0 v0,CP0_ENTRYHI + sd v0,GDB_FR_CP0_ENTRYHI(sp) + mfc0 v0,CP0_PRID + sd v0,GDB_FR_CP0_PRID(sp) + + .set at + +/* + * Continue with the higher level handler + */ + + move a0,sp + + jal handle_exception + nop + +/* + * Restore all writable registers, in reverse order + */ + + .set noat + + ld v0,GDB_FR_CP0_ENTRYHI(sp) + ld v1,GDB_FR_CP0_WIRED(sp) + dmtc0 v0,CP0_ENTRYHI + mtc0 v1,CP0_WIRED + ld v0,GDB_FR_CP0_PAGEMASK(sp) + ld v1,GDB_FR_CP0_ENTRYLO1(sp) + mtc0 v0,CP0_PAGEMASK + dmtc0 v1,CP0_ENTRYLO1 + ld v0,GDB_FR_CP0_ENTRYLO0(sp) + ld v1,GDB_FR_CP0_INDEX(sp) + dmtc0 v0,CP0_ENTRYLO0 + ld v0,GDB_FR_CP0_CONTEXT(sp) + mtc0 v1,CP0_INDEX + dmtc0 v0,CP0_CONTEXT + + +/* + * Next, the floating point registers + */ + mfc0 v0,CP0_STATUS /* check if the FPU is enabled */ + srl v0,v0,16 + andi v0,v0,(ST0_CU1 >> 16) + + beqz v0,3f /* disabled, skip */ + nop + + ldc1 $31,GDB_FR_FPR31(sp) + ldc1 $30,GDB_FR_FPR30(sp) + ldc1 $29,GDB_FR_FPR29(sp) + ldc1 $28,GDB_FR_FPR28(sp) + ldc1 $27,GDB_FR_FPR27(sp) + ldc1 $26,GDB_FR_FPR26(sp) + ldc1 $25,GDB_FR_FPR25(sp) + ldc1 $24,GDB_FR_FPR24(sp) + ldc1 $23,GDB_FR_FPR23(sp) + ldc1 $22,GDB_FR_FPR22(sp) + ldc1 $21,GDB_FR_FPR21(sp) + ldc1 $20,GDB_FR_FPR20(sp) + ldc1 $19,GDB_FR_FPR19(sp) + ldc1 $18,GDB_FR_FPR18(sp) + ldc1 $17,GDB_FR_FPR17(sp) + ldc1 $16,GDB_FR_FPR16(sp) + ldc1 $15,GDB_FR_FPR15(sp) + ldc1 $14,GDB_FR_FPR14(sp) + ldc1 $13,GDB_FR_FPR13(sp) + ldc1 $12,GDB_FR_FPR12(sp) + ldc1 $11,GDB_FR_FPR11(sp) + ldc1 $10,GDB_FR_FPR10(sp) + ldc1 $9,GDB_FR_FPR9(sp) + ldc1 $8,GDB_FR_FPR8(sp) + ldc1 $7,GDB_FR_FPR7(sp) + ldc1 $6,GDB_FR_FPR6(sp) + ldc1 $5,GDB_FR_FPR5(sp) + ldc1 $4,GDB_FR_FPR4(sp) + ldc1 $3,GDB_FR_FPR3(sp) + ldc1 $2,GDB_FR_FPR2(sp) + ldc1 $1,GDB_FR_FPR1(sp) + ldc1 $0,GDB_FR_FPR0(sp) + +/* + * Now the CP0 and integer registers + */ + +3: + mfc0 t0,CP0_STATUS + ori t0,0x1f + xori t0,0x1f + mtc0 t0,CP0_STATUS + + ld v0,GDB_FR_STATUS(sp) + ld v1,GDB_FR_EPC(sp) + mtc0 v0,CP0_STATUS + dmtc0 v1,CP0_EPC + ld v0,GDB_FR_HI(sp) + ld v1,GDB_FR_LO(sp) + mthi v0 + mtlo v0 + ld ra,GDB_FR_REG31(sp) + ld fp,GDB_FR_REG30(sp) + ld gp,GDB_FR_REG28(sp) + ld k1,GDB_FR_REG27(sp) + ld k0,GDB_FR_REG26(sp) + ld t9,GDB_FR_REG25(sp) + ld t8,GDB_FR_REG24(sp) + ld s7,GDB_FR_REG23(sp) + ld s6,GDB_FR_REG22(sp) + ld s5,GDB_FR_REG21(sp) + ld s4,GDB_FR_REG20(sp) + ld s3,GDB_FR_REG19(sp) + ld s2,GDB_FR_REG18(sp) + ld s1,GDB_FR_REG17(sp) + ld s0,GDB_FR_REG16(sp) + ld t3,GDB_FR_REG15(sp) + ld t2,GDB_FR_REG14(sp) + ld t1,GDB_FR_REG13(sp) + ld t0,GDB_FR_REG12(sp) + ld a7,GDB_FR_REG11(sp) + ld a6,GDB_FR_REG10(sp) + ld a5,GDB_FR_REG9(sp) + ld a4,GDB_FR_REG8(sp) + ld a3,GDB_FR_REG7(sp) + ld a2,GDB_FR_REG6(sp) + ld a1,GDB_FR_REG5(sp) + ld a0,GDB_FR_REG4(sp) + ld v1,GDB_FR_REG3(sp) + ld v0,GDB_FR_REG2(sp) + ld $1,GDB_FR_REG1(sp) +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) + ld k0, GDB_FR_EPC(sp) + ld sp, GDB_FR_REG29(sp) /* Deallocate stack */ + jr k0 + rfe +#else + ld sp, GDB_FR_REG29(sp) /* Deallocate stack */ + + .set mips3 + eret + .set mips0 +#endif + .set at + .set reorder + END(trap_low) + +LEAF(kgdb_read_byte) +4: lb t0, (a0) + sb t0, (a1) + li v0, 0 + jr ra + .section __ex_table,"a" + PTR 4b, kgdbfault + .previous + END(kgdb_read_byte) + +LEAF(kgdb_write_byte) +5: sb a0, (a1) + li v0, 0 + jr ra + .section __ex_table,"a" + PTR 5b, kgdbfault + .previous + END(kgdb_write_byte) + + .type kgdbfault@function + .ent kgdbfault + +kgdbfault: li v0, -EFAULT + jr ra + .end kgdbfault diff -urN linux-2.4.21-bk37/arch/mips64/kernel/gdb-stub.c linux-2.4.21-bk38/arch/mips64/kernel/gdb-stub.c --- linux-2.4.21-bk37/arch/mips64/kernel/gdb-stub.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/gdb-stub.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,1082 @@ +/* + * arch/mips/kernel/gdb-stub.c + * + * Originally written by Glenn Engel, Lake Stevens Instrument Division + * + * Contributed by HP Systems + * + * Modified for SPARC by Stu Grossman, Cygnus Support. + * + * Modified for Linux/MIPS (and MIPS in general) by Andreas Busse + * Send complaints, suggestions etc. to + * + * Copyright (C) 1995 Andreas Busse + * + * Copyright (C) 2003 MontaVista Software Inc + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + */ + +/* + * To enable debugger support, two things need to happen. One, a + * call to set_debug_traps() is necessary in order to allow any breakpoints + * or error conditions to be properly intercepted and reported to gdb. + * Two, a breakpoint needs to be generated to begin communication. This + * is most easily accomplished by a call to breakpoint(). Breakpoint() + * simulates a breakpoint by executing a BREAK instruction. + * + * + * The following gdb commands are supported: + * + * command function Return value + * + * g return the value of the CPU registers hex data or ENN + * G set the value of the CPU registers OK or ENN + * + * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN + * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN + * + * c Resume at current address SNN ( signal NN) + * cAA..AA Continue at address AA..AA SNN + * + * s Step one instruction SNN + * sAA..AA Step one instruction from AA..AA SNN + * + * k kill + * + * ? What was the last sigval ? SNN (signal NN) + * + * bBB..BB Set baud rate to BB..BB OK or BNN, then sets + * baud rate + * + * All commands and responses are sent with a packet which includes a + * checksum. A packet consists of + * + * $#. + * + * where + * :: + * :: < two hex digits computed as modulo 256 sum of > + * + * When a packet is received, it is first acknowledged with either '+' or '-'. + * '+' indicates a successful transfer. '-' indicates a failed transfer. + * + * Example: + * + * Host: Reply: + * $m0,10#2a +$00010203040506070809101112131415#42 + * + * + * ============== + * MORE EXAMPLES: + * ============== + * + * For reference -- the following are the steps that one + * company took (RidgeRun Inc) to get remote gdb debugging + * going. In this scenario the host machine was a PC and the + * target platform was a Galileo EVB64120A MIPS evaluation + * board. + * + * Step 1: + * First download gdb-5.0.tar.gz from the internet. + * and then build/install the package. + * + * Example: + * $ tar zxf gdb-5.0.tar.gz + * $ cd gdb-5.0 + * $ ./configure --target=mips-linux-elf + * $ make + * $ install + * $ which mips-linux-elf-gdb + * /usr/local/bin/mips-linux-elf-gdb + * + * Step 2: + * Configure linux for remote debugging and build it. + * + * Example: + * $ cd ~/linux + * $ make menuconfig + * $ make dep; make vmlinux + * + * Step 3: + * Download the kernel to the remote target and start + * the kernel running. It will promptly halt and wait + * for the host gdb session to connect. It does this + * since the "Kernel Hacking" option has defined + * CONFIG_KGDB which in turn enables your calls + * to: + * set_debug_traps(); + * breakpoint(); + * + * Step 4: + * Start the gdb session on the host. + * + * Example: + * $ mips-linux-elf-gdb vmlinux + * (gdb) set remotebaud 115200 + * (gdb) target remote /dev/ttyS1 + * ...at this point you are connected to + * the remote target and can use gdb + * in the normal fasion. Setting + * breakpoints, single stepping, + * printing variables, etc. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* + * external low-level support routines + */ + +extern int putDebugChar(char c); /* write a single character */ +extern char getDebugChar(void); /* read and return a single char */ +extern void trap_low(void); + +/* + * breakpoint and test functions + */ +extern void breakpoint(void); +extern void breakinst(void); +extern void async_breakpoint(void); +extern void async_breakinst(void); +extern void adel(void); + +/* + * local prototypes + */ + +static void getpacket(char *buffer); +static void putpacket(char *buffer); +static int computeSignal(int tt); +static int hex(unsigned char ch); +static int hexToInt(char **ptr, int *intValue); +static int hexToLong(char **ptr, long *longValue); +static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault); +void handle_exception(struct gdb_regs *regs); + +/* + * spin locks for smp case + */ +static spinlock_t kgdb_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t kgdb_cpulock[NR_CPUS] = { [0 ... NR_CPUS-1] = SPIN_LOCK_UNLOCKED}; + +/* + * BUFMAX defines the maximum number of characters in inbound/outbound buffers + * at least NUMREGBYTES*2 are needed for register packets + */ +#define BUFMAX 2048 + +static char input_buffer[BUFMAX]; +static char output_buffer[BUFMAX]; +static int initialized; /* !0 means we've been initialized */ +static int kgdb_started; +static const char hexchars[]="0123456789abcdef"; + +/* Used to prevent crashes in memory access. Note that they'll crash anyway if + we haven't set up fault handlers yet... */ +int kgdb_read_byte(unsigned char *address, unsigned char *dest); +int kgdb_write_byte(unsigned char val, unsigned char *dest); + +/* + * Convert ch from a hex digit to an int + */ +static int hex(unsigned char ch) +{ + if (ch >= 'a' && ch <= 'f') + return ch-'a'+10; + if (ch >= '0' && ch <= '9') + return ch-'0'; + if (ch >= 'A' && ch <= 'F') + return ch-'A'+10; + return -1; +} + +/* + * scan for the sequence $# + */ +static void getpacket(char *buffer) +{ + unsigned char checksum; + unsigned char xmitcsum; + int i; + int count; + unsigned char ch; + + do { + /* + * wait around for the start character, + * ignore all other characters + */ + while ((ch = (getDebugChar() & 0x7f)) != '$') ; + + checksum = 0; + xmitcsum = -1; + count = 0; + + /* + * now, read until a # or end of buffer is found + */ + while (count < BUFMAX) { + ch = getDebugChar() & 0x7f; + if (ch == '#') + break; + checksum = checksum + ch; + buffer[count] = ch; + count = count + 1; + } + + if (count >= BUFMAX) + continue; + + buffer[count] = 0; + + if (ch == '#') { + xmitcsum = hex(getDebugChar() & 0x7f) << 4; + xmitcsum |= hex(getDebugChar() & 0x7f); + + if (checksum != xmitcsum) + putDebugChar('-'); /* failed checksum */ + else { + putDebugChar('+'); /* successful transfer */ + + /* + * if a sequence char is present, + * reply the sequence ID + */ + if (buffer[2] == ':') { + putDebugChar(buffer[0]); + putDebugChar(buffer[1]); + + /* + * remove sequence chars from buffer + */ + count = strlen(buffer); + for (i=3; i <= count; i++) + buffer[i-3] = buffer[i]; + } + } + } + } + while (checksum != xmitcsum); +} + +/* + * send the packet in buffer. + */ +static void putpacket(char *buffer) +{ + unsigned char checksum; + int count; + unsigned char ch; + + /* + * $#. + */ + + do { + putDebugChar('$'); + checksum = 0; + count = 0; + + while ((ch = buffer[count]) != 0) { + if (!(putDebugChar(ch))) + return; + checksum += ch; + count += 1; + } + + putDebugChar('#'); + putDebugChar(hexchars[checksum >> 4]); + putDebugChar(hexchars[checksum & 0xf]); + + } + while ((getDebugChar() & 0x7f) != '+'); +} + + +/* + * Convert the memory pointed to by mem into hex, placing result in buf. + * Return a pointer to the last char put in buf (null), in case of mem fault, + * return 0. + * may_fault is non-zero if we are reading from arbitrary memory, but is currently + * not used. + */ +static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault) +{ + unsigned char ch; + + while (count-- > 0) { + if (kgdb_read_byte(mem++, &ch) != 0) + return 0; + *buf++ = hexchars[ch >> 4]; + *buf++ = hexchars[ch & 0xf]; + } + + *buf = 0; + + return buf; +} + +/* + * convert the hex array pointed to by buf into binary to be placed in mem + * return a pointer to the character AFTER the last byte written + * may_fault is non-zero if we are reading from arbitrary memory, but is currently + * not used. + */ +static char *hex2mem(char *buf, char *mem, int count, int may_fault) +{ + int i; + unsigned char ch; + + for (i=0; itt && ht->signo; ht++) + saved_vectors[ht->tt] = set_except_vector(ht->tt, trap_low); + + putDebugChar('+'); /* 'hello world' */ + /* + * In case GDB is started before us, ack any packets + * (presumably "$?#xx") sitting there. + */ + while((c = getDebugChar()) != '$'); + while((c = getDebugChar()) != '#'); + c = getDebugChar(); /* eat first csum byte */ + c = getDebugChar(); /* eat second csum byte */ + putDebugChar('+'); /* ack it */ + + initialized = 1; + restore_flags(flags); +} + +void restore_debug_traps(void) +{ + struct hard_trap_info *ht; + unsigned long flags; + + save_and_cli(flags); + for (ht = hard_trap_info; ht->tt && ht->signo; ht++) + set_except_vector(ht->tt, saved_vectors[ht->tt]); + restore_flags(flags); +} + +/* + * Convert the MIPS hardware trap type code to a Unix signal number. + */ +static int computeSignal(int tt) +{ + struct hard_trap_info *ht; + + for (ht = hard_trap_info; ht->tt && ht->signo; ht++) + if (ht->tt == tt) + return ht->signo; + + return SIGHUP; /* default for things we don't know about */ +} + +/* + * While we find nice hex chars, build an int. + * Return number of chars processed. + */ +static int hexToInt(char **ptr, int *intValue) +{ + int numChars = 0; + int hexValue; + + *intValue = 0; + + while (**ptr) { + hexValue = hex(**ptr); + if (hexValue < 0) + break; + + *intValue = (*intValue << 4) | hexValue; + numChars ++; + + (*ptr)++; + } + + return (numChars); +} + +static int hexToLong(char **ptr, long *longValue) +{ + int numChars = 0; + int hexValue; + + *longValue = 0; + + while (**ptr) { + hexValue = hex(**ptr); + if (hexValue < 0) + break; + + *longValue = (*longValue << 4) | hexValue; + numChars ++; + + (*ptr)++; + } + + return (numChars); +} + + +#if 0 +/* + * Print registers (on target console) + * Used only to debug the stub... + */ +void show_gdbregs(struct gdb_regs * regs) +{ + /* + * Saved main processor registers + */ + printk("$0 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + regs->reg0, regs->reg1, regs->reg2, regs->reg3, + regs->reg4, regs->reg5, regs->reg6, regs->reg7); + printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + regs->reg8, regs->reg9, regs->reg10, regs->reg11, + regs->reg12, regs->reg13, regs->reg14, regs->reg15); + printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + regs->reg16, regs->reg17, regs->reg18, regs->reg19, + regs->reg20, regs->reg21, regs->reg22, regs->reg23); + printk("$24: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", + regs->reg24, regs->reg25, regs->reg26, regs->reg27, + regs->reg28, regs->reg29, regs->reg30, regs->reg31); + + /* + * Saved cp0 registers + */ + printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\n", + regs->cp0_epc, regs->cp0_status, regs->cp0_cause); +} +#endif /* dead code */ + +/* + * We single-step by setting breakpoints. When an exception + * is handled, we need to restore the instructions hoisted + * when the breakpoints were set. + * + * This is where we save the original instructions. + */ +static struct gdb_bp_save { + unsigned long addr; + unsigned int val; +} step_bp[2]; + +#define BP 0x0000000d /* break opcode */ + +/* + * Set breakpoint instructions for single stepping. + */ +static void single_step(struct gdb_regs *regs) +{ + union mips_instruction insn; + unsigned long targ; + int is_branch, is_cond, i; + + targ = regs->cp0_epc; + insn.word = *(unsigned int *)targ; + is_branch = is_cond = 0; + + switch (insn.i_format.opcode) { + /* + * jr and jalr are in r_format format. + */ + case spec_op: + switch (insn.r_format.func) { + case jalr_op: + case jr_op: + targ = *(®s->reg0 + insn.r_format.rs); + is_branch = 1; + break; + } + break; + + /* + * This group contains: + * bltz_op, bgez_op, bltzl_op, bgezl_op, + * bltzal_op, bgezal_op, bltzall_op, bgezall_op. + */ + case bcond_op: + is_branch = is_cond = 1; + targ += 4 + (insn.i_format.simmediate << 2); + break; + + /* + * These are unconditional and in j_format. + */ + case jal_op: + case j_op: + is_branch = 1; + targ += 4; + targ >>= 28; + targ <<= 28; + targ |= (insn.j_format.target << 2); + break; + + /* + * These are conditional. + */ + case beq_op: + case beql_op: + case bne_op: + case bnel_op: + case blez_op: + case blezl_op: + case bgtz_op: + case bgtzl_op: + case cop0_op: + case cop1_op: + case cop2_op: + case cop1x_op: + is_branch = is_cond = 1; + targ += 4 + (insn.i_format.simmediate << 2); + break; + } + + if (is_branch) { + i = 0; + if (is_cond && targ != (regs->cp0_epc + 8)) { + step_bp[i].addr = regs->cp0_epc + 8; + step_bp[i++].val = *(unsigned *)(regs->cp0_epc + 8); + *(unsigned *)(regs->cp0_epc + 8) = BP; + } + step_bp[i].addr = targ; + step_bp[i].val = *(unsigned *)targ; + *(unsigned *)targ = BP; + } else { + step_bp[0].addr = regs->cp0_epc + 4; + step_bp[0].val = *(unsigned *)(regs->cp0_epc + 4); + *(unsigned *)(regs->cp0_epc + 4) = BP; + } +} + +/* + * If asynchronously interrupted by gdb, then we need to set a breakpoint + * at the interrupted instruction so that we wind up stopped with a + * reasonable stack frame. + */ +static struct gdb_bp_save async_bp; + +/* + * Swap the interrupted EPC with our asynchronous breakpoint routine. + * This is safer than stuffing the breakpoint in-place, since no cache + * flushes (or resulting smp_call_functions) are required. The + * assumption is that only one CPU will be handling asynchronous bp's, + * and only one can be active at a time. + */ +extern spinlock_t smp_call_lock; +void set_async_breakpoint(unsigned long *epc) +{ + /* skip breaking into userland */ + if ((*epc & 0x80000000) == 0) + return; + + /* avoid deadlock if someone is make IPC */ + if (spin_is_locked(&smp_call_lock)) + return; + + async_bp.addr = *epc; + *epc = (unsigned long)async_breakpoint; +} + +void kgdb_wait(void *arg) +{ + unsigned flags; + int cpu = smp_processor_id(); + + local_irq_save(flags); + + spin_lock(&kgdb_cpulock[cpu]); + spin_unlock(&kgdb_cpulock[cpu]); + + local_irq_restore(flags); +} + + +/* + * This function does all command processing for interfacing to gdb. It + * returns 1 if you should skip the instruction at the trap address, 0 + * otherwise. + */ +void handle_exception (struct gdb_regs *regs) +{ + int trap; /* Trap type */ + int sigval; + long addr; + int length; + char *ptr; + unsigned long *stack; + int i; + + kgdb_started = 1; + + /* + * acquire the big kgdb spinlock + */ + if (!spin_trylock(&kgdb_lock)) { + /* + * some other CPU has the lock, we should go back to + * receive the gdb_wait IPC + */ + return; + } + + /* + * If we're in async_breakpoint(), restore the real EPC from + * the breakpoint. + */ + if (regs->cp0_epc == (unsigned long)async_breakinst) { + regs->cp0_epc = async_bp.addr; + async_bp.addr = 0; + } + + /* + * acquire the CPU spinlocks + */ + for (i=0; i< smp_num_cpus; i++) + if (spin_trylock(&kgdb_cpulock[i]) == 0) + panic("kgdb: couldn't get cpulock %d\n", i); + + /* + * force other cpus to enter kgdb + */ + smp_call_function(kgdb_wait, NULL, 0, 0); + + /* + * If we're in breakpoint() increment the PC + */ + trap = (regs->cp0_cause & 0x7c) >> 2; + if (trap == 9 && regs->cp0_epc == (unsigned long)breakinst) + regs->cp0_epc += 4; + + /* + * If we were single_stepping, restore the opcodes hoisted + * for the breakpoint[s]. + */ + if (step_bp[0].addr) { + *(unsigned *)step_bp[0].addr = step_bp[0].val; + step_bp[0].addr = 0; + + if (step_bp[1].addr) { + *(unsigned *)step_bp[1].addr = step_bp[1].val; + step_bp[1].addr = 0; + } + } + + stack = (long *)regs->reg29; /* stack ptr */ + sigval = computeSignal(trap); + + /* + * reply to host that an exception has occurred + */ + ptr = output_buffer; + + /* + * Send trap type (converted to signal) + */ + *ptr++ = 'T'; + *ptr++ = hexchars[sigval >> 4]; + *ptr++ = hexchars[sigval & 0xf]; + + /* + * Send Error PC + */ + *ptr++ = hexchars[REG_EPC >> 4]; + *ptr++ = hexchars[REG_EPC & 0xf]; + *ptr++ = ':'; + ptr = mem2hex((char *)®s->cp0_epc, ptr, 8, 0); + *ptr++ = ';'; + + /* + * Send frame pointer + */ + *ptr++ = hexchars[REG_FP >> 4]; + *ptr++ = hexchars[REG_FP & 0xf]; + *ptr++ = ':'; + ptr = mem2hex((char *)®s->reg30, ptr, 8, 0); + *ptr++ = ';'; + + /* + * Send stack pointer + */ + *ptr++ = hexchars[REG_SP >> 4]; + *ptr++ = hexchars[REG_SP & 0xf]; + *ptr++ = ':'; + ptr = mem2hex((char *)®s->reg29, ptr, 8, 0); + *ptr++ = ';'; + + *ptr++ = 0; + putpacket(output_buffer); /* send it off... */ + + /* + * Wait for input from remote GDB + */ + while (1) { + output_buffer[0] = 0; + getpacket(input_buffer); + + if (0) { +#include + prom_printf("got %c\n", input_buffer[0]); + } + + switch (input_buffer[0]) + { + case '?': + output_buffer[0] = 'S'; + output_buffer[1] = hexchars[sigval >> 4]; + output_buffer[2] = hexchars[sigval & 0xf]; + output_buffer[3] = 0; + break; + + /* + * Detach debugger; let CPU run + */ + case 'D': + putpacket(output_buffer); + goto finish_kgdb; + break; + + case 'd': + /* toggle debug flag */ + break; + + /* + * Return the value of the CPU registers + */ + case 'g': + ptr = output_buffer; + ptr = mem2hex((char *)®s->reg0, ptr, 32*8, 0); /* r0...r31 */ + ptr = mem2hex((char *)®s->cp0_status, ptr, 6*8, 0); /* cp0 */ + ptr = mem2hex((char *)®s->fpr0, ptr, 32*8, 0); /* f0...31 */ + ptr = mem2hex((char *)®s->cp1_fsr, ptr, 2*8, 0); /* cp1 */ + ptr = mem2hex((char *)®s->frame_ptr, ptr, 2*8, 0); /* frp */ + ptr = mem2hex((char *)®s->cp0_index, ptr, 16*8, 0); /* cp0 */ + break; + + /* + * set the value of the CPU registers - return OK + */ + case 'G': + { + ptr = &input_buffer[1]; + hex2mem(ptr, (char *)®s->reg0, 32*8, 0); + ptr += 32*16; + hex2mem(ptr, (char *)®s->cp0_status, 6*8, 0); + ptr += 6*16; + hex2mem(ptr, (char *)®s->fpr0, 32*8, 0); + ptr += 32*16; + hex2mem(ptr, (char *)®s->cp1_fsr, 2*8, 0); + ptr += 2*16; + hex2mem(ptr, (char *)®s->frame_ptr, 2*8, 0); + ptr += 2*16; + hex2mem(ptr, (char *)®s->cp0_index, 16*8, 0); + strcpy(output_buffer,"OK"); + } + break; + + /* + * mAA..AA,LLLL Read LLLL bytes at address AA..AA + */ + case 'm': + ptr = &input_buffer[1]; + + if (hexToLong(&ptr, &addr) + && *ptr++ == ',' + && hexToInt(&ptr, &length)) { + if (mem2hex((char *)addr, output_buffer, length, 1)) + break; + strcpy (output_buffer, "E03"); + } else + strcpy(output_buffer,"E01"); + break; + + /* + * MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK + */ + case 'M': + ptr = &input_buffer[1]; + + if (hexToLong(&ptr, &addr) + && *ptr++ == ',' + && hexToInt(&ptr, &length) + && *ptr++ == ':') { + if (hex2mem(ptr, (char *)addr, length, 1)) + strcpy(output_buffer, "OK"); + else + strcpy(output_buffer, "E03"); + } + else + strcpy(output_buffer, "E02"); + break; + + /* + * cAA..AA Continue at address AA..AA(optional) + */ + case 'c': + /* try to read optional parameter, pc unchanged if no parm */ + + ptr = &input_buffer[1]; + if (hexToLong(&ptr, &addr)) + regs->cp0_epc = addr; + + goto exit_kgdb_exception; + break; + + /* + * kill the program; let us try to restart the machine + * Reset the whole machine. + */ + case 'k': + case 'r': + machine_restart("kgdb restarts machine"); + break; + + /* + * Step to next instruction + */ + case 's': + /* + * There is no single step insn in the MIPS ISA, so we + * use breakpoints and continue, instead. + */ + single_step(regs); + goto exit_kgdb_exception; + /* NOTREACHED */ + break; + + /* + * Set baud rate (bBB) + * FIXME: Needs to be written + */ + case 'b': + { +#if 0 + int baudrate; + extern void set_timer_3(); + + ptr = &input_buffer[1]; + if (!hexToInt(&ptr, &baudrate)) + { + strcpy(output_buffer,"B01"); + break; + } + + /* Convert baud rate to uart clock divider */ + + switch (baudrate) + { + case 38400: + baudrate = 16; + break; + case 19200: + baudrate = 33; + break; + case 9600: + baudrate = 65; + break; + default: + baudrate = 0; + strcpy(output_buffer,"B02"); + goto x1; + } + + if (baudrate) { + putpacket("OK"); /* Ack before changing speed */ + set_timer_3(baudrate); /* Set it */ + } +#endif + } + break; + + } /* switch */ + + /* + * reply to the request + */ + + putpacket(output_buffer); + + } /* while */ + + return; + +finish_kgdb: + restore_debug_traps(); + +exit_kgdb_exception: + /* release locks so other CPUs can go */ + for (i=0; i < smp_num_cpus; i++) + spin_unlock(&kgdb_cpulock[i]); + spin_unlock(&kgdb_lock); + + __flush_cache_all(); + return; +} + +/* + * This function will generate a breakpoint exception. It is used at the + * beginning of a program to sync up with a debugger and can be used + * otherwise as a quick means to stop program execution and "break" into + * the debugger. + */ +void breakpoint(void) +{ + if (!initialized) + return; + + __asm__ __volatile__( + ".globl breakinst\n\t" + ".set\tnoreorder\n\t" + "nop\n\t" + "breakinst:\tbreak\n\t" + "nop\n\t" + ".set\treorder" + ); +} + +/* Nothing but the break; don't pollute any registers */ +void async_breakpoint(void) +{ + __asm__ __volatile__( + ".globl async_breakinst\n\t" + ".set\tnoreorder\n\t" + "nop\n\t" + "async_breakinst:\tbreak\n\t" + "nop\n\t" + ".set\treorder" + ); +} + +void adel(void) +{ + __asm__ __volatile__( + ".globl\tadel\n\t" + "lui\t$8,0x8000\n\t" + "lw\t$9,1($8)\n\t" + ); +} + +/* + * malloc is needed by gdb client in "call func()", even a private one + * will make gdb happy + */ +static void *malloc(size_t size) +{ + return kmalloc(size, GFP_ATOMIC); +} + +static void free(void *where) +{ + kfree(where); +} + +#ifdef CONFIG_GDB_CONSOLE + +void gdb_putsn(const char *str, int l) +{ + char outbuf[18]; + + if (!kgdb_started) + return; + + outbuf[0]='O'; + + while(l) { + int i = (l>8)?8:l; + mem2hex((char *)str, &outbuf[1], i, 0); + outbuf[(i*2)+1]=0; + putpacket(outbuf); + str += i; + l -= i; + } +} + +static kdev_t gdb_console_dev(struct console *con) +{ + return MKDEV(1, 3); /* /dev/null */ +} + +static void gdb_console_write(struct console *con, const char *s, unsigned n) +{ + gdb_putsn(s, n); +} + +static struct console gdb_console = { + .name = "gdb", + .write = gdb_console_write, + .device = gdb_console_dev, + .flags = CON_PRINTBUFFER, + .index = -1 +}; + +__init void register_gdb_console(void) +{ + register_console(&gdb_console); +} + +#endif diff -urN linux-2.4.21-bk37/arch/mips64/kernel/head.S linux-2.4.21-bk38/arch/mips64/kernel/head.S --- linux-2.4.21-bk37/arch/mips64/kernel/head.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/head.S 2003-08-24 02:55:58.000000000 -0700 @@ -107,7 +107,7 @@ PTR_LA $28, init_task_union # init current pointer daddiu sp, $28, KERNEL_STACK_SIZE-32 - set_saved_sp sp, t0 + set_saved_sp sp, t0, t1 /* The firmware/bootloader passes argc/argp/envp * to us as arguments. But clear bss first because @@ -157,8 +157,6 @@ or t0, ST0_KX mtc0 t0, CP0_STATUS - set_saved_sp sp, t0 - jal start_secondary # XXX: IP27: cboot END(smp_bootstrap) @@ -168,13 +166,10 @@ declare_saved_sp -#undef PAGE_SIZE -#define PAGE_SIZE 0x1000 - .macro page name, order=0 .globl \name -\name: .size \name, (PAGE_SIZE << \order) - .org . + (PAGE_SIZE << \order) +\name: .size \name, (_PAGE_SIZE << \order) + .org . + (_PAGE_SIZE << \order) .type \name, @object .endm diff -urN linux-2.4.21-bk37/arch/mips64/kernel/i8259.c linux-2.4.21-bk38/arch/mips64/kernel/i8259.c --- linux-2.4.21-bk37/arch/mips64/kernel/i8259.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/i8259.c 2003-08-24 02:55:58.000000000 -0700 @@ -15,6 +15,7 @@ #include #include +#include #include void enable_8259A_irq(unsigned int irq); diff -urN linux-2.4.21-bk37/arch/mips64/kernel/ioctl32.c linux-2.4.21-bk38/arch/mips64/kernel/ioctl32.c --- linux-2.4.21-bk37/arch/mips64/kernel/ioctl32.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/ioctl32.c 2003-08-24 02:55:58.000000000 -0700 @@ -4,6 +4,7 @@ * Copyright (C) 2000 Silicon Graphics, Inc. * Written by Ulf Carlsson (ulfc@engr.sgi.com) * Copyright (C) 2000 Ralf Baechle + * Copyright (C) 2002 Maciej W. Rozycki * * Mostly stolen from the sparc64 ioctl32 implementation. */ @@ -22,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -31,17 +33,28 @@ #include #include #include +#include #include #include +#include #include #undef __KERNEL__ /* This file was born to be ugly ... */ #include #define __KERNEL__ +#include + #include #include #include +#ifdef CONFIG_MTD_CHAR +#include +#endif + +#ifdef CONFIG_SIBYTE_TBPROF +#include +#endif long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); @@ -77,6 +90,166 @@ #define A(__x) ((unsigned long)(__x)) + +#ifdef CONFIG_FB + +struct fb_fix_screeninfo32 { + char id[16]; /* identification string eg "TT Builtin" */ + __u32 smem_start; /* Start of frame buffer mem */ + /* (physical address) */ + __u32 smem_len; /* Length of frame buffer mem */ + __u32 type; /* see FB_TYPE_* */ + __u32 type_aux; /* Interleave for interleaved Planes */ + __u32 visual; /* see FB_VISUAL_* */ + __u16 xpanstep; /* zero if no hardware panning */ + __u16 ypanstep; /* zero if no hardware panning */ + __u16 ywrapstep; /* zero if no hardware ywrap */ + __u32 line_length; /* length of a line in bytes */ + __u32 mmio_start; /* Start of Memory Mapped I/O */ + /* (physical address) */ + __u32 mmio_len; /* Length of Memory Mapped I/O */ + __u32 accel; /* Type of acceleration available */ + __u16 reserved[3]; /* Reserved for future compatibility */ +}; + +static int do_fbioget_fscreeninfo_ioctl(unsigned int fd, unsigned int cmd, + unsigned long arg) +{ + mm_segment_t old_fs = get_fs(); + struct fb_fix_screeninfo fix; + struct fb_fix_screeninfo32 *fix32 = (struct fb_fix_screeninfo32 *)arg; + int err; + + set_fs(KERNEL_DS); + err = sys_ioctl(fd, cmd, (unsigned long)&fix); + set_fs(old_fs); + + if (err == 0) { + err = __copy_to_user((char *)fix32->id, (char *)fix.id, + sizeof(fix.id)); + err |= __put_user((__u32)(unsigned long)fix.smem_start, + &fix32->smem_start); + err |= __put_user(fix.smem_len, &fix32->smem_len); + err |= __put_user(fix.type, &fix32->type); + err |= __put_user(fix.type_aux, &fix32->type_aux); + err |= __put_user(fix.visual, &fix32->visual); + err |= __put_user(fix.xpanstep, &fix32->xpanstep); + err |= __put_user(fix.ypanstep, &fix32->ypanstep); + err |= __put_user(fix.ywrapstep, &fix32->ywrapstep); + err |= __put_user(fix.line_length, &fix32->line_length); + err |= __put_user((__u32)(unsigned long)fix.mmio_start, + &fix32->mmio_start); + err |= __put_user(fix.mmio_len, &fix32->mmio_len); + err |= __put_user(fix.accel, &fix32->accel); + err |= __copy_to_user((char *)fix32->reserved, + (char *)fix.reserved, + sizeof(fix.reserved)); + if (err) + err = -EFAULT; + } + + return err; +} + +struct fb_cmap32 { + __u32 start; /* First entry */ + __u32 len; /* Number of entries */ + __u32 red; /* Red values */ + __u32 green; + __u32 blue; + __u32 transp; /* transparency, can be NULL */ +}; + +static int do_fbiocmap_ioctl(unsigned int fd, unsigned int cmd, + unsigned long arg) +{ + mm_segment_t old_fs = get_fs(); + u32 red = 0, green = 0, blue = 0, transp = 0; + struct fb_cmap cmap; + struct fb_cmap32 *cmap32 = (struct fb_cmap32 *)arg; + int err; + + memset(&cmap, 0, sizeof(cmap)); + + err = __get_user(cmap.start, &cmap32->start); + err |= __get_user(cmap.len, &cmap32->len); + err |= __get_user(red, &cmap32->red); + err |= __get_user(green, &cmap32->green); + err |= __get_user(blue, &cmap32->blue); + err |= __get_user(transp, &cmap32->transp); + if (err) + return -EFAULT; + + err = -ENOMEM; + cmap.red = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); + if (!cmap.red) + goto out; + cmap.green = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); + if (!cmap.green) + goto out; + cmap.blue = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); + if (!cmap.blue) + goto out; + if (transp) { + cmap.transp = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); + if (!cmap.transp) + goto out; + } + + if (cmd == FBIOPUTCMAP) { + err = __copy_from_user(cmap.red, (char *)A(red), + cmap.len * sizeof(__u16)); + err |= __copy_from_user(cmap.green, (char *)A(green), + cmap.len * sizeof(__u16)); + err |= __copy_from_user(cmap.blue, (char *)A(blue), + cmap.len * sizeof(__u16)); + if (cmap.transp) + err |= __copy_from_user(cmap.transp, (char *)A(transp), + cmap.len * sizeof(__u16)); + if (err) { + err = -EFAULT; + goto out; + } + } + + set_fs(KERNEL_DS); + err = sys_ioctl(fd, cmd, (unsigned long)&cmap); + set_fs(old_fs); + if (err) + goto out; + + if (cmd == FBIOGETCMAP) { + err = __copy_to_user((char *)A(red), cmap.red, + cmap.len * sizeof(__u16)); + err |= __copy_to_user((char *)A(green), cmap.blue, + cmap.len * sizeof(__u16)); + err |= __copy_to_user((char *)A(blue), cmap.blue, + cmap.len * sizeof(__u16)); + if (cmap.transp) + err |= __copy_to_user((char *)A(transp), cmap.transp, + cmap.len * sizeof(__u16)); + if (err) { + err = -EFAULT; + goto out; + } + } + +out: + if (cmap.red) + kfree(cmap.red); + if (cmap.green) + kfree(cmap.green); + if (cmap.blue) + kfree(cmap.blue); + if (cmap.transp) + kfree(cmap.transp); + + return err; +} + +#endif /* CONFIG_FB */ + + struct timeval32 { int tv_sec; int tv_usec; @@ -571,6 +744,127 @@ return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg); } +/* serial_struct_ioctl was taken from x86_64/ia32/ia32_ioctl.c and + * slightly modified for mips */ +/* iomem_base is unsigned char * in linux/serial.h (reserved in sgiserial.h) */ +struct serial_struct32 { + int type; + int line; + unsigned int port; + int irq; + int flags; + int xmit_fifo_size; + int custom_divisor; + int baud_base; + unsigned short close_delay; + char io_type; + char reserved_char[1]; + int hub6; + unsigned short closing_wait; /* time to wait before closing */ + unsigned short closing_wait2; /* no longer used... */ + __u32 iomem_base; + unsigned short iomem_reg_shift; + unsigned int port_high; + int reserved[1]; +}; + +static int serial_struct_ioctl(unsigned fd, unsigned cmd, void *ptr) +{ + typedef struct serial_struct SS; + struct serial_struct32 *ss32 = ptr; + int err = 0; + struct serial_struct ss; + mm_segment_t oldseg = get_fs(); + set_fs(KERNEL_DS); + if (cmd == TIOCSSERIAL) { + err = -EFAULT; + if (copy_from_user(&ss, ss32, sizeof(struct serial_struct32))) + goto out; + memmove(&ss.iomem_reg_shift, ((char*)&ss.iomem_base)+4, + sizeof(SS)-offsetof(SS,iomem_reg_shift)); + ss.iomem_base = (void *)(long)ss.iomem_base; /* sign extend */ + } + if (!err) + err = sys_ioctl(fd,cmd,(unsigned long)(&ss)); + if (cmd == TIOCGSERIAL && err >= 0) { + __u32 base; + if (__copy_to_user(ss32,&ss,offsetof(SS,iomem_base)) || + __copy_to_user(&ss32->iomem_reg_shift, + &ss.iomem_reg_shift, + sizeof(SS) - offsetof(SS, iomem_reg_shift))) + err = -EFAULT; + base = (unsigned long)ss.iomem_base; + err |= __put_user(base, &ss32->iomem_base); + } + out: + set_fs(oldseg); + return err; +} + +/* loop_status was taken from sparc64/kernel/ioctl32.c */ +struct loop_info32 { + int lo_number; /* ioctl r/o */ + __kernel_dev_t32 lo_device; /* ioctl r/o */ + unsigned int lo_inode; /* ioctl r/o */ + __kernel_dev_t32 lo_rdevice; /* ioctl r/o */ + int lo_offset; + int lo_encrypt_type; + int lo_encrypt_key_size; /* ioctl w/o */ + int lo_flags; /* ioctl r/o */ + char lo_name[LO_NAME_SIZE]; + unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ + unsigned int lo_init[2]; + char reserved[4]; +}; + +static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + mm_segment_t old_fs = get_fs(); + struct loop_info l; + int err = -EINVAL; + + switch(cmd) { + case LOOP_SET_STATUS: + err = get_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number); + err |= __get_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device); + err |= __get_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode); + err |= __get_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice); + err |= __copy_from_user((char *)&l.lo_offset, (char *)&((struct loop_info32 *)arg)->lo_offset, + 8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); + if (err) { + err = -EFAULT; + } else { + set_fs (KERNEL_DS); + err = sys_ioctl (fd, cmd, (unsigned long)&l); + set_fs (old_fs); + } + break; + case LOOP_GET_STATUS: + set_fs (KERNEL_DS); + err = sys_ioctl (fd, cmd, (unsigned long)&l); + set_fs (old_fs); + if (!err) { + err = put_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number); + err |= __put_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device); + err |= __put_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode); + err |= __put_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice); + err |= __copy_to_user((char *)&((struct loop_info32 *)arg)->lo_offset, + (char *)&l.lo_offset, (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); + if (err) + err = -EFAULT; + } + break; + default: { + static int count; + if (++count <= 20) + printk("%s: Unknown loop ioctl cmd, fd(%d) " + "cmd(%08x) arg(%08lx)\n", + __FUNCTION__, fd, cmd, arg); + } + } + return err; +} + struct ioctl32_handler { unsigned int cmd; int (*function)(unsigned int, unsigned int, unsigned long); @@ -620,8 +914,8 @@ IOCTL32_DEFAULT(TIOCSCTTY), IOCTL32_DEFAULT(TIOCGPTN), IOCTL32_DEFAULT(TIOCSPTLCK), - IOCTL32_DEFAULT(TIOCGSERIAL), - IOCTL32_DEFAULT(TIOCSSERIAL), + IOCTL32_HANDLER(TIOCGSERIAL, serial_struct_ioctl), + IOCTL32_HANDLER(TIOCSSERIAL, serial_struct_ioctl), IOCTL32_DEFAULT(TIOCSERGETLSR), IOCTL32_DEFAULT(FIOCLEX), @@ -630,6 +924,16 @@ IOCTL32_DEFAULT(FIONBIO), IOCTL32_DEFAULT(FIONREAD), +#ifdef CONFIG_FB + /* Big F */ + IOCTL32_DEFAULT(FBIOGET_VSCREENINFO), + IOCTL32_DEFAULT(FBIOPUT_VSCREENINFO), + IOCTL32_HANDLER(FBIOGET_FSCREENINFO, do_fbioget_fscreeninfo_ioctl), + IOCTL32_HANDLER(FBIOGETCMAP, do_fbiocmap_ioctl), + IOCTL32_HANDLER(FBIOPUTCMAP, do_fbiocmap_ioctl), + IOCTL32_DEFAULT(FBIOPAN_DISPLAY), +#endif /* CONFIG_FB */ + /* Big K */ IOCTL32_DEFAULT(PIO_FONT), IOCTL32_DEFAULT(GIO_FONT), @@ -651,6 +955,7 @@ IOCTL32_DEFAULT(KDSKBSENT), IOCTL32_DEFAULT(KDGKBDIACR), IOCTL32_DEFAULT(KDSKBDIACR), + IOCTL32_DEFAULT(KDKBDREP), IOCTL32_DEFAULT(KDGKBLED), IOCTL32_DEFAULT(KDSKBLED), IOCTL32_DEFAULT(KDGETLED), @@ -793,6 +1098,8 @@ /* Big L */ IOCTL32_DEFAULT(LOOP_SET_FD), IOCTL32_DEFAULT(LOOP_CLR_FD), + IOCTL32_HANDLER(LOOP_SET_STATUS, loop_status), + IOCTL32_HANDLER(LOOP_GET_STATUS, loop_status), /* And these ioctls need translation */ IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32), @@ -915,6 +1222,12 @@ IOCTL32_DEFAULT(RESTART_ARRAY_RW), #endif /* CONFIG_MD */ +#ifdef CONFIG_SIBYTE_TBPROF + IOCTL32_DEFAULT(SBPROF_ZBSTART), + IOCTL32_DEFAULT(SBPROF_ZBSTOP), + IOCTL32_DEFAULT(SBPROF_ZBWAITFULL), +#endif /* CONFIG_SIBYTE_TBPROF */ + IOCTL32_DEFAULT(MTIOCTOP), /* mtio.h ioctls */ IOCTL32_HANDLER(MTIOCGET32, mt_ioctl_trans), IOCTL32_HANDLER(MTIOCPOS32, mt_ioctl_trans), @@ -933,6 +1246,7 @@ IOCTL32_DEFAULT(AUTOFS_IOC_PROTOVER), IOCTL32_HANDLER(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout), IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE), + IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE_MULTI), /* Little p (/dev/rtc, /dev/envctrl, etc.) */ IOCTL32_DEFAULT(_IOR('p', 20, int[7])), /* RTCGET */ @@ -950,7 +1264,18 @@ IOCTL32_DEFAULT(RTC_RD_TIME), IOCTL32_DEFAULT(RTC_SET_TIME), IOCTL32_DEFAULT(RTC_WKALM_SET), - IOCTL32_DEFAULT(RTC_WKALM_RD) + IOCTL32_DEFAULT(RTC_WKALM_RD), +#ifdef CONFIG_MTD_CHAR + /* Big M */ + IOCTL32_DEFAULT(MEMGETINFO), + IOCTL32_DEFAULT(MEMERASE), + // IOCTL32_DEFAULT(MEMWRITEOOB32, mtd_rw_oob), + // IOCTL32_DEFAULT(MEMREADOOB32, mtd_rw_oob), + IOCTL32_DEFAULT(MEMLOCK), + IOCTL32_DEFAULT(MEMUNLOCK), + IOCTL32_DEFAULT(MEMGETREGIONCOUNT), + IOCTL32_DEFAULT(MEMGETREGIONINFO), +#endif }; #define NR_IOCTL32_HANDLERS (sizeof(ioctl32_handler_table) / \ diff -urN linux-2.4.21-bk37/arch/mips64/kernel/irq.c linux-2.4.21-bk38/arch/mips64/kernel/irq.c --- linux-2.4.21-bk37/arch/mips64/kernel/irq.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/irq.c 2003-08-24 02:55:58.000000000 -0700 @@ -211,7 +211,7 @@ void __global_cli(void) { - unsigned int flags; + unsigned long flags; __save_flags(flags); if (flags & ST0_IE) { diff -urN linux-2.4.21-bk37/arch/mips64/kernel/irq_cpu.c linux-2.4.21-bk38/arch/mips64/kernel/irq_cpu.c --- linux-2.4.21-bk37/arch/mips64/kernel/irq_cpu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/irq_cpu.c 2003-08-24 02:55:58.000000000 -0700 @@ -35,13 +35,13 @@ static inline void unmask_mips_irq(unsigned int irq) { - clear_cp0_cause(0x100 << (irq - mips_cpu_irq_base)); - set_cp0_status(0x100 << (irq - mips_cpu_irq_base)); + clear_c0_cause(0x100 << (irq - mips_cpu_irq_base)); + set_c0_status(0x100 << (irq - mips_cpu_irq_base)); } static inline void mask_mips_irq(unsigned int irq) { - clear_cp0_status(0x100 << (irq - mips_cpu_irq_base)); + clear_c0_status(0x100 << (irq - mips_cpu_irq_base)); } static inline void mips_cpu_irq_enable(unsigned int irq) @@ -78,7 +78,7 @@ static void mips_cpu_irq_ack(unsigned int irq) { /* Only necessary for soft interrupts */ - clear_cp0_cause(1 << (irq - mips_cpu_irq_base + 8)); + clear_c0_cause(1 << (irq - mips_cpu_irq_base + 8)); mask_mips_irq(irq); } diff -urN linux-2.4.21-bk37/arch/mips64/kernel/linux32.c linux-2.4.21-bk38/arch/mips64/kernel/linux32.c --- linux-2.4.21-bk37/arch/mips64/kernel/linux32.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/linux32.c 2003-08-24 02:55:58.000000000 -0700 @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -32,6 +31,7 @@ #include #include #include +#include #include #include @@ -179,7 +179,32 @@ return err; } -asmlinkage int sys_mmap2(void) {return 0;} +asmlinkage unsigned long +sys32_mmap2(unsigned long addr, size_t len, unsigned long prot, + unsigned long flags, unsigned long fd, unsigned long pgoff) +{ + struct file * file = NULL; + unsigned long error; + + error = -EINVAL; + if (!(flags & MAP_ANONYMOUS)) { + error = -EBADF; + file = fget(fd); + if (!file) + goto out; + } + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + + down_write(¤t->mm->mmap_sem); + error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); + up_write(¤t->mm->mmap_sem); + if (file) + fput(file); + +out: + return error; +} + asmlinkage long sys_truncate(const char * path, unsigned long length); @@ -241,15 +266,15 @@ if (argv != NULL) { for (;;) { - u32 p; - /* egcs is stupid */ - if (!access_ok(VERIFY_READ, argv, sizeof (u32))) - return -EFAULT; - __get_user(p,argv); + u32 p; int error; + + error = get_user(p,argv); + if (error) + return error; if (!p) break; argv++; - if(++i > max) + if (++i > max) return -E2BIG; } } @@ -309,7 +334,6 @@ } err = copy_from_user(kaddr + offset, (char *)A(str), bytes_to_copy); - flush_page_to_ram(page); kunmap(page); if (err) @@ -416,26 +440,22 @@ #else static int nargs(unsigned int arg, char **ap) { - char *ptr; - int n, ret; + unsigned int addr; + int n, err; if (!arg) return 0; n = 0; do { - /* egcs is stupid */ - if (!access_ok(VERIFY_READ, arg, sizeof (unsigned int))) - return -EFAULT; - if (IS_ERR(ret = __get_user((long)ptr,(int *)A(arg)))) - return ret; - if (ap) /* no access_ok needed, we allocated */ - if (IS_ERR(ret = __put_user(ptr, ap++))) - return ret; + err = get_user(addr, (unsigned int *)A(arg)); + if (err) + return err; + if (ap) + *ap++ = (char *) A(addr); arg += sizeof(unsigned int); n++; - } while (ptr); - + } while (addr); return n - 1; } @@ -451,19 +471,20 @@ char * filename; na = nargs(argv, NULL); - if (IS_ERR(na)) - return(na); + if (na < 0) + return na; ne = nargs(envp, NULL); - if (IS_ERR(ne)) - return(ne); + if (ne < 0) + return ne; len = (na + ne + 2) * sizeof(*av); + /* * kmalloc won't work because the `sys_exec' code will attempt * to do a `get_user' on the arg list and `get_user' will fail * on a kernel address (simplifies `get_user'). Instead we * do an mmap to get a user address. Note that since a successful * `execve' frees all current memory we only have to do an - * `munmap' if the `execve' failes. + * `munmap' if the `execve' fails. */ down_write(¤t->mm->mmap_sem); av = (char **) do_mmap_pgoff(0, 0, len, PROT_READ | PROT_WRITE, @@ -473,13 +494,15 @@ if (IS_ERR(av)) return (long) av; ae = av + na + 1; - if (IS_ERR(r = __put_user(0, (av + na)))) - goto out; - if (IS_ERR(r = __put_user(0, (ae + ne)))) + r = __put_user(0, (av + na)); + r |= __put_user(0, (ae + ne)); + if (r) goto out; - if (IS_ERR(r = nargs(argv, av))) + r = nargs(argv, av); + if (r < 0) goto out; - if (IS_ERR(r = nargs(envp, ae))) + r = nargs(envp, ae); + if (r < 0) goto out; filename = getname((char *) (long)regs.regs[4]); r = PTR_ERR(filename); @@ -488,10 +511,10 @@ r = do_execve(filename, av, ae, ®s); putname(filename); - if (IS_ERR(r)) + if (r) out: sys_munmap((unsigned long)av, len); - return(r); + return r ; } #endif @@ -586,7 +609,10 @@ { int err; - err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec); + if (verify_area(VERIFY_WRITE, ru, sizeof *ru)) + return -EFAULT; + + err = __put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec); err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec); err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec); err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec); @@ -604,6 +630,7 @@ err |= __put_user (r->ru_nsignals, &ru->ru_nsignals); err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw); err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw); + return err; } @@ -635,6 +662,52 @@ return sys32_wait4(pid, stat_addr, options, NULL); } +struct sysinfo32 { + s32 uptime; + u32 loads[3]; + u32 totalram; + u32 freeram; + u32 sharedram; + u32 bufferram; + u32 totalswap; + u32 freeswap; + u16 procs; + u32 totalhigh; + u32 freehigh; + u32 mem_unit; + char _f[8]; +}; + +extern asmlinkage int sys_sysinfo(struct sysinfo *info); + +asmlinkage int sys32_sysinfo(struct sysinfo32 *info) +{ + struct sysinfo s; + int ret, err; + mm_segment_t old_fs = get_fs (); + + set_fs (KERNEL_DS); + ret = sys_sysinfo(&s); + set_fs (old_fs); + err = put_user (s.uptime, &info->uptime); + err |= __put_user (s.loads[0], &info->loads[0]); + err |= __put_user (s.loads[1], &info->loads[1]); + err |= __put_user (s.loads[2], &info->loads[2]); + err |= __put_user (s.totalram, &info->totalram); + err |= __put_user (s.freeram, &info->freeram); + err |= __put_user (s.sharedram, &info->sharedram); + err |= __put_user (s.bufferram, &info->bufferram); + err |= __put_user (s.totalswap, &info->totalswap); + err |= __put_user (s.freeswap, &info->freeswap); + err |= __put_user (s.procs, &info->procs); + err |= __put_user (s.totalhigh, &info->totalhigh); + err |= __put_user (s.freehigh, &info->freehigh); + err |= __put_user (s.mem_unit, &info->mem_unit); + if (err) + return -EFAULT; + return ret; +} + #define RLIM_INFINITY32 0x7fffffff #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x) @@ -725,12 +798,17 @@ int ret; struct statfs s; mm_segment_t old_fs = get_fs(); - - set_fs (KERNEL_DS); - ret = sys_statfs((const char *)path, &s); - set_fs (old_fs); - if (put_statfs(buf, &s)) - return -EFAULT; + char *pth; + + pth = getname (path); + ret = PTR_ERR(pth); + if (!IS_ERR(pth)) { + set_fs (KERNEL_DS); + ret = sys_statfs((const char *)path, &s); + set_fs (old_fs); + if (!ret && put_statfs(buf, &s)) + return -EFAULT; + } return ret; } @@ -751,6 +829,38 @@ return ret; } +#ifdef __MIPSEB__ +asmlinkage long sys32_truncate64(const char * path, unsigned long __dummy, + int length_hi, int length_lo) +#endif +#ifdef __MIPSEL__ +asmlinkage long sys32_truncate64(const char * path, unsigned long __dummy, + int length_lo, int length_hi) +#endif +{ + loff_t length; + + length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo; + + return sys_truncate(path, length); +} + +#ifdef __MIPSEB__ +asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy, + int length_hi, int length_lo) +#endif +#ifdef __MIPSEL__ +asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy, + int length_lo, int length_hi) +#endif +{ + loff_t length; + + length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo; + + return sys_ftruncate(fd, length); +} + extern asmlinkage int sys_getrusage(int who, struct rusage *ru); @@ -843,25 +953,6 @@ return -EFAULT; return 0; - -} -asmlinkage unsigned long -sys32_alarm(unsigned int seconds) -{ - struct itimerval it_new, it_old; - unsigned int oldalarm; - - it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0; - it_new.it_value.tv_sec = seconds; - it_new.it_value.tv_usec = 0; - do_setitimer(ITIMER_REAL, &it_new, &it_old); - oldalarm = it_old.it_value.tv_sec; - /* ehhh.. We can't return 0 if we have an alarm pending.. */ - /* And we'd better return too much than too little anyway */ - if (it_old.it_value.tv_usec) - oldalarm++; - - return oldalarm; } /* Translations due to time_t size differences. Which affects all @@ -1572,6 +1663,15 @@ unsigned short sem_nsems; /* no. of semaphores in array */ }; +struct semid64_ds32 { + struct ipc64_perm32 sem_perm; + __kernel_time_t32 sem_otime; + __kernel_time_t32 sem_ctime; + unsigned int sem_nsems; + unsigned int __unused1; + unsigned int __unused2; +}; + struct msqid_ds32 { struct ipc_perm32 msg_perm; @@ -1617,6 +1717,19 @@ unsigned short shm_nattch; }; +struct shmid64_ds32 { + struct ipc64_perm32 shm_perm; + __kernel_size_t32 shm_segsz; + __kernel_time_t32 shm_atime; + __kernel_time_t32 shm_dtime; + __kernel_time_t32 shm_ctime; + __kernel_pid_t32 shm_cpid; + __kernel_pid_t32 shm_lpid; + unsigned int shm_nattch; + unsigned int __unused1; + unsigned int __unused2; +}; + struct ipc_kludge32 { u32 msgp; s32 msgtyp; @@ -1629,7 +1742,6 @@ u32 pad; int err, err2; struct semid64_ds s; - struct semid_ds32 *usp; mm_segment_t old_fs; if (!uptr) @@ -1642,7 +1754,6 @@ else fourth.__pad = (void *)A(pad); switch (third & ~IPC_64) { - case IPC_INFO: case IPC_RMID: case IPC_SET: @@ -1659,34 +1770,60 @@ case IPC_STAT: case SEM_STAT: - usp = (struct semid_ds32 *)A(pad); fourth.__pad = &s; old_fs = get_fs (); set_fs (KERNEL_DS); err = sys_semctl (first, second, third, fourth); set_fs (old_fs); - err2 = put_user(s.sem_perm.key, &usp->sem_perm.key); - err2 |= __put_user(s.sem_perm.uid, &usp->sem_perm.uid); - err2 |= __put_user(s.sem_perm.gid, &usp->sem_perm.gid); - err2 |= __put_user(s.sem_perm.cuid, - &usp->sem_perm.cuid); - err2 |= __put_user (s.sem_perm.cgid, - &usp->sem_perm.cgid); - err2 |= __put_user (s.sem_perm.mode, - &usp->sem_perm.mode); - err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq); - err2 |= __put_user (s.sem_otime, &usp->sem_otime); - err2 |= __put_user (s.sem_ctime, &usp->sem_ctime); - err2 |= __put_user (s.sem_nsems, &usp->sem_nsems); + + if (third & IPC_64) { + struct semid64_ds32 *usp64 = (struct semid64_ds32 *) A(pad); + + if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) { + err = -EFAULT; + break; + } + err2 = __put_user(s.sem_perm.key, &usp64->sem_perm.key); + err2 |= __put_user(s.sem_perm.uid, &usp64->sem_perm.uid); + err2 |= __put_user(s.sem_perm.gid, &usp64->sem_perm.gid); + err2 |= __put_user(s.sem_perm.cuid, &usp64->sem_perm.cuid); + err2 |= __put_user(s.sem_perm.cgid, &usp64->sem_perm.cgid); + err2 |= __put_user(s.sem_perm.mode, &usp64->sem_perm.mode); + err2 |= __put_user(s.sem_perm.seq, &usp64->sem_perm.seq); + err2 |= __put_user(s.sem_otime, &usp64->sem_otime); + err2 |= __put_user(s.sem_ctime, &usp64->sem_ctime); + err2 |= __put_user(s.sem_nsems, &usp64->sem_nsems); + } else { + struct semid_ds32 *usp32 = (struct semid_ds32 *) A(pad); + + if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) { + err = -EFAULT; + break; + } + err2 = __put_user(s.sem_perm.key, &usp32->sem_perm.key); + err2 |= __put_user(s.sem_perm.uid, &usp32->sem_perm.uid); + err2 |= __put_user(s.sem_perm.gid, &usp32->sem_perm.gid); + err2 |= __put_user(s.sem_perm.cuid, &usp32->sem_perm.cuid); + err2 |= __put_user(s.sem_perm.cgid, &usp32->sem_perm.cgid); + err2 |= __put_user(s.sem_perm.mode, &usp32->sem_perm.mode); + err2 |= __put_user(s.sem_perm.seq, &usp32->sem_perm.seq); + err2 |= __put_user(s.sem_otime, &usp32->sem_otime); + err2 |= __put_user(s.sem_ctime, &usp32->sem_ctime); + err2 |= __put_user(s.sem_nsems, &usp32->sem_nsems); + } if (err2) err = -EFAULT; break; + default: + err = - EINVAL; + break; } return err; } +static int do_sys32_msgsnd (int first, int second, int third, void *uptr) { struct msgbuf32 *up = (struct msgbuf32 *)uptr; @@ -1886,7 +2023,8 @@ int err = -EFAULT, err2; struct shmid_ds s; struct shmid64_ds s64; - struct shmid_ds32 *up = (struct shmid_ds32 *)uptr; + struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr; + struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr; mm_segment_t old_fs; struct shm_info32 { int used_ids; @@ -1895,18 +2033,24 @@ } *uip = (struct shm_info32 *)uptr; struct shm_info si; - switch (second) { - + switch (second & ~IPC_64) { case IPC_INFO: + second = IPC_INFO; /* So that we don't have to translate it */ case IPC_RMID: case SHM_LOCK: case SHM_UNLOCK: err = sys_shmctl (first, second, (struct shmid_ds *)uptr); break; case IPC_SET: - err = get_user (s.shm_perm.uid, &up->shm_perm.uid); - err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid); - err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode); + if (second & IPC_64) { + err = get_user(s.shm_perm.uid, &up64->shm_perm.uid); + err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid); + err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode); + } else { + err = get_user(s.shm_perm.uid, &up32->shm_perm.uid); + err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid); + err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode); + } if (err) break; old_fs = get_fs (); @@ -1923,23 +2067,45 @@ set_fs (old_fs); if (err < 0) break; - err2 = put_user (s64.shm_perm.key, &up->shm_perm.key); - err2 |= __put_user (s64.shm_perm.uid, &up->shm_perm.uid); - err2 |= __put_user (s64.shm_perm.gid, &up->shm_perm.gid); - err2 |= __put_user (s64.shm_perm.cuid, - &up->shm_perm.cuid); - err2 |= __put_user (s64.shm_perm.cgid, - &up->shm_perm.cgid); - err2 |= __put_user (s64.shm_perm.mode, - &up->shm_perm.mode); - err2 |= __put_user (s64.shm_perm.seq, &up->shm_perm.seq); - err2 |= __put_user (s64.shm_atime, &up->shm_atime); - err2 |= __put_user (s64.shm_dtime, &up->shm_dtime); - err2 |= __put_user (s64.shm_ctime, &up->shm_ctime); - err2 |= __put_user (s64.shm_segsz, &up->shm_segsz); - err2 |= __put_user (s64.shm_nattch, &up->shm_nattch); - err2 |= __put_user (s64.shm_cpid, &up->shm_cpid); - err2 |= __put_user (s64.shm_lpid, &up->shm_lpid); + if (second & IPC_64) { + if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) { + err = -EFAULT; + break; + } + err2 = __put_user(s64.shm_perm.key, &up64->shm_perm.key); + err2 |= __put_user(s64.shm_perm.uid, &up64->shm_perm.uid); + err2 |= __put_user(s64.shm_perm.gid, &up64->shm_perm.gid); + err2 |= __put_user(s64.shm_perm.cuid, &up64->shm_perm.cuid); + err2 |= __put_user(s64.shm_perm.cgid, &up64->shm_perm.cgid); + err2 |= __put_user(s64.shm_perm.mode, &up64->shm_perm.mode); + err2 |= __put_user(s64.shm_perm.seq, &up64->shm_perm.seq); + err2 |= __put_user(s64.shm_atime, &up64->shm_atime); + err2 |= __put_user(s64.shm_dtime, &up64->shm_dtime); + err2 |= __put_user(s64.shm_ctime, &up64->shm_ctime); + err2 |= __put_user(s64.shm_segsz, &up64->shm_segsz); + err2 |= __put_user(s64.shm_nattch, &up64->shm_nattch); + err2 |= __put_user(s64.shm_cpid, &up64->shm_cpid); + err2 |= __put_user(s64.shm_lpid, &up64->shm_lpid); + } else { + if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) { + err = -EFAULT; + break; + } + err2 = __put_user(s64.shm_perm.key, &up32->shm_perm.key); + err2 |= __put_user(s64.shm_perm.uid, &up32->shm_perm.uid); + err2 |= __put_user(s64.shm_perm.gid, &up32->shm_perm.gid); + err2 |= __put_user(s64.shm_perm.cuid, &up32->shm_perm.cuid); + err2 |= __put_user(s64.shm_perm.cgid, &up32->shm_perm.cgid); + err2 |= __put_user(s64.shm_perm.mode, &up32->shm_perm.mode); + err2 |= __put_user(s64.shm_perm.seq, &up32->shm_perm.seq); + err2 |= __put_user(s64.shm_atime, &up32->shm_atime); + err2 |= __put_user(s64.shm_dtime, &up32->shm_dtime); + err2 |= __put_user(s64.shm_ctime, &up32->shm_ctime); + err2 |= __put_user(s64.shm_segsz, &up32->shm_segsz); + err2 |= __put_user(s64.shm_nattch, &up32->shm_nattch); + err2 |= __put_user(s64.shm_cpid, &up32->shm_cpid); + err2 |= __put_user(s64.shm_lpid, &up32->shm_lpid); + } if (err2) err = -EFAULT; break; @@ -1963,7 +2129,11 @@ err = -EFAULT; break; + default: + err = -ENOSYS; + break; } + return err; } @@ -2037,83 +2207,55 @@ unsigned int __unused[4]; }; -asmlinkage long sys32_sysctl(struct sysctl_args32 *uargs32) -{ - struct __sysctl_args kargs; - struct sysctl_args32 kargs32; - mm_segment_t old_fs; - int name[CTL_MAXNAME]; - size_t oldlen[1]; - int err, ret; - - ret = -EFAULT; - - memset(&kargs, 0, sizeof (kargs)); - - err = get_user(kargs32.name, &uargs32->name); - err |= __get_user(kargs32.nlen, &uargs32->nlen); - err |= __get_user(kargs32.oldval, &uargs32->oldval); - err |= __get_user(kargs32.oldlenp, &uargs32->oldlenp); - err |= __get_user(kargs32.newval, &uargs32->newval); - err |= __get_user(kargs32.newlen, &uargs32->newlen); - if (err) - goto out; +#ifdef CONFIG_SYSCTL - if (kargs32.nlen == 0 || kargs32.nlen >= CTL_MAXNAME) { - ret = -ENOTDIR; - goto out; - } +asmlinkage long sys32_sysctl(struct sysctl_args32 *args) +{ + struct sysctl_args32 tmp; + int error; + size_t oldlen, *oldlenp = NULL; + unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7; - kargs.name = name; - kargs.nlen = kargs32.nlen; - if (copy_from_user(kargs.name, (int *)A(kargs32.name), - kargs32.nlen * sizeof(name) / sizeof(name[0]))) - goto out; + if (copy_from_user(&tmp, args, sizeof(tmp))) + return -EFAULT; - if (kargs32.oldval) { - if (!kargs32.oldlenp || get_user(oldlen[0], - (int *)A(kargs32.oldlenp))) + if (tmp.oldval && tmp.oldlenp) { + /* Duh, this is ugly and might not work if sysctl_args + is in read-only memory, but do_sysctl does indirectly + a lot of uaccess in both directions and we'd have to + basically copy the whole sysctl.c here, and + glibc's __sysctl uses rw memory for the structure + anyway. */ + if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) || + put_user(oldlen, (size_t *)addr)) return -EFAULT; - kargs.oldlenp = oldlen; - kargs.oldval = kmalloc(oldlen[0], GFP_KERNEL); - if (!kargs.oldval) { - ret = -ENOMEM; - goto out; - } + oldlenp = (size_t *)addr; } - if (kargs32.newval && kargs32.newlen) { - kargs.newval = kmalloc(kargs32.newlen, GFP_KERNEL); - if (!kargs.newval) { - ret = -ENOMEM; - goto out; + lock_kernel(); + error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval), + oldlenp, (void *)A(tmp.newval), tmp.newlen); + unlock_kernel(); + if (oldlenp) { + if (!error) { + if (get_user(oldlen, (size_t *)addr) || + put_user(oldlen, (u32 *)A(tmp.oldlenp))) + error = -EFAULT; } - if (copy_from_user(kargs.newval, (int *)A(kargs32.newval), - kargs32.newlen)) - goto out; + copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); } + return error; +} - old_fs = get_fs(); set_fs (KERNEL_DS); - ret = sys_sysctl(&kargs); - set_fs (old_fs); - - if (ret) - goto out; +#else /* CONFIG_SYSCTL */ - if (kargs.oldval) { - if (put_user(oldlen[0], (int *)A(kargs32.oldlenp)) || - copy_to_user((int *)A(kargs32.oldval), kargs.oldval, - oldlen[0])) - ret = -EFAULT; - } -out: - if (kargs.oldval) - kfree(kargs.oldval); - if (kargs.newval) - kfree(kargs.newval); - return ret; +asmlinkage long sys32_sysctl(struct sysctl_args32 *args) +{ + return -ENOSYS; } +#endif /* CONFIG_SYSCTL */ + asmlinkage long sys32_newuname(struct new_utsname * name) { int ret = 0; @@ -2219,7 +2361,7 @@ /* * Declare the 32-bit version of the msghdr */ - + struct msghdr32 { unsigned int msg_name; /* Socket name */ int msg_namelen; /* Length of name */ @@ -2230,74 +2372,132 @@ unsigned msg_flags; }; -static inline int -shape_msg(struct msghdr *mp, struct msghdr32 *mp32) +struct cmsghdr32 { + __kernel_size_t32 cmsg_len; + int cmsg_level; + int cmsg_type; +}; + +/* Bleech... */ +#define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen)) +#define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen)) + +#define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) ) + +#define CMSG32_DATA(cmsg) ((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32)))) +#define CMSG32_SPACE(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len)) +#define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len)) + +#define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? \ + (struct cmsghdr32 *)(ctl) : \ + (struct cmsghdr32 *)NULL) +#define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen) + +__inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size, + struct cmsghdr32 *__cmsg, int __cmsg_len) { - int ret; - unsigned int i; + struct cmsghdr32 * __ptr; - if (!access_ok(VERIFY_READ, mp32, sizeof(*mp32))) - return(-EFAULT); - ret = __get_user(i, &mp32->msg_name); - mp->msg_name = (void *)A(i); - ret |= __get_user(mp->msg_namelen, &mp32->msg_namelen); - ret |= __get_user(i, &mp32->msg_iov); - mp->msg_iov = (struct iovec *)A(i); - ret |= __get_user(mp->msg_iovlen, &mp32->msg_iovlen); - ret |= __get_user(i, &mp32->msg_control); - mp->msg_control = (void *)A(i); - ret |= __get_user(mp->msg_controllen, &mp32->msg_controllen); - ret |= __get_user(mp->msg_flags, &mp32->msg_flags); - return(ret ? -EFAULT : 0); + __ptr = (struct cmsghdr32 *)(((unsigned char *) __cmsg) + + CMSG32_ALIGN(__cmsg_len)); + if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size) + return NULL; + + return __ptr; } -/* - * Verify & re-shape IA32 iovec. The caller must ensure that the - * iovec is big enough to hold the re-shaped message iovec. - * - * Save time not doing verify_area. copy_*_user will make this work - * in any case. - * - * Don't need to check the total size for overflow (cf net/core/iovec.c), - * 32-bit sizes can't overflow a 64-bit count. - */ +__inline__ struct cmsghdr32 *cmsg32_nxthdr (struct msghdr *__msg, + struct cmsghdr32 *__cmsg, + int __cmsg_len) +{ + return __cmsg32_nxthdr(__msg->msg_control, __msg->msg_controllen, + __cmsg, __cmsg_len); +} -static inline int -verify_iovec32(struct msghdr *m, struct iovec *iov, char *address, int mode) +static inline int iov_from_user32_to_kern(struct iovec *kiov, + struct iovec32 *uiov32, + int niov) { - int size, err, ct; - struct iovec32 *iov32; + int tot_len = 0; - if(m->msg_namelen) - { - if(mode==VERIFY_READ) - { - err=move_addr_to_kernel(m->msg_name, m->msg_namelen, address); - if(err<0) - goto out; + while(niov > 0) { + u32 len, buf; + + if(get_user(len, &uiov32->iov_len) || + get_user(buf, &uiov32->iov_base)) { + tot_len = -EFAULT; + break; } + tot_len += len; + kiov->iov_base = (void *)AA(buf); + kiov->iov_len = (__kernel_size_t) len; + uiov32++; + kiov++; + niov--; + } + return tot_len; +} - m->msg_name = address; - } else - m->msg_name = NULL; +static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg, + struct msghdr32 *umsg) +{ + u32 tmp1, tmp2, tmp3; + int err; - err = -EFAULT; - size = m->msg_iovlen * sizeof(struct iovec32); - if (copy_from_user(iov, m->msg_iov, size)) - goto out; - m->msg_iov=iov; + err = get_user(tmp1, &umsg->msg_name); + err |= __get_user(tmp2, &umsg->msg_iov); + err |= __get_user(tmp3, &umsg->msg_control); + if (err) + return -EFAULT; - err = 0; - iov32 = (struct iovec32 *)iov; - for (ct = m->msg_iovlen; ct-- > 0; ) { - iov[ct].iov_len = (__kernel_size_t)iov32[ct].iov_len; - iov[ct].iov_base = (void *) A(iov32[ct].iov_base); - err += iov[ct].iov_len; - } -out: + kmsg->msg_name = (void *)AA(tmp1); + kmsg->msg_iov = (struct iovec *)AA(tmp2); + kmsg->msg_control = (void *)AA(tmp3); + + err = get_user(kmsg->msg_namelen, &umsg->msg_namelen); + err |= get_user(kmsg->msg_iovlen, &umsg->msg_iovlen); + err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen); + err |= get_user(kmsg->msg_flags, &umsg->msg_flags); + return err; } +/* I've named the args so it is easy to tell whose space the pointers are in. */ +static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov, + char *kern_address, int mode) +{ + int tot_len; + + if(kern_msg->msg_namelen) { + if(mode==VERIFY_READ) { + int err = move_addr_to_kernel(kern_msg->msg_name, + kern_msg->msg_namelen, + kern_address); + if(err < 0) + return err; + } + kern_msg->msg_name = kern_address; + } else + kern_msg->msg_name = NULL; + + if(kern_msg->msg_iovlen > UIO_FASTIOV) { + kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec), + GFP_KERNEL); + if(!kern_iov) + return -ENOMEM; + } + + tot_len = iov_from_user32_to_kern(kern_iov, + (struct iovec32 *)kern_msg->msg_iov, + kern_msg->msg_iovlen); + if(tot_len >= 0) + kern_msg->msg_iov = kern_iov; + else if(kern_msg->msg_iovlen > UIO_FASTIOV) + kfree(kern_iov); + + return tot_len; +} + extern __inline__ void sockfd_put(struct socket *sock) { @@ -2305,177 +2505,406 @@ } /* XXX This really belongs in some header file... -DaveM */ -#define MAX_SOCK_ADDR 128 /* 108 for Unix domain - +#define MAX_SOCK_ADDR 128 /* 108 for Unix domain - 16 for IP, 16 for IPX, 24 for IPv6, about 80 for AX.25 */ extern struct socket *sockfd_lookup(int fd, int *err); -/* - * BSD sendmsg interface +/* There is a lot of hair here because the alignment rules (and + * thus placement) of cmsg headers and length are different for + * 32-bit apps. -DaveM */ - -int sys32_sendmsg(int fd, struct msghdr32 *msg, unsigned flags) +static int cmsghdr_from_user32_to_kern(struct msghdr *kmsg, + unsigned char *stackbuf, int stackbuf_size) { - struct socket *sock; - char address[MAX_SOCK_ADDR]; - struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; - unsigned char ctl[sizeof(struct cmsghdr) + 20]; /* 20 is size of ipv6_pktinfo */ - unsigned char *ctl_buf = ctl; - struct msghdr msg_sys; - int err, ctl_len, iov_size, total_len; + struct cmsghdr32 *ucmsg; + struct cmsghdr *kcmsg, *kcmsg_base; + __kernel_size_t32 ucmlen; + __kernel_size_t kcmlen, tmp; + + kcmlen = 0; + kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf; + ucmsg = CMSG32_FIRSTHDR(kmsg); + while(ucmsg != NULL) { + if(get_user(ucmlen, &ucmsg->cmsg_len)) + return -EFAULT; - err = -EFAULT; - if (shape_msg(&msg_sys, msg)) - goto out; + /* Catch bogons. */ + if(CMSG32_ALIGN(ucmlen) < + CMSG32_ALIGN(sizeof(struct cmsghdr32))) + return -ENOBUFS; + if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control) + + ucmlen) > kmsg->msg_controllen) + return -EINVAL; + + tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) + + CMSG_ALIGN(sizeof(struct cmsghdr))); + kcmlen += tmp; + ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen); + } + if(kcmlen == 0) + return -EINVAL; - sock = sockfd_lookup(fd, &err); - if (!sock) - goto out; + /* The kcmlen holds the 64-bit version of the control length. + * It may not be modified as we do not stick it into the kmsg + * until we have successfully copied over all of the data + * from the user. + */ + if(kcmlen > stackbuf_size) + kcmsg_base = kcmsg = kmalloc(kcmlen, GFP_KERNEL); + if(kcmsg == NULL) + return -ENOBUFS; + + /* Now copy them over neatly. */ + memset(kcmsg, 0, kcmlen); + ucmsg = CMSG32_FIRSTHDR(kmsg); + while(ucmsg != NULL) { + __get_user(ucmlen, &ucmsg->cmsg_len); + tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) + + CMSG_ALIGN(sizeof(struct cmsghdr))); + kcmsg->cmsg_len = tmp; + __get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level); + __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type); + + /* Copy over the data. */ + if(copy_from_user(CMSG_DATA(kcmsg), + CMSG32_DATA(ucmsg), + (ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))))) + goto out_free_efault; + + /* Advance. */ + kcmsg = (struct cmsghdr *)((char *)kcmsg + CMSG_ALIGN(tmp)); + ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen); + } + + /* Ok, looks like we made it. Hook it up and return success. */ + kmsg->msg_control = kcmsg_base; + kmsg->msg_controllen = kcmlen; + return 0; - /* do not move before msg_sys is valid */ - err = -EINVAL; - if (msg_sys.msg_iovlen > UIO_MAXIOV) - goto out_put; +out_free_efault: + if(kcmsg_base != (struct cmsghdr *)stackbuf) + kfree(kcmsg_base); + return -EFAULT; +} - /* Check whether to allocate the iovec area*/ - err = -ENOMEM; - iov_size = msg_sys.msg_iovlen * sizeof(struct iovec32); - if (msg_sys.msg_iovlen > UIO_FASTIOV) { - iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL); - if (!iov) - goto out_put; +static void put_cmsg32(struct msghdr *kmsg, int level, int type, + int len, void *data) +{ + struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control; + struct cmsghdr32 cmhdr; + int cmlen = CMSG32_LEN(len); + + if(cm == NULL || kmsg->msg_controllen < sizeof(*cm)) { + kmsg->msg_flags |= MSG_CTRUNC; + return; } - /* This will also move the address data into kernel space */ - err = verify_iovec32(&msg_sys, iov, address, VERIFY_READ); - if (err < 0) - goto out_freeiov; - total_len = err; + if(kmsg->msg_controllen < cmlen) { + kmsg->msg_flags |= MSG_CTRUNC; + cmlen = kmsg->msg_controllen; + } + cmhdr.cmsg_level = level; + cmhdr.cmsg_type = type; + cmhdr.cmsg_len = cmlen; - err = -ENOBUFS; + if(copy_to_user(cm, &cmhdr, sizeof cmhdr)) + return; + if(copy_to_user(CMSG32_DATA(cm), data, cmlen - sizeof(struct cmsghdr32))) + return; + cmlen = CMSG32_SPACE(len); + kmsg->msg_control += cmlen; + kmsg->msg_controllen -= cmlen; +} + +static void scm_detach_fds32(struct msghdr *kmsg, struct scm_cookie *scm) +{ + struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control; + int fdmax = (kmsg->msg_controllen - sizeof(struct cmsghdr32)) / sizeof(int); + int fdnum = scm->fp->count; + struct file **fp = scm->fp->fp; + int *cmfptr; + int err = 0, i; + + if (fdnum < fdmax) + fdmax = fdnum; + + for (i = 0, cmfptr = (int *) CMSG32_DATA(cm); i < fdmax; i++, cmfptr++) { + int new_fd; + err = get_unused_fd(); + if (err < 0) + break; + new_fd = err; + err = put_user(new_fd, cmfptr); + if (err) { + put_unused_fd(new_fd); + break; + } + /* Bump the usage count and install the file. */ + get_file(fp[i]); + fd_install(new_fd, fp[i]); + } - if (msg_sys.msg_controllen > INT_MAX) - goto out_freeiov; - ctl_len = msg_sys.msg_controllen; - if (ctl_len) - { - if (ctl_len > sizeof(ctl)) - { - err = -ENOBUFS; - ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL); - if (ctl_buf == NULL) - goto out_freeiov; + if (i > 0) { + int cmlen = CMSG32_LEN(i * sizeof(int)); + if (!err) + err = put_user(SOL_SOCKET, &cm->cmsg_level); + if (!err) + err = put_user(SCM_RIGHTS, &cm->cmsg_type); + if (!err) + err = put_user(cmlen, &cm->cmsg_len); + if (!err) { + cmlen = CMSG32_SPACE(i * sizeof(int)); + kmsg->msg_control += cmlen; + kmsg->msg_controllen -= cmlen; } - err = -EFAULT; - if (copy_from_user(ctl_buf, msg_sys.msg_control, ctl_len)) - goto out_freectl; - msg_sys.msg_control = ctl_buf; - } - msg_sys.msg_flags = flags; - - if (sock->file->f_flags & O_NONBLOCK) - msg_sys.msg_flags |= MSG_DONTWAIT; - err = sock_sendmsg(sock, &msg_sys, total_len); - -out_freectl: - if (ctl_buf != ctl) - sock_kfree_s(sock->sk, ctl_buf, ctl_len); -out_freeiov: - if (iov != iovstack) - sock_kfree_s(sock->sk, iov, iov_size); -out_put: - sockfd_put(sock); -out: - return err; + } + if (i < fdnum) + kmsg->msg_flags |= MSG_CTRUNC; + + /* + * All of the files that fit in the message have had their + * usage counts incremented, so we just free the list. + */ + __scm_destroy(scm); } -/* - * BSD recvmsg interface +/* In these cases we (currently) can just copy to data over verbatim + * because all CMSGs created by the kernel have well defined types which + * have the same layout in both the 32-bit and 64-bit API. One must add + * some special cased conversions here if we start sending control messages + * with incompatible types. + * + * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after + * we do our work. The remaining cases are: + * + * SOL_IP IP_PKTINFO struct in_pktinfo 32-bit clean + * IP_TTL int 32-bit clean + * IP_TOS __u8 32-bit clean + * IP_RECVOPTS variable length 32-bit clean + * IP_RETOPTS variable length 32-bit clean + * (these last two are clean because the types are defined + * by the IPv4 protocol) + * IP_RECVERR struct sock_extended_err + + * struct sockaddr_in 32-bit clean + * SOL_IPV6 IPV6_RECVERR struct sock_extended_err + + * struct sockaddr_in6 32-bit clean + * IPV6_PKTINFO struct in6_pktinfo 32-bit clean + * IPV6_HOPLIMIT int 32-bit clean + * IPV6_FLOWINFO u32 32-bit clean + * IPV6_HOPOPTS ipv6 hop exthdr 32-bit clean + * IPV6_DSTOPTS ipv6 dst exthdr(s) 32-bit clean + * IPV6_RTHDR ipv6 routing exthdr 32-bit clean + * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean */ - -int -sys32_recvmsg (int fd, struct msghdr32 *msg, unsigned int flags) +static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr) { - struct socket *sock; - struct iovec iovstack[UIO_FASTIOV]; - struct iovec *iov=iovstack; - struct msghdr msg_sys; - unsigned long cmsg_ptr; - int err, iov_size, total_len, len; + unsigned char *workbuf, *wp; + unsigned long bufsz, space_avail; + struct cmsghdr *ucmsg; + + bufsz = ((unsigned long)kmsg->msg_control) - orig_cmsg_uptr; + space_avail = kmsg->msg_controllen + bufsz; + wp = workbuf = kmalloc(bufsz, GFP_KERNEL); + if(workbuf == NULL) + goto fail; + + /* To make this more sane we assume the kernel sends back properly + * formatted control messages. Because of how the kernel will truncate + * the cmsg_len for MSG_TRUNC cases, we need not check that case either. + */ + ucmsg = (struct cmsghdr *) orig_cmsg_uptr; + while(((unsigned long)ucmsg) <= + (((unsigned long)kmsg->msg_control) - sizeof(struct cmsghdr))) { + struct cmsghdr32 *kcmsg32 = (struct cmsghdr32 *) wp; + int clen64, clen32; + + /* UCMSG is the 64-bit format CMSG entry in user-space. + * KCMSG32 is within the kernel space temporary buffer + * we use to convert into a 32-bit style CMSG. + */ + __get_user(kcmsg32->cmsg_len, &ucmsg->cmsg_len); + __get_user(kcmsg32->cmsg_level, &ucmsg->cmsg_level); + __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type); + + clen64 = kcmsg32->cmsg_len; + copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg), + clen64 - CMSG_ALIGN(sizeof(*ucmsg))); + clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) + + CMSG32_ALIGN(sizeof(struct cmsghdr32))); + kcmsg32->cmsg_len = clen32; + + ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64)); + wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32)); + } + + /* Copy back fixed up data, and adjust pointers. */ + bufsz = (wp - workbuf); + copy_to_user((void *)orig_cmsg_uptr, workbuf, bufsz); + + kmsg->msg_control = (struct cmsghdr *) + (((char *)orig_cmsg_uptr) + bufsz); + kmsg->msg_controllen = space_avail - bufsz; - /* kernel mode address */ - char addr[MAX_SOCK_ADDR]; + kfree(workbuf); + return; - /* user mode address pointers */ - struct sockaddr *uaddr; - int *uaddr_len; +fail: + /* If we leave the 64-bit format CMSG chunks in there, + * the application could get confused and crash. So to + * ensure greater recovery, we report no CMSGs. + */ + kmsg->msg_controllen += bufsz; + kmsg->msg_control = (void *) orig_cmsg_uptr; +} - err=-EFAULT; - if (shape_msg(&msg_sys, msg)) - goto out; +asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags) +{ + struct socket *sock; + char address[MAX_SOCK_ADDR]; + struct iovec iov[UIO_FASTIOV]; + unsigned char ctl[sizeof(struct cmsghdr) + 20]; + unsigned char *ctl_buf = ctl; + struct msghdr kern_msg; + int err, total_len; - sock = sockfd_lookup(fd, &err); - if (!sock) + if(msghdr_from_user32_to_kern(&kern_msg, user_msg)) + return -EFAULT; + if(kern_msg.msg_iovlen > UIO_MAXIOV) + return -EINVAL; + err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ); + if (err < 0) goto out; + total_len = err; - err = -EINVAL; - if (msg_sys.msg_iovlen > UIO_MAXIOV) - goto out_put; + if(kern_msg.msg_controllen) { + err = cmsghdr_from_user32_to_kern(&kern_msg, ctl, sizeof(ctl)); + if(err) + goto out_freeiov; + ctl_buf = kern_msg.msg_control; + } + kern_msg.msg_flags = user_flags; - /* Check whether to allocate the iovec area*/ - err = -ENOMEM; - iov_size = msg_sys.msg_iovlen * sizeof(struct iovec); - if (msg_sys.msg_iovlen > UIO_FASTIOV) { - iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL); - if (!iov) - goto out_put; + sock = sockfd_lookup(fd, &err); + if (sock != NULL) { + if (sock->file->f_flags & O_NONBLOCK) + kern_msg.msg_flags |= MSG_DONTWAIT; + err = sock_sendmsg(sock, &kern_msg, total_len); + sockfd_put(sock); } - /* - * Save the user-mode address (verify_iovec will change the - * kernel msghdr to use the kernel address space) - */ + /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */ + if(ctl_buf != ctl) + kfree(ctl_buf); +out_freeiov: + if(kern_msg.msg_iov != iov) + kfree(kern_msg.msg_iov); +out: + return err; +} - uaddr = msg_sys.msg_name; - uaddr_len = &msg->msg_namelen; - err = verify_iovec32(&msg_sys, iov, addr, VERIFY_WRITE); - if (err < 0) - goto out_freeiov; - total_len=err; +asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags) +{ + struct iovec iovstack[UIO_FASTIOV]; + struct msghdr kern_msg; + char addr[MAX_SOCK_ADDR]; + struct socket *sock; + struct iovec *iov = iovstack; + struct sockaddr *uaddr; + int *uaddr_len; + unsigned long cmsg_ptr; + int err, total_len, len = 0; - cmsg_ptr = (unsigned long)msg_sys.msg_control; - msg_sys.msg_flags = 0; + if(msghdr_from_user32_to_kern(&kern_msg, user_msg)) + return -EFAULT; + if(kern_msg.msg_iovlen > UIO_MAXIOV) + return -EINVAL; - if (sock->file->f_flags & O_NONBLOCK) - flags |= MSG_DONTWAIT; - err = sock_recvmsg(sock, &msg_sys, total_len, flags); + uaddr = kern_msg.msg_name; + uaddr_len = &user_msg->msg_namelen; + err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE); if (err < 0) - goto out_freeiov; - len = err; + goto out; + total_len = err; - if (uaddr != NULL) { - err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len); - if (err < 0) - goto out_freeiov; + cmsg_ptr = (unsigned long) kern_msg.msg_control; + kern_msg.msg_flags = 0; + + sock = sockfd_lookup(fd, &err); + if (sock != NULL) { + struct scm_cookie scm; + + if (sock->file->f_flags & O_NONBLOCK) + user_flags |= MSG_DONTWAIT; + memset(&scm, 0, sizeof(scm)); + err = sock->ops->recvmsg(sock, &kern_msg, total_len, + user_flags, &scm); + if(err >= 0) { + len = err; + if(!kern_msg.msg_control) { + if(sock->passcred || scm.fp) + kern_msg.msg_flags |= MSG_CTRUNC; + if(scm.fp) + __scm_destroy(&scm); + } else { + /* If recvmsg processing itself placed some + * control messages into user space, it's is + * using 64-bit CMSG processing, so we need + * to fix it up before we tack on more stuff. + */ + if((unsigned long) kern_msg.msg_control != cmsg_ptr) + cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr); + + /* Wheee... */ + if(sock->passcred) + put_cmsg32(&kern_msg, + SOL_SOCKET, SCM_CREDENTIALS, + sizeof(scm.creds), &scm.creds); + if(scm.fp != NULL) + scm_detach_fds32(&kern_msg, &scm); + } + } + sockfd_put(sock); } - err = __put_user(msg_sys.msg_flags, &msg->msg_flags); - if (err) - goto out_freeiov; - err = __put_user((unsigned long)msg_sys.msg_control-cmsg_ptr, - &msg->msg_controllen); - if (err) - goto out_freeiov; - err = len; -out_freeiov: - if (iov != iovstack) - sock_kfree_s(sock->sk, iov, iov_size); -out_put: - sockfd_put(sock); + if(uaddr != NULL && kern_msg.msg_namelen && err >= 0) + err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len); + if(cmsg_ptr != 0 && err >= 0) { + unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control); + __kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr); + err |= __put_user(uclen, &user_msg->msg_controllen); + } + if(err >= 0) + err = __put_user(kern_msg.msg_flags, &user_msg->msg_flags); + if(kern_msg.msg_iov != iov) + kfree(kern_msg.msg_iov); out: - return err; + if(err < 0) + return err; + return len; +} + +extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count); + +asmlinkage int sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count) +{ + mm_segment_t old_fs = get_fs(); + int ret; + off_t of; + + if (offset && get_user(of, offset)) + return -EFAULT; + + set_fs(KERNEL_DS); + ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count); + set_fs(old_fs); + + if (offset && put_user(of, offset)) + return -EFAULT; + + return ret; } asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count); @@ -2520,7 +2949,37 @@ return i; } -#else +#else /* CONFIG_MODULES */ + +asmlinkage unsigned long +sys32_create_module(const char *name_user, size_t size) +{ + return -ENOSYS; +} + +asmlinkage int +sys32_init_module(const char *name_user, struct module *mod_user) +{ + return -ENOSYS; +} + +asmlinkage int +sys32_delete_module(const char *name_user) +{ + return -ENOSYS; +} + +asmlinkage int +sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize, + size_t *ret) +{ + /* Let the program know about the new interface. Not that + it'll do them much good. */ + if (which == 0) + return 0; + + return -ENOSYS; +} asmlinkage long sys32_get_kernel_syms(struct kernel_sym *table) @@ -2528,4 +2987,4 @@ return -ENOSYS; } -#endif +#endif /* CONFIG_MODULES */ diff -urN linux-2.4.21-bk37/arch/mips64/kernel/mips64_ksyms.c linux-2.4.21-bk38/arch/mips64/kernel/mips64_ksyms.c --- linux-2.4.21-bk37/arch/mips64/kernel/mips64_ksyms.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/mips64_ksyms.c 2003-08-24 02:55:58.000000000 -0700 @@ -19,7 +19,9 @@ #include #include +#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE) #include +#endif #include #include #include @@ -79,17 +81,6 @@ /* Networking helper routines. */ EXPORT_SYMBOL(csum_partial_copy); -/* - * Functions to control caches. - */ -EXPORT_SYMBOL(_flush_page_to_ram); -EXPORT_SYMBOL(_flush_cache_l1); - -#ifdef CONFIG_NONCOHERENT_IO -EXPORT_SYMBOL(_dma_cache_wback_inv); -EXPORT_SYMBOL(_dma_cache_inv); -#endif - EXPORT_SYMBOL(invalid_pte_table); /* diff -urN linux-2.4.21-bk37/arch/mips64/kernel/pci-dma.c linux-2.4.21-bk38/arch/mips64/kernel/pci-dma.c --- linux-2.4.21-bk37/arch/mips64/kernel/pci-dma.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/pci-dma.c 2003-08-24 02:55:58.000000000 -0700 @@ -21,6 +21,7 @@ { void *ret; int gfp = GFP_ATOMIC; + struct pci_bus *bus = NULL; #ifdef CONFIG_ISA if (hwdev == NULL || hwdev->dma_mask != 0xffffffff) @@ -30,7 +31,9 @@ if (ret != NULL) { memset(ret, 0, size); - *dma_handle = bus_to_baddr(hwdev->bus->number, __pa(ret)); + if (hwdev) + bus = hwdev->bus; + *dma_handle = bus_to_baddr(bus, __pa(ret)); #ifdef CONFIG_NONCOHERENT_IO dma_cache_wback_inv((unsigned long) ret, size); ret = UNCAC_ADDR(ret); diff -urN linux-2.4.21-bk37/arch/mips64/kernel/proc.c linux-2.4.21-bk38/arch/mips64/kernel/proc.c --- linux-2.4.21-bk37/arch/mips64/kernel/proc.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/proc.c 2003-08-24 02:55:58.000000000 -0700 @@ -17,10 +17,6 @@ unsigned int vced_count, vcei_count; -#ifndef CONFIG_CPU_HAS_LLSC -unsigned long ll_ops, sc_ops; -#endif - static const char *cpu_name[] = { [CPU_UNKNOWN] "unknown", [CPU_R2000] "R2000", @@ -66,21 +62,21 @@ [CPU_VR41XX] "NEC Vr41xx", [CPU_R5500] "R5500", [CPU_TX49XX] "TX49xx", - [CPU_TX39XX] "TX39xx", [CPU_20KC] "MIPS 20Kc", [CPU_VR4111] "NEC VR4111", [CPU_VR4121] "NEC VR4121", [CPU_VR4122] "NEC VR4122", [CPU_VR4131] "NEC VR4131", [CPU_VR4181] "NEC VR4181", - [CPU_VR4181A] "NEC VR4181A" + [CPU_VR4181A] "NEC VR4181A", + [CPU_SR71000] "Sandcraft SR71000" }; static int show_cpuinfo(struct seq_file *m, void *v) { - unsigned int version = mips_cpu.processor_id; - unsigned int fp_vers = mips_cpu.fpu_id; + unsigned int version = current_cpu_data.processor_id; + unsigned int fp_vers = current_cpu_data.fpu_id; unsigned long n = (unsigned long) v - 1; char fmt [64]; @@ -97,9 +93,9 @@ seq_printf(m, "processor\t\t: %ld\n", n); sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n", - (mips_cpu.options & MIPS_CPU_FPU) ? " FPU V%d.%d" : ""); - seq_printf(m, fmt, cpu_name[mips_cpu.cputype <= CPU_LAST ? - mips_cpu.cputype : CPU_UNKNOWN], + cpu_has_fpu ? " FPU V%d.%d" : ""); + seq_printf(m, fmt, cpu_name[current_cpu_data.cputype <= CPU_LAST ? + current_cpu_data.cputype : CPU_UNKNOWN], (version >> 4) & 0x0f, version & 0x0f, (fp_vers >> 4) & 0x0f, fp_vers & 0x0f); seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n", @@ -107,23 +103,18 @@ (loops_per_jiffy / (5000/HZ)) % 100); seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no"); seq_printf(m, "microsecond timers\t: %s\n", - (mips_cpu.options & MIPS_CPU_COUNTER) ? "yes" : "no"); - seq_printf(m, "tlb_entries\t\t: %d\n", mips_cpu.tlbsize); + cpu_has_counter ? "yes" : "no"); + seq_printf(m, "tlb_entries\t\t: %d\n", current_cpu_data.tlbsize); seq_printf(m, "extra interrupt vector\t: %s\n", - (mips_cpu.options & MIPS_CPU_DIVEC) ? "yes" : "no"); + cpu_has_divec ? "yes" : "no"); seq_printf(m, "hardware watchpoint\t: %s\n", - watch_available ? "yes" : "no"); + cpu_has_watch ? "yes" : "no"); sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", - (mips_cpu.options & MIPS_CPU_VCE) ? "%d" : "not available"); + cpu_has_vce ? "%d" : "not available"); seq_printf(m, fmt, 'D', vced_count); seq_printf(m, fmt, 'I', vcei_count); -#ifndef CONFIG_CPU_HAS_LLSC - seq_printf(m, "ll emulations\t\t: %lu\n", ll_ops); - seq_printf(m, "sc emulations\t\t: %lu\n", sc_ops); -#endif - return 0; } @@ -145,8 +136,8 @@ } struct seq_operations cpuinfo_op = { - start: c_start, - next: c_next, - stop: c_stop, - show: show_cpuinfo, + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = show_cpuinfo, }; diff -urN linux-2.4.21-bk37/arch/mips64/kernel/process.c linux-2.4.21-bk38/arch/mips64/kernel/process.c --- linux-2.4.21-bk37/arch/mips64/kernel/process.c 2003-06-13 07:51:31.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips64/kernel/process.c 2003-08-24 02:55:58.000000000 -0700 @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include @@ -30,6 +32,8 @@ #include #include #include +#include +#include ATTRIB_NORET void cpu_idle(void) { @@ -46,32 +50,30 @@ } } -struct task_struct *last_task_used_math = NULL; - asmlinkage void ret_from_fork(void); +void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) +{ + unsigned long status; + + /* New thread loses kernel privileges. */ + status = regs->cp0_status & ~(ST0_CU0|ST0_FR|ST0_KSU); + status |= KSU_USER; + status |= (current->thread.mflags & MF_32BIT_REGS) ? 0 : ST0_FR; + regs->cp0_status = status; + current->used_math = 0; + lose_fpu(); + regs->cp0_epc = pc; + regs->regs[29] = sp; + current->thread.current_ds = USER_DS; +} + void exit_thread(void) { - /* Forget lazy fpu state */ - if (IS_FPU_OWNER()) { - if (mips_cpu.options & MIPS_CPU_FPU) { - __enable_fpu(); - __asm__ __volatile__("cfc1\t$0,$31"); - } - CLEAR_FPU_OWNER(); - } } void flush_thread(void) { - /* Forget lazy fpu state */ - if (IS_FPU_OWNER()) { - if (mips_cpu.options & MIPS_CPU_FPU) { - __enable_fpu(); - __asm__ __volatile__("cfc1\t$0,$31"); - } - CLEAR_FPU_OWNER(); - } } int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, @@ -83,10 +85,10 @@ childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32; - if (IS_FPU_OWNER()) { - if (mips_cpu.options & MIPS_CPU_FPU) - save_fp(p); + if (is_fpu_owner()) { + save_fp(p); } + /* set up new TSS. */ childregs = (struct pt_regs *) childksp - 1; *childregs = *regs; @@ -106,12 +108,12 @@ p->thread.reg31 = (unsigned long) ret_from_fork; /* - * New tasks loose permission to use the fpu. This accelerates context - * switching for most programs since they don't use the fpu. + * New tasks lose permission to use the fpu. This accelerates context + * switching for most programs since they don't use the fpu. Most + * MIPS IV CPUs use ST0_CU3 as ST0_XX flag so we leave it unchanged. */ - p->thread.cp0_status = read_32bit_cp0_register(CP0_STATUS) & - ~(ST0_CU3|ST0_CU2|ST0_CU1|ST0_KSU); - childregs->cp0_status &= ~(ST0_CU3|ST0_CU2|ST0_CU1); + p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1|ST0_KSU); + childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); return 0; } @@ -119,33 +121,8 @@ /* Fill in the fpu structure for a core dump.. */ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r) { - /* We actually store the FPU info in the task->thread - * area. - */ - if (regs->cp0_status & ST0_CU1) { - memcpy(r, ¤t->thread.fpu, sizeof(current->thread.fpu)); - return 1; - } - - return 0; /* Task didn't use the fpu at all. */ -} - -/* Fill in the user structure for a core dump.. */ -void dump_thread(struct pt_regs *regs, struct user *dump) -{ - dump->magic = CMAGIC; - dump->start_code = current->mm->start_code; - dump->start_data = current->mm->start_data; - dump->start_stack = regs->regs[29] & ~(PAGE_SIZE - 1); - dump->u_tsize = (current->mm->end_code - dump->start_code) - >> PAGE_SHIFT; - dump->u_dsize = (current->mm->brk + (PAGE_SIZE - 1) - dump->start_data) - >> PAGE_SHIFT; - dump->u_ssize = (current->mm->start_stack - dump->start_stack + - PAGE_SIZE - 1) >> PAGE_SHIFT; - memcpy(&dump->regs[0], regs, sizeof(struct pt_regs)); - memcpy(&dump->regs[EF_SIZE/4], ¤t->thread.fpu, - sizeof(current->thread.fpu)); + memcpy(r, ¤t->thread.fpu, sizeof(current->thread.fpu)); + return 1; } /* @@ -156,25 +133,26 @@ int retval; __asm__ __volatile__( - "move\t$6, $sp\n\t" - "move\t$4, %5\n\t" - "li\t$2, %1\n\t" - "syscall\n\t" - "beq\t$6, $sp, 1f\n\t" - "move\t$4, %3\n\t" - "jalr\t%4\n\t" - "move\t$4, $2\n\t" - "li\t$2, %2\n\t" - "syscall\n" - "1:\tmove\t%0, $2" - :"=r" (retval) - :"i" (__NR_clone), "i" (__NR_exit), "r" (arg), "r" (fn), - "r" (flags | CLONE_VM) - - /* The called subroutine might have destroyed any of the - * at, result, argument or temporary registers ... */ + " move $6, $sp \n" + " move $4, %5 \n" + " li $2, %1 \n" + " syscall \n" + " beq $6, $sp, 1f \n" + " move $4, %3 \n" + " jalr %4 \n" + " move $4, $2 \n" + " li $2, %2 \n" + " syscall \n" + "1: move %0, $2 \n" + : "=r" (retval) + : "i" (__NR_clone), "i" (__NR_exit), "r" (arg), "r" (fn), + "r" (flags | CLONE_VM) + /* + * The called subroutine might have destroyed any of the + * at, result, argument or temporary registers ... + */ : "$2", "$3", "$4", "$5", "$6", "$7", "$8", - "$9","$10","$11","$12","$13","$14","$15","$24","$25"); + "$9","$10","$11","$12","$13","$14","$15","$24","$25","$31"); return retval; } @@ -187,6 +165,62 @@ #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) +struct mips_frame_info schedule_frame; +static struct mips_frame_info schedule_timeout_frame; +static struct mips_frame_info sleep_on_frame; +static struct mips_frame_info sleep_on_timeout_frame; +static struct mips_frame_info wait_for_completion_frame; +static int mips_frame_info_initialized; +static int __init get_frame_info(struct mips_frame_info *info, void *func) +{ + int i; + union mips_instruction *ip = (union mips_instruction *)func; + info->pc_offset = -1; + info->frame_offset = -1; + for (i = 0; i < 128; i++, ip++) { + /* if jal, jalr, jr, stop. */ + if (ip->j_format.opcode == jal_op || + (ip->r_format.opcode == spec_op && + (ip->r_format.func == jalr_op || + ip->r_format.func == jr_op))) + break; + if (ip->i_format.opcode == sd_op && + ip->i_format.rs == 29) { + /* sd $ra, offset($sp) */ + if (ip->i_format.rt == 31) { + if (info->pc_offset != -1) + break; + info->pc_offset = + ip->i_format.simmediate / sizeof(long); + } + /* sd $s8, offset($sp) */ + if (ip->i_format.rt == 30) { + if (info->frame_offset != -1) + break; + info->frame_offset = + ip->i_format.simmediate / sizeof(long); + } + } + } + if (info->pc_offset == -1 || info->frame_offset == -1) { + printk("Can't analyze prologue code at %p\n", func); + info->pc_offset = -1; + info->frame_offset = -1; + return -1; + } + + return 0; +} +void __init frame_info_init(void) +{ + mips_frame_info_initialized = + !get_frame_info(&schedule_frame, schedule) && + !get_frame_info(&schedule_timeout_frame, schedule_timeout) && + !get_frame_info(&sleep_on_frame, sleep_on) && + !get_frame_info(&sleep_on_timeout_frame, sleep_on_timeout) && + !get_frame_info(&wait_for_completion_frame, wait_for_completion); +} + /* get_wchan - a maintenance nightmare ... */ unsigned long get_wchan(struct task_struct *p) { @@ -195,6 +229,8 @@ if (!p || p == current || p->state == TASK_RUNNING) return 0; + if (!mips_frame_info_initialized) + return 0; pc = thread_saved_pc(&p->thread); if (pc < first_sched || pc >= last_sched) goto out; @@ -207,30 +243,33 @@ goto schedule_timeout_caller; if (pc >= (unsigned long)interruptible_sleep_on) goto schedule_caller; + if (pc >= (unsigned long)wait_for_completion) + goto schedule_caller; goto schedule_timeout_caller; schedule_caller: - frame = ((unsigned long *)p->thread.reg30)[10]; - pc = ((unsigned long *)frame)[7]; + frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset]; + if (pc >= (unsigned long) sleep_on) + pc = ((unsigned long *)frame)[sleep_on_frame.pc_offset]; + else + pc = ((unsigned long *)frame)[wait_for_completion_frame.pc_offset]; goto out; schedule_timeout_caller: /* Must be schedule_timeout ... */ - pc = ((unsigned long *)p->thread.reg30)[11]; - frame = ((unsigned long *)p->thread.reg30)[10]; + frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset]; /* The schedule_timeout frame ... */ - pc = ((unsigned long *)frame)[9]; - frame = ((unsigned long *)frame)[8]; + pc = ((unsigned long *)frame)[schedule_timeout_frame.pc_offset]; if (pc >= first_sched && pc < last_sched) { - /* schedule_timeout called by interruptible_sleep_on_timeout */ - pc = ((unsigned long *)frame)[7]; - frame = ((unsigned long *)frame)[6]; + /* schedule_timeout called by [interruptible_]sleep_on_timeout */ + frame = ((unsigned long *)frame)[schedule_timeout_frame.frame_offset]; + pc = ((unsigned long *)frame)[sleep_on_timeout_frame.pc_offset]; } out: - if (current->thread.mflags & MF_32BIT) /* Kludge for 32-bit ps */ + if (current->thread.mflags & MF_32BIT_ADDR) /* Kludge for 32-bit ps */ pc &= 0xffffffff; return pc; diff -urN linux-2.4.21-bk37/arch/mips64/kernel/ptrace.c linux-2.4.21-bk38/arch/mips64/kernel/ptrace.c --- linux-2.4.21-bk37/arch/mips64/kernel/ptrace.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/ptrace.c 2003-08-24 02:55:58.000000000 -0700 @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -112,34 +113,19 @@ break; case FPR_BASE ... FPR_BASE + 31: if (child->used_math) { - unsigned long long *fregs - = (unsigned long long *) - &child->thread.fpu.hard.fp_regs[0]; - if (mips_cpu.options & MIPS_CPU_FPU) { -#ifndef CONFIG_SMP - if (last_task_used_math == child) { - __enable_fpu(); - save_fp(child); - __disable_fpu(); - last_task_used_math = NULL; - } -#endif - } else { - fregs = (unsigned long long *) - child->thread.fpu.soft.regs; - } - + unsigned long long *fregs; + fregs = (unsigned long long *)get_fpu_regs(child); /* * The odd registers are actually the high * order bits of the values stored in the even - * registers. + * registers - unless we're using r2k_switch.S. */ if (addr & 1) tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32); else tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff); } else { - tmp = -EIO; + tmp = -1; /* FP not yet used */ } break; case PC: @@ -158,13 +144,13 @@ tmp = regs->lo; break; case FPC_CSR: - if (mips_cpu.options & MIPS_CPU_FPU) + if (cpu_has_fpu) tmp = child->thread.fpu.hard.control; else tmp = child->thread.fpu.soft.sr; break; case FPC_EIR: { /* implementation / version register */ - unsigned int flags; + unsigned long flags; __save_flags(flags); __enable_fpu(); __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); @@ -200,22 +186,8 @@ break; case FPR_BASE ... FPR_BASE + 31: { unsigned long long *fregs; - fregs = (unsigned long long *)&child->thread.fpu.hard.fp_regs[0]; - if (child->used_math) { -#ifndef CONFIG_SMP - if (last_task_used_math == child) - if (mips_cpu.options & MIPS_CPU_FPU) { - __enable_fpu(); - save_fp(child); - __disable_fpu(); - last_task_used_math = NULL; - regs->cp0_status &= ~ST0_CU1; - } else { - fregs = (unsigned long long *) - child->thread.fpu.soft.regs; - } -#endif - } else { + fregs = (unsigned long long *)get_fpu_regs(child); + if (!child->used_math) { /* FP not yet used */ memset(&child->thread.fpu.hard, ~0, sizeof(child->thread.fpu.hard)); @@ -228,10 +200,12 @@ */ if (addr & 1) { fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff; - fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long) data) << 32; + fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long long) data) << 32; } else { fregs[addr - FPR_BASE] &= ~0xffffffffLL; - fregs[addr - FPR_BASE] |= data; + /* Must cast, lest sign extension fill upper + bits! */ + fregs[addr - FPR_BASE] |= (unsigned int)data; } break; } @@ -245,7 +219,7 @@ regs->lo = data; break; case FPC_CSR: - if (mips_cpu.options & MIPS_CPU_FPU) + if (cpu_has_fpu) child->thread.fpu.hard.control = data; else child->thread.fpu.soft.sr = data; @@ -255,7 +229,7 @@ ret = -EIO; break; } - goto out; + break; } case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ case PTRACE_CONT: { /* restart after signal. */ @@ -342,7 +316,7 @@ ret = -EPERM; if (pid == 1) /* you may not mess with init */ - goto out; + goto out_tsk; if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); @@ -383,32 +357,8 @@ break; case FPR_BASE ... FPR_BASE + 31: if (child->used_math) { - unsigned long long *fregs - = (unsigned long long *) - &child->thread.fpu.hard.fp_regs[0]; - if (mips_cpu.options & MIPS_CPU_FPU) { -#ifndef CONFIG_SMP - if (last_task_used_math == child) { - __enable_fpu(); - save_fp(child); - __disable_fpu(); - last_task_used_math = NULL; - } -#endif - } else { - fregs = (unsigned long long *) - child->thread.fpu.soft.regs; - } - - /* - * The odd registers are actually the high - * order bits of the values stored in the even - * registers. - */ - if (addr & 1) - tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32); - else - tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff); + unsigned long *fregs = get_fpu_regs(child); + tmp = fregs[addr - FPR_BASE]; } else { tmp = -EIO; } @@ -429,13 +379,13 @@ tmp = regs->lo; break; case FPC_CSR: - if (mips_cpu.options & MIPS_CPU_FPU) + if (cpu_has_fpu) tmp = child->thread.fpu.hard.control; else tmp = child->thread.fpu.soft.sr; break; case FPC_EIR: { /* implementation / version register */ - unsigned int flags; + unsigned long flags; __save_flags(flags); __enable_fpu(); __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); @@ -470,42 +420,14 @@ regs->regs[addr] = data; break; case FPR_BASE ... FPR_BASE + 31: { - unsigned long long *fregs = (unsigned long long *) - &child->thread.fpu.hard.fp_regs[0]; - - if (child->used_math) { -#ifndef CONFIG_SMP - if (mips_cpu.options & MIPS_CPU_FPU) { - if (last_task_used_math == child) { - __enable_fpu(); - save_fp(child); - __disable_fpu(); - last_task_used_math = NULL; - regs->cp0_status &= ~ST0_CU1; - } else { - fregs = (unsigned long long *) - child->thread.fpu.soft.regs; - } - } -#endif - } else { + unsigned long *fregs = get_fpu_regs(child); + if (!child->used_math) { /* FP not yet used */ memset(&child->thread.fpu.hard, ~0, sizeof(child->thread.fpu.hard)); child->thread.fpu.hard.control = 0; } - /* - * The odd registers are actually the high order bits - * of the values stored in the even registers - unless - * we're using r2k_switch.S. - */ - if (addr & 1) { - fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff; - fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long) data) << 32; - } else { - fregs[addr - FPR_BASE] &= ~0xffffffffLL; - fregs[addr - FPR_BASE] |= data; - } + fregs[addr - FPR_BASE] = data; break; } case PC: @@ -518,7 +440,7 @@ regs->lo = data; break; case FPC_CSR: - if (mips_cpu.options & MIPS_CPU_FPU) + if (cpu_has_fpu) child->thread.fpu.hard.control = data; else child->thread.fpu.soft.sr = data; @@ -528,7 +450,7 @@ ret = -EIO; break; } - goto out; + break; } case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ case PTRACE_CONT: { /* restart after signal. */ diff -urN linux-2.4.21-bk37/arch/mips64/kernel/r4k_fpu.S linux-2.4.21-bk38/arch/mips64/kernel/r4k_fpu.S --- linux-2.4.21-bk37/arch/mips64/kernel/r4k_fpu.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/r4k_fpu.S 2003-08-24 02:55:58.000000000 -0700 @@ -32,11 +32,8 @@ .set noreorder /* Save floating point context */ LEAF(_save_fp_context) - mfc0 t1, CP0_STATUS - sll t2, t1,5 + cfc1 t1, fcr31 - bgez t2, 1f - cfc1 t1, fcr31 /* Store the 16 odd double precision registers */ EX sdc1 $f1, SC_FPREGS+8(a0) EX sdc1 $f3, SC_FPREGS+24(a0) @@ -56,7 +53,6 @@ EX sdc1 $f31, SC_FPREGS+248(a0) /* Store the 16 even double precision registers */ -1: EX sdc1 $f0, SC_FPREGS+0(a0) EX sdc1 $f2, SC_FPREGS+16(a0) EX sdc1 $f4, SC_FPREGS+32(a0) @@ -81,24 +77,42 @@ li v0, 0 # success END(_save_fp_context) + /* Save 32-bit process floating point context */ +LEAF(_save_fp_context32) + cfc1 t1, fcr31 + + EX sdc1 $f0, SC32_FPREGS+0(a0) + EX sdc1 $f2, SC32_FPREGS+16(a0) + EX sdc1 $f4, SC32_FPREGS+32(a0) + EX sdc1 $f6, SC32_FPREGS+48(a0) + EX sdc1 $f8, SC32_FPREGS+64(a0) + EX sdc1 $f10, SC32_FPREGS+80(a0) + EX sdc1 $f12, SC32_FPREGS+96(a0) + EX sdc1 $f14, SC32_FPREGS+112(a0) + EX sdc1 $f16, SC32_FPREGS+128(a0) + EX sdc1 $f18, SC32_FPREGS+144(a0) + EX sdc1 $f20, SC32_FPREGS+160(a0) + EX sdc1 $f22, SC32_FPREGS+176(a0) + EX sdc1 $f24, SC32_FPREGS+192(a0) + EX sdc1 $f26, SC32_FPREGS+208(a0) + EX sdc1 $f28, SC32_FPREGS+224(a0) + EX sdc1 $f30, SC32_FPREGS+240(a0) + EX sw t1, SC32_FPC_CSR(a0) + cfc1 t0, $0 # implementation/version + EX sw t0, SC32_FPC_EIR(a0) + + jr ra + li v0, 0 # success + END(_save_fp_context32) + /* * Restore FPU state: * - fp gp registers * - cp1 status/control register - * - * We base the decision which registers to restore from the signal stack - * frame on the current content of c0_status, not on the content of the - * stack frame which might have been changed by the user. */ LEAF(_restore_fp_context) - mfc0 t1, CP0_STATUS - sll t0, t1,5 - bgez t0, 1f - EX lw t0, SC_FPC_CSR(a0) - - /* Restore the 16 odd double precision registers only - * when enabled in the cp0 status register. - */ + /* Restore an o32/64 sigcontext. */ + EX lw t0, SC_FPC_CSR(a0) EX ldc1 $f1, SC_FPREGS+8(a0) EX ldc1 $f3, SC_FPREGS+24(a0) EX ldc1 $f5, SC_FPREGS+40(a0) @@ -116,11 +130,7 @@ EX ldc1 $f29, SC_FPREGS+232(a0) EX ldc1 $f31, SC_FPREGS+248(a0) - /* - * Restore the 16 even double precision registers - * when cp1 was enabled in the cp0 status register. - */ -1: EX ldc1 $f0, SC_FPREGS+0(a0) + EX ldc1 $f0, SC_FPREGS+0(a0) EX ldc1 $f2, SC_FPREGS+16(a0) EX ldc1 $f4, SC_FPREGS+32(a0) EX ldc1 $f6, SC_FPREGS+48(a0) @@ -141,6 +151,30 @@ li v0, 0 # success END(_restore_fp_context) +LEAF(_restore_fp_context32) + /* Restore an o32 sigcontext. */ + EX lw t0, SC32_FPC_CSR(a0) + EX ldc1 $f0, SC32_FPREGS+0(a0) + EX ldc1 $f2, SC32_FPREGS+16(a0) + EX ldc1 $f4, SC32_FPREGS+32(a0) + EX ldc1 $f6, SC32_FPREGS+48(a0) + EX ldc1 $f8, SC32_FPREGS+64(a0) + EX ldc1 $f10, SC32_FPREGS+80(a0) + EX ldc1 $f12, SC32_FPREGS+96(a0) + EX ldc1 $f14, SC32_FPREGS+112(a0) + EX ldc1 $f16, SC32_FPREGS+128(a0) + EX ldc1 $f18, SC32_FPREGS+144(a0) + EX ldc1 $f20, SC32_FPREGS+160(a0) + EX ldc1 $f22, SC32_FPREGS+176(a0) + EX ldc1 $f24, SC32_FPREGS+192(a0) + EX ldc1 $f26, SC32_FPREGS+208(a0) + EX ldc1 $f28, SC32_FPREGS+224(a0) + EX ldc1 $f30, SC32_FPREGS+240(a0) + ctc1 t0, fcr31 + jr ra + li v0, 0 # success + END(_restore_fp_context32) + .type fault@function .ent fault fault: jr ra diff -urN linux-2.4.21-bk37/arch/mips64/kernel/r4k_genex.S linux-2.4.21-bk38/arch/mips64/kernel/r4k_genex.S --- linux-2.4.21-bk37/arch/mips64/kernel/r4k_genex.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/r4k_genex.S 2003-08-24 02:55:58.000000000 -0700 @@ -5,6 +5,7 @@ * * Copyright (C) 1994 - 1999 by Ralf Baechle * Copyright (C) 1999 Silicon Graphics + * Copyright (C) 2002 Maciej W. Rozycki * * Low level exception handling */ @@ -15,7 +16,7 @@ #include #include #include -#include +#include BUILD_HANDLER adel ade ade silent /* #4 */ BUILD_HANDLER ades ade ade silent /* #5 */ @@ -27,29 +28,38 @@ BUILD_HANDLER ov ov sti silent /* #12 */ BUILD_HANDLER tr tr sti silent /* #13 */ BUILD_HANDLER fpe fpe fpe silent /* #15 */ + BUILD_HANDLER mdmx mdmx sti silent /* #22 */ BUILD_HANDLER watch watch sti verbose /* #23 */ BUILD_HANDLER mcheck mcheck cli verbose /* #24 */ BUILD_HANDLER reserved reserved sti verbose /* others */ + __INIT +/* A temporary overflow handler used by check_daddi(). */ + + BUILD_HANDLER daddi_ov daddi_ov none silent /* #12 */ + + /* General exception handler for CPUs with virtual coherency exception. * - * Be careful when changing this, it has to be at most 128 bytes to fit - * into space reserved for the exception handler. + * Be careful when changing this, it has to be at most 256 (as a special + * exception) bytes to fit into space reserved for the exception handler. */ - NESTED(except_vec3_r4000, 0, sp) + .set push .set noat -#if defined(R5432_CP0_INTERRUPT_WAR) - mfc0 k0, CP0_INDEX -#endif +NESTED(except_vec3_r4000, 0, sp) mfc0 k1, CP0_CAUSE - andi k1, k1, 0x7c li k0, 31<<2 + andi k1, k1, 0x7c + .set push + .set noreorder + .set nomacro beq k1, k0, handle_vced li k0, 14<<2 beq k1, k0, handle_vcei dsll k1, k1, 1 + .set pop ld k0, exception_handlers(k1) jr k0 @@ -60,51 +70,61 @@ * store will be re-executed. */ handle_vced: - mfc0 k0, CP0_BADVADDR + dmfc0 k0, CP0_BADVADDR li k1, -4 # Is this ... and k0, k1 # ... really needed? mtc0 zero, CP0_TAGLO cache Index_Store_Tag_D,(k0) cache Hit_Writeback_Inv_SD,(k0) - lui k0, %hi(vced_count) - lw k1, %lo(vced_count)(k0) + dla k0, vced_count + lw k1, (k0) addiu k1, 1 - sw k1, %lo(vced_count)(k0) + sw k1, (k0) eret handle_vcei: - mfc0 k0, CP0_BADVADDR + dmfc0 k0, CP0_BADVADDR cache Hit_Writeback_Inv_SD,(k0) # also cleans pi - lui k0, %hi(vcei_count) - lw k1, %lo(vcei_count)(k0) + dla k0, vcei_count + lw k1, (k0) addiu k1, 1 - sw k1, %lo(vcei_count)(k0) + sw k1, (k0) eret +END(except_vec3_r4000) + .set pop - END(except_vec3_r4000) - .set at - /* General exception vector for all other CPUs. */ - NESTED(except_vec3_generic, 0, sp) +/* General exception vector for all other CPUs. + * + * Be careful when changing this, it has to be at most 128 bytes + * to fit into space reserved for the exception handler. + */ + .set push .set noat +NESTED(except_vec3_generic, 0, sp) +#if R5432_CP0_INTERRUPT_WAR + mfc0 k0, CP0_INDEX +#endif mfc0 k1, CP0_CAUSE andi k1, k1, 0x7c dsll k1, k1, 1 ld k0, exception_handlers(k1) jr k0 - nop - END(except_vec3_generic) - .set at +END(except_vec3_generic) + .set pop + /* - * Special interrupt vector for embedded MIPS. This is a dedicated interrupt - * vector which reduces interrupt processing overhead. The jump instruction - * will be inserted here at initialization time. This handler may only be 8 - * bytes in size! + * Special interrupt vector for MIPS64 ISA & embedded MIPS processors. + * This is a dedicated interrupt exception vector which reduces the + * interrupt processing overhead. The jump instruction will be replaced + * at the initialization time. + * + * Be careful when changing this, it has to be at most 128 bytes + * to fit into space reserved for the exception handler. */ NESTED(except_vec4, 0, sp) 1: j 1b /* Dummy, will be replaced */ - nop - END(except_vec4) +END(except_vec4) __FINIT diff -urN linux-2.4.21-bk37/arch/mips64/kernel/r4k_switch.S linux-2.4.21-bk38/arch/mips64/kernel/r4k_switch.S --- linux-2.4.21-bk37/arch/mips64/kernel/r4k_switch.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/r4k_switch.S 2003-08-24 02:55:58.000000000 -0700 @@ -23,6 +23,19 @@ .set mips3 +#define PF_USEDFPU 0x00100000 /* task used FPU this quantum (SMP) */ +#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS) + +/* + * [jsun] FPU context is saved if and only if the process has used FPU in + * the current run (PF_USEDFPU). In any case, the CU1 bit for user space + * STATUS register should be 0, so that a process *always* starts its + * userland with FPU disabled after each context switch. + * + * FPU will be enabled as soon as the process accesses FPU again, through + * do_cpu() trap. + */ + /* * task_struct *resume(task_struct *prev, task_struct *next) */ @@ -35,6 +48,38 @@ sd ra, THREAD_REG31(a0) /* + * check if we need to save FPU registers + */ + ld t0, TASK_FLAGS(a0) + li t1, PF_USEDFPU + and t2, t0, t1 + beqz t2, 1f + nor t1, zero, t1 + + /* + * clear PF_USEDFPU bit in task flags + */ + and t0, t0, t1 + sd t0, TASK_FLAGS(a0) + + /* + * clear saved user stack CU1 bit + */ + ld t0, ST_OFF(a0) + li t1, ~ST0_CU1 + and t0, t0, t1 + sd t0, ST_OFF(a0) + + + sll t2, t0, 5 + bgez t2, 2f + sdc1 $f0, (THREAD_FPU + 0x00)(a0) + fpu_save_16odd a0 +2: + fpu_save_16even a0 t1 # clobbers t1 +1: + + /* * The order of restoring the registers takes care of the race * updating $28, $29 and kernelsp without disabling ints. */ @@ -42,7 +87,7 @@ cpu_restore_nonscratch $28 daddiu a1, $28, KERNEL_STACK_SIZE-32 - set_saved_sp a1 t0 + set_saved_sp a1, t0, t1 mfc0 t1, CP0_STATUS /* Do we really need this? */ li a3, 0xff00 @@ -57,51 +102,10 @@ END(resume) /* - * Do lazy fpu context switch. Saves FPU context to the process in a0 - * and loads the new context of the current process. - */ - -#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS) - -LEAF(lazy_fpu_switch) - mfc0 t0, CP0_STATUS # enable cp1 - li t3, ST0_CU1 - or t0, t3 - mtc0 t0, CP0_STATUS - FPU_ENABLE_HAZARD - - beqz a0, 2f # Save floating point state - nor t3, zero, t3 - - ld t1, ST_OFF(a0) # last thread looses fpu - and t1, t3 - sd t1, ST_OFF(a0) - sll t2, t1, 5 - bgez t2, 1f - sdc1 $f0, (THREAD_FPU + 0x00)(a0) - fpu_save_16odd a0 -1: - fpu_save_16even a0 t1 # clobbers t1 -2: - - beqz a1, 3f - - sll t0, t0, 5 # load new fp state - bgez t0, 1f - ldc1 $f0, (THREAD_FPU + 0x00)(a1) - fpu_restore_16odd a1 -1: - .set reorder - fpu_restore_16even a1, t0 # clobbers t0 -3: - jr ra - END(lazy_fpu_switch) - -/* * Save a thread's fp context. */ .set noreorder -LEAF(save_fp) +LEAF(_save_fp) mfc0 t0, CP0_STATUS sll t1, t0, 5 bgez t1, 1f # 16 register mode? @@ -111,12 +115,12 @@ fpu_save_16even a0 t1 # clobbers t1 jr ra sdc1 $f0, (THREAD_FPU + 0x00)(a0) - END(save_fp) + END(_save_fp) /* * Restore a thread's fp context. */ -LEAF(restore_fp) +LEAF(_restore_fp) mfc0 t0, CP0_STATUS sll t1, t0, 5 bgez t1, 1f # 16 register mode? @@ -128,7 +132,7 @@ jr ra ldc1 $f0, (THREAD_FPU + 0x00)(a0) - END(restore_fp) + END(_restore_fp) /* * Load the FPU with signalling NANS. This bit pattern we're using has @@ -140,7 +144,7 @@ #define FPU_DEFAULT 0x00000000 -LEAF(init_fpu) +LEAF(_init_fpu) mfc0 t0, CP0_STATUS li t1, ST0_CU1 or t0, t1 @@ -188,4 +192,4 @@ dmtc1 t0, $f28 jr ra dmtc1 t0, $f30 - END(init_fpu) + END(_init_fpu) diff -urN linux-2.4.21-bk37/arch/mips64/kernel/scall_64.S linux-2.4.21-bk38/arch/mips64/kernel/scall_64.S --- linux-2.4.21-bk37/arch/mips64/kernel/scall_64.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/scall_64.S 2003-08-24 02:55:58.000000000 -0700 @@ -17,14 +17,15 @@ #include #include -#ifndef CONFIG_MIPS32_COMPAT +#ifndef CONFIG_BINFMT_ELF32 +/* Neither O32 nor N32, so define handle_sys here */ #define handle_sys64 handle_sys #endif .align 5 NESTED(handle_sys64, PT_SIZE, sp) /* When 32-bit compatibility is configured scall_o32.S already did this. */ -#ifndef CONFIG_MIPS32_COMPAT +#if !defined(CONFIG_MIPS32_O32) && !defined(CONFIG_MIPS32_N32) .set noat SAVE_SOME STI @@ -66,7 +67,7 @@ SSNOP; SSNOP; SSNOP ld t2, TASK_NEED_RESCHED($28) - bnez t2, reschedule + bnez t2, _64_reschedule lw v0, TASK_SIGPENDING($28) bnez v0, signal_return @@ -83,12 +84,14 @@ ori t0, t0, 1 mtc0 t0, CP0_STATUS + SAVE_STATIC move a0, zero move a1, sp jal do_signal + RESTORE_STATIC b restore_all -reschedule: +_64_reschedule: SAVE_STATIC jal schedule b ret_from_sys_call @@ -130,237 +133,215 @@ .align 3 sys_call_table: - PTR sys_syscall /* 5000 */ - PTR sys_exit - PTR sys_fork - PTR sys_read + PTR sys_read /* 5000 */ PTR sys_write - PTR sys_open /* 5005 */ + PTR sys_open PTR sys_close - PTR sys_waitpid - PTR sys_creat - PTR sys_link - PTR sys_unlink /* 5010 */ - PTR sys_execve - PTR sys_chdir - PTR sys_time - PTR sys_mknod - PTR sys_chmod /* 5015 */ - PTR sys_lchown - PTR sys_ni_syscall - PTR sys_stat + PTR sys_newstat + PTR sys_newfstat /* 5005 */ + PTR sys_newlstat + PTR sys_poll PTR sys_lseek - PTR sys_getpid /* 5020 */ - PTR sys_mount - PTR sys_oldumount - PTR sys_setuid - PTR sys_getuid - PTR sys_stime /* 5025 */ - PTR sys_ni_syscall /* ptrace */ - PTR sys_alarm - PTR sys_fstat + PTR sys_mmap + PTR sys_mprotect /* 5010 */ + PTR sys_munmap + PTR sys_brk + PTR sys_rt_sigaction + PTR sys_rt_sigprocmask + PTR sys_ioctl /* 5015 */ + PTR sys_pread + PTR sys_pwrite + PTR sys_readv + PTR sys_writev + PTR sys_access /* 5020 */ + PTR sys_pipe + PTR sys_select + PTR sys_sched_yield + PTR sys_mremap + PTR sys_msync /* 5025 */ + PTR sys_mincore + PTR sys_madvise + PTR sys_shmget + PTR sys_shmat + PTR sys_shmctl /* 5030 */ + PTR sys_dup + PTR sys_dup2 PTR sys_pause - PTR sys_utime /* 5030 */ - PTR sys_ni_syscall - PTR sys_ni_syscall - PTR sys_access - PTR sys_nice - PTR sys_ni_syscall /* 5035 */ - PTR sys_sync - PTR sys_kill - PTR sys_rename + PTR sys_nanosleep + PTR sys_getitimer /* 5035 */ + PTR sys_setitimer + PTR sys_alarm + PTR sys_getpid + PTR sys_sendfile + PTR sys_socket /* 5040 */ + PTR sys_connect + PTR sys_accept + PTR sys_sendto + PTR sys_recvfrom + PTR sys_sendmsg /* 5045 */ + PTR sys_recvmsg + PTR sys_shutdown + PTR sys_bind + PTR sys_listen + PTR sys_getsockname /* 5050 */ + PTR sys_getpeername + PTR sys_socketpair + PTR sys_setsockopt + PTR sys_getsockopt + PTR sys_clone /* 5055 */ + PTR sys_fork + PTR sys_execve + PTR sys_exit + PTR sys_wait4 + PTR sys_kill /* 5060 */ + PTR sys_newuname + PTR sys_semget + PTR sys_semop + PTR sys_semctl + PTR sys_shmdt /* 5065 */ + PTR sys_msgget + PTR sys_msgsnd + PTR sys_msgrcv + PTR sys_msgctl + PTR sys_fcntl /* 5070 */ + PTR sys_flock + PTR sys_fsync + PTR sys_fdatasync + PTR sys_truncate + PTR sys_ftruncate /* 5075 */ + PTR sys_getdents + PTR sys_getcwd + PTR sys_chdir + PTR sys_fchdir + PTR sys_rename /* 5080 */ PTR sys_mkdir - PTR sys_rmdir /* 5040 */ - PTR sys_dup - PTR sys_pipe + PTR sys_rmdir + PTR sys_creat + PTR sys_link + PTR sys_unlink /* 5085 */ + PTR sys_symlink + PTR sys_readlink + PTR sys_chmod + PTR sys_fchmod + PTR sys_chown /* 5090 */ + PTR sys_fchown + PTR sys_lchown + PTR sys_umask + PTR sys_gettimeofday + PTR sys_getrlimit /* 5095 */ + PTR sys_getrusage + PTR sys_sysinfo PTR sys_times - PTR sys_ni_syscall - PTR sys_brk /* 5045 */ - PTR sys_setgid + PTR sys_ptrace + PTR sys_getuid /* 5100 */ + PTR sys_syslog PTR sys_getgid - PTR sys_ni_syscall /* was signal 2 */ - PTR sys_geteuid - PTR sys_getegid /* 5050 */ - PTR sys_acct - PTR sys_umount - PTR sys_ni_syscall - PTR sys_ioctl - PTR sys_fcntl /* 5055 */ - PTR sys_ni_syscall + PTR sys_setuid + PTR sys_setgid + PTR sys_geteuid /* 5105 */ + PTR sys_getegid PTR sys_setpgid - PTR sys_ni_syscall - PTR sys_ni_syscall - PTR sys_umask /* 5060 */ - PTR sys_chroot - PTR sys_ustat - PTR sys_dup2 PTR sys_getppid - PTR sys_getpgrp /* 5065 */ - PTR sys_setsid - PTR sys_sigaction - PTR sys_sgetmask - PTR sys_ssetmask - PTR sys_setreuid /* 5070 */ + PTR sys_getpgrp + PTR sys_setsid /* 5110 */ + PTR sys_setreuid PTR sys_setregid - PTR sys_sigsuspend - PTR sys_sigpending - PTR sys_sethostname - PTR sys_setrlimit /* 5075 */ - PTR sys_getrlimit - PTR sys_getrusage - PTR sys_gettimeofday - PTR sys_settimeofday - PTR sys_getgroups /* 5080 */ + PTR sys_getgroups PTR sys_setgroups - PTR sys_ni_syscall /* old_select */ - PTR sys_symlink - PTR sys_lstat - PTR sys_readlink /* 5085 */ - PTR sys_uselib - PTR sys_swapon - PTR sys_reboot - PTR sys_ni_syscall /* old_readdir */ - PTR sys_mmap /* 5090 */ - PTR sys_munmap - PTR sys_truncate - PTR sys_ftruncate - PTR sys_fchmod - PTR sys_fchown /* 5095 */ - PTR sys_getpriority - PTR sys_setpriority - PTR sys_ni_syscall - PTR sys_statfs - PTR sys_fstatfs /* 5100 */ - PTR sys_ni_syscall /* sys_ioperm */ - PTR sys_socketcall - PTR sys_syslog - PTR sys_setitimer - PTR sys_getitimer /* 5105 */ - PTR sys_newstat - PTR sys_newlstat - PTR sys_newfstat - PTR sys_ni_syscall - PTR sys_ni_syscall /* sys_ioperm *//* 5110 */ - PTR sys_vhangup - PTR sys_ni_syscall /* was sys_idle */ - PTR sys_ni_syscall /* sys_vm86 */ - PTR sys_wait4 - PTR sys_swapoff /* 5115 */ - PTR sys_sysinfo - PTR sys_ipc - PTR sys_fsync - PTR sys_sigreturn - PTR sys_clone /* 5120 */ - PTR sys_setdomainname - PTR sys_newuname - PTR sys_ni_syscall /* sys_modify_ldt */ - PTR sys_adjtimex - PTR sys_mprotect /* 5125 */ - PTR sys_sigprocmask - PTR sys_create_module - PTR sys_init_module - PTR sys_delete_module - PTR sys_get_kernel_syms /* 5130 */ - PTR sys_quotactl + PTR sys_setresuid /* 5115 */ + PTR sys_getresuid + PTR sys_setresgid + PTR sys_getresgid PTR sys_getpgid - PTR sys_fchdir - PTR sys_bdflush - PTR sys_sysfs /* 5135 */ - PTR sys_personality - PTR sys_ni_syscall /* for afs_syscall */ - PTR sys_setfsuid + PTR sys_setfsuid /* 5120 */ PTR sys_setfsgid - PTR sys_llseek /* 5140 */ - PTR sys_getdents - PTR sys_select - PTR sys_flock - PTR sys_msync - PTR sys_readv /* 5145 */ - PTR sys_writev - PTR sys_cacheflush - PTR sys_cachectl - PTR sys_sysmips - PTR sys_ni_syscall /* 5150 */ PTR sys_getsid - PTR sys_fdatasync - PTR sys_sysctl - PTR sys_mlock - PTR sys_munlock /* 5155 */ - PTR sys_mlockall - PTR sys_munlockall + PTR sys_capget + PTR sys_capset + PTR sys_rt_sigpending /* 5125 */ + PTR sys_rt_sigtimedwait + PTR sys_rt_sigqueueinfo + PTR sys_rt_sigsuspend + PTR sys_sigaltstack + PTR sys_utime /* 5130 */ + PTR sys_mknod + PTR sys_personality + PTR sys_ustat + PTR sys_statfs + PTR sys_fstatfs /* 5135 */ + PTR sys_sysfs + PTR sys_getpriority + PTR sys_setpriority PTR sys_sched_setparam - PTR sys_sched_getparam - PTR sys_sched_setscheduler /* 5160 */ + PTR sys_sched_getparam /* 5140 */ + PTR sys_sched_setscheduler PTR sys_sched_getscheduler - PTR sys_sched_yield PTR sys_sched_get_priority_max PTR sys_sched_get_priority_min - PTR sys_sched_rr_get_interval /* 5165 */ - PTR sys_nanosleep - PTR sys_mremap - PTR sys_accept - PTR sys_bind - PTR sys_connect /* 5170 */ - PTR sys_getpeername - PTR sys_getsockname - PTR sys_getsockopt - PTR sys_listen - PTR sys_recv /* 5175 */ - PTR sys_recvfrom - PTR sys_recvmsg - PTR sys_send - PTR sys_sendmsg - PTR sys_sendto /* 5180 */ - PTR sys_setsockopt - PTR sys_shutdown - PTR sys_socket - PTR sys_socketpair - PTR sys_setresuid /* 5185 */ - PTR sys_getresuid + PTR sys_sched_rr_get_interval /* 5145 */ + PTR sys_mlock + PTR sys_munlock + PTR sys_mlockall + PTR sys_munlockall + PTR sys_vhangup /* 5150 */ + PTR sys_pivot_root + PTR sys_sysctl + PTR sys_prctl + PTR sys_adjtimex + PTR sys_setrlimit /* 5155 */ + PTR sys_chroot + PTR sys_sync + PTR sys_acct + PTR sys_settimeofday + PTR sys_mount /* 5160 */ + PTR sys_umount + PTR sys_swapon + PTR sys_swapoff + PTR sys_reboot + PTR sys_sethostname /* 5165 */ + PTR sys_setdomainname + PTR sys_create_module + PTR sys_init_module + PTR sys_delete_module + PTR sys_get_kernel_syms /* 5170 */ PTR sys_query_module - PTR sys_poll + PTR sys_quotactl PTR sys_nfsservctl - PTR sys_setresgid /* 5190 */ - PTR sys_getresgid - PTR sys_prctl - PTR sys_rt_sigreturn - PTR sys_rt_sigaction - PTR sys_rt_sigprocmask /* 5195 */ - PTR sys_rt_sigpending - PTR sys_rt_sigtimedwait - PTR sys_rt_sigqueueinfo - PTR sys_rt_sigsuspend - PTR sys_pread /* 5200 */ - PTR sys_pwrite - PTR sys_chown - PTR sys_getcwd - PTR sys_capget - PTR sys_capset /* 5205 */ - PTR sys_sigaltstack - PTR sys_sendfile - PTR sys_ni_syscall - PTR sys_ni_syscall - PTR sys_pivot_root /* 5210 */ - PTR sys_mincore - PTR sys_madvise - PTR sys_getdents64 - PTR sys_ni_syscall - PTR sys_gettid /* 5215 */ + PTR sys_ni_syscall /* res. for getpmsg */ + PTR sys_ni_syscall /* 5175 for putpmsg */ + PTR sys_ni_syscall /* res. for afs_syscall */ + PTR sys_ni_syscall /* res. for security */ + PTR sys_gettid PTR sys_readahead - PTR sys_setxattr + PTR sys_setxattr /* 5180 */ PTR sys_lsetxattr PTR sys_fsetxattr - PTR sys_getxattr /* 5220 */ + PTR sys_getxattr PTR sys_lgetxattr - PTR sys_fgetxattr + PTR sys_fgetxattr /* 5185 */ PTR sys_listxattr PTR sys_llistxattr - PTR sys_flistxattr /* 5225 */ + PTR sys_flistxattr PTR sys_removexattr - PTR sys_lremovexattr + PTR sys_lremovexattr /* 5190 */ PTR sys_fremovexattr - PTR sys_tkill, 2 - PTR sys_ni_syscall, 0 /* 5230 res. for sendfile64 */ - PTR sys_ni_syscall, 0 /* res. for futex */ - PTR sys_ni_syscall, 0 /* res. for sched_setaffinity */ - PTR sys_ni_syscall, 0 /* res. for sched_getaffinity */ + PTR sys_tkill + PTR sys_time + PTR sys_ni_syscall /* res. for futex */ + PTR sys_ni_syscall /* 5195 rs. sched_setaffinity */ + PTR sys_ni_syscall /* res. f. sched_getaffinity */ + PTR sys_cacheflush + PTR sys_cachectl + PTR sys_sysmips + PTR sys_ni_syscall /* 5200 */ + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall /* 5205 */ + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall /* 5210 */ + PTR sys_rt_sigreturn diff -urN linux-2.4.21-bk37/arch/mips64/kernel/scall_n32.S linux-2.4.21-bk38/arch/mips64/kernel/scall_n32.S --- linux-2.4.21-bk37/arch/mips64/kernel/scall_n32.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/scall_n32.S 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,355 @@ +/* + * 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. + * + * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01 by Ralf Baechle + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + * Copyright (C) 2001 MIPS Technologies, Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* This duplicates the definition from */ +#define PT_TRACESYS 0x00000002 /* tracing system calls */ + +/* This duplicates the definition from */ +#define SIGILL 4 /* Illegal instruction (ANSI). */ + +#ifndef CONFIG_MIPS32_O32 +/* No O32, so define handle_sys here */ +#define handle_sysn32 handle_sys +#endif + + .align 5 +NESTED(handle_sysn32, PT_SIZE, sp) +#ifndef CONFIG_MIPS32_O32 + .set noat + SAVE_SOME + STI + .set at +#endif + ld t1, PT_EPC(sp) # skip syscall on return + + subu t0, v0, __NR_N32_Linux # check syscall number + sltiu t0, t0, __NR_N32_Linux_syscalls + 1 + daddiu t1, 4 # skip to next instruction + beqz t0, not_n32_scall + sd t1, PT_EPC(sp) + + dsll t0, v0, 3 # offset into table + ld t2, (sysn32_call_table - (__NR_N32_Linux * 8))(t0) + + sd a3, PT_R26(sp) # save a3 for syscall restarting + + ld t0, TASK_PTRACE($28) # syscall tracing enabled? + andi t0, PT_TRACESYS + bnez t0, trace_a_syscall + + jalr t2 # Do The Real Thing (TM) + + li t0, -EMAXERRNO - 1 # error? + sltu t0, t0, v0 + sd t0, PT_R7(sp) # set error flag + beqz t0, 1f + + negu v0 # error + sd v0, PT_R0(sp) # set flag for syscall restarting +1: sd v0, PT_R2(sp) # result + +ret_from_sys_call: + mfc0 t0, CP0_STATUS + xori t0, t0, 1 + ori t0, t0, 1 + mtc0 t0, CP0_STATUS + + ld t2, TASK_NEED_RESCHED($28) + bnez t2, n32_reschedule + lw v0, TASK_SIGPENDING($28) + bnez v0, signal_return + +restore_all: + RESTORE_SOME + RESTORE_SP + eret + +/* Put this behind restore_all for the sake of the branch prediction. */ +signal_return: + .type signal_return, @function + + mfc0 t0, CP0_STATUS + ori t0, t0, 1 + mtc0 t0, CP0_STATUS + + SAVE_STATIC + move a0, zero + move a1, sp + jal do_signal + RESTORE_STATIC + b restore_all + +n32_reschedule: + SAVE_STATIC + jal schedule + b ret_from_sys_call + +/* ------------------------------------------------------------------------ */ + +trace_a_syscall: + SAVE_STATIC + sd t2,PT_R1(sp) + jal syscall_trace + ld t2,PT_R1(sp) + + ld a0, PT_R4(sp) # Restore argument registers + ld a1, PT_R5(sp) + ld a2, PT_R6(sp) + ld a3, PT_R7(sp) + jalr t2 + + li t0, -EMAXERRNO - 1 # error? + sltu t0, t0, v0 + sd t0, PT_R7(sp) # set error flag + beqz t0, 1f + + negu v0 # error + sd v0, PT_R0(sp) # set flag for syscall restarting +1: sd v0, PT_R2(sp) # result + + jal syscall_trace + j ret_from_sys_call + +not_n32_scall: + /* This is not an n32 compatibility syscall, pass it on to + the n64 syscall handlers. */ + j handle_sys64 + + END(handle_sysn32) + +EXPORT(sysn32_call_table) + PTR sys_read /* 6000 */ + PTR sys_write + PTR sys_open + PTR sys_close + PTR sys_newstat + PTR sys_newfstat /* 6005 */ + PTR sys_newlstat + PTR sys_poll + PTR sys_lseek + PTR sys_mmap + PTR sys_mprotect /* 6010 */ + PTR sys_munmap + PTR sys_brk + PTR sys32_rt_sigaction + PTR sys32_rt_sigprocmask + PTR sys32_ioctl /* 6015 */ + PTR sys_pread + PTR sys_pwrite + PTR sys32_readv + PTR sys32_writev + PTR sys_access /* 6020 */ + PTR sys_pipe + PTR sys32_select + PTR sys_sched_yield + PTR sys_mremap + PTR sys_msync /* 6025 */ + PTR sys_mincore + PTR sys_madvise + PTR sys_shmget + PTR sys_shmat + PTR sys_shmctl /* 6030 */ + PTR sys_dup + PTR sys_dup2 + PTR sys_pause + PTR sys32_nanosleep + PTR sys32_getitimer /* 6035 */ + PTR sys32_setitimer + PTR sys_alarm + PTR sys_getpid + PTR sys32_sendfile + PTR sys_socket /* 6040 */ + PTR sys_connect + PTR sys_accept + PTR sys_sendto + PTR sys_recvfrom + PTR sys32_sendmsg /* 6045 */ + PTR sys32_recvmsg + PTR sys_shutdown + PTR sys_bind + PTR sys_listen + PTR sys_getsockname /* 6050 */ + PTR sys_getpeername + PTR sys_socketpair + PTR sys32_setsockopt + PTR sys_getsockopt + PTR sys_clone /* 6055 */ + PTR sys_fork + PTR sys32_execve + PTR sys_exit + PTR sys32_wait4 + PTR sys_kill /* 6060 */ + PTR sys32_newuname + PTR sys_semget + PTR sys_semop + PTR sys_semctl + PTR sys_shmdt /* 6065 */ + PTR sys_msgget + PTR sys_msgsnd + PTR sys_msgrcv + PTR sys_msgctl + PTR sys32_fcntl /* 6070 */ + PTR sys_flock + PTR sys_fsync + PTR sys_fdatasync + PTR sys_truncate + PTR sys_ftruncate /* 6075 */ + PTR sys32_getdents + PTR sys_getcwd + PTR sys_chdir + PTR sys_fchdir + PTR sys_rename /* 6080 */ + PTR sys_mkdir + PTR sys_rmdir + PTR sys_creat + PTR sys_link + PTR sys_unlink /* 6085 */ + PTR sys_symlink + PTR sys_readlink + PTR sys_chmod + PTR sys_fchmod + PTR sys_chown /* 6090 */ + PTR sys_fchown + PTR sys_lchown + PTR sys_umask + PTR sys32_gettimeofday + PTR sys32_getrlimit /* 6095 */ + PTR sys32_getrusage + PTR sys32_sysinfo + PTR sys32_times + PTR sys_ptrace + PTR sys_getuid /* 6100 */ + PTR sys_syslog + PTR sys_getgid + PTR sys_setuid + PTR sys_setgid + PTR sys_geteuid /* 6105 */ + PTR sys_getegid + PTR sys_setpgid + PTR sys_getppid + PTR sys_getpgrp + PTR sys_setsid /* 6110 */ + PTR sys_setreuid + PTR sys_setregid + PTR sys_getgroups + PTR sys_setgroups + PTR sys_setresuid /* 6115 */ + PTR sys_getresuid + PTR sys_setresgid + PTR sys_getresgid + PTR sys_getpgid + PTR sys_setfsuid /* 6120 */ + PTR sys_setfsgid + PTR sys_getsid + PTR sys_capget + PTR sys_capset + PTR sys32_rt_sigpending /* 6125 */ + PTR sys32_rt_sigtimedwait + PTR sys32_rt_sigqueueinfo + PTR sys32_rt_sigsuspend + PTR sys32_sigaltstack + PTR sys32_utime /* 6130 */ + PTR sys_mknod + PTR sys32_personality + PTR sys_ustat + PTR sys32_statfs + PTR sys32_fstatfs /* 6135 */ + PTR sys_sysfs + PTR sys_getpriority + PTR sys_setpriority + PTR sys_sched_setparam + PTR sys_sched_getparam /* 6140 */ + PTR sys_sched_setscheduler + PTR sys_sched_getscheduler + PTR sys_sched_get_priority_max + PTR sys_sched_get_priority_min + PTR sys32_sched_rr_get_interval /* 6145 */ + PTR sys_mlock + PTR sys_munlock + PTR sys_mlockall + PTR sys_munlockall + PTR sys_vhangup /* 6150 */ + PTR sys_pivot_root + PTR sys32_sysctl + PTR sys_prctl + PTR sys32_adjtimex + PTR sys32_setrlimit /* 6155 */ + PTR sys_chroot + PTR sys_sync + PTR sys_acct + PTR sys32_settimeofday + PTR sys_mount /* 6160 */ + PTR sys_umount + PTR sys_swapon + PTR sys_swapoff + PTR sys_reboot + PTR sys_sethostname /* 6165 */ + PTR sys_setdomainname + PTR sys_create_module + PTR sys_init_module + PTR sys_delete_module + PTR sys_get_kernel_syms /* 6170 */ + PTR sys_query_module + PTR sys_quotactl + PTR sys_nfsservctl + PTR sys_ni_syscall /* res. for getpmsg */ + PTR sys_ni_syscall /* 6175 for putpmsg */ + PTR sys_ni_syscall /* res. for afs_syscall */ + PTR sys_ni_syscall /* res. for security */ + PTR sys_gettid + PTR sys32_readahead + PTR sys_setxattr /* 6180 */ + PTR sys_lsetxattr + PTR sys_fsetxattr + PTR sys_getxattr + PTR sys_lgetxattr + PTR sys_fgetxattr /* 6185 */ + PTR sys_listxattr + PTR sys_llistxattr + PTR sys_flistxattr + PTR sys_removexattr + PTR sys_lremovexattr /* 6190 */ + PTR sys_fremovexattr + PTR sys_tkill + PTR sys_time + PTR sys_ni_syscall /* res. for futex */ + PTR sys_ni_syscall /* 6195 rs. sched_setaffinity */ + PTR sys_ni_syscall /* res. f. sched_getaffinity */ + PTR sys_cacheflush + PTR sys_cachectl + PTR sys_sysmips + PTR sys_ni_syscall /* 6200 */ + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall /* 6205 */ + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall /* 6210 */ + PTR sysn32_rt_sigreturn + PTR sys_fcntl + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall /* 6215 */ + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_ni_syscall + PTR sys_sendfile64 diff -urN linux-2.4.21-bk37/arch/mips64/kernel/scall_o32.S linux-2.4.21-bk38/arch/mips64/kernel/scall_o32.S --- linux-2.4.21-bk37/arch/mips64/kernel/scall_o32.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/scall_o32.S 2003-08-24 02:55:58.000000000 -0700 @@ -22,9 +22,6 @@ #include #include -/* Highest syscall used of any syscall flavour */ -#define MAX_SYSCALL_NO __NR_Linux32 + __NR_Linux32_syscalls - .align 5 NESTED(handle_sys, PT_SIZE, sp) .set noat @@ -33,8 +30,8 @@ .set at ld t1, PT_EPC(sp) # skip syscall on return - subu t0, v0, __NR_Linux32 # check syscall number - sltiu t0, t0, __NR_Linux32_syscalls + 1 + subu t0, v0, __NR_O32_Linux # check syscall number + sltiu t0, t0, __NR_O32_Linux_syscalls + 1 daddiu t1, 4 # skip to next instruction beqz t0, not_o32_scall sd t1, PT_EPC(sp) @@ -45,10 +42,15 @@ RESTORE_ALL #endif + sll a0, a0, 0 + sll a1, a1, 0 + sll a2, a2, 0 + sll a3, a3, 0 + /* XXX Put both in one cacheline, should save a bit. */ dsll t0, v0, 3 # offset into table - ld t2, (sys_call_table - (__NR_Linux32 * 8))(t0) # syscall routine - lbu t3, (sys_narg_table - __NR_Linux32)(v0) # number of arguments + ld t2, (sys_call_table - (__NR_O32_Linux * 8))(t0) + lbu t3, (sys_narg_table - __NR_O32_Linux)(v0) subu t0, t3, 5 # 5 or more arguments? sd a3, PT_R26(sp) # save a3 for syscall restarting @@ -88,18 +90,24 @@ eret .set mips0 -signal_return: mfc0 t0, CP0_STATUS # need_resched and signals atomic test +signal_return: + .type signal_return, @function + + mfc0 t0, CP0_STATUS ori t0, t0, 1 mtc0 t0, CP0_STATUS + + SAVE_STATIC move a0, zero move a1, sp - SAVE_STATIC jal do_signal + RESTORE_STATIC + b restore_all o32_reschedule: SAVE_STATIC jal schedule - b o32_ret_from_sys_call + j ret_from_sys_call /* ------------------------------------------------------------------------ */ @@ -184,9 +192,13 @@ j ret_from_sys_call not_o32_scall: - /* This is not an 32-bit compatibility syscall, pass it on to + /* This is not an o32 compatibility syscall, pass it on to the 64-bit syscall handlers. */ +#ifdef CONFIG_MIPS32_N32 + j handle_sysn32 +#else j handle_sys64 +#endif illegal_syscall: /* This also isn't a 64-bit syscall, throw an error. */ @@ -197,7 +209,7 @@ j ret_from_sys_call END(handle_sys) - LEAF(mips_atomic_set) +LEAF(mips_atomic_set) andi v0, a1, 3 # must be word aligned bnez v0, bad_alignment @@ -205,7 +217,7 @@ daddiu a0, a1, 4 or a0, a0, a1 and a0, a0, v1 - bltz a0, bad_address + bnez a0, bad_address /* Ok, this is the ll/sc case. World is sane :-) */ 1: ll v0, (a1) @@ -240,21 +252,21 @@ jr ra END(mips_atomic_set) - LEAF(sys32_sysmips) +LEAF(sys32_sysmips) beq a0, MIPS_ATOMIC_SET, mips_atomic_set j sys_sysmips END(sys32_sysmips) - LEAF(sys32_syscall) +LEAF(sys32_syscall) ld t0, PT_R29(sp) # user sp - sltu v0, a0, __NR_Linux + __NR_Linux_syscalls + 1 + sltu v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1 beqz v0, enosys dsll v0, a0, 3 dla v1, sys32_syscall - ld t2, (sys_call_table - (__NR_Linux32 * 8))(v0) # function pointer - lbu t3, (sys_narg_table - __NR_Linux32)(a0) # number of arguments + ld t2, (sys_call_table - (__NR_O32_Linux * 8))(v0) + lbu t3, (sys_narg_table - __NR_O32_Linux)(a0) li v0, -EINVAL beq t2, v1, out # do not recurse @@ -269,7 +281,7 @@ ld v1, THREAD_CURDS($28) or v0, v0, t1 and v1, v1, v0 - bltz v1, efault + bnez v1, efault move a0, a1 # shift argument registers move a1, a2 @@ -330,7 +342,7 @@ sys sys_chmod 2 /* 4015 */ sys sys_lchown 3 sys sys_ni_syscall 0 - sys sys_stat 2 + sys sys_ni_syscall 0 /* was sys_stat */ sys sys_lseek 3 sys sys_getpid 0 /* 4020 */ sys sys_mount 5 @@ -339,8 +351,8 @@ sys sys_getuid 0 sys sys_stime 1 /* 4025 */ sys sys32_ptrace 4 - sys sys32_alarm 1 - sys sys_fstat 2 + sys sys_alarm 1 + sys sys_ni_syscall 0 /* was sys_fstat */ sys sys_pause 0 sys sys32_utime 2 /* 4030 */ sys sys_ni_syscall 0 @@ -394,9 +406,9 @@ sys sys32_settimeofday 2 sys sys_getgroups 2 /* 4080 */ sys sys_setgroups 2 - sys sys_ni_syscall 0 /* old_select */ + sys sys_ni_syscall 0 /* old_select */ sys sys_symlink 2 - sys sys_lstat 2 + sys sys_ni_syscall 0 /* was sys_lstat */ sys sys_readlink 3 /* 4085 */ sys sys_uselib 1 sys sys_swapon 2 @@ -428,7 +440,7 @@ sys sys_ni_syscall 0 /* sys_vm86 */ sys sys32_wait4 4 sys sys_swapoff 1 /* 4115 */ - sys sys_sysinfo 1 + sys sys32_sysinfo 1 sys sys32_ipc 6 sys sys_fsync 1 sys sys32_sigreturn 0 @@ -519,12 +531,12 @@ sys sys_capget 2 sys sys_capset 2 /* 4205 */ sys sys32_sigaltstack 0 - sys sys_sendfile 4 + sys sys32_sendfile 4 sys sys_ni_syscall 0 sys sys_ni_syscall 0 - sys sys_mmap2 6 /* 4210 */ - sys sys_truncate64 2 - sys sys_ftruncate64 2 + sys sys32_mmap2 6 /* 4210 */ + sys sys32_truncate64 4 + sys sys32_ftruncate64 4 sys sys_newstat 2 sys sys_newlstat 2 sys sys_newfstat 2 /* 4215 */ @@ -549,7 +561,7 @@ sys sys_lremovexattr 2 sys sys_fremovexattr 2 /* 4235 */ sys sys_tkill, 2 - sys sys_ni_syscall, 0 /* res. for sendfile64 */ + sys sys_sendfile64, 5 sys sys_ni_syscall, 0 /* res. for futex */ sys sys_ni_syscall, 0 /* res. for sched_setaffinity */ sys sys_ni_syscall, 0 /* 4240 res. for sched_getaffinity */ diff -urN linux-2.4.21-bk37/arch/mips64/kernel/setup.c linux-2.4.21-bk38/arch/mips64/kernel/setup.c --- linux-2.4.21-bk37/arch/mips64/kernel/setup.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/setup.c 2003-08-24 02:55:58.000000000 -0700 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -39,42 +40,35 @@ #include #include -#ifndef CONFIG_SMP -struct cpuinfo_mips cpu_data[1]; -#endif +struct cpuinfo_mips cpu_data[NR_CPUS]; #ifdef CONFIG_VT struct screen_info screen_info; #endif /* - * Not all of the MIPS CPUs have the "wait" instruction available. This - * is set to true if it is available. The wait instruction stops the - * pipeline and reduces the power consumption of the CPU very much. - */ -char wait_available; - -/* * Set if box has EISA slots. */ #ifdef CONFIG_EISA int EISA_bus = 0; #endif -#ifdef CONFIG_BLK_DEV_FD +#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE) +#include extern struct fd_ops no_fd_ops; struct fd_ops *fd_ops; #endif -#ifdef CONFIG_BLK_DEV_IDE +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) extern struct ide_ops no_ide_ops; struct ide_ops *ide_ops; #endif +extern void * __rd_start, * __rd_end; + extern struct rtc_ops no_rtc_ops; struct rtc_ops *rtc_ops; -extern struct kbd_ops no_kbd_ops; struct kbd_ops *kbd_ops; /* @@ -89,7 +83,7 @@ unsigned char aux_device_present; -extern void load_mmu(void); +extern char _ftext, _etext, _fdata, _edata, _end; static char command_line[CL_SIZE] = { 0, }; char saved_command_line[CL_SIZE]; @@ -102,23 +96,21 @@ const unsigned long mips_io_port_base = -1; EXPORT_SYMBOL(mips_io_port_base); -extern void ip22_setup(void); -extern void ip27_setup(void); -extern void ip32_setup(void); - /* - * isa_slot_offset is the address where E(ISA) busaddress 0 is is mapped + * isa_slot_offset is the address where E(ISA) busaddress 0 is mapped * for the processor. */ unsigned long isa_slot_offset; EXPORT_SYMBOL(isa_slot_offset); -extern void sgi_sysinit(void); extern void SetUpBootInfo(void); extern void load_mmu(void); extern ATTRIB_NORET asmlinkage void start_kernel(void); extern void prom_init(int, char **, char **, int *); +static struct resource code_resource = { "Kernel code" }; +static struct resource data_resource = { "Kernel data" }; + asmlinkage void __init init_arch(int argc, char **argv, char **envp, int *prom_vec) { @@ -127,10 +119,6 @@ prom_init(argc, argv, envp, prom_vec); -#ifdef CONFIG_SGI_IP22 - sgi_sysinit(); -#endif - cpu_report(); /* @@ -145,8 +133,8 @@ * Maybe because the kernel is in ckseg0 and not xkphys? Clear it * anyway ... */ - clear_cp0_status(ST0_BEV|ST0_TS|ST0_CU1|ST0_CU2|ST0_CU3); - set_cp0_status(ST0_CU0|ST0_KX|ST0_SX|ST0_FR); + clear_c0_status(ST0_BEV|ST0_TS|ST0_CU1|ST0_CU2|ST0_CU3); + set_c0_status(ST0_CU0|ST0_KX|ST0_SX|ST0_FR); start_kernel(); } @@ -243,7 +231,12 @@ } } -void bootmem_init(void) + +#define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) +#define PFN_PHYS(x) ((x) << PAGE_SHIFT) + +static inline void bootmem_init(void) { #ifdef CONFIG_BLK_DEV_INITRD unsigned long tmp; @@ -252,19 +245,26 @@ unsigned long bootmap_size; unsigned long start_pfn, max_pfn; int i; - extern int _end; - -#define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) -#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) -#define PFN_PHYS(x) ((x) << PAGE_SHIFT) +#ifdef CONFIG_BLK_DEV_INITRD + tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8; + if (tmp < (unsigned long)&_end) + tmp += PAGE_SIZE; + initrd_header = (unsigned long *)tmp; + if (initrd_header[0] == 0x494E5244) { + initrd_start = (unsigned long)&initrd_header[2]; + initrd_end = initrd_start + initrd_header[1]; + } + start_pfn = PFN_UP(CPHYSADDR((&_end)+(initrd_end - initrd_start) + PAGE_SIZE)); +#else /* * Partially used pages are not usable - thus * we are rounding upwards. - * start_pfn = PFN_UP(__pa(&_end)); */ - start_pfn = PFN_UP((unsigned long)&_end - KSEG0); + start_pfn = PFN_UP(CPHYSADDR(&_end)); +#endif /* CONFIG_BLK_DEV_INITRD */ +#ifndef CONFIG_SGI_IP27 /* Find the highest page frame number we have available. */ max_pfn = 0; for (i = 0; i < boot_mem_map.nr_map; i++) { @@ -329,50 +329,128 @@ /* Reserve the bootmap memory. */ reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size); +#endif #ifdef CONFIG_BLK_DEV_INITRD -#error "Initrd is broken, please fit it." - tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8; - if (tmp < (unsigned long)&_end) - tmp += PAGE_SIZE; - initrd_header = (unsigned long *)tmp; - if (initrd_header[0] == 0x494E5244) { - initrd_start = (unsigned long)&initrd_header[2]; - initrd_end = initrd_start + initrd_header[1]; - initrd_below_start_ok = 1; - if (initrd_end > memory_end) { + /* Board specific code should have set up initrd_start and initrd_end */ + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + if (&__rd_start != &__rd_end) { + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; + } + initrd_below_start_ok = 1; + if (initrd_start) { + unsigned long initrd_size = ((unsigned char *)initrd_end) - ((unsigned char *)initrd_start); + printk("Initial ramdisk at: 0x%p (%lu bytes)\n", + (void *)initrd_start, + initrd_size); +/* FIXME: is this right? */ +#ifndef CONFIG_SGI_IP27 + if (CPHYSADDR(initrd_end) > PFN_PHYS(max_pfn)) { printk("initrd extends beyond end of memory " - "(0x%08lx > 0x%08lx)\ndisabling initrd\n", - initrd_end,memory_end); + "(0x%p > 0x%p)\ndisabling initrd\n", + (void *)CPHYSADDR(initrd_end), + (void *)PFN_PHYS(max_pfn)); initrd_start = 0; - } else - *memory_start_p = initrd_end; + } +#endif /* !CONFIG_SGI_IP27 */ } #endif +} + +static inline void resource_init(void) +{ + int i; + + code_resource.start = virt_to_bus(&_ftext); + code_resource.end = virt_to_bus(&_etext) - 1; + data_resource.start = virt_to_bus(&_fdata); + data_resource.end = virt_to_bus(&_edata) - 1; + + /* + * Request address space for all standard RAM. + */ + for (i = 0; i < boot_mem_map.nr_map; i++) { + struct resource *res; + + res = alloc_bootmem(sizeof(struct resource)); + switch (boot_mem_map.map[i].type) { + case BOOT_MEM_RAM: + case BOOT_MEM_ROM_DATA: + res->name = "System RAM"; + break; + case BOOT_MEM_RESERVED: + default: + res->name = "reserved"; + } + + res->start = boot_mem_map.map[i].addr; + res->end = boot_mem_map.map[i].addr + + boot_mem_map.map[i].size - 1; + + res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + request_resource(&iomem_resource, res); + + /* + * We dont't know which RAM region contains kernel data, + * so we try it repeatedly and let the resource manager + * test it. + */ + request_resource(res, &code_resource); + request_resource(res, &data_resource); + } +} #undef PFN_UP #undef PFN_DOWN #undef PFN_PHYS -} void __init setup_arch(char **cmdline_p) { + extern void atlas_setup(void); + extern void decstation_setup(void); + extern void ip22_setup(void); + extern void ip27_setup(void); + extern void malta_setup(void); + extern void momenco_ocelot_setup(void); + extern void momenco_ocelot_g_setup(void); + extern void momenco_ocelot_c_setup(void); + extern void sead_setup(void); + extern void swarm_setup(void); + extern void frame_info_init(void); + + frame_info_init(); +#ifdef CONFIG_MIPS_ATLAS + atlas_setup(); +#endif +#ifdef CONFIG_DECSTATION + decstation_setup(); +#endif #ifdef CONFIG_SGI_IP22 ip22_setup(); #endif #ifdef CONFIG_SGI_IP27 ip27_setup(); #endif -#ifdef CONFIG_SGI_IP32 - ip32_setup(); -#endif -#ifdef CONFIG_SIBYTE_SWARM +#ifdef CONFIG_SIBYTE_BOARD swarm_setup(); #endif #ifdef CONFIG_MIPS_MALTA malta_setup(); #endif +#ifdef CONFIG_MIPS_SEAD + sead_setup(); +#endif +#ifdef CONFIG_MOMENCO_OCELOT + momenco_ocelot_setup(); +#endif +#ifdef CONFIG_MOMENCO_OCELOT_G + momenco_ocelot_g_setup(); +#endif +#ifdef CONFIG_MOMENCO_OCELOT_C + momenco_ocelot_c_setup(); +#endif strncpy(command_line, arcs_cmdline, CL_SIZE); memcpy(saved_command_line, command_line, CL_SIZE); @@ -385,11 +463,15 @@ bootmem_init(); paging_init(); + + resource_init(); } int __init fpu_disable(char *s) { - mips_cpu.options &= ~MIPS_CPU_FPU; + cpu_data[0].options &= ~MIPS_CPU_FPU; + return 1; } + __setup("nofpu", fpu_disable); diff -urN linux-2.4.21-bk37/arch/mips64/kernel/signal.c linux-2.4.21-bk38/arch/mips64/kernel/signal.c --- linux-2.4.21-bk37/arch/mips64/kernel/signal.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/signal.c 2003-08-24 02:55:58.000000000 -0700 @@ -26,14 +26,13 @@ #include #include #include +#include #define DEBUG_SIG 0 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) extern asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); -extern asmlinkage int (*save_fp_context)(struct sigcontext *sc); -extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc); extern asmlinkage void syscall_trace(void); @@ -75,35 +74,7 @@ /* * Atomically swap in the new signal mask, and wait for a signal. */ -asmlinkage inline int -sys_sigsuspend(abi64_no_regargs, struct pt_regs regs) -{ - sigset_t *uset, saveset, newset; - - save_static(®s); - uset = (sigset_t *) regs.regs[4]; - if (copy_from_user(&newset, uset, sizeof(sigset_t))) - return -EFAULT; - sigdelsetmask(&newset, ~_BLOCKABLE); - - spin_lock_irq(¤t->sigmask_lock); - saveset = current->blocked; - current->blocked = newset; - recalc_sigpending(current); - spin_unlock_irq(¤t->sigmask_lock); - - regs.regs[2] = EINTR; - regs.regs[7] = 1; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (do_signal(&saveset, ®s)) - return -EINTR; - } -} - -asmlinkage int -sys_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs) +asmlinkage int sys_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs) { sigset_t *unewset, saveset, newset; size_t sigsetsize; @@ -136,47 +107,7 @@ } } -asmlinkage int -sys_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) -{ - struct k_sigaction new_ka, old_ka; - int ret; - int err = 0; - - if (act) { - old_sigset_t mask; - - if (!access_ok(VERIFY_READ, act, sizeof(*act))) - return -EFAULT; - err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler); - err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); - err |= __get_user(mask, &act->sa_mask.sig[0]); - err |= __get_user(new_ka.sa.sa_restorer, &act->sa_restorer); - if (err) - return -EFAULT; - - siginitset(&new_ka.sa.sa_mask, mask); - } - - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); - - if (!ret && oact) { - if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact))) - return -EFAULT; - err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); - err |= __put_user(old_ka.sa.sa_handler, &oact->sa_handler); - err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig); - err |= __put_user(0, &oact->sa_mask.sig[1]); - err |= __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer); - if (err) - return -EFAULT; - } - - return ret; -} - -asmlinkage int -sys_sigaltstack(abi64_no_regargs, struct pt_regs regs) +asmlinkage int sys_sigaltstack(abi64_no_regargs, struct pt_regs regs) { const stack_t *uss = (const stack_t *) regs.regs[4]; stack_t *uoss = (stack_t *) regs.regs[5]; @@ -185,58 +116,8 @@ return do_sigaltstack(uss, uoss, usp); } -static inline int restore_thread_fp_context(struct sigcontext *sc) -{ - u64 *pfreg = ¤t->thread.fpu.soft.regs[0]; - int err = 0; - - /* - * Copy all 32 64-bit values. - */ - -#define restore_fpr(i) \ - do { err |= __get_user(pfreg[i], &sc->sc_fpregs[i]); } while(0) - - restore_fpr( 0); restore_fpr( 1); restore_fpr( 2); restore_fpr( 3); - restore_fpr( 4); restore_fpr( 5); restore_fpr( 6); restore_fpr( 7); - restore_fpr( 8); restore_fpr( 9); restore_fpr(10); restore_fpr(11); - restore_fpr(12); restore_fpr(13); restore_fpr(14); restore_fpr(15); - restore_fpr(16); restore_fpr(17); restore_fpr(18); restore_fpr(19); - restore_fpr(20); restore_fpr(21); restore_fpr(22); restore_fpr(23); - restore_fpr(24); restore_fpr(25); restore_fpr(26); restore_fpr(27); - restore_fpr(28); restore_fpr(29); restore_fpr(30); restore_fpr(31); - - err |= __get_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr); - - return err; -} - -static inline int save_thread_fp_context(struct sigcontext *sc) -{ - u64 *pfreg = ¤t->thread.fpu.soft.regs[0]; - int err = 0; - -#define save_fpr(i) \ - do { err |= __put_user(pfreg[i], &sc->sc_fpregs[i]); } while(0) - - save_fpr( 0); save_fpr( 1); save_fpr( 2); save_fpr( 3); - save_fpr( 4); save_fpr( 5); save_fpr( 6); save_fpr( 7); - save_fpr( 8); save_fpr( 9); save_fpr(10); save_fpr(11); - save_fpr(12); save_fpr(13); save_fpr(14); save_fpr(15); - save_fpr(16); save_fpr(17); save_fpr(18); save_fpr(19); - save_fpr(20); save_fpr(21); save_fpr(22); save_fpr(23); - save_fpr(24); save_fpr(25); save_fpr(26); save_fpr(27); - save_fpr(28); save_fpr(29); save_fpr(30); save_fpr(31); - - err |= __put_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr); - - return err; -} - -asmlinkage int -restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) +asmlinkage int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) { - int owned_fp; int err = 0; err |= __get_user(regs->cp0_epc, &sc->sc_pc); @@ -259,35 +140,20 @@ restore_gp_reg(31); #undef restore_gp_reg - err |= __get_user(owned_fp, &sc->sc_ownedfp); err |= __get_user(current->used_math, &sc->sc_used_math); - if (owned_fp) { - err |= restore_fp_context(sc); - goto out; - } - - if (IS_FPU_OWNER()) { - /* Signal handler acquired FPU - give it back */ - CLEAR_FPU_OWNER(); - regs->cp0_status &= ~ST0_CU1; - } if (current->used_math) { - /* Undo possible contamination of thread state */ - err |= restore_thread_fp_context(sc); + /* restore fpu context if we have used it before */ + own_fpu(); + err |= restore_fp_context(sc); + } else { + /* signal handler may have used FPU. Give it up. */ + lose_fpu(); } -out: return err; } -struct sigframe { - u32 sf_ass[4]; /* argument save space for o32 */ - u32 sf_code[2]; /* signal trampoline */ - struct sigcontext sf_sc; - sigset_t sf_mask; -}; - struct rt_sigframe { u32 rs_ass[4]; /* argument save space for o32 */ u32 rs_code[2]; /* signal trampoline */ @@ -295,42 +161,6 @@ struct ucontext rs_uc; }; -asmlinkage void sys_sigreturn(abi64_no_regargs, struct pt_regs regs) -{ - struct sigframe *frame; - sigset_t blocked; - - frame = (struct sigframe *) regs.regs[29]; - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) - goto badframe; - if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked))) - goto badframe; - - sigdelsetmask(&blocked, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); - current->blocked = blocked; - recalc_sigpending(current); - spin_unlock_irq(¤t->sigmask_lock); - - if (restore_sigcontext(®s, &frame->sf_sc)) - goto badframe; - - /* - * Don't let your children do this ... - */ - if (current->ptrace & PT_TRACESYS) - syscall_trace(); - __asm__ __volatile__( - "move\t$29, %0\n\t" - "j\tret_from_sys_call" - :/* no outputs */ - :"r" (®s)); - /* Unreached */ - -badframe: - force_sig(SIGSEGV, current); -} - asmlinkage void sys_rt_sigreturn(abi64_no_regargs, struct pt_regs regs) { struct rt_sigframe *frame; @@ -372,10 +202,8 @@ force_sig(SIGSEGV, current); } -static int inline setup_sigcontext(struct pt_regs *regs, - struct sigcontext *sc) +int inline setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) { - int owned_fp; int err = 0; err |= __put_user(regs->cp0_epc, &sc->sc_pc); @@ -400,25 +228,20 @@ err |= __put_user(regs->cp0_cause, &sc->sc_cause); err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); - owned_fp = IS_FPU_OWNER(); - err |= __put_user(owned_fp, &sc->sc_ownedfp); err |= __put_user(current->used_math, &sc->sc_used_math); if (!current->used_math) goto out; - /* There exists FP thread state that may be trashed by signal */ - if (owned_fp) { - /* fp is active. Save context from FPU */ - err |= save_fp_context(sc); - goto out; - } - - /* - * Someone else has FPU. - * Copy Thread context into signal context + /* + * Save FPU state to signal context. Signal handler will "inherit" + * current FPU state. */ - err |= save_thread_fp_context(sc); + if (!is_fpu_owner()) { + own_fpu(); + restore_fp(current); + } + err |= save_fp_context(sc); out: return err; @@ -428,7 +251,7 @@ * Determine which stack to use.. */ static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, - size_t frame_size) + size_t frame_size) { unsigned long sp; @@ -449,97 +272,25 @@ return (void *)((sp - frame_size) & ALMASK); } -static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs, - int signr, sigset_t *set) +static void inline setup_rt_frame(struct k_sigaction * ka, + struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) { - struct sigframe *frame; + struct rt_sigframe *frame; int err = 0; frame = get_sigframe(ka, regs, sizeof(*frame)); if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto give_sigsegv; - /* Set up to return from userspace. If provided, use a stub already - in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) - regs->regs[31] = (unsigned long) ka->sa.sa_restorer; - else { - /* - * Set up the return code ... - * - * li v0, __NR_sigreturn - * syscall - */ - err |= __put_user(0x24020000 + __NR_sigreturn, - frame->sf_code + 0); - err |= __put_user(0x0000000c , - frame->sf_code + 1); - flush_cache_sigtramp((unsigned long) frame->sf_code); - } - - err |= setup_sigcontext(regs, &frame->sf_sc); - err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); - if (err) - goto give_sigsegv; - /* - * Arguments to signal handler: - * - * a0 = signal number - * a1 = 0 (should be cause) - * a2 = pointer to struct sigcontext + * Set up the return code ... * - * $25 and c0_epc point to the signal handler, $29 points to the - * struct sigframe. + * li v0, __NR_rt_sigreturn + * syscall */ - regs->regs[ 4] = signr; - regs->regs[ 5] = 0; - regs->regs[ 6] = (unsigned long) &frame->sf_sc; - regs->regs[29] = (unsigned long) frame; - regs->regs[31] = (unsigned long) frame->sf_code; - regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; - -#if DEBUG_SIG - printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n", - current->comm, current->pid, - frame, regs->cp0_epc, frame->sf_code); -#endif - return; - -give_sigsegv: - if (signr == SIGSEGV) - ka->sa.sa_handler = SIG_DFL; - force_sig(SIGSEGV, current); -} - -static void inline setup_rt_frame(struct k_sigaction * ka, - struct pt_regs *regs, int signr, - sigset_t *set, siginfo_t *info) -{ - struct rt_sigframe *frame; - int err = 0; - - frame = get_sigframe(ka, regs, sizeof(*frame)); - if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) - goto give_sigsegv; - - /* Set up to return from userspace. If provided, use a stub already - in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) - regs->regs[31] = (unsigned long) ka->sa.sa_restorer; - else { - /* - * Set up the return code ... - * - * li v0, __NR_rt_sigreturn - * syscall - */ - err |= __put_user(0x24020000 + __NR_rt_sigreturn, - frame->rs_code + 0); - err |= __put_user(0x0000000c , - frame->rs_code + 1); - flush_cache_sigtramp((unsigned long) frame->rs_code); - } + err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0); + err |= __put_user(0x0000000c , frame->rs_code + 1); + flush_cache_sigtramp((unsigned long) frame->rs_code); /* Create siginfo. */ err |= copy_siginfo_to_user(&frame->rs_info, info); @@ -579,7 +330,7 @@ #if DEBUG_SIG printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n", current->comm, current->pid, - frame, regs->cp0_epc, frame->rs_code); + frame, regs->cp0_epc, regs->regs[31]); #endif return; @@ -589,14 +340,18 @@ force_sig(SIGSEGV, current); } +extern void setup_rt_frame_n32(struct k_sigaction * ka, + struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info); + static inline void handle_signal(unsigned long sig, struct k_sigaction *ka, - siginfo_t *info, sigset_t *oldset, - struct pt_regs *regs) + siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { - if (ka->sa.sa_flags & SA_SIGINFO) +#ifdef CONFIG_MIPS32_N32 + if ((current->thread.mflags & MF_ABI_MASK) == MF_N32) + setup_rt_frame_n32 (ka, regs, sig, oldset, info); + else +#endif setup_rt_frame(ka, regs, sig, oldset, info); - else - setup_frame(ka, regs, sig, oldset); if (ka->sa.sa_flags & SA_ONESHOT) ka->sa.sa_handler = SIG_DFL; @@ -609,8 +364,7 @@ } } -static inline void syscall_restart(struct pt_regs *regs, - struct k_sigaction *ka) +static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) { switch(regs->regs[0]) { case ERESTARTNOHAND: @@ -639,7 +393,7 @@ siginfo_t info; #ifdef CONFIG_BINFMT_ELF32 - if (current->thread.mflags & MF_32BIT) { + if ((current->thread.mflags & MF_ABI_MASK) == MF_O32) { return do_signal32(oldset, regs); } #endif diff -urN linux-2.4.21-bk37/arch/mips64/kernel/signal32.c linux-2.4.21-bk38/arch/mips64/kernel/signal32.c --- linux-2.4.21-bk37/arch/mips64/kernel/signal32.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/signal32.c 2003-08-24 02:55:58.000000000 -0700 @@ -25,14 +25,13 @@ #include #include #include +#include #define DEBUG_SIG 0 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) extern asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs); -extern asmlinkage int (*save_fp_context)(struct sigcontext *sc); -extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc); extern asmlinkage void syscall_trace(void); @@ -52,8 +51,6 @@ unsigned int sa_flags; __sighandler32_t sa_handler; sigset32_t sa_mask; - unsigned int sa_restorer; - int sa_resv[1]; /* reserved */ }; /* IRIX compatible stack_t */ @@ -63,6 +60,14 @@ int ss_flags; } stack32_t; +struct ucontext32 { + u32 uc_flags; + s32 uc_link; + stack32_t uc_stack; + struct sigcontext32 uc_mcontext; + sigset_t32 uc_sigmask; /* mask last for extensibility */ +}; + extern void __put_sigset_unknown_nsig(void); extern void __get_sigset_unknown_nsig(void); @@ -190,8 +195,6 @@ &act->sa_handler); err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); err |= __get_user(mask, &act->sa_mask.sig[0]); - err |= __get_user((u32)(u64)new_ka.sa.sa_restorer, - &act->sa_restorer); if (err) return -EFAULT; @@ -210,8 +213,6 @@ err |= __put_user(0, &oact->sa_mask.sig[1]); err |= __put_user(0, &oact->sa_mask.sig[2]); err |= __put_user(0, &oact->sa_mask.sig[3]); - err |= __put_user((u32)(u64)old_ka.sa.sa_restorer, - &oact->sa_restorer); if (err) return -EFAULT; } @@ -257,58 +258,9 @@ return ret; } -static inline int restore_thread_fp_context(struct sigcontext *sc) -{ - u64 *pfreg = ¤t->thread.fpu.soft.regs[0]; - int err = 0; - - /* - * Copy all 32 64-bit values. - */ - -#define restore_fpr(i) \ - do { err |= __get_user(pfreg[i], &sc->sc_fpregs[i]); } while(0) - - restore_fpr( 0); restore_fpr( 1); restore_fpr( 2); restore_fpr( 3); - restore_fpr( 4); restore_fpr( 5); restore_fpr( 6); restore_fpr( 7); - restore_fpr( 8); restore_fpr( 9); restore_fpr(10); restore_fpr(11); - restore_fpr(12); restore_fpr(13); restore_fpr(14); restore_fpr(15); - restore_fpr(16); restore_fpr(17); restore_fpr(18); restore_fpr(19); - restore_fpr(20); restore_fpr(21); restore_fpr(22); restore_fpr(23); - restore_fpr(24); restore_fpr(25); restore_fpr(26); restore_fpr(27); - restore_fpr(28); restore_fpr(29); restore_fpr(30); restore_fpr(31); - - err |= __get_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr); - - return err; -} - -static inline int save_thread_fp_context(struct sigcontext *sc) -{ - u64 *pfreg = ¤t->thread.fpu.soft.regs[0]; - int err = 0; - -#define save_fpr(i) \ - do { err |= __put_user(pfreg[i], &sc->sc_fpregs[i]); } while(0) - - save_fpr( 0); save_fpr( 1); save_fpr( 2); save_fpr( 3); - save_fpr( 4); save_fpr( 5); save_fpr( 6); save_fpr( 7); - save_fpr( 8); save_fpr( 9); save_fpr(10); save_fpr(11); - save_fpr(12); save_fpr(13); save_fpr(14); save_fpr(15); - save_fpr(16); save_fpr(17); save_fpr(18); save_fpr(19); - save_fpr(20); save_fpr(21); save_fpr(22); save_fpr(23); - save_fpr(24); save_fpr(25); save_fpr(26); save_fpr(27); - save_fpr(28); save_fpr(29); save_fpr(30); save_fpr(31); - - err |= __put_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr); - - return err; -} - -static asmlinkage int restore_sigcontext(struct pt_regs *regs, - struct sigcontext *sc) +static asmlinkage int restore_sigcontext32(struct pt_regs *regs, + struct sigcontext32 *sc) { - int owned_fp; int err = 0; err |= __get_user(regs->cp0_epc, &sc->sc_pc); @@ -331,32 +283,24 @@ restore_gp_reg(31); #undef restore_gp_reg - err |= __get_user(owned_fp, &sc->sc_ownedfp); err |= __get_user(current->used_math, &sc->sc_used_math); - if (owned_fp) { - err |= restore_fp_context(sc); - goto out; - } - - if (IS_FPU_OWNER()) { - /* Signal handler acquired FPU - give it back */ - CLEAR_FPU_OWNER(); - regs->cp0_status &= ~ST0_CU1; - } if (current->used_math) { - /* Undo possible contamination of thread state */ - err |= restore_thread_fp_context(sc); + /* restore fpu context if we have used it before */ + own_fpu(); + err |= restore_fp_context32(sc); + } else { + /* signal handler may have used FPU. Give it up. */ + lose_fpu(); } -out: return err; } struct sigframe { u32 sf_ass[4]; /* argument save space for o32 */ u32 sf_code[2]; /* signal trampoline */ - struct sigcontext sf_sc; + struct sigcontext32 sf_sc; sigset_t sf_mask; }; @@ -364,7 +308,7 @@ u32 rs_ass[4]; /* argument save space for o32 */ u32 rs_code[2]; /* signal trampoline */ struct siginfo32 rs_info; - struct ucontext rs_uc; + struct ucontext32 rs_uc; }; static int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from) @@ -426,7 +370,7 @@ recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); - if (restore_sigcontext(®s, &frame->sf_sc)) + if (restore_sigcontext32(®s, &frame->sf_sc)) goto badframe; /* @@ -450,6 +394,7 @@ struct rt_sigframe32 *frame; sigset_t set; stack_t st; + s32 sp; frame = (struct rt_sigframe32 *) regs.regs[29]; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) @@ -463,11 +408,18 @@ recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); - if (restore_sigcontext(®s, &frame->rs_uc.uc_mcontext)) + if (restore_sigcontext32(®s, &frame->rs_uc.uc_mcontext)) goto badframe; - if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st))) + /* The ucontext contains a stack32_t, so we must convert! */ + if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) + goto badframe; + st.ss_size = (long) sp; + if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size)) goto badframe; + if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags)) + goto badframe; + /* It is more difficult to avoid calling this function than to call it and ignore errors. */ do_sigaltstack(&st, NULL, regs.regs[29]); @@ -486,10 +438,9 @@ force_sig(SIGSEGV, current); } -static int inline setup_sigcontext(struct pt_regs *regs, - struct sigcontext *sc) +static int inline setup_sigcontext32(struct pt_regs *regs, + struct sigcontext32 *sc) { - int owned_fp; int err = 0; err |= __put_user(regs->cp0_epc, &sc->sc_pc); @@ -514,25 +465,20 @@ err |= __put_user(regs->cp0_cause, &sc->sc_cause); err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); - owned_fp = IS_FPU_OWNER(); - err |= __put_user(owned_fp, &sc->sc_ownedfp); err |= __put_user(current->used_math, &sc->sc_used_math); if (!current->used_math) goto out; - /* There exists FP thread state that may be trashed by signal */ - if (owned_fp) { - /* fp is active. Save context from FPU */ - err |= save_fp_context(sc); - goto out; - } - - /* - * Someone else has FPU. - * Copy Thread context into signal context + /* + * Save FPU state to signal context. Signal handler will "inherit" + * current FPU state. */ - err |= save_thread_fp_context(sc); + if (!is_fpu_owner()) { + own_fpu(); + restore_fp(current); + } + err |= save_fp_context32(sc); out: return err; @@ -573,25 +519,17 @@ if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto give_sigsegv; - /* Set up to return from userspace. If provided, use a stub already - in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) - regs->regs[31] = (unsigned long) ka->sa.sa_restorer; - else { - /* - * Set up the return code ... - * - * li v0, __NR_Linux32_sigreturn - * syscall - */ - err |= __put_user(0x24020000 + __NR_Linux32_sigreturn, - frame->sf_code + 0); - err |= __put_user(0x0000000c , - frame->sf_code + 1); - flush_cache_sigtramp((unsigned long) frame->sf_code); - } + /* + * Set up the return code ... + * + * li v0, __NR_O32_sigreturn + * syscall + */ + err |= __put_user(0x24020000 + __NR_O32_sigreturn, frame->sf_code + 0); + err |= __put_user(0x0000000c , frame->sf_code + 1); + flush_cache_sigtramp((unsigned long) frame->sf_code); - err |= setup_sigcontext(regs, &frame->sf_sc); + err |= setup_sigcontext32(regs, &frame->sf_sc); err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); if (err) goto give_sigsegv; @@ -632,6 +570,7 @@ { struct rt_sigframe32 *frame; int err = 0; + s32 sp; frame = get_sigframe(ka, regs, sizeof(*frame)); if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) @@ -639,21 +578,15 @@ /* Set up to return from userspace. If provided, use a stub already in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) - regs->regs[31] = (unsigned long) ka->sa.sa_restorer; - else { - /* - * Set up the return code ... - * - * li v0, __NR_Linux32_rt_sigreturn - * syscall - */ - err |= __put_user(0x24020000 + __NR_Linux32_rt_sigreturn, - frame->rs_code + 0); - err |= __put_user(0x0000000c , - frame->rs_code + 1); - flush_cache_sigtramp((unsigned long) frame->rs_code); - } + /* + * Set up the return code ... + * + * li v0, __NR_O32_rt_sigreturn + * syscall + */ + err |= __put_user(0x24020000 + __NR_O32_rt_sigreturn, frame->rs_code + 0); + err |= __put_user(0x0000000c , frame->rs_code + 1); + flush_cache_sigtramp((unsigned long) frame->rs_code); /* Convert (siginfo_t -> siginfo_t32) and copy to user. */ err |= copy_siginfo_to_user32(&frame->rs_info, info); @@ -661,13 +594,14 @@ /* Create the ucontext. */ err |= __put_user(0, &frame->rs_uc.uc_flags); err |= __put_user(0, &frame->rs_uc.uc_link); - err |= __put_user((void *)current->sas_ss_sp, + sp = (int) (long) current->sas_ss_sp; + err |= __put_user(sp, &frame->rs_uc.uc_stack.ss_sp); err |= __put_user(sas_ss_flags(regs->regs[29]), &frame->rs_uc.uc_stack.ss_flags); err |= __put_user(current->sas_ss_size, &frame->rs_uc.uc_stack.ss_size); - err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext); + err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext); err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set)); if (err) @@ -876,11 +810,14 @@ if (set && get_user (s, set)) return -EFAULT; + set_fs (KERNEL_DS); ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL); set_fs (old_fs); + if (!ret && oset && put_user (s, oset)) return -EFAULT; + return ret; } @@ -921,8 +858,6 @@ err |= __get_user((u32)(u64)new_sa.sa.sa_handler, &act->sa_handler); err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags); - err |= __get_user((u32)(u64)new_sa.sa.sa_restorer, - &act->sa_restorer); err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask); if (err) return -EFAULT; @@ -939,8 +874,6 @@ err |= __put_user((u32)(u64)old_sa.sa.sa_handler, &oact->sa_handler); err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags); - err |= __put_user((u32)(u64)old_sa.sa.sa_restorer, - &oact->sa_restorer); err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask); if (err) return -EFAULT; @@ -991,12 +924,114 @@ return ret; } -asmlinkage void sys32_rt_sigtimedwait(void) +struct timespec32 { + int tv_sec; + int tv_nsec; +}; + +asmlinkage int sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo, + struct timespec32 *uts, __kernel_size_t32 sigsetsize) { - panic("%s called.", __FUNCTION__); + int ret, sig; + sigset_t these; + sigset_t32 these32; + struct timespec ts; + siginfo_t info; + long timeout = 0; + + /* + * As the result of a brainfarting competition a few years ago the + * size of sigset_t for the 32-bit kernel was choosen to be 128 bits + * but nothing so far is actually using that many, 64 are enough. So + * for now we just drop the high bits. + */ + if (copy_from_user (&these32, uthese, sizeof(old_sigset_t32))) + return -EFAULT; + + switch (_NSIG_WORDS) { +#ifdef __MIPSEB__ + case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32); + case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32); + case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32); + case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32); +#endif +#ifdef __MIPSEL__ + case 4: these.sig[3] = these32.sig[7] | (((long)these32.sig[6]) << 32); + case 3: these.sig[2] = these32.sig[5] | (((long)these32.sig[4]) << 32); + case 2: these.sig[1] = these32.sig[3] | (((long)these32.sig[2]) << 32); + case 1: these.sig[0] = these32.sig[1] | (((long)these32.sig[0]) << 32); +#endif + } + + /* + * Invert the set of allowed signals to get those we + * want to block. + */ + sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP)); + signotset(&these); + + if (uts) { + if (get_user (ts.tv_sec, &uts->tv_sec) || + get_user (ts.tv_nsec, &uts->tv_nsec)) + return -EINVAL; + if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0 + || ts.tv_sec < 0) + return -EINVAL; + } + + spin_lock_irq(¤t->sigmask_lock); + sig = dequeue_signal(&these, &info); + if (!sig) { + /* None ready -- temporarily unblock those we're interested + in so that we'll be awakened when they arrive. */ + sigset_t oldblocked = current->blocked; + sigandsets(¤t->blocked, ¤t->blocked, &these); + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + + timeout = MAX_SCHEDULE_TIMEOUT; + if (uts) + timeout = (timespec_to_jiffies(&ts) + + (ts.tv_sec || ts.tv_nsec)); + + current->state = TASK_INTERRUPTIBLE; + timeout = schedule_timeout(timeout); + + spin_lock_irq(¤t->sigmask_lock); + sig = dequeue_signal(&these, &info); + current->blocked = oldblocked; + recalc_sigpending(current); + } + spin_unlock_irq(¤t->sigmask_lock); + + if (sig) { + ret = sig; + if (uinfo) { + if (copy_siginfo_to_user32(uinfo, &info)) + ret = -EFAULT; + } + } else { + ret = -EAGAIN; + if (timeout) + ret = -EINTR; + } + + return ret; } -asmlinkage void sys32_rt_sigqueueinfo(void) +extern asmlinkage int sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo); + +asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo) { - panic("%s called.", __FUNCTION__); + siginfo_t info; + int ret; + mm_segment_t old_fs = get_fs(); + + if (copy_from_user (&info, uinfo, 3*sizeof(int)) || + copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE)) + return -EFAULT; + set_fs (KERNEL_DS); + ret = sys_rt_sigqueueinfo(pid, sig, &info); + set_fs (old_fs); + return ret; } diff -urN linux-2.4.21-bk37/arch/mips64/kernel/signal_n32.c linux-2.4.21-bk38/arch/mips64/kernel/signal_n32.c --- linux-2.4.21-bk37/arch/mips64/kernel/signal_n32.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/signal_n32.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2003 Broadcom Corporation + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) + +/* IRIX compatible stack_t */ +typedef struct sigaltstack32 { + s32 ss_sp; + __kernel_size_t32 ss_size; + int ss_flags; +} stack32_t; + +struct ucontextn32 { + u32 uc_flags; + s32 uc_link; + stack32_t uc_stack; + struct sigcontext uc_mcontext; + sigset_t uc_sigmask; /* mask last for extensibility */ +}; + +struct rt_sigframe_n32 { + u32 rs_ass[4]; /* argument save space for o32 */ + u32 rs_code[2]; /* signal trampoline */ + struct siginfo rs_info; + struct ucontextn32 rs_uc; +}; + +extern asmlinkage int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc); +extern int inline setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc); + +asmlinkage void sysn32_rt_sigreturn(abi64_no_regargs, struct pt_regs regs) +{ + struct rt_sigframe_n32 *frame; + sigset_t set; + stack_t st; + s32 sp; + + frame = (struct rt_sigframe_n32 *) regs.regs[29]; + if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sigmask_lock); + current->blocked = set; + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + + if (restore_sigcontext(®s, &frame->rs_uc.uc_mcontext)) + goto badframe; + + /* The ucontext contains a stack32_t, so we must convert! */ + if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) + goto badframe; + st.ss_size = (long) sp; + if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size)) + goto badframe; + if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags)) + goto badframe; + + /* It is more difficult to avoid calling this function than to + call it and ignore errors. */ + do_sigaltstack(&st, NULL, regs.regs[29]); + + /* + * Don't let your children do this ... + */ + __asm__ __volatile__( + "move\t$29, %0\n\t" + "j\tret_from_sys_call" + :/* no outputs */ + :"r" (®s)); + /* Unreached */ + +badframe: + force_sig(SIGSEGV, current); +} + +/* + * Determine which stack to use.. + */ +static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, + size_t frame_size) +{ + unsigned long sp; + + /* Default to using normal stack */ + sp = regs->regs[29]; + + /* + * FPU emulator may have it's own trampoline active just + * above the user stack, 16-bytes before the next lowest + * 16 byte boundary. Try to avoid trashing it. + */ + sp -= 32; + + /* This is the X/Open sanctioned signal stack switching. */ + if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp)) + sp = current->sas_ss_sp + current->sas_ss_size; + + return (void *)((sp - frame_size) & ALMASK); +} + +void setup_rt_frame_n32(struct k_sigaction * ka, + struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) +{ + struct rt_sigframe_n32 *frame; + int err = 0; + s32 sp; + + frame = get_sigframe(ka, regs, sizeof(*frame)); + if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) + goto give_sigsegv; + + /* + * Set up the return code ... + * + * li v0, __NR_rt_sigreturn + * syscall + */ + err |= __put_user(0x24020000 + __NR_N32_rt_sigreturn, frame->rs_code + 0); + err |= __put_user(0x0000000c , frame->rs_code + 1); + flush_cache_sigtramp((unsigned long) frame->rs_code); + + /* Create siginfo. */ + err |= copy_siginfo_to_user(&frame->rs_info, info); + + /* Create the ucontext. */ + err |= __put_user(0, &frame->rs_uc.uc_flags); + err |= __put_user(0, &frame->rs_uc.uc_link); + sp = (int) (long) current->sas_ss_sp; + err |= __put_user(sp, + &frame->rs_uc.uc_stack.ss_sp); + err |= __put_user(sas_ss_flags(regs->regs[29]), + &frame->rs_uc.uc_stack.ss_flags); + err |= __put_user(current->sas_ss_size, + &frame->rs_uc.uc_stack.ss_size); + err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext); + err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set)); + + if (err) + goto give_sigsegv; + + /* + * Arguments to signal handler: + * + * a0 = signal number + * a1 = 0 (should be cause) + * a2 = pointer to ucontext + * + * $25 and c0_epc point to the signal handler, $29 points to + * the struct rt_sigframe. + */ + regs->regs[ 4] = signr; + regs->regs[ 5] = (unsigned long) &frame->rs_info; + regs->regs[ 6] = (unsigned long) &frame->rs_uc; + regs->regs[29] = (unsigned long) frame; + regs->regs[31] = (unsigned long) frame->rs_code; + regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; + +#if DEBUG_SIG + printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n", + current->comm, current->pid, + frame, regs->cp0_epc, regs->regs[31]); +#endif + return; + +give_sigsegv: + if (signr == SIGSEGV) + ka->sa.sa_handler = SIG_DFL; + force_sig(SIGSEGV, current); +} diff -urN linux-2.4.21-bk37/arch/mips64/kernel/smp.c linux-2.4.21-bk38/arch/mips64/kernel/smp.c --- linux-2.4.21-bk37/arch/mips64/kernel/smp.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/smp.c 2003-08-24 02:55:58.000000000 -0700 @@ -43,9 +43,7 @@ spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; int smp_threads_ready; /* Not used */ atomic_t smp_commenced = ATOMIC_INIT(0); -struct cpuinfo_mips cpu_data[NR_CPUS]; -// static atomic_t cpus_booted = ATOMIC_INIT(0); atomic_t cpus_booted = ATOMIC_INIT(0); int smp_num_cpus = 1; /* Number that came online. */ @@ -104,6 +102,7 @@ { unsigned int cpu = smp_processor_id(); + cpu_probe(); prom_init_secondary(); per_cpu_trap_init(); @@ -138,7 +137,7 @@ core_send_ipi(cpu, SMP_RESCHEDULE_YOURSELF); } -static spinlock_t call_lock = SPIN_LOCK_UNLOCKED; +spinlock_t smp_call_lock = SPIN_LOCK_UNLOCKED; struct call_data_struct *call_data; @@ -170,7 +169,7 @@ if (wait) atomic_set(&data.finished, 0); - spin_lock(&call_lock); + spin_lock(&smp_call_lock); call_data = &data; /* Send a message to all other CPUs and wait for them to respond */ @@ -186,7 +185,7 @@ if (wait) while (atomic_read(&data.finished) != cpus) barrier(); - spin_unlock(&call_lock); + spin_unlock(&smp_call_lock); return 0; } @@ -224,7 +223,7 @@ */ clear_bit(smp_processor_id(), &cpu_online_map); /* May need to service _machine_restart IPI */ - __sti(); + local_irq_enable(); /* XXXKW wait if available? */ for (;;); } @@ -282,7 +281,7 @@ int i; for (i = 0; i < smp_num_cpus; i++) if (smp_processor_id() != i) - CPU_CONTEXT(i, mm) = 0; + cpu_context(i, mm) = 0; } local_flush_tlb_mm(mm); } @@ -314,7 +313,7 @@ int i; for (i = 0; i < smp_num_cpus; i++) if (smp_processor_id() != i) - CPU_CONTEXT(i, mm) = 0; + cpu_context(i, mm) = 0; } local_flush_tlb_range(mm, start, end); } @@ -338,7 +337,7 @@ int i; for (i = 0; i < smp_num_cpus; i++) if (smp_processor_id() != i) - CPU_CONTEXT(i, vma->vm_mm) = 0; + cpu_context(i, vma->vm_mm) = 0; } local_flush_tlb_page(vma, page); } diff -urN linux-2.4.21-bk37/arch/mips64/kernel/syscall.c linux-2.4.21-bk38/arch/mips64/kernel/syscall.c --- linux-2.4.21-bk37/arch/mips64/kernel/syscall.c 2003-08-24 02:55:49.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips64/kernel/syscall.c 2003-08-24 02:55:58.000000000 -0700 @@ -50,9 +50,11 @@ return res; } -#define COLOUR_ALIGN(addr,pgoff) \ - ((((addr)+SHMLBA-1)&~(SHMLBA-1)) + \ - (((pgoff)< #include #include +#include #include #include #include #include +#include #include #include @@ -28,9 +31,14 @@ #include #include -/* This is for machines which generate the exact clock. */ -#define USECS_PER_JIFFY (1000000/HZ) -#define USECS_PER_JIFFY_FRAC ((u32)((1000000ULL << 32) / HZ)) +/* + * The integer part of the number of usecs per jiffy is taken from tick, + * but the fractional part is not recorded, so we calculate it using the + * initial value of HZ. This aids systems where tick isn't really an + * integer (e.g. for HZ = 128). + */ +#define USECS_PER_JIFFY tick +#define USECS_PER_JIFFY_FRAC ((unsigned long)(u32)((1000000ULL << 32) / HZ)) /* * forward reference @@ -38,11 +46,14 @@ extern rwlock_t xtime_lock; extern volatile unsigned long wall_jiffies; +spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; + /* * whether we emulate local_timer_interrupts for SMP machines. */ int emulate_local_timer_interrupt; + /* * By default we provide the null RTC ops */ @@ -58,6 +69,85 @@ unsigned long (*rtc_get_time)(void) = null_rtc_get_time; int (*rtc_set_time)(unsigned long) = null_rtc_set_time; +int (*rtc_set_mmss)(unsigned long); + + +/* usecs per counter cycle, shifted to left by 32 bits */ +static unsigned int sll32_usecs_per_cycle; + +/* how many counter cycles in a jiffy */ +static unsigned long cycles_per_jiffy; + +/* Cycle counter value at the previous timer interrupt.. */ +static unsigned int timerhi, timerlo; + +/* expirelo is the count value for next CPU timer interrupt */ +static unsigned int expirelo; + + +/* + * Null timer ack for systems not needing one (e.g. i8254). + */ +static void null_timer_ack(void) { /* nothing */ } + +/* + * Null high precision timer functions for systems lacking one. + */ +static unsigned int null_hpt_read(void) +{ + return 0; +} + +static void null_hpt_init(unsigned int count) { /* nothing */ } + + +/* + * Timer ack for a R4k-compatible timer of a known frequency. + */ +static void c0_fixed_timer_ack(void) +{ + unsigned int count; + + /* Ack this timer interrupt and set the next one. */ + expirelo += cycles_per_jiffy; + write_c0_compare(expirelo); + + /* Check to see if we have missed any timer interrupts. */ + count = read_c0_count(); + if ((count - expirelo) < 0x7fffffff) { + /* missed_timer_count++; */ + expirelo = count + cycles_per_jiffy; + write_c0_compare(expirelo); + } +} + +/* + * High precision timer functions for a R4k-compatible timer. + */ +static unsigned int c0_hpt_read(void) +{ + return read_c0_count(); +} + +/* For unknown frequency. */ +static void c0_hpt_init(unsigned int count) +{ + write_c0_count(read_c0_count() - count); +} + +/* For a known frequency. Used as an interrupt source. */ +static void c0_fixed_hpt_init(unsigned int count) +{ + expirelo = cycles_per_jiffy; + count = read_c0_count() - count; + write_c0_count(0); + write_c0_compare(cycles_per_jiffy); + write_c0_count(count); +} + +void (*mips_timer_ack)(void); +unsigned int (*mips_hpt_read)(void); +void (*mips_hpt_init)(unsigned int); /* @@ -65,22 +155,23 @@ */ void do_gettimeofday(struct timeval *tv) { - unsigned long flags; + unsigned long flags, lost; + + read_lock_irqsave(&xtime_lock, flags); - read_lock_irqsave (&xtime_lock, flags); *tv = xtime; tv->tv_usec += do_gettimeoffset(); - /* - * xtime is atomically updated in timer_bh. jiffies - wall_jiffies - * is nonzero if the timer bottom half hasnt executed yet. + * xtime is atomically updated in timer_bh. jiffies - wall_jiffies + * is nonzero if the timer bottom half hasn't executed yet. */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; + lost = jiffies - wall_jiffies; + if (lost) + tv->tv_usec += lost * USECS_PER_JIFFY; - read_unlock_irqrestore (&xtime_lock, flags); + read_unlock_irqrestore(&xtime_lock, flags); - if (tv->tv_usec >= 1000000) { + while (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; tv->tv_sec++; } @@ -88,27 +179,29 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq (&xtime_lock); + write_lock_irq(&xtime_lock); - /* This is revolting. We need to set the xtime.tv_usec - * correctly. However, the value in this location is - * is value at the last tick. - * Discover what correction gettimeofday - * would have done, and then undo it! + /* + * This is revolting. We need to set "xtime" correctly. However, + * the value in this location is the value at the most recent update + * of wall time. Discover what correction gettimeofday() would have + * done, and then undo it! */ tv->tv_usec -= do_gettimeoffset(); + tv->tv_usec -= (jiffies - wall_jiffies) * USECS_PER_JIFFY; - if (tv->tv_usec < 0) { + while (tv->tv_usec < 0) { tv->tv_usec += 1000000; tv->tv_sec--; } + xtime = *tv; time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq (&xtime_lock); + write_unlock_irq(&xtime_lock); } @@ -119,76 +212,61 @@ * If the exact CPU counter frequency is known, use fixed_rate_gettimeoffset. * Otherwise use calibrate_gettimeoffset() * - * If the CPU does not have counter register all, you can either supply - * your own gettimeoffset() routine, or use null_gettimeoffset() routines, - * which gives the same resolution as HZ. + * If the CPU does not have the counter register, you can either supply + * your own gettimeoffset() routine, or use null_gettimeoffset(), which + * gives the same resolution as HZ. */ +static unsigned long null_gettimeoffset(void) +{ + return 0; +} -/* This is for machines which generate the exact clock. */ -#define USECS_PER_JIFFY (1000000/HZ) - -/* usecs per counter cycle, shifted to left by 32 bits */ -static unsigned int sll32_usecs_per_cycle=0; - -/* how many counter cycles in a jiffy */ -static unsigned long cycles_per_jiffy=0; - -/* Cycle counter value at the previous timer interrupt.. */ -static unsigned int timerhi, timerlo; - -/* last time when xtime and rtc are sync'ed up */ -static long last_rtc_update; -/* the function pointer to one of the gettimeoffset funcs*/ +/* The function pointer to one of the gettimeoffset funcs. */ unsigned long (*do_gettimeoffset)(void) = null_gettimeoffset; -unsigned long null_gettimeoffset(void) -{ - return 0; -} -unsigned long fixed_rate_gettimeoffset(void) +static unsigned long fixed_rate_gettimeoffset(void) { u32 count; unsigned long res; /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = mips_hpt_read(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; - __asm__("multu\t%1,%2\n\t" - "mfhi\t%0" - :"=r" (res) - :"r" (count), - "r" (sll32_usecs_per_cycle)); + __asm__("multu %1,%2" + : "=h" (res) + : "r" (count), "r" (sll32_usecs_per_cycle) + : "lo", "accum"); /* * Due to possible jiffies inconsistencies, we need to check * the result so that we'll get a timer that is monotonic. */ if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY-1; + res = USECS_PER_JIFFY - 1; return res; } + /* - * Cached "1/(clocks per usec)*2^32" value. + * Cached "1/(clocks per usec) * 2^32" value. * It has to be recalculated once each jiffy. */ static unsigned long cached_quotient; /* Last jiffy when calibrate_divXX_gettimeoffset() was called. */ -static unsigned long last_jiffies = 0; - +static unsigned long last_jiffies; /* - * This is copied from dec/time.c:do_ioasic_gettimeoffset() by Mercij. + * This is moved from dec/time.c:do_ioasic_gettimeoffset() by Maciej. */ -unsigned long calibrate_div32_gettimeoffset(void) +static unsigned long calibrate_div32_gettimeoffset(void) { u32 count; unsigned long res, tmp; @@ -204,20 +282,21 @@ unsigned long r0; do_div64_32(r0, timerhi, timerlo, tmp); do_div64_32(quotient, USECS_PER_JIFFY, - USECS_PER_JIFFY_FRAC, r0); + USECS_PER_JIFFY_FRAC, r0); cached_quotient = quotient; } } /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = mips_hpt_read(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; - __asm__("multu %2,%3" - : "=l" (tmp), "=h" (res) - : "r" (count), "r" (quotient)); + __asm__("multu %1,%2" + : "=h" (res) + : "r" (count), "r" (quotient) + : "lo", "accum"); /* * Due to possible jiffies inconsistencies, we need to check @@ -229,7 +308,7 @@ return res; } -unsigned long calibrate_div64_gettimeoffset(void) +static unsigned long calibrate_div64_gettimeoffset(void) { u32 count; unsigned long res, tmp; @@ -239,54 +318,56 @@ quotient = cached_quotient; - if (tmp && last_jiffies != tmp) { + if (last_jiffies != tmp) { last_jiffies = tmp; - __asm__(".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "lwu\t%0,%2\n\t" - "dsll32\t$1,%1,0\n\t" - "or\t$1,$1,%0\n\t" - "ddivu\t$0,$1,%3\n\t" - "mflo\t$1\n\t" - "dsll32\t%0,%4,0\n\t" - "nop\n\t" - "ddivu\t$0,%0,$1\n\t" - "mflo\t%0\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=&r" (quotient) - :"r" (timerhi), - "m" (timerlo), - "r" (tmp), - "r" (USECS_PER_JIFFY)); - cached_quotient = quotient; + if (last_jiffies) { + unsigned long r0; + __asm__(".set push\n\t" + ".set mips3\n\t" + "lwu %0,%3\n\t" + "dsll32 %1,%2,0\n\t" + "or %1,%1,%0\n\t" + "ddivu $0,%1,%4\n\t" + "dsll32 %0,%5,0\n\t" + "or %0,%0,%6\n\t" + "mflo %1\n\t" + "ddivu $0,%0,%1\n\t" + "mflo %0\n\t" + ".set pop" + : "=&r" (quotient), "=&r" (r0) + : "r" (timerhi), "m" (timerlo), + "r" (tmp), "r" (USECS_PER_JIFFY), + "r" (USECS_PER_JIFFY_FRAC) + : "hi", "lo", "accum"); + cached_quotient = quotient; + } } /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = mips_hpt_read(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; - __asm__("multu\t%1,%2\n\t" - "mfhi\t%0" - :"=r" (res) - :"r" (count), - "r" (quotient)); + __asm__("multu %1,%2" + : "=h" (res) + : "r" (count), "r" (quotient) + : "lo", "accum"); /* * Due to possible jiffies inconsistencies, we need to check * the result so that we'll get a timer that is monotonic. */ if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY-1; + res = USECS_PER_JIFFY - 1; return res; } +/* last time when xtime and rtc are sync'ed up */ +static long last_rtc_update; + /* * local_timer_interrupt() does profiling and process accounting * on a per-CPU basis. @@ -299,7 +380,7 @@ */ void local_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - if(!user_mode(regs)) { + if (!user_mode(regs)) { if (prof_buffer && current->pid) { extern int _stext; unsigned long pc = regs->cp0_epc; @@ -311,44 +392,32 @@ * put them into the last histogram slot, so if * present, they will show up as a sharp peak. */ - if (pc > prof_len-1) - pc = prof_len-1; + if (pc > prof_len - 1) + pc = prof_len - 1; atomic_inc((atomic_t *)&prof_buffer[pc]); } } -#if defined(CONFIG_SMP) +#ifdef CONFIG_SMP /* in UP mode, update_process_times() is invoked by do_timer() */ update_process_times(user_mode(regs)); #endif } /* - * high-level timer interrupt service routines. This function + * High-level timer interrupt service routines. This function * is set as irqaction->handler and is invoked through do_IRQ. */ void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - if (mips_cpu.options & MIPS_CPU_COUNTER) { - unsigned int count; + unsigned int count; - /* - * The cycle counter is only 32 bit which is good for about - * a minute at current count rates of upto 150MHz or so. - */ - count = read_32bit_cp0_register(CP0_COUNT); - timerhi += (count < timerlo); /* Wrap around */ - timerlo = count; + count = mips_hpt_read(); + mips_timer_ack(); - /* - * set up for next timer interrupt - no harm if the machine - * is using another timer interrupt source. - * Note that writing to COMPARE register clears the interrupt - */ - write_32bit_cp0_register (CP0_COMPARE, - count + cycles_per_jiffy); - - } + /* Update timerhi/timerlo for intra-jiffy calibration. */ + timerhi += count < timerlo; /* Wrap around */ + timerlo = count; /* * call the generic timer interrupt handling @@ -360,27 +429,28 @@ * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be * called as close as possible to 500 ms before the new second starts. */ - read_lock (&xtime_lock); + read_lock(&xtime_lock); if ((time_status & STA_UNSYNC) == 0 && xtime.tv_sec > last_rtc_update + 660 && xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 && xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) { - if (rtc_set_time(xtime.tv_sec) == 0) { + if (rtc_set_mmss(xtime.tv_sec) == 0) { last_rtc_update = xtime.tv_sec; } else { - last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ + last_rtc_update = xtime.tv_sec - 600; } } - read_unlock (&xtime_lock); + read_unlock(&xtime_lock); /* - * If jiffies has overflowed in this timer_interrupt we must + * If jiffies has overflown in this timer_interrupt, we must * update the timer[hi]/[lo] to make fast gettimeoffset funcs * quotient calc still valid. -arca */ if (!jiffies) { timerhi = timerlo = 0; + mips_hpt_init(count); } #if !defined(CONFIG_SMP) @@ -391,7 +461,7 @@ * In SMP mode, local_timer_interrupt() is invoked by appropriate * low-level local timer interrupt handler. */ - local_timer_interrupt(0, NULL, regs); + local_timer_interrupt(irq, dev_id, regs); #else /* CONFIG_SMP */ @@ -458,73 +528,92 @@ * c) enable the timer interrupt */ -void (*board_time_init)(void) = NULL; -void (*board_timer_setup)(struct irqaction *irq) = NULL; +void (*board_time_init)(void); +void (*board_timer_setup)(struct irqaction *irq); -unsigned int mips_counter_frequency = 0; +unsigned int mips_counter_frequency; static struct irqaction timer_irqaction = { - timer_interrupt, - SA_INTERRUPT, - 0, - "timer", - NULL, - NULL}; + .handler = timer_interrupt, + .flags = SA_INTERRUPT, + .name = "timer", +}; void __init time_init(void) { if (board_time_init) board_time_init(); + if (!rtc_set_mmss) + rtc_set_mmss = rtc_set_time; + xtime.tv_sec = rtc_get_time(); xtime.tv_usec = 0; - /* choose appropriate gettimeoffset routine */ - if (!(mips_cpu.options & MIPS_CPU_COUNTER)) { - /* no cpu counter - sorry */ - do_gettimeoffset = null_gettimeoffset; - } else if (mips_counter_frequency != 0) { - /* we have cpu counter and know counter frequency! */ - do_gettimeoffset = fixed_rate_gettimeoffset; - } else if ((mips_cpu.isa_level == MIPS_CPU_ISA_M32) || - (mips_cpu.isa_level == MIPS_CPU_ISA_I) || - (mips_cpu.isa_level == MIPS_CPU_ISA_II) ) { - /* we need to calibrate the counter but we don't have - * 64-bit division. */ - do_gettimeoffset = calibrate_div32_gettimeoffset; + /* Choose appropriate high precision timer routines. */ + if (!cpu_has_counter && !mips_hpt_read) { + /* No high precision timer -- sorry. */ + mips_hpt_read = null_hpt_read; + mips_hpt_init = null_hpt_init; + } else if (!mips_counter_frequency) { + /* A high precision timer of unknown frequency. */ + if (!mips_hpt_read) { + /* No external high precision timer -- use R4k. */ + mips_hpt_read = c0_hpt_read; + mips_hpt_init = c0_hpt_init; + } + + if ((current_cpu_data.isa_level == MIPS_CPU_ISA_M32) || + (current_cpu_data.isa_level == MIPS_CPU_ISA_I) || + (current_cpu_data.isa_level == MIPS_CPU_ISA_II)) + /* + * We need to calibrate the counter but we don't have + * 64-bit division. + */ + do_gettimeoffset = calibrate_div32_gettimeoffset; + else + /* + * We need to calibrate the counter but we *do* have + * 64-bit division. + */ + do_gettimeoffset = calibrate_div64_gettimeoffset; } else { - /* we need to calibrate the counter but we *do* have - * 64-bit division. */ - do_gettimeoffset = calibrate_div64_gettimeoffset; - } + /* We know counter frequency! */ + if (!mips_hpt_read) { + /* No external high precision timer -- use R4k. */ + mips_hpt_read = c0_hpt_read; + mips_hpt_init = c0_fixed_hpt_init; + + if (!mips_timer_ack) + /* R4k timer interrupt ack. */ + mips_timer_ack = c0_fixed_timer_ack; + } - /* caclulate cache parameters */ - if (mips_counter_frequency) { - u32 count; + do_gettimeoffset = fixed_rate_gettimeoffset; + /* Calculate cache parameters. */ cycles_per_jiffy = mips_counter_frequency / HZ; - /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */ - /* any better way to do this? */ + /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */ + /* Any better way to do this? */ sll32_usecs_per_cycle = mips_counter_frequency / 100000; sll32_usecs_per_cycle = 0xffffffff / sll32_usecs_per_cycle; sll32_usecs_per_cycle *= 10; - - /* - * For those using cpu counter as timer, this sets up the - * first interrupt - */ - count = read_32bit_cp0_register(CP0_COUNT); - write_32bit_cp0_register (CP0_COMPARE, - count + cycles_per_jiffy); } + if (!mips_timer_ack) + /* No timer interrupt ack (e.g. i8254). */ + mips_timer_ack = null_timer_ack; + + /* This sets up the high precision timer for the first interrupt. */ + mips_hpt_init(mips_hpt_read()); + /* * Call board specific timer interrupt setup. * * this pointer must be setup in machine setup routine. * - * Even if the machine choose to use low-level timer interrupt, + * Even if a machine chooses to use a low-level timer interrupt, * it still needs to setup the timer_irqaction. * In that case, it might be better to set timer_irqaction.handler * to be NULL function so that we are sure the high-level code @@ -537,15 +626,15 @@ #define STARTOFTIME 1970 #define SECDAY 86400L #define SECYR (SECDAY * 365) -#define leapyear(year) ((year) % 4 == 0) -#define days_in_year(a) (leapyear(a) ? 366 : 365) -#define days_in_month(a) (month_days[(a) - 1]) +#define leapyear(y) ((!((y) % 4) && ((y) % 100)) || !((y) % 400)) +#define days_in_year(y) (leapyear(y) ? 366 : 365) +#define days_in_month(m) (month_days[(m) - 1]) static int month_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; -void to_tm(unsigned long tim, struct rtc_time * tm) +void to_tm(unsigned long tim, struct rtc_time *tm) { long hms, day, gday; int i; @@ -560,16 +649,16 @@ /* Number of years in days */ for (i = STARTOFTIME; day >= days_in_year(i); i++) - day -= days_in_year(i); + day -= days_in_year(i); tm->tm_year = i; /* Number of months in days left */ if (leapyear(tm->tm_year)) - days_in_month(FEBRUARY) = 29; + days_in_month(FEBRUARY) = 29; for (i = 1; day >= days_in_month(i); i++) - day -= days_in_month(i); + day -= days_in_month(i); days_in_month(FEBRUARY) = 28; - tm->tm_mon = i-1; /* tm_mon starts from 0 to 11 */ + tm->tm_mon = i - 1; /* tm_mon starts from 0 to 11 */ /* Days are what is left over (+1) from all that. */ tm->tm_mday = day + 1; @@ -577,5 +666,10 @@ /* * Determine the day of week */ - tm->tm_wday = (gday + 4) % 7; /* 1970/1/1 was Thursday */ + tm->tm_wday = (gday + 4) % 7; /* 1970/1/1 was Thursday */ } + +EXPORT_SYMBOL(rtc_lock); +EXPORT_SYMBOL(to_tm); +EXPORT_SYMBOL(rtc_set_time); +EXPORT_SYMBOL(rtc_get_time); diff -urN linux-2.4.21-bk37/arch/mips64/kernel/traps.c linux-2.4.21-bk38/arch/mips64/kernel/traps.c --- linux-2.4.21-bk37/arch/mips64/kernel/traps.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/traps.c 2003-08-24 02:55:58.000000000 -0700 @@ -3,11 +3,13 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994 - 1999 by Ralf Baechle + * Copyright (C) 1994 - 1999, 2000, 01 Ralf Baechle * Copyright (C) 1995, 1996 Paul M. Antoine * Copyright (C) 1998 Ulf Carlsson * Copyright (C) 1999 Silicon Graphics, Inc. - * Copyright (C) 2002 Maciej W. Rozycki + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000, 01 MIPS Technologies, Inc. + * Copyright (C) 2002, 2003 Maciej W. Rozycki */ #include #include @@ -21,12 +23,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -47,6 +51,7 @@ extern asmlinkage void handle_ov(void); extern asmlinkage void handle_tr(void); extern asmlinkage void handle_fpe(void); +extern asmlinkage void handle_mdmx(void); extern asmlinkage void handle_watch(void); extern asmlinkage void handle_mcheck(void); extern asmlinkage void handle_reserved(void); @@ -54,12 +59,8 @@ extern int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx); -void fpu_emulator_init_fpu(void); - -char watch_available = 0; -char dedicated_iv_available = 0; - -int (*be_board_handler)(struct pt_regs *regs, int is_fixup); +void (*board_be_init)(void); +int (*board_be_handler)(struct pt_regs *regs, int is_fixup); int kstack_depth_to_print = 24; @@ -69,8 +70,6 @@ */ #define MODULE_RANGE (8*1024*1024) -#define OPCODE 0xfc000000 - /* * If the address is either in the .text section of the * kernel, or in the vmalloc'ed module regions, it *may* @@ -190,7 +189,6 @@ show_trace((long *)tsk->thread.reg29); } - void show_code(unsigned int *pc) { long i; @@ -214,15 +212,15 @@ printk("$0 : %016lx %016lx %016lx %016lx\n", 0UL, regs->regs[1], regs->regs[2], regs->regs[3]); printk("$4 : %016lx %016lx %016lx %016lx\n", - regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); + regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); printk("$8 : %016lx %016lx %016lx %016lx\n", regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]); printk("$12 : %016lx %016lx %016lx %016lx\n", - regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]); + regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]); printk("$16 : %016lx %016lx %016lx %016lx\n", regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]); printk("$20 : %016lx %016lx %016lx %016lx\n", - regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]); + regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]); printk("$24 : %016lx %016lx\n", regs->regs[24], regs->regs[25]); printk("$28 : %016lx %016lx %016lx %016lx\n", @@ -336,7 +334,7 @@ spin_lock_irqsave(&modlist_lock, flags); for (mp = module_list; mp != NULL; mp = mp->next) { if (!mod_member_present(mp, archdata_end) || - !mod_archdata_member_present(mp, struct archdata, + !mod_archdata_member_present(mp, struct archdata, dbe_table_end)) continue; ap = (struct archdata *)(mp->archdata_start); @@ -367,8 +365,8 @@ if (fixup) action = MIPS_BE_FIXUP; - if (be_board_handler) - action = be_board_handler(regs, fixup != 0); + if (board_be_handler) + action = board_be_handler(regs, fixup != 0); switch (action) { case MIPS_BE_DISCARD: @@ -395,12 +393,151 @@ force_sig(SIGBUS, current); } -asmlinkage void do_ov(struct pt_regs *regs) +static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode) { - siginfo_t info; + unsigned int *epc; + + epc = (unsigned int *) regs->cp0_epc + + ((regs->cp0_cause & CAUSEF_BD) != 0); + if (!get_user(*opcode, epc)) + return 0; + + force_sig(SIGSEGV, current); + return 1; +} + +/* + * ll/sc emulation + */ + +#define OPCODE 0xfc000000 +#define BASE 0x03e00000 +#define RT 0x001f0000 +#define OFFSET 0x0000ffff +#define LL 0xc0000000 +#define SC 0xe0000000 + +/* + * The ll_bit is cleared by r*_switch.S + */ + +unsigned long ll_bit; + +static struct task_struct *ll_task = NULL; + +static inline void simulate_ll(struct pt_regs *regs, unsigned int opcode) +{ + unsigned long value, *vaddr; + long offset; + int signal = 0; + + /* + * analyse the ll instruction that just caused a ri exception + * and put the referenced address to addr. + */ + + /* sign extend offset */ + offset = opcode & OFFSET; + offset <<= 16; + offset >>= 16; + + vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset); + + if ((unsigned long)vaddr & 3) { + signal = SIGBUS; + goto sig; + } + if (get_user(value, vaddr)) { + signal = SIGSEGV; + goto sig; + } + + if (ll_task == NULL || ll_task == current) { + ll_bit = 1; + } else { + ll_bit = 0; + } + ll_task = current; - if (compute_return_epc(regs)) + regs->regs[(opcode & RT) >> 16] = value; + + compute_return_epc(regs); + return; + +sig: + force_sig(signal, current); +} + +static inline void simulate_sc(struct pt_regs *regs, unsigned int opcode) +{ + unsigned long *vaddr, reg; + long offset; + int signal = 0; + + /* + * analyse the sc instruction that just caused a ri exception + * and put the referenced address to addr. + */ + + /* sign extend offset */ + offset = opcode & OFFSET; + offset <<= 16; + offset >>= 16; + + vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset); + reg = (opcode & RT) >> 16; + + if ((unsigned long)vaddr & 3) { + signal = SIGBUS; + goto sig; + } + if (ll_bit == 0 || ll_task != current) { + regs->regs[reg] = 0; + compute_return_epc(regs); return; + } + + if (put_user(regs->regs[reg], vaddr)) { + signal = SIGSEGV; + goto sig; + } + + regs->regs[reg] = 1; + + compute_return_epc(regs); + return; + +sig: + force_sig(signal, current); +} + +/* + * ll uses the opcode of lwc0 and sc uses the opcode of swc0. That is both + * opcodes are supposed to result in coprocessor unusable exceptions if + * executed on ll/sc-less processors. That's the theory. In practice a + * few processors such as NEC's VR4100 throw reserved instruction exceptions + * instead, so we're doing the emulation thing in both exception handlers. + */ +static inline int simulate_llsc(struct pt_regs *regs) +{ + unsigned int opcode; + + if (unlikely(get_insn_opcode(regs, &opcode))) + return -EFAULT; + + if ((opcode & OPCODE) == LL) { + simulate_ll(regs, opcode); + return 0; + } + if ((opcode & OPCODE) == SC) { + simulate_sc(regs, opcode); + return 0; + } +} + +asmlinkage void do_ov(struct pt_regs *regs) +{ + siginfo_t info; info.si_code = FPE_INTOVF; info.si_signo = SIGFPE; @@ -444,36 +581,14 @@ /* If something went wrong, signal */ if (sig) - { - /* - * Return EPC is not calculated in the FPU emulator, - * if a signal is being send. So we calculate it here. - */ - compute_return_epc(regs); force_sig(sig, current); - } return; } - if (compute_return_epc(regs)) - return; force_sig(SIGFPE, current); } -static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode) -{ - unsigned long *epc; - - epc = (unsigned long *) regs->cp0_epc + - ((regs->cp0_cause & CAUSEF_BD) != 0); - if (!get_user(opcode, epc)) - return 0; - - force_sig(SIGSEGV, current); - return 1; -} - asmlinkage void do_bp(struct pt_regs *regs) { unsigned int opcode, bcode; @@ -520,7 +635,7 @@ if (get_insn_opcode(regs, &opcode)) return; - /* Immediate versions don't provide a code. */ + /* Immediate versions don't provide a code. */ if (!(opcode & OPCODE)) tcode = ((opcode >> 6) & ((1 << 20) - 1)); @@ -551,8 +666,9 @@ { die_if_kernel("Reserved instruction in kernel code", regs); - if (compute_return_epc(regs)) - return; + if (!cpu_has_llsc) + if (!simulate_llsc(regs)) + return; force_sig(SIGILL, current); } @@ -560,69 +676,53 @@ asmlinkage void do_cpu(struct pt_regs *regs) { unsigned int cpid; - void fpu_emulator_init_fpu(void); - int sig; + + die_if_kernel("do_cpu invoked from kernel context!", regs); cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; - if (cpid != 1) - goto bad_cid; - if (!(mips_cpu.options & MIPS_CPU_FPU)) - goto fp_emul; + switch (cpid) { + case 0: + if (cpu_has_llsc) + break; - regs->cp0_status |= ST0_CU1; + if (!simulate_llsc(regs)) + return; + break; + + case 1: + own_fpu(); + if (current->used_math) { /* Using the FPU again. */ + restore_fp(current); + } else { /* First time FPU user. */ + init_fpu(); + current->used_math = 1; + } + + if (!cpu_has_fpu) { + int sig = fpu_emulator_cop1Handler(0, regs, + ¤t->thread.fpu.soft); + if (sig) + force_sig(sig, current); + } -#ifdef CONFIG_SMP - if (current->used_math) { - lazy_fpu_switch(0, current); - } else { - init_fpu(); - current->used_math = 1; - } - current->flags |= PF_USEDFPU; -#else - if (last_task_used_math == current) return; - if (current->used_math) { /* Using the FPU again. */ - lazy_fpu_switch(last_task_used_math, current); - } else { /* First time FPU user. */ - lazy_fpu_switch(last_task_used_math, 0); - init_fpu(); - current->used_math = 1; + case 2: + case 3: + break; } - last_task_used_math = current; -#endif - return; -fp_emul: - if (last_task_used_math != current) { - if (!current->used_math) { - fpu_emulator_init_fpu(); - current->used_math = 1; - } - } - sig = fpu_emulator_cop1Handler(0, regs, ¤t->thread.fpu.soft); - last_task_used_math = current; - if (sig) { - /* - * Return EPC is not calculated in the FPU emulator, if - * a signal is being send. So we calculate it here. - */ - compute_return_epc(regs); - force_sig(sig, current); - } - return; + force_sig(SIGILL, current); +} -bad_cid: - compute_return_epc(regs); +asmlinkage void do_mdmx(struct pt_regs *regs) +{ force_sig(SIGILL, current); } asmlinkage void do_watch(struct pt_regs *regs) { - extern void dump_tlb_all(void); - /* * We use the watch exception where available to detect stack * overflows. @@ -652,26 +752,9 @@ * caused by a new unknown cpu type or after another deadly * hard/software error. */ + show_regs(regs); panic("Caught reserved exception %ld - should not happen.", - (regs->cp0_cause & 0x1f) >> 2); -} - -static inline void watch_init(unsigned long cputype) -{ - switch(cputype) { - case CPU_R10000: - case CPU_R4000MC: - case CPU_R4400MC: - case CPU_R4000SC: - case CPU_R4400SC: - case CPU_R4000PC: - case CPU_R4400PC: - case CPU_R4200: - case CPU_R4300: - set_except_vector(23, handle_watch); - watch_available = 1; - break; - } + (regs->cp0_cause & 0x7f) >> 2); } unsigned long exception_handlers[32]; @@ -687,7 +770,7 @@ unsigned long old_handler = exception_handlers[n]; exception_handlers[n] = handler; - if (n == 0 && mips_cpu.options & MIPS_CPU_DIVEC) { + if (n == 0 && cpu_has_divec) { *(volatile u32 *)(KSEG0+0x200) = 0x08000000 | (0x03ffffff & (handler >> 2)); flush_icache_range(KSEG0+0x200, KSEG0 + 0x204); @@ -697,164 +780,149 @@ asmlinkage int (*save_fp_context)(struct sigcontext *sc); asmlinkage int (*restore_fp_context)(struct sigcontext *sc); + +asmlinkage int (*save_fp_context32)(struct sigcontext32 *sc); +asmlinkage int (*restore_fp_context32)(struct sigcontext32 *sc); + extern asmlinkage int _save_fp_context(struct sigcontext *sc); extern asmlinkage int _restore_fp_context(struct sigcontext *sc); +extern asmlinkage int _save_fp_context32(struct sigcontext32 *sc); +extern asmlinkage int _restore_fp_context32(struct sigcontext32 *sc); + extern asmlinkage int fpu_emulator_save_context(struct sigcontext *sc); extern asmlinkage int fpu_emulator_restore_context(struct sigcontext *sc); +extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 *sc); +extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 *sc); + void __init per_cpu_trap_init(void) { unsigned int cpu = smp_processor_id(); /* Some firmware leaves the BEV flag set, clear it. */ - clear_cp0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_BEV); - set_cp0_status(ST0_CU0|ST0_FR|ST0_KX|ST0_SX|ST0_UX); + clear_c0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_BEV); + set_c0_status(ST0_CU0|ST0_FR|ST0_KX|ST0_SX|ST0_UX); + + if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV) + set_c0_status(ST0_XX); /* * Some MIPS CPUs have a dedicated interrupt vector which reduces the * interrupt processing overhead. Use it where available. */ - if (mips_cpu.options & MIPS_CPU_DIVEC) - set_cp0_cause(CAUSEF_IV); + if (cpu_has_divec) + set_c0_cause(CAUSEF_IV); cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; - set_context(((long)(&pgd_current[cpu])) << 23); - set_wired(0); + write_c0_context(((long)(&pgd_current[cpu])) << 23); + write_c0_wired(0); + + atomic_inc(&init_mm.mm_count); + current->active_mm = &init_mm; + if (current->mm) + BUG(); + enter_lazy_tlb(&init_mm, current, cpu); } void __init trap_init(void) { - extern char except_vec0; - extern char except_vec1_r4k; - extern char except_vec1_r10k; - extern char except_vec2_generic; + extern char except_vec0_generic; extern char except_vec3_generic, except_vec3_r4000; extern char except_vec4; unsigned long i; - int dummy; per_cpu_trap_init(); /* Copy the generic exception handlers to their final destination. */ - memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80); + memcpy((void *) KSEG0 , &except_vec0_generic, 0x80); memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80); /* * Setup default vectors */ - for(i = 0; i <= 31; i++) + for (i = 0; i <= 31; i++) set_except_vector(i, handle_reserved); /* * Only some CPUs have the watch exceptions or a dedicated * interrupt vector. */ - watch_init(mips_cpu.cputype); + if (cpu_has_watch) + set_except_vector(23, handle_watch); /* * Some MIPS CPUs have a dedicated interrupt vector which reduces the * interrupt processing overhead. Use it where available. */ - memcpy((void *)(KSEG0 + 0x200), &except_vec4, 8); - - if (mips_cpu.options & MIPS_CPU_MCHECK) - set_except_vector(24, handle_mcheck); + if (cpu_has_divec) + memcpy((void *)(KSEG0 + 0x200), &except_vec4, 0x8); /* * The Data Bus Errors / Instruction Bus Errors are signaled * by external hardware. Therefore these two exceptions * may have board specific handlers. */ - bus_error_init(); + if (board_be_init) + board_be_init(); - /* - * Handling the following exceptions depends mostly of the cpu type - */ - switch(mips_cpu.cputype) { - case CPU_SB1: -#ifdef CONFIG_SB1_CACHE_ERROR - { - /* Special cache error handler for SB1 */ - extern char except_vec2_sb1; - memcpy((void *)(KSEG0 + 0x100), &except_vec2_sb1, 0x80); - memcpy((void *)(KSEG1 + 0x100), &except_vec2_sb1, 0x80); - } -#endif - /* Enable timer interrupt and scd mapped interrupt */ - clear_cp0_status(0xf000); - set_cp0_status(0xc00); - - /* Fall through. */ - case CPU_R10000: - case CPU_R4000MC: - case CPU_R4400MC: - case CPU_R4000SC: - case CPU_R4400SC: - case CPU_R4000PC: - case CPU_R4400PC: - case CPU_R4200: - case CPU_R4300: - case CPU_R4600: - case CPU_R5000: - case CPU_NEVADA: - case CPU_5KC: - case CPU_20KC: - case CPU_RM7000: - /* Debug TLB refill handler. */ - memcpy((void *)KSEG0, &except_vec0, 0x80); - if ((mips_cpu.options & MIPS_CPU_4KEX) - && (mips_cpu.options & MIPS_CPU_4KTLB)) { - memcpy((void *)KSEG0 + 0x080, &except_vec1_r4k, 0x80); - } else { - memcpy((void *)KSEG0 + 0x080, &except_vec1_r10k, 0x80); - } - if (mips_cpu.options & MIPS_CPU_VCE) { - memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, - 0x80); - } else { - memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, - 0x80); - } + set_except_vector(1, __xtlb_mod); + set_except_vector(2, __xtlb_tlbl); + set_except_vector(3, __xtlb_tlbs); + set_except_vector(4, handle_adel); + set_except_vector(5, handle_ades); + + set_except_vector(6, handle_ibe); + set_except_vector(7, handle_dbe); + + set_except_vector(8, handle_sys); + set_except_vector(9, handle_bp); + set_except_vector(10, handle_ri); + set_except_vector(11, handle_cpu); + set_except_vector(12, handle_ov); + set_except_vector(13, handle_tr); + set_except_vector(22, handle_mdmx); - set_except_vector(1, __xtlb_mod); - set_except_vector(2, __xtlb_tlbl); - set_except_vector(3, __xtlb_tlbs); - set_except_vector(4, handle_adel); - set_except_vector(5, handle_ades); - - set_except_vector(6, handle_ibe); - set_except_vector(7, handle_dbe); - - set_except_vector(8, handle_sys); - set_except_vector(9, handle_bp); - set_except_vector(10, handle_ri); - set_except_vector(11, handle_cpu); - set_except_vector(12, handle_ov); - set_except_vector(13, handle_tr); + if (cpu_has_fpu && !cpu_has_nofpuex) set_except_vector(15, handle_fpe); - break; - case CPU_R8000: - panic("R8000 is unsupported"); - break; + if (cpu_has_mcheck) + set_except_vector(24, handle_mcheck); - case CPU_UNKNOWN: - default: - panic("Unknown CPU type"); + if (cpu_has_vce) + memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, 0x100); + else if (cpu_has_4kex) + memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80); + else + memcpy((void *)(KSEG0 + 0x080), &except_vec3_generic, 0x80); + + if (current_cpu_data.cputype == CPU_R6000 || + current_cpu_data.cputype == CPU_R6000A) { + /* + * The R6000 is the only R-series CPU that features a machine + * check exception (similar to the R4000 cache error) and + * unaligned ldc1/sdc1 exception. The handlers have not been + * written yet. Well, anyway there is no R6000 machine on the + * current list of targets for Linux/MIPS. + * (Duh, crap, there is someone with a tripple R6k machine) + */ + //set_except_vector(14, handle_mc); + //set_except_vector(15, handle_ndc); } - flush_icache_range(KSEG0, KSEG0 + 0x200); - if (mips_cpu.options & MIPS_CPU_FPU) { - save_fp_context = _save_fp_context; + if (cpu_has_fpu) { + save_fp_context = _save_fp_context; restore_fp_context = _restore_fp_context; + save_fp_context32 = _save_fp_context32; + restore_fp_context32 = _restore_fp_context32; } else { save_fp_context = fpu_emulator_save_context; restore_fp_context = fpu_emulator_restore_context; + save_fp_context32 = fpu_emulator_save_context32; + restore_fp_context32 = fpu_emulator_restore_context32; } - if (mips_cpu.isa_level == MIPS_CPU_ISA_IV) - set_cp0_status(ST0_XX); + flush_icache_range(KSEG0, KSEG0 + 0x400); atomic_inc(&init_mm.mm_count); /* XXX UP? */ current->active_mm = &init_mm; diff -urN linux-2.4.21-bk37/arch/mips64/kernel/unaligned.c linux-2.4.21-bk38/arch/mips64/kernel/unaligned.c --- linux-2.4.21-bk37/arch/mips64/kernel/unaligned.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/kernel/unaligned.c 2003-08-24 02:55:58.000000000 -0700 @@ -88,21 +88,21 @@ #define STR(x) __STR(x) #define __STR(x) #x -/* - * User code may only access USEG; kernel code may access the - * entire address space. - */ -#define check_axs(pc,a,s) \ - if ((long)(~(pc) & ((a) | ((a)+(s)))) < 0) \ - goto sigbus; +#ifdef CONFIG_PROC_FS +unsigned long unaligned_instructions; +#endif static inline int emulate_load_store_insn(struct pt_regs *regs, - unsigned long addr, unsigned long pc) + void *addr, unsigned long pc, + unsigned long **regptr, unsigned long *newvalue) { union mips_instruction insn; unsigned long value, fixup; + unsigned int res; regs->regs[0] = 0; + *regptr=NULL; + /* * This load never faults. */ @@ -142,183 +142,295 @@ * The remaining opcodes are the ones that are really of interest. */ case lh_op: - check_axs(pc, addr, 2); - __asm__( - ".set\tnoat\n" + if (verify_area(VERIFY_READ, addr, 2)) + goto sigbus; + + __asm__ __volatile__ (".set\tnoat\n" #ifdef __BIG_ENDIAN - "1:\tlb\t%0,0(%1)\n" - "2:\tlbu\t$1,1(%1)\n\t" + "1:\tlb\t%0, 0(%2)\n" + "2:\tlbu\t$1, 1(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tlb\t%0,1(%1)\n" - "2:\tlbu\t$1,0(%1)\n\t" + "1:\tlb\t%0, 1(%2)\n" + "2:\tlbu\t$1, 0(%2)\n\t" #endif - "sll\t%0,0x8\n\t" - "or\t%0,$1\n\t" - ".set\tat\n\t" + "sll\t%0, 0x8\n\t" + "or\t%0, $1\n\t" + "li\t%1, 0\n" + "3:\t.set\tat\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault)); - regs->regs[insn.i_format.rt] = value; - return 0; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; case lw_op: - check_axs(pc, addr, 4); - __asm__( + if (verify_area(VERIFY_READ, addr, 4)) + goto sigbus; + + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tlwl\t%0,(%1)\n" - "2:\tlwr\t%0,3(%1)\n\t" + "1:\tlwl\t%0, (%2)\n" + "2:\tlwr\t%0, 3(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tlwl\t%0,3(%1)\n" - "2:\tlwr\t%0,(%1)\n\t" + "1:\tlwl\t%0, 3(%2)\n" + "2:\tlwr\t%0, (%2)\n\t" #endif + "li\t%1, 0\n" + "3:\t.section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault)); - regs->regs[insn.i_format.rt] = value; - return 0; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; case lhu_op: - check_axs(pc, addr, 2); - __asm__( + if (verify_area(VERIFY_READ, addr, 2)) + goto sigbus; + + __asm__ __volatile__ ( ".set\tnoat\n" #ifdef __BIG_ENDIAN - "1:\tlbu\t%0,0(%1)\n" - "2:\tlbu\t$1,1(%1)\n\t" + "1:\tlbu\t%0, 0(%2)\n" + "2:\tlbu\t$1, 1(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tlbu\t%0,1(%1)\n" - "2:\tlbu\t$1,0(%1)\n\t" + "1:\tlbu\t%0, 1(%2)\n" + "2:\tlbu\t$1, 0(%2)\n\t" #endif - "sll\t%0,0x8\n\t" - "or\t%0,$1\n\t" - ".set\tat\n\t" + "sll\t%0, 0x8\n\t" + "or\t%0, $1\n\t" + "li\t%1, 0\n" + "3:\t.set\tat\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault)); - regs->regs[insn.i_format.rt] = value; - return 0; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; case lwu_op: - check_axs(pc, addr, 4); - __asm__( +#ifdef CONFIG_MIPS64 + /* + * A 32-bit kernel might be running on a 64-bit processor. But + * if we're on a 32-bit processor and an i-cache incoherency + * or race makes us see a 64-bit instruction here the sdl/sdr + * would blow up, so for now we don't handle unaligned 64-bit + * instructions on 32-bit kernels. + */ + if (verify_area(VERIFY_READ, addr, 4)) + goto sigbus; + + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tlwl\t%0,(%1)\n" - "2:\tlwr\t%0,3(%1)\n\t" + "1:\tlwl\t%0, (%2)\n" + "2:\tlwr\t%0, 3(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tlwl\t%0,3(%1)\n" - "2:\tlwr\t%0,(%1)\n\t" + "1:\tlwl\t%0, 3(%2)\n" + "2:\tlwr\t%0, (%2)\n\t" #endif + "dsll\t%0, %0, 32\n\t" + "dsrl\t%0, %0, 32\n\t" + "li\t%1, 0\n" + "3:\t.section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault)); - value &= 0xffffffff; - regs->regs[insn.i_format.rt] = value; - return 0; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; +#endif /* CONFIG_MIPS64 */ + + /* Cannot handle 64-bit instructions in 32-bit kernel */ + goto sigill; case ld_op: - check_axs(pc, addr, 8); - __asm__( - ".set\tmips3\n" +#ifdef CONFIG_MIPS64 + /* + * A 32-bit kernel might be running on a 64-bit processor. But + * if we're on a 32-bit processor and an i-cache incoherency + * or race makes us see a 64-bit instruction here the sdl/sdr + * would blow up, so for now we don't handle unaligned 64-bit + * instructions on 32-bit kernels. + */ + if (verify_area(VERIFY_READ, addr, 8)) + goto sigbus; + + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tldl\t%0,(%1)\n" - "2:\tldr\t%0,7(%1)\n\t" + "1:\tldl\t%0, (%2)\n" + "2:\tldr\t%0, 7(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tldl\t%0,7(%1)\n" - "2:\tldr\t%0,(%1)\n\t" + "1:\tldl\t%0, 7(%2)\n" + "2:\tldr\t%0, (%2)\n\t" #endif - ".set\tmips0\n\t" + "li\t%1, 0\n" + "3:\t.section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault)); - regs->regs[insn.i_format.rt] = value; - return 0; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; +#endif /* CONFIG_MIPS64 */ + + /* Cannot handle 64-bit instructions in 32-bit kernel */ + goto sigill; case sh_op: - check_axs(pc, addr, 2); + if (verify_area(VERIFY_WRITE, addr, 2)) + goto sigbus; + value = regs->regs[insn.i_format.rt]; - __asm__( + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN ".set\tnoat\n" - "1:\tsb\t%0,1(%1)\n\t" - "srl\t$1,%0,0x8\n" - "2:\tsb\t$1,0(%1)\n\t" + "1:\tsb\t%1, 1(%2)\n\t" + "srl\t$1, %1, 0x8\n" + "2:\tsb\t$1, 0(%2)\n\t" ".set\tat\n\t" #endif #ifdef __LITTLE_ENDIAN ".set\tnoat\n" - "1:\tsb\t%0,0(%1)\n\t" - "srl\t$1,%0,0x8\n" - "2:\tsb\t$1,1(%1)\n\t" + "1:\tsb\t%1, 0(%2)\n\t" + "srl\t$1,%1, 0x8\n" + "2:\tsb\t$1, 1(%2)\n\t" ".set\tat\n\t" #endif + "li\t%0, 0\n" + "3:\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%0, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - : /* no outputs */ - :"r" (value), "r" (addr), "i" (&&fault)); - return 0; + : "=r" (res) + : "r" (value), "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + break; case sw_op: - check_axs(pc, addr, 4); + if (verify_area(VERIFY_WRITE, addr, 4)) + goto sigbus; + value = regs->regs[insn.i_format.rt]; - __asm__( + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tswl\t%0,(%1)\n" - "2:\tswr\t%0,3(%1)\n\t" + "1:\tswl\t%1,(%2)\n" + "2:\tswr\t%1, 3(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tswl\t%0,3(%1)\n" - "2:\tswr\t%0,(%1)\n\t" + "1:\tswl\t%1, 3(%2)\n" + "2:\tswr\t%1, (%2)\n\t" #endif + "li\t%0, 0\n" + "3:\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%0, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - : /* no outputs */ - :"r" (value), "r" (addr), "i" (&&fault)); - return 0; + : "=r" (res) + : "r" (value), "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + break; case sd_op: - check_axs(pc, addr, 8); +#ifdef CONFIG_MIPS64 + /* + * A 32-bit kernel might be running on a 64-bit processor. But + * if we're on a 32-bit processor and an i-cache incoherency + * or race makes us see a 64-bit instruction here the sdl/sdr + * would blow up, so for now we don't handle unaligned 64-bit + * instructions on 32-bit kernels. + */ + if (verify_area(VERIFY_WRITE, addr, 8)) + goto sigbus; + value = regs->regs[insn.i_format.rt]; - __asm__( - ".set\tmips3\n" + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tsdl\t%0,(%1)\n" - "2:\tsdr\t%0,7(%1)\n\t" + "1:\tsdl\t%1,(%2)\n" + "2:\tsdr\t%1, 7(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tsdl\t%0,7(%1)\n" - "2:\tsdr\t%0,(%1)\n\t" + "1:\tsdl\t%1, 7(%2)\n" + "2:\tsdr\t%1, (%2)\n\t" #endif - ".set\tmips0\n\t" + "li\t%0, 0\n" + "3:\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%0, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - : /* no outputs */ - :"r" (value), "r" (addr), "i" (&&fault)); - return 0; + : "=r" (res) + : "r" (value), "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + break; +#endif /* CONFIG_MIPS64 */ + + /* Cannot handle 64-bit instructions in 32-bit kernel */ + goto sigill; case lwc1_op: case ldc1_op: @@ -347,6 +459,11 @@ */ goto sigill; } + +#ifdef CONFIG_PROC_FS + unaligned_instructions++; +#endif + return 0; fault: @@ -363,52 +480,48 @@ die_if_kernel ("Unhandled kernel unaligned access", regs); send_sig(SIGSEGV, current, 1); + return 0; + sigbus: - die_if_kernel ("Unhandled kernel unaligned access", regs); + die_if_kernel("Unhandled kernel unaligned access", regs); send_sig(SIGBUS, current, 1); + return 0; + sigill: - die_if_kernel ("Unhandled kernel unaligned access or invalid instruction", regs); + die_if_kernel("Unhandled kernel unaligned access or invalid instruction", regs); send_sig(SIGILL, current, 1); + return 0; } -#ifdef CONFIG_PROC_FS -unsigned long unaligned_instructions; -#endif - asmlinkage void do_ade(struct pt_regs *regs) { - unsigned long pc; + unsigned long *regptr, newval; extern int do_dsemulret(struct pt_regs *); - -#if 0 - printk("ade: Cpu%d[%s:%d:%0lx:%0lx]\n", smp_processor_id(), - current->comm, current->pid, regs->cp0_badvaddr, regs->cp0_epc); -#endif + mm_segment_t seg; + unsigned long pc; /* - * Address errors may be deliberately induced - * by the FPU emulator to take retake control - * of the CPU after executing the instruction - * in the delay slot of an emulated branch. + * Address errors may be deliberately induced by the FPU emulator to + * retake control of the CPU after executing the instruction in the + * delay slot of an emulated branch. */ /* Terminate if exception was recognized as a delay slot return */ if (do_dsemulret(regs)) return; - /* Otherwise handle as normal */ + /* Otherwise handle as normal */ /* * Did we catch a fault trying to load an instruction? - * This also catches attempts to activate MIPS16 code on - * CPUs which don't support it. + * Or are we running in MIPS16 mode? */ - if (regs->cp0_badvaddr == regs->cp0_epc) + if ((regs->cp0_badvaddr == regs->cp0_epc) || (regs->cp0_epc & 0x1)) goto sigbus; - pc = regs->cp0_epc + ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0); + pc = exception_epc(regs); if ((current->thread.mflags & MF_FIXADE) == 0) goto sigbus; @@ -416,16 +529,28 @@ * Do branch emulation only if we didn't forward the exception. * This is all so but ugly ... */ - if (!emulate_load_store_insn(regs, regs->cp0_badvaddr, pc)) + seg = get_fs(); + if (!user_mode(regs)) + set_fs(KERNEL_DS); + if (!emulate_load_store_insn(regs, (void *)regs->cp0_badvaddr, pc, + ®ptr, &newval)) { compute_return_epc(regs); - -#ifdef CONFIG_PROC_FS - unaligned_instructions++; -#endif + /* + * Now that branch is evaluated, update the dest + * register if necessary + */ + if (regptr) + *regptr = newval; + } + set_fs(seg); return; sigbus: die_if_kernel("Kernel unaligned instruction access", regs); force_sig(SIGBUS, current); + + /* + * XXX On return from the signal handler we should advance the epc + */ } diff -urN linux-2.4.21-bk37/arch/mips64/ld.script.elf32.S linux-2.4.21-bk38/arch/mips64/ld.script.elf32.S --- linux-2.4.21-bk37/arch/mips64/ld.script.elf32.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/ld.script.elf32.S 2003-08-24 02:55:58.000000000 -0700 @@ -77,6 +77,14 @@ { _fdata = . ; *(.data) + + /* Align the initial ramdisk image (INITRD) on page boundaries. */ + . = ALIGN(4096); + __rd_start = .; + *(.initrd) + . = ALIGN(4096); + __rd_end = .; + CONSTRUCTORS } .data1 : { *(.data1) } diff -urN linux-2.4.21-bk37/arch/mips64/ld.script.elf64 linux-2.4.21-bk38/arch/mips64/ld.script.elf64 --- linux-2.4.21-bk37/arch/mips64/ld.script.elf64 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/ld.script.elf64 2003-08-24 02:55:58.000000000 -0700 @@ -86,6 +86,14 @@ { _fdata = . ; *(.data) + + /* Align the initial ramdisk image (INITRD) on page boundaries. */ + . = ALIGN(4096); + __rd_start = .; + *(.initrd) + . = ALIGN(4096); + __rd_end = .; + CONSTRUCTORS } .data1 : { *(.data1) } diff -urN linux-2.4.21-bk37/arch/mips64/lib/Makefile linux-2.4.21-bk38/arch/mips64/lib/Makefile --- linux-2.4.21-bk37/arch/mips64/lib/Makefile 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips64/lib/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -6,12 +6,12 @@ L_TARGET = lib.a -obj-y += csum_partial.o csum_partial_copy.o dump_tlb.o rtc-std.o \ +obj-y += csum_partial.o csum_partial_copy.o dump_tlb.o promlib.o rtc-std.o \ rtc-no.o memset.o memcpy.o strlen_user.o strncpy_user.o \ strnlen_user.o watch.o obj-$(CONFIG_BLK_DEV_FD) += floppy-no.o floppy-std.o -obj-$(CONFIG_IDE) += ide-std.o ide-no.o -obj-$(CONFIG_PC_KEYB) += kbd-std.o kbd-no.o +obj-$(subst m,y,$(CONFIG_IDE)) += ide-std.o ide-no.o # needed for ide module +obj-$(CONFIG_PC_KEYB) += kbd-std.o include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/arch/mips64/lib/dump_tlb.c linux-2.4.21-bk38/arch/mips64/lib/dump_tlb.c --- linux-2.4.21-bk37/arch/mips64/lib/dump_tlb.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips64/lib/dump_tlb.c 2003-08-24 02:55:58.000000000 -0700 @@ -36,22 +36,22 @@ unsigned long s_entryhi, entryhi, entrylo0, entrylo1, asid; unsigned int s_index, pagemask, c0, c1, i; - s_entryhi = get_entryhi(); - s_index = get_index(); + s_entryhi = read_c0_entryhi(); + s_index = read_c0_index(); asid = s_entryhi & 0xff; for (i = first; i <= last; i++) { - write_32bit_cp0_register(CP0_INDEX, i); + write_c0_index(i); __asm__ __volatile__( ".set\tnoreorder\n\t" "nop;nop;nop;nop\n\t" "tlbr\n\t" "nop;nop;nop;nop\n\t" ".set\treorder"); - pagemask = read_32bit_cp0_register(CP0_PAGEMASK); - entryhi = get_entryhi(); - entrylo0 = get_entrylo0(); - entrylo1 = get_entrylo1(); + pagemask = read_c0_pagemask(); + entryhi = read_c0_entryhi(); + entrylo0 = read_c0_entrylo0(); + entrylo1 = read_c0_entrylo1(); /* Unused entries have a virtual address of CKSEG0. */ if ((entryhi & ~0x1ffffUL) != CKSEG0 @@ -81,22 +81,22 @@ } printk("\n"); - set_entryhi(s_entryhi); - set_index(s_index); + write_c0_entryhi(s_entryhi); + write_c0_index(s_index); } void dump_tlb_all(void) { - dump_tlb(0, mips_cpu.tlbsize - 1); + dump_tlb(0, current_cpu_data.tlbsize - 1); } void dump_tlb_wired(void) { int wired; - wired = read_32bit_cp0_register(CP0_WIRED); + wired = read_c0_wired(); printk("Wired: %d", wired); - dump_tlb(0, read_32bit_cp0_register(CP0_WIRED)); + dump_tlb(0, read_c0_wired()); } #define BARRIER \ @@ -107,19 +107,19 @@ void dump_tlb_addr(unsigned long addr) { - unsigned int flags, oldpid; + unsigned long flags, oldpid; int index; - __save_and_cli(flags); - oldpid = get_entryhi() & 0xff; + local_irq_save(flags); + oldpid = read_c0_entryhi() & 0xff; BARRIER; - set_entryhi((addr & PAGE_MASK) | oldpid); + write_c0_entryhi((addr & PAGE_MASK) | oldpid); BARRIER; tlb_probe(); BARRIER; - index = get_index(); - set_entryhi(oldpid); - __restore_flags(flags); + index = read_c0_index(); + write_c0_entryhi(oldpid); + local_irq_restore(flags); if (index < 0) { printk("No entry for address 0x%08lx in TLB\n", addr); @@ -132,7 +132,7 @@ void dump_tlb_nonwired(void) { - dump_tlb(read_32bit_cp0_register(CP0_WIRED), mips_cpu.tlbsize - 1); + dump_tlb(read_c0_wired(), current_cpu_data.tlbsize - 1); } void dump_list_process(struct task_struct *t, void *address) @@ -161,7 +161,7 @@ printk("pte == %08lx, ", (unsigned long) pte); page = *pte; - printk("page == %08lx\n", (unsigned long) pte_val(page)); + printk("page == %08lx\n", pte_val(page)); val = pte_val(page); if (val & _PAGE_PRESENT) printk("present "); diff -urN linux-2.4.21-bk37/arch/mips64/lib/ide-no.c linux-2.4.21-bk38/arch/mips64/lib/ide-no.c --- linux-2.4.21-bk37/arch/mips64/lib/ide-no.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/lib/ide-no.c 2003-08-24 02:55:58.000000000 -0700 @@ -29,42 +29,8 @@ { } -static int no_ide_request_irq(unsigned int irq, - void (*handler)(int,void *, struct pt_regs *), - unsigned long flags, const char *device, - void *dev_id) -{ - panic("no_no_ide_request_irq called - shouldn't happen"); -} - -static void no_ide_free_irq(unsigned int irq, void *dev_id) -{ - panic("no_ide_free_irq called - shouldn't happen"); -} - -static int no_ide_check_region(ide_ioreg_t from, unsigned int extent) -{ - panic("no_ide_check_region called - shouldn't happen"); -} - -static void no_ide_request_region(ide_ioreg_t from, unsigned int extent, - const char *name) -{ - panic("no_ide_request_region called - shouldn't happen"); -} - -static void no_ide_release_region(ide_ioreg_t from, unsigned int extent) -{ - panic("no_ide_release_region called - shouldn't happen"); -} - struct ide_ops no_ide_ops = { &no_ide_default_irq, &no_ide_default_io_base, - &no_ide_init_hwif_ports, - &no_ide_request_irq, - &no_ide_free_irq, - &no_ide_check_region, - &no_ide_request_region, - &no_ide_release_region + &no_ide_init_hwif_ports }; diff -urN linux-2.4.21-bk37/arch/mips64/lib/ide-std.c linux-2.4.21-bk38/arch/mips64/lib/ide-std.c --- linux-2.4.21-bk37/arch/mips64/lib/ide-std.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/lib/ide-std.c 2003-08-24 02:55:58.000000000 -0700 @@ -62,42 +62,8 @@ hw->io_ports[IDE_IRQ_OFFSET] = 0; } -static int std_ide_request_irq(unsigned int irq, - void (*handler)(int,void *, struct pt_regs *), - unsigned long flags, const char *device, - void *dev_id) -{ - return request_irq(irq, handler, flags, device, dev_id); -} - -static void std_ide_free_irq(unsigned int irq, void *dev_id) -{ - free_irq(irq, dev_id); -} - -static int std_ide_check_region(ide_ioreg_t from, unsigned int extent) -{ - return check_region(from, extent); -} - -static void std_ide_request_region(ide_ioreg_t from, unsigned int extent, - const char *name) -{ - request_region(from, extent, name); -} - -static void std_ide_release_region(ide_ioreg_t from, unsigned int extent) -{ - release_region(from, extent); -} - struct ide_ops std_ide_ops = { &std_ide_default_irq, &std_ide_default_io_base, - &std_ide_init_hwif_ports, - &std_ide_request_irq, - &std_ide_free_irq, - &std_ide_check_region, - &std_ide_request_region, - &std_ide_release_region + &std_ide_init_hwif_ports }; diff -urN linux-2.4.21-bk37/arch/mips64/lib/kbd-no.c linux-2.4.21-bk38/arch/mips64/lib/kbd-no.c --- linux-2.4.21-bk37/arch/mips64/lib/kbd-no.c 2001-09-09 10:43:01.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips64/lib/kbd-no.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,62 +0,0 @@ -/* - * 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. - * - * Stub keyboard and psaux routines to keep Linux from crashing on machines - * without a keyboard. - * - * Copyright (C) 1998 by Ralf Baechle - */ -#include -#include - -static void no_kbd_request_region(void) -{ - /* No I/O ports are being used on the Indy. */ -} - -static int no_kbd_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - return -ENODEV; -} - -static int no_aux_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - return -ENODEV; -} - -static void no_aux_free_irq(void) -{ -} - -static unsigned char no_kbd_read_input(void) -{ - return 0; -} - -static void no_kbd_write_output(unsigned char val) -{ -} - -static void no_kbd_write_command(unsigned char val) -{ -} - -static unsigned char no_kbd_read_status(void) -{ - return 0; -} - -struct kbd_ops no_kbd_ops = { - no_kbd_request_region, - no_kbd_request_irq, - - no_aux_request_irq, - no_aux_free_irq, - - no_kbd_read_input, - no_kbd_write_output, - no_kbd_write_command, - no_kbd_read_status -}; diff -urN linux-2.4.21-bk37/arch/mips64/lib/memcpy.S linux-2.4.21-bk38/arch/mips64/lib/memcpy.S --- linux-2.4.21-bk37/arch/mips64/lib/memcpy.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/lib/memcpy.S 2003-08-24 02:55:58.000000000 -0700 @@ -5,776 +5,500 @@ * * Unified implementation of memcpy, memmove and the __copy_user backend. * - * Copyright (C) 1998, 1999, 2000, 2001 Ralf Baechle - * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + * Copyright (C) 1998, 99, 2000, 01, 2002 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc. + * Copyright (C) 2002 Broadcom, Inc. + * memcpy/copy_user author: Mark Vandevoorde * - * For __rmemcpy and memmove an exception is always a kernel bug, therefore - * they're not protected. In order to keep the exception fixup routine - * simple all memory accesses in __copy_user to src rsp. dst are stricly - * incremental. The fixup routine depends on $at not being changed. + * Mnemonic names for arguments to memcpy/__copy_user */ +#include #include #include #include +#define dst a0 +#define src a1 +#define len a2 + /* - * The fixup routine for copy_to_user depends on copying strictly in - * increasing order. Gas expands the ulw/usw macros in the wrong order for - * little endian machines, so we cannot depend on them. + * Spec + * + * memcpy copies len bytes from src to dst and sets v0 to dst. + * It assumes that + * - src and dst don't overlap + * - src is readable + * - dst is writable + * memcpy uses the standard calling convention + * + * __copy_user copies up to len bytes from src to dst and sets a2 (len) to + * the number of uncopied bytes due to an exception caused by a read or write. + * __copy_user assumes that src and dst don't overlap, and that the call is + * implementing one of the following: + * copy_to_user + * - src is readable (no exceptions when reading src) + * copy_from_user + * - dst is writable (no exceptions when writing dst) + * __copy_user uses a non-standard calling convention; see + * include/asm-mips/uaccess.h + * + * When an exception happens on a load, the handler must + # ensure that all of the destination buffer is overwritten to prevent + * leaking information to user mode programs. */ -#ifdef __MIPSEB__ -#define uswL swl -#define uswU swr -#define ulwL lwl -#define ulwU lwr -#define usdL sdl -#define usdU sdr -#define uldL ldl -#define uldU ldr -#endif -#ifdef __MIPSEL__ -#define uswL swr -#define uswU swl -#define ulwL lwr -#define ulwU lwl -#define usdL sdr -#define usdU sdl -#define uldL ldr -#define uldU ldl -#endif -#define EX(insn,reg,addr,handler) \ -9: insn reg, addr; \ - .section __ex_table,"a"; \ - PTR 9b, handler; \ - .previous +/* + * Implementation + */ -#define UEX(insn,reg,addr,handler) \ -9: insn ## L reg, addr; \ -10: insn ## U reg, 3 + addr; \ - .section __ex_table,"a"; \ - PTR 9b, handler; \ - PTR 10b, handler; \ - .previous +/* + * The exception handler for loads requires that: + * 1- AT contain the address of the byte just past the end of the source + * of the copy, + * 2- src_entry <= src < AT, and + * 3- (dst - src) == (dst_entry - src_entry), + * The _entry suffix denotes values when __copy_user was called. + * + * (1) is set up up by uaccess.h and maintained by not writing AT in copy_user + * (2) is met by incrementing src by the number of bytes copied + * (3) is met by not doing loads between a pair of increments of dst and src + * + * The exception handlers for stores adjust len (if necessary) and return. + * These handlers do not need to overwrite any data. + * + * For __rmemcpy and memmove an exception is always a kernel bug, therefore + * they're not protected. + */ -#define UEXD(insn,reg,addr,handler) \ -9: insn ## L reg, addr; \ -10: insn ## U reg, 7 + addr; \ - .section __ex_table,"a"; \ - PTR 9b, handler; \ - PTR 10b, handler; \ +#define EXC(inst_reg,addr,handler) \ +9: inst_reg, addr; \ + .section __ex_table,"a"; \ + PTR 9b, handler; \ .previous -/* ascending order, destination aligned */ -#define MOVE_BIGGERCHUNK(src, dst, offset, t0, t1, t2, t3) \ - EX(ld, t0, (offset + 0x00)(src), l_fixup); \ - EX(ld, t1, (offset + 0x08)(src), l_fixup); \ - EX(ld, t2, (offset + 0x10)(src), l_fixup); \ - EX(ld, t3, (offset + 0x18)(src), l_fixup); \ - EX(sd, t0, (offset + 0x00)(dst), s_fixup); \ - EX(sd, t1, (offset + 0x08)(dst), s_fixup); \ - EX(sd, t2, (offset + 0x10)(dst), s_fixup); \ - EX(sd, t3, (offset + 0x18)(dst), s_fixup); \ - EX(ld, t0, (offset + 0x20)(src), l_fixup); \ - EX(ld, t1, (offset + 0x28)(src), l_fixup); \ - EX(ld, t2, (offset + 0x30)(src), l_fixup); \ - EX(ld, t3, (offset + 0x38)(src), l_fixup); \ - EX(sd, t0, (offset + 0x20)(dst), s_fixup); \ - EX(sd, t1, (offset + 0x28)(dst), s_fixup); \ - EX(sd, t2, (offset + 0x30)(dst), s_fixup); \ - EX(sd, t3, (offset + 0x38)(dst), s_fixup) - -/* ascending order, destination aligned */ -#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \ - EX(lw, t0, (offset + 0x00)(src), l_fixup); \ - EX(lw, t1, (offset + 0x04)(src), l_fixup); \ - EX(lw, t2, (offset + 0x08)(src), l_fixup); \ - EX(lw, t3, (offset + 0x0c)(src), l_fixup); \ - EX(sw, t0, (offset + 0x00)(dst), s_fixup); \ - EX(sw, t1, (offset + 0x04)(dst), s_fixup); \ - EX(sw, t2, (offset + 0x08)(dst), s_fixup); \ - EX(sw, t3, (offset + 0x0c)(dst), s_fixup); \ - EX(lw, t0, (offset + 0x10)(src), l_fixup); \ - EX(lw, t1, (offset + 0x14)(src), l_fixup); \ - EX(lw, t2, (offset + 0x18)(src), l_fixup); \ - EX(lw, t3, (offset + 0x1c)(src), l_fixup); \ - EX(sw, t0, (offset + 0x10)(dst), s_fixup); \ - EX(sw, t1, (offset + 0x14)(dst), s_fixup); \ - EX(sw, t2, (offset + 0x18)(dst), s_fixup); \ - EX(sw, t3, (offset + 0x1c)(dst), s_fixup) - -/* ascending order, destination unaligned */ -#define UMOVE_BIGGERCHUNK(src, dst, offset, t0, t1, t2, t3) \ - EX(ld, t0, (offset + 0x00)(src), l_fixup); \ - EX(ld, t1, (offset + 0x08)(src), l_fixup); \ - EX(ld, t2, (offset + 0x10)(src), l_fixup); \ - EX(ld, t3, (offset + 0x18)(src), l_fixup); \ - UEXD(usd, t0, (offset + 0x00)(dst), s_fixup); \ - UEXD(usd, t1, (offset + 0x08)(dst), s_fixup); \ - UEXD(usd, t2, (offset + 0x10)(dst), s_fixup); \ - UEXD(usd, t3, (offset + 0x18)(dst), s_fixup); \ - EX(ld, t0, (offset + 0x20)(src), l_fixup); \ - EX(ld, t1, (offset + 0x28)(src), l_fixup); \ - EX(ld, t2, (offset + 0x30)(src), l_fixup); \ - EX(ld, t3, (offset + 0x38)(src), l_fixup); \ - UEXD(usd, t0, (offset + 0x20)(dst), s_fixup); \ - UEXD(usd, t1, (offset + 0x28)(dst), s_fixup); \ - UEXD(usd, t2, (offset + 0x30)(dst), s_fixup); \ - UEXD(usd, t3, (offset + 0x38)(dst), s_fixup) - -/* ascending order, destination unaligned */ -#define UMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \ - EX(lw, t0, (offset + 0x00)(src), l_fixup); \ - EX(lw, t1, (offset + 0x04)(src), l_fixup); \ - EX(lw, t2, (offset + 0x08)(src), l_fixup); \ - EX(lw, t3, (offset + 0x0c)(src), l_fixup); \ - UEX(usw, t0, (offset + 0x00)(dst), s_fixup); \ - UEX(usw, t1, (offset + 0x04)(dst), s_fixup); \ - UEX(usw, t2, (offset + 0x08)(dst), s_fixup); \ - UEX(usw, t3, (offset + 0x0c)(dst), s_fixup); \ - EX(lw, t0, (offset + 0x10)(src), l_fixup); \ - EX(lw, t1, (offset + 0x14)(src), l_fixup); \ - EX(lw, t2, (offset + 0x18)(src), l_fixup); \ - EX(lw, t3, (offset + 0x1c)(src), l_fixup); \ - UEX(usw, t0, (offset + 0x10)(dst), s_fixup); \ - UEX(usw, t1, (offset + 0x14)(dst), s_fixup); \ - UEX(usw, t2, (offset + 0x18)(dst), s_fixup); \ - UEX(usw, t3, (offset + 0x1c)(dst), s_fixup) +/* + * Only on the 64-bit kernel we can made use of 64-bit registers. + */ +#ifdef CONFIG_MIPS64 +#define USE_DOUBLE +#endif + +#ifdef USE_DOUBLE + +#define LOAD ld +#define LOADL ldl +#define LOADR ldr +#define STOREL sdl +#define STORER sdr +#define STORE sd +#define ADD daddu +#define SUB dsubu +#define SRL dsrl +#define SRA dsra +#define SLL dsll +#define SLLV dsllv +#define SRLV dsrlv +#define NBYTES 8 +#define LOG_NBYTES 3 + +/* + * As we are sharing code base with the mips32 tree (which use the o32 ABI + * register definitions). We need to redefine the register definitions from + * the n64 ABI register naming to the o32 ABI register naming. + */ +#undef t0 +#undef t1 +#undef t2 +#undef t3 +#define t0 $8 +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 + +#else + +#define LOAD lw +#define LOADL lwl +#define LOADR lwr +#define STOREL swl +#define STORER swr +#define STORE sw +#define ADD addu +#define SUB subu +#define SRL srl +#define SLL sll +#define SRA sra +#define SLLV sllv +#define SRLV srlv +#define NBYTES 4 +#define LOG_NBYTES 2 + +#endif /* USE_DOUBLE */ + +#ifdef CONFIG_CPU_LITTLE_ENDIAN +#define LDFIRST LOADR +#define LDREST LOADL +#define STFIRST STORER +#define STREST STOREL +#define SHIFT_DISCARD SLLV +#else +#define LDFIRST LOADL +#define LDREST LOADR +#define STFIRST STOREL +#define STREST STORER +#define SHIFT_DISCARD SRLV +#endif + +#define FIRST(unit) ((unit)*NBYTES) +#define REST(unit) (FIRST(unit)+NBYTES-1) +#define UNIT(unit) FIRST(unit) + +#define ADDRMASK (NBYTES-1) .text .set noreorder .set noat +/* + * A combined memcpy/__copy_user + * __copy_user sets len to 0 for success; else to an upper bound of + * the number of uncopied bytes. + * memcpy sets v0 to dst. + */ .align 5 LEAF(memcpy) /* a0=dst a1=src a2=len */ - move v0, a0 /* return value */ + move v0, dst /* return value */ __memcpy: FEXPORT(__copy_user) - xor ta0, a0, a1 - andi ta0, ta0, 0x7 - move t3, a0 - beqz ta0, can_align - sltiu t8, a2, 0x8 - - b memcpy_u_src # bad alignment - move ta2, a2 - -can_align: - bnez t8, small_memcpy # < 8 bytes to copy - move ta2, a2 - - beqz a2, out - andi t8, a1, 0x1 - -hword_align: - beqz t8, word_align - andi t8, a1, 0x2 - - EX(lb, ta0, (a1), l_fixup) - dsubu a2, a2, 0x1 - EX(sb, ta0, (a0), s_fixup) - daddu a1, a1, 0x1 - daddu a0, a0, 0x1 - andi t8, a1, 0x2 - -word_align: - beqz t8, dword_align - sltiu t8, a2, 56 - - EX(lh, ta0, (a1), l_fixup) - dsubu a2, a2, 0x2 - EX(sh, ta0, (a0), s_fixup) - sltiu t8, a2, 56 - daddu a0, a0, 0x2 - daddu a1, a1, 0x2 - -dword_align: - bnez t8, do_end_words - move t8, a2 - - andi t8, a1, 0x4 - beqz t8, qword_align - andi t8, a1, 0x8 - - EX(lw, ta0, 0x00(a1), l_fixup) - dsubu a2, a2, 0x4 - EX(sw, ta0, 0x00(a0), s_fixup) - daddu a1, a1, 0x4 - daddu a0, a0, 0x4 - andi t8, a1, 0x8 - -qword_align: - beqz t8, oword_align - andi t8, a1, 0x10 - - EX(lw, ta0, 0x00(a1), l_fixup) - EX(lw, ta1, 0x04(a1), l_fixup) - dsubu a2, a2, 0x8 - EX(sw, ta0, 0x00(a0), s_fixup) - EX(sw, ta1, 0x04(a0), s_fixup) - daddu a1, a1, 0x8 - andi t8, a1, 0x10 - daddu a0, a0, 0x8 - -oword_align: - beqz t8, begin_movement - srl t8, a2, 0x7 - - EX(lw, ta3, 0x00(a1), l_fixup) - EX(lw, t0, 0x04(a1), l_fixup) - EX(lw, ta0, 0x08(a1), l_fixup) - EX(lw, ta1, 0x0c(a1), l_fixup) - EX(sw, ta3, 0x00(a0), s_fixup) - EX(sw, t0, 0x04(a0), s_fixup) - EX(sw, ta0, 0x08(a0), s_fixup) - EX(sw, ta1, 0x0c(a0), s_fixup) - dsubu a2, a2, 0x10 - daddu a1, a1, 0x10 - srl t8, a2, 0x7 - daddu a0, a0, 0x10 - -begin_movement: - beqz t8, 0f - andi ta2, a2, 0x40 - -move_128bytes: - PREF (0, 2*128(a0)) - PREF (1, 2*128(a1)) - MOVE_BIGGERCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - MOVE_BIGGERCHUNK(a1, a0, 0x40, ta0, ta1, ta3, t0) - dsubu t8, t8, 0x01 - daddu a1, a1, 0x80 - bnez t8, move_128bytes - daddu a0, a0, 0x80 - -0: - beqz ta2, 1f - andi ta2, a2, 0x20 - -move_64bytes: - MOVE_BIGGERCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - daddu a1, a1, 0x40 - daddu a0, a0, 0x40 + /* + * Note: dst & src may be unaligned, len may be 0 + * Temps + */ +#define rem t8 + /* + * The "issue break"s below are very approximate. + * Issue delays for dcache fills will perturb the schedule, as will + * load queue full replay traps, etc. + * + * If len < NBYTES use byte operations. + */ + PREF( 0, 0(src) ) + PREF( 1, 0(dst) ) + sltu t2, len, NBYTES + and t1, dst, ADDRMASK + PREF( 0, 1*32(src) ) + PREF( 1, 1*32(dst) ) + bnez t2, copy_bytes_checklen + and t0, src, ADDRMASK + PREF( 0, 2*32(src) ) + PREF( 1, 2*32(dst) ) + bnez t1, dst_unaligned + nop + bnez t0, src_unaligned_dst_aligned + /* + * use delay slot for fall-through + * src and dst are aligned; need to compute rem + */ +both_aligned: + SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter + beqz t0, cleanup_both_aligned # len < 8*NBYTES + and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES) + PREF( 0, 3*32(src) ) + PREF( 1, 3*32(dst) ) + .align 4 1: - beqz ta2, do_end_words - andi t8, a2, 0x1c - -move_32bytes: - MOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - andi t8, a2, 0x1c - daddu a1, a1, 0x20 - daddu a0, a0, 0x20 - -do_end_words: - beqz t8, maybe_end_cruft - srl t8, t8, 0x2 - -end_words: - EX(lw, ta0, (a1), l_fixup) - dsubu t8, t8, 0x1 - EX(sw, ta0, (a0), s_fixup) - daddu a1, a1, 0x4 - bnez t8, end_words - daddu a0, a0, 0x4 - -maybe_end_cruft: - andi ta2, a2, 0x3 - -small_memcpy: - beqz ta2, out - move a2, ta2 - -end_bytes: - EX(lb, ta0, (a1), l_fixup) - dsubu a2, a2, 0x1 - EX(sb, ta0, (a0), s_fixup) - daddu a1, a1, 0x1 - bnez a2, end_bytes - daddu a0, a0, 0x1 - -out: jr ra - move a2, zero +EXC( LOAD t0, UNIT(0)(src), l_exc) +EXC( LOAD t1, UNIT(1)(src), l_exc_copy) +EXC( LOAD t2, UNIT(2)(src), l_exc_copy) +EXC( LOAD t3, UNIT(3)(src), l_exc_copy) + SUB len, len, 8*NBYTES +EXC( LOAD t4, UNIT(4)(src), l_exc_copy) +EXC( LOAD t7, UNIT(5)(src), l_exc_copy) +EXC( STORE t0, UNIT(0)(dst), s_exc_p8u) +EXC( STORE t1, UNIT(1)(dst), s_exc_p7u) +EXC( LOAD t0, UNIT(6)(src), l_exc_copy) +EXC( LOAD t1, UNIT(7)(src), l_exc_copy) + ADD src, src, 8*NBYTES + ADD dst, dst, 8*NBYTES +EXC( STORE t2, UNIT(-6)(dst), s_exc_p6u) +EXC( STORE t3, UNIT(-5)(dst), s_exc_p5u) +EXC( STORE t4, UNIT(-4)(dst), s_exc_p4u) +EXC( STORE t7, UNIT(-3)(dst), s_exc_p3u) +EXC( STORE t0, UNIT(-2)(dst), s_exc_p2u) +EXC( STORE t1, UNIT(-1)(dst), s_exc_p1u) + PREF( 0, 8*32(src) ) + PREF( 1, 8*32(dst) ) + bne len, rem, 1b + nop -/* ------------------------------------------------------------------------- */ + /* + * len == rem == the number of bytes left to copy < 8*NBYTES + */ +cleanup_both_aligned: + beqz len, done + sltu t0, len, 4*NBYTES + bnez t0, less_than_4units + and rem, len, (NBYTES-1) # rem = len % NBYTES + /* + * len >= 4*NBYTES + */ +EXC( LOAD t0, UNIT(0)(src), l_exc) +EXC( LOAD t1, UNIT(1)(src), l_exc_copy) +EXC( LOAD t2, UNIT(2)(src), l_exc_copy) +EXC( LOAD t3, UNIT(3)(src), l_exc_copy) + SUB len, len, 4*NBYTES + ADD src, src, 4*NBYTES +EXC( STORE t0, UNIT(0)(dst), s_exc_p4u) +EXC( STORE t1, UNIT(1)(dst), s_exc_p3u) +EXC( STORE t2, UNIT(2)(dst), s_exc_p2u) +EXC( STORE t3, UNIT(3)(dst), s_exc_p1u) + beqz len, done + ADD dst, dst, 4*NBYTES +less_than_4units: + /* + * rem = len % NBYTES + */ + beq rem, len, copy_bytes + nop +1: +EXC( LOAD t0, 0(src), l_exc) + ADD src, src, NBYTES + SUB len, len, NBYTES +EXC( STORE t0, 0(dst), s_exc_p1u) + bne rem, len, 1b + ADD dst, dst, NBYTES -/* Bad, bad. At least try to align the source */ + /* + * src and dst are aligned, need to copy rem bytes (rem < NBYTES) + * A loop would do only a byte at a time with possible branch + * mispredicts. Can't do an explicit LOAD dst,mask,or,STORE + * because can't assume read-access to dst. Instead, use + * STREST dst, which doesn't require read access to dst. + * + * This code should perform better than a simple loop on modern, + * wide-issue mips processors because the code has fewer branches and + * more instruction-level parallelism. + */ +#define bits t2 + beqz len, done + ADD t1, dst, len # t1 is just past last byte of dst + li bits, 8*NBYTES + SLL rem, len, 3 # rem = number of bits to keep +EXC( LOAD t0, 0(src), l_exc) + SUB bits, bits, rem # bits = number of bits to discard + SHIFT_DISCARD t0, t0, bits +EXC( STREST t0, -1(t1), s_exc) + jr ra + move len, zero +dst_unaligned: + /* + * dst is unaligned + * t0 = src & ADDRMASK + * t1 = dst & ADDRMASK; T1 > 0 + * len >= NBYTES + * + * Copy enough bytes to align dst + * Set match = (src and dst have same alignment) + */ +#define match rem +EXC( LDFIRST t3, FIRST(0)(src), l_exc) + ADD t2, zero, NBYTES +EXC( LDREST t3, REST(0)(src), l_exc_copy) + SUB t2, t2, t1 # t2 = number of bytes copied + xor match, t0, t1 +EXC( STFIRST t3, FIRST(0)(dst), s_exc) + beq len, t2, done + SUB len, len, t2 + ADD dst, dst, t2 + beqz match, both_aligned + ADD src, src, t2 + +src_unaligned_dst_aligned: + SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter + PREF( 0, 3*32(src) ) + beqz t0, cleanup_src_unaligned + and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES + PREF( 1, 3*32(dst) ) +1: +/* + * Avoid consecutive LD*'s to the same register since some mips + * implementations can't issue them in the same cycle. + * It's OK to load FIRST(N+1) before REST(N) because the two addresses + * are to the same unit (unless src is aligned, but it's not). + */ +EXC( LDFIRST t0, FIRST(0)(src), l_exc) +EXC( LDFIRST t1, FIRST(1)(src), l_exc_copy) + SUB len, len, 4*NBYTES +EXC( LDREST t0, REST(0)(src), l_exc_copy) +EXC( LDREST t1, REST(1)(src), l_exc_copy) +EXC( LDFIRST t2, FIRST(2)(src), l_exc_copy) +EXC( LDFIRST t3, FIRST(3)(src), l_exc_copy) +EXC( LDREST t2, REST(2)(src), l_exc_copy) +EXC( LDREST t3, REST(3)(src), l_exc_copy) + PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed) + ADD src, src, 4*NBYTES +#ifdef CONFIG_CPU_SB1 + nop # improves slotting +#endif +EXC( STORE t0, UNIT(0)(dst), s_exc_p4u) +EXC( STORE t1, UNIT(1)(dst), s_exc_p3u) +EXC( STORE t2, UNIT(2)(dst), s_exc_p2u) +EXC( STORE t3, UNIT(3)(dst), s_exc_p1u) + PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed) + bne len, rem, 1b + ADD dst, dst, 4*NBYTES + +cleanup_src_unaligned: + beqz len, done + and rem, len, NBYTES-1 # rem = len % NBYTES + beq rem, len, copy_bytes + nop +1: +EXC( LDFIRST t0, FIRST(0)(src), l_exc) +EXC( LDREST t0, REST(0)(src), l_exc_copy) + ADD src, src, NBYTES + SUB len, len, NBYTES +EXC( STORE t0, 0(dst), s_exc_p1u) + bne len, rem, 1b + ADD dst, dst, NBYTES -memcpy_u_src: - bnez t8, small_memcpy # < 8 bytes? - move ta2, a2 - - daddiu ta0, a1, 7 # ta0: how much to align - ori ta0, 7 - xori ta0, 7 - dsubu ta0, a1 - - UEXD(uld, ta1, 0(a1), l_fixup) # dword alignment - UEXD(usd, ta1, 0(a0), s_fixup) - - daddu a1, ta0 # src - daddu a0, ta0 # dst - dsubu a2, ta0 # len - - sltiu t8, a2, 56 - bnez t8, u_do_end_words - andi t8, a2, 0x3c - - andi t8, a1, 8 # now qword aligned? - -u_qword_align: - beqz t8, u_oword_align - andi t8, a1, 0x10 - - EX(ld, ta0, 0x00(a1), l_fixup) - dsubu a2, a2, 0x8 - UEXD(usd, ta0, 0x00(a0), s_fixup) - daddu a1, a1, 0x8 - andi t8, a1, 0x10 - daddu a0, a0, 0x8 - -u_oword_align: - beqz t8, u_begin_movement - srl t8, a2, 0x7 - - EX(lw, ta3, 0x08(a1), l_fixup) - EX(lw, t0, 0x0c(a1), l_fixup) - EX(lw, ta0, 0x00(a1), l_fixup) - EX(lw, ta1, 0x04(a1), l_fixup) - UEX(usw, ta3, 0x08(a0), s_fixup) - UEX(usw, t0, 0x0c(a0), s_fixup) - UEX(usw, ta0, 0x00(a0), s_fixup) - UEX(usw, ta1, 0x04(a0), s_fixup) - dsubu a2, a2, 0x10 - daddu a1, a1, 0x10 - srl t8, a2, 0x7 - daddu a0, a0, 0x10 - -u_begin_movement: - beqz t8, 0f - andi ta2, a2, 0x40 - -u_move_128bytes: - UMOVE_BIGGERCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - UMOVE_BIGGERCHUNK(a1, a0, 0x40, ta0, ta1, ta3, t0) - dsubu t8, t8, 0x01 - daddu a1, a1, 0x80 - bnez t8, u_move_128bytes - daddu a0, a0, 0x80 - -0: - beqz ta2, 1f - andi ta2, a2, 0x20 - -u_move_64bytes: - UMOVE_BIGGERCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - daddu a1, a1, 0x40 - daddu a0, a0, 0x40 +copy_bytes_checklen: + beqz len, done + nop +copy_bytes: + /* 0 < len < NBYTES */ +#define COPY_BYTE(N) \ +EXC( lb t0, N(src), l_exc); \ + SUB len, len, 1; \ + beqz len, done; \ +EXC( sb t0, N(dst), s_exc_p1) + + COPY_BYTE(0) + COPY_BYTE(1) +#ifdef USE_DOUBLE + COPY_BYTE(2) + COPY_BYTE(3) + COPY_BYTE(4) + COPY_BYTE(5) +#endif +EXC( lb t0, NBYTES-2(src), l_exc) + SUB len, len, 1 + jr ra +EXC( sb t0, NBYTES-2(dst), s_exc_p1) +done: + jr ra + nop + END(memcpy) +l_exc_copy: + /* + * Copy bytes from src until faulting load address (or until a + * lb faults) + * + * When reached by a faulting LDFIRST/LDREST, THREAD_BUADDR($28) + * may be more than a byte beyond the last address. + * Hence, the lb below may get an exception. + * + * Assumes src < THREAD_BUADDR($28) + */ + LOAD t0, THREAD_BUADDR($28) 1: - beqz ta2, u_do_end_words - andi t8, a2, 0x1c +EXC( lb t1, 0(src), l_exc) + ADD src, src, 1 + sb t1, 0(dst) # can't fault -- we're copy_from_user + bne src, t0, 1b + ADD dst, dst, 1 +l_exc: + LOAD t0, THREAD_BUADDR($28) # t0 is just past last good address + nop + SUB len, AT, t0 # len number of uncopied bytes + /* + * Here's where we rely on src and dst being incremented in tandem, + * See (3) above. + * dst += (fault addr - src) to put dst at first byte to clear + */ + ADD dst, t0 # compute start address in a1 + SUB dst, src + /* + * Clear len bytes starting at dst. Can't call __bzero because it + * might modify len. An inefficient loop for these rare times... + */ + beqz len, done + SUB src, len, 1 +1: sb zero, 0(dst) + ADD dst, dst, 1 + bnez src, 1b + SUB src, src, 1 + jr ra + nop -u_move_32bytes: - UMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - andi t8, a2, 0x1c - daddu a1, a1, 0x20 - daddu a0, a0, 0x20 - -u_do_end_words: - beqz t8, u_maybe_end_cruft - srl t8, t8, 0x2 - -u_end_words: - EX(lw, ta0, 0x00(a1), l_fixup) - dsubu t8, t8, 0x1 - UEX(usw, ta0, 0x00(a0), s_fixup) - daddu a1, a1, 0x4 - bnez t8, u_end_words - daddu a0, a0, 0x4 - -u_maybe_end_cruft: - andi ta2, a2, 0x3 - -u_cannot_optimize: - beqz ta2, out - move a2, ta2 - -u_end_bytes: - EX(lb, ta0, (a1), l_fixup) - dsubu a2, a2, 0x1 - EX(sb, ta0, (a0), s_fixup) - daddu a1, a1, 0x1 - bnez a2, u_end_bytes - daddu a0, a0, 0x1 - jr ra - move a2, zero - END(memcpy) +#define SEXC(n) \ +s_exc_p ## n ## u: \ + jr ra; \ + ADD len, len, n*NBYTES + +SEXC(8) +SEXC(7) +SEXC(6) +SEXC(5) +SEXC(4) +SEXC(3) +SEXC(2) +SEXC(1) -/* descending order, destination aligned */ -#define RMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \ - lw t0, (offset + 0x10)(src); \ - lw t1, (offset + 0x14)(src); \ - lw t2, (offset + 0x18)(src); \ - lw t3, (offset + 0x1c)(src); \ - sw t0, (offset + 0x10)(dst); \ - sw t1, (offset + 0x14)(dst); \ - sw t2, (offset + 0x18)(dst); \ - sw t3, (offset + 0x1c)(dst); \ - lw t0, (offset + 0x00)(src); \ - lw t1, (offset + 0x04)(src); \ - lw t2, (offset + 0x08)(src); \ - lw t3, (offset + 0x0c)(src); \ - sw t0, (offset + 0x00)(dst); \ - sw t1, (offset + 0x04)(dst); \ - sw t2, (offset + 0x08)(dst); \ - sw t3, (offset + 0x0c)(dst) - -/* descending order, destination ununaligned */ -#define RUMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \ - lw t0, (offset + 0x10)(src); \ - lw t1, (offset + 0x14)(src); \ - lw t2, (offset + 0x18)(src); \ - lw t3, (offset + 0x1c)(src); \ - usw t0, (offset + 0x10)(dst); \ - usw t1, (offset + 0x14)(dst); \ - usw t2, (offset + 0x18)(dst); \ - usw t3, (offset + 0x1c)(dst); \ - lw t0, (offset + 0x00)(src); \ - lw t1, (offset + 0x04)(src); \ - lw t2, (offset + 0x08)(src); \ - lw t3, (offset + 0x0c)(src); \ - usw t0, (offset + 0x00)(dst); \ - usw t1, (offset + 0x04)(dst); \ - usw t2, (offset + 0x08)(dst); \ - usw t3, (offset + 0x0c)(dst) +s_exc_p1: + jr ra + ADD len, len, 1 +s_exc: + jr ra + nop .align 5 LEAF(memmove) - daddu t0, a0, a2 + ADD t0, a0, a2 + ADD t1, a1, a2 sltu t0, a1, t0 # dst + len <= src -> memcpy - daddu t1, a1, a2 sltu t1, a0, t1 # dst >= src + len -> memcpy and t0, t1 beqz t0, __memcpy - move v0, a0 /* return value */ beqz a2, r_out END(memmove) + /* fall through to __rmemcpy */ LEAF(__rmemcpy) /* a0=dst a1=src a2=len */ - sltu t0, a1, a0 + sltu t0, a1, a0 beqz t0, r_end_bytes_up # src >= dst nop - daddu a0, a2 # dst = dst + len - daddu a1, a2 # src = src + len - -#if 0 /* Horror fix */ - xor ta0, a0, a1 - andi ta0, ta0, 0x3 - move t3, a0 - beqz ta0, r_can_align - sltiu t8, a2, 0x8 - - b r_memcpy_u_src # bad alignment - move ta2, a2 - -r_can_align: - bnez t8, r_small_memcpy # < 8 bytes to copy - move ta2, a2 - - beqz a2, r_out - andi t8, a1, 0x1 - -r_hword_align: - beqz t8, r_word_align - andi t8, a1, 0x2 - - lb ta0, -1(a1) - dsubu a2, a2, 0x1 - sb ta0, -1(a0) - dsubu a1, a1, 0x1 - dsubu a0, a0, 0x1 - andi t8, a1, 0x2 - -r_word_align: - beqz t8, r_dword_align - sltiu t8, a2, 56 - - lh ta0, -2(a1) - dsubu a2, a2, 0x2 - sh ta0, -2(a0) - sltiu t8, a2, 56 - dsubu a0, a0, 0x2 - dsubu a1, a1, 0x2 - -r_dword_align: - bnez t8, r_do_end_words - move t8, a2 - - andi t8, a1, 0x4 - beqz t8, r_qword_align - andi t8, a1, 0x8 - - lw ta0, -4(a1) - dsubu a2, a2, 0x4 - sw ta0, -4(a0) - dsubu a1, a1, 0x4 - dsubu a0, a0, 0x4 - andi t8, a1, 0x8 - -r_qword_align: - beqz t8, r_oword_align - andi t8, a1, 0x10 - - dsubu a1, a1, 0x8 - lw ta0, 0x04(a1) - lw ta1, 0x00(a1) - dsubu a0, a0, 0x8 - sw ta0, 0x04(a0) - sw ta1, 0x00(a0) - dsubu a2, a2, 0x8 - - andi t8, a1, 0x10 - -r_oword_align: - beqz t8, r_begin_movement - srl t8, a2, 0x7 - - dsubu a1, a1, 0x10 - lw ta3, 0x08(a1) # assumes subblock ordering - lw t0, 0x0c(a1) - lw ta0, 0x00(a1) - lw ta1, 0x04(a1) - dsubu a0, a0, 0x10 - sw ta3, 0x08(a0) - sw t0, 0x0c(a0) - sw ta0, 0x00(a0) - sw ta1, 0x04(a0) - dsubu a2, a2, 0x10 - srl t8, a2, 0x7 - -r_begin_movement: - beqz t8, 0f - andi ta2, a2, 0x40 - -r_move_128bytes: - RMOVE_BIGCHUNK(a1, a0, -0x80, ta0, ta1, ta3, t0) - RMOVE_BIGCHUNK(a1, a0, -0x60, ta0, ta1, ta3, t0) - RMOVE_BIGCHUNK(a1, a0, -0x40, ta0, ta1, ta3, t0) - RMOVE_BIGCHUNK(a1, a0, -0x20, ta0, ta1, ta3, t0) - dsubu t8, t8, 0x01 - dsubu a1, a1, 0x80 - bnez t8, r_move_128bytes - dsubu a0, a0, 0x80 - -0: - beqz ta2, 1f - andi ta2, a2, 0x20 - -r_move_64bytes: - dsubu a1, a1, 0x40 - dsubu a0, a0, 0x40 - RMOVE_BIGCHUNK(a1, a0, 0x20, ta0, ta1, ta3, t0) - RMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - -1: - beqz ta2, r_do_end_words - andi t8, a2, 0x1c - -r_move_32bytes: - dsubu a1, a1, 0x20 - dsubu a0, a0, 0x20 - RMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - andi t8, a2, 0x1c - -r_do_end_words: - beqz t8, r_maybe_end_cruft - srl t8, t8, 0x2 - -r_end_words: - lw ta0, -4(a1) - dsubu t8, t8, 0x1 - sw ta0, -4(a0) - dsubu a1, a1, 0x4 - bnez t8, r_end_words - dsubu a0, a0, 0x4 - -r_maybe_end_cruft: - andi ta2, a2, 0x3 - -r_small_memcpy: - beqz ta2, r_out - move a2, ta2 -#endif /* Horror fix */ + ADD a0, a2 # dst = dst + len + ADD a1, a2 # src = src + len r_end_bytes: - lb ta0, -1(a1) - dsubu a2, a2, 0x1 - sb ta0, -1(a0) - dsubu a1, a1, 0x1 + lb t0, -1(a1) + SUB a2, a2, 0x1 + sb t0, -1(a0) + SUB a1, a1, 0x1 bnez a2, r_end_bytes - dsubu a0, a0, 0x1 + SUB a0, a0, 0x1 r_out: - jr ra - move a2, zero + jr ra + move a2, zero r_end_bytes_up: lb t0, (a1) - dsubu a2, a2, 0x1 + SUB a2, a2, 0x1 sb t0, (a0) - daddu a1, a1, 0x1 + ADD a1, a1, 0x1 bnez a2, r_end_bytes_up - daddu a0, a0, 0x1 + ADD a0, a0, 0x1 jr ra move a2, zero - -#if 0 /* Horror fix */ -/* ------------------------------------------------------------------------- */ - -/* Bad, bad. At least try to align the source */ - -r_memcpy_u_src: - bnez t8, r_small_memcpy # < 8 bytes? - move ta2, a2 - - andi ta0, a1, 7 # ta0: how much to align - - ulw ta1, -8(a1) # dword alignment - ulw ta2, -4(a1) - usw ta1, -8(a0) - usw ta2, -4(a0) - - dsubu a1, ta0 # src - dsubu a0, ta0 # dst - dsubu a2, ta0 # len - - sltiu t8, a2, 56 - bnez t8, ru_do_end_words - andi t8, a2, 0x3c - - andi t8, a1, 8 # now qword aligned? - -ru_qword_align: - beqz t8, ru_oword_align - andi t8, a1, 0x10 - - dsubu a1, a1, 0x8 - lw ta0, 0x00(a1) - lw ta1, 0x04(a1) - dsubu a0, a0, 0x8 - usw ta0, 0x00(a0) - usw ta1, 0x04(a0) - dsubu a2, a2, 0x8 - - andi t8, a1, 0x10 - -ru_oword_align: - beqz t8, ru_begin_movement - srl t8, a2, 0x7 - - dsubu a1, a1, 0x10 - lw ta3, 0x08(a1) # assumes subblock ordering - lw t0, 0x0c(a1) - lw ta0, 0x00(a1) - lw ta1, 0x04(a1) - dsubu a0, a0, 0x10 - usw ta3, 0x08(a0) - usw t0, 0x0c(a0) - usw ta0, 0x00(a0) - usw ta1, 0x04(a0) - dsubu a2, a2, 0x10 - - srl t8, a2, 0x7 - -ru_begin_movement: - beqz t8, 0f - andi ta2, a2, 0x40 - -ru_move_128bytes: - RUMOVE_BIGCHUNK(a1, a0, -0x80, ta0, ta1, ta3, t0) - RUMOVE_BIGCHUNK(a1, a0, -0x60, ta0, ta1, ta3, t0) - RUMOVE_BIGCHUNK(a1, a0, -0x40, ta0, ta1, ta3, t0) - RUMOVE_BIGCHUNK(a1, a0, -0x20, ta0, ta1, ta3, t0) - dsubu t8, t8, 0x01 - dsubu a1, a1, 0x80 - bnez t8, ru_move_128bytes - dsubu a0, a0, 0x80 - -0: - beqz ta2, 1f - andi ta2, a2, 0x20 - -ru_move_64bytes: - dsubu a1, a1, 0x40 - dsubu a0, a0, 0x40 - RUMOVE_BIGCHUNK(a1, a0, 0x20, ta0, ta1, ta3, t0) - RUMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - -1: - beqz ta2, ru_do_end_words - andi t8, a2, 0x1c - -ru_move_32bytes: - dsubu a1, a1, 0x20 - dsubu a0, a0, 0x20 - RUMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - andi t8, a2, 0x1c - -ru_do_end_words: - beqz t8, ru_maybe_end_cruft - srl t8, t8, 0x2 - -ru_end_words: - lw ta0, -4(a1) - usw ta0, -4(a0) - dsubu t8, t8, 0x1 - dsubu a1, a1, 0x4 - bnez t8, ru_end_words - dsubu a0, a0, 0x4 - -ru_maybe_end_cruft: - andi ta2, a2, 0x3 - -ru_cannot_optimize: - beqz ta2, r_out - move a2, ta2 - -ru_end_bytes: - lb ta0, -1(a1) - dsubu a2, a2, 0x1 - sb ta0, -1(a0) - dsubu a1, a1, 0x1 - bnez a2, ru_end_bytes - dsubu a0, a0, 0x1 - - jr ra - move a2, zero -#endif /* Horror fix */ END(__rmemcpy) - -l_fixup: # clear the rest of the buffer - ld ta0, THREAD_BUADDR($28) - nop - dsubu a2, AT, ta0 # a2 bytes to go - daddu a0, ta0 # compute start address in a1 - dsubu a0, a1 - /* - * Clear len bytes starting at dst. Can't call __bzero because it - * might modify len. An inefficient loop for these rare times... - */ - beqz a2, 2f - dsubu a1, a2, 1 -1: sb zero, 0(a0) - daddu a0, a0, 1 - bnez a1, 1b - dsubu a1, a1, 1 -2: jr ra - nop - -s_fixup: - jr ra - nop diff -urN linux-2.4.21-bk37/arch/mips64/lib/promlib.c linux-2.4.21-bk38/arch/mips64/lib/promlib.c --- linux-2.4.21-bk37/arch/mips64/lib/promlib.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/lib/promlib.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,24 @@ +#include +#include + +extern void prom_putchar(char); + +void prom_printf(char *fmt, ...) +{ + va_list args; + char ppbuf[1024]; + char *bptr; + + va_start(args, fmt); + vsprintf(ppbuf, fmt, args); + + bptr = ppbuf; + + while (*bptr != 0) { + if (*bptr == '\n') + prom_putchar('\r'); + + prom_putchar(*bptr++); + } + va_end(args); +} diff -urN linux-2.4.21-bk37/arch/mips64/lib/strlen_user.S linux-2.4.21-bk38/arch/mips64/lib/strlen_user.S --- linux-2.4.21-bk37/arch/mips64/lib/strlen_user.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/lib/strlen_user.S 2003-08-24 02:55:58.000000000 -0700 @@ -25,7 +25,7 @@ LEAF(__strlen_user_asm) ld v0, THREAD_CURDS($28) # pointer ok? and v0, a0 - bltz v0, fault + bnez v0, fault FEXPORT(__strlen_user_nocheck_asm) move v0, a0 diff -urN linux-2.4.21-bk37/arch/mips64/lib/strncpy_user.S linux-2.4.21-bk38/arch/mips64/lib/strncpy_user.S --- linux-2.4.21-bk37/arch/mips64/lib/strncpy_user.S 2001-09-09 10:43:02.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips64/lib/strncpy_user.S 2003-08-24 02:55:58.000000000 -0700 @@ -30,7 +30,7 @@ LEAF(__strncpy_from_user_asm) ld v0, THREAD_CURDS($28) # pointer ok? and v0, a1 - bltz v0, fault + bnez v0, fault FEXPORT(__strncpy_from_user_nocheck_asm) move v0, zero diff -urN linux-2.4.21-bk37/arch/mips64/lib/strnlen_user.S linux-2.4.21-bk38/arch/mips64/lib/strnlen_user.S --- linux-2.4.21-bk37/arch/mips64/lib/strnlen_user.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/lib/strnlen_user.S 2003-08-24 02:55:58.000000000 -0700 @@ -25,7 +25,7 @@ LEAF(__strnlen_user_asm) ld v0, THREAD_CURDS($28) # pointer ok? and v0, a0 - bltz v0, fault + bnez v0, fault FEXPORT(__strnlen_user_nocheck_asm) move v0, a0 diff -urN linux-2.4.21-bk37/arch/mips64/mm/Makefile linux-2.4.21-bk38/arch/mips64/mm/Makefile --- linux-2.4.21-bk37/arch/mips64/mm/Makefile 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/Makefile 2003-08-24 02:55:58.000000000 -0700 @@ -6,27 +6,29 @@ O_TARGET := mm.o -export-objs += umap.o -obj-y := extable.o init.o fault.o loadmmu.o - -obj-$(CONFIG_CPU_R4300) += r4xx0.o tlbex-r4k.o tlb-glue-r4k.o -obj-$(CONFIG_CPU_R4X00) += r4xx0.o tlbex-r4k.o tlb-glue-r4k.o -obj-$(CONFIG_CPU_R5000) += r4xx0.o tlbex-r4k.o tlb-glue-r4k.o \ - r5k-sc.o -obj-$(CONFIG_CPU_NEVADA) += r4xx0.o tlbex-r4k.o tlb-glue-r4k.o \ - r5k-sc.o -obj-$(CONFIG_CPU_R10000) += andes.o tlbex-r4k.o tlb-glue-r4k.o -obj-$(CONFIG_CPU_SB1) += pg-sb1.o c-sb1.o tlb-sb1.o tlbex-r4k.o \ - tlb-glue-r4k.o -obj-$(CONFIG_CPU_MIPS64) += pg-mips64.o c-mips64.o tlb-r4k.o \ - tlbex-r4k.o tlb-glue-r4k.o +export-objs := cache.o loadmmu.o +obj-y := cache.o extable.o init.o fault.o loadmmu.o \ + tlbex-r4k.o + +obj-$(CONFIG_CPU_R4300) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_R4X00) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_R5000) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_NEVADA) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_R5432) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_RM7000) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_R10000) += c-r4k.o pg-r4k.o tlb-andes.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_SB1) += c-sb1.o pg-sb1.o tlb-sb1.o tlb-glue-sb1.o \ + cex-sb1.o cerr-sb1.o +obj-$(CONFIG_CPU_MIPS64) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o + +obj-$(CONFIG_CPU_RM7000) += sc-rm7k.o +obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o +obj-$(CONFIG_SGI_IP22) += sc-ip22.o # # Debug TLB exception handler, currently unused # -#obj-y += tlb-dbg-r4k.o tlb-glue-r4k.o - -obj-$(CONFIG_SGI_IP22) += umap.o +#obj-y += tlb-dbg-r4k.o AFLAGS_tlb-glue-r4k.o := -P diff -urN linux-2.4.21-bk37/arch/mips64/mm/andes.c linux-2.4.21-bk38/arch/mips64/mm/andes.c --- linux-2.4.21-bk37/arch/mips64/mm/andes.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/andes.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,350 +0,0 @@ -/* - * 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. - * - * Copyright (C) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 1999 Silicon Graphics, Inc. - * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com) - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int scache_lsz64; - -/* - * This version has been tuned on an Origin. For other machines the arguments - * of the pref instructin may have to be tuned differently. - */ -static void andes_clear_page(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tpref 7,512(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE) - : "memory"); -} - -/* R10000 has no Create_Dirty type cacheops. */ -static void andes_copy_page(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%8\n" - "1:\tpref\t0,2*128(%1)\n\t" - "pref\t1,2*128(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "ld\t%4,16(%1)\n\t" - "ld\t%5,24(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "sd\t%4,16(%0)\n\t" - "sd\t%5,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "ld\t%4,-16(%1)\n\t" - "ld\t%5,-8(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "sd\t%4,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%5,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2), - "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), "I" (PAGE_SIZE)); -} - -/* Cache operations. These are only used with the virtual memory system, - not for non-coherent I/O so it's ok to ignore the secondary caches. */ -static void -andes_flush_cache_l1(void) -{ - blast_dcache32(); blast_icache64(); -} - -/* - * This is only used during initialization time. vmalloc() also calls - * this, but that will be changed pretty soon. - */ -static void andes_flush_cache_l2(void) -{ - switch (sc_lsize()) { - case 64: - blast_scache64(); - break; - case 128: - blast_scache128(); - break; - default: - printk(KERN_EMERG "Unknown L2 line size\n"); - while(1); - } -} - -void -andes_flush_icache_page(unsigned long page) -{ - if (scache_lsz64) - blast_scache64_page(page); - else - blast_scache128_page(page); -} - -static void -andes_flush_cache_sigtramp(unsigned long addr) -{ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -#define NTLB_ENTRIES 64 -#define NTLB_ENTRIES_HALF 32 - -void local_flush_tlb_all(void) -{ - unsigned long flags; - unsigned long old_ctx; - unsigned long entry; - -#ifdef DEBUG_TLB - printk("[tlball]"); -#endif - - __save_and_cli(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = get_entryhi() & ASID_MASK; - set_entryhi(CKSEG0); - set_entrylo0(0); - set_entrylo1(0); - - entry = get_wired(); - - /* Blast 'em all away. */ - while (entry < NTLB_ENTRIES) { - set_index(entry); - tlb_write_indexed(); - entry++; - } - set_entryhi(old_ctx); - __restore_flags(flags); -} - -void local_flush_tlb_mm(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { - unsigned long flags; - -#ifdef DEBUG_TLB - printk("[tlbmm<%d>]", mm->context); -#endif - __save_and_cli(flags); - get_new_mmu_context(mm, smp_processor_id()); - if(mm == current->mm) - set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) - & ASID_MASK); - __restore_flags(flags); - } -} - -void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, - unsigned long end) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { - unsigned long flags; - int size; - -#ifdef DEBUG_TLB - printk("[tlbrange<%02x,%08lx,%08lx>]", - (mm->context & ASID_MASK), start, end); -#endif - __save_and_cli(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - size = (size + 1) >> 1; - if (size <= NTLB_ENTRIES_HALF) { - int oldpid = (get_entryhi() & ASID_MASK); - int newpid = (CPU_CONTEXT(smp_processor_id(), mm) - & ASID_MASK); - - start &= (PAGE_MASK << 1); - end += ((PAGE_SIZE << 1) - 1); - end &= (PAGE_MASK << 1); - while(start < end) { - int idx; - - set_entryhi(start | newpid); - start += (PAGE_SIZE << 1); - tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - if(idx < 0) - continue; - tlb_write_indexed(); - } - set_entryhi(oldpid); - } else { - get_new_mmu_context(mm, smp_processor_id()); - if(mm == current->mm) - set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) - & ASID_MASK); - } - __restore_flags(flags); - } -} - -void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - if (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) != 0) { - unsigned long flags; - int oldpid, newpid, idx; - -#ifdef DEBUG_TLB - printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); -#endif - newpid = (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & - ASID_MASK); - page &= (PAGE_MASK << 1); - __save_and_cli(flags); - oldpid = (get_entryhi() & ASID_MASK); - set_entryhi(page | newpid); - tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - if (idx < 0) - goto finish; - tlb_write_indexed(); - - finish: - set_entryhi(oldpid); - __restore_flags(flags); - } -} - -/* XXX Simplify this. On the R10000 writing a TLB entry for an virtual - address that already exists will overwrite the old entry and not result - in TLB malfunction or TLB shutdown. */ -static void andes_update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx, pid; - - /* - * Handle debugger faulting in for debugee. - */ - if (current->active_mm != vma->vm_mm) - return; - - pid = get_entryhi() & ASID_MASK; - - if ((pid != (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & ASID_MASK)) - || (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) == 0)) { - printk(KERN_WARNING - "%s: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n", - __FUNCTION__, (int) (CPU_CONTEXT(smp_processor_id(), - vma->vm_mm) & ASID_MASK), pid); - } - - __save_and_cli(flags); - address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); - pgdp = pgd_offset(vma->vm_mm, address); - tlb_probe(); - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); - if (idx < 0) { - tlb_write_random(); - } else { - tlb_write_indexed(); - } - set_entryhi(pid); - __restore_flags(flags); -} - -void __init ld_mmu_andes(void) -{ - printk("Primary instruction cache %dkb, linesize %d bytes\n", - icache_size >> 10, ic_lsize); - printk("Primary data cache %dkb, linesize %d bytes\n", - dcache_size >> 10, dc_lsize); - printk("Secondary cache sized at %ldK, linesize %ld\n", - scache_size() >> 10, sc_lsize()); - - _clear_page = andes_clear_page; - _copy_page = andes_copy_page; - - _flush_cache_l1 = andes_flush_cache_l1; - _flush_cache_l2 = andes_flush_cache_l2; - _flush_cache_sigtramp = andes_flush_cache_sigtramp; - - switch (sc_lsize()) { - case 64: - scache_lsz64 = 1; - break; - case 128: - scache_lsz64 = 0; - break; - default: - printk(KERN_EMERG "Unknown L2 line size\n"); - while(1); - } - - _update_mmu_cache = andes_update_mmu_cache; - - flush_cache_l1(); - - /* - * You should never change this register: - * - On R4600 1.7 the tlbp never hits for pages smaller than - * the value in the c0_pagemask register. - * - The entire mm handling assumes the c0_pagemask register to - * be set for 4kb pages. - */ - write_32bit_cp0_register(CP0_PAGEMASK, PM_4K); - write_32bit_cp0_register(CP0_FRAMEMASK, 0); - - /* From this point on the ARC firmware is dead. */ - local_flush_tlb_all(); - - /* Did I tell you that ARC SUCKS? */ -} diff -urN linux-2.4.21-bk37/arch/mips64/mm/c-mips64.c linux-2.4.21-bk38/arch/mips64/mm/c-mips64.c --- linux-2.4.21-bk37/arch/mips64/mm/c-mips64.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/c-mips64.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,670 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * MIPS64 CPU variant specific Cache routines. - * These routine are not optimized in any way, they are done in a generic way - * so they can be used on all MIPS64 compliant CPUs, and also done in an - * attempt not to break anything for the R4xx0 style CPUs. - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/* CP0 hazard avoidance. */ -#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ - "nop; nop; nop; nop; nop; nop;\n\t" \ - ".set reorder\n\t") - -/* Primary cache parameters. */ -int icache_size, dcache_size; /* Size in bytes */ -int ic_lsize, dc_lsize; /* LineSize in bytes */ - -/* Secondary cache (if present) parameters. */ -unsigned int scache_size, sc_lsize; /* Again, in bytes */ - -#include -#include - -#undef DEBUG_CACHE - -/* - * Dummy cache handling routines for machines without boardcaches - */ -static void no_sc_noop(void) {} - -static struct bcache_ops no_sc_ops = { - (void *)no_sc_noop, (void *)no_sc_noop, - (void *)no_sc_noop, (void *)no_sc_noop -}; - -struct bcache_ops *bcops = &no_sc_ops; - - -static inline void mips64_flush_cache_all_sc(void) -{ - unsigned long flags; - - __save_and_cli(flags); - blast_dcache(); blast_icache(); blast_scache(); - __restore_flags(flags); -} - -static inline void mips64_flush_cache_all_pc(void) -{ - unsigned long flags; - - __save_and_cli(flags); - blast_dcache(); blast_icache(); - __restore_flags(flags); -} - -static void -mips64_flush_cache_range_sc(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - unsigned long flags; - - if(mm->context == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if(mm->context != current->mm->context) { - mips64_flush_cache_all_sc(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - __save_and_cli(flags); - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache_page(start); - start += PAGE_SIZE; - } - __restore_flags(flags); - } - } -} - -static void mips64_flush_cache_range_pc(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if(mm->context != 0) { - unsigned long flags; - -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - __save_and_cli(flags); - blast_dcache(); blast_icache(); - __restore_flags(flags); - } -} - -/* - * On architectures like the Sparc, we could get rid of lines in - * the cache created only by a certain context, but on the MIPS - * (and actually certain Sparc's) we cannot. - */ -static void mips64_flush_cache_mm_sc(struct mm_struct *mm) -{ - if(mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - mips64_flush_cache_all_sc(); - } -} - -static void mips64_flush_cache_mm_pc(struct mm_struct *mm) -{ - if(mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - mips64_flush_cache_all_pc(); - } -} - -static void mips64_flush_cache_page_sc(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - __save_and_cli(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache_page_indexed(page); - blast_scache_page_indexed(page); - } else - blast_scache_page(page); -out: - __restore_flags(flags); -} - -static void mips64_flush_cache_page_pc(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - __save_and_cli(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since Mips64 caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm == current->active_mm) { - blast_dcache_page(page); - } else { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & ((unsigned long)dcache_size - 1))); - blast_dcache_page_indexed(page); - } -out: - __restore_flags(flags); -} - -/* If the addresses passed to these routines are valid, they are - * either: - * - * 1) In KSEG0, so we can do a direct flush of the page. - * 2) In KSEG2, and since every process can translate those - * addresses all the time in kernel mode we can do a direct - * flush. - * 3) In KSEG1, no flush necessary. - */ -static void mips64_flush_page_to_ram_sc(struct page *page) -{ - blast_scache_page((unsigned long)page_address(page)); -} - -static void mips64_flush_page_to_ram_pc(struct page *page) -{ - blast_dcache_page((unsigned long)page_address(page)); -} - -static void -mips64_flush_icache_page_s(struct vm_area_struct *vma, struct page *page) -{ - /* - * We did an scache flush therefore PI is already clean. - */ -} - -static void -mips64_flush_icache_range(unsigned long start, unsigned long end) -{ - flush_cache_all(); -} - -static void -mips64_flush_icache_page(struct vm_area_struct *vma, struct page *page) -{ - unsigned long address; - - if (!(vma->vm_flags & VM_EXEC)) - return; - - address = KSEG0 + ((unsigned long)page_address(page) & PAGE_MASK & ((unsigned long)icache_size - 1)); - blast_icache_page_indexed(address); -} - -/* - * Writeback and invalidate the primary cache dcache before DMA. - */ -static void -mips64_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= (unsigned long)dcache_size) { - blast_dcache(); - } else { - __save_and_cli(flags); - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~((unsigned long)dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - __restore_flags(flags); - } - bc_wback_inv(addr, size); -} - -static void -mips64_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= scache_size) { - blast_scache(); - return; - } - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} - -static void -mips64_dma_cache_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= (unsigned long)dcache_size) { - blast_dcache(); - } else { - __save_and_cli(flags); - a = addr & ~((unsigned long)dc_lsize - 1); - end = (addr + size) & ~((unsigned long)dc_lsize - 1); - while (1) { - invalidate_dcache_line(a); /* Hit_Inv_D */ - if (a == end) break; - a += (unsigned long)dc_lsize; - } - __restore_flags(flags); - } - - bc_inv(addr, size); -} - -static void -mips64_dma_cache_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= scache_size) { - blast_scache(); - return; - } - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - invalidate_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} - -static void -mips64_dma_cache_wback(unsigned long addr, unsigned long size) -{ - panic("mips64_dma_cache called - should not happen.\n"); -} - -/* - * While we're protected against bad userland addresses we don't care - * very much about what happens in that case. Usually a segmentation - * fault will dump the process later on anyway ... - */ -static void mips64_flush_cache_sigtramp(unsigned long addr) -{ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -static void -mips64_flush_icache_all(void) -{ - if (mips_cpu.cputype == CPU_20KC) { - blast_icache(); - } -} - - -/* Detect and size the various caches. */ -static void __init probe_icache(unsigned long config) -{ - unsigned long config1; - unsigned int lsize; - - if (!(config & (1 << 31))) { - /* - * Not a MIPS64 complainant CPU. - * Config 1 register not supported, we assume R4k style. - */ - icache_size = 1 << (12 + ((config >> 9) & 7)); - ic_lsize = 16 << ((config >> 5) & 1); - mips_cpu.icache.linesz = ic_lsize; - - /* - * We cannot infer associativity - assume direct map - * unless probe template indicates otherwise - */ - if(!mips_cpu.icache.ways) mips_cpu.icache.ways = 1; - mips_cpu.icache.sets = - (icache_size / ic_lsize) / mips_cpu.icache.ways; - } else { - config1 = read_mips32_cp0_config1(); - - if ((lsize = ((config1 >> 19) & 7))) - mips_cpu.icache.linesz = 2 << lsize; - else - mips_cpu.icache.linesz = lsize; - mips_cpu.icache.sets = 64 << ((config1 >> 22) & 7); - mips_cpu.icache.ways = 1 + ((config1 >> 16) & 7); - - ic_lsize = mips_cpu.icache.linesz; - icache_size = mips_cpu.icache.sets * mips_cpu.icache.ways * - ic_lsize; - } - printk("Primary instruction cache %dkb, linesize %d bytes (%d ways)\n", - icache_size >> 10, ic_lsize, mips_cpu.icache.ways); -} - -static void __init probe_dcache(unsigned long config) -{ - unsigned long config1; - unsigned int lsize; - - if (!(config & (1 << 31))) { - /* - * Not a MIPS64 complainant CPU. - * Config 1 register not supported, we assume R4k style. - */ - dcache_size = 1 << (12 + ((config >> 6) & 7)); - dc_lsize = 16 << ((config >> 4) & 1); - mips_cpu.dcache.linesz = dc_lsize; - /* - * We cannot infer associativity - assume direct map - * unless probe template indicates otherwise - */ - if(!mips_cpu.dcache.ways) mips_cpu.dcache.ways = 1; - mips_cpu.dcache.sets = - (dcache_size / dc_lsize) / mips_cpu.dcache.ways; - } else { - config1 = read_mips32_cp0_config1(); - - if ((lsize = ((config1 >> 10) & 7))) - mips_cpu.dcache.linesz = 2 << lsize; - else - mips_cpu.dcache.linesz= lsize; - mips_cpu.dcache.sets = 64 << ((config1 >> 13) & 7); - mips_cpu.dcache.ways = 1 + ((config1 >> 7) & 7); - - dc_lsize = mips_cpu.dcache.linesz; - dcache_size = - mips_cpu.dcache.sets * mips_cpu.dcache.ways - * dc_lsize; - } - printk("Primary data cache %dkb, linesize %d bytes (%d ways)\n", - dcache_size >> 10, dc_lsize, mips_cpu.dcache.ways); -} - - -/* If you even _breathe_ on this function, look at the gcc output - * and make sure it does not pop things on and off the stack for - * the cache sizing loop that executes in KSEG1 space or else - * you will crash and burn badly. You have been warned. - */ -static int __init probe_scache(unsigned long config) -{ - extern unsigned long stext; - unsigned long flags, addr, begin, end, pow2; - int tmp; - - if (mips_cpu.scache.flags == MIPS_CACHE_NOT_PRESENT) - return 0; - - tmp = ((config >> 17) & 1); - if(tmp) - return 0; - tmp = ((config >> 22) & 3); - switch(tmp) { - case 0: - sc_lsize = 16; - break; - case 1: - sc_lsize = 32; - break; - case 2: - sc_lsize = 64; - break; - case 3: - sc_lsize = 128; - break; - } - - begin = (unsigned long) &stext; - begin &= ~((4 * 1024 * 1024) - 1); - end = begin + (4 * 1024 * 1024); - - /* This is such a bitch, you'd think they would make it - * easy to do this. Away you daemons of stupidity! - */ - __save_and_cli(flags); - - /* Fill each size-multiple cache line with a valid tag. */ - pow2 = (64 * 1024); - for(addr = begin; addr < end; addr = (begin + pow2)) { - unsigned long *p = (unsigned long *) addr; - __asm__ __volatile__("nop" : : "r" (*p)); /* whee... */ - pow2 <<= 1; - } - - /* Load first line with zero (therefore invalid) tag. */ - set_taglo(0); - set_taghi(0); - __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */ - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 8, (%0)\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 9, (%0)\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 11, (%0)\n\t" - ".set reorder\n\t" : : "r" (begin)); - - /* Now search for the wrap around point. */ - pow2 = (128 * 1024); - tmp = 0; - for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) { - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 7, (%0)\n\t" - ".set reorder\n\t" : : "r" (addr)); - __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */ - if(!get_taglo()) - break; - pow2 <<= 1; - } - __restore_flags(flags); - addr -= begin; - printk("Secondary cache sized at %dK linesize %d bytes.\n", - (int) (addr >> 10), sc_lsize); - scache_size = addr; - return 1; -} - -static void __init setup_noscache_funcs(void) -{ - _clear_page = (void *)mips64_clear_page_dc; - _copy_page = (void *)mips64_copy_page_dc; - _flush_cache_all = mips64_flush_cache_all_pc; - ___flush_cache_all = mips64_flush_cache_all_pc; - _flush_cache_mm = mips64_flush_cache_mm_pc; - _flush_cache_range = mips64_flush_cache_range_pc; - _flush_cache_page = mips64_flush_cache_page_pc; - _flush_page_to_ram = mips64_flush_page_to_ram_pc; - - _flush_icache_page = mips64_flush_icache_page; - - _dma_cache_wback_inv = mips64_dma_cache_wback_inv_pc; - _dma_cache_wback = mips64_dma_cache_wback; - _dma_cache_inv = mips64_dma_cache_inv_pc; -} - -static void __init setup_scache_funcs(void) -{ - _flush_cache_all = mips64_flush_cache_all_sc; - ___flush_cache_all = mips64_flush_cache_all_sc; - _flush_cache_mm = mips64_flush_cache_mm_sc; - _flush_cache_range = mips64_flush_cache_range_sc; - _flush_cache_page = mips64_flush_cache_page_sc; - _flush_page_to_ram = mips64_flush_page_to_ram_sc; - _clear_page = (void *)mips64_clear_page_sc; - _copy_page = (void *)mips64_copy_page_sc; - - _flush_icache_page = mips64_flush_icache_page_s; - - _dma_cache_wback_inv = mips64_dma_cache_wback_inv_sc; - _dma_cache_wback = mips64_dma_cache_wback; - _dma_cache_inv = mips64_dma_cache_inv_sc; -} - -typedef int (*probe_func_t)(unsigned long); - -static inline void __init setup_scache(unsigned int config) -{ - probe_func_t probe_scache_kseg1; - int sc_present = 0; - - /* Maybe the cpu knows about a l2 cache? */ - probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); - sc_present = probe_scache_kseg1(config); - - if (sc_present) { - mips_cpu.scache.linesz = sc_lsize; - /* - * We cannot infer associativity - assume direct map - * unless probe template indicates otherwise - */ - if(!mips_cpu.scache.ways) mips_cpu.scache.ways = 1; - mips_cpu.scache.sets = - (scache_size / sc_lsize) / mips_cpu.scache.ways; - - setup_scache_funcs(); - return; - } - - setup_noscache_funcs(); -} - -void __init ld_mmu_mips64(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - - change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); - - probe_icache(config); - probe_dcache(config); - setup_scache(config); - - _flush_cache_sigtramp = mips64_flush_cache_sigtramp; - _flush_icache_range = mips64_flush_icache_range; /* Ouch */ - _flush_icache_all = mips64_flush_icache_all; - _flush_cache_l1 = _flush_cache_all; - _flush_cache_l2 = _flush_cache_all; - - __flush_cache_all(); -} diff -urN linux-2.4.21-bk37/arch/mips64/mm/c-r4k.c linux-2.4.21-bk38/arch/mips64/mm/c-r4k.c --- linux-2.4.21-bk37/arch/mips64/mm/c-r4k.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/c-r4k.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,1250 @@ +/* + * 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. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static unsigned long icache_size, dcache_size, scache_size; + +extern void andes_clear_page(void * page); +extern void r4k_clear_page32_d16(void * page); +extern void r4k_clear_page32_d32(void * page); +extern void r4k_clear_page_d16(void * page); +extern void r4k_clear_page_d32(void * page); +extern void r4k_clear_page_r4600_v1(void * page); +extern void r4k_clear_page_r4600_v2(void * page); +extern void r4k_clear_page_s16(void * page); +extern void r4k_clear_page_s32(void * page); +extern void r4k_clear_page_s64(void * page); +extern void r4k_clear_page_s128(void * page); +extern void andes_copy_page(void * to, void * from); +extern void r4k_copy_page_d16(void * to, void * from); +extern void r4k_copy_page_d32(void * to, void * from); +extern void r4k_copy_page_r4600_v1(void * to, void * from); +extern void r4k_copy_page_r4600_v2(void * to, void * from); +extern void r4k_copy_page_s16(void * to, void * from); +extern void r4k_copy_page_s32(void * to, void * from); +extern void r4k_copy_page_s64(void * to, void * from); +extern void r4k_copy_page_s128(void * to, void * from); + +/* + * Dummy cache handling routines for machines without boardcaches + */ +static void no_sc_noop(void) {} + +static struct bcache_ops no_sc_ops = { + .bc_enable = (void *)no_sc_noop, + .bc_disable = (void *)no_sc_noop, + .bc_wback_inv = (void *)no_sc_noop, + .bc_inv = (void *)no_sc_noop +}; + +struct bcache_ops *bcops = &no_sc_ops; + +#define R4600_HIT_CACHEOP_WAR_IMPL \ +do { \ + if (R4600_V2_HIT_CACHEOP_WAR && \ + (read_c0_prid() & 0xfff0) == 0x2020) { /* R4600 V2.0 */\ + *(volatile unsigned long *)KSEG1; \ + } \ + if (R4600_V1_HIT_CACHEOP_WAR) \ + __asm__ __volatile__("nop;nop;nop;nop"); \ +} while (0) + +static void r4k_blast_dcache_page(unsigned long addr) +{ + static void *l = &&init; + unsigned long dc_lsize; + + goto *l; + +dc_16: + blast_dcache16_page(addr); + return; + +dc_32: + R4600_HIT_CACHEOP_WAR_IMPL; + blast_dcache32_page(addr); + return; + +init: + dc_lsize = current_cpu_data.dcache.linesz; + + if (dc_lsize == 16) + l = &&dc_16; + else if (dc_lsize == 32) + l = &&dc_32; + goto *l; +} + +static void r4k_blast_dcache_page_indexed(unsigned long addr) +{ + static void *l = &&init; + unsigned long dc_lsize; + + goto *l; + +dc_16: + blast_dcache16_page_indexed(addr); + return; + +dc_32: + blast_dcache32_page_indexed(addr); + return; + +init: + dc_lsize = current_cpu_data.dcache.linesz; + + if (dc_lsize == 16) + l = &&dc_16; + else if (dc_lsize == 32) + l = &&dc_32; + goto *l; +} + +static void r4k_blast_dcache(void) +{ + static void *l = &&init; + unsigned long dc_lsize; + + goto *l; + +dc_16: + blast_dcache16(); + return; + +dc_32: + blast_dcache32(); + return; + +init: + dc_lsize = current_cpu_data.dcache.linesz; + + if (dc_lsize == 16) + l = &&dc_16; + else if (dc_lsize == 32) + l = &&dc_32; + goto *l; +} + +/* force code alignment (used for TX49XX_ICACHE_INDEX_INV_WAR) */ +#define JUMP_TO_ALIGN(order) \ + __asm__ __volatile__( \ + "b\t1f\n\t" \ + ".align\t" #order "\n\t" \ + "1:\n\t" \ + ) +#define CACHE32_UNROLL32_ALIGN JUMP_TO_ALIGN(10) /* 32 * 32 = 1024 */ +#define CACHE32_UNROLL32_ALIGN2 JUMP_TO_ALIGN(11) + +static inline void tx49_blast_icache32(void) +{ + unsigned long start = KSEG0; + unsigned long end = start + current_cpu_data.icache.waysize; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; + + CACHE32_UNROLL32_ALIGN2; + /* I'm in even chunk. blast odd chunks */ + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start + 0x400; addr < end; addr += 0x400 * 2) + cache32_unroll32(addr|ws,Index_Invalidate_I); + CACHE32_UNROLL32_ALIGN; + /* I'm in odd chunk. blast even chunks */ + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400 * 2) + cache32_unroll32(addr|ws,Index_Invalidate_I); +} + +static inline void tx49_blast_icache32_page_indexed(unsigned long page) +{ + unsigned long start = page; + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; + + CACHE32_UNROLL32_ALIGN2; + /* I'm in even chunk. blast odd chunks */ + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start + 0x400; addr < end; addr += 0x400 * 2) + cache32_unroll32(addr|ws,Index_Invalidate_I); + CACHE32_UNROLL32_ALIGN; + /* I'm in odd chunk. blast even chunks */ + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400 * 2) + cache32_unroll32(addr|ws,Index_Invalidate_I); +} + +static void r4k_blast_icache_page(unsigned long addr) +{ + unsigned long ic_lsize = current_cpu_data.icache.linesz; + static void *l = &&init; + + goto *l; + +ic_16: + blast_icache16_page(addr); + return; + +ic_32: + blast_icache32_page(addr); + return; + +ic_64: + blast_icache64_page(addr); + return; + +init: + if (ic_lsize == 16) + l = &&ic_16; + else if (ic_lsize == 32) + l = &&ic_32; + else if (ic_lsize == 64) + l = &&ic_64; + goto *l; +} + +static void r4k_blast_icache_page_indexed(unsigned long addr) +{ + unsigned long ic_lsize = current_cpu_data.icache.linesz; + static void *l = &&init; + + goto *l; + +ic_16: + blast_icache16_page_indexed(addr); + return; + +ic_32: + blast_icache32_page_indexed(addr); + return; + +ic_64: + blast_icache64_page_indexed(addr); + return; + +ic_32_tx49: + tx49_blast_icache32_page_indexed(addr); + return; + +init: + if (ic_lsize == 16) + l = &&ic_16; + else if (ic_lsize == 32) + if (TX49XX_ICACHE_INDEX_INV_WAR) + l = &&ic_32_tx49; + else + l = &&ic_32; + else if (ic_lsize == 64) + l = &&ic_64; + goto *l; +} + +static void r4k_blast_icache(void) +{ + unsigned long ic_lsize = current_cpu_data.icache.linesz; + static void *l = &&init; + + goto *l; + +ic_16: + blast_icache16(); + return; + +ic_32: + blast_icache32(); + return; + +ic_64: + blast_icache64(); + return; + +ic_32_tx49: + tx49_blast_icache32(); + return; + +init: + if (ic_lsize == 16) + l = &&ic_16; + else if (ic_lsize == 32) + if (TX49XX_ICACHE_INDEX_INV_WAR) + l = &&ic_32_tx49; + else + l = &&ic_32; + else if (ic_lsize == 64) + l = &&ic_64; + goto *l; +} + +static void r4k_blast_scache_page(unsigned long addr) +{ + unsigned long sc_lsize = current_cpu_data.scache.linesz; + static void *l = &&init; + + goto *l; + +sc_16: + blast_scache16_page(addr); + return; + +sc_32: + blast_scache32_page(addr); + return; + +sc_64: + blast_scache64_page(addr); + return; + +sc_128: + blast_scache128_page(addr); + return; + +init: + if (sc_lsize == 16) + l = &&sc_16; + else if (sc_lsize == 32) + l = &&sc_32; + else if (sc_lsize == 64) + l = &&sc_64; + else if (sc_lsize == 128) + l = &&sc_128; + goto *l; +} + +static void r4k_blast_scache(void) +{ + unsigned long sc_lsize = current_cpu_data.scache.linesz; + static void *l = &&init; + + goto *l; + +sc_16: + blast_scache16(); + return; + +sc_32: + blast_scache32(); + return; + +sc_64: + blast_scache64(); + return; + +sc_128: + blast_scache128(); + return; + +init: + if (sc_lsize == 16) + l = &&sc_16; + else if (sc_lsize == 32) + l = &&sc_32; + else if (sc_lsize == 64) + l = &&sc_64; + else if (sc_lsize == 128) + l = &&sc_128; + goto *l; +} + +static void r4k_flush_cache_all(void) +{ + if (!cpu_has_dc_aliases) + return; + + r4k_blast_dcache(); + r4k_blast_icache(); +} + +static void r4k___flush_cache_all(void) +{ + r4k_blast_dcache(); + r4k_blast_icache(); + + switch (current_cpu_data.cputype) { + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400SC: + case CPU_R4400MC: + case CPU_R10000: + case CPU_R12000: + r4k_blast_scache(); + } +} + +static void r4k_flush_cache_range(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + if (!cpu_has_dc_aliases) + return; + + if (cpu_context(smp_processor_id(), mm) != 0) { + r4k_blast_dcache(); + r4k_blast_icache(); + } +} + +static void r4k_flush_cache_mm(struct mm_struct *mm) +{ + if (!cpu_has_dc_aliases) + return; + + if (!cpu_context(smp_processor_id(), mm)) + return; + + r4k_blast_dcache(); + r4k_blast_icache(); + + /* + * Kludge alert. For obscure reasons R4000SC and R4400SC go nuts if we + * only flush the primary caches but R10000 and R12000 behave sane ... + */ + if (current_cpu_data.cputype == CPU_R4000SC || + current_cpu_data.cputype == CPU_R4000MC || + current_cpu_data.cputype == CPU_R4400SC || + current_cpu_data.cputype == CPU_R4400MC) + r4k_blast_scache(); +} + +static void r4k_flush_cache_page(struct vm_area_struct *vma, + unsigned long page) +{ + int exec = vma->vm_flags & VM_EXEC; + struct mm_struct *mm = vma->vm_mm; + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + + /* + * If ownes no valid ASID yet, cannot possibly have gotten + * this page into the cache. + */ + if (cpu_context(smp_processor_id(), mm) == 0) + return; + + page &= PAGE_MASK; + pgdp = pgd_offset(mm, page); + pmdp = pmd_offset(pgdp, page); + ptep = pte_offset(pmdp, page); + + /* + * If the page isn't marked valid, the page cannot possibly be + * in the cache. + */ + if (!(pte_val(*ptep) & _PAGE_PRESENT)) + return; + + /* + * Doing flushes for another ASID than the current one is + * too difficult since stupid R4k caches do a TLB translation + * for every cache flush operation. So we do indexed flushes + * in that case, which doesn't overly flush the cache too much. + */ + if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { + if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) + r4k_blast_dcache_page(page); + if (exec) + r4k_blast_icache_page(page); + + return; + } + + /* + * Do indexed flush, too much work to get the (possible) TLB refills + * to work correctly. + */ + page = (KSEG0 + (page & (dcache_size - 1))); + if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) + r4k_blast_dcache_page_indexed(page); + if (exec) { + if (cpu_has_vtag_icache) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); + } else + r4k_blast_icache_page_indexed(page); + } +} + +static void r4k_flush_data_cache_page(unsigned long addr) +{ + r4k_blast_dcache_page(addr); +} + +static void r4k_flush_icache_range(unsigned long start, unsigned long end) +{ + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + unsigned long addr, aend; + + if (!cpu_has_ic_fills_f_dc) { + if (end - start > dcache_size) + r4k_blast_dcache(); + else { + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); + + while (1) { + /* Hit_Writeback_Inv_D */ + protected_writeback_dcache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } + } + } + + if (end - start > icache_size) + r4k_blast_icache(); + else { + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); + while (1) { + /* Hit_Invalidate_I */ + protected_flush_icache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } + } +} + +/* + * Ok, this seriously sucks. We use them to flush a user page but don't + * know the virtual address, so we have to blast away the whole icache + * which is significantly more expensive than the real thing. Otoh we at + * least know the kernel address of the page so we can flush it + * selectivly. + */ +static void r4k_flush_icache_page(struct vm_area_struct *vma, + struct page *page) +{ + /* + * If there's no context yet, or the page isn't executable, no icache + * flush is needed. + */ + if (!(vma->vm_flags & VM_EXEC)) + return; + + /* + * Tricky ... Because we don't know the virtual address we've got the + * choice of either invalidating the entire primary and secondary + * caches or invalidating the secondary caches also. With the subset + * enforcment on R4000SC, R4400SC, R10000 and R12000 invalidating the + * secondary cache will result in any entries in the primary caches + * also getting invalidated which hopefully is a bit more economical. + */ + if (cpu_has_subset_pcaches) { + unsigned long addr = (unsigned long) page_address(page); + r4k_blast_scache_page(addr); + + return; + } + + if (!cpu_has_ic_fills_f_dc) { + unsigned long addr = (unsigned long) page_address(page); + r4k_blast_dcache_page(addr); + } + + /* + * We're not sure of the virtual address(es) involved here, so + * we have to flush the entire I-cache. + */ + if (cpu_has_vtag_icache) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); + } else + r4k_blast_icache(); +} + +#ifdef CONFIG_NONCOHERENT_IO + +static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + + if (cpu_has_subset_pcaches) { + unsigned long sc_lsize = current_cpu_data.scache.linesz; + + if (size >= scache_size) { + r4k_blast_scache(); + return; + } + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } + return; + } + + /* + * Either no secondary cache or the available caches don't have the + * subset property so we have to flush the primary caches + * explicitly + */ + if (size >= dcache_size) { + r4k_blast_dcache(); + } else { + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + + R4600_HIT_CACHEOP_WAR_IMPL; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); + while (1) { + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) + break; + a += dc_lsize; + } + } + + bc_wback_inv(addr, size); +} + +static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + + if (cpu_has_subset_pcaches) { + unsigned long sc_lsize = current_cpu_data.scache.linesz; + + if (size >= scache_size) { + r4k_blast_scache(); + return; + } + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } + return; + } + + if (size >= dcache_size) { + r4k_blast_dcache(); + } else { + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + + R4600_HIT_CACHEOP_WAR_IMPL; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); + while (1) { + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) + break; + a += dc_lsize; + } + } + + bc_inv(addr, size); +} +#endif /* CONFIG_NONCOHERENT_IO */ + +/* + * While we're protected against bad userland addresses we don't care + * very much about what happens in that case. Usually a segmentation + * fault will dump the process later on anyway ... + */ +static void r4k_flush_cache_sigtramp(unsigned long addr) +{ + unsigned long ic_lsize = current_cpu_data.icache.linesz; + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + + R4600_HIT_CACHEOP_WAR_IMPL; + protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); + protected_flush_icache_line(addr & ~(ic_lsize - 1)); + if (MIPS4K_ICACHE_REFILL_WAR) { + __asm__ __volatile__ ( + ".set push\n\t" + ".set noat\n\t" + ".set mips3\n\t" +#if CONFIG_MIPS32 + "la $at,1f\n\t" +#endif +#if CONFIG_MIPS64 + "dla $at,1f\n\t" +#endif + "cache %0,($at)\n\t" + "nop; nop; nop\n" + "1:\n\t" + ".set pop" + : + : "i" (Hit_Invalidate_I)); + } + if (MIPS_CACHE_SYNC_WAR) + __asm__ __volatile__ ("sync"); +} + +static void r4k_flush_icache_all(void) +{ + if (cpu_has_vtag_icache) + r4k_blast_icache(); +} + +static inline void rm7k_erratum31(void) +{ + const unsigned long ic_lsize = 32; + unsigned long addr; + + /* RM7000 erratum #31. The icache is screwed at startup. */ + write_c0_taglo(0); + write_c0_taghi(0); + + for (addr = KSEG0; addr <= KSEG0 + 4096; addr += ic_lsize) { + __asm__ __volatile__ ( + ".set noreorder\n\t" + ".set mips3\n\t" + "cache\t%1, 0(%0)\n\t" + "cache\t%1, 0x1000(%0)\n\t" + "cache\t%1, 0x2000(%0)\n\t" + "cache\t%1, 0x3000(%0)\n\t" + "cache\t%2, 0(%0)\n\t" + "cache\t%2, 0x1000(%0)\n\t" + "cache\t%2, 0x2000(%0)\n\t" + "cache\t%2, 0x3000(%0)\n\t" + "cache\t%1, 0(%0)\n\t" + "cache\t%1, 0x1000(%0)\n\t" + "cache\t%1, 0x2000(%0)\n\t" + "cache\t%1, 0x3000(%0)\n\t" + ".set\tmips0\n\t" + ".set\treorder\n\t" + : + : "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill)); + } +} + +static char *way_string[] = { NULL, "direct mapped", "2-way", "3-way", "4-way", + "5-way", "6-way", "7-way", "8-way" +}; + +static void __init probe_pcache(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int config = read_c0_config(); + unsigned int prid = read_c0_prid(); + unsigned long config1; + unsigned int lsize; + + switch (c->cputype) { + case CPU_R4600: /* QED style two way caches? */ + case CPU_R4700: + case CPU_R5000: + case CPU_NEVADA: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 2; + c->icache.waybit = ffs(icache_size/2) - 1; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 2; + c->dcache.waybit= ffs(dcache_size/2) - 1; + break; + + case CPU_R5432: + case CPU_R5500: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 2; + c->icache.waybit= 0; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 2; + c->dcache.waybit = 0; + break; + + case CPU_TX49XX: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 4; + c->icache.waybit= 0; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 4; + c->dcache.waybit = 0; + break; + + case CPU_R4000PC: + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400PC: + case CPU_R4400SC: + case CPU_R4400MC: + case CPU_R4300: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 1; + c->icache.waybit = 0; /* doesn't matter */ + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 1; + c->dcache.waybit = 0; /* does not matter */ + break; + + case CPU_R10000: + case CPU_R12000: + icache_size = 1 << (12 + ((config & R10K_CONF_IC) >> 29)); + c->icache.linesz = 64; + c->icache.ways = 2; + c->icache.waybit = 0; + + dcache_size = 1 << (12 + ((config & R10K_CONF_DC) >> 26)); + c->dcache.linesz = 32; + c->dcache.ways = 2; + c->dcache.waybit = 0; + break; + + case CPU_VR4131: + icache_size = 1 << (10 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 2; + c->icache.waybit = ffs(icache_size/2) - 1; + + dcache_size = 1 << (10 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 2; + c->dcache.waybit = ffs(dcache_size/2) - 1; + break; + + case CPU_VR41XX: + case CPU_VR4111: + case CPU_VR4121: + case CPU_VR4122: + case CPU_VR4181: + case CPU_VR4181A: + icache_size = 1 << (10 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 1; + c->icache.waybit = 0; /* doesn't matter */ + + dcache_size = 1 << (10 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 1; + c->dcache.waybit = 0; /* does not matter */ + break; + + case CPU_RM7000: + rm7k_erratum31(); + + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 4; + c->icache.waybit = ffs(icache_size / c->icache.ways) - 1; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 4; + c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1; + break; + + default: + if (!(config & MIPS_CONF_M)) + panic("Don't know how to probe P-caches on this cpu."); + + /* + * So we seem to be a MIPS32 or MIPS64 CPU + * So let's probe the I-cache ... + */ + config1 = read_c0_config1(); + + if ((lsize = ((config1 >> 19) & 7))) + c->icache.linesz = 2 << lsize; + else + c->icache.linesz = lsize; + c->icache.sets = 64 << ((config1 >> 22) & 7); + c->icache.ways = 1 + ((config1 >> 16) & 7); + + icache_size = c->icache.sets * + c->icache.ways * + c->icache.linesz; + c->icache.waybit = ffs(icache_size/c->icache.ways) - 1; + + /* + * Now probe the MIPS32 / MIPS64 data cache. + */ + c->dcache.flags = 0; + + if ((lsize = ((config1 >> 10) & 7))) + c->dcache.linesz = 2 << lsize; + else + c->dcache.linesz= lsize; + c->dcache.sets = 64 << ((config1 >> 13) & 7); + c->dcache.ways = 1 + ((config1 >> 7) & 7); + + dcache_size = c->dcache.sets * + c->dcache.ways * + c->dcache.linesz; + c->dcache.waybit = ffs(dcache_size/c->dcache.ways) - 1; + break; + } + + /* + * Processor configuration sanity check for the R4000SC erratum + * #5. With page sizes larger than 32kB there is no possibility + * to get a VCE exception anymore so we don't care about this + * misconfiguration. The case is rather theoretical anyway; + * presumably no vendor is shipping his hardware in the "bad" + * configuration. + */ + if ((prid & 0xff00) == PRID_IMP_R4000 && (prid & 0xff) < 0x40 && + !(config & CONF_SC) && c->icache.linesz != 16 && + PAGE_SIZE <= 0x8000) + panic("Improper R4000SC processor configuration detected"); + + /* compute a couple of other cache variables */ + c->icache.waysize = icache_size / c->icache.ways; + c->dcache.waysize = dcache_size / c->dcache.ways; + + c->icache.sets = icache_size / (c->icache.linesz * c->icache.ways); + c->dcache.sets = dcache_size / (c->dcache.linesz * c->dcache.ways); + + /* + * R10000 and R12000 P-caches are odd in a positive way. They're 32kB + * 2-way virtually indexed so normally would suffer from aliases. So + * normally they'd suffer from aliases but magic in the hardware deals + * with that for us so we don't need to take care ourselves. + */ + if (c->cputype != CPU_R10000 && c->cputype != CPU_R12000) + if (c->dcache.waysize > PAGE_SIZE) + c->dcache.flags |= MIPS_CACHE_ALIASES; + + if (config & 0x8) /* VI bit */ + c->icache.flags |= MIPS_CACHE_VTAG; + + switch (c->cputype) { + case CPU_20KC: + /* + * Some older 20Kc chips doesn't have the 'VI' bit in + * the config register. + */ + c->icache.flags |= MIPS_CACHE_VTAG; + break; + + case CPU_AU1500: + c->icache.flags |= MIPS_CACHE_IC_F_DC; + break; + } + + printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n", + icache_size >> 10, + cpu_has_vtag_icache ? "virtually tagged" : "physically tagged", + way_string[c->icache.ways], c->icache.linesz); + + printk("Primary data cache %ldkB %s, linesize %d bytes.\n", + dcache_size >> 10, way_string[c->dcache.ways], c->dcache.linesz); +} + +/* + * If you even _breathe_ on this function, look at the gcc output and make sure + * it does not pop things on and off the stack for the cache sizing loop that + * executes in KSEG1 space or else you will crash and burn badly. You have + * been warned. + */ +static int __init probe_scache(void) +{ + extern unsigned long stext; + unsigned long flags, addr, begin, end, pow2; + unsigned int config = read_c0_config(); + struct cpuinfo_mips *c = ¤t_cpu_data; + int tmp; + + if (config & CONF_SC) + return 0; + + begin = (unsigned long) &stext; + begin &= ~((4 * 1024 * 1024) - 1); + end = begin + (4 * 1024 * 1024); + + /* + * This is such a bitch, you'd think they would make it easy to do + * this. Away you daemons of stupidity! + */ + local_irq_save(flags); + + /* Fill each size-multiple cache line with a valid tag. */ + pow2 = (64 * 1024); + for (addr = begin; addr < end; addr = (begin + pow2)) { + unsigned long *p = (unsigned long *) addr; + __asm__ __volatile__("nop" : : "r" (*p)); /* whee... */ + pow2 <<= 1; + } + + /* Load first line with zero (therefore invalid) tag. */ + write_c0_taglo(0); + write_c0_taghi(0); + __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */ + cache_op(Index_Store_Tag_I, begin); + cache_op(Index_Store_Tag_D, begin); + cache_op(Index_Store_Tag_SD, begin); + + /* Now search for the wrap around point. */ + pow2 = (128 * 1024); + tmp = 0; + for (addr = begin + (128 * 1024); addr < end; addr = begin + pow2) { + cache_op(Index_Load_Tag_SD, addr); + __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */ + if (!read_c0_taglo()) + break; + pow2 <<= 1; + } + local_irq_restore(flags); + addr -= begin; + + scache_size = addr; + c->scache.linesz = 16 << ((config & R4K_CONF_SB) >> 22); + c->scache.ways = 1; + c->dcache.waybit = 0; /* does not matter */ + + return 1; +} + +static void __init setup_noscache_funcs(void) +{ + unsigned int prid; + + switch (current_cpu_data.dcache.linesz) { + case 16: + if (cpu_has_64bits) + _clear_page = r4k_clear_page_d16; + else + _clear_page = r4k_clear_page32_d16; + _copy_page = r4k_copy_page_d16; + + break; + case 32: + prid = read_c0_prid() & 0xfff0; + if (prid == 0x2010) { /* R4600 V1.7 */ + _clear_page = r4k_clear_page_r4600_v1; + _copy_page = r4k_copy_page_r4600_v1; + } else if (prid == 0x2020) { /* R4600 V2.0 */ + _clear_page = r4k_clear_page_r4600_v2; + _copy_page = r4k_copy_page_r4600_v2; + } else { + if (cpu_has_64bits) + _clear_page = r4k_clear_page_d32; + else + _clear_page = r4k_clear_page32_d32; + _copy_page = r4k_copy_page_d32; + } + break; + } +} + +static void __init setup_scache_funcs(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + + if (c->dcache.linesz > c->scache.linesz) + panic("Invalid primary cache configuration detected"); + + if (c->cputype == CPU_R10000 || c->cputype == CPU_R12000) { + _clear_page = andes_clear_page; + _copy_page = andes_copy_page; + return; + } + + switch (c->scache.linesz) { + case 16: + _clear_page = r4k_clear_page_s16; + _copy_page = r4k_copy_page_s16; + break; + case 32: + _clear_page = r4k_clear_page_s32; + _copy_page = r4k_copy_page_s32; + break; + case 64: + _clear_page = r4k_clear_page_s64; + _copy_page = r4k_copy_page_s64; + break; + case 128: + _clear_page = r4k_clear_page_s128; + _copy_page = r4k_copy_page_s128; + break; + } +} + +typedef int (*probe_func_t)(unsigned long); +extern int r5k_sc_init(void); +extern int rm7k_sc_init(void); + +static void __init setup_scache(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int config = read_c0_config(); + probe_func_t probe_scache_kseg1; + int sc_present = 0; + + /* + * Do the probing thing on R4000SC and R4400SC processors. Other + * processors don't have a S-cache that would be relevant to the + * Linux memory managment. + */ + switch (c->cputype) { + case CPU_R4000PC: + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400PC: + case CPU_R4400SC: + case CPU_R4400MC: + probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); + sc_present = probe_scache_kseg1(config); + break; + + case CPU_R10000: + case CPU_R12000: + scache_size = 0x80000 << ((config & R10K_CONF_SS) >> 16); + c->scache.linesz = 64 << ((config >> 13) & 1); + c->scache.ways = 2; + c->scache.waybit= 0; + sc_present = 1; + break; + + case CPU_R5000: + case CPU_NEVADA: + setup_noscache_funcs(); +#ifdef CONFIG_R5000_CPU_SCACHE + r5k_sc_init(); +#endif + return; + + case CPU_RM7000: + setup_noscache_funcs(); +#ifdef CONFIG_RM7000_CPU_SCACHE + rm7k_sc_init(); +#endif + return; + + default: + sc_present = 0; + } + + if (!sc_present) { + setup_noscache_funcs(); + return; + } + + if ((c->isa_level == MIPS_CPU_ISA_M32 || + c->isa_level == MIPS_CPU_ISA_M64) && + !(c->scache.flags & MIPS_CACHE_NOT_PRESENT)) + panic("Dunno how to handle MIPS32 / MIPS64 second level cache"); + + /* compute a couple of other cache variables */ + c->scache.waysize = scache_size / c->scache.ways; + + c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways); + + printk("Unified secondary cache %ldkB %s, linesize %d bytes.\n", + scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); + + c->options |= MIPS_CPU_SUBSET_CACHES; + setup_scache_funcs(); +} + +static inline void coherency_setup(void) +{ + change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); + + /* + * c0_status.cu=0 specifies that updates by the sc instruction use + * the coherency mode specified by the TLB; 1 means cachable + * coherent update on write will be used. Not all processors have + * this bit and; some wire it to zero, others like Toshiba had the + * silly idea of putting something else there ... + */ + switch (current_cpu_data.cputype) { + case CPU_R4000PC: + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400PC: + case CPU_R4400SC: + case CPU_R4400MC: + clear_c0_config(CONF_CU); + break; + } + +} + +void __init ld_mmu_r4xx0(void) +{ + extern char except_vec2_generic; + struct cpuinfo_mips *c = ¤t_cpu_data; + + /* Default cache error handler for R4000 and R5000 family */ + memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80); + memcpy((void *)(KSEG1 + 0x100), &except_vec2_generic, 0x80); + + probe_pcache(); + setup_scache(); + coherency_setup(); + + if (c->dcache.sets * c->dcache.ways > PAGE_SIZE) + c->dcache.flags |= MIPS_CACHE_ALIASES; + + /* + * Some MIPS32 and MIPS64 processors have physically indexed caches. + * This code supports virtually indexed processors and will be + * unnecessarily inefficient on physically indexed processors. + */ + shm_align_mask = max_t( unsigned long, + c->dcache.sets * c->dcache.linesz - 1, + PAGE_SIZE - 1); + + _flush_cache_all = r4k_flush_cache_all; + ___flush_cache_all = r4k___flush_cache_all; + _flush_cache_mm = r4k_flush_cache_mm; + _flush_cache_page = r4k_flush_cache_page; + _flush_icache_page = r4k_flush_icache_page; + _flush_cache_range = r4k_flush_cache_range; + + _flush_cache_sigtramp = r4k_flush_cache_sigtramp; + _flush_icache_all = r4k_flush_icache_all; + _flush_data_cache_page = r4k_flush_data_cache_page; + _flush_icache_range = r4k_flush_icache_range; + +#ifdef CONFIG_NONCOHERENT_IO + _dma_cache_wback_inv = r4k_dma_cache_wback_inv; + _dma_cache_wback = r4k_dma_cache_wback_inv; + _dma_cache_inv = r4k_dma_cache_inv; +#endif + + __flush_cache_all(); +} diff -urN linux-2.4.21-bk37/arch/mips64/mm/c-sb1.c linux-2.4.21-bk38/arch/mips64/mm/c-sb1.c --- linux-2.4.21-bk37/arch/mips64/mm/c-sb1.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/c-sb1.c 2003-08-24 02:55:58.000000000 -0700 @@ -25,6 +25,15 @@ #include #include +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS +extern void sb1_dma_init(void); +extern void sb1_clear_page_dma(void * page); +extern void sb1_copy_page_dma(void * to, void * from); +#else +extern void sb1_clear_page(void * page); +extern void sb1_copy_page(void * to, void * from); +#endif + /* These are probed at ld_mmu time */ static unsigned long icache_size; static unsigned long dcache_size; @@ -33,6 +42,7 @@ static unsigned long dcache_line_size; static unsigned int icache_index_mask; +static unsigned int dcache_index_mask; static unsigned long icache_assoc; static unsigned long dcache_assoc; @@ -40,6 +50,9 @@ static unsigned int icache_sets; static unsigned int dcache_sets; +static unsigned int icache_range_cutoff; +static unsigned int dcache_range_cutoff; + /* * The dcache is fully coherent to the system, with one * big caveat: the instruction stream. In other words, @@ -53,68 +66,223 @@ * to flush it */ -static void sb1_flush_cache_all(void) -{ -} - -static inline void local_sb1___flush_dcache_all(void) +/* + * Writeback and invalidate the entire dcache + */ +static inline void __sb1_writeback_inv_dcache_all(void) { - /* - * Haven't worried too much about speed here; given that we're flushing - * the icache, the time to invalidate is dwarfed by the time it's going - * to take to refill it. Register usage: - * - * $1 - moving cache index - * $2 - set count - */ __asm__ __volatile__ ( ".set push \n" ".set noreorder \n" ".set noat \n" ".set mips4 \n" - " move $1, %2 \n" /* Start at index 0 */ - "1: cache %3, 0($1) \n" /* WB/Invalidate this index */ - " daddiu %1, %1, -1 \n" /* Decrement loop count */ + " move $1, $0 \n" /* Start at index 0 */ + "1: cache %2, 0($1) \n" /* Invalidate this index */ + " cache %2, (1<<13)($1)\n" /* Invalidate this index */ + " cache %2, (2<<13)($1)\n" /* Invalidate this index */ + " cache %2, (3<<13)($1)\n" /* Invalidate this index */ + " daddiu %1, %1, -1 \n" /* Decrement loop count */ " bnez %1, 1b \n" /* loop test */ - " daddu $1, $1, %0 \n" /* Next address */ + " daddu $1, $1, %0 \n" /* Next address */ ".set pop \n" : - : "r" (dcache_line_size), "r" (dcache_sets * dcache_assoc), - "r" (KSEG0), "i" (Index_Writeback_Inv_D)); + : "r" (dcache_line_size), "r" (dcache_sets), + "i" (Index_Writeback_Inv_D)); +} +/* + * Writeback and invalidate a range of the dcache. The addresses are + * virtual, and since we're using index ops and bit 12 is part of both + * the virtual frame and physical index, we have to clear both sets + * (bit 12 set and cleared). + */ +static inline void __sb1_writeback_inv_dcache_range(unsigned long start, + unsigned long end) +{ + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips4 \n" + " and $1, %0, %3 \n" /* mask non-index bits */ + "1: cache %4, (0<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-WB-inval this address */ + " xori $1, $1, 1<<12 \n" + " cache %4, (0<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-WB-inval this address */ + " daddu %0, %0, %2 \n" /* next line */ + " bne %0, %1, 1b \n" /* loop test */ + " and $1, %0, %3 \n" /* mask non-index bits */ + " sync \n" + " .set pop \n" + : + : "r" (start & ~(dcache_line_size - 1)), + "r" ((end + dcache_line_size - 1) & ~(dcache_line_size - 1)), + "r" (dcache_line_size), + "r" (dcache_index_mask), + "i" (Index_Writeback_Inv_D)); +} + +/* + * Writeback and invalidate a range of the dcache. With physical + * addresseses, we don't have to worry about possible bit 12 aliasing. + * XXXKW is it worth turning on KX and using hit ops with xkphys? + */ +static inline void __sb1_writeback_inv_dcache_phys_range(unsigned long start, + unsigned long end) +{ + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips4 \n" + " and $1, %0, %3 \n" /* mask non-index bits */ + "1: cache %4, (0<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-WB-inval this address */ + " daddu %0, %0, %2 \n" /* next line */ + " bne %0, %1, 1b \n" /* loop test */ + " and $1, %0, %3 \n" /* mask non-index bits */ + " sync \n" + " .set pop \n" + : + : "r" (start & ~(dcache_line_size - 1)), + "r" ((end + dcache_line_size - 1) & ~(dcache_line_size - 1)), + "r" (dcache_line_size), + "r" (dcache_index_mask), + "i" (Index_Writeback_Inv_D)); +} + + +/* + * Invalidate the entire icache + */ +static inline void __sb1_flush_icache_all(void) +{ __asm__ __volatile__ ( ".set push \n" ".set noreorder \n" - ".set mips2 \n" - "sync \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS /* Bug 1384 */ - "sync \n" + ".set noat \n" + ".set mips4 \n" + " move $1, $0 \n" /* Start at index 0 */ + "1: cache %2, 0($1) \n" /* Invalidate this index */ + " cache %2, (1<<13)($1)\n" /* Invalidate this index */ + " cache %2, (2<<13)($1)\n" /* Invalidate this index */ + " cache %2, (3<<13)($1)\n" /* Invalidate this index */ + " daddiu %1, %1, -1 \n" /* Decrement loop count */ + " bnez %1, 1b \n" /* loop test */ + " daddu $1, $1, %0 \n" /* Next address */ + " bnezl $0, 2f \n" /* Force mispredict */ + " nop \n" + "2: sync \n" + ".set pop \n" + : + : "r" (icache_line_size), "r" (icache_sets), + "i" (Index_Invalidate_I)); +} + +/* + * Flush the icache for a given physical page. Need to writeback the + * dcache first, then invalidate the icache. If the page isn't + * executable, nothing is required. + */ +static void local_sb1_flush_cache_page(struct vm_area_struct *vma, + unsigned long addr) +{ + int cpu = smp_processor_id(); + +#ifndef CONFIG_SMP + if (!(vma->vm_flags & VM_EXEC)) + return; #endif - ".set pop \n"); + + __sb1_writeback_inv_dcache_range(addr, addr + PAGE_SIZE); + + /* + * Bumping the ASID is probably cheaper than the flush ... + */ + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); +} + +#ifdef CONFIG_SMP +struct flush_cache_page_args { + struct vm_area_struct *vma; + unsigned long addr; +}; + +static void sb1_flush_cache_page_ipi(void *info) +{ + struct flush_cache_page_args *args = info; + + local_sb1_flush_cache_page(args->vma, args->addr); } -static inline void local_sb1___flush_icache_all(void) +/* Dirty dcache could be on another CPU, so do the IPIs */ +static void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr) +{ + struct flush_cache_page_args args; + + if (!(vma->vm_flags & VM_EXEC)) + return; + + args.vma = vma; + args.addr = addr; + smp_call_function(sb1_flush_cache_page_ipi, (void *) &args, 1, 1); + local_sb1_flush_cache_page(vma, addr); +} +#else +void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr); +asm("sb1_flush_cache_page = local_sb1_flush_cache_page"); +#endif + +/* + * Invalidate a range of the icache. The addresses are virtual, and + * the cache is virtually indexed and tagged. However, we don't + * necessarily have the right ASID context, so use index ops instead + * of hit ops. + */ +static inline void __sb1_flush_icache_range(unsigned long start, + unsigned long end) { __asm__ __volatile__ ( ".set push \n" ".set noreorder \n" ".set noat \n" ".set mips4 \n" - " move $1, %2 \n" /* Start at index 0 */ - "1: cache %3, 0($1) \n" /* Invalidate this index */ - " daddiu %1, %1, -1 \n" /* Decrement loop count */ - " bnez %1, 1b \n" /* loop test */ - " daddu $1, $1, %0 \n" /* Next address */ + " and $1, %0, %3 \n" /* mask non-index bits */ + "1: cache %4, (0<<13)($1) \n" /* Index-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-inval this address */ + " daddu %0, %0, %2 \n" /* next line */ + " bne %0, %1, 1b \n" /* loop test */ + " and $1, %0, %3 \n" /* mask non-index bits */ + " bnezl $0, 2f \n" /* Force mispredict */ + " nop \n" + "2: sync \n" ".set pop \n" : - : "r" (icache_line_size), "r" (icache_sets * icache_assoc), - "r" (KSEG0), "i" (Index_Invalidate_I)); + : "r" (start & ~(icache_line_size - 1)), + "r" ((end + icache_line_size - 1) & ~(icache_line_size - 1)), + "r" (icache_line_size), + "r" (icache_index_mask), + "i" (Index_Invalidate_I)); } + +/* + * Invalidate all caches on this CPU + */ static void local_sb1___flush_cache_all(void) { - local_sb1___flush_dcache_all(); - local_sb1___flush_icache_all(); + __sb1_writeback_inv_dcache_all(); + __sb1_flush_icache_all(); } #ifdef CONFIG_SMP @@ -131,81 +299,28 @@ asm("sb1___flush_cache_all = local_sb1___flush_cache_all"); #endif - /* * When flushing a range in the icache, we have to first writeback * the dcache for the same range, so new ifetches will see any * data that was dirty in the dcache. * - * The start/end arguments are expected to be Kseg addresses. + * The start/end arguments are Kseg addresses (possibly mapped Kseg). */ static void local_sb1_flush_icache_range(unsigned long start, unsigned long end) { -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - unsigned long flags; - local_irq_save(flags); -#endif - - __asm__ __volatile__ ( - ".set push \n" - ".set noreorder \n" - ".set noat \n" - ".set mips4 \n" - " move $1, %0 \n" - "1: \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - ".align 3 \n" - " lw $0, 0($1) \n" /* Bug 1370, 1368 */ - " sync \n" -#endif - " cache %3, 0($1) \n" /* Hit-WB{,-inval} this address */ - " bne $1, %1, 1b \n" /* loop test */ - " daddu $1, $1, %2 \n" /* next line */ - ".set pop \n" - : - : "r" ((start + dcache_line_size - 1) & ~(dcache_line_size - 1)), - "r" ((end + dcache_line_size - 1) & ~(dcache_line_size - 1)), - "r" (dcache_line_size), -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - "i" (Hit_Writeback_Inv_D) -#else - "i" (Hit_Writeback_D) -#endif - ); - __asm__ __volatile__ ( - ".set push \n" - ".set noreorder \n" - ".set mips2 \n" - "sync \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS /* Bug 1384 */ - "sync \n" -#endif - ".set pop \n"); -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - local_irq_restore(flags); -#endif - - __asm__ __volatile__ ( - ".set push \n" - ".set noreorder \n" - ".set noat \n" - ".set mips4 \n" - " move $1, %0 \n" - ".align 3 \n" - "1: cache %3, (0<<13)($1) \n" /* Index-inval this address */ - " cache %3, (1<<13)($1) \n" /* Index-inval this address */ - " cache %3, (2<<13)($1) \n" /* Index-inval this address */ - " cache %3, (3<<13)($1) \n" /* Index-inval this address */ - " bne $1, %1, 1b \n" /* loop test */ - " daddu $1, $1, %2 \n" /* next line */ - ".set pop \n" - : - : "r" (start & ~(icache_line_size - 1)), - "r" ((end - 1) & ~(icache_line_size - 1)), - "r" (icache_line_size), - "i" (Index_Invalidate_I)); + /* Just wb-inv the whole dcache if the range is big enough */ + if ((end - start) > dcache_range_cutoff) + __sb1_writeback_inv_dcache_all(); + else + __sb1_writeback_inv_dcache_range(start, end); + + /* Just flush the whole icache if the range is big enough */ + if ((end - start) > icache_range_cutoff) + __sb1_flush_icache_all(); + else + __sb1_flush_icache_range(start, end); } #ifdef CONFIG_SMP @@ -236,127 +351,105 @@ #endif /* - * If there's no context yet, or the page isn't executable, no icache flush - * is needed - * - * This is broken. If there is no context yet we still have to writeback - * the d-cache to memory. + * Flush the icache for a given physical page. Need to writeback the + * dcache first, then invalidate the icache. If the page isn't + * executable, nothing is required. */ -static void sb1_flush_icache_page(struct vm_area_struct *vma, +static void local_sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page) { - if (!(vma->vm_flags & VM_EXEC)) { + unsigned long start; + int cpu = smp_processor_id(); + +#ifndef CONFIG_SMP + if (!(vma->vm_flags & VM_EXEC)) return; - } +#endif + /* Need to writeback any dirty data for that page, we have the PA */ + start = (unsigned long)(page-mem_map) << PAGE_SHIFT; + __sb1_writeback_inv_dcache_phys_range(start, start + PAGE_SIZE); /* - * We're not sure of the virtual address(es) involved here, so - * conservatively flush the entire caches on all processors - * (ouch). - * - * Bumping the ASID may well be cheaper, need to experiment ... + * If there's a context, bump the ASID (cheaper than a flush, + * since we don't know VAs!) */ - sb1___flush_cache_all(); + if (cpu_context(cpu, vma->vm_mm) != 0) { + drop_mmu_context(vma->vm_mm, cpu); + } } -static inline void protected_flush_icache_line(unsigned long addr) +#ifdef CONFIG_SMP +struct flush_icache_page_args { + struct vm_area_struct *vma; + struct page *page; +}; + +static void sb1_flush_icache_page_ipi(void *info) { - __asm__ __volatile__( - " .set push \n" - " .set noreorder \n" - " .set mips4 \n" - "1: cache %1, (%0) \n" - "2: .set pop \n" - " .section __ex_table,\"a\"\n" - " .dword 1b, 2b \n" - " .previous" - : - : "r" (addr), "i" (Hit_Invalidate_I)); + struct flush_icache_page_args *args = info; + local_sb1_flush_icache_page(args->vma, args->page); } -static inline void protected_writeback_dcache_line(unsigned long addr) +/* Dirty dcache could be on another CPU, so do the IPIs */ +static void sb1_flush_icache_page(struct vm_area_struct *vma, + struct page *page) { -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - /* Have to be sure the TLB entry exists for the cache op, - so we have to be sure that nothing happens in between the - lw and the cache op - */ - unsigned long flags; - local_irq_save(flags); -#endif - __asm__ __volatile__( - " .set push \n" - " .set noreorder \n" - " .set mips4 \n" - " \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - "1: lw $0, (%0) \n" - " sync \n" - " .section __ex_table,\"a\"\n" - " .dword 1b, 3f \n" - " .previous \n" -#endif - "2: cache %1, 0(%0) \n" /* Hit-WB{-inval} this address */ - /* XXX: should be able to do this after both dcache cache - ops, but there's no guarantee that this will be inlined, - and the pass1 restriction checker can't detect syncs - following cache ops except in the following basic block. - */ - " sync \n" -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS /* Bug 1384 */ - " sync \n" -#endif - "3: .set pop \n" - " .section __ex_table,\"a\"\n" - " .dword 2b, 3b \n" - " .previous" - : - : "r" (addr), -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - "i" (Hit_Writeback_Inv_D) + struct flush_icache_page_args args; + + if (!(vma->vm_flags & VM_EXEC)) + return; + args.vma = vma; + args.page = page; + smp_call_function(sb1_flush_icache_page_ipi, (void *) &args, 1, 1); + local_sb1_flush_icache_page(vma, page); +} #else - "i" (Hit_Writeback_D) +void sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page); +asm("sb1_flush_icache_page = local_sb1_flush_icache_page"); #endif - ); -#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - local_irq_restore(flags); -#endif -} /* * A signal trampoline must fit into a single cacheline. */ static void local_sb1_flush_cache_sigtramp(unsigned long addr) { - unsigned long daddr, iaddr; - - daddr = addr & ~(dcache_line_size - 1); - protected_writeback_dcache_line(daddr); - iaddr = addr & ~(icache_line_size - 1); - protected_flush_icache_line(iaddr); + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips4 \n" + " cache %2, (0<<13)(%0) \n" /* Index-inval this address */ + " cache %2, (1<<13)(%0) \n" /* Index-inval this address */ + " cache %2, (2<<13)(%0) \n" /* Index-inval this address */ + " cache %2, (3<<13)(%0) \n" /* Index-inval this address */ + " xori $1, %0, 1<<12 \n" /* Flip index bit 12 */ + " cache %2, (0<<13)($1) \n" /* Index-inval this address */ + " cache %2, (1<<13)($1) \n" /* Index-inval this address */ + " cache %2, (2<<13)($1) \n" /* Index-inval this address */ + " cache %2, (3<<13)($1) \n" /* Index-inval this address */ + " cache %3, (0<<13)(%1) \n" /* Index-inval this address */ + " cache %3, (1<<13)(%1) \n" /* Index-inval this address */ + " cache %3, (2<<13)(%1) \n" /* Index-inval this address */ + " cache %3, (3<<13)(%1) \n" /* Index-inval this address */ + " bnezl $0, 1f \n" /* Force mispredict */ + " nop \n" + "1: \n" + " .set pop \n" + : + : "r" (addr & dcache_index_mask), "r" (addr & icache_index_mask), + "i" (Index_Writeback_Inv_D), "i" (Index_Invalidate_I)); } #ifdef CONFIG_SMP static void sb1_flush_cache_sigtramp_ipi(void *info) { unsigned long iaddr = (unsigned long) info; - - iaddr = iaddr & ~(icache_line_size - 1); - protected_flush_icache_line(iaddr); + local_sb1_flush_cache_sigtramp(iaddr); } static void sb1_flush_cache_sigtramp(unsigned long addr) { - unsigned long tmp; - - /* - * Flush the local dcache, then load the instruction back into a - * register. That will make sure that any remote CPU also has - * written back it's data cache to memory. - */ local_sb1_flush_cache_sigtramp(addr); - __get_user(tmp, (unsigned long *)addr); - smp_call_function(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1); } #else @@ -364,64 +457,17 @@ asm("sb1_flush_cache_sigtramp = local_sb1_flush_cache_sigtramp"); #endif -static void sb1_flush_icache_all(void) -{ - /* - * Haven't worried too much about speed here; given that we're flushing - * the icache, the time to invalidate is dwarfed by the time it's going - * to take to refill it. Register usage: - * - * $1 - moving cache index - * $2 - set count - */ - __asm__ __volatile__ ( - ".set push \n" - ".set noreorder \n" - ".set noat \n" - ".set mips4 \n" - " move $1, %2 \n" /* Start at index 0 */ - "1: cache %3, 0($1) \n" /* Invalidate this index */ - " daddiu %1, %1, -1 \n" /* Decrement loop count */ - " bnez %1, 1b \n" /* loop test */ - " daddu $1, $1, %0 \n" /* Next address */ - ".set pop \n" - : - : "r" (icache_line_size), "r" (icache_sets * icache_assoc), - "r" (KSEG0), "i" (Index_Invalidate_I)); -} /* * Anything that just flushes dcache state can be ignored, as we're always * coherent in dcache space. This is just a dummy function that all the * nop'ed routines point to */ - static void sb1_nop(void) { } /* - * This only needs to make sure stores done up to this - * point are visible to other agents outside the CPU. Given - * the coherent nature of the ZBbus, all that's required here is - * a sync to make sure the data gets out to the caches and is - * visible to an arbitrary A Phase from an external agent - * - * Actually, I'm not even sure that's necessary; the semantics - * of this function aren't clear. If it's supposed to serve as - * a memory barrier, this is needed. If it's only meant to - * prevent data from being invisible to non-cpu memory accessors - * for some indefinite period of time (e.g. in a non-coherent - * dcache) then this function would be a complete nop. - */ -static void sb1_flush_page_to_ram(struct page *page) -{ - __asm__ __volatile__( - " sync \n" /* Short pipe */ - :::"memory"); -} - -/* * Cache set values (from the mips64 spec) * 0 - 64 * 1 - 128 @@ -480,7 +526,7 @@ { u32 config1; - config1 = read_mips32_cp0_config1(); + config1 = read_c0_config1(); icache_line_size = decode_cache_line_size((config1 >> 19) & 0x7); dcache_line_size = decode_cache_line_size((config1 >> 10) & 0x7); icache_sets = decode_cache_sets((config1 >> 22) & 0x7); @@ -489,7 +535,17 @@ dcache_assoc = ((config1 >> 7) & 0x7) + 1; icache_size = icache_line_size * icache_sets * icache_assoc; dcache_size = dcache_line_size * dcache_sets * dcache_assoc; + /* Need to remove non-index bits for index ops */ icache_index_mask = (icache_sets - 1) * icache_line_size; + dcache_index_mask = (dcache_sets - 1) * dcache_line_size; + /* + * These are for choosing range (index ops) versus all. + * icache flushes all ways for each set, so drop icache_assoc. + * dcache flushes all ways and each setting of bit 12 for each + * index, so drop dcache_assoc and halve the dcache_sets. + */ + icache_range_cutoff = icache_sets * icache_line_size; + dcache_range_cutoff = (dcache_sets / 2) * icache_line_size; } /* @@ -499,25 +555,56 @@ */ void ld_mmu_sb1(void) { + extern char except_vec2_sb1; + unsigned long temp; + + /* Special cache error handler for SB1 */ + memcpy((void *)(KSEG0 + 0x100), &except_vec2_sb1, 0x80); + memcpy((void *)(KSEG1 + 0x100), &except_vec2_sb1, 0x80); + probe_cache_sizes(); +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS + _clear_page = sb1_clear_page_dma; + _copy_page = sb1_copy_page_dma; + sb1_dma_init(); +#else _clear_page = sb1_clear_page; _copy_page = sb1_copy_page; +#endif - _flush_cache_all = sb1_flush_cache_all; - ___flush_cache_all = sb1___flush_cache_all; - _flush_cache_mm = (void (*)(struct mm_struct *))sb1_nop; + /* + * None of these are needed for the SB1 - the Dcache is + * physically indexed and tagged, so no virtual aliasing can + * occur + */ _flush_cache_range = (void *) sb1_nop; - _flush_page_to_ram = sb1_flush_page_to_ram; - _flush_icache_page = sb1_flush_icache_page; - _flush_icache_range = sb1_flush_icache_range; - - /* None of these are needed for the sb1 */ - _flush_cache_page = (void *) sb1_nop; + _flush_cache_page = sb1_flush_cache_page; + _flush_cache_mm = (void (*)(struct mm_struct *))sb1_nop; + _flush_cache_all = sb1_nop; + /* These routines are for Icache coherence with the Dcache */ + _flush_icache_range = sb1_flush_icache_range; + _flush_icache_page = sb1_flush_icache_page; + _flush_icache_all = __sb1_flush_icache_all; /* local only */ _flush_cache_sigtramp = sb1_flush_cache_sigtramp; - _flush_icache_all = sb1_flush_icache_all; + _flush_data_cache_page = (void *) sb1_nop; - change_cp0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); + /* Full flushes */ + ___flush_cache_all = sb1___flush_cache_all; + + change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); + /* + * This is the only way to force the update of K0 to complete + * before subsequent instruction fetch. + */ + __asm__ __volatile__ ( + " .set push \n" + " .set mips4 \n" + " dla %0, 1f \n" + " dmtc0 %0, $14 \n" + " eret \n" + "1: .set pop \n" + : "=r" (temp)); flush_cache_all(); } diff -urN linux-2.4.21-bk37/arch/mips64/mm/cache.c linux-2.4.21-bk38/arch/mips64/mm/cache.c --- linux-2.4.21-bk37/arch/mips64/mm/cache.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/cache.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,60 @@ +/* + * 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. + * + * Copyright (C) 1994 - 2003 by Ralf Baechle + */ +#include +#include +#include +#include + +#include + +asmlinkage int sys_cacheflush(void *addr, int bytes, int cache) +{ + /* This should flush more selectivly ... */ + __flush_cache_all(); + + return 0; +} + +void flush_dcache_page(struct page *page) +{ + unsigned long addr; + + if (page->mapping && page->mapping->i_mmap == NULL && + page->mapping->i_mmap_shared == NULL) { + SetPageDcacheDirty(page); + + return; + } + + /* + * We could delay the flush for the !page->mapping case too. But that + * case is for exec env/arg pages and those are %99 certainly going to + * get faulted into the tlb (and thus flushed) anyways. + */ + addr = (unsigned long) page_address(page); + flush_data_cache_page(addr); +} + +void __update_cache(struct vm_area_struct *vma, unsigned long address, + pte_t pte) +{ + struct page *page = pte_page(pte); + unsigned long addr; + + if (VALID_PAGE(page) && page->mapping && + (page->flags & (1UL << PG_dcache_dirty))) { + if (pages_do_alias((unsigned long) page_address(page), address & PAGE_MASK)) { + addr = (unsigned long) page_address(page); + flush_data_cache_page(addr); + } + + ClearPageDcacheDirty(page); + } +} + +EXPORT_SYMBOL(flush_dcache_page); diff -urN linux-2.4.21-bk37/arch/mips64/mm/cerr-sb1.c linux-2.4.21-bk38/arch/mips64/mm/cerr-sb1.c --- linux-2.4.21-bk37/arch/mips64/mm/cerr-sb1.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/cerr-sb1.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,542 @@ +/* + * Copyright (C) 2001 Broadcom Corporation + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include + +#ifndef CONFIG_SIBYTE_BUS_WATCHER +#include +#include +#include +#include +#endif + +/* SB1 definitions */ + +/* XXX should come from config1 XXX */ +#define SB1_CACHE_INDEX_MASK 0x1fe0 + +#define CP0_ERRCTL_RECOVERABLE (1 << 31) +#define CP0_ERRCTL_DCACHE (1 << 30) +#define CP0_ERRCTL_ICACHE (1 << 29) +#define CP0_ERRCTL_MULTIBUS (1 << 23) +#define CP0_ERRCTL_MC_TLB (1 << 15) +#define CP0_ERRCTL_MC_TIMEOUT (1 << 14) + +#define CP0_CERRI_TAG_PARITY (1 << 29) +#define CP0_CERRI_DATA_PARITY (1 << 28) +#define CP0_CERRI_EXTERNAL (1 << 26) + +#define CP0_CERRI_IDX_VALID(c) (!((c) & CP0_CERRI_EXTERNAL)) +#define CP0_CERRI_DATA (CP0_CERRI_DATA_PARITY) + +#define CP0_CERRD_MULTIPLE (1 << 31) +#define CP0_CERRD_TAG_STATE (1 << 30) +#define CP0_CERRD_TAG_ADDRESS (1 << 29) +#define CP0_CERRD_DATA_SBE (1 << 28) +#define CP0_CERRD_DATA_DBE (1 << 27) +#define CP0_CERRD_EXTERNAL (1 << 26) +#define CP0_CERRD_LOAD (1 << 25) +#define CP0_CERRD_STORE (1 << 24) +#define CP0_CERRD_FILLWB (1 << 23) +#define CP0_CERRD_COHERENCY (1 << 22) +#define CP0_CERRD_DUPTAG (1 << 21) + +#define CP0_CERRD_DPA_VALID(c) (!((c) & CP0_CERRD_EXTERNAL)) +#define CP0_CERRD_IDX_VALID(c) \ + (((c) & (CP0_CERRD_LOAD | CP0_CERRD_STORE)) ? (!((c) & CP0_CERRD_EXTERNAL)) : 0) +#define CP0_CERRD_CAUSES \ + (CP0_CERRD_LOAD | CP0_CERRD_STORE | CP0_CERRD_FILLWB | CP0_CERRD_COHERENCY | CP0_CERRD_DUPTAG) +#define CP0_CERRD_TYPES \ + (CP0_CERRD_TAG_STATE | CP0_CERRD_TAG_ADDRESS | CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE | CP0_CERRD_EXTERNAL) +#define CP0_CERRD_DATA (CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE) + +static uint32_t extract_ic(unsigned short addr, int data); +static uint32_t extract_dc(unsigned short addr, int data); + +static inline void breakout_errctl(unsigned int val) +{ + if (val & CP0_ERRCTL_RECOVERABLE) + prom_printf(" recoverable"); + if (val & CP0_ERRCTL_DCACHE) + prom_printf(" dcache"); + if (val & CP0_ERRCTL_ICACHE) + prom_printf(" icache"); + if (val & CP0_ERRCTL_MULTIBUS) + prom_printf(" multiple-buserr"); + prom_printf("\n"); +} + +static inline void breakout_cerri(unsigned int val) +{ + if (val & CP0_CERRI_TAG_PARITY) + prom_printf(" tag-parity"); + if (val & CP0_CERRI_DATA_PARITY) + prom_printf(" data-parity"); + if (val & CP0_CERRI_EXTERNAL) + prom_printf(" external"); + prom_printf("\n"); +} + +static inline void breakout_cerrd(unsigned int val) +{ + switch (val & CP0_CERRD_CAUSES) { + case CP0_CERRD_LOAD: + prom_printf(" load,"); + break; + case CP0_CERRD_STORE: + prom_printf(" store,"); + break; + case CP0_CERRD_FILLWB: + prom_printf(" fill/wb,"); + break; + case CP0_CERRD_COHERENCY: + prom_printf(" coherency,"); + break; + case CP0_CERRD_DUPTAG: + prom_printf(" duptags,"); + break; + default: + prom_printf(" NO CAUSE,"); + break; + } + if (!(val & CP0_CERRD_TYPES)) + prom_printf(" NO TYPE"); + else { + if (val & CP0_CERRD_MULTIPLE) + prom_printf(" multi-err"); + if (val & CP0_CERRD_TAG_STATE) + prom_printf(" tag-state"); + if (val & CP0_CERRD_TAG_ADDRESS) + prom_printf(" tag-address"); + if (val & CP0_CERRD_DATA_SBE) + prom_printf(" data-SBE"); + if (val & CP0_CERRD_DATA_DBE) + prom_printf(" data-DBE"); + if (val & CP0_CERRD_EXTERNAL) + prom_printf(" external"); + } + prom_printf("\n"); +} + +#ifndef CONFIG_SIBYTE_BUS_WATCHER + +static void check_bus_watcher(void) +{ + uint32_t status, l2_err, memio_err; + + /* Destructive read, clears register and interrupt */ + status = csr_in32(IO_SPACE_BASE | A_SCD_BUS_ERR_STATUS); + /* Bit 31 is always on, but there's no #define for that */ + if (status & ~(1UL << 31)) { + l2_err = csr_in32(IO_SPACE_BASE | A_BUS_L2_ERRORS); + memio_err = csr_in32(IO_SPACE_BASE | A_BUS_MEM_IO_ERRORS); + prom_printf("Bus watcher error counters: %08x %08x\n", l2_err, memio_err); + prom_printf("\nLast recorded signature:\n"); + prom_printf("Request %02x from %d, answered by %d with Dcode %d\n", + (unsigned int)(G_SCD_BERR_TID(status) & 0x3f), + (int)(G_SCD_BERR_TID(status) >> 6), + (int)G_SCD_BERR_RID(status), + (int)G_SCD_BERR_DCODE(status)); + } else { + prom_printf("Bus watcher indicates no error\n"); + } +} +#else +extern void check_bus_watcher(void); +#endif + +asmlinkage void sb1_cache_error(void) +{ + uint64_t cerr_dpa; + uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res; + + prom_printf("Cache error exception on CPU %x:\n", + (read_c0_prid() >> 25) & 0x7); + + __asm__ __volatile__ ( + " .set push\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " mfc0 %0, $26\n\t" + " mfc0 %1, $27\n\t" + " mfc0 %2, $27, 1\n\t" + " dmfc0 $1, $27, 3\n\t" + " dsrl32 %3, $1, 0 \n\t" + " sll %4, $1, 0 \n\t" + " mfc0 %5, $30\n\t" + " .set pop" + : "=r" (errctl), "=r" (cerr_i), "=r" (cerr_d), + "=r" (dpahi), "=r" (dpalo), "=r" (eepc)); + + cerr_dpa = (((uint64_t)dpahi) << 32) | dpalo; + prom_printf(" c0_errorepc == %08x\n", eepc); + prom_printf(" c0_errctl == %08x", errctl); + breakout_errctl(errctl); + if (errctl & CP0_ERRCTL_ICACHE) { + prom_printf(" c0_cerr_i == %08x", cerr_i); + breakout_cerri(cerr_i); + if (CP0_CERRI_IDX_VALID(cerr_i)) { + if ((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK)) + prom_printf(" cerr_i idx doesn't match eepc\n"); + else { + res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK, + (cerr_i & CP0_CERRI_DATA) != 0); + if (!(res & cerr_i)) + prom_printf("...didn't see indicated icache problem\n"); + } + } + } + if (errctl & CP0_ERRCTL_DCACHE) { + prom_printf(" c0_cerr_d == %08x", cerr_d); + breakout_cerrd(cerr_d); + if (CP0_CERRD_DPA_VALID(cerr_d)) { + prom_printf(" c0_cerr_dpa == %010llx\n", cerr_dpa); + if (!CP0_CERRD_IDX_VALID(cerr_d)) { + res = extract_dc(cerr_dpa & SB1_CACHE_INDEX_MASK, + (cerr_d & CP0_CERRD_DATA) != 0); + if (!(res & cerr_d)) + prom_printf("...didn't see indicated dcache problem\n"); + } else { + if ((cerr_dpa & SB1_CACHE_INDEX_MASK) != (cerr_d & SB1_CACHE_INDEX_MASK)) + prom_printf(" cerr_d idx doesn't match cerr_dpa\n"); + else { + res = extract_dc(cerr_d & SB1_CACHE_INDEX_MASK, + (cerr_d & CP0_CERRD_DATA) != 0); + if (!(res & cerr_d)) + prom_printf("...didn't see indicated problem\n"); + } + } + } + } + + check_bus_watcher(); + + while (1); + /* + * This tends to make things get really ugly; let's just stall instead. + * panic("Can't handle the cache error!"); + */ +} + + +/* Parity lookup table. */ +static const uint8_t parity[256] = { + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0 +}; + +/* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */ +static const uint64_t mask_72_64[8] = { + 0x0738C808099264FFL, + 0x38C808099264FF07L, + 0xC808099264FF0738L, + 0x08099264FF0738C8L, + 0x099264FF0738C808L, + 0x9264FF0738C80809L, + 0x64FF0738C8080992L, + 0xFF0738C808099264L +}; + +/* Calculate the parity on a range of bits */ +static char range_parity(uint64_t dword, int max, int min) +{ + char parity = 0; + int i; + dword >>= min; + for (i=max-min; i>=0; i--) { + if (dword & 0x1) + parity = !parity; + dword >>= 1; + } + return parity; +} + +/* Calculate the 4-bit even byte-parity for an instruction */ +static unsigned char inst_parity(uint32_t word) +{ + int i, j; + char parity = 0; + for (j=0; j<4; j++) { + char byte_parity = 0; + for (i=0; i<8; i++) { + if (word & 0x80000000) + byte_parity = !byte_parity; + word <<= 1; + } + parity <<= 1; + parity |= byte_parity; + } + return parity; +} + +static uint32_t extract_ic(unsigned short addr, int data) +{ + unsigned short way; + int valid; + uint64_t taglo, va, tlo_tmp; + uint32_t taghi, taglolo, taglohi; + uint8_t lru; + int res = 0; + + prom_printf("Icache index 0x%04x ", addr); + for (way = 0; way < 4; way++) { + /* Index-load-tag-I */ + __asm__ __volatile__ ( + " .set push \n\t" + " .set noreorder \n\t" + " .set mips64 \n\t" + " .set noat \n\t" + " cache 4, 0(%3) \n\t" + " mfc0 %0, $29 \n\t" + " dmfc0 $1, $28 \n\t" + " dsrl32 %1, $1, 0 \n\t" + " sll %2, $1, 0 \n\t" + " .set pop" + : "=r" (taghi), "=r" (taglohi), "=r" (taglolo) + : "r" ((way << 13) | addr)); + + taglo = ((unsigned long long)taglohi << 32) | taglolo; + if (way == 0) { + lru = (taghi >> 14) & 0xff; + prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", + ((addr >> 5) & 0x3), /* bank */ + ((addr >> 7) & 0x3f), /* index */ + (lru & 0x3), + ((lru >> 2) & 0x3), + ((lru >> 4) & 0x3), + ((lru >> 6) & 0x3)); + } + va = (taglo & 0xC0000FFFFFFFE000) | addr; + if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3)) + va |= 0x3FFFF00000000000; + valid = ((taghi >> 29) & 1); + if (valid) { + tlo_tmp = taglo & 0xfff3ff; + if (((taglo >> 10) & 1) ^ range_parity(tlo_tmp, 23, 0)) { + prom_printf(" ** bad parity in VTag0/G/ASID\n"); + res |= CP0_CERRI_TAG_PARITY; + } + if (((taglo >> 11) & 1) ^ range_parity(taglo, 63, 24)) { + prom_printf(" ** bad parity in R/VTag1\n"); + res |= CP0_CERRI_TAG_PARITY; + } + } + if (valid ^ ((taghi >> 27) & 1)) { + prom_printf(" ** bad parity for valid bit\n"); + res |= CP0_CERRI_TAG_PARITY; + } + prom_printf(" %d [VA %016llx] [Vld? %d] raw tags: %08X-%016llX\n", + way, va, valid, taghi, taglo); + + if (data) { + uint32_t datahi, insta, instb; + uint8_t predecode; + int offset; + + /* (hit all banks and ways) */ + for (offset = 0; offset < 4; offset++) { + /* Index-load-data-I */ + __asm__ __volatile__ ( + " .set push\n\t" + " .set noreorder\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " cache 6, 0(%3) \n\t" + " mfc0 %0, $29, 1\n\t" + " dmfc0 $1, $28, 1\n\t" + " dsrl32 %1, $1, 0 \n\t" + " sll %2, $1, 0 \n\t" + " .set pop \n" + : "=r" (datahi), "=r" (insta), "=r" (instb) + : "r" ((way << 13) | addr | (offset << 3))); + predecode = (datahi >> 8) & 0xff; + if (((datahi >> 16) & 1) != (uint32_t)range_parity(predecode, 7, 0)) { + prom_printf(" ** bad parity in predecode\n"); + res |= CP0_CERRI_DATA_PARITY; + } + /* XXXKW should/could check predecode bits themselves */ + if (((datahi >> 4) & 0xf) ^ inst_parity(insta)) { + prom_printf(" ** bad parity in instruction a\n"); + res |= CP0_CERRI_DATA_PARITY; + } + if ((datahi & 0xf) ^ inst_parity(instb)) { + prom_printf(" ** bad parity in instruction b\n"); + res |= CP0_CERRI_DATA_PARITY; + } + prom_printf(" %05X-%08X%08X", datahi, insta, instb); + } + prom_printf("\n"); + } + } + return res; +} + +/* Compute the ECC for a data doubleword */ +static uint8_t dc_ecc(uint64_t dword) +{ + uint64_t t; + uint32_t w; + uint8_t p; + int i; + + p = 0; + for (i = 7; i >= 0; i--) + { + p <<= 1; + t = dword & mask_72_64[i]; + w = (uint32_t)(t >> 32); + p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF] + ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]); + w = (uint32_t)(t & 0xFFFFFFFF); + p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF] + ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]); + } + return p; +} + +struct dc_state { + unsigned char val; + char *name; +}; + +static struct dc_state dc_states[] = { + { 0x00, "INVALID" }, + { 0x0f, "COH-SHD" }, + { 0x13, "NCO-E-C" }, + { 0x19, "NCO-E-D" }, + { 0x16, "COH-E-C" }, + { 0x1c, "COH-E-D" }, + { 0xff, "*ERROR*" } +}; + +#define DC_TAG_VALID(state) \ + (((state) == 0xf) || ((state) == 0x13) || ((state) == 0x19) || ((state == 0x16)) || ((state) == 0x1c)) + +static char *dc_state_str(unsigned char state) +{ + struct dc_state *dsc = dc_states; + while (dsc->val != 0xff) { + if (dsc->val == state) + break; + dsc++; + } + return dsc->name; +} + +static uint32_t extract_dc(unsigned short addr, int data) +{ + int valid, way; + unsigned char state; + uint64_t taglo, pa; + uint32_t taghi, taglolo, taglohi; + uint8_t ecc, lru; + int res = 0; + + prom_printf("Dcache index 0x%04x ", addr); + for (way = 0; way < 4; way++) { + __asm__ __volatile__ ( + " .set push\n\t" + " .set noreorder\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " cache 5, 0(%3)\n\t" /* Index-load-tag-D */ + " mfc0 %0, $29, 2\n\t" + " dmfc0 $1, $28, 2\n\t" + " dsrl32 %1, $1, 0\n\t" + " sll %2, $1, 0\n\t" + " .set pop" + : "=r" (taghi), "=r" (taglohi), "=r" (taglolo) + : "r" ((way << 13) | addr)); + + taglo = ((unsigned long long)taglohi << 32) | taglolo; + pa = (taglo & 0xFFFFFFE000) | addr; + if (way == 0) { + lru = (taghi >> 14) & 0xff; + prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", + ((addr >> 11) & 0x2) | ((addr >> 5) & 1), /* bank */ + ((addr >> 6) & 0x3f), /* index */ + (lru & 0x3), + ((lru >> 2) & 0x3), + ((lru >> 4) & 0x3), + ((lru >> 6) & 0x3)); + } + state = (taghi >> 25) & 0x1f; + valid = DC_TAG_VALID(state); + prom_printf(" %d [PA %010llx] [state %s (%02x)] raw tags: %08X-%016llX\n", + way, pa, dc_state_str(state), state, taghi, taglo); + if (valid) { + if (((taglo >> 11) & 1) ^ range_parity(taglo, 39, 26)) { + prom_printf(" ** bad parity in PTag1\n"); + res |= CP0_CERRD_TAG_ADDRESS; + } + if (((taglo >> 10) & 1) ^ range_parity(taglo, 25, 13)) { + prom_printf(" ** bad parity in PTag0\n"); + res |= CP0_CERRD_TAG_ADDRESS; + } + } else { + res |= CP0_CERRD_TAG_STATE; + } + + if (data) { + uint64_t datalo; + uint32_t datalohi, datalolo, datahi; + int offset; + + for (offset = 0; offset < 4; offset++) { + /* Index-load-data-D */ + __asm__ __volatile__ ( + " .set push\n\t" + " .set noreorder\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " cache 7, 0(%3)\n\t" /* Index-load-data-D */ + " mfc0 %0, $29, 3\n\t" + " dmfc0 $1, $28, 3\n\t" + " dsrl32 %1, $1, 0 \n\t" + " sll %2, $1, 0 \n\t" + " .set pop" + : "=r" (datahi), "=r" (datalohi), "=r" (datalolo) + : "r" ((way << 13) | addr | (offset << 3))); + datalo = ((unsigned long long)datalohi << 32) | datalolo; + ecc = dc_ecc(datalo); + if (ecc != datahi) { + int bits = 0; + prom_printf(" ** bad ECC (%02x %02x) ->", + datahi, ecc); + ecc ^= datahi; + while (ecc) { + if (ecc & 1) bits++; + ecc >>= 1; + } + res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE; + } + prom_printf(" %02X-%016llX", datahi, datalo); + } + prom_printf("\n"); + } + } + return res; +} diff -urN linux-2.4.21-bk37/arch/mips64/mm/cex-sb1.S linux-2.4.21-bk38/arch/mips64/mm/cex-sb1.S --- linux-2.4.21-bk37/arch/mips64/mm/cex-sb1.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/cex-sb1.S 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2001,2002,2003 Broadcom Corporation + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include +#include + +#include +#include +#include +#include +#include + + .text + .set noat + .set mips4 + + __INIT + + /* Cache Error handler for SB1 */ + LEAF(except_vec2_sb1) + mfc0 k1, $26 + # check if error was recoverable + bltz k1, leave_cerr +#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS + # look for signature of spurious CErr + lui k0, 0x4000 + bne k0, k1, 1f + .word 0x401Bd801 # mfc0 k1, $27, 1 + lui k0, 0xffe0 + and k1, k0, k1 + lui k0, 0x0200 + beq k0, k1, leave_cerr +1: +#endif + j handle_vec2_sb1 + +leave_cerr: + # clear/unlock the registers + mtc0 zero, $26 + mtc0 zero, $27 + .word 0x4080d801 # mtc0 zero, $27, 1 + .word 0x4080d803 # mtc0 zero, $27, 3 + eret + END(except_vec2_sb1) + + __FINIT + + LEAF(handle_vec2_sb1) + mfc0 k0,CP0_CONFIG + li k1,~CONF_CM_CMASK + and k0,k0,k1 + ori k0,k0,CONF_CM_UNCACHED + mtc0 k0,CP0_CONFIG + + SSNOP + SSNOP + SSNOP + SSNOP + bnezl $0, 1f +1: + mfc0 k0, CP0_STATUS + sll k0, k0, 3 # check CU0 (kernel?) + bltz k0, 2f + get_saved_sp + move sp, k1 # want Kseg SP (so uncached) +2: + j sb1_cache_error + + END(handle_vec2_sb1) diff -urN linux-2.4.21-bk37/arch/mips64/mm/fault.c linux-2.4.21-bk38/arch/mips64/mm/fault.c --- linux-2.4.21-bk37/arch/mips64/mm/fault.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/fault.c 2003-08-24 02:55:58.000000000 -0700 @@ -194,7 +194,6 @@ address, (unsigned long) regs->cp0_epc, (unsigned long) regs->regs[31]); -while(1); #endif info.si_signo = SIGSEGV; info.si_errno = 0; diff -urN linux-2.4.21-bk37/arch/mips64/mm/init.c linux-2.4.21-bk38/arch/mips64/mm/init.c --- linux-2.4.21-bk37/arch/mips64/mm/init.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/init.c 2003-08-24 02:55:58.000000000 -0700 @@ -110,14 +110,6 @@ return freed; } - -asmlinkage int sys_cacheflush(void *addr, int bytes, int cache) -{ - /* XXX Just get it working for now... */ - flush_cache_l1(); - return 0; -} - /* * We have up to 8 empty zeroed pages so we can map one of the right colour * when needed. This is necessary only on R4000 / R4400 SC and MC versions @@ -132,16 +124,10 @@ unsigned long order, size; struct page *page; - switch (mips_cpu.cputype) { - case CPU_R4000SC: - case CPU_R4000MC: - case CPU_R4400SC: - case CPU_R4400MC: + if (cpu_has_vce) order = 3; - break; - default: + else order = 0; - } empty_zero_page = __get_free_pages(GFP_KERNEL, order); if (!empty_zero_page) @@ -297,19 +283,24 @@ #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { + /* Switch from KSEG0 to XKPHYS addresses */ + start = (unsigned long)phys_to_virt(CPHYSADDR(start)); + end = (unsigned long)phys_to_virt(CPHYSADDR(end)); + if (start < end) + printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", + (end - start) >> 10); + for (; start < end; start += PAGE_SIZE) { ClearPageReserved(virt_to_page(start)); set_page_count(virt_to_page(start), 1); free_page(start); totalram_pages++; } - printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", - (end - start) >> 10); } #endif extern char __init_begin, __init_end; -extern void prom_free_prom_memory(void); +extern void prom_free_prom_memory(void) __init; void free_initmem(void) diff -urN linux-2.4.21-bk37/arch/mips64/mm/loadmmu.c linux-2.4.21-bk38/arch/mips64/mm/loadmmu.c --- linux-2.4.21-bk37/arch/mips64/mm/loadmmu.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/loadmmu.c 2003-08-24 02:55:58.000000000 -0700 @@ -4,20 +4,23 @@ * for more details. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1999 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003 Ralf Baechle (ralf@gnu.org) * Copyright (C) 1999 Silicon Graphics, Inc. + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. */ #include #include #include #include #include +#include +#include +#include #include #include #include -#include -#include /* memory functions */ void (*_clear_page)(void * page); @@ -28,62 +31,79 @@ void (*___flush_cache_all)(void); void (*_flush_cache_mm)(struct mm_struct *mm); void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start, - unsigned long end); + unsigned long end); void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page); -void (*_flush_cache_sigtramp)(unsigned long addr); void (*_flush_icache_range)(unsigned long start, unsigned long end); void (*_flush_icache_page)(struct vm_area_struct *vma, struct page *page); -void (*_flush_page_to_ram)(struct page * page); -void (*_flush_icache_all)(void); -/* MIPS specific cache operations */ -void (*_flush_cache_l2)(void); -void (*_flush_cache_l1)(void); +void (*_flush_cache_sigtramp)(unsigned long addr); +void (*_flush_data_cache_page)(unsigned long addr); +void (*_flush_icache_all)(void); +#ifdef CONFIG_NONCOHERENT_IO /* DMA cache operations. */ void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size); void (*_dma_cache_wback)(unsigned long start, unsigned long size); void (*_dma_cache_inv)(unsigned long start, unsigned long size); -/* Miscellaneous. */ -void (*_update_mmu_cache)(struct vm_area_struct * vma, - unsigned long address, pte_t pte); +EXPORT_SYMBOL(_dma_cache_wback_inv); +EXPORT_SYMBOL(_dma_cache_wback); +EXPORT_SYMBOL(_dma_cache_inv); + +#endif /* CONFIG_NONCOHERENT_IO */ +extern void ld_mmu_r23000(void); extern void ld_mmu_r4xx0(void); +extern void ld_mmu_tx39(void); +extern void ld_mmu_r6000(void); +extern void ld_mmu_tfp(void); extern void ld_mmu_andes(void); extern void ld_mmu_sb1(void); extern void sb1_tlb_init(void); -extern void ld_mmu_mips64(void); +extern void r3k_tlb_init(void); extern void r4k_tlb_init(void); +extern void sb1_tlb_init(void); void __init load_mmu(void) { - if (mips_cpu.options & MIPS_CPU_4KTLB) { -#if defined (CONFIG_CPU_R4300) \ - || defined (CONFIG_CPU_R4X00) \ - || defined (CONFIG_CPU_R5000) \ - || defined (CONFIG_CPU_NEVADA) - printk(KERN_INFO "Loading R4000 MMU routines.\n"); + if (cpu_has_4ktlb) { +#if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_VR41XX) || \ + defined(CONFIG_CPU_R4300) || defined(CONFIG_CPU_R5000) || \ + defined(CONFIG_CPU_NEVADA) || defined(CONFIG_CPU_R5432) || \ + defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_MIPS32) || \ + defined(CONFIG_CPU_MIPS64) || defined(CONFIG_CPU_TX49XX) || \ + defined(CONFIG_CPU_RM7000) ld_mmu_r4xx0(); -#endif -#if defined(CONFIG_CPU_MIPS64) - printk(KERN_INFO "Loading MIPS64 MMU routines.\n"); - ld_mmu_mips64(); r4k_tlb_init(); #endif - - } else switch(mips_cpu.cputype) { + } else switch (current_cpu_data.cputype) { +#ifdef CONFIG_CPU_R3000 + case CPU_R2000: + case CPU_R3000: + case CPU_R3000A: + case CPU_R3081E: + ld_mmu_r23000(); + r3k_tlb_init(); + break; +#endif +#ifdef CONFIG_CPU_TX39XX + case CPU_TX3912: + case CPU_TX3922: + case CPU_TX3927: + ld_mmu_tx39(); + r3k_tlb_init(); + break; +#endif #ifdef CONFIG_CPU_R10000 case CPU_R10000: case CPU_R12000: - printk(KERN_INFO "Loading R10000 MMU routines.\n"); - ld_mmu_andes(); + ld_mmu_r4xx0(); + andes_tlb_init(); break; #endif -#if defined CONFIG_CPU_SB1 +#ifdef CONFIG_CPU_SB1 case CPU_SB1: - printk(KERN_INFO "Loading SB1 MMU routines.\n"); ld_mmu_sb1(); sb1_tlb_init(); break; @@ -94,13 +114,6 @@ break; default: - /* XXX We need an generic routine in the MIPS port - * XXX to jabber stuff onto the screen on all machines - * XXX before the console is setup. The ARCS prom - * XXX routines look good for this, but only the SGI - * XXX code has a full library for that at this time. - */ - panic("Yeee, unsupported mmu/cache architecture or " - "wrong compiletime kernel configuration."); + panic("Yeee, unsupported mmu/cache architecture."); } } diff -urN linux-2.4.21-bk37/arch/mips64/mm/pg-mips64.c linux-2.4.21-bk38/arch/mips64/mm/pg-mips64.c --- linux-2.4.21-bk37/arch/mips64/mm/pg-mips64.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/pg-mips64.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,126 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * MIPS64 CPU variant specific Cache routines. - * These routine are not optimized in any way, they are done in a generic way - * so they can be used on all MIPS64 compliant CPUs, and also done in an - * attempt not to break anything for the R4xx0 style CPUs. - */ -#include -#include - -#include -#include -#include - -extern int dc_lsize, ic_lsize, sc_lsize; - -/* - * Zero an entire page. - */ - -void mips64_clear_page_dc(unsigned long page) -{ - unsigned long i; - - if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) - { - for (i=page; i +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Zero an entire page. Basically a simple unrolled loop should do the + * job but we want more performance by saving memory bus bandwidth. We + * have five flavours of the routine available for: + * + * - 16byte cachelines and no second level cache + * - 32byte cachelines second level cache + * - a version which handles the buggy R4600 v1.x + * - a version which handles the buggy R4600 v2.0 + * - Finally a last version without fancy cache games for the SC and MC + * versions of R4000 and R4400. + */ + +void r4k_clear_page_d16(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "cache\t%3,16(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "cache\t%3,-16(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) + : "memory"); +} + +void r4k_clear_page_d32(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) + : "memory"); +} + + +/* + * This flavour of r4k_clear_page is for the R4600 V1.x. Cite from the + * IDT R4600 V1.7 errata: + * + * 18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D, + * Hit_Invalidate_D and Create_Dirty_Excl_D should only be + * executed if there is no other dcache activity. If the dcache is + * accessed for another instruction immeidately preceding when these + * cache instructions are executing, it is possible that the dcache + * tag match outputs used by these cache instructions will be + * incorrect. These cache instructions should be preceded by at least + * four instructions that are not any kind of load or store + * instruction. + * + * This is not allowed: lw + * nop + * nop + * nop + * cache Hit_Writeback_Invalidate_D + * + * This is allowed: lw + * nop + * nop + * nop + * nop + * cache Hit_Writeback_Invalidate_D + */ +void r4k_clear_page_r4600_v1(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tnop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "cache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) + : "memory"); +} + +/* + * And this one is for the R4600 V2.0 + */ +void r4k_clear_page_r4600_v2(void * page) +{ + unsigned long flags; + + local_irq_save(flags); + *(volatile unsigned int *)KSEG1; + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) + : "memory"); + local_irq_restore(flags); +} + +/* + * The next 4 versions are optimized for all possible scache configurations + * of the SC / MC versions of R4000 and R4400 ... + * + * Todo: For even better performance we should have a routine optimized for + * every legal combination of dcache / scache linesize. When I (Ralf) tried + * this the kernel crashed shortly after mounting the root filesystem. CPU + * bug? Weirdo cache instruction semantics? + */ +void r4k_clear_page_s16(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "cache\t%3,16(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "cache\t%3,-16(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) + : "memory"); +} + +void r4k_clear_page_s32(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) + : "memory"); +} + +void r4k_clear_page_s64(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) + : "memory"); +} + +void r4k_clear_page_s128(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "sd\t$0,32(%0)\n\t" + "sd\t$0,40(%0)\n\t" + "sd\t$0,48(%0)\n\t" + "sd\t$0,56(%0)\n\t" + "daddiu\t%0,128\n\t" + "sd\t$0,-64(%0)\n\t" + "sd\t$0,-56(%0)\n\t" + "sd\t$0,-48(%0)\n\t" + "sd\t$0,-40(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) + : "memory"); +} + +/* + * This version has been tuned on an Origin. For other machines the arguments + * of the pref instructin may have to be tuned differently. + */ +void andes_clear_page(void * page) +{ + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tmips4\n\t" + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tpref 7,512(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tpop" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE) + : "memory"); +} + + +/* + * This is still inefficient. We only can do better if we know the + * virtual address where the copy will be accessed. + */ + +void r4k_copy_page_d16(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "cache\t%7,16(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "cache\t%7,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "cache\t%7,-16(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_D)); +} + +void r4k_copy_page_d32(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "cache\t%7,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_D)); +} + +/* + * Again a special version for the R4600 V1.x + */ +void r4k_copy_page_r4600_v1(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tnop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "cache\t%7,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_D)); +} + +void r4k_copy_page_r4600_v2(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + unsigned long flags; + + local_irq_save(flags); + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tnop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "cache\t%7,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_D)); + local_irq_restore(flags); +} + +/* + * These are for R4000SC / R4400MC + */ +void r4k_copy_page_s16(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "cache\t%7,16(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "cache\t%7,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "cache\t%7,-16(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD)); +} + +void r4k_copy_page_s32(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "cache\t%7,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD)); +} + +void r4k_copy_page_s64(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD)); +} + +void r4k_copy_page_s128(void * to, void * from) +{ + unsigned long dummy1, dummy2; + unsigned long reg1, reg2, reg3, reg4; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%8\n" + "1:\tcache\t%9,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "ld\t%4,16(%1)\n\t" + "ld\t%5,24(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "sd\t%4,16(%0)\n\t" + "sd\t%5,24(%0)\n\t" + "ld\t%2,32(%1)\n\t" + "ld\t%3,40(%1)\n\t" + "ld\t%4,48(%1)\n\t" + "ld\t%5,56(%1)\n\t" + "sd\t%2,32(%0)\n\t" + "sd\t%3,40(%0)\n\t" + "sd\t%4,48(%0)\n\t" + "sd\t%5,56(%0)\n\t" + "daddiu\t%0,128\n\t" + "daddiu\t%1,128\n\t" + "ld\t%2,-64(%1)\n\t" + "ld\t%3,-56(%1)\n\t" + "ld\t%4,-48(%1)\n\t" + "ld\t%5,-40(%1)\n\t" + "sd\t%2,-64(%0)\n\t" + "sd\t%3,-56(%0)\n\t" + "sd\t%4,-48(%0)\n\t" + "sd\t%5,-40(%0)\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "ld\t%4,-16(%1)\n\t" + "ld\t%5,-8(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "sd\t%4,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%5,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), + "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) + :"0" (to), "1" (from), + "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD)); +} + +/* + * This version has been tuned on an Origin. For other machines the arguments + * of the pref instructin may have to be tuned differently. + */ +void andes_copy_page(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2, reg3, reg4; + + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tmips4\n\t" + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%8\n" + "1:\tpref\t0,2*128(%1)\n\t" + "pref\t1,2*128(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "ld\t%4,16(%1)\n\t" + "ld\t%5,24(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "sd\t%4,16(%0)\n\t" + "sd\t%5,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "ld\t%4,-16(%1)\n\t" + "ld\t%5,-8(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "sd\t%4,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%5,-8(%0)\n\t" + ".set\tpop\n\t" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2), + "=&r" (reg3), "=&r" (reg4) + :"0" (to), "1" (from), "I" (PAGE_SIZE)); +} diff -urN linux-2.4.21-bk37/arch/mips64/mm/pg-sb1.c linux-2.4.21-bk38/arch/mips64/mm/pg-sb1.c --- linux-2.4.21-bk37/arch/mips64/mm/pg-sb1.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/pg-sb1.c 2003-08-24 02:55:58.000000000 -0700 @@ -1,9 +1,10 @@ /* * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 2000 Sibyte + * Copyright (C) 2000 SiByte, Inc. * - * Written by Justin Carlson (carlson@sibyte.com) + * Written by Justin Carlson of SiByte, Inc. + * and Kip Walker of Broadcom Corp. * * * This program is free software; you can redistribute it and/or @@ -20,8 +21,16 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + #include -#include +#include +#include + +#include +#include +#include +#include +#include #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS #define SB1_PREF_LOAD_STREAMED_HINT "0" @@ -49,15 +58,19 @@ ".set noat \n" ".set mips4 \n" " daddiu $1, %0, %2 \n" /* Calculate the end of the page to clear */ +#ifdef CONFIG_CPU_HAS_PREFETCH " pref " SB1_PREF_STORE_STREAMED_HINT ", 0(%0) \n" /* Prefetch the first 4 lines */ " pref " SB1_PREF_STORE_STREAMED_HINT ", 32(%0) \n" " pref " SB1_PREF_STORE_STREAMED_HINT ", 64(%0) \n" " pref " SB1_PREF_STORE_STREAMED_HINT ", 96(%0) \n" +#endif "1: sd $0, 0(%0) \n" /* Throw out a cacheline of 0's */ " sd $0, 8(%0) \n" " sd $0, 16(%0) \n" " sd $0, 24(%0) \n" +#ifdef CONFIG_CPU_HAS_PREFETCH " pref " SB1_PREF_STORE_STREAMED_HINT ",128(%0) \n" /* Prefetch 4 lines ahead */ +#endif " bne $1, %0, 1b \n" " daddiu %0, %0, 32\n" /* Next cacheline (This instruction better be short piped!) */ ".set pop \n" @@ -87,12 +100,14 @@ ".set noat \n" ".set mips4 \n" " daddiu $1, %0, %4 \n" /* Calculate the end of the page to copy */ +#ifdef CONFIG_CPU_HAS_PREFETCH " pref " SB1_PREF_LOAD_STREAMED_HINT ", 0(%0) \n" /* Prefetch the first 3 lines */ " pref " SB1_PREF_STORE_STREAMED_HINT ", 0(%1) \n" " pref " SB1_PREF_LOAD_STREAMED_HINT ", 32(%0) \n" " pref " SB1_PREF_STORE_STREAMED_HINT ", 32(%1) \n" " pref " SB1_PREF_LOAD_STREAMED_HINT ", 64(%0) \n" " pref " SB1_PREF_STORE_STREAMED_HINT ", 64(%1) \n" +#endif "1: lw $2, 0(%0) \n" /* Block copy a cacheline */ " lw $3, 4(%0) \n" " lw $4, 8(%0) \n" @@ -101,8 +116,10 @@ " lw $7, 20(%0) \n" " lw $8, 24(%0) \n" " lw $9, 28(%0) \n" +#ifdef CONFIG_CPU_HAS_PREFETCH " pref " SB1_PREF_LOAD_STREAMED_HINT ", 96(%0) \n" /* Prefetch ahead */ " pref " SB1_PREF_STORE_STREAMED_HINT ", 96(%1) \n" +#endif " sw $2, 0(%1) \n" " sw $3, 4(%1) \n" " sw $4, 8(%1) \n" @@ -121,3 +138,78 @@ : "0" (from), "1" (to), "I" (PAGE_SIZE-32) : "$2","$3","$4","$5","$6","$7","$8","$9","memory"); } + + +#ifdef CONFIG_SIBYTE_DMA_PAGEOPS + +/* + * Pad descriptors to cacheline, since each is exclusively owned by a + * particular CPU. + */ +typedef struct dmadscr_s { + uint64_t dscr_a; + uint64_t dscr_b; + uint64_t pad_a; + uint64_t pad_b; +} dmadscr_t; + +static dmadscr_t page_descr[NR_CPUS] __attribute__((aligned(SMP_CACHE_BYTES))); + +void sb1_dma_init(void) +{ + int cpu = smp_processor_id(); + uint64_t base_val = PHYSADDR(&page_descr[cpu]) | V_DM_DSCR_BASE_RINGSZ(1); + + out64(base_val, + IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); + out64(base_val | M_DM_DSCR_BASE_RESET, + IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); + out64(base_val | M_DM_DSCR_BASE_ENABL, + IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); +} + +void sb1_clear_page_dma(void *page) +{ + int cpu = smp_processor_id(); + + /* if the page is above Kseg0, use old way */ + if (KSEGX(page) != K0BASE) + return sb1_clear_page(page); + + page_descr[cpu].dscr_a = PHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT; + page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE); + out64(1, IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)); + + /* + * Don't really want to do it this way, but there's no + * reliable way to delay completion detection. + */ + while (!(in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & M_DM_DSCR_BASE_INTERRUPT)) + ; + in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); +} + +void sb1_copy_page_dma(void *to, void *from) +{ + unsigned long from_phys = PHYSADDR(from); + unsigned long to_phys = PHYSADDR(to); + int cpu = smp_processor_id(); + + /* if either page is above Kseg0, use old way */ + if ((KSEGX(to) != K0BASE) || (KSEGX(from) != K0BASE)) + return sb1_copy_page(to, from); + + page_descr[cpu].dscr_a = PHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT; + page_descr[cpu].dscr_b = PHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE); + out64(1, IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)); + + /* + * Don't really want to do it this way, but there's no + * reliable way to delay completion detection. + */ + while (!(in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & M_DM_DSCR_BASE_INTERRUPT)) + ; + in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE)); +} + +#endif diff -urN linux-2.4.21-bk37/arch/mips64/mm/r4xx0.c linux-2.4.21-bk38/arch/mips64/mm/r4xx0.c --- linux-2.4.21-bk37/arch/mips64/mm/r4xx0.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/r4xx0.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,2313 +0,0 @@ -/* - * 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. - * - * r4xx0.c: R4000 processor variant specific MMU/Cache routines. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998, 1999, 2000, 2001 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 1999, 2000 Silicon Graphics, Inc. - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/* CP0 hazard avoidance. */ -#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ - "nop; nop; nop; nop; nop; nop;\n\t" \ - ".set reorder\n\t") - -/* Primary cache parameters. */ -static int icache_size, dcache_size; /* Size in bytes */ -static int ic_lsize, dc_lsize; /* LineSize in bytes */ - -/* Secondary cache (if present) parameters. */ -static unsigned int scache_size, sc_lsize; /* Again, in bytes */ - -#include -#include - -#undef DEBUG_CACHE - - -/* - * Dummy cache handling routines for machines without boardcaches - */ -static void no_sc_noop(void) {} - -static struct bcache_ops no_sc_ops = { - (void *)no_sc_noop, (void *)no_sc_noop, - (void *)no_sc_noop, (void *)no_sc_noop -}; - -struct bcache_ops *bcops = &no_sc_ops; - -/* - * On processors with QED R4600 style two set assosicative cache - * this is the bit which selects the way in the cache for the - * indexed cachops. - */ -#define icache_waybit (icache_size >> 1) -#define dcache_waybit (dcache_size >> 1) - -/* - * Zero an entire page. Basically a simple unrolled loop should do the - * job but we want more performance by saving memory bus bandwidth. We - * have five flavours of the routine available for: - * - * - 16byte cachelines and no second level cache - * - 32byte cachelines second level cache - * - a version which handles the buggy R4600 v1.x - * - a version which handles the buggy R4600 v2.0 - * - Finally a last version without fancy cache games for the SC and MC - * versions of R4000 and R4400. - */ - -static void r4k_clear_page_d16(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "cache\t%3,16(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "cache\t%3,-16(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) - : "memory"); -} - -static void r4k_clear_page_d32(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) - : "memory"); -} - - -/* - * This flavour of r4k_clear_page is for the R4600 V1.x. Cite from the - * IDT R4600 V1.7 errata: - * - * 18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D, - * Hit_Invalidate_D and Create_Dirty_Excl_D should only be - * executed if there is no other dcache activity. If the dcache is - * accessed for another instruction immeidately preceding when these - * cache instructions are executing, it is possible that the dcache - * tag match outputs used by these cache instructions will be - * incorrect. These cache instructions should be preceded by at least - * four instructions that are not any kind of load or store - * instruction. - * - * This is not allowed: lw - * nop - * nop - * nop - * cache Hit_Writeback_Invalidate_D - * - * This is allowed: lw - * nop - * nop - * nop - * nop - * cache Hit_Writeback_Invalidate_D - */ -static void r4k_clear_page_r4600_v1(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tnop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) - : "memory"); -} - -/* - * And this one is for the R4600 V2.0 - */ -static void r4k_clear_page_r4600_v2(void * page) -{ - unsigned int flags; - - __save_and_cli(flags); - *(volatile unsigned int *)KSEG1; - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) - : "memory"); - __restore_flags(flags); -} - -/* - * The next 4 versions are optimized for all possible scache configurations - * of the SC / MC versions of R4000 and R4400 ... - * - * Todo: For even better performance we should have a routine optimized for - * every legal combination of dcache / scache linesize. When I (Ralf) tried - * this the kernel crashed shortly after mounting the root filesystem. CPU - * bug? Weirdo cache instruction semantics? - */ -static void r4k_clear_page_s16(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "cache\t%3,16(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "cache\t%3,-16(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) - : "memory"); -} - -static void r4k_clear_page_s32(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) - : "memory"); -} - -static void r4k_clear_page_s64(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) - : "memory"); -} - -static void r4k_clear_page_s128(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "sd\t$0,32(%0)\n\t" - "sd\t$0,40(%0)\n\t" - "sd\t$0,48(%0)\n\t" - "sd\t$0,56(%0)\n\t" - "daddiu\t%0,128\n\t" - "sd\t$0,-64(%0)\n\t" - "sd\t$0,-56(%0)\n\t" - "sd\t$0,-48(%0)\n\t" - "sd\t$0,-40(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (page) - : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) - : "memory"); -} - - -/* - * This is still inefficient. We only can do better if we know the - * virtual address where the copy will be accessed. - */ - -static void r4k_copy_page_d16(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "cache\t%7,16(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "cache\t%7,-16(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - -static void r4k_copy_page_d32(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - -/* - * Again a special version for the R4600 V1.x - */ -static void r4k_copy_page_r4600_v1(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tnop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - -static void r4k_copy_page_r4600_v2(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - unsigned int flags; - - __save_and_cli(flags); - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tnop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); - __restore_flags(flags); -} - -/* - * These are for R4000SC / R4400MC - */ -static void r4k_copy_page_s16(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "cache\t%7,16(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "cache\t%7,-16(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - -static void r4k_copy_page_s32(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - -static void r4k_copy_page_s64(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - -static void r4k_copy_page_s128(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%8\n" - "1:\tcache\t%9,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "ld\t%4,16(%1)\n\t" - "ld\t%5,24(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "sd\t%4,16(%0)\n\t" - "sd\t%5,24(%0)\n\t" - "ld\t%2,32(%1)\n\t" - "ld\t%3,40(%1)\n\t" - "ld\t%4,48(%1)\n\t" - "ld\t%5,56(%1)\n\t" - "sd\t%2,32(%0)\n\t" - "sd\t%3,40(%0)\n\t" - "sd\t%4,48(%0)\n\t" - "sd\t%5,56(%0)\n\t" - "daddiu\t%0,128\n\t" - "daddiu\t%1,128\n\t" - "ld\t%2,-64(%1)\n\t" - "ld\t%3,-56(%1)\n\t" - "ld\t%4,-48(%1)\n\t" - "ld\t%5,-40(%1)\n\t" - "sd\t%2,-64(%0)\n\t" - "sd\t%3,-56(%0)\n\t" - "sd\t%4,-48(%0)\n\t" - "sd\t%5,-40(%0)\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "ld\t%4,-16(%1)\n\t" - "ld\t%5,-8(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "sd\t%4,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%5,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - - -/* - * If you think for one second that this stuff coming up is a lot - * of bulky code eating too many kernel cache lines. Think _again_. - * - * Consider: - * 1) Taken branches have a 3 cycle penalty on R4k - * 2) The branch itself is a real dead cycle on even R4600/R5000. - * 3) Only one of the following variants of each type is even used by - * the kernel based upon the cache parameters we detect at boot time. - * - * QED. - */ - -static inline void r4k_flush_cache_all_s16d16i16(void) -{ - blast_dcache16(); blast_icache16(); blast_scache16(); -} - -static inline void r4k_flush_cache_all_s32d16i16(void) -{ - blast_dcache16(); blast_icache16(); blast_scache32(); -} - -static inline void r4k_flush_cache_all_s64d16i16(void) -{ - blast_dcache16(); blast_icache16(); blast_scache64(); -} - -static inline void r4k_flush_cache_all_s128d16i16(void) -{ - blast_dcache16(); blast_icache16(); blast_scache128(); -} - -static inline void r4k_flush_cache_all_s32d32i32(void) -{ - blast_dcache32(); blast_icache32(); blast_scache32(); -} - -static inline void r4k_flush_cache_all_s64d32i32(void) -{ - blast_dcache32(); blast_icache32(); blast_scache64(); -} - -static inline void r4k_flush_cache_all_s128d32i32(void) -{ - blast_dcache32(); blast_icache32(); blast_scache128(); -} - -static inline void r4k_flush_cache_all_d16i16(void) -{ - blast_dcache16(); blast_icache16(); -} - -static inline void r4k_flush_cache_all_d32i32(void) -{ - blast_dcache32(); blast_icache32(); -} - -static void r4k_flush_cache_range_s16d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s16d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache16_page(start); - start += PAGE_SIZE; - } - } - } -} - -static void r4k_flush_cache_range_s32d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s32d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache32_page(start); - start += PAGE_SIZE; - } - } - } -} - -static void r4k_flush_cache_range_s64d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s64d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache64_page(start); - start += PAGE_SIZE; - } - } - } -} - -static void r4k_flush_cache_range_s128d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s128d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache128_page(start); - start += PAGE_SIZE; - } - } - } -} - -static void r4k_flush_cache_range_s32d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s32d32i32(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache32_page(start); - start += PAGE_SIZE; - } - } - } -} - -static void r4k_flush_cache_range_s64d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s64d32i32(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache64_page(start); - start += PAGE_SIZE; - } - } - } -} - -static void r4k_flush_cache_range_s128d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - struct vm_area_struct *vma; - - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - vma = find_vma(mm, start); - if(vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s128d32i32(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache128_page(start); - start += PAGE_SIZE; - } - } - } -} - -static void r4k_flush_cache_range_d16i16(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - blast_dcache16(); blast_icache16(); - } -} - -static void r4k_flush_cache_range_d32i32(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - blast_dcache32(); blast_icache32(); - } -} - -/* - * On architectures like the Sparc, we could get rid of lines in - * the cache created only by a certain context, but on the MIPS - * (and actually certain Sparc's) we cannot. - */ -static void r4k_flush_cache_mm_s16d16i16(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s16d16i16(); - } -} - -static void r4k_flush_cache_mm_s32d16i16(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s32d16i16(); - } -} - -static void r4k_flush_cache_mm_s64d16i16(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s64d16i16(); - } -} - -static void r4k_flush_cache_mm_s128d16i16(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s128d16i16(); - } -} - -static void r4k_flush_cache_mm_s32d32i32(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s32d32i32(); - } -} - -static void r4k_flush_cache_mm_s64d32i32(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s64d32i32(); - } -} - -static void r4k_flush_cache_mm_s128d32i32(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s128d32i32(); - } -} - -static void r4k_flush_cache_mm_d16i16(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_d16i16(); - } -} - -static void r4k_flush_cache_mm_d32i32(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_d32i32(); - } -} - -static void r4k_flush_cache_page_s16d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache16_page_indexed(page); - } else - blast_scache16_page(page); -out: -} - -static void r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache32_page_indexed(page); - } else - blast_scache32_page(page); -out: -} - -static void r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache64_page_indexed(page); - } else - blast_scache64_page(page); -out: -} - -static void r4k_flush_cache_page_s128d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache128_page_indexed(page); - } else - blast_scache128_page(page); -out: -} - -static void r4k_flush_cache_page_s32d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache32_page_indexed(page); - blast_scache32_page_indexed(page); - } else - blast_scache32_page(page); -out: -} - -static void r4k_flush_cache_page_s64d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache32_page_indexed(page); - blast_scache64_page_indexed(page); - } else - blast_scache64_page(page); -out: -} - -static void r4k_flush_cache_page_s128d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache32_page_indexed(page); - blast_scache128_page_indexed(page); - } else - blast_scache128_page(page); -out: -} - -static void r4k_flush_cache_page_d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if(mm == current->mm) { - blast_dcache16_page(page); - } else { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache16_page_indexed(page); - } -out: -} - -static void r4k_flush_cache_page_d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_PRESENT)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if((mm == current->mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache32_page(page); - } else { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache32_page_indexed(page); - } -out: -} - -static void r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_PRESENT)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if((mm == current->mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache32_page(page); - } else { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache32_page_indexed(page); - blast_dcache32_page_indexed(page ^ dcache_waybit); - } -out: -} - -static void r4k_flush_page_to_ram_s16(struct page *page) -{ - blast_scache16_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_s32(struct page *page) -{ - blast_scache32_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_s64(struct page *page) -{ - blast_scache64_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_s128(struct page *page) -{ - blast_scache128_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_d16(struct page *page) -{ - blast_dcache16_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_d32(struct page *page) -{ - blast_dcache32_page((unsigned long)page_address(page)); -} - -static void -r4k_flush_icache_range(unsigned long start, unsigned long end) -{ - flush_cache_all(); -} - -static void -r4k_flush_icache_page_s(struct vm_area_struct *vma, struct page *page) -{ - /* - * We did an scache flush therefore PI is already clean. - */ -} - -/* - * Ok, this seriously sucks. We use them to flush a user page but don't - * know the virtual address, so we have to blast away the whole icache - * which is significantly more expensive than the real thing. - */ -static void -r4k_flush_icache_page_p(struct vm_area_struct *vma, struct page *page) -{ - if (!(vma->vm_flags & VM_EXEC)) - return; - - flush_cache_all(); -} - -/* - * Writeback and invalidate the primary cache dcache before DMA. - * - * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D, - * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Exclusive_D will only - * operate correctly if the internal data cache refill buffer is empty. These - * CACHE instructions should be separated from any potential data cache miss - * by a load instruction to an uncached address to empty the response buffer." - * (Revision 2.0 device errata from IDT available on http://www.idt.com/ - * in .pdf format.) - */ -static void r4k_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= (unsigned long)dcache_size) { - flush_cache_l1(); - } else { - /* Workaround for R4600 bug. See comment above. */ - __save_and_cli(flags); - *(volatile unsigned long *)KSEG1; - - a = addr & ~((unsigned long)dc_lsize - 1); - end = (addr + size) & ~((unsigned long)dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - __restore_flags(flags); - } - bc_wback_inv(addr, size); -} - -static void r4k_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= (unsigned long)scache_size) { - flush_cache_l1(); - return; - } - - a = addr & ~((unsigned long)sc_lsize - 1); - end = (addr + size) & ~((unsigned long)sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} - -static void r4k_dma_cache_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= (unsigned long)dcache_size) { - flush_cache_l1(); - } else { - /* Workaround for R4600 bug. See comment above. */ - __save_and_cli(flags); - *(volatile unsigned long *)KSEG1; - - a = addr & ~((unsigned long)dc_lsize - 1); - end = (addr + size) & ~((unsigned long)dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - __restore_flags(flags); - } - - bc_inv(addr, size); -} - -static void r4k_dma_cache_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= (unsigned long)scache_size) { - flush_cache_l1(); - return; - } - - a = addr & ~((unsigned long)sc_lsize - 1); - end = (addr + size) & ~((unsigned long)sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} - -/* - * While we're protected against bad userland addresses we don't care - * very much about what happens in that case. Usually a segmentation - * fault will dump the process later on anyway ... - */ -static void r4k_flush_cache_sigtramp(unsigned long addr) -{ - __asm__ __volatile__("nop;nop;nop;nop"); /* R4600 V1.7 */ - - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -static void r4600v20k_flush_cache_sigtramp(unsigned long addr) -{ - unsigned int flags; - - __save_and_cli(flags); - - /* Clear internal cache refill buffer */ - *(volatile unsigned int *)KSEG1; - - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); - - __restore_flags(flags); -} - -#undef DEBUG_TLB - -#define NTLB_ENTRIES 48 /* Fixed on all R4XX0 variants... */ - -#define NTLB_ENTRIES_HALF 24 /* Fixed on all R4XX0 variants... */ - -void local_flush_tlb_all(void) -{ - unsigned long flags; - unsigned long old_ctx; - int entry; - -#ifdef DEBUG_TLB - printk("[tlball]"); -#endif - - __save_and_cli(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - set_entryhi(KSEG0); - set_entrylo0(0); - set_entrylo1(0); - BARRIER; - - entry = get_wired(); - - /* Blast 'em all away. */ - while(entry < NTLB_ENTRIES) { - set_index(entry); - BARRIER; - tlb_write_indexed(); - BARRIER; - entry++; - } - BARRIER; - set_entryhi(old_ctx); - __restore_flags(flags); -} - -void local_flush_tlb_mm(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { - unsigned long flags; - -#ifdef DEBUG_TLB - printk("[tlbmm<%d>]", mm->context); -#endif - __save_and_cli(flags); - get_new_mmu_context(mm, smp_processor_id()); - if(mm == current->mm) - set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) & 0xff); - __restore_flags(flags); - } -} - -void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, - unsigned long end) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { - unsigned long flags; - int size; - -#ifdef DEBUG_TLB - printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff), - start, end); -#endif - __save_and_cli(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - size = (size + 1) >> 1; - if(size <= NTLB_ENTRIES_HALF) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (CPU_CONTEXT(smp_processor_id(), mm) & 0xff); - - start &= (PAGE_MASK << 1); - end += ((PAGE_SIZE << 1) - 1); - end &= (PAGE_MASK << 1); - while(start < end) { - int idx; - - set_entryhi(start | newpid); - start += (PAGE_SIZE << 1); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - BARRIER; - if(idx < 0) - continue; - tlb_write_indexed(); - BARRIER; - } - set_entryhi(oldpid); - } else { - get_new_mmu_context(mm, smp_processor_id()); - if(mm == current->mm) - set_entryhi(CPU_CONTEXT(smp_processor_id(), - mm) & 0xff); - } - __restore_flags(flags); - } -} - -void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - if (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) != 0) { - unsigned long flags; - int oldpid, newpid, idx; - -#ifdef DEBUG_TLB - printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); -#endif - newpid = (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff); - page &= (PAGE_MASK << 1); - __save_and_cli(flags); - oldpid = (get_entryhi() & 0xff); - set_entryhi(page | newpid); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - if(idx < 0) - goto finish; - BARRIER; - tlb_write_indexed(); - - finish: - BARRIER; - set_entryhi(oldpid); - __restore_flags(flags); - } -} - -static void r4k_flush_cache_l2(void) -{ -} - -/* We will need multiple versions of update_mmu_cache(), one that just - * updates the TLB with the new pte(s), and another which also checks - * for the R4k "end of page" hardware bug and does the needy. - */ -static void r4k_update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx, pid; - - /* - * Handle debugger faulting in for debugee. - */ - if (current->active_mm != vma->vm_mm) - return; - - __save_and_cli(flags); - pid = (get_entryhi() & 0xff); - -#ifdef DEBUG_TLB - if((pid != (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff)) || - (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d - tlbpid=%d\n", (int) (CPU_CONTEXT(smp_processor_id(), - vma->vm_mm) & 0xff), pid); - } -#endif - - address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); - pgdp = pgd_offset(vma->vm_mm, address); - BARRIER; - tlb_probe(); - BARRIER; - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - BARRIER; - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); - BARRIER; - if(idx < 0) { - tlb_write_random(); - } else { - tlb_write_indexed(); - } - BARRIER; - set_entryhi(pid); - BARRIER; - __restore_flags(flags); -} - -#if 0 -static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx; - - __save_and_cli(flags); - address &= (PAGE_MASK << 1); - set_entryhi(address | (get_entryhi() & 0xff)); - pgdp = pgd_offset(vma->vm_mm, address); - tlb_probe(); - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - BARRIER; - if(idx < 0) - tlb_write_random(); - else - tlb_write_indexed(); - BARRIER; - __restore_flags(flags); -} -#endif - -/* Detect and size the various r4k caches. */ -static void __init probe_icache(unsigned long config) -{ - icache_size = 1 << (12 + ((config >> 9) & 7)); - ic_lsize = 16 << ((config >> 5) & 1); - - printk("Primary instruction cache %dkb, linesize %d bytes)\n", - icache_size >> 10, ic_lsize); -} - -static void __init probe_dcache(unsigned long config) -{ - dcache_size = 1 << (12 + ((config >> 6) & 7)); - dc_lsize = 16 << ((config >> 4) & 1); - - printk("Primary data cache %dkb, linesize %d bytes)\n", - dcache_size >> 10, dc_lsize); -} - - -/* If you even _breathe_ on this function, look at the gcc output - * and make sure it does not pop things on and off the stack for - * the cache sizing loop that executes in KSEG1 space or else - * you will crash and burn badly. You have been warned. - */ -static int __init probe_scache(unsigned long config) -{ - extern unsigned long stext; - unsigned long flags, addr, begin, end, pow2; - int tmp; - - tmp = ((config >> 17) & 1); - if(tmp) - return 0; - tmp = ((config >> 22) & 3); - switch(tmp) { - case 0: - sc_lsize = 16; - break; - case 1: - sc_lsize = 32; - break; - case 2: - sc_lsize = 64; - break; - case 3: - sc_lsize = 128; - break; - } - - begin = (unsigned long) &stext; - begin &= ~((4 * 1024 * 1024) - 1); - end = begin + (4 * 1024 * 1024); - - /* This is such a bitch, you'd think they would make it - * easy to do this. Away you daemons of stupidity! - */ - __save_and_cli(flags); - - /* Fill each size-multiple cache line with a valid tag. */ - pow2 = (64 * 1024); - for(addr = begin; addr < end; addr = (begin + pow2)) { - unsigned long *p = (unsigned long *) addr; - __asm__ __volatile__("nop" : : "r" (*p)); /* whee... */ - pow2 <<= 1; - } - - /* Load first line with zero (therefore invalid) tag. */ - set_taglo(0); - set_taghi(0); - __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */ - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 8, (%0)\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 9, (%0)\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 11, (%0)\n\t" - ".set reorder\n\t" : : "r" (begin)); - - /* Now search for the wrap around point. */ - pow2 = (128 * 1024); - tmp = 0; - for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) { - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 7, (%0)\n\t" - ".set reorder\n\t" : : "r" (addr)); - __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */ - if(!get_taglo()) - break; - pow2 <<= 1; - } - __restore_flags(flags); - addr -= begin; - printk("Secondary cache sized at %dK linesize %d\n", - (int) (addr >> 10), sc_lsize); - scache_size = addr; - return 1; -} - -static void __init setup_noscache_funcs(void) -{ - unsigned int prid; - - switch(dc_lsize) { - case 16: - _clear_page = r4k_clear_page_d16; - _copy_page = r4k_copy_page_d16; - _flush_cache_all = r4k_flush_cache_all_d16i16; - _flush_cache_l1 = r4k_flush_cache_all_d16i16; - _flush_cache_mm = r4k_flush_cache_mm_d16i16; - _flush_cache_range = r4k_flush_cache_range_d16i16; - _flush_cache_page = r4k_flush_cache_page_d16i16; - break; - case 32: - prid = read_32bit_cp0_register(CP0_PRID) & 0xfff0; - if (prid == 0x2010) { /* R4600 V1.7 */ - _clear_page = r4k_clear_page_r4600_v1; - _copy_page = r4k_copy_page_r4600_v1; - } else if (prid == 0x2020) { /* R4600 V2.0 */ - _clear_page = r4k_clear_page_r4600_v2; - _copy_page = r4k_copy_page_r4600_v2; - } else { - _clear_page = r4k_clear_page_d32; - _copy_page = r4k_copy_page_d32; - } - _flush_cache_all = r4k_flush_cache_all_d32i32; - _flush_cache_l1 = r4k_flush_cache_all_d32i32; - _flush_cache_mm = r4k_flush_cache_mm_d32i32; - _flush_cache_range = r4k_flush_cache_range_d32i32; - _flush_cache_page = r4k_flush_cache_page_d32i32; - break; - } - - switch(ic_lsize) { - case 16: - _flush_page_to_ram = r4k_flush_page_to_ram_d16; - break; - case 32: - _flush_page_to_ram = r4k_flush_page_to_ram_d32; - break; - } - _flush_icache_page = r4k_flush_icache_page_p; - _dma_cache_wback_inv = r4k_dma_cache_wback_inv_pc; - _dma_cache_wback = r4k_dma_cache_wback_inv_pc; - _dma_cache_inv = r4k_dma_cache_inv_pc; -} - -static void __init setup_scache_funcs(void) -{ - switch(sc_lsize) { - case 16: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s16d16i16; - _flush_cache_l1 = r4k_flush_cache_all_s16d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s16d16i16; - _flush_cache_range = r4k_flush_cache_range_s16d16i16; - _flush_cache_page = r4k_flush_cache_page_s16d16i16; - break; - case 32: - panic("Invalid cache configuration detected"); - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s16; - _clear_page = r4k_clear_page_s16; - _copy_page = r4k_copy_page_s16; - break; - case 32: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s32d16i16; - _flush_cache_l1 = r4k_flush_cache_all_s32d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s32d16i16; - _flush_cache_range = r4k_flush_cache_range_s32d16i16; - _flush_cache_page = r4k_flush_cache_page_s32d16i16; - break; - case 32: - _flush_cache_all = r4k_flush_cache_all_s32d32i32; - _flush_cache_l1 = r4k_flush_cache_all_s32d32i32; - _flush_cache_mm = r4k_flush_cache_mm_s32d32i32; - _flush_cache_range = r4k_flush_cache_range_s32d32i32; - _flush_cache_page = r4k_flush_cache_page_s32d32i32; - break; - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s32; - _clear_page = r4k_clear_page_s32; - _copy_page = r4k_copy_page_s32; - break; - case 64: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s64d16i16; - _flush_cache_l1 = r4k_flush_cache_all_s64d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s64d16i16; - _flush_cache_range = r4k_flush_cache_range_s64d16i16; - _flush_cache_page = r4k_flush_cache_page_s64d16i16; - break; - case 32: - _flush_cache_all = r4k_flush_cache_all_s64d32i32; - _flush_cache_l1 = r4k_flush_cache_all_s64d32i32; - _flush_cache_mm = r4k_flush_cache_mm_s64d32i32; - _flush_cache_range = r4k_flush_cache_range_s64d32i32; - _flush_cache_page = r4k_flush_cache_page_s64d32i32; - break; - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s64; - _clear_page = r4k_clear_page_s64; - _copy_page = r4k_copy_page_s64; - break; - case 128: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s128d16i16; - _flush_cache_l1 = r4k_flush_cache_all_s128d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s128d16i16; - _flush_cache_range = r4k_flush_cache_range_s128d16i16; - _flush_cache_page = r4k_flush_cache_page_s128d16i16; - break; - case 32: - _flush_cache_all = r4k_flush_cache_all_s128d32i32; - _flush_cache_l1 = r4k_flush_cache_all_s128d32i32; - _flush_cache_mm = r4k_flush_cache_mm_s128d32i32; - _flush_cache_range = r4k_flush_cache_range_s128d32i32; - _flush_cache_page = r4k_flush_cache_page_s128d32i32; - break; - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s128; - _clear_page = r4k_clear_page_s128; - _copy_page = r4k_copy_page_s128; - break; - } - _flush_icache_page = r4k_flush_icache_page_s; - _dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc; - _dma_cache_wback = r4k_dma_cache_wback_inv_sc; - _dma_cache_inv = r4k_dma_cache_inv_sc; -} - -typedef int (*probe_func_t)(unsigned long); -extern int r5k_sc_init(void); - -static inline void __init setup_scache(unsigned int config) -{ - probe_func_t probe_scache_kseg1; - int sc_present = 0; - - /* Maybe the cpu knows about a l2 cache? */ - probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); - sc_present = probe_scache_kseg1(config); - - if (!sc_present) { - setup_noscache_funcs(); - return; - } - - switch(mips_cpu.cputype) { - case CPU_R5000: - case CPU_NEVADA: - setup_noscache_funcs(); -#if defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_NEVADA) - r5k_sc_init(); -#endif - break; - default: - setup_scache_funcs(); - } - -} - -void __init ld_mmu_r4xx0(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - - change_cp0_config(CONF_CM_CMASK | CONF_CU, CONF_CM_DEFAULT); - - probe_icache(config); - probe_dcache(config); - setup_scache(config); - - switch(mips_cpu.cputype) { - case CPU_R4600: /* QED style two way caches? */ - case CPU_R4700: - case CPU_R5000: - case CPU_NEVADA: - _flush_cache_page = r4k_flush_cache_page_d32i32_r4600; - } - - _flush_cache_sigtramp = r4k_flush_cache_sigtramp; - if ((read_32bit_cp0_register(CP0_PRID) & 0xfff0) == 0x2020) { - _flush_cache_sigtramp = r4600v20k_flush_cache_sigtramp; - } - _flush_icache_range = r4k_flush_icache_range; /* Ouch */ - - _flush_cache_l2 = r4k_flush_cache_l2; - - _update_mmu_cache = r4k_update_mmu_cache; - - flush_cache_l1(); - - /* - * You should never change this register: - * - On R4600 1.7 the tlbp never hits for pages smaller than - * the value in the c0_pagemask register. - * - The entire mm handling assumes the c0_pagemask register to - * be set for 4kb pages. - */ - write_32bit_cp0_register(CP0_PAGEMASK, PM_4K); - local_flush_tlb_all(); -} diff -urN linux-2.4.21-bk37/arch/mips64/mm/r5k-sc.c linux-2.4.21-bk38/arch/mips64/mm/r5k-sc.c --- linux-2.4.21-bk37/arch/mips64/mm/r5k-sc.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/r5k-sc.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,115 +0,0 @@ -/* - * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), - * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* Secondary cache size in bytes, if present. */ -static unsigned long scache_size; - -#define SC_LINE 32 -#define SC_PAGE (128*SC_LINE) - -#define cache_op(base,op) \ -__asm__ __volatile__(" \ - .set noreorder; \ - .set mips3; \ - cache %1, (%0); \ - .set mips0; \ - .set reorder" \ - : \ - : "r" (base), \ - "i" (op)); - -static inline void blast_r5000_scache(void) -{ - unsigned long start = KSEG0; - unsigned long end = KSEG0 + scache_size; - - while(start < end) { - cache_op(start, R5K_Page_Invalidate_S); - start += SC_PAGE; - } -} - -static void r5k_dma_cache_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= scache_size) { - blast_r5000_scache(); - return; - } - - /* On the R5000 secondary cache we cannot - * invalidate less than a page at a time. - * The secondary cache is physically indexed, write-through. - */ - a = addr & ~(SC_PAGE - 1); - end = (addr + size - 1) & ~(SC_PAGE - 1); - while (a <= end) { - cache_op(a, R5K_Page_Invalidate_S); - a += SC_PAGE; - } -} - -static void r5k_sc_enable(void) -{ - unsigned long flags; - - __save_and_cli(flags); - change_cp0_config(CONF_SE, CONF_SE); - blast_r5000_scache(); - __restore_flags(flags); -} - -static void r5k_sc_disable(void) -{ - unsigned long flags; - - __save_and_cli(flags); - blast_r5000_scache(); - change_cp0_config(CONF_SE, 0); - __restore_flags(flags); -} - -static inline int __init r5k_sc_probe(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - - if(config & CONF_SC) - return(0); - - scache_size = (512*1024) << ((config >> 20)&3); - - printk("R5000 SCACHE size %ldK, linesize 32 bytes.\n", - scache_size >> 10); - - return 1; -} - -struct bcache_ops r5k_sc_ops = { - r5k_sc_enable, - r5k_sc_disable, - r5k_dma_cache_inv_sc, - r5k_dma_cache_inv_sc -}; - -void __init r5k_sc_init(void) -{ - if (r5k_sc_probe()) { - r5k_sc_enable(); - bcops = &r5k_sc_ops; - } -} diff -urN linux-2.4.21-bk37/arch/mips64/mm/sc-ip22.c linux-2.4.21-bk38/arch/mips64/mm/sc-ip22.c --- linux-2.4.21-bk37/arch/mips64/mm/sc-ip22.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/sc-ip22.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,177 @@ +/* + * sc-ip22.c: Indy cache management functions. + * + * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), + * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Secondary cache size in bytes, if present. */ +static unsigned long scache_size; + +#undef DEBUG_CACHE + +#define SC_SIZE 0x00080000 +#define SC_LINE 32 +#define CI_MASK (SC_SIZE - SC_LINE) +#define SC_INDEX(n) ((n) & CI_MASK) + +static inline void indy_sc_wipe(unsigned long first, unsigned long last) +{ + unsigned long tmp; + + __asm__ __volatile__( + ".set\tpush\t\t\t# indy_sc_wipe\n\t" + ".set\tnoreorder\n\t" + ".set\tmips3\n\t" + ".set\tnoat\n\t" + "mfc0\t%2, $12\n\t" + "li\t$1, 0x80\t\t\t# Go 64 bit\n\t" + "mtc0\t$1, $12\n\t" + + "dli\t$1, 0x9000000080000000\n\t" + "or\t%0, $1\t\t\t# first line to flush\n\t" + "or\t%1, $1\t\t\t# last line to flush\n\t" + ".set\tat\n\t" + + "1:\tsw\t$0, 0(%0)\n\t" + "bne\t%0, %1, 1b\n\t" + " daddu\t%0, 32\n\t" + + "mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t" + "nop; nop; nop; nop;\n\t" + ".set\tpop" + : "=r" (first), "=r" (last), "=&r" (tmp) + : "0" (first), "1" (last)); +} + +static void indy_sc_wback_invalidate(unsigned long addr, unsigned long size) +{ + unsigned long first_line, last_line; + unsigned long flags; + +#ifdef DEBUG_CACHE + printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size); +#endif + + if (!size) + return; + + /* Which lines to flush? */ + first_line = SC_INDEX(addr); + last_line = SC_INDEX(addr + size - 1); + + local_irq_save(flags); + if (first_line <= last_line) { + indy_sc_wipe(first_line, last_line); + goto out; + } + + indy_sc_wipe(first_line, SC_SIZE - SC_LINE); + indy_sc_wipe(0, last_line); +out: + local_irq_restore(flags); +} + +static void indy_sc_enable(void) +{ + unsigned long addr, tmp1, tmp2; + + /* This is really cool... */ +#ifdef DEBUG_CACHE + printk("Enabling R4600 SCACHE\n"); +#endif + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tnoreorder\n\t" + ".set\tmips3\n\t" + "mfc0\t%2, $12\n\t" + "nop; nop; nop; nop;\n\t" + "li\t%1, 0x80\n\t" + "mtc0\t%1, $12\n\t" + "nop; nop; nop; nop;\n\t" + "li\t%0, 0x1\n\t" + "dsll\t%0, 31\n\t" + "lui\t%1, 0x9000\n\t" + "dsll32\t%1, 0\n\t" + "or\t%0, %1, %0\n\t" + "sb\t$0, 0(%0)\n\t" + "mtc0\t$0, $12\n\t" + "nop; nop; nop; nop;\n\t" + "mtc0\t%2, $12\n\t" + "nop; nop; nop; nop;\n\t" + ".set\tpop" + : "=r" (tmp1), "=r" (tmp2), "=r" (addr)); +} + +static void indy_sc_disable(void) +{ + unsigned long tmp1, tmp2, tmp3; + +#ifdef DEBUG_CACHE + printk("Disabling R4600 SCACHE\n"); +#endif + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tnoreorder\n\t" + ".set\tmips3\n\t" + "li\t%0, 0x1\n\t" + "dsll\t%0, 31\n\t" + "lui\t%1, 0x9000\n\t" + "dsll32\t%1, 0\n\t" + "or\t%0, %1, %0\n\t" + "mfc0\t%2, $12\n\t" + "nop; nop; nop; nop\n\t" + "li\t%1, 0x80\n\t" + "mtc0\t%1, $12\n\t" + "nop; nop; nop; nop\n\t" + "sh\t$0, 0(%0)\n\t" + "mtc0\t$0, $12\n\t" + "nop; nop; nop; nop\n\t" + "mtc0\t%2, $12\n\t" + "nop; nop; nop; nop\n\t" + ".set\tpop" + : "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)); +} + +static inline int __init indy_sc_probe(void) +{ + unsigned int size = ip22_eeprom_read(&sgimc->eeprom, 17); + if (size == 0) + return 0; + + size <<= PAGE_SHIFT; + printk(KERN_INFO "R4600/R5000 SCACHE size %dK, linesize 32 bytes.\n", + size >> 10); + scache_size = size; + + return 1; +} + +/* XXX Check with wje if the Indy caches can differenciate between + writeback + invalidate and just invalidate. */ +struct bcache_ops indy_sc_ops = { + .bc_enable = indy_sc_enable, + .bc_disable = indy_sc_disable, + .bc_wback_inv = indy_sc_wback_invalidate, + .bc_inv = indy_sc_wback_invalidate +}; + +void __init indy_sc_init(void) +{ + if (indy_sc_probe()) { + indy_sc_enable(); + bcops = &indy_sc_ops; + } +} diff -urN linux-2.4.21-bk37/arch/mips64/mm/sc-r5k.c linux-2.4.21-bk38/arch/mips64/mm/sc-r5k.c --- linux-2.4.21-bk37/arch/mips64/mm/sc-r5k.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/sc-r5k.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,115 @@ +/* + * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), + * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Secondary cache size in bytes, if present. */ +static unsigned long scache_size; + +#define SC_LINE 32 +#define SC_PAGE (128*SC_LINE) + +#define cache_op(base,op) \ +__asm__ __volatile__(" \ + .set noreorder; \ + .set mips3; \ + cache %1, (%0); \ + .set mips0; \ + .set reorder" \ + : \ + : "r" (base), \ + "i" (op)); + +static inline void blast_r5000_scache(void) +{ + unsigned long start = KSEG0; + unsigned long end = KSEG0 + scache_size; + + while(start < end) { + cache_op(start, R5K_Page_Invalidate_S); + start += SC_PAGE; + } +} + +static void r5k_dma_cache_inv_sc(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + + if (size >= scache_size) { + blast_r5000_scache(); + return; + } + + /* On the R5000 secondary cache we cannot + * invalidate less than a page at a time. + * The secondary cache is physically indexed, write-through. + */ + a = addr & ~(SC_PAGE - 1); + end = (addr + size - 1) & ~(SC_PAGE - 1); + while (a <= end) { + cache_op(a, R5K_Page_Invalidate_S); + a += SC_PAGE; + } +} + +static void r5k_sc_enable(void) +{ + unsigned long flags; + + local_irq_save(flags); + change_c0_config(R5K_CONF_SE, R5K_CONF_SE); + blast_r5000_scache(); + local_irq_restore(flags); +} + +static void r5k_sc_disable(void) +{ + unsigned long flags; + + local_irq_save(flags); + blast_r5000_scache(); + change_c0_config(R5K_CONF_SE, 0); + local_irq_restore(flags); +} + +static inline int __init r5k_sc_probe(void) +{ + unsigned long config = read_c0_config(); + + if (config & CONF_SC) + return(0); + + scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20); + + printk("R5000 SCACHE size %ldkB, linesize 32 bytes.\n", + scache_size >> 10); + + return 1; +} + +static struct bcache_ops r5k_sc_ops = { + .bc_enable = r5k_sc_enable, + .bc_disable = r5k_sc_disable, + .bc_wback_inv = r5k_dma_cache_inv_sc, + .bc_inv = r5k_dma_cache_inv_sc +}; + +void __init r5k_sc_init(void) +{ + if (r5k_sc_probe()) { + r5k_sc_enable(); + bcops = &r5k_sc_ops; + } +} diff -urN linux-2.4.21-bk37/arch/mips64/mm/sc-rm7k.c linux-2.4.21-bk38/arch/mips64/mm/sc-rm7k.c --- linux-2.4.21-bk37/arch/mips64/mm/sc-rm7k.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/sc-rm7k.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,191 @@ +/* + * sc-rm7k.c: RM7000 cache management functions. + * + * Copyright (C) 1997, 2001, 2003 Ralf Baechle (ralf@gnu.org), + */ +#include +#include +#include + +#include +#include +#include +#include +#include + +/* Primary cache parameters. */ +#define sc_lsize 32 +#define tc_pagesize (32*128) + +/* Secondary cache parameters. */ +#define scache_size (256*1024) /* Fixed to 256KiB on RM7000 */ + +extern unsigned long icache_way_size, dcache_way_size; + +#include + +int rm7k_tcache_enabled; + +/* + * Writeback and invalidate the primary cache dcache before DMA. + * (XXX These need to be fixed ...) + */ +static void rm7k_sc_wback_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + +#ifdef DEBUG_CACHE + printk("rm7k_sc_wback_inv[%08lx,%08lx]", addr, size); +#endif + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } + + if (!rm7k_tcache_enabled) + return; + + a = addr & ~(tc_pagesize - 1); + end = (addr + size - 1) & ~(tc_pagesize - 1); + while(1) { + invalidate_tcache_page(a); /* Page_Invalidate_T */ + if (a == end) + break; + a += tc_pagesize; + } +} + +static void rm7k_sc_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + +#ifdef DEBUG_CACHE + printk("rm7k_sc_inv[%08lx,%08lx]", addr, size); +#endif + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + invalidate_scache_line(a); /* Hit_Invalidate_SD */ + if (a == end) + break; + a += sc_lsize; + } + + if (!rm7k_tcache_enabled) + return; + + a = addr & ~(tc_pagesize - 1); + end = (addr + size - 1) & ~(tc_pagesize - 1); + while(1) { + invalidate_tcache_page(a); /* Page_Invalidate_T */ + if (a == end) + break; + a += tc_pagesize; + } +} + +/* + * This function is executed in the uncached segment KSEG1. + * It must not touch the stack, because the stack pointer still points + * into KSEG0. + * + * Three options: + * - Write it in assembly and guarantee that we don't use the stack. + * - Disable caching for KSEG0 before calling it. + * - Pray that GCC doesn't randomly start using the stack. + * + * This being Linux, we obviously take the least sane of those options - + * following DaveM's lead in c-r4k.c + * + * It seems we get our kicks from relying on unguaranteed behaviour in GCC + */ +static __init void rm7k_sc_enable(void) +{ + int i; + + set_c0_config(1<<3); /* CONF_SE */ + + write_c0_taglo(0); + write_c0_taghi(0); + + for (i=0; i> 31) & 1) + return 0; + + printk(KERN_INFO "Secondary cache size %ldK, linesize 32 bytes.\n", + (scache_size >> 10), sc_lsize); + + if ((config >> 3) & 1) + return; + + printk(KERN_INFO "Enabling secondary cache..."); + func(); + printk(" done\n"); + + /* + * While we're at it let's deal with the tertiary cache. + */ + if ((config >> 17) & 1) + return 1; + + /* + * We can't enable the L3 cache yet. There may be board-specific + * magic necessary to turn it on, and blindly asking the CPU to + * start using it would may give cache errors. + * + * Also, board-specific knowledge may allow us to use the + * CACHE Flash_Invalidate_T instruction if the tag RAM supports + * it, and may specify the size of the L3 cache so we don't have + * to probe it. + */ + printk(KERN_INFO "Tertiary cache present, %s enabled\n", + config&(1<<12) ? "already" : "not (yet)"); + + if ((config >> 12) & 1) + rm7k_tcache_enabled = 1; + + return 1; +} + +struct bcache_ops rm7k_sc_ops = { + .bc_enable = rm7k_sc_enable, + .bc_disable = rm7k_sc_disable, + .bc_wback_inv = rm7k_sc_wback_inv, + .bc_inv = rm7k_sc_inv +}; + +void __init rm7k_sc_init(void) +{ + if (rm7k_sc_probe()) { + rm7k_sc_enable(); + bcops = &rm7k_sc_ops; + } +} diff -urN linux-2.4.21-bk37/arch/mips64/mm/tlb-andes.c linux-2.4.21-bk38/arch/mips64/mm/tlb-andes.c --- linux-2.4.21-bk37/arch/mips64/mm/tlb-andes.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/tlb-andes.c 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,205 @@ +/* + * 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. + * + * Copyright (C) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999 Silicon Graphics, Inc. + * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com) + */ +#include +#include +#include +#include +#include +#include +#include +#include + +extern void except_vec1_r10k(void); + +#define NTLB_ENTRIES 64 +#define NTLB_ENTRIES_HALF 32 + +void local_flush_tlb_all(void) +{ + unsigned long flags; + unsigned long old_ctx; + unsigned long entry; + +#ifdef DEBUG_TLB + printk("[tlball]"); +#endif + + local_irq_save(flags); + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi() & ASID_MASK; + write_c0_entryhi(CKSEG0); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + + entry = read_c0_wired(); + + /* Blast 'em all away. */ + while (entry < NTLB_ENTRIES) { + write_c0_index(entry); + tlb_write_indexed(); + entry++; + } + write_c0_entryhi(old_ctx); + local_irq_restore(flags); +} + +void local_flush_tlb_mm(struct mm_struct *mm) +{ + int cpu = smp_processor_id(); + if (cpu_context(cpu, mm) != 0) { +#ifdef DEBUG_TLB + printk("[tlbmm<%d>]", mm->context); +#endif + drop_mmu_context(mm,cpu); + } +} + +void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, + unsigned long end) +{ + int cpu = smp_processor_id(); + if (cpu_context(cpu, mm) != 0) { + unsigned long flags; + int size; + +#ifdef DEBUG_TLB + printk("[tlbrange<%02x,%08lx,%08lx>]", + (mm->context & ASID_MASK), start, end); +#endif + local_irq_save(flags); + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; + if (size <= NTLB_ENTRIES_HALF) { + int oldpid = (read_c0_entryhi() & ASID_MASK); + int newpid = (cpu_context(smp_processor_id(), mm) + & ASID_MASK); + + start &= (PAGE_MASK << 1); + end += ((PAGE_SIZE << 1) - 1); + end &= (PAGE_MASK << 1); + while(start < end) { + int idx; + + write_c0_entryhi(start | newpid); + start += (PAGE_SIZE << 1); + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + write_c0_entryhi(KSEG0); + if(idx < 0) + continue; + tlb_write_indexed(); + } + write_c0_entryhi(oldpid); + } else { + drop_mmu_context(mm, cpu); + } + local_irq_restore(flags); + } +} + +void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + if (cpu_context(smp_processor_id(), vma->vm_mm) != 0) { + unsigned long flags; + int oldpid, newpid, idx; + +#ifdef DEBUG_TLB + printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); +#endif + newpid = (cpu_context(smp_processor_id(), vma->vm_mm) & + ASID_MASK); + page &= (PAGE_MASK << 1); + local_irq_save(flags); + oldpid = (read_c0_entryhi() & ASID_MASK); + write_c0_entryhi(page | newpid); + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + write_c0_entryhi(KSEG0); + if (idx < 0) + goto finish; + tlb_write_indexed(); + + finish: + write_c0_entryhi(oldpid); + local_irq_restore(flags); + } +} + +/* XXX Simplify this. On the R10000 writing a TLB entry for an virtual + address that already exists will overwrite the old entry and not result + in TLB malfunction or TLB shutdown. */ +void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) +{ + unsigned int cpu = smp_processor_id(); + unsigned long flags; + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + int idx, pid; + + /* + * Handle debugger faulting in for debugee. + */ + if (current->active_mm != vma->vm_mm) + return; + + pid = read_c0_entryhi() & ASID_MASK; + + if ((pid != cpu_asid(cpu, vma->vm_mm)) + || (cpu_context(cpu, vma->vm_mm) == 0)) { + printk(KERN_WARNING + "%s: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n", + __FUNCTION__, (int) cpu_asid(cpu, vma->vm_mm), pid); + } + + local_irq_save(flags); + address &= (PAGE_MASK << 1); + write_c0_entryhi(address | (pid)); + pgdp = pgd_offset(vma->vm_mm, address); + tlb_probe(); + pmdp = pmd_offset(pgdp, address); + idx = read_c0_index(); + ptep = pte_offset(pmdp, address); + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); + write_c0_entryhi(address | (pid)); + if (idx < 0) { + tlb_write_random(); + } else { + tlb_write_indexed(); + } + write_c0_entryhi(pid); + local_irq_restore(flags); +} + +void __init andes_tlb_init(void) +{ + /* + * You should never change this register: + * - On R4600 1.7 the tlbp never hits for pages smaller than + * the value in the c0_pagemask register. + * - The entire mm handling assumes the c0_pagemask register to + * be set for 4kb pages. + */ + write_c0_pagemask(PM_4K); + write_c0_wired(0); + write_c0_framemask(0); + + /* From this point on the ARC firmware is dead. */ + local_flush_tlb_all(); + + /* Did I tell you that ARC SUCKS? */ + + memcpy((void *)KSEG1 + 0x080, except_vec1_r10k, 0x80); +} diff -urN linux-2.4.21-bk37/arch/mips64/mm/tlb-dbg-r4k.c linux-2.4.21-bk38/arch/mips64/mm/tlb-dbg-r4k.c --- linux-2.4.21-bk37/arch/mips64/mm/tlb-dbg-r4k.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips64/mm/tlb-dbg-r4k.c 2003-08-24 02:55:58.000000000 -0700 @@ -39,8 +39,8 @@ pmd = pmd_offset(pgd, addr); pte = pte_offset(pmd, addr); - set_entrylo0(pte_val(pte[0]) >> 6); - set_entrylo1(pte_val(pte[1]) >> 6); + write_c0_entrylo0(pte_val(pte[0]) >> 6); + write_c0_entrylo1(pte_val(pte[1]) >> 6); __asm__ __volatile__("nop;nop;nop"); tlb_write_random(); diff -urN linux-2.4.21-bk37/arch/mips64/mm/tlb-glue-r4k.S linux-2.4.21-bk38/arch/mips64/mm/tlb-glue-r4k.S --- linux-2.4.21-bk37/arch/mips64/mm/tlb-glue-r4k.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/arch/mips64/mm/tlb-glue-r4k.S 2003-08-24 02:55:58.000000000 -0700 @@ -19,6 +19,10 @@ STI .endm + .macro __BUILD_kmode + KMODE + .endm + .macro tlb_handler name interruptible writebit NESTED(__\name, PT_SIZE, sp) SAVE_ALL @@ -32,6 +36,6 @@ END(__\name) .endm - tlb_handler xtlb_mod sti 1 - tlb_handler xtlb_tlbl sti 0 - tlb_handler xtlb_tlbs sti 1 + tlb_handler xtlb_mod kmode 1 + tlb_handler xtlb_tlbl kmode 0 + tlb_handler xtlb_tlbs kmode 1 diff -urN linux-2.4.21-bk37/arch/mips64/mm/tlb-glue-sb1.S linux-2.4.21-bk38/arch/mips64/mm/tlb-glue-sb1.S --- linux-2.4.21-bk37/arch/mips64/mm/tlb-glue-sb1.S 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/tlb-glue-sb1.S 2003-08-24 02:55:58.000000000 -0700 @@ -0,0 +1,66 @@ +/* + * 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. + * + * Copyright (C) 1999 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#include +#include +#include +#include +#include +#include + + .macro __BUILD_cli + CLI + .endm + + .macro __BUILD_sti + STI + .endm + + .macro __BUILD_kmode + KMODE + .endm + + .macro tlb_handler name interruptible writebit + NESTED(__\name, PT_SIZE, sp) + SAVE_ALL + dmfc0 a2, CP0_BADVADDR + __BUILD_\interruptible + li a1, \writebit + sd a2, PT_BVADDR(sp) + move a0, sp + jal do_page_fault + j ret_from_exception + END(__\name) + .endm + + .macro tlb_handler_m3 name interruptible writebit + NESTED(__\name, PT_SIZE, sp) + dmfc0 k0, CP0_BADVADDR + dmfc0 k1, CP0_ENTRYHI + xor k0, k1 + dsrl k0, k0, PAGE_SHIFT + 1 + bnez k0, 1f + SAVE_ALL + dmfc0 a2, CP0_BADVADDR + __BUILD_\interruptible + li a1, \writebit + sd a2, PT_BVADDR(sp) + move a0, sp + jal do_page_fault +1: + j ret_from_exception + END(__\name) + .endm + + tlb_handler xtlb_mod kmode 1 +#if BCM1250_M3_WAR + tlb_handler_m3 xtlb_tlbl kmode 0 +#else + tlb_handler xtlb_tlbl kmode 0 +#endif + tlb_handler xtlb_tlbs kmode 1 diff -urN linux-2.4.21-bk37/arch/mips64/mm/tlb-r4k.c linux-2.4.21-bk38/arch/mips64/mm/tlb-r4k.c --- linux-2.4.21-bk37/arch/mips64/mm/tlb-r4k.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/tlb-r4k.c 2003-08-24 02:55:58.000000000 -0700 @@ -33,7 +33,7 @@ #undef DEBUG_TLB #undef DEBUG_TLBUPDATE -extern char except_vec1_r4k; +extern void except_vec1_r4k(void); /* CP0 hazard avoidance. */ #define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ @@ -50,66 +50,62 @@ printk("[tlball]"); #endif - __save_and_cli(flags); + local_irq_save(flags); /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - set_entryhi(KSEG0); - set_entrylo0(0); - set_entrylo1(0); + old_ctx = (read_c0_entryhi() & ASID_MASK); + write_c0_entryhi(XKPHYS); + write_c0_entrylo0(0); + write_c0_entrylo1(0); BARRIER; - entry = get_wired(); + entry = read_c0_wired(); /* Blast 'em all away. */ - while(entry < mips_cpu.tlbsize) { + while(entry < current_cpu_data.tlbsize) { /* Make sure all entries differ. */ - set_entryhi(KSEG0+entry*0x2000); - set_index(entry); + write_c0_entryhi(XKPHYS+entry*0x2000); + write_c0_index(entry); BARRIER; tlb_write_indexed(); BARRIER; entry++; } BARRIER; - set_entryhi(old_ctx); - __restore_flags(flags); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); } void local_flush_tlb_mm(struct mm_struct *mm) { - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { - unsigned long flags; + int cpu = smp_processor_id(); + if (cpu_context(cpu, mm) != 0) { #ifdef DEBUG_TLB printk("[tlbmm<%d>]", mm->context); #endif - __save_and_cli(flags); - get_new_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) & - 0xff); - __restore_flags(flags); + drop_mmu_context(mm,cpu); } } void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end) { - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, mm) != 0) { unsigned long flags; int size; #ifdef DEBUG_TLB - printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff), + printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & ASID_MASK), start, end); #endif - __save_and_cli(flags); + local_irq_save(flags); size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; size = (size + 1) >> 1; - if(size <= mips_cpu.tlbsize/2) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (CPU_CONTEXT(smp_processor_id(), mm) & - 0xff); + if(size <= current_cpu_data.tlbsize/2) { + int oldpid = read_c0_entryhi() & ASID_MASK; + int newpid = cpu_asid(cpu, mm); start &= (PAGE_MASK << 1); end += ((PAGE_SIZE << 1) - 1); @@ -117,71 +113,69 @@ while(start < end) { int idx; - set_entryhi(start | newpid); + write_c0_entryhi(start | newpid); start += (PAGE_SIZE << 1); BARRIER; tlb_probe(); BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); if(idx < 0) continue; /* Make sure all entries differ. */ - set_entryhi(KSEG0+idx*0x2000); + write_c0_entryhi(XKPHYS+idx*0x2000); BARRIER; tlb_write_indexed(); BARRIER; } - set_entryhi(oldpid); + write_c0_entryhi(oldpid); } else { - get_new_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) - set_entryhi(CPU_CONTEXT(smp_processor_id(), - mm) & 0xff); + drop_mmu_context(mm, cpu); } - __restore_flags(flags); + local_irq_restore(flags); } } void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) { - if (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) != 0) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, vma->vm_mm) != 0) { unsigned long flags; unsigned long oldpid, newpid, idx; #ifdef DEBUG_TLB printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); #endif - newpid = (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff); + newpid = cpu_asid(cpu, vma->vm_mm); page &= (PAGE_MASK << 1); - __save_and_cli(flags); - oldpid = (get_entryhi() & 0xff); - set_entryhi(page | newpid); + local_irq_save(flags); + oldpid = (read_c0_entryhi() & ASID_MASK); + write_c0_entryhi(page | newpid); BARRIER; tlb_probe(); BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); if(idx < 0) goto finish; /* Make sure all entries differ. */ - set_entryhi(KSEG0+idx*0x2000); + write_c0_entryhi(XKPHYS+idx*0x2000); BARRIER; tlb_write_indexed(); finish: BARRIER; - set_entryhi(oldpid); - __restore_flags(flags); + write_c0_entryhi(oldpid); + local_irq_restore(flags); } } /* * Updates the TLB with the new pte(s). */ -void mips64_update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) +void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) { unsigned long flags; pgd_t *pgdp; @@ -195,31 +189,31 @@ if (current->active_mm != vma->vm_mm) return; - pid = get_entryhi() & 0xff; + pid = read_c0_entryhi() & ASID_MASK; #ifdef DEBUG_TLB - if((pid != (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff)) || - (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d - tlbpid=%d\n", (int) (CPU_CONTEXT(smp_processor_id(), - vma->vm_mm) & 0xff), pid); + if ((pid != (cpu_asid(smp_processor_id(), vma->vm_mm))) || + (cpu_context(smp_processor_id(), vma->vm_mm) == 0)) { + printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d" + "tlbpid=%d\n", (int) (cpu_context(smp_processor_id(), + vma->vm_mm) & ASID_MASK), pid); } #endif - __save_and_cli(flags); + local_irq_save(flags); address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); + write_c0_entryhi(address | (pid)); pgdp = pgd_offset(vma->vm_mm, address); BARRIER; tlb_probe(); BARRIER; pmdp = pmd_offset(pgdp, address); - idx = get_index(); + idx = read_c0_index(); ptep = pte_offset(pmdp, address); BARRIER; - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); + write_c0_entryhi(address | (pid)); BARRIER; if(idx < 0) { tlb_write_random(); @@ -227,70 +221,9 @@ tlb_write_indexed(); } BARRIER; - set_entryhi(pid); - BARRIER; - __restore_flags(flags); -} - -void dump_mm_page(unsigned long addr) -{ - pgd_t *page_dir, *pgd; - pmd_t *pmd; - pte_t *pte, page; - unsigned long val; - - page_dir = pgd_offset(current->mm, 0); - pgd = pgd_offset(current->mm, addr); - pmd = pmd_offset(pgd, addr); - pte = pte_offset(pmd, addr); - page = *pte; - printk("Memory Mapping: VA = %08x, PA = %08x ", addr, (unsigned int) pte_val(page)); - val = pte_val(page); - if (val & _PAGE_PRESENT) printk("present "); - if (val & _PAGE_READ) printk("read "); - if (val & _PAGE_WRITE) printk("write "); - if (val & _PAGE_ACCESSED) printk("accessed "); - if (val & _PAGE_MODIFIED) printk("modified "); - if (val & _PAGE_R4KBUG) printk("r4kbug "); - if (val & _PAGE_GLOBAL) printk("global "); - if (val & _PAGE_VALID) printk("valid "); - printk("\n"); -} - -void show_tlb(void) -{ - unsigned int flags; - unsigned int old_ctx; - unsigned int entry; - unsigned int entrylo0, entrylo1, entryhi; - - __save_and_cli(flags); - - /* Save old context */ - old_ctx = (get_entryhi() & 0xff); - - printk("TLB content:\n"); - entry = 0; - while(entry < mips_cpu.tlbsize) { - set_index(entry); - BARRIER; - tlb_read(); - BARRIER; - entryhi = get_entryhi(); - entrylo0 = get_entrylo0(); - entrylo1 = get_entrylo1(); - printk("%02d: ASID=%02d%s VA=0x%08x ", entry, entryhi & ASID_MASK, (entrylo0 & entrylo1 & 1) ? "(G)" : " ", entryhi & ~ASID_MASK); - printk("PA0=0x%08x C0=%x %s%s%s\n", (entrylo0>>6)<<12, (entrylo0>>3) & 7, (entrylo0 & 4) ? "Dirty " : "", (entrylo0 & 2) ? "Valid " : "Invalid ", (entrylo0 & 1) ? "Global" : ""); - printk("\t\t\t PA1=0x%08x C1=%x %s%s%s\n", (entrylo1>>6)<<12, (entrylo1>>3) & 7, (entrylo1 & 4) ? "Dirty " : "", (entrylo1 & 2) ? "Valid " : "Invalid ", (entrylo1 & 1) ? "Global" : ""); - - dump_mm_page(entryhi & ~0xff); - dump_mm_page((entryhi & ~0xff) | 0x1000); - entry++; - } + write_c0_entryhi(pid); BARRIER; - set_entryhi(old_ctx); - - __restore_flags(flags); + local_irq_restore(flags); } void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, @@ -301,27 +234,27 @@ unsigned long old_pagemask; unsigned long old_ctx; - __save_and_cli(flags); + local_irq_save(flags); /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - old_pagemask = get_pagemask(); - wired = get_wired(); - set_wired (wired + 1); - set_index (wired); + old_ctx = (read_c0_entryhi() & ASID_MASK); + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); + write_c0_wired(wired + 1); + write_c0_index(wired); BARRIER; - set_pagemask (pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); - set_entrylo1(entrylo1); + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); BARRIER; tlb_write_indexed(); BARRIER; - set_entryhi(old_ctx); + write_c0_entryhi(old_ctx); BARRIER; - set_pagemask (old_pagemask); + write_c0_pagemask(old_pagemask); local_flush_tlb_all(); - __restore_flags(flags); + local_irq_restore(flags); } /* @@ -341,67 +274,66 @@ unsigned long old_pagemask; unsigned long old_ctx; - __save_and_cli(flags); + local_irq_save(flags); /* Save old context and create impossible VPN2 value */ - old_ctx = get_entryhi() & 0xff; - old_pagemask = get_pagemask(); - wired = get_wired(); + old_ctx = read_c0_entryhi() & ASID_MASK; + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); if (--temp_tlb_entry < wired) { printk(KERN_WARNING "No TLB space left for add_temporary_entry\n"); ret = -ENOSPC; goto out; } - set_index(temp_tlb_entry); + write_c0_index(temp_tlb_entry); BARRIER; - set_pagemask(pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); - set_entrylo1(entrylo1); + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); BARRIER; tlb_write_indexed(); BARRIER; - set_entryhi(old_ctx); + write_c0_entryhi(old_ctx); BARRIER; - set_pagemask(old_pagemask); + write_c0_pagemask(old_pagemask); out: - __restore_flags(flags); + local_irq_restore(flags); return ret; } static void __init probe_tlb(unsigned long config) { - unsigned long config1; - if (!(config & (1 << 31))) { /* * Not a MIPS64 complainant CPU. * Config 1 register not supported, we assume R4k style. */ - mips_cpu.tlbsize = 48; + current_cpu_data.tlbsize = 48; } else { - config1 = read_mips32_cp0_config1(); + unsigned long config1; + + config1 = read_c0_config1(); if (!((config >> 7) & 3)) panic("No MMU present"); else - mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1; + current_cpu_data.tlbsize = ((config1 >> 25) & 0x3f) + 1; } - printk("Number of TLB entries %d.\n", mips_cpu.tlbsize); + printk("Number of TLB entries %d.\n", current_cpu_data.tlbsize); } void __init r4k_tlb_init(void) { - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); + unsigned long config = read_c0_config(); probe_tlb(config); - _update_mmu_cache = mips64_update_mmu_cache; - set_pagemask(PM_4K); - write_32bit_cp0_register(CP0_WIRED, 0); - temp_tlb_entry = mips_cpu.tlbsize - 1; + write_c0_pagemask(PM_4K); + write_c0_wired(0); + temp_tlb_entry = current_cpu_data.tlbsize - 1; local_flush_tlb_all(); - memcpy((void *)(KSEG0 + 0x80), &except_vec1_r4k, 0x80); + memcpy((void *)(KSEG0 + 0x80), except_vec1_r4k, 0x80); flush_icache_range(KSEG0, KSEG0 + 0x80); } diff -urN linux-2.4.21-bk37/arch/mips64/mm/tlb-sb1.c linux-2.4.21-bk38/arch/mips64/mm/tlb-sb1.c --- linux-2.4.21-bk37/arch/mips64/mm/tlb-sb1.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/tlb-sb1.c 2003-08-24 02:55:58.000000000 -0700 @@ -22,6 +22,8 @@ #include #include +extern void except_vec1_sb1(void); + /* Dump the current entry* and pagemask registers */ static inline void dump_cur_tlb_regs(void) { @@ -65,30 +67,24 @@ unsigned long old_ctx; unsigned long flags; int entry; - __save_and_cli(flags); - old_ctx = get_entryhi(); + local_irq_save(flags); + old_ctx = read_c0_entryhi(); printk("Current TLB registers state:\n" " EntryHi EntryLo0 EntryLo1 PageMask Index\n" "--------------------------------------------------------------------\n"); dump_cur_tlb_regs(); - printk(" %08X\n", read_32bit_cp0_register(CP0_INDEX)); + printk(" %08X\n", read_c0_index()); printk("\n\nFull TLB Dump:\n" "Idx EntryHi EntryLo0 EntryLo1 PageMask\n" "--------------------------------------------------------------\n"); - for (entry = 0; entry < mips_cpu.tlbsize; entry++) { - set_index(entry); + for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { + write_c0_index(entry); printk("\n%02i ", entry); - __asm__ __volatile__ ( - ".set push \n" - "#.set mips64 \n" - ".set mips4 \n" - " tlbr \n" - ".set pop \n"); dump_cur_tlb_regs(); } printk("\n"); - set_entryhi(old_ctx); - __restore_flags(flags); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); } void local_flush_tlb_all(void) @@ -97,18 +93,18 @@ unsigned long old_ctx; int entry; - __save_and_cli(flags); + local_irq_save(flags); /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - set_entrylo0(0); - set_entrylo1(0); - for (entry = 0; entry < mips_cpu.tlbsize; entry++) { - set_entryhi(KSEG0 + (PAGE_SIZE << 1) * entry); - set_index(entry); + old_ctx = read_c0_entryhi() & ASID_MASK; + write_c0_entrylo0(0); + write_c0_entrylo1(0); + for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { + write_c0_entryhi(KSEG0 + (PAGE_SIZE << 1) * entry); + write_c0_index(entry); tlb_write_indexed(); } - set_entryhi(old_ctx); - __restore_flags(flags); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); } @@ -126,15 +122,15 @@ long inc = 1<<24; /* 16MB */ /* Save old context and create impossible VPN2 value */ - set_entrylo0(0); - set_entrylo1(0); - for (entry = 0; entry < mips_cpu.tlbsize; entry++) { + write_c0_entrylo0(0); + write_c0_entrylo1(0); + for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { do { addr += inc; - set_entryhi(addr); + write_c0_entryhi(addr); tlb_probe(); - } while ((int)(get_index()) >= 0); - set_index(entry); + } while ((int)(read_c0_index()) >= 0); + write_c0_index(entry); tlb_write_indexed(); } /* Now that we know we're safe from collisions, we can safely flush @@ -149,15 +145,15 @@ unsigned long flags; int cpu; - __save_and_cli(flags); + local_irq_save(flags); cpu = smp_processor_id(); - if(CPU_CONTEXT(cpu, mm) != 0) { + if (cpu_context(cpu, mm) != 0) { int size; size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; size = (size + 1) >> 1; - if(size <= (mips_cpu.tlbsize/2)) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (CPU_CONTEXT(cpu, mm) & 0xff); + if(size <= (current_cpu_data.tlbsize/2)) { + int oldpid = read_c0_entryhi() & ASID_MASK; + int newpid = cpu_asid(cpu, mm); start &= (PAGE_MASK << 1); end += ((PAGE_SIZE << 1) - 1); @@ -165,63 +161,50 @@ while(start < end) { int idx; - set_entryhi(start | newpid); + write_c0_entryhi(start | newpid); start += (PAGE_SIZE << 1); tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0 + (idx << (PAGE_SHIFT+1))); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + write_c0_entryhi(KSEG0 + (idx << (PAGE_SHIFT+1))); if(idx < 0) continue; tlb_write_indexed(); } - set_entryhi(oldpid); + write_c0_entryhi(oldpid); } else { - get_new_mmu_context(mm, cpu); - if (mm == current->active_mm) - set_entryhi(CPU_CONTEXT(cpu, mm) & 0xff); + drop_mmu_context(mm, cpu); } } - __restore_flags(flags); + local_irq_restore(flags); } void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) { unsigned long flags; - -#ifdef CONFIG_SMP - /* - * This variable is eliminated from CPU_CONTEXT() if SMP isn't defined, - * so conditional it to get rid of silly "unused variable" compiler - * complaints - */ int cpu = smp_processor_id(); -#endif - __save_and_cli(flags); - if (CPU_CONTEXT(cpu, vma->vm_mm) != 0) { + local_irq_save(flags); + if (cpu_context(cpu, vma->vm_mm) != 0) { int oldpid, newpid, idx; -#ifdef DEBUG_TLB - printk("[tlbpage<%d,%08lx>]", CPU_CONTEXT(cpu, vma->vm_mm), page); -#endif - newpid = (CPU_CONTEXT(cpu, vma->vm_mm) & 0xff); + newpid = cpu_asid(cpu, vma->vm_mm); page &= (PAGE_MASK << 1); - oldpid = (get_entryhi() & 0xff); - set_entryhi (page | newpid); + oldpid = read_c0_entryhi() & ASID_MASK; + write_c0_entryhi(page | newpid); tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); if(idx < 0) goto finish; /* Make sure all entries differ. */ - set_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1))); + write_c0_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1))); tlb_write_indexed(); finish: - set_entryhi(oldpid); + write_c0_entryhi(oldpid); } - __restore_flags(flags); + local_irq_restore(flags); } @@ -229,23 +212,15 @@ these entries, we just bump the asid. */ void local_flush_tlb_mm(struct mm_struct *mm) { - unsigned long flags; - int cpu; - __save_and_cli(flags); - cpu = smp_processor_id(); - if (CPU_CONTEXT(cpu, mm) != 0) { - get_new_mmu_context(mm, smp_processor_id()); - if (mm == current->active_mm) { - set_entryhi(CPU_CONTEXT(cpu, mm) & 0xff); - } + int cpu = smp_processor_id(); + if (cpu_context(cpu, mm) != 0) { + drop_mmu_context(mm, cpu); } - __restore_flags(flags); } /* Stolen from mips32 routines */ -void sb1_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, - pte_t pte) +void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) { unsigned long flags; pgd_t *pgdp; @@ -259,35 +234,24 @@ if (current->active_mm != vma->vm_mm) return; - __save_and_cli(flags); - - - pid = get_entryhi() & 0xff; - -#ifdef DEBUG_TLB - if((pid != (CPU_CONTEXT(cpu, vma->vm_mm) & 0xff)) || (CPU_CONTEXT(cpu, vma->vm_mm) == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n", - (int) (CPU_CONTEXT(cpu, vma->vm_mm) & 0xff), pid); - } -#endif + local_irq_save(flags); + pid = read_c0_entryhi() & ASID_MASK; address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); + write_c0_entryhi(address | (pid)); pgdp = pgd_offset(vma->vm_mm, address); tlb_probe(); pmdp = pmd_offset(pgdp, address); - idx = get_index(); + idx = read_c0_index(); ptep = pte_offset(pmdp, address); - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); if (idx < 0) { tlb_write_random(); } else { tlb_write_indexed(); } - set_entryhi(pid); - __restore_flags(flags); + local_irq_restore(flags); } /* @@ -297,10 +261,7 @@ */ void sb1_tlb_init(void) { - u32 config1; - - config1 = read_mips32_cp0_config1(); - mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1; + write_c0_pagemask(PM_4K); /* * We don't know what state the firmware left the TLB's in, so this is @@ -308,5 +269,7 @@ * check exceptions due to duplicate TLB entries */ sb1_sanitize_tlb(); - _update_mmu_cache = sb1_update_mmu_cache; + + memcpy((void *)KSEG0 + 0x080, except_vec1_sb1, 0x80); + flush_icache_range(KSEG0, KSEG0 + 0x80); } diff -urN linux-2.4.21-bk37/arch/mips64/mm/tlbex-r4k.S linux-2.4.21-bk38/arch/mips64/mm/tlbex-r4k.S --- linux-2.4.21-bk37/arch/mips64/mm/tlbex-r4k.S 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/tlbex-r4k.S 2003-08-24 02:55:58.000000000 -0700 @@ -15,6 +15,7 @@ #include #include #include +#include .data .comm pgd_current, NR_CPUS * 8, 8 @@ -72,8 +73,9 @@ * Determine that fault address is within vmalloc range. */ dla \tmp, ekptbl - sltu \tmp, \ptr, \tmp + slt \tmp, \ptr, \tmp beqz \tmp, \not_vmalloc # not vmalloc + nop .endm @@ -96,16 +98,16 @@ __INIT .align 5 -LEAF(except_vec0) +LEAF(except_vec0_generic) .set noat PANIC("Unused vector called") 1: b 1b nop -END(except_vec0) +END(except_vec0_generic) /* - * TLB refill handler for the R4000. + * TLB refill handlers for the R4000 and SB1. * Attention: We may only use 32 instructions / 128 bytes. */ .align 5 @@ -116,6 +118,23 @@ nop END(except_vec1_r4k) +LEAF(except_vec1_sb1) +#if BCM1250_M3_WAR + dmfc0 k0, CP0_BADVADDR + dmfc0 k1, CP0_ENTRYHI + xor k0, k1 + dsrl k0, k0, PAGE_SHIFT+1 + bnez k0, 1f +#endif + .set noat + dla k0, handle_vec1_r4k + jr k0 + nop + +1: eret + nop +END(except_vec1_sb1) + __FINIT .align 5 @@ -141,6 +160,7 @@ eret END(handle_vec1_r4k) + __INIT /* diff -urN linux-2.4.21-bk37/arch/mips64/mm/umap.c linux-2.4.21-bk38/arch/mips64/mm/umap.c --- linux-2.4.21-bk37/arch/mips64/mm/umap.c 2002-11-28 15:53:10.000000000 -0800 +++ linux-2.4.21-bk38/arch/mips64/mm/umap.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,217 +0,0 @@ -/* - * 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. - * - * Copyright (C) 1994 Linus Torvalds - * Copyright (C) 1997 Miguel de Icaza - * Copyright (C) 2001 Ralf Baechle - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static inline void remove_mapping_pte_range (pmd_t *pmd, unsigned long address, - unsigned long size) -{ - pte_t *pte; - unsigned long end; - - if (pmd_none (*pmd)) - return; - if (pmd_bad (*pmd)){ - printk ("remove_graphics_pte_range: bad pmd (%08lx)\n", - pmd_val (*pmd)); - pmd_clear (pmd); - return; - } - pte = pte_offset (pmd, address); - address &= ~PMD_MASK; - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; - do { - pte_t entry = *pte; - if (pte_present (entry)) - set_pte (pte, pte_modify (entry, PAGE_NONE)); - address += PAGE_SIZE; - pte++; - } while (address < end); - -} - -static inline void remove_mapping_pmd_range (pgd_t *pgd, unsigned long address, - unsigned long size) -{ - pmd_t *pmd; - unsigned long end; - - if (pgd_none (*pgd)) - return; - - if (pgd_bad (*pgd)){ - printk ("remove_graphics_pmd_range: bad pgd (%08lx)\n", - pgd_val (*pgd)); - pgd_clear (pgd); - return; - } - pmd = pmd_offset (pgd, address); - address &= ~PGDIR_MASK; - end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - do { - remove_mapping_pte_range (pmd, address, end - address); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address < end); - -} - -/* - * This routine is called from the page fault handler to remove a - * range of active mappings at this point - */ -void remove_mapping (struct task_struct *task, unsigned long start, - unsigned long end) -{ - unsigned long beg = start; - pgd_t *dir; - - down_write (&task->mm->mmap_sem); - dir = pgd_offset (task->mm, start); - flush_cache_range (task->mm, beg, end); - while (start < end){ - remove_mapping_pmd_range (dir, start, end - start); - start = (start + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } - flush_tlb_range (task->mm, beg, end); - up_write (&task->mm->mmap_sem); -} - -EXPORT_SYMBOL(remove_mapping); - -void *vmalloc_uncached (unsigned long size) -{ - return __vmalloc (size, GFP_KERNEL | __GFP_HIGHMEM, - PAGE_KERNEL_UNCACHED); -} - -static inline void free_pte(pte_t page) -{ - if (pte_present(page)) { - struct page *ptpage = pte_page(page); - if ((!VALID_PAGE(ptpage)) || PageReserved(ptpage)) - return; - __free_page(ptpage); - if (current->mm->rss <= 0) - return; - current->mm->rss--; - return; - } - swap_free(pte_to_swp_entry(page)); -} - -static inline void forget_pte(pte_t page) -{ - if (!pte_none(page)) { - printk("forget_pte: old mapping existed!\n"); - free_pte(page); - } -} - -/* - * maps a range of vmalloc()ed memory into the requested pages. the old - * mappings are removed. - */ -static inline void vmap_pte_range (pte_t *pte, unsigned long address, - unsigned long size, unsigned long vaddr) -{ - unsigned long end; - pgd_t *vdir; - pmd_t *vpmd; - pte_t *vpte; - - address &= ~PMD_MASK; - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; - do { - pte_t oldpage = *pte; - struct page * page; - pte_clear(pte); - - vdir = pgd_offset_k (vaddr); - vpmd = pmd_offset (vdir, vaddr); - vpte = pte_offset (vpmd, vaddr); - page = pte_page (*vpte); - - set_pte(pte, mk_pte(page, PAGE_USERIO)); - forget_pte(oldpage); - address += PAGE_SIZE; - vaddr += PAGE_SIZE; - pte++; - } while (address < end); -} - -static inline int vmap_pmd_range (pmd_t *pmd, unsigned long address, - unsigned long size, unsigned long vaddr) -{ - unsigned long end; - - address &= ~PGDIR_MASK; - end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - vaddr -= address; - do { - pte_t * pte = pte_alloc(current->mm, pmd, address); - if (!pte) - return -ENOMEM; - vmap_pte_range(pte, address, end - address, address + vaddr); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address < end); - return 0; -} - -int vmap_page_range (unsigned long from, unsigned long size, - unsigned long vaddr) -{ - int error = 0; - pgd_t * dir; - unsigned long beg = from; - unsigned long end = from + size; - - vaddr -= from; - dir = pgd_offset(current->mm, from); - flush_cache_range(current->mm, beg, end); - while (from < end) { - pmd_t *pmd = pmd_alloc(current->mm, dir, from); - error = -ENOMEM; - if (!pmd) - break; - error = vmap_pmd_range(pmd, from, end - from, vaddr + from); - if (error) - break; - from = (from + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } - flush_tlb_range(current->mm, beg, end); - return error; -} diff -urN linux-2.4.21-bk37/drivers/Makefile linux-2.4.21-bk38/drivers/Makefile --- linux-2.4.21-bk37/drivers/Makefile 2003-08-24 02:55:50.000000000 -0700 +++ linux-2.4.21-bk38/drivers/Makefile 2003-08-24 02:55:59.000000000 -0700 @@ -6,7 +6,7 @@ # -mod-subdirs := dio hil mtd sbus video macintosh usb input telephony sgi ide \ +mod-subdirs := dio hil mtd sbus video macintosh usb input telephony ide \ message/i2o message/fusion scsi md ieee1394 pnp isdn atm \ fc4 net/hamradio i2c acpi bluetooth @@ -30,7 +30,6 @@ subdir-$(CONFIG_USB) += usb subdir-$(CONFIG_INPUT) += input subdir-$(CONFIG_PHONE) += telephony -subdir-$(CONFIG_SGI) += sgi subdir-$(CONFIG_IDE) += ide subdir-$(CONFIG_SCSI) += scsi subdir-$(CONFIG_I2O) += message/i2o diff -urN linux-2.4.21-bk37/drivers/char/au1000_gpio.c linux-2.4.21-bk38/drivers/char/au1000_gpio.c --- linux-2.4.21-bk37/drivers/char/au1000_gpio.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/drivers/char/au1000_gpio.c 2003-08-24 02:56:03.000000000 -0700 @@ -86,7 +86,7 @@ #ifdef CONFIG_USB_OHCI avail_mask &= ~((1<<4) | (1<<11)); -#ifndef CONFIG_AU1000_USB_DEVICE +#ifndef CONFIG_AU1X00_USB_DEVICE avail_mask &= ~((1<<5) | (1<<13)); #endif #endif diff -urN linux-2.4.21-bk37/drivers/char/au1000_ts.c linux-2.4.21-bk38/drivers/char/au1000_ts.c --- linux-2.4.21-bk37/drivers/char/au1000_ts.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/drivers/char/au1000_ts.c 2003-08-24 02:56:03.000000000 -0700 @@ -261,7 +261,7 @@ calc_clkdiv(int baud) { u32 sys_busclk = - (get_au1000_speed() / (int)(inl(PM_POWERUP_CONTROL)&0x03) + 2); + (get_au1x00_speed() / (int)(inl(SYS_POWERCTRL)&0x03) + 2); return (sys_busclk / (2 * baud)) - 1; } @@ -269,7 +269,7 @@ calc_baudrate(u32 clkdiv) { u32 sys_busclk = - (get_au1000_speed() / (int)(inl(PM_POWERUP_CONTROL)&0x03) + 2); + (get_au1x00_speed() / (int)(inl(SYS_POWERCTRL)&0x03) + 2); return sys_busclk / (2 * (clkdiv + 1)); } @@ -642,7 +642,7 @@ ts->y_plate_ohms = DEFAULT_Y_PLATE_OHMS; // set GPIO to SSI0 function - outl(inl(PIN_FUNCTION) & ~1, PIN_FUNCTION); + outl(inl(SYS_PINFUNC) & ~1, SYS_PINFUNC); // enable SSI0 clock and bring SSI0 out of reset outl(0, SSI0_CONTROL); diff -urN linux-2.4.21-bk37/drivers/char/au1000_usbraw.c linux-2.4.21-bk38/drivers/char/au1000_usbraw.c --- linux-2.4.21-bk37/drivers/char/au1000_usbraw.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/drivers/char/au1000_usbraw.c 2003-08-24 02:56:03.000000000 -0700 @@ -0,0 +1,575 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1x00 USB Device-Side Raw Block Driver (function layer) + * + * Copyright 2001-2002 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * stevel@mvista.com or source@mvista.com + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#undef DEBUG +#include + +#include +#include +#include +#include +#include + +#define USBRAW_MAJOR 190 // FIXME: need a legal major +#define USBRAW_NAME "usbraw" + +#define MAX_NUM_PORTS 2 + +#define IN_MAX_PACKET_SIZE 64 +#define OUT_MAX_PACKET_SIZE 64 + +// FIXME: when Au1x00 endpoints 3 and 5 are fixed, make NUM_PORTS=2 +#define NUM_PORTS 1 +#define NUM_EP 2*NUM_PORTS + +#define CONFIG_DESC_LEN \ + USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + NUM_EP*USB_DT_ENDPOINT_SIZE + +/* must be power of two */ +#define READ_BUF_SIZE (1<<12) + +struct usb_raw_port { + unsigned char number; + spinlock_t port_lock; + + struct usb_endpoint_descriptor* out_desc; + struct usb_endpoint_descriptor* in_desc; + + int out_ep_addr; /* endpoint address of OUT endpoint */ + int in_ep_addr; /* endpoint address of IN endpoint */ + + __u8 read_buf[READ_BUF_SIZE]; // FIXME: allocate with get_free_pages + int read_nextin, read_nextout; + int read_count; + + wait_queue_head_t wait; + struct fasync_struct *fasync; // asynch notification + + int active; /* someone has this device open */ + int open_count; /* number of times this port has been opened */ +}; + +static struct usb_serial { + struct usb_device_descriptor* dev_desc; + struct usb_config_descriptor* config_desc; + struct usb_interface_descriptor* if_desc; + struct usb_string_descriptor * str_desc[6]; + void* str_desc_buf; + + usbdev_state_t dev_state; + + struct usb_raw_port port[NUM_PORTS]; +} usbraw; + +static struct usb_device_descriptor dev_desc = { + bLength:USB_DT_DEVICE_SIZE, + bDescriptorType:USB_DT_DEVICE, + bcdUSB:USBDEV_REV, //usb rev + bDeviceClass:USB_CLASS_PER_INTERFACE, //class (none) + bDeviceSubClass:0x00, //subclass (none) + bDeviceProtocol:0x00, //protocol (none) + bMaxPacketSize0:USBDEV_EP0_MAX_PACKET_SIZE, //max packet size for ep0 + idVendor:0x6d04, //vendor id + idProduct:0x0bc0, //product id + bcdDevice:0x0001, //BCD rev 0.1 + iManufacturer:0x01, //manufactuer string index + iProduct:0x02, //product string index + iSerialNumber:0x03, //serial# string index + bNumConfigurations:0x01 //num configurations +}; + +static struct usb_endpoint_descriptor ep_desc[] = { + { + // Bulk IN for Port 0 + bLength:USB_DT_ENDPOINT_SIZE, + bDescriptorType:USB_DT_ENDPOINT, + bEndpointAddress:USB_DIR_IN, + bmAttributes:USB_ENDPOINT_XFER_BULK, + wMaxPacketSize:IN_MAX_PACKET_SIZE, + bInterval:0x00 // ignored for bulk + }, + { + // Bulk OUT for Port 0 + bLength:USB_DT_ENDPOINT_SIZE, + bDescriptorType:USB_DT_ENDPOINT, + bEndpointAddress:USB_DIR_OUT, + bmAttributes:USB_ENDPOINT_XFER_BULK, + wMaxPacketSize:OUT_MAX_PACKET_SIZE, + bInterval:0x00 // ignored for bulk + }, + { + // Bulk IN for Port 1 + bLength:USB_DT_ENDPOINT_SIZE, + bDescriptorType:USB_DT_ENDPOINT, + bEndpointAddress:USB_DIR_IN, + bmAttributes:USB_ENDPOINT_XFER_BULK, + wMaxPacketSize:IN_MAX_PACKET_SIZE, + bInterval:0x00 // ignored for bulk + }, + { + // Bulk OUT for Port 1 + bLength:USB_DT_ENDPOINT_SIZE, + bDescriptorType:USB_DT_ENDPOINT, + bEndpointAddress:USB_DIR_OUT, + bmAttributes:USB_ENDPOINT_XFER_BULK, + wMaxPacketSize:OUT_MAX_PACKET_SIZE, + bInterval:0x00 // ignored for bulk + } +}; + +static struct usb_interface_descriptor if_desc = { + bLength:USB_DT_INTERFACE_SIZE, + bDescriptorType:USB_DT_INTERFACE, + bInterfaceNumber:0x00, + bAlternateSetting:0x00, + bNumEndpoints:NUM_EP, + bInterfaceClass:0xff, + bInterfaceSubClass:0xab, + bInterfaceProtocol:0x00, + iInterface:0x05 +}; + +static struct usb_config_descriptor config_desc = { + bLength:USB_DT_CONFIG_SIZE, + bDescriptorType:USB_DT_CONFIG, + wTotalLength:CONFIG_DESC_LEN, + bNumInterfaces:0x01, + bConfigurationValue:0x01, + iConfiguration:0x04, // configuration string + bmAttributes:0xc0, // self-powered + MaxPower:20 // 40 mA +}; + +// String[0] is a list of Language IDs supported by this device +static struct usb_string_descriptor string_desc0 = { + bLength:4, + bDescriptorType:USB_DT_STRING, + wData:{0x0409} // English, US +}; + +// These strings will be converted to Unicode in string_desc[] +static char *strings[5] = { + "Alchemy Semiconductor", // iManufacturer + "USB Raw Block Device", // iProduct + "0.1", // iSerialNumber + "USB Raw Config", // iConfiguration + "USB Raw Interface" // iInterface +}; + + +static void +receive_callback(struct usb_raw_port *port) +{ + int i, pkt_size; + usbdev_pkt_t* pkt; + + if ((pkt_size = usbdev_receive_packet(port->out_ep_addr, + &pkt)) <= 0) { + dbg(__FUNCTION__ ": usbdev_receive_packet returns %d", + pkt_size); + return; + } + + dbg(__FUNCTION__ ": ep%d, size=%d", port->out_ep_addr, pkt_size); + + spin_lock(&port->port_lock); + for (i=0; i < pkt_size; i++) { + port->read_buf[port->read_nextin++] = pkt->payload[i]; + port->read_nextin &= (READ_BUF_SIZE - 1); + if (++port->read_count == READ_BUF_SIZE) + break; + } + spin_unlock(&port->port_lock); + + /* free the packet */ + kfree(pkt); + + // async notify + if (port->fasync) + kill_fasync(&port->fasync, SIGIO, POLL_IN); + // wake up any read call + if (waitqueue_active(&port->wait)) + wake_up_interruptible(&port->wait); +} + +static void +transmit_callback(struct usb_raw_port *port, usbdev_pkt_t* pkt) +{ + dbg(__FUNCTION__ ": ep%d", port->in_ep_addr); + /* just free the returned packet */ + kfree(pkt); +} + + +static void +usbraw_callback(usbdev_cb_type_t cb_type, unsigned long arg, void* data) +{ + usbdev_pkt_t* pkt; + int i; + + switch (cb_type) { + case CB_NEW_STATE: + usbraw.dev_state = (usbdev_state_t)arg; + break; + case CB_PKT_COMPLETE: + pkt = (usbdev_pkt_t*)arg; + for (i=0; iep_addr == port->in_ep_addr) { + transmit_callback(port, pkt); + break; + } else if (pkt->ep_addr == port->out_ep_addr) { + receive_callback(port); + break; + } + } + break; + } +} + +/***************************************************************************** + * Here begins the driver interface functions + *****************************************************************************/ + +static unsigned int usbraw_poll(struct file * filp, poll_table * wait) +{ + struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data; + unsigned long flags; + int count; + + poll_wait(filp, &port->wait, wait); + + spin_lock_irqsave(&port->port_lock, flags); + count = port->read_count; + spin_unlock_irqrestore(&port->port_lock, flags); + + if (count > 0) { + dbg(__FUNCTION__ ": count=%d", count); + return POLLIN | POLLRDNORM; + } + + return 0; +} + +static int usbraw_fasync(int fd, struct file *filp, int mode) +{ + struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data; + return fasync_helper(fd, filp, mode, &port->fasync); +} + +static int usbraw_open(struct inode * inode, struct file *filp) +{ + int portNumber; + struct usb_raw_port *port; + unsigned long flags; + + /* + * the device-layer must be in the configured state before the + * function layer can operate. + */ + if (usbraw.dev_state != CONFIGURED) + return -ENODEV; + + MOD_INC_USE_COUNT; + + /* set up our port structure making the tty driver remember + our port object, and us it */ + portNumber = MINOR(inode->i_rdev); + port = &usbraw.port[portNumber]; + filp->private_data = port; + + dbg(__FUNCTION__ ": port %d", port->number); + + spin_lock_irqsave(&port->port_lock, flags); + + ++port->open_count; + + if (!port->active) { + port->active = 1; + } + + /* flush read buffer */ + port->read_nextin = port->read_nextout = port->read_count = 0; + + spin_unlock_irqrestore(&port->port_lock, flags); + + return 0; +} + +static int usbraw_release(struct inode * inode, struct file * filp) +{ + struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data; + unsigned long flags; + + dbg(__FUNCTION__ ": port %d", port->number); + + if (!port->active) { + err(__FUNCTION__ ": port not opened"); + return -ENODEV; + } + + usbraw_fasync(-1, filp, 0); + + spin_lock_irqsave(&port->port_lock, flags); + + --port->open_count; + + if (port->open_count <= 0) { + port->active = 0; + port->open_count = 0; + } + + spin_unlock_irqrestore(&port->port_lock, flags); + MOD_DEC_USE_COUNT; + return 0; +} + + +static ssize_t usbraw_read(struct file * filp, char * buf, + size_t count, loff_t * l) +{ + struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data; + unsigned long flags; + int i, cnt; + + /* + * the device-layer must be in the configured state before the + * function layer can operate. + */ + if (usbraw.dev_state != CONFIGURED) + return -ENODEV; + + do { + spin_lock_irqsave(&port->port_lock, flags); + cnt = port->read_count; + spin_unlock_irqrestore(&port->port_lock, flags); + if (cnt == 0) { + if (filp->f_flags & O_NONBLOCK) + return -EAGAIN; + interruptible_sleep_on(&port->wait); + if (signal_pending(current)) + return -ERESTARTSYS; + } + } while (cnt == 0); + + count = (count > cnt) ? cnt : count; + + for (i=0; iread_buf[port->read_nextout++], &buf[i]); + port->read_nextout &= (READ_BUF_SIZE - 1); + spin_lock_irqsave(&port->port_lock, flags); + port->read_count--; + spin_unlock_irqrestore(&port->port_lock, flags); + if (port->read_count == 0) + break; + } + + return i+1; +} + +static ssize_t usbraw_write(struct file * filp, const char * buf, + size_t count, loff_t *ppos) +{ + struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data; + usbdev_pkt_t* pkt; + int ret, max_pkt_sz; + + /* + * the device-layer must be in the configured state before the + * function layer can operate. + */ + if (usbraw.dev_state != CONFIGURED) + return -ENODEV; + + if (!port->active) { + err(__FUNCTION__ ": port not opened"); + return -EINVAL; + } + + if (count == 0) { + dbg(__FUNCTION__ ": write request of 0 bytes"); + return (0); + } + + max_pkt_sz = port->in_desc->wMaxPacketSize; + count = (count > max_pkt_sz) ? max_pkt_sz : count; + + if ((ret = usbdev_alloc_packet(port->in_ep_addr, count, &pkt)) < 0) + return ret; + + copy_from_user(pkt->payload, buf, count); + + return usbdev_send_packet(port->in_ep_addr, pkt); +} + +static int usbraw_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data; + + if (!port->active) { + err(__FUNCTION__ ": port not open"); + return -ENODEV; + } + // FIXME: need any IOCTLs? + + return -ENOIOCTLCMD; +} + + +static struct file_operations usbraw_fops = { + owner: THIS_MODULE, + write: usbraw_write, + read: usbraw_read, + poll: usbraw_poll, + ioctl: usbraw_ioctl, + fasync: usbraw_fasync, + open: usbraw_open, + release: usbraw_release, +}; + +void usbfn_raw_exit(void) +{ + /* kill the device layer */ + usbdev_exit(); + + unregister_chrdev(USBRAW_MAJOR, USBRAW_NAME); + + if (usbraw.str_desc_buf) + kfree(usbraw.str_desc_buf); +} + + +int usbfn_raw_init(void) +{ + int ret = 0, i, str_desc_len; + + /* register our character device */ + if ((ret = register_chrdev(USBRAW_MAJOR, USBRAW_NAME, + &usbraw_fops)) < 0) { + err("can't get major number"); + return ret; + } + info("registered"); + + /* + * initialize pointers to descriptors + */ + usbraw.dev_desc = &dev_desc; + usbraw.config_desc = &config_desc; + usbraw.if_desc = &if_desc; + + /* + * initialize the string descriptors + */ + + /* alloc buffer big enough for all string descriptors */ + str_desc_len = string_desc0.bLength; + for (i = 0; i < 5; i++) + str_desc_len += 2 + 2 * strlen(strings[i]); + usbraw.str_desc_buf = (void *) kmalloc(str_desc_len, GFP_KERNEL); + if (!usbraw.str_desc_buf) { + err(__FUNCTION__ ": failed to alloc string descriptors"); + ret = -ENOMEM; + goto out; + } + + usbraw.str_desc[0] = + (struct usb_string_descriptor *)usbraw.str_desc_buf; + memcpy(usbraw.str_desc[0], &string_desc0, string_desc0.bLength); + usbraw.str_desc[1] = (struct usb_string_descriptor *) + (usbraw.str_desc_buf + string_desc0.bLength); + for (i = 1; i < 6; i++) { + struct usb_string_descriptor *desc = usbraw.str_desc[i]; + char *str = strings[i - 1]; + int j, str_len = strlen(str); + + desc->bLength = 2 + 2 * str_len; + desc->bDescriptorType = USB_DT_STRING; + for (j = 0; j < str_len; j++) { + desc->wData[j] = (u16) str[j]; + } + if (i < 5) + usbraw.str_desc[i + 1] = + (struct usb_string_descriptor *) + ((u8 *) desc + desc->bLength); + } + + /* + * start the device layer. The device layer assigns us + * our endpoint addresses + */ + if ((ret = usbdev_init(&dev_desc, &config_desc, &if_desc, ep_desc, + usbraw.str_desc, usbraw_callback, NULL))) { + err(__FUNCTION__ ": device-layer init failed"); + goto out; + } + + /* initialize the devfs nodes for this device and let the user + know what ports we are bound to */ + for (i = 0; i < NUM_PORTS; ++i) { + struct usb_raw_port *port = &usbraw.port[i]; + + port->number = i; + port->in_desc = &ep_desc[NUM_PORTS*i]; + port->out_desc = &ep_desc[NUM_PORTS*i + 1]; + port->in_ep_addr = port->in_desc->bEndpointAddress & 0x0f; + port->out_ep_addr = port->out_desc->bEndpointAddress & 0x0f; + init_waitqueue_head(&port->wait); + spin_lock_init(&port->port_lock); + } + + out: + if (ret) + usbfn_raw_exit(); + return ret; +} + + +/* Module information */ +MODULE_AUTHOR("Steve Longerbeam, stevel@mvista.com, www.mvista.com"); +MODULE_DESCRIPTION("Au1x00 USB Device-Side Raw Block Driver"); +MODULE_LICENSE("GPL"); + +module_init(usbfn_raw_init); +module_exit(usbfn_raw_exit); diff -urN linux-2.4.21-bk37/drivers/char/au1000_usbtty.c linux-2.4.21-bk38/drivers/char/au1000_usbtty.c --- linux-2.4.21-bk37/drivers/char/au1000_usbtty.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/drivers/char/au1000_usbtty.c 2003-08-24 02:56:03.000000000 -0700 @@ -0,0 +1,764 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1x00 USB Device-Side Serial TTY Driver (function layer) + * + * Copyright 2001-2002 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * stevel@mvista.com or source@mvista.com + * + * Derived from drivers/usb/serial/usbserial.c: + * + * Copyright (C) 1999 - 2001 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (c) 2000 Peter Berger (pberger@brimson.com) + * Copyright (c) 2000 Al Borchers (borchers@steinerpoint.com) + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#undef DEBUG +#include + +#include +#include +#include +#include +#include + + +/* local function prototypes */ +static int serial_open(struct tty_struct *tty, struct file *filp); +static void serial_close(struct tty_struct *tty, struct file *filp); +static int serial_write(struct tty_struct *tty, int from_user, + const unsigned char *buf, int count); +static int serial_write_room(struct tty_struct *tty); +static int serial_chars_in_buffer(struct tty_struct *tty); +static void serial_throttle(struct tty_struct *tty); +static void serial_unthrottle(struct tty_struct *tty); +static int serial_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg); +static void serial_set_termios (struct tty_struct *tty, struct termios * old); + +#define SERIAL_TTY_MAJOR 189 // FIXME: need a legal major + +#define MAX_NUM_PORTS 2 + +#define IN_MAX_PACKET_SIZE 32 +#define OUT_MAX_PACKET_SIZE 32 + +// FIXME: when Au1x00 endpoints 3 and 5 are fixed, make NUM_PORTS=2 +#define NUM_PORTS 2 +#define NUM_EP 2*NUM_PORTS + +#define CONFIG_DESC_LEN \ + USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + NUM_EP*USB_DT_ENDPOINT_SIZE + +struct usb_serial_port { + struct tty_struct *tty; /* the coresponding tty for this port */ + unsigned char number; + spinlock_t port_lock; + + struct usb_endpoint_descriptor* out_desc; + struct usb_endpoint_descriptor* in_desc; + + int out_ep_addr; /* endpoint address of OUT endpoint */ + int in_ep_addr; /* endpoint address of IN endpoint */ + + /* task queue for line discipline waking up on send packet complete */ + struct tq_struct send_complete_tq; + /* task queue for line discipline wakeup on receive packet complete */ + struct tq_struct receive_complete_tq; + + int active; /* someone has this device open */ + int writing; /* a packet write is in progress */ + int open_count; /* number of times this port has been opened */ + +}; + +static struct usb_serial { + usbdev_state_t dev_state; // current state of device layer + struct usb_device_descriptor* dev_desc; + struct usb_config_descriptor* config_desc; + struct usb_interface_descriptor* if_desc; + struct usb_string_descriptor * str_desc[6]; + void* str_desc_buf; + + struct usb_serial_port port[NUM_PORTS]; +} usbtty; + +static int serial_refcount; +static struct tty_driver serial_tty_driver; +static struct tty_struct * serial_tty[NUM_PORTS]; +static struct termios * serial_termios[NUM_PORTS]; +static struct termios * serial_termios_locked[NUM_PORTS]; + +static struct usb_device_descriptor dev_desc = { + bLength:USB_DT_DEVICE_SIZE, + bDescriptorType:USB_DT_DEVICE, + bcdUSB:USBDEV_REV, //usb rev + bDeviceClass:USB_CLASS_PER_INTERFACE, //class (none) + bDeviceSubClass:0x00, //subclass (none) + bDeviceProtocol:0x00, //protocol (none) + bMaxPacketSize0:USBDEV_EP0_MAX_PACKET_SIZE, //max packet size for ep0 + idVendor:0x6d04, //vendor id + idProduct:0x0bc0, //product id + bcdDevice:0x0001, //BCD rev 0.1 + iManufacturer:0x01, //manufactuer string index + iProduct:0x02, //product string index + iSerialNumber:0x03, //serial# string index + bNumConfigurations:0x01 //num configurations +}; + +static struct usb_endpoint_descriptor ep_desc[] = { + { + // Bulk IN for Port 0 + bLength:USB_DT_ENDPOINT_SIZE, + bDescriptorType:USB_DT_ENDPOINT, + bEndpointAddress:USB_DIR_IN, + bmAttributes:USB_ENDPOINT_XFER_BULK, + wMaxPacketSize:IN_MAX_PACKET_SIZE, + bInterval:0x00 // ignored for bulk + }, + { + // Bulk OUT for Port 0 + bLength:USB_DT_ENDPOINT_SIZE, + bDescriptorType:USB_DT_ENDPOINT, + bEndpointAddress:USB_DIR_OUT, + bmAttributes:USB_ENDPOINT_XFER_BULK, + wMaxPacketSize:OUT_MAX_PACKET_SIZE, + bInterval:0x00 // ignored for bulk + }, + { + // Bulk IN for Port 1 + bLength:USB_DT_ENDPOINT_SIZE, + bDescriptorType:USB_DT_ENDPOINT, + bEndpointAddress:USB_DIR_IN, + bmAttributes:USB_ENDPOINT_XFER_BULK, + wMaxPacketSize:IN_MAX_PACKET_SIZE, + bInterval:0x00 // ignored for bulk + }, + { + // Bulk OUT for Port 1 + bLength:USB_DT_ENDPOINT_SIZE, + bDescriptorType:USB_DT_ENDPOINT, + bEndpointAddress:USB_DIR_OUT, + bmAttributes:USB_ENDPOINT_XFER_BULK, + wMaxPacketSize:OUT_MAX_PACKET_SIZE, + bInterval:0x00 // ignored for bulk + } +}; + +static struct usb_interface_descriptor if_desc = { + bLength:USB_DT_INTERFACE_SIZE, + bDescriptorType:USB_DT_INTERFACE, + bInterfaceNumber:0x00, + bAlternateSetting:0x00, + bNumEndpoints:NUM_EP, + bInterfaceClass:0xff, + bInterfaceSubClass:0xab, + bInterfaceProtocol:0x00, + iInterface:0x05 +}; + +static struct usb_config_descriptor config_desc = { + bLength:USB_DT_CONFIG_SIZE, + bDescriptorType:USB_DT_CONFIG, + wTotalLength:CONFIG_DESC_LEN, + bNumInterfaces:0x01, + bConfigurationValue:0x01, + iConfiguration:0x04, // configuration string + bmAttributes:0xc0, // self-powered + MaxPower:20 // 40 mA +}; + +// String[0] is a list of Language IDs supported by this device +static struct usb_string_descriptor string_desc0 = { + bLength:4, + bDescriptorType:USB_DT_STRING, + wData:{0x0409} // English, US +}; + +// These strings will be converted to Unicode in string_desc[] +static char *strings[5] = { + "Alchemy Semiconductor", // iManufacturer + "WutzAMattaU", // iProduct + "1.0.doh!", // iSerialNumber + "Au1000 TTY Config", // iConfiguration + "Au1000 TTY Interface" // iInterface +}; + +static inline int +port_paranoia_check(struct usb_serial_port *port, const char *function) +{ + if (!port) { + err("%s: port is NULL", function); + return -1; + } + if (!port->tty) { + err("%s: port->tty is NULL", function); + return -1; + } + + return 0; +} + + +static void +port_rx_callback(struct usb_serial_port *port) +{ + dbg(__FUNCTION__ ": ep%d", port->out_ep_addr); + // mark a bh to push this data up to the tty + queue_task(&port->receive_complete_tq, &tq_immediate); + mark_bh(IMMEDIATE_BH); +} + +static void +port_tx_callback(struct usb_serial_port *port, usbdev_pkt_t* pkt) +{ + dbg(__FUNCTION__ ": ep%d", port->in_ep_addr); + // mark a bh to wakeup any tty write system call on the port. + queue_task(&port->send_complete_tq, &tq_immediate); + mark_bh(IMMEDIATE_BH); + + /* free the returned packet */ + kfree(pkt); +} + +static void +usbtty_callback(usbdev_cb_type_t cb_type, unsigned long arg, void* data) +{ + usbdev_pkt_t* pkt; + int i; + + switch (cb_type) { + case CB_NEW_STATE: + dbg(__FUNCTION__ ": new dev_state=%d", (int)arg); + usbtty.dev_state = (usbdev_state_t)arg; + break; + case CB_PKT_COMPLETE: + pkt = (usbdev_pkt_t*)arg; + for (i=0; iep_addr == port->in_ep_addr) { + port_tx_callback(port, pkt); + break; + } else if (pkt->ep_addr == port->out_ep_addr) { + port_rx_callback(port); + break; + } + } + break; + } +} + + +/***************************************************************************** + * Here begins the tty driver interface functions + *****************************************************************************/ + +static int serial_open(struct tty_struct *tty, struct file *filp) +{ + int portNumber; + struct usb_serial_port *port; + unsigned long flags; + + /* initialize the pointer incase something fails */ + tty->driver_data = NULL; + + MOD_INC_USE_COUNT; + + /* set up our port structure making the tty driver remember + our port object, and us it */ + portNumber = MINOR(tty->device); + port = &usbtty.port[portNumber]; + tty->driver_data = port; + port->tty = tty; + + if (usbtty.dev_state != CONFIGURED || + port_paranoia_check(port, __FUNCTION__)) { + /* + * the device-layer must be in the configured state before + * the function layer can operate. + */ + MOD_DEC_USE_COUNT; + return -ENODEV; + } + + dbg(__FUNCTION__ ": port %d", port->number); + + spin_lock_irqsave(&port->port_lock, flags); + + ++port->open_count; + + if (!port->active) { + port->active = 1; + + /* + * force low_latency on so that our tty_push actually forces + * the data through, otherwise it is scheduled, and with high + * data rates (like with OHCI) data can get lost. + */ + port->tty->low_latency = 1; + + } + + spin_unlock_irqrestore(&port->port_lock, flags); + + return 0; +} + + +static void serial_close(struct tty_struct *tty, struct file *filp) +{ + struct usb_serial_port *port = + (struct usb_serial_port *) tty->driver_data; + unsigned long flags; + + dbg(__FUNCTION__ ": port %d", port->number); + + if (!port->active) { + err(__FUNCTION__ ": port not opened"); + return; + } + + spin_lock_irqsave(&port->port_lock, flags); + + --port->open_count; + + if (port->open_count <= 0) { + port->active = 0; + port->open_count = 0; + } + + spin_unlock_irqrestore(&port->port_lock, flags); + MOD_DEC_USE_COUNT; +} + + +static int serial_write(struct tty_struct *tty, int from_user, + const unsigned char *buf, int count) +{ + struct usb_serial_port *port = + (struct usb_serial_port *) tty->driver_data; + usbdev_pkt_t* pkt; + int max_pkt_sz, ret; + unsigned long flags; + + /* + * the device-layer must be in the configured state before the + * function layer can operate. + */ + if (usbtty.dev_state != CONFIGURED) + return -ENODEV; + + if (!port->active) { + err(__FUNCTION__ ": port not open"); + return -EINVAL; + } + + if (count == 0) { + dbg(__FUNCTION__ ": request of 0 bytes"); + return (0); + } + +#if 0 + if (port->writing) { + dbg(__FUNCTION__ ": already writing"); + return 0; + } +#endif + + max_pkt_sz = port->in_desc->wMaxPacketSize; + count = (count > max_pkt_sz) ? max_pkt_sz : count; + + if ((ret = usbdev_alloc_packet(port->in_ep_addr, count, &pkt))) + return ret; + + if (from_user) + copy_from_user(pkt->payload, buf, count); + else + memcpy(pkt->payload, buf, count); + + ret = usbdev_send_packet(port->in_ep_addr, pkt); + + spin_lock_irqsave(&port->port_lock, flags); + port->writing = 1; + spin_unlock_irqrestore(&port->port_lock, flags); + + return ret; +} + + +static int serial_write_room(struct tty_struct *tty) +{ + struct usb_serial_port *port = + (struct usb_serial_port *) tty->driver_data; + int room = 0; + + /* + * the device-layer must be in the configured state before the + * function layer can operate. + */ + if (usbtty.dev_state != CONFIGURED) + return -ENODEV; + + if (!port->active) { + err(__FUNCTION__ ": port not open"); + return -EINVAL; + } + + //room = port->writing ? 0 : port->in_desc->wMaxPacketSize; + room = port->in_desc->wMaxPacketSize; + + dbg(__FUNCTION__ ": %d", room); + return room; +} + + +static int serial_chars_in_buffer(struct tty_struct *tty) +{ + struct usb_serial_port *port = + (struct usb_serial_port *) tty->driver_data; + int chars = 0; + + /* + * the device-layer must be in the configured state before the + * function layer can operate. + */ + if (usbtty.dev_state != CONFIGURED) + return -ENODEV; + + if (!port->active) { + err(__FUNCTION__ ": port not open"); + return -EINVAL; + } + + //chars = port->writing ? usbdev_get_byte_count(port->in_ep_addr) : 0; + chars = usbdev_get_byte_count(port->in_ep_addr); + + dbg(__FUNCTION__ ": %d", chars); + return chars; +} + + +static void serial_throttle(struct tty_struct *tty) +{ + struct usb_serial_port *port = + (struct usb_serial_port *) tty->driver_data; + + if (!port->active || usbtty.dev_state != CONFIGURED) { + err(__FUNCTION__ ": port not open"); + return; + } + + // FIXME: anything to do? + dbg(__FUNCTION__); +} + + +static void serial_unthrottle(struct tty_struct *tty) +{ + struct usb_serial_port *port = + (struct usb_serial_port *) tty->driver_data; + + if (!port->active || usbtty.dev_state != CONFIGURED) { + err(__FUNCTION__ ": port not open"); + return; + } + + // FIXME: anything to do? + dbg(__FUNCTION__); +} + + +static int serial_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct usb_serial_port *port = + (struct usb_serial_port *) tty->driver_data; + + if (!port->active) { + err(__FUNCTION__ ": port not open"); + return -ENODEV; + } + // FIXME: need any IOCTLs? + dbg(__FUNCTION__); + + return -ENOIOCTLCMD; +} + + +static void serial_set_termios(struct tty_struct *tty, struct termios *old) +{ + struct usb_serial_port *port = + (struct usb_serial_port *) tty->driver_data; + + if (!port->active || usbtty.dev_state != CONFIGURED) { + err(__FUNCTION__ ": port not open"); + return; + } + + dbg(__FUNCTION__); + // FIXME: anything to do? +} + + +static void serial_break(struct tty_struct *tty, int break_state) +{ + struct usb_serial_port *port = + (struct usb_serial_port *) tty->driver_data; + + if (!port->active || usbtty.dev_state != CONFIGURED) { + err(__FUNCTION__ ": port not open"); + return; + } + + dbg(__FUNCTION__); + // FIXME: anything to do? +} + + +static void port_send_complete(void *private) +{ + struct usb_serial_port *port = (struct usb_serial_port *) private; + struct tty_struct *tty; + unsigned long flags; + + dbg(__FUNCTION__ ": port %d, ep%d", port->number, port->in_ep_addr); + + tty = port->tty; + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) { + dbg(__FUNCTION__ ": write wakeup call."); + (tty->ldisc.write_wakeup) (tty); + } + + wake_up_interruptible(&tty->write_wait); + + spin_lock_irqsave(&port->port_lock, flags); + port->writing = usbdev_get_byte_count(port->in_ep_addr) <= 0 ? 0 : 1; + spin_unlock_irqrestore(&port->port_lock, flags); +} + + +static void port_receive_complete(void *private) +{ + struct usb_serial_port *port = (struct usb_serial_port *) private; + struct tty_struct *tty = port->tty; + usbdev_pkt_t* pkt = NULL; + int i, count; + + /* while there is a packet available */ + while ((count = usbdev_receive_packet(port->out_ep_addr, + &pkt)) != -ENODATA) { + if (count < 0) { + if (pkt) + kfree(pkt); + break; /* exit if error other than ENODATA */ + } + + dbg(__FUNCTION__ ": port %d, ep%d, size=%d", + port->number, port->out_ep_addr, count); + + for (i = 0; i < count; i++) { + /* if we insert more than TTY_FLIPBUF_SIZE characters, + we drop them. */ + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + tty_flip_buffer_push(tty); + } + /* this doesn't actually push the data through + unless tty->low_latency is set */ + tty_insert_flip_char(tty, pkt->payload[i], 0); + } + tty_flip_buffer_push(tty); + + kfree(pkt); /* make sure we free the packet */ + } + +} + + +static struct tty_driver serial_tty_driver = { + magic:TTY_DRIVER_MAGIC, + driver_name:"usbfn-tty", + name:"usb/ttsdev/%d", + major:SERIAL_TTY_MAJOR, + minor_start:0, + num:NUM_PORTS, + type:TTY_DRIVER_TYPE_SERIAL, + subtype:SERIAL_TYPE_NORMAL, + flags:TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS, + refcount:&serial_refcount, + table:serial_tty, + termios:serial_termios, + termios_locked:serial_termios_locked, + + open:serial_open, + close:serial_close, + write:serial_write, + write_room:serial_write_room, + ioctl:serial_ioctl, + set_termios:serial_set_termios, + throttle:serial_throttle, + unthrottle:serial_unthrottle, + break_ctl:serial_break, + chars_in_buffer:serial_chars_in_buffer, +}; + + +void usbfn_tty_exit(void) +{ + int i; + + /* kill the device layer */ + usbdev_exit(); + + for (i=0; i < NUM_PORTS; i++) { + tty_unregister_devfs(&serial_tty_driver, i); + info("usb serial converter now disconnected from ttyUSBdev%d", + i); + } + + tty_unregister_driver(&serial_tty_driver); + + if (usbtty.str_desc_buf) + kfree(usbtty.str_desc_buf); +} + + +int usbfn_tty_init(void) +{ + int ret = 0, i, str_desc_len; + + /* register the tty driver */ + serial_tty_driver.init_termios = tty_std_termios; + serial_tty_driver.init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + + if (tty_register_driver(&serial_tty_driver)) { + err(__FUNCTION__ ": failed to register tty driver"); + ret = -ENXIO; + goto out; + } + + /* + * initialize pointers to descriptors + */ + usbtty.dev_desc = &dev_desc; + usbtty.config_desc = &config_desc; + usbtty.if_desc = &if_desc; + + /* + * initialize the string descriptors + */ + + /* alloc buffer big enough for all string descriptors */ + str_desc_len = string_desc0.bLength; + for (i = 0; i < 5; i++) + str_desc_len += 2 + 2 * strlen(strings[i]); + usbtty.str_desc_buf = (void *) kmalloc(str_desc_len, GFP_KERNEL); + if (!usbtty.str_desc_buf) { + err(__FUNCTION__ ": failed to alloc string descriptors"); + ret = -ENOMEM; + goto out; + } + + usbtty.str_desc[0] = + (struct usb_string_descriptor *)usbtty.str_desc_buf; + memcpy(usbtty.str_desc[0], &string_desc0, string_desc0.bLength); + usbtty.str_desc[1] = (struct usb_string_descriptor *) + (usbtty.str_desc_buf + string_desc0.bLength); + for (i = 1; i < 6; i++) { + struct usb_string_descriptor *desc = usbtty.str_desc[i]; + char *str = strings[i - 1]; + int j, str_len = strlen(str); + + desc->bLength = 2 + 2 * str_len; + desc->bDescriptorType = USB_DT_STRING; + for (j = 0; j < str_len; j++) { + desc->wData[j] = (u16) str[j]; + } + if (i < 5) + usbtty.str_desc[i + 1] = + (struct usb_string_descriptor *) + ((u8 *) desc + desc->bLength); + } + + /* + * start the device layer. The device layer assigns us + * our endpoint addresses + */ + if ((ret = usbdev_init(&dev_desc, &config_desc, &if_desc, ep_desc, + usbtty.str_desc, usbtty_callback, NULL))) { + err(__FUNCTION__ ": device-layer init failed"); + goto out; + } + + /* initialize the devfs nodes for this device and let the user + know what ports we are bound to */ + for (i = 0; i < NUM_PORTS; ++i) { + struct usb_serial_port *port; + tty_register_devfs(&serial_tty_driver, 0, i); + info("usbdev serial attached to ttyUSBdev%d " + "(or devfs usb/ttsdev/%d)", i, i); + port = &usbtty.port[i]; + port->number = i; + port->in_desc = &ep_desc[NUM_PORTS*i]; + port->out_desc = &ep_desc[NUM_PORTS*i + 1]; + port->in_ep_addr = port->in_desc->bEndpointAddress & 0x0f; + port->out_ep_addr = port->out_desc->bEndpointAddress & 0x0f; + port->send_complete_tq.routine = port_send_complete; + port->send_complete_tq.data = port; + port->receive_complete_tq.routine = port_receive_complete; + port->receive_complete_tq.data = port; + spin_lock_init(&port->port_lock); + } + + out: + if (ret) + usbfn_tty_exit(); + return ret; +} + + +/* Module information */ +MODULE_AUTHOR("Steve Longerbeam, stevel@mvista.com, www.mvista.com"); +MODULE_DESCRIPTION("Au1x00 USB Device-Side Serial TTY Driver"); +MODULE_LICENSE("GPL"); + +module_init(usbfn_tty_init); +module_exit(usbfn_tty_exit); diff -urN linux-2.4.21-bk37/drivers/char/au1x00-serial.c linux-2.4.21-bk38/drivers/char/au1x00-serial.c --- linux-2.4.21-bk37/drivers/char/au1x00-serial.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/drivers/char/au1x00-serial.c 2003-08-24 02:56:03.000000000 -0700 @@ -0,0 +1,3098 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Au1x00 serial port driver. + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * Derived almost entirely from drivers/char/serial.c: + * + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, + * 1998, 1999 Theodore Ts'o + * + * 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. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +static char *serial_version = "1.01"; +static char *serial_revdate = "2001-02-08"; + + +#include +#include + +#undef SERIAL_PARANOIA_CHECK +#define CONFIG_SERIAL_NOPAUSE_IO +#define SERIAL_DO_RESTART + + +/* Set of debugging defines */ + +#undef SERIAL_DEBUG_INTR +#undef SERIAL_DEBUG_OPEN +#undef SERIAL_DEBUG_FLOW +#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT +#undef SERIAL_DEBUG_PCI +#undef SERIAL_DEBUG_AUTOCONF + +#ifdef MODULE +#undef CONFIG_AU1X00_SERIAL_CONSOLE +#endif + +#define CONFIG_SERIAL_RSA + +#define RS_STROBE_TIME (10*HZ) +#define RS_ISR_PASS_LIMIT 256 + +/* + * End of serial driver configuration section. + */ + +#include + +#include +#ifdef LOCAL_HEADERS +#include "serial_local.h" +#else +#include +#include +#include +#include +#define LOCAL_VERSTRING "" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_AU1X00_SERIAL_CONSOLE +#include +#endif +#ifdef CONFIG_MAGIC_SYSRQ +#include +#endif + +#include +#include +#include +#include + +#ifdef CONFIG_MAC_SERIAL +#define SERIAL_DEV_OFFSET 2 +#else +#define SERIAL_DEV_OFFSET 0 +#endif + +#ifdef SERIAL_INLINE +#define _INLINE_ inline +#else +#define _INLINE_ +#endif + +static char *serial_name = "Serial driver"; + +static DECLARE_TASK_QUEUE(tq_serial); + +static struct tty_driver serial_driver, callout_driver; +static int serial_refcount; + +static struct timer_list serial_timer; + +extern unsigned long get_au1x00_uart_baud_base(void); + +/* serial subtype definitions */ +#ifndef SERIAL_TYPE_NORMAL +#define SERIAL_TYPE_NORMAL 1 +#define SERIAL_TYPE_CALLOUT 2 +#endif + +/* number of characters left in xmit buffer before we ask for more */ +#define WAKEUP_CHARS 256 + +/* + * IRQ_timeout - How long the timeout should be for each IRQ + * should be after the IRQ has been active. + */ + +static struct async_struct *IRQ_ports[NR_IRQS]; +static int IRQ_timeout[NR_IRQS]; +#ifdef CONFIG_AU1X00_SERIAL_CONSOLE +static struct console sercons; +static int lsr_break_flag; +#endif +#if defined(CONFIG_AU1X00_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +static unsigned long break_pressed; /* break, really ... */ +#endif + +static void autoconfig(struct serial_state * state); +static void change_speed(struct async_struct *info, struct termios *old); +static void rs_wait_until_sent(struct tty_struct *tty, int timeout); + +/* + * Here we define the default xmit fifo size used for each type of + * UART + */ +static struct serial_uart_config uart_config[] = { + { "unknown", 1, 0 }, + { "8250", 1, 0 }, + { "16450", 1, 0 }, + { "16550", 1, 0 }, + { 0, 0} +}; + + +static struct serial_state rs_table[RS_TABLE_SIZE] = { + SERIAL_PORT_DFNS /* Defined in serial.h */ +}; + +#define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state)) + +#ifndef PREPARE_FUNC +#define PREPARE_FUNC(dev) (dev->prepare) +#define ACTIVATE_FUNC(dev) (dev->activate) +#define DEACTIVATE_FUNC(dev) (dev->deactivate) +#endif + +#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) + +static struct tty_struct *serial_table[NR_PORTS]; +static struct termios *serial_termios[NR_PORTS]; +static struct termios *serial_termios_locked[NR_PORTS]; + + +#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) +#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \ + kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s) +#else +#define DBG_CNT(s) +#endif + +/* + * tmp_buf is used as a temporary buffer by serial_write. We need to + * lock it in case the copy_from_user blocks while swapping in a page, + * and some other program tries to do a serial write at the same time. + * Since the lock will only come under contention when the system is + * swapping and available memory is low, it makes sense to share one + * buffer across all the serial ports, since it significantly saves + * memory if large numbers of serial ports are open. + */ +static unsigned char *tmp_buf; +#ifdef DECLARE_MUTEX +static DECLARE_MUTEX(tmp_buf_sem); +#else +static struct semaphore tmp_buf_sem = MUTEX; +#endif + +static spinlock_t serial_lock = SPIN_LOCK_UNLOCKED; + +static inline int serial_paranoia_check(struct async_struct *info, + kdev_t device, const char *routine) +{ +#ifdef SERIAL_PARANOIA_CHECK + static const char *badmagic = + "Warning: bad magic number for serial struct (%s) in %s\n"; + static const char *badinfo = + "Warning: null async_struct for (%s) in %s\n"; + + if (!info) { + printk(badinfo, kdevname(device), routine); + return 1; + } + if (info->magic != SERIAL_MAGIC) { + printk(badmagic, kdevname(device), routine); + return 1; + } +#endif + return 0; +} + +static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset) +{ + return (au_readl(info->port+offset) & 0xffff); +} + +static _INLINE_ void serial_out(struct async_struct *info, int offset, int value) +{ + au_writel(value & 0xffff, info->port+offset); +} + + +/* + * We used to support using pause I/O for certain machines. We + * haven't supported this for a while, but just in case it's badly + * needed for certain old 386 machines, I've left these #define's + * in.... + */ +#define serial_inp(info, offset) serial_in(info, offset) +#define serial_outp(info, offset, value) serial_out(info, offset, value) + + +/* + * ------------------------------------------------------------ + * rs_stop() and rs_start() + * + * This routines are called before setting or resetting tty->stopped. + * They enable or disable transmitter interrupts, as necessary. + * ------------------------------------------------------------ + */ +static void rs_stop(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_stop")) + return; + + spin_lock_irqsave(&serial_lock, flags); + if (info->IER & UART_IER_THRI) { + info->IER &= ~UART_IER_THRI; + serial_out(info, UART_IER, info->IER); + } + spin_unlock_irqrestore(&serial_lock, flags); +} + +static void rs_start(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_start")) + return; + + spin_lock_irqsave(&serial_lock, flags); + if (info->xmit.head != info->xmit.tail + && info->xmit.buf + && !(info->IER & UART_IER_THRI)) { + info->IER |= UART_IER_THRI; + serial_out(info, UART_IER, info->IER); + } + spin_unlock_irqrestore(&serial_lock, flags); +} + +/* + * ---------------------------------------------------------------------- + * + * Here starts the interrupt handling routines. All of the following + * subroutines are declared as inline and are folded into + * rs_interrupt(). They were separated out for readability's sake. + * + * Note: rs_interrupt() is a "fast" interrupt, which means that it + * runs with interrupts turned off. People who may want to modify + * rs_interrupt() should try to keep the interrupt handler as fast as + * possible. After you are done making modifications, it is not a bad + * idea to do: + * + * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c + * + * and look at the resulting assemble code in serial.s. + * + * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 + * ----------------------------------------------------------------------- + */ + +/* + * This routine is used by the interrupt handler to schedule + * processing in the software interrupt portion of the driver. + */ +static _INLINE_ void rs_sched_event(struct async_struct *info, + int event) +{ + info->event |= 1 << event; + queue_task(&info->tqueue, &tq_serial); + mark_bh(SERIAL_BH); +} + +static _INLINE_ void receive_chars(struct async_struct *info, + int *status, struct pt_regs * regs) +{ + struct tty_struct *tty = info->tty; + unsigned char ch; + int ignored = 0; + struct async_icount *icount; + + icount = &info->state->icount; + do { + ch = serial_inp(info, UART_RX); + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + goto ignore_char; + *tty->flip.char_buf_ptr = ch; + icount->rx++; + +#ifdef SERIAL_DEBUG_INTR + printk("DR%02x:%02x...", ch, *status); +#endif + *tty->flip.flag_buf_ptr = 0; + if (*status & (UART_LSR_BI | UART_LSR_PE | + UART_LSR_FE | UART_LSR_OE)) { + /* + * For statistics only + */ + if (*status & UART_LSR_BI) { + *status &= ~(UART_LSR_FE | UART_LSR_PE); + icount->brk++; + /* + * We do the SysRQ and SAK checking + * here because otherwise the break + * may get masked by ignore_status_mask + * or read_status_mask. + */ +#if defined(CONFIG_AU1X00_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) + if (info->line == sercons.index) { + if (!break_pressed) { + break_pressed = jiffies; + goto ignore_char; + } + break_pressed = 0; + } +#endif + if (info->flags & ASYNC_SAK) + do_SAK(tty); + } else if (*status & UART_LSR_PE) + icount->parity++; + else if (*status & UART_LSR_FE) + icount->frame++; + if (*status & UART_LSR_OE) + icount->overrun++; + + /* + * Now check to see if character should be + * ignored, and mask off conditions which + * should be ignored. + */ + if (*status & info->ignore_status_mask) { + if (++ignored > 100) + break; + goto ignore_char; + } + *status &= info->read_status_mask; + +#ifdef CONFIG_AU1X00_SERIAL_CONSOLE + if (info->line == sercons.index) { + /* Recover the break flag from console xmit */ + *status |= lsr_break_flag; + lsr_break_flag = 0; + } +#endif + if (*status & (UART_LSR_BI)) { +#ifdef SERIAL_DEBUG_INTR + printk("handling break...."); +#endif + *tty->flip.flag_buf_ptr = TTY_BREAK; + } else if (*status & UART_LSR_PE) + *tty->flip.flag_buf_ptr = TTY_PARITY; + else if (*status & UART_LSR_FE) + *tty->flip.flag_buf_ptr = TTY_FRAME; + if (*status & UART_LSR_OE) { + /* + * Overrun is special, since it's + * reported immediately, and doesn't + * affect the current character + */ + tty->flip.count++; + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + *tty->flip.flag_buf_ptr = TTY_OVERRUN; + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + goto ignore_char; + } + } +#if defined(CONFIG_AU1X00_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) + if (break_pressed && info->line == sercons.index) { + if (ch != 0 && + time_before(jiffies, break_pressed + HZ*5)) { + handle_sysrq(ch, regs, NULL, NULL); + break_pressed = 0; + goto ignore_char; + } + break_pressed = 0; + } +#endif + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + tty->flip.count++; + ignore_char: + *status = serial_inp(info, UART_LSR); + } while (*status & UART_LSR_DR); + tty_flip_buffer_push(tty); +} + +static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) +{ + int count; + + if (info->x_char) { + serial_outp(info, UART_TX, info->x_char); + info->state->icount.tx++; + info->x_char = 0; + if (intr_done) + *intr_done = 0; + return; + } + if (info->xmit.head == info->xmit.tail + || info->tty->stopped + || info->tty->hw_stopped) { + info->IER &= ~UART_IER_THRI; + serial_out(info, UART_IER, info->IER); + return; + } + + count = info->xmit_fifo_size; + do { + serial_out(info, UART_TX, info->xmit.buf[info->xmit.tail]); + info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1); + info->state->icount.tx++; + if (info->xmit.head == info->xmit.tail) + break; + } while (--count > 0); + + if (CIRC_CNT(info->xmit.head, + info->xmit.tail, + SERIAL_XMIT_SIZE) < WAKEUP_CHARS) + rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); + +#ifdef SERIAL_DEBUG_INTR + printk("THRE..."); +#endif + if (intr_done) + *intr_done = 0; + + if (info->xmit.head == info->xmit.tail) { + info->IER &= ~UART_IER_THRI; + serial_out(info, UART_IER, info->IER); + } +} + +static _INLINE_ void check_modem_status(struct async_struct *info) +{ + int status; + struct async_icount *icount; + + status = serial_in(info, UART_MSR); + + if (status & UART_MSR_ANY_DELTA) { + icount = &info->state->icount; + /* update input line counters */ + if (status & UART_MSR_TERI) + icount->rng++; + if (status & UART_MSR_DDSR) + icount->dsr++; + if (status & UART_MSR_DDCD) { + icount->dcd++; +#ifdef CONFIG_HARD_PPS + if ((info->flags & ASYNC_HARDPPS_CD) && + (status & UART_MSR_DCD)) + hardpps(); +#endif + } + if (status & UART_MSR_DCTS) + icount->cts++; + wake_up_interruptible(&info->delta_msr_wait); + } + + if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { +#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) + printk("ttys%d CD now %s...", info->line, + (status & UART_MSR_DCD) ? "on" : "off"); +#endif + if (status & UART_MSR_DCD) + wake_up_interruptible(&info->open_wait); + else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) && + (info->flags & ASYNC_CALLOUT_NOHUP))) { +#ifdef SERIAL_DEBUG_OPEN + printk("doing serial hangup..."); +#endif + if (info->tty) + tty_hangup(info->tty); + } + } + if (info->flags & ASYNC_CTS_FLOW) { + if (info->tty->hw_stopped) { + if (status & UART_MSR_CTS) { +#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) + printk("CTS tx start..."); +#endif + info->tty->hw_stopped = 0; + info->IER |= UART_IER_THRI; + serial_out(info, UART_IER, info->IER); + rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); + return; + } + } else { + if (!(status & UART_MSR_CTS)) { +#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) + printk("CTS tx stop..."); +#endif + info->tty->hw_stopped = 1; + info->IER &= ~UART_IER_THRI; + serial_out(info, UART_IER, info->IER); + } + } + } +} + + + +/* + * This is the serial driver's interrupt routine for a single port + */ +static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs) +{ + int status; + int pass_counter = 0; + struct async_struct * info; + +#ifdef SERIAL_DEBUG_INTR + printk("rs_interrupt_single(%d)...", irq); +#endif + + info = IRQ_ports[irq]; + if (!info || !info->tty) + return; + + do { + status = serial_inp(info, UART_LSR); +#ifdef SERIAL_DEBUG_INTR + printk("status = %x...", status); +#endif + if (status & UART_LSR_DR) + receive_chars(info, &status, regs); + check_modem_status(info); + if (status & UART_LSR_THRE) + transmit_chars(info, 0); + if (pass_counter++ > RS_ISR_PASS_LIMIT) { +#if 0 + printk("rs_single loop break.\n"); +#endif + break; + } + } while (!(serial_in(info, UART_IIR) & UART_IIR_NO_INT)); + info->last_active = jiffies; +#ifdef SERIAL_DEBUG_INTR + printk("end.\n"); +#endif +} + + +/* + * ------------------------------------------------------------------- + * Here ends the serial interrupt routines. + * ------------------------------------------------------------------- + */ + +/* + * This routine is used to handle the "bottom half" processing for the + * serial driver, known also the "software interrupt" processing. + * This processing is done at the kernel interrupt level, after the + * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This + * is where time-consuming activities which can not be done in the + * interrupt driver proper are done; the interrupt driver schedules + * them using rs_sched_event(), and they get done here. + */ +static void do_serial_bh(void) +{ + run_task_queue(&tq_serial); +} + +static void do_softint(void *private_) +{ + struct async_struct *info = (struct async_struct *) private_; + struct tty_struct *tty; + + tty = info->tty; + if (!tty) + return; + + if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); + wake_up_interruptible(&tty->write_wait); +#ifdef SERIAL_HAVE_POLL_WAIT + wake_up_interruptible(&tty->poll_wait); +#endif + } +} + +/* + * This subroutine is called when the RS_TIMER goes off. It is used + * by the serial driver to handle ports that do not have an interrupt + * (irq=0). This doesn't work very well for 16450's, but gives barely + * passable results for a 16550A. (Although at the expense of much + * CPU overhead). + */ +static void rs_timer(unsigned long dummy) +{ + static unsigned long last_strobe; + struct async_struct *info; + unsigned int i; + unsigned long flags; + + if ((jiffies - last_strobe) >= RS_STROBE_TIME) { + for (i=0; i < NR_IRQS; i++) { + info = IRQ_ports[i]; + if (!info) + continue; + spin_lock_irqsave(&serial_lock, flags); + rs_interrupt_single(i, NULL, NULL); + spin_unlock_irqrestore(&serial_lock, flags); + } + } + last_strobe = jiffies; + mod_timer(&serial_timer, jiffies + RS_STROBE_TIME); + +#if 0 + if (IRQ_ports[0]) { + spin_lock_irqsave(&serial_lock, flags); + rs_interrupt_single(0, NULL, NULL); + spin_unlock_irqrestore(&serial_lock, flags); + + mod_timer(&serial_timer, jiffies + IRQ_timeout[0]); + } +#endif +} + +/* + * --------------------------------------------------------------- + * Low level utility subroutines for the serial driver: routines to + * figure out the appropriate timeout for an interrupt chain, routines + * to initialize and startup a serial port, and routines to shutdown a + * serial port. Useful stuff like that. + * --------------------------------------------------------------- + */ + +/* + * This routine figures out the correct timeout for a particular IRQ. + * It uses the smallest timeout of all of the serial ports in a + * particular interrupt chain. Now only used for IRQ 0.... + */ +static void figure_IRQ_timeout(int irq) +{ + struct async_struct *info; + int timeout = 60*HZ; /* 60 seconds === a long time :-) */ + + info = IRQ_ports[irq]; + if (!info) { + IRQ_timeout[irq] = 60*HZ; + return; + } + while (info) { + if (info->timeout < timeout) + timeout = info->timeout; + info = info->next_port; + } + if (!irq) + timeout = timeout / 2; + IRQ_timeout[irq] = (timeout > 3) ? timeout-2 : 1; +} + + +static int startup(struct async_struct * info) +{ + unsigned long flags; + int retval=0; + void (*handler)(int, void *, struct pt_regs *); + struct serial_state *state= info->state; + unsigned long page; + + page = get_zeroed_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + + spin_lock_irqsave(&serial_lock, flags); + + if (info->flags & ASYNC_INITIALIZED) { + free_page(page); + goto errout; + } + + if (!CONFIGURED_SERIAL_PORT(state) || !state->type) { + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + free_page(page); + goto errout; + } + if (info->xmit.buf) + free_page(page); + else + info->xmit.buf = (unsigned char *) page; + + + if (au_readl(UART_MOD_CNTRL + state->port) != 0x3) { + au_writel(3, UART_MOD_CNTRL + state->port); + au_sync_delay(10); + } +#ifdef SERIAL_DEBUG_OPEN + printk("starting up ttys%d (irq %d)...", info->line, state->irq); +#endif + + + /* + * Clear the FIFO buffers and disable them + * (they will be reenabled in change_speed()) + */ + if (uart_config[state->type].flags & UART_CLEAR_FIFO) { + serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO); + serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | + UART_FCR_CLEAR_XMIT)); + serial_outp(info, UART_FCR, 0); + } + + /* + * Clear the interrupt registers. + */ + (void) serial_inp(info, UART_LSR); + (void) serial_inp(info, UART_RX); + (void) serial_inp(info, UART_IIR); + (void) serial_inp(info, UART_MSR); + + /* + * At this point there's no way the LSR could still be 0xFF; + * if it is, then bail out, because there's likely no UART + * here. + */ + if (!(info->flags & ASYNC_BUGGY_UART) && + (serial_inp(info, UART_LSR) == 0xff)) { + printk("LSR safety check engaged!\n"); + if (capable(CAP_SYS_ADMIN)) { + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + } else + retval = -ENODEV; + goto errout; + } + + /* + * Allocate the IRQ if necessary + */ +#if 0 + /* au1000, uart0 irq is 0 */ + if (state->irq && (!IRQ_ports[state->irq] || !IRQ_ports[state->irq]->next_port)) { +#endif + if ((!IRQ_ports[state->irq] || !IRQ_ports[state->irq]->next_port)) { + if (IRQ_ports[state->irq]) { + retval = -EBUSY; + goto errout; + } else + handler = rs_interrupt_single; + + retval = request_irq(state->irq, handler, SA_SHIRQ, + "serial", &IRQ_ports[state->irq]); + if (retval) { + if (capable(CAP_SYS_ADMIN)) { + if (info->tty) + set_bit(TTY_IO_ERROR, + &info->tty->flags); + retval = 0; + } + goto errout; + } + } + + /* + * Insert serial port into IRQ chain. + */ + info->prev_port = 0; + info->next_port = IRQ_ports[state->irq]; + if (info->next_port) + info->next_port->prev_port = info; + IRQ_ports[state->irq] = info; + figure_IRQ_timeout(state->irq); + + /* + * Now, initialize the UART + */ + serial_outp(info, UART_LCR, UART_LCR_WLEN8); + + info->MCR = 0; + if (info->tty->termios->c_cflag & CBAUD) + info->MCR = UART_MCR_DTR | UART_MCR_RTS; + { + if (state->irq != 0) + info->MCR |= UART_MCR_OUT2; + } + info->MCR |= ALPHA_KLUDGE_MCR; /* Don't ask */ + serial_outp(info, UART_MCR, info->MCR); + + /* + * Finally, enable interrupts + */ + info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI; + serial_outp(info, UART_IER, info->IER); /* enable interrupts */ + + + /* + * And clear the interrupt registers again for luck. + */ + (void)serial_inp(info, UART_LSR); + (void)serial_inp(info, UART_RX); + (void)serial_inp(info, UART_IIR); + (void)serial_inp(info, UART_MSR); + + if (info->tty) + clear_bit(TTY_IO_ERROR, &info->tty->flags); + info->xmit.head = info->xmit.tail = 0; + + /* + * Set up serial timers... + */ + mod_timer(&serial_timer, jiffies + 2*HZ/100); + + /* + * Set up the tty->alt_speed kludge + */ + if (info->tty) { + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + info->tty->alt_speed = 57600; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + info->tty->alt_speed = 115200; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + info->tty->alt_speed = 230400; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + info->tty->alt_speed = 460800; + } + + /* + * and set the speed of the serial port + */ + change_speed(info, 0); + + info->flags |= ASYNC_INITIALIZED; + spin_unlock_irqrestore(&serial_lock, flags); + return 0; + +errout: + spin_unlock_irqrestore(&serial_lock, flags); + return retval; +} + +/* + * This routine will shutdown a serial port; interrupts are disabled, and + * DTR is dropped if the hangup on close termio flag is on. + */ +static void shutdown(struct async_struct * info) +{ + unsigned long flags; + struct serial_state *state; + int retval; + + if (!(info->flags & ASYNC_INITIALIZED)) + return; + + state = info->state; + +#ifdef SERIAL_DEBUG_OPEN + printk("Shutting down serial port %d (irq %d)....", info->line, + state->irq); +#endif + + spin_lock_irqsave(&serial_lock, flags); + + /* + * clear delta_msr_wait queue to avoid mem leaks: we may free the irq + * here so the queue might never be waken up + */ + wake_up_interruptible(&info->delta_msr_wait); + + /* + * First unlink the serial port from the IRQ chain... + */ + if (info->next_port) + info->next_port->prev_port = info->prev_port; + if (info->prev_port) + info->prev_port->next_port = info->next_port; + else + IRQ_ports[state->irq] = info->next_port; + figure_IRQ_timeout(state->irq); + + /* + * Free the IRQ, if necessary + */ +// if (state->irq && (!IRQ_ports[state->irq] || + if ((!IRQ_ports[state->irq] || + !IRQ_ports[state->irq]->next_port)) { + if (IRQ_ports[state->irq]) { + free_irq(state->irq, &IRQ_ports[state->irq]); + retval = request_irq(state->irq, rs_interrupt_single, + SA_SHIRQ, "serial", + &IRQ_ports[state->irq]); + + if (retval) + printk("serial shutdown: request_irq: error %d" + " Couldn't reacquire IRQ.\n", retval); + } else + free_irq(state->irq, &IRQ_ports[state->irq]); + } + + if (info->xmit.buf) { + unsigned long pg = (unsigned long) info->xmit.buf; + info->xmit.buf = 0; + free_page(pg); + } + + info->IER = 0; + serial_outp(info, UART_IER, 0x00); /* disable all intrs */ + info->MCR &= ~UART_MCR_OUT2; + info->MCR |= ALPHA_KLUDGE_MCR; /* Don't ask */ + + /* disable break condition */ + serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC); + + if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) + info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); + serial_outp(info, UART_MCR, info->MCR); + + /* disable FIFO's */ + serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | + UART_FCR_CLEAR_XMIT)); + serial_outp(info, UART_FCR, 0); + + (void)serial_in(info, UART_RX); /* read data port to reset things */ + + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + + info->flags &= ~ASYNC_INITIALIZED; +#ifndef CONFIG_KGDB + au_writel(0, UART_MOD_CNTRL + state->port); + au_sync_delay(10); +#endif + spin_unlock_irqrestore(&serial_lock, flags); +} + + +/* + * This routine is called to set the UART divisor registers to match + * the specified baud rate for a serial port. + */ +static void change_speed(struct async_struct *info, + struct termios *old_termios) +{ + int quot = 0, baud_base, baud; + unsigned cflag, cval, fcr = 0; + int bits; + unsigned long flags; + + if (!info->tty || !info->tty->termios) + return; + cflag = info->tty->termios->c_cflag; + if (!CONFIGURED_SERIAL_PORT(info)) + return; + + /* byte size and parity */ + switch (cflag & CSIZE) { + case CS5: cval = 0x00; bits = 7; break; + case CS6: cval = 0x01; bits = 8; break; + case CS7: cval = 0x02; bits = 9; break; + case CS8: cval = 0x03; bits = 10; break; + /* Never happens, but GCC is too dumb to figure it out */ + default: cval = 0x00; bits = 7; break; + } + if (cflag & CSTOPB) { + cval |= 0x04; + bits++; + } + if (cflag & PARENB) { + cval |= UART_LCR_PARITY; + bits++; + } + if (!(cflag & PARODD)) + cval |= UART_LCR_EPAR; +#ifdef CMSPAR + if (cflag & CMSPAR) + cval |= UART_LCR_SPAR; +#endif + + /* Determine divisor based on baud rate */ + baud = tty_get_baud_rate(info->tty); + if (!baud) { + baud = 9600; /* B0 transition handled in rs_set_termios */ + } + baud_base = get_au1x00_uart_baud_base(); + + //if (baud == 38400 && + if (((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) { + quot = info->state->custom_divisor; + } + else { + if (baud == 134) + /* Special case since 134 is really 134.5 */ + quot = (2*baud_base / 269); + else if (baud) + quot = baud_base / baud; + } + /* If the quotient is zero refuse the change */ + if (!quot && old_termios) { + info->tty->termios->c_cflag &= ~CBAUD; + info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD); + baud = tty_get_baud_rate(info->tty); + if (!baud) + baud = 9600; + if (baud == 38400 && + ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) + quot = info->state->custom_divisor; + else { + if (baud == 134) + /* Special case since 134 is really 134.5 */ + quot = (2*baud_base / 269); + else if (baud) + quot = baud_base / baud; + } + } + /* As a last resort, if the quotient is zero, default to 9600 bps */ + if (!quot) + quot = baud_base / 9600; + + info->quot = quot; + info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base); + info->timeout += HZ/50; /* Add .02 seconds of slop */ + + /* Set up FIFO's */ + if (uart_config[info->state->type].flags & UART_USE_FIFO) { + if ((info->state->baud_base / quot) < 2400) + fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIGGER_1; + else + fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIGGER_8; + } + + /* CTS flow control flag and modem status interrupts */ + info->IER &= ~UART_IER_MSI; + if (info->flags & ASYNC_HARDPPS_CD) + info->IER |= UART_IER_MSI; + if (cflag & CRTSCTS) { + info->flags |= ASYNC_CTS_FLOW; + info->IER |= UART_IER_MSI; + } else + info->flags &= ~ASYNC_CTS_FLOW; + if (cflag & CLOCAL) + info->flags &= ~ASYNC_CHECK_CD; + else { + info->flags |= ASYNC_CHECK_CD; + info->IER |= UART_IER_MSI; + } + serial_out(info, UART_IER, info->IER); + + /* + * Set up parity check flag + */ +#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) + + info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; + if (I_INPCK(info->tty)) + info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; + if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) + info->read_status_mask |= UART_LSR_BI; + + /* + * Characters to ignore + */ + info->ignore_status_mask = 0; + if (I_IGNPAR(info->tty)) + info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; + if (I_IGNBRK(info->tty)) { + info->ignore_status_mask |= UART_LSR_BI; + /* + * If we're ignore parity and break indicators, ignore + * overruns too. (For real raw support). + */ + if (I_IGNPAR(info->tty)) + info->ignore_status_mask |= UART_LSR_OE; + } + /* + * !!! ignore all characters if CREAD is not set + */ + if ((cflag & CREAD) == 0) + info->ignore_status_mask |= UART_LSR_DR; + spin_lock_irqsave(&serial_lock, flags); + + serial_outp(info, UART_CLK, quot & 0xffff); + serial_outp(info, UART_LCR, cval); + info->LCR = cval; /* Save LCR */ + spin_unlock_irqrestore(&serial_lock, flags); +} + +static void rs_put_char(struct tty_struct *tty, unsigned char ch) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_put_char")) + return; + + if (!tty || !info->xmit.buf) + return; + + spin_lock_irqsave(&serial_lock, flags); + if (CIRC_SPACE(info->xmit.head, + info->xmit.tail, + SERIAL_XMIT_SIZE) == 0) { + spin_unlock_irqrestore(&serial_lock, flags); + return; + } + + info->xmit.buf[info->xmit.head] = ch; + info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1); + spin_unlock_irqrestore(&serial_lock, flags); +} + +static void rs_flush_chars(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_flush_chars")) + return; + + if (info->xmit.head == info->xmit.tail + || tty->stopped + || tty->hw_stopped + || !info->xmit.buf) + return; + + spin_lock_irqsave(&serial_lock, flags); + info->IER |= UART_IER_THRI; + serial_out(info, UART_IER, info->IER); + spin_unlock_irqrestore(&serial_lock, flags); +} + +static int rs_write(struct tty_struct * tty, int from_user, + const unsigned char *buf, int count) +{ + int c, ret = 0; + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_write")) + return 0; + + if (!tty || !info->xmit.buf || !tmp_buf) + return 0; + + spin_lock_irqsave(&serial_lock, flags); + if (from_user) { + down(&tmp_buf_sem); + while (1) { + int c1; + c = CIRC_SPACE_TO_END(info->xmit.head, + info->xmit.tail, + SERIAL_XMIT_SIZE); + if (count < c) + c = count; + if (c <= 0) + break; + + c -= copy_from_user(tmp_buf, buf, c); + if (!c) { + if (!ret) + ret = -EFAULT; + break; + } + cli(); + c1 = CIRC_SPACE_TO_END(info->xmit.head, + info->xmit.tail, + SERIAL_XMIT_SIZE); + if (c1 < c) + c = c1; + memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c); + info->xmit.head = ((info->xmit.head + c) & + (SERIAL_XMIT_SIZE-1)); + spin_unlock_irqrestore(&serial_lock, flags); + buf += c; + count -= c; + ret += c; + } + up(&tmp_buf_sem); + } else { + cli(); + while (1) { + c = CIRC_SPACE_TO_END(info->xmit.head, + info->xmit.tail, + SERIAL_XMIT_SIZE); + if (count < c) + c = count; + if (c <= 0) { + break; + } + memcpy(info->xmit.buf + info->xmit.head, buf, c); + info->xmit.head = ((info->xmit.head + c) & + (SERIAL_XMIT_SIZE-1)); + buf += c; + count -= c; + ret += c; + } + spin_unlock_irqrestore(&serial_lock, flags); + } + if (info->xmit.head != info->xmit.tail + && !tty->stopped + && !tty->hw_stopped + && !(info->IER & UART_IER_THRI)) { + info->IER |= UART_IER_THRI; + serial_out(info, UART_IER, info->IER); + } + return ret; +} + +static int rs_write_room(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + + if (serial_paranoia_check(info, tty->device, "rs_write_room")) + return 0; + return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); +} + +static int rs_chars_in_buffer(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + + if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer")) + return 0; + return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); +} + +static void rs_flush_buffer(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_flush_buffer")) + return; + spin_lock_irqsave(&serial_lock, flags); + info->xmit.head = info->xmit.tail = 0; + spin_unlock_irqrestore(&serial_lock, flags); + wake_up_interruptible(&tty->write_wait); +#ifdef SERIAL_HAVE_POLL_WAIT + wake_up_interruptible(&tty->poll_wait); +#endif + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); +} + +/* + * This function is used to send a high-priority XON/XOFF character to + * the device + */ +static void rs_send_xchar(struct tty_struct *tty, char ch) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + + if (serial_paranoia_check(info, tty->device, "rs_send_char")) + return; + + info->x_char = ch; + if (ch) { + /* Make sure transmit interrupts are on */ + info->IER |= UART_IER_THRI; + serial_out(info, UART_IER, info->IER); + } +} + +/* + * ------------------------------------------------------------ + * rs_throttle() + * + * This routine is called by the upper-layer tty layer to signal that + * incoming characters should be throttled. + * ------------------------------------------------------------ + */ +static void rs_throttle(struct tty_struct * tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + printk("throttle %s: %d....\n", tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (serial_paranoia_check(info, tty->device, "rs_throttle")) + return; + + if (I_IXOFF(tty)) + rs_send_xchar(tty, STOP_CHAR(tty)); + + if (tty->termios->c_cflag & CRTSCTS) + info->MCR &= ~UART_MCR_RTS; + + spin_lock_irqsave(&serial_lock, flags); + serial_out(info, UART_MCR, info->MCR); + spin_unlock_irqrestore(&serial_lock, flags); +} + +static void rs_unthrottle(struct tty_struct * tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + printk("unthrottle %s: %d....\n", tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (serial_paranoia_check(info, tty->device, "rs_unthrottle")) + return; + + if (I_IXOFF(tty)) { + if (info->x_char) + info->x_char = 0; + else + rs_send_xchar(tty, START_CHAR(tty)); + } + if (tty->termios->c_cflag & CRTSCTS) + info->MCR |= UART_MCR_RTS; + spin_lock_irqsave(&serial_lock, flags); + serial_out(info, UART_MCR, info->MCR); + spin_unlock_irqrestore(&serial_lock, flags); +} + +/* + * ------------------------------------------------------------ + * rs_ioctl() and friends + * ------------------------------------------------------------ + */ + +static int get_serial_info(struct async_struct * info, + struct serial_struct * retinfo) +{ + struct serial_struct tmp; + struct serial_state *state = info->state; + + if (!retinfo) + return -EFAULT; + memset(&tmp, 0, sizeof(tmp)); + tmp.type = state->type; + tmp.line = state->line; + tmp.port = state->port; + if (HIGH_BITS_OFFSET) + tmp.port_high = state->port >> HIGH_BITS_OFFSET; + else + tmp.port_high = 0; + tmp.irq = state->irq; + tmp.flags = state->flags; + tmp.xmit_fifo_size = state->xmit_fifo_size; + tmp.baud_base = state->baud_base; + tmp.close_delay = state->close_delay; + tmp.closing_wait = state->closing_wait; + tmp.custom_divisor = state->custom_divisor; + tmp.hub6 = state->hub6; + tmp.io_type = state->io_type; + if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) + return -EFAULT; + return 0; +} + +static int set_serial_info(struct async_struct * info, + struct serial_struct * new_info) +{ + struct serial_struct new_serial; + struct serial_state old_state, *state; + unsigned int i,change_irq,change_port; + int retval = 0; + unsigned long new_port; + + if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) + return -EFAULT; + state = info->state; + old_state = *state; + + new_port = new_serial.port; + if (HIGH_BITS_OFFSET) + new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET; + + change_irq = new_serial.irq != state->irq; + change_port = (new_port != ((int) state->port)) || + (new_serial.hub6 != state->hub6); + + if (!capable(CAP_SYS_ADMIN)) { + if (change_irq || change_port || + (new_serial.baud_base != state->baud_base) || + (new_serial.type != state->type) || + (new_serial.close_delay != state->close_delay) || + (new_serial.xmit_fifo_size != state->xmit_fifo_size) || + ((new_serial.flags & ~ASYNC_USR_MASK) != + (state->flags & ~ASYNC_USR_MASK))) + return -EPERM; + state->flags = ((state->flags & ~ASYNC_USR_MASK) | + (new_serial.flags & ASYNC_USR_MASK)); + info->flags = ((info->flags & ~ASYNC_USR_MASK) | + (new_serial.flags & ASYNC_USR_MASK)); + state->custom_divisor = new_serial.custom_divisor; + goto check_and_exit; + } + + new_serial.irq = irq_cannonicalize(new_serial.irq); + + if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || + (new_serial.baud_base < 9600)|| (new_serial.type < PORT_UNKNOWN) || + (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) || + (new_serial.type == PORT_STARTECH)) { + return -EINVAL; + } + + if ((new_serial.type != state->type) || + (new_serial.xmit_fifo_size <= 0)) + new_serial.xmit_fifo_size = + uart_config[new_serial.type].dfl_xmit_fifo_size; + + /* Make sure address is not already in use */ + if (new_serial.type) { + for (i = 0 ; i < NR_PORTS; i++) + if ((state != &rs_table[i]) && + (rs_table[i].port == new_port) && + rs_table[i].type) + return -EADDRINUSE; + } + + if ((change_port || change_irq) && (state->count > 1)) + return -EBUSY; + + /* + * OK, past this point, all the error checking has been done. + * At this point, we start making changes..... + */ + + state->baud_base = new_serial.baud_base; + state->flags = ((state->flags & ~ASYNC_FLAGS) | + (new_serial.flags & ASYNC_FLAGS)); + info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | + (info->flags & ASYNC_INTERNAL_FLAGS)); + state->custom_divisor = new_serial.custom_divisor; + state->close_delay = new_serial.close_delay * HZ/100; + state->closing_wait = new_serial.closing_wait * HZ/100; + info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; + info->xmit_fifo_size = state->xmit_fifo_size = + new_serial.xmit_fifo_size; + + if ((state->type != PORT_UNKNOWN) && state->port) { + release_region(state->port,8); + } + state->type = new_serial.type; + if (change_port || change_irq) { + /* + * We need to shutdown the serial port at the old + * port/irq combination. + */ + shutdown(info); + state->irq = new_serial.irq; + info->port = state->port = new_port; + info->hub6 = state->hub6 = new_serial.hub6; + if (info->hub6) + info->io_type = state->io_type = SERIAL_IO_HUB6; + else if (info->io_type == SERIAL_IO_HUB6) + info->io_type = state->io_type = SERIAL_IO_PORT; + } + if ((state->type != PORT_UNKNOWN) && state->port) { + request_region(state->port,8,"serial(set)"); + } + + +check_and_exit: + if (!state->port || !state->type) + return 0; + if (info->flags & ASYNC_INITIALIZED) { + if (((old_state.flags & ASYNC_SPD_MASK) != + (state->flags & ASYNC_SPD_MASK)) || + (old_state.custom_divisor != state->custom_divisor)) { + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + info->tty->alt_speed = 57600; + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + info->tty->alt_speed = 115200; + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + info->tty->alt_speed = 230400; + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + info->tty->alt_speed = 460800; + change_speed(info, 0); + } + } else { + retval = startup(info); + } + return retval; +} + + +/* + * get_lsr_info - get line status register info + * + * Purpose: Let user call ioctl() to get info when the UART physically + * is emptied. On bus types like RS485, the transmitter must + * release the bus after transmitting. This must be done when + * the transmit shift register is empty, not be done when the + * transmit holding register is empty. This functionality + * allows an RS485 driver to be written in user space. + */ +static int get_lsr_info(struct async_struct * info, unsigned int *value) +{ + unsigned char status; + unsigned int result; + unsigned long flags; + + spin_lock_irqsave(&serial_lock, flags); + status = serial_in(info, UART_LSR); + spin_unlock_irqrestore(&serial_lock, flags); + result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); + + /* + * If we're about to load something into the transmit + * register, we'll pretend the transmitter isn't empty to + * avoid a race condition (depending on when the transmit + * interrupt happens). + */ + if (info->x_char || + ((CIRC_CNT(info->xmit.head, info->xmit.tail, + SERIAL_XMIT_SIZE) > 0) && + !info->tty->stopped && !info->tty->hw_stopped)) + result &= TIOCSER_TEMT; + + if (copy_to_user(value, &result, sizeof(int))) + return -EFAULT; + return 0; +} + + +static int get_modem_info(struct async_struct * info, unsigned int *value) +{ + unsigned char control, status; + unsigned int result; + unsigned long flags; + + control = info->MCR; + spin_lock_irqsave(&serial_lock, flags); + status = serial_in(info, UART_MSR); + spin_unlock_irqrestore(&serial_lock, flags); + result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) + | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) +#ifdef TIOCM_OUT1 + | ((control & UART_MCR_OUT1) ? TIOCM_OUT1 : 0) + | ((control & UART_MCR_OUT2) ? TIOCM_OUT2 : 0) +#endif + | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) + | ((status & UART_MSR_RI) ? TIOCM_RNG : 0) + | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) + | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0); + + if (copy_to_user(value, &result, sizeof(int))) + return -EFAULT; + return 0; +} + +static int set_modem_info(struct async_struct * info, unsigned int cmd, + unsigned int *value) +{ + unsigned int arg; + unsigned long flags; + + if (copy_from_user(&arg, value, sizeof(int))) + return -EFAULT; + + switch (cmd) { + case TIOCMBIS: + if (arg & TIOCM_RTS) + info->MCR |= UART_MCR_RTS; + if (arg & TIOCM_DTR) + info->MCR |= UART_MCR_DTR; +#ifdef TIOCM_OUT1 + if (arg & TIOCM_OUT1) + info->MCR |= UART_MCR_OUT1; + if (arg & TIOCM_OUT2) + info->MCR |= UART_MCR_OUT2; +#endif + if (arg & TIOCM_LOOP) + info->MCR |= UART_MCR_LOOP; + break; + case TIOCMBIC: + if (arg & TIOCM_RTS) + info->MCR &= ~UART_MCR_RTS; + if (arg & TIOCM_DTR) + info->MCR &= ~UART_MCR_DTR; +#ifdef TIOCM_OUT1 + if (arg & TIOCM_OUT1) + info->MCR &= ~UART_MCR_OUT1; + if (arg & TIOCM_OUT2) + info->MCR &= ~UART_MCR_OUT2; +#endif + if (arg & TIOCM_LOOP) + info->MCR &= ~UART_MCR_LOOP; + break; + case TIOCMSET: + info->MCR = ((info->MCR & ~(UART_MCR_RTS | +#ifdef TIOCM_OUT1 + UART_MCR_OUT1 | + UART_MCR_OUT2 | +#endif + UART_MCR_LOOP | + UART_MCR_DTR)) + | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0) +#ifdef TIOCM_OUT1 + | ((arg & TIOCM_OUT1) ? UART_MCR_OUT1 : 0) + | ((arg & TIOCM_OUT2) ? UART_MCR_OUT2 : 0) +#endif + | ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0) + | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0)); + break; + default: + return -EINVAL; + } + spin_lock_irqsave(&serial_lock, flags); + info->MCR |= ALPHA_KLUDGE_MCR; /* Don't ask */ + serial_out(info, UART_MCR, info->MCR); + spin_unlock_irqrestore(&serial_lock, flags); + return 0; +} + +static int do_autoconfig(struct async_struct * info) +{ + int retval; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (info->state->count > 1) + return -EBUSY; + + shutdown(info); + + autoconfig(info->state); + retval = startup(info); + if (retval) + return retval; + return 0; +} + +/* + * rs_break() --- routine which turns the break handling on or off + */ +static void rs_break(struct tty_struct *tty, int break_state) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_break")) + return; + + if (!CONFIGURED_SERIAL_PORT(info)) + return; + spin_lock_irqsave(&serial_lock, flags); + if (break_state == -1) + info->LCR |= UART_LCR_SBC; + else + info->LCR &= ~UART_LCR_SBC; + serial_out(info, UART_LCR, info->LCR); + spin_unlock_irqrestore(&serial_lock, flags); +} + + +static int rs_ioctl(struct tty_struct *tty, struct file * file, + unsigned int cmd, unsigned long arg) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + struct async_icount cprev, cnow; /* kernel counter temps */ + struct serial_icounter_struct icount; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_ioctl")) + return -ENODEV; + + if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && + (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && + (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + } + + switch (cmd) { + case TIOCMGET: + return get_modem_info(info, (unsigned int *) arg); + case TIOCMBIS: + case TIOCMBIC: + case TIOCMSET: + return set_modem_info(info, cmd, (unsigned int *) arg); + case TIOCGSERIAL: + return get_serial_info(info, + (struct serial_struct *) arg); + case TIOCSSERIAL: + return set_serial_info(info, + (struct serial_struct *) arg); + case TIOCSERCONFIG: + return do_autoconfig(info); + + case TIOCSERGETLSR: /* Get line status register */ + return get_lsr_info(info, (unsigned int *) arg); + + case TIOCSERGSTRUCT: + if (copy_to_user((struct async_struct *) arg, + info, sizeof(struct async_struct))) + return -EFAULT; + return 0; + + + /* + * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change + * - mask passed in arg for lines of interest + * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) + * Caller should use TIOCGICOUNT to see which one it was + */ + case TIOCMIWAIT: + spin_lock_irqsave(&serial_lock, flags); + /* note the counters on entry */ + cprev = info->state->icount; + spin_unlock_irqrestore(&serial_lock, flags); + /* Force modem status interrupts on */ + info->IER |= UART_IER_MSI; + serial_out(info, UART_IER, info->IER); + while (1) { + interruptible_sleep_on(&info->delta_msr_wait); + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; + spin_lock_irqsave(&serial_lock, flags); + cnow = info->state->icount; /* atomic copy */ + spin_unlock_irqrestore(&serial_lock, flags); + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && + cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) + return -EIO; /* no change => error */ + if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || + ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || + ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || + ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { + return 0; + } + cprev = cnow; + } + /* NOTREACHED */ + + /* + * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) + * Return: write counters to the user passed counter struct + * NB: both 1->0 and 0->1 transitions are counted except for + * RI where only 0->1 is counted. + */ + case TIOCGICOUNT: + spin_lock_irqsave(&serial_lock, flags); + cnow = info->state->icount; + spin_unlock_irqrestore(&serial_lock, flags); + icount.cts = cnow.cts; + icount.dsr = cnow.dsr; + icount.rng = cnow.rng; + icount.dcd = cnow.dcd; + icount.rx = cnow.rx; + icount.tx = cnow.tx; + icount.frame = cnow.frame; + icount.overrun = cnow.overrun; + icount.parity = cnow.parity; + icount.brk = cnow.brk; + icount.buf_overrun = cnow.buf_overrun; + + if (copy_to_user((void *)arg, &icount, sizeof(icount))) + return -EFAULT; + return 0; + case TIOCSERGWILD: + case TIOCSERSWILD: + /* "setserial -W" is called in Debian boot */ + printk ("TIOCSER?WILD ioctl obsolete, ignored.\n"); + return 0; + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + unsigned int cflag = tty->termios->c_cflag; + + if ( (cflag == old_termios->c_cflag) + && ( RELEVANT_IFLAG(tty->termios->c_iflag) + == RELEVANT_IFLAG(old_termios->c_iflag))) + return; + + change_speed(info, old_termios); + + /* Handle transition to B0 status */ + if ((old_termios->c_cflag & CBAUD) && + !(cflag & CBAUD)) { + info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); + spin_lock_irqsave(&serial_lock, flags); + serial_out(info, UART_MCR, info->MCR); + spin_unlock_irqrestore(&serial_lock, flags); + } + + /* Handle transition away from B0 status */ + if (!(old_termios->c_cflag & CBAUD) && + (cflag & CBAUD)) { + info->MCR |= UART_MCR_DTR; + if (!(tty->termios->c_cflag & CRTSCTS) || + !test_bit(TTY_THROTTLED, &tty->flags)) { + info->MCR |= UART_MCR_RTS; + } + spin_lock_irqsave(&serial_lock, flags); + serial_out(info, UART_MCR, info->MCR); + spin_unlock_irqrestore(&serial_lock, flags); + } + + /* Handle turning off CRTSCTS */ + if ((old_termios->c_cflag & CRTSCTS) && + !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + rs_start(tty); + } +} + +/* + * ------------------------------------------------------------ + * rs_close() + * + * This routine is called when the serial port gets closed. First, we + * wait for the last remaining data to be sent. Then, we unlink its + * async structure from the interrupt chain if necessary, and we free + * that IRQ if nothing is left in the chain. + * ------------------------------------------------------------ + */ +static void rs_close(struct tty_struct *tty, struct file * filp) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + struct serial_state *state; + unsigned long flags; + + if (!info || serial_paranoia_check(info, tty->device, "rs_close")) + return; + + state = info->state; + + spin_lock_irqsave(&serial_lock, flags); + + if (tty_hung_up_p(filp)) { + DBG_CNT("before DEC-hung"); + MOD_DEC_USE_COUNT; + spin_unlock_irqrestore(&serial_lock, flags); + return; + } + +#ifdef SERIAL_DEBUG_OPEN + printk("rs_close ttys%d, count = %d\n", info->line, state->count); +#endif + if ((tty->count == 1) && (state->count != 1)) { + /* + * Uh, oh. tty->count is 1, which means that the tty + * structure will be freed. state->count should always + * be one in these conditions. If it's greater than + * one, we've got real problems, since it means the + * serial port won't be shutdown. + */ + printk("rs_close: bad serial port count; tty->count is 1, " + "state->count is %d\n", state->count); + state->count = 1; + } + if (--state->count < 0) { + printk("rs_close: bad serial port count for ttys%d: %d\n", + info->line, state->count); + state->count = 0; + } + if (state->count) { + DBG_CNT("before DEC-2"); + MOD_DEC_USE_COUNT; + spin_unlock_irqrestore(&serial_lock, flags); + return; + } + info->flags |= ASYNC_CLOSING; + spin_unlock_irqrestore(&serial_lock, flags); + /* + * Save the termios structure, since this port may have + * separate termios for callout and dialin. + */ + if (info->flags & ASYNC_NORMAL_ACTIVE) + info->state->normal_termios = *tty->termios; + if (info->flags & ASYNC_CALLOUT_ACTIVE) + info->state->callout_termios = *tty->termios; + /* + * Now we wait for the transmit buffer to clear; and we notify + * the line discipline to only process XON/XOFF characters. + */ + tty->closing = 1; + if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) + tty_wait_until_sent(tty, info->closing_wait); + /* + * At this point we stop accepting input. To do this, we + * disable the receive line status interrupts, and tell the + * interrupt driver to stop checking the data ready bit in the + * line status register. + */ + info->IER &= ~UART_IER_RLSI; + info->read_status_mask &= ~UART_LSR_DR; + if (info->flags & ASYNC_INITIALIZED) { + serial_out(info, UART_IER, info->IER); + /* + * Before we drop DTR, make sure the UART transmitter + * has completely drained; this is especially + * important if there is a transmit FIFO! + */ + rs_wait_until_sent(tty, info->timeout); + } + shutdown(info); + if (tty->driver.flush_buffer) + tty->driver.flush_buffer(tty); + if (tty->ldisc.flush_buffer) + tty->ldisc.flush_buffer(tty); + tty->closing = 0; + info->event = 0; + info->tty = 0; + if (info->blocked_open) { + if (info->close_delay) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(info->close_delay); + } + wake_up_interruptible(&info->open_wait); + } + info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE| + ASYNC_CLOSING); + wake_up_interruptible(&info->close_wait); + MOD_DEC_USE_COUNT; +} + +/* + * rs_wait_until_sent() --- wait until the transmitter is empty + */ +static void rs_wait_until_sent(struct tty_struct *tty, int timeout) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + unsigned long orig_jiffies, char_time; + int lsr; + + if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent")) + return; + + if (info->state->type == PORT_UNKNOWN) + return; + + if (info->xmit_fifo_size == 0) + return; /* Just in case.... */ + + orig_jiffies = jiffies; + /* + * Set the check interval to be 1/5 of the estimated time to + * send a single character, and make it at least 1. The check + * interval should also be less than the timeout. + * + * Note: we have to use pretty tight timings here to satisfy + * the NIST-PCTS. + */ + char_time = (info->timeout - HZ/50) / info->xmit_fifo_size; + char_time = char_time / 5; + if (char_time == 0) + char_time = 1; + if (timeout && timeout < char_time) + char_time = timeout; + /* + * If the transmitter hasn't cleared in twice the approximate + * amount of time to send the entire FIFO, it probably won't + * ever clear. This assumes the UART isn't doing flow + * control, which is currently the case. Hence, if it ever + * takes longer than info->timeout, this is probably due to a + * UART bug of some kind. So, we clamp the timeout parameter at + * 2*info->timeout. + */ + if (!timeout || timeout > 2*info->timeout) + timeout = 2*info->timeout; +#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time); + printk("jiff=%lu...", jiffies); +#endif + while (!((lsr = serial_inp(info, UART_LSR)) & UART_LSR_TEMT)) { +#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + printk("lsr = %d (jiff=%lu)...", lsr, jiffies); +#endif + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(char_time); + if (signal_pending(current)) + break; + if (timeout && time_after(jiffies, orig_jiffies + timeout)) + break; + } + set_current_state(TASK_RUNNING); +#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); +#endif +} + +/* + * rs_hangup() --- called by tty_hangup() when a hangup is signaled. + */ +static void rs_hangup(struct tty_struct *tty) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + struct serial_state *state = info->state; + + if (serial_paranoia_check(info, tty->device, "rs_hangup")) + return; + + state = info->state; + + rs_flush_buffer(tty); + if (info->flags & ASYNC_CLOSING) + return; + shutdown(info); + info->event = 0; + state->count = 0; + info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE); + info->tty = 0; + wake_up_interruptible(&info->open_wait); +} + +/* + * ------------------------------------------------------------ + * rs_open() and friends + * ------------------------------------------------------------ + */ +static int block_til_ready(struct tty_struct *tty, struct file * filp, + struct async_struct *info) +{ + DECLARE_WAITQUEUE(wait, current); + struct serial_state *state = info->state; + int retval; + int do_clocal = 0, extra_count = 0; + unsigned long flags; + + /* + * If the device is in the middle of being closed, then block + * until it's done, and then try again. + */ + if (tty_hung_up_p(filp) || + (info->flags & ASYNC_CLOSING)) { + if (info->flags & ASYNC_CLOSING) + interruptible_sleep_on(&info->close_wait); +#ifdef SERIAL_DO_RESTART + return ((info->flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS); +#else + return -EAGAIN; +#endif + } + + /* + * If this is a callout device, then just make sure the normal + * device isn't being used. + */ + if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) { + if (info->flags & ASYNC_NORMAL_ACTIVE) + return -EBUSY; + if ((info->flags & ASYNC_CALLOUT_ACTIVE) && + (info->flags & ASYNC_SESSION_LOCKOUT) && + (info->session != current->session)) + return -EBUSY; + if ((info->flags & ASYNC_CALLOUT_ACTIVE) && + (info->flags & ASYNC_PGRP_LOCKOUT) && + (info->pgrp != current->pgrp)) + return -EBUSY; + info->flags |= ASYNC_CALLOUT_ACTIVE; + return 0; + } + + /* + * If non-blocking mode is set, or the port is not enabled, + * then make the check up front and then exit. + */ + if ((filp->f_flags & O_NONBLOCK) || + (tty->flags & (1 << TTY_IO_ERROR))) { + if (info->flags & ASYNC_CALLOUT_ACTIVE) + return -EBUSY; + info->flags |= ASYNC_NORMAL_ACTIVE; + return 0; + } + + if (info->flags & ASYNC_CALLOUT_ACTIVE) { + if (state->normal_termios.c_cflag & CLOCAL) + do_clocal = 1; + } else { + if (tty->termios->c_cflag & CLOCAL) + do_clocal = 1; + } + + /* + * Block waiting for the carrier detect and the line to become + * free (i.e., not in use by the callout). While we are in + * this loop, state->count is dropped by one, so that + * rs_close() knows when to free things. We restore it upon + * exit, either normal or abnormal. + */ + retval = 0; + add_wait_queue(&info->open_wait, &wait); +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready before block: ttys%d, count = %d\n", + state->line, state->count); +#endif + spin_lock_irqsave(&serial_lock, flags); + if (!tty_hung_up_p(filp)) { + extra_count = 1; + state->count--; + } + spin_unlock_irqrestore(&serial_lock, flags); + info->blocked_open++; + while (1) { + spin_lock_irqsave(&serial_lock, flags); + if (!(info->flags & ASYNC_CALLOUT_ACTIVE) && + (tty->termios->c_cflag & CBAUD)) + serial_out(info, UART_MCR, + serial_inp(info, UART_MCR) | + (UART_MCR_DTR | UART_MCR_RTS)); + spin_unlock_irqrestore(&serial_lock, flags); + set_current_state(TASK_INTERRUPTIBLE); + if (tty_hung_up_p(filp) || + !(info->flags & ASYNC_INITIALIZED)) { +#ifdef SERIAL_DO_RESTART + if (info->flags & ASYNC_HUP_NOTIFY) + retval = -EAGAIN; + else + retval = -ERESTARTSYS; +#else + retval = -EAGAIN; +#endif + break; + } + if (!(info->flags & ASYNC_CALLOUT_ACTIVE) && + !(info->flags & ASYNC_CLOSING) && + (do_clocal || (serial_in(info, UART_MSR) & + UART_MSR_DCD))) + break; + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready blocking: ttys%d, count = %d\n", + info->line, state->count); +#endif + schedule(); + } + set_current_state(TASK_RUNNING); + remove_wait_queue(&info->open_wait, &wait); + if (extra_count) + state->count++; + info->blocked_open--; +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready after blocking: ttys%d, count = %d\n", + info->line, state->count); +#endif + if (retval) + return retval; + info->flags |= ASYNC_NORMAL_ACTIVE; + return 0; +} + +static int get_async_struct(int line, struct async_struct **ret_info) +{ + struct async_struct *info; + struct serial_state *sstate; + + sstate = rs_table + line; + sstate->count++; + if (sstate->info) { + *ret_info = sstate->info; + return 0; + } + info = kmalloc(sizeof(struct async_struct), GFP_KERNEL); + if (!info) { + sstate->count--; + return -ENOMEM; + } + memset(info, 0, sizeof(struct async_struct)); + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + init_waitqueue_head(&info->delta_msr_wait); + info->magic = SERIAL_MAGIC; + info->port = sstate->port; + info->flags = sstate->flags; + info->io_type = sstate->io_type; + info->iomem_base = sstate->iomem_base; + info->iomem_reg_shift = sstate->iomem_reg_shift; + info->xmit_fifo_size = sstate->xmit_fifo_size; + info->line = line; + info->tqueue.routine = do_softint; + info->tqueue.data = info; + info->state = sstate; + if (sstate->info) { + kfree(info); + *ret_info = sstate->info; + return 0; + } + *ret_info = sstate->info = info; + return 0; +} + +/* + * This routine is called whenever a serial port is opened. It + * enables interrupts for a serial port, linking in its async structure into + * the IRQ chain. It also performs the serial-specific + * initialization for the tty structure. + */ +static int rs_open(struct tty_struct *tty, struct file * filp) +{ + struct async_struct *info; + int retval, line; + unsigned long page; + + MOD_INC_USE_COUNT; + line = MINOR(tty->device) - tty->driver.minor_start; + if ((line < 0) || (line >= NR_PORTS)) { + MOD_DEC_USE_COUNT; + return -ENODEV; + } + retval = get_async_struct(line, &info); + if (retval) { + MOD_DEC_USE_COUNT; + return retval; + } + tty->driver_data = info; + info->tty = tty; + if (serial_paranoia_check(info, tty->device, "rs_open")) { + MOD_DEC_USE_COUNT; + return -ENODEV; + } + +#ifdef SERIAL_DEBUG_OPEN + printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line, + info->state->count); +#endif + info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; + + if (!tmp_buf) { + page = get_zeroed_page(GFP_KERNEL); + if (!page) { + MOD_DEC_USE_COUNT; + return -ENOMEM; + } + if (tmp_buf) + free_page(page); + else + tmp_buf = (unsigned char *) page; + } + + /* + * If the port is the middle of closing, bail out now + */ + if (tty_hung_up_p(filp) || + (info->flags & ASYNC_CLOSING)) { + if (info->flags & ASYNC_CLOSING) + interruptible_sleep_on(&info->close_wait); + MOD_DEC_USE_COUNT; +#ifdef SERIAL_DO_RESTART + return ((info->flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS); +#else + return -EAGAIN; +#endif + } + + /* + * Start up serial port + */ + retval = startup(info); + if (retval) { + MOD_DEC_USE_COUNT; + return retval; + } + + retval = block_til_ready(tty, filp, info); + if (retval) { +#ifdef SERIAL_DEBUG_OPEN + printk("rs_open returning after block_til_ready with %d\n", + retval); +#endif + MOD_DEC_USE_COUNT; + return retval; + } + + if ((info->state->count == 1) && + (info->flags & ASYNC_SPLIT_TERMIOS)) { + if (tty->driver.subtype == SERIAL_TYPE_NORMAL) + *tty->termios = info->state->normal_termios; + else + *tty->termios = info->state->callout_termios; + change_speed(info, 0); + } +#ifdef CONFIG_AU1X00_SERIAL_CONSOLE + if (sercons.cflag && sercons.index == line) { + tty->termios->c_cflag = sercons.cflag; + sercons.cflag = 0; + change_speed(info, 0); + } +#endif + info->session = current->session; + info->pgrp = current->pgrp; + +#ifdef SERIAL_DEBUG_OPEN + printk("rs_open ttys%d successful...", info->line); +#endif + return 0; +} + +/* + * /proc fs routines.... + */ + +static inline int line_info(char *buf, struct serial_state *state) +{ + struct async_struct *info = state->info, scr_info; + char stat_buf[30], control, status; + int ret; + unsigned long flags; + + ret = sprintf(buf, "%d: uart:%s port:%lX irq:%d", + state->line, uart_config[state->type].name, + state->port, state->irq); + + if (!state->port || (state->type == PORT_UNKNOWN)) { + ret += sprintf(buf+ret, "\n"); + return ret; + } + + /* + * Figure out the current RS-232 lines + */ + if (!info) { + info = &scr_info; /* This is just for serial_{in,out} */ + + info->magic = SERIAL_MAGIC; + info->port = state->port; + info->flags = state->flags; + info->quot = 0; + info->tty = 0; + } + spin_lock_irqsave(&serial_lock, flags); + status = serial_in(info, UART_MSR); + control = info != &scr_info ? info->MCR : serial_in(info, UART_MCR); + spin_unlock_irqrestore(&serial_lock, flags); + + stat_buf[0] = 0; + stat_buf[1] = 0; + if (control & UART_MCR_RTS) + strcat(stat_buf, "|RTS"); + if (status & UART_MSR_CTS) + strcat(stat_buf, "|CTS"); + if (control & UART_MCR_DTR) + strcat(stat_buf, "|DTR"); + if (status & UART_MSR_DSR) + strcat(stat_buf, "|DSR"); + if (status & UART_MSR_DCD) + strcat(stat_buf, "|CD"); + if (status & UART_MSR_RI) + strcat(stat_buf, "|RI"); + + if (info->quot) { + ret += sprintf(buf+ret, " baud:%d", + state->baud_base / info->quot); + } + + ret += sprintf(buf+ret, " tx:%d rx:%d", + state->icount.tx, state->icount.rx); + + if (state->icount.frame) + ret += sprintf(buf+ret, " fe:%d", state->icount.frame); + + if (state->icount.parity) + ret += sprintf(buf+ret, " pe:%d", state->icount.parity); + + if (state->icount.brk) + ret += sprintf(buf+ret, " brk:%d", state->icount.brk); + + if (state->icount.overrun) + ret += sprintf(buf+ret, " oe:%d", state->icount.overrun); + + /* + * Last thing is the RS-232 status lines + */ + ret += sprintf(buf+ret, " %s\n", stat_buf+1); + return ret; +} + +int rs_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + int i, len = 0, l; + off_t begin = 0; + + len += sprintf(page, "serinfo:1.0 driver:%s%s revision:%s\n", + serial_version, LOCAL_VERSTRING, serial_revdate); + for (i = 0; i < NR_PORTS && len < 4000; i++) { + l = line_info(page + len, &rs_table[i]); + len += l; + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } + } + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (off-begin); + return ((count < begin+len-off) ? count : begin+len-off); +} + +/* + * --------------------------------------------------------------------- + * rs_init() and friends + * + * rs_init() is called at boot-time to initialize the serial driver. + * --------------------------------------------------------------------- + */ + +/* + * This routine prints out the appropriate serial driver version + * number, and identifies which options were configured into this + * driver. + */ +static char serial_options[] __initdata = + " no serial options enabled\n"; +#undef SERIAL_OPT + +static _INLINE_ void show_serial_version(void) +{ + printk(KERN_INFO "%s version %s%s (%s) with%s", serial_name, + serial_version, LOCAL_VERSTRING, serial_revdate, + serial_options); +} + + +/* + * This routine is called by rs_init() to initialize a specific serial + * port. It determines what type of UART chip this serial port is + * using: 8250, 16450, 16550, 16550A. The important question is + * whether or not this UART is a 16550A or not, since this will + * determine whether or not we can use its FIFO features or not. + */ +static void autoconfig(struct serial_state * state) +{ + struct async_struct *info, scr_info; + unsigned long flags; + + +#ifdef SERIAL_DEBUG_AUTOCONF + printk("Testing ttyS%d (0x%04lx, 0x%04x)...\n", state->line, + state->port, (unsigned) state->iomem_base); +#endif + + if (!CONFIGURED_SERIAL_PORT(state)) + return; + + if (au_readl(UART_MOD_CNTRL + state->port) != 0x3) { + au_writel(3, UART_MOD_CNTRL + state->port); + au_sync_delay(10); + } + + state->type = PORT_16550; + info = &scr_info; /* This is just for serial_{in,out} */ + + info->magic = SERIAL_MAGIC; + info->state = state; + info->port = state->port; + info->flags = state->flags; + info->io_type = state->io_type; + info->iomem_base = state->iomem_base; + info->iomem_reg_shift = state->iomem_reg_shift; + + + spin_lock_irqsave(&serial_lock, flags); + state->xmit_fifo_size = uart_config[state->type].dfl_xmit_fifo_size; + + if (info->port) { + request_region(info->port,8,"serial(auto)"); + } + + /* + * Reset the UART. + */ + serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | + UART_FCR_CLEAR_XMIT)); + serial_outp(info, UART_FCR, 0); + (void)serial_in(info, UART_RX); + serial_outp(info, UART_IER, 0); + spin_unlock_irqrestore(&serial_lock, flags); +} + +int register_serial(struct serial_struct *req); +void unregister_serial(int line); + +/* + * The serial driver boot-time initialization code! + */ +static int __init rs_init(void) +{ + int i; + struct serial_state * state; + + init_bh(SERIAL_BH, do_serial_bh); + init_timer(&serial_timer); + serial_timer.function = rs_timer; + mod_timer(&serial_timer, jiffies + RS_STROBE_TIME); + + for (i = 0; i < NR_IRQS; i++) { + IRQ_ports[i] = 0; + IRQ_timeout[i] = 0; + } +#ifdef CONFIG_AU1X00_SERIAL_CONSOLE + /* + * The interrupt of the serial console port + * can't be shared. + */ + if (sercons.flags & CON_CONSDEV) { + for(i = 0; i < NR_PORTS; i++) + if (i != sercons.index && + rs_table[i].irq == rs_table[sercons.index].irq) + rs_table[i].irq = 0; + } +#endif + show_serial_version(); + + /* Initialize the tty_driver structure */ + + memset(&serial_driver, 0, sizeof(struct tty_driver)); + serial_driver.magic = TTY_DRIVER_MAGIC; + serial_driver.driver_name = "serial"; +#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS)) + serial_driver.name = "tts/%d"; +#else + serial_driver.name = "ttyS"; +#endif + serial_driver.major = TTY_MAJOR; + serial_driver.minor_start = 64 + SERIAL_DEV_OFFSET; + serial_driver.num = NR_PORTS; + serial_driver.type = TTY_DRIVER_TYPE_SERIAL; + serial_driver.subtype = SERIAL_TYPE_NORMAL; + serial_driver.init_termios = tty_std_termios; + serial_driver.init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; + serial_driver.refcount = &serial_refcount; + serial_driver.table = serial_table; + serial_driver.termios = serial_termios; + serial_driver.termios_locked = serial_termios_locked; + + serial_driver.open = rs_open; + serial_driver.close = rs_close; + serial_driver.write = rs_write; + serial_driver.put_char = rs_put_char; + serial_driver.flush_chars = rs_flush_chars; + serial_driver.write_room = rs_write_room; + serial_driver.chars_in_buffer = rs_chars_in_buffer; + serial_driver.flush_buffer = rs_flush_buffer; + serial_driver.ioctl = rs_ioctl; + serial_driver.throttle = rs_throttle; + serial_driver.unthrottle = rs_unthrottle; + serial_driver.set_termios = rs_set_termios; + serial_driver.stop = rs_stop; + serial_driver.start = rs_start; + serial_driver.hangup = rs_hangup; + serial_driver.break_ctl = rs_break; + serial_driver.send_xchar = rs_send_xchar; + serial_driver.wait_until_sent = rs_wait_until_sent; + serial_driver.read_proc = rs_read_proc; + + /* + * The callout device is just like normal device except for + * major number and the subtype code. + */ + callout_driver = serial_driver; +#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS)) + callout_driver.name = "cua/%d"; +#else + callout_driver.name = "cua"; +#endif + callout_driver.major = TTYAUX_MAJOR; + callout_driver.subtype = SERIAL_TYPE_CALLOUT; + callout_driver.read_proc = 0; + callout_driver.proc_entry = 0; + + if (tty_register_driver(&serial_driver)) + panic("Couldn't register serial driver"); + if (tty_register_driver(&callout_driver)) + panic("Couldn't register callout driver"); + + for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { + state->baud_base = get_au1x00_uart_baud_base(); + state->magic = SSTATE_MAGIC; + state->line = i; + state->type = PORT_UNKNOWN; + state->custom_divisor = 0; + state->close_delay = 5*HZ/10; + state->closing_wait = 30*HZ; + state->callout_termios = callout_driver.init_termios; + state->normal_termios = serial_driver.init_termios; + state->icount.cts = state->icount.dsr = + state->icount.rng = state->icount.dcd = 0; + state->icount.rx = state->icount.tx = 0; + state->icount.frame = state->icount.parity = 0; + state->icount.overrun = state->icount.brk = 0; + state->irq = irq_cannonicalize(state->irq); + if (state->hub6) + state->io_type = SERIAL_IO_HUB6; + if (state->port && check_region(state->port,8)) { + continue; + } + + if (state->flags & ASYNC_BOOT_AUTOCONF) { + autoconfig(state); + } + } + for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { + if (state->type == PORT_UNKNOWN) { + continue; + } + printk(KERN_INFO "ttyS%02d%s at 0x%04lx (irq = %d) is a %s\n", + state->line + SERIAL_DEV_OFFSET, + (state->flags & ASYNC_FOURPORT) ? " FourPort" : "", + state->port, state->irq, + uart_config[state->type].name); + tty_register_devfs(&serial_driver, 0, + serial_driver.minor_start + state->line); + tty_register_devfs(&callout_driver, 0, + callout_driver.minor_start + state->line); + } + return 0; +} + +/* + * register_serial and unregister_serial allows for 16x50 serial ports to be + * configured at run-time, to support PCMCIA modems. + */ + +/** + * register_serial - configure a 16x50 serial port at runtime + * @req: request structure + * + * Configure the serial port specified by the request. If the + * port exists and is in use an error is returned. If the port + * is not currently in the table it is added. + * + * The port is then probed and if neccessary the IRQ is autodetected + * If this fails an error is returned. + * + * On success the port is ready to use and the line number is returned. + */ + +int register_serial(struct serial_struct *req) +{ + int i; + unsigned long flags; + struct serial_state *state; + struct async_struct *info; + unsigned long port; + + port = req->port; + if (HIGH_BITS_OFFSET) + port += (unsigned long) req->port_high << HIGH_BITS_OFFSET; + + spin_lock_irqsave(&serial_lock, flags); + for (i = 0; i < NR_PORTS; i++) { + if ((rs_table[i].port == port) && + (rs_table[i].iomem_base == req->iomem_base)) + break; + } + if (i == NR_PORTS) { + for (i = 0; i < NR_PORTS; i++) + if ((rs_table[i].type == PORT_UNKNOWN) && + (rs_table[i].count == 0)) + break; + } + if (i == NR_PORTS) { + spin_unlock_irqrestore(&serial_lock, flags); + return -1; + } + state = &rs_table[i]; + if (rs_table[i].count) { + spin_unlock_irqrestore(&serial_lock, flags); + printk("Couldn't configure serial #%d (port=%ld,irq=%d): " + "device already open\n", i, port, req->irq); + return -1; + } + state->irq = req->irq; + state->port = port; + state->flags = req->flags; + state->io_type = req->io_type; + state->iomem_base = req->iomem_base; + state->iomem_reg_shift = req->iomem_reg_shift; + if (req->baud_base) + state->baud_base = req->baud_base; + if ((info = state->info) != NULL) { + info->port = port; + info->flags = req->flags; + info->io_type = req->io_type; + info->iomem_base = req->iomem_base; + info->iomem_reg_shift = req->iomem_reg_shift; + } + autoconfig(state); + if (state->type == PORT_UNKNOWN) { + spin_unlock_irqrestore(&serial_lock, flags); + printk("register_serial(): autoconfig failed\n"); + return -1; + } + spin_unlock_irqrestore(&serial_lock, flags); + + printk(KERN_INFO "ttyS%02d at %s 0x%04lx (irq = %d) is a %s\n", + state->line + SERIAL_DEV_OFFSET, + state->iomem_base ? "iomem" : "port", + state->iomem_base ? (unsigned long)state->iomem_base : + state->port, state->irq, uart_config[state->type].name); + tty_register_devfs(&serial_driver, 0, + serial_driver.minor_start + state->line); + tty_register_devfs(&callout_driver, 0, + callout_driver.minor_start + state->line); + return state->line + SERIAL_DEV_OFFSET; +} + +/** + * unregister_serial - deconfigure a 16x50 serial port + * @line: line to deconfigure + * + * The port specified is deconfigured and its resources are freed. Any + * user of the port is disconnected as if carrier was dropped. Line is + * the port number returned by register_serial(). + */ + +void unregister_serial(int line) +{ + unsigned long flags; + struct serial_state *state = &rs_table[line]; + + spin_lock_irqsave(&serial_lock, flags); + if (state->info && state->info->tty) + tty_hangup(state->info->tty); + state->type = PORT_UNKNOWN; + printk(KERN_INFO "tty%02d unloaded\n", state->line); + /* These will be hidden, because they are devices that will no longer + * be available to the system. (ie, PCMCIA modems, once ejected) + */ + tty_unregister_devfs(&serial_driver, + serial_driver.minor_start + state->line); + tty_unregister_devfs(&callout_driver, + callout_driver.minor_start + state->line); + spin_unlock_irqrestore(&serial_lock, flags); +} + +static void __exit rs_fini(void) +{ + unsigned long flags; + int e1, e2; + int i; + struct async_struct *info; + + /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ + del_timer_sync(&serial_timer); + spin_lock_irqsave(&serial_lock, flags); + remove_bh(SERIAL_BH); + if ((e1 = tty_unregister_driver(&serial_driver))) + printk("serial: failed to unregister serial driver (%d)\n", + e1); + if ((e2 = tty_unregister_driver(&callout_driver))) + printk("serial: failed to unregister callout driver (%d)\n", + e2); + spin_unlock_irqrestore(&serial_lock, flags); + + for (i = 0; i < NR_PORTS; i++) { + if ((info = rs_table[i].info)) { + rs_table[i].info = NULL; + kfree(info); + } + if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port) { + release_region(rs_table[i].port, 8); + } + } + if (tmp_buf) { + unsigned long pg = (unsigned long) tmp_buf; + tmp_buf = NULL; + free_page(pg); + } +} + +module_init(rs_init); +module_exit(rs_fini); +MODULE_DESCRIPTION("Au1x00 serial driver"); + + +/* + * ------------------------------------------------------------ + * Serial console driver + * ------------------------------------------------------------ + */ +#ifdef CONFIG_AU1X00_SERIAL_CONSOLE + +#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) + +static struct async_struct async_sercons; + +/* + * Wait for transmitter & holding register to empty + */ +static inline void wait_for_xmitr(struct async_struct *info) +{ + unsigned int status, tmout = 0xffffff; + + do { + status = serial_in(info, UART_LSR); + + if (status & UART_LSR_BI) + lsr_break_flag = UART_LSR_BI; + + if (--tmout == 0) + break; + } while((status & BOTH_EMPTY) != BOTH_EMPTY); +} + + +/* + * Print a string to the serial port trying not to disturb + * any possible real use of the port... + * + * The console_lock must be held when we get here. + */ +static void serial_console_write(struct console *co, const char *s, + unsigned count) +{ + static struct async_struct *info = &async_sercons; + int ier; + unsigned i; + + /* + * First save the IER then disable the interrupts + */ + ier = serial_in(info, UART_IER); + serial_out(info, UART_IER, 0x00); + + /* + * Now, do each character + */ + for (i = 0; i < count; i++, s++) { + wait_for_xmitr(info); + + /* + * Send the character out. + * If a LF, also do CR... + */ + serial_out(info, UART_TX, *s); + if (*s == 10) { + wait_for_xmitr(info); + serial_out(info, UART_TX, 13); + } + } + + /* + * Finally, Wait for transmitter & holding register to empty + * and restore the IER + */ + wait_for_xmitr(info); + serial_out(info, UART_IER, ier); +} + +/* + * Receive character from the serial port + */ +static int serial_console_wait_key(struct console *co) +{ + static struct async_struct *info; + int ier, c; + + info = &async_sercons; + + /* + * First save the IER then disable the interrupts so + * that the real driver for the port does not get the + * character. + */ + ier = serial_in(info, UART_IER); + serial_out(info, UART_IER, 0x00); + + while ((serial_in(info, UART_LSR) & UART_LSR_DR) == 0); + c = serial_in(info, UART_RX); + + /* + * Restore the interrupts + */ + serial_out(info, UART_IER, ier); + + return c; +} + +static kdev_t serial_console_device(struct console *c) +{ + return MKDEV(TTY_MAJOR, 64 + c->index); +} + +/* + * Setup initial baud/bits/parity. We do two things here: + * - construct a cflag setting for the first rs_open() + * - initialize the serial port + * Return non-zero if we didn't find a serial port. + */ +static int __init serial_console_setup(struct console *co, char *options) +{ + static struct async_struct *info; + struct serial_state *state; + unsigned cval; + int baud = 9600; + int bits = 8; + int parity = 'n'; + int cflag = CREAD | HUPCL | CLOCAL; + int quot = 0; + char *s; + + if (options) { + baud = simple_strtoul(options, NULL, 10); + s = options; + while(*s >= '0' && *s <= '9') + s++; + if (*s) parity = *s++; + if (*s) bits = *s - '0'; + } + + /* + * Now construct a cflag setting. + */ + switch(baud) { + case 1200: + cflag |= B1200; + break; + case 2400: + cflag |= B2400; + break; + case 4800: + cflag |= B4800; + break; + case 19200: + cflag |= B19200; + break; + case 38400: + cflag |= B38400; + break; + case 57600: + cflag |= B57600; + break; + case 115200: + cflag |= B115200; + break; + case 9600: + default: + cflag |= B9600; + break; + } + switch(bits) { + case 7: + cflag |= CS7; + break; + default: + case 8: + cflag |= CS8; + break; + } + switch(parity) { + case 'o': case 'O': + cflag |= PARODD; + break; + case 'e': case 'E': + cflag |= PARENB; + break; + } + co->cflag = cflag; + + /* + * Divisor, bytesize and parity + */ + state = rs_table + co->index; + info = &async_sercons; + info->magic = SERIAL_MAGIC; + info->state = state; + info->port = state->port; + info->flags = state->flags; + info->io_type = state->io_type; + info->iomem_base = state->iomem_base; + info->iomem_reg_shift = state->iomem_reg_shift; + state->baud_base = get_au1x00_uart_baud_base(); + quot = state->baud_base / baud; + + cval = cflag & (CSIZE | CSTOPB); + cval >>= 4; + if (cflag & PARENB) + cval |= UART_LCR_PARITY; + if (!(cflag & PARODD)) + cval |= UART_LCR_EPAR; + + /* + * Disable UART interrupts, set DTR and RTS high + * and set speed. + */ + serial_out(info, UART_CLK, quot & 0xffff); + serial_out(info, UART_IER, 0); + serial_out(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS); + + /* + * If we read 0xff from the LSR, there is no UART here. + */ + if (serial_in(info, UART_LSR) == 0xff) + return -1; + + return 0; +} + +static struct console sercons = { + .name = "ttyS", + .write = serial_console_write, + .device = serial_console_device, + .setup = serial_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +/* + * Register console. + */ +void __init au1x00_serial_console_init(void) +{ + register_console(&sercons); +} +#endif + +/* + Local variables: + compile-command: "gcc -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -fno-strength-reduce -march=i586 -DMODULE -DMODVERSIONS -include ../../include/linux/modversions.h -DEXPORT_SYMTAB -c serial.c" + End: +*/ diff -urN linux-2.4.21-bk37/drivers/char/decserial.c linux-2.4.21-bk38/drivers/char/decserial.c --- linux-2.4.21-bk37/drivers/char/decserial.c 2001-09-09 10:43:02.000000000 -0700 +++ linux-2.4.21-bk38/drivers/char/decserial.c 2003-08-24 02:56:03.000000000 -0700 @@ -28,7 +28,7 @@ extern int dz_init(void); #endif -#ifdef CONFIG_SERIAL_CONSOLE +#ifdef CONFIG_SERIAL_DEC_CONSOLE #ifdef CONFIG_ZS extern void zs_serial_console_init(void); @@ -43,7 +43,7 @@ /* rs_init - starts up the serial interface - handle normal case of starting up the serial interface */ -#ifdef CONFIG_SERIAL +#ifdef CONFIG_SERIAL_DEC int __init rs_init(void) { @@ -70,12 +70,12 @@ #endif -#ifdef CONFIG_SERIAL_CONSOLE +#ifdef CONFIG_SERIAL_DEC_CONSOLE -/* serial_console_init handles the special case of starting +/* dec_serial_console_init handles the special case of starting * up the console on the serial port */ -void __init serial_console_init(void) +void __init dec_serial_console_init(void) { #if defined(CONFIG_ZS) && defined(CONFIG_DZ) if (IOASIC) diff -urN linux-2.4.21-bk37/drivers/char/ds1286.c linux-2.4.21-bk38/drivers/char/ds1286.c --- linux-2.4.21-bk37/drivers/char/ds1286.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/drivers/char/ds1286.c 2003-08-24 02:56:03.000000000 -0700 @@ -0,0 +1,529 @@ +/* + * DS1286 Real Time Clock interface for Linux + * + * Copyright (C) 1998, 1999, 2000 Ralf Baechle + * + * Based on code written by Paul Gortmaker. + * + * This driver allows use of the real time clock (built into nearly all + * computers) from user space. It exports the /dev/rtc interface supporting + * various ioctl() and also the /proc/rtc pseudo-file for status + * information. + * + * The ioctls can be used to set the interrupt behaviour and generation rate + * from the RTC via IRQ 8. Then the /dev/rtc interface can be used to make + * use of these timer interrupts, be they interval or alarm based. + * + * The /dev/rtc interface will block on reads until an interrupt has been + * received. If a RTC interrupt has already happened, it will output an + * unsigned long and then block. The output value contains the interrupt + * status in the low byte and the number of interrupts since the last read + * in the remaining high bytes. The /dev/rtc interface can also be used with + * the select(2) call. + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define DS1286_VERSION "1.0" + +/* + * We sponge a minor off of the misc major. No need slurping + * up another valuable major dev number for this. If you add + * an ioctl, make sure you don't conflict with SPARC's RTC + * ioctls. + */ + +static DECLARE_WAIT_QUEUE_HEAD(ds1286_wait); + +static ssize_t ds1286_read(struct file *file, char *buf, + size_t count, loff_t *ppos); + +static int ds1286_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); + +static unsigned int ds1286_poll(struct file *file, poll_table *wait); + +void ds1286_get_alm_time (struct rtc_time *alm_tm); +void ds1286_get_time(struct rtc_time *rtc_tm); +int ds1286_set_time(struct rtc_time *rtc_tm); + +void set_rtc_irq_bit(unsigned char bit); +void clear_rtc_irq_bit(unsigned char bit); + +static inline unsigned char ds1286_is_updating(void); + +static spinlock_t ds1286_lock = SPIN_LOCK_UNLOCKED; + +/* + * Bits in rtc_status. (7 bits of room for future expansion) + */ + +#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ +#define RTC_TIMER_ON 0x02 /* missed irq timer active */ + +unsigned char ds1286_status; /* bitmapped status byte. */ +unsigned long ds1286_freq; /* Current periodic IRQ rate */ + +unsigned char days_in_mo[] = +{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +/* + * Now all the various file operations that we export. + */ + +static ssize_t ds1286_read(struct file *file, char *buf, + size_t count, loff_t *ppos) +{ + return -EIO; +} + +static int ds1286_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + + struct rtc_time wtime; + + switch (cmd) { + case RTC_AIE_OFF: /* Mask alarm int. enab. bit */ + { + unsigned int flags; + unsigned char val; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + spin_lock_irqsave(&ds1286_lock, flags); + val = CMOS_READ(RTC_CMD); + val |= RTC_TDM; + CMOS_WRITE(val, RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + return 0; + } + case RTC_AIE_ON: /* Allow alarm interrupts. */ + { + unsigned int flags; + unsigned char val; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + spin_lock_irqsave(&ds1286_lock, flags); + val = CMOS_READ(RTC_CMD); + val &= ~RTC_TDM; + CMOS_WRITE(val, RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + return 0; + } + case RTC_WIE_OFF: /* Mask watchdog int. enab. bit */ + { + unsigned int flags; + unsigned char val; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + spin_lock_irqsave(&ds1286_lock, flags); + val = CMOS_READ(RTC_CMD); + val |= RTC_WAM; + CMOS_WRITE(val, RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + return 0; + } + case RTC_WIE_ON: /* Allow watchdog interrupts. */ + { + unsigned int flags; + unsigned char val; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + spin_lock_irqsave(&ds1286_lock, flags); + val = CMOS_READ(RTC_CMD); + val &= ~RTC_WAM; + CMOS_WRITE(val, RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + return 0; + } + case RTC_ALM_READ: /* Read the present alarm time */ + { + /* + * This returns a struct rtc_time. Reading >= 0xc0 + * means "don't care" or "match all". Only the tm_hour, + * tm_min, and tm_sec values are filled in. + */ + + ds1286_get_alm_time(&wtime); + break; + } + case RTC_ALM_SET: /* Store a time into the alarm */ + { + /* + * This expects a struct rtc_time. Writing 0xff means + * "don't care" or "match all". Only the tm_hour, + * tm_min and tm_sec are used. + */ + unsigned char hrs, min, sec; + struct rtc_time alm_tm; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&alm_tm, (struct rtc_time*)arg, + sizeof(struct rtc_time))) + return -EFAULT; + + hrs = alm_tm.tm_hour; + min = alm_tm.tm_min; + + if (hrs >= 24) + hrs = 0xff; + + if (min >= 60) + min = 0xff; + + BIN_TO_BCD(sec); + BIN_TO_BCD(min); + BIN_TO_BCD(hrs); + + spin_lock(&ds1286_lock); + CMOS_WRITE(hrs, RTC_HOURS_ALARM); + CMOS_WRITE(min, RTC_MINUTES_ALARM); + spin_unlock(&ds1286_lock); + + return 0; + } + case RTC_RD_TIME: /* Read the time/date from RTC */ + { + ds1286_get_time(&wtime); + break; + } + case RTC_SET_TIME: /* Set the RTC */ + { + struct rtc_time rtc_tm; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, + sizeof(struct rtc_time))) + return -EFAULT; + + return ds1286_set_time(&rtc_tm); + } + default: + return -EINVAL; + } + return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; +} + +/* + * We enforce only one user at a time here with the open/close. + * Also clear the previous interrupt data on an open, and clean + * up things on a close. + */ + +static int ds1286_open(struct inode *inode, struct file *file) +{ + spin_lock_irq(&ds1286_lock); + + if (ds1286_status & RTC_IS_OPEN) + goto out_busy; + + ds1286_status |= RTC_IS_OPEN; + + spin_lock_irq(&ds1286_lock); + return 0; + +out_busy: + spin_lock_irq(&ds1286_lock); + return -EBUSY; +} + +static int ds1286_release(struct inode *inode, struct file *file) +{ + ds1286_status &= ~RTC_IS_OPEN; + + return 0; +} + +static unsigned int ds1286_poll(struct file *file, poll_table *wait) +{ + poll_wait(file, &ds1286_wait, wait); + + return 0; +} + +/* + * The various file operations we support. + */ + +static struct file_operations ds1286_fops = { + .llseek = no_llseek, + .read = ds1286_read, + .poll = ds1286_poll, + .ioctl = ds1286_ioctl, + .open = ds1286_open, + .release = ds1286_release, +}; + +static struct miscdevice ds1286_dev= +{ + .minor = RTC_MINOR, + .name = "rtc", + .fops = &ds1286_fops, +}; + +int __init ds1286_init(void) +{ + printk(KERN_INFO "DS1286 Real Time Clock Driver v%s\n", DS1286_VERSION); + return misc_register(&ds1286_dev); +} + +static char *days[] = { + "***", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" +}; + +/* + * Info exported via "/proc/rtc". + */ +int get_ds1286_status(char *buf) +{ + char *p, *s; + struct rtc_time tm; + unsigned char hundredth, month, cmd, amode; + + p = buf; + + ds1286_get_time(&tm); + hundredth = CMOS_READ(RTC_HUNDREDTH_SECOND); + BCD_TO_BIN(hundredth); + + p += sprintf(p, + "rtc_time\t: %02d:%02d:%02d.%02d\n" + "rtc_date\t: %04d-%02d-%02d\n", + tm.tm_hour, tm.tm_min, tm.tm_sec, hundredth, + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); + + /* + * We implicitly assume 24hr mode here. Alarm values >= 0xc0 will + * match any value for that particular field. Values that are + * greater than a valid time, but less than 0xc0 shouldn't appear. + */ + ds1286_get_alm_time(&tm); + p += sprintf(p, "alarm\t\t: %s ", days[tm.tm_wday]); + if (tm.tm_hour <= 24) + p += sprintf(p, "%02d:", tm.tm_hour); + else + p += sprintf(p, "**:"); + + if (tm.tm_min <= 59) + p += sprintf(p, "%02d\n", tm.tm_min); + else + p += sprintf(p, "**\n"); + + month = CMOS_READ(RTC_MONTH); + p += sprintf(p, + "oscillator\t: %s\n" + "square_wave\t: %s\n", + (month & RTC_EOSC) ? "disabled" : "enabled", + (month & RTC_ESQW) ? "disabled" : "enabled"); + + amode = ((CMOS_READ(RTC_MINUTES_ALARM) & 0x80) >> 5) | + ((CMOS_READ(RTC_HOURS_ALARM) & 0x80) >> 6) | + ((CMOS_READ(RTC_DAY_ALARM) & 0x80) >> 7); + if (amode == 7) s = "each minute"; + else if (amode == 3) s = "minutes match"; + else if (amode == 1) s = "hours and minutes match"; + else if (amode == 0) s = "days, hours and minutes match"; + else s = "invalid"; + p += sprintf(p, "alarm_mode\t: %s\n", s); + + cmd = CMOS_READ(RTC_CMD); + p += sprintf(p, + "alarm_enable\t: %s\n" + "wdog_alarm\t: %s\n" + "alarm_mask\t: %s\n" + "wdog_alarm_mask\t: %s\n" + "interrupt_mode\t: %s\n" + "INTB_mode\t: %s_active\n" + "interrupt_pins\t: %s\n", + (cmd & RTC_TDF) ? "yes" : "no", + (cmd & RTC_WAF) ? "yes" : "no", + (cmd & RTC_TDM) ? "disabled" : "enabled", + (cmd & RTC_WAM) ? "disabled" : "enabled", + (cmd & RTC_PU_LVL) ? "pulse" : "level", + (cmd & RTC_IBH_LO) ? "low" : "high", + (cmd & RTC_IPSW) ? "unswapped" : "swapped"); + + return p - buf; +} + +/* + * Returns true if a clock update is in progress + */ +static inline unsigned char ds1286_is_updating(void) +{ + return CMOS_READ(RTC_CMD) & RTC_TE; +} + + +void ds1286_get_time(struct rtc_time *rtc_tm) +{ + unsigned char save_control; + unsigned int flags; + unsigned long uip_watchdog = jiffies; + + /* + * read RTC once any update in progress is done. The update + * can take just over 2ms. We wait 10 to 20ms. There is no need to + * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. + * If you need to know *exactly* when a second has started, enable + * periodic update complete interrupts, (via ioctl) and then + * immediately read /dev/rtc which will block until you get the IRQ. + * Once the read clears, read the RTC time (again via ioctl). Easy. + */ + + if (ds1286_is_updating() != 0) + while (jiffies - uip_watchdog < 2*HZ/100) + barrier(); + + /* + * Only the values that we read from the RTC are set. We leave + * tm_wday, tm_yday and tm_isdst untouched. Even though the + * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated + * by the RTC when initially set to a non-zero value. + */ + spin_lock_irqsave(&ds1286_lock, flags); + save_control = CMOS_READ(RTC_CMD); + CMOS_WRITE((save_control|RTC_TE), RTC_CMD); + + rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); + rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); + rtc_tm->tm_hour = CMOS_READ(RTC_HOURS) & 0x1f; + rtc_tm->tm_mday = CMOS_READ(RTC_DATE); + rtc_tm->tm_mon = CMOS_READ(RTC_MONTH) & 0x1f; + rtc_tm->tm_year = CMOS_READ(RTC_YEAR); + + CMOS_WRITE(save_control, RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + BCD_TO_BIN(rtc_tm->tm_sec); + BCD_TO_BIN(rtc_tm->tm_min); + BCD_TO_BIN(rtc_tm->tm_hour); + BCD_TO_BIN(rtc_tm->tm_mday); + BCD_TO_BIN(rtc_tm->tm_mon); + BCD_TO_BIN(rtc_tm->tm_year); + + /* + * Account for differences between how the RTC uses the values + * and how they are defined in a struct rtc_time; + */ + if (rtc_tm->tm_year < 45) + rtc_tm->tm_year += 30; + if ((rtc_tm->tm_year += 40) < 70) + rtc_tm->tm_year += 100; + + rtc_tm->tm_mon--; +} + +int ds1286_set_time(struct rtc_time *rtc_tm) +{ + unsigned char mon, day, hrs, min, sec, leap_yr; + unsigned char save_control; + unsigned int yrs, flags; + + + yrs = rtc_tm->tm_year + 1900; + mon = rtc_tm->tm_mon + 1; /* tm_mon starts at zero */ + day = rtc_tm->tm_mday; + hrs = rtc_tm->tm_hour; + min = rtc_tm->tm_min; + sec = rtc_tm->tm_sec; + + if (yrs < 1970) + return -EINVAL; + + leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); + + if ((mon > 12) || (day == 0)) + return -EINVAL; + + if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) + return -EINVAL; + + if ((hrs >= 24) || (min >= 60) || (sec >= 60)) + return -EINVAL; + + if ((yrs -= 1940) > 255) /* They are unsigned */ + return -EINVAL; + + if (yrs >= 100) + yrs -= 100; + + BIN_TO_BCD(sec); + BIN_TO_BCD(min); + BIN_TO_BCD(hrs); + BIN_TO_BCD(day); + BIN_TO_BCD(mon); + BIN_TO_BCD(yrs); + + spin_lock_irqsave(&ds1286_lock, flags); + save_control = CMOS_READ(RTC_CMD); + CMOS_WRITE((save_control|RTC_TE), RTC_CMD); + + CMOS_WRITE(yrs, RTC_YEAR); + CMOS_WRITE(mon, RTC_MONTH); + CMOS_WRITE(day, RTC_DATE); + CMOS_WRITE(hrs, RTC_HOURS); + CMOS_WRITE(min, RTC_MINUTES); + CMOS_WRITE(sec, RTC_SECONDS); + CMOS_WRITE(0, RTC_HUNDREDTH_SECOND); + + CMOS_WRITE(save_control, RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + return 0; +} + +void ds1286_get_alm_time(struct rtc_time *alm_tm) +{ + unsigned char cmd; + unsigned int flags; + + /* + * Only the values that we read from the RTC are set. That + * means only tm_wday, tm_hour, tm_min. + */ + spin_lock_irqsave(&ds1286_lock, flags); + alm_tm->tm_min = CMOS_READ(RTC_MINUTES_ALARM) & 0x7f; + alm_tm->tm_hour = CMOS_READ(RTC_HOURS_ALARM) & 0x1f; + alm_tm->tm_wday = CMOS_READ(RTC_DAY_ALARM) & 0x07; + cmd = CMOS_READ(RTC_CMD); + spin_unlock_irqrestore(&ds1286_lock, flags); + + BCD_TO_BIN(alm_tm->tm_min); + BCD_TO_BIN(alm_tm->tm_hour); + alm_tm->tm_sec = 0; +} diff -urN linux-2.4.21-bk37/drivers/char/dummy_keyb.c linux-2.4.21-bk38/drivers/char/dummy_keyb.c --- linux-2.4.21-bk37/drivers/char/dummy_keyb.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/drivers/char/dummy_keyb.c 2003-08-24 02:56:03.000000000 -0700 @@ -23,9 +23,12 @@ * CONFIG_VT. * */ + +#include #include #include #include +#include void kbd_leds(unsigned char leds) { @@ -41,6 +44,84 @@ return scancode; } +#ifdef CONFIG_INPUT +static unsigned char e0_keys[128] = { + 0, 0, 0, KEY_KPCOMMA, 0, KEY_INTL3, 0, 0, /* 0x00-0x07 */ + 0, 0, 0, 0, KEY_LANG1, KEY_LANG2, 0, 0, /* 0x08-0x0f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */ + 0, 0, 0, 0, KEY_KPENTER, KEY_RIGHTCTRL, KEY_VOLUMEUP, 0,/* 0x18-0x1f */ + 0, 0, 0, 0, 0, KEY_VOLUMEDOWN, KEY_MUTE, 0, /* 0x20-0x27 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */ + 0, 0, 0, 0, 0, KEY_KPSLASH, 0, KEY_SYSRQ, /* 0x30-0x37 */ + KEY_RIGHTALT, KEY_BRIGHTNESSUP, KEY_BRIGHTNESSDOWN, + KEY_EJECTCD, 0, 0, 0, 0, /* 0x38-0x3f */ + 0, 0, 0, 0, 0, 0, 0, KEY_HOME, /* 0x40-0x47 */ + KEY_UP, KEY_PAGEUP, 0, KEY_LEFT, 0, KEY_RIGHT, 0, KEY_END, /* 0x48-0x4f */ + KEY_DOWN, KEY_PAGEDOWN, KEY_INSERT, KEY_DELETE, 0, 0, 0, 0, /* 0x50-0x57 */ + 0, 0, 0, KEY_LEFTMETA, KEY_RIGHTMETA, KEY_COMPOSE, KEY_POWER, 0, /* 0x58-0x5f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */ + 0, 0, 0, 0, 0, 0, 0, KEY_MACRO, /* 0x68-0x6f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */ + 0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */ +}; + +int kbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode) +{ + /* This code was copied from char/pc_keyb.c and will be + * superflous when the input layer is fully integrated. + * We don't need the high_keys handling, so this part + * has been removed. + */ + static int prev_scancode = 0; + + /* special prefix scancodes.. */ + if (scancode == 0xe0 || scancode == 0xe1) { + prev_scancode = scancode; + return 0; + } + + scancode &= 0x7f; + + if (prev_scancode) { + if (prev_scancode != 0xe0) { + if (prev_scancode == 0xe1 && scancode == 0x1d) { + prev_scancode = 0x100; + return 0; + } else if (prev_scancode == 0x100 && scancode == 0x45) { + *keycode = KEY_PAUSE; + prev_scancode = 0; + } else { + if (!raw_mode) + printk(KERN_INFO "keyboard: unknown e1 escape sequence\n"); + prev_scancode = 0; + return 0; + } + } else { + prev_scancode = 0; + if (scancode == 0x2a || scancode == 0x36) + return 0; + } + if (e0_keys[scancode]) + *keycode = e0_keys[scancode]; + else { + if (!raw_mode) + printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n", + scancode); + return 0; + } + } else { + switch (scancode) { + case 91: scancode = KEY_LINEFEED; break; + case 92: scancode = KEY_KPEQUAL; break; + case 125: scancode = KEY_INTL1; break; + } + *keycode = scancode; + } + return 1; +} + +#else int kbd_translate(unsigned char scancode, unsigned char *keycode, char raw_mode) { @@ -48,6 +129,7 @@ return 1; } +#endif char kbd_unexpected_up(unsigned char keycode) { diff -urN linux-2.4.21-bk37/drivers/char/dz.c linux-2.4.21-bk38/drivers/char/dz.c --- linux-2.4.21-bk37/drivers/char/dz.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/drivers/char/dz.c 2003-08-24 02:56:03.000000000 -0700 @@ -35,28 +35,27 @@ #include #include #include -#include -#include #include #include #include #include -#include -#include -#include -#include -#include - #include #include + #include +#include +#include +#include +#include +#include +#include +#include +#include #define CONSOLE_LINE (3) /* for definition of struct console */ -extern int (*prom_printf) (char *,...); - #include "dz.h" #define DZ_INTR_DEBUG 1 @@ -211,13 +210,12 @@ if (!(status & DZ_DVAL)) goto ignore_char; - ch = UCHAR(status); /* grab the char */ #if 0 if (info->is_console) { if (ch == 0) - return; /* it's a break ... */ + return; /* it's a break ... */ } #endif @@ -862,7 +860,7 @@ tmp.type = info->type; tmp.line = info->line; tmp.port = info->port; - tmp.irq = SERIAL; + tmp.irq = dec_interrupt[DEC_IRQ_DZ11]; tmp.flags = info->flags; tmp.baud_base = info->baud_base; tmp.close_delay = info->close_delay; @@ -1404,7 +1402,7 @@ return 0; printk("ttyS%02d at 0x%08x (irq = %d)\n", info->line, - info->port, SERIAL); + info->port, dec_interrupt[DEC_IRQ_DZ11]); tty_register_devfs(&serial_driver, 0, serial_driver.minor_start + info->line); @@ -1413,10 +1411,10 @@ } /* reset the chip */ -#ifndef CONFIG_SERIAL_CONSOLE +#ifndef CONFIG_SERIAL_DEC_CONSOLE dz_out(info, DZ_CSR, DZ_CLR); while ((tmp = dz_in(info, DZ_CSR)) & DZ_CLR); - wbflush(); + iob(); /* enable scanning */ dz_out(info, DZ_CSR, DZ_MSE); @@ -1428,13 +1426,14 @@ restore_flags(flags); - if (request_irq(SERIAL, dz_interrupt, SA_INTERRUPT, "DZ", lines[0])) + if (request_irq(dec_interrupt[DEC_IRQ_DZ11], dz_interrupt, + SA_INTERRUPT, "DZ", lines[0])) panic("Unable to register DZ interrupt"); return 0; } -#ifdef CONFIG_SERIAL_CONSOLE +#ifdef CONFIG_SERIAL_DEC_CONSOLE static void dz_console_put_char(unsigned char ch) { unsigned long flags; @@ -1575,12 +1574,12 @@ static struct console dz_sercons = { - name: "ttyS", - write: dz_console_print, - device: dz_console_device, - setup: dz_console_setup, - flags: CON_CONSDEV | CON_PRINTBUFFER, - index: CONSOLE_LINE, + .name = "ttyS", + .write = dz_console_print, + .device = dz_console_device, + .setup = dz_console_setup, + .flags = CON_CONSDEV | CON_PRINTBUFFER, + .index = CONSOLE_LINE, }; void __init dz_serial_console_init(void) @@ -1588,6 +1587,6 @@ register_console(&dz_sercons); } -#endif /* CONFIG_SERIAL_CONSOLE */ +#endif /* CONFIG_SERIAL_DEC_CONSOLE */ MODULE_LICENSE("GPL"); diff -urN linux-2.4.21-bk37/drivers/char/indydog.c linux-2.4.21-bk38/drivers/char/indydog.c --- linux-2.4.21-bk37/drivers/char/indydog.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.21-bk38/drivers/char/indydog.c 2003-08-24 02:56:03.000000000 -0700 @@ -22,10 +22,9 @@ #include #include #include -#include +#include static unsigned long indydog_alive; -static struct sgimc_misc_ctrl *mcmisc_regs; static int expect_close = 0; #ifdef CONFIG_WATCHDOG_NOWAYOUT @@ -37,56 +36,51 @@ MODULE_PARM(nowayout,"i"); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); -static void indydog_ping() +static inline void indydog_ping(void) { - mcmisc_regs->watchdogt = 0; + sgimc->watchdogt = 0; } - /* * Allow only one person to hold it open */ - static int indydog_open(struct inode *inode, struct file *file) { u32 mc_ctrl0; - if( test_and_set_bit(0,&indydog_alive) ) + if (test_and_set_bit(0,&indydog_alive)) return -EBUSY; + if (nowayout) { MOD_INC_USE_COUNT; } - /* - * Activate timer - */ - mcmisc_regs = (struct sgimc_misc_ctrl *)(KSEG1+0x1fa00000); - mc_ctrl0 = mcmisc_regs->cpuctrl0 | SGIMC_CCTRL0_WDOG; - mcmisc_regs->cpuctrl0 = mc_ctrl0; + /* Activate timer */ + mc_ctrl0 = sgimc->cpuctrl0 | SGIMC_CCTRL0_WDOG; + sgimc->cpuctrl0 = mc_ctrl0; indydog_ping(); - printk("Started watchdog timer.\n"); + indydog_alive = 1; + printk(KERN_INFO "Started watchdog timer.\n"); + return 0; } static int indydog_release(struct inode *inode, struct file *file) { - /* - * Shut off the timer. - * Lock it in if it's a module and we set nowayout. - */ - if (expect_close) - { - u32 mc_ctrl0 = mcmisc_regs->cpuctrl0; + /* Shut off the timer. + * Lock it in if it's a module and we set nowayout. */ + lock_kernel(); + if (expect_close) { + u32 mc_ctrl0 = sgimc->cpuctrl0; mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG; - mcmisc_regs->cpuctrl0 = mc_ctrl0; - printk("Stopped watchdog timer.\n"); - } - else - { + sgimc->cpuctrl0 = mc_ctrl0; + printk(KERN_INFO "Stopped watchdog timer.\n"); + } else printk(KERN_CRIT "WDT device closed unexpectedly. WDT will not stop!\n"); - } - clear_bit(0,&indydog_alive); + clear_bit(0, &indydog_alive); + unlock_kernel(); + return 0; } @@ -99,13 +93,13 @@ /* * Refresh the timer. */ - if(len) { + if (len) { if (!nowayout) { size_t i; /* In case it was set long ago */ expect_close = 0; - + for (i = 0; i != len; i++) { char c; if (get_user(c, data + i)) @@ -161,9 +155,7 @@ static int __init watchdog_init(void) { - int ret; - - ret = misc_register(&indydog_miscdev); + int ret = misc_register(&indydog_miscdev); if (ret) return ret; diff -urN linux-2.4.21-bk37/drivers/char/ip27-rtc.c linux-2.4.21-bk38/drivers/char/ip27-rtc.c --- linux-2.4.21-bk37/drivers/char/ip27-rtc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/drivers/char/ip27-rtc.c 2003-08-24 02:56:03.000000000 -0700 @@ -0,0 +1,326 @@ +/* + * Driver for the SGS-Thomson M48T35 Timekeeper RAM chip + * + * Real Time Clock interface for Linux + * + * TODO: Implement periodic interrupts. + * + * Copyright (C) 2000 Silicon Graphics, Inc. + * Written by Ulf Carlsson (ulfc@engr.sgi.com) + * + * Based on code written by Paul Gortmaker. + * + * This driver allows use of the real time clock (built into + * nearly all computers) from user space. It exports the /dev/rtc + * interface supporting various ioctl() and also the /proc/rtc + * pseudo-file for status information. + * + * 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. + * + */ + +#define RTC_VERSION "1.09b" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static int rtc_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); + +static int rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data); + +static void get_rtc_time(struct rtc_time *rtc_tm); + +/* + * Bits in rtc_status. (6 bits of room for future expansion) + */ + +#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ +#define RTC_TIMER_ON 0x02 /* missed irq timer active */ + +static unsigned char rtc_status; /* bitmapped status byte. */ +static unsigned long rtc_freq; /* Current periodic IRQ rate */ +static struct m48t35_rtc *rtc; + +/* + * If this driver ever becomes modularised, it will be really nice + * to make the epoch retain its value across module reload... + */ + +static unsigned long epoch = 1970; /* year corresponding to 0x00 */ + +static const unsigned char days_in_mo[] = +{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + + struct rtc_time wtime; + + switch (cmd) { + case RTC_RD_TIME: /* Read the time/date from RTC */ + { + get_rtc_time(&wtime); + break; + } + case RTC_SET_TIME: /* Set the RTC */ + { + struct rtc_time rtc_tm; + unsigned char mon, day, hrs, min, sec, leap_yr; + unsigned int yrs; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, + sizeof(struct rtc_time))) + return -EFAULT; + + yrs = rtc_tm.tm_year + 1900; + mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ + day = rtc_tm.tm_mday; + hrs = rtc_tm.tm_hour; + min = rtc_tm.tm_min; + sec = rtc_tm.tm_sec; + + if (yrs < 1970) + return -EINVAL; + + leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); + + if ((mon > 12) || (day == 0)) + return -EINVAL; + + if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) + return -EINVAL; + + if ((hrs >= 24) || (min >= 60) || (sec >= 60)) + return -EINVAL; + + if ((yrs -= epoch) > 255) /* They are unsigned */ + return -EINVAL; + + if (yrs > 169) { + return -EINVAL; + } + if (yrs >= 100) + yrs -= 100; + + BIN_TO_BCD(sec); + BIN_TO_BCD(min); + BIN_TO_BCD(hrs); + BIN_TO_BCD(day); + BIN_TO_BCD(mon); + BIN_TO_BCD(yrs); + + spin_lock_irq(&rtc_lock); + rtc->control |= M48T35_RTC_SET; + rtc->year = yrs; + rtc->month = mon; + rtc->date = day; + rtc->hour = hrs; + rtc->min = min; + rtc->sec = sec; + rtc->control &= ~M48T35_RTC_SET; + spin_unlock_irq(&rtc_lock); + + return 0; + } + default: + return -EINVAL; + } + return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; +} + +/* + * We enforce only one user at a time here with the open/close. + * Also clear the previous interrupt data on an open, and clean + * up things on a close. + */ + +static int rtc_open(struct inode *inode, struct file *file) +{ + spin_lock_irq(&rtc_lock); + + if (rtc_status & RTC_IS_OPEN) { + spin_unlock_irq(&rtc_lock); + return -EBUSY; + } + + rtc_status |= RTC_IS_OPEN; + spin_unlock_irq(&rtc_lock); + + return 0; +} + +static int rtc_release(struct inode *inode, struct file *file) +{ + /* + * No need for locking -- nobody else can do anything until this rmw + * is committed, and no timer is running. + */ + rtc_status &= ~RTC_IS_OPEN; + + return 0; +} + +/* + * The various file operations we support. + */ + +static struct file_operations rtc_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .ioctl = rtc_ioctl, + .open = rtc_open, + .release = rtc_release, +}; + +static struct miscdevice rtc_dev= +{ + RTC_MINOR, + "rtc", + &rtc_fops +}; + +static int __init rtc_init(void) +{ + nasid_t nid; + + nid = get_nasid(); + rtc = (struct m48t35_rtc *) + (KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0); + + printk(KERN_INFO "Real Time Clock Driver v%s\n", RTC_VERSION); + if (misc_register(&rtc_dev)) { + printk(KERN_ERR "rtc: cannot register misc device.\n"); + return -ENODEV; + } + if (!create_proc_read_entry("driver/rtc", 0, NULL, rtc_read_proc, NULL)) { + printk(KERN_ERR "rtc: cannot create /proc/rtc.\n"); + misc_deregister(&rtc_dev); + return -ENOENT; + } + + + rtc_freq = 1024; + return 0; +} + +static void __exit rtc_exit (void) +{ + /* interrupts and timer disabled at this point by rtc_release */ + + remove_proc_entry ("rtc", NULL); + misc_deregister(&rtc_dev); +} + +module_init(rtc_init); +module_exit(rtc_exit); + +/* + * Info exported via "/proc/rtc". + */ + +static int rtc_get_status(char *buf) +{ + char *p; + struct rtc_time tm; + + /* + * Just emulate the standard /proc/rtc + */ + + p = buf; + + get_rtc_time(&tm); + + /* + * There is no way to tell if the luser has the RTC set for local + * time or for Universal Standard Time (GMT). Probably local though. + */ + p += sprintf(p, + "rtc_time\t: %02d:%02d:%02d\n" + "rtc_date\t: %04d-%02d-%02d\n" + "rtc_epoch\t: %04lu\n" + "24hr\t\t: yes\n", + tm.tm_hour, tm.tm_min, tm.tm_sec, + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch); + + return p - buf; +} + +static int rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = rtc_get_status(page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; +} + +static void get_rtc_time(struct rtc_time *rtc_tm) +{ + /* + * Do we need to wait for the last update to finish? + */ + + /* + * Only the values that we read from the RTC are set. We leave + * tm_wday, tm_yday and tm_isdst untouched. Even though the + * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated + * by the RTC when initially set to a non-zero value. + */ + spin_lock_irq(&rtc_lock); + rtc->control |= M48T35_RTC_READ; + rtc_tm->tm_sec = rtc->sec; + rtc_tm->tm_min = rtc->min; + rtc_tm->tm_hour = rtc->hour; + rtc_tm->tm_mday = rtc->date; + rtc_tm->tm_mon = rtc->month; + rtc_tm->tm_year = rtc->year; + rtc->control &= ~M48T35_RTC_READ; + spin_unlock_irq(&rtc_lock); + + BCD_TO_BIN(rtc_tm->tm_sec); + BCD_TO_BIN(rtc_tm->tm_min); + BCD_TO_BIN(rtc_tm->tm_hour); + BCD_TO_BIN(rtc_tm->tm_mday); + BCD_TO_BIN(rtc_tm->tm_mon); + BCD_TO_BIN(rtc_tm->tm_year); + + /* + * Account for differences between how the RTC uses the values + * and how they are defined in a struct rtc_time; + */ + if ((rtc_tm->tm_year += (epoch - 1900)) <= 69) + rtc_tm->tm_year += 100; + + rtc_tm->tm_mon--; +} diff -urN linux-2.4.21-bk37/drivers/char/ite_gpio.c linux-2.4.21-bk38/drivers/char/ite_gpio.c --- linux-2.4.21-bk37/drivers/char/ite_gpio.c 2001-09-09 10:43:02.000000000 -0700 +++ linux-2.4.21-bk38/drivers/char/ite_gpio.c 2003-08-24 02:56:03.000000000 -0700 @@ -30,9 +30,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include -#include #include #include #include diff -urN linux-2.4.21-bk37/drivers/char/keyboard.c linux-2.4.21-bk38/drivers/char/keyboard.c --- linux-2.4.21-bk37/drivers/char/keyboard.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.21-bk38/drivers/char/keyboard.c 2003-08-24 02:56:03.000000000 -0700 @@ -336,21 +336,6 @@ schedule_console_callback(); } -#ifdef CONFIG_FORWARD_KEYBOARD -extern int forward_chars; - -void put_queue(int ch) -{ - if (forward_chars == fg_console+1){ - kbd_forward_char (ch); - } else { - if (tty) { - tty_insert_flip_char(tty, ch, 0); - con_schedule_flip(tty); - } - } -} -#else void put_queue(int ch) { if (tty) { @@ -358,7 +343,6 @@ con_schedule_flip(tty); } } -#endif static void puts_queue(char *cp) { diff -urN linux-2.4.21-bk37/drivers/char/lcd.c linux-2.4.21-bk38/drivers/char/lcd.c --- linux-2.4.21-bk37/drivers/char/lcd.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/drivers/char/lcd.c 2003-08-24 02:56:03.000000000 -0700 @@ -14,6 +14,7 @@ #define RTC_IO_EXTENT 0x10 /*Only really two ports, but... */ +#include #include #include #include diff -urN linux-2.4.21-bk37/drivers/char/lcd.h linux-2.4.21-bk38/drivers/char/lcd.h --- linux-2.4.21-bk37/drivers/char/lcd.h 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/drivers/char/lcd.h 2003-08-24 02:56:03.000000000 -0700 @@ -37,10 +37,10 @@ #define LCD_DRIVER "Cobalt LCD Driver v2.10" -#define kLCD_IR 0xBF000000 -#define kLCD_DR 0xBF000010 -#define kGPI 0xBD000000 -#define kLED 0xBC000000 +#define kLCD_IR 0x0F000000 +#define kLCD_DR 0x0F000010 +#define kGPI 0x0D000000 +#define kLED 0x0C000000 #define kDD_R00 0x00 #define kDD_R01 0x27 @@ -53,7 +53,7 @@ // Flash definitions AMD 29F040 -#define kFlashBase 0xBFC00000 +#define kFlashBase 0x0FC00000 #define kFlash_Addr1 0x5555 #define kFlash_Addr2 0x2AAA @@ -74,21 +74,21 @@ // Macros -#define LCDWriteData(x) (*(volatile unsigned long *) kLCD_DR) = (x << 24) -#define LCDWriteInst(x) (*(volatile unsigned long *) kLCD_IR) = (x << 24) +#define LCDWriteData(x) outl((x << 24), kLCD_DR) +#define LCDWriteInst(x) outl((x << 24), kLCD_IR) -#define LCDReadData (((*(volatile unsigned long *) kLCD_DR) >> 24)) -#define LCDReadInst (((*(volatile unsigned long *) kLCD_IR) >> 24)) +#define LCDReadData (inl(kLCD_DR) >> 24) +#define LCDReadInst (inl(kLCD_IR) >> 24) -#define GPIRead (( (*(volatile unsigned long *) kGPI) >> 24)) +#define GPIRead (inl(kGPI) >> 24) -#define LEDSet(x) (*(volatile unsigned char *) kLED) = ((char)x) +#define LEDSet(x) outb((char)x, kLED) -#define WRITE_GAL(x,y) (*((volatile unsigned long *) (0xB4000000 | (x)) ) =y) -#define BusyCheck() while ((LCDReadInst & 0x80) == 0x80) +#define WRITE_GAL(x,y) outl(y, 0x04000000 | (x)) +#define BusyCheck() while ((LCDReadInst & 0x80) == 0x80) -#define WRITE_FLASH(x,y) (*((volatile unsigned char *) (kFlashBase | (x)) ) = y) -#define READ_FLASH(x) *((volatile unsigned char *) (kFlashBase | (x)) ) +#define WRITE_FLASH(x,y) outb((char)y, kFlashBase | (x)) +#define READ_FLASH(x) (inb(kFlashBase | (x))) diff -urN linux-2.4.21-bk37/drivers/char/mips_rtc.c linux-2.4.21-bk38/drivers/char/mips_rtc.c --- linux-2.4.21-bk37/drivers/char/mips_rtc.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/drivers/char/mips_rtc.c 2003-08-24 02:56:03.000000000 -0700 @@ -0,0 +1,221 @@ +/* + * A simple generic Real Time Clock interface for Linux/MIPS + * + * Copyright (C) 1996 Paul Gortmaker + * + * Copyright (C) 2001 Monta Vista Software + * Author Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * This is a simple generic RTC driver for MIPS boards configured + * with CONFIG_NEW_TIME_C. For now, it makes use of the two + * abstract kernel RTC functions introduced in include/asm-mips/time.h: + * + * extern unsigned long (*rtc_get_time)(void); + * extern int (*rtc_set_time)(unsigned long); + * + * It uses the same protocol as the original drivers/char/rtc.c driver, + * but only implements two ioctls: RTC_RD_TIME and RTC_SET_TIME. + * + * TODO : + * + * 1. we can extend the null rtc ops defined in arch/mips/time.c to + * at least record the elapsed time (by recording/checking jiffies) + * This way RTC_RD_TIME and RTC_SET_TIME will make more sense. + * (Maybe not. A machine without a real RTC is broken anymore. + * Just a thought.) + * + * 2. If we make use of timer bh, we can emulate many RTC functions + * such as RTC alarm interrupt, periodic interrupts, etc. + * + * 3. It is possible to extend the kernel RTC abstractions to more + * than two functions, so that perhaps we can implement more + * full-featured RTC driver and also have a better abstraction + * to support more RTC hardware than the original RTC driver. + * It needs to be done very carefully. + * + * Change Log : + * v1.0 - [jsun] initial version + */ + +#define RTC_VERSION "1.0" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * Check machine + */ +#if !defined(CONFIG_MIPS) || !defined(CONFIG_NEW_TIME_C) +#error "This driver is for MIPS machines with CONFIG_NEW_TIME_C defined" +#endif + +#include + +static unsigned long rtc_status = 0; /* bitmapped status byte. */ + +static int rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data); + + +#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ + +static spinlock_t rtc_lock; + +static int +rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct rtc_time rtc_tm; + ulong curr_time; + + switch (cmd) { + case RTC_RD_TIME: /* Read the time/date from RTC */ + curr_time = rtc_get_time(); + to_tm(curr_time, &rtc_tm); + rtc_tm.tm_year -= 1900; + return copy_to_user((void *) arg, &rtc_tm, sizeof(rtc_tm)) ? + -EFAULT : 0; + case RTC_SET_TIME: /* Set the RTC */ + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&rtc_tm, + (struct rtc_time *) arg, + sizeof(struct rtc_time))) + return -EFAULT; + + curr_time = mktime(rtc_tm.tm_year + 1900, + rtc_tm.tm_mon + 1, /* tm_mon starts from 0 */ + rtc_tm.tm_mday, + rtc_tm.tm_hour, + rtc_tm.tm_min, + rtc_tm.tm_sec); + return rtc_set_time(curr_time); + default: + return -EINVAL; + } +} + +/* We use rtc_lock to protect against concurrent opens. So the BKL is not + * needed here. Or anywhere else in this driver. */ +static int rtc_open(struct inode *inode, struct file *file) +{ + spin_lock_irq(&rtc_lock); + + if (rtc_status & RTC_IS_OPEN) { + spin_unlock_irq(&rtc_lock); + return -EBUSY; + } + + rtc_status |= RTC_IS_OPEN; + + spin_unlock_irq(&rtc_lock); + return 0; +} + +static int rtc_release(struct inode *inode, struct file *file) +{ + spin_lock_irq(&rtc_lock); + rtc_status &= ~RTC_IS_OPEN; + spin_unlock_irq(&rtc_lock); + return 0; +} + +/* + * The various file operations we support. + */ + +static struct file_operations rtc_fops = { + owner:THIS_MODULE, + llseek:no_llseek, + ioctl:rtc_ioctl, + open:rtc_open, + release:rtc_release, +}; + +static struct miscdevice rtc_dev = { + RTC_MINOR, + "rtc", + &rtc_fops +}; + +static int __init rtc_init(void) +{ + + misc_register(&rtc_dev); + create_proc_read_entry("driver/rtc", 0, 0, rtc_read_proc, NULL); + + printk(KERN_INFO "Generic MIPS RTC Driver v" RTC_VERSION "\n"); + + return 0; +} + +static void __exit rtc_exit(void) +{ + remove_proc_entry("driver/rtc", NULL); + misc_deregister(&rtc_dev); + +} + +module_init(rtc_init); +module_exit(rtc_exit); +EXPORT_NO_SYMBOLS; + +/* + * Info exported via "/proc/driver/rtc". + */ + +static int rtc_proc_output(char *buf) +{ + char *p; + struct rtc_time tm; + unsigned long curr_time; + + curr_time = rtc_get_time(); + to_tm(curr_time, &tm); + + p = buf; + + /* + * There is no way to tell if the luser has the RTC set for local + * time or for Universal Standard Time (GMT). Probably local though. + */ + p += sprintf(p, + "rtc_time\t: %02d:%02d:%02d\n" + "rtc_date\t: %04d-%02d-%02d\n" + "rtc_epoch\t: %04lu\n", + tm.tm_hour, tm.tm_min, tm.tm_sec, + tm.tm_year, tm.tm_mon + 1, tm.tm_mday, 0L); + + return p - buf; +} + +static int rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = rtc_proc_output(page); + if (len <= off + count) + *eof = 1; + *start = page + off; + len -= off; + if (len > count) + len = count; + if (len < 0) + len = 0; + return len; +} + +MODULE_AUTHOR("Jun Sun"); +MODULE_LICENSE("GPL"); diff -urN linux-2.4.21-bk37/drivers/char/misc.c linux-2.4.21-bk38/drivers/char/misc.c --- linux-2.4.21-bk37/drivers/char/misc.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/drivers/char/misc.c 2003-08-24 02:56:03.000000000 -0700 @@ -66,10 +66,7 @@ static unsigned char misc_minors[DYNAMIC_MINORS / 8]; extern int psaux_init(void); -#ifdef CONFIG_SGI_NEWPORT_GFX extern void gfx_register(void); -#endif -extern void streamable_init(void); extern int rtc_DP8570A_init(void); extern int rtc_MK48T08_init(void); extern int ds1286_init(void); @@ -270,9 +267,6 @@ #ifdef CONFIG_SGI_NEWPORT_GFX gfx_register (); #endif -#ifdef CONFIG_SGI_IP22 - streamable_init (); -#endif #ifdef CONFIG_SGI_NEWPORT_GFX gfx_register (); #endif diff -urN linux-2.4.21-bk37/drivers/char/qtronixmap.c linux-2.4.21-bk38/drivers/char/qtronixmap.c --- linux-2.4.21-bk37/drivers/char/qtronixmap.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/drivers/char/qtronixmap.c 2003-08-24 02:56:03.000000000 -0700 @@ -226,40 +226,40 @@ }; struct kbdiacr accent_table[MAX_DIACR] = { - {'`', 'A', 'À'}, {'`', 'a', 'à'}, - {'\'', 'A', 'Á'}, {'\'', 'a', 'á'}, - {'^', 'A', 'Â'}, {'^', 'a', 'â'}, - {'~', 'A', 'Ã'}, {'~', 'a', 'ã'}, - {'"', 'A', 'Ä'}, {'"', 'a', 'ä'}, - {'O', 'A', 'Å'}, {'o', 'a', 'å'}, - {'0', 'A', 'Å'}, {'0', 'a', 'å'}, - {'A', 'A', 'Å'}, {'a', 'a', 'å'}, - {'A', 'E', 'Æ'}, {'a', 'e', 'æ'}, - {',', 'C', 'Ç'}, {',', 'c', 'ç'}, - {'`', 'E', 'È'}, {'`', 'e', 'è'}, - {'\'', 'E', 'É'}, {'\'', 'e', 'é'}, - {'^', 'E', 'Ê'}, {'^', 'e', 'ê'}, - {'"', 'E', 'Ë'}, {'"', 'e', 'ë'}, - {'`', 'I', 'Ì'}, {'`', 'i', 'ì'}, - {'\'', 'I', 'Í'}, {'\'', 'i', 'í'}, - {'^', 'I', 'Î'}, {'^', 'i', 'î'}, - {'"', 'I', 'Ï'}, {'"', 'i', 'ï'}, - {'-', 'D', 'Ð'}, {'-', 'd', 'ð'}, - {'~', 'N', 'Ñ'}, {'~', 'n', 'ñ'}, - {'`', 'O', 'Ò'}, {'`', 'o', 'ò'}, - {'\'', 'O', 'Ó'}, {'\'', 'o', 'ó'}, - {'^', 'O', 'Ô'}, {'^', 'o', 'ô'}, - {'~', 'O', 'Õ'}, {'~', 'o', 'õ'}, - {'"', 'O', 'Ö'}, {'"', 'o', 'ö'}, - {'/', 'O', 'Ø'}, {'/', 'o', 'ø'}, - {'`', 'U', 'Ù'}, {'`', 'u', 'ù'}, - {'\'', 'U', 'Ú'}, {'\'', 'u', 'ú'}, - {'^', 'U', 'Û'}, {'^', 'u', 'û'}, - {'"', 'U', 'Ü'}, {'"', 'u', 'ü'}, - {'\'', 'Y', 'Ý'}, {'\'', 'y', 'ý'}, - {'T', 'H', 'Þ'}, {'t', 'h', 'þ'}, - {'s', 's', 'ß'}, {'"', 'y', 'ÿ'}, - {'s', 'z', 'ß'}, {'i', 'j', 'ÿ'}, + {'`', 'A', '\300'}, {'`', 'a', '\340'}, + {'\'', 'A', '\301'}, {'\'', 'a', '\341'}, + {'^', 'A', '\302'}, {'^', 'a', '\342'}, + {'~', 'A', '\303'}, {'~', 'a', '\343'}, + {'"', 'A', '\304'}, {'"', 'a', '\344'}, + {'O', 'A', '\305'}, {'o', 'a', '\345'}, + {'0', 'A', '\305'}, {'0', 'a', '\345'}, + {'A', 'A', '\305'}, {'a', 'a', '\345'}, + {'A', 'E', '\306'}, {'a', 'e', '\346'}, + {',', 'C', '\307'}, {',', 'c', '\347'}, + {'`', 'E', '\310'}, {'`', 'e', '\350'}, + {'\'', 'E', '\311'}, {'\'', 'e', '\351'}, + {'^', 'E', '\312'}, {'^', 'e', '\352'}, + {'"', 'E', '\313'}, {'"', 'e', '\353'}, + {'`', 'I', '\314'}, {'`', 'i', '\354'}, + {'\'', 'I', '\315'}, {'\'', 'i', '\355'}, + {'^', 'I', '\316'}, {'^', 'i', '\356'}, + {'"', 'I', '\317'}, {'"', 'i', '\357'}, + {'-', 'D', '\320'}, {'-', 'd', '\360'}, + {'~', 'N', '\321'}, {'~', 'n', '\361'}, + {'`', 'O', '\322'}, {'`', 'o', '\362'}, + {'\'', 'O', '\323'}, {'\'', 'o', '\363'}, + {'^', 'O', '\324'}, {'^', 'o', '\364'}, + {'~', 'O', '\325'}, {'~', 'o', '\365'}, + {'"', 'O', '\326'}, {'"', 'o', '\366'}, + {'/', 'O', '\330'}, {'/', 'o', '\370'}, + {'`', 'U', '\331'}, {'`', 'u', '\371'}, + {'\'', 'U', '\332'}, {'\'', 'u', '\372'}, + {'^', 'U', '\333'}, {'^', 'u', '\373'}, + {'"', 'U', '\334'}, {'"', 'u', '\374'}, + {'\'', 'Y', '\335'}, {'\'', 'y', '\375'}, + {'T', 'H', '\336'}, {'t', 'h', '\376'}, + {'s', 's', '\337'}, {'"', 'y', '\377'}, + {'s', 'z', '\337'}, {'i', 'j', '\377'}, }; unsigned int accent_table_size = 68; diff -urN linux-2.4.21-bk37/drivers/char/sb1250_duart.c linux-2.4.21-bk38/drivers/char/sb1250_duart.c --- linux-2.4.21-bk37/drivers/char/sb1250_duart.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/drivers/char/sb1250_duart.c 2003-08-24 02:56:03.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -16,18 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /* * Driver support for the on-chip sb1250 dual-channel serial port, * running in asynchronous mode. Also, support for doing a serial console * on one of those ports - * - * The non-console part of this code is based heavily on the serial_21285.c - * driver also in this directory. See tty_driver.h for a description of some - * of the driver functions, though it (like most of the inline code documentation :) - * is a bit out of date. */ - +#include #include #include #include @@ -43,113 +37,183 @@ #include #include #include +#include +#include #include #include #include -#include #include #include #include +#include #include +#include /* Toggle spewing of debugging output */ #undef DUART_SPEW #define DEFAULT_CFLAGS (CS8 | B115200) +#define TX_INTEN 1 +#define DUART_INITIALIZED 2 -/* - Still not sure what the termios structures set up here are for, - but we have to supply pointers to them to register the tty driver -*/ +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#define DUART_MAX_LINE 2 +char sb1250_duart_present[DUART_MAX_LINE] = {1,1}; +/* + * Still not sure what the termios structures set up here are for, + * but we have to supply pointers to them to register the tty driver + */ static struct tty_driver sb1250_duart_driver, sb1250_duart_callout_driver; -static int ref_count; -static struct tty_struct *duart_table[2]; -static struct termios *duart_termios[2]; -static struct termios *duart_termios_locked[2]; +static int duart_refcount; +static struct tty_struct *duart_table[DUART_MAX_LINE]; +static struct termios *duart_termios[DUART_MAX_LINE]; +static struct termios *duart_termios_locked[DUART_MAX_LINE]; -/* This lock protects both the open flags for all the uart states as - well as the reference count for the module */ +/* + * This lock protects both the open flags for all the uart states as + * well as the reference count for the module + */ static spinlock_t open_lock = SPIN_LOCK_UNLOCKED; -/* Protect the writing stuff from contention */ -//static spinlock_t console_lock = SPIN_LOCK_UNLOCKED; - -/* Bit fields of flags in the flags field below */ - -#define SD_WRITE_WAKE 0x000000001 - - typedef struct { - struct tty_struct *tty; - unsigned char outp_buf[CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE]; + unsigned char outp_buf[SERIAL_XMIT_SIZE]; unsigned int outp_head; unsigned int outp_tail; unsigned int outp_count; spinlock_t outp_lock; - unsigned int outp_stopped; unsigned int open; - unsigned long flags; + unsigned int line; unsigned int last_cflags; + unsigned long flags; + struct tty_struct *tty; + /* CSR addresses */ + u32 *status; + u32 *imr; + u32 *tx_hold; + u32 *rx_hold; + u32 *mode_1; + u32 *mode_2; + u32 *clk_sel; + u32 *cmd; } uart_state_t; -static uart_state_t uart_states[2] = { [0 ... 1] = { - tty: 0, - outp_head: 0, - outp_tail: 0, - outp_lock: SPIN_LOCK_UNLOCKED, - outp_count: 0, - open: 0, - flags: 0, - last_cflags: 0, -}}; +static uart_state_t uart_states[DUART_MAX_LINE]; /* * Inline functions local to this module */ - /* - * Mask out the passed interrupt lines at the duart level. This should be - * called while holding the associated outp_lock. + * In bug 1956, we get glitches that can mess up uart registers. This + * "write-mode-1 after any register access" is the accepted + * workaround. */ -static inline void duart_mask_ints(unsigned int line, unsigned int mask) +#if SIBYTE_1956_WAR +static unsigned int last_mode1[DUART_MAX_LINE]; +#endif + +static inline u32 READ_SERCSR(u32 *addr, int line) { - u64 tmp; - tmp = in64(IO_SPACE_BASE | A_DUART_IMRREG(line)); - tmp &= ~mask; - out64(tmp, IO_SPACE_BASE | A_DUART_IMRREG(line)); + u32 val = csr_in32(addr); +#if SIBYTE_1956_WAR + csr_out32(last_mode1[line], uart_states[line].mode_1); +#endif + return val; } - -/* Unmask the passed interrupt lines at the duart level */ -static inline void duart_unmask_ints(unsigned int line, unsigned int mask) +static inline void WRITE_SERCSR(u32 val, u32 *addr, int line) { - u64 tmp; - tmp = in64(IO_SPACE_BASE | A_DUART_IMRREG(line)); - tmp |= mask; - out64(tmp, IO_SPACE_BASE | A_DUART_IMRREG(line)); + csr_out32(val, addr); +#if SIBYTE_1956_WAR + csr_out32(last_mode1[line], uart_states[line].mode_1); +#endif } -static inline unsigned long get_status_reg(unsigned int line) +static void init_duart_port(uart_state_t *port, int line) { - return in64(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_STATUS)); + if (!(port->flags & DUART_INITIALIZED)) { + port->line = line; + port->status = (u32 *)(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_STATUS)); + port->imr = (u32 *)(IO_SPACE_BASE | A_DUART_IMRREG(line)); + port->tx_hold = (u32 *)(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_TX_HOLD)); + port->rx_hold = (u32 *)(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_RX_HOLD)); + port->mode_1 = (u32 *)(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_MODE_REG_1)); + port->mode_2 = (u32 *)(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_MODE_REG_2)); + port->clk_sel = (u32 *)(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_CLK_SEL)); + port->cmd = (u32 *)(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_CMD)); + port->flags |= DUART_INITIALIZED; + } } -/* Derive which uart a call is for from the passed tty line. */ -static inline unsigned int get_line(struct tty_struct *tty) +/* + * Mask out the passed interrupt lines at the duart level. This should be + * called while holding the associated outp_lock. + */ +static inline void duart_mask_ints(unsigned int line, unsigned int mask) { - unsigned int line = MINOR(tty->device) - 64; - if (line > 1) - printk(KERN_CRIT "Invalid line\n"); - - return line; + uart_state_t *port = uart_states + line; + u64 tmp = READ_SERCSR(port->imr, line); + WRITE_SERCSR(tmp & ~mask, port->imr, line); } + +/* Unmask the passed interrupt lines at the duart level */ +static inline void duart_unmask_ints(unsigned int line, unsigned int mask) +{ + uart_state_t *port = uart_states + line; + u64 tmp = READ_SERCSR(port->imr, line); + WRITE_SERCSR(tmp | mask, port->imr, line); +} + +static inline void transmit_char_pio(uart_state_t *us) +{ + struct tty_struct *tty = us->tty; + int blocked = 0; + + if (spin_trylock(&us->outp_lock)) { + for (;;) { + if (!(READ_SERCSR(us->status, us->line) & M_DUART_TX_RDY)) + break; + if (us->outp_count <= 0 || tty->stopped || tty->hw_stopped) { + break; + } else { + WRITE_SERCSR(us->outp_buf[us->outp_head], + us->tx_hold, us->line); + us->outp_head = (us->outp_head + 1) & (SERIAL_XMIT_SIZE-1); + if (--us->outp_count <= 0) + break; + } + udelay(10); + } + spin_unlock(&us->outp_lock); + } else { + blocked = 1; + } - -#define MIN(a, b) (((a)<(b))?(a):(b)) + if (!us->outp_count || tty->stopped || + tty->hw_stopped || blocked) { + us->flags &= ~TX_INTEN; + duart_mask_ints(us->line, M_DUART_IMR_TX); + } + + if (us->open && + (us->outp_count < (SERIAL_XMIT_SIZE/2))) { + /* + * We told the discipline at one point that we had no + * space, so it went to sleep. Wake it up when we hit + * half empty + */ + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + tty->ldisc.write_wakeup(tty); + wake_up_interruptible(&tty->write_wait); + } +} /* * Generic interrupt handler for both channels. dev_id is a pointer @@ -159,52 +223,44 @@ static void duart_int(int irq, void *dev_id, struct pt_regs *regs) { - unsigned int line; uart_state_t *us = (uart_state_t *)dev_id; - line = us-uart_states; + struct tty_struct *tty = us->tty; + unsigned int status = READ_SERCSR(us->status, us->line); + #ifdef DUART_SPEW -// setleds("INT!"); - printk("DUART INT\n"); + printk("DUART INT\n"); #endif - /* We could query the ISR to figure out why we are here, but since - we are here, we may as well just take care of both rx and tx */ - spin_lock(&us->outp_lock); - if (get_status_reg(line) & M_DUART_RX_RDY) { - do { - unsigned int status = get_status_reg(line); - unsigned int ch = in64(IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_RX_HOLD)); - unsigned int flag = 0; - if (status & 0x10) { - tty_insert_flip_char(us->tty, 0, TTY_OVERRUN); } - if (status & 0x20) { - printk("Parity error!\n"); - flag = TTY_PARITY; - } else if (status & 0x40) { - printk("Frame error!\n"); - flag = TTY_FRAME; - } - tty_insert_flip_char(us->tty, ch, flag); - } while (get_status_reg(line) & M_DUART_RX_RDY); - tty_flip_buffer_push(us->tty); - } - if ((get_status_reg(line) & M_DUART_TX_RDY) && us->outp_count) { - do { - out64(us->outp_buf[us->outp_head], IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_TX_HOLD)); - us->outp_head = (us->outp_head + 1) & (CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE-1); - us->outp_count--; - } while ((get_status_reg(line) & M_DUART_TX_RDY) && us->outp_count); - - if (us->open && (us->flags & SD_WRITE_WAKE) && - (us->outp_count < (CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE/2))) { - /* We told the discipline at one point that we had no space, so it went - to sleep. Wake it up when we hit half empty */ - wake_up_interruptible(&us->tty->write_wait); + + if (status & M_DUART_RX_RDY) { + int counter = 2048; + unsigned int ch; + + if (status & M_DUART_OVRUN_ERR) + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + if (status & M_DUART_PARITY_ERR) { + printk("Parity error!\n"); + } else if (status & M_DUART_FRM_ERR) { + printk("Frame error!\n"); } - if (!us->outp_count) { - duart_mask_ints(line, M_DUART_IMR_TX); + + while (counter > 0) { + if (!(READ_SERCSR(us->status, us->line) & M_DUART_RX_RDY)) + break; + ch = READ_SERCSR(us->rx_hold, us->line); + if (tty->flip.count < TTY_FLIPBUF_SIZE) { + *tty->flip.char_buf_ptr++ = ch; + *tty->flip.flag_buf_ptr++ = 0; + tty->flip.count++; + } + udelay(1); + counter--; } + tty_flip_buffer_push(tty); + } + + if (status & M_DUART_TX_RDY) { + transmit_char_pio(us); } - spin_unlock(&us->outp_lock); } /* @@ -214,19 +270,15 @@ /* Return the number of characters we can accomodate in a write at this instant */ static int duart_write_room(struct tty_struct *tty) { - unsigned long flags; + uart_state_t *us = (uart_state_t *) tty->driver_data; int retval; - uart_state_t *us = &uart_states[get_line(tty)]; - spin_lock_irqsave(&us->outp_lock, flags); - retval = CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE - uart_states[get_line(tty)].outp_count; - if (!retval) { - us->flags |= SD_WRITE_WAKE; - } - spin_unlock_irqrestore(&us->outp_lock, flags); + retval = SERIAL_XMIT_SIZE - us->outp_count; + #ifdef DUART_SPEW printk("duart_write_room called, returning %i\n", retval); #endif + return retval; } @@ -242,88 +294,119 @@ return size; } -/* Buffer up to count characters from buf to be written. If we don't have other - characters buffered, enable the tx interrupt to start sending */ +/* + * Buffer up to count characters from buf to be written. If we don't have + * other characters buffered, enable the tx interrupt to start sending + */ static int duart_write(struct tty_struct * tty, int from_user, - const unsigned char *buf, int count) + const unsigned char *buf, int count) { uart_state_t *us; + int c, t, total = 0; unsigned long flags; - unsigned int line; - int chars_written = 0; - if (from_user && verify_area(VERIFY_READ, buf, count)) { - return -EINVAL; - } + + if (!tty) return 0; + + us = tty->driver_data; + if (!us) return 0; + #ifdef DUART_SPEW printk("duart_write called for %i chars by %i (%s)\n", count, current->pid, current->comm); #endif - line = get_line(tty); - us = &uart_states[line]; + spin_lock_irqsave(&us->outp_lock, flags); - if (!count || (us->outp_count == CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE)) { - spin_unlock_irqrestore(&us->outp_lock, flags); - return 0; - } - if (us->outp_tail < us->outp_head) { - /* Straightforward case; copy from tail to head */ - chars_written += copy_buf(us->outp_buf + us->outp_tail, buf, - MIN(count, us->outp_head - us->outp_tail), from_user); - } else { - /* Copy from tail to end of buffer, wrap around and then - copy to head */ - chars_written += copy_buf(us->outp_buf + us->outp_tail, buf, - MIN(CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE - us->outp_tail, count), - from_user); - if (chars_written < count) { - chars_written += copy_buf(us->outp_buf, buf + chars_written, - MIN(us->outp_head, count - chars_written), from_user); + + for (;;) { + c = count; + + t = SERIAL_XMIT_SIZE - us->outp_tail; + if (t < c) c = t; + + t = SERIAL_XMIT_SIZE - 1 - us->outp_count; + if (t < c) c = t; + + if (c <= 0) break; + + if (from_user) { + if (copy_from_user(us->outp_buf + us->outp_tail, buf, c)) { + spin_unlock_irqrestore(&us->outp_lock, flags); + return -EFAULT; + } + } else { + memcpy(us->outp_buf + us->outp_tail, buf, c); } + + us->outp_count += c; + us->outp_tail = (us->outp_tail + c) & (SERIAL_XMIT_SIZE - 1); + buf += c; + count -= c; + total += c; } - us->outp_tail = (us->outp_tail + chars_written) &(CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE-1); - if (!(us->outp_count || us->outp_stopped)) { - duart_unmask_ints(line, M_DUART_IMR_TX); - } - us->outp_count += chars_written; + spin_unlock_irqrestore(&us->outp_lock, flags); - return chars_written; -} + + if (us->outp_count && !tty->stopped && + !tty->hw_stopped && !(us->flags & TX_INTEN)) { + us->flags |= TX_INTEN; + duart_unmask_ints(us->line, M_DUART_IMR_TX); + } + + return total; +} /* Buffer one character to be written. If there's not room for it, just drop it on the floor. This is used for echo, among other things */ static void duart_put_char(struct tty_struct *tty, u_char ch) { + uart_state_t *us = (uart_state_t *) tty->driver_data; unsigned long flags; - unsigned int line = get_line(tty); - uart_state_t *us = &uart_states[line]; + #ifdef DUART_SPEW printk("duart_put_char called. Char is %x (%c)\n", (int)ch, ch); #endif + spin_lock_irqsave(&us->outp_lock, flags); - if (us->outp_count != CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE) { - us->outp_buf[us->outp_tail] = ch; - us->outp_tail = (us->outp_tail + 1) &(CONFIG_SB1250_DUART_OUTPUT_BUF_SIZE-1); - if (!(us->outp_count || us->outp_stopped)) { - duart_unmask_ints(line, M_DUART_IMR_TX); - } - us->outp_count++; + + if (us->outp_count >= SERIAL_XMIT_SIZE - 1) { + spin_unlock_irqrestore(&us->outp_lock, flags); + return; } + + us->outp_buf[us->outp_tail] = ch; + us->outp_tail = (us->outp_tail + 1) &(SERIAL_XMIT_SIZE-1); + us->outp_count++; + spin_unlock_irqrestore(&us->outp_lock, flags); } +static void duart_flush_chars(struct tty_struct * tty) +{ + uart_state_t *port; + + if (!tty) return; + + port = tty->driver_data; + + if (!port) return; + + if (port->outp_count <= 0 || tty->stopped || tty->hw_stopped) { + return; + } + + port->flags |= TX_INTEN; + duart_unmask_ints(port->line, M_DUART_IMR_TX); +} + /* Return the number of characters in the output buffer that have yet to be written */ static int duart_chars_in_buffer(struct tty_struct *tty) { + uart_state_t *us = (uart_state_t *) tty->driver_data; int retval; - unsigned long flags; - uart_state_t *us = &uart_states[get_line(tty)]; - spin_lock_irqsave(&us->outp_lock, flags); + retval = us->outp_count; - if (retval) { - us->flags |= SD_WRITE_WAKE; - } - spin_unlock_irqrestore(&us->outp_lock, flags); + #ifdef DUART_SPEW printk("duart_chars_in_buffer returning %i\n", retval); #endif @@ -334,19 +417,20 @@ transmit interrupt since we've nothing more to transmit */ static void duart_flush_buffer(struct tty_struct *tty) { + uart_state_t *us = (uart_state_t *) tty->driver_data; unsigned long flags; - unsigned int line = get_line(tty); - uart_state_t *us = &uart_states[get_line(tty)]; + #ifdef DUART_SPEW printk("duart_flush_buffer called\n"); #endif - duart_mask_ints(line, M_DUART_IMR_TX); spin_lock_irqsave(&us->outp_lock, flags); us->outp_head = us->outp_tail = us->outp_count = 0; - if (us->flags & SD_WRITE_WAKE) { - wake_up_interruptible(&us->tty->write_wait); - } spin_unlock_irqrestore(&us->outp_lock, flags); + + wake_up_interruptible(&us->tty->write_wait); + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + tty->ldisc.write_wakeup(tty); } @@ -355,6 +439,8 @@ { unsigned int mode_reg1 = 0, mode_reg2 = 0; unsigned int clk_divisor; + uart_state_t *port = uart_states + line; + switch (cflag & CSIZE) { case CS7: mode_reg1 |= V_DUART_BITS_PER_CHAR_7; @@ -366,10 +452,10 @@ break; } if (cflag & CSTOPB) { - mode_reg2 |= M_DUART_STOP_BIT_LEN_2; /* XXX was: 0x4; */ + mode_reg2 |= M_DUART_STOP_BIT_LEN_2; } if (!(cflag & PARENB)) { - mode_reg1 |= V_DUART_PARITY_MODE_NONE; /* XXX was: 0x8; */ + mode_reg1 |= V_DUART_PARITY_MODE_NONE; } if (cflag & PARODD) { mode_reg1 |= M_DUART_PARITY_TYPE_ODD; @@ -392,38 +478,24 @@ case B57600: clk_divisor = 85; break; case B115200: clk_divisor = 42; break; } - out64(mode_reg1, IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_MODE_REG_1)); - out64(mode_reg2, IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_MODE_REG_2)); - out64(clk_divisor, IO_SPACE_BASE | A_DUART_CHANREG(line, R_DUART_CLK_SEL)); - uart_states[line].last_cflags = cflag; + WRITE_SERCSR(mode_reg1, port->mode_1, port->line); + WRITE_SERCSR(mode_reg2, port->mode_2, port->line); + WRITE_SERCSR(clk_divisor, port->clk_sel, port->line); + port->last_cflags = cflag; } /* Handle notification of a termios change. */ static void duart_set_termios(struct tty_struct *tty, struct termios *old) { + uart_state_t *us = (uart_state_t *) tty->driver_data; + #ifdef DUART_SPEW printk("duart_set_termios called by %i (%s)\n", current->pid, current->comm); #endif if (old && tty->termios->c_cflag == old->c_cflag) return; - duart_set_cflag(get_line(tty), tty->termios->c_cflag); -} - -/* Stop pushing stuff into the fifo, now. Do the mask under the - outp_lock to avoid races involving turning the interrupt line on/off */ -static void duart_stop(struct tty_struct *tty) -{ - unsigned long flags; - unsigned int line = get_line(tty); - uart_state_t *us = &uart_states[line]; -#ifdef DUART_SPEW - printk("duart_stop called\n"); -#endif - spin_lock_irqsave(&us->outp_lock, flags); - duart_mask_ints(get_line(tty), M_DUART_IMR_TX); - us->outp_stopped = 1; - spin_unlock_irqrestore(&us->outp_lock, flags); + duart_set_cflag(us->line, tty->termios->c_cflag); } static int duart_ioctl(struct tty_struct *tty, struct file * file, @@ -508,22 +580,34 @@ return 0; } -/* Stop pushing stuff into the fifo, now. Do the mask under the - outp_lock to avoid races involving turning the interrupt line on/off */ +/* XXXKW locking? */ static void duart_start(struct tty_struct *tty) { - unsigned long flags; - unsigned int line = get_line(tty); - uart_state_t *us = &uart_states[line]; + uart_state_t *us = (uart_state_t *) tty->driver_data; + #ifdef DUART_SPEW printk("duart_start called\n"); #endif - spin_lock_irqsave(&us->outp_lock, flags); - if (us->outp_count) { - duart_unmask_ints(get_line(tty), M_DUART_IMR_TX); + + if (us->outp_count && !(us->flags & TX_INTEN)) { + us->flags |= TX_INTEN; + duart_unmask_ints(us->line, M_DUART_IMR_TX); + } +} + +/* XXXKW locking? */ +static void duart_stop(struct tty_struct *tty) +{ + uart_state_t *us = (uart_state_t *) tty->driver_data; + +#ifdef DUART_SPEW + printk("duart_stop called\n"); +#endif + + if (us->outp_count && (us->flags & TX_INTEN)) { + us->flags &= ~TX_INTEN; + duart_mask_ints(us->line, M_DUART_IMR_TX); } - us->outp_stopped = 0; - spin_unlock_irqrestore(&us->outp_lock, flags); } /* Not sure on the semantics of this; are we supposed to wait until the stuff @@ -534,17 +618,20 @@ static void duart_wait_until_sent(struct tty_struct *tty, int timeout) { - unsigned long target_time; - unsigned int line; - uart_state_t *us; + uart_state_t *us = (uart_state_t *) tty->driver_data; + unsigned long orig_jiffies; + + orig_jiffies = jiffies; #ifdef DUART_SPEW printk("duart_wait_until_sent(%d)+\n", timeout); #endif - target_time = jiffies + timeout; - line = get_line(tty); - us = &uart_states[line]; - while (!(get_status_reg(line) & M_DUART_TX_EMT) && (jiffies < target_time)) { + while (!(READ_SERCSR(us->status, us->line) & M_DUART_TX_EMT)) { + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1); + if (signal_pending(current)) + break; + if (timeout && time_after(jiffies, orig_jiffies + timeout)) + break; } #ifdef DUART_SPEW printk("duart_wait_until_sent()-\n"); @@ -552,53 +639,54 @@ } /* + * duart_hangup() --- called by tty_hangup() when a hangup is signaled. + */ +static void duart_hangup(struct tty_struct *tty) +{ + uart_state_t *us = (uart_state_t *) tty->driver_data; + + duart_flush_buffer(tty); + us->open = 0; + us->tty = 0; +} + +/* * Open a tty line. Note that this can be called multiple times, so ->open can * be >1. Only set up the tty struct if this is a "new" open, e.g. ->open was * zero */ static int duart_open(struct tty_struct *tty, struct file *filp) { - unsigned long flags; - unsigned int line; uart_state_t *us; + unsigned int line = MINOR(tty->device) - tty->driver.minor_start; + unsigned long flags; MOD_INC_USE_COUNT; -#ifndef CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1 - if (get_line(tty) > 1) -#else - if (get_line(tty) > 0) -#endif - { + + if ((line < 0) || (line >= DUART_MAX_LINE) || !sb1250_duart_present[line]) { MOD_DEC_USE_COUNT; return -ENODEV; } + #ifdef DUART_SPEW - printk("duart_open called by %i (%s), tty is %p, rw is %p, ww is %p\n", current->pid, current->comm, tty, - tty->read_wait, tty->write_wait); + printk("duart_open called by %i (%s), tty is %p, rw is %p, ww is %p\n", + current->pid, current->comm, tty, tty->read_wait, + tty->write_wait); #endif - line = get_line(tty); - tty->driver_data = NULL; - us = &uart_states[line]; - + + us = uart_states + line; + tty->driver_data = us; + spin_lock_irqsave(&open_lock, flags); if (!us->open) { us->tty = tty; us->tty->termios->c_cflag = us->last_cflags; } us->open++; -#ifdef FORCED_INPUT - if (!line && (us->open == 1)) { - next_inp = inp_cmds; - init_timer(&inp_timer); - inp_timer.expires = jiffies + 20; - inp_timer.data = 0; - inp_timer.function = stuff_char; - stuff_char_tty = tty; - add_timer(&inp_timer); - } -#endif + us->flags &= ~TX_INTEN; duart_unmask_ints(line, M_DUART_IMR_RX); spin_unlock_irqrestore(&open_lock, flags); + return 0; } @@ -610,26 +698,48 @@ */ static void duart_close(struct tty_struct *tty, struct file *filp) { + uart_state_t *us = (uart_state_t *) tty->driver_data; unsigned long flags; - unsigned int line = get_line(tty); - uart_state_t *us = &uart_states[line]; + #ifdef DUART_SPEW printk("duart_close called by %i (%s)\n", current->pid, current->comm); #endif + + if (!us || !us->open) + return; + spin_lock_irqsave(&open_lock, flags); - us->open--; -#if 0 - if (!us->open) { - /* Flushing TX stuff here is conservative */ - duart_mask_ints(line, M_DUART_IMR_IN | M_DUART_IMR_BRK | M_DUART_IMR_RX | M_DUART_IMR_TX); - spin_lock(&us->outp_lock); - us->outp_head = us->outp_tail = us->outp_count = us->outp_stopped = 0; - us->tty = NULL; - spin_unlock(&us->outp_lock); + if (tty_hung_up_p(filp)) { + MOD_DEC_USE_COUNT; + spin_unlock_irqrestore(&open_lock, flags); + return; } -#endif - ref_count--; + + if (--us->open < 0) { + us->open = 0; + printk(KERN_ERR "duart: bad open count: %d\n", us->open); + } + if (us->open) { + spin_unlock_irqrestore(&open_lock, flags); + return; + } + spin_unlock_irqrestore(&open_lock, flags); + + tty->closing = 1; + + /* Stop accepting input */ + duart_mask_ints(us->line, M_DUART_IMR_RX); + /* Wait for FIFO to drain */ + while (!(READ_SERCSR(us->status, us->line) & M_DUART_TX_EMT)) + ; + + if (tty->driver.flush_buffer) + tty->driver.flush_buffer(tty); + if (tty->ldisc.flush_buffer) + tty->ldisc.flush_buffer(tty); + tty->closing = 0; + MOD_DEC_USE_COUNT; } @@ -638,6 +748,8 @@ is called from tty_init, or as a part of the module init */ static int __init sb1250_duart_init(void) { + int i; + sb1250_duart_driver.magic = TTY_DRIVER_MAGIC; sb1250_duart_driver.driver_name = "serial"; #ifdef CONFIG_DEVFS_FS @@ -646,13 +758,13 @@ sb1250_duart_driver.name = "ttyS"; #endif sb1250_duart_driver.major = TTY_MAJOR; - sb1250_duart_driver.minor_start = 64; - sb1250_duart_driver.num = 2; + sb1250_duart_driver.minor_start = SB1250_DUART_MINOR_BASE; + sb1250_duart_driver.num = DUART_MAX_LINE; sb1250_duart_driver.type = TTY_DRIVER_TYPE_SERIAL; sb1250_duart_driver.subtype = SERIAL_TYPE_NORMAL; sb1250_duart_driver.init_termios = tty_std_termios; sb1250_duart_driver.flags = TTY_DRIVER_REAL_RAW; - sb1250_duart_driver.refcount = &ref_count; + sb1250_duart_driver.refcount = &duart_refcount; sb1250_duart_driver.table = duart_table; sb1250_duart_driver.termios = duart_termios; sb1250_duart_driver.termios_locked = duart_termios_locked; @@ -662,12 +774,14 @@ sb1250_duart_driver.write = duart_write; sb1250_duart_driver.put_char = duart_put_char; sb1250_duart_driver.write_room = duart_write_room; + sb1250_duart_driver.flush_chars = duart_flush_chars; sb1250_duart_driver.chars_in_buffer = duart_chars_in_buffer; sb1250_duart_driver.flush_buffer = duart_flush_buffer; sb1250_duart_driver.ioctl = duart_ioctl; sb1250_duart_driver.set_termios = duart_set_termios; sb1250_duart_driver.stop = duart_stop; sb1250_duart_driver.start = duart_start; + sb1250_duart_driver.hangup = duart_hangup; sb1250_duart_driver.wait_until_sent = duart_wait_until_sent; sb1250_duart_callout_driver = sb1250_duart_driver; @@ -679,16 +793,22 @@ sb1250_duart_callout_driver.major = TTYAUX_MAJOR; sb1250_duart_callout_driver.subtype = SERIAL_TYPE_CALLOUT; - duart_mask_ints(0, 0xf); - if (request_irq(K_INT_UART_0, duart_int, 0, "uart0", &uart_states[0])) { - panic("Couldn't get uart0 interrupt line"); - } -#ifndef CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1 - duart_mask_ints(1, 0xf); - if (request_irq(K_INT_UART_1, duart_int, 0, "uart1", &uart_states[1])) { - panic("Couldn't get uart1 interrupt line"); + for (i=0; ioutp_lock); + duart_mask_ints(i, M_DUART_IMR_ALL); + if (request_irq(K_INT_UART_0+i, duart_int, 0, "uart", port)) { + panic("Couldn't get uart0 interrupt line"); + } + out64(M_DUART_RX_EN|M_DUART_TX_EN, + IO_SPACE_BASE | A_DUART_CHANREG(i, R_DUART_CMD)); + duart_set_cflag(i, DEFAULT_CFLAGS); } -#endif /* Interrupts are now active, our ISR can be called. */ @@ -698,10 +818,6 @@ if (tty_register_driver(&sb1250_duart_callout_driver)) { printk(KERN_ERR "Couldn't register sb1250 duart callout driver\n"); } - duart_set_cflag(0, DEFAULT_CFLAGS); -#ifndef CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1 - duart_set_cflag(1, DEFAULT_CFLAGS); -#endif return 0; } @@ -709,10 +825,10 @@ static void __exit sb1250_duart_fini(void) { unsigned long flags; + int i; int ret; - save_flags(flags); - cli(); + save_and_cli(flags); ret = tty_unregister_driver(&sb1250_duart_callout_driver); if (ret) { printk(KERN_ERR "Unable to unregister sb1250 duart callout driver (%d)\n", ret); @@ -721,69 +837,85 @@ if (ret) { printk(KERN_ERR "Unable to unregister sb1250 duart serial driver (%d)\n", ret); } - free_irq(K_INT_UART_0, &uart_states[0]); - free_irq(K_INT_UART_1, &uart_states[1]); - - /* mask lines in the scd */ - disable_irq(K_INT_UART_0); - disable_irq(K_INT_UART_1); - + for (i=0; i"); +MODULE_AUTHOR("Justin Carlson, Broadcom Corp."); -#ifdef CONFIG_SERIAL_CONSOLE +#ifdef CONFIG_SIBYTE_SB1250_DUART_CONSOLE /* - * Serial console stuff. - * Very basic, polling driver for doing serial console output. - * FIXME; there is a race here; we can't be sure that - * the tx is still empty without holding outp_lock for this line. - * Worst that can happen for now, though, is dropped characters. + * Serial console stuff. Very basic, polling driver for doing serial + * console output. The console_sem is held by the caller, so we + * shouldn't be interrupted for more console activity. + * XXXKW What about getting interrupted by uart driver activity? */ -static void ser_console_write(struct console *cons, const char *str, - unsigned int count) +void serial_outc(unsigned char c, int line) { - unsigned int i; - unsigned long flags; - spin_lock_irqsave(&uart_states[0].outp_lock, flags); - - for (i = 0; i < count; i++) { - if (str[i] == '\n') { - /* Expand LF -> CRLF */ - while (!(get_status_reg(0) & M_DUART_TX_RDY)) { - /* Spin, doing nothing. */ - } - out64('\r', IO_SPACE_BASE | A_DUART_CHANREG(0, R_DUART_TX_HOLD)); - } - while (!(get_status_reg(0) & M_DUART_TX_RDY)) { - /* Spin, doing nothing. */ - } - out64(str[i], IO_SPACE_BASE | A_DUART_CHANREG(0, R_DUART_TX_HOLD)); - } - spin_unlock_irqrestore(&uart_states[0].outp_lock, flags); + uart_state_t *port = uart_states + line; + while (!(READ_SERCSR(port->status, line) & M_DUART_TX_RDY)) ; + WRITE_SERCSR(c, port->tx_hold, line); + while (!(READ_SERCSR(port->status, port->line) & M_DUART_TX_EMT)) ; +} + +static void ser_console_write(struct console *cons, const char *s, + unsigned int count) +{ + int line = cons->index; + uart_state_t *port = uart_states + line; + u32 imr; + + imr = READ_SERCSR(port->imr, line); + WRITE_SERCSR(0, port->imr, line); + while (count--) { + if (*s == '\n') + serial_outc('\r', line); + serial_outc(*s++, line); + } + WRITE_SERCSR(imr, port->imr, line); } static kdev_t ser_console_device(struct console *c) { - return MKDEV(TTY_MAJOR, 64 + c->index); + return MKDEV(TTY_MAJOR, SB1250_DUART_MINOR_BASE + c->index); } static int ser_console_setup(struct console *cons, char *str) { - /* Initialize the transmitter */ - - duart_set_cflag(0, DEFAULT_CFLAGS); + int i; + + for (i=0; imode_1, i); + WRITE_SERCSR(M_DUART_STOP_BIT_LEN_1, + port->mode_2, i); + WRITE_SERCSR(V_DUART_BAUD_RATE(115200), + port->clk_sel, i); + } return 0; } static struct console sb1250_ser_cons = { - name: "ttyS", + name: "duart", write: ser_console_write, device: ser_console_device, setup: ser_console_setup, @@ -796,4 +928,4 @@ register_console(&sb1250_ser_cons); } -#endif /* CONFIG_SERIAL_CONSOLE */ +#endif /* CONFIG_SIBYTE_SB1250_DUART_CONSOLE */ diff -urN linux-2.4.21-bk37/drivers/char/serial_tx3912.c linux-2.4.21-bk38/drivers/char/serial_tx3912.c --- linux-2.4.21-bk37/drivers/char/serial_tx3912.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.21-bk38/drivers/char/serial_tx3912.c 2003-08-24 02:56:03.000000000 -0700 @@ -752,6 +752,21 @@ outl(int2, TX3912_INT2_ENABLE); } +static int serial_console_wait_key(struct console *co) +{ + unsigned int int2, res; + + int2 = inl(TX3912_INT2_ENABLE); + outl(0, TX3912_INT2_ENABLE); + + while (!(inl(TX3912_UARTA_CTRL1) & TX3912_UART_CTRL1_RXHOLDFULL)); + res = inl(TX3912_UARTA_DATA); + udelay(10); + + outl(int2, TX3912_INT2_ENABLE); + return res; +} + static void serial_console_write(struct console *co, const char *s, unsigned count) { diff -urN linux-2.4.21-bk37/drivers/char/serial_txx9.c linux-2.4.21-bk38/drivers/char/serial_txx9.c --- linux-2.4.21-bk37/drivers/char/serial_txx9.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/drivers/char/serial_txx9.c 2003-08-24 02:56:03.000000000 -0700 @@ -0,0 +1,1768 @@ +/* + * drivers/char/serial_txx9.c + * + * Copyright (C) 1999 Harald Koerfgen + * Copyright (C) 2000 Jim Pick + * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com) + * Copyright (C) 2000-2002 Toshiba Corporation + * + * 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. + * + * Serial driver for TX3927/TX4927/TX4925/TX4938 internal SIO controller + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_MAGIC_SYSRQ +#include +#endif + +#define DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +static char *serial_version = "0.30-mvl"; +static char *serial_name = "TX39/49 Serial driver"; + +#define GS_INTERNAL_FLAGS (GS_TX_INTEN|GS_RX_INTEN|GS_ACTIVE) + +#define TXX9_SERIAL_MAGIC 0x39274927 + +#ifdef CONFIG_SERIAL +/* "ttyS","cua" is used for standard serial driver */ +#define TXX9_TTY_NAME "ttyTX" +#define TXX9_TTY_DEVFS_NAME "tts/TX%d" +#define TXX9_TTY_MINOR_START (64 + 64) /* ttyTX0(128), ttyTX1(129) */ +#define TXX9_CU_NAME "cuatx" +#define TXX9_CU_DEVFS_NAME "cua/TX%d" +#else +/* acts like standard serial driver */ +#define TXX9_TTY_NAME "ttyS" +#define TXX9_TTY_DEVFS_NAME "tts/%d" +#define TXX9_TTY_MINOR_START 64 +#define TXX9_CU_NAME "cua" +#define TXX9_CU_DEVFS_NAME "cua/%d" +#endif +#define TXX9_TTY_MAJOR TTY_MAJOR +#define TXX9_TTYAUX_MAJOR TTYAUX_MAJOR + +#define TXX9_SERIAL_HAVE_CTS_LINE 1 + +#ifdef CONFIG_PCI +/* support for Toshiba TC86C001 SIO */ +#define ENABLE_SERIAL_TXX9_PCI +#endif + +/* + * Number of serial ports + */ +#ifdef ENABLE_SERIAL_TXX9_PCI +#define NR_PCI_BOARDS 4 +#define NR_PORTS (2 + NR_PCI_BOARDS) +#else +#define NR_PORTS 2 +#endif + +/* + * Hardware specific serial port structure + */ +static struct rs_port { + struct gs_port gs; /* Must be first field! */ + + unsigned long base; + int irq; + int baud_base; + int flags; + struct async_icount icount; + int x_char; /* XON/XOFF character */ + int read_status_mask; + int ignore_status_mask; + int quot; + char io_type; +#ifdef ENABLE_SERIAL_TXX9_PCI + struct pci_dev * pci_dev; +#endif +} rs_ports[NR_PORTS] +#ifdef CONFIG_TOSHIBA_RBTX4925 += { + /* NR_PORTS = 0 */ + {base: 0xff1f0000 + 0xf300, + irq: 36, + baud_base: 40000000 / 16 / 2, + io_type: -1, /* virtual memory mapped */ + flags: TXX9_SERIAL_HAVE_CTS_LINE,}, + /* NR_PORTS = 1 */ + {base: 0xff1f0000 + 0xf400, + irq: 37, + baud_base: 40000000 / 16 / 2, + io_type: -1, /* virtual memory mapped */ + flags: TXX9_SERIAL_HAVE_CTS_LINE,} +}; +#endif +#ifdef CONFIG_TOSHIBA_RBTX4927 += { + /* NR_PORTS = 0 */ + {base: 0xff1f0000 + 0xf300, + irq: 32, + baud_base: 50000000 / 16 / 2, + io_type: -1, /* virtual memory mapped */ + flags: TXX9_SERIAL_HAVE_CTS_LINE,}, + /* NR_PORTS = 1 */ + {base: 0xff1f0000 + 0xf400, + irq: 33, + baud_base: 50000000 / 16 / 2, + io_type: -1, /* virtual memory mapped */ + flags: TXX9_SERIAL_HAVE_CTS_LINE,} +}; +#endif + +/* TXX9 Serial Registers */ +#define TXX9_SILCR 0x00 +#define TXX9_SIDICR 0x04 +#define TXX9_SIDISR 0x08 +#define TXX9_SICISR 0x0c +#define TXX9_SIFCR 0x10 +#define TXX9_SIFLCR 0x14 +#define TXX9_SIBGR 0x18 +#define TXX9_SITFIFO 0x1c +#define TXX9_SIRFIFO 0x20 + +/* SILCR : Line Control */ +#define TXX9_SILCR_SCS_MASK 0x00000060 +#define TXX9_SILCR_SCS_IMCLK 0x00000000 +#define TXX9_SILCR_SCS_IMCLK_BG 0x00000020 +#define TXX9_SILCR_SCS_SCLK 0x00000040 +#define TXX9_SILCR_SCS_SCLK_BG 0x00000060 +#define TXX9_SILCR_UEPS 0x00000010 +#define TXX9_SILCR_UPEN 0x00000008 +#define TXX9_SILCR_USBL_MASK 0x00000004 +//#define TXX9_SILCR_USBL_1BIT 0x00000004 +//#define TXX9_SILCR_USBL_2BIT 0x00000000 +#define TXX9_SILCR_USBL_1BIT 0x00000000 +#define TXX9_SILCR_USBL_2BIT 0x00000004 +#define TXX9_SILCR_UMODE_MASK 0x00000003 +#define TXX9_SILCR_UMODE_8BIT 0x00000000 +#define TXX9_SILCR_UMODE_7BIT 0x00000001 + +/* SIDICR : DMA/Int. Control */ +#define TXX9_SIDICR_TDE 0x00008000 +#define TXX9_SIDICR_RDE 0x00004000 +#define TXX9_SIDICR_TIE 0x00002000 +#define TXX9_SIDICR_RIE 0x00001000 +#define TXX9_SIDICR_SPIE 0x00000800 +#define TXX9_SIDICR_CTSAC 0x00000600 +#define TXX9_SIDICR_STIE_MASK 0x0000003f +#define TXX9_SIDICR_STIE_OERS 0x00000020 +#define TXX9_SIDICR_STIE_CTSS 0x00000010 +#define TXX9_SIDICR_STIE_RBRKD 0x00000008 +#define TXX9_SIDICR_STIE_TRDY 0x00000004 +#define TXX9_SIDICR_STIE_TXALS 0x00000002 +#define TXX9_SIDICR_STIE_UBRKD 0x00000001 + +/* SIDISR : DMA/Int. Status */ +#define TXX9_SIDISR_UBRK 0x00008000 +#define TXX9_SIDISR_UVALID 0x00004000 +#define TXX9_SIDISR_UFER 0x00002000 +#define TXX9_SIDISR_UPER 0x00001000 +#define TXX9_SIDISR_UOER 0x00000800 +#define TXX9_SIDISR_ERI 0x00000400 +#define TXX9_SIDISR_TOUT 0x00000200 +#define TXX9_SIDISR_TDIS 0x00000100 +#define TXX9_SIDISR_RDIS 0x00000080 +#define TXX9_SIDISR_STIS 0x00000040 +#define TXX9_SIDISR_RFDN_MASK 0x0000001f + +/* SICISR : Change Int. Status */ +#define TXX9_SICISR_OERS 0x00000020 +#define TXX9_SICISR_CTSS 0x00000010 +#define TXX9_SICISR_RBRKD 0x00000008 +#define TXX9_SICISR_TRDY 0x00000004 +#define TXX9_SICISR_TXALS 0x00000002 +#define TXX9_SICISR_UBRKD 0x00000001 + +/* SIFCR : FIFO Control */ +#define TXX9_SIFCR_SWRST 0x00008000 +#define TXX9_SIFCR_RDIL_MASK 0x00000180 +#define TXX9_SIFCR_RDIL_1 0x00000000 +#define TXX9_SIFCR_RDIL_4 0x00000080 +#define TXX9_SIFCR_RDIL_8 0x00000100 +#define TXX9_SIFCR_RDIL_12 0x00000180 +#define TXX9_SIFCR_RDIL_MAX 0x00000180 +#define TXX9_SIFCR_TDIL_MASK 0x00000018 +#define TXX9_SIFCR_TDIL_MASK 0x00000018 +#define TXX9_SIFCR_TDIL_1 0x00000000 +#define TXX9_SIFCR_TDIL_4 0x00000001 +#define TXX9_SIFCR_TDIL_8 0x00000010 +#define TXX9_SIFCR_TDIL_MAX 0x00000010 +#define TXX9_SIFCR_TFRST 0x00000004 +#define TXX9_SIFCR_RFRST 0x00000002 +#define TXX9_SIFCR_FRSTE 0x00000001 +#define TXX9_SIO_TX_FIFO 8 +#define TXX9_SIO_RX_FIFO 16 + +/* SIFLCR : Flow Control */ +#define TXX9_SIFLCR_RCS 0x00001000 +#define TXX9_SIFLCR_TES 0x00000800 +#define TXX9_SIFLCR_RTSSC 0x00000200 +#define TXX9_SIFLCR_RSDE 0x00000100 +#define TXX9_SIFLCR_TSDE 0x00000080 +#define TXX9_SIFLCR_RTSTL_MASK 0x0000001e +#define TXX9_SIFLCR_RTSTL_MAX 0x0000001e +#define TXX9_SIFLCR_TBRK 0x00000001 + +/* SIBGR : Baudrate Control */ +#define TXX9_SIBGR_BCLK_MASK 0x00000300 +#define TXX9_SIBGR_BCLK_T0 0x00000000 +#define TXX9_SIBGR_BCLK_T2 0x00000100 +#define TXX9_SIBGR_BCLK_T4 0x00000200 +#define TXX9_SIBGR_BCLK_T6 0x00000300 +#define TXX9_SIBGR_BRD_MASK 0x000000ff + +static /*inline*/ unsigned int +sio_in(struct rs_port *port, int offset) +{ + if (port->io_type < 0) + /* don't use __raw_readl that does swapping for big endian */ + return (*(volatile unsigned long*)(port->base + offset)); + else + return inl(port->base + offset); +} + +static /*inline*/ void +sio_out(struct rs_port *port, int offset, unsigned int value) +{ + if (port->io_type < 0) + /* don't use __raw_writel that does swapping for big endian */ + (*(volatile unsigned long*)(port->base + offset))=(value); + else + outl(value, port->base + offset); +} + +static inline void +sio_mask(struct rs_port *port, int offset, unsigned int value) +{ + sio_out(port, offset, sio_in(port, offset) & ~value); +} +static inline void +sio_set(struct rs_port *port, int offset, unsigned int value) +{ + sio_out(port, offset, sio_in(port, offset) | value); +} + +/* + * Forward declarations for serial routines + */ +static void rs_disable_tx_interrupts (void * ptr); +static void rs_enable_tx_interrupts (void * ptr); +static void rs_disable_rx_interrupts (void * ptr); +static void rs_enable_rx_interrupts (void * ptr); +static int rs_get_CD (void * ptr); +static void rs_shutdown_port (void * ptr); +static int rs_set_real_termios (void *ptr); +static int rs_chars_in_buffer (void * ptr); +static void rs_hungup (void *ptr); +static void rs_getserial (void*, struct serial_struct *sp); +static void rs_close (void *ptr); + +/* + * Used by generic serial driver to access hardware + */ +static struct real_driver rs_real_driver = { + disable_tx_interrupts: rs_disable_tx_interrupts, + enable_tx_interrupts: rs_enable_tx_interrupts, + disable_rx_interrupts: rs_disable_rx_interrupts, + enable_rx_interrupts: rs_enable_rx_interrupts, + get_CD: rs_get_CD, + shutdown_port: rs_shutdown_port, + set_real_termios: rs_set_real_termios, + chars_in_buffer: rs_chars_in_buffer, + close: rs_close, + hungup: rs_hungup, + getserial: rs_getserial, +}; + +/* + * Structures and such for TTY sessions and usage counts + */ +static struct tty_driver rs_driver, rs_callout_driver; +static struct tty_struct *rs_table[NR_PORTS]; +static struct termios *rs_termios[NR_PORTS]; +static struct termios *rs_termios_locked[NR_PORTS]; +int rs_refcount; +int rs_initialized = 0; + +#ifdef CONFIG_SERIAL_TXX9_CONSOLE +static struct console sercons; +#endif +#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +static unsigned long break_pressed; /* break, really ... */ +#endif + +static inline void receive_chars(struct rs_port *port, + int *status, struct pt_regs *regs) +{ + struct tty_struct *tty = port->gs.tty; + unsigned char ch; + struct async_icount *icount; + int max_count = 256; + + icount = &port->icount; + do { + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + tty->flip.tqueue.routine((void *) tty); + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + return; // if TTY_DONT_FLIP is set + } + ch = sio_in(port, TXX9_SIRFIFO); + *tty->flip.char_buf_ptr = ch; + icount->rx++; + + *tty->flip.flag_buf_ptr = 0; + if (*status & (TXX9_SIDISR_UBRK | TXX9_SIDISR_UPER | + TXX9_SIDISR_UFER | TXX9_SIDISR_UOER)) { + /* + * For statistics only + */ + if (*status & TXX9_SIDISR_UBRK) { + *status &= ~(TXX9_SIDISR_UFER | TXX9_SIDISR_UPER); + icount->brk++; + /* + * We do the SysRQ and SAK checking + * here because otherwise the break + * may get masked by ignore_status_mask + * or read_status_mask. + */ +#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) + if (port == &rs_ports[sercons.index]) { + if (!break_pressed) { + break_pressed = jiffies; + goto ignore_char; + } + break_pressed = 0; + } +#endif + if (port->gs.flags & ASYNC_SAK) + do_SAK(tty); + } else if (*status & TXX9_SIDISR_UPER) + icount->parity++; + else if (*status & TXX9_SIDISR_UFER) + icount->frame++; + if (*status & TXX9_SIDISR_UOER) + icount->overrun++; + + /* + * Mask off conditions which should be ignored. + */ + *status &= port->read_status_mask; + +#ifdef CONFIG_SERIAL_TXX9_CONSOLE + /* Break flag is updated by reading RFIFO. */ +#endif + if (*status & (TXX9_SIDISR_UBRK)) { + *tty->flip.flag_buf_ptr = TTY_BREAK; + } else if (*status & TXX9_SIDISR_UPER) + *tty->flip.flag_buf_ptr = TTY_PARITY; + else if (*status & TXX9_SIDISR_UFER) + *tty->flip.flag_buf_ptr = TTY_FRAME; + } +#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) + if (break_pressed && port == &rs_ports[sercons.index]) { + if (ch != 0 && + time_before(jiffies, break_pressed + HZ*5)) { + handle_sysrq(ch, regs, NULL, NULL); + break_pressed = 0; + goto ignore_char; + } + break_pressed = 0; + } +#endif + if ((*status & port->ignore_status_mask) == 0) { + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + tty->flip.count++; + } + if ((*status & TXX9_SIDISR_UOER) && + (tty->flip.count < TTY_FLIPBUF_SIZE)) { + /* + * Overrun is special, since it's reported + * immediately, and doesn't affect the current + * character + */ + *tty->flip.flag_buf_ptr = TTY_OVERRUN; + tty->flip.count++; + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + } +#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) + ignore_char: +#endif + *status = sio_in(port, TXX9_SIDISR); + } while ((!(*status & TXX9_SIDISR_UVALID)) && (max_count-- > 0)); + tty_flip_buffer_push(tty); +} + +static inline void transmit_chars(struct rs_port *port) +{ + int count; + + if (port->x_char) { + sio_out(port, TXX9_SITFIFO, port->x_char); + port->icount.tx++; + port->x_char = 0; + return; + } + if (port->gs.xmit_cnt <= 0 + || port->gs.tty->stopped + || port->gs.tty->hw_stopped) { + rs_disable_tx_interrupts(port); + return; + } + + count = TXX9_SIO_TX_FIFO; + do { + sio_out(port, TXX9_SITFIFO, port->gs.xmit_buf[port->gs.xmit_tail++]); + port->gs.xmit_tail &= SERIAL_XMIT_SIZE-1; + port->icount.tx++; + if (--port->gs.xmit_cnt <= 0) + break; + } while (--count > 0); + + if (port->gs.xmit_cnt <= 0 || port->gs.tty->stopped || + port->gs.tty->hw_stopped) { + rs_disable_tx_interrupts(port); + } + + if (port->gs.xmit_cnt <= port->gs.wakeup_chars) { + if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + port->gs.tty->ldisc.write_wakeup) + (port->gs.tty->ldisc.write_wakeup)(port->gs.tty); + wake_up_interruptible(&port->gs.tty->write_wait); + } +} + +static inline void check_modem_status(struct rs_port *port) +{ + /* We don't have a carrier detect line - but just respond + like we had one anyways so that open() becomes unblocked */ + wake_up_interruptible(&port->gs.open_wait); +} + +#define RS_ISR_PASS_LIMIT 256 + +static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) +{ + struct rs_port * port = (struct rs_port *)dev_id; + unsigned long flags; + int status; + int pass_counter = 0; + + local_irq_save(flags); + + if (!port || !port->gs.tty) { + local_irq_restore(flags); + return; + } + + do { + status = sio_in(port, TXX9_SIDISR); + if (!(sio_in(port, TXX9_SIDICR) & TXX9_SIDICR_TIE)) + status &= ~TXX9_SIDISR_TDIS; + if (!(status & (TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS | + TXX9_SIDISR_TOUT))) + break; + + if (status & TXX9_SIDISR_RDIS) + receive_chars(port, &status, regs); +#if 0 /* RTS/CTS are controled by HW. (if possible) */ + check_modem_status(port); +#endif + if (status & TXX9_SIDISR_TDIS) + transmit_chars(port); + /* Clear TX/RX Int. Status */ + sio_mask(port, TXX9_SIDISR, + TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS | + TXX9_SIDISR_TOUT); + + if (pass_counter++ > RS_ISR_PASS_LIMIT) { + break; + } + } while (1); + local_irq_restore(flags); +} + +/* + *********************************************************************** + * Here are the routines that actually * + * interface with the generic_serial driver * + *********************************************************************** + */ +static void rs_disable_tx_interrupts (void * ptr) +{ + struct rs_port *port = ptr; + unsigned long flags; + + local_irq_save(flags); + port->gs.flags &= ~GS_TX_INTEN; + sio_mask(port, TXX9_SIDICR, TXX9_SIDICR_TIE); + local_irq_restore(flags); +} + +static void rs_enable_tx_interrupts (void * ptr) +{ + struct rs_port *port = ptr; + unsigned long flags; + + local_irq_save(flags); + sio_set(port, TXX9_SIDICR, TXX9_SIDICR_TIE); + local_irq_restore(flags); +} + +static void rs_disable_rx_interrupts (void * ptr) +{ + struct rs_port *port = ptr; + unsigned long flags; + + local_irq_save(flags); + port->read_status_mask &= ~TXX9_SIDISR_RDIS; +#if 0 + sio_mask(port, TXX9_SIDICR, TXX9_SIDICR_RIE); +#endif + local_irq_restore(flags); +} + +static void rs_enable_rx_interrupts (void * ptr) +{ + struct rs_port *port = ptr; + sio_set(port, TXX9_SIDICR, TXX9_SIDICR_RIE); +} + + +static int rs_get_CD (void * ptr) +{ + /* No Carried Detect in Hardware - just return true */ + return (1); +} + +static void rs_shutdown_port (void * ptr) +{ + struct rs_port *port = ptr; + + port->gs.flags &= ~GS_ACTIVE; + + free_irq(port->irq, port); + sio_out(port, TXX9_SIDICR, 0); /* disable all intrs */ + /* disable break condition */ + sio_mask(port, TXX9_SIFLCR, TXX9_SIFLCR_TBRK); + +#ifdef CONFIG_SERIAL_TXX9_CONSOLE + if (port == &rs_ports[sercons.index]) { +#endif + if (!port->gs.tty || (port->gs.tty->termios->c_cflag & HUPCL)) { + /* drop RTS */ + sio_set(port, TXX9_SIFLCR, + TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE); + /* TXX9-SIO can not control DTR... */ + } + + /* reset FIFO's */ + sio_set(port, TXX9_SIFCR, + TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE); + /* clear reset */ + sio_mask(port, TXX9_SIFCR, + TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE); + /* Disable RX/TX */ + sio_set(port, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE); +#ifdef CONFIG_SERIAL_TXX9_CONSOLE + } +#endif +} + +static int rs_set_real_termios (void *ptr) +{ + struct rs_port *port = ptr; + int quot = 0, baud_base, baud; + unsigned cflag, cval, fcr = 0; + int bits; + unsigned long flags; + + if (!port->gs.tty || !port->gs.tty->termios) + return 0; + cflag = port->gs.tty->termios->c_cflag; + cval = sio_in(port, TXX9_SILCR); + /* byte size and parity */ + cval &= ~TXX9_SILCR_UMODE_MASK; + switch (cflag & CSIZE) { + case CS7: + cval |= TXX9_SILCR_UMODE_7BIT; + bits = 9; + break; + case CS5: /* not supported */ + case CS6: /* not supported */ + case CS8: + default: + cval |= TXX9_SILCR_UMODE_8BIT; + bits = 10; + break; + } + cval &= ~TXX9_SILCR_USBL_MASK; + if (cflag & CSTOPB) { + cval |= TXX9_SILCR_USBL_2BIT; + bits++; + } else { + cval |= TXX9_SILCR_USBL_1BIT; + } + + cval &= ~(TXX9_SILCR_UPEN | TXX9_SILCR_UEPS); + if (cflag & PARENB) { + cval |= TXX9_SILCR_UPEN; + bits++; + } + if (!(cflag & PARODD)) + cval |= TXX9_SILCR_UEPS; + + /* Determine divisor based on baud rate */ + baud = tty_get_baud_rate(port->gs.tty); + if (!baud) + baud = 9600; /* B0 transition handled in rs_set_termios */ + baud_base = port->baud_base; + quot = (baud_base + baud / 2) / baud; + /* As a last resort, if the quotient is zero, default to 9600 bps */ + if (!quot) + quot = (baud_base + 9600 / 2) / 9600; + port->quot = quot; + + /* Set up FIFO's */ + /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */ + fcr = TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1; + + /* CTS flow control flag */ + if (cflag & CRTSCTS) { + port->gs.flags |= ASYNC_CTS_FLOW; + if (port->flags & TXX9_SERIAL_HAVE_CTS_LINE) + sio_out(port, TXX9_SIFLCR, + TXX9_SIFLCR_RCS | TXX9_SIFLCR_TES | + TXX9_SIFLCR_RTSTL_MAX /* 15 */); + } else { + port->gs.flags &= ~ASYNC_CTS_FLOW; + sio_mask(port, TXX9_SIFLCR, + TXX9_SIFLCR_RCS | TXX9_SIFLCR_TES | + TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE); + } + + /* + * Set up parity check flag + */ +#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) + + port->read_status_mask = TXX9_SIDISR_UOER | + TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS; + if (I_INPCK(port->gs.tty)) + port->read_status_mask |= TXX9_SIDISR_UFER | TXX9_SIDISR_UPER; + if (I_BRKINT(port->gs.tty) || I_PARMRK(port->gs.tty)) + port->read_status_mask |= TXX9_SIDISR_UBRK; + + /* + * Characters to ignore + */ + port->ignore_status_mask = 0; + if (I_IGNPAR(port->gs.tty)) + port->ignore_status_mask |= TXX9_SIDISR_UPER | TXX9_SIDISR_UFER; + if (I_IGNBRK(port->gs.tty)) { + port->ignore_status_mask |= TXX9_SIDISR_UBRK; + /* + * If we're ignore parity and break indicators, ignore + * overruns too. (For real raw support). + */ + if (I_IGNPAR(port->gs.tty)) + port->ignore_status_mask |= TXX9_SIDISR_UOER; + } +#if 0 /* XXX: This cause problem with some programs(init, mingetty, etc) */ + /* + * !!! ignore all characters if CREAD is not set + */ + if ((cflag & CREAD) == 0) + port->ignore_status_mask |= TXX9_SIDISR_RDIS; +#endif + local_irq_save(flags); + cval &= ~TXX9_SILCR_SCS_IMCLK; + sio_out(port, TXX9_SILCR, cval | TXX9_SILCR_SCS_IMCLK_BG); + sio_out(port, TXX9_SIBGR, quot | TXX9_SIBGR_BCLK_T0); + sio_out(port, TXX9_SIFCR, fcr); + local_irq_restore(flags); + return 0; +} + +static int rs_chars_in_buffer (void * ptr) +{ + struct rs_port *port = ptr; + + /* return 0 if transmitter disabled. */ + if (sio_in(port, TXX9_SIFLCR) & TXX9_SIFLCR_TSDE) + return 0; + return (sio_in(port, TXX9_SICISR) & TXX9_SICISR_TXALS) ? 0 : 1; +} + +/* ********************************************************************** * + * Here are the routines that actually * + * interface with the rest of the system * + * ********************************************************************** */ +static int rs_open (struct tty_struct * tty, struct file * filp) +{ + struct rs_port *port; + int retval, line; + + if (!rs_initialized) { + return -EIO; + } + + line = MINOR(tty->device) - tty->driver.minor_start; + + if ((line < 0) || (line >= NR_PORTS)) + return -ENODEV; + + /* Pre-initialized already */ + port = & rs_ports[line]; + + if (!port->base) + return -ENODEV; + + tty->driver_data = port; + port->gs.tty = tty; + port->gs.count++; + + /* + * Start up serial port + */ + retval = gs_init_port(&port->gs); + if (retval) { + port->gs.count--; + return retval; + } + + port->gs.flags |= GS_ACTIVE; + + if (port->gs.count == 1) { + MOD_INC_USE_COUNT; + + /* + * Clear the FIFO buffers and disable them + * (they will be reenabled in rs_set_real_termios()) + */ + sio_set(port, TXX9_SIFCR, + TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | + TXX9_SIFCR_FRSTE); + /* clear reset */ + sio_mask(port, TXX9_SIFCR, + TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | + TXX9_SIFCR_FRSTE); + sio_out(port, TXX9_SIDICR, 0); + + retval = request_irq(port->irq, rs_interrupt, SA_SHIRQ, + "serial_txx9", port); + if (retval) { + printk(KERN_ERR "serial_txx9: request_irq: err %d\n", + retval); + MOD_DEC_USE_COUNT; + port->gs.count--; + return retval; + } + /* + * Clear the interrupt registers. + */ + sio_out(port, TXX9_SIDISR, 0); + + /* HW RTS/CTS control */ + if (port->flags & TXX9_SERIAL_HAVE_CTS_LINE) + sio_out(port, TXX9_SIFLCR, + TXX9_SIFLCR_RCS | TXX9_SIFLCR_TES | + TXX9_SIFLCR_RTSTL_MAX /* 15 */); + } + + /* Enable RX/TX */ + sio_mask(port, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE); + + /* + * Finally, enable interrupts + */ + rs_enable_rx_interrupts(port); + + /* + * and set the speed of the serial port + */ + rs_set_real_termios(port); + + retval = gs_block_til_ready(&port->gs, filp); + + if (retval) { + if (port->gs.count == 1) { + free_irq(port->irq, port); + MOD_DEC_USE_COUNT; + } + port->gs.count--; + return retval; + } + /* tty->low_latency = 1; */ + + if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) { + if (tty->driver.subtype == SERIAL_TYPE_NORMAL) + *tty->termios = port->gs.normal_termios; + else + *tty->termios = port->gs.callout_termios; + rs_set_real_termios(port); + } +#ifdef CONFIG_SERIAL_TXX9_CONSOLE + if (sercons.cflag && sercons.index == line) { + tty->termios->c_cflag = sercons.cflag; + sercons.cflag = 0; + rs_set_real_termios(port); + } +#endif + port->gs.session = current->session; + port->gs.pgrp = current->pgrp; + return 0; +} + +/* + * /proc fs routines.... + */ + +static inline int line_info(char *buf, struct rs_port *port) +{ + char stat_buf[30]; + int ret; + unsigned long flags; + + ret = sprintf(buf, "%d: uart:txx9 io%s:%lx irq:%d", + port - &rs_ports[0], + port->io_type < 0 ? "mem" : "port", + port->base, port->irq); + + if (!port->base) { + ret += sprintf(buf+ret, "\n"); + return ret; + } + + /* + * Figure out the current RS-232 lines + */ + stat_buf[0] = 0; + stat_buf[1] = 0; + local_irq_save(flags); + if (!(sio_in(port, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC)) + strcat(stat_buf, "|RTS"); + if (!(sio_in(port, TXX9_SICISR) & TXX9_SICISR_CTSS)) + strcat(stat_buf, "|CTS"); + local_irq_restore(flags); + + if (port->quot) { + ret += sprintf(buf+ret, " baud:%d", + port->baud_base / port->quot); + } + + ret += sprintf(buf+ret, " tx:%d rx:%d", + port->icount.tx, port->icount.rx); + + if (port->icount.frame) + ret += sprintf(buf+ret, " fe:%d", port->icount.frame); + + if (port->icount.parity) + ret += sprintf(buf+ret, " pe:%d", port->icount.parity); + + if (port->icount.brk) + ret += sprintf(buf+ret, " brk:%d", port->icount.brk); + + if (port->icount.overrun) + ret += sprintf(buf+ret, " oe:%d", port->icount.overrun); + + /* + * Last thing is the RS-232 status lines + */ + ret += sprintf(buf+ret, " %s\n", stat_buf+1); + return ret; +} + +static int rs_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + int i, len = 0, l; + off_t begin = 0; + + len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version); + for (i = 0; i < NR_PORTS && len < 4000; i++) { + l = line_info(page + len, &rs_ports[i]); + len += l; + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } + } + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (begin-off); + return ((count < begin+len-off) ? count : begin+len-off); +} + +static void rs_close (void *ptr) +{ +#if 0 + struct rs_port *port = ptr; + free_irq(port->irq, port); +#endif + MOD_DEC_USE_COUNT; +} + +/* I haven't the foggiest why the decrement use count has to happen + here. The whole linux serial drivers stuff needs to be redesigned. + My guess is that this is a hack to minimize the impact of a bug + elsewhere. Thinking about it some more. (try it sometime) Try + running minicom on a serial port that is driven by a modularized + driver. Have the modem hangup. Then remove the driver module. Then + exit minicom. I expect an "oops". -- REW */ +static void rs_hungup (void *ptr) +{ + MOD_DEC_USE_COUNT; +} + +static void rs_getserial (void *ptr, struct serial_struct *sp) +{ + struct rs_port *port = ptr; + struct tty_struct *tty = port->gs.tty; + /* some applications (busybox, dbootstrap, etc.) look this */ + sp->line = MINOR(tty->device) - tty->driver.minor_start; +} + +/* + * rs_break() --- routine which turns the break handling on or off + */ +static void rs_break(struct tty_struct *tty, int break_state) +{ + struct rs_port *port = tty->driver_data; + unsigned long flags; + + if (!port->base) + return; + local_irq_save(flags); + if (break_state == -1) + sio_set(port, TXX9_SIFLCR, TXX9_SIFLCR_TBRK); + else + sio_mask(port, TXX9_SIFLCR, TXX9_SIFLCR_TBRK); + local_irq_restore(flags); +} + +static int get_modem_info(struct rs_port *port, unsigned int *value) +{ + unsigned int result; + unsigned long flags; + + local_irq_save(flags); + result = ((sio_in(port, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS) + | ((sio_in(port, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS); + local_irq_restore(flags); + return put_user(result,value); +} + +static int set_modem_info(struct rs_port *port, unsigned int cmd, + unsigned int *value) +{ + int error = 0; + unsigned int arg; + unsigned long flags; + + if (copy_from_user(&arg, value, sizeof(int))) + return -EFAULT; + + local_irq_save(flags); + switch (cmd) { + case TIOCMBIS: + if (arg & TIOCM_RTS) + sio_mask(port, TXX9_SIFLCR, + TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE); + break; + case TIOCMBIC: + if (arg & TIOCM_RTS) + sio_set(port, TXX9_SIFLCR, + TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE); + break; + case TIOCMSET: + if (arg & TIOCM_RTS) + sio_mask(port, TXX9_SIFLCR, + TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE); + else + sio_set(port, TXX9_SIFLCR, + TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE); + break; + default: + error = -EINVAL; + } + local_irq_restore(flags); + return error; +} + +static int rs_ioctl (struct tty_struct * tty, struct file * filp, + unsigned int cmd, unsigned long arg) +{ + int rc; + struct rs_port *port = tty->driver_data; + int ival; + + rc = 0; + switch (cmd) { + case TIOCMGET: + return get_modem_info(port, (unsigned int *) arg); + case TIOCMBIS: + case TIOCMBIC: + case TIOCMSET: + return set_modem_info(port, cmd, (unsigned int *) arg); + return 0; + case TIOCGSOFTCAR: + rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0), + (unsigned int *) arg); + break; + case TIOCSSOFTCAR: + if ((rc = verify_area(VERIFY_READ, (void *) arg, + sizeof(int))) == 0) { + get_user(ival, (unsigned int *) arg); + tty->termios->c_cflag = + (tty->termios->c_cflag & ~CLOCAL) | + (ival ? CLOCAL : 0); + } + break; + case TIOCGSERIAL: + if ((rc = verify_area(VERIFY_WRITE, (void *) arg, + sizeof(struct serial_struct))) == 0) + rc = gs_getserial(&port->gs, (struct serial_struct *) arg); + break; + case TIOCSSERIAL: + if ((rc = verify_area(VERIFY_READ, (void *) arg, + sizeof(struct serial_struct))) == 0) + rc = gs_setserial(&port->gs, (struct serial_struct *) arg); + break; + default: + rc = -ENOIOCTLCMD; + break; + } + + return rc; +} + + +/* + * This function is used to send a high-priority XON/XOFF character to + * the device + */ +static void rs_send_xchar(struct tty_struct * tty, char ch) +{ + struct rs_port *port = (struct rs_port *)tty->driver_data; + + port->x_char = ch; + if (ch) { + /* Make sure transmit interrupts are on */ + rs_enable_tx_interrupts(tty); + } +} + + +/* + * ------------------------------------------------------------ + * rs_throttle() + * + * This routine is called by the upper-layer tty layer to signal that + * incoming characters should be throttled. + * ------------------------------------------------------------ + */ +static void rs_throttle(struct tty_struct * tty) +{ + struct rs_port *port = (struct rs_port *)tty->driver_data; + unsigned long flags; + + if (I_IXOFF(tty)) + rs_send_xchar(tty, STOP_CHAR(tty)); + if (tty->termios->c_cflag & CRTSCTS) { + local_irq_save(flags); + /* drop RTS */ + sio_set(port, TXX9_SIFLCR, + TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE); + local_irq_restore(flags); + } +} + +static void rs_unthrottle(struct tty_struct * tty) +{ + struct rs_port *port = tty->driver_data; + unsigned long flags; + + if (I_IXOFF(tty)) { + if (port->x_char) + port->x_char = 0; + else + rs_send_xchar(tty, START_CHAR(tty)); + } + if (tty->termios->c_cflag & CRTSCTS) { + local_irq_save(flags); + sio_mask(port, TXX9_SIFLCR, + TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE); + local_irq_restore(flags); + } +} + +/* ********************************************************************** * + * Here are the initialization routines. * + * ********************************************************************** */ + +static inline void show_serial_version(void) +{ + printk(KERN_INFO "%s version %s\n", serial_name, serial_version); +} + +static int rs_init_portstructs(void) +{ + struct rs_port *port; + int i; + + /* Adjust the values in the "driver" */ + rs_driver.termios = rs_termios; + rs_driver.termios_locked = rs_termios_locked; + + port = rs_ports; + for (i=0; i < NR_PORTS;i++) { + port->gs.callout_termios = tty_std_termios; + port->gs.normal_termios = tty_std_termios; + port->gs.magic = TXX9_SERIAL_MAGIC; + port->gs.close_delay = HZ/2; + port->gs.closing_wait = 30 * HZ; + port->gs.rd = &rs_real_driver; +#ifdef NEW_WRITE_LOCKING + port->gs.port_write_sem = MUTEX; +#endif +#ifdef DECLARE_WAITQUEUE + init_waitqueue_head(&port->gs.open_wait); + init_waitqueue_head(&port->gs.close_wait); +#endif + port++; + } + + return 0; +} + +static int rs_init_drivers(void) +{ + int error; + + memset(&rs_driver, 0, sizeof(rs_driver)); + rs_driver.magic = TTY_DRIVER_MAGIC; + rs_driver.driver_name = "serial_txx9"; +#if defined(CONFIG_DEVFS_FS) + rs_driver.name = TXX9_TTY_DEVFS_NAME; +#else + rs_driver.name = TXX9_TTY_NAME; +#endif + rs_driver.major = TXX9_TTY_MAJOR; + rs_driver.minor_start = TXX9_TTY_MINOR_START; + rs_driver.num = NR_PORTS; + rs_driver.type = TTY_DRIVER_TYPE_SERIAL; + rs_driver.subtype = SERIAL_TYPE_NORMAL; + rs_driver.init_termios = tty_std_termios; + rs_driver.init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + rs_driver.refcount = &rs_refcount; + rs_driver.table = rs_table; + rs_driver.termios = rs_termios; + rs_driver.termios_locked = rs_termios_locked; + + rs_driver.open = rs_open; + rs_driver.close = gs_close; + rs_driver.write = gs_write; + rs_driver.put_char = gs_put_char; + rs_driver.flush_chars = gs_flush_chars; + rs_driver.write_room = gs_write_room; + rs_driver.chars_in_buffer = gs_chars_in_buffer; + rs_driver.flush_buffer = gs_flush_buffer; + rs_driver.ioctl = rs_ioctl; + rs_driver.throttle = rs_throttle; + rs_driver.unthrottle = rs_unthrottle; + rs_driver.set_termios = gs_set_termios; + rs_driver.stop = gs_stop; + rs_driver.start = gs_start; + rs_driver.hangup = gs_hangup; + rs_driver.break_ctl = rs_break; + rs_driver.read_proc = rs_read_proc; + + rs_callout_driver = rs_driver; +#if defined(CONFIG_DEVFS_FS) + rs_callout_driver.name = TXX9_CU_DEVFS_NAME; +#else + rs_callout_driver.name = TXX9_CU_NAME; +#endif + rs_callout_driver.major = TXX9_TTYAUX_MAJOR; + rs_callout_driver.subtype = SERIAL_TYPE_CALLOUT; + rs_callout_driver.read_proc = 0; + rs_callout_driver.proc_entry = 0; + + if ((error = tty_register_driver(&rs_driver))) { + printk(KERN_ERR + "Couldn't register serial driver, error = %d\n", + error); + return 1; + } + if ((error = tty_register_driver(&rs_callout_driver))) { + tty_unregister_driver(&rs_driver); + printk(KERN_ERR + "Couldn't register callout driver, error = %d\n", + error); + return 1; + } + + return 0; +} + +/* + * This routine is called by txx9_rs_init() to initialize a specific serial + * port. + */ +static void txx9_config(struct rs_port *port) +{ + unsigned long flags; + + if (port - &rs_ports[0] != sercons.index) { + local_irq_save(flags); + /* + * Reset the UART. + */ + sio_out(port, TXX9_SIFCR, TXX9_SIFCR_SWRST); +#ifdef CONFIG_CPU_TX49XX + /* TX4925 BUG WORKAROUND. Accessing SIOC register + * immediately after soft reset causes bus error. */ + wbflush();/* change iob(); */ + udelay(1); +#endif + while (sio_in(port, TXX9_SIFCR) & TXX9_SIFCR_SWRST) + ; + /* TX Int by FIFO Empty, RX Int by Receiving 1 char. */ + sio_set(port, TXX9_SIFCR, + TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1); + /* initial settings */ + sio_out(port, TXX9_SILCR, + TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT | + TXX9_SILCR_SCS_IMCLK_BG); + sio_out(port, TXX9_SIBGR, + ((port->baud_base + 9600 / 2) / 9600) | + TXX9_SIBGR_BCLK_T0); + local_irq_restore(flags); + } + DBG("txx9_config: port->io_type is %d\n", port->io_type); + if (port->io_type < 0) + request_mem_region(port->base, 36, "serial_txx9"); + else + request_region(port->base, 36, "serial_txx9"); +} + +#ifdef ENABLE_SERIAL_TXX9_PCI +static int __devinit serial_txx9_init_one(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + int rc, i; + struct rs_port *port; + + rc = pci_enable_device(dev); + if (rc) return rc; + + /* find empty slot */ + for (i = 0; i < NR_PORTS && rs_ports[i].base; i++) + ; + if (i == NR_PORTS) + return -ENODEV; + port = &rs_ports[i]; + DBG("port number is %d\n",i); + + port->pci_dev = dev; + port->base = pci_resource_start(dev, 1); + + DBG("port->base is %x\n",(u32)port->base); + port->io_type = SERIAL_IO_PORT; + port->irq = dev->irq; + port->flags |= TXX9_SERIAL_HAVE_CTS_LINE; + port->baud_base = 66670000 / 16 / 2; /* 66.67MHz */ + DBG("port->baud_base %x\n",port->baud_base); + + txx9_config(port); + + printk(KERN_INFO + "%s%d at 0x%08lx (irq = %d) is a TX39/49 SIO\n", + TXX9_TTY_NAME, i, port->base, port->irq); + return 0; +} + +static void __devexit serial_txx9_remove_one(struct pci_dev *dev) +{ + int i; + for (i = 0; i < NR_PORTS; i++) { + if (rs_ports[i].pci_dev == dev) { + rs_ports[i].irq = 0; + rs_ports[i].base = 0; + rs_ports[i].pci_dev = 0; + /* XXX NOT IMPLEMENTED YET */ + break; + } + } +} + +static struct pci_device_id serial_txx9_pci_tbl[] __devinitdata = { +#ifdef PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC + { PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + 0 }, +#endif + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, serial_txx9_pci_tbl); + +static struct pci_driver serial_txx9_pci_driver = { + name: "serial_txx9", + probe: serial_txx9_init_one, + remove: __devexit_p(serial_txx9_remove_one), + id_table: serial_txx9_pci_tbl, +}; + +/* + * Query PCI space for known serial boards + * If found, add them to the PCI device space in rs_table[] + */ +static void __devinit probe_serial_txx9_pci(void) +{ + /* Register call PCI serial devices. Null out + * the driver name upon failure, as a signal + * not to attempt to unregister the driver later + */ + if (pci_module_init (&serial_txx9_pci_driver) != 0) + serial_txx9_pci_driver.name = ""; + + return; +} +#endif /* ENABLE_SERIAL_TXX9_PCI */ + +static int __init txx9_rs_init(void) +{ + int rc; + struct rs_port *port; + int i; + +#ifndef ENABLE_SERIAL_TXX9_PCI + for (i = 0, port = &rs_ports[0]; i < NR_PORTS; i++,port++) { + if (port->base) + goto config_ok; + } + return -ENODEV; + config_ok: +#endif + + show_serial_version(); + rc = rs_init_portstructs (); + rs_init_drivers (); + for (i = 0, port = &rs_ports[0]; i < NR_PORTS; i++,port++) { + if (!port->base) + continue; + if (port->io_type < 0) { + if (check_mem_region(port->base, 36)) + continue; + } else { + if (check_region(port->base, 36)) + continue; + } + txx9_config(port); + printk(KERN_INFO + "%s%d at 0x%08lx (irq = %d) is a TX39/49 SIO\n", + TXX9_TTY_NAME, i, port->base, port->irq); + } + + /* Note: I didn't do anything to enable the second UART */ + if (rc >= 0) + rs_initialized++; + +#ifdef ENABLE_SERIAL_TXX9_PCI + probe_serial_txx9_pci(); +#endif + return 0; +} + +/* + * This is for use by architectures that know their serial console + * attributes only at run time. Not to be invoked after rs_init(). + */ +int __init early_serial_txx9_setup(int line, unsigned long base, int irq, + int baud_base, int have_cts) +{ + if (line >= NR_PORTS) + return(-ENOENT); + rs_ports[line].base = base; + rs_ports[line].irq = irq; + rs_ports[line].baud_base = baud_base; + rs_ports[line].io_type = -1; /* virtual memory mapped */ + if (have_cts) + rs_ports[line].flags |= TXX9_SERIAL_HAVE_CTS_LINE; + return(0); +} + +static void __exit txx9_rs_fini(void) +{ + unsigned long flags; + int e1, e2; + int i; + + local_irq_save(flags); + if ((e1 = tty_unregister_driver(&rs_driver))) + printk("serial: failed to unregister serial driver (%d)\n", + e1); + if ((e2 = tty_unregister_driver(&rs_callout_driver))) + printk("serial: failed to unregister callout driver (%d)\n", + e2); + local_irq_restore(flags); + + for (i = 0; i < NR_PORTS; i++) { + if (!rs_ports[i].base) + continue; + if (rs_ports[i].io_type < 0) + release_mem_region(rs_ports[i].base, 36); + else + release_region(rs_ports[i].base, 36); + } + +#ifdef ENABLE_SERIAL_PCI + if (serial_txx9_pci_driver.name[0]) + pci_unregister_driver (&serial_txx9_pci_driver); +#endif +} + +module_init(txx9_rs_init); +module_exit(txx9_rs_fini); +MODULE_DESCRIPTION("TX39/49 serial driver"); +MODULE_AUTHOR("TOSHIBA Corporation"); +MODULE_LICENSE("GPL"); + +/* + * Begin serial console routines + */ +#ifdef CONFIG_SERIAL_TXX9_CONSOLE + +/* + * Wait for transmitter & holding register to empty + */ +static inline void wait_for_xmitr(struct rs_port *port) +{ + unsigned int tmout = 1000000; + + do { + if (--tmout == 0) break; + } while (!(sio_in(port, TXX9_SICISR) & TXX9_SICISR_TXALS)); + + /* Wait for flow control if necessary */ +#if (ASYNC_INTERNAL_FLAGS & GS_INTERNAL_FLAGS) == 0 /* check conflict... */ + if (port->gs.flags & ASYNC_CONS_FLOW) { + tmout = 1000000; + while (--tmout && + (sio_in(port, TXX9_SICISR) & TXX9_SICISR_CTSS)); + } +#endif +} + +/* + * Print a string to the serial port trying not to disturb + * any possible real use of the port... + * + * The console_lock must be held when we get here. + */ +static void serial_console_write(struct console *co, const char *s, + unsigned count) +{ + struct rs_port *port = &rs_ports[co->index]; + int ier; + unsigned i; + + /* + * First save the IER then disable the interrupts + */ + ier = sio_in(port, TXX9_SIDICR); + sio_out(port, TXX9_SIDICR, 0); + + /* + * Now, do each character + */ + for (i = 0; i < count; i++, s++) { + wait_for_xmitr(port); + + /* + * Send the character out. + * If a LF, also do CR... + */ + sio_out(port, TXX9_SITFIFO, *s); + if (*s == 10) { + wait_for_xmitr(port); + sio_out(port, TXX9_SITFIFO, 13); + } + } + + /* + * Finally, Wait for transmitter & holding register to empty + * and restore the IER + */ + wait_for_xmitr(port); + sio_out(port, TXX9_SIDICR, ier); +} + +static kdev_t serial_console_device(struct console *c) +{ + return MKDEV(TXX9_TTY_MAJOR, TXX9_TTY_MINOR_START + c->index); +} + +static __init int serial_console_setup(struct console *co, char *options) +{ + struct rs_port *port; + unsigned cval; + int baud = 9600; + int bits = 8; + int parity = 'n'; + int doflow = 0; + int cflag = CREAD | HUPCL | CLOCAL; + int quot = 0; + char *s; + + if (co->index < 0 || co->index >= NR_PORTS) + return -1; + if (options) { + baud = simple_strtoul(options, NULL, 10); + s = options; + while(*s >= '0' && *s <= '9') + s++; + if (*s) parity = *s++; + if (*s) bits = *s - '0'; + if (*s) doflow = (*s++ == 'r'); + } + + /* + * Now construct a cflag setting. + */ + switch(baud) { + case 1200: cflag |= B1200; break; + case 2400: cflag |= B2400; break; + case 4800: cflag |= B4800; break; + case 19200: cflag |= B19200; break; + case 38400: cflag |= B38400; break; + case 57600: cflag |= B57600; break; + case 115200: cflag |= B115200; break; + default: + /* + * Set this to a sane value to prevent a divide error + */ + baud = 9600; + case 9600: cflag |= B9600; break; + } + + switch(bits) { + case 7: cflag |= CS7; break; + default: + case 8: cflag |= CS8; break; + } + switch(parity) { + case 'o': case 'O': cflag |= PARODD; break; + case 'e': case 'E': cflag |= PARENB; break; + } + co->cflag = cflag; + + port = &rs_ports[co->index]; + if (!port->base) + return -1; + + /* + * Divisor, bytesize and parity + */ +#if (ASYNC_INTERNAL_FLAGS & GS_INTERNAL_FLAGS) == 0 /* check conflict... */ + if (doflow) + port->gs.flags |= ASYNC_CONS_FLOW; +#endif + quot = port->baud_base / baud; + switch (cflag & CSIZE) { + case CS7: cval = TXX9_SILCR_UMODE_7BIT; break; + default: + case CS8: cval = TXX9_SILCR_UMODE_8BIT; break; + } + if (cflag & CSTOPB) + cval |= TXX9_SILCR_USBL_2BIT; + else + cval |= TXX9_SILCR_USBL_1BIT; + if (cflag & PARENB) + cval |= TXX9_SILCR_UPEN; + if (!(cflag & PARODD)) + cval |= TXX9_SILCR_UEPS; + + /* + * Disable UART interrupts, set DTR and RTS high + * and set speed. + */ + sio_out(port, TXX9_SIDICR, 0); + sio_out(port, TXX9_SILCR, cval | TXX9_SILCR_SCS_IMCLK_BG); + sio_out(port, TXX9_SIBGR, quot | TXX9_SIBGR_BCLK_T0); + /* no RTS/CTS control */ + sio_out(port, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */); + /* Enable RX/TX */ + sio_mask(port, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE); + + /* console port should not use RTC/CTS. */ + port->flags &= ~TXX9_SERIAL_HAVE_CTS_LINE; + return 0; +} + +static struct console sercons = { + name: TXX9_TTY_NAME, + write: serial_console_write, + device: serial_console_device, + setup: serial_console_setup, + flags: CON_PRINTBUFFER, + index: -1, +}; + +void __init txx9_serial_console_init(void) +{ + register_console(&sercons); +} + +#endif + +/******************************************************************************/ +/* BEG: KDBG Routines */ +/******************************************************************************/ + +#ifdef CONFIG_KGDB +int kgdb_init_count = 0; +#endif + +#ifdef CONFIG_KGDB +void txx9_sio_kgdb_hook(unsigned int port, unsigned int baud_rate) +{ + static struct resource kgdb_resource; + int ret; + + /* prevent initialization by driver */ + kgdb_resource.name = "serial_txx9(debug)"; + kgdb_resource.start = rs_ports[port].base; + kgdb_resource.end = rs_ports[port].base + 36 - 1; + kgdb_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY; + + ret = request_resource(&iomem_resource, &kgdb_resource); + if(ret == -EBUSY) + printk(" serial_txx9(debug): request_resource failed\n"); + + return; +} +#endif /* CONFIG_KGDB */ + +#ifdef CONFIG_KGDB +void +txx9_sio_kdbg_init( unsigned int port_number ) +{ + if ( port_number == 1 ) { + txx9_sio_kgdb_hook( port_number, 38400 ); + } else { + printk("Bad Port Number [%u] != [1]\n",port_number); + } + return; +} +#endif /* CONFIG_KGDB */ + +#ifdef CONFIG_KGDB +u8 +txx9_sio_kdbg_rd( void ) +{ + unsigned int status,ch; + + if ( kgdb_init_count == 0 ) + { + txx9_sio_kdbg_init( 1 ); + kgdb_init_count = 1; + } + + while ( 1 ) + { + status = sio_in(&rs_ports[1], TXX9_SIDISR); + if ( status & 0x1f ) + { + ch = sio_in(&rs_ports[1], TXX9_SIRFIFO ); + break; + } + } + + return( ch ); +} +#endif /* CONFIG_KGDB */ + +#ifdef CONFIG_KGDB +int +txx9_sio_kdbg_wr( u8 ch ) +{ + unsigned int status; + + if ( kgdb_init_count == 0 ) + { + txx9_sio_kdbg_init( 1 ); + kgdb_init_count = 1; + } + + while ( 1 ) + { + status = sio_in(&rs_ports[1], TXX9_SICISR); + if (status & TXX9_SICISR_TRDY) + { + if ( ch == '\n' ) + { + txx9_sio_kdbg_wr( '\r' ); + } + sio_out(&rs_ports[1], TXX9_SITFIFO, (u32)ch ); + + break; + } + } + + return( 1 ); +} +#endif /* CONFIG_KGDB */ + +/******************************************************************************/ +/* END: KDBG Routines */ +/******************************************************************************/ + +void txx9_raw_output(char c) +{ + struct rs_port *port = &rs_ports[0]; + if ( c == '\n' ) + { + sio_out(port, TXX9_SITFIFO, '\r'); + wait_for_xmitr(port); + } + sio_out(port, TXX9_SITFIFO, c); + wait_for_xmitr(port); + return; +} diff -urN linux-2.4.21-bk37/drivers/char/sgiserial.c linux-2.4.21-bk38/drivers/char/sgiserial.c --- linux-2.4.21-bk37/drivers/char/sgiserial.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/drivers/char/sgiserial.c 2003-08-24 02:56:03.000000000 -0700 @@ -0,0 +1,2235 @@ +/* sgiserial.c: Serial port driver for SGI machines. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ + +/* + * Note: This driver seems to have been derived from some + * version of the sbus/char/zs.c driver. A lot of clean-up + * and bug fixes seem to have happened to the Sun driver in + * the intervening time. As of 21.09.1999, I have merged in + * ONLY the changes necessary to fix observed functional + * problems on the Indy. Someone really ought to do a + * thorough pass to merge in the rest of the updates. + * Better still, someone really ought to make it a common + * code module for both platforms. kevink@mips.com + * + * 20010616 - Klaus Naumann : Make serial console work with + * any speed - not only 9600 + */ + +#include /* for CONFIG_KGDB */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sgiserial.h" + +#define NUM_SERIAL 1 /* One chip on board. */ +#define NUM_CHANNELS (NUM_SERIAL * 2) + +struct sgi_zslayout *zs_chips[NUM_SERIAL]; +struct sgi_zschannel *zs_channels[NUM_CHANNELS]; +struct sgi_zschannel *zs_conschan; +struct sgi_zschannel *zs_kgdbchan; + +struct sgi_serial zs_soft[NUM_CHANNELS]; +struct sgi_serial *zs_chain; /* IRQ servicing chain */ +static int zilog_irq = SGI_SERIAL_IRQ; + +/* Console hooks... */ +static int zs_cons_chanout; +static int zs_cons_chanin; +struct sgi_serial *zs_consinfo; + +static unsigned char kgdb_regs[16] = { + 0, 0, 0, /* write 0, 1, 2 */ + (Rx8 | RxENABLE), /* write 3 */ + (X16CLK | SB1 | PAR_EVEN), /* write 4 */ + (Tx8 | TxENAB), /* write 5 */ + 0, 0, 0, /* write 6, 7, 8 */ + (NV), /* write 9 */ + (NRZ), /* write 10 */ + (TCBR | RCBR), /* write 11 */ + 0, 0, /* BRG time constant, write 12 + 13 */ + (BRENABL), /* write 14 */ + (DCDIE) /* write 15 */ +}; + +static unsigned char zscons_regs[16] = { + 0, /* write 0 */ + (EXT_INT_ENAB | INT_ALL_Rx), /* write 1 */ + 0, /* write 2 */ + (Rx8 | RxENABLE), /* write 3 */ + (X16CLK), /* write 4 */ + (DTR | Tx8 | TxENAB), /* write 5 */ + 0, 0, 0, /* write 6, 7, 8 */ + (NV | MIE), /* write 9 */ + (NRZ), /* write 10 */ + (TCBR | RCBR), /* write 11 */ + 0, 0, /* BRG time constant, write 12 + 13 */ + (BRENABL), /* write 14 */ + (DCDIE | CTSIE | TxUIE | BRKIE) /* write 15 */ +}; + +#define ZS_CLOCK 3672000 /* Zilog input clock rate */ + +DECLARE_TASK_QUEUE(tq_serial); + +struct tty_driver serial_driver, callout_driver; +struct console *sgisercon; +static int serial_refcount; + +/* serial subtype definitions */ +#define SERIAL_TYPE_NORMAL 1 +#define SERIAL_TYPE_CALLOUT 2 + +/* number of characters left in xmit buffer before we ask for more */ +#define WAKEUP_CHARS 256 + +#undef SERIAL_DEBUG_OPEN + +static void change_speed(struct sgi_serial *info); + +static struct tty_struct *serial_table[NUM_CHANNELS]; +static struct termios *serial_termios[NUM_CHANNELS]; +static struct termios *serial_termios_locked[NUM_CHANNELS]; + +/* + * tmp_buf is used as a temporary buffer by serial_write. We need to + * lock it in case the memcpy_fromfs blocks while swapping in a page, + * and some other program tries to do a serial write at the same time. + * Since the lock will only come under contention when the system is + * swapping and available memory is low, it makes sense to share one + * buffer across all the serial ports, since it significantly saves + * memory if large numbers of serial ports are open. + */ +static unsigned char tmp_buf[PAGE_SIZE]; /* This is cheating */ +static DECLARE_MUTEX(tmp_buf_sem); + +static inline int serial_paranoia_check(struct sgi_serial *info, + dev_t device, const char *routine) +{ +#ifdef SERIAL_PARANOIA_CHECK + static const char *badmagic = KERN_WARNING + "Warning: bad magic number for serial struct (%d, %d) in %s\n"; + static const char *badinfo = KERN_WARNING + "Warning: null sgi_serial for (%d, %d) in %s\n"; + + if (!info) { + printk(badinfo, MAJOR(device), MINOR(device), routine); + return 1; + } + if (info->magic != SERIAL_MAGIC) { + printk(badmagic, MAJOR(device), MINOR(device), routine); + return 1; + } +#endif + return 0; +} + +/* + * This is used to figure out the divisor speeds and the timeouts + */ +static int baud_table[] = { + 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, + 9600, 19200, 38400, 57600, 115200, 0 }; + +/* + * Reading and writing Zilog8530 registers. The delays are to make this + * driver work on the Sun4 which needs a settling delay after each chip + * register access, other machines handle this in hardware via auxiliary + * flip-flops which implement the settle time we do in software. + * + * read_zsreg() and write_zsreg() may get called from rs_kgdb_hook() before + * interrupts are enabled. Therefore we have to check ioc_iocontrol before we + * access it. + */ +static inline unsigned char read_zsreg(struct sgi_zschannel *channel, + unsigned char reg) +{ + unsigned char retval; + volatile unsigned char junk; + + udelay(2); + channel->control = reg; + junk = sgint->istat0; + udelay(1); + retval = channel->control; + return retval; +} + +static inline void write_zsreg(struct sgi_zschannel *channel, + unsigned char reg, unsigned char value) +{ + volatile unsigned char junk; + + udelay(2); + channel->control = reg; + junk = sgint->istat0; + udelay(1); + channel->control = value; + junk = sgint->istat0; + return; +} + +static inline void load_zsregs(struct sgi_zschannel *channel, unsigned char *regs) +{ + ZS_CLEARERR(channel); + ZS_CLEARFIFO(channel); + /* Load 'em up */ + write_zsreg(channel, R4, regs[R4]); + write_zsreg(channel, R10, regs[R10]); + write_zsreg(channel, R3, regs[R3] & ~RxENABLE); + write_zsreg(channel, R5, regs[R5] & ~TxENAB); + write_zsreg(channel, R1, regs[R1]); + write_zsreg(channel, R9, regs[R9]); + write_zsreg(channel, R11, regs[R11]); + write_zsreg(channel, R12, regs[R12]); + write_zsreg(channel, R13, regs[R13]); + write_zsreg(channel, R14, regs[R14]); + write_zsreg(channel, R15, regs[R15]); + write_zsreg(channel, R3, regs[R3]); + write_zsreg(channel, R5, regs[R5]); + return; +} + +/* Sets or clears DTR/RTS on the requested line */ +static inline void zs_rtsdtr(struct sgi_serial *ss, int set) +{ + if(set) { + ss->curregs[5] |= (RTS | DTR); + write_zsreg(ss->zs_channel, 5, ss->curregs[5]); + } else { + ss->curregs[5] &= ~(RTS | DTR); + write_zsreg(ss->zs_channel, 5, ss->curregs[5]); + } + return; +} + +static inline void kgdb_chaninit(struct sgi_serial *ss, int intson, int bps) +{ + int brg; + + if(intson) { + kgdb_regs[R1] = INT_ALL_Rx; + kgdb_regs[R9] |= MIE; + } else { + kgdb_regs[R1] = 0; + kgdb_regs[R9] &= ~MIE; + } + brg = BPS_TO_BRG(bps, ZS_CLOCK/ss->clk_divisor); + kgdb_regs[R12] = (brg & 255); + kgdb_regs[R13] = ((brg >> 8) & 255); + load_zsregs(ss->zs_channel, kgdb_regs); +} + +/* Utility routines for the Zilog */ +static inline int get_zsbaud(struct sgi_serial *ss) +{ + struct sgi_zschannel *channel = ss->zs_channel; + int brg; + + /* The baud rate is split up between two 8-bit registers in + * what is termed 'BRG time constant' format in my docs for + * the chip, it is a function of the clk rate the chip is + * receiving which happens to be constant. + */ + brg = ((read_zsreg(channel, 13)&0xff) << 8); + brg |= (read_zsreg(channel, 12)&0xff); + return BRG_TO_BPS(brg, (ZS_CLOCK/(ss->clk_divisor))); +} + +/* + * ------------------------------------------------------------ + * rs_stop() and rs_start() + * + * This routines are called before setting or resetting tty->stopped. + * They enable or disable transmitter interrupts, as necessary. + * ------------------------------------------------------------ + */ +static void rs_stop(struct tty_struct *tty) +{ + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_stop")) + return; + + save_flags(flags); cli(); + if (info->curregs[5] & TxENAB) { + info->curregs[5] &= ~TxENAB; + write_zsreg(info->zs_channel, 5, info->curregs[5]); + } + restore_flags(flags); +} + +static void rs_start(struct tty_struct *tty) +{ + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_start")) + return; + + save_flags(flags); cli(); + if (info->xmit_cnt && info->xmit_buf && !(info->curregs[5] & TxENAB)) { + info->curregs[5] |= TxENAB; + write_zsreg(info->zs_channel, 5, info->curregs[5]); + } + restore_flags(flags); +} + +/* Drop into either the boot monitor or kadb upon receiving a break + * from keyboard/console input. + */ +static void batten_down_hatches(void) +{ + ArcEnterInteractiveMode(); +#if 0 + /* If we are doing kadb, we call the debugger + * else we just drop into the boot monitor. + * Note that we must flush the user windows + * first before giving up control. + */ + printk("\n"); + if((((unsigned long)linux_dbvec)>=DEBUG_FIRSTVADDR) && + (((unsigned long)linux_dbvec)<=DEBUG_LASTVADDR)) + sp_enter_debugger(); + else + prom_halt(); + + /* XXX We want to notify the keyboard driver that all + * XXX keys are in the up state or else weird things + * XXX happen... + */ +#endif + return; +} + +/* On receive, this clears errors and the receiver interrupts */ +static inline void rs_recv_clear(struct sgi_zschannel *zsc) +{ + volatile unsigned char junk; + + udelay(2); + zsc->control = ERR_RES; + junk = sgint->istat0; + udelay(2); + zsc->control = RES_H_IUS; + junk = sgint->istat0; +} + +/* + * ---------------------------------------------------------------------- + * + * Here starts the interrupt handling routines. All of the following + * subroutines are declared as inline and are folded into + * rs_interrupt(). They were separated out for readability's sake. + * + * Note: rs_interrupt() is a "fast" interrupt, which means that it + * runs with interrupts turned off. People who may want to modify + * rs_interrupt() should try to keep the interrupt handler as fast as + * possible. After you are done making modifications, it is not a bad + * idea to do: + * + * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c + * + * and look at the resulting assemble code in serial.s. + * + * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 + * ----------------------------------------------------------------------- + */ + +/* + * This routine is used by the interrupt handler to schedule + * processing in the software interrupt portion of the driver. + */ +static inline void rs_sched_event(struct sgi_serial *info, + int event) +{ + info->event |= 1 << event; + queue_task(&info->tqueue, &tq_serial); + mark_bh(SERIAL_BH); +} + +#ifdef CONFIG_KGDB +extern void set_async_breakpoint(unsigned int epc); +#endif + +static inline void receive_chars(struct sgi_serial *info, struct pt_regs *regs) +{ + struct tty_struct *tty = info->tty; + volatile unsigned char junk; + unsigned char ch, stat; + + udelay(2); + ch = info->zs_channel->data; + junk = sgint->istat0; + udelay(2); + stat = read_zsreg(info->zs_channel, R1); + + /* If this is the console keyboard, we need to handle + * L1-A's here. + */ + if(info->is_cons) { + if(ch==0) { /* whee, break received */ + batten_down_hatches(); + rs_recv_clear(info->zs_channel); + return; + } else if (ch == 1) { + show_state(); + return; + } else if (ch == 2) { + show_buffers(); + return; + } + } + /* Look for kgdb 'stop' character, consult the gdb documentation + * for remote target debugging and arch/sparc/kernel/sparc-stub.c + * to see how all this works. + */ +#ifdef CONFIG_KGDB + if((info->kgdb_channel) && (ch =='\003')) { + set_async_breakpoint(read_32bit_cp0_register(CP0_EPC)); + goto clear_and_exit; + } +#endif + if(!tty) + goto clear_and_exit; + + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + queue_task(&tty->flip.tqueue, &tq_timer); + tty->flip.count++; + if(stat & PAR_ERR) + *tty->flip.flag_buf_ptr++ = TTY_PARITY; + else if(stat & Rx_OVR) + *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; + else if(stat & CRC_ERR) + *tty->flip.flag_buf_ptr++ = TTY_FRAME; + else + *tty->flip.flag_buf_ptr++ = 0; /* XXX */ + *tty->flip.char_buf_ptr++ = ch; + + queue_task(&tty->flip.tqueue, &tq_timer); + +clear_and_exit: + rs_recv_clear(info->zs_channel); + return; +} + +static inline void transmit_chars(struct sgi_serial *info) +{ + volatile unsigned char junk; + + /* P3: In theory we have to test readiness here because a + * serial console can clog the chip through zs_cons_put_char(). + * David did not do this. I think he relies on 3-chars FIFO in 8530. + * Let's watch for lost _output_ characters. XXX + */ + + /* SGI ADDENDUM: On most SGI machines, the Zilog does possess + * a 16 or 17 byte fifo, so no worries. -dm + */ + + if (info->x_char) { + /* Send next char */ + udelay(2); + info->zs_channel->data = info->x_char; + junk = sgint->istat0; + + info->x_char = 0; + goto clear_and_return; + } + + if((info->xmit_cnt <= 0) || info->tty->stopped) { + /* That's peculiar... */ + udelay(2); + info->zs_channel->control = RES_Tx_P; + junk = sgint->istat0; + goto clear_and_return; + } + + /* Send char */ + udelay(2); + info->zs_channel->data = info->xmit_buf[info->xmit_tail++]; + junk = sgint->istat0; + + info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); + info->xmit_cnt--; + + if (info->xmit_cnt < WAKEUP_CHARS) + rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); + + if(info->xmit_cnt <= 0) { + udelay(2); + info->zs_channel->control = RES_Tx_P; + junk = sgint->istat0; + goto clear_and_return; + } + +clear_and_return: + /* Clear interrupt */ + udelay(2); + info->zs_channel->control = RES_H_IUS; + junk = sgint->istat0; + return; +} + +static inline void status_handle(struct sgi_serial *info) +{ + volatile unsigned char junk; + unsigned char status; + + /* Get status from Read Register 0 */ + udelay(2); + status = info->zs_channel->control; + junk = sgint->istat0; + /* Clear status condition... */ + udelay(2); + info->zs_channel->control = RES_EXT_INT; + junk = sgint->istat0; + /* Clear the interrupt */ + udelay(2); + info->zs_channel->control = RES_H_IUS; + junk = sgint->istat0; + +#if 0 + if(status & DCD) { + if((info->tty->termios->c_cflag & CRTSCTS) && + ((info->curregs[3] & AUTO_ENAB)==0)) { + info->curregs[3] |= AUTO_ENAB; + write_zsreg(info->zs_channel, 3, info->curregs[3]); + } + } else { + if((info->curregs[3] & AUTO_ENAB)) { + info->curregs[3] &= ~AUTO_ENAB; + write_zsreg(info->zs_channel, 3, info->curregs[3]); + } + } +#endif + /* Whee, if this is console input and this is a + * 'break asserted' status change interrupt, call + * the boot prom. + */ + if((status & BRK_ABRT) && info->break_abort) + batten_down_hatches(); + + /* XXX Whee, put in a buffer somewhere, the status information + * XXX whee whee whee... Where does the information go... + */ + return; +} + +/* + * This is the serial driver's generic interrupt routine + */ +void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) +{ + struct sgi_serial * info = (struct sgi_serial *) dev_id; + unsigned char zs_intreg; + + zs_intreg = read_zsreg(info->zs_next->zs_channel, 3); + + /* NOTE: The read register 3, which holds the irq status, + * does so for both channels on each chip. Although + * the status value itself must be read from the A + * channel and is only valid when read from channel A. + * Yes... broken hardware... + */ +#define CHAN_A_IRQMASK (CHARxIP | CHATxIP | CHAEXT) +#define CHAN_B_IRQMASK (CHBRxIP | CHBTxIP | CHBEXT) + + /* *** Chip 1 *** */ + /* Channel B -- /dev/ttyb, could be the console */ + if(zs_intreg & CHAN_B_IRQMASK) { + if (zs_intreg & CHBRxIP) + receive_chars(info, regs); + if (zs_intreg & CHBTxIP) + transmit_chars(info); + if (zs_intreg & CHBEXT) + status_handle(info); + } + + info=info->zs_next; + + /* Channel A -- /dev/ttya, could be the console */ + if(zs_intreg & CHAN_A_IRQMASK) { + if (zs_intreg & CHARxIP) + receive_chars(info, regs); + if (zs_intreg & CHATxIP) + transmit_chars(info); + if (zs_intreg & CHAEXT) + status_handle(info); + } +} + +/* + * ------------------------------------------------------------------- + * Here ends the serial interrupt routines. + * ------------------------------------------------------------------- + */ + +/* + * This routine is used to handle the "bottom half" processing for the + * serial driver, known also the "software interrupt" processing. + * This processing is done at the kernel interrupt level, after the + * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This + * is where time-consuming activities which can not be done in the + * interrupt driver proper are done; the interrupt driver schedules + * them using rs_sched_event(), and they get done here. + */ +static void do_serial_bh(void) +{ + run_task_queue(&tq_serial); +} + +static void do_softint(void *private_) +{ + struct sgi_serial *info = (struct sgi_serial *) private_; + struct tty_struct *tty; + + tty = info->tty; + if (!tty) + return; + + if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); + wake_up_interruptible(&tty->write_wait); + } +} + +/* + * This routine is called from the scheduler tqueue when the interrupt + * routine has signalled that a hangup has occurred. The path of + * hangup processing is: + * + * serial interrupt routine -> (scheduler tqueue) -> + * do_serial_hangup() -> tty->hangup() -> rs_hangup() + * + */ +static void do_serial_hangup(void *private_) +{ + struct sgi_serial *info = (struct sgi_serial *) private_; + struct tty_struct *tty; + + tty = info->tty; + if (!tty) + return; + + tty_hangup(tty); +} + + +static int startup(struct sgi_serial * info) +{ + volatile unsigned char junk; + unsigned long flags; + + if (info->flags & ZILOG_INITIALIZED) + return 0; + + if (!info->xmit_buf) { + info->xmit_buf = (unsigned char *) get_free_page(GFP_KERNEL); + if (!info->xmit_buf) + return -ENOMEM; + } + + save_flags(flags); cli(); + +#ifdef SERIAL_DEBUG_OPEN + printk("starting up ttys%d (irq %d)...\n", info->line, info->irq); +#endif + + /* + * Clear the FIFO buffers and disable them + * (they will be reenabled in change_speed()) + */ + ZS_CLEARFIFO(info->zs_channel); + info->xmit_fifo_size = 1; + + /* + * Clear the interrupt registers. + */ + udelay(2); + info->zs_channel->control = ERR_RES; + junk = sgint->istat0; + udelay(2); + info->zs_channel->control = RES_H_IUS; + junk = sgint->istat0; + + /* + * Now, initialize the Zilog + */ + zs_rtsdtr(info, 1); + + /* + * Finally, enable sequencing and interrupts + */ + info->curregs[1] |= (info->curregs[1] & ~0x18) | (EXT_INT_ENAB|INT_ALL_Rx); + info->curregs[3] |= (RxENABLE | Rx8); + /* We enable Tx interrupts as needed. */ + info->curregs[5] |= (TxENAB | Tx8); + info->curregs[9] |= (NV | MIE); + write_zsreg(info->zs_channel, 3, info->curregs[3]); + write_zsreg(info->zs_channel, 5, info->curregs[5]); + write_zsreg(info->zs_channel, 9, info->curregs[9]); + + /* + * And clear the interrupt registers again for luck. + */ + udelay(2); + info->zs_channel->control = ERR_RES; + junk = sgint->istat0; + udelay(2); + info->zs_channel->control = RES_H_IUS; + junk = sgint->istat0; + + if (info->tty) + clear_bit(TTY_IO_ERROR, &info->tty->flags); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + + /* + * and set the speed of the serial port + */ + change_speed(info); + + info->flags |= ZILOG_INITIALIZED; + restore_flags(flags); + return 0; +} + +/* + * This routine will shutdown a serial port; interrupts are disabled, and + * DTR is dropped if the hangup on close termio flag is on. + */ +static void shutdown(struct sgi_serial * info) +{ + unsigned long flags; + + if (!(info->flags & ZILOG_INITIALIZED)) + return; + +#ifdef SERIAL_DEBUG_OPEN + printk("Shutting down serial port %d (irq %d)....", info->line, + info->irq); +#endif + + save_flags(flags); cli(); /* Disable interrupts */ + + if (info->xmit_buf) { + free_page((unsigned long) info->xmit_buf); + info->xmit_buf = 0; + } + + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + + info->flags &= ~ZILOG_INITIALIZED; + restore_flags(flags); +} + +/* + * This routine is called to set the UART divisor registers to match + * the specified baud rate for a serial port. + */ +static void change_speed(struct sgi_serial *info) +{ + unsigned int port, cflag; + int i; + int brg; + + if (!info->tty || !info->tty->termios) + return; + cflag = info->tty->termios->c_cflag; + if (!(port = info->port)) + return; + i = cflag & CBAUD; + if (i & CBAUDEX) { + /* XXX CBAUDEX is not obeyed. + * It is impossible at a 32bits SPARC. + * But we have to report this to user ... someday. + */ + i = B9600; + } + if (i == 0) { + /* XXX B0, hangup the line. */ + do_serial_hangup(info); + } else if (baud_table[i]) { + info->zs_baud = baud_table[i]; + info->clk_divisor = 16; + + info->curregs[4] = X16CLK; + info->curregs[11] = TCBR | RCBR; + brg = BPS_TO_BRG(info->zs_baud, ZS_CLOCK/info->clk_divisor); + info->curregs[12] = (brg & 255); + info->curregs[13] = ((brg >> 8) & 255); + info->curregs[14] = BRENABL; + } + + /* byte size and parity */ + switch (cflag & CSIZE) { + case CS5: + info->curregs[3] &= ~(0xc0); + info->curregs[3] |= Rx5; + info->curregs[5] &= ~(0xe0); + info->curregs[5] |= Tx5; + break; + case CS6: + info->curregs[3] &= ~(0xc0); + info->curregs[3] |= Rx6; + info->curregs[5] &= ~(0xe0); + info->curregs[5] |= Tx6; + break; + case CS7: + info->curregs[3] &= ~(0xc0); + info->curregs[3] |= Rx7; + info->curregs[5] &= ~(0xe0); + info->curregs[5] |= Tx7; + break; + case CS8: + default: /* defaults to 8 bits */ + info->curregs[3] &= ~(0xc0); + info->curregs[3] |= Rx8; + info->curregs[5] &= ~(0xe0); + info->curregs[5] |= Tx8; + break; + } + info->curregs[4] &= ~(0x0c); + if (cflag & CSTOPB) + info->curregs[4] |= SB2; + else + info->curregs[4] |= SB1; + + if (cflag & PARENB) + info->curregs[4] |= PAR_ENA; + else + info->curregs[4] &= ~PAR_ENA; + + if (!(cflag & PARODD)) + info->curregs[4] |= PAR_EVEN; + else + info->curregs[4] &= ~PAR_EVEN; + + /* Load up the new values */ + load_zsregs(info->zs_channel, info->curregs); + + return; +} + +/* This is for console output over ttya/ttyb */ +static void zs_cons_put_char(char ch) +{ + struct sgi_zschannel *chan = zs_conschan; + volatile unsigned char junk; + unsigned long flags; + int loops = 0; + + save_flags(flags); cli(); + while(((junk = chan->control) & Tx_BUF_EMP)==0 && loops < 10000) { + loops++; + udelay(2); + } + + udelay(2); + chan->data = ch; + junk = sgint->istat0; + restore_flags(flags); +} + +/* + * This is the more generic put_char function for the driver. + * In earlier versions of this driver, "rs_put_char" was the + * name of the console-specific fucntion, now called zs_cons_put_char + */ + +static void rs_put_char(struct tty_struct *tty, char ch) +{ + struct sgi_zschannel *chan = + ((struct sgi_serial *)tty->driver_data)->zs_channel; + volatile unsigned char junk; + unsigned long flags; + int loops = 0; + + save_flags(flags); cli(); + while(((junk = chan->control) & Tx_BUF_EMP)==0 && loops < 10000) { + loops++; + udelay(2); + } + + udelay(2); + chan->data = ch; + junk = sgint->istat0; + restore_flags(flags); +} + +/* These are for receiving and sending characters under the kgdb + * source level kernel debugger. + */ +int putDebugChar(char kgdb_char) +{ + struct sgi_zschannel *chan = zs_kgdbchan; + volatile unsigned char junk; + unsigned long flags; + + save_flags(flags); cli(); + udelay(2); + while((chan->control & Tx_BUF_EMP)==0) + udelay(2); + + udelay(2); + chan->data = kgdb_char; + junk = sgint->istat0; + restore_flags(flags); + + return 1; +} + +char getDebugChar(void) +{ + struct sgi_zschannel *chan = zs_kgdbchan; + unsigned char junk; + + while((chan->control & Rx_CH_AV)==0) + udelay(2); + + junk = sgint->istat0; + udelay(2); + return chan->data; +} + +/* + * Fair output driver allows a process to speak. + */ +static void rs_fair_output(void) +{ + int left; /* Output no more than that */ + unsigned long flags; + struct sgi_serial *info = zs_consinfo; + volatile unsigned char junk; + char c; + + if (info == 0) return; + if (info->xmit_buf == 0) return; + + save_flags(flags); cli(); + left = info->xmit_cnt; + while (left != 0) { + c = info->xmit_buf[info->xmit_tail]; + info->xmit_tail = (info->xmit_tail+1) & (SERIAL_XMIT_SIZE-1); + info->xmit_cnt--; + restore_flags(flags); + + zs_cons_put_char(c); + + save_flags(flags); cli(); + left = min(info->xmit_cnt, left-1); + } + + /* Last character is being transmitted now (hopefully). */ + udelay(2); + zs_conschan->control = RES_Tx_P; + junk = sgint->istat0; + + restore_flags(flags); + return; +} + + +static int rs_write(struct tty_struct * tty, int from_user, + const unsigned char *buf, int count) +{ + int c, total = 0; + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_write")) + return 0; + + if (!tty || !info->xmit_buf) + return 0; + + save_flags(flags); + while (1) { + cli(); + c = min(count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + if (c <= 0) + break; + + if (from_user) { + down(&tmp_buf_sem); + copy_from_user(tmp_buf, buf, c); + c = min(c, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c); + up(&tmp_buf_sem); + } else + memcpy(info->xmit_buf + info->xmit_head, buf, c); + info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); + info->xmit_cnt += c; + restore_flags(flags); + buf += c; + count -= c; + total += c; + } + + if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { + /* + * The above test used to include the condition + * "&& !(info->curregs[5] & TxENAB)", but there + * is reason to suspect that it is never statisfied + * when the port is running. The problem may in fact + * have been masked by the fact that, if O_POST is set, + * there is always a rs_flush_xx operation following the + * rs_write, and the flush ignores that condition when + * it kicks off the transmit. + */ + /* Enable transmitter */ + info->curregs[1] |= TxINT_ENAB|EXT_INT_ENAB; + write_zsreg(info->zs_channel, 1, info->curregs[1]); + info->curregs[5] |= TxENAB; + write_zsreg(info->zs_channel, 5, info->curregs[5]); + + /* + * The following code is imported from the 2.3.6 Sun sbus zs.c + * driver, of which an earlier version served as the basis + * for sgiserial.c. Perhaps due to changes over time in + * the line discipline code, ns_write()s with from_user + * set would not otherwise actually kick-off output in + * Linux 2.2.x or later. Maybe it never really worked. + */ + + rs_put_char(tty, info->xmit_buf[info->xmit_tail++]); + info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); + info->xmit_cnt--; + } + + restore_flags(flags); + return total; +} + +static int rs_write_room(struct tty_struct *tty) +{ + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; + int ret; + + if (serial_paranoia_check(info, tty->device, "rs_write_room")) + return 0; + ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; + if (ret < 0) + ret = 0; + return ret; +} + +static int rs_chars_in_buffer(struct tty_struct *tty) +{ + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; + + if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer")) + return 0; + return info->xmit_cnt; +} + +static void rs_flush_buffer(struct tty_struct *tty) +{ + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; + + if (serial_paranoia_check(info, tty->device, "rs_flush_buffer")) + return; + cli(); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + sti(); + wake_up_interruptible(&tty->write_wait); + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); +} + +static void rs_flush_chars(struct tty_struct *tty) +{ + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_flush_chars")) + return; + + if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || + !info->xmit_buf) + return; + + /* Enable transmitter */ + save_flags(flags); cli(); + info->curregs[1] |= TxINT_ENAB|EXT_INT_ENAB; + write_zsreg(info->zs_channel, 1, info->curregs[1]); + info->curregs[5] |= TxENAB; + write_zsreg(info->zs_channel, 5, info->curregs[5]); + + /* + * Send a first (bootstrapping) character. A best solution is + * to call transmit_chars() here which handles output in a + * generic way. Current transmit_chars() not only transmits, + * but resets interrupts also what we do not desire here. + * XXX Discuss with David. + */ + if (info->zs_channel->control & Tx_BUF_EMP) { + volatile unsigned char junk; + + /* Send char */ + udelay(2); + info->zs_channel->data = info->xmit_buf[info->xmit_tail++]; + junk = sgint->istat0; + info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); + info->xmit_cnt--; + } + restore_flags(flags); +} + +/* + * ------------------------------------------------------------ + * rs_throttle() + * + * This routine is called by the upper-layer tty layer to signal that + * incoming characters should be throttled. + * ------------------------------------------------------------ + */ +static void rs_throttle(struct tty_struct * tty) +{ + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + printk("throttle %s: %d....\n", _tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (serial_paranoia_check(info, tty->device, "rs_throttle")) + return; + + if (I_IXOFF(tty)) + info->x_char = STOP_CHAR(tty); + + /* Turn off RTS line */ + cli(); + info->curregs[5] &= ~RTS; + write_zsreg(info->zs_channel, 5, info->curregs[5]); + sti(); +} + +static void rs_unthrottle(struct tty_struct * tty) +{ + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + printk("unthrottle %s: %d....\n", _tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (serial_paranoia_check(info, tty->device, "rs_unthrottle")) + return; + + if (I_IXOFF(tty)) { + if (info->x_char) + info->x_char = 0; + else + info->x_char = START_CHAR(tty); + } + + /* Assert RTS line */ + cli(); + info->curregs[5] |= RTS; + write_zsreg(info->zs_channel, 5, info->curregs[5]); + sti(); +} + +/* + * ------------------------------------------------------------ + * rs_ioctl() and friends + * ------------------------------------------------------------ + */ + +static int get_serial_info(struct sgi_serial * info, + struct serial_struct * retinfo) +{ + struct serial_struct tmp; + + if (!retinfo) + return -EFAULT; + memset(&tmp, 0, sizeof(tmp)); + tmp.type = info->type; + tmp.line = info->line; + tmp.port = info->port; + tmp.irq = info->irq; + tmp.flags = info->flags; + tmp.baud_base = info->baud_base; + tmp.close_delay = info->close_delay; + tmp.closing_wait = info->closing_wait; + tmp.custom_divisor = info->custom_divisor; + return copy_to_user(retinfo,&tmp,sizeof(*retinfo)) ? -EFAULT : 0; +} + +static int set_serial_info(struct sgi_serial * info, + struct serial_struct * new_info) +{ + struct serial_struct new_serial; + struct sgi_serial old_info; + int retval = 0; + + if (!new_info) + return -EFAULT; + copy_from_user(&new_serial,new_info,sizeof(new_serial)); + old_info = *info; + + if (!capable(CAP_SYS_ADMIN)) { + if ((new_serial.baud_base != info->baud_base) || + (new_serial.type != info->type) || + (new_serial.close_delay != info->close_delay) || + ((new_serial.flags & ~ZILOG_USR_MASK) != + (info->flags & ~ZILOG_USR_MASK))) + return -EPERM; + info->flags = ((info->flags & ~ZILOG_USR_MASK) | + (new_serial.flags & ZILOG_USR_MASK)); + info->custom_divisor = new_serial.custom_divisor; + goto check_and_exit; + } + + if (info->count > 1) + return -EBUSY; + + /* + * OK, past this point, all the error checking has been done. + * At this point, we start making changes..... + */ + + info->baud_base = new_serial.baud_base; + info->flags = ((info->flags & ~ZILOG_FLAGS) | + (new_serial.flags & ZILOG_FLAGS)); + info->type = new_serial.type; + info->close_delay = new_serial.close_delay; + info->closing_wait = new_serial.closing_wait; + +check_and_exit: + retval = startup(info); + return retval; +} + +/* + * get_lsr_info - get line status register info + * + * Purpose: Let user call ioctl() to get info when the UART physically + * is emptied. On bus types like RS485, the transmitter must + * release the bus after transmitting. This must be done when + * the transmit shift register is empty, not be done when the + * transmit holding register is empty. This functionality + * allows an RS485 driver to be written in user space. + */ +static int get_lsr_info(struct sgi_serial * info, unsigned int *value) +{ + volatile unsigned char junk; + unsigned char status; + + cli(); + udelay(2); + status = info->zs_channel->control; + junk = sgint->istat0; + sti(); + return put_user(status,value); +} + +static int get_modem_info(struct sgi_serial * info, unsigned int *value) +{ + unsigned char status; + unsigned int result; + + cli(); + status = info->zs_channel->control; + udelay(2); + sti(); + result = ((info->curregs[5] & RTS) ? TIOCM_RTS : 0) + | ((info->curregs[5] & DTR) ? TIOCM_DTR : 0) + | ((status & DCD) ? TIOCM_CAR : 0) + | ((status & SYNC) ? TIOCM_DSR : 0) + | ((status & CTS) ? TIOCM_CTS : 0); + if (put_user(result, value)) + return -EFAULT; + return 0; +} + +static int set_modem_info(struct sgi_serial * info, unsigned int cmd, + unsigned int *value) +{ + unsigned int arg; + + if (get_user(arg, value)) + return -EFAULT; + switch (cmd) { + case TIOCMBIS: + if (arg & TIOCM_RTS) + info->curregs[5] |= RTS; + if (arg & TIOCM_DTR) + info->curregs[5] |= DTR; + break; + case TIOCMBIC: + if (arg & TIOCM_RTS) + info->curregs[5] &= ~RTS; + if (arg & TIOCM_DTR) + info->curregs[5] &= ~DTR; + break; + case TIOCMSET: + info->curregs[5] = ((info->curregs[5] & ~(RTS | DTR)) + | ((arg & TIOCM_RTS) ? RTS : 0) + | ((arg & TIOCM_DTR) ? DTR : 0)); + break; + default: + return -EINVAL; + } + cli(); + write_zsreg(info->zs_channel, 5, info->curregs[5]); + sti(); + return 0; +} + +/* + * This routine sends a break character out the serial port. + */ +static void send_break( struct sgi_serial * info, int duration) +{ + if (!info->port) + return; + current->state = TASK_INTERRUPTIBLE; + cli(); + write_zsreg(info->zs_channel, 5, (info->curregs[5] | SND_BRK)); + schedule_timeout(duration); + write_zsreg(info->zs_channel, 5, info->curregs[5]); + sti(); +} + +static int rs_ioctl(struct tty_struct *tty, struct file * file, + unsigned int cmd, unsigned long arg) +{ + struct sgi_serial * info = (struct sgi_serial *) tty->driver_data; + int retval; + + if (serial_paranoia_check(info, tty->device, "zs_ioctl")) + return -ENODEV; + + if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && + (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) && + (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) { + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + } + + switch (cmd) { + case TCSBRK: /* SVID version: non-zero arg --> no break */ + retval = tty_check_change(tty); + if (retval) + return retval; + tty_wait_until_sent(tty, 0); + if (!arg) + send_break(info, HZ/4); /* 1/4 second */ + return 0; + case TCSBRKP: /* support for POSIX tcsendbreak() */ + retval = tty_check_change(tty); + if (retval) + return retval; + tty_wait_until_sent(tty, 0); + send_break(info, arg ? arg*(HZ/10) : HZ/4); + return 0; + case TIOCGSOFTCAR: + if (put_user(C_CLOCAL(tty) ? 1 : 0, + (unsigned long *) arg)) + return -EFAULT; + return 0; + case TIOCSSOFTCAR: + if (get_user(arg, (unsigned long *) arg)) + return -EFAULT; + tty->termios->c_cflag = + ((tty->termios->c_cflag & ~CLOCAL) | + (arg ? CLOCAL : 0)); + return 0; + case TIOCMGET: + return get_modem_info(info, (unsigned int *) arg); + case TIOCMBIS: + case TIOCMBIC: + case TIOCMSET: + return set_modem_info(info, cmd, (unsigned int *) arg); + case TIOCGSERIAL: + return get_serial_info(info, + (struct serial_struct *) arg); + case TIOCSSERIAL: + return set_serial_info(info, + (struct serial_struct *) arg); + case TIOCSERGETLSR: /* Get line status register */ + return get_lsr_info(info, (unsigned int *) arg); + + case TIOCSERGSTRUCT: + if (copy_to_user((struct sgi_serial *) arg, + info, sizeof(struct sgi_serial))) + return -EFAULT; + return 0; + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) +{ + struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; + + if (tty->termios->c_cflag == old_termios->c_cflag) + return; + + change_speed(info); + + if ((old_termios->c_cflag & CRTSCTS) && + !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + rs_start(tty); + } +} + +/* + * ------------------------------------------------------------ + * rs_close() + * + * This routine is called when the serial port gets closed. First, we + * wait for the last remaining data to be sent. Then, we unlink its + * ZILOG structure from the interrupt chain if necessary, and we free + * that IRQ if nothing is left in the chain. + * ------------------------------------------------------------ + */ +static void rs_close(struct tty_struct *tty, struct file * filp) +{ + struct sgi_serial * info = (struct sgi_serial *)tty->driver_data; + unsigned long flags; + + if (!info || serial_paranoia_check(info, tty->device, "rs_close")) + return; + + save_flags(flags); cli(); + + if (tty_hung_up_p(filp)) { + restore_flags(flags); + return; + } + +#ifdef SERIAL_DEBUG_OPEN + printk("rs_close ttys%d, count = %d\n", info->line, info->count); +#endif + if ((tty->count == 1) && (info->count != 1)) { + /* + * Uh, oh. tty->count is 1, which means that the tty + * structure will be freed. Info->count should always + * be one in these conditions. If it's greater than + * one, we've got real problems, since it means the + * serial port won't be shutdown. + */ + printk("rs_close: bad serial port count; tty->count is 1, " + "info->count is %d\n", info->count); + info->count = 1; + } + if (--info->count < 0) { + printk("rs_close: bad serial port count for ttys%d: %d\n", + info->line, info->count); + info->count = 0; + } + if (info->count) { + restore_flags(flags); + return; + } + info->flags |= ZILOG_CLOSING; + /* + * Save the termios structure, since this port may have + * separate termios for callout and dialin. + */ + if (info->flags & ZILOG_NORMAL_ACTIVE) + info->normal_termios = *tty->termios; + if (info->flags & ZILOG_CALLOUT_ACTIVE) + info->callout_termios = *tty->termios; + /* + * Now we wait for the transmit buffer to clear; and we notify + * the line discipline to only process XON/XOFF characters. + */ + tty->closing = 1; + if (info->closing_wait != ZILOG_CLOSING_WAIT_NONE) + tty_wait_until_sent(tty, info->closing_wait); + /* + * At this point we stop accepting input. To do this, we + * disable the receive line status interrupts, and tell the + * interrupt driver to stop checking the data ready bit in the + * line status register. + */ + /** if (!info->iscons) ... **/ + info->curregs[3] &= ~RxENABLE; + write_zsreg(info->zs_channel, 3, info->curregs[3]); + info->curregs[1] &= ~(0x18); + write_zsreg(info->zs_channel, 1, info->curregs[1]); + ZS_CLEARFIFO(info->zs_channel); + + shutdown(info); + if (tty->driver.flush_buffer) + tty->driver.flush_buffer(tty); + if (tty->ldisc.flush_buffer) + tty->ldisc.flush_buffer(tty); + tty->closing = 0; + info->event = 0; + info->tty = 0; + if (tty->ldisc.num != ldiscs[N_TTY].num) { + if (tty->ldisc.close) + (tty->ldisc.close)(tty); + tty->ldisc = ldiscs[N_TTY]; + tty->termios->c_line = N_TTY; + if (tty->ldisc.open) + (tty->ldisc.open)(tty); + } + if (info->blocked_open) { + if (info->close_delay) { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(info->close_delay); + } + wake_up_interruptible(&info->open_wait); + } + info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CALLOUT_ACTIVE| + ZILOG_CLOSING); + wake_up_interruptible(&info->close_wait); + restore_flags(flags); +} + +/* + * rs_hangup() --- called by tty_hangup() when a hangup is signaled. + */ +void rs_hangup(struct tty_struct *tty) +{ + struct sgi_serial * info = (struct sgi_serial *)tty->driver_data; + + if (serial_paranoia_check(info, tty->device, "rs_hangup")) + return; + + rs_flush_buffer(tty); + shutdown(info); + info->event = 0; + info->count = 0; + info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CALLOUT_ACTIVE); + info->tty = 0; + wake_up_interruptible(&info->open_wait); +} + +/* + * ------------------------------------------------------------ + * rs_open() and friends + * ------------------------------------------------------------ + */ +static int block_til_ready(struct tty_struct *tty, struct file * filp, + struct sgi_serial *info) +{ + DECLARE_WAITQUEUE(wait, current); + int retval; + int do_clocal = 0; + + /* + * If the device is in the middle of being closed, then block + * until it's done, and then try again. + */ + if (info->flags & ZILOG_CLOSING) { + interruptible_sleep_on(&info->close_wait); +#ifdef SERIAL_DO_RESTART + if (info->flags & ZILOG_HUP_NOTIFY) + return -EAGAIN; + else + return -ERESTARTSYS; +#else + return -EAGAIN; +#endif + } + + /* + * If this is a callout device, then just make sure the normal + * device isn't being used. + */ + if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) { + if (info->flags & ZILOG_NORMAL_ACTIVE) + return -EBUSY; + if ((info->flags & ZILOG_CALLOUT_ACTIVE) && + (info->flags & ZILOG_SESSION_LOCKOUT) && + (info->session != current->session)) + return -EBUSY; + if ((info->flags & ZILOG_CALLOUT_ACTIVE) && + (info->flags & ZILOG_PGRP_LOCKOUT) && + (info->pgrp != current->pgrp)) + return -EBUSY; + info->flags |= ZILOG_CALLOUT_ACTIVE; + return 0; + } + + /* + * If non-blocking mode is set, or the port is not enabled, + * then make the check up front and then exit. + */ + if ((filp->f_flags & O_NONBLOCK) || + (tty->flags & (1 << TTY_IO_ERROR))) { + if (info->flags & ZILOG_CALLOUT_ACTIVE) + return -EBUSY; + info->flags |= ZILOG_NORMAL_ACTIVE; + return 0; + } + + if (info->flags & ZILOG_CALLOUT_ACTIVE) { + if (info->normal_termios.c_cflag & CLOCAL) + do_clocal = 1; + } else { + if (tty->termios->c_cflag & CLOCAL) + do_clocal = 1; + } + + /* + * Block waiting for the carrier detect and the line to become + * free (i.e., not in use by the callout). While we are in + * this loop, info->count is dropped by one, so that + * rs_close() knows when to free things. We restore it upon + * exit, either normal or abnormal. + */ + retval = 0; + add_wait_queue(&info->open_wait, &wait); +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready before block: ttys%d, count = %d\n", + info->line, info->count); +#endif + info->count--; + info->blocked_open++; + while (1) { + cli(); + if (!(info->flags & ZILOG_CALLOUT_ACTIVE)) + zs_rtsdtr(info, 1); + sti(); + set_current_state(TASK_INTERRUPTIBLE); + if (tty_hung_up_p(filp) || + !(info->flags & ZILOG_INITIALIZED)) { +#ifdef SERIAL_DO_RESTART + if (info->flags & ZILOG_HUP_NOTIFY) + retval = -EAGAIN; + else + retval = -ERESTARTSYS; +#else + retval = -EAGAIN; +#endif + break; + } + if (!(info->flags & ZILOG_CALLOUT_ACTIVE) && + !(info->flags & ZILOG_CLOSING) && do_clocal) + break; + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready blocking: ttys%d, count = %d\n", + info->line, info->count); +#endif + schedule(); + } + current->state = TASK_RUNNING; + remove_wait_queue(&info->open_wait, &wait); + if (!tty_hung_up_p(filp)) + info->count++; + info->blocked_open--; +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready after blocking: ttys%d, count = %d\n", + info->line, info->count); +#endif + if (retval) + return retval; + info->flags |= ZILOG_NORMAL_ACTIVE; + return 0; +} + +/* + * This routine is called whenever a serial port is opened. It + * enables interrupts for a serial port, linking in its ZILOG structure into + * the IRQ chain. It also performs the serial-specific + * initialization for the tty structure. + */ +int rs_open(struct tty_struct *tty, struct file * filp) +{ + struct sgi_serial *info; + int retval, line; + + line = MINOR(tty->device) - tty->driver.minor_start; + /* The zilog lines for the mouse/keyboard must be + * opened using their respective drivers. + */ + if ((line < 0) || (line >= NUM_CHANNELS)) + return -ENODEV; + info = zs_soft + line; + /* Is the kgdb running over this line? */ + if (info->kgdb_channel) + return -ENODEV; + if (serial_paranoia_check(info, tty->device, "rs_open")) + return -ENODEV; +#ifdef SERIAL_DEBUG_OPEN + printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line, + info->count); +#endif + info->count++; + tty->driver_data = info; + info->tty = tty; + + /* + * Start up serial port + */ + retval = startup(info); + if (retval) + return retval; + + retval = block_til_ready(tty, filp, info); + if (retval) { +#ifdef SERIAL_DEBUG_OPEN + printk("rs_open returning after block_til_ready with %d\n", + retval); +#endif + return retval; + } + + if ((info->count == 1) && (info->flags & ZILOG_SPLIT_TERMIOS)) { + if (tty->driver.subtype == SERIAL_TYPE_NORMAL) + *tty->termios = info->normal_termios; + else + *tty->termios = info->callout_termios; + change_speed(info); + } + + /* If this is the serial console change the speed to + * the right value + */ + if (info->is_cons) { + info->tty->termios->c_cflag = sgisercon->cflag; + change_speed(info); + } + + info->session = current->session; + info->pgrp = current->pgrp; + +#ifdef SERIAL_DEBUG_OPEN + printk("rs_open ttys%d successful...\n", info->line); +#endif + return 0; +} + +/* Finally, routines used to initialize the serial driver. */ + +static void show_serial_version(void) +{ + printk("SGI Zilog8530 serial driver version 1.00\n"); +} + +/* Return layout for the requested zs chip number. */ +static inline struct sgi_zslayout *get_zs(int chip) +{ + if (chip > 0) + panic("Wheee, bogus zs chip number requested."); + + return (struct sgi_zslayout *) (&sgioc->serport); +} + + +static inline void +rs_cons_check(struct sgi_serial *ss, int channel) +{ + int i, o, io; + static int msg_printed = 0; + + i = o = io = 0; + + /* Is this one of the serial console lines? */ + if((zs_cons_chanout != channel) && + (zs_cons_chanin != channel)) + return; + zs_conschan = ss->zs_channel; + zs_consinfo = ss; + + + + /* If this is console input, we handle the break received + * status interrupt on this line to mean prom_halt(). + */ + if(zs_cons_chanin == channel) { + ss->break_abort = 1; + i = 1; + } + if(o && i) + io = 1; + + /* Set flag variable for this port so that it cannot be + * opened for other uses by accident. + */ + ss->is_cons = 1; + + if(io) { + if (!msg_printed) { + printk("zs%d: console I/O\n", ((channel>>1)&1)); + msg_printed = 1; + } + + } else { + printk("zs%d: console %s\n", ((channel>>1)&1), + (i==1 ? "input" : (o==1 ? "output" : "WEIRD"))); + } +} + +/* rs_init inits the driver */ +int rs_init(void) +{ + unsigned long flags; + int chip, channel, i; + struct sgi_serial *info; + + + /* Setup base handler, and timer table. */ + init_bh(SERIAL_BH, do_serial_bh); + + show_serial_version(); + + /* Initialize the tty_driver structure */ + /* SGI: Not all of this is exactly right for us. */ + + memset(&serial_driver, 0, sizeof(struct tty_driver)); + serial_driver.magic = TTY_DRIVER_MAGIC; +#ifdef CONFIG_DEVFS_FS + serial_driver.name = "tts/%d"; +#else + serial_driver.name = "ttyS"; +#endif + serial_driver.major = TTY_MAJOR; + serial_driver.minor_start = 64; + serial_driver.num = NUM_CHANNELS; + serial_driver.type = TTY_DRIVER_TYPE_SERIAL; + serial_driver.subtype = SERIAL_TYPE_NORMAL; + serial_driver.init_termios = tty_std_termios; + + serial_driver.init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + serial_driver.flags = TTY_DRIVER_REAL_RAW; + serial_driver.refcount = &serial_refcount; + serial_driver.table = serial_table; + serial_driver.termios = serial_termios; + serial_driver.termios_locked = serial_termios_locked; + + serial_driver.open = rs_open; + serial_driver.close = rs_close; + serial_driver.write = rs_write; + serial_driver.flush_chars = rs_flush_chars; + serial_driver.write_room = rs_write_room; + serial_driver.chars_in_buffer = rs_chars_in_buffer; + serial_driver.flush_buffer = rs_flush_buffer; + serial_driver.ioctl = rs_ioctl; + serial_driver.throttle = rs_throttle; + serial_driver.unthrottle = rs_unthrottle; + serial_driver.set_termios = rs_set_termios; + serial_driver.stop = rs_stop; + serial_driver.start = rs_start; + serial_driver.hangup = rs_hangup; + + /* + * The callout device is just like normal device except for + * major number and the subtype code. + */ + callout_driver = serial_driver; +#ifdef CONFIG_DEVFS_FS + callout_driver.name = "cua/%d"; +#else + callout_driver.name = "cua"; +#endif + callout_driver.major = TTYAUX_MAJOR; + callout_driver.subtype = SERIAL_TYPE_CALLOUT; + + if (tty_register_driver(&serial_driver)) + panic("Couldn't register serial driver"); + if (tty_register_driver(&callout_driver)) + panic("Couldn't register callout driver"); + + save_flags(flags); cli(); + + /* Set up our interrupt linked list */ + zs_chain = &zs_soft[0]; + zs_soft[0].zs_next = &zs_soft[1]; + zs_soft[1].zs_next = 0; + + for(chip = 0; chip < NUM_SERIAL; chip++) { + /* If we are doing kgdb over one of the channels on + * chip zero, kgdb_channel will be set to 1 by the + * rs_kgdb_hook() routine below. + */ + if(!zs_chips[chip]) { + zs_chips[chip] = get_zs(chip); + /* Two channels per chip */ + zs_channels[(chip*2)] = &zs_chips[chip]->channelB; + zs_channels[(chip*2)+1] = &zs_chips[chip]->channelA; + zs_soft[(chip*2)].kgdb_channel = 0; + zs_soft[(chip*2)+1].kgdb_channel = 0; + } + /* First, set up channel A on this chip. */ + channel = chip * 2; + zs_soft[channel].zs_channel = zs_channels[channel]; + zs_soft[channel].change_needed = 0; + zs_soft[channel].clk_divisor = 16; + zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]); + zs_soft[channel].cons_mouse = 0; + /* If not keyboard/mouse and is console serial + * line, then enable receiver interrupts. + */ + if(zs_soft[channel].is_cons) { + write_zsreg(zs_soft[channel].zs_channel, R1, + (EXT_INT_ENAB | INT_ALL_Rx)); + write_zsreg(zs_soft[channel].zs_channel, R9, (NV | MIE)); + write_zsreg(zs_soft[channel].zs_channel, R10, (NRZ)); + write_zsreg(zs_soft[channel].zs_channel, R3, (Rx8|RxENABLE)); + write_zsreg(zs_soft[channel].zs_channel, R5, (Tx8 | TxENAB)); + } + /* If this is the kgdb line, enable interrupts because we + * now want to receive the 'control-c' character from the + * client attached to us asynchronously. + */ + if(zs_soft[channel].kgdb_channel) + kgdb_chaninit(&zs_soft[channel], 1, + zs_soft[channel].zs_baud); + + /* Now, channel B */ + channel++; + zs_soft[channel].zs_channel = zs_channels[channel]; + zs_soft[channel].change_needed = 0; + zs_soft[channel].clk_divisor = 16; + zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]); + zs_soft[channel].cons_keyb = 0; + /* If console serial line, then enable receiver interrupts. */ + if(zs_soft[channel].is_cons) { + write_zsreg(zs_soft[channel].zs_channel, R1, + (EXT_INT_ENAB | INT_ALL_Rx)); + write_zsreg(zs_soft[channel].zs_channel, R9, + (NV | MIE)); + write_zsreg(zs_soft[channel].zs_channel, R10, + (NRZ)); + write_zsreg(zs_soft[channel].zs_channel, R3, + (Rx8|RxENABLE)); + write_zsreg(zs_soft[channel].zs_channel, R5, + (Tx8 | TxENAB | RTS | DTR)); + } + } + + for(info=zs_chain, i=0; info; info = info->zs_next, i++) + { + info->magic = SERIAL_MAGIC; + info->port = (int) info->zs_channel; + info->line = i; + info->tty = 0; + info->irq = zilog_irq; + info->custom_divisor = 16; + info->close_delay = 50; + info->closing_wait = 3000; + info->x_char = 0; + info->event = 0; + info->count = 0; + info->blocked_open = 0; + info->tqueue.routine = do_softint; + info->tqueue.data = info; + info->tqueue_hangup.routine = do_serial_hangup; + info->tqueue_hangup.data = info; + info->callout_termios =callout_driver.init_termios; + info->normal_termios = serial_driver.init_termios; + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + printk("tty%02d at 0x%04x (irq = %d)", info->line, + info->port, info->irq); + printk(" is a Zilog8530\n"); + } + + if (request_irq(zilog_irq, rs_interrupt, (SA_INTERRUPT), + "Zilog8530", zs_chain)) + panic("Unable to attach zs intr"); + restore_flags(flags); + + return 0; +} + +/* + * register_serial and unregister_serial allows for serial ports to be + * configured at run-time, to support PCMCIA modems. + */ +/* SGI: Unused at this time, just here to make things link. */ +int register_serial(struct serial_struct *req) +{ + return -1; +} + +void unregister_serial(int line) +{ + return; +} + +/* Hooks for running a serial console. con_init() calls this if the + * console is being run over one of the ttya/ttyb serial ports. + * 'chip' should be zero, as chip 1 drives the mouse/keyboard. + * 'channel' is decoded as 0=TTYA 1=TTYB, note that the channels + * are addressed backwards, channel B is first, then channel A. + */ +void +rs_cons_hook(int chip, int out, int line) +{ + int channel; + + if(chip) + panic("rs_cons_hook called with chip not zero"); + if(line != 0 && line != 1) + panic("rs_cons_hook called with line not ttya or ttyb"); + channel = line; + if(!zs_chips[chip]) { + zs_chips[chip] = get_zs(chip); + /* Two channels per chip */ + zs_channels[(chip*2)] = &zs_chips[chip]->channelB; + zs_channels[(chip*2)+1] = &zs_chips[chip]->channelA; + } + zs_soft[channel].zs_channel = zs_channels[channel]; + zs_soft[channel].change_needed = 0; + zs_soft[channel].clk_divisor = 16; + zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]); + if(out) + zs_cons_chanout = ((chip * 2) + channel); + else + zs_cons_chanin = ((chip * 2) + channel); + + rs_cons_check(&zs_soft[channel], channel); +} + +/* This is called at boot time to prime the kgdb serial debugging + * serial line. The 'tty_num' argument is 0 for /dev/ttyd2 and 1 for + * /dev/ttyd1 (yes they are backwards on purpose) which is determined + * in setup_arch() from the boot command line flags. + */ +void +rs_kgdb_hook(int tty_num) +{ + int chip = 0; + + if(!zs_chips[chip]) { + zs_chips[chip] = get_zs(chip); + /* Two channels per chip */ + zs_channels[(chip*2)] = &zs_chips[chip]->channelA; + zs_channels[(chip*2)+1] = &zs_chips[chip]->channelB; + } + zs_soft[tty_num].zs_channel = zs_channels[tty_num]; + zs_kgdbchan = zs_soft[tty_num].zs_channel; + zs_soft[tty_num].change_needed = 0; + zs_soft[tty_num].clk_divisor = 16; + zs_soft[tty_num].zs_baud = get_zsbaud(&zs_soft[tty_num]); + zs_soft[tty_num].kgdb_channel = 1; /* This runs kgdb */ + zs_soft[tty_num ^ 1].kgdb_channel = 0; /* This does not */ + + /* Turn on transmitter/receiver at 8-bits/char */ + kgdb_chaninit(&zs_soft[tty_num], 0, 9600); + ZS_CLEARERR(zs_kgdbchan); + udelay(5); + ZS_CLEARFIFO(zs_kgdbchan); +} + +static void zs_console_write(struct console *co, const char *str, + unsigned int count) +{ + + while(count--) { + if(*str == '\n') + zs_cons_put_char('\r'); + zs_cons_put_char(*str++); + } + + /* Comment this if you want to have a strict interrupt-driven output */ + rs_fair_output(); +} + +static kdev_t zs_console_device(struct console *con) +{ + return MKDEV(TTY_MAJOR, 64 + con->index); +} + + +static int __init zs_console_setup(struct console *con, char *options) +{ + struct sgi_serial *info; + int baud; + int bits = 8; + int parity = 'n'; + int cflag = CREAD | HUPCL | CLOCAL; + char *s, *dbaud; + int i, brg; + + if (options) { + baud = simple_strtoul(options, NULL, 10); + s = options; + while(*s >= '0' && *s <= '9') + s++; + if (*s) parity = *s++; + if (*s) bits = *s - '0'; + } + else { + /* If the user doesn't set console=... try to read the + * PROM variable - if this fails use 9600 baud and + * inform the user about the problem + */ + dbaud = ArcGetEnvironmentVariable("dbaud"); + if(dbaud) baud = simple_strtoul(dbaud, NULL, 10); + else { + /* Use prom_printf() to make sure that the user + * is getting anything ... + */ + prom_printf("No dbaud set in PROM ?!? Using 9600.\n"); + baud = 9600; + } + } + + /* + * Now construct a cflag setting. + */ + switch(baud) { + case 1200: + cflag |= B1200; + break; + case 2400: + cflag |= B2400; + break; + case 4800: + cflag |= B4800; + break; + case 19200: + cflag |= B19200; + break; + case 38400: + cflag |= B38400; + break; + case 57600: + cflag |= B57600; + break; + case 115200: + cflag |= B115200; + break; + case 9600: + default: + cflag |= B9600; + break; + } + switch(bits) { + case 7: + cflag |= CS7; + break; + default: + case 8: + cflag |= CS8; + break; + } + switch(parity) { + case 'o': case 'O': + cflag |= PARODD; + break; + case 'e': case 'E': + cflag |= PARENB; + break; + } + con->cflag = cflag; + + rs_cons_hook(0, 0, con->index); + info = zs_soft + con->index; + info->is_cons = 1; + + printk("Console: ttyS%d (Zilog8530), %d baud\n", + info->line, baud); + + i = con->cflag & CBAUD; + if (con->cflag & CBAUDEX) { + i &= ~CBAUDEX; + con->cflag &= ~CBAUDEX; + } + info->zs_baud = baud; + + switch (con->cflag & CSIZE) { + case CS5: + zscons_regs[3] = Rx5 | RxENABLE; + zscons_regs[5] = Tx5 | TxENAB; + break; + case CS6: + zscons_regs[3] = Rx6 | RxENABLE; + zscons_regs[5] = Tx6 | TxENAB; + break; + case CS7: + zscons_regs[3] = Rx7 | RxENABLE; + zscons_regs[5] = Tx7 | TxENAB; + break; + default: + case CS8: + zscons_regs[3] = Rx8 | RxENABLE; + zscons_regs[5] = Tx8 | TxENAB; + break; + } + zscons_regs[5] |= DTR; + + if (con->cflag & PARENB) + zscons_regs[4] |= PAR_ENA; + if (!(con->cflag & PARODD)) + zscons_regs[4] |= PAR_EVEN; + + if (con->cflag & CSTOPB) + zscons_regs[4] |= SB2; + else + zscons_regs[4] |= SB1; + + sgisercon = con; + + brg = BPS_TO_BRG(baud, ZS_CLOCK / info->clk_divisor); + zscons_regs[12] = brg & 0xff; + zscons_regs[13] = (brg >> 8) & 0xff; + memcpy(info->curregs, zscons_regs, sizeof(zscons_regs)); + load_zsregs(info->zs_channel, zscons_regs); + ZS_CLEARERR(info->zs_channel); + ZS_CLEARFIFO(info->zs_channel); + return 0; +} + +static struct console sgi_console_driver = { + .name = "ttyS", + .write = zs_console_write, + .device = zs_console_device, + .setup = zs_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +/* + * Register console. + */ +void __init sgi_serial_console_init(void) +{ + register_console(&sgi_console_driver); +} +__initcall(rs_init); diff -urN linux-2.4.21-bk37/drivers/char/sgiserial.h linux-2.4.21-bk38/drivers/char/sgiserial.h --- linux-2.4.21-bk37/drivers/char/sgiserial.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/drivers/char/sgiserial.h 2003-08-24 02:56:03.000000000 -0700 @@ -0,0 +1,444 @@ +/* sgiserial.h: Definitions for the SGI Zilog85C30 serial driver. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#ifndef _SGI_SERIAL_H +#define _SGI_SERIAL_H + +/* Just one channel */ +struct sgi_zschannel { +#ifdef __MIPSEB__ + volatile unsigned char unused0[3]; + volatile unsigned char control; + volatile unsigned char unused1[3]; + volatile unsigned char data; +#else /* __MIPSEL__ */ + volatile unsigned char control; + volatile unsigned char unused0[3]; + volatile unsigned char data; + volatile unsigned char unused1[3]; +#endif +}; + +/* The address space layout for each zs chip. Yes they are + * backwards. + */ +struct sgi_zslayout { + struct sgi_zschannel channelB; + struct sgi_zschannel channelA; +}; + +#define NUM_ZSREGS 16 + +struct serial_struct { + int type; + int line; + unsigned int port; + int irq; + int flags; + int xmit_fifo_size; + int custom_divisor; + int baud_base; + unsigned short close_delay; + char reserved_char[2]; + int hub6; + unsigned short closing_wait; /* time to wait before closing */ + unsigned short closing_wait2; /* no longer used... */ + int reserved[4]; +}; + +/* + * For the close wait times, 0 means wait forever for serial port to + * flush its output. 65535 means don't wait at all. + */ +#define ZILOG_CLOSING_WAIT_INF 0 +#define ZILOG_CLOSING_WAIT_NONE 65535 + +/* + * Definitions for ZILOG_struct (and serial_struct) flags field + */ +#define ZILOG_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes + on the callout port */ +#define ZILOG_FOURPORT 0x0002 /* Set OU1, OUT2 per AST Fourport settings */ +#define ZILOG_SAK 0x0004 /* Secure Attention Key (Orange book) */ +#define ZILOG_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */ + +#define ZILOG_SPD_MASK 0x0030 +#define ZILOG_SPD_HI 0x0010 /* Use 56000 instead of 38400 bps */ + +#define ZILOG_SPD_VHI 0x0020 /* Use 115200 instead of 38400 bps */ +#define ZILOG_SPD_CUST 0x0030 /* Use user-specified divisor */ + +#define ZILOG_SKIP_TEST 0x0040 /* Skip UART test during autoconfiguration */ +#define ZILOG_AUTO_IRQ 0x0080 /* Do automatic IRQ during autoconfiguration */ +#define ZILOG_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */ +#define ZILOG_PGRP_LOCKOUT 0x0200 /* Lock out cua opens based on pgrp */ +#define ZILOG_CALLOUT_NOHUP 0x0400 /* Don't do hangups for cua device */ + +#define ZILOG_FLAGS 0x0FFF /* Possible legal ZILOG flags */ +#define ZILOG_USR_MASK 0x0430 /* Legal flags that non-privileged + * users can set or reset */ + +/* Internal flags used only by kernel/chr_drv/serial.c */ +#define ZILOG_INITIALIZED 0x80000000 /* Serial port was initialized */ +#define ZILOG_CALLOUT_ACTIVE 0x40000000 /* Call out device is active */ +#define ZILOG_NORMAL_ACTIVE 0x20000000 /* Normal device is active */ +#define ZILOG_BOOT_AUTOCONF 0x10000000 /* Autoconfigure port on bootup */ +#define ZILOG_CLOSING 0x08000000 /* Serial port is closing */ +#define ZILOG_CTS_FLOW 0x04000000 /* Do CTS flow control */ +#define ZILOG_CHECK_CD 0x02000000 /* i.e., CLOCAL */ + +/* Software state per channel */ + +#ifdef __KERNEL__ +/* + * This is our internal structure for each serial port's state. + * + * Many fields are paralleled by the structure used by the serial_struct + * structure. + * + * For definitions of the flags field, see tty.h + */ + +struct sgi_serial { + struct sgi_serial *zs_next; /* For IRQ servicing chain */ + struct sgi_zschannel *zs_channel; /* Channel registers */ + unsigned char read_reg_zero; + + char soft_carrier; /* Use soft carrier on this channel */ + char cons_keyb; /* Channel runs the keyboard */ + char cons_mouse; /* Channel runs the mouse */ + char break_abort; /* Is serial console in, so process brk/abrt */ + char kgdb_channel; /* Kgdb is running on this channel */ + char is_cons; /* Is this our console. */ + + /* We need to know the current clock divisor + * to read the bps rate the chip has currently + * loaded. + */ + unsigned char clk_divisor; /* May be 1, 16, 32, or 64 */ + int zs_baud; + + /* Current write register values */ + unsigned char curregs[NUM_ZSREGS]; + + char change_needed; + + int magic; + int baud_base; + unsigned int port; + int irq; + int flags; /* defined in tty.h */ + int type; /* UART type */ + struct tty_struct *tty; + int read_status_mask; + int ignore_status_mask; + int timeout; + int xmit_fifo_size; + int custom_divisor; + int x_char; /* xon/xoff character */ + int close_delay; + unsigned short closing_wait; + unsigned short closing_wait2; + unsigned long event; + unsigned long last_active; + int line; + int count; /* # of fd on device */ + int blocked_open; /* # of blocked opens */ + long session; /* Session of opening process */ + long pgrp; /* pgrp of opening process */ + unsigned char *xmit_buf; + int xmit_head; + int xmit_tail; + int xmit_cnt; + struct tq_struct tqueue; + struct tq_struct tqueue_hangup; + struct termios normal_termios; + struct termios callout_termios; + wait_queue_head_t open_wait; + wait_queue_head_t close_wait; +}; + + +#define SERIAL_MAGIC 0x5301 + +/* + * The size of the serial xmit buffer is 1 page. + */ +#define SERIAL_XMIT_SIZE PAGE_SIZE + +/* + * Events are used to schedule things to happen at timer-interrupt + * time, instead of at rs interrupt time. + */ +#define RS_EVENT_WRITE_WAKEUP 0 + +#endif /* __KERNEL__ */ + +/* Conversion routines to/from brg time constants from/to bits + * per second. + */ +#define BRG_TO_BPS(brg, freq) ((freq) / 2 / ((brg) + 2)) +#define BPS_TO_BRG(bps, freq) ((((freq) + (bps)) / (2 * (bps))) - 2) + +/* The Zilog register set */ + +#define FLAG 0x7e + +/* Write Register 0 */ +#define R0 0 /* Register selects */ +#define R1 1 +#define R2 2 +#define R3 3 +#define R4 4 +#define R5 5 +#define R6 6 +#define R7 7 +#define R8 8 +#define R9 9 +#define R10 10 +#define R11 11 +#define R12 12 +#define R13 13 +#define R14 14 +#define R15 15 + +#define NULLCODE 0 /* Null Code */ +#define POINT_HIGH 0x8 /* Select upper half of registers */ +#define RES_EXT_INT 0x10 /* Reset Ext. Status Interrupts */ +#define SEND_ABORT 0x18 /* HDLC Abort */ +#define RES_RxINT_FC 0x20 /* Reset RxINT on First Character */ +#define RES_Tx_P 0x28 /* Reset TxINT Pending */ +#define ERR_RES 0x30 /* Error Reset */ +#define RES_H_IUS 0x38 /* Reset highest IUS */ + +#define RES_Rx_CRC 0x40 /* Reset Rx CRC Checker */ +#define RES_Tx_CRC 0x80 /* Reset Tx CRC Checker */ +#define RES_EOM_L 0xC0 /* Reset EOM latch */ + +/* Write Register 1 */ + +#define EXT_INT_ENAB 0x1 /* Ext Int Enable */ +#define TxINT_ENAB 0x2 /* Tx Int Enable */ +#define PAR_SPEC 0x4 /* Parity is special condition */ + +#define RxINT_DISAB 0 /* Rx Int Disable */ +#define RxINT_FCERR 0x8 /* Rx Int on First Character Only or Error */ +#define INT_ALL_Rx 0x10 /* Int on all Rx Characters or error */ +#define INT_ERR_Rx 0x18 /* Int on error only */ + +#define WT_RDY_RT 0x20 /* Wait/Ready on R/T */ +#define WT_FN_RDYFN 0x40 /* Wait/FN/Ready FN */ +#define WT_RDY_ENAB 0x80 /* Wait/Ready Enable */ + +/* Write Register #2 (Interrupt Vector) */ + +/* Write Register 3 */ + +#define RxENABLE 0x1 /* Rx Enable */ +#define SYNC_L_INH 0x2 /* Sync Character Load Inhibit */ +#define ADD_SM 0x4 /* Address Search Mode (SDLC) */ +#define RxCRC_ENAB 0x8 /* Rx CRC Enable */ +#define ENT_HM 0x10 /* Enter Hunt Mode */ +#define AUTO_ENAB 0x20 /* Auto Enables */ +#define Rx5 0x0 /* Rx 5 Bits/Character */ +#define Rx7 0x40 /* Rx 7 Bits/Character */ +#define Rx6 0x80 /* Rx 6 Bits/Character */ +#define Rx8 0xc0 /* Rx 8 Bits/Character */ + +/* Write Register 4 */ + +#define PAR_ENA 0x1 /* Parity Enable */ +#define PAR_EVEN 0x2 /* Parity Even/Odd* */ + +#define SYNC_ENAB 0 /* Sync Modes Enable */ +#define SB1 0x4 /* 1 stop bit/char */ +#define SB15 0x8 /* 1.5 stop bits/char */ +#define SB2 0xc /* 2 stop bits/char */ + +#define MONSYNC 0 /* 8 Bit Sync character */ +#define BISYNC 0x10 /* 16 bit sync character */ +#define SDLC 0x20 /* SDLC Mode (01111110 Sync Flag) */ +#define EXTSYNC 0x30 /* External Sync Mode */ + +#define X1CLK 0x0 /* x1 clock mode */ +#define X16CLK 0x40 /* x16 clock mode */ +#define X32CLK 0x80 /* x32 clock mode */ +#define X64CLK 0xC0 /* x64 clock mode */ + +/* Write Register 5 */ + +#define TxCRC_ENAB 0x1 /* Tx CRC Enable */ +#define RTS 0x2 /* RTS */ +#define SDLC_CRC 0x4 /* SDLC/CRC-16 */ +#define TxENAB 0x8 /* Tx Enable */ +#define SND_BRK 0x10 /* Send Break */ +#define Tx5 0x0 /* Tx 5 bits (or less)/character */ +#define Tx7 0x20 /* Tx 7 bits/character */ +#define Tx6 0x40 /* Tx 6 bits/character */ +#define Tx8 0x60 /* Tx 8 bits/character */ +#define DTR 0x80 /* DTR */ + +/* Write Register 6 (Sync bits 0-7/SDLC Address Field) */ + +/* Write Register 7 (Sync bits 8-15/SDLC 01111110) */ + +/* Write Register 8 (transmit buffer) */ + +/* Write Register 9 (Master interrupt control) */ +#define VIS 1 /* Vector Includes Status */ +#define NV 2 /* No Vector */ +#define DLC 4 /* Disable Lower Chain */ +#define MIE 8 /* Master Interrupt Enable */ +#define STATHI 0x10 /* Status high */ +#define NORESET 0 /* No reset on write to R9 */ +#define CHRB 0x40 /* Reset channel B */ +#define CHRA 0x80 /* Reset channel A */ +#define FHWRES 0xc0 /* Force hardware reset */ + +/* Write Register 10 (misc control bits) */ +#define BIT6 1 /* 6 bit/8bit sync */ +#define LOOPMODE 2 /* SDLC Loop mode */ +#define ABUNDER 4 /* Abort/flag on SDLC xmit underrun */ +#define MARKIDLE 8 /* Mark/flag on idle */ +#define GAOP 0x10 /* Go active on poll */ +#define NRZ 0 /* NRZ mode */ +#define NRZI 0x20 /* NRZI mode */ +#define FM1 0x40 /* FM1 (transition = 1) */ +#define FM0 0x60 /* FM0 (transition = 0) */ +#define CRCPS 0x80 /* CRC Preset I/O */ + +/* Write Register 11 (Clock Mode control) */ +#define TRxCXT 0 /* TRxC = Xtal output */ +#define TRxCTC 1 /* TRxC = Transmit clock */ +#define TRxCBR 2 /* TRxC = BR Generator Output */ +#define TRxCDP 3 /* TRxC = DPLL output */ +#define TRxCOI 4 /* TRxC O/I */ +#define TCRTxCP 0 /* Transmit clock = RTxC pin */ +#define TCTRxCP 8 /* Transmit clock = TRxC pin */ +#define TCBR 0x10 /* Transmit clock = BR Generator output */ +#define TCDPLL 0x18 /* Transmit clock = DPLL output */ +#define RCRTxCP 0 /* Receive clock = RTxC pin */ +#define RCTRxCP 0x20 /* Receive clock = TRxC pin */ +#define RCBR 0x40 /* Receive clock = BR Generator output */ +#define RCDPLL 0x60 /* Receive clock = DPLL output */ +#define RTxCX 0x80 /* RTxC Xtal/No Xtal */ + +/* Write Register 12 (lower byte of baud rate generator time constant) */ + +/* Write Register 13 (upper byte of baud rate generator time constant) */ + +/* Write Register 14 (Misc control bits) */ +#define BRENABL 1 /* Baud rate generator enable */ +#define BRSRC 2 /* Baud rate generator source */ +#define DTRREQ 4 /* DTR/Request function */ +#define AUTOECHO 8 /* Auto Echo */ +#define LOOPBAK 0x10 /* Local loopback */ +#define SEARCH 0x20 /* Enter search mode */ +#define RMC 0x40 /* Reset missing clock */ +#define DISDPLL 0x60 /* Disable DPLL */ +#define SSBR 0x80 /* Set DPLL source = BR generator */ +#define SSRTxC 0xa0 /* Set DPLL source = RTxC */ +#define SFMM 0xc0 /* Set FM mode */ +#define SNRZI 0xe0 /* Set NRZI mode */ + +/* Write Register 15 (external/status interrupt control) */ +#define ZCIE 2 /* Zero count IE */ +#define DCDIE 8 /* DCD IE */ +#define SYNCIE 0x10 /* Sync/hunt IE */ +#define CTSIE 0x20 /* CTS IE */ +#define TxUIE 0x40 /* Tx Underrun/EOM IE */ +#define BRKIE 0x80 /* Break/Abort IE */ + + +/* Read Register 0 */ +#define Rx_CH_AV 0x1 /* Rx Character Available */ +#define ZCOUNT 0x2 /* Zero count */ +#define Tx_BUF_EMP 0x4 /* Tx Buffer empty */ +#define DCD 0x8 /* DCD */ +#define SYNC 0x10 /* Sync/hunt */ +#define CTS 0x20 /* CTS */ +#define TxEOM 0x40 /* Tx underrun */ +#define BRK_ABRT 0x80 /* Break/Abort */ + +/* Read Register 1 */ +#define ALL_SNT 0x1 /* All sent */ +/* Residue Data for 8 Rx bits/char programmed */ +#define RES3 0x8 /* 0/3 */ +#define RES4 0x4 /* 0/4 */ +#define RES5 0xc /* 0/5 */ +#define RES6 0x2 /* 0/6 */ +#define RES7 0xa /* 0/7 */ +#define RES8 0x6 /* 0/8 */ +#define RES18 0xe /* 1/8 */ +#define RES28 0x0 /* 2/8 */ +/* Special Rx Condition Interrupts */ +#define PAR_ERR 0x10 /* Parity error */ +#define Rx_OVR 0x20 /* Rx Overrun Error */ +#define CRC_ERR 0x40 /* CRC/Framing Error */ +#define END_FR 0x80 /* End of Frame (SDLC) */ + +/* Read Register 2 (channel b only) - Interrupt vector */ + +/* Read Register 3 (interrupt pending register) ch a only */ +#define CHBEXT 0x1 /* Channel B Ext/Stat IP */ +#define CHBTxIP 0x2 /* Channel B Tx IP */ +#define CHBRxIP 0x4 /* Channel B Rx IP */ +#define CHAEXT 0x8 /* Channel A Ext/Stat IP */ +#define CHATxIP 0x10 /* Channel A Tx IP */ +#define CHARxIP 0x20 /* Channel A Rx IP */ + +/* Read Register 8 (receive data register) */ + +/* Read Register 10 (misc status bits) */ +#define ONLOOP 2 /* On loop */ +#define LOOPSEND 0x10 /* Loop sending */ +#define CLK2MIS 0x40 /* Two clocks missing */ +#define CLK1MIS 0x80 /* One clock missing */ + +/* Read Register 12 (lower byte of baud rate generator constant) */ + +/* Read Register 13 (upper byte of baud rate generator constant) */ + +/* Read Register 15 (value of WR 15) */ + +/* Misc inlines */ +static inline void ZS_CLEARERR(struct sgi_zschannel *channel) +{ + volatile unsigned char junk; + + udelay(2); + channel->control = ERR_RES; + junk = sgint->istat0; +} + +static inline void ZS_CLEARFIFO(struct sgi_zschannel *channel) +{ + volatile unsigned char junk; + + udelay(2); + junk = channel->data; + udelay(2); + junk = sgint->istat0; + junk = channel->data; + udelay(2); + junk = sgint->istat0; + junk = channel->data; + udelay(2); + junk = sgint->istat0; +} + +#if 0 + +#define ZS_CLEARERR(channel) (channel->control = ERR_RES) +#define ZS_CLEARFIFO(channel) do { volatile unsigned char garbage; \ + garbage = channel->data; \ + udelay(2); \ + garbage = channel->data; \ + udelay(2); \ + garbage = channel->data; \ + udelay(2); } while(0) + +#endif + +#endif /* !(_SGI_SERIAL_H) */ diff -urN linux-2.4.21-bk37/drivers/char/tty_io.c linux-2.4.21-bk38/drivers/char/tty_io.c --- linux-2.4.21-bk37/drivers/char/tty_io.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.21-bk38/drivers/char/tty_io.c 2003-08-24 02:56:03.000000000 -0700 @@ -142,6 +142,7 @@ extern int serial167_init(void); extern long serial167_console_init(void); extern void console_8xx_init(void); +extern void au1x00_serial_console_init(void); extern int rs_8xx_init(void); extern void mac_scc_console_init(void); extern void hwc_console_init(void); @@ -154,10 +155,14 @@ extern void sa1100_rs_console_init(void); extern void sgi_serial_console_init(void); extern void sci_console_init(void); +extern void dec_serial_console_init(void); extern void tx3912_console_init(void); extern void tx3912_rs_init(void); extern void txx927_console_init(void); +extern void txx9_rs_init(void); +extern void txx9_serial_console_init(void); extern void sb1250_serial_console_init(void); +extern void arc_console_init(void); #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -2235,8 +2240,8 @@ #ifdef CONFIG_VT con_init(); #endif -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - au1000_serial_console_init(); +#ifdef CONFIG_AU1X00_SERIAL_CONSOLE + au1x00_serial_console_init(); #endif #ifdef CONFIG_SERIAL_CONSOLE #if (defined(CONFIG_8xx) || defined(CONFIG_8260)) @@ -2253,9 +2258,6 @@ #elif defined(CONFIG_SERIAL) serial_console_init(); #endif /* CONFIG_8xx */ -#ifdef CONFIG_SGI_SERIAL - sgi_serial_console_init(); -#endif #if defined(CONFIG_MVME162_SCC) || defined(CONFIG_BVME6000_SCC) || defined(CONFIG_MVME147_SCC) vme_scc_console_init(); #endif @@ -2266,6 +2268,9 @@ sci_console_init(); #endif #endif +#ifdef CONFIG_SERIAL_DEC_CONSOLE + dec_serial_console_init(); +#endif #ifdef CONFIG_TN3270_CONSOLE tub3270_con_init(); #endif @@ -2296,9 +2301,15 @@ #ifdef CONFIG_TXX927_SERIAL_CONSOLE txx927_console_init(); #endif +#ifdef CONFIG_SERIAL_TXX9_CONSOLE + txx9_serial_console_init(); +#endif #ifdef CONFIG_SIBYTE_SB1250_DUART_CONSOLE sb1250_serial_console_init(); #endif +#ifdef CONFIG_IP22_SERIAL + sgi_serial_console_init(); +#endif } static struct tty_driver dev_tty_driver, dev_syscons_driver; diff -urN linux-2.4.21-bk37/drivers/char/vac-serial.c linux-2.4.21-bk38/drivers/char/vac-serial.c --- linux-2.4.21-bk37/drivers/char/vac-serial.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/drivers/char/vac-serial.c 2003-08-24 02:56:03.000000000 -0700 @@ -0,0 +1,2905 @@ +/* + * vacserial.c: VAC UART serial driver + * This code stealed and adopted from linux/drivers/char/serial.c + * See that for author info + * + * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov + */ + +#undef SERIAL_PARANOIA_CHECK +#define CONFIG_SERIAL_NOPAUSE_IO +#define SERIAL_DO_RESTART + +#define CONFIG_SERIAL_SHARE_IRQ + +/* Set of debugging defines */ + +#undef SERIAL_DEBUG_INTR +#undef SERIAL_DEBUG_OPEN +#undef SERIAL_DEBUG_FLOW +#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + +#define RS_STROBE_TIME (10*HZ) +#define RS_ISR_PASS_LIMIT 2 /* Beget is not a super-computer (old=256) */ + +#define IRQ_T(state) \ + ((state->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT) + +#define SERIAL_INLINE + +#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) +#define DBG_CNT(s) baget_printk("(%s):[%x] refc=%d, serc=%d, ttyc=%d-> %s\n", \ + kdevname(tty->device),(info->flags),serial_refcount,info->count,tty->count,s) +#else +#define DBG_CNT(s) +#endif + +#define QUAD_UART_SPEED /* Useful for Baget */ + +/* + * End of serial driver configuration section. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SERIAL_CONSOLE +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#define BAGET_VAC_UART_IRQ 0x35 + +/* + * Implementation note: + * It was descovered by means of advanced electronic tools, + * if the driver works via TX_READY interrupts then VIC generates + * strange self-eliminating traps. Thus, the driver is rewritten to work + * via TX_EMPTY + */ + +/* VAC-specific check/debug switches */ + +#undef CHECK_REG_INDEX +#undef DEBUG_IO_PORT_A + +#ifdef SERIAL_INLINE +#define _INLINE_ inline +#endif + +static char *serial_name = "VAC Serial driver"; +static char *serial_version = "4.26"; + +static DECLARE_TASK_QUEUE(tq_serial); + +static struct tty_driver serial_driver, callout_driver; +static int serial_refcount; + +/* number of characters left in xmit buffer before we ask for more */ +#define WAKEUP_CHARS 256 + +/* + * IRQ_timeout - How long the timeout should be for each IRQ + * should be after the IRQ has been active. + */ + +static struct async_struct *IRQ_ports[NR_IRQS]; +static int IRQ_timeout[NR_IRQS]; +#ifdef CONFIG_SERIAL_CONSOLE +static struct console sercons; +#endif + +static void autoconfig(struct serial_state * info); +static void change_speed(struct async_struct *info); +static void rs_wait_until_sent(struct tty_struct *tty, int timeout); +static void rs_timer(unsigned long dummy); + +static struct timer_list vacs_timer; + +/* + * Here we define the default xmit fifo size used for each type of + * UART + */ +static struct serial_uart_config uart_config[] = { + { "unknown", 1, 0 }, /* Must go first -- used as unasigned */ + { "VAC UART", 1, 0 } +}; +#define VAC_UART_TYPE 1 /* Just index in above array */ + +static struct serial_state rs_table[] = { +/* + * VAC has tricky layout for pair of his SIO registers, + * so we need special function to access ones. + * To identify port we use their TX offset + */ + { 0, 9600, VAC_UART_B_TX, BAGET_VAC_UART_IRQ, + STD_COM_FLAGS }, /* VAC UART B */ + { 0, 9600, VAC_UART_A_TX, BAGET_VAC_UART_IRQ, + STD_COM_FLAGS } /* VAC UART A */ +}; + +#define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state)) + +static struct tty_struct *serial_table[NR_PORTS]; +static struct termios *serial_termios[NR_PORTS]; +static struct termios *serial_termios_locked[NR_PORTS]; + +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +/* + * tmp_buf is used as a temporary buffer by serial_write. We need to + * lock it in case the copy_from_user blocks while swapping in a page, + * and some other program tries to do a serial write at the same time. + * Since the lock will only come under contention when the system is + * swapping and available memory is low, it makes sense to share one + * buffer across all the serial ports, since it significantly saves + * memory if large numbers of serial ports are open. + */ +static unsigned char *tmp_buf; +static DECLARE_MUTEX(tmp_buf_sem); + +static inline int serial_paranoia_check(struct async_struct *info, + kdev_t device, const char *routine) +{ +#ifdef SERIAL_PARANOIA_CHECK + static const char *badmagic = + "Warning: bad magic number for serial struct (%s) in %s\n"; + static const char *badinfo = + "Warning: null async_struct for (%s) in %s\n"; + + if (!info) { + printk(badinfo, kdevname(device), routine); + return 1; + } + if (info->magic != SERIAL_MAGIC) { + printk(badmagic, kdevname(device), routine); + return 1; + } +#endif + return 0; +} + +/* + To unify UART A/B access we will use following function + to compute register offsets by register index. + */ + +#define VAC_UART_MODE 0 +#define VAC_UART_TX 1 +#define VAC_UART_RX 2 +#define VAC_UART_INT_MASK 3 +#define VAC_UART_INT_STATUS 4 + +#define VAC_UART_REG_NR 5 + +static inline int uart_offset_map(unsigned long port, int reg_index) +{ + static const unsigned int ind_to_reg[VAC_UART_REG_NR][NR_PORTS] = { + { VAC_UART_B_MODE, VAC_UART_A_MODE }, + { VAC_UART_B_TX, VAC_UART_A_TX }, + { VAC_UART_B_RX, VAC_UART_A_RX }, + { VAC_UART_B_INT_MASK, VAC_UART_A_INT_MASK }, + { VAC_UART_B_INT_STATUS, VAC_UART_A_INT_STATUS } + }; +#ifdef CHECK_REG_INDEX + if (reg_index > VAC_UART_REG_NR) panic("vacserial: bad reg_index"); +#endif + return ind_to_reg[reg_index][port == VAC_UART_B_TX ? 0 : 1]; +} + +static inline unsigned int serial_inw(struct async_struct *info, int offset) +{ + int val = vac_inw(uart_offset_map(info->port,offset)); +#ifdef DEBUG_IO_PORT_A + if (info->port == VAC_UART_A_TX) + printk("UART_A_IN: reg = 0x%04x, val = 0x%04x\n", + uart_offset_map(info->port,offset), val); +#endif + return val; +} + +static inline unsigned int serial_inp(struct async_struct *info, int offset) +{ + return serial_inw(info, offset); +} + +static inline unsigned int serial_in(struct async_struct *info, int offset) +{ + return serial_inw(info, offset); +} + +static inline void serial_outw(struct async_struct *info,int offset, int value) +{ +#ifdef DEBUG_IO_PORT_A + if (info->port == VAC_UART_A_TX) + printk("UART_A_OUT: offset = 0x%04x, val = 0x%04x\n", + uart_offset_map(info->port,offset), value); +#endif + vac_outw(value, uart_offset_map(info->port,offset)); +} + +static inline void serial_outp(struct async_struct *info,int offset, int value) +{ + serial_outw(info,offset,value); +} + +static inline void serial_out(struct async_struct *info,int offset, int value) +{ + serial_outw(info,offset,value); +} + +/* + * ------------------------------------------------------------ + * rs_stop() and rs_start() + * + * This routines are called before setting or resetting tty->stopped. + * They enable or disable transmitter interrupts, as necessary. + * ------------------------------------------------------------ + */ +static void rs_stop(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_stop")) + return; + + save_flags(flags); cli(); + if (info->IER & VAC_UART_INT_TX_EMPTY) { + info->IER &= ~VAC_UART_INT_TX_EMPTY; + serial_out(info, VAC_UART_INT_MASK, info->IER); + } + restore_flags(flags); +} + +static void rs_start(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_start")) + return; + + save_flags(flags); cli(); + if (info->xmit_cnt && info->xmit_buf + && !(info->IER & VAC_UART_INT_TX_EMPTY)) { + info->IER |= VAC_UART_INT_TX_EMPTY; + serial_out(info, VAC_UART_INT_MASK, info->IER); + } + restore_flags(flags); +} + +/* + * ---------------------------------------------------------------------- + * + * Here starts the interrupt handling routines. All of the following + * subroutines are declared as inline and are folded into + * rs_interrupt(). They were separated out for readability's sake. + * + * Note: rs_interrupt() is a "fast" interrupt, which means that it + * runs with interrupts turned off. People who may want to modify + * rs_interrupt() should try to keep the interrupt handler as fast as + * possible. After you are done making modifications, it is not a bad + * idea to do: + * + * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c + * + * and look at the resulting assemble code in serial.s. + * + * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 + * ----------------------------------------------------------------------- + */ + +/* + * This routine is used by the interrupt handler to schedule + * processing in the software interrupt portion of the driver. + */ +static _INLINE_ void rs_sched_event(struct async_struct *info, + int event) +{ + info->event |= 1 << event; + queue_task(&info->tqueue, &tq_serial); + mark_bh(SERIAL_BH); +} + +static _INLINE_ void receive_chars(struct async_struct *info, + int *status) +{ + struct tty_struct *tty = info->tty; + unsigned short rx; + unsigned char ch; + int ignored = 0; + struct async_icount *icount; + + icount = &info->state->icount; + do { + rx = serial_inw(info, VAC_UART_RX); + ch = VAC_UART_RX_DATA_MASK & rx; + + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + break; + *tty->flip.char_buf_ptr = ch; + icount->rx++; + +#ifdef SERIAL_DEBUG_INTR + baget_printk("DR%02x:%02x...", rx, *status); +#endif + *tty->flip.flag_buf_ptr = 0; + if (*status & (VAC_UART_STATUS_RX_BREAK_CHANGE + | VAC_UART_STATUS_RX_ERR_PARITY + | VAC_UART_STATUS_RX_ERR_FRAME + | VAC_UART_STATUS_RX_ERR_OVERRUN)) { + /* + * For statistics only + */ + if (*status & VAC_UART_STATUS_RX_BREAK_CHANGE) { + *status &= ~(VAC_UART_STATUS_RX_ERR_FRAME + | VAC_UART_STATUS_RX_ERR_PARITY); + icount->brk++; + } else if (*status & VAC_UART_STATUS_RX_ERR_PARITY) + icount->parity++; + else if (*status & VAC_UART_STATUS_RX_ERR_FRAME) + icount->frame++; + if (*status & VAC_UART_STATUS_RX_ERR_OVERRUN) + icount->overrun++; + + /* + * Now check to see if character should be + * ignored, and mask off conditions which + * should be ignored. + */ + if (*status & info->ignore_status_mask) { + if (++ignored > 100) + break; + goto ignore_char; + } + *status &= info->read_status_mask; + + if (*status & (VAC_UART_STATUS_RX_BREAK_CHANGE)) { +#ifdef SERIAL_DEBUG_INTR + baget_printk("handling break...."); +#endif + *tty->flip.flag_buf_ptr = TTY_BREAK; + if (info->flags & ASYNC_SAK) + do_SAK(tty); + } else if (*status & VAC_UART_STATUS_RX_ERR_PARITY) + *tty->flip.flag_buf_ptr = TTY_PARITY; + else if (*status & VAC_UART_STATUS_RX_ERR_FRAME) + *tty->flip.flag_buf_ptr = TTY_FRAME; + if (*status & VAC_UART_STATUS_RX_ERR_OVERRUN) { + /* + * Overrun is special, since it's + * reported immediately, and doesn't + * affect the current character + */ + if (tty->flip.count < TTY_FLIPBUF_SIZE) { + tty->flip.count++; + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + *tty->flip.flag_buf_ptr = TTY_OVERRUN; + } + } + } + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + tty->flip.count++; + ignore_char: + *status = serial_inw(info, VAC_UART_INT_STATUS); + } while ((*status & VAC_UART_STATUS_RX_READY)); + tty_flip_buffer_push(tty); +} + +static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) +{ + int count; + + if (info->x_char) { + serial_outw(info, VAC_UART_TX, + (((unsigned short)info->x_char)<<8)); + info->state->icount.tx++; + info->x_char = 0; + if (intr_done) + *intr_done = 0; + return; + } + if ((info->xmit_cnt <= 0) || info->tty->stopped || + info->tty->hw_stopped) { + info->IER &= ~VAC_UART_INT_TX_EMPTY; + serial_outw(info, VAC_UART_INT_MASK, info->IER); + return; + } + count = info->xmit_fifo_size; + do { + serial_out(info, VAC_UART_TX, + (unsigned short)info->xmit_buf[info->xmit_tail++] \ + << 8); + info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); + info->state->icount.tx++; + if (--info->xmit_cnt <= 0) + break; + } while (--count > 0); + + if (info->xmit_cnt < WAKEUP_CHARS) + rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); + +#ifdef SERIAL_DEBUG_INTR + baget_printk("THRE..."); +#endif + if (intr_done) + *intr_done = 0; + + if (info->xmit_cnt <= 0) { + info->IER &= ~VAC_UART_INT_TX_EMPTY; + serial_outw(info, VAC_UART_INT_MASK, info->IER); + } +} + +static _INLINE_ void check_modem_status(struct async_struct *info) +{ +#if 0 /* VAC hasn't modem control */ + wake_up_interruptible(&info->open_wait); + rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); +#endif +} + +#ifdef CONFIG_SERIAL_SHARE_IRQ + + +/* + * Specific functions needed for VAC UART interrupt enter/leave + */ + +#define VAC_INT_CTRL_UART_ENABLE \ + (VAC_INT_CTRL_TIMER_PIO10|VAC_INT_CTRL_UART_B_PIO7|VAC_INT_CTRL_UART_A_PIO7) + +#define VAC_INT_CTRL_UART_DISABLE(info) \ + (VAC_INT_CTRL_TIMER_PIO10 | \ + ((info->port == VAC_UART_A_TX) ? \ + (VAC_INT_CTRL_UART_A_DISABLE|VAC_INT_CTRL_UART_B_PIO7) : \ + (VAC_INT_CTRL_UART_A_PIO7|VAC_INT_CTRL_UART_B_DISABLE))) + +/* + * Following two functions were proposed by Pavel Osipenko + * to make VAC/VIC behaviour more regular. + */ +static void intr_begin(struct async_struct* info) +{ + serial_outw(info, VAC_UART_INT_MASK, 0); +} + +static void intr_end(struct async_struct* info) +{ + vac_outw(VAC_INT_CTRL_UART_DISABLE(info), VAC_INT_CTRL); + vac_outw(VAC_INT_CTRL_UART_ENABLE, VAC_INT_CTRL); + + serial_outw(info, VAC_UART_INT_MASK, info->IER); +} + +/* + * This is the serial driver's generic interrupt routine + */ +static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) +{ + int status; + struct async_struct * info; + int pass_counter = 0; + struct async_struct *end_mark = 0; + +#ifdef SERIAL_DEBUG_INTR + baget_printk("rs_interrupt(%d)...", irq); +#endif + + info = IRQ_ports[irq]; + if (!info) + return; + + do { + intr_begin(info); /* Mark we begin port handling */ + + if (!info->tty || + (serial_inw (info, VAC_UART_INT_STATUS) + & VAC_UART_STATUS_INTS) == 0) + { + if (!end_mark) + end_mark = info; + goto next; + } + end_mark = 0; + + info->last_active = jiffies; + + status = serial_inw(info, VAC_UART_INT_STATUS); +#ifdef SERIAL_DEBUG_INTR + baget_printk("status = %x...", status); +#endif + if (status & VAC_UART_STATUS_RX_READY) { + receive_chars(info, &status); + } + check_modem_status(info); + if (status & VAC_UART_STATUS_TX_EMPTY) + transmit_chars(info, 0); + + next: + intr_end(info); /* Mark this port handled */ + + info = info->next_port; + if (!info) { + info = IRQ_ports[irq]; + if (pass_counter++ > RS_ISR_PASS_LIMIT) { + break; /* Prevent infinite loops */ + } + continue; + } + } while (end_mark != info); +#ifdef SERIAL_DEBUG_INTR + baget_printk("end.\n"); +#endif + + +} +#endif /* #ifdef CONFIG_SERIAL_SHARE_IRQ */ + + +/* The original driver was simplified here: + two functions were joined to reduce code */ + +#define rs_interrupt_single rs_interrupt + + +/* + * ------------------------------------------------------------------- + * Here ends the serial interrupt routines. + * ------------------------------------------------------------------- + */ + +/* + * This routine is used to handle the "bottom half" processing for the + * serial driver, known also the "software interrupt" processing. + * This processing is done at the kernel interrupt level, after the + * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This + * is where time-consuming activities which can not be done in the + * interrupt driver proper are done; the interrupt driver schedules + * them using rs_sched_event(), and they get done here. + */ +static void do_serial_bh(void) +{ + run_task_queue(&tq_serial); +} + +static void do_softint(void *private_) +{ + struct async_struct *info = (struct async_struct *) private_; + struct tty_struct *tty; + + tty = info->tty; + if (!tty) + return; + + if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); + wake_up_interruptible(&tty->write_wait); + } +} + +/* + * --------------------------------------------------------------- + * Low level utility subroutines for the serial driver: routines to + * figure out the appropriate timeout for an interrupt chain, routines + * to initialize and startup a serial port, and routines to shutdown a + * serial port. Useful stuff like that. + * --------------------------------------------------------------- + */ + +/* + * This routine figures out the correct timeout for a particular IRQ. + * It uses the smallest timeout of all of the serial ports in a + * particular interrupt chain. Now only used for IRQ 0.... + */ +static void figure_IRQ_timeout(int irq) +{ + struct async_struct *info; + int timeout = 60*HZ; /* 60 seconds === a long time :-) */ + + info = IRQ_ports[irq]; + if (!info) { + IRQ_timeout[irq] = 60*HZ; + return; + } + while (info) { + if (info->timeout < timeout) + timeout = info->timeout; + info = info->next_port; + } + if (!irq) + timeout = timeout / 2; + IRQ_timeout[irq] = timeout ? timeout : 1; +} + +static int startup(struct async_struct * info) +{ + unsigned long flags; + int retval=0; + void (*handler)(int, void *, struct pt_regs *); + struct serial_state *state= info->state; + unsigned long page; + + page = get_free_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + + save_flags(flags); cli(); + + if (info->flags & ASYNC_INITIALIZED) { + free_page(page); + goto errout; + } + if (!state->port || !state->type) { + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + free_page(page); + goto errout; + } + if (info->xmit_buf) + free_page(page); + else + info->xmit_buf = (unsigned char *) page; + +#ifdef SERIAL_DEBUG_OPEN + baget_printk("starting up ttys%d (irq %d)...", info->line, state->irq); +#endif + + if (uart_config[info->state->type].flags & UART_STARTECH) { + /* Wake up UART */ + serial_outp(info, VAC_UART_MODE, 0); + serial_outp(info, VAC_UART_INT_MASK, 0); + } + + /* + * Allocate the IRQ if necessary + */ + if (state->irq && (!IRQ_ports[state->irq] || + !IRQ_ports[state->irq]->next_port)) { + + if (IRQ_ports[state->irq]) { +#ifdef CONFIG_SERIAL_SHARE_IRQ + free_irq(state->irq, NULL); + handler = rs_interrupt; +#else + retval = -EBUSY; + goto errout; +#endif /* CONFIG_SERIAL_SHARE_IRQ */ + } else + handler = rs_interrupt_single; + + + retval = request_irq(state->irq, handler, IRQ_T(state), + "serial", NULL); + if (retval) { + if (capable(CAP_SYS_ADMIN)) { + if (info->tty) + set_bit(TTY_IO_ERROR, + &info->tty->flags); + retval = 0; + } + goto errout; + } + } + + /* + * Insert serial port into IRQ chain. + */ + info->prev_port = 0; + info->next_port = IRQ_ports[state->irq]; + if (info->next_port) + info->next_port->prev_port = info; + IRQ_ports[state->irq] = info; + figure_IRQ_timeout(state->irq); + + /* + * Clear the interrupt registers. + */ + /* (void) serial_inw(info, VAC_UART_INT_STATUS); */ /* (see above) */ + (void) serial_inw(info, VAC_UART_RX); + + /* + * Now, initialize the UART + */ + serial_outp(info, VAC_UART_MODE, VAC_UART_MODE_INITIAL); /*reset DLAB*/ + + /* + * Finally, enable interrupts + */ + info->IER = VAC_UART_INT_RX_BREAK_CHANGE | VAC_UART_INT_RX_ERRS | \ + VAC_UART_INT_RX_READY; + serial_outp(info, VAC_UART_INT_MASK, info->IER); /*enable interrupts*/ + + /* + * And clear the interrupt registers again for luck. + */ + (void)serial_inp(info, VAC_UART_INT_STATUS); + (void)serial_inp(info, VAC_UART_RX); + + if (info->tty) + clear_bit(TTY_IO_ERROR, &info->tty->flags); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + + /* + * Set up serial timers... + */ + mod_timer(&vacs_timer, jiffies + 2*HZ/100); + + /* + * and set the speed of the serial port + */ + change_speed(info); + + info->flags |= ASYNC_INITIALIZED; + restore_flags(flags); + return 0; + +errout: + restore_flags(flags); + return retval; +} + +/* + * This routine will shutdown a serial port; interrupts are disabled, and + * DTR is dropped if the hangup on close termio flag is on. + */ +static void shutdown(struct async_struct * info) +{ + unsigned long flags; + struct serial_state *state; + int retval; + + if (!(info->flags & ASYNC_INITIALIZED)) + return; + + state = info->state; + +#ifdef SERIAL_DEBUG_OPEN + baget_printk("Shutting down serial port %d (irq %d)....", info->line, + state->irq); +#endif + + save_flags(flags); cli(); /* Disable interrupts */ + + /* + * clear delta_msr_wait queue to avoid mem leaks: we may free the irq + * here so the queue might never be waken up + */ + wake_up_interruptible(&info->delta_msr_wait); + + /* + * First unlink the serial port from the IRQ chain... + */ + if (info->next_port) + info->next_port->prev_port = info->prev_port; + if (info->prev_port) + info->prev_port->next_port = info->next_port; + else + IRQ_ports[state->irq] = info->next_port; + figure_IRQ_timeout(state->irq); + + /* + * Free the IRQ, if necessary + */ + if (state->irq && (!IRQ_ports[state->irq] || + !IRQ_ports[state->irq]->next_port)) { + if (IRQ_ports[state->irq]) { + free_irq(state->irq, NULL); + retval = request_irq(state->irq, rs_interrupt_single, + IRQ_T(state), "serial", NULL); + + if (retval) + printk("serial shutdown: request_irq: error %d" + " Couldn't reacquire IRQ.\n", retval); + } else + free_irq(state->irq, NULL); + } + + if (info->xmit_buf) { + free_page((unsigned long) info->xmit_buf); + info->xmit_buf = 0; + } + + info->IER = 0; + serial_outp(info, VAC_UART_INT_MASK, 0x00); /* disable all intrs */ + + /* disable break condition */ + serial_out(info, VAC_UART_MODE, serial_inp(info, VAC_UART_MODE) & \ + ~VAC_UART_MODE_SEND_BREAK); + + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + + info->flags &= ~ASYNC_INITIALIZED; + restore_flags(flags); +} + +/* + * When we set line mode, we call this function + * for Baget-specific adjustments. + */ + +static inline unsigned short vac_uart_mode_fixup (unsigned short cval) +{ +#ifdef QUAD_UART_SPEED + /* + * When we are using 4-x advantage in speed: + * + * Disadvantage : can't support 75, 150 bauds + * Advantage : can support 19200, 38400 bauds + */ + char speed = 7 & (cval >> 10); + cval &= ~(7 << 10); + cval |= VAC_UART_MODE_BAUD(speed-2); +#endif + + /* + * In general, we have Tx and Rx ON all time + * and use int mask flag for their disabling. + */ + cval |= VAC_UART_MODE_RX_ENABLE; + cval |= VAC_UART_MODE_TX_ENABLE; + cval |= VAC_UART_MODE_CHAR_RX_ENABLE; + cval |= VAC_UART_MODE_CHAR_TX_ENABLE; + + /* Low 4 bits are not used in UART */ + cval &= ~0xf; + + return cval; +} + +/* + * This routine is called to set the UART divisor registers to match + * the specified baud rate for a serial port. + */ +static void change_speed(struct async_struct *info) +{ + unsigned short port; + int quot = 0, baud_base, baud; + unsigned cflag, cval; + int bits; + unsigned long flags; + + if (!info->tty || !info->tty->termios) + return; + cflag = info->tty->termios->c_cflag; + if (!(port = info->port)) + return; + + /* byte size and parity */ + switch (cflag & CSIZE) { + case CS7: cval = 0x0; bits = 9; break; + case CS8: cval = VAC_UART_MODE_8BIT_CHAR; bits = 10; break; + /* Never happens, but GCC is too dumb to figure it out */ + case CS5: + case CS6: + default: cval = 0x0; bits = 9; break; + } + cval &= ~VAC_UART_MODE_PARITY_ENABLE; + if (cflag & PARENB) { + cval |= VAC_UART_MODE_PARITY_ENABLE; + bits++; + } + if (cflag & PARODD) + cval |= VAC_UART_MODE_PARITY_ODD; + + /* Determine divisor based on baud rate */ + baud = tty_get_baud_rate(info->tty); + if (!baud) + baud = 9600; /* B0 transition handled in rs_set_termios */ + baud_base = info->state->baud_base; + if (baud == 38400 && + ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) + quot = info->state->custom_divisor; + else { + if (baud == 134) + /* Special case since 134 is really 134.5 */ + quot = (2*baud_base / 269); + else if (baud) + quot = baud_base / baud; + } + /* If the quotient is ever zero, default to 9600 bps */ + if (!quot) + quot = baud_base / 9600; + info->quot = quot; + info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base); + info->timeout += HZ/50; /* Add .02 seconds of slop */ + + serial_out(info, VAC_UART_INT_MASK, info->IER); + + /* + * Set up parity check flag + */ +#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) + + info->read_status_mask = VAC_UART_STATUS_RX_ERR_OVERRUN | \ + VAC_UART_STATUS_TX_EMPTY | VAC_UART_STATUS_RX_READY; + if (I_INPCK(info->tty)) + info->read_status_mask |= VAC_UART_STATUS_RX_ERR_FRAME | \ + VAC_UART_STATUS_RX_ERR_PARITY; + if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) + info->read_status_mask |= VAC_UART_STATUS_RX_BREAK_CHANGE; + + /* + * Characters to ignore + */ + info->ignore_status_mask = 0; + if (I_IGNPAR(info->tty)) + info->ignore_status_mask |= VAC_UART_STATUS_RX_ERR_PARITY | \ + VAC_UART_STATUS_RX_ERR_FRAME; + if (I_IGNBRK(info->tty)) { + info->ignore_status_mask |= VAC_UART_STATUS_RX_BREAK_CHANGE; + /* + * If we're ignore parity and break indicators, ignore + * overruns too. (For real raw support). + */ + if (I_IGNPAR(info->tty)) + info->ignore_status_mask |= \ + VAC_UART_STATUS_RX_ERR_OVERRUN; + } + /* + * !!! ignore all characters if CREAD is not set + */ + if ((cflag & CREAD) == 0) + info->ignore_status_mask |= VAC_UART_STATUS_RX_READY; + save_flags(flags); cli(); + + + switch (baud) { + default: + case 9600: + cval |= VAC_UART_MODE_BAUD(7); + break; + case 4800: + cval |= VAC_UART_MODE_BAUD(6); + break; + case 2400: + cval |= VAC_UART_MODE_BAUD(5); + break; + case 1200: + cval |= VAC_UART_MODE_BAUD(4); + break; + case 600: + cval |= VAC_UART_MODE_BAUD(3); + break; + case 300: + cval |= VAC_UART_MODE_BAUD(2); + break; +#ifndef QUAD_UART_SPEED + case 150: +#else + case 38400: +#endif + cval |= VAC_UART_MODE_BAUD(1); + break; +#ifndef QUAD_UART_SPEED + case 75: +#else + case 19200: +#endif + cval |= VAC_UART_MODE_BAUD(0); + break; + } + + /* Baget VAC need some adjustments for computed value */ + cval = vac_uart_mode_fixup(cval); + + serial_outp(info, VAC_UART_MODE, cval); + restore_flags(flags); +} + +static void rs_put_char(struct tty_struct *tty, unsigned char ch) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_put_char")) + return; + + if (!tty || !info->xmit_buf) + return; + + save_flags(flags); cli(); + if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { + restore_flags(flags); + return; + } + + info->xmit_buf[info->xmit_head++] = ch; + info->xmit_head &= SERIAL_XMIT_SIZE-1; + info->xmit_cnt++; + restore_flags(flags); +} + +static void rs_flush_chars(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_flush_chars")) + return; + + if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || + !info->xmit_buf) + return; + + save_flags(flags); cli(); + info->IER |= VAC_UART_INT_TX_EMPTY; + serial_out(info, VAC_UART_INT_MASK, info->IER); + restore_flags(flags); +} + +static int rs_write(struct tty_struct * tty, int from_user, + const unsigned char *buf, int count) +{ + int c, ret = 0; + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_write")) + return 0; + + if (!tty || !info->xmit_buf || !tmp_buf) + return 0; + + save_flags(flags); + if (from_user) { + down(&tmp_buf_sem); + while (1) { + c = MIN(count, + MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + if (c <= 0) + break; + + c -= copy_from_user(tmp_buf, buf, c); + if (!c) { + if (!ret) + ret = -EFAULT; + break; + } + cli(); + c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c); + info->xmit_head = ((info->xmit_head + c) & + (SERIAL_XMIT_SIZE-1)); + info->xmit_cnt += c; + restore_flags(flags); + buf += c; + count -= c; + ret += c; + } + up(&tmp_buf_sem); + } else { + while (1) { + cli(); + c = MIN(count, + MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, + SERIAL_XMIT_SIZE - info->xmit_head)); + if (c <= 0) { + restore_flags(flags); + break; + } + memcpy(info->xmit_buf + info->xmit_head, buf, c); + info->xmit_head = ((info->xmit_head + c) & + (SERIAL_XMIT_SIZE-1)); + info->xmit_cnt += c; + restore_flags(flags); + buf += c; + count -= c; + ret += c; + } + } + if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped && + !(info->IER & VAC_UART_INT_TX_EMPTY)) { + info->IER |= VAC_UART_INT_TX_EMPTY; + serial_out(info, VAC_UART_INT_MASK, info->IER); + } + return ret; +} + +static int rs_write_room(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + int ret; + + if (serial_paranoia_check(info, tty->device, "rs_write_room")) + return 0; + ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; + if (ret < 0) + ret = 0; + return ret; +} + +static int rs_chars_in_buffer(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + + if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer")) + return 0; + return info->xmit_cnt; +} + +static void rs_flush_buffer(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_flush_buffer")) + return; + + save_flags(flags); cli(); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + restore_flags(flags); + + wake_up_interruptible(&tty->write_wait); + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); +} + +/* + * This function is used to send a high-priority XON/XOFF character to + * the device + */ +static void rs_send_xchar(struct tty_struct *tty, char ch) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + + if (serial_paranoia_check(info, tty->device, "rs_send_char")) + return; + + info->x_char = ch; + if (ch) { + /* Make sure transmit interrupts are on */ + info->IER |= VAC_UART_INT_TX_EMPTY; + serial_out(info, VAC_UART_INT_MASK, info->IER); + } +} + +/* + * ------------------------------------------------------------ + * rs_throttle() + * + * This routine is called by the upper-layer tty layer to signal that + * incoming characters should be throttled. + * ------------------------------------------------------------ + */ +static void rs_throttle(struct tty_struct * tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + baget_printk("throttle %s: %d....\n", tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (serial_paranoia_check(info, tty->device, "rs_throttle")) + return; + + if (I_IXOFF(tty)) + rs_send_xchar(tty, STOP_CHAR(tty)); +} + +static void rs_unthrottle(struct tty_struct * tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; +#ifdef SERIAL_DEBUG_THROTTLE + char buf[64]; + + baget_printk("unthrottle %s: %d....\n", tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty)); +#endif + + if (serial_paranoia_check(info, tty->device, "rs_unthrottle")) + return; + + if (I_IXOFF(tty)) { + if (info->x_char) + info->x_char = 0; + else + rs_send_xchar(tty, START_CHAR(tty)); + } +} + +/* + * ------------------------------------------------------------ + * rs_ioctl() and friends + * ------------------------------------------------------------ + */ + +static int get_serial_info(struct async_struct * info, + struct serial_struct * retinfo) +{ + struct serial_struct tmp; + struct serial_state *state = info->state; + + if (!retinfo) + return -EFAULT; + memset(&tmp, 0, sizeof(tmp)); + tmp.type = state->type; + tmp.line = state->line; + tmp.port = state->port; + tmp.irq = state->irq; + tmp.flags = state->flags; + tmp.xmit_fifo_size = state->xmit_fifo_size; + tmp.baud_base = state->baud_base; + tmp.close_delay = state->close_delay; + tmp.closing_wait = state->closing_wait; + tmp.custom_divisor = state->custom_divisor; + tmp.hub6 = state->hub6; + if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) + return -EFAULT; + return 0; +} + +static int set_serial_info(struct async_struct * info, + struct serial_struct * new_info) +{ + struct serial_struct new_serial; + struct serial_state old_state, *state; + unsigned int i,change_irq,change_port; + int retval = 0; + + if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) + return -EFAULT; + state = info->state; + old_state = *state; + + change_irq = new_serial.irq != state->irq; + change_port = (new_serial.port != state->port) || + (new_serial.hub6 != state->hub6); + + if (!capable(CAP_SYS_ADMIN)) { + if (change_irq || change_port || + (new_serial.baud_base != state->baud_base) || + (new_serial.type != state->type) || + (new_serial.close_delay != state->close_delay) || + (new_serial.xmit_fifo_size != state->xmit_fifo_size) || + ((new_serial.flags & ~ASYNC_USR_MASK) != + (state->flags & ~ASYNC_USR_MASK))) + return -EPERM; + state->flags = ((state->flags & ~ASYNC_USR_MASK) | + (new_serial.flags & ASYNC_USR_MASK)); + info->flags = ((state->flags & ~ASYNC_USR_MASK) | + (info->flags & ASYNC_USR_MASK)); + state->custom_divisor = new_serial.custom_divisor; + goto check_and_exit; + } + + new_serial.irq = new_serial.irq; + + if ((new_serial.irq >= NR_IRQS) || (new_serial.port > 0xffff) || + (new_serial.baud_base == 0) || (new_serial.type < PORT_UNKNOWN) || + (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) || + (new_serial.type == PORT_STARTECH)) { + return -EINVAL; + } + + if ((new_serial.type != state->type) || + (new_serial.xmit_fifo_size <= 0)) + new_serial.xmit_fifo_size = + uart_config[state->type].dfl_xmit_fifo_size; + + /* Make sure address is not already in use */ + if (new_serial.type) { + for (i = 0 ; i < NR_PORTS; i++) + if ((state != &rs_table[i]) && + (rs_table[i].port == new_serial.port) && + rs_table[i].type) + return -EADDRINUSE; + } + + if ((change_port || change_irq) && (state->count > 1)) + return -EBUSY; + + /* + * OK, past this point, all the error checking has been done. + * At this point, we start making changes..... + */ + + state->baud_base = new_serial.baud_base; + state->flags = ((state->flags & ~ASYNC_FLAGS) | + (new_serial.flags & ASYNC_FLAGS)); + info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | + (info->flags & ASYNC_INTERNAL_FLAGS)); + state->custom_divisor = new_serial.custom_divisor; + state->type = new_serial.type; + state->close_delay = new_serial.close_delay * HZ/100; + state->closing_wait = new_serial.closing_wait * HZ/100; + info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; + info->xmit_fifo_size = state->xmit_fifo_size = + new_serial.xmit_fifo_size; + + release_region(state->port,8); + if (change_port || change_irq) { + /* + * We need to shutdown the serial port at the old + * port/irq combination. + */ + shutdown(info); + state->irq = new_serial.irq; + info->port = state->port = new_serial.port; + info->hub6 = state->hub6 = new_serial.hub6; + } + if (state->type != PORT_UNKNOWN) + request_region(state->port,8,"serial(set)"); + + +check_and_exit: + if (!state->port || !state->type) + return 0; + if (info->flags & ASYNC_INITIALIZED) { + if (((old_state.flags & ASYNC_SPD_MASK) != + (state->flags & ASYNC_SPD_MASK)) || + (old_state.custom_divisor != state->custom_divisor)) { + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + info->tty->alt_speed = 57600; + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + info->tty->alt_speed = 115200; + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + info->tty->alt_speed = 230400; + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + info->tty->alt_speed = 460800; + change_speed(info); + } + } else + retval = startup(info); + return retval; +} + + +/* + * get_lsr_info - get line status register info + * + * Purpose: Let user call ioctl() to get info when the UART physically + * is emptied. On bus types like RS485, the transmitter must + * release the bus after transmitting. This must be done when + * the transmit shift register is empty, not be done when the + * transmit holding register is empty. This functionality + * allows an RS485 driver to be written in user space. + */ +static int get_lsr_info(struct async_struct * info, unsigned int *value) +{ + unsigned short status; + unsigned int result; + unsigned long flags; + + save_flags(flags); cli(); + status = serial_inw(info, VAC_UART_INT_STATUS); + restore_flags(flags); + result = ((status & VAC_UART_STATUS_TX_EMPTY) ? TIOCSER_TEMT : 0); + return put_user(result,value); +} + + +static int get_modem_info(struct async_struct * info, unsigned int *value) +{ + unsigned int result; + + result = TIOCM_CAR | TIOCM_DSR; + return put_user(result,value); +} + +static int set_modem_info(struct async_struct * info, unsigned int cmd, + unsigned int *value) +{ + unsigned int arg; + + if (get_user(arg, value)) + return -EFAULT; + switch (cmd) { + default: + return -EINVAL; + } + return 0; +} + +static int do_autoconfig(struct async_struct * info) +{ + int retval; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (info->state->count > 1) + return -EBUSY; + + shutdown(info); + + autoconfig(info->state); + + retval = startup(info); + if (retval) + return retval; + return 0; +} + +/* + * rs_break() --- routine which turns the break handling on or off + */ +static void rs_break(struct tty_struct *tty, int break_state) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_break")) + return; + + if (!info->port) + return; + save_flags(flags); cli(); + if (break_state == -1) + serial_outp(info, VAC_UART_MODE, + serial_inp(info, VAC_UART_MODE) | \ + VAC_UART_MODE_SEND_BREAK); + else + serial_outp(info, VAC_UART_MODE, + serial_inp(info, VAC_UART_MODE) & \ + ~VAC_UART_MODE_SEND_BREAK); + restore_flags(flags); +} + +static int rs_ioctl(struct tty_struct *tty, struct file * file, + unsigned int cmd, unsigned long arg) +{ + int error; + struct async_struct * info = (struct async_struct *)tty->driver_data; + struct async_icount cprev, cnow; /* kernel counter temps */ + struct serial_icounter_struct *p_cuser; /* user space */ + unsigned long flags; + + if (serial_paranoia_check(info, tty->device, "rs_ioctl")) + return -ENODEV; + + if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && + (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && + (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + } + + switch (cmd) { + case TIOCMGET: + return get_modem_info(info, (unsigned int *) arg); + case TIOCMBIS: + case TIOCMBIC: + case TIOCMSET: + return set_modem_info(info, cmd, (unsigned int *) arg); + case TIOCGSERIAL: + return get_serial_info(info, + (struct serial_struct *) arg); + case TIOCSSERIAL: + return set_serial_info(info, + (struct serial_struct *) arg); + case TIOCSERCONFIG: + return do_autoconfig(info); + + case TIOCSERGETLSR: /* Get line status register */ + return get_lsr_info(info, (unsigned int *) arg); + + case TIOCSERGSTRUCT: + if (copy_to_user((struct async_struct *) arg, + info, sizeof(struct async_struct))) + return -EFAULT; + return 0; + + /* + * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)to change + * - mask passed in arg for lines of interest + * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) + * Caller should use TIOCGICOUNT to see which one it was + */ + case TIOCMIWAIT: + save_flags(flags); cli(); + /* note the counters on entry */ + cprev = info->state->icount; + restore_flags(flags); + while (1) { + interruptible_sleep_on(&info->delta_msr_wait); + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; + save_flags(flags); cli(); + cnow = info->state->icount; /* atomic copy */ + restore_flags(flags); + if (cnow.rng == cprev.rng && + cnow.dsr == cprev.dsr && + cnow.dcd == cprev.dcd && + cnow.cts == cprev.cts) + return -EIO; /* no change => error */ + if ( ((arg & TIOCM_RNG) && + (cnow.rng != cprev.rng)) || + ((arg & TIOCM_DSR) && + (cnow.dsr != cprev.dsr)) || + ((arg & TIOCM_CD) && + (cnow.dcd != cprev.dcd)) || + ((arg & TIOCM_CTS) && + (cnow.cts != cprev.cts)) ) { + return 0; + } + cprev = cnow; + } + /* NOTREACHED */ + + /* + * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) + * Return: write counters to the user passed counter struct + * NB: both 1->0 and 0->1 transitions are counted except for + * RI where only 0->1 is counted. + */ + case TIOCGICOUNT: + save_flags(flags); cli(); + cnow = info->state->icount; + restore_flags(flags); + p_cuser = (struct serial_icounter_struct *) arg; + error = put_user(cnow.cts, &p_cuser->cts); + if (error) return error; + error = put_user(cnow.dsr, &p_cuser->dsr); + if (error) return error; + error = put_user(cnow.rng, &p_cuser->rng); + if (error) return error; + error = put_user(cnow.dcd, &p_cuser->dcd); + if (error) return error; + error = put_user(cnow.rx, &p_cuser->rx); + if (error) return error; + error = put_user(cnow.tx, &p_cuser->tx); + if (error) return error; + error = put_user(cnow.frame, &p_cuser->frame); + if (error) return error; + error = put_user(cnow.overrun, &p_cuser->overrun); + if (error) return error; + error = put_user(cnow.parity, &p_cuser->parity); + if (error) return error; + error = put_user(cnow.brk, &p_cuser->brk); + if (error) return error; + error = put_user(cnow.buf_overrun, &p_cuser->buf_overrun); + + if (error) return error; + return 0; + + case TIOCSERGWILD: + case TIOCSERSWILD: + /* "setserial -W" is called in Debian boot */ + printk ("TIOCSER?WILD ioctl obsolete, ignored.\n"); + return 0; + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned int cflag = tty->termios->c_cflag; + + if ( (cflag == old_termios->c_cflag) + && ( RELEVANT_IFLAG(tty->termios->c_iflag) + == RELEVANT_IFLAG(old_termios->c_iflag))) + return; + + change_speed(info); + + /* Handle turning off CRTSCTS */ + if ((old_termios->c_cflag & CRTSCTS) && + !(cflag & CRTSCTS)) { + tty->hw_stopped = 0; + rs_start(tty); + } + +} + +/* + * ------------------------------------------------------------ + * rs_close() + * + * This routine is called when the serial port gets closed. First, we + * wait for the last remaining data to be sent. Then, we unlink its + * async structure from the interrupt chain if necessary, and we free + * that IRQ if nothing is left in the chain. + * ------------------------------------------------------------ + */ +static void rs_close(struct tty_struct *tty, struct file * filp) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + struct serial_state *state; + unsigned long flags; + + if (!info || serial_paranoia_check(info, tty->device, "rs_close")) + return; + + state = info->state; + + save_flags(flags); cli(); + + if (tty_hung_up_p(filp)) { + DBG_CNT("before DEC-hung"); + MOD_DEC_USE_COUNT; + restore_flags(flags); + return; + } + +#ifdef SERIAL_DEBUG_OPEN + baget_printk("rs_close ttys%d, count = %d\n", + info->line, state->count); +#endif + if ((tty->count == 1) && (state->count != 1)) { + /* + * Uh, oh. tty->count is 1, which means that the tty + * structure will be freed. state->count should always + * be one in these conditions. If it's greater than + * one, we've got real problems, since it means the + * serial port won't be shutdown. + */ + baget_printk("rs_close: bad serial port count; " + "tty->count is 1, " + "state->count is %d\n", state->count); + state->count = 1; + } + if (--state->count < 0) { + baget_printk("rs_close: bad serial port count for " + "ttys%d: %d\n", + info->line, state->count); + state->count = 0; + } + if (state->count) { + DBG_CNT("before DEC-2"); + MOD_DEC_USE_COUNT; + restore_flags(flags); + return; + } + info->flags |= ASYNC_CLOSING; + /* + * Save the termios structure, since this port may have + * separate termios for callout and dialin. + */ + if (info->flags & ASYNC_NORMAL_ACTIVE) + info->state->normal_termios = *tty->termios; + if (info->flags & ASYNC_CALLOUT_ACTIVE) + info->state->callout_termios = *tty->termios; + /* + * Now we wait for the transmit buffer to clear; and we notify + * the line discipline to only process XON/XOFF characters. + */ + tty->closing = 1; + if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) + tty_wait_until_sent(tty, info->closing_wait); + /* + * At this point we stop accepting input. To do this, we + * disable the receive line status interrupts, and tell the + * interrupt driver to stop checking the data ready bit in the + * line status register. + */ + info->IER &= ~(VAC_UART_INT_RX_BREAK_CHANGE | VAC_UART_INT_RX_ERRS); + info->read_status_mask &= ~VAC_UART_STATUS_RX_READY; + if (info->flags & ASYNC_INITIALIZED) { + serial_outw(info, VAC_UART_INT_MASK, info->IER); + /* + * Before we drop DTR, make sure the UART transmitter + * has completely drained; this is especially + * important if there is a transmit FIFO! + */ + rs_wait_until_sent(tty, info->timeout); + } + shutdown(info); + if (tty->driver.flush_buffer) + tty->driver.flush_buffer(tty); + if (tty->ldisc.flush_buffer) + tty->ldisc.flush_buffer(tty); + tty->closing = 0; + info->event = 0; + info->tty = 0; + if (info->blocked_open) { + if (info->close_delay) { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(info->close_delay); + } + wake_up_interruptible(&info->open_wait); + } + info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE| + ASYNC_CLOSING); + wake_up_interruptible(&info->close_wait); + MOD_DEC_USE_COUNT; + restore_flags(flags); +} + +/* + * rs_wait_until_sent() --- wait until the transmitter is empty + */ +static void rs_wait_until_sent(struct tty_struct *tty, int timeout) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + unsigned long orig_jiffies, char_time; + int lsr; + + if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent")) + return; + + if (info->state->type == PORT_UNKNOWN) + return; + + if (info->xmit_fifo_size == 0) + return; /* Just in case.... */ + + orig_jiffies = jiffies; + /* + * Set the check interval to be 1/5 of the estimated time to + * send a single character, and make it at least 1. The check + * interval should also be less than the timeout. + * + * Note: we have to use pretty tight timings here to satisfy + * the NIST-PCTS. + */ + char_time = (info->timeout - HZ/50) / info->xmit_fifo_size; + char_time = char_time / 5; + if (char_time == 0) + char_time = 1; + if (timeout) + char_time = MIN(char_time, timeout); +#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + baget_printk("In rs_wait_until_sent(%d) check=%lu...", + timeout, char_time); + baget_printk("jiff=%lu...", jiffies); +#endif + while (!((lsr = serial_inp(info, VAC_UART_INT_STATUS)) & \ + VAC_UART_STATUS_TX_EMPTY)) { +#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + baget_printk("lsr = %d (jiff=%lu)...", lsr, jiffies); +#endif + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(char_time); + if (signal_pending(current)) + break; + if (timeout && time_after(jiffies, orig_jiffies + timeout)) + break; + } + current->state = TASK_RUNNING; +#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT + baget_printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); +#endif +} + +/* + * rs_hangup() --- called by tty_hangup() when a hangup is signaled. + */ +static void rs_hangup(struct tty_struct *tty) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + struct serial_state *state = info->state; + + if (serial_paranoia_check(info, tty->device, "rs_hangup")) + return; + + state = info->state; + + rs_flush_buffer(tty); + shutdown(info); + info->event = 0; + state->count = 0; + info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE); + info->tty = 0; + wake_up_interruptible(&info->open_wait); +} + +/* + * ------------------------------------------------------------ + * rs_open() and friends + * ------------------------------------------------------------ + */ +static int block_til_ready(struct tty_struct *tty, struct file * filp, + struct async_struct *info) +{ + DECLARE_WAITQUEUE(wait, current); + struct serial_state *state = info->state; + int retval; + int do_clocal = 0, extra_count = 0; + unsigned long flags; + + /* + * If the device is in the middle of being closed, then block + * until it's done, and then try again. + */ + if (tty_hung_up_p(filp) || + (info->flags & ASYNC_CLOSING)) { + if (info->flags & ASYNC_CLOSING) + interruptible_sleep_on(&info->close_wait); +#ifdef SERIAL_DO_RESTART + return ((info->flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS); +#else + return -EAGAIN; +#endif + } + + /* + * If this is a callout device, then just make sure the normal + * device isn't being used. + */ + if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) { + if (info->flags & ASYNC_NORMAL_ACTIVE) + return -EBUSY; + if ((info->flags & ASYNC_CALLOUT_ACTIVE) && + (info->flags & ASYNC_SESSION_LOCKOUT) && + (info->session != current->session)) + return -EBUSY; + if ((info->flags & ASYNC_CALLOUT_ACTIVE) && + (info->flags & ASYNC_PGRP_LOCKOUT) && + (info->pgrp != current->pgrp)) + return -EBUSY; + info->flags |= ASYNC_CALLOUT_ACTIVE; + return 0; + } + + /* + * If non-blocking mode is set, or the port is not enabled, + * then make the check up front and then exit. + */ + if ((filp->f_flags & O_NONBLOCK) || + (tty->flags & (1 << TTY_IO_ERROR))) { + if (info->flags & ASYNC_CALLOUT_ACTIVE) + return -EBUSY; + info->flags |= ASYNC_NORMAL_ACTIVE; + return 0; + } + + if (info->flags & ASYNC_CALLOUT_ACTIVE) { + if (state->normal_termios.c_cflag & CLOCAL) + do_clocal = 1; + } else { + if (tty->termios->c_cflag & CLOCAL) + do_clocal = 1; + } + + /* + * Block waiting for the carrier detect and the line to become + * free (i.e., not in use by the callout). While we are in + * this loop, state->count is dropped by one, so that + * rs_close() knows when to free things. We restore it upon + * exit, either normal or abnormal. + */ + retval = 0; + add_wait_queue(&info->open_wait, &wait); +#ifdef SERIAL_DEBUG_OPEN + baget_printk("block_til_ready before block: ttys%d, count = %d\n", + state->line, state->count); +#endif + save_flags(flags); cli(); + if (!tty_hung_up_p(filp)) { + extra_count = 1; + state->count--; + } + restore_flags(flags); + info->blocked_open++; + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + if (tty_hung_up_p(filp) || + !(info->flags & ASYNC_INITIALIZED)) { +#ifdef SERIAL_DO_RESTART + if (info->flags & ASYNC_HUP_NOTIFY) + retval = -EAGAIN; + else + retval = -ERESTARTSYS; +#else + retval = -EAGAIN; +#endif + break; + } + if (!(info->flags & ASYNC_CALLOUT_ACTIVE) && + !(info->flags & ASYNC_CLOSING)) + break; + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } +#ifdef SERIAL_DEBUG_OPEN + baget_printk("block_til_ready blocking: ttys%d, count = %d\n", + info->line, state->count); +#endif + schedule(); + } + current->state = TASK_RUNNING; + remove_wait_queue(&info->open_wait, &wait); + if (extra_count) + state->count++; + info->blocked_open--; +#ifdef SERIAL_DEBUG_OPEN + baget_printk("block_til_ready after blocking: ttys%d, count = %d\n", + info->line, state->count); +#endif + if (retval) + return retval; + info->flags |= ASYNC_NORMAL_ACTIVE; + return 0; +} + +static int get_async_struct(int line, struct async_struct **ret_info) +{ + struct async_struct *info; + struct serial_state *sstate; + + sstate = rs_table + line; + sstate->count++; + if (sstate->info) { + *ret_info = sstate->info; + return 0; + } + info = kmalloc(sizeof(struct async_struct), GFP_KERNEL); + if (!info) { + sstate->count--; + return -ENOMEM; + } + memset(info, 0, sizeof(struct async_struct)); + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + init_waitqueue_head(&info->delta_msr_wait); + info->magic = SERIAL_MAGIC; + info->port = sstate->port; + info->flags = sstate->flags; + info->xmit_fifo_size = sstate->xmit_fifo_size; + info->line = line; + info->tqueue.routine = do_softint; + info->tqueue.data = info; + info->state = sstate; + if (sstate->info) { + kfree(info); + *ret_info = sstate->info; + return 0; + } + *ret_info = sstate->info = info; + return 0; +} + +/* + * This routine is called whenever a serial port is opened. It + * enables interrupts for a serial port, linking in its async structure into + * the IRQ chain. It also performs the serial-specific + * initialization for the tty structure. + */ +static int rs_open(struct tty_struct *tty, struct file * filp) +{ + struct async_struct *info; + int retval, line; + unsigned long page; + + MOD_INC_USE_COUNT; + line = MINOR(tty->device) - tty->driver.minor_start; + if ((line < 0) || (line >= NR_PORTS)) { + MOD_DEC_USE_COUNT; + return -ENODEV; + } + retval = get_async_struct(line, &info); + if (retval) { + MOD_DEC_USE_COUNT; + return retval; + } + tty->driver_data = info; + info->tty = tty; + if (serial_paranoia_check(info, tty->device, "rs_open")) { + /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ + return -ENODEV; + } + +#ifdef SERIAL_DEBUG_OPEN + baget_printk("rs_open %s%d, count = %d\n", + tty->driver.name, info->line, + info->state->count); +#endif + info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; + + if (!tmp_buf) { + page = get_free_page(GFP_KERNEL); + if (!page) { + /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ + return -ENOMEM; + } + if (tmp_buf) + free_page(page); + else + tmp_buf = (unsigned char *) page; + } + + /* + * If the port is the middle of closing, bail out now + */ + if (tty_hung_up_p(filp) || + (info->flags & ASYNC_CLOSING)) { + if (info->flags & ASYNC_CLOSING) + interruptible_sleep_on(&info->close_wait); + /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ +#ifdef SERIAL_DO_RESTART + return ((info->flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS); +#else + return -EAGAIN; +#endif + } + + /* + * Start up serial port + */ + retval = startup(info); + if (retval) { + /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ + return retval; + } + + retval = block_til_ready(tty, filp, info); + if (retval) { + /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ +#ifdef SERIAL_DEBUG_OPEN + baget_printk("rs_open returning after block_til_ready " + "with %d\n", + retval); +#endif + return retval; + } + + if ((info->state->count == 1) && + (info->flags & ASYNC_SPLIT_TERMIOS)) { + if (tty->driver.subtype == SERIAL_TYPE_NORMAL) + *tty->termios = info->state->normal_termios; + else + *tty->termios = info->state->callout_termios; + change_speed(info); + } +#ifdef CONFIG_SERIAL_CONSOLE + if (sercons.cflag && sercons.index == line) { + tty->termios->c_cflag = sercons.cflag; + sercons.cflag = 0; + change_speed(info); + } +#endif + info->session = current->session; + info->pgrp = current->pgrp; + +#ifdef SERIAL_DEBUG_OPEN + baget_printk("rs_open ttys%d successful...", info->line); +#endif + return 0; +} + +/* + * /proc fs routines.... + */ + +static inline int line_info(char *buf, struct serial_state *state) +{ + struct async_struct *info = state->info, scr_info; + int ret; + + ret = sprintf(buf, "%d: uart:%s port:%X irq:%d", + state->line, uart_config[state->type].name, + state->port, state->irq); + + if (!state->port || (state->type == PORT_UNKNOWN)) { + ret += sprintf(buf+ret, "\n"); + return ret; + } + + /* + * Figure out the current RS-232 lines + */ + if (!info) { + info = &scr_info; /* This is just for serial_{in,out} */ + + info->magic = SERIAL_MAGIC; + info->port = state->port; + info->flags = state->flags; + info->quot = 0; + info->tty = 0; + } + + if (info->quot) { + ret += sprintf(buf+ret, " baud:%d", + state->baud_base / info->quot); + } + + ret += sprintf(buf+ret, " tx:%d rx:%d", + state->icount.tx, state->icount.rx); + + if (state->icount.frame) + ret += sprintf(buf+ret, " fe:%d", state->icount.frame); + + if (state->icount.parity) + ret += sprintf(buf+ret, " pe:%d", state->icount.parity); + + if (state->icount.brk) + ret += sprintf(buf+ret, " brk:%d", state->icount.brk); + + if (state->icount.overrun) + ret += sprintf(buf+ret, " oe:%d", state->icount.overrun); + + return ret; +} + +int rs_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + int i, len = 0, l; + off_t begin = 0; + + len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version); + for (i = 0; i < NR_PORTS && len < 4000; i++) { + l = line_info(page + len, &rs_table[i]); + len += l; + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } + } + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (off-begin); + return ((count < begin+len-off) ? count : begin+len-off); +} + +/* + * --------------------------------------------------------------------- + * rs_init() and friends + * + * rs_init() is called at boot-time to initialize the serial driver. + * --------------------------------------------------------------------- + */ + +/* + * This routine prints out the appropriate serial driver version + * number, and identifies which options were configured into this + * driver. + */ +static _INLINE_ void show_serial_version(void) +{ + printk(KERN_INFO "%s version %s with", serial_name, serial_version); +#ifdef CONFIG_SERIAL_SHARE_IRQ + printk(" SHARE_IRQ"); +#endif +#define SERIAL_OPT +#ifdef CONFIG_SERIAL_DETECT_IRQ + printk(" DETECT_IRQ"); +#endif +#ifdef SERIAL_OPT + printk(" enabled\n"); +#else + printk(" no serial options enabled\n"); +#endif +#undef SERIAL_OPT +} + + +/* + * This routine is called by rs_init() to initialize a specific serial + * port. It determines what type of UART chip this serial port is + * using: 8250, 16450, 16550, 16550A. The important question is + * whether or not this UART is a 16550A or not, since this will + * determine whether or not we can use its FIFO features or not. + */ + +/* + * Functionality of this function is reduced: we already know we have a VAC, + * but still need to perform some important actions (see code :-). + */ +static void autoconfig(struct serial_state * state) +{ + struct async_struct *info, scr_info; + unsigned long flags; + + /* Setting up important parameters */ + state->type = VAC_UART_TYPE; + state->xmit_fifo_size = uart_config[state->type].dfl_xmit_fifo_size; + + info = &scr_info; /* This is just for serial_{in,out} */ + + info->magic = SERIAL_MAGIC; + info->port = state->port; + info->flags = state->flags; + + save_flags(flags); cli(); + + /* + Flush VAC input fifo */ + (void)serial_in(info, VAC_UART_RX); + (void)serial_in(info, VAC_UART_RX); + (void)serial_in(info, VAC_UART_RX); + (void)serial_in(info, VAC_UART_RX); + + /* Disable interrupts */ + serial_outp(info, VAC_UART_INT_MASK, 0); + + restore_flags(flags); +} + +int register_serial(struct serial_struct *req); +void unregister_serial(int line); + +EXPORT_SYMBOL(register_serial); +EXPORT_SYMBOL(unregister_serial); + +/* + * Important function for VAC UART check and reanimation. + */ + +static void rs_timer(unsigned long dummy) +{ + static unsigned long last_strobe = 0; + struct async_struct *info; + unsigned int i; + unsigned long flags; + + if ((jiffies - last_strobe) >= RS_STROBE_TIME) { + for (i=1; i < NR_IRQS; i++) { + info = IRQ_ports[i]; + if (!info) + continue; + save_flags(flags); cli(); +#ifdef CONFIG_SERIAL_SHARE_IRQ + if (info->next_port) { + do { + serial_out(info, VAC_UART_INT_MASK, 0); + info->IER |= VAC_UART_INT_TX_EMPTY; + serial_out(info, VAC_UART_INT_MASK, + info->IER); + info = info->next_port; + } while (info); + rs_interrupt(i, NULL, NULL); + } else +#endif /* CONFIG_SERIAL_SHARE_IRQ */ + rs_interrupt_single(i, NULL, NULL); + restore_flags(flags); + } + } + last_strobe = jiffies; + mod_timer(&vacs_timer, jiffies + RS_STROBE_TIME); + + /* + * It looks this code for case we share IRQ with console... + */ + + if (IRQ_ports[0]) { + save_flags(flags); cli(); +#ifdef CONFIG_SERIAL_SHARE_IRQ + rs_interrupt(0, NULL, NULL); +#else + rs_interrupt_single(0, NULL, NULL); +#endif + restore_flags(flags); + + mod_timer(&vacs_timer, jiffies + IRQ_timeout[0] - 2); + } +} + +/* + * The serial driver boot-time initialization code! + */ +int __init rs_init(void) +{ + int i; + struct serial_state * state; + extern void atomwide_serial_init (void); + extern void dualsp_serial_init (void); + +#ifdef CONFIG_ATOMWIDE_SERIAL + atomwide_serial_init (); +#endif +#ifdef CONFIG_DUALSP_SERIAL + dualsp_serial_init (); +#endif + + init_bh(SERIAL_BH, do_serial_bh); + init_timer(&vacs_timer); + vacs_timer.function = rs_timer; + vacs_timer.expires = 0; + + for (i = 0; i < NR_IRQS; i++) { + IRQ_ports[i] = 0; + IRQ_timeout[i] = 0; + } + + +/* + * It is not a good idea to share interrupts with console, + * but it looks we cannot avoid it. + */ +#if 0 + +#ifdef CONFIG_SERIAL_CONSOLE + /* + * The interrupt of the serial console port + * can't be shared. + */ + if (sercons.flags & CON_CONSDEV) { + for(i = 0; i < NR_PORTS; i++) + if (i != sercons.index && + rs_table[i].irq == rs_table[sercons.index].irq) + rs_table[i].irq = 0; + } +#endif + +#endif + show_serial_version(); + + /* Initialize the tty_driver structure */ + + memset(&serial_driver, 0, sizeof(struct tty_driver)); + serial_driver.magic = TTY_DRIVER_MAGIC; + serial_driver.driver_name = "serial"; + serial_driver.name = "ttyS"; + serial_driver.major = TTY_MAJOR; + serial_driver.minor_start = 64; + serial_driver.num = NR_PORTS; + serial_driver.type = TTY_DRIVER_TYPE_SERIAL; + serial_driver.subtype = SERIAL_TYPE_NORMAL; + serial_driver.init_termios = tty_std_termios; + serial_driver.init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + serial_driver.flags = TTY_DRIVER_REAL_RAW; + serial_driver.refcount = &serial_refcount; + serial_driver.table = serial_table; + serial_driver.termios = serial_termios; + serial_driver.termios_locked = serial_termios_locked; + + serial_driver.open = rs_open; + serial_driver.close = rs_close; + serial_driver.write = rs_write; + serial_driver.put_char = rs_put_char; + serial_driver.flush_chars = rs_flush_chars; + serial_driver.write_room = rs_write_room; + serial_driver.chars_in_buffer = rs_chars_in_buffer; + serial_driver.flush_buffer = rs_flush_buffer; + serial_driver.ioctl = rs_ioctl; + serial_driver.throttle = rs_throttle; + serial_driver.unthrottle = rs_unthrottle; + serial_driver.send_xchar = rs_send_xchar; + serial_driver.set_termios = rs_set_termios; + serial_driver.stop = rs_stop; + serial_driver.start = rs_start; + serial_driver.hangup = rs_hangup; + serial_driver.break_ctl = rs_break; + serial_driver.wait_until_sent = rs_wait_until_sent; + serial_driver.read_proc = rs_read_proc; + + /* + * The callout device is just like normal device except for + * major number and the subtype code. + */ + callout_driver = serial_driver; + callout_driver.name = "cua"; + callout_driver.major = TTYAUX_MAJOR; + callout_driver.subtype = SERIAL_TYPE_CALLOUT; + callout_driver.read_proc = 0; + callout_driver.proc_entry = 0; + + if (tty_register_driver(&serial_driver)) + panic("Couldn't register serial driver"); + if (tty_register_driver(&callout_driver)) + panic("Couldn't register callout driver"); + + for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { + state->magic = SSTATE_MAGIC; + state->line = i; + state->type = PORT_UNKNOWN; + state->custom_divisor = 0; + state->close_delay = 5*HZ/10; + state->closing_wait = 30*HZ; + state->callout_termios = callout_driver.init_termios; + state->normal_termios = serial_driver.init_termios; + state->icount.cts = state->icount.dsr = + state->icount.rng = state->icount.dcd = 0; + state->icount.rx = state->icount.tx = 0; + state->icount.frame = state->icount.parity = 0; + state->icount.overrun = state->icount.brk = 0; + state->irq = state->irq; + if (check_region(state->port,8)) + continue; + if (state->flags & ASYNC_BOOT_AUTOCONF) + autoconfig(state); + } + + /* + * Detect the IRQ only once every port is initialised, + * because some 16450 do not reset to 0 the MCR register. + */ + for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { + if (state->type == PORT_UNKNOWN) + continue; + printk(KERN_INFO "ttyS%02d%s at 0x%04x (irq = %d) is a %s\n", + state->line, + (state->flags & ASYNC_FOURPORT) ? " FourPort" : "", + state->port, state->irq, + uart_config[state->type].name); + } + return 0; +} + +/* + * register_serial and unregister_serial allows for serial ports to be + * configured at run-time, to support PCMCIA modems. + */ +int register_serial(struct serial_struct *req) +{ + int i; + unsigned long flags; + struct serial_state *state; + + save_flags(flags); + cli(); + for (i = 0; i < NR_PORTS; i++) { + if (rs_table[i].port == req->port) + break; + } + if (i == NR_PORTS) { + for (i = 0; i < NR_PORTS; i++) + if ((rs_table[i].type == PORT_UNKNOWN) && + (rs_table[i].count == 0)) + break; + } + if (i == NR_PORTS) { + restore_flags(flags); + return -1; + } + state = &rs_table[i]; + if (rs_table[i].count) { + restore_flags(flags); + printk("Couldn't configure serial #%d (port=%d,irq=%d): " + "device already open\n", i, req->port, req->irq); + return -1; + } + state->irq = req->irq; + state->port = req->port; + state->flags = req->flags; + + autoconfig(state); + if (state->type == PORT_UNKNOWN) { + restore_flags(flags); + printk("register_serial(): autoconfig failed\n"); + return -1; + } + restore_flags(flags); + + printk(KERN_INFO "tty%02d at 0x%04x (irq = %d) is a %s\n", + state->line, state->port, state->irq, + uart_config[state->type].name); + return state->line; +} + +void unregister_serial(int line) +{ + unsigned long flags; + struct serial_state *state = &rs_table[line]; + + save_flags(flags); + cli(); + if (state->info && state->info->tty) + tty_hangup(state->info->tty); + state->type = PORT_UNKNOWN; + printk(KERN_INFO "tty%02d unloaded\n", state->line); + restore_flags(flags); +} + +#ifdef MODULE +int init_module(void) +{ + return rs_init(); +} + +void cleanup_module(void) +{ + unsigned long flags; + int e1, e2; + int i; + + printk("Unloading %s: version %s\n", serial_name, serial_version); + save_flags(flags); + cli(); + + del_timer_sync(&vacs_timer); + remove_bh(SERIAL_BH); + + if ((e1 = tty_unregister_driver(&serial_driver))) + printk("SERIAL: failed to unregister serial driver (%d)\n", + e1); + if ((e2 = tty_unregister_driver(&callout_driver))) + printk("SERIAL: failed to unregister callout driver (%d)\n", + e2); + restore_flags(flags); + + for (i = 0; i < NR_PORTS; i++) { + if (rs_table[i].type != PORT_UNKNOWN) + release_region(rs_table[i].port, 8); + } + if (tmp_buf) { + free_page((unsigned long) tmp_buf); + tmp_buf = NULL; + } +} +#endif /* MODULE */ + + +/* + * ------------------------------------------------------------ + * Serial console driver + * ------------------------------------------------------------ + */ +#ifdef CONFIG_SERIAL_CONSOLE + +#define BOTH_EMPTY (VAC_UART_STATUS_TX_EMPTY | VAC_UART_STATUS_TX_EMPTY) + +/* + * Wait for transmitter & holding register to empty + */ +static inline void wait_for_xmitr(struct async_struct *info) +{ + int lsr; + unsigned int tmout = 1000000; + + do { + lsr = serial_inp(info, VAC_UART_INT_STATUS); + if (--tmout == 0) break; + } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY); +} + +/* + * Print a string to the serial port trying not to disturb + * any possible real use of the port... + */ +static void serial_console_write(struct console *co, const char *s, + unsigned count) +{ + struct serial_state *ser; + int ier; + unsigned i; + struct async_struct scr_info; /* serial_{in,out} because HUB6 */ + + ser = rs_table + co->index; + scr_info.magic = SERIAL_MAGIC; + scr_info.port = ser->port; + scr_info.flags = ser->flags; + + /* + * First save the IER then disable the interrupts + */ + ier = serial_inp(&scr_info, VAC_UART_INT_MASK); + serial_outw(&scr_info, VAC_UART_INT_MASK, 0x00); + + /* + * Now, do each character + */ + for (i = 0; i < count; i++, s++) { + wait_for_xmitr(&scr_info); + + /* + * Send the character out. + * If a LF, also do CR... + */ + serial_outp(&scr_info, VAC_UART_TX, (unsigned short)*s << 8); + if (*s == 10) { + wait_for_xmitr(&scr_info); + serial_outp(&scr_info, VAC_UART_TX, 13 << 8); + } + } + + /* + * Finally, Wait for transmitter & holding register to empty + * and restore the IER + */ + wait_for_xmitr(&scr_info); + serial_outp(&scr_info, VAC_UART_INT_MASK, ier); +} + +static kdev_t serial_console_device(struct console *c) +{ + return MKDEV(TTY_MAJOR, 64 + c->index); +} + +/* + * Setup initial baud/bits/parity. We do two things here: + * - construct a cflag setting for the first rs_open() + * - initialize the serial port + * Return non-zero if we didn't find a serial port. + */ +static int __init serial_console_setup(struct console *co, char *options) +{ + struct serial_state *ser; + unsigned cval; + int baud = 9600; + int bits = 8; + int parity = 'n'; + int cflag = CREAD | HUPCL | CLOCAL; + int quot = 0; + char *s; + struct async_struct scr_info; /* serial_{in,out} because HUB6 */ + + if (options) { + baud = simple_strtoul(options, NULL, 10); + s = options; + while(*s >= '0' && *s <= '9') + s++; + if (*s) parity = *s++; + if (*s) bits = *s - '0'; + } + + /* + * Now construct a cflag setting. + */ + switch(baud) { + case 1200: + cflag |= B1200; + break; + case 2400: + cflag |= B2400; + break; + case 4800: + cflag |= B4800; + break; + case 19200: + cflag |= B19200; + break; + case 38400: + cflag |= B38400; + break; + case 57600: + cflag |= B57600; + break; + case 115200: + cflag |= B115200; + break; + case 9600: + default: + cflag |= B9600; + break; + } + switch(bits) { + case 7: + cflag |= CS7; + break; + default: + case 8: + cflag |= CS8; + break; + } + switch(parity) { + case 'o': case 'O': + cflag |= PARODD; + break; + case 'e': case 'E': + cflag |= PARENB; + break; + } + co->cflag = cflag; + + /* + * Divisor, bytesize and parity + */ + ser = rs_table + co->index; + scr_info.magic = SERIAL_MAGIC; + scr_info.port = ser->port; + scr_info.flags = ser->flags; + + quot = ser->baud_base / baud; + cval = cflag & (CSIZE | CSTOPB); + + cval >>= 4; + + cval &= ~VAC_UART_MODE_PARITY_ENABLE; + if (cflag & PARENB) + cval |= VAC_UART_MODE_PARITY_ENABLE; + if (cflag & PARODD) + cval |= VAC_UART_MODE_PARITY_ODD; + + /* + * Disable UART interrupts, set DTR and RTS high + * and set speed. + */ + switch (baud) { + default: + case 9600: + cval |= VAC_UART_MODE_BAUD(7); + break; + case 4800: + cval |= VAC_UART_MODE_BAUD(6); + break; + case 2400: + cval |= VAC_UART_MODE_BAUD(5); + break; + case 1200: + cval |= VAC_UART_MODE_BAUD(4); + break; + case 600: + cval |= VAC_UART_MODE_BAUD(3); + break; + case 300: + cval |= VAC_UART_MODE_BAUD(2); + break; +#ifndef QUAD_UART_SPEED + case 150: +#else + case 38400: +#endif + cval |= VAC_UART_MODE_BAUD(1); + break; +#ifndef QUAD_UART_SPEED + case 75: +#else + case 19200: +#endif + cval |= VAC_UART_MODE_BAUD(0); + break; + } + + /* Baget VAC need some adjustments for computed value */ + cval = vac_uart_mode_fixup(cval); + + serial_outp(&scr_info, VAC_UART_MODE, cval); + serial_outp(&scr_info, VAC_UART_INT_MASK, 0); + + return 0; +} + +static struct console sercons = { + .name = "ttyS", + .write = serial_console_write, + .device = serial_console_device, + .setup = serial_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +/* + * Register console. + */ +long __init serial_console_init(long kmem_start, long kmem_end) +{ + register_console(&sercons); + return kmem_start; +} +#endif + +#ifdef CONFIG_KGDB +#undef PRINT_DEBUG_PORT_INFO + +/* + * This is the interface to the remote debugger stub. + * I've put that here to be able to control the serial + * device more directly. + */ + +static int initialized; + +static int rs_debug_init(struct async_struct *info) +{ + int quot; + + autoconfig(info); /* autoconfigure ttyS0, whatever that is */ + +#ifdef PRINT_DEBUG_PORT_INFO + baget_printk("kgdb debug interface:: tty%02d at 0x%04x", + info->line, info->port); + switch (info->type) { + case PORT_8250: + baget_printk(" is a 8250\n"); + break; + case PORT_16450: + baget_printk(" is a 16450\n"); + break; + case PORT_16550: + baget_printk(" is a 16550\n"); + break; + case PORT_16550A: + baget_printk(" is a 16550A\n"); + break; + case PORT_16650: + baget_printk(" is a 16650\n"); + break; + default: + baget_printk(" is of unknown type -- unusable\n"); + break; + } +#endif + + if (info->port == PORT_UNKNOWN) + return -1; + + /* + * Clear all interrupts + */ + + (void)serial_inp(info, VAC_UART_INT_STATUS); + (void)serial_inp(info, VAC_UART_RX); + + /* + * Now, initialize the UART + */ + serial_outp(info,VAC_UART_MODE,VAC_UART_MODE_INITIAL); /* reset DLAB */ + if (info->flags & ASYNC_FOURPORT) { + info->MCR = UART_MCR_DTR | UART_MCR_RTS; + info->MCR_noint = UART_MCR_DTR | UART_MCR_OUT1; + } else { + info->MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; + info->MCR_noint = UART_MCR_DTR | UART_MCR_RTS; + } + + info->MCR = info->MCR_noint; /* no interrupts, please */ + /* + * and set the speed of the serial port + * (currently hardwired to 9600 8N1 + */ + + quot = info->baud_base / 9600; /* baud rate is fixed to 9600 */ + /* FIXME: if rs_debug interface is needed, we need to set speed here */ + + return 0; +} + +int putDebugChar(char c) +{ + struct async_struct *info = rs_table; + + if (!initialized) { /* need to init device first */ + if (rs_debug_init(info) == 0) + initialized = 1; + else + return 0; + } + + while ((serial_inw(info, VAC_UART_INT_STATUS) & \ + VAC_UART_STATUS_TX_EMPTY) == 0) + ; + serial_out(info, VAC_UART_TX, (unsigned short)c << 8); + + return 1; +} + +char getDebugChar(void) +{ + struct async_struct *info = rs_table; + + if (!initialized) { /* need to init device first */ + if (rs_debug_init(info) == 0) + initialized = 1; + else + return 0; + } + while (!(serial_inw(info, VAC_UART_INT_STATUS) & \ + VAC_UART_STATUS_RX_READY)) + ; + + return(serial_inp(info, VAC_UART_RX)); +} + +#endif /* CONFIG_KGDB */ diff -urN linux-2.4.21-bk37/drivers/hotplug/Config.in linux-2.4.21-bk38/drivers/hotplug/Config.in --- linux-2.4.21-bk37/drivers/hotplug/Config.in 2003-08-24 02:55:51.000000000 -0700 +++ linux-2.4.21-bk38/drivers/hotplug/Config.in 2003-08-24 02:56:03.000000000 -0700 @@ -11,6 +11,7 @@ if [ "$CONFIG_X86_IO_APIC" = "y" ]; then dep_tristate ' IBM PCI Hotplug driver' CONFIG_HOTPLUG_PCI_IBM $CONFIG_HOTPLUG_PCI $CONFIG_X86_IO_APIC $CONFIG_X86 fi -dep_tristate ' ACPI PCI Hotplug driver' CONFIG_HOTPLUG_PCI_ACPI $CONFIG_ACPI_INTERPRETER $CONFIG_HOTPLUG_PCI - +if [ "$CONFIG_ACPI_INTERPRETER" ]; then + dep_tristate ' ACPI PCI Hotplug driver' CONFIG_HOTPLUG_PCI_ACPI $CONFIG_HOTPLUG_PCI +fi endmenu diff -urN linux-2.4.21-bk37/drivers/i2c/Config.in linux-2.4.21-bk38/drivers/i2c/Config.in --- linux-2.4.21-bk37/drivers/i2c/Config.in 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.21-bk38/drivers/i2c/Config.in 2003-08-24 02:56:03.000000000 -0700 @@ -49,6 +49,11 @@ dep_tristate 'Keywest I2C interface in Apple Core99 machines' CONFIG_I2C_KEYWEST $CONFIG_I2C fi + if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then + dep_tristate 'SiByte SMBus interface' CONFIG_I2C_ALGO_SIBYTE $CONFIG_I2C + dep_tristate ' MAX1617 Temperature Sensor' CONFIG_I2C_MAX1617 $CONFIG_I2C_ALGO_SIBYTE + fi + # This is needed for automatic patch generation: sensors code starts here # This is needed for automatic patch generation: sensors code ends here diff -urN linux-2.4.21-bk37/drivers/i2c/Makefile linux-2.4.21-bk38/drivers/i2c/Makefile --- linux-2.4.21-bk37/drivers/i2c/Makefile 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.21-bk38/drivers/i2c/Makefile 2003-08-24 02:56:03.000000000 -0700 @@ -5,7 +5,7 @@ O_TARGET := i2c.o export-objs := i2c-core.o i2c-algo-bit.o i2c-algo-pcf.o \ - i2c-algo-ite.o i2c-proc.o + i2c-algo-ite.o i2c-proc.o i2c-algo-sibyte.o obj-$(CONFIG_I2C) += i2c-core.o obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o @@ -21,6 +21,8 @@ obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o obj-$(CONFIG_SCx200_ACB) += scx200_acb.o obj-$(CONFIG_I2C_KEYWEST) += i2c-keywest.o +obj-$(CONFIG_I2C_ALGO_SIBYTE) += i2c-algo-sibyte.o i2c-sibyte.o +obj-$(CONFIG_I2C_MAX1617) += i2c-max1617.o # This is needed for automatic patch generation: sensors code starts here # This is needed for automatic patch generation: sensors code ends here diff -urN linux-2.4.21-bk37/drivers/i2c/i2c-algo-sibyte.c linux-2.4.21-bk38/drivers/i2c/i2c-algo-sibyte.c --- linux-2.4.21-bk37/drivers/i2c/i2c-algo-sibyte.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/drivers/i2c/i2c-algo-sibyte.c 2003-08-24 02:56:03.000000000 -0700 @@ -0,0 +1,231 @@ +/* ------------------------------------------------------------------------- */ +/* i2c-algo-sibyte.c i2c driver algorithms for bit-shift adapters */ +/* ------------------------------------------------------------------------- */ +/* Copyright (C) 2001,2002,2003 Broadcom Corporation + Copyright (C) 1995-2000 Simon G. Vogl + + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* ------------------------------------------------------------------------- */ + +/* With some changes from Kyösti Mälkki and even + Frodo Looijaard . */ + +/* Ported for SiByte SOCs by Broadcom Corporation. */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +/* ----- global defines ----------------------------------------------- */ +#define SMB_CSR(a,r) ((long)(a->reg_base + r)) + +/* ----- global variables --------------------------------------------- */ + +/* module parameters: + */ +static int bit_scan=0; /* have a look at what's hanging 'round */ + + +static int smbus_xfer(struct i2c_adapter *i2c_adap, u16 addr, + unsigned short flags, char read_write, + u8 command, int size, union i2c_smbus_data * data) +{ + struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data; + int data_bytes = 0; + int error; + + while (csr_in32(SMB_CSR(adap, R_SMB_STATUS)) & M_SMB_BUSY) + ; + + switch (size) { + case I2C_SMBUS_QUICK: + csr_out32((V_SMB_ADDR(addr) | (read_write == I2C_SMBUS_READ ? M_SMB_QDATA : 0) | + V_SMB_TT_QUICKCMD), SMB_CSR(adap, R_SMB_START)); + break; + case I2C_SMBUS_BYTE: + if (read_write == I2C_SMBUS_READ) { + csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_RD1BYTE), + SMB_CSR(adap, R_SMB_START)); + data_bytes = 1; + } else { + csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD)); + csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR1BYTE), + SMB_CSR(adap, R_SMB_START)); + } + break; + case I2C_SMBUS_BYTE_DATA: + csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD)); + if (read_write == I2C_SMBUS_READ) { + csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_CMD_RD1BYTE), + SMB_CSR(adap, R_SMB_START)); + data_bytes = 1; + } else { + csr_out32(V_SMB_LB(data->byte), SMB_CSR(adap, R_SMB_DATA)); + csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR2BYTE), + SMB_CSR(adap, R_SMB_START)); + } + break; + case I2C_SMBUS_WORD_DATA: + csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD)); + if (read_write == I2C_SMBUS_READ) { + csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_CMD_RD2BYTE), + SMB_CSR(adap, R_SMB_START)); + data_bytes = 2; + } else { + csr_out32(V_SMB_LB(data->word & 0xff), SMB_CSR(adap, R_SMB_DATA)); + csr_out32(V_SMB_MB(data->word >> 8), SMB_CSR(adap, R_SMB_DATA)); + csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR2BYTE), + SMB_CSR(adap, R_SMB_START)); + } + break; + default: + return -1; /* XXXKW better error code? */ + } + + while (csr_in32(SMB_CSR(adap, R_SMB_STATUS)) & M_SMB_BUSY) + ; + + error = csr_in32(SMB_CSR(adap, R_SMB_STATUS)); + if (error & M_SMB_ERROR) { + /* Clear error bit by writing a 1 */ + csr_out32(M_SMB_ERROR, SMB_CSR(adap, R_SMB_STATUS)); + return -1; /* XXXKW better error code? */ + } + + if (data_bytes == 1) + data->byte = csr_in32(SMB_CSR(adap, R_SMB_DATA)) & 0xff; + if (data_bytes == 2) + data->word = csr_in32(SMB_CSR(adap, R_SMB_DATA)) & 0xffff; + + return 0; +} + +static int algo_control(struct i2c_adapter *adapter, + unsigned int cmd, unsigned long arg) +{ + return 0; +} + +static u32 bit_func(struct i2c_adapter *adap) +{ + return (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA); +} + + +/* -----exported algorithm data: ------------------------------------- */ + +static struct i2c_algorithm i2c_sibyte_algo = { + "SiByte algorithm", + I2C_ALGO_SIBYTE, + NULL, /* master_xfer */ + smbus_xfer, /* smbus_xfer */ + NULL, /* slave_xmit */ + NULL, /* slave_recv */ + algo_control, /* ioctl */ + bit_func, /* functionality */ +}; + +/* + * registering functions to load algorithms at runtime + */ +int i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed) +{ + int i; + struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data; + + /* register new adapter to i2c module... */ + + i2c_adap->id |= i2c_sibyte_algo.id; + i2c_adap->algo = &i2c_sibyte_algo; + + /* Set the frequency to 100 kHz */ + csr_out32(speed, SMB_CSR(adap,R_SMB_FREQ)); + csr_out32(0, SMB_CSR(adap,R_SMB_CONTROL)); + + /* scan bus */ + if (bit_scan) { + union i2c_smbus_data data; + int rc; + printk(KERN_INFO " i2c-algo-sibyte.o: scanning bus %s.\n", + i2c_adap->name); + for (i = 0x00; i < 0x7f; i++) { + /* XXXKW is this a realistic probe? */ + rc = smbus_xfer(i2c_adap, i, 0, I2C_SMBUS_READ, 0, + I2C_SMBUS_BYTE_DATA, &data); + if (!rc) { + printk("(%02x)",i); + } else + printk("."); + } + printk("\n"); + } + +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif + i2c_add_adapter(i2c_adap); + + return 0; +} + + +int i2c_sibyte_del_bus(struct i2c_adapter *adap) +{ + int res; + + if ((res = i2c_del_adapter(adap)) < 0) + return res; + +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif + return 0; +} + +int __init i2c_algo_sibyte_init (void) +{ + printk("i2c-algo-sibyte.o: i2c SiByte algorithm module\n"); + return 0; +} + + +EXPORT_SYMBOL(i2c_sibyte_add_bus); +EXPORT_SYMBOL(i2c_sibyte_del_bus); + +#ifdef MODULE +MODULE_AUTHOR("Kip Walker, Broadcom Corp."); +MODULE_DESCRIPTION("SiByte I2C-Bus algorithm"); +MODULE_PARM(bit_scan, "i"); +MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus"); +MODULE_LICENSE("GPL"); + +int init_module(void) +{ + return i2c_algo_sibyte_init(); +} + +void cleanup_module(void) +{ +} +#endif diff -urN linux-2.4.21-bk37/drivers/i2c/i2c-core.c linux-2.4.21-bk38/drivers/i2c/i2c-core.c --- linux-2.4.21-bk37/drivers/i2c/i2c-core.c 2003-08-24 02:55:51.000000000 -0700 +++ linux-2.4.21-bk38/drivers/i2c/i2c-core.c 2003-08-24 02:56:03.000000000 -0700 @@ -1311,6 +1311,15 @@ #ifdef CONFIG_I2C_RPXLITE extern int i2c_rpx_init(void); #endif + +#ifdef CONFIG_I2C_ALGO_SIBYTE + extern int i2c_algo_sibyte_init(void); + extern int i2c_sibyte_init(void); +#endif +#ifdef CONFIG_I2C_MAX1617 + extern int i2c_max1617_init(void); +#endif + #ifdef CONFIG_I2C_PROC extern int sensors_init(void); #endif @@ -1356,6 +1365,15 @@ i2c_rpx_init(); #endif + /* --------------------- SiByte -------- */ +#ifdef CONFIG_I2C_ALGO_SIBYTE + i2c_algo_sibyte_init(); + i2c_sibyte_init(); +#endif +#ifdef CONFIG_I2C_MAX1617 + i2c_max1617_init(); +#endif + /* -------------- proc interface ---- */ #ifdef CONFIG_I2C_PROC sensors_init(); diff -urN linux-2.4.21-bk37/drivers/i2c/i2c-max1617.c linux-2.4.21-bk38/drivers/i2c/i2c-max1617.c --- linux-2.4.21-bk37/drivers/i2c/i2c-max1617.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/drivers/i2c/i2c-max1617.c 2003-08-24 02:56:03.000000000 -0700 @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2001,2002,2003 Broadcom Corporation + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * SMBus/I2C device driver for the MAX1617 temperature sensor + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define IF_NAME "max1617" + +#define MAX1617_SMBUS_DEV 0x2A +#define MAX1617_LOCAL 0 +#define MAX1617_REMOTE 1 +#define MAX1617_STATUS 2 +#define MAX1617_POLL_PERIOD 10 + +static int max1617_verbose = 0; +static int max1617_polling = 1; + +/* Addresses to scan */ +static unsigned short normal_i2c[] = {MAX1617_SMBUS_DEV, I2C_CLIENT_END}; +static unsigned short normal_i2c_range[] = {I2C_CLIENT_END}; +static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; + +static struct i2c_client_address_data addr_data = { + normal_i2c, normal_i2c_range, + probe, probe_range, + ignore, ignore_range, + force +}; + +struct max1617_info { + struct i2c_client *client; + struct timer_list timer; + int local; + int remote; +}; + +static int max1617_probe(struct i2c_adapter *adap); +static int max1617_detach(struct i2c_client *device); +static int max1617_command(struct i2c_client *device, unsigned int cmd, void *arg); +static void max1617_inc_use(struct i2c_client *device); +static void max1617_dec_use(struct i2c_client *device); + +struct i2c_driver i2c_driver_max1617 = { + name: IF_NAME, + id: I2C_DRIVERID_MAX1617, + flags: I2C_DF_NOTIFY, + attach_adapter: max1617_probe, + detach_client: max1617_detach, + command: max1617_command, + inc_use: max1617_inc_use, + dec_use: max1617_dec_use +}; +\ +static int max1617_read(struct i2c_client *client, unsigned char subaddr) +{ + return i2c_smbus_read_byte_data(client, subaddr); +} + +/* poll the device, check for temperature/status changes */ +static void max1617_update(unsigned long arg) +{ + struct max1617_info *m = (struct max1617_info *)arg; + int status, remote, local; + char statstr[50]; + + status = max1617_read(m->client, MAX1617_STATUS); + remote = max1617_read(m->client, MAX1617_REMOTE); + local = max1617_read(m->client, MAX1617_LOCAL); + if (status < 0 || remote < 0 || local < 0) { + printk(KERN_ERR IF_NAME ": sensor device did not respond.\n"); + } else { + statstr[0] = 0; + if (status & 0x80) strcat(statstr,"Busy "); + if (status & 0x40) strcat(statstr,"HiTempLcl "); + if (status & 0x20) strcat(statstr,"LoTempLcl "); + if (status & 0x10) strcat(statstr,"HiTempRem "); + if (status & 0x08) strcat(statstr,"LoTempRem "); + if (status & 0x04) strcat(statstr,"Fault "); + + if (max1617_verbose || (local != m->local) || (remote != m->remote)) { + printk(KERN_DEBUG IF_NAME ": Temperature - CPU: %dC Board: %dC Status:%02X [ %s]\n", + remote, local, status, statstr); + } + m->local = local; + m->remote = remote; + mod_timer(&m->timer, jiffies + (HZ * MAX1617_POLL_PERIOD)); + } +} + +/* attach to an instance of the device that was probed on a bus */ +static int max1617_attach(struct i2c_adapter *adap, int addr, unsigned short flags, int kind) +{ + struct max1617_info *m; + struct i2c_client *client; + int err; + + client = kmalloc(sizeof(*client), GFP_KERNEL); + if (client == NULL) + return -ENOMEM; + client->adapter = adap; + client->addr = addr; + client->driver = &i2c_driver_max1617; + sprintf(client->name, "%s-%x", IF_NAME, addr); + if ((err = i2c_attach_client(client)) < 0) { + kfree(client); + return err; + } + + m = kmalloc(sizeof(*m), GFP_KERNEL); + if (m == NULL) { + i2c_detach_client(client); + kfree(client); + return -ENOMEM; + } + m->client = client; + m->remote = m->local = 0; + init_timer(&m->timer); + m->timer.data = (unsigned long)m; + m->timer.function = max1617_update; + if (max1617_polling) { + m->timer.expires = jiffies + (HZ * MAX1617_POLL_PERIOD); + add_timer(&m->timer); + } + client->data = m; + return 0; +} + +/* initiate probing on a particular bus */ +static int max1617_probe(struct i2c_adapter *adap) +{ + /* Look for this device on the given adapter (bus) */ + if (adap->id == (I2C_ALGO_SIBYTE | I2C_HW_SIBYTE)) + return i2c_probe(adap, &addr_data, &max1617_attach); + else + return 0; +} + +static int max1617_detach(struct i2c_client *device) +{ + struct max1617_info *m = (struct max1617_info *)device->data; + int rc = 0; + + if ((rc = i2c_detach_client(device)) != 0) { + printk(IF_NAME "detach failed: %d\n", rc); + } else { + kfree(device); + if (max1617_polling) + del_timer(&m->timer); + kfree(m); + } + return rc; +} + +static int max1617_command(struct i2c_client *device, unsigned int cmd, void *arg) +{ + return 0; +} + +static void max1617_inc_use(struct i2c_client *client) +{ +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif +} + +static void max1617_dec_use(struct i2c_client *client) +{ +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif +} + +void i2c_max1617_init(void) +{ + i2c_add_driver(&i2c_driver_max1617); +} + +EXPORT_NO_SYMBOLS; + +#ifdef MODULE +MODULE_AUTHOR("Kip Walker, Broadcom Corp."); +MODULE_DESCRIPTION("Max 1617 temperature sensor for SiByte SOC boards"); +MODULE_LICENSE("GPL"); + +int init_module(void) +{ + i2c_max1617_init(); + return 0; +} + +void cleanup_module(void) +{ + i2c_del_driver(&i2c_driver_max1617); +} +#endif diff -urN linux-2.4.21-bk37/drivers/i2c/i2c-sibyte.c linux-2.4.21-bk38/drivers/i2c/i2c-sibyte.c --- linux-2.4.21-bk37/drivers/i2c/i2c-sibyte.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/drivers/i2c/i2c-sibyte.c 2003-08-24 02:56:03.000000000 -0700 @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2001,2002,2003 Broadcom Corporation + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +static int sibyte_reg(struct i2c_client *client) +{ + return 0; +} + +static int sibyte_unreg(struct i2c_client *client) +{ + return 0; +} + +static void sibyte_inc_use(struct i2c_adapter *adap) +{ +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif +} + +static void sibyte_dec_use(struct i2c_adapter *adap) +{ +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif +} + +static struct i2c_algo_sibyte_data sibyte_board_data[2] = { + { NULL, 0, (void *)(KSEG1+A_SMB_BASE(0)) }, + { NULL, 1, (void *)(KSEG1+A_SMB_BASE(1)) } +}; + +static struct i2c_adapter sibyte_board_adapter[2] = { + { + name: "SiByte SMBus 0", + id: I2C_HW_SIBYTE, + algo: NULL, + algo_data: &sibyte_board_data[0], + inc_use: sibyte_inc_use, + dec_use: sibyte_dec_use, + client_register: sibyte_reg, + client_unregister: sibyte_unreg, + client_count: 0 + } , + { + name: "SiByte SMBus 1", + id: I2C_HW_SIBYTE, + algo: NULL, + algo_data: &sibyte_board_data[1], + inc_use: sibyte_inc_use, + dec_use: sibyte_dec_use, + client_register: sibyte_reg, + client_unregister: sibyte_unreg, + client_count: 0 + } +}; + +int __init i2c_sibyte_init(void) +{ + printk("i2c-swarm.o: i2c SMBus adapter module for SiByte board\n"); + if (i2c_sibyte_add_bus(&sibyte_board_adapter[0], K_SMB_FREQ_100KHZ) < 0) + return -ENODEV; + if (i2c_sibyte_add_bus(&sibyte_board_adapter[1], K_SMB_FREQ_400KHZ) < 0) + return -ENODEV; + return 0; +} + + +EXPORT_NO_SYMBOLS; + +#ifdef MODULE +MODULE_AUTHOR("Kip Walker, Broadcom Corp."); +MODULE_DESCRIPTION("SMBus adapter routines for SiByte boards"); +MODULE_LICENSE("GPL"); + +int init_module(void) +{ + return i2c_sibyte_init(); +} + +void cleanup_module(void) +{ + i2c_sibyte_del_bus(&sibyte_board_adapter[0]); + i2c_sibyte_del_bus(&sibyte_board_adapter[1]); +} + +#endif diff -urN linux-2.4.21-bk37/drivers/ide/Config.in linux-2.4.21-bk38/drivers/ide/Config.in --- linux-2.4.21-bk37/drivers/ide/Config.in 2003-08-24 02:55:51.000000000 -0700 +++ linux-2.4.21-bk38/drivers/ide/Config.in 2003-08-24 02:56:03.000000000 -0700 @@ -93,7 +93,7 @@ define_bool CONFIG_BLK_DEV_IDEPCI $CONFIG_BLK_DEV_IDEDMA_PMAC fi fi - if [ "$CONFIG_SIBYTE_SWARM" = "y" ]; then + if [ "$CONFIG_SIBYTE_GENBUS_IDE" = "y" ]; then bool ' Broadcom SiByte onboard IDE support' CONFIG_BLK_DEV_IDE_SIBYTE fi if [ "$CONFIG_ARCH_ACORN" = "y" ]; then diff -urN linux-2.4.21-bk37/drivers/ide/Makefile linux-2.4.21-bk38/drivers/ide/Makefile --- linux-2.4.21-bk37/drivers/ide/Makefile 2003-08-24 02:55:51.000000000 -0700 +++ linux-2.4.21-bk38/drivers/ide/Makefile 2003-08-24 02:56:03.000000000 -0700 @@ -48,6 +48,8 @@ obj-$(CONFIG_BLK_DEV_IDE) += ide-core.o +obj-$(CONFIG_BLK_DEV_IDE_SIBYTE) += ide-sibyte.o + ifeq ($(CONFIG_BLK_DEV_IDE),y) obj-y += legacy/idedriver-legacy.o obj-y += ppc/idedriver-ppc.o diff -urN linux-2.4.21-bk37/drivers/ide/ide-cd.c linux-2.4.21-bk38/drivers/ide/ide-cd.c --- linux-2.4.21-bk37/drivers/ide/ide-cd.c 2003-06-13 07:51:33.000000000 -0700 +++ linux-2.4.21-bk38/drivers/ide/ide-cd.c 2003-08-24 02:56:03.000000000 -0700 @@ -765,6 +765,8 @@ if ((stat & ERR_STAT) != 0) cdrom_queue_request_sense(drive, wait, pc->sense, pc); } else if (blk_fs_request(rq)) { + int do_end_request = 0; + /* Handle errors from READ and WRITE requests. */ if (sense_key == NOT_READY) { @@ -773,7 +775,7 @@ /* Fail the request. */ printk ("%s: tray open\n", drive->name); - cdrom_end_request(drive, 0); + do_end_request = 1; } else if (sense_key == UNIT_ATTENTION) { /* Media change. */ cdrom_saw_media_change (drive); @@ -782,28 +784,31 @@ But be sure to give up if we've retried too many times. */ if (++rq->errors > ERROR_MAX) - cdrom_end_request(drive, 0); + do_end_request = 1; } else if (sense_key == ILLEGAL_REQUEST || sense_key == DATA_PROTECT) { /* No point in retrying after an illegal request or data protect error.*/ ide_dump_status (drive, "command error", stat); - cdrom_end_request(drive, 0); + do_end_request = 1; + } else if (sense_key == MEDIUM_ERROR) { + /* No point in re-trying a zillion times on a bad + * sector... If we got here the error is not correctable */ + ide_dump_status (drive, "media error (bad sector)", stat); + do_end_request = 1; } else if ((err & ~ABRT_ERR) != 0) { /* Go to the default handler for other errors. */ *startstop = DRIVER(drive)->error(drive, "cdrom_decode_status", stat); return 1; - } else if (sense_key == MEDIUM_ERROR) { - /* No point in re-trying a zillion times on a bad - * sector... If we got here the error is not correctable */ - ide_dump_status (drive, "media error (bad sector)", stat); - cdrom_end_request(drive, 0); } else if ((++rq->errors > ERROR_MAX)) { /* We've racked up too many retries. Abort. */ - cdrom_end_request(drive, 0); + do_end_request = 1; } + if (do_end_request) + cdrom_end_request(drive, 0); + /* If we got a CHECK_CONDITION status, queue a request sense command. */ if ((stat & ERR_STAT) != 0) diff -urN linux-2.4.21-bk37/drivers/ide/ide-sibyte.c linux-2.4.21-bk38/drivers/ide/ide-sibyte.c --- linux-2.4.21-bk37/drivers/ide/ide-sibyte.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/drivers/ide/ide-sibyte.c 2003-08-24 02:56:03.000000000 -0700 @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2001, 2002, 2003 Broadcom Corporation + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* Derived loosely from ide-pmac.c, so: + * + * Copyright (C) 1998 Paul Mackerras. + * Copyright (C) 1995-1998 Mark Lord + */ +#include +#include + +#include + +#define SIBYTE_IDE_BASE (IO_SPACE_BASE + IDE_PHYS - mips_io_port_base) +#define SIBYTE_IDE_REG(pcaddr) (SIBYTE_IDE_BASE + ((pcaddr) << 5)) + +extern void sibyte_set_ideops(ide_hwif_t *hwif); + +void __init sibyte_ide_probe(void) +{ + int i; + ide_hwif_t *hwif = NULL; + + /* + * Find the first untaken slot in hwifs. Also set the io ops + * to the non-swapping SiByte versions. XXXKW It would be + * nice to find a safe place to do this outside of + * ide-sibyte.c so PCI-IDE would work without the SiByte + * driver. + */ + for (i = 0; i < MAX_HWIFS; i++) { + sibyte_set_ideops(&ide_hwifs[i]); + if (!ide_hwifs[i].io_ports[IDE_DATA_OFFSET] && (hwif == NULL)) { + hwif = &ide_hwifs[i]; + } + } + if (hwif == NULL) { + printk("No space for SiByte onboard IDE driver in ide_hwifs[]. Not enabled.\n"); + return; + } + + /* + * Set up our stuff; we're a little odd because our io_ports + * aren't in the usual place, and byte-swapping isn't + * necessary. + */ + hwif->hw.io_ports[IDE_DATA_OFFSET] = SIBYTE_IDE_REG(0x1f0); + hwif->hw.io_ports[IDE_ERROR_OFFSET] = SIBYTE_IDE_REG(0x1f1); + hwif->hw.io_ports[IDE_NSECTOR_OFFSET] = SIBYTE_IDE_REG(0x1f2); + hwif->hw.io_ports[IDE_SECTOR_OFFSET] = SIBYTE_IDE_REG(0x1f3); + hwif->hw.io_ports[IDE_LCYL_OFFSET] = SIBYTE_IDE_REG(0x1f4); + hwif->hw.io_ports[IDE_HCYL_OFFSET] = SIBYTE_IDE_REG(0x1f5); + hwif->hw.io_ports[IDE_SELECT_OFFSET] = SIBYTE_IDE_REG(0x1f6); + hwif->hw.io_ports[IDE_STATUS_OFFSET] = SIBYTE_IDE_REG(0x1f7); + hwif->hw.io_ports[IDE_CONTROL_OFFSET] = SIBYTE_IDE_REG(0x3f6); + hwif->hw.irq = K_INT_GB_IDE; + hwif->irq = hwif->hw.irq; + hwif->noprobe = 0; + hwif->hw.ack_intr = NULL; + hwif->mmio = 2; + + memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); + printk("SiByte onboard IDE configured as device %i\n", hwif-ide_hwifs); +} diff -urN linux-2.4.21-bk37/drivers/media/video/Config.in linux-2.4.21-bk38/drivers/media/video/Config.in --- linux-2.4.21-bk37/drivers/media/video/Config.in 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.21-bk38/drivers/media/video/Config.in 2003-08-24 02:56:05.000000000 -0700 @@ -24,6 +24,9 @@ dep_tristate ' W9966CF Webcam (FlyCam Supra and others) Video For Linux' CONFIG_VIDEO_W9966 $CONFIG_VIDEO_DEV $CONFIG_PARPORT fi fi +if [ "$CONFIG_SIBYTE_SWARM" = "y" -a "$CONFIG_I2C" != "n" ]; then + dep_tristate ' Philips 7114H decoder (for Swarm)' CONFIG_VIDEO_SWARM_7114H $CONFIG_VIDEO_DEV $CONFIG_I2C_ALGO_SIBYTE +fi dep_tristate ' CPiA Video For Linux' CONFIG_VIDEO_CPIA $CONFIG_VIDEO_DEV if [ "$CONFIG_VIDEO_CPIA" != "n" ]; then if [ "$CONFIG_PARPORT_1284" != "n" ]; then @@ -36,8 +39,8 @@ dep_tristate ' SAA5249 Teletext processor' CONFIG_VIDEO_SAA5249 $CONFIG_VIDEO_DEV $CONFIG_I2C dep_tristate ' SAB3036 tuner' CONFIG_TUNER_3036 $CONFIG_VIDEO_DEV $CONFIG_I2C if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - if [ "$CONFIG_SGI" = "y" ]; then - dep_tristate ' SGI Vino Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_VINO $CONFIG_VIDEO_DEV $CONFIG_SGI + if [ "$CONFIG_SGI_IP22" = "y" ]; then + dep_tristate ' SGI Vino Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_VINO $CONFIG_VIDEO_DEV fi dep_tristate ' Stradis 4:2:2 MPEG-2 video driver (EXPERIMENTAL)' CONFIG_VIDEO_STRADIS $CONFIG_VIDEO_DEV $CONFIG_PCI fi diff -urN linux-2.4.21-bk37/drivers/media/video/Makefile linux-2.4.21-bk38/drivers/media/video/Makefile --- linux-2.4.21-bk37/drivers/media/video/Makefile 2003-06-13 07:51:34.000000000 -0700 +++ linux-2.4.21-bk38/drivers/media/video/Makefile 2003-08-24 02:56:05.000000000 -0700 @@ -57,6 +57,7 @@ obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o obj-$(CONFIG_VIDEO_MEYE) += meye.o +obj-$(CONFIG_VIDEO_SWARM_7114H) += swarm_saa7114h.o obj-$(CONFIG_TUNER_3036) += tuner-3036.o # Extract lists of the multi-part drivers. diff -urN linux-2.4.21-bk37/drivers/media/video/swarm_saa7114h.c linux-2.4.21-bk38/drivers/media/video/swarm_saa7114h.c --- linux-2.4.21-bk37/drivers/media/video/swarm_saa7114h.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/drivers/media/video/swarm_saa7114h.c 2003-08-24 02:56:05.000000000 -0700 @@ -0,0 +1,1695 @@ +/* + saa7114h - Philips SAA7114H video decoder driver + + Copyright (C) 2001,2002,2003 Broadcom Corporation + + From saa7111.c: + Copyright (C) 1998 Dave Perks + From cpia.c: + (C) Copyright 1999-2000 Peter Pregler + (C) Copyright 1999-2000 Scott J. Bertin + (C) Copyright 1999-2000 Johannes Erdfelt + + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Important note: this driver is reasonably functional, and has been + * tested with the "camserv" v4l application. But it primarily a + * proof-of-concept, and example for setting up FIFO-mode. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#define SAA_BRIGHTNESS 0x0a +#define SAA_CONTRAST 0x0b +#define SAA_SATURATION 0x0c +#define SAA_HUE 0x0d + +#define DECODER_STATUS 0x1f +#define SLICER_STATUS_0 0x60 +#define SLICER_STATUS_1 0x61 +#define SLICER_STATUS_2 0x62 +#define SCALER_STATUS 0x8f + +#define NUM_FRAME 2 +#define MAX_HORIZ 720 +#define MAX_VERT 480 +#define MIN_HORIZ 180 +#define MIN_VERT 120 +#define MAX_PER_PIXEL 3 +#define MAX_FRAME_SIZE (MAX_HORIZ*MAX_VERT*MAX_PER_PIXEL) +#define MAX_MMAP_SIZE (PAGE_ALIGN(MAX_FRAME_SIZE*NUM_FRAME)) +#define RAW_PER_PIXEL 2 +#define RAW_LINE_PAD 8 +#define RAW_LINE_SIZE (((MAX_HORIZ*RAW_PER_PIXEL)+RAW_LINE_PAD+0x1f) & ~0x1f) +#define RAW_FRAME_SIZE (RAW_LINE_SIZE*MAX_VERT) + +#define NUM_DESCR 64 +#define INTR_PKT_CNT 8 + +/* Extensions to videodev.h IOCTL definitions */ +#define VIDIOREADREG _IOR('v', 50, int) +#define VIDIOWRITEREG _IOW('v', 50, int) +#define VIDIOGRABFRAME _IOR('v', 51, int) +#define VIDIOSHOWEAV _IOR('v', 52, int) + +#define IF_NAME "saa7114h" + +#define MAC2_CSR(r) (KSEG1 + A_MAC_REGISTER(2, r)) +#define MAC2_DMARX0_CSR(r) (KSEG1 + A_MAC_DMA_REGISTER(2, DMA_RX, 0, r)) + +/* Options */ +#define DMA_DEINTERLACE 1 +#define LAZY_READ 1 +#define NULL_DMA 0 + +/* Debug filters */ +#define DBG_NULL 0x0000 +#define DBG_IO 0x0001 +#define DBG_DESCR 0x0002 +#define DBG_INTR 0x0004 +#define DBG_CONVERT 0x0008 +#define DBG_FRAMING 0x0010 +#define DBG_REGISTER 0x0020 +#define DBG_CALL 0x0040 +#define DBG_FRAMING_LOUD 0x0080 + +/* XXXKW make this settable through /proc... */ +#define DEBUG_LVL (DBG_NULL) + +#if DEBUG_LVL +#define DBG(l, p) do { if (DEBUG_LVL & l) p; } while (0) +#else +#define DBG(l, p) +#endif + +/* ----------------------------------------------------------------------- */ + +enum { + FRAME_READY, /* Ready to grab into */ + FRAME_GRABBING, /* In the process of being grabbed into */ + FRAME_DONE, /* Finished grabbing, but not been synced yet */ + FRAME_UNUSED, /* Unused (belongs to driver, but can't be used) */ +}; + +struct saa_frame { + uint8_t *data; + uint8_t *pos; + int width; + int height; + uint32_t size; + volatile int state; + wait_queue_head_t read_wait; +}; + +typedef struct fifo_descr_s { + uint64_t descr_a; + uint64_t descr_b; +} fifo_descr_t; + +typedef unsigned long paddr_t; + +typedef struct fifo_s { + unsigned ringsz; + fifo_descr_t *descrtab; + fifo_descr_t *descrtab_end; + fifo_descr_t *next_descr; + paddr_t descrtab_phys; + void *dma_buf; /* DMA buffer */ +} fifo_t; + +struct saa7114h { + struct i2c_client *client; + struct video_device *vd; + struct video_window vw; + struct video_picture vp; + uint8_t reg[256]; + + fifo_t ff; + void *frame_buf; /* hold frames for the client */ + struct saa_frame frame[NUM_FRAME]; /* point into frame_buf */ + int hwframe; + int swframe; + + uint16_t depth; + uint16_t palette; + uint8_t bright; + uint8_t contrast; + uint8_t hue; + uint8_t sat; + + struct proc_dir_entry *proc_entry; + struct semaphore param_lock; + struct semaphore busy_lock; + + int dma_enable; + int opened; + int irq; + int interlaced; +}; + +static int saa7114h_probe(struct i2c_adapter *adap); +static int saa7114h_detach(struct i2c_client *device); + +struct i2c_driver i2c_driver_saa7114h = +{ + name: "saa7114h", /* name */ + id: I2C_DRIVERID_SAA7114H, /* ID */ + flags: I2C_DF_NOTIFY, /* XXXKW do I care? */ + attach_adapter: saa7114h_probe, + detach_client: saa7114h_detach +}; + +/* ----------------------------------------------------------------------- + * VM assist for MMAPed space + * ----------------------------------------------------------------------- */ + +/* Given PGD from the address space's page table, return the kernel + * virtual mapping of the physical memory mapped at ADR. + */ +static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr) +{ + unsigned long ret = 0UL; + pmd_t *pmd; + pte_t *ptep, pte; + + if (!pgd_none(*pgd)) { + pmd = pmd_offset(pgd, adr); + if (!pmd_none(*pmd)) { + ptep = pte_offset(pmd, adr); + pte = *ptep; + if (pte_present(pte)) { + ret = (unsigned long) page_address(pte_page(pte)); + ret |= (adr & (PAGE_SIZE-1)); + } + } + } + return ret; +} + +/* Here we want the physical address of the memory. + * This is used when initializing the contents of the + * area and marking the pages as reserved. + */ +static inline unsigned long kvirt_to_pa(unsigned long adr) +{ + unsigned long va, kva, ret; + + va = VMALLOC_VMADDR(adr); + kva = uvirt_to_kva(pgd_offset_k(va), va); + ret = __pa(kva); + return ret; +} + +static void *rvmalloc(unsigned long size) +{ + void *mem; + unsigned long adr, page; + + /* Round it off to PAGE_SIZE */ + size += (PAGE_SIZE - 1); + size &= ~(PAGE_SIZE - 1); + + mem = vmalloc_32(size); + if (!mem) + return NULL; + + memset(mem, 0, size); /* Clear the ram out, no junk to the user */ + adr = (unsigned long) mem; + while (size > 0) { + page = kvirt_to_pa(adr); + mem_map_reserve(virt_to_page(__va(page))); + adr += PAGE_SIZE; + if (size > PAGE_SIZE) + size -= PAGE_SIZE; + else + size = 0; + } + + return mem; +} + +static void rvfree(void *mem, unsigned long size) +{ + unsigned long adr, page; + + if (!mem) + return; + + size += (PAGE_SIZE - 1); + size &= ~(PAGE_SIZE - 1); + + adr = (unsigned long) mem; + while (size > 0) { + page = kvirt_to_pa(adr); + mem_map_unreserve(virt_to_page(__va(page))); + adr += PAGE_SIZE; + if (size > PAGE_SIZE) + size -= PAGE_SIZE; + else + size = 0; + } + vfree(mem); +} + +/* ----------------------------------------------------------------------- + * Control interface (i2c) + * ----------------------------------------------------------------------- */ + +static int saa7114h_reg_read(struct saa7114h *dev, unsigned char subaddr) +{ + return i2c_smbus_read_byte_data(dev->client, subaddr); +} + +static int saa7114h_reg_write(struct saa7114h *dev, unsigned char subaddr, int data) +{ + return i2c_smbus_write_byte_data(dev->client, subaddr, data & 0xff); +} + +static int saa7114h_reg_init(struct saa7114h *dev, unsigned const char *data, unsigned int len) +{ + int rc = 0; + int val; + + while (len && !rc) { + dev->reg[data[0]] = data[1]; + rc = saa7114h_reg_write(dev, data[0], data[1]); + if (!rc && (data[0] != 0)) { + val = saa7114h_reg_read(dev, data[0]); + if ((val < 0) || (val != data[1])) { + printk(KERN_ERR + IF_NAME ": init readback mismatch reg %02x = %02x (should be %02x)\n", + data[0], val, data[1]); + } + } + len -= 2; + data += 2; + } + return rc; +} + +/* ----------------------------------------------------------------------- + * /proc interface + * ----------------------------------------------------------------------- */ + +#ifdef CONFIG_PROC_FS +static struct proc_dir_entry *saa7114h_proc_root=NULL; + +static int decoder_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + char *out = page; + int len, status; + struct saa7114h *decoder = data; + + out += sprintf(out, " SWARM saa7114h\n------------------\n"); + status = saa7114h_reg_read(decoder, DECODER_STATUS); + out += sprintf(out, " Decoder status = %02x\n", status); + if (status & 0x80) + out += sprintf(out, " interlaced\n"); + if (status & 0x40) + out += sprintf(out, " not locked\n"); + if (status & 0x02) + out += sprintf(out, " Macrovision detected\n"); + if (status & 0x01) + out += sprintf(out, " color\n"); + out += sprintf(out, " Brightness = %02x\n", decoder->bright); + out += sprintf(out, " Contrast = %02x\n", decoder->contrast); + out += sprintf(out, " Saturation = %02x\n", decoder->sat); + out += sprintf(out, " Hue = %02x\n\n", decoder->hue); + + out += sprintf(out, " Scaler status = %02x\n", + (int)saa7114h_reg_read(decoder, SCALER_STATUS)); + + len = out - page; + len -= off; + if (len < count) { + *eof = 1; + if (len <= 0) return 0; + } else + len = count; + + *start = page + off; + return len; +} + +static int decoder_write_proc(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct saa7114h *d = data; + int retval; + unsigned int cmd, reg, reg_val; + + if (down_interruptible(&d->param_lock)) + return -ERESTARTSYS; + +#define VALUE \ + ({ \ + char *_p; \ + unsigned long int _ret; \ + while (count && isspace(*buffer)) { \ + buffer++; \ + count--; \ + } \ + _ret = simple_strtoul(buffer, &_p, 16); \ + if (_p == buffer) \ + retval = -EINVAL; \ + else { \ + count -= _p - buffer; \ + buffer = _p; \ + } \ + _ret; \ + }) + + retval = 0; + while (count && !retval) { + cmd = VALUE; + if (retval) + break; + switch (cmd) { + case 1: + reg = VALUE; + if (retval) + break; + reg_val = VALUE; + if (retval) + break; + printk(IF_NAME ": write reg %x <- %x\n", reg, reg_val); + if (saa7114h_reg_write(d, reg, reg_val) == -1) + retval = -EINVAL; + break; + case 2: + reg = VALUE; + if (retval) + break; + reg_val = saa7114h_reg_read(d, reg); + if (reg_val == -1) + retval = -EINVAL; + else + printk(IF_NAME ": read reg %x -> %x\n", reg, reg_val); + break; + default: + break; + } + } + up(&d->param_lock); + + return retval; +} + +static void create_proc_decoder(struct saa7114h *decoder) +{ + char name[8]; + struct proc_dir_entry *ent; + + if (!saa7114h_proc_root || !decoder) + return; + + sprintf(name, "video%d", decoder->vd->minor); + + ent = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, saa7114h_proc_root); + if (!ent) { + printk(KERN_INFO IF_NAME ": Unable to initialize /proc/saa7114h/%s\n", name); + return; + } + + ent->data = decoder; + ent->read_proc = decoder_read_proc; + ent->write_proc = decoder_write_proc; + ent->size = 3626; /* XXXKW ??? */ + decoder->proc_entry = ent; +} + +static void destroy_proc_decoder(struct saa7114h *decoder) +{ + char name[7]; + + if (!decoder || !decoder->proc_entry) + return; + + sprintf(name, "video%d", decoder->vd->minor); + remove_proc_entry(name, saa7114h_proc_root); + decoder->proc_entry = NULL; +} + +static void proc_saa7114h_create(void) +{ + saa7114h_proc_root = create_proc_entry("saa7114h", S_IFDIR, 0); + + if (saa7114h_proc_root) + saa7114h_proc_root->owner = THIS_MODULE; + else + printk(KERN_INFO IF_NAME ": Unable to initialize /proc/saa7114h\n"); +} + +static void proc_saa7114h_destroy(void) +{ + remove_proc_entry("saa7114h", 0); +} +#endif /* CONFIG_PROC_FS */ + + +/* ----------------------------------------------------------------------- + * Initialization + * ----------------------------------------------------------------------- */ + +static int dma_setup(struct saa7114h *d) +{ + int i; + void *curbuf; + + /* Reset the port */ + out64(M_MAC_PORT_RESET, MAC2_CSR(R_MAC_ENABLE)); + in64(MAC2_CSR(R_MAC_ENABLE)); + + /* Zero everything out, disable filters */ + out64(0, MAC2_CSR(R_MAC_TXD_CTL)); + out64(M_MAC_ALLPKT_EN, MAC2_CSR(R_MAC_ADFILTER_CFG)); + out64(V_MAC_RX_RD_THRSH(4) | V_MAC_RX_RL_THRSH(4), + MAC2_CSR(R_MAC_THRSH_CFG)); + for (i=0; iff.descrtab = kmalloc(NUM_DESCR * sizeof(fifo_descr_t), GFP_KERNEL); + d->ff.descrtab_phys = __pa(d->ff.descrtab); + d->ff.descrtab_end = d->ff.descrtab + NUM_DESCR; + d->ff.next_descr = d->ff.descrtab; + d->ff.ringsz = NUM_DESCR; +#if 0 + /* XXXKW this won't work because the physical may not be + contiguous; how do I handle a bigger alloc then? */ + d->ff.dma_buf = rvmalloc(RAW_LINE_SIZE*NUM_DESCR); + printk(KERN_DEBUG IF_NAME ": DMA buffer allocated (%p)\n", + d->ff.dma_buf); +#else + d->ff.dma_buf = kmalloc(RAW_LINE_SIZE*NUM_DESCR, GFP_KERNEL); +#endif + if (!d->ff.dma_buf) { + printk(KERN_ERR IF_NAME ": couldn't allocate DMA buffer\n"); + return -ENOMEM; + } + memset(d->ff.dma_buf, 0, RAW_LINE_SIZE*NUM_DESCR); + + for (i=0, curbuf=d->ff.dma_buf; iff.ringsz; i++, curbuf+=RAW_LINE_SIZE) { + d->ff.descrtab[i].descr_a = (__pa(curbuf) | + V_DMA_DSCRA_A_SIZE(RAW_LINE_SIZE >> 5)); + d->ff.descrtab[i].descr_b = 0; + } + + out64(V_DMA_INT_PKTCNT(INTR_PKT_CNT) | M_DMA_EOP_INT_EN | + V_DMA_RINGSZ(d->ff.ringsz) | M_DMA_TDX_EN, + MAC2_DMARX0_CSR(R_MAC_DMA_CONFIG0)); + out64(M_DMA_L2CA, MAC2_DMARX0_CSR(R_MAC_DMA_CONFIG1)); + out64(d->ff.descrtab_phys, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_BASE)); + + /* Enable interrupts and DMA */ + out64(M_MAC_INT_EOP_COUNT<0xffffff)?0xff0000:(((x)<=0xffff)?0:(x)&0xff0000))>>16) + +static void yuvconvert_inplace(uint8_t *data, uint32_t in_uyvy, int out_fmt, int mmap) +{ + int y, u, v, r, g, b, y1; + uint8_t *src, *dst; + + if (out_fmt == VIDEO_PALETTE_RGB24) { + src = (uint8_t *)((int)data + in_uyvy); + dst = (uint8_t *)((int)data + in_uyvy + (in_uyvy >> 1)); + DBG(DBG_CONVERT, printk(KERN_DEBUG "inplace: %p %p %p\n", data, src, dst)); + while (src > data) { + if ((int)(src-data) < 4) + break; + //printk("freaky %p %p\n", src, data); + y1 = (*(--src) - 16) * 76310; + v = *(--src) - 128; + y = (*(--src) - 16) * 76310; + u = *(--src) - 128; + r = 104635 * v; + g = -25690 * u + -53294 * v; + b = 132278 * u; + /* XXXKW what on earth is up with mmap? */ + if (mmap) { + *(--dst) = LIMIT(r+y1); + *(--dst) = LIMIT(g+y1); + *(--dst) = LIMIT(b+y1); + *(--dst) = LIMIT(r+y); + *(--dst) = LIMIT(g+y); + *(--dst) = LIMIT(b+y); + } else { + *(--dst) = LIMIT(b+y1); + *(--dst) = LIMIT(g+y1); + *(--dst) = LIMIT(r+y1); + *(--dst) = LIMIT(b+y); + *(--dst) = LIMIT(g+y); + *(--dst) = LIMIT(r+y); + } + } + } +} + +static int saa7114h_get_cparams(struct saa7114h *decoder) +{ + /* XXX check for error code */ + decoder->bright = saa7114h_reg_read(decoder, SAA_BRIGHTNESS); + decoder->contrast = saa7114h_reg_read(decoder, SAA_CONTRAST); + decoder->sat = saa7114h_reg_read(decoder, SAA_SATURATION); + decoder->hue = saa7114h_reg_read(decoder, SAA_HUE); + + decoder->vp.brightness = (uint16_t)decoder->bright << 8; + decoder->vp.contrast = (uint16_t)decoder->contrast << 9; + decoder->vp.colour = decoder->sat << 9; + decoder->vp.hue = ((int16_t)decoder->hue + 128) << 8; + return 0; +} + +static int saa7114h_set_cparams(struct saa7114h *decoder) +{ + decoder->bright = decoder->vp.brightness >> 8; + decoder->contrast = decoder->vp.contrast >> 9; + decoder->sat = decoder->vp.colour >> 9; + decoder->hue = (uint8_t)((int8_t)(decoder->vp.hue >> 8) - 128); + + return (saa7114h_reg_write(decoder, SAA_BRIGHTNESS, decoder->bright) || + saa7114h_reg_write(decoder, SAA_CONTRAST, decoder->contrast) || + saa7114h_reg_write(decoder, SAA_SATURATION, decoder->sat) || + saa7114h_reg_write(decoder, SAA_HUE, decoder->hue)); +} + +/* ----------------------------------------------------------------------- + * Custom IOCTL support + * ----------------------------------------------------------------------- */ + +unsigned char eav[625][2]; +static int grab_frame(struct saa7114h *d, void *user_buf, int print_eav) +{ + int cur_idx = 0; + int to_go = 625; + int delta; + int i, len, eav_val, sav_val; + int started = 0; + uint8_t *buf; + fifo_descr_t *cur_d; + int swptr = d->ff.next_descr - d->ff.descrtab; + int hwptr; + + DBG(DBG_CALL, printk(IF_NAME ": grabbing frame\n")); + + /* Check for Macrovision -- if it's on, DMA won't happen */ + if (saa7114h_reg_read(d, DECODER_STATUS) & 0x2) + return -EACCES; + + out64(d->ff.ringsz, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + do { + hwptr = (unsigned) (((in64(MAC2_DMARX0_CSR(R_MAC_DMA_CUR_DSCRADDR)) & + M_DMA_CURDSCR_ADDR) - + d->ff.descrtab_phys) / + sizeof(fifo_descr_t)); + delta = (hwptr + d->ff.ringsz - swptr) % d->ff.ringsz; + + if (delta == 0) { +#if 0 + uint64_t val = in64(MAC2_DMARX0_CSR(R_MAC_STATUS)); + printk("mac status: %08x%08x\n", + (u32)(val >> 32), (u32)(val&0xffffffff)); +#endif + } + + for (i=0; iff.next_descr; + if (++d->ff.next_descr == d->ff.descrtab_end) + d->ff.next_descr = d->ff.descrtab; + + if (!(cur_d->descr_a & M_DMA_ETHRX_SOP)) { + printk("bogus RX\n"); + continue; + } + cur_d->descr_a &= ~M_DMA_ETHRX_SOP; + len = G_DMA_DSCRB_PKT_SIZE(cur_d->descr_b); + buf = (uint8_t *)__va(cur_d->descr_a & M_DMA_DSCRA_A_ADDR); + if (len != (d->vw.width*RAW_PER_PIXEL)+RAW_LINE_PAD) { + printk("funny size %d\n", len); + continue; + } + eav_val = buf[1]; + sav_val = buf[5]; + if (eav_val == 0xf1) { /* end of field 2, V-blank */ + if (started) { + started = 0; + delta = to_go = 0; + /* just let DMA finish in background */ + } else { + started = 1; + } + } + if (started) { + eav[cur_idx][0] = eav_val; + eav[cur_idx++][1] = sav_val; + if (copy_to_user(user_buf, &buf[6], 1440)) + return -EFAULT; + user_buf += 1440; + } + } + swptr = hwptr; + if (delta) { + if (started) + to_go -= delta; + if (delta > to_go) + delta = to_go; + out64(delta, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + } + } while (to_go); + + if (print_eav) { + for (i=0; iff.next_descr - d->ff.descrtab; + int hwptr; + + status_val = in64(MAC2_CSR(R_MAC_STATUS)); + + /* Process finished decsriptors */ + hwptr = (unsigned) (((in64(MAC2_DMARX0_CSR(R_MAC_DMA_CUR_DSCRADDR)) & + M_DMA_CURDSCR_ADDR) - d->ff.descrtab_phys) / + sizeof(fifo_descr_t)); + delta = (hwptr + d->ff.ringsz - swptr) % d->ff.ringsz; + if (!delta) { + if (status_val & M_MAC_INT_EOP_SEEN<ff.ringsz; + } else { + /* XXXKW why would this happen? */ + return; + } + } + + for (i=0; iff.next_descr; + if (++d->ff.next_descr == d->ff.descrtab_end) + d->ff.next_descr = d->ff.descrtab; + + if (!(cur_d->descr_a & M_DMA_ETHRX_SOP)) { + printk(KERN_DEBUG "bogus RX\n"); + continue; + } + cur_d->descr_a &= ~M_DMA_ETHRX_SOP; + if (!d->dma_enable) + continue; + + len = G_DMA_DSCRB_PKT_SIZE(cur_d->descr_b); + buf = (uint8_t *)__va(cur_d->descr_a & M_DMA_DSCRA_A_ADDR); + if (len != (d->vw.width*RAW_PER_PIXEL)+RAW_LINE_PAD) { + printk(KERN_DEBUG "funny size %d\n", len); +// continue; + } + len -= RAW_LINE_PAD; + eav_val = buf[1]; + DBG(DBG_FRAMING_LOUD, + printk(KERN_DEBUG "eav: %02x len: %d\n", eav_val, len)); + if (eav_val == 0xf1) { /* end of field 2, V-blank: start-of-frame */ + switch (d->frame[d->hwframe].state) { + case FRAME_UNUSED: + DBG(DBG_FRAMING, + printk(KERN_ERR "capture to unused frame %d\n", + d->hwframe)); + break; + case FRAME_READY: + DBG(DBG_FRAMING, + printk(KERN_DEBUG "frame started %d\n", + d->hwframe)); + /* start this frame (skip eav/sav) */ + memcpy(d->frame[d->hwframe].pos, &buf[6], len); +#if DMA_DEINTERLACE + if (!d->interlaced) + memcpy(d->frame[d->hwframe].pos-len, &buf[6], len); + d->frame[d->hwframe].pos += len*2; +#else + d->frame[d->hwframe].pos += len; +#endif + d->frame[d->hwframe].state = FRAME_GRABBING; + /* XXXKW check pos overflow */ + break; + case FRAME_GRABBING: + /* kick over to new frame */ + d->frame[d->hwframe].size = d->frame[d->hwframe].pos - + d->frame[d->hwframe].data; + d->frame[d->hwframe].state = FRAME_DONE; + DBG(DBG_FRAMING, + printk(KERN_DEBUG "frame finished %d\n", + d->frame[d->hwframe].size)); + /* wake up a waiting reader */ + DBG(DBG_IO, printk(KERN_DEBUG "wakeup\n")); + wake_up(&d->frame[d->hwframe].read_wait); + d->hwframe = (d->hwframe + 1) % NUM_FRAME; + if (d->frame[d->hwframe].state == FRAME_READY) { + /* start this frame */ + DBG(DBG_FRAMING, + printk(KERN_DEBUG "frame bumped %d\n", + d->hwframe)); + memcpy(d->frame[d->hwframe].pos, &buf[6], len); +#if DMA_DEINTERLACE + if (!d->interlaced) + memcpy(d->frame[d->hwframe].pos-len, &buf[6], len); + d->frame[d->hwframe].pos += len*2; +#else + d->frame[d->hwframe].pos += len; +#endif + d->frame[d->hwframe].state = FRAME_GRABBING; + } else { + /* drop on the floor, + note that we've stopped DMA'ing */ + DBG(DBG_FRAMING, + printk(KERN_DEBUG "frame capture halted\n")); + d->dma_enable = 0; + } + break; + case FRAME_DONE: + /* drop on the floor (must be waiting for sw) */ + DBG(DBG_FRAMING, + printk(KERN_DEBUG "frame capture halted\n")); + d->dma_enable = 0; + break; + } + } else { + switch (d->frame[d->hwframe].state) { + case FRAME_UNUSED: + DBG(DBG_FRAMING, + printk(KERN_ERR "capture to unused frame %d\n", + d->hwframe)); + break; + case FRAME_READY: + /* drop on the floor (must have dropped something) */ + DBG(DBG_FRAMING_LOUD, + printk(KERN_DEBUG "missed SOF\n")); + break; + case FRAME_DONE: + /* drop on the floor (must be waiting for sw) */ + DBG(DBG_FRAMING, + printk(KERN_DEBUG "frame overflow\n")); + d->dma_enable = 0; + break; + case FRAME_GRABBING: +#if DMA_DEINTERLACE + if (eav_val == 0xb6) { + d->frame[d->hwframe].pos = d->frame[d->hwframe].data; + } + memcpy(d->frame[d->hwframe].pos, &buf[6], len); + if (!d->interlaced) + memcpy(d->frame[d->hwframe].pos-len, &buf[6], len); + d->frame[d->hwframe].pos += len*2; +#else + memcpy(d->frame[d->hwframe].pos, &buf[6], len); + d->frame[d->hwframe].pos += len; +#endif + /* XXXKW check pos overflow */ + break; + } + } + } + + if (d->dma_enable) { + out64(delta, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + DBG(DBG_DESCR, + printk(KERN_DEBUG IF_NAME ": interrupt adds %d -> %d descrs\n", + delta, (int)in64(MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)))); + } +} + +/* ----------------------------------------------------------------------- + * /dev/video interface + * ----------------------------------------------------------------------- */ + +static int saa7114h_open(struct video_device *vd, int nb) +{ + struct saa7114h *d = vd->priv; + uint32_t status; + + if (!d || d->opened) + return -EBUSY; + + d->opened = 1; + DBG(DBG_CALL, printk(KERN_DEBUG IF_NAME ": open\n")); + + /* XXKW Should check this periodically!? */ + status = saa7114h_reg_read(d, DECODER_STATUS); + d->interlaced = ((status & 0x80) != 0); + +#if !NULL_DMA + if (d->dma_enable) { + printk(IF_NAME ": open found DMA on?!\n"); +#if LAZY_READ + } +#else + } else { + int descr; + d->dma_enable = 1; + DBG(DBG_DESCR, printk(IF_NAME ": open enabling DMA\n")); + /* Force capture to start into frame buffer 0 */ + descr = in64(MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + DBG(DBG_DESCR, + printk(IF_NAME ": open adds %d -> %d descrs\n", + d->ff.ringsz-desc, descr)); + out64(d->ff.ringsz-descr, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + } +#endif +#endif + + return 0; +} + +static void saa7114h_release(struct video_device *vd) +{ + struct saa7114h *d = vd->priv; + + DBG(DBG_CALL, printk(KERN_DEBUG IF_NAME ": release\n")); + d->opened = 0; + d->dma_enable = 0; + + /* XXXKW do a clean drain of outstanding DMAs? toss leftover + buffer contents to avoid stale pictures? */ + + return; +} + +static long saa7114h_read(struct video_device *vd, char *buf, + unsigned long count, int noblock) +{ + struct saa7114h *d = vd->priv; + int descr, status; + + if (!d) + return -ENODEV; + + /* XXKW Should check this periodically!? */ + status = saa7114h_reg_read(d, DECODER_STATUS); +// d->interlaced = ((status & 0x80) != 0); + +#if !NULL_DMA +#if LAZY_READ + if (!d->dma_enable) { + DBG(DBG_DESCR, printk(KERN_DEBUG IF_NAME ": enabling DMA\n")); + /* Give the buffer to the DMA engine (force ptr reset) */ + d->swframe = d->hwframe; + d->frame[d->swframe].state = FRAME_READY; +#if DMA_DEINTERLACE + d->frame[d->swframe].pos = d->frame[d->swframe].data+d->vw.width*RAW_PER_PIXEL; +#else + d->frame[d->swframe].pos = d->frame[d->swframe].data; +#endif + /* Fire up the DMA engine again if it stopped */ + d->dma_enable = 1; + descr = in64(MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + out64(d->ff.ringsz-descr, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + } +#endif +#endif + + /* XXXKW mmap/read mixture could break the swframe sequence */ + + if (d->frame[d->swframe].state != FRAME_DONE) { + if (noblock) + return -EAGAIN; + else { + DBG(DBG_IO, + printk(KERN_DEBUG IF_NAME ": sleeping for frame\n")); + interruptible_sleep_on(&d->frame[d->swframe].read_wait); + DBG(DBG_IO, + printk(KERN_DEBUG IF_NAME ": awakened\n")); + if (signal_pending(current)) + return -ERESTARTSYS; + } + } + + if (count < d->frame[d->swframe].size) + return -EFAULT; + + count = d->frame[d->swframe].size; + yuvconvert_inplace(d->frame[d->swframe].data, d->frame[d->swframe].size, d->vp.palette, 0); + copy_to_user(buf, d->frame[d->swframe].data, d->frame[d->swframe].size); + d->swframe = (d->swframe + 1) % NUM_FRAME; + /* XXXKW doesn't do format conversion!!! */ +#if !NULL_DMA +#if !LAZY_READ + /* XXXKW Fire up the DMA engine again if it stopped ??? */ + if (!d->dma_enable) { + DBG(DBG_DESCR, printk(KERN_DEBUG IF_NAME ": enabling DMA\n")); + /* Fire up the DMA engine again if it stopped */ + d->dma_enable = 1; + descr = in64(MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + out64(d->ff.ringsz-descr, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + } +#endif +#endif + + return count; +} + +static int saa7114h_ioctl(struct video_device *vd, unsigned int cmd, void *arg) +{ + struct saa7114h *d = vd->priv; + int val, reg, retval = 0; + + if (!d) + return -ENODEV; + + switch (cmd) { + case VIDIOCGCHAN: + { + struct video_channel v; + + if (copy_from_user(&v, arg, sizeof(v))) { + retval = -EFAULT; + break; + } + if (v.channel != 0) { + retval = -EINVAL; + break; + } + + v.channel = 0; + strcpy(v.name, "Camera"); + v.tuners = 0; + v.flags = 0; + v.type = VIDEO_TYPE_CAMERA; + v.norm = 0; + + if (copy_to_user(arg, &v, sizeof(v))) + retval = -EFAULT; + break; + } + + case VIDIOCSCHAN: + { + int v; + + if (copy_from_user(&v, arg, sizeof(v))) + retval = -EFAULT; + + if (retval == 0 && v != 0) + retval = -EINVAL; + + break; + } + + case VIDIOCGCAP: + { + struct video_capability b; + + strcpy(b.name, "Philips SAA7114H Decoder"); + b.type = VID_TYPE_CAPTURE /* | VID_TYPE_TELETEXT */ | VID_TYPE_SCALES; + b.channels = 1; + b.audios = 0; + b.maxwidth = MAX_HORIZ; + b.maxheight = MAX_VERT; + /* XXXKW find real values */ + b.minwidth = 48; + b.minheight = 48; + + if (copy_to_user(arg, &b, sizeof(b))) + retval = -EFAULT; + + break; + } + + /* image properties */ + case VIDIOCGPICT: + if (copy_to_user(arg, &d->vp, sizeof(struct video_picture))) + retval = -EFAULT; + break; + + case VIDIOCSPICT: + { + struct video_picture vp; + + /* copy_from_user */ + if (copy_from_user(&vp, arg, sizeof(vp))) { + retval = -EFAULT; + break; + } + + down(&d->param_lock); + /* brightness, colour, contrast need not check 0-65535 */ + memcpy( &d->vp, &vp, sizeof(vp) ); + /* update cam->params.colourParams */ + saa7114h_set_cparams(d); + up(&d->param_lock); + break; + } + + /* get/set capture window */ + case VIDIOCGWIN: + if (copy_to_user(arg, &d->vw, sizeof(struct video_window))) + retval = -EFAULT; + break; + + case VIDIOCSWIN: + { + /* copy_from_user, check validity, copy to internal structure */ + struct video_window vw; + if (copy_from_user(&vw, arg, sizeof(vw))) { + retval = -EFAULT; + break; + } + + if (vw.clipcount != 0) { /* clipping not supported */ + retval = -EINVAL; + break; + } + if (vw.clips != NULL) { /* clipping not supported */ + retval = -EINVAL; + break; + } + if ((vw.width > MAX_HORIZ || vw.width < MIN_HORIZ) || + (vw.height > MAX_VERT || vw.height < MIN_VERT)) { + retval = -EINVAL; + break; + } + + /* we set the video window to something smaller or equal to what + * is requested by the user??? + */ + down(&d->param_lock); + if (vw.width != d->vw.width || vw.height != d->vw.height) { + uint32_t scale_factor; + /* XXXKW base percentage on input stream, not MAX? */ + + /* Assert scaler reset */ + saa7114h_reg_write(d, 0x88, 0x98); + + /* Vertical scaling */ + scale_factor = (MAX_VERT*1024) / vw.height; + saa7114h_reg_write(d, 0x9e, vw.height & 0xff); + saa7114h_reg_write(d, 0x9f, (vw.height >> 8) & 0xf); + saa7114h_reg_write(d, 0xb0, scale_factor & 0xff); + saa7114h_reg_write(d, 0xb1, (scale_factor >> 8) & 0xff); + saa7114h_reg_write(d, 0xb2, scale_factor & 0xff); + saa7114h_reg_write(d, 0xb3, (scale_factor >> 8) & 0xff); + /* Horizontal scaling */ + scale_factor = (MAX_HORIZ*1024) / vw.width; + saa7114h_reg_write(d, 0x9c, vw.width & 0xff); + saa7114h_reg_write(d, 0x9d, (vw.width >> 8) & 0xf); + saa7114h_reg_write(d, 0xa8, scale_factor & 0xff); + saa7114h_reg_write(d, 0xa9, (scale_factor >> 8) & 0xff); + saa7114h_reg_write(d, 0xac, (scale_factor >> 1) & 0xff); + saa7114h_reg_write(d, 0xad, (scale_factor >> 9) & 0xff); +#if 0 + /* prescaler + saa7114h_reg_write(d, 0xa0, 2); + saa7114h_reg_write(d, 0xa1, 1); + saa7114h_reg_write(d, 0xa2, 1); + */ +#endif + + /* Release scaler reset */ + saa7114h_reg_write(d, 0x88, 0xb8); + d->vw.width = vw.width; + d->vw.height = vw.height; + } + up(&d->param_lock); + break; + } + + /* mmap interface */ + case VIDIOCGMBUF: + { + struct video_mbuf vm; + int i; + + memset(&vm, 0, sizeof(vm)); + vm.size = MAX_FRAME_SIZE*NUM_FRAME; + vm.frames = NUM_FRAME; + for (i = 0; i < NUM_FRAME; i++) + vm.offsets[i] = MAX_FRAME_SIZE * i; + + if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm))) + retval = -EFAULT; + + break; + } + + case VIDIOCMCAPTURE: + { + struct video_mmap vm; + int descr, status; + + if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm))) { + retval = -EFAULT; + break; + } + if (vm.frame<0||vm.frame>NUM_FRAME) { + retval = -EINVAL; + break; + } + + DBG(DBG_CALL, + printk(KERN_DEBUG IF_NAME ":ioctl MCAPTURE %d\n", vm.frame)); + + d->vp.palette = vm.format; + /* XXXKW set depth? */ + /* XXXKW match/update for vm.width, vm.height */ + + /* XXKW Should check this periodically!? */ + status = saa7114h_reg_read(d, DECODER_STATUS); +// d->interlaced = ((status & 0x80) != 0); + + /* Give the buffer to the DMA engine */ + /* XXXKW vm.frame vs d->swframe!! mmap/read mismatch */ +#if DMA_DEINTERLACE + d->frame[vm.frame].pos = d->frame[vm.frame].data + d->vw.width*RAW_PER_PIXEL; +#else + d->frame[vm.frame].pos = d->frame[vm.frame].data; +#endif +#if !NULL_DMA + d->frame[vm.frame].state = FRAME_READY; + /* Fire up the DMA engine again if it stopped */ + if (!d->dma_enable) { + d->dma_enable = 1; + d->hwframe = d->swframe = vm.frame; + descr = in64(MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + DBG(DBG_DESCR, + printk(KERN_DEBUG IF_NAME ": capture adds %d -> %d descrs\n", + d->ff.ringsz-descr, descr)); + out64(d->ff.ringsz-descr, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT)); + } +#endif + break; + } + + case VIDIOCSYNC: + { + int frame; + + if (copy_from_user((void *)&frame, arg, sizeof(int))) { + retval = -EFAULT; + break; + } + + if (frame<0 || frame >= NUM_FRAME) { + retval = -EINVAL; + break; + } + + DBG(DBG_CALL, printk(KERN_DEBUG IF_NAME ":ioctl CSYNC %d\n", frame)); + + switch (d->frame[frame].state) { + case FRAME_UNUSED: + DBG(DBG_IO, + printk(KERN_ERR IF_NAME ":sync to unused frame %d\n", frame)); + retval = -EINVAL; + break; + + case FRAME_READY: + case FRAME_GRABBING: + DBG(DBG_IO, + printk(KERN_DEBUG IF_NAME ": sleeping for frame %d\n", frame)); + interruptible_sleep_on(&d->frame[frame].read_wait); + DBG(DBG_IO, + printk(KERN_DEBUG IF_NAME ": awakened\n")); + if (signal_pending(current)) + return -ERESTARTSYS; + case FRAME_DONE: +#if !NULL_DMA + yuvconvert_inplace(d->frame[frame].data, + d->frame[frame].size, + d->vp.palette, 1); + d->frame[frame].state = FRAME_UNUSED; +#endif + DBG(DBG_IO, + printk(KERN_DEBUG IF_NAME ": sync finished %d\n", + frame)); + break; + } + break; + } + + case VIDIOREADREG: + reg = *(int *)arg; + DBG(DBG_REGISTER, printk(KERN_DEBUG IF_NAME ": read of %02x\n", reg)); + if ((reg > 0xEF) || (reg < 0)) + return -EINVAL; + val = saa7114h_reg_read((struct saa7114h *)vd->priv, reg); + if (val == -1) + return -EIO; + *(int *)arg = val; + break; + case VIDIOWRITEREG: + if (copy_from_user(®, arg, sizeof(int)) || + copy_from_user(&val, arg+sizeof(int), sizeof(int))) + return -EFAULT; + DBG(DBG_REGISTER, printk(KERN_DEBUG IF_NAME ": write of %02x <- %02x\n", reg, val)); + if ((reg > 0xEF) || (reg < 0)) + return -EINVAL; + val = saa7114h_reg_write((struct saa7114h *)vd->priv, reg, val); + if (val == -1) + return -EIO; + break; + case VIDIOGRABFRAME: + return grab_frame((struct saa7114h *)vd->priv, arg, 0); + case VIDIOSHOWEAV: + return grab_frame((struct saa7114h *)vd->priv, arg, 1); + default: + retval = -EINVAL; + break; + } + + return retval; +} + +static int saa7114h_mmap(struct video_device *vd, const char *adr, + unsigned long size) +{ + struct saa7114h *d = vd->priv; + unsigned long start = (unsigned long)adr; + unsigned long page, pos; + + if (!d) + return -ENODEV; + + if (size > MAX_MMAP_SIZE) { + printk("mmap: bad size %lu > %lu\n", size, MAX_MMAP_SIZE); + return -EINVAL; + } + + /* make this _really_ smp-safe */ + if (down_interruptible(&d->busy_lock)) + return -EINTR; + + pos = (unsigned long)(d->frame_buf); + while (size > 0) { + page = kvirt_to_pa(pos); + if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) { + up(&d->busy_lock); + return -EAGAIN; + } + start += PAGE_SIZE; + pos += PAGE_SIZE; + if (size > PAGE_SIZE) + size -= PAGE_SIZE; + else + size = 0; + } + up(&d->busy_lock); + + return 0; +} + +/* ----------------------------------------------------------------------- + * Device probing and initialization + * ----------------------------------------------------------------------- */ + +/* Default values to program into SAA7114H */ +static const unsigned char reg_init[] = { + 0x00, 0x00, /* 00 - ID byte */ + + /*front end */ + 0x01, 0x08, /* 01 - Horizontal increment -> recommended delay */ + 0x02, 0xC4, /* 02 - AI Control 1 (CVBS AI23) */ + 0x03, 0x10, /* 03 - AI Control 2 */ + 0x04, 0x90, /* 04 - AI Control 3 (Gain ch 1) */ + 0x05, 0x90, /* 05 - AI Control 4 (Gain ch 2) */ + + /* decoder */ + 0x06, 0xEB, /* 06 - Horiz sync start */ + 0x07, 0xE0, /* 07 - Horiz sync stop */ + 0x08, 0x98, /* 08 - Sync control */ + 0x09, 0x40, /* 09 - L Control */ + 0x0a, 0x80, /* 0a - L Brightness */ + 0x0b, 0x44, /* 0b - L Contrast */ + 0x0c, 0x40, /* 0c - C Saturation */ + 0x0d, 0x00, /* 0d - C Hue */ + 0x0e, 0x89, /* 0e - C Control 1 */ + 0x0f, 0x0f, /* 0f - C Gain (??? 0x2A recommended) */ + 0x10, 0x0E, /* 10 - C Control 2 */ + 0x11, 0x00, /* 11 - Mode/Delay */ + 0x12, 0x00, /* 12 - RT signal control */ + 0x13, 0x00, /* 13 - RT/X output */ + 0x14, 0x00, /* 14 - Analog, Compat */ + 0x15, 0x11, /* 15 - VGATE start */ + 0x16, 0xFE, /* 16 - VGATE stop */ + 0x17, 0x40, /* 17 - Misc VGATE (disable LLC2) */ + 0x18, 0x40, /* 18 - Raw data gain - 128 */ + 0x19, 0x80, /* 19 - Raw data offset - 0 */ + + /* Global settings */ + 0x88, 0x98, /* 88 - AI1x on, AI2x off; decoder/slicer off; ACLK gen off */ + 0x83, 0x00, /* 83 - X-port output disabled */ + 0x84, 0xF0, /* 84 - I-port V/G output framing, IGP1=0=IGP0=0 */ + 0x85, 0x00, /* 85 - I-port default polarities, X-port signals */ + 0x86, 0x40, /* 86 - more IGP1/0, FIFO level, only video transmitted */ + 0x87, 0x01, /* 87 - ICK default, IDQ default, I-port output enabled */ + + /* Task A: scaler input config and output format */ + 0x90, 0x00, /* 90 - Task handling */ + 0x91, 0x08, /* 91 - Scalar input and format */ + 0x92, 0x10, /* 92 - Reference signal def */ + 0x93, 0x80, /* 93 - I-port output */ + + /* Task B */ + 0xc0, 0x42, /* 90 - Task handling */ + 0xc1, 0x08, /* 91 - Scalar input and format */ + 0xc2, 0x10, /* 92 - Reference signal def */ + 0xc3, 0x80, /* 93 - I-port output */ + + /* Input and Output windows */ + 0x94, 0x10, /* - */ + 0x95, 0x00, /* - */ + 0x96, 0xD0, /* - */ + 0x97, 0x02, /* - */ + 0x98, 0x0A, /* - */ + 0x99, 0x00, /* - */ + 0x9a, 0xF2, /* - */ + 0x9b, 0x00, /* - */ + 0x9c, 0xD0, /* - */ + 0x9d, 0x02, /* - */ + 0xc4, 0x10, /* - */ + 0xc5, 0x00, /* - */ + 0xc6, 0xD0, /* - */ + 0xc7, 0x02, /* - */ + 0xc8, 0x0A, /* - */ + 0xc9, 0x00, /* - */ + 0xca, 0xF2, /* - */ + 0xcb, 0x00, /* - */ + 0xcc, 0xD0, /* - */ + 0xcd, 0x02, /* - */ + + 0x9e, 0xf0, /* - */ + 0x9f, 0x00, /* - */ + 0xce, 0xf0, /* - */ + 0xcf, 0x00, /* - */ + + /* Prefiltering and prescaling */ + 0xa0, 0x01, /* - */ + 0xa1, 0x00, /* - */ + 0xa2, 0x00, /* - */ + 0xa4, 0x80, /* - */ + 0xa5, 0x40, /* - */ + 0xa6, 0x40, /* - */ + 0xd4, 0x80, /* - */ + 0xd5, 0x40, /* - */ + 0xd6, 0x40, /* - */ + + /* Horizontal phase scaling */ + 0xa8, 0x00, /* - */ + 0xa9, 0x04, /* - */ + 0xaa, 0x00, /* - */ + 0xd8, 0x00, /* - */ + 0xd9, 0x04, /* - */ + 0xda, 0x00, /* - */ + + 0xac, 0x00, /* - */ + 0xad, 0x02, /* - */ + 0xae, 0x00, /* - */ + 0xdc, 0x00, /* - */ + 0xdd, 0x02, /* - */ + 0xde, 0x00, /* - */ + + /* Vertical phase scaling */ + 0xb0, 0x00, /* - */ + 0xb1, 0x04, /* - */ + 0xb2, 0x00, /* - */ + 0xb3, 0x04, /* - */ + 0xe0, 0x00, /* - */ + 0xe1, 0x04, /* - */ + 0xe2, 0x00, /* - */ + 0xe3, 0x04, /* - */ + 0xb4, 0x00, /* b4 - vscale mode control */ + 0xe4, 0x00, /* b4 - vscale mode control */ + + /* Task enables */ + 0x80, 0x10, /* 80 - LLC->ICLK, dq->IDQ, scaler->F/V timing, task enables */ + + /* Reset the slicer */ + 0x88, 0xb8, /* 88 - AI1x on, AI2x off; decoder/slicer on; ACLK gen off */ +}; + +static int saa7114h_attach(struct i2c_adapter *adap, int addr, unsigned short flags, int kind) +{ + struct i2c_client *client; + struct video_device *vd; + struct saa7114h *decoder; + int err; + int val, i; + + client = kmalloc(sizeof(*client), GFP_KERNEL); + if (client == NULL) + return -ENOMEM; + client->adapter = adap; + client->addr = addr; + client->driver = &i2c_driver_saa7114h; + strcpy(client->name, IF_NAME); + + decoder = kmalloc(sizeof(*decoder), GFP_KERNEL); + if (decoder == NULL) { + kfree(client); + return -ENOMEM; + } + memset(decoder, 0, sizeof(struct saa7114h)); + decoder->client = client; + decoder->dma_enable = 0; + decoder->palette = VIDEO_PALETTE_UYVY; + decoder->depth = 16; + decoder->vw.width = MAX_HORIZ; + decoder->vw.height = MAX_VERT; + decoder->frame_buf = rvmalloc(MAX_FRAME_SIZE*NUM_FRAME); + if (!decoder->frame_buf) { + kfree(decoder); + kfree(client); + return -ENOMEM; + } + /* XXXKW use clear_page? */ + memset(decoder->frame_buf, 0, MAX_FRAME_SIZE*NUM_FRAME); + printk("saa7114h_attach: frame_buf = (fb=%8p / %08lx)\n", + decoder->frame_buf, kvirt_to_pa((int)decoder->frame_buf)); + for (i=0; iframe[i].data = decoder->frame_buf+i*MAX_FRAME_SIZE; +#if NULL_DMA + decoder->frame[i].state = FRAME_DONE; +#else + decoder->frame[i].state = FRAME_UNUSED; +#endif + init_waitqueue_head(&decoder->frame[i].read_wait); + } + decoder->irq = K_INT_MAC_2; + if (request_irq + (decoder->irq, saa7114h_interrupt, 0, "Philips SAA7114h", decoder)) { + rvfree(decoder->frame_buf, MAX_FRAME_SIZE*NUM_FRAME); + kfree(decoder); + kfree(client); + return -ENOMEM; + } + init_MUTEX(&decoder->param_lock); + init_MUTEX(&decoder->busy_lock); + + if ((err = i2c_attach_client(client)) < 0) { + kfree(client); + kfree(decoder); + return err; + } + + if (saa7114h_reg_init(decoder, reg_init, sizeof(reg_init)) || + saa7114h_get_cparams(decoder)) { + i2c_detach_client(client); + kfree(client); + kfree(decoder); + return -ENODEV; + } + + vd = kmalloc(sizeof(*vd), GFP_KERNEL); + memset(vd, 0, sizeof(*vd)); + if (vd == NULL) { + i2c_detach_client(client); + kfree(client); + kfree(decoder); + return -ENOMEM; + } + vd->priv = decoder; + strcpy(vd->name, IF_NAME); + vd->type = VID_TYPE_CAPTURE; + vd->hardware = VID_HARDWARE_SAA7114H; + vd->open = saa7114h_open; + vd->close = saa7114h_release; + vd->read = saa7114h_read; + vd->ioctl = saa7114h_ioctl; + vd->mmap = saa7114h_mmap; + + if ((err = video_register_device(vd, VFL_TYPE_GRABBER, -1)) < 0) { + i2c_detach_client(client); + kfree(client); + kfree(decoder); + kfree(vd); + return err; + } + + client->data = vd; + decoder->vd = vd; + + /* Turn on the ITRDY - preserve the GENO pin for syncser */ + val = in64(KSEG1 + A_MAC_REGISTER(2, R_MAC_MDIO)); + out64(M_MAC_MDIO_OUT | (val & M_MAC_GENC), + KSEG1 + A_MAC_REGISTER(2, R_MAC_MDIO)); + + if ((err = dma_setup(decoder))) { + i2c_detach_client(client); + kfree(client); + kfree(decoder); + kfree(vd); + return err; + } + + printk("saa7114h_attach successful\n"); + +#ifdef CONFIG_PROC_FS + proc_saa7114h_create(); + create_proc_decoder(vd->priv); +#endif + + MOD_INC_USE_COUNT; + + return 0; +} + +/* Addresses to scan */ +static unsigned short normal_i2c[] = {I2C_CLIENT_END}; +static unsigned short normal_i2c_range[] = {0x20, 0x21, I2C_CLIENT_END}; +static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; + +static struct i2c_client_address_data addr_data = { + normal_i2c, normal_i2c_range, + probe, probe_range, + ignore, ignore_range, + force +}; + +static int saa7114h_probe(struct i2c_adapter *adap) +{ + /* Look for this device on the given adapter (bus) */ + if (adap->id == (I2C_ALGO_SIBYTE | I2C_HW_SIBYTE)) + return i2c_probe(adap, &addr_data, &saa7114h_attach); + else + return 0; +} + +static int saa7114h_detach(struct i2c_client *device) +{ +#if 0 + kfree(device->data); + MOD_DEC_USE_COUNT; +#endif +#ifdef CONFIG_PROC_FS + destroy_proc_decoder(((struct video_device *)device->data)->priv); + proc_saa7114h_destroy(); +#endif + return 0; +} + +/* ----------------------------------------------------------------------- */ + +static int __init swarm_7114h_init(void) +{ + return i2c_add_driver(&i2c_driver_saa7114h); +} + +static void __exit swarm_7114h_cleanup(void) +{ +} + +MODULE_AUTHOR("Kip Walker, Broadcom Corp."); +MODULE_DESCRIPTION("Philips SAA7114H Driver for Broadcom SWARM board"); + +module_init(swarm_7114h_init); +module_exit(swarm_7114h_cleanup); diff -urN linux-2.4.21-bk37/drivers/net/Config.in linux-2.4.21-bk38/drivers/net/Config.in --- linux-2.4.21-bk37/drivers/net/Config.in 2003-08-24 02:55:52.000000000 -0700 +++ linux-2.4.21-bk38/drivers/net/Config.in 2003-08-24 02:56:06.000000000 -0700 @@ -210,7 +210,7 @@ if [ "$CONFIG_PCI" = "y" -o "$CONFIG_EISA" = "y" ]; then tristate ' TI ThunderLAN support' CONFIG_TLAN fi - dep_tristate ' TOSHIBA TC35815 Ethernet support' CONFIG_TC35815 $CONFIG_PCI + dep_tristate ' TOSHIBA TC35815 Ethernet support' CONFIG_TC35815 $CONFIG_TOSHIBA_JMR3927 $CONFIG_PCI dep_tristate ' VIA Rhine support' CONFIG_VIA_RHINE $CONFIG_PCI dep_mbool ' Use MMIO instead of PIO (EXPERIMENTAL)' CONFIG_VIA_RHINE_MMIO $CONFIG_VIA_RHINE $CONFIG_EXPERIMENTAL dep_tristate ' Winbond W89c840 Ethernet support' CONFIG_WINBOND_840 $CONFIG_PCI diff -urN linux-2.4.21-bk37/drivers/net/tc35815.c linux-2.4.21-bk38/drivers/net/tc35815.c --- linux-2.4.21-bk37/drivers/net/tc35815.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.21-bk38/drivers/net/tc35815.c 2003-08-24 02:56:08.000000000 -0700 @@ -7,9 +7,6 @@ * Based on skelton.c by Donald Becker. * Copyright (C) 2000-2001 Toshiba Corporation * - * Cleaned up various non portable stuff (save_and_cli etc) and made it - * build on x86 platforms -- Alan Cox 20020302 - * * 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 @@ -29,13 +26,10 @@ * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. - * - * TODO: - * Switch to spin_lock not lock_kernel for scalability. */ static const char *version = - "tc35815.c:v0.00-ac 26/07/2000 by Toshiba Corporation\n"; + "tc35815.c:v0.00 26/07/2000 by Toshiba Corporation\n"; #include @@ -405,14 +399,8 @@ }; -#if defined(__mips__) -/* MIPS weirdness */ extern unsigned long tc_readl(volatile __u32 *addr); extern void tc_writel(unsigned long data, volatile __u32 *addr); -#else -#define tc_readl readl -#define tc_writel writel -#endif dma_addr_t priv_dma_handle; @@ -477,6 +465,7 @@ static void tc35815_chip_reset(struct net_device *dev); static void tc35815_chip_init(struct net_device *dev); static void tc35815_phy_chip_init(struct net_device *dev); +static int tc35815_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data); /* A list of all installed tc35815 devices. */ static struct net_device *root_tc35815_dev = NULL; @@ -507,7 +496,7 @@ return -ENODEV; if (pdev) { - unsigned long pci_memaddr; + unsigned int pci_memaddr; unsigned int pci_irq_line; printk(KERN_INFO "tc35815_probe: found device %#08x.%#08x\n", ent->vendor, ent->device); @@ -571,12 +560,12 @@ /* Retrieve and print the ethernet address. */ while (tc_readl(&tr->PROM_Ctl) & PROM_Busy) - cpu_relax(); + ; for (i = 0; i < 6; i += 2) { unsigned short data; tc_writel(PROM_Busy | PROM_Read | (i / 2 + 2), &tr->PROM_Ctl); while (tc_readl(&tr->PROM_Ctl) & PROM_Busy) - cpu_relax(); + ; data = tc_readl(&tr->PROM_Data); dev->dev_addr[i] = data & 0xff; dev->dev_addr[i+1] = data >> 8; @@ -842,7 +831,6 @@ panic("%s: Illegal queue state.", dev->name); } -#if 0 static void print_buf(char *add, int length) { int i; @@ -859,7 +847,6 @@ } printk("\n"); } -#endif static void print_eth(char *add) { @@ -920,8 +907,7 @@ struct tc35815_regs *tr = (struct tc35815_regs *)dev->base_addr; int flags; - save_flags(flags); - cli(); + save_and_cli(flags); printk(KERN_WARNING "%s: transmit timed out, status %#x\n", dev->name, tc_readl(&tr->Tx_Stat)); /* Try to restart the adaptor. */ @@ -977,8 +963,7 @@ dma_cache_wback_inv((unsigned long)buf, length); #endif - save_flags(flags); - cli(); + save_and_cli(flags); /* failsafe... */ if (lp->tfd_start != lp->tfd_end) @@ -1428,8 +1413,7 @@ unsigned long flags; if (netif_running(dev)) { - save_flags(flags); - cli(); + save_and_cli(flags); /* Update the statistics from the device registers. */ lp->stats.rx_missed_errors = tc_readl(&tr->Miss_Cnt); restore_flags(flags); @@ -1537,11 +1521,10 @@ { unsigned long data; int flags; - save_flags(flags); - cli(); + save_and_cli(flags); tc_writel(MD_CA_Busy | (phy << 5) | phy_reg, &tr->MD_CA); while (tc_readl(&tr->MD_CA) & MD_CA_Busy) - cpu_relax(); + ; data = tc_readl(&tr->MD_Data); restore_flags(flags); return data; @@ -1550,12 +1533,11 @@ static void tc_phy_write(unsigned long d, struct tc35815_regs *tr, int phy, int phy_reg) { int flags; - save_flags(flags); - cli(); + save_and_cli(flags); tc_writel(d, &tr->MD_Data); tc_writel(MD_CA_Busy | MD_CA_Wr | (phy << 5) | phy_reg, &tr->MD_CA); while (tc_readl(&tr->MD_CA) & MD_CA_Busy) - cpu_relax(); + ; restore_flags(flags); } @@ -1643,7 +1625,7 @@ /* reset the controller */ tc_writel(MAC_Reset, &tr->MAC_Ctl); while (tc_readl(&tr->MAC_Ctl) & MAC_Reset) - cpu_relax(); + ; tc_writel(0, &tr->MAC_Ctl); @@ -1680,8 +1662,7 @@ tc_writel(CAM_Ena_Bit(CAM_ENTRY_SOURCE), &tr->CAM_Ena); tc_writel(CAM_CompEn | CAM_BroadAcc, &tr->CAM_Ctl); - save_flags(flags); - cli(); + save_and_cli(flags); tc_writel(DMA_BURST_SIZE, &tr->DMA_Ctl); @@ -1715,6 +1696,39 @@ restore_flags(flags); } +static int tc35815_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data) +{ + int len = 0; + off_t pos = 0; + off_t begin = 0; + struct net_device *dev; + + len += sprintf(buffer, "TC35815 statistics:\n"); + for (dev = root_tc35815_dev; dev; dev = ((struct tc35815_local *)dev->priv)->next_module) { + struct tc35815_local *lp = (struct tc35815_local *)dev->priv; + len += sprintf(buffer + len, + "%s: tx_ints %d, rx_ints %d, max_tx_qlen %d\n", + dev->name, + lp->lstats.tx_ints, + lp->lstats.rx_ints, + lp->lstats.max_tx_qlen); + pos = begin + len; + + if (pos < offset) { + len = 0; + begin = pos; + } + + if (pos > offset+length) break; + } + + *start = buffer + (offset - begin); + len -= (offset - begin); + + if (len > length) len = length; + + return len; +} /* XXX */ void diff -urN linux-2.4.21-bk37/drivers/pci/Makefile linux-2.4.21-bk38/drivers/pci/Makefile --- linux-2.4.21-bk37/drivers/pci/Makefile 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.21-bk38/drivers/pci/Makefile 2003-08-24 02:56:09.000000000 -0700 @@ -29,7 +29,6 @@ obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o obj-$(CONFIG_PPC32) += setup-irq.o obj-$(CONFIG_SGI_IP27) += setup-irq.o -obj-$(CONFIG_SGI_IP32) += setup-irq.o ifndef CONFIG_X86 obj-y += syscall.o diff -urN linux-2.4.21-bk37/drivers/pci/pci.ids linux-2.4.21-bk38/drivers/pci/pci.ids --- linux-2.4.21-bk37/drivers/pci/pci.ids 2003-08-24 02:55:52.000000000 -0700 +++ linux-2.4.21-bk38/drivers/pci/pci.ids 2003-08-24 02:56:09.000000000 -0700 @@ -1151,6 +1151,7 @@ 0009 r4x00 0020 ATM Meteor 155 102f 00f8 ATM Meteor 155 + 0180 TX4927 1030 TMC Research 1031 Miro Computer Products AG 5601 DC20 ASIC @@ -1196,6 +1197,7 @@ 0074 56k Voice Modem 1033 8014 RCV56ACF 56k Voice Modem 009b Vrc5476 + 00a5 VRC4173 00a6 VRC5477 AC97 00cd IEEE 1394 [OrangeLink] Host Controller 12ee 8011 Root hub diff -urN linux-2.4.21-bk37/drivers/pcmcia/au1000_db1x00.c linux-2.4.21-bk38/drivers/pcmcia/au1000_db1x00.c --- linux-2.4.21-bk37/drivers/pcmcia/au1000_db1x00.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/drivers/pcmcia/au1000_db1x00.c 2003-08-24 02:56:09.000000000 -0700 @@ -0,0 +1,269 @@ +/* + * + * Alchemy Semi Db1x00 boards specific pcmcia routines. + * + * Copyright 2002 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "cs_internal.h" + +#include +#include +#include + +#include +#include + +#include + +static BCSR * const bcsr = (BCSR *)0xAE000000; + +static int db1x00_pcmcia_init(struct pcmcia_init *init) +{ + bcsr->pcmcia = 0; /* turn off power */ + au_sync_delay(2); + return PCMCIA_NUM_SOCKS; +} + +static int db1x00_pcmcia_shutdown(void) +{ + bcsr->pcmcia = 0; /* turn off power */ + au_sync_delay(2); + return 0; +} + +static int +db1x00_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state) +{ + u32 inserted; + unsigned char vs; + + if(sock > PCMCIA_MAX_SOCK) return -1; + + state->ready = 0; + state->vs_Xv = 0; + state->vs_3v = 0; + state->detect = 0; + + if (sock == 0) { + vs = bcsr->status & 0x3; + inserted = !(bcsr->status & (1<<4)); + } + else { + vs = (bcsr->status & 0xC)>>2; + inserted = !(bcsr->status & (1<<5)); + } + + DEBUG(KERN_DEBUG "db1x00 socket %d: inserted %d, vs %d\n", + sock, inserted, vs); + + if (inserted) { + switch (vs) { + case 0: + case 2: + state->vs_3v=1; + break; + case 3: /* 5V */ + break; + default: + /* return without setting 'detect' */ + printk(KERN_ERR "db1x00 bad VS (%d)\n", + vs); + return -1; + } + state->detect = 1; + state->ready = 1; + } + else { + /* if the card was previously inserted and then ejected, + * we should turn off power to it + */ + if ((sock == 0) && (bcsr->pcmcia & BCSR_PCMCIA_PC0RST)) { + bcsr->pcmcia &= ~(BCSR_PCMCIA_PC0RST | + BCSR_PCMCIA_PC0DRVEN | + BCSR_PCMCIA_PC0VPP | + BCSR_PCMCIA_PC0VCC); + } + else if ((sock == 1) && (bcsr->pcmcia & BCSR_PCMCIA_PC1RST)) { + bcsr->pcmcia &= ~(BCSR_PCMCIA_PC1RST | + BCSR_PCMCIA_PC1DRVEN | + BCSR_PCMCIA_PC1VPP | + BCSR_PCMCIA_PC1VCC); + } + } + + state->bvd1=1; + state->bvd2=1; + state->wrprot=0; + return 1; +} + + +static int db1x00_pcmcia_get_irq_info(struct pcmcia_irq_info *info) +{ + if(info->sock > PCMCIA_MAX_SOCK) return -1; + + if(info->sock == 0) { + info->irq = AU1000_GPIO_2; + } + else + info->irq = AU1000_GPIO_5; + + return 0; +} + + +static int +db1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure) +{ + u16 pwr; + int sock = configure->sock; + + if(sock > PCMCIA_MAX_SOCK) return -1; + + DEBUG(KERN_DEBUG "socket %d Vcc %dV Vpp %dV, reset %d\n", + sock, configure->vcc, configure->vpp, configure->reset); + + /* pcmcia reg was set to zero at init time. Be careful when + * initializing a socket not to wipe out the settings of the + * other socket. + */ + pwr = bcsr->pcmcia; + pwr &= ~(0xf << sock*8); /* clear voltage settings */ + + switch(configure->vcc){ + case 0: /* Vcc 0 */ + pwr |= SET_VCC_VPP(0,0,sock); + break; + case 50: /* Vcc 5V */ + switch(configure->vpp) { + case 0: + pwr |= SET_VCC_VPP(2,0,sock); + break; + case 50: + pwr |= SET_VCC_VPP(2,1,sock); + break; + case 12: + pwr |= SET_VCC_VPP(2,2,sock); + break; + case 33: + default: + pwr |= SET_VCC_VPP(0,0,sock); + printk("%s: bad Vcc/Vpp (%d:%d)\n", + __FUNCTION__, + configure->vcc, + configure->vpp); + break; + } + break; + case 33: /* Vcc 3.3V */ + switch(configure->vpp) { + case 0: + pwr |= SET_VCC_VPP(1,0,sock); + break; + case 12: + pwr |= SET_VCC_VPP(1,2,sock); + break; + case 33: + pwr |= SET_VCC_VPP(1,1,sock); + break; + case 50: + default: + pwr |= SET_VCC_VPP(0,0,sock); + printk("%s: bad Vcc/Vpp (%d:%d)\n", + __FUNCTION__, + configure->vcc, + configure->vpp); + break; + } + break; + default: /* what's this ? */ + pwr |= SET_VCC_VPP(0,0,sock); + printk(KERN_ERR "%s: bad Vcc %d\n", + __FUNCTION__, configure->vcc); + break; + } + + bcsr->pcmcia = pwr; + au_sync_delay(300); + + if (sock == 0) { + if (!configure->reset) { + pwr |= BCSR_PCMCIA_PC0DRVEN; + bcsr->pcmcia = pwr; + au_sync_delay(300); + pwr |= BCSR_PCMCIA_PC0RST; + bcsr->pcmcia = pwr; + au_sync_delay(100); + } + else { + pwr &= ~(BCSR_PCMCIA_PC0RST | BCSR_PCMCIA_PC0DRVEN); + bcsr->pcmcia = pwr; + au_sync_delay(100); + } + } + else { + if (!configure->reset) { + pwr |= BCSR_PCMCIA_PC1DRVEN; + bcsr->pcmcia = pwr; + au_sync_delay(300); + pwr |= BCSR_PCMCIA_PC1RST; + bcsr->pcmcia = pwr; + au_sync_delay(100); + } + else { + pwr &= ~(BCSR_PCMCIA_PC1RST | BCSR_PCMCIA_PC1DRVEN); + bcsr->pcmcia = pwr; + au_sync_delay(100); + } + } + return 0; +} + +struct pcmcia_low_level db1x00_pcmcia_ops = { + db1x00_pcmcia_init, + db1x00_pcmcia_shutdown, + db1x00_pcmcia_socket_state, + db1x00_pcmcia_get_irq_info, + db1x00_pcmcia_configure_socket +}; diff -urN linux-2.4.21-bk37/drivers/pcmcia/au1000_generic.c linux-2.4.21-bk38/drivers/pcmcia/au1000_generic.c --- linux-2.4.21-bk37/drivers/pcmcia/au1000_generic.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.21-bk38/drivers/pcmcia/au1000_generic.c 2003-08-24 02:56:09.000000000 -0700 @@ -2,7 +2,7 @@ * * Alchemy Semi Au1000 pcmcia driver * - * Copyright 2001 MontaVista Software Inc. + * Copyright 2001-2003 MontaVista Software Inc. * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com * @@ -132,13 +132,16 @@ #endif }; +static spinlock_t pcmcia_lock = SPIN_LOCK_UNLOCKED; + +extern const unsigned long mips_io_port_base; + static int __init au1000_pcmcia_driver_init(void) { servinfo_t info; struct pcmcia_init pcmcia_init; struct pcmcia_state state; unsigned int i; - unsigned long timing3; printk("\nAu1x00 PCMCIA (CS release %s)\n", CS_RELEASE); @@ -156,6 +159,10 @@ #if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500) pcmcia_low_level=&pb1x00_pcmcia_ops; +#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) + pcmcia_low_level=&db1x00_pcmcia_ops; +#elif defined(CONFIG_MIPS_XXS1500) + pcmcia_low_level=&xxs1500_pcmcia_ops; #else #error Unsupported AU1000 board. #endif @@ -192,18 +199,31 @@ pcmcia_socket[i].k_state=state; pcmcia_socket[i].cs_state.csc_mask=SS_DETECT; + /* + * PCMCIA drivers use the inb/outb macros to access the + * IO registers. Since mips_io_port_base is added to the + * access address, we need to subtract it here. + */ if (i == 0) { pcmcia_socket[i].virt_io = - (u32)ioremap((ioaddr_t)0xF00000000, 0x1000); - pcmcia_socket[i].phys_attr = (memaddr_t)0xF40000000; - pcmcia_socket[i].phys_mem = (memaddr_t)0xF80000000; + (u32)ioremap((ioaddr_t)AU1X_SOCK0_IO, 0x1000) - + mips_io_port_base; + pcmcia_socket[i].phys_attr = + (ioaddr_t)AU1X_SOCK0_PHYS_ATTR; + pcmcia_socket[i].phys_mem = + (ioaddr_t)AU1X_SOCK0_PHYS_MEM; } +#ifndef CONFIG_MIPS_XXS1500 else { pcmcia_socket[i].virt_io = - (u32)ioremap((ioaddr_t)0xF08000000, 0x1000); - pcmcia_socket[i].phys_attr = (memaddr_t)0xF48000000; - pcmcia_socket[i].phys_mem = (memaddr_t)0xF88000000; + (u32)ioremap((ioaddr_t)AU1X_SOCK1_IO, 0x1000) - + mips_io_port_base; + pcmcia_socket[i].phys_attr = + (ioaddr_t)AU1X_SOCK1_PHYS_ATTR; + pcmcia_socket[i].phys_mem = + (ioaddr_t)AU1X_SOCK1_PHYS_MEM; } +#endif } /* Only advertise as many sockets as we can detect: */ @@ -234,7 +254,8 @@ flush_scheduled_tasks(); for(i=0; i < socket_count; i++) { if (pcmcia_socket[i].virt_io) - iounmap((void *)pcmcia_socket[i].virt_io); + iounmap((void *)pcmcia_socket[i].virt_io + + mips_io_port_base); } DEBUG(1, "au1000: shutdown complete\n"); } @@ -585,8 +606,7 @@ } } - save_flags(flags); - cli(); + spin_lock_irqsave(&pcmcia_lock, flags); start=map->sys_start; if(map->sys_stop==0) @@ -603,7 +623,7 @@ map->sys_stop=map->sys_start+(map->sys_stop-start); pcmcia_socket[sock].mem_map[map->map]=*map; - restore_flags(flags); + spin_unlock_irqrestore(&pcmcia_lock, flags); DEBUG(3, "set_mem_map %d start %x stop %x card_start %x\n", map->map, map->sys_start, map->sys_stop, map->card_start); diff -urN linux-2.4.21-bk37/drivers/pcmcia/au1000_pb1x00.c linux-2.4.21-bk38/drivers/pcmcia/au1000_pb1x00.c --- linux-2.4.21-bk37/drivers/pcmcia/au1000_pb1x00.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.21-bk38/drivers/pcmcia/au1000_pb1x00.c 2003-08-24 02:56:09.000000000 -0700 @@ -54,7 +54,7 @@ #define PCMCIA_IRQ AU1000_GPIO_15 #elif defined (CONFIG_MIPS_PB1500) #include -#define PCMCIA_IRQ AU1000_GPIO_11 /* fixme */ +#define PCMCIA_IRQ AU1500_GPIO_203 #elif defined (CONFIG_MIPS_PB1100) #include #define PCMCIA_IRQ AU1000_GPIO_11 @@ -81,9 +81,9 @@ #else /* fixme -- take care of the Pb1500 at some point */ u16 pcr; - pcr = au_readw(PB1100_MEM_PCMCIA) & ~0xf; /* turn off power */ - pcr &= ~(PB1100_PC_DEASSERT_RST | PB1100_PC_DRV_EN); - au_writew(pcr, PB1100_MEM_PCMCIA); + pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf; /* turn off power */ + pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN); + au_writew(pcr, PCMCIA_BOARD_REG); au_sync_delay(500); return PCMCIA_NUM_SOCKS; #endif @@ -101,9 +101,9 @@ return 0; #else u16 pcr; - pcr = au_readw(PB1100_MEM_PCMCIA) & ~0xf; /* turn off power */ - pcr &= ~(PB1100_PC_DEASSERT_RST | PB1100_PC_DRV_EN); - au_writew(pcr, PB1100_MEM_PCMCIA); + pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf; /* turn off power */ + pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN); + au_writew(pcr, PCMCIA_BOARD_REG); au_sync_delay(2); return 0; #endif @@ -122,9 +122,14 @@ vs0 = (vs0 >> 4) & 0x3; vs1 = (vs1 >> 12) & 0x3; #else - vs0 = (au_readw(PB1100_BOARD_STATUS) >> 4) & 0x3; + vs0 = (au_readw(BOARD_STATUS_REG) >> 4) & 0x3; +#ifdef CONFIG_MIPS_PB1500 + inserted0 = !((au_readl(GPIO2_PIN_STATE) >> 1) & 0x1); /* gpio 201 */ +#else /* Pb1100 */ inserted0 = !((au_readl(SYS_PINSTATERD) >> 9) & 0x1); /* gpio 9 */ #endif + inserted1 = 0; +#endif state->ready = 0; state->vs_Xv = 0; @@ -144,7 +149,7 @@ /* return without setting 'detect' */ printk(KERN_ERR "pb1x00 bad VS (%d)\n", vs0); - return; + return 0; } state->detect = 1; } @@ -162,7 +167,7 @@ /* return without setting 'detect' */ printk(KERN_ERR "pb1x00 bad VS (%d)\n", vs1); - return; + return 0; } state->detect = 1; } @@ -323,7 +328,7 @@ #else - pcr = au_readw(PB1100_MEM_PCMCIA) & ~0xf; + pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf; DEBUG(KERN_INFO "Vcc %dV Vpp %dV, pcr %x, reset %d\n", configure->vcc, configure->vpp, pcr, configure->reset); @@ -382,26 +387,27 @@ break; } - au_writew(pcr, PB1100_MEM_PCMCIA); + au_writew(pcr, PCMCIA_BOARD_REG); au_sync_delay(300); if (!configure->reset) { - pcr |= PB1100_PC_DRV_EN; - au_writew(pcr, PB1100_MEM_PCMCIA); + pcr |= PC_DRV_EN; + au_writew(pcr, PCMCIA_BOARD_REG); au_sync_delay(100); - pcr |= PB1100_PC_DEASSERT_RST; - au_writew(pcr, PB1100_MEM_PCMCIA); + pcr |= PC_DEASSERT_RST; + au_writew(pcr, PCMCIA_BOARD_REG); au_sync_delay(100); } else { - pcr &= ~(PB1100_PC_DEASSERT_RST | PB1100_PC_DRV_EN); - au_writew(pcr, PB1100_MEM_PCMCIA); + pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN); + au_writew(pcr, PCMCIA_BOARD_REG); au_sync_delay(100); } #endif return 0; } + struct pcmcia_low_level pb1x00_pcmcia_ops = { pb1x00_pcmcia_init, pb1x00_pcmcia_shutdown, diff -urN linux-2.4.21-bk37/drivers/pcmcia/au1000_xxs1500.c linux-2.4.21-bk38/drivers/pcmcia/au1000_xxs1500.c --- linux-2.4.21-bk37/drivers/pcmcia/au1000_xxs1500.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.4.21-bk38/drivers/pcmcia/au1000_xxs1500.c 2003-08-24 02:56:09.000000000 -0700 @@ -0,0 +1,191 @@ +/* + * + * MyCable board specific pcmcia routines. + * + * Copyright 2003 MontaVista Software Inc. + * Author: Pete Popov, MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "cs_internal.h" + +#include +#include +#include + +#include +#include +#include + +#if 0 +#define DEBUG(x,args...) printk(__FUNCTION__ ": " x,##args) +#else +#define DEBUG(x,args...) +#endif + +static int xxs1500_pcmcia_init(struct pcmcia_init *init) +{ + return PCMCIA_NUM_SOCKS; +} + +static int xxs1500_pcmcia_shutdown(void) +{ + /* turn off power */ + au_writel(au_readl(GPIO2_PINSTATE) | (1<<14)|(1<<30), + GPIO2_OUTPUT); + au_sync_delay(100); + + /* assert reset */ + au_writel(au_readl(GPIO2_PINSTATE) | (1<<4)|(1<<20), + GPIO2_OUTPUT); + au_sync_delay(100); + return 0; +} + + +static int +xxs1500_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state) +{ + u32 inserted; u32 vs; + unsigned long gpio, gpio2; + + if(sock > PCMCIA_MAX_SOCK) return -1; + + gpio = au_readl(SYS_PINSTATERD); + gpio2 = au_readl(GPIO2_PINSTATE); + + vs = gpio2 & ((1<<8) | (1<<9)); + inserted = (!(gpio & 0x1) && !(gpio & 0x2)); + + state->ready = 0; + state->vs_Xv = 0; + state->vs_3v = 0; + state->detect = 0; + + if (inserted) { + switch (vs) { + case 0: + case 1: + case 2: + state->vs_3v=1; + break; + case 3: /* 5V */ + default: + /* return without setting 'detect' */ + printk(KERN_ERR "au1x00_cs: unsupported VS\n", + vs); + return; + } + state->detect = 1; + } + + if (state->detect) { + state->ready = 1; + } + + state->bvd1= gpio2 & (1<<10); + state->bvd2 = gpio2 & (1<<11); + state->wrprot=0; + return 1; +} + + +static int xxs1500_pcmcia_get_irq_info(struct pcmcia_irq_info *info) +{ + + if(info->sock > PCMCIA_MAX_SOCK) return -1; + info->irq = PCMCIA_IRQ; + return 0; +} + + +static int +xxs1500_pcmcia_configure_socket(const struct pcmcia_configure *configure) +{ + + if(configure->sock > PCMCIA_MAX_SOCK) return -1; + + DEBUG("Vcc %dV Vpp %dV, reset %d\n", + configure->vcc, configure->vpp, configure->reset); + + switch(configure->vcc){ + case 33: /* Vcc 3.3V */ + /* turn on power */ + DEBUG("turn on power\n"); + au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<14))|(1<<30), + GPIO2_OUTPUT); + au_sync_delay(100); + break; + case 50: /* Vcc 5V */ + default: /* what's this ? */ + printk(KERN_ERR "au1x00_cs: unsupported VCC\n"); + case 0: /* Vcc 0 */ + /* turn off power */ + au_sync_delay(100); + au_writel(au_readl(GPIO2_PINSTATE) | (1<<14)|(1<<30), + GPIO2_OUTPUT); + break; + } + + if (!configure->reset) { + DEBUG("deassert reset\n"); + au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<4))|(1<<20), + GPIO2_OUTPUT); + au_sync_delay(100); + au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<5))|(1<<21), + GPIO2_OUTPUT); + } + else { + DEBUG("assert reset\n"); + au_writel(au_readl(GPIO2_PINSTATE) | (1<<4)|(1<<20), + GPIO2_OUTPUT); + } + au_sync_delay(100); + return 0; +} + +struct pcmcia_low_level xxs1500_pcmcia_ops = { + xxs1500_pcmcia_init, + xxs1500_pcmcia_shutdown, + xxs1500_pcmcia_socket_state, + xxs1500_pcmcia_get_irq_info, + xxs1500_pcmcia_configure_socket +}; diff -urN linux-2.4.21-bk37/drivers/scsi/Config.in linux-2.4.21-bk38/drivers/scsi/Config.in --- linux-2.4.21-bk37/drivers/scsi/Config.in 2003-08-24 02:55:52.000000000 -0700 +++ linux-2.4.21-bk38/drivers/scsi/Config.in 2003-08-24 02:56:11.000000000 -0700 @@ -37,7 +37,7 @@ fi if [ "$CONFIG_DECSTATION" = "y" ]; then dep_tristate 'DEC NCR53C94 Scsi Driver' CONFIG_SCSI_DECNCR $CONFIG_SCSI $CONFIG_TC - dep_tristate 'DEC SII Scsi Driver' CONFIG_SCSI_DECSII $CONFIG_SCSI + dep_tristate 'DEC SII Scsi Driver' CONFIG_SCSI_DECSII $CONFIG_SCSI $CONFIG_MIPS32 fi if [ "$CONFIG_PCI" = "y" ]; then diff -urN linux-2.4.21-bk37/drivers/scsi/dec_esp.c linux-2.4.21-bk38/drivers/scsi/dec_esp.c --- linux-2.4.21-bk37/drivers/scsi/dec_esp.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.21-bk38/drivers/scsi/dec_esp.c 2003-08-24 02:56:13.000000000 -0700 @@ -17,6 +17,8 @@ * data. * 20001005 - Initialization fixes for 2.4.0-test9 * Florian Lohoff + * + * Copyright (C) 2002, 2003 Maciej W. Rozycki */ #include @@ -26,56 +28,48 @@ #include #include #include +#include #include -#include "scsi.h" -#include "hosts.h" -#include "NCR53C9x.h" -#include "dec_esp.h" - -#include -#include -#include #include - +#include #include +#include -#include #include +#include #include #include #include +#include + +#include "scsi.h" +#include "hosts.h" +#include "NCR53C9x.h" +#include "dec_esp.h" -#include -/* - * Once upon a time the pmaz code used to be working but - * it hasn't been maintained for quite some time. - * It isn't working anymore but I'll leave here as a - * starting point. #define this an be prepared for tons - * of warnings and errors :) - */ static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count); static void dma_drain(struct NCR_ESP *esp); static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd * sp); static void dma_dump_state(struct NCR_ESP *esp); -static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length); -static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length); +static void dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length); +static void dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length); static void dma_ints_off(struct NCR_ESP *esp); static void dma_ints_on(struct NCR_ESP *esp); static int dma_irq_p(struct NCR_ESP *esp); static int dma_ports_p(struct NCR_ESP *esp); -static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write); +static void dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write); static void dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp); static void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd * sp); static void dma_advance_sg(Scsi_Cmnd * sp); static void pmaz_dma_drain(struct NCR_ESP *esp); -static void pmaz_dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length); -static void pmaz_dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length); +static void pmaz_dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length); +static void pmaz_dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length); static void pmaz_dma_ints_off(struct NCR_ESP *esp); static void pmaz_dma_ints_on(struct NCR_ESP *esp); -static void pmaz_dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write); +static void pmaz_dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write); static void pmaz_dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp); #define TC_ESP_RAM_SIZE 0x20000 @@ -86,7 +80,7 @@ #define TC_ESP_DMAR_WRITE 0x80000000 #define TC_ESP_DMA_ADDR(x) ((unsigned)(x) & TC_ESP_DMAR_MASK) -__u32 esp_virt_buffer; +u32 esp_virt_buffer; int scsi_current_length; volatile unsigned char cmd_buffer[16]; @@ -96,13 +90,6 @@ * via PIO. */ -volatile unsigned long *scsi_dma_ptr; -volatile unsigned long *scsi_next_ptr; -volatile unsigned long *scsi_scr; -volatile unsigned long *ioasic_ssr; -volatile unsigned long *scsi_sdr0; -volatile unsigned long *scsi_sdr1; - static void scsi_dma_merr_int(int, void *, struct pt_regs *); static void scsi_dma_err_int(int, void *, struct pt_regs *); static void scsi_dma_int(int, void *, struct pt_regs *); @@ -122,17 +109,10 @@ if (IOASIC) { esp_dev = 0; esp = esp_allocate(tpnt, (void *) esp_dev); - - scsi_dma_ptr = (unsigned long *) (system_base + IOCTL + SCSI_DMA_P); - scsi_next_ptr = (unsigned long *) (system_base + IOCTL + SCSI_DMA_BP); - scsi_scr = (unsigned long *) (system_base + IOCTL + SCSI_SCR); - ioasic_ssr = (unsigned long *) (system_base + IOCTL + SSR); - scsi_sdr0 = (unsigned long *) (system_base + IOCTL + SCSI_SDR0); - scsi_sdr1 = (unsigned long *) (system_base + IOCTL + SCSI_SDR1); /* Do command transfer with programmed I/O */ esp->do_pio_cmds = 1; - + /* Required functions */ esp->dma_bytes_sent = &dma_bytes_sent; esp->dma_can_transfer = &dma_can_transfer; @@ -155,7 +135,7 @@ esp->dma_reset = 0; esp->dma_led_off = 0; esp->dma_led_on = 0; - + /* virtual DMA functions */ esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one; esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl; @@ -167,47 +147,42 @@ /* SCSI chip speed */ esp->cfreq = 25000000; - /* - * we don't give the address of DMA channel, but the number - * of DMA channel, so we can use the jazz DMA functions - * - */ - esp->dregs = JAZZ_SCSI_DMA; - + esp->dregs = 0; + /* ESP register base */ - esp->eregs = (struct ESP_regs *) (system_base + SCSI); - + esp->eregs = (struct ESP_regs *) (system_base + IOASIC_SCSI); + /* Set the command buffer */ esp->esp_command = (volatile unsigned char *) cmd_buffer; - + /* get virtual dma address for command buffer */ - esp->esp_command_dvma = (__u32) KSEG1ADDR((volatile unsigned char *) cmd_buffer); - + esp->esp_command_dvma = virt_to_phys(cmd_buffer); + esp->irq = dec_interrupt[DEC_IRQ_ASC]; esp->scsi_id = 7; - + /* Check for differential SCSI-bus */ esp->diff = 0; esp_initialize(esp); - if (request_irq(esp->irq, esp_intr, SA_INTERRUPT, + if (request_irq(esp->irq, esp_intr, SA_INTERRUPT, "ncr53c94", NULL)) goto err_dealloc; if (request_irq(dec_interrupt[DEC_IRQ_ASC_MERR], - scsi_dma_merr_int, SA_INTERRUPT, + scsi_dma_merr_int, SA_INTERRUPT, "ncr53c94 error", NULL)) goto err_free_irq; if (request_irq(dec_interrupt[DEC_IRQ_ASC_ERR], - scsi_dma_err_int, SA_INTERRUPT, + scsi_dma_err_int, SA_INTERRUPT, "ncr53c94 overrun", NULL)) goto err_free_irq_merr; if (request_irq(dec_interrupt[DEC_IRQ_ASC_DMA], - scsi_dma_int, SA_INTERRUPT, + scsi_dma_int, SA_INTERRUPT, "ncr53c94 dma", NULL)) goto err_free_irq_err; - + } if (TURBOCHANNEL) { @@ -220,7 +195,7 @@ mem_start = get_tc_base_addr(slot); /* Store base addr into esp struct */ - esp->slot = mem_start; + esp->slot = PHYSADDR(mem_start); esp->dregs = 0; esp->eregs = (struct ESP_regs *) (mem_start + DEC_SCSI_SREG); @@ -230,7 +205,7 @@ esp->esp_command = (volatile unsigned char *) pmaz_cmd_buffer; /* get virtual dma address for command buffer */ - esp->esp_command_dvma = (__u32) KSEG0ADDR((volatile unsigned char *) pmaz_cmd_buffer); + esp->esp_command_dvma = virt_to_phys(pmaz_cmd_buffer); esp->cfreq = get_tc_speed(); @@ -265,7 +240,7 @@ esp->dma_mmu_release_scsi_sgl = 0; esp->dma_advance_sg = 0; - if (request_irq(esp->irq, esp_intr, SA_INTERRUPT, + if (request_irq(esp->irq, esp_intr, SA_INTERRUPT, "PMAZ_AA", NULL)) { esp_deallocate(esp); release_tc_card(slot); @@ -310,40 +285,53 @@ static void scsi_dma_int(int irq, void *dev_id, struct pt_regs *regs) { + u32 scsi_next_ptr; + + scsi_next_ptr = ioasic_read(IO_REG_SCSI_DMA_P); + /* next page */ - *scsi_next_ptr = ((*scsi_dma_ptr + PAGE_SIZE) & PAGE_MASK) << 3; + scsi_next_ptr = (((scsi_next_ptr >> 3) + PAGE_SIZE) & PAGE_MASK) << 3; + ioasic_write(IO_REG_SCSI_DMA_BP, scsi_next_ptr); fast_iob(); } static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count) { - return fifo_count; + return fifo_count; } static void dma_drain(struct NCR_ESP *esp) { - unsigned long nw = *scsi_scr; - unsigned short *p = KSEG1ADDR((unsigned short *) ((*scsi_dma_ptr) >> 3)); + u32 nw, data0, data1, scsi_data_ptr; + u16 *p; + + nw = ioasic_read(IO_REG_SCSI_SCR); - /* + /* * Is there something in the dma buffers left? - */ + */ if (nw) { + scsi_data_ptr = ioasic_read(IO_REG_SCSI_DMA_P) >> 3; + p = phys_to_virt(scsi_data_ptr); switch (nw) { case 1: - *p = (unsigned short) *scsi_sdr0; + data0 = ioasic_read(IO_REG_SCSI_SDR0); + p[0] = data0 & 0xffff; break; case 2: - *p++ = (unsigned short) (*scsi_sdr0); - *p = (unsigned short) ((*scsi_sdr0) >> 16); + data0 = ioasic_read(IO_REG_SCSI_SDR0); + p[0] = data0 & 0xffff; + p[1] = (data0 >> 16) & 0xffff; break; case 3: - *p++ = (unsigned short) (*scsi_sdr0); - *p++ = (unsigned short) ((*scsi_sdr0) >> 16); - *p = (unsigned short) (*scsi_sdr1); + data0 = ioasic_read(IO_REG_SCSI_SDR0); + data1 = ioasic_read(IO_REG_SCSI_SDR1); + p[0] = data0 & 0xffff; + p[1] = (data0 >> 16) & 0xffff; + p[2] = data1 & 0xffff; break; default: - printk("Strange: %d words in dma buffer left\n", (int) nw); + printk("Strange: %d words in dma buffer left\n", nw); break; } } @@ -356,44 +344,74 @@ static void dma_dump_state(struct NCR_ESP *esp) { -/* - ESPLOG(("esp%d: dma -- enable <%08x> residue <%08x\n", - esp->esp_id, vdma_get_enable((int)esp->dregs), vdma_get_resdiue((int)esp->dregs))); - */ } -static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length) +static void dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length) { + u32 scsi_next_ptr, ioasic_ssr; + unsigned long flags; + if (vaddress & 3) - panic("dec_efs.c: unable to handle partial word transfers, yet..."); + panic("dec_esp.c: unable to handle partial word transfers, yet..."); dma_cache_wback_inv((unsigned long) phys_to_virt(vaddress), length); - *ioasic_ssr &= ~SCSI_DMA_EN; - *scsi_scr = 0; - *scsi_dma_ptr = vaddress << 3; + spin_lock_irqsave(&ioasic_ssr_lock, flags); + + fast_mb(); + ioasic_ssr = ioasic_read(IO_REG_SSR); + + ioasic_ssr &= ~IO_SSR_SCSI_DMA_EN; + ioasic_write(IO_REG_SSR, ioasic_ssr); + + fast_wmb(); + ioasic_write(IO_REG_SCSI_SCR, 0); + ioasic_write(IO_REG_SCSI_DMA_P, vaddress << 3); /* prepare for next page */ - *scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3; - *ioasic_ssr |= (SCSI_DMA_DIR | SCSI_DMA_EN); + scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3; + ioasic_write(IO_REG_SCSI_DMA_BP, scsi_next_ptr); + + ioasic_ssr |= (IO_SSR_SCSI_DMA_DIR | IO_SSR_SCSI_DMA_EN); + fast_wmb(); + ioasic_write(IO_REG_SSR, ioasic_ssr); + fast_iob(); + spin_unlock_irqrestore(&ioasic_ssr_lock, flags); } -static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length) +static void dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length) { + u32 scsi_next_ptr, ioasic_ssr; + unsigned long flags; + if (vaddress & 3) - panic("dec_efs.c: unable to handle partial word transfers, yet..."); + panic("dec_esp.c: unable to handle partial word transfers, yet..."); dma_cache_wback_inv((unsigned long) phys_to_virt(vaddress), length); - *ioasic_ssr &= ~(SCSI_DMA_DIR | SCSI_DMA_EN); - *scsi_scr = 0; - *scsi_dma_ptr = vaddress << 3; + spin_lock_irqsave(&ioasic_ssr_lock, flags); + + fast_mb(); + ioasic_ssr = ioasic_read(IO_REG_SSR); + + ioasic_ssr &= ~(IO_SSR_SCSI_DMA_DIR | IO_SSR_SCSI_DMA_EN); + ioasic_write(IO_REG_SSR, ioasic_ssr); + + fast_wmb(); + ioasic_write(IO_REG_SCSI_SCR, 0); + ioasic_write(IO_REG_SCSI_DMA_P, vaddress << 3); /* prepare for next page */ - *scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3; - *ioasic_ssr |= SCSI_DMA_EN; + scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3; + ioasic_write(IO_REG_SCSI_DMA_BP, scsi_next_ptr); + + ioasic_ssr |= IO_SSR_SCSI_DMA_EN; + fast_wmb(); + ioasic_write(IO_REG_SSR, ioasic_ssr); + fast_iob(); + spin_unlock_irqrestore(&ioasic_ssr_lock, flags); } static void dma_ints_off(struct NCR_ESP *esp) @@ -408,71 +426,67 @@ static int dma_irq_p(struct NCR_ESP *esp) { - return (esp->eregs->esp_status & ESP_STAT_INTR); + return (esp->eregs->esp_status & ESP_STAT_INTR); } static int dma_ports_p(struct NCR_ESP *esp) { -/* - * FIXME: what's this good for? - */ + /* + * FIXME: what's this good for? + */ return 1; } -static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) +static void dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write) { - /* - * On the Sparc, DMA_ST_WRITE means "move data from device to memory" - * so when (write) is true, it actually means READ! - */ - if (write) { - dma_init_read(esp, addr, count); - } else { - dma_init_write(esp, addr, count); - } + /* + * DMA_ST_WRITE means "move data from device to memory" + * so when (write) is true, it actually means READ! + */ + if (write) + dma_init_read(esp, addr, count); + else + dma_init_write(esp, addr, count); } -/* - * These aren't used yet - */ static void dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp) { - sp->SCp.have_data_in = PHYSADDR(sp->SCp.buffer); - sp->SCp.ptr = (char *) ((unsigned long) sp->SCp.have_data_in); + sp->SCp.ptr = (char *)virt_to_phys(sp->request_buffer); } static void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd * sp) { - int sz = sp->SCp.buffers_residual; - struct mmu_sglist *sg = (struct mmu_sglist *) sp->SCp.buffer; + int sz = sp->SCp.buffers_residual; + struct scatterlist *sg = sp->SCp.buffer; - while (sz >= 0) { - sg[sz].dvma_addr = PHYSADDR(sg[sz].addr); - sz--; - } - sp->SCp.ptr = (char *) ((unsigned long) sp->SCp.buffer->dma_address); + while (sz >= 0) { + sg[sz].dma_address = virt_to_phys(sg[sz].address); + sz--; + } + sp->SCp.ptr = (char *)(sp->SCp.buffer->dma_address); } static void dma_advance_sg(Scsi_Cmnd * sp) { - sp->SCp.ptr = (char *) ((unsigned long) sp->SCp.buffer->dma_address); + sp->SCp.ptr = (char *)(sp->SCp.buffer->dma_address); } static void pmaz_dma_drain(struct NCR_ESP *esp) { - memcpy((void *) (KSEG0ADDR(esp_virt_buffer)), - (void *) ( esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE), + memcpy(phys_to_virt(esp_virt_buffer), + (void *)KSEG1ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE), scsi_current_length); } -static void pmaz_dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length) +static void pmaz_dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length) { - volatile int *dmareg = (volatile int *) (esp->slot + DEC_SCSI_DMAREG); + volatile u32 *dmareg = + (volatile u32 *)KSEG1ADDR(esp->slot + DEC_SCSI_DMAREG); if (length > ESP_TGT_DMA_SIZE) length = ESP_TGT_DMA_SIZE; - *dmareg = TC_ESP_DMA_ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE); + *dmareg = TC_ESP_DMA_ADDR(ESP_TGT_DMA_SIZE); iob(); @@ -480,15 +494,16 @@ scsi_current_length = length; } -static void pmaz_dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length) +static void pmaz_dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length) { - volatile int *dmareg = (volatile int *) ( esp->slot + DEC_SCSI_DMAREG ); + volatile u32 *dmareg = + (volatile u32 *)KSEG1ADDR(esp->slot + DEC_SCSI_DMAREG); - memcpy((void *) (esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE), - KSEG0ADDR((void *) vaddress), length); + memcpy((void *)KSEG1ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE), + phys_to_virt(vaddress), length); - *dmareg = TC_ESP_DMAR_WRITE | - TC_ESP_DMA_ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE); + wmb(); + *dmareg = TC_ESP_DMAR_WRITE | TC_ESP_DMA_ADDR(ESP_TGT_DMA_SIZE); iob(); } @@ -501,22 +516,19 @@ { } -static void pmaz_dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) +static void pmaz_dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write) { /* - * On the Sparc, DMA_ST_WRITE means "move data from device to memory" + * DMA_ST_WRITE means "move data from device to memory" * so when (write) is true, it actually means READ! */ - if (write) { + if (write) pmaz_dma_init_read(esp, addr, count); - } else { + else pmaz_dma_init_write(esp, addr, count); - } } static void pmaz_dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp) { - sp->SCp.have_data_in = (int) sp->SCp.ptr = - (char *) KSEG0ADDR((sp->request_buffer)); + sp->SCp.ptr = (char *)virt_to_phys(sp->request_buffer); } - diff -urN linux-2.4.21-bk37/drivers/scsi/sgiwd93.c linux-2.4.21-bk38/drivers/scsi/sgiwd93.c --- linux-2.4.21-bk37/drivers/scsi/sgiwd93.c 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.21-bk38/drivers/scsi/sgiwd93.c 2003-08-24 02:56:14.000000000 -0700 @@ -24,9 +24,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include @@ -70,7 +70,6 @@ return value; } -/* XXX woof! */ static void sgiwd93_intr(int irq, void *dev_id, struct pt_regs *regs) { unsigned long flags; @@ -123,10 +122,10 @@ * IMHO a better fix would be, not to do these * dma setups in the first place */ - if (cmd->SCp.ptr == NULL) + if (cmd->SCp.ptr == NULL || cmd->SCp.this_residual == 0) return 1; - fill_hpc_entries (&hcp, cmd->SCp.ptr,cmd->SCp.this_residual); + fill_hpc_entries (&hcp, cmd->SCp.ptr, cmd->SCp.this_residual); /* To make sure, if we trip an HPC bug, that we transfer * every single byte, we tag on an extra zero length dma @@ -230,7 +229,7 @@ sgiwd93_host->base = (unsigned long) hregs; sgiwd93_host->irq = SGI_WD93_0_IRQ; - buf = (uchar *) get_free_page(GFP_KERNEL); + buf = (uchar *) get_zeroed_page(GFP_KERNEL); if (!buf) { printk(KERN_WARNING "sgiwd93: Could not allocate memory for host0 buffer.\n"); scsi_unregister(sgiwd93_host); @@ -257,14 +256,14 @@ return 0; } /* set up second controller on the Indigo2 */ - if(!sgi_guiness) { + if(ip22_is_fullhouse()) { sgiwd93_host1 = scsi_register(SGIblows, sizeof(struct WD33C93_hostdata)); if(sgiwd93_host1 != NULL) { sgiwd93_host1->base = (unsigned long) hregs1; sgiwd93_host1->irq = SGI_WD93_1_IRQ; - buf = (uchar *) get_free_page(GFP_KERNEL); + buf = (uchar *) get_zeroed_page(GFP_KERNEL); if (!buf) { printk(KERN_WARNING "sgiwd93: Could not allocate memory for host1 buffer.\n"); scsi_unregister(sgiwd93_host1); @@ -314,7 +313,7 @@ free_irq(SGI_WD93_0_IRQ, sgiwd93_intr); free_page(KSEG0ADDR(hdata->dma_bounce_buffer)); wd33c93_release(); - if(!sgi_guiness) { + if(ip22_is_fullhouse()) { free_irq(SGI_WD93_1_IRQ, sgiwd93_intr); free_page(KSEG0ADDR(hdata1->dma_bounce_buffer)); wd33c93_release(); diff -urN linux-2.4.21-bk37/drivers/sgi/Config.in linux-2.4.21-bk38/drivers/sgi/Config.in --- linux-2.4.21-bk37/drivers/sgi/Config.in 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.21-bk38/drivers/sgi/Config.in 1969-12-31 16:00:00.000000000 -0800 @@ -1,17 +0,0 @@ -# -# Character device configuration -# -mainmenu_option next_comment -comment 'SGI devices' - -bool 'SGI Zilog85C30 serial support' CONFIG_SGI_SERIAL -if [ "$CONFIG_SGI_SERIAL" = "y" ]; then - bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE -fi -bool 'SGI DS1286 RTC support' CONFIG_SGI_DS1286 - -if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'SGI Newport Graphics support (EXPERIMENTAL)' CONFIG_SGI_NEWPORT_GFX -fi - -endmenu diff -urN linux-2.4.21-bk37/drivers/sgi/Makefile linux-2.4.21-bk38/drivers/sgi/Makefile --- linux-2.4.21-bk37/drivers/sgi/Makefile 2001-04-13 20:26:07.000000000 -0700 +++ linux-2.4.21-bk38/drivers/sgi/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,19 +0,0 @@ -# -# Makefile for the linux kernel. -# -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# -# Note 2! The CFLAGS definitions are now in the main makefile... - -L_TARGET := sgi.a - -# -# Character and Audio devices for SGI machines. -# -subdir-y += char -subdir-m += char -obj-y += char/sgichar.o - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/drivers/sgi/char/Makefile linux-2.4.21-bk38/drivers/sgi/char/Makefile --- linux-2.4.21-bk37/drivers/sgi/char/Makefile 2002-08-02 17:39:44.000000000 -0700 +++ linux-2.4.21-bk38/drivers/sgi/char/Makefile 1969-12-31 16:00:00.000000000 -0800 @@ -1,19 +0,0 @@ -# -# Makefile for the linux kernel. -# -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# -# Note 2! The CFLAGS definitions are now in the main makefile... - -O_TARGET := sgichar.o - -export-objs := newport.o rrm.o shmiq.o sgicons.o usema.o -obj-y := newport.o shmiq.o sgicons.o usema.o streamable.o - -obj-$(CONFIG_SGI_SERIAL) += sgiserial.o -obj-$(CONFIG_SGI_DS1286) += ds1286.o -obj-$(CONFIG_SGI_NEWPORT_GFX) += graphics.o rrm.o - -include $(TOPDIR)/Rules.make diff -urN linux-2.4.21-bk37/drivers/sgi/char/ds1286.c linux-2.4.21-bk38/drivers/sgi/char/ds1286.c --- linux-2.4.21-bk37/drivers/sgi/char/ds1286.c 2003-08-24 02:55:53.000000000 -0700 +++ linux-2.4.21-bk38/drivers/sgi/char/ds1286.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,529 +0,0 @@ -/* - * DS1286 Real Time Clock interface for Linux - * - * Copyright (C) 1998, 1999, 2000 Ralf Baechle - * - * Based on code written by Paul Gortmaker. - * - * This driver allows use of the real time clock (built into nearly all - * computers) from user space. It exports the /dev/rtc interface supporting - * various ioctl() and also the /proc/rtc pseudo-file for status - * information. - * - * The ioctls can be used to set the interrupt behaviour and generation rate - * from the RTC via IRQ 8. Then the /dev/rtc interface can be used to make - * use of these timer interrupts, be they interval or alarm based. - * - * The /dev/rtc interface will block on reads until an interrupt has been - * received. If a RTC interrupt has already happened, it will output an - * unsigned long and then block. The output value contains the interrupt - * status in the low byte and the number of interrupts since the last read - * in the remaining high bytes. The /dev/rtc interface can also be used with - * the select(2) call. - * - * 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. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define DS1286_VERSION "1.0" - -/* - * We sponge a minor off of the misc major. No need slurping - * up another valuable major dev number for this. If you add - * an ioctl, make sure you don't conflict with SPARC's RTC - * ioctls. - */ - -static DECLARE_WAIT_QUEUE_HEAD(ds1286_wait); - -static ssize_t ds1286_read(struct file *file, char *buf, - size_t count, loff_t *ppos); - -static int ds1286_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); - -static unsigned int ds1286_poll(struct file *file, poll_table *wait); - -void ds1286_get_alm_time (struct rtc_time *alm_tm); -void ds1286_get_time(struct rtc_time *rtc_tm); -int ds1286_set_time(struct rtc_time *rtc_tm); - -void set_rtc_irq_bit(unsigned char bit); -void clear_rtc_irq_bit(unsigned char bit); - -static inline unsigned char ds1286_is_updating(void); - -static spinlock_t ds1286_lock = SPIN_LOCK_UNLOCKED; - -/* - * Bits in rtc_status. (7 bits of room for future expansion) - */ - -#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ -#define RTC_TIMER_ON 0x02 /* missed irq timer active */ - -unsigned char ds1286_status; /* bitmapped status byte. */ -unsigned long ds1286_freq; /* Current periodic IRQ rate */ - -unsigned char days_in_mo[] = -{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - -/* - * Now all the various file operations that we export. - */ - -static ssize_t ds1286_read(struct file *file, char *buf, - size_t count, loff_t *ppos) -{ - return -EIO; -} - -static int ds1286_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - - struct rtc_time wtime; - - switch (cmd) { - case RTC_AIE_OFF: /* Mask alarm int. enab. bit */ - { - unsigned int flags; - unsigned char val; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - spin_lock_irqsave(&ds1286_lock, flags); - val = CMOS_READ(RTC_CMD); - val |= RTC_TDM; - CMOS_WRITE(val, RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - return 0; - } - case RTC_AIE_ON: /* Allow alarm interrupts. */ - { - unsigned int flags; - unsigned char val; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - spin_lock_irqsave(&ds1286_lock, flags); - val = CMOS_READ(RTC_CMD); - val &= ~RTC_TDM; - CMOS_WRITE(val, RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - return 0; - } - case RTC_WIE_OFF: /* Mask watchdog int. enab. bit */ - { - unsigned int flags; - unsigned char val; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - spin_lock_irqsave(&ds1286_lock, flags); - val = CMOS_READ(RTC_CMD); - val |= RTC_WAM; - CMOS_WRITE(val, RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - return 0; - } - case RTC_WIE_ON: /* Allow watchdog interrupts. */ - { - unsigned int flags; - unsigned char val; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - spin_lock_irqsave(&ds1286_lock, flags); - val = CMOS_READ(RTC_CMD); - val &= ~RTC_WAM; - CMOS_WRITE(val, RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - return 0; - } - case RTC_ALM_READ: /* Read the present alarm time */ - { - /* - * This returns a struct rtc_time. Reading >= 0xc0 - * means "don't care" or "match all". Only the tm_hour, - * tm_min, and tm_sec values are filled in. - */ - - ds1286_get_alm_time(&wtime); - break; - } - case RTC_ALM_SET: /* Store a time into the alarm */ - { - /* - * This expects a struct rtc_time. Writing 0xff means - * "don't care" or "match all". Only the tm_hour, - * tm_min and tm_sec are used. - */ - unsigned char hrs, min, sec; - struct rtc_time alm_tm; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - if (copy_from_user(&alm_tm, (struct rtc_time*)arg, - sizeof(struct rtc_time))) - return -EFAULT; - - hrs = alm_tm.tm_hour; - min = alm_tm.tm_min; - - if (hrs >= 24) - hrs = 0xff; - - if (min >= 60) - min = 0xff; - - BIN_TO_BCD(sec); - BIN_TO_BCD(min); - BIN_TO_BCD(hrs); - - spin_lock(&ds1286_lock); - CMOS_WRITE(hrs, RTC_HOURS_ALARM); - CMOS_WRITE(min, RTC_MINUTES_ALARM); - spin_unlock(&ds1286_lock); - - return 0; - } - case RTC_RD_TIME: /* Read the time/date from RTC */ - { - ds1286_get_time(&wtime); - break; - } - case RTC_SET_TIME: /* Set the RTC */ - { - struct rtc_time rtc_tm; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, - sizeof(struct rtc_time))) - return -EFAULT; - - return ds1286_set_time(&rtc_tm); - } - default: - return -EINVAL; - } - return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; -} - -/* - * We enforce only one user at a time here with the open/close. - * Also clear the previous interrupt data on an open, and clean - * up things on a close. - */ - -static int ds1286_open(struct inode *inode, struct file *file) -{ - spin_lock_irq(&ds1286_lock); - - if (ds1286_status & RTC_IS_OPEN) - goto out_busy; - - ds1286_status |= RTC_IS_OPEN; - - spin_lock_irq(&ds1286_lock); - return 0; - -out_busy: - spin_lock_irq(&ds1286_lock); - return -EBUSY; -} - -static int ds1286_release(struct inode *inode, struct file *file) -{ - ds1286_status &= ~RTC_IS_OPEN; - - return 0; -} - -static unsigned int ds1286_poll(struct file *file, poll_table *wait) -{ - poll_wait(file, &ds1286_wait, wait); - - return 0; -} - -/* - * The various file operations we support. - */ - -static struct file_operations ds1286_fops = { - llseek: no_llseek, - read: ds1286_read, - poll: ds1286_poll, - ioctl: ds1286_ioctl, - open: ds1286_open, - release: ds1286_release, -}; - -static struct miscdevice ds1286_dev= -{ - RTC_MINOR, - "rtc", - &ds1286_fops -}; - -int __init ds1286_init(void) -{ - printk(KERN_INFO "DS1286 Real Time Clock Driver v%s\n", DS1286_VERSION); - return misc_register(&ds1286_dev); -} - -static char *days[] = { - "***", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" -}; - -/* - * Info exported via "/proc/rtc". - */ -int get_ds1286_status(char *buf) -{ - char *p, *s; - struct rtc_time tm; - unsigned char hundredth, month, cmd, amode; - - p = buf; - - ds1286_get_time(&tm); - hundredth = CMOS_READ(RTC_HUNDREDTH_SECOND); - BCD_TO_BIN(hundredth); - - p += sprintf(p, - "rtc_time\t: %02d:%02d:%02d.%02d\n" - "rtc_date\t: %04d-%02d-%02d\n", - tm.tm_hour, tm.tm_min, tm.tm_sec, hundredth, - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); - - /* - * We implicitly assume 24hr mode here. Alarm values >= 0xc0 will - * match any value for that particular field. Values that are - * greater than a valid time, but less than 0xc0 shouldn't appear. - */ - ds1286_get_alm_time(&tm); - p += sprintf(p, "alarm\t\t: %s ", days[tm.tm_wday]); - if (tm.tm_hour <= 24) - p += sprintf(p, "%02d:", tm.tm_hour); - else - p += sprintf(p, "**:"); - - if (tm.tm_min <= 59) - p += sprintf(p, "%02d\n", tm.tm_min); - else - p += sprintf(p, "**\n"); - - month = CMOS_READ(RTC_MONTH); - p += sprintf(p, - "oscillator\t: %s\n" - "square_wave\t: %s\n", - (month & RTC_EOSC) ? "disabled" : "enabled", - (month & RTC_ESQW) ? "disabled" : "enabled"); - - amode = ((CMOS_READ(RTC_MINUTES_ALARM) & 0x80) >> 5) | - ((CMOS_READ(RTC_HOURS_ALARM) & 0x80) >> 6) | - ((CMOS_READ(RTC_DAY_ALARM) & 0x80) >> 7); - if (amode == 7) s = "each minute"; - else if (amode == 3) s = "minutes match"; - else if (amode == 1) s = "hours and minutes match"; - else if (amode == 0) s = "days, hours and minutes match"; - else s = "invalid"; - p += sprintf(p, "alarm_mode\t: %s\n", s); - - cmd = CMOS_READ(RTC_CMD); - p += sprintf(p, - "alarm_enable\t: %s\n" - "wdog_alarm\t: %s\n" - "alarm_mask\t: %s\n" - "wdog_alarm_mask\t: %s\n" - "interrupt_mode\t: %s\n" - "INTB_mode\t: %s_active\n" - "interrupt_pins\t: %s\n", - (cmd & RTC_TDF) ? "yes" : "no", - (cmd & RTC_WAF) ? "yes" : "no", - (cmd & RTC_TDM) ? "disabled" : "enabled", - (cmd & RTC_WAM) ? "disabled" : "enabled", - (cmd & RTC_PU_LVL) ? "pulse" : "level", - (cmd & RTC_IBH_LO) ? "low" : "high", - (cmd & RTC_IPSW) ? "unswapped" : "swapped"); - - return p - buf; -} - -/* - * Returns true if a clock update is in progress - */ -static inline unsigned char ds1286_is_updating(void) -{ - return CMOS_READ(RTC_CMD) & RTC_TE; -} - - -void ds1286_get_time(struct rtc_time *rtc_tm) -{ - unsigned char save_control; - unsigned int flags; - unsigned long uip_watchdog = jiffies; - - /* - * read RTC once any update in progress is done. The update - * can take just over 2ms. We wait 10 to 20ms. There is no need to - * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. - * If you need to know *exactly* when a second has started, enable - * periodic update complete interrupts, (via ioctl) and then - * immediately read /dev/rtc which will block until you get the IRQ. - * Once the read clears, read the RTC time (again via ioctl). Easy. - */ - - if (ds1286_is_updating() != 0) - while (jiffies - uip_watchdog < 2*HZ/100) - barrier(); - - /* - * Only the values that we read from the RTC are set. We leave - * tm_wday, tm_yday and tm_isdst untouched. Even though the - * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated - * by the RTC when initially set to a non-zero value. - */ - spin_lock_irqsave(&ds1286_lock, flags); - save_control = CMOS_READ(RTC_CMD); - CMOS_WRITE((save_control|RTC_TE), RTC_CMD); - - rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); - rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); - rtc_tm->tm_hour = CMOS_READ(RTC_HOURS) & 0x1f; - rtc_tm->tm_mday = CMOS_READ(RTC_DATE); - rtc_tm->tm_mon = CMOS_READ(RTC_MONTH) & 0x1f; - rtc_tm->tm_year = CMOS_READ(RTC_YEAR); - - CMOS_WRITE(save_control, RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - BCD_TO_BIN(rtc_tm->tm_sec); - BCD_TO_BIN(rtc_tm->tm_min); - BCD_TO_BIN(rtc_tm->tm_hour); - BCD_TO_BIN(rtc_tm->tm_mday); - BCD_TO_BIN(rtc_tm->tm_mon); - BCD_TO_BIN(rtc_tm->tm_year); - - /* - * Account for differences between how the RTC uses the values - * and how they are defined in a struct rtc_time; - */ - if (rtc_tm->tm_year < 45) - rtc_tm->tm_year += 30; - if ((rtc_tm->tm_year += 40) < 70) - rtc_tm->tm_year += 100; - - rtc_tm->tm_mon--; -} - -int ds1286_set_time(struct rtc_time *rtc_tm) -{ - unsigned char mon, day, hrs, min, sec, leap_yr; - unsigned char save_control; - unsigned int yrs, flags; - - - yrs = rtc_tm->tm_year + 1900; - mon = rtc_tm->tm_mon + 1; /* tm_mon starts at zero */ - day = rtc_tm->tm_mday; - hrs = rtc_tm->tm_hour; - min = rtc_tm->tm_min; - sec = rtc_tm->tm_sec; - - if (yrs < 1970) - return -EINVAL; - - leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); - - if ((mon > 12) || (day == 0)) - return -EINVAL; - - if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) - return -EINVAL; - - if ((hrs >= 24) || (min >= 60) || (sec >= 60)) - return -EINVAL; - - if ((yrs -= 1940) > 255) /* They are unsigned */ - return -EINVAL; - - if (yrs >= 100) - yrs -= 100; - - BIN_TO_BCD(sec); - BIN_TO_BCD(min); - BIN_TO_BCD(hrs); - BIN_TO_BCD(day); - BIN_TO_BCD(mon); - BIN_TO_BCD(yrs); - - spin_lock_irqsave(&ds1286_lock, flags); - save_control = CMOS_READ(RTC_CMD); - CMOS_WRITE((save_control|RTC_TE), RTC_CMD); - - CMOS_WRITE(yrs, RTC_YEAR); - CMOS_WRITE(mon, RTC_MONTH); - CMOS_WRITE(day, RTC_DATE); - CMOS_WRITE(hrs, RTC_HOURS); - CMOS_WRITE(min, RTC_MINUTES); - CMOS_WRITE(sec, RTC_SECONDS); - CMOS_WRITE(0, RTC_HUNDREDTH_SECOND); - - CMOS_WRITE(save_control, RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - return 0; -} - -void ds1286_get_alm_time(struct rtc_time *alm_tm) -{ - unsigned char cmd; - unsigned int flags; - - /* - * Only the values that we read from the RTC are set. That - * means only tm_wday, tm_hour, tm_min. - */ - spin_lock_irqsave(&ds1286_lock, flags); - alm_tm->tm_min = CMOS_READ(RTC_MINUTES_ALARM) & 0x7f; - alm_tm->tm_hour = CMOS_READ(RTC_HOURS_ALARM) & 0x1f; - alm_tm->tm_wday = CMOS_READ(RTC_DAY_ALARM) & 0x07; - cmd = CMOS_READ(RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - BCD_TO_BIN(alm_tm->tm_min); - BCD_TO_BIN(alm_tm->tm_hour); - alm_tm->tm_sec = 0; -} diff -urN linux-2.4.21-bk37/drivers/sgi/char/gconsole.h linux-2.4.21-bk38/drivers/sgi/char/gconsole.h --- linux-2.4.21-bk37/drivers/sgi/char/gconsole.h 1997-12-10 10:31:11.000000000 -0800 +++ linux-2.4.21-bk38/drivers/sgi/char/gconsole.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,33 +0,0 @@ -/* - * This is a temporary measure, we should eventually migrate to - * Gert's generic graphic console code. - */ - -#define cmapsz 8192 -#define CHAR_HEIGHT 16 - -struct console_ops { - void (*set_origin)(unsigned short offset); - void (*hide_cursor)(void); - void (*set_cursor)(int currcons); - void (*get_scrmem)(int currcons); - void (*set_scrmem)(int currcons, long offset); - int (*set_get_cmap)(unsigned char *arg, int set); - void (*blitc)(unsigned short charattr, unsigned long addr); - void (*memsetw)(void *s, unsigned short c, unsigned int count); - void (*memcpyw)(unsigned short *to, unsigned short *from, unsigned int count); -}; - -void register_gconsole (struct console_ops *); - -/* This points to the system console */ -extern struct console_ops *gconsole; - -extern void gfx_init (const char **name); - -extern void __set_origin (unsigned short offset); -extern void hide_cursor (void); -extern unsigned char vga_font[]; - -extern void disable_gconsole (void); -extern void enable_gconsole (void); diff -urN linux-2.4.21-bk37/drivers/sgi/char/graphics.c linux-2.4.21-bk38/drivers/sgi/char/graphics.c --- linux-2.4.21-bk37/drivers/sgi/char/graphics.c 2002-11-28 15:53:14.000000000 -0800 +++ linux-2.4.21-bk38/drivers/sgi/char/graphics.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,376 +0,0 @@ -/* - * gfx.c: support for SGI's /dev/graphics, /dev/opengl - * - * Author: Miguel de Icaza (miguel@nuclecu.unam.mx) - * Ralf Baechle (ralf@gnu.org) - * Ulf Carlsson (ulfc@bun.falkenberg.se) - * - * On IRIX, /dev/graphics is [10, 146] - * /dev/opengl is [10, 147] - * - * From a mail with Mark J. Kilgard, /dev/opengl and /dev/graphics are - * the same thing, the use of /dev/graphics seems deprecated though. - * - * The reason that the original SGI programmer had to use only one - * device for all the graphic cards on the system will remain a - * mistery for the rest of our lives. Why some ioctls take a board - * number and some others not? Mistery. Why do they map the hardware - * registers into the user address space with an ioctl instead of - * mmap? Mistery too. Why they did not use the standard way of - * making ioctl constants and instead sticked a random constant? - * Mistery too. - * - * We implement those misterious things, and tried not to think about - * the reasons behind them. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "gconsole.h" -#include "graphics.h" -#include "usema.h" -#include -#include -#include -#include -#include