diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2001-01-31 22:22:27 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2001-01-31 22:22:27 +0000 |
commit | 825423e4c4f18289df2393951cfd2a7a31fc0464 (patch) | |
tree | 4ad80e981c3d9effa910d2247d118d254f9a5d09 /arch/ppc | |
parent | c4693dc4856ab907a5c02187a8d398861bebfc7e (diff) |
Merge with Linux 2.4.1.
Diffstat (limited to 'arch/ppc')
71 files changed, 7419 insertions, 3516 deletions
diff --git a/arch/ppc/8260_io/enet.c b/arch/ppc/8260_io/enet.c index e1ff3c092..77b0eb279 100644 --- a/arch/ppc/8260_io/enet.c +++ b/arch/ppc/8260_io/enet.c @@ -633,6 +633,9 @@ int __init scc_enet_init(void) /* Allocate some private information. */ cep = (struct scc_enet_private *)kmalloc(sizeof(*cep), GFP_KERNEL); + if (cep == NULL) + return -ENOMEM; + __clear_user(cep,sizeof(*cep)); spin_lock_init(&cep->lock); diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c index da3991ae3..c8c31bd42 100644 --- a/arch/ppc/8260_io/fcc_enet.c +++ b/arch/ppc/8260_io/fcc_enet.c @@ -1082,6 +1082,9 @@ int __init fec_enet_init(void) */ cep = (struct fcc_enet_private *) kmalloc(sizeof(*cep), GFP_KERNEL); + if (cep == NULL) + return -ENOMEM; + __clear_user(cep,sizeof(*cep)); spin_lock_init(&cep->lock); cep->fip = fip; diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c index b77cf32da..01eb2758b 100644 --- a/arch/ppc/8xx_io/enet.c +++ b/arch/ppc/8xx_io/enet.c @@ -652,7 +652,9 @@ int __init scc_enet_init(void) /* Allocate some private information. */ cep = (struct scc_enet_private *)kmalloc(sizeof(*cep), GFP_KERNEL); - /*memset(cep, 0, sizeof(*cep));*/ + if (cep == NULL) + return -ENOMEM; + __clear_user(cep,sizeof(*cep)); spin_lock_init(&cep->lock); diff --git a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c index 659576e8c..6e5e9e686 100644 --- a/arch/ppc/8xx_io/fec.c +++ b/arch/ppc/8xx_io/fec.c @@ -1459,6 +1459,9 @@ int __init fec_enet_init(void) /* Allocate some private information. */ fep = (struct fec_enet_private *)kmalloc(sizeof(*fep), GFP_KERNEL); + if (fep == NULL) + return -ENOMEM; + __clear_user(fep,sizeof(*fep)); /* Create an Ethernet device instance. diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index d4172ed4a..488766003 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -145,9 +145,6 @@ endif clean_config: rm -f .config arch/ppc/defconfig -gemini_config: clean_config - cp -f arch/ppc/configs/gemini_defconfig arch/ppc/defconfig - pmac_config: clean_config cp -f arch/ppc/configs/pmac_defconfig arch/ppc/defconfig diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile index 26961e8ea..32c2926a1 100644 --- a/arch/ppc/boot/Makefile +++ b/arch/ppc/boot/Makefile @@ -25,22 +25,12 @@ ZSZ = 0 IOFF = 0 ISZ = 0 -ifeq ($(CONFIG_ALL_PPC),y) -CONFIG_PREP=y -endif - ifeq ($(CONFIG_SMP),y) TFTPIMAGE=/tftpboot/zImage.prep.smp$(MSIZE) else TFTPIMAGE=/tftpboot/zImage.prep$(MSIZE) endif -ifeq ($(CONFIG_SMP),y) -TFTPSIMAGE=/tftpboot/sImage.smp -else -TFTPSIMAGE=/tftpboot/sImage -endif - ifeq ($(CONFIG_PPC64BRIDGE),y) MSIZE=.64 else @@ -81,8 +71,8 @@ zvmlinux.initrd: zvmlinux zvmlinux.initrd.tmp $@ rm zvmlinux.initrd.tmp -zImage: zvmlinux mkprep sImage -ifdef CONFIG_PREP +zImage: zvmlinux mkprep +ifdef CONFIG_ALL_PPC ./mkprep -pbp zvmlinux zImage endif ifdef CONFIG_APUS @@ -90,13 +80,8 @@ ifdef CONFIG_APUS gzip $(GZIP_FLAGS) vmapus endif -sImage: ../../../vmlinux -ifdef CONFIG_GEMINI - $(OBJCOPY) -I elf32-powerpc -O binary ../../../vmlinux sImage -endif - zImage.initrd: zvmlinux.initrd mkprep -ifdef CONFIG_PREP +ifdef CONFIG_ALL_PPC ./mkprep -pbp zvmlinux.initrd zImage.initrd endif @@ -128,18 +113,15 @@ mkprep : mkprep.c $(HOSTCC) -o mkprep mkprep.c znetboot : zImage -ifdef CONFIG_PREP +ifdef CONFIG_ALL_PPC cp zImage $(TFTPIMAGE) endif -ifdef CONFIG_GEMINI - cp sImage $(TFTPSIMAGE) -endif znetboot.initrd : zImage.initrd cp zImage.initrd $(TFTPIMAGE) clean: - rm -f vmlinux* zvmlinux* mkprep zImage* sImage* + rm -f vmlinux* zvmlinux* mkprep zImage* fastdep: $(TOPDIR)/scripts/mkdep *.[Sch] > .depend diff --git a/arch/ppc/boot/vreset.c b/arch/ppc/boot/vreset.c index c01361dc6..dfabd72e7 100644 --- a/arch/ppc/boot/vreset.c +++ b/arch/ppc/boot/vreset.c @@ -19,12 +19,16 @@ */ #include "iso_font.h" -#include <linux/delay.h> extern char *vidmem; extern int lines, cols; -/* estimate for delay */ -unsigned long loops_per_sec = 50000000;; + +static void mdelay(int ms) +{ + for (; ms > 0; --ms) + udelay(1000); +} + /* * VGA Register */ diff --git a/arch/ppc/chrpboot/Makefile b/arch/ppc/chrpboot/Makefile index f7ea3a3fa..9dbb7909d 100644 --- a/arch/ppc/chrpboot/Makefile +++ b/arch/ppc/chrpboot/Makefile @@ -23,11 +23,6 @@ LD_ARGS = -Ttext 0x00400000 OBJS = crt0.o start.o main.o misc.o ../coffboot/string.o ../coffboot/zlib.o image.o LIBS = $(TOPDIR)/lib/lib.a -ifeq ($(CONFIG_ALL_PPC),y) -# yes, we want to build chrp stuff -CONFIG_CHRP = y -endif - ifeq ($(CONFIG_SMP),y) TFTPIMAGE=/tftpboot/zImage.chrp.smp$(MSIZE) else @@ -37,10 +32,10 @@ endif all: $(TOPDIR)/zImage # -# Only build anything here if we're configured for CHRP +# Only build anything here if we're configured for ALL_PPC # -- cort # -ifeq ($(CONFIG_CHRP),y) +ifeq ($(CONFIG_ALL_PPC),y) znetboot: zImage cp zImage $(TFTPIMAGE) @@ -96,6 +91,7 @@ vmlinux.coff.initrd: clean: rm -f piggyback note addnote $(OBJS) zImage + rm -f zImage.rs6k zImage.initrd zImage.initrd.rs6k fastdep: $(TOPDIR)/scripts/mkdep *.[Sch] > .depend diff --git a/arch/ppc/coffboot/Makefile b/arch/ppc/coffboot/Makefile index 494026e42..2835e1f89 100644 --- a/arch/ppc/coffboot/Makefile +++ b/arch/ppc/coffboot/Makefile @@ -20,18 +20,13 @@ else MSIZE= endif -ifeq ($(CONFIG_ALL_PPC),y) -# yes, we want to build pmac stuff -CONFIG_PMAC = y -endif - ifeq ($(CONFIG_SMP),y) TFTPIMAGE=/tftpboot/zImage.pmac.smp$(MSIZE) else TFTPIMAGE=/tftpboot/zImage.pmac$(MSIZE) endif -ifeq ($(CONFIG_PMAC),y) +ifeq ($(CONFIG_ALL_PPC),y) chrpmain.o: chrpmain.c $(CC) $(CFLAGS) -DSYSMAP_OFFSET=0 -DSYSMAP_SIZE=0 -c chrpmain.c diff --git a/arch/ppc/coffboot/coffmain.c b/arch/ppc/coffboot/coffmain.c index b76ba5976..49e769f22 100644 --- a/arch/ppc/coffboot/coffmain.c +++ b/arch/ppc/coffboot/coffmain.c @@ -22,11 +22,18 @@ void gunzip(void *, int, unsigned char *, int *); #define get_32be(x) (*(unsigned *)(x)) #define RAM_START 0xc0000000 -#define PROG_START RAM_START #define RAM_END (RAM_START + 0x800000) /* only 8M mapped with BATs */ +#define PROG_START RAM_START +#define PROG_SIZE 0x00400000 + +#define SCRATCH_SIZE (128 << 10) + char *avail_ram; -char *end_avail; +char *begin_avail, *end_avail; +char *avail_high; +unsigned int heap_use; +unsigned int heap_max; extern char _start[], _end[]; extern char image_data[]; @@ -34,6 +41,7 @@ extern int image_len; extern char initrd_data[]; extern int initrd_len; +char heap[SCRATCH_SIZE]; boot(int a1, int a2, void *prom) { @@ -58,16 +66,18 @@ boot(int a1, int a2, void *prom) im = image_data; len = image_len; /* claim 3MB starting at 0 */ - claim(0, 3 << 20, 0); + claim(0, PROG_SIZE, 0); dst = (void *) RAM_START; if (im[0] == 0x1f && im[1] == 0x8b) { - /* claim 512kB for scratch space */ - avail_ram = claim(0, 512 << 10, 0x10) + RAM_START; - end_avail = avail_ram + (512 << 10); - printf("avail_ram = %x\n", avail_ram); + /* claim some memory for scratch space */ + begin_avail = avail_high = avail_ram = heap; + end_avail = heap + sizeof(heap); + printf("heap at 0x%x\n", avail_ram); printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len); - gunzip(dst, 3 << 20, im, &len); + gunzip(dst, PROG_SIZE, im, &len); printf("done %u bytes\n", len); + printf("%u bytes of heap consumed, max in use %u\n", + avail_high - begin_avail, heap_max); } else { memmove(dst, im, len); } @@ -78,9 +88,6 @@ boot(int a1, int a2, void *prom) sa = (unsigned long)PROG_START; printf("start address = 0x%x\n", sa); -#if 0 - pause(); -#endif (*(void (*)())sa)(a1, a2, prom); printf("returned?\n"); @@ -114,13 +121,33 @@ void make_bi_recs(unsigned long addr) rec = (struct bi_record *)((unsigned long)rec + rec->size); } +struct memchunk { + unsigned int size; + struct memchunk *next; +}; + +static struct memchunk *freechunks; + void *zalloc(void *x, unsigned items, unsigned size) { - void *p = avail_ram; + void *p; + struct memchunk **mpp, *mp; size *= items; size = (size + 7) & -8; + heap_use += size; + if (heap_use > heap_max) + heap_max = heap_use; + for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) { + if (mp->size == size) { + *mpp = mp->next; + return mp; + } + } + p = avail_ram; avail_ram += size; + if (avail_ram > avail_high) + avail_high = avail_ram; if (avail_ram > end_avail) { printf("oops... out of memory\n"); pause(); @@ -130,6 +157,17 @@ void *zalloc(void *x, unsigned items, unsigned size) void zfree(void *x, void *addr, unsigned nb) { + struct memchunk *mp = addr; + + nb = (nb + 7) & -8; + heap_use -= nb; + if (avail_ram == addr + nb) { + avail_ram = addr; + return; + } + mp->size = nb; + mp->next = freechunks; + freechunks = mp; } #define HEAD_CRC 2 diff --git a/arch/ppc/config.in b/arch/ppc/config.in index 34606f99a..3b4c2c141 100644 --- a/arch/ppc/config.in +++ b/arch/ppc/config.in @@ -24,21 +24,24 @@ mainmenu_option next_comment comment 'Platform support' define_bool CONFIG_PPC y choice 'Processor Type' \ - "6xx/7xx/7400 CONFIG_6xx \ + "6xx/7xx/74xx/8260 CONFIG_6xx \ 4xx CONFIG_4xx \ POWER3 CONFIG_POWER3 \ POWER4 CONFIG_POWER4 \ - 8260 CONFIG_8260 \ 8xx CONFIG_8xx" 6xx +if [ "$CONFIG_6xx" = "y" ]; then + bool 'MPC8260 CPM Support' CONFIG_8260 +fi + if [ "$CONFIG_POWER3" = "y" -o "$CONFIG_POWER4" = "y" ]; then define_bool CONFIG_PPC64BRIDGE y define_bool CONFIG_ALL_PPC y fi - + if [ "$CONFIG_8260" = "y" ]; then - define_bool CONFIG_6xx y define_bool CONFIG_SERIAL_CONSOLE y + bool 'Support for EST8260' CONFIG_EST8260 fi if [ "$CONFIG_4xx" = "y" ]; then @@ -59,25 +62,32 @@ if [ "$CONFIG_8xx" = "y" ]; then TQM860 CONFIG_TQM860 \ MBX CONFIG_MBX \ WinCept CONFIG_WINCEPT" RPX-Lite + + if [ "$CONFIG_TQM8xxL" = "y" ]; then + bool 'FPS850 Mainboard' CONFIG_FPS850 + fi fi -if [ "$CONFIG_6xx" = "y" ]; then + +if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "n" ]; then choice 'Machine Type' \ "PowerMac/PReP/MTX/CHRP CONFIG_ALL_PPC \ - Gemini CONFIG_GEMINI \ - EST8260 CONFIG_EST8260 \ APUS CONFIG_APUS" PowerMac/PReP/MTX/CHRP fi +if [ "$CONFIG_PPC64BRIDGE" != "y" ]; then + bool 'Workarounds for PPC601 bugs' CONFIG_PPC601_SYNC_FIX +fi + if [ "$CONFIG_8xx" = "y" -o "$CONFIG_8260" = "y" ]; then define_bool CONFIG_ALL_PPC n fi -if [ "$CONFIG_TQM8xxL" = "y" ]; then - bool 'FPS850 Mainboard' CONFIG_FPS850 +bool 'Symmetric multi-processing support' CONFIG_SMP +if [ "$CONFIG_SMP" = "y" ]; then + bool ' Distribute interrupts on all CPUs by default' CONFIG_IRQ_ALL_CPUS fi -bool 'Symmetric multi-processing support' CONFIG_SMP -if [ "$CONFIG_6xx" = "y" ];then +if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "n" ];then bool 'AltiVec Support' CONFIG_ALTIVEC fi @@ -106,14 +116,14 @@ define_bool CONFIG_MCA n if [ "$CONFIG_APUS" = "y" -o "$CONFIG_4xx" = "y" -o \ "$CONFIG_8260" = "y" ]; then - define_bool CONFIG_PCI n + define_bool CONFIG_PCI n else - if [ "$CONFIG_8xx" = "y" ]; then - bool 'QSpan PCI' CONFIG_PCI_QSPAN - define_bool CONFIG_PCI $CONFIG_PCI_QSPAN - else - define_bool CONFIG_PCI y - fi + if [ "$CONFIG_8xx" = "y" ]; then + bool 'QSpan PCI' CONFIG_PCI_QSPAN + define_bool CONFIG_PCI $CONFIG_PCI_QSPAN + else + define_bool CONFIG_PCI y + fi fi bool 'Networking support' CONFIG_NET @@ -123,40 +133,34 @@ bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT # only elf supported, a.out is not -- Cort if [ "$CONFIG_PROC_FS" = "y" ]; then - define_bool CONFIG_KCORE_ELF y + define_bool CONFIG_KCORE_ELF y fi define_bool CONFIG_BINFMT_ELF y define_bool CONFIG_KERNEL_ELF y tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC source drivers/pci/Config.in -source drivers/zorro/Config.in bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG if [ "$CONFIG_HOTPLUG" = "y" ]; then - source drivers/pcmcia/Config.in + source drivers/pcmcia/Config.in else - define_bool CONFIG_PCMCIA n + define_bool CONFIG_PCMCIA n fi source drivers/parport/Config.in if [ "$CONFIG_4xx" != "y" -a "$CONFIG_8xx" != "y" ]; then - bool 'Support for VGA Console' CONFIG_VGA_CONSOLE - bool 'Support for frame buffer devices' CONFIG_FB - if [ "$CONFIG_FB" = "y" ]; then - bool 'Backward compatibility mode for Xpmac' CONFIG_FB_COMPAT_XPMAC - fi - tristate 'Support for /dev/rtc' CONFIG_PPC_RTC - bool 'Support for Open Firmware device tree in /proc' CONFIG_PROC_DEVICETREE - bool 'Support for early boot text console (BootX only)' CONFIG_BOOTX_TEXT - bool 'Support for Motorola Hot Swap' CONFIG_MOTOROLA_HOTSWAP fi -if [ "$CONFIG_PREP" = "y" -o "$CONFIG_ALL_PPC" = "y" ]; then - bool 'PReP bootloader kernel arguments' CONFIG_CMDLINE_BOOL +if [ "$CONFIG_ALL_PPC" = "y" ]; then + bool 'Support for Open Firmware device tree in /proc' CONFIG_PROC_DEVICETREE + bool 'Support for RTAS (RunTime Abstraction Services) in /proc' CONFIG_PPC_RTAS + bool 'Support for early boot text console (BootX or OpenFirmware only)' CONFIG_BOOTX_TEXT + bool 'Support for PReP Residual Data' CONFIG_PREP_RESIDUAL + bool 'Default bootloader kernel arguments' CONFIG_CMDLINE_BOOL if [ "$CONFIG_CMDLINE_BOOL" = "y" ] ; then string 'Initial kernel command string' CONFIG_CMDLINE "console=ttyS0,9600 console=tty0 root=/dev/sda2" fi @@ -181,6 +185,7 @@ if [ "$CONFIG_APUS" = "y" ]; then fi bool 'Use power LED as a heartbeat' CONFIG_HEARTBEAT bool '/proc/hardware support' CONFIG_PROC_HARDWARE + source drivers/zorro/Config.in fi endmenu @@ -254,7 +259,13 @@ endmenu mainmenu_option next_comment comment 'Console drivers' -source drivers/video/Config.in +if [ "$CONFIG_4xx" != "y" -a "$CONFIG_8xx" != "y" ]; then + bool 'Support for VGA Console' CONFIG_VGA_CONSOLE +fi + source drivers/video/Config.in +if [ "$CONFIG_FB" = "y" -a "$CONFIG_ALL_PPC" = "y" ]; then + bool 'Backward compatibility mode for Xpmac' CONFIG_FB_COMPAT_XPMAC +fi endmenu source drivers/input/Config.in @@ -267,29 +278,26 @@ if [ "$CONFIG_ALL_PPC" = "y" ]; then bool 'Support for CUDA based PowerMacs' CONFIG_ADB_CUDA bool 'Support for PMU based PowerMacs' CONFIG_ADB_PMU if [ "$CONFIG_ADB_PMU" = "y" ]; then - bool ' Power management support for PowerBooks' CONFIG_PMAC_PBOOK - # made a separate option since backlight may end up beeing used - # on non-powerbook machines (but only on PMU based ones AFAIK) - bool ' Backlight control for LCD screens' CONFIG_PMAC_BACKLIGHT + bool ' Power management support for PowerBooks' CONFIG_PMAC_PBOOK + # made a separate option since backlight may end up beeing used + # on non-powerbook machines (but only on PMU based ones AFAIK) + bool ' Backlight control for LCD screens' CONFIG_PMAC_BACKLIGHT fi bool 'Support for PowerMac floppy' CONFIG_MAC_FLOPPY tristate 'Support for PowerMac serial ports' CONFIG_MAC_SERIAL if [ "$CONFIG_MAC_SERIAL" = "y" ]; then - bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE + bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE fi bool 'Apple Desktop Bus (ADB) support' CONFIG_ADB if [ "$CONFIG_ADB" = "y" ]; then - bool ' Include MacIO (CHRP) ADB driver' CONFIG_ADB_MACIO - fi -fi -if [ "$CONFIG_ADB" = "y" ]; then - dep_bool ' Use input layer for ADB devices' CONFIG_INPUT_ADBHID $CONFIG_INPUT - if [ "$CONFIG_INPUT_ADBHID" = "y" ]; then - define_bool CONFIG_MAC_HID y - bool ' Support for ADB raw keycodes' CONFIG_MAC_ADBKEYCODES - bool ' Support for mouse button 2+3 emulation' CONFIG_MAC_EMUMOUSEBTN - else - bool ' Support for ADB keyboard (old driver)' CONFIG_ADB_KEYBOARD + bool ' Include MacIO (CHRP) ADB driver' CONFIG_ADB_MACIO + dep_bool ' Use input layer for ADB devices' CONFIG_INPUT_ADBHID $CONFIG_INPUT + if [ "$CONFIG_INPUT_ADBHID" = "y" ]; then + bool ' Support for ADB raw keycodes' CONFIG_MAC_ADBKEYCODES + bool ' Support for mouse button 2+3 emulation' CONFIG_MAC_EMUMOUSEBTN + else + bool ' Support for ADB keyboard (old driver)' CONFIG_ADB_KEYBOARD + fi fi fi endmenu diff --git a/arch/ppc/configs/apus_defconfig b/arch/ppc/configs/apus_defconfig index ed930fff2..69e25a9b3 100644 --- a/arch/ppc/configs/apus_defconfig +++ b/arch/ppc/configs/apus_defconfig @@ -11,9 +11,7 @@ CONFIG_EXPERIMENTAL=y # # Loadable module support # -CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set -CONFIG_KMOD=y +# CONFIG_MODULES is not set # # Platform support @@ -23,14 +21,14 @@ CONFIG_6xx=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set # CONFIG_8xx is not set -CONFIG_ALL_PPC=y -# CONFIG_GEMINI is not set -# CONFIG_EST8260 is not set -# CONFIG_APUS is not set +# CONFIG_8260 is not set +# CONFIG_ALL_PPC is not set +CONFIG_APUS=y +CONFIG_PPC601_SYNC_FIX=y # CONFIG_SMP is not set # CONFIG_ALTIVEC is not set +CONFIG_MACH_SPECIFIC=y # # General setup @@ -38,8 +36,10 @@ CONFIG_ALL_PPC=y # CONFIG_HIGHMEM is not set # CONFIG_MOL is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set -CONFIG_PCI=y +# CONFIG_MCA is not set +# CONFIG_PCI is not set CONFIG_NET=y CONFIG_SYSCTL=y CONFIG_SYSVIPC=y @@ -47,23 +47,35 @@ CONFIG_SYSVIPC=y CONFIG_KCORE_ELF=y CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y -CONFIG_BINFMT_MISC=m -# CONFIG_PCI_NAMES is not set -# CONFIG_HOTPLUG is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# # CONFIG_PCMCIA is not set # # Parallel port support # # CONFIG_PARPORT is not set -# CONFIG_VGA_CONSOLE is not set +CONFIG_PPC_RTC=y +CONFIG_FB_CONSOLE=y +CONFIG_AMIGA=y +CONFIG_ZORRO=y +CONFIG_AMIGAMOUSE=y +CONFIG_ABSTRACT_CONSOLE=y CONFIG_FB=y -CONFIG_FB_COMPAT_XPMAC=y -# CONFIG_PPC_RTC is not set -CONFIG_PROC_DEVICETREE=y -# CONFIG_BOOTX_TEXT is not set -# CONFIG_MOTOROLA_HOTSWAP is not set -# CONFIG_CMDLINE_BOOL is not set +CONFIG_AMIGA_BUILTIN_SERIAL=y +# CONFIG_M68K_PRINTER is not set +CONFIG_GVPIOEXT=y +# CONFIG_GVPIOEXT_LP is not set +CONFIG_GVPIOEXT_PLIP=y +CONFIG_MULTIFACE_III_TTY=y +# CONFIG_SERIAL_CONSOLE is not set +CONFIG_HEARTBEAT=y +CONFIG_PROC_HARDWARE=y +CONFIG_ZORRO_NAMES=y # # Memory Technology Devices (MTD) @@ -80,12 +92,14 @@ CONFIG_PROC_DEVICETREE=y # Block devices # # CONFIG_BLK_DEV_FD is not set +CONFIG_AMIGA_FLOPPY=y +CONFIG_AMIGA_Z2RAM=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_LOOP 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 @@ -106,21 +120,17 @@ CONFIG_BLK_DEV_INITRD=y # # Networking options # -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_NETLINK=y -# CONFIG_RTNETLINK is not set -# CONFIG_NETLINK_DEV is not set +# CONFIG_PACKET is not set +# CONFIG_NETLINK is not set # CONFIG_NETFILTER is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y -CONFIG_IP_MULTICAST=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_IP_MROUTE is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set @@ -131,7 +141,7 @@ CONFIG_IP_MULTICAST=y # # # CONFIG_IPX is not set -CONFIG_ATALK=m +# CONFIG_ATALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -151,9 +161,48 @@ CONFIG_ATALK=m # # 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_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI 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_GAYLE=y +CONFIG_BLK_DEV_IDEDOUBLER=y +CONFIG_BLK_DEV_BUDDHA=y +# 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 # # SCSI support @@ -165,7 +214,8 @@ CONFIG_SCSI=y # CONFIG_BLK_DEV_SD=y CONFIG_SD_EXTRA_DEVS=40 -CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SR_EXTRA_DEVS=2 @@ -176,29 +226,23 @@ CONFIG_SR_EXTRA_DEVS=2 # # CONFIG_SCSI_DEBUG_QUEUES is not set # CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_CONSTANTS=y +# 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_AIC7XXX=y -# CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT is not set -CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 -CONFIG_AIC7XXX_PROC_STATS=y -CONFIG_AIC7XXX_RESET_DELAY=15 +# CONFIG_SCSI_AIC7XXX 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 @@ -211,30 +255,18 @@ CONFIG_AIC7XXX_RESET_DELAY=15 # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set # CONFIG_SCSI_NCR53C7xx 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_SCSI_MESH=y -CONFIG_SCSI_MESH_SYNC_RATE=5 -CONFIG_SCSI_MAC53C94=y - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set +# CONFIG_SCSI_MESH is not set +# CONFIG_SCSI_MAC53C94 is not set # # Network device support @@ -245,34 +277,30 @@ CONFIG_NETDEVICES=y # ARCnet devices # # CONFIG_ARCNET is not set - -# -# Appletalk devices -# -# CONFIG_APPLETALK 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 # CONFIG_NET_SB1000 is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -CONFIG_MACE=y -CONFIG_BMAC=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set # CONFIG_GMAC is not set -# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set +CONFIG_ARIADNE=y +# CONFIG_NE2K_ZORRO is not set +CONFIG_A2065=y +CONFIG_HYDRA=y # 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 @@ -287,13 +315,16 @@ CONFIG_BMAC=y # CONFIG_FDDI is not set # CONFIG_HIPPI is not set CONFIG_PPP=y -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_ASYNC is not set -# CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PPP_DEFLATE is not set -# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_BSDCOMP=y # CONFIG_PPPOE is not set -# CONFIG_SLIP is not set +CONFIG_SLIP=y +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_SMART=y +# CONFIG_SLIP_MODE_SLIP6 is not set # # Wireless LAN (non-hamradio) @@ -336,44 +367,47 @@ CONFIG_PPP=y # # Console drivers # +# CONFIG_VGA_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_CLGEN=y +CONFIG_FB_PM2=y +CONFIG_FB_PM2_CVPPC=y # CONFIG_FB_CYBER2000 is not set -CONFIG_FB_OF=y -CONFIG_FB_CONTROL=y -CONFIG_FB_PLATINUM=y -CONFIG_FB_VALKYRIE=y -CONFIG_FB_CT65550=y -CONFIG_FB_IMSTT=y +CONFIG_FB_AMIGA=y +CONFIG_FB_AMIGA_OCS=y +CONFIG_FB_AMIGA_ECS=y +CONFIG_FB_AMIGA_AGA=y +CONFIG_FB_CYBER=y +CONFIG_FB_VIRGE=y +CONFIG_FB_RETINAZ3=y +# CONFIG_FB_FM2 is not set +# CONFIG_FB_OF is not set +# CONFIG_FB_CONTROL is not set +# CONFIG_FB_PLATINUM is not set +# CONFIG_FB_VALKYRIE is not set +# CONFIG_FB_CT65550 is not set +# CONFIG_FB_IMSTT is not set # CONFIG_FB_S3TRIO is not set # CONFIG_FB_VGA16 is not set -# CONFIG_FB_MATROX is not set -CONFIG_FB_ATY=y -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_3DFX is not set -# CONFIG_FB_SIS is not set # CONFIG_FB_VIRTUAL is not set # CONFIG_FBCON_ADVANCED is not set +CONFIG_FBCON_MFB=y CONFIG_FBCON_CFB8=y CONFIG_FBCON_CFB16=y CONFIG_FBCON_CFB24=y CONFIG_FBCON_CFB32=y -# CONFIG_FBCON_FONTWIDTH8_ONLY is not set -CONFIG_FBCON_FONTS=y -# CONFIG_FONT_8x8 is not set +CONFIG_FBCON_AFB=y +CONFIG_FBCON_ILBM=y +CONFIG_FBCON_FONTWIDTH8_ONLY=y +# CONFIG_FBCON_FONTS is not set +CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y -CONFIG_FONT_SUN8x16=y -CONFIG_FONT_SUN12x22=y -# CONFIG_FONT_6x11 is not set -# CONFIG_FONT_PEARL_8x8 is not set -# CONFIG_FONT_ACORN_8x8 is not set +CONFIG_FONT_PEARL_8x8=y # # Input core support @@ -383,23 +417,17 @@ CONFIG_FONT_SUN12x22=y # # Macintosh device drivers # -# CONFIG_ADB_CUDA is not set -# CONFIG_ADB_PMU is not set -CONFIG_MAC_FLOPPY=y -CONFIG_MAC_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set -# CONFIG_ADB is not set # # Character devices # CONFIG_VT=y CONFIG_VT_CONSOLE=y -CONFIG_SERIAL=m +CONFIG_SERIAL=y +# CONFIG_SERIAL_CONSOLE is not set # 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 @@ -427,7 +455,7 @@ CONFIG_UNIX98_PTY_COUNT=256 # # CONFIG_WATCHDOG is not set # CONFIG_INTEL_RNG is not set -CONFIG_NVRAM=y +# CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set @@ -449,24 +477,24 @@ CONFIG_NVRAM=y # File systems # # CONFIG_QUOTA is not set -CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set -# CONFIG_AFFS_FS is not set +CONFIG_AFFS_FS=y CONFIG_HFS_FS=y # CONFIG_BFS_FS is not set -CONFIG_FAT_FS=m -CONFIG_MSDOS_FS=m +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y # CONFIG_UMSDOS_FS is not set -CONFIG_VFAT_FS=m +CONFIG_VFAT_FS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set # CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set -# CONFIG_MINIX_FS is not set +CONFIG_MINIX_FS=y # CONFIG_NTFS_FS is not set # CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set @@ -474,7 +502,7 @@ 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_DEVPTS_FS is not set # CONFIG_QNX4FS_FS is not set # CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set @@ -493,7 +521,7 @@ CONFIG_EXT2_FS=y CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set # CONFIG_ROOT_NFS is not set -CONFIG_NFSD=y +# CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y @@ -505,8 +533,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -514,14 +540,15 @@ CONFIG_LOCKD=y # Partition Types # # CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y +CONFIG_AMIGA_PARTITION=y +# CONFIG_SMB_NLS is not set CONFIG_NLS=y # # Native Language Support # CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y +# 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 @@ -541,7 +568,7 @@ CONFIG_NLS_CODEPAGE_437=y # CONFIG_NLS_CODEPAGE_936 is not set # CONFIG_NLS_CODEPAGE_949 is not set # CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_ISO8859_1 is not set +CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set @@ -558,23 +585,7 @@ CONFIG_NLS_CODEPAGE_437=y # # Sound # -CONFIG_SOUND=y -# CONFIG_DMASOUND_AWACS is not set -# CONFIG_SOUND_CMPCI is not set -# CONFIG_SOUND_EMU10K1 is not set -# CONFIG_SOUND_FUSION is not set -# CONFIG_SOUND_CS4281 is not set -# CONFIG_SOUND_ES1370 is not set -# CONFIG_SOUND_ES1371 is not set -# CONFIG_SOUND_ESSSOLO1 is not set -# CONFIG_SOUND_MAESTRO is not set -# CONFIG_SOUND_SONICVIBES is not set -# CONFIG_SOUND_TRIDENT is not set -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set -# CONFIG_SOUND_VIA82CXXX is not set -# CONFIG_SOUND_OSS is not set -# CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND is not set # # USB support diff --git a/arch/ppc/configs/bseip_defconfig b/arch/ppc/configs/bseip_defconfig index f0ff611f4..82b7174bd 100644 --- a/arch/ppc/configs/bseip_defconfig +++ b/arch/ppc/configs/bseip_defconfig @@ -21,7 +21,6 @@ CONFIG_PPC=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set CONFIG_8xx=y CONFIG_SERIAL_CONSOLE=y # CONFIG_RPXLITE is not set @@ -32,6 +31,7 @@ CONFIG_BSEIP=y # CONFIG_TQM860 is not set # CONFIG_MBX is not set # CONFIG_WINCEPT is not set +CONFIG_PPC601_SYNC_FIX=y # CONFIG_ALL_PPC is not set # CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y @@ -43,7 +43,9 @@ CONFIG_MATH_EMULATION=y # CONFIG_HIGHMEM is not set # CONFIG_MOL is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set # CONFIG_PCI_QSPAN is not set # CONFIG_PCI is not set CONFIG_NET=y @@ -182,7 +184,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set -# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -190,7 +191,6 @@ CONFIG_NET_ETHERNET=y # 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 @@ -377,8 +377,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -395,6 +393,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # diff --git a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/common_defconfig index 5574ecbdb..210887de7 100644 --- a/arch/ppc/configs/common_defconfig +++ b/arch/ppc/configs/common_defconfig @@ -23,12 +23,11 @@ CONFIG_6xx=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set # CONFIG_8xx is not set +# CONFIG_8260 is not set CONFIG_ALL_PPC=y -# CONFIG_GEMINI is not set -# CONFIG_EST8260 is not set # CONFIG_APUS is not set +CONFIG_PPC601_SYNC_FIX=y # CONFIG_SMP is not set CONFIG_ALTIVEC=y @@ -36,9 +35,11 @@ CONFIG_ALTIVEC=y # General setup # # CONFIG_HIGHMEM is not set -# CONFIG_MOL is not set +CONFIG_MOL=y # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set CONFIG_PCI=y CONFIG_NET=y CONFIG_SYSCTL=y @@ -49,21 +50,24 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y CONFIG_BINFMT_MISC=m CONFIG_PCI_NAMES=y -# CONFIG_HOTPLUG is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# # CONFIG_PCMCIA is not set # # Parallel port support # # CONFIG_PARPORT is not set -CONFIG_VGA_CONSOLE=y -CONFIG_FB=y -CONFIG_FB_COMPAT_XPMAC=y CONFIG_PPC_RTC=y CONFIG_PROC_DEVICETREE=y +CONFIG_PPC_RTAS=y CONFIG_BOOTX_TEXT=y -# CONFIG_MOTOROLA_HOTSWAP is not set -# CONFIG_CMDLINE_BOOL is not set +CONFIG_PREP_RESIDUAL=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttyS0,9600 console=tty0 root=/dev/sda2" # # Memory Technology Devices (MTD) @@ -79,7 +83,7 @@ CONFIG_BOOTX_TEXT=y # # Block devices # -# CONFIG_BLK_DEV_FD is not set +CONFIG_BLK_DEV_FD=m # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set @@ -111,7 +115,8 @@ CONFIG_PACKET=y CONFIG_NETLINK=y # CONFIG_RTNETLINK is not set # CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y @@ -123,6 +128,34 @@ CONFIG_IP_MULTICAST=y # CONFIG_IP_MROUTE is not set # CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set @@ -239,6 +272,7 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_SD_EXTRA_DEVS=40 CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SR_EXTRA_DEVS=2 @@ -344,7 +378,6 @@ CONFIG_NET_ETHERNET=y CONFIG_MACE=y CONFIG_BMAC=y CONFIG_GMAC=y -# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -357,27 +390,28 @@ CONFIG_GMAC=y CONFIG_NET_PCI=y CONFIG_PCNET32=y # CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_AC3200 is not set # CONFIG_APRICOT is not set # CONFIG_CS89x0 is not set -CONFIG_DE4X5=y -# CONFIG_TULIP is not set +CONFIG_TULIP=y +CONFIG_DE4X5=m # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PM is not set # CONFIG_LNE390 is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set # CONFIG_NE3210 is not set # CONFIG_ES3210 is not set -# CONFIG_RTL8129 is not set # CONFIG_8139TOO is not set +# CONFIG_RTL8129 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set # CONFIG_WINBOND_840 is not set +# CONFIG_HAPPYMEAL is not set # CONFIG_NET_POCKET is not set # @@ -439,6 +473,7 @@ CONFIG_PPP_DEFLATE=y # # Console drivers # +CONFIG_VGA_CONSOLE=y # # Frame-buffer support @@ -460,7 +495,8 @@ CONFIG_FB_IMSTT=y CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y -CONFIG_FB_MATROX_G100=y +# CONFIG_FB_MATROX_G100 is not set +# CONFIG_FB_MATROX_G450 is not set # CONFIG_FB_MATROX_MULTIHEAD is not set CONFIG_FB_ATY=y CONFIG_FB_ATY128=y @@ -481,6 +517,7 @@ CONFIG_FONT_SUN12x22=y # CONFIG_FONT_6x11 is not set # CONFIG_FONT_PEARL_8x8 is not set # CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FB_COMPAT_XPMAC is not set # # Input core support @@ -498,15 +535,13 @@ CONFIG_INPUT_EVDEV=y # CONFIG_ADB_CUDA=y CONFIG_ADB_PMU=y -CONFIG_PMAC_PBOOK=y -CONFIG_PMAC_BACKLIGHT=y -CONFIG_MAC_FLOPPY=y -CONFIG_MAC_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set +# CONFIG_PMAC_PBOOK is not set +# CONFIG_PMAC_BACKLIGHT is not set +# CONFIG_MAC_FLOPPY is not set +CONFIG_MAC_SERIAL=m CONFIG_ADB=y CONFIG_ADB_MACIO=y CONFIG_INPUT_ADBHID=y -CONFIG_MAC_HID=y CONFIG_MAC_ADBKEYCODES=y CONFIG_MAC_EMUMOUSEBTN=y @@ -575,17 +610,17 @@ CONFIG_NVRAM=y # File systems # # CONFIG_QUOTA is not set -CONFIG_AUTOFS_FS=y -CONFIG_AUTOFS4_FS=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set +CONFIG_HFS_FS=m # CONFIG_BFS_FS is not set -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m # CONFIG_UMSDOS_FS is not set -CONFIG_VFAT_FS=y +CONFIG_VFAT_FS=m # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set @@ -631,8 +666,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -652,6 +685,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set CONFIG_NLS=y # @@ -678,7 +712,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_936 is not set # CONFIG_NLS_CODEPAGE_949 is not set # CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_ISO8859_1 is not set +CONFIG_NLS_ISO8859_1=m # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set @@ -695,9 +729,9 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Sound # -CONFIG_SOUND=y -CONFIG_DMASOUND_AWACS=y -CONFIG_DMASOUND=y +CONFIG_SOUND=m +CONFIG_DMASOUND_AWACS=m +CONFIG_DMASOUND=m # CONFIG_SOUND_CMPCI is not set # CONFIG_SOUND_EMU10K1 is not set # CONFIG_SOUND_FUSION is not set @@ -711,43 +745,14 @@ CONFIG_DMASOUND=y # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set # CONFIG_SOUND_VIA82CXXX is not set -CONFIG_SOUND_OSS=y -# CONFIG_SOUND_TRACEINIT is not set -# CONFIG_SOUND_DMAP is not set -# CONFIG_SOUND_AD1816 is not set -# CONFIG_SOUND_SGALAXY is not set -# CONFIG_SOUND_ADLIB is not set -# CONFIG_SOUND_ACI_MIXER is not set -CONFIG_SOUND_CS4232=m -# CONFIG_SOUND_SSCAPE is not set -# CONFIG_SOUND_GUS is not set -# CONFIG_SOUND_ICH is not set -# CONFIG_SOUND_VMIDI is not set -# CONFIG_SOUND_TRIX is not set -# CONFIG_SOUND_MSS is not set -# CONFIG_SOUND_MPU401 is not set -# CONFIG_SOUND_NM256 is not set -# CONFIG_SOUND_MAD16 is not set -# CONFIG_SOUND_PAS is not set -# CONFIG_PAS_JOYSTICK is not set -# CONFIG_SOUND_PSS is not set -# CONFIG_SOUND_SB is not set -# CONFIG_SOUND_AWE32_SYNTH is not set -# CONFIG_SOUND_WAVEFRONT is not set -# CONFIG_SOUND_MAUI is not set -# CONFIG_SOUND_YM3812 is not set -# CONFIG_SOUND_OPL3SA1 is not set -# CONFIG_SOUND_OPL3SA2 is not set -# CONFIG_SOUND_YMPCI is not set -# CONFIG_SOUND_UART6850 is not set -# CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set # # USB support # CONFIG_USB=y -CONFIG_USB_DEBUG=y +# CONFIG_USB_DEBUG is not set # # Miscellaneous USB options @@ -763,33 +768,69 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_OHCI=y # -# USB Devices +# USB Device Class drivers # +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +CONFIG_USB_ACM=m # CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +# CONFIG_USB_WACOM 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_AUDIO is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_SERIAL is not set + +# +# USB Multimedia devices +# # CONFIG_USB_IBMCAM is not set # CONFIG_USB_OV511 is not set -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_USS720 is not set +# CONFIG_USB_DSBR is not set # CONFIG_USB_DABUSB is not set + +# +# USB Network adaptors +# # CONFIG_USB_PLUSB is not set # CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_DSBR is not set -# CONFIG_USB_BLUETOOTH is not set # CONFIG_USB_NET1080 is not set # -# USB Human Interface Devices (HID) +# USB port drivers # -CONFIG_USB_HID=y -# CONFIG_USB_WACOM is not set +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_SERIAL_DEBUG 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=m +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB misc drivers +# +# CONFIG_USB_RIO500 is not set # # Kernel hacking diff --git a/arch/ppc/configs/est8260_defconfig b/arch/ppc/configs/est8260_defconfig index afb972c03..a4a44f0ab 100644 --- a/arch/ppc/configs/est8260_defconfig +++ b/arch/ppc/configs/est8260_defconfig @@ -17,21 +17,17 @@ CONFIG_EXPERIMENTAL=y # Platform support # CONFIG_PPC=y -# CONFIG_6xx is not set +CONFIG_6xx=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -CONFIG_8260=y # CONFIG_8xx is not set -CONFIG_6xx=y +CONFIG_8260=y CONFIG_SERIAL_CONSOLE=y -# CONFIG_ALL_PPC is not set -# CONFIG_GEMINI is not set CONFIG_EST8260=y -# CONFIG_APUS is not set +CONFIG_PPC601_SYNC_FIX=y # CONFIG_ALL_PPC is not set # CONFIG_SMP is not set -# CONFIG_ALTIVEC is not set CONFIG_MACH_SPECIFIC=y # @@ -40,7 +36,9 @@ CONFIG_MACH_SPECIFIC=y # CONFIG_HIGHMEM is not set # CONFIG_MOL is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set # CONFIG_PCI is not set CONFIG_NET=y CONFIG_SYSCTL=y @@ -57,12 +55,7 @@ CONFIG_KERNEL_ELF=y # Parallel port support # # CONFIG_PARPORT is not set -# CONFIG_VGA_CONSOLE is not set -# CONFIG_FB is not set # CONFIG_PPC_RTC is not set -# CONFIG_PROC_DEVICETREE is not set -# CONFIG_BOOTX_TEXT is not set -# CONFIG_MOTOROLA_HOTSWAP is not set # # Memory Technology Devices (MTD) @@ -184,7 +177,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set -# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -192,7 +184,6 @@ CONFIG_NET_ETHERNET=y # 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 @@ -250,6 +241,7 @@ CONFIG_NET_ETHERNET=y # # Console drivers # +# CONFIG_VGA_CONSOLE is not set # # Frame-buffer support @@ -379,8 +371,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -397,6 +387,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # diff --git a/arch/ppc/configs/ibmchrp_defconfig b/arch/ppc/configs/ibmchrp_defconfig new file mode 100644 index 000000000..652b94209 --- /dev/null +++ b/arch/ppc/configs/ibmchrp_defconfig @@ -0,0 +1,636 @@ +# +# Automatically generated by make menuconfig: don't edit +# +# CONFIG_UID16 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8260 is not set +# CONFIG_8xx is not set +CONFIG_ALL_PPC=y +# CONFIG_GEMINI is not set +# CONFIG_APUS is not set +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_SMP is not set +# CONFIG_ALTIVEC is not set + +# +# General setup +# +CONFIG_HIGHMEM=y +# CONFIG_MOL is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_MISC=y +CONFIG_PCI_NAMES=y +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +CONFIG_PPC_RTC=y +CONFIG_PROC_DEVICETREE=y +CONFIG_PPC_RTAS=y +# CONFIG_BOOTX_TEXT is not set +# CONFIG_PREP_RESIDUAL is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD 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_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +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=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK 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 is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_IPX is not set +# CONFIG_ATALK 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 + +# +# 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 +CONFIG_BLK_DEV_SD=y +CONFIG_SD_EXTRA_DEVS=40 +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_SR_EXTRA_DEVS=2 +CONFIG_CHR_DEV_SG=y +# 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_AIC7XXX 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_NCR53C8XX is not set +CONFIG_SCSI_SYM53C8XX=y +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 +CONFIG_SCSI_NCR53C8XX_SYNC=20 +# CONFIG_SCSI_NCR53C8XX_PROFILE is not set +# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set +# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set +# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT 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_SCSI_MESH is not set +# CONFIG_SCSI_MAC53C94 is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 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 +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=y +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +CONFIG_DE4X5=y +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PM is not set +# CONFIG_LNE390 is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_RTL8129 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI 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=y +# CONFIG_IBMTR is not set +CONFIG_IBMOL=y +# CONFIG_IBMLS is not set +# CONFIG_TMS380TR is not set +# CONFIG_SMCTR 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 + +# +# Console drivers +# +CONFIG_VGA_CONSOLE=y + +# +# 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_CYBER2000 is not set +CONFIG_FB_OF=y +# CONFIG_FB_CONTROL is not set +# CONFIG_FB_PLATINUM is not set +# CONFIG_FB_VALKYRIE is not set +# CONFIG_FB_CT65550 is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_S3TRIO is not set +# CONFIG_FB_VGA16 is not set +CONFIG_FB_MATROX=y +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G100=y +# CONFIG_FB_MATROX_G450 is not set +# CONFIG_FB_MATROX_MULTIHEAD is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_ATY128 is not set +CONFIG_FB_3DFX=y +# CONFIG_FB_SIS is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FBCON_ADVANCED is not set +CONFIG_FBCON_CFB8=y +CONFIG_FBCON_CFB16=y +CONFIG_FBCON_CFB24=y +CONFIG_FBCON_CFB32=y +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +CONFIG_FBCON_FONTS=y +# CONFIG_FONT_8x8 is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_SUN8x16=y +CONFIG_FONT_SUN12x22=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FB_COMPAT_XPMAC 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 + +# +# Macintosh device drivers +# +# CONFIG_ADB_CUDA is not set +# CONFIG_ADB_PMU is not set +# CONFIG_MAC_FLOPPY is not set +# CONFIG_MAC_SERIAL is not set +# CONFIG_ADB is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +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=y +# CONFIG_ATIXL_BUSMOUSE is not set +# CONFIG_LOGIBUSMOUSE is not set +# CONFIG_MS_BUSMOUSE is not set +CONFIG_MOUSE=y +CONFIG_PSMOUSE=y +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +CONFIG_NVRAM=y +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 + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +# CONFIG_UMSDOS_FS is not set +CONFIG_VFAT_FS=m +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_RAMFS is not set +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +# 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_SYSV_FS_WRITE is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_NFS_FS 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_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 + +# +# 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=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# 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_874 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_950 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_8 is not set +# CONFIG_NLS_ISO8859_9 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_UTF8 is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +CONFIG_MAGIC_SYSRQ=y +# CONFIG_KGDB is not set +CONFIG_XMON=y diff --git a/arch/ppc/configs/mbx_defconfig b/arch/ppc/configs/mbx_defconfig index 6230f5877..81829327a 100644 --- a/arch/ppc/configs/mbx_defconfig +++ b/arch/ppc/configs/mbx_defconfig @@ -21,7 +21,6 @@ CONFIG_PPC=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set CONFIG_8xx=y CONFIG_SERIAL_CONSOLE=y # CONFIG_RPXLITE is not set @@ -32,6 +31,7 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_TQM860 is not set CONFIG_MBX=y # CONFIG_WINCEPT is not set +CONFIG_PPC601_SYNC_FIX=y # CONFIG_ALL_PPC is not set # CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y @@ -43,7 +43,9 @@ CONFIG_MATH_EMULATION=y # CONFIG_HIGHMEM is not set # CONFIG_MOL is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set # CONFIG_PCI_QSPAN is not set # CONFIG_PCI is not set CONFIG_NET=y @@ -176,7 +178,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set -# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -184,7 +185,6 @@ CONFIG_NET_ETHERNET=y # 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 @@ -370,8 +370,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -388,6 +386,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # diff --git a/arch/ppc/configs/oak_defconfig b/arch/ppc/configs/oak_defconfig index f33966d35..d8f39c36e 100644 --- a/arch/ppc/configs/oak_defconfig +++ b/arch/ppc/configs/oak_defconfig @@ -12,7 +12,7 @@ CONFIG_EXPERIMENTAL=y # Loadable module support # CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set +CONFIG_MODVERSIONS=y CONFIG_KMOD=y # @@ -23,10 +23,10 @@ CONFIG_PPC=y CONFIG_4xx=y # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set # CONFIG_8xx is not set CONFIG_OAK=y # CONFIG_WALNUT is not set +CONFIG_PPC601_SYNC_FIX=y # CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y # CONFIG_MATH_EMULATION is not set @@ -37,7 +37,9 @@ CONFIG_MACH_SPECIFIC=y # CONFIG_HIGHMEM is not set # CONFIG_MOL is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set # CONFIG_PCI is not set CONFIG_NET=y CONFIG_SYSCTL=y @@ -171,7 +173,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set -# CONFIG_NCR885E is not set CONFIG_OAKNET=y # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -179,7 +180,6 @@ CONFIG_OAKNET=y # 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 @@ -366,8 +366,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -376,6 +374,7 @@ CONFIG_LOCKD=y # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # diff --git a/arch/ppc/configs/power3_defconfig b/arch/ppc/configs/power3_defconfig new file mode 100644 index 000000000..0deb9b5e8 --- /dev/null +++ b/arch/ppc/configs/power3_defconfig @@ -0,0 +1,662 @@ +# +# Automatically generated by make menuconfig: don't edit +# +# CONFIG_UID16 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +# CONFIG_6xx is not set +# CONFIG_4xx is not set +CONFIG_POWER3=y +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +CONFIG_PPC64BRIDGE=y +CONFIG_ALL_PPC=y +CONFIG_SMP=y + +# +# General setup +# +CONFIG_HIGHMEM=y +# CONFIG_MOL is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_MISC=y +CONFIG_PCI_NAMES=y +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_FIFO=y +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_AMIGA is not set +# CONFIG_PARPORT_MFC3 is not set +# CONFIG_PARPORT_ATARI is not set +# CONFIG_PARPORT_SUNBPP is not set +# CONFIG_PARPORT_OTHER is not set +# CONFIG_PARPORT_1284 is not set +# CONFIG_PPC_RTC is not set +CONFIG_PROC_DEVICETREE=y +CONFIG_PPC_RTAS=y +# CONFIG_BOOTX_TEXT is not set +# CONFIG_PREP_RESIDUAL is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD 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_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +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=y + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=y +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +CONFIG_MD_RAID5=y +# CONFIG_MD_BOOT is not set +# CONFIG_AUTODETECT_RAID is not set +CONFIG_BLK_DEV_LVM=y +CONFIG_LVM_PROC_FS=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK 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=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_INET_ECN is not set +CONFIG_SYN_COOKIES=y +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_IPX is not set +# CONFIG_ATALK 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 + +# +# 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 +CONFIG_BLK_DEV_SD=y +CONFIG_SD_EXTRA_DEVS=40 +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_SR_EXTRA_DEVS=2 +CONFIG_CHR_DEV_SG=y +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +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_AIC7XXX 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_PPA is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_NCR53C8XX is not set +CONFIG_SCSI_SYM53C8XX=y +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 +CONFIG_SCSI_NCR53C8XX_SYNC=20 +# CONFIG_SCSI_NCR53C8XX_PROFILE is not set +# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set +# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set +# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT 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_SCSI_MESH is not set +# CONFIG_SCSI_MAC53C94 is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 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 +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_OAKNET is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=y +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT 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_PM is not set +# CONFIG_LNE390 is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_RTL8129 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN 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=y +# CONFIG_IBMTR is not set +CONFIG_IBMOL=y +# CONFIG_IBMLS is not set +# CONFIG_TMS380TR is not set +# CONFIG_SMCTR 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 + +# +# Console drivers +# +# CONFIG_VGA_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_CYBER2000 is not set +CONFIG_FB_OF=y +# CONFIG_FB_CONTROL is not set +# CONFIG_FB_PLATINUM is not set +# CONFIG_FB_VALKYRIE is not set +# CONFIG_FB_CT65550 is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_S3TRIO is not set +# CONFIG_FB_VGA16 is not set +CONFIG_FB_MATROX=y +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G100=y +CONFIG_FB_MATROX_I2C=y +# CONFIG_FB_MATROX_MAVEN is not set +# CONFIG_FB_MATROX_G450 is not set +CONFIG_FB_MATROX_MULTIHEAD=y +# CONFIG_FB_ATY is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FBCON_ADVANCED is not set +CONFIG_FBCON_CFB8=y +CONFIG_FBCON_CFB16=y +CONFIG_FBCON_CFB24=y +CONFIG_FBCON_CFB32=y +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +CONFIG_FBCON_FONTS=y +# CONFIG_FONT_8x8 is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_SUN8x16=y +CONFIG_FONT_SUN12x22=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FB_COMPAT_XPMAC 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 + +# +# Macintosh device drivers +# +# CONFIG_ADB_CUDA is not set +# CONFIG_ADB_PMU is not set +# CONFIG_MAC_FLOPPY is not set +# CONFIG_MAC_SERIAL is not set +# CONFIG_ADB is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +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=2048 +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_PHILIPSPAR is not set +# CONFIG_I2C_ELV is not set +# CONFIG_I2C_VELLEMAN is not set +CONFIG_I2C_ALGOPCF=y +# CONFIG_I2C_ELEKTOR is not set +CONFIG_I2C_CHARDEV=y + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +CONFIG_MOUSE=y +CONFIG_PSMOUSE=y +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +CONFIG_NVRAM=y +# 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 + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV 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_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +# CONFIG_UMSDOS_FS is not set +CONFIG_VFAT_FS=y +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_RAMFS is not set +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS 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_SYSV_FS_WRITE is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_ROOT_NFS is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_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 + +# +# 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=y +# 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_874 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +CONFIG_NLS_ISO8859_1=y +# 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_8 is not set +# CONFIG_NLS_ISO8859_9 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_UTF8 is not set + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_DMASOUND_AWACS is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +CONFIG_SOUND_OSS=y +CONFIG_SOUND_TRACEINIT=y +# CONFIG_SOUND_DMAP is not set +# CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_SGALAXY is not set +# CONFIG_SOUND_ADLIB is not set +# CONFIG_SOUND_ACI_MIXER is not set +CONFIG_SOUND_CS4232=m +# CONFIG_SOUND_SSCAPE is not set +# CONFIG_SOUND_GUS is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_TRIX is not set +CONFIG_SOUND_MSS=m +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_NM256 is not set +# CONFIG_SOUND_MAD16 is not set +# CONFIG_SOUND_PAS is not set +# CONFIG_PAS_JOYSTICK is not set +# CONFIG_SOUND_PSS is not set +# CONFIG_SOUND_SB is not set +# CONFIG_SOUND_AWE32_SYNTH is not set +# CONFIG_SOUND_WAVEFRONT is not set +# CONFIG_SOUND_MAUI is not set +# CONFIG_SOUND_YM3812 is not set +# CONFIG_SOUND_OPL3SA1 is not set +# CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_YMPCI is not set +# CONFIG_SOUND_YMFPCI is not set +# CONFIG_SOUND_UART6850 is not set +# CONFIG_SOUND_AEDSP16 is not set +CONFIG_SOUND_TVMIXER=y + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +CONFIG_MAGIC_SYSRQ=y +# CONFIG_KGDB is not set +CONFIG_XMON=y diff --git a/arch/ppc/configs/rpxcllf_defconfig b/arch/ppc/configs/rpxcllf_defconfig index 78ee82230..258d3e79f 100644 --- a/arch/ppc/configs/rpxcllf_defconfig +++ b/arch/ppc/configs/rpxcllf_defconfig @@ -21,7 +21,6 @@ CONFIG_PPC=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set CONFIG_8xx=y CONFIG_SERIAL_CONSOLE=y # CONFIG_RPXLITE is not set @@ -32,6 +31,7 @@ CONFIG_RPXCLASSIC=y # CONFIG_TQM860 is not set # CONFIG_MBX is not set # CONFIG_WINCEPT is not set +CONFIG_PPC601_SYNC_FIX=y # CONFIG_ALL_PPC is not set # CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y @@ -43,7 +43,9 @@ CONFIG_MATH_EMULATION=y # CONFIG_HIGHMEM is not set # CONFIG_MOL is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set # CONFIG_PCI_QSPAN is not set # CONFIG_PCI is not set CONFIG_NET=y @@ -182,7 +184,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set -# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -190,7 +191,6 @@ CONFIG_NET_ETHERNET=y # 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 @@ -377,8 +377,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -395,6 +393,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # diff --git a/arch/ppc/configs/rpxlite_defconfig b/arch/ppc/configs/rpxlite_defconfig index 741d9265f..df00f5ace 100644 --- a/arch/ppc/configs/rpxlite_defconfig +++ b/arch/ppc/configs/rpxlite_defconfig @@ -21,7 +21,6 @@ CONFIG_PPC=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set CONFIG_8xx=y CONFIG_SERIAL_CONSOLE=y CONFIG_RPXLITE=y @@ -32,6 +31,7 @@ CONFIG_RPXLITE=y # CONFIG_TQM860 is not set # CONFIG_MBX is not set # CONFIG_WINCEPT is not set +CONFIG_PPC601_SYNC_FIX=y # CONFIG_ALL_PPC is not set # CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y @@ -43,7 +43,9 @@ CONFIG_MATH_EMULATION=y # CONFIG_HIGHMEM is not set # CONFIG_MOL is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set # CONFIG_PCI_QSPAN is not set # CONFIG_PCI is not set CONFIG_NET=y @@ -182,7 +184,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set -# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -190,7 +191,6 @@ CONFIG_NET_ETHERNET=y # 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 @@ -377,8 +377,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -395,6 +393,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # diff --git a/arch/ppc/configs/walnut_defconfig b/arch/ppc/configs/walnut_defconfig index c3e95c6ac..eef439fc2 100644 --- a/arch/ppc/configs/walnut_defconfig +++ b/arch/ppc/configs/walnut_defconfig @@ -12,7 +12,7 @@ CONFIG_EXPERIMENTAL=y # Loadable module support # CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set +CONFIG_MODVERSIONS=y CONFIG_KMOD=y # @@ -23,10 +23,10 @@ CONFIG_PPC=y CONFIG_4xx=y # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set # CONFIG_8xx is not set # CONFIG_OAK is not set CONFIG_WALNUT=y +CONFIG_PPC601_SYNC_FIX=y # CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y # CONFIG_MATH_EMULATION is not set @@ -37,7 +37,9 @@ CONFIG_MACH_SPECIFIC=y # CONFIG_HIGHMEM is not set # CONFIG_MOL is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set # CONFIG_PCI is not set CONFIG_NET=y CONFIG_SYSCTL=y @@ -171,7 +173,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set -# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -179,7 +180,6 @@ CONFIG_NET_ETHERNET=y # 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 @@ -369,8 +369,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -379,6 +377,7 @@ CONFIG_LOCKD=y # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig index 5574ecbdb..210887de7 100644 --- a/arch/ppc/defconfig +++ b/arch/ppc/defconfig @@ -23,12 +23,11 @@ CONFIG_6xx=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set # CONFIG_8xx is not set +# CONFIG_8260 is not set CONFIG_ALL_PPC=y -# CONFIG_GEMINI is not set -# CONFIG_EST8260 is not set # CONFIG_APUS is not set +CONFIG_PPC601_SYNC_FIX=y # CONFIG_SMP is not set CONFIG_ALTIVEC=y @@ -36,9 +35,11 @@ CONFIG_ALTIVEC=y # General setup # # CONFIG_HIGHMEM is not set -# CONFIG_MOL is not set +CONFIG_MOL=y # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set CONFIG_PCI=y CONFIG_NET=y CONFIG_SYSCTL=y @@ -49,21 +50,24 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y CONFIG_BINFMT_MISC=m CONFIG_PCI_NAMES=y -# CONFIG_HOTPLUG is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# # CONFIG_PCMCIA is not set # # Parallel port support # # CONFIG_PARPORT is not set -CONFIG_VGA_CONSOLE=y -CONFIG_FB=y -CONFIG_FB_COMPAT_XPMAC=y CONFIG_PPC_RTC=y CONFIG_PROC_DEVICETREE=y +CONFIG_PPC_RTAS=y CONFIG_BOOTX_TEXT=y -# CONFIG_MOTOROLA_HOTSWAP is not set -# CONFIG_CMDLINE_BOOL is not set +CONFIG_PREP_RESIDUAL=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttyS0,9600 console=tty0 root=/dev/sda2" # # Memory Technology Devices (MTD) @@ -79,7 +83,7 @@ CONFIG_BOOTX_TEXT=y # # Block devices # -# CONFIG_BLK_DEV_FD is not set +CONFIG_BLK_DEV_FD=m # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set @@ -111,7 +115,8 @@ CONFIG_PACKET=y CONFIG_NETLINK=y # CONFIG_RTNETLINK is not set # CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y @@ -123,6 +128,34 @@ CONFIG_IP_MULTICAST=y # CONFIG_IP_MROUTE is not set # CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set @@ -239,6 +272,7 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_SD_EXTRA_DEVS=40 CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SR_EXTRA_DEVS=2 @@ -344,7 +378,6 @@ CONFIG_NET_ETHERNET=y CONFIG_MACE=y CONFIG_BMAC=y CONFIG_GMAC=y -# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -357,27 +390,28 @@ CONFIG_GMAC=y CONFIG_NET_PCI=y CONFIG_PCNET32=y # CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_AC3200 is not set # CONFIG_APRICOT is not set # CONFIG_CS89x0 is not set -CONFIG_DE4X5=y -# CONFIG_TULIP is not set +CONFIG_TULIP=y +CONFIG_DE4X5=m # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PM is not set # CONFIG_LNE390 is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set # CONFIG_NE3210 is not set # CONFIG_ES3210 is not set -# CONFIG_RTL8129 is not set # CONFIG_8139TOO is not set +# CONFIG_RTL8129 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set # CONFIG_WINBOND_840 is not set +# CONFIG_HAPPYMEAL is not set # CONFIG_NET_POCKET is not set # @@ -439,6 +473,7 @@ CONFIG_PPP_DEFLATE=y # # Console drivers # +CONFIG_VGA_CONSOLE=y # # Frame-buffer support @@ -460,7 +495,8 @@ CONFIG_FB_IMSTT=y CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y -CONFIG_FB_MATROX_G100=y +# CONFIG_FB_MATROX_G100 is not set +# CONFIG_FB_MATROX_G450 is not set # CONFIG_FB_MATROX_MULTIHEAD is not set CONFIG_FB_ATY=y CONFIG_FB_ATY128=y @@ -481,6 +517,7 @@ CONFIG_FONT_SUN12x22=y # CONFIG_FONT_6x11 is not set # CONFIG_FONT_PEARL_8x8 is not set # CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FB_COMPAT_XPMAC is not set # # Input core support @@ -498,15 +535,13 @@ CONFIG_INPUT_EVDEV=y # CONFIG_ADB_CUDA=y CONFIG_ADB_PMU=y -CONFIG_PMAC_PBOOK=y -CONFIG_PMAC_BACKLIGHT=y -CONFIG_MAC_FLOPPY=y -CONFIG_MAC_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set +# CONFIG_PMAC_PBOOK is not set +# CONFIG_PMAC_BACKLIGHT is not set +# CONFIG_MAC_FLOPPY is not set +CONFIG_MAC_SERIAL=m CONFIG_ADB=y CONFIG_ADB_MACIO=y CONFIG_INPUT_ADBHID=y -CONFIG_MAC_HID=y CONFIG_MAC_ADBKEYCODES=y CONFIG_MAC_EMUMOUSEBTN=y @@ -575,17 +610,17 @@ CONFIG_NVRAM=y # File systems # # CONFIG_QUOTA is not set -CONFIG_AUTOFS_FS=y -CONFIG_AUTOFS4_FS=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set +CONFIG_HFS_FS=m # CONFIG_BFS_FS is not set -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m # CONFIG_UMSDOS_FS is not set -CONFIG_VFAT_FS=y +CONFIG_VFAT_FS=m # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set @@ -631,8 +666,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -652,6 +685,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set CONFIG_NLS=y # @@ -678,7 +712,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_936 is not set # CONFIG_NLS_CODEPAGE_949 is not set # CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_ISO8859_1 is not set +CONFIG_NLS_ISO8859_1=m # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set @@ -695,9 +729,9 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Sound # -CONFIG_SOUND=y -CONFIG_DMASOUND_AWACS=y -CONFIG_DMASOUND=y +CONFIG_SOUND=m +CONFIG_DMASOUND_AWACS=m +CONFIG_DMASOUND=m # CONFIG_SOUND_CMPCI is not set # CONFIG_SOUND_EMU10K1 is not set # CONFIG_SOUND_FUSION is not set @@ -711,43 +745,14 @@ CONFIG_DMASOUND=y # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set # CONFIG_SOUND_VIA82CXXX is not set -CONFIG_SOUND_OSS=y -# CONFIG_SOUND_TRACEINIT is not set -# CONFIG_SOUND_DMAP is not set -# CONFIG_SOUND_AD1816 is not set -# CONFIG_SOUND_SGALAXY is not set -# CONFIG_SOUND_ADLIB is not set -# CONFIG_SOUND_ACI_MIXER is not set -CONFIG_SOUND_CS4232=m -# CONFIG_SOUND_SSCAPE is not set -# CONFIG_SOUND_GUS is not set -# CONFIG_SOUND_ICH is not set -# CONFIG_SOUND_VMIDI is not set -# CONFIG_SOUND_TRIX is not set -# CONFIG_SOUND_MSS is not set -# CONFIG_SOUND_MPU401 is not set -# CONFIG_SOUND_NM256 is not set -# CONFIG_SOUND_MAD16 is not set -# CONFIG_SOUND_PAS is not set -# CONFIG_PAS_JOYSTICK is not set -# CONFIG_SOUND_PSS is not set -# CONFIG_SOUND_SB is not set -# CONFIG_SOUND_AWE32_SYNTH is not set -# CONFIG_SOUND_WAVEFRONT is not set -# CONFIG_SOUND_MAUI is not set -# CONFIG_SOUND_YM3812 is not set -# CONFIG_SOUND_OPL3SA1 is not set -# CONFIG_SOUND_OPL3SA2 is not set -# CONFIG_SOUND_YMPCI is not set -# CONFIG_SOUND_UART6850 is not set -# CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set # # USB support # CONFIG_USB=y -CONFIG_USB_DEBUG=y +# CONFIG_USB_DEBUG is not set # # Miscellaneous USB options @@ -763,33 +768,69 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_OHCI=y # -# USB Devices +# USB Device Class drivers # +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +CONFIG_USB_ACM=m # CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +# CONFIG_USB_WACOM 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_AUDIO is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_SERIAL is not set + +# +# USB Multimedia devices +# # CONFIG_USB_IBMCAM is not set # CONFIG_USB_OV511 is not set -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_USS720 is not set +# CONFIG_USB_DSBR is not set # CONFIG_USB_DABUSB is not set + +# +# USB Network adaptors +# # CONFIG_USB_PLUSB is not set # CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_DSBR is not set -# CONFIG_USB_BLUETOOTH is not set # CONFIG_USB_NET1080 is not set # -# USB Human Interface Devices (HID) +# USB port drivers # -CONFIG_USB_HID=y -# CONFIG_USB_WACOM is not set +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_SERIAL_DEBUG 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=m +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB misc drivers +# +# CONFIG_USB_RIO500 is not set # # Kernel hacking diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 4a9852612..545fce0cd 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_PPC) := entry.o traps.o irq.o idle.o time.o misc.o \ process.o signal.o bitops.o ptrace.o \ ppc_htab.o semaphore.o syscalls.o \ align.o setup.o +obj-$(CONFIG_MODULES) += ppc_ksyms.o obj-$(CONFIG_POWER4) += xics.o obj-$(CONFIG_PCI) += pci.o pci-dma.o obj-$(CONFIG_KGDB) += ppc-stub.o @@ -62,11 +63,8 @@ obj-$(CONFIG_ALL_PPC) += pmac_pic.o pmac_setup.o pmac_time.o prom.o \ feature.o pmac_pci.o chrp_setup.o \ chrp_time.o chrp_pci.o open_pic.o \ indirect_pci.o i8259.o prep_pci.o \ - prep_time.o prep_nvram.o ppc_ksyms.o \ - prep_setup.o + prep_time.o prep_nvram.o prep_setup.o obj-$(CONFIG_PMAC_BACKLIGHT) += pmac_backlight.o -obj-$(CONFIG_GEMINI) += gemini_prom.o gemini_pci.o gemini_setup.o \ - open_pic.o obj-$(CONFIG_8260) += m8260_setup.o ppc8260_pic.o diff --git a/arch/ppc/kernel/apus_setup.c b/arch/ppc/kernel/apus_setup.c index 5979c9312..70a683d20 100644 --- a/arch/ppc/kernel/apus_setup.c +++ b/arch/ppc/kernel/apus_setup.c @@ -647,25 +647,6 @@ apus_ide_default_io_base(int index) return 0; } -int -apus_ide_check_region(ide_ioreg_t from, unsigned int extent) -{ - return 0; -} - -void -apus_ide_request_region(ide_ioreg_t from, - unsigned int extent, - const char *name) -{ -} - -void -apus_ide_release_region(ide_ioreg_t from, - unsigned int extent) -{ -} - void apus_ide_fix_driveid(struct hd_driveid *id) { @@ -1131,9 +1112,6 @@ void apus_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_ide_md.outsw = apus_ide_outsw; ppc_ide_md.default_irq = apus_ide_default_irq; ppc_ide_md.default_io_base = apus_ide_default_io_base; - ppc_ide_md.ide_check_region = apus_ide_check_region; - ppc_ide_md.ide_request_region = apus_ide_request_region; - ppc_ide_md.ide_release_region = apus_ide_release_region; ppc_ide_md.fix_driveid = apus_ide_fix_driveid; ppc_ide_md.ide_init_hwif = apus_ide_init_hwif_ports; diff --git a/arch/ppc/kernel/chrp_pci.c b/arch/ppc/kernel/chrp_pci.c index 43b678861..914ed02ff 100644 --- a/arch/ppc/kernel/chrp_pci.c +++ b/arch/ppc/kernel/chrp_pci.c @@ -8,8 +8,8 @@ #include <linux/delay.h> #include <linux/string.h> #include <linux/init.h> -#include <linux/openpic.h> #include <linux/ide.h> +#include <linux/bootmem.h> #include <asm/io.h> #include <asm/pgtable.h> @@ -19,16 +19,19 @@ #include <asm/gg2.h> #include <asm/machdep.h> #include <asm/init.h> +#include <asm/pci-bridge.h> +#include "open_pic.h" #include "pci.h" + #ifdef CONFIG_POWER4 -static unsigned long pci_address_offset(int, unsigned int); +extern unsigned long pci_address_offset(int, unsigned int); #endif /* CONFIG_POWER4 */ /* LongTrail */ -#define pci_config_addr(bus, dev, offset) \ -(GG2_PCI_CONFIG_BASE | ((bus)<<16) | ((dev)<<8) | (offset)) +#define pci_config_addr(dev, offset) \ +(GG2_PCI_CONFIG_BASE | ((dev->bus->number)<<16) | ((dev->devfn)<<8) | (offset)) volatile struct Hydra *Hydra = NULL; @@ -37,205 +40,127 @@ volatile struct Hydra *Hydra = NULL; * limit the bus number to 3 bits */ -int __chrp gg2_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) -{ - if (bus > 7) { - *val = 0xff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - *val = in_8((unsigned char *)pci_config_addr(bus, dev_fn, offset)); - return PCIBIOS_SUCCESSFUL; +#define cfg_read(val, addr, type, op) *val = op((type)(addr)) +#define cfg_write(val, addr, type, op) op((type *)(addr), (val)) + +#define cfg_read_bad(val, size) *val = bad_##size; +#define cfg_write_bad(val, size) + +#define bad_byte 0xff +#define bad_word 0xffff +#define bad_dword 0xffffffffU + +#define GG2_PCI_OP(rw, size, type, op) \ +int __chrp gg2_##rw##_config_##size(struct pci_dev *dev, int off, type val) \ +{ \ + if (dev->bus->number > 7) { \ + cfg_##rw##_bad(val, size) \ + return PCIBIOS_DEVICE_NOT_FOUND; \ + } \ + cfg_##rw(val, pci_config_addr(dev, off), type, op); \ + return PCIBIOS_SUCCESSFUL; \ } -int __chrp gg2_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) -{ - if (bus > 7) { - *val = 0xffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - *val = in_le16((unsigned short *)pci_config_addr(bus, dev_fn, offset)); - return PCIBIOS_SUCCESSFUL; -} - - -int __chrp gg2_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) -{ - if (bus > 7) { - *val = 0xffffffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - *val = in_le32((unsigned int *)pci_config_addr(bus, dev_fn, offset)); - return PCIBIOS_SUCCESSFUL; -} - -int __chrp gg2_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) -{ - if (bus > 7) - return PCIBIOS_DEVICE_NOT_FOUND; - out_8((unsigned char *)pci_config_addr(bus, dev_fn, offset), val); - return PCIBIOS_SUCCESSFUL; -} - -int __chrp gg2_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) -{ - if (bus > 7) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le16((unsigned short *)pci_config_addr(bus, dev_fn, offset), val); - return PCIBIOS_SUCCESSFUL; -} +GG2_PCI_OP(read, byte, u8 *, in_8) +GG2_PCI_OP(read, word, u16 *, in_le16) +GG2_PCI_OP(read, dword, u32 *, in_le32) +GG2_PCI_OP(write, byte, u8, out_8) +GG2_PCI_OP(write, word, u16, out_le16) +GG2_PCI_OP(write, dword, u32, out_le32) -int __chrp gg2_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) +static struct pci_ops gg2_pci_ops = { - if (bus > 7) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32((unsigned int *)pci_config_addr(bus, dev_fn, offset), val); - return PCIBIOS_SUCCESSFUL; -} + gg2_read_config_byte, + gg2_read_config_word, + gg2_read_config_dword, + gg2_write_config_byte, + gg2_write_config_word, + gg2_write_config_dword +}; -#define python_config_address(bus) (unsigned *)((0xfef00000+0xf8000)-(bus*0x100000)) -#define python_config_data(bus) ((0xfef00000+0xf8010)-(bus*0x100000)) -#define PYTHON_CFA(b, d, o) (0x80 | ((b<<6) << 8) | ((d) << 16) \ +/* + * Access functions for PCI config space on IBM "python" host bridges. + */ +#define PYTHON_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \ | (((o) & ~3) << 24)) -unsigned int python_busnr = 0; - -int __chrp python_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) -{ - if (bus > python_busnr) { - *val = 0xff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset)); - *val = in_8((unsigned char *)python_config_data(bus) + (offset&3)); - return PCIBIOS_SUCCESSFUL; -} -int __chrp python_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) -{ - if (bus > python_busnr) { - *val = 0xffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset)); - *val = in_le16((unsigned short *)(python_config_data(bus) + (offset&3))); - return PCIBIOS_SUCCESSFUL; +#define PYTHON_PCI_OP(rw, size, type, op, mask) \ +int __chrp \ +python_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + struct pci_controller *hose = dev->sysdata; \ + \ + out_be32(hose->cfg_addr, \ + PYTHON_CFA(dev->bus->number, dev->devfn, offset)); \ + cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \ + return PCIBIOS_SUCCESSFUL; \ } +PYTHON_PCI_OP(read, byte, u8 *, in_8, 3) +PYTHON_PCI_OP(read, word, u16 *, in_le16, 2) +PYTHON_PCI_OP(read, dword, u32 *, in_le32, 0) +PYTHON_PCI_OP(write, byte, u8, out_8, 3) +PYTHON_PCI_OP(write, word, u16, out_le16, 2) +PYTHON_PCI_OP(write, dword, u32, out_le32, 0) -int __chrp python_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) -{ - if (bus > python_busnr) { - *val = 0xffffffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset)); - *val = in_le32((unsigned *)python_config_data(bus)); - return PCIBIOS_SUCCESSFUL; -} - -int __chrp python_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) +static struct pci_ops python_pci_ops = { - if (bus > python_busnr) - return PCIBIOS_DEVICE_NOT_FOUND; - out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset)); - out_8((volatile unsigned char *)python_config_data(bus) + (offset&3), val); - return PCIBIOS_SUCCESSFUL; -} - -int __chrp python_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) -{ - if (bus > python_busnr) - return PCIBIOS_DEVICE_NOT_FOUND; - out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset)); - out_le16((volatile unsigned short *)python_config_data(bus) + (offset&3), - val); - return PCIBIOS_SUCCESSFUL; -} - -int __chrp python_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) -{ - if (bus > python_busnr) - return PCIBIOS_DEVICE_NOT_FOUND; - out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset)); - out_le32((unsigned *)python_config_data(bus) + (offset&3), val); - return PCIBIOS_SUCCESSFUL; -} - - -int __chrp rtas_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) -{ - unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); - unsigned long ret; - - if (call_rtas( "read-pci-config", 2, 2, &ret, addr, 1) != 0) - return PCIBIOS_DEVICE_NOT_FOUND; - *val = ret; - return PCIBIOS_SUCCESSFUL; -} - -int __chrp rtas_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) -{ - unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); - unsigned long ret; - - if (call_rtas("read-pci-config", 2, 2, &ret, addr, 2) != 0) - return PCIBIOS_DEVICE_NOT_FOUND; - *val = ret; - return PCIBIOS_SUCCESSFUL; -} - - -int __chrp rtas_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) -{ - unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); - unsigned long ret; + python_read_config_byte, + python_read_config_word, + python_read_config_dword, + python_write_config_byte, + python_write_config_word, + python_write_config_dword +}; - if (call_rtas("read-pci-config", 2, 2, &ret, addr, 4) != 0) - return PCIBIOS_DEVICE_NOT_FOUND; - *val = ret; - return PCIBIOS_SUCCESSFUL; +#ifdef CONFIG_POWER4 +/* + * Access functions for PCI config space using RTAS calls. + */ +#define RTAS_PCI_READ_OP(size, type, nbytes) \ +int __chrp \ +rtas_read_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + unsigned long addr = (offset & 0xff) | ((dev->devfn & 0xff) << 8) \ + | ((dev->bus->number & 0xff) << 16); \ + unsigned long ret = ~0UL; \ + int rval; \ + \ + rval = call_rtas("read-pci-config", 2, 2, &ret, addr, nbytes); \ + *val = ret; \ + return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; \ } -int __chrp rtas_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) -{ - unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); - if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 1, (ulong)val ) != 0 ) - return PCIBIOS_DEVICE_NOT_FOUND; - return PCIBIOS_SUCCESSFUL; +#define RTAS_PCI_WRITE_OP(size, type, nbytes) \ +int __chrp \ +rtas_write_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + unsigned long addr = (offset & 0xff) | ((dev->devfn & 0xff) << 8) \ + | ((dev->bus->number & 0xff) << 16); \ + int rval; \ + \ + rval = call_rtas("write-pci-config", 3, 1, NULL, \ + addr, nbytes, (ulong)val); \ + return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; \ } -int __chrp rtas_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) -{ - unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); - if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 2, (ulong)val ) != 0 ) - return PCIBIOS_DEVICE_NOT_FOUND; - return PCIBIOS_SUCCESSFUL; -} +RTAS_PCI_READ_OP(byte, u8 *, 1) +RTAS_PCI_READ_OP(word, u16 *, 2) +RTAS_PCI_READ_OP(dword, u32 *, 4) +RTAS_PCI_WRITE_OP(byte, u8, 1) +RTAS_PCI_WRITE_OP(word, u16, 2) +RTAS_PCI_WRITE_OP(dword, u32, 4) -int __chrp rtas_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) +static struct pci_ops rtas_pci_ops = { - unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); - if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 4, (ulong)val ) != 0 ) - return PCIBIOS_DEVICE_NOT_FOUND; - return PCIBIOS_SUCCESSFUL; -} + rtas_read_config_byte, + rtas_read_config_word, + rtas_read_config_dword, + rtas_write_config_byte, + rtas_write_config_word, + rtas_write_config_dword +}; +#endif /* CONFIG_POWER4 */ /* * Temporary fixes for PCI devices. These should be replaced by OF query @@ -278,7 +203,7 @@ hydra_init(void) HYDRA_FC_MPIC_ENABLE | HYDRA_FC_SLOW_SCC_PCLK | HYDRA_FC_MPIC_IS_MASTER)); - OpenPIC = (volatile struct OpenPIC *)&Hydra->OpenPIC; + OpenPIC_Addr = &Hydra->OpenPIC; OpenPIC_InitSenses = hydra_openpic_initsenses; OpenPIC_NumInitSenses = sizeof(hydra_openpic_initsenses); return 1; @@ -316,54 +241,25 @@ void __init chrp_pcibios_fixup(void) { struct pci_dev *dev; - int *brp; struct device_node *np; - extern struct pci_ops generic_pci_ops; - -#ifndef CONFIG_POWER4 - np = find_devices("device-tree"); - if (np != 0) { - for (np = np->child; np != NULL; np = np->sibling) { - if (np->type == NULL || strcmp(np->type, "pci") != 0) - continue; - if ((brp = (int *) get_property(np, "bus-range", NULL)) == 0) - continue; - if (brp[0] != 0) /* bus 0 is already done */ - pci_scan_bus(brp[0], &generic_pci_ops, NULL); - } - } -#else - /* XXX kludge for now because we can't properly handle - physical addresses > 4GB. -- paulus */ - pci_scan_bus(0x1e, &generic_pci_ops, NULL); -#endif /* CONFIG_POWER4 */ /* PCI interrupts are controlled by the OpenPIC */ pci_for_each_dev(dev) { - np = find_pci_device_OFnode(dev->bus->number, dev->devfn); + np = pci_device_to_OF_node(dev); if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0)) dev->irq = np->intrs[0].line; - /* these need to be absolute addrs for OF and Matrox FB -- Cort */ - if ( dev->vendor == PCI_VENDOR_ID_MATROX ) - { - if ( dev->resource[0].start < isa_mem_base ) - dev->resource[0].start += isa_mem_base; - if ( dev->resource[1].start < isa_mem_base ) - dev->resource[1].start += isa_mem_base; - } + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + /* the F50 identifies the amd as a trident */ if ( (dev->vendor == PCI_VENDOR_ID_TRIDENT) && (dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET) ) { dev->vendor = PCI_VENDOR_ID_AMD; - pcibios_write_config_word(dev->bus->number, - dev->devfn, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD); + pci_write_config_word(dev, PCI_VENDOR_ID, + PCI_VENDOR_ID_AMD); } #ifdef CONFIG_POWER4 power4_fixup_dev(dev); -#else - if (dev->bus->number > 0 && python_busnr > 0) - dev->resource[0].start += dev->bus->number*0x01000000; #endif } } @@ -402,86 +298,213 @@ static void __init gg2_pcibios_fixup_bus(struct pci_bus *bus) bus->resource[1] = &gg2_resources.pci_mem; } -decl_config_access_method(grackle); -decl_config_access_method(indirect); -decl_config_access_method(rtas); +static void process_bridge_ranges(struct pci_controller *hose, + struct device_node *dev, int index) +{ + unsigned int *ranges; + int rlen = 0; + int memno = 0; + struct resource *res; + + hose->io_base_phys = 0; + ranges = (unsigned int *) get_property(dev, "ranges", &rlen); + while ((rlen -= 6 * sizeof(unsigned int)) >= 0) { + res = NULL; + switch (ranges[0] >> 24) { + case 1: /* I/O space */ + if (ranges[2] != 0) + break; + hose->io_base_phys = ranges[3]; + hose->io_base_virt = ioremap(ranges[3], ranges[5]); + if (index == 0) { + isa_io_base = (unsigned long) hose->io_base_virt; + printk("isa_io_base=%lx\n", isa_io_base); + } + res = &hose->io_resource; + res->flags = IORESOURCE_IO; + break; + case 2: /* memory space */ + if (index == 0 && ranges[1] == 0 && ranges[2] == 0){ + isa_mem_base = ranges[3]; + printk("isa_mem_base=%lx\n", isa_mem_base); + } + if (memno == 0) { + hose->pci_mem_offset = ranges[3] - ranges[2]; + printk("pci_mem_offset=%lx for this bridge\n", + hose->pci_mem_offset); + } + res = &hose->mem_resources[memno]; + res->flags = IORESOURCE_MEM; + ++memno; + break; + } + if (res != NULL) { + res->name = dev->full_name; + res->start = ranges[3]; + res->end = res->start + ranges[5] - 1; + res->parent = NULL; + res->sibling = NULL; + res->child = NULL; + } + ranges += 6; + } +} + +/* this is largely modeled and stolen after the pmac_pci code -- tgall + */ + +static void __init +ibm_add_bridges(struct device_node *dev) +{ + int *bus_range; + int len, index = 0; + struct pci_controller *hose; + volatile unsigned char *cfg; + unsigned int *dma; +#ifdef CONFIG_POWER3 + unsigned long *opprop = (unsigned long *) + get_property(find_path_device("/"), "platform-open-pic", NULL); +#endif + + for(; dev != NULL; dev = dev->next, ++index) { + if (dev->n_addrs < 1) { + printk(KERN_WARNING "Can't use %s: no address\n", + dev->full_name); + continue; + } + bus_range = (int *) get_property(dev, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s\n", + dev->full_name); + continue; + } + if (bus_range[1] == bus_range[0]) + printk(KERN_INFO "PCI bus %d", bus_range[0]); + else + printk(KERN_INFO "PCI buses %d..%d", + bus_range[0], bus_range[1]); + printk(" controlled by %s at %x\n", dev->type, + dev->addrs[0].address); + + hose = pcibios_alloc_controller(); + if (!hose) { + printk("Can't allocate PCI controller structure for %s\n", + dev->full_name); + continue; + } + hose->arch_data = dev; + hose->first_busno = bus_range[0]; + hose->last_busno = bus_range[1]; + hose->ops = &python_pci_ops; + + cfg = ioremap(dev->addrs[0].address + 0xf8000, 0x20); + hose->cfg_addr = (volatile unsigned int *) cfg; + hose->cfg_data = cfg + 0x10; + + process_bridge_ranges(hose, dev, index); + +#ifdef CONFIG_POWER3 + openpic_setup_ISU(index, opprop[index+1]); +#endif /* CONFIG_POWER3 */ + + /* check the first bridge for a property that we can + use to set pci_dram_offset */ + dma = (unsigned int *) + get_property(dev, "ibm,dma-ranges", &len); + if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) { + pci_dram_offset = dma[2] - dma[3]; + printk("pci_dram_offset = %lx\n", pci_dram_offset); + } + } +} + +#ifdef CONFIG_POWER4 +void __init +power4_add_bridge(void) +{ + struct pci_controller* hose; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + hose->first_busno = 0; + hose->last_busno = 0xff; + + hose->ops = &rtas_pci_ops; + pci_dram_offset = 0; +} +#endif /* CONFIG_POWER4 */ void __init -chrp_setup_pci_ptrs(void) +chrp_find_bridges(void) { struct device_node *py; + char *model, *name; + struct pci_controller* hose; ppc_md.pcibios_fixup = chrp_pcibios_fixup; + #ifdef CONFIG_POWER4 - set_config_access_method(rtas); - pci_dram_offset = 0; + power4_add_bridge(); #else /* CONFIG_POWER4 */ - if ( !strncmp("MOT", - get_property(find_path_device("/"), "model", NULL),3) ) - { - pci_dram_offset = 0; - isa_mem_base = 0xf7000000; - isa_io_base = 0xfe000000; - set_config_access_method(grackle); - } - else - { - if ((py = find_compatible_devices("pci", "IBM,python")) != 0 - || (py = find_compatible_devices("pci", "IBM,python3.0")) != 0) - { - char *name = get_property(find_path_device("/"), "name", NULL); - - /* find out how many pythons */ - while ( (py = py->next) ) python_busnr++; - set_config_access_method(python); - - /* - * We base these values on the machine type but should - * try to read them from the python controller itself. - * -- Cort - */ - if ( !strncmp("IBM,7025-F50", name, 12) ) - { - pci_dram_offset = 0x80000000; - isa_mem_base = 0xa0000000; - isa_io_base = 0x88000000; - } else if ( !strncmp("IBM,7043-260", name, 12) - || !strncmp("IBM,7044-270", name, 12)) - { - pci_dram_offset = 0x0; - isa_mem_base = 0xc0000000; - isa_io_base = 0xf8000000; - } - } - else - { - if ( !strncmp("IBM,7043-150", get_property(find_path_device("/"), "name", NULL),12) || - !strncmp("IBM,7046-155", get_property(find_path_device("/"), "name", NULL),12) || - !strncmp("IBM,7046-B50", get_property(find_path_device("/"), "name", NULL),12) ) - { - pci_dram_offset = 0; - isa_mem_base = 0x80000000; - isa_io_base = 0xfe000000; - pci_config_address = (unsigned int *)0xfec00000; - pci_config_data = (unsigned char *)0xfee00000; - set_config_access_method(indirect); - } - else - { - /* LongTrail */ - pci_dram_offset = 0; - isa_mem_base = 0xf7000000; - isa_io_base = 0xf8000000; - set_config_access_method(gg2); - ppc_md.pcibios_fixup = gg2_pcibios_fixup; - ppc_md.pcibios_fixup_bus = gg2_pcibios_fixup_bus; - } - } + model = get_property(find_path_device("/"), "model", NULL); + if (!strncmp("MOT", model, 3)) { + struct pci_controller* hose; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + hose->first_busno = 0; + hose->last_busno = 0xff; + /* Check that please. This must be the root of the OF + * PCI tree (the root host bridge + */ + hose->arch_data = find_devices("pci"); + setup_grackle(hose, 0x20000); + return; } + + if ((py = find_compatible_devices("pci", "IBM,python"))) + { + /* XXX xmon_init_scc needs this set and the BAT + set up in MMU_init */ + ibm_add_bridges(find_devices("pci")); + return; + } + + + hose = pcibios_alloc_controller(); + if (!hose) + return; + hose->first_busno = 0; + hose->last_busno = 0xff; + /* Check that please. This must be the root of the OF + * PCI tree (the root host bridge + */ + hose->arch_data = find_devices("pci"); + name = get_property(find_path_device("/"), "name", NULL); + if (!strncmp("IBM,7043-150", name, 12) || + !strncmp("IBM,7046-155", name, 12) || + !strncmp("IBM,7046-B50", name, 12) ) { + setup_grackle(hose, 0x01000000); + isa_mem_base = 0x80000000; + return; + } + + /* LongTrail */ + hose->ops = &gg2_pci_ops; + pci_dram_offset = 0; + isa_mem_base = 0xf7000000; + hose->io_base_phys = (unsigned long) 0xf8000000; + hose->io_base_virt = ioremap(hose->io_base_phys, 0x10000); + isa_io_base = (unsigned long) hose->io_base_virt; + ppc_md.pcibios_fixup = gg2_pcibios_fixup; + ppc_md.pcibios_fixup_bus = gg2_pcibios_fixup_bus; #endif /* CONFIG_POWER4 */ } #ifdef CONFIG_PPC64BRIDGE +#ifdef CONFIG_POWER4 /* * Hack alert!!! * 64-bit machines like POWER3 and POWER4 have > 32 bit @@ -490,9 +513,7 @@ chrp_setup_pci_ptrs(void) * page table gives us into parts of the physical address * space above 4GB so we can access the I/O devices. */ - -#ifdef CONFIG_POWER4 -static unsigned long pci_address_offset(int busnr, unsigned int flags) +unsigned long pci_address_offset(int busnr, unsigned int flags) { unsigned long offset = 0; @@ -508,34 +529,5 @@ static unsigned long pci_address_offset(int busnr, unsigned int flags) } return offset; } - -unsigned long phys_to_bus(unsigned long pa) -{ - if (pa >= 0xf8000000) - pa -= 0x38000000; - else if (pa >= 0x80000000 && pa < 0xc0000000) - pa += 0x40000000; - return pa; -} - -unsigned long bus_to_phys(unsigned int ba, int busnr) -{ - return ba + pci_address_offset(busnr, IORESOURCE_MEM); -} - -#else /* CONFIG_POWER4 */ -/* - * For now assume I/O addresses are < 4GB and PCI bridges don't - * remap addresses on POWER3 machines. - */ -unsigned long phys_to_bus(unsigned long pa) -{ - return pa; -} - -unsigned long bus_to_phys(unsigned int ba, int busnr) -{ - return ba; -} #endif /* CONFIG_POWER4 */ #endif /* CONFIG_PPC64BRIDGE */ diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c index ccc6621de..5682f3fad 100644 --- a/arch/ppc/kernel/chrp_setup.c +++ b/arch/ppc/kernel/chrp_setup.c @@ -30,7 +30,6 @@ #include <linux/ioport.h> #include <linux/console.h> #include <linux/pci.h> -#include <linux/openpic.h> #include <linux/version.h> #include <linux/adb.h> #include <linux/module.h> @@ -50,21 +49,19 @@ #include <asm/hydra.h> #include <asm/keyboard.h> #include <asm/init.h> - #include <asm/time.h> + #include "local_irq.h" #include "i8259.h" #include "open_pic.h" #include "xics.h" -extern volatile unsigned char *chrp_int_ack_special; - unsigned long chrp_get_rtc_time(void); int chrp_set_rtc_time(unsigned long nowtime); void chrp_calibrate_decr(void); long chrp_time_init(void); -void chrp_setup_pci_ptrs(void); +void chrp_find_bridges(void); void chrp_event_scan(void); void rtas_display_progress(char *, unsigned short); void rtas_indicator_progress(char *, unsigned short); @@ -92,7 +89,7 @@ kdev_t boot_dev; extern PTE *Hash, *Hash_end; extern unsigned long Hash_size, Hash_mask; extern int probingmem; -extern unsigned long loops_per_sec; +extern unsigned long loops_per_jiffy; extern int bootx_text_mapped; static int max_width; @@ -244,7 +241,7 @@ chrp_setup_arch(void) struct device_node *device; /* init to some ~sane value until calibrate_delay() runs */ - loops_per_sec = 50000000; + loops_per_jiffy = 50000000/HZ; #ifdef CONFIG_BLK_DEV_INITRD /* this is fine for chrp */ @@ -257,6 +254,9 @@ chrp_setup_arch(void) ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */ printk("Boot arguments: %s\n", cmd_line); + /* Lookup PCI host bridges */ + chrp_find_bridges(); + #ifndef CONFIG_PPC64BRIDGE /* PCI bridge config space access area - * appears to be not in devtree on longtrail. */ @@ -266,11 +266,12 @@ chrp_setup_arch(void) * -- Geert */ hydra_init(); /* Mac I/O */ + #endif /* CONFIG_PPC64BRIDGE */ #ifndef CONFIG_POWER4 /* Some IBM machines don't have the hydra -- Cort */ - if ( !OpenPIC ) + if ( !OpenPIC_Addr ) { unsigned long *opprop; @@ -279,7 +280,7 @@ chrp_setup_arch(void) if (opprop != 0) { printk("OpenPIC addrs: %lx %lx %lx\n", opprop[0], opprop[1], opprop[2]); - OpenPIC = ioremap(opprop[0], sizeof(struct OpenPIC)); + OpenPIC_Addr = ioremap(opprop[0], 0x40000); } } #endif @@ -292,23 +293,17 @@ chrp_setup_arch(void) conswitchp = &dummy_con; #endif -#ifndef CONFIG_PPC64BRIDGE - pmac_find_bridges(); -#endif /* CONFIG_PPC64BRIDGE */ - /* Get the event scan rate for the rtas so we know how * often it expects a heartbeat. -- Cort */ - if ( rtas_data ) - { + if ( rtas_data ) { struct property *p; device = find_devices("rtas"); for ( p = device->properties; p && strncmp(p->name, "rtas-event-scan-rate", 20); p = p->next ) /* nothing */ ; - if ( p && *(unsigned long *)p->value ) - { + if ( p && *(unsigned long *)p->value ) { ppc_md.heartbeat = chrp_event_scan; ppc_md.heartbeat_reset = (HZ/(*(unsigned long *)p->value)*30)-1; ppc_md.heartbeat_count = 1; @@ -365,79 +360,44 @@ chrp_irq_cannonicalize(u_int irq) } } -int __chrp chrp_get_irq( struct pt_regs *regs ) -{ - int irq; - - irq = openpic_irq( smp_processor_id() ); - if (irq == IRQ_8259_CASCADE) - { - /* - * This magic address generates a PCI IACK cycle. - */ - if ( chrp_int_ack_special ) - irq = *chrp_int_ack_special; - else - irq = i8259_irq( smp_processor_id() ); - openpic_eoi( smp_processor_id() ); - } - if (irq == OPENPIC_VEC_SPURIOUS) - /* - * Spurious interrupts should never be - * acknowledged - */ - irq = -1; - /* - * I would like to openpic_eoi here but there seem to be timing problems - * between the openpic ack and the openpic eoi. - * -- Cort - */ - return irq; -} - -void __chrp chrp_post_irq(struct pt_regs* regs, int irq) -{ - /* - * If it's an i8259 irq then we've already done the - * openpic irq. So we just check to make sure the controller - * is an openpic and if it is then eoi - * - * We do it this way since our irq_desc[irq].handler can change - * with RTL and no longer be open_pic -- Cort - */ - if ( irq >= open_pic_irq_offset) - openpic_eoi( smp_processor_id() ); -} - void __init chrp_init_IRQ(void) { struct device_node *np; int i; unsigned long *addrp; + unsigned char* chrp_int_ack_special = 0; + unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS]; + int nmi_irq = -1; +#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON) + struct device_node *kbd; +#endif if (!(np = find_devices("pci")) || !(addrp = (unsigned long *) get_property(np, "8259-interrupt-acknowledge", NULL))) printk("Cannot find pci to get ack address\n"); else - chrp_int_ack_special = (volatile unsigned char *) - ioremap(*addrp, 1); - open_pic_irq_offset = 16; - for ( i = 16 ; i < NR_IRQS ; i++ ) - irq_desc[i].handler = &open_pic; - openpic_init(1); - enable_irq(IRQ_8259_CASCADE); - for ( i = 0 ; i < 16 ; i++ ) + chrp_int_ack_special = (unsigned char *)ioremap(*addrp, 1); + /* hydra still sets OpenPIC_InitSenses to a static set of values */ + if (OpenPIC_InitSenses == NULL) { + prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS); + OpenPIC_InitSenses = init_senses; + OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS; + } + openpic_init(1, NUM_8259_INTERRUPTS, chrp_int_ack_special, nmi_irq); + for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ ) irq_desc[i].handler = &i8259_pic; i8259_init(); -#ifdef CONFIG_XMON - request_irq(openpic_to_irq(HYDRA_INT_ADB_NMI), - xmon_irq, 0, "NMI", 0); -#endif /* CONFIG_XMON */ -#ifdef CONFIG_SMP - request_irq(openpic_to_irq(OPENPIC_VEC_IPI), - openpic_ipi_action, 0, "IPI0", 0); -#endif /* CONFIG_SMP */ +#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON) + /* see if there is a keyboard in the device tree + with a parent of type "adb" */ + for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next) + if (kbd->parent && kbd->parent->type + && strcmp(kbd->parent->type, "adb") == 0) + break; + if (kbd) + request_irq( HYDRA_INT_ADB_NMI, xmon_irq, 0, "XMON break", 0); +#endif } void __init @@ -556,12 +516,6 @@ chrp_ide_release_region(ide_ioreg_t from, } void __chrp -chrp_ide_fix_driveid(struct hd_driveid *id) -{ - ppc_generic_ide_fix_driveid(id); -} - -void __chrp chrp_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq) { ide_ioreg_t reg = data_port; @@ -586,7 +540,6 @@ void __init chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { - chrp_setup_pci_ptrs(); #ifdef CONFIG_BLK_DEV_INITRD /* take care of initrd if we have one */ if ( r6 ) @@ -596,10 +549,10 @@ void __init } #endif /* CONFIG_BLK_DEV_INITRD */ - /* pci_dram_offset/isa_io_base/isa_mem_base set by setup_pci_ptrs() */ ISA_DMA_THRESHOLD = ~0L; DMA_MODE_READ = 0x44; DMA_MODE_WRITE = 0x48; + isa_io_base = CHRP_ISA_IO_BASE; /* default value */ ppc_md.setup_arch = chrp_setup_arch; ppc_md.setup_residual = NULL; @@ -607,8 +560,8 @@ void __init ppc_md.irq_cannonicalize = chrp_irq_cannonicalize; #ifndef CONFIG_POWER4 ppc_md.init_IRQ = chrp_init_IRQ; - ppc_md.get_irq = chrp_get_irq; - ppc_md.post_irq = chrp_post_irq; + ppc_md.get_irq = openpic_get_irq; + ppc_md.post_irq = NULL; #else ppc_md.init_IRQ = xics_init_IRQ; ppc_md.get_irq = xics_get_irq; @@ -669,11 +622,12 @@ void __init ppc_ide_md.ide_check_region = chrp_ide_check_region; ppc_ide_md.ide_request_region = chrp_ide_request_region; ppc_ide_md.ide_release_region = chrp_ide_release_region; - ppc_ide_md.fix_driveid = chrp_ide_fix_driveid; + ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid; ppc_ide_md.ide_init_hwif = chrp_ide_init_hwif_ports; ppc_ide_md.io_base = _IO_BASE; #endif + /* * Print the banner, then scroll down so boot progress * can be printed. -- Cort diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index 89922aaab..93bb8ca00 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S @@ -234,7 +234,6 @@ _GLOBAL(_switch) li r0,0x0ff0 stw r0,TRAP(r1) stw r1,KSP(r3) /* Set old stack pointer */ - sync tophys(r0,r4) CLR_TOP32(r0) mtspr SPRG3,r0 /* Update current THREAD phys addr */ @@ -251,7 +250,7 @@ _GLOBAL(_switch) #endif mtspr M_TWB,r9 /* Update MMU base address */ tlbia - SYNC + sync #endif /* CONFIG_8xx */ lwz r1,KSP(r4) /* Load new stack pointer */ /* save the old current 'last' for return value */ @@ -342,23 +341,23 @@ lost_irq_ret: do_bottom_half_ret: 2: lwz r3,_MSR(r1) /* Returning to user mode? */ andi. r3,r3,MSR_PR - beq+ restore /* if so, check need_resched and signals */ - .globl ret_to_user_hook -ret_to_user_hook: - nop + beq+ do_signal_ret /* if so, check need_resched and signals */ lwz r3,NEED_RESCHED(r2) cmpi 0,r3,0 /* check need_resched flag */ beq+ 7f bl schedule 7: lwz r5,SIGPENDING(r2) /* Check for pending unblocked signals */ cmpwi 0,r5,0 - beq+ restore + beq+ do_signal_ret li r3,0 addi r4,r1,STACK_FRAME_OVERHEAD MOL_HOOK_MMU(8,r8) bl do_signal .globl do_signal_ret do_signal_ret: + .globl ret_to_user_hook +ret_to_user_hook: + nop restore: lwz r3,_XER(r1) mtspr XER,r3 @@ -372,7 +371,7 @@ restore: */ mfmsr r0 /* Get current interrupt state */ rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */ - sync /* Some chip revs have problems here... */ + SYNC /* Some chip revs have problems here... */ mtmsr r0 /* Update machine state */ /* if returning to user mode, set new sprg2 and save kernel SP */ @@ -468,7 +467,7 @@ enter_rtas: andc r0,r9,r0 li r10,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP andc r9,r0,r10 - sync /* disable interrupts so SRR0/1 */ + SYNC /* disable interrupts so SRR0/1 */ mtmsr r0 /* don't get trashed */ mtlr r6 CLR_TOP32(r7) diff --git a/arch/ppc/kernel/error_log.c b/arch/ppc/kernel/error_log.c new file mode 100644 index 000000000..5ee750dda --- /dev/null +++ b/arch/ppc/kernel/error_log.c @@ -0,0 +1,183 @@ +/* + * arch/ppc/kernel/error_log.c + * + * Copyright (c) 2000 Tilmann Bitterberg + * (tilmann@bitterberg.de) + * + * Error processing of errors found by rtas even-scan routine + * which is done with every heartbeat. (chrp_setup.c) + */ + +#include <linux/sched.h> + +#include <asm/prom.h> + +#include "error_log.h" + +/* ****************************************************************** */ +/* + * EVENT-SCAN + * The whole stuff below here doesn't take any action when it found + * an error, it just prints as much information as possible and + * then its up to the user to decide what to do. + * + * Returns 0 if no errors were found + * Returns 1 if there may be more errors + */ +int ppc_rtas_errorlog_scan(void) +{ +const char *_errlog_severity[] = { +#ifdef VERBOSE_ERRORS + "No Error\n\t\ +Should require no further information", + "Event\n\t\ +This is not really an error, it is an event. I use events\n\t\ +to communicate with RTAS back and forth.", + "Warning\n\t\ +Indicates a non-state-losing error, either fully recovered\n\t\ +by RTAS or not needing recovery. Ignore it.", + "Error sync\n\t\ +May only be fatal to a certain program or thread. Recovery\n\t\ +and continuation is possible, if I only had a handler for\n\t\ +this. Less serious", + "Error\n\t\ +Less serious, but still causing a loss of data and state.\n\t\ +I can't tell you exactly what to do, You have to decide\n\t\ +with help from the target and initiator field, what kind\n\t\ +of further actions may take place.", + "Fatal\n\t\ +Represent a permanent hardware failure and I believe this\n\t\ +affects my overall performance and behaviour. I would not\n\t\ +attempt to continue normal operation." +#else + "No Error", + "Event", + "Warning", + "Error sync", + "Error", + "Fatal" +#endif /* VERBOSE_ERRORS */ +}; + +#if 0 /* unused?? */ +const char *_errlog_disposition[] = { +#ifdef VERBOSE_ERRORS + "Fully recovered\n\t\ +There was an error, but it is fully recovered by RTAS.", + "Limited recovery\n\t\ +RTAS was able to recover the state of the machine, but some\n\t\ +feature of the machine has been disabled or lost (for example\n\t\ +error checking) or performance may suffer.", + "Not recovered\n\t\ +Whether RTAS did not try to recover anything or recovery failed:\n\t\ +HOUSTON, WE HAVE A PROBLEM!" +#else + "Fully recovered", + "Limited recovery", + "Not recovered" +#endif /* VERBOSE_ERRORS */ +}; +#endif + +const char *_errlog_extended[] = { +#ifdef VERBOSE_ERRORS + "Not present\n\t\ +Sad, the RTAS call didn't return an extended error log.", + "Present\n\t\ +The extended log is present and hopefully it contains a lot of\n\t\ +useful information, which leads to the solution of the problem." +#else + "Not present", + "Present" +#endif /* VERBOSE_ERRORS */ +}; + +const char *_errlog_initiator[] = { + "Unknown or not applicable", + "CPU", + "PCI", + "ISA", + "Memory", + "Power management" +}; + +const char *_errlog_target[] = { + "Unknown or not applicable", + "CPU", + "PCI", + "ISA", + "Memory", + "Power management" +}; + rtas_error_log error_log; + char logdata[1024]; + int error; +#if 0 /* unused?? */ + int retries = 0; /* if HW error, try 10 times */ +#endif + + error = call_rtas ("event-scan", 4, 1, (unsigned long *)&error_log, + INTERNAL_ERROR | EPOW_WARNING, + 0, __pa(logdata), 1024); + + if (error == 1) /* no errors found */ + return 0; + + if (error == -1) { + printk(KERN_ERR "Unable to get errors. Do you a favor and throw this box away\n"); + return 0; + } + if (error_log.version != 1) + printk(KERN_WARNING "Unknown version (%d), please implement me\n", + error_log.version); + + switch (error_log.disposition) { + case DISP_FULLY_RECOVERED: + /* there was an error, but everything is fine now */ + return 0; + case DISP_NOT_RECOVERED: + printk("We have a really serious Problem!\n"); + case DISP_LIMITED_RECOVERY: + printk("Error classification\n"); + printk("Severity : %s\n", + ppc_rtas_errorlog_check_severity (error_log)); + printk("Initiator : %s\n", + ppc_rtas_errorlog_check_initiator (error_log)); + printk("Target : %s\n", + ppc_rtas_errorlog_check_target (error_log)); + printk("Type : %s\n", + ppc_rtas_errorlog_check_type (error_log)); + printk("Ext. log : %s\n", + ppc_rtas_errorlog_check_extended (error_log)); + if (error_log.extended) + ppc_rtas_errorlog_disect_extended (logdata); + return 1; + default: + /* nothing */ + break; + } + return 0; +} +/* ****************************************************************** */ +const char * ppc_rtas_errorlog_check_type (rtas_error_log error_log) +{ + const char *_errlog_type[] = { + "unknown type", + "too many tries failed", + "TCE error", + "RTAS device failed", + "target timed out", + "parity error on data", /* 5 */ + "parity error on address", + "parity error on external cache", + "access to invalid address", + "uncorrectable ECC error", + "corrected ECC error" /* 10 */ + }; + if (error_log.type == TYPE_EPOW) + return "EPOW"; + if (error_log.type >= TYPE_PMGM_POWER_SW_ON) + return "PowerMGM Event (not handled right now)"; + return _errlog_type[error_log.type]; +} + diff --git a/arch/ppc/kernel/error_log.h b/arch/ppc/kernel/error_log.h new file mode 100644 index 000000000..579fc3e0d --- /dev/null +++ b/arch/ppc/kernel/error_log.h @@ -0,0 +1,95 @@ +#ifndef __ERROR_LOG_H__ +#define __ERROR_LOG_H__ + +#define VERBOSE_ERRORS 1 /* Maybe I enlarge the kernel too much */ +#undef VERBOSE_ERRORS + +/* Event classes */ +/* XXX: Endianess correct? NOW*/ +#define INTERNAL_ERROR 0x80000000 /* set bit 0 */ +#define EPOW_WARNING 0x40000000 /* set bit 1 */ +#define POWERMGM_EVENTS 0x20000000 /* set bit 2 */ + +/* event-scan returns */ +#define SEVERITY_FATAL 0x5 +#define SEVERITY_ERROR 0x4 +#define SEVERITY_ERROR_SYNC 0x3 +#define SEVERITY_WARNING 0x2 +#define SEVERITY_EVENT 0x1 +#define SEVERITY_NO_ERROR 0x0 +#define DISP_FULLY_RECOVERED 0x0 +#define DISP_LIMITED_RECOVERY 0x1 +#define DISP_NOT_RECOVERED 0x2 +#define PART_PRESENT 0x0 +#define PART_NOT_PRESENT 0x1 +#define INITIATOR_UNKNOWN 0x0 +#define INITIATOR_CPU 0x1 +#define INITIATOR_PCI 0x2 +#define INITIATOR_ISA 0x3 +#define INITIATOR_MEMORY 0x4 +#define INITIATOR_POWERMGM 0x5 +#define TARGET_UNKNOWN 0x0 +#define TARGET_CPU 0x1 +#define TARGET_PCI 0x2 +#define TARGET_ISA 0x3 +#define TARGET_MEMORY 0x4 +#define TARGET_POWERMGM 0x5 +#define TYPE_RETRY 0x01 +#define TYPE_TCE_ERR 0x02 +#define TYPE_INTERN_DEV_FAIL 0x03 +#define TYPE_TIMEOUT 0x04 +#define TYPE_DATA_PARITY 0x05 +#define TYPE_ADDR_PARITY 0x06 +#define TYPE_CACHE_PARITY 0x07 +#define TYPE_ADDR_INVALID 0x08 +#define TYPE_ECC_UNCORR 0x09 +#define TYPE_ECC_CORR 0x0a +#define TYPE_EPOW 0x40 +/* I don't add PowerMGM events right now, this is a different topic */ +#define TYPE_PMGM_POWER_SW_ON 0x60 +#define TYPE_PMGM_POWER_SW_OFF 0x61 +#define TYPE_PMGM_LID_OPEN 0x62 +#define TYPE_PMGM_LID_CLOSE 0x63 +#define TYPE_PMGM_SLEEP_BTN 0x64 +#define TYPE_PMGM_WAKE_BTN 0x65 +#define TYPE_PMGM_BATTERY_WARN 0x66 +#define TYPE_PMGM_BATTERY_CRIT 0x67 +#define TYPE_PMGM_SWITCH_TO_BAT 0x68 +#define TYPE_PMGM_SWITCH_TO_AC 0x69 +#define TYPE_PMGM_KBD_OR_MOUSE 0x6a +#define TYPE_PMGM_ENCLOS_OPEN 0x6b +#define TYPE_PMGM_ENCLOS_CLOSED 0x6c +#define TYPE_PMGM_RING_INDICATE 0x6d +#define TYPE_PMGM_LAN_ATTENTION 0x6e +#define TYPE_PMGM_TIME_ALARM 0x6f +#define TYPE_PMGM_CONFIG_CHANGE 0x70 +#define TYPE_PMGM_SERVICE_PROC 0x71 + +typedef struct _rtas_error_log { + unsigned long version:8; /* Architectural version */ + unsigned long severity:3; /* Severity level of error */ + unsigned long disposition:2; /* Degree of recovery */ + unsigned long extended:1; /* extended log present? */ + unsigned long /* reserved */ :2; /* Reserved for future use */ + unsigned long initiator:4; /* Initiator of event */ + unsigned long target:4; /* Target of failed operation */ + unsigned long type:8; /* General event or error*/ + unsigned long extended_log_length:32; /* length in bytes */ +} rtas_error_log; + +/* ****************************************************************** */ +#define ppc_rtas_errorlog_check_severity(x) \ + (_errlog_severity[x.severity]) +#define ppc_rtas_errorlog_check_target(x) \ + (_errlog_target[x.target]) +#define ppc_rtas_errorlog_check_initiator(x) \ + (_errlog_initiator[x.initiator]) +#define ppc_rtas_errorlog_check_extended(x) \ + (_errlog_extended[x.extended]) +#define ppc_rtas_errorlog_disect_extended(x) \ + do { /* implement me */ } while(0) +extern const char * ppc_rtas_errorlog_check_type (rtas_error_log error_log); +extern int ppc_rtas_errorlog_scan(void); + + +#endif /* __ERROR_LOG_H__ */ diff --git a/arch/ppc/kernel/feature.c b/arch/ppc/kernel/feature.c index 57599917a..f22f4b163 100644 --- a/arch/ppc/kernel/feature.c +++ b/arch/ppc/kernel/feature.c @@ -238,12 +238,15 @@ feature_add_controller(struct device_node *controller_device, fbit* bits); static struct feature_controller* feature_lookup_controller(struct device_node *device); +#ifdef CONFIG_PMAC_PBOOK static void heathrow_prepare_for_sleep(struct feature_controller* ctrler); static void heathrow_wakeup(struct feature_controller* ctrler); -static void keylargo_init(void); -static void uninorth_init(void); static void core99_prepare_for_sleep(struct feature_controller* ctrler); static void core99_wake_up(struct feature_controller* ctrler); +#endif /* CONFIG_PMAC_PBOOK */ + +static void keylargo_init(void); +static void uninorth_init(void); /* static variables */ static struct feature_controller controllers[MAX_FEATURE_CONTROLLERS]; @@ -255,6 +258,10 @@ static volatile u32* keylargo_base = NULL; static int uninorth_rev; static int keylargo_rev; +/* + * WARNING ! This function is called early in setup_arch, neither the IO base + * nor the udelay calibration have been done yet + */ void feature_init(void) { @@ -527,14 +534,31 @@ feature_set_usb_power(struct device_node* device, int power) void feature_set_firewire_power(struct device_node* device, int power) { + if (!uninorth_base) + return; + if (power) + UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW); + else + UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW); + udelay(20); +} + +#ifdef CONFIG_SMP +void +feature_core99_kick_cpu1(void) +{ + out_8((volatile u8 *)KL_FCR(KL_GPIO_KICK_CPU1), KL_GPIO_KICK_CPU1_UP); + udelay(1); + out_8((volatile u8 *)KL_FCR(KL_GPIO_KICK_CPU1), KL_GPIO_KICK_CPU1_DOWN); } +#endif /* CONFIG_SMP */ /* Initialize the Core99 UniNorth host bridge and memory controller */ static void uninorth_init(void) { - struct device_node* gmac; + struct device_node* gmac, *fw; unsigned long actrl; /* Set the arbitrer QAck delay according to what Apple does @@ -564,6 +588,11 @@ uninorth_init(void) } if (gmac) feature_set_gmac_power(gmac, 0); + + /* Kludge (enable FW before PCI probe) */ + fw = find_devices("firewire"); + if (fw && device_is_compatible(fw, "pci106b,18")) + feature_set_firewire_power(fw, 1); } /* Initialize the Core99 KeyLargo ASIC. Currently, we just make sure @@ -576,6 +605,43 @@ keylargo_init(void) } #ifdef CONFIG_PMAC_PBOOK + +static u32 save_fcr[5]; +static u32 save_mbcr; + +static void +heathrow_prepare_for_sleep(struct feature_controller* ctrler) +{ + save_mbcr = in_le32(FREG(ctrler, 0x34)); + save_fcr[0] = in_le32(FREG(ctrler, 0x38)); + save_fcr[1] = in_le32(FREG(ctrler, 0x3c)); + + out_le32(FREG(ctrler, 0x38), save_fcr[0] & ~HRW_IOBUS_ENABLE); +} + +static void +heathrow_wakeup(struct feature_controller* ctrler) +{ + out_le32(FREG(ctrler, 0x38), save_fcr[0]); + out_le32(FREG(ctrler, 0x3c), save_fcr[1]); + out_le32(FREG(ctrler, 0x34), save_mbcr); + mdelay(1); + out_le32(FREG(ctrler, 0x38), save_fcr[0] | HRW_IOBUS_ENABLE); + mdelay(1); +} + +static void +core99_prepare_for_sleep(struct feature_controller* ctrler) +{ + /* Not yet implemented */ +} + +static void +core99_wake_up(struct feature_controller* ctrler) +{ + /* Not yet implemented */ +} + void feature_prepare_for_sleep(void) { @@ -599,7 +665,6 @@ feature_prepare_for_sleep(void) } } - void feature_wake_up(void) { @@ -622,39 +687,4 @@ feature_wake_up(void) } } -static u32 save_fcr[5]; -static u32 save_mbcr; - -static void -heathrow_prepare_for_sleep(struct feature_controller* ctrler) -{ - save_mbcr = in_le32(FREG(ctrler, 0x34)); - save_fcr[0] = in_le32(FREG(ctrler, 0x38)); - save_fcr[1] = in_le32(FREG(ctrler, 0x3c)); - - out_le32(FREG(ctrler, 0x38), save_fcr[0] & ~HRW_IOBUS_ENABLE); -} - -static void -heathrow_wakeup(struct feature_controller* ctrler) -{ - out_le32(FREG(ctrler, 0x38), save_fcr[0]); - out_le32(FREG(ctrler, 0x3c), save_fcr[1]); - out_le32(FREG(ctrler, 0x34), save_mbcr); - mdelay(1); - out_le32(FREG(ctrler, 0x38), save_fcr[0] | HRW_IOBUS_ENABLE); - mdelay(1); -} - -static void -core99_prepare_for_sleep(struct feature_controller* ctrler) -{ - /* Not yet implemented */ -} - -static void -core99_wake_up(struct feature_controller* ctrler) -{ - /* Not yet implemented */ -} #endif /* CONFIG_PMAC_PBOOK */ diff --git a/arch/ppc/kernel/galaxy_pci.c b/arch/ppc/kernel/galaxy_pci.c index aeddd9a0e..36e7e14fb 100644 --- a/arch/ppc/kernel/galaxy_pci.c +++ b/arch/ppc/kernel/galaxy_pci.c @@ -36,67 +36,84 @@ /* Function Prototypes */ -decl_config_access_method(galaxy); - - void __init galaxy_pcibios_fixup(void) { } -void __init -galaxy_setup_pci_ptrs(void) +static int +galaxy_pcibios_read_config_byte(struct pci_controller* hose, + u8 bus, u8 dev, u8 offset, u8 *val) { - set_config_access_method(galaxy); - ppc_md.pcibios_fixup = galaxy_pcibios_fixup; + return (PCIBIOS_SUCCESSFUL); } -int -galaxy_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) +static int +galaxy_pcibios_read_config_word(struct pci_controller* hose, + u8 bus, u8 dev, u8 offset, u16 *val) { return (PCIBIOS_SUCCESSFUL); } -int -galaxy_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) +static int +galaxy_pcibios_read_config_dword(struct pci_controller* hose, + u8 bus, u8 dev, u8 offset, u32 *val) { return (PCIBIOS_SUCCESSFUL); } -int -galaxy_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) +static int +galaxy_pcibios_write_config_byte(struct pci_controller* hose, + u8 bus, u8 dev, u8 offset, u8 val) { return (PCIBIOS_SUCCESSFUL); } -int -galaxy_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) +static int +galaxy_pcibios_write_config_word(struct pci_controller* hose, + u8 bus, u8 dev, u8 offset, u16 val) { return (PCIBIOS_SUCCESSFUL); } -int -galaxy_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) +static int +galaxy_pcibios_write_config_dword(struct pci_controller* hose, + u8 bus, u8 dev, u8 offset, u32 val) { return (PCIBIOS_SUCCESSFUL); } -int -galaxy_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) +static struct pci_controller_ops galaxy_pci_ops = { + galaxy_pcibios_read_config_byte, + galaxy_pcibios_read_config_word, + galaxy_pcibios_read_config_dword, + galaxy_pcibios_write_config_byte, + galaxy_pcibios_write_config_word, + galaxy_pcibios_write_config_dword +}; - return (PCIBIOS_SUCCESSFUL); +void __init +galaxy_find_bridges(void) +{ + struct pci_controller* hose; + + set_config_access_method(galaxy); + + ppc_md.pcibios_fixup = galaxy_pcibios_fixup; + hose = pcibios_alloc_controller(); + if (!hose) + return; + hose->ops = &galaxy_pci_ops; + /* Todo ... + hose->cfg_data = ioremap(PCICFGDATA, ...); + hose->cfg_addr = ioremap(PCICFGADDR, ...); + */ } diff --git a/arch/ppc/kernel/hashtable.S b/arch/ppc/kernel/hashtable.S index 06b7c6f1d..8ea3cdc7a 100644 --- a/arch/ppc/kernel/hashtable.S +++ b/arch/ppc/kernel/hashtable.S @@ -56,7 +56,6 @@ hash_page: #ifdef CONFIG_PPC64BRIDGE mfmsr r0 clrldi r0,r0,1 /* make sure it's in 32-bit mode */ - sync MTMSRD(r0) isync #endif @@ -112,23 +111,31 @@ hash_page: #endif tophys(r2,r5) rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */ - lwz r6,0(r2) /* get linux-style pte */ ori r4,r4,1 /* set _PAGE_PRESENT bit in access */ + rlwinm r5,r4,5,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */ + rlwimi r5,r4,7,22,22 /* _PAGE_RW -> _PAGE_HWWRITE */ + ori r5,r5,0x100 /* set _PAGE_ACCESSED */ +retry: + lwz r6,0(r2) /* get linux-style pte */ andc. r0,r4,r6 /* check access & ~permission */ #ifdef CONFIG_SMP bne- hash_page_out /* return if access not permitted */ #else bnelr- #endif + andc. r0,r5,r6 /* any bits not yet set? */ + beq 2f - ori r6,r6,0x100 /* set _PAGE_ACCESSED in pte */ - rlwinm r5,r4,5,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */ - rlwimi r5,r4,7,22,22 /* _PAGE_RW -> _PAGE_HWWRITE */ - or r6,r6,r5 - stw r6,0(r2) /* update PTE (accessed/dirty bits) */ + /* Update the linux PTE atomically */ + lwarx r0,0,r2 /* refetch the pte and check */ + cmpw 0,r0,r6 /* that it hasn't been changed */ + bne- retry /* retry if it has */ + or r6,r6,r5 /* set accessed/dirty bits */ + stwcx. r6,0,r2 /* attempt to update PTE */ + bne- retry /* retry if someone got there first */ /* Convert linux-style PTE to low word of PPC-style PTE */ - rlwinm r4,r6,32-9,31,31 /* _PAGE_HWWRITE -> PP lsb */ +2: rlwinm r4,r6,32-9,31,31 /* _PAGE_HWWRITE -> PP lsb */ rlwimi r6,r6,32-1,31,31 /* _PAGE_USER -> PP (both bits now) */ ori r4,r4,0xe04 /* clear out reserved bits */ andc r6,r6,r4 /* PP=2 or 0, when _PAGE_HWWRITE */ @@ -166,12 +173,16 @@ hash_page_patch_A: rlwimi r4,r5,32-5,25-Hash_bits,24 /* (VSID & hash_mask) << 7 */ rlwinm r0,r3,32-5,25-Hash_bits,24 /* (PI & hash_mask) << 7 */ xor r4,r4,r0 /* make primary hash */ + li r2,8 /* PTEs/group */ +#ifndef CONFIG_SMP + /* We don't do this for SMP - another cpu could have put in + the appropriate PTE since we took the exception. -- paulus. */ /* See whether it was a PTE not found exception or a protection violation. */ andis. r0,r20,0x4000 - li r2,8 /* PTEs/group */ bne 10f /* no PTE: go look for an empty slot */ +#endif /* CONFIG_SMP */ tlbie r3 /* invalidate TLB entry */ /* Search the primary PTEG for a PTE whose 1st dword matches r5 */ @@ -263,7 +274,6 @@ found_empty: std r5,0(r3) found_slot: std r6,8(r3) - sync #else /* CONFIG_SMP */ /* @@ -311,12 +321,16 @@ hash_page_patch_A: rlwimi r4,r5,32-1,26-Hash_bits,25 /* (VSID & hash_mask) << 6 */ rlwinm r0,r3,32-6,26-Hash_bits,25 /* (PI & hash_mask) << 6 */ xor r4,r4,r0 /* make primary hash */ + li r2,8 /* PTEs/group */ +#ifndef CONFIG_SMP + /* We don't do this for SMP - another cpu could have put in + the appropriate PTE since we took the exception. -- paulus. */ /* See whether it was a PTE not found exception or a protection violation. */ andis. r0,r20,0x4000 - li r2,8 /* PTEs/group */ bne 10f /* no PTE: go look for an empty slot */ +#endif /* CONFIG_SMP */ tlbie r3 /* invalidate TLB entry */ /* Search the primary PTEG for a PTE whose 1st word matches r5 */ @@ -394,7 +408,6 @@ found_empty: stw r5,0(r3) found_slot: stw r6,4(r3) - sync #else /* CONFIG_SMP */ /* @@ -428,6 +441,8 @@ found_slot: #endif /* CONFIG_SMP */ #endif /* CONFIG_PPC64BRIDGE */ + sync /* make sure pte updates get to memory */ + /* * Update the hash table miss count. We only want misses here * that _are_ valid addresses and have a pte otherwise we don't @@ -517,7 +532,7 @@ _GLOBAL(flush_hash_segments) a hash table miss while we have the hash table locked, or we'll get a deadlock. -paulus */ mfmsr r10 - sync + SYNC rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ mtmsr r0 SYNC @@ -616,7 +631,7 @@ _GLOBAL(flush_hash_page) a hash table miss while we have the hash table locked, or we'll get a deadlock. -paulus */ mfmsr r10 - sync + SYNC rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ mtmsr r0 SYNC @@ -628,10 +643,14 @@ _GLOBAL(flush_hash_page) oris r8,r8,9 10: lwarx r7,0,r9 cmpi 0,r7,0 - bne- 10b + bne- 11f stwcx. r8,0,r9 - bne- 10b - eieio + beq+ 12f +11: lwz r7,0(r9) + cmpi 0,r7,0 + beq 10b + b 11b +12: eieio #endif #ifndef CONFIG_PPC64BRIDGE rlwinm r3,r3,11,1,20 /* put context into vsid */ diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index 71b5a96c5..f296d1606 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S @@ -149,6 +149,8 @@ __start: mr r28,r6 mr r27,r7 li r24,0 /* cpu # */ + /* N.B. prom_init clears the BSS even if it doesn't do + * anything else -- paulus. */ bl prom_init #ifdef CONFIG_APUS @@ -159,7 +161,6 @@ __start: bl fix_mem_constants #endif /* CONFIG_APUS */ -#ifndef CONFIG_GEMINI /* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains * the physical address we are running at, returned by prom_init() */ @@ -167,7 +168,6 @@ __start: __after_mmu_off: bl clear_bats bl flush_tlbs -#endif #ifndef CONFIG_POWER4 /* POWER4 doesn't have BATs */ @@ -290,6 +290,7 @@ label: \ addi r3,r1,STACK_FRAME_OVERHEAD; \ li r20,MSR_KERNEL; \ bl transfer_to_handler; \ +i##n: \ .long hdlr; \ .long ret_from_except @@ -301,17 +302,13 @@ label: \ addi r3,r1,STACK_FRAME_OVERHEAD; \ li r20,MSR_KERNEL; \ bl transfer_to_handler; \ +i##n: \ .long hdlr; \ .long ret_from_except /* System reset */ -#ifdef CONFIG_SMP /* MVME/MTX and gemini start the secondary here */ -#ifdef CONFIG_GEMINI - . = 0x100 - b __secondary_start_gemini -#else /* CONFIG_GEMINI */ +#ifdef CONFIG_SMP /* MVME/MTX start the secondary here */ STD_EXCEPTION(0x100, Reset, __secondary_start_psurge) -#endif /* CONFIG_GEMINI */ #else STD_EXCEPTION(0x100, Reset, UnknownException) #endif @@ -344,6 +341,7 @@ DataAccess: li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ bl transfer_to_handler +i0x300: .long do_page_fault .long ret_from_except @@ -384,6 +382,7 @@ InstructionAccess: li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ bl transfer_to_handler +i0x400: .long do_page_fault .long ret_from_except @@ -429,6 +428,7 @@ Alignment: li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ bl transfer_to_handler +i0x600: .long AlignmentException .long ret_from_except @@ -441,6 +441,7 @@ ProgramCheck: li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ bl transfer_to_handler +i0x700: .long ProgramCheckException .long ret_from_except @@ -452,6 +453,7 @@ FPUnavailable: bne load_up_fpu /* if from user, just load it up */ li r20,MSR_KERNEL bl transfer_to_handler /* if from kernel, take a trap */ +i0x800: .long KernelFP .long ret_from_except @@ -575,7 +577,7 @@ InstructionAddressInvalid: mfmsr r0 /* Restore "normal" registers */ xoris r0,r0,MSR_TGPR>>16 mtcrf 0x80,r3 /* Restore CR0 */ - sync /* Some chip revs have problems here... */ + SYNC /* Some chip revs have problems here... */ mtmsr r0 b InstructionAccess @@ -646,7 +648,7 @@ DataAddressInvalid: mfmsr r0 /* Restore "normal" registers */ xoris r0,r0,MSR_TGPR>>16 mtcrf 0x80,r3 /* Restore CR0 */ - sync /* Some chip revs have problems here... */ + SYNC /* Some chip revs have problems here... */ mtmsr r0 b DataAccess @@ -843,7 +845,7 @@ load_up_fpu: #endif /* CONFIG_PPC64BRIDGE */ SYNC MTMSRD(r5) /* enable use of fpu now */ - SYNC + isync /* * For SMP, we don't do lazy FPU switching because it just gets too * horrendously complex, especially when a task switches from one CPU @@ -929,7 +931,7 @@ load_up_altivec: oris r5,r5,MSR_VEC@h SYNC mtmsr r5 /* enable use of AltiVec now */ - SYNC + isync /* * For SMP, we don't do lazy AltiVec switching because it just gets too * horrendously complex, especially when a task switches from one CPU @@ -1023,7 +1025,7 @@ giveup_altivec: oris r5,r5,MSR_VEC@h SYNC mtmsr r5 /* enable use of AltiVec now */ - SYNC + isync cmpi 0,r3,0 beqlr- /* if no previous owner, done */ addi r3,r3,THREAD /* want THREAD of task */ @@ -1064,7 +1066,7 @@ giveup_fpu: ori r5,r5,MSR_FP SYNC mtmsr r5 /* enable use of fpu now */ - SYNC + isync cmpi 0,r3,0 beqlr- /* if no previous owner, done */ addi r3,r3,THREAD /* want THREAD of task */ @@ -1163,6 +1165,7 @@ fix_mem_constants: icbi r0,r14 /* flush the icache line */ cmpw r12,r13 bne 1b + isync /* * Map the memory where the exception handlers will @@ -1208,9 +1211,9 @@ apus_interrupt_entry: mfmsr 20 xori r20,r20,MSR_DR - sync + SYNC mtmsr r20 - sync + isync lis r4,APUS_IPL_EMU@h @@ -1243,9 +1246,9 @@ apus_interrupt_entry: mfmsr r20 xori r20,r20,MSR_DR - sync + SYNC mtmsr r20 - sync + isync stw r3,(_CCR+4)(r21); @@ -1263,28 +1266,24 @@ apus_interrupt_entry: #endif /* CONFIG_APUS */ #ifdef CONFIG_SMP -#ifdef CONFIG_GEMINI - .globl __secondary_start_gemini -__secondary_start_gemini: - mfspr r4,HID0 - ori r4,r4,HID0_ICFI - li r3,0 - ori r3,r3,HID0_ICE - andc r4,r4,r3 - mtspr HID0,r4 - sync - bl prom_init - b __secondary_start -#endif /* CONFIG_GEMINI */ - .globl __secondary_start_psurge __secondary_start_psurge: li r24,1 /* cpu # */ + b __secondary_start_psurge99 + .globl __secondary_start_psurge2 +__secondary_start_psurge2: + li r24,2 /* cpu # */ + b __secondary_start_psurge99 + .globl __secondary_start_psurge3 +__secondary_start_psurge3: + li r24,3 /* cpu # */ + b __secondary_start_psurge99 +__secondary_start_psurge99: /* we come in here with IR=0 and DR=1, and DBAT 0 set to map the 0xf0000000 - 0xffffffff region */ mfmsr r0 rlwinm r0,r0,0,28,26 /* clear DR (0x10) */ - sync + SYNC mtmsr r0 isync @@ -1293,7 +1292,7 @@ __secondary_start: #ifdef CONFIG_PPC64BRIDGE mfmsr r0 clrldi r0,r0,1 /* make sure it's in 32-bit mode */ - sync + SYNC MTMSRD(r0) isync #else @@ -1445,21 +1444,6 @@ start_here: li r3,0 mtspr SPRG2,r3 /* 0 => r1 has kernel sp */ - /* Clear out the BSS */ - lis r11,_end@ha - addi r11,r11,_end@l - lis r8,__bss_start@ha - addi r8,r8,__bss_start@l - subf r11,r8,r11 - addi r11,r11,3 - rlwinm. r11,r11,30,2,31 - beq 2f - addi r8,r8,-4 - mtctr r11 - li r0,0 -3: stwu r0,4(r8) - bdnz 3b -2: /* stack */ addi r1,r2,TASK_UNION_SIZE li r0,0 @@ -1504,7 +1488,7 @@ start_here: RFI /* Load up the kernel context */ 2: - SYNC /* Force all PTE updates to finish */ + sync /* Force all PTE updates to finish */ tlbia /* Clear all TLB entries */ sync /* wait for tlbia/tlbie to finish */ #ifdef CONFIG_SMP @@ -1552,7 +1536,6 @@ _GLOBAL(set_context) * -- Cort */ clear_bats: -#if !defined(CONFIG_GEMINI) li r20,0 mfspr r9,PVR rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ @@ -1576,10 +1559,8 @@ clear_bats: mtspr IBAT2L,r20 mtspr IBAT3U,r20 mtspr IBAT3L,r20 -#endif /* !defined(CONFIG_GEMINI) */ blr -#ifndef CONFIG_GEMINI flush_tlbs: lis r20, 0x40 1: addic. r20, r20, -0x1000 @@ -1598,7 +1579,6 @@ mmu_off: mtspr SRR1,r3 sync RFI -#endif #ifndef CONFIG_POWER4 /* @@ -1745,3 +1725,12 @@ swapper_pg_dir: .globl cmd_line cmd_line: .space 512 + + .globl intercept_table +intercept_table: + .long 0, i0x100, i0x200, i0x300, i0x400, 0, i0x600, i0x700 + .long i0x800, 0, 0, 0, 0, i0xd00, 0, 0 + .long 0, 0, 0, i0x1300, 0, 0, 0, 0 + .long 0, 0, 0, 0, 0, 0, 0, 0 + .long 0, 0, 0, 0, 0, 0, 0, 0 + .long 0, 0, 0, 0, 0, 0, 0, 0 diff --git a/arch/ppc/kernel/i8259.c b/arch/ppc/kernel/i8259.c index bdb6ec844..7690d9091 100644 --- a/arch/ppc/kernel/i8259.c +++ b/arch/ppc/kernel/i8259.c @@ -10,12 +10,15 @@ unsigned char cached_8259[2] = { 0xff, 0xff }; #define cached_A1 (cached_8259[0]) #define cached_21 (cached_8259[1]) +spinlock_t i8259_lock = SPIN_LOCK_UNLOCKED; + int i8259_pic_irq_offset; int i8259_irq(int cpu) { int irq; + spin_lock/*_irqsave*/(&i8259_lock/*, flags*/); /* * Perform an interrupt acknowledge cycle on controller 1 */ @@ -40,14 +43,20 @@ int i8259_irq(int cpu) * interrupt */ outb(0x0b, 0x20); - if(~inb(0x20)&0x80) + if(~inb(0x20)&0x80) { + spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/); return -1; + } } + spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/); return irq; } static void i8259_mask_and_ack_irq(unsigned int irq_nr) { + unsigned long flags; + + spin_lock_irqsave(&i8259_lock, flags); if ( irq_nr >= i8259_pic_irq_offset ) irq_nr -= i8259_pic_irq_offset; @@ -63,6 +72,7 @@ static void i8259_mask_and_ack_irq(unsigned int irq_nr) outb(cached_21,0x21); outb(0x20,0x20); /* Non-specific EOI */ } + spin_unlock_irqrestore(&i8259_lock, flags); } static void i8259_set_irq_mask(int irq_nr) @@ -73,6 +83,9 @@ static void i8259_set_irq_mask(int irq_nr) static void i8259_mask_irq(unsigned int irq_nr) { + unsigned long flags; + + spin_lock_irqsave(&i8259_lock, flags); if ( irq_nr >= i8259_pic_irq_offset ) irq_nr -= i8259_pic_irq_offset; if ( irq_nr < 8 ) @@ -80,11 +93,14 @@ static void i8259_mask_irq(unsigned int irq_nr) else cached_A1 |= 1 << (irq_nr-8); i8259_set_irq_mask(irq_nr); + spin_unlock_irqrestore(&i8259_lock, flags); } static void i8259_unmask_irq(unsigned int irq_nr) { + unsigned long flags; + spin_lock_irqsave(&i8259_lock, flags); if ( irq_nr >= i8259_pic_irq_offset ) irq_nr -= i8259_pic_irq_offset; if ( irq_nr < 8 ) @@ -92,6 +108,13 @@ static void i8259_unmask_irq(unsigned int irq_nr) else cached_A1 &= ~(1 << (irq_nr-8)); i8259_set_irq_mask(irq_nr); + spin_unlock_irqrestore(&i8259_lock, flags); +} + +static void i8259_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + i8259_unmask_irq(irq); } struct hw_interrupt_type i8259_pic = { @@ -101,11 +124,15 @@ struct hw_interrupt_type i8259_pic = { i8259_unmask_irq, i8259_mask_irq, i8259_mask_and_ack_irq, - 0 + i8259_end_irq, + NULL }; void __init i8259_init(void) { + unsigned long flags; + + spin_lock_irqsave(&i8259_lock, flags); /* init master interrupt controller */ outb(0x11, 0x20); /* Start init sequence */ outb(0x00, 0x21); /* Vector base */ @@ -120,7 +147,7 @@ void __init i8259_init(void) outb(0xFF, 0xA1); /* Mask all */ outb(cached_A1, 0xA1); outb(cached_21, 0x21); + spin_unlock_irqrestore(&i8259_lock, flags); request_irq( i8259_pic_irq_offset + 2, no_action, SA_INTERRUPT, "82c59 secondary cascade", NULL ); - enable_irq(i8259_pic_irq_offset + 2); /* Enable cascade interrupt */ } diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c index a363a0e34..6ca616979 100644 --- a/arch/ppc/kernel/idle.c +++ b/arch/ppc/kernel/idle.c @@ -47,24 +47,35 @@ atomic_t zeropage_calls; /* # zero'd pages request that've been made */ int idled(void) { + int do_power_save = 0; + + /* only sleep on the 603-family/750 processors */ + switch (_get_PVR() >> 16) { + case 3: /* 603 */ + case 6: /* 603e */ + case 7: /* 603ev */ + case 8: /* 750 */ + case 12: /* 7400 */ + do_power_save = 1; + } + /* endless loop with no priority at all */ current->nice = 20; current->counter = -100; init_idle(); for (;;) { - __sti(); - - check_pgt_cache(); - - /*if ( !current->need_resched && zero_paged_on ) zero_paged();*/ - if ( !current->need_resched && htab_reclaim_on ) htab_reclaim(); - if ( !current->need_resched ) power_save(); + /*if ( !current->need_resched && zero_paged_on ) + zero_paged();*/ + if (!current->need_resched && htab_reclaim_on) + htab_reclaim(); + if (do_power_save && !current->need_resched) + power_save(); -#ifdef CONFIG_SMP - if (current->need_resched) -#endif + if (current->need_resched) { schedule(); + check_pgt_cache(); + } } return 0; } @@ -278,31 +289,31 @@ void zero_paged(void) void power_save(void) { - unsigned long msr, hid0; - - /* only sleep on the 603-family/750 processors */ - switch (_get_PVR() >> 16) { - case 3: /* 603 */ - case 6: /* 603e */ - case 7: /* 603ev */ - case 8: /* 750 */ - case 12: /* 7400 */ - save_flags(msr); - __cli(); - if (!current->need_resched) { - asm("mfspr %0,1008" : "=r" (hid0) :); - hid0 &= ~(HID0_NAP | HID0_SLEEP | HID0_DOZE); - hid0 |= (powersave_nap? HID0_NAP: HID0_DOZE) | HID0_DPM; - asm("mtspr 1008,%0" : : "r" (hid0)); + unsigned long hid0; + /* + * Disable interrupts to prevent a lost wakeup + * when going to sleep. This is necessary even with + * RTLinux since we are not guaranteed an interrupt + * didn't come in and is waiting for a __sti() before + * emulating one. This way, we really do hard disable. + * + * We assume that we're sti-ed when we come in here. We + * are in the idle loop so if we're cli-ed then it's a bug + * anyway. + * -- Cort + */ + _nmask_and_or_msr(MSR_EE, 0); + if (!current->need_resched) + { + asm("mfspr %0,1008" : "=r" (hid0) :); + hid0 &= ~(HID0_NAP | HID0_SLEEP | HID0_DOZE); + hid0 |= (powersave_nap? HID0_NAP: HID0_DOZE) | HID0_DPM; + asm("mtspr 1008,%0" : : "r" (hid0)); - /* set the POW bit in the MSR, and enable interrupts - * so we wake up sometime! */ - __sti(); /* this keeps rtl from getting confused -- Cort */ - _nmask_and_or_msr(0, MSR_POW | MSR_EE); - } - restore_flags(msr); - default: - return; + /* set the POW bit in the MSR, and enable interrupts + * so we wake up sometime! */ + _nmask_and_or_msr(0, MSR_POW | MSR_EE); } + _nmask_and_or_msr(0, MSR_EE); } diff --git a/arch/ppc/kernel/indirect_pci.c b/arch/ppc/kernel/indirect_pci.c index 552c552dc..3ba335d1f 100644 --- a/arch/ppc/kernel/indirect_pci.c +++ b/arch/ppc/kernel/indirect_pci.c @@ -9,113 +9,59 @@ * 2 of the License, or (at your option) any later version. */ +#include <linux/kernel.h> #include <linux/pci.h> -#include <asm/io.h> -#include <asm/system.h> - -unsigned int * pci_config_address; -unsigned char * pci_config_data; - -int indirect_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) -{ - unsigned long flags; - - save_flags(flags); cli(); - - out_be32(pci_config_address, - ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80); +#include <linux/delay.h> +#include <linux/string.h> +#include <linux/init.h> +#include <linux/bootmem.h> - *val= in_8(pci_config_data + (offset&3)); - - restore_flags(flags); - return PCIBIOS_SUCCESSFUL; +#include <asm/init.h> +#include <asm/io.h> +#include <asm/prom.h> +#include <asm/pci-bridge.h> +#include <asm/machdep.h> + +#include "pci.h" + +#define cfg_read(val, addr, type, op) *val = op((type)(addr)) +#define cfg_write(val, addr, type, op) op((type *)(addr), (val)) + +#define INDIRECT_PCI_OP(rw, size, type, op, mask) \ +static int \ +indirect_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + struct pci_controller *hose = dev->sysdata; \ + \ + out_be32(hose->cfg_addr, \ + ((offset & 0xfc) << 24) | (dev->devfn << 16) \ + | (dev->bus->number << 8) | 0x80); \ + cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \ + return PCIBIOS_SUCCESSFUL; \ } -int indirect_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) -{ - unsigned long flags; - - if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER; - - save_flags(flags); cli(); - - out_be32(pci_config_address, - ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80); +INDIRECT_PCI_OP(read, byte, u8 *, in_8, 3) +INDIRECT_PCI_OP(read, word, u16 *, in_le16, 2) +INDIRECT_PCI_OP(read, dword, u32 *, in_le32, 0) +INDIRECT_PCI_OP(write, byte, u8, out_8, 3) +INDIRECT_PCI_OP(write, word, u16, out_le16, 2) +INDIRECT_PCI_OP(write, dword, u32, out_le32, 0) - *val= in_le16((unsigned short *)(pci_config_data + (offset&3))); - - restore_flags(flags); - return PCIBIOS_SUCCESSFUL; -} - -int indirect_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) +static struct pci_ops indirect_pci_ops = { - unsigned long flags; - - if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER; - - save_flags(flags); cli(); - - out_be32(pci_config_address, - ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80); - - *val= in_le32((unsigned *)pci_config_data); - - restore_flags(flags); - return PCIBIOS_SUCCESSFUL; -} - -int indirect_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) + indirect_read_config_byte, + indirect_read_config_word, + indirect_read_config_dword, + indirect_write_config_byte, + indirect_write_config_word, + indirect_write_config_dword +}; + +void __init +setup_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data) { - unsigned long flags; - - save_flags(flags); cli(); - - out_be32(pci_config_address, - ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80); - - out_8(pci_config_data + (offset&3), val); - - restore_flags(flags); - return PCIBIOS_SUCCESSFUL; -} - -int indirect_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) -{ - unsigned long flags; - - if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER; - - save_flags(flags); cli(); - - out_be32(pci_config_address, - ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80); - - out_le16((unsigned short *)(pci_config_data + (offset&3)), val); - - restore_flags(flags); - return PCIBIOS_SUCCESSFUL; + hose->ops = &indirect_pci_ops; + hose->cfg_addr = (unsigned int *) ioremap(cfg_addr, 4); + hose->cfg_data = (unsigned char *) ioremap(cfg_data, 4); } -int indirect_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) -{ - unsigned long flags; - - if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER; - - save_flags(flags); cli(); - - out_be32(pci_config_address, - ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80); - - out_le32((unsigned *)pci_config_data, val); - - restore_flags(flags); - return PCIBIOS_SUCCESSFUL; -} diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c index a0caa4a4c..02ff4d964 100644 --- a/arch/ppc/kernel/irq.c +++ b/arch/ppc/kernel/irq.c @@ -41,11 +41,11 @@ #include <linux/config.h> #include <linux/init.h> #include <linux/malloc.h> -#include <linux/openpic.h> #include <linux/pci.h> #include <linux/delay.h> #include <linux/irq.h> #include <linux/proc_fs.h> +#include <linux/random.h> #include <asm/uaccess.h> #include <asm/bitops.h> @@ -64,19 +64,22 @@ #include "local_irq.h" -extern volatile unsigned long ipi_count; +atomic_t ipi_recv; +atomic_t ipi_sent; void enable_irq(unsigned int irq_nr); void disable_irq(unsigned int irq_nr); -volatile unsigned char *chrp_int_ack_special; +static void register_irq_proc (unsigned int irq); #define MAXCOUNT 10000000 -irq_desc_t irq_desc[NR_IRQS]; +irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = + { [0 ... NR_IRQS-1] = { 0, NULL, NULL, 0, SPIN_LOCK_UNLOCKED}}; + int ppc_spurious_interrupts = 0; struct irqaction *ppc_irq_action[NR_IRQS]; -unsigned int ppc_cached_irq_mask[NR_MASK_WORDS]; -unsigned int ppc_lost_interrupts[NR_MASK_WORDS]; +unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; +unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; atomic_t ppc_n_lost_interrupts; /* nasty hack for shared irq's since we need to do kmalloc calls but @@ -115,52 +118,136 @@ void irq_kfree(void *ptr) kfree(ptr); } +int +setup_irq(unsigned int irq, struct irqaction * new) +{ + int shared = 0; + unsigned long flags; + struct irqaction *old, **p; + irq_desc_t *desc = irq_desc + irq; + + /* + * Some drivers like serial.c use request_irq() heavily, + * so we have to be careful not to interfere with a + * running system. + */ + if (new->flags & SA_SAMPLE_RANDOM) { + /* + * This function might sleep, we want to call it first, + * outside of the atomic block. + * Yes, this might clear the entropy pool if the wrong + * driver is attempted to be loaded, without actually + * installing a new handler, but is this really a problem, + * only the sysadmin is able to do this. + */ + rand_initialize_irq(irq); + } + + /* + * The following block of code has to be executed atomically + */ + spin_lock_irqsave(&desc->lock,flags); + p = &desc->action; + if ((old = *p) != NULL) { + /* Can't share interrupts unless both agree to */ + if (!(old->flags & new->flags & SA_SHIRQ)) { + spin_unlock_irqrestore(&desc->lock,flags); + return -EBUSY; + } + + /* add new interrupt at end of irq queue */ + do { + p = &old->next; + old = *p; + } while (old); + shared = 1; + } + + *p = new; + + if (!shared) { + desc->depth = 0; + desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING); + unmask_irq(irq); + } + spin_unlock_irqrestore(&desc->lock,flags); + + register_irq_proc(irq); + return 0; +} + +/* This could be promoted to a real free_irq() ... */ +static int +do_free_irq(int irq, void* dev_id) +{ + irq_desc_t *desc; + struct irqaction **p; + unsigned long flags; + + desc = irq_desc + irq; + spin_lock_irqsave(&desc->lock,flags); + p = &desc->action; + for (;;) { + struct irqaction * action = *p; + if (action) { + struct irqaction **pp = p; + p = &action->next; + if (action->dev_id != dev_id) + continue; + + /* Found it - now remove it from the list of entries */ + *pp = action->next; + if (!desc->action) { + desc->status |= IRQ_DISABLED; + mask_irq(irq); + } + spin_unlock_irqrestore(&desc->lock,flags); + +#ifdef CONFIG_SMP + /* Wait to make sure it's not being used on another CPU */ + while (desc->status & IRQ_INPROGRESS) + barrier(); +#endif + irq_kfree(action); + return 0; + } + printk("Trying to free free IRQ%d\n",irq); + spin_unlock_irqrestore(&desc->lock,flags); + break; + } + return -ENOENT; +} + #if (defined(CONFIG_8xx) || defined(CONFIG_8260)) /* Name change so we can catch standard drivers that potentially mess up * the internal interrupt controller on 8xx and 8260. Just bear with me, * I don't like this either and I am searching a better solution. For * now, this is what I need. -- Dan */ -int request_8xxirq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), +#define request_irq request_8xxirq #elif defined(CONFIG_APUS) -int request_sysirq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), -#else -int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), +#define request_irq request_sysirq +#define free_irq sys_free_irq #endif + +int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char * devname, void *dev_id) { - struct irqaction *old, **p, *action; - unsigned long flags; + struct irqaction *action; + int retval; if (irq >= NR_IRQS) return -EINVAL; if (!handler) - { - /* Free */ - p = &irq_desc[irq].action; - while ((action = *p) != NULL && action->dev_id != dev_id) - p = &action->next; - if (action == NULL) - return -ENOENT; - - /* Found it - now free it */ - save_flags(flags); - cli(); - *p = action->next; - if (irq_desc[irq].action == NULL) - disable_irq(irq); - restore_flags(flags); - irq_kfree(action); - return 0; - } + /* We could implement really free_irq() instead of that... */ + return do_free_irq(irq, dev_id); action = (struct irqaction *) irq_kmalloc(sizeof(struct irqaction), GFP_KERNEL); - if (!action) + if (!action) { + printk(KERN_ERR "irq_kmalloc() failed for irq %d !\n", irq); return -ENOMEM; - - save_flags(flags); - cli(); + } action->handler = handler; action->flags = irqflags; @@ -168,57 +255,109 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *) action->name = devname; action->dev_id = dev_id; action->next = NULL; - enable_irq(irq); - p = &irq_desc[irq].action; - - if ((old = *p) != NULL) { - /* Can't share interrupts unless both agree to */ - if (!(old->flags & action->flags & SA_SHIRQ)) - return -EBUSY; - /* add new interrupt at end of irq queue */ - do { - p = &old->next; - old = *p; - } while (old); - } - *p = action; - - restore_flags(flags); + retval = setup_irq(irq, action); + if (retval) + kfree(action); + return 0; } -#ifdef CONFIG_APUS -void sys_free_irq(unsigned int irq, void *dev_id) -{ - sys_request_irq(irq, NULL, 0, NULL, dev_id); -} -#else void free_irq(unsigned int irq, void *dev_id) { -#if (defined(CONFIG_8xx) || defined(CONFIG_8260)) - request_8xxirq(irq, NULL, 0, NULL, dev_id); -#else request_irq(irq, NULL, 0, NULL, dev_id); -#endif } -#endif -/* XXX should implement irq disable depth like on intel */ -void disable_irq_nosync(unsigned int irq_nr) +/* + * Generic enable/disable code: this just calls + * down into the PIC-specific version for the actual + * hardware disable after having gotten the irq + * controller lock. + */ + +/** + * disable_irq_nosync - disable an irq without waiting + * @irq: Interrupt to disable + * + * Disable the selected interrupt line. Disables of an interrupt + * stack. Unlike disable_irq(), this function does not ensure existing + * instances of the IRQ handler have completed before returning. + * + * This function may be called from IRQ context. + */ + + void disable_irq_nosync(unsigned int irq) { - mask_irq(irq_nr); + irq_desc_t *desc = irq_desc + irq; + unsigned long flags; + + spin_lock_irqsave(&desc->lock, flags); + if (!desc->depth++) { + if (!(desc->status & IRQ_PER_CPU)) + desc->status |= IRQ_DISABLED; + mask_irq(irq); + } + spin_unlock_irqrestore(&desc->lock, flags); } -void disable_irq(unsigned int irq_nr) +/** + * disable_irq - disable an irq and wait for completion + * @irq: Interrupt to disable + * + * Disable the selected interrupt line. Disables of an interrupt + * stack. That is for two disables you need two enables. This + * function waits for any pending IRQ handlers for this interrupt + * to complete before returning. If you use this function while + * holding a resource the IRQ handler may need you will deadlock. + * + * This function may be called - with care - from IRQ context. + */ + +void disable_irq(unsigned int irq) { - mask_irq(irq_nr); - synchronize_irq(); + disable_irq_nosync(irq); + + if (!local_irq_count(smp_processor_id())) { + do { + barrier(); + } while (irq_desc[irq].status & IRQ_INPROGRESS); + } } -void enable_irq(unsigned int irq_nr) +/** + * enable_irq - enable interrupt handling on an irq + * @irq: Interrupt to enable + * + * Re-enables the processing of interrupts on this IRQ line + * providing no disable_irq calls are now in effect. + * + * This function may be called from IRQ context. + */ + +void enable_irq(unsigned int irq) { - unmask_irq(irq_nr); + irq_desc_t *desc = irq_desc + irq; + unsigned long flags; + + spin_lock_irqsave(&desc->lock, flags); + switch (desc->depth) { + case 1: { + unsigned int status = desc->status & ~IRQ_DISABLED; + desc->status = status; + if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { + desc->status = status | IRQ_REPLAY; + hw_resend_irq(desc->handler,irq); + } + unmask_irq(irq); + /* fall-through */ + } + default: + desc->depth--; + break; + case 0: + printk("enable_irq(%u) unbalanced\n", irq); + } + spin_unlock_irqrestore(&desc->lock, flags); } int get_irq_list(char *buf) @@ -257,15 +396,41 @@ int get_irq_list(char *buf) } len += sprintf(buf+len, "\n"); } +#ifdef CONFIG_TAU + len += sprintf(buf+len, "TAU: "); + for (j = 0; j < smp_num_cpus; j++) + len += sprintf(buf+len, "%10u ", + tau_interrupts(j)); + len += sprintf(buf+len, "\n"); +#endif #ifdef CONFIG_SMP /* should this be per processor send/receive? */ - len += sprintf(buf+len, "IPI: %10lu\n", ipi_count); + len += sprintf(buf+len, "IPI (recv/sent): %10u/%u\n", + atomic_read(&ipi_recv), atomic_read(&ipi_sent)); #endif len += sprintf(buf+len, "BAD: %10u\n", ppc_spurious_interrupts); return len; #endif /* CONFIG_APUS */ } +static inline void +handle_irq_event(int irq, struct pt_regs *regs, struct irqaction *action) +{ + int status = 0; + + if (!(action->flags & SA_INTERRUPT)) + __sti(); + + do { + status |= action->flags; + action->handler(irq, action->dev_id, regs); + action = action->next; + } while (action); + if (status & SA_SAMPLE_RANDOM) + add_interrupt_randomness(irq); + __cli(); +} + /* * Eventually, this should take an array of interrupts and an array size * so it can dispatch multiple interrupts. @@ -275,33 +440,87 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq) int status; struct irqaction *action; int cpu = smp_processor_id(); + irq_desc_t *desc = irq_desc + irq; - mask_and_ack_irq(irq); - status = 0; - action = irq_desc[irq].action; kstat.irqs[cpu][irq]++; - if (action && action->handler) { - if (!(action->flags & SA_INTERRUPT)) - __sti(); - do { - status |= action->flags; - action->handler(irq, action->dev_id, regs); - action = action->next; - } while ( action ); - __cli(); - if (irq_desc[irq].handler) { - if (irq_desc[irq].handler->end) - irq_desc[irq].handler->end(irq); - else if (irq_desc[irq].handler->enable) - irq_desc[irq].handler->enable(irq); + spin_lock(&desc->lock); + ack_irq(irq); + /* + REPLAY is when Linux resends an IRQ that was dropped earlier + WAITING is used by probe to mark irqs that are being tested + */ + status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING); + if (!(status & IRQ_PER_CPU)) + status |= IRQ_PENDING; /* we _want_ to handle it */ + + /* + * If the IRQ is disabled for whatever reason, we cannot + * use the action we have. + */ + action = NULL; + if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + action = desc->action; + if (!action || !action->handler) { + ppc_spurious_interrupts++; + printk(KERN_DEBUG "Unhandled interrupt %x, disabled\n", irq); + /* We can't call disable_irq here, it would deadlock */ + if (!desc->depth) + desc->depth = 1; + desc->status |= IRQ_DISABLED; + /* This is not a real spurrious interrupt, we + * have to eoi it, so we jump to out + */ + mask_irq(irq); + goto out; } - } else { - ppc_spurious_interrupts++; - printk(KERN_DEBUG "Unhandled interrupt %x, disabled\n", irq); - disable_irq(irq); + status &= ~IRQ_PENDING; /* we commit to handling */ + if (!(status & IRQ_PER_CPU)) + status |= IRQ_INPROGRESS; /* we are handling it */ + } + desc->status = status; + + /* + * If there is no IRQ handler or it was disabled, exit early. + Since we set PENDING, if another processor is handling + a different instance of this same irq, the other processor + will take care of it. + */ + if (!action) + goto out; + + + /* + * Edge triggered interrupts need to remember + * pending events. + * This applies to any hw interrupts that allow a second + * instance of the same irq to arrive while we are in do_IRQ + * or in the handler. But the code here only handles the _second_ + * instance of the irq, not the third or fourth. So it is mostly + * useful for irq hardware that does not mask cleanly in an + * SMP environment. + */ + for (;;) { + spin_unlock(&desc->lock); + handle_irq_event(irq, regs, action); + spin_lock(&desc->lock); + + if (!(desc->status & IRQ_PENDING)) + break; + desc->status &= ~IRQ_PENDING; + } + desc->status &= ~IRQ_INPROGRESS; +out: + /* + * The ->end() handler has to deal with interrupts which got + * disabled while the handler was running. + */ + if (irq_desc[irq].handler) { if (irq_desc[irq].handler->end) irq_desc[irq].handler->end(irq); + else if (irq_desc[irq].handler->enable) + irq_desc[irq].handler->enable(irq); } + spin_unlock(&desc->lock); } int do_IRQ(struct pt_regs *regs, int isfake) @@ -320,6 +539,7 @@ int do_IRQ(struct pt_regs *regs, int isfake) { printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n", irq, regs->nip); + /* That's not SMP safe ... but who cares ? */ ppc_spurious_interrupts++; } goto out; @@ -362,7 +582,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SMP unsigned char global_irq_holder = NO_PROC_ID; -unsigned volatile int global_irq_lock; +unsigned volatile long global_irq_lock; /* pendantic :long for set_bit--RR*/ atomic_t global_irq_count; atomic_t global_bh_count; @@ -634,7 +854,11 @@ static struct proc_dir_entry * root_irq_dir; static struct proc_dir_entry * irq_dir [NR_IRQS]; static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; +#ifdef CONFIG_IRQ_ALL_CPUS unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0xffffffff}; +#else /* CONFIG_IRQ_ALL_CPUS */ +unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0x00000000}; +#endif /* CONFIG_IRQ_ALL_CPUS */ #define HEX_DIGITS 8 @@ -694,6 +918,7 @@ static int irq_affinity_write_proc (struct file *file, const char *buffer, err = parse_hex_value(buffer, count, &new_value); +/* Why is this disabled ? --BenH */ #if 0/*CONFIG_SMP*/ /* * Do not allow disabling IRQs completely - it's a too easy diff --git a/arch/ppc/kernel/local_irq.h b/arch/ppc/kernel/local_irq.h index 5c616bbbd..319e3377c 100644 --- a/arch/ppc/kernel/local_irq.h +++ b/arch/ppc/kernel/local_irq.h @@ -15,8 +15,5 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq); extern int ppc_spurious_interrupts; extern int ppc_second_irq; extern struct irqaction *ppc_irq_action[NR_IRQS]; -extern unsigned int ppc_cached_irq_mask[NR_MASK_WORDS]; -extern unsigned int ppc_lost_interrupts[NR_MASK_WORDS]; -extern atomic_t ppc_n_lost_interrupts; #endif /* _PPC_KERNEL_LOCAL_IRQ_H */ diff --git a/arch/ppc/kernel/m8260_setup.c b/arch/ppc/kernel/m8260_setup.c index 6e006a867..a55f5235d 100644 --- a/arch/ppc/kernel/m8260_setup.c +++ b/arch/ppc/kernel/m8260_setup.c @@ -62,7 +62,7 @@ extern void mackbd_leds(unsigned char leds); extern void mackbd_init_hw(void); #endif -extern unsigned long loops_per_sec; +extern unsigned long loops_per_jiffy; unsigned char __res[sizeof(bd_t)]; unsigned long empty_zero_page[1024]; @@ -286,10 +286,7 @@ m8260_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_ide_md.outsw = m8xx_ide_outsw; ppc_ide_md.default_irq = m8xx_ide_default_irq; ppc_ide_md.default_io_base = m8xx_ide_default_io_base; - ppc_ide_md.check_region = m8xx_ide_check_region; - ppc_ide_md.request_region = m8xx_ide_request_region; - ppc_ide_md.release_region = m8xx_ide_release_region; - ppc_ide_md.fix_driveid = m8xx_ide_fix_driveid; + ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid; ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports; ppc_ide_md.ide_request_irq = m8xx_ide_request_irq; @@ -297,13 +294,39 @@ m8260_init(unsigned long r3, unsigned long r4, unsigned long r5, #endif } -void +/* + * Copied from prom.c so I don't have include all of that crap. + * -- Dan + * + * prom_init() is called very early on, before the kernel text + * and data have been mapped to KERNELBASE. At this point the code + * is running at whatever address it has been loaded at, so + * references to extern and static variables must be relocated + * explicitly. The procedure reloc_offset() returns the address + * we're currently running at minus the address we were linked at. + * (Note that strings count as static variables.) + */ +extern unsigned long reloc_offset(void); +#define PTRRELOC(x) ((typeof(x))((unsigned long)(x) + offset)) + +__init +unsigned long prom_init(uint r3, uint r4, uint r5, uint r6) { - /* Nothing to do now, but we are called immediatedly upon - * kernel start up with MMU disabled, so if there is - * anything we need to do...... - */ + unsigned long offset = reloc_offset(); + unsigned long phys; + extern char __bss_start, _end; + + /* First zero the BSS -- use memset, some arches don't have + * caches on yet */ + memset_io(PTRRELOC(&__bss_start),0 , &_end - &__bss_start); + + /* Default */ + phys = offset + KERNELBASE; + + /* We are done. + */ + return phys; } /* Mainly for ksyms. diff --git a/arch/ppc/kernel/m8xx_setup.c b/arch/ppc/kernel/m8xx_setup.c index 7dc408a13..f9813fa75 100644 --- a/arch/ppc/kernel/m8xx_setup.c +++ b/arch/ppc/kernel/m8xx_setup.c @@ -63,8 +63,6 @@ extern void mackbd_leds(unsigned char leds); extern void mackbd_init_hw(void); #endif -extern unsigned long loops_per_sec; - unsigned char __res[sizeof(bd_t)]; unsigned long empty_zero_page[1024]; @@ -344,25 +342,6 @@ m8xx_ide_default_io_base(int index) } int -m8xx_ide_check_region(ide_ioreg_t from, unsigned int extent) -{ - return 0; -} - -void -m8xx_ide_request_region(ide_ioreg_t from, - unsigned int extent, - const char *name) -{ -} - -void -m8xx_ide_release_region(ide_ioreg_t from, - unsigned int extent) -{ -} - -int m8xx_ide_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, @@ -376,12 +355,6 @@ m8xx_ide_request_irq(unsigned int irq, #endif } -void -m8xx_ide_fix_driveid(struct hd_driveid *id) -{ - ppc_generic_ide_fix_driveid(id); -} - /* We can use an external IDE controller or wire the IDE interface to * the internal PCMCIA controller. */ @@ -515,10 +488,7 @@ m8xx_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_ide_md.outsw = m8xx_ide_outsw; ppc_ide_md.default_irq = m8xx_ide_default_irq; ppc_ide_md.default_io_base = m8xx_ide_default_io_base; - ppc_ide_md.check_region = m8xx_ide_check_region; - ppc_ide_md.request_region = m8xx_ide_request_region; - ppc_ide_md.release_region = m8xx_ide_release_region; - ppc_ide_md.fix_driveid = m8xx_ide_fix_driveid; + ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid; ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports; ppc_ide_md.ide_request_irq = m8xx_ide_request_irq; diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 94e1cd277..3f54003c7 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -37,6 +37,14 @@ .text + .align 5 +_GLOBAL(__delay) + cmpwi 0,r3,0 + mtctr r3 + beqlr +1: bdnz 1b + blr + /* * Returns (address we're running at) - (address we were linked at) * for use before the text and data are mapped to KERNELBASE. @@ -82,16 +90,16 @@ _GLOBAL(__no_use_restore_flags) lwz r7,ppc_n_lost_interrupts@l(r7) cmpi 0,r7,0 /* lost interrupts to process first? */ bne- do_lost_interrupts -1: sync +1: SYNC mtmsr r3 - isync + SYNC blr _GLOBAL(__no_use_cli) mfmsr r0 /* Get current interrupt state */ rlwinm r3,r0,16+1,32-1,31 /* Extract old value of 'EE' */ rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */ - sync /* Some chip revs have problems here... */ + SYNC /* Some chip revs have problems here... */ mtmsr r0 /* Update machine state */ blr /* Done */ @@ -102,7 +110,7 @@ _GLOBAL(__no_use_sti) ori r3,r3,MSR_EE /* Turn on 'EE' bit */ cmpi 0,r4,0 /* lost interrupts to process first? */ bne- do_lost_interrupts - sync /* Some chip revs have problems here... */ + SYNC /* Some chip revs have problems here... */ mtmsr r3 /* Update machine state */ blr @@ -121,7 +129,7 @@ _GLOBAL(do_lost_interrupts) cmpi 0,r4,0 bne- 1b lwz r3,8(r1) - sync + SYNC mtmsr r3 lwz r0,20(r1) mtlr r0 @@ -137,8 +145,9 @@ _GLOBAL(do_lost_interrupts) mfmsr r0 /* Get current msr */ andc r0,r0,r3 /* And off the bits set in r3 (first parm) */ or r0,r0,r4 /* Or on the bits in r4 (second parm) */ - sync /* Some chip revs have problems here... */ + SYNC /* Some chip revs have problems here... */ mtmsr r0 /* Update machine state */ + isync blr /* Done */ @@ -148,7 +157,7 @@ _GLOBAL(do_lost_interrupts) _GLOBAL(_tlbia) #if defined(CONFIG_SMP) mfmsr r10 - sync + SYNC rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ mtmsr r0 SYNC @@ -161,7 +170,6 @@ _GLOBAL(_tlbia) bne- 10b stwcx. r8,0,r9 bne- 10b - eieio #endif /* CONFIG_SMP */ sync tlbia @@ -182,7 +190,7 @@ _GLOBAL(_tlbia) _GLOBAL(_tlbie) #if defined(CONFIG_SMP) mfmsr r10 - sync + SYNC rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ mtmsr r0 SYNC @@ -228,7 +236,7 @@ _GLOBAL(flush_instruction_cache) ori r3,r3,HID0_ICFI mtspr HID0,r3 #endif /* CONFIG_8xx */ - SYNC + isync blr /* @@ -259,7 +267,6 @@ _GLOBAL(flush_icache_range) 2: icbi 0,r6 addi r6,r6,CACHE_LINE_SIZE bdnz 2b - sync isync blr @@ -717,6 +724,8 @@ _GLOBAL(_get_SP) mr r3,r1 /* Close enough */ blr +#if 0 +/* isn't it just easier to use the mtspr/mfspr inline macros?? --Troy */ _GLOBAL(_get_THRM1) mfspr r3,THRM1 blr @@ -740,6 +749,7 @@ _GLOBAL(_set_THRM2) _GLOBAL(_set_THRM3) mtspr THRM3,r3 blr +#endif _GLOBAL(_get_PVR) mfspr r3,PVR @@ -755,6 +765,12 @@ _GLOBAL(_get_HID0) mfspr r3,HID0 blr +_GLOBAL(_set_HID0) + sync + mtspr HID0, r3 + SYNC /* Handle erratas in some cases */ + blr + _GLOBAL(_get_ICTC) mfspr r3,ICTC blr @@ -763,7 +779,6 @@ _GLOBAL(_set_ICTC) mtspr ICTC,r3 blr - /* L2CR functions Copyright © 1997-1998 by PowerLogix R & D, Inc. @@ -785,6 +800,17 @@ _GLOBAL(_set_ICTC) /* Thur, Dec. 12, 1998. - First public release, contributed by PowerLogix. + *********** + Sat, Aug. 7, 1999. + - Terry: Made sure code disabled interrupts before running. (Previously + it was assumed interrupts were already disabled). + - Terry: Updated for tentative G4 support. 4MB of memory is now flushed + instead of 2MB. (Prob. only 3 is necessary). + - Terry: Updated for workaround to HID0[DPM] processor bug + during global invalidates. + *********** + Thu, July 13, 2000. + - Terry: Added isync to correct for an errata. Author: Terry Greeniaus (tgree@phys.ualberta.ca) Please e-mail updates to this file to me, thanks! @@ -823,82 +849,94 @@ _GLOBAL(_set_ICTC) causes cache pushes from the L1 cache to go to the L2 cache instead of to main memory. */ - +/* + * Summary: this procedure ignores the L2I bit in the value passed in, + * flushes the cache if it was already enabled, always invalidates the + * cache, then enables the cache if the L2E bit is set in the value + * passed in. + * -- paulus. + */ _GLOBAL(_set_L2CR) - /* Make sure this is a 750 chip */ + /* Make sure this is a 750 or 7400 chip */ mfspr r4,PVR rlwinm r4,r4,16,16,31 - cmplwi r4,0x0008 - beq thisIs750 - cmplwi r4,0x000c - beq thisIs750 - li r3,-1 - blr - -thisIs750: - /* Get the current enable bit of the L2CR into r4 */ - mfspr r4,L2CR - mfmsr r7 - - /* See if we want to perform a global inval this time. */ - rlwinm r6,r3,0,10,10 /* r6 contains the new invalidate bit */ - rlwinm. r5,r3,0,0,0 /* r5 contains the new enable bit */ - rlwinm r3,r3,0,11,9 /* Turn off the invalidate bit */ - rlwimi r3,r4,0,0,0 /* Keep the enable bit the same as it was. */ - bne dontDisableCache /* Only disable the cache if L2CRApply - has the enable bit off */ - -disableCache: - /* Disable the cache. First, we turn off interrupts. - An interrupt while we are flushing the cache could bring - in data which may not get properly flushed. */ - rlwinm r4,r7,0,17,15 /* Turn off EE bit */ + cmpwi r4,0x0008 + cmpwi cr1,r4,0x000c + cror 2,2,4*cr1+2 + bne 99f + + /* Turn off interrupts and data relocation. */ + mfmsr r7 /* Save MSR in r7 */ + rlwinm r4,r7,0,17,15 + rlwinm r4,r4,0,28,26 /* Turn off DR bit */ sync mtmsr r4 - sync + isync + + /* Get the current enable bit of the L2CR into r4 */ + mfspr r4,L2CR -/* - Now, read the first 2MB of memory to put new data in the cache. - (Actually we only need the size of the L2 cache plus the size - of the L1 cache, but 2MB will cover everything just to be safe). -*/ - lis r4,0x0001 + /* Tweak some bits */ + rlwinm r5,r3,0,0,0 /* r5 contains the new enable bit */ + rlwinm r3,r3,0,11,9 /* Turn off the invalidate bit */ + rlwinm r3,r3,0,1,31 /* Turn off the enable bit */ + + /* Check to see if we need to flush */ + rlwinm. r4,r4,0,0,0 + beq 2f + + /* Flush the cache. First, read the first 4MB of memory (physical) to + * put new data in the cache. (Actually we only need + * the size of the L2 cache plus the size of the L1 cache, but 4MB will + * cover everything just to be safe). + */ + + /**** Might be a good idea to set L2DO here - to prevent instructions + from getting into the cache. But since we invalidate + the next time we enable the cache it doesn't really matter. + ****/ + + lis r4,0x0002 mtctr r4 - lis r4,KERNELBASE@h -1: lwzx r0,r0,r4 - addi r4,r4,0x0020 /* Go to start of next cache line */ + li r4,0 +1: + lwzx r0,r0,r4 + addi r4,r4,32 /* Go to start of next cache line */ bdnz 1b - /* Now, flush the first 2MB of memory */ - lis r4,0x0001 + /* Now, flush the first 4MB of memory */ + lis r4,0x0002 mtctr r4 - lis r4,KERNELBASE@h + li r4,0 sync -2: dcbf r0,r4 - addi r4,r4,0x0020 /* Go to start of next cache line */ - bdnz 2b - - /* Turn off the L2CR enable bit. */ - rlwinm r3,r3,0,1,31 - -dontDisableCache: - /* Set up the L2CR configuration bits */ +1: + dcbf r0,r4 + addi r4,r4,32 /* Go to start of next cache line */ + bdnz 1b + +2: + /* Set up the L2CR configuration bits (and switch L2 off) */ sync mtspr L2CR,r3 sync - /* Reenable interrupts if necessary. */ - mtmsr r7 + /* Before we perform the global invalidation, we must disable dynamic + * power management via HID0[DPM] to work around a processor bug where + * DPM can possibly interfere with the state machine in the processor + * that invalidates the L2 cache tags. + */ + mfspr r8,HID0 /* Save HID0 in r8 */ + rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */ sync - - cmplwi r6,0 - beq noInval - + mtspr HID0,r4 /* Disable DPM */ + sync + /* Perform a global invalidation */ oris r3,r3,0x0020 sync mtspr L2CR,r3 sync + isync /* For errata */ /* Wait for the invalidation to complete */ 3: mfspr r3,L2CR @@ -910,27 +948,38 @@ dontDisableCache: mtspr L2CR,r3 sync -noInval: + /* Restore HID0[DPM] to whatever it was before */ + sync + mtspr 1008,r8 + sync + /* See if we need to enable the cache */ cmplwi r5,0 - beqlr + beq 4f /* Enable the cache */ oris r3,r3,0x8000 mtspr L2CR,r3 sync + + /* Restore MSR (restores EE and DR bits to original state) */ +4: SYNC + mtmsr r7 + isync + blr + +99: li r3,-1 blr _GLOBAL(_get_L2CR) /* Make sure this is a 750 chip */ mfspr r3,PVR - rlwinm r3,r3,16,16,31 - cmplwi r3,0x0008 - beq 1f - cmplwi r3,0x000c + srwi r3,r3,16 + cmpwi r3,0x0008 + cmpwi cr1,r3,0x000c li r3,0 + cror 2,2,4*cr1+2 bnelr -1: /* Return the L2CR contents */ mfspr r3,L2CR blr @@ -986,15 +1035,6 @@ _GLOBAL(cvt_df) blr #endif -_GLOBAL(__clear_msr_me) - mfmsr r0 /* Get current interrupt state */ - lis r3,0 - ori r3,r3,MSR_ME - andc r0,r0,r3 /* Clears bit in (r4) */ - sync /* Some chip revs have problems here */ - mtmsr r0 /* Update machine state */ - blr - /* * Create a kernel thread * kernel_thread(fn, arg, flags) @@ -1244,16 +1284,20 @@ _GLOBAL(sys_call_table) .long sys_getrlimit /* 190 */ .long sys_ni_syscall /* 191 */ /* Unused */ .long sys_ni_syscall /* 192 - reserved - mmap2 */ - .long sys_ni_syscall /* 193 - reserved - truncate64 */ - .long sys_ni_syscall /* 194 - reserved - ftruncate64 */ - .long sys_ni_syscall /* 195 - reserved - stat64 */ - .long sys_ni_syscall /* 196 - reserved - lstat64 */ - .long sys_ni_syscall /* 197 - reserved - fstat64 */ + .long sys_truncate64 /* 193 */ + .long sys_ftruncate64 /* 194 */ + .long sys_stat64 /* 195 */ + .long sys_lstat64 /* 196 */ + .long sys_fstat64 /* 197 */ .long sys_pciconfig_read /* 198 */ .long sys_pciconfig_write /* 199 */ .long sys_pciconfig_iobase /* 200 */ .long sys_ni_syscall /* 201 - reserved - MacOnLinux - new */ .long sys_getdents64 /* 202 */ + .long sys_pivot_root /* 203 */ + .long sys_fcntl64 /* 204 */ + .long sys_madvise /* 205 */ + .long sys_mincore /* 206 */ .rept NR_syscalls-(.-sys_call_table)/4 .long sys_ni_syscall .endr diff --git a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c index 5ca365b1c..0cbd4f553 100644 --- a/arch/ppc/kernel/open_pic.c +++ b/arch/ppc/kernel/open_pic.c @@ -1,5 +1,5 @@ /* - * arch/ppc/kernel/openpic.c -- OpenPIC Interrupt Handling + * arch/ppc/kernel/open_pic.c -- OpenPIC Interrupt Handling * * Copyright (C) 1997 Geert Uytterhoeven * @@ -13,35 +13,38 @@ #include <linux/kernel.h> #include <linux/sched.h> #include <linux/init.h> -#include <linux/openpic.h> +#include <linux/irq.h> #include <asm/ptrace.h> #include <asm/signal.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/prom.h> + #include "local_irq.h" +#include "open_pic.h" +#include "open_pic_defs.h" -volatile struct OpenPIC *OpenPIC = NULL; +void* OpenPIC_Addr; +static volatile struct OpenPIC *OpenPIC = NULL; u_int OpenPIC_NumInitSenses __initdata = 0; u_char *OpenPIC_InitSenses __initdata = NULL; -int open_pic_irq_offset; extern int use_of_interrupt_tree; -void chrp_mask_irq(unsigned int); -void chrp_unmask_irq(unsigned int); void find_ISUs(void); static u_int NumProcessors; static u_int NumSources; -OpenPIC_Source *ISU; -/* - * We should use this if we have > 1 ISU. - * We can just point each entry to the - * appropriate source regs but it wastes a lot of space - * so until we have >1 ISU I'll leave it unimplemented. - * -- Cort -OpenPIC_Source ISU[128]; -*/ +#ifdef CONFIG_POWER3 +static int NumISUs; +#endif +static int open_pic_irq_offset; +static volatile unsigned char* chrp_int_ack_special; + +OpenPIC_SourcePtr ISU[OPENPIC_MAX_ISU]; + +static void openpic_end_irq(unsigned int irq_nr); +static void openpic_ack_irq(unsigned int irq_nr); +static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask); struct hw_interrupt_type open_pic = { " OpenPIC ", @@ -49,45 +52,69 @@ struct hw_interrupt_type open_pic = { NULL, openpic_enable_irq, openpic_disable_irq, - 0, + openpic_ack_irq, + openpic_end_irq, + openpic_set_affinity +}; + +#ifdef CONFIG_SMP +static void openpic_end_ipi(unsigned int irq_nr); +static void openpic_ack_ipi(unsigned int irq_nr); +static void openpic_enable_ipi(unsigned int irq_nr); +static void openpic_disable_ipi(unsigned int irq_nr); + +struct hw_interrupt_type open_pic_ipi = { + " OpenPIC ", + NULL, + NULL, + openpic_enable_ipi, + openpic_disable_ipi, + openpic_ack_ipi, + openpic_end_ipi, 0 }; +#endif /* CONFIG_SMP */ /* - * Accesses to the current processor's registers + * Accesses to the current processor's openpic registers */ -#ifndef __powerpc__ -#define THIS_CPU Private -#define CHECK_THIS_CPU do {} while (0) -#else +#ifdef CONFIG_SMP #define THIS_CPU Processor[cpu] +#define DECL_THIS_CPU int cpu = smp_hw_index[smp_processor_id()] #define CHECK_THIS_CPU check_arg_cpu(cpu) -#endif +#else +#define THIS_CPU Processor[0] +#define DECL_THIS_CPU +#define CHECK_THIS_CPU +#endif /* CONFIG_SMP */ #if 1 #define check_arg_ipi(ipi) \ if (ipi < 0 || ipi >= OPENPIC_NUM_IPI) \ - printk("openpic.c:%d: illegal ipi %d\n", __LINE__, ipi); + printk("open_pic.c:%d: illegal ipi %d\n", __LINE__, ipi); #define check_arg_timer(timer) \ if (timer < 0 || timer >= OPENPIC_NUM_TIMERS) \ - printk("openpic.c:%d: illegal timer %d\n", __LINE__, timer); + printk("open_pic.c:%d: illegal timer %d\n", __LINE__, timer); #define check_arg_vec(vec) \ if (vec < 0 || vec >= OPENPIC_NUM_VECTORS) \ - printk("openpic.c:%d: illegal vector %d\n", __LINE__, vec); + printk("open_pic.c:%d: illegal vector %d\n", __LINE__, vec); #define check_arg_pri(pri) \ if (pri < 0 || pri >= OPENPIC_NUM_PRI) \ - printk("openpic.c:%d: illegal priority %d\n", __LINE__, pri); + printk("open_pic.c:%d: illegal priority %d\n", __LINE__, pri); /* - * I changed this to return to keep us from from trying to use irq #'s - * that we're using for IPI's. - * -- Cort - */ + * Print out a backtrace if it's out of range, since if it's larger than NR_IRQ's + * data has probably been corrupted and we're going to panic or deadlock later + * anyway --Troy + */ +extern unsigned long* _get_SP(void); #define check_arg_irq(irq) \ - /*if (irq < 0 || irq >= (NumSources+open_pic_irq_offset)) \ - printk("openpic.c:%d: illegal irq %d\n", __LINE__, irq);*/ + if (irq < open_pic_irq_offset || irq >= (NumSources+open_pic_irq_offset)){ \ + printk("open_pic.c:%d: illegal irq %d\n", __LINE__, irq); \ + print_backtrace(_get_SP()); } #define check_arg_cpu(cpu) \ - if (cpu < 0 || cpu >= NumProcessors) \ - printk("openpic.c:%d: illegal cpu %d\n", __LINE__, cpu); + if (cpu < 0 || cpu >= NumProcessors){ \ + printk("open_pic.c:%d: illegal cpu %d\n", __LINE__, cpu); \ + print_backtrace(_get_SP()); } #else #define check_arg_ipi(ipi) do {} while (0) #define check_arg_timer(timer) do {} while (0) @@ -97,23 +124,10 @@ struct hw_interrupt_type open_pic = { #define check_arg_cpu(cpu) do {} while (0) #endif -#ifdef CONFIG_SMP -void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs) -{ - smp_message_recv(cpl-OPENPIC_VEC_IPI, regs); -} -#endif /* CONFIG_SMP */ - -#ifdef __i386__ -static inline u_int in_le32(volatile u_int *addr) -{ - return *addr; -} - -static inline void out_le32(volatile u_int *addr, u_int val) -{ - *addr = val; -} +#ifdef CONFIG_POWER3 + #define GET_ISU(source) ISU[(source) >> 4][(source) & 0xf] +#else + #define GET_ISU(source) ISU[0][(source)] #endif u_int openpic_read(volatile u_int *addr) @@ -156,22 +170,66 @@ static void openpic_safe_writefield(volatile u_int *addr, u_int mask, u_int field) { openpic_setfield(addr, OPENPIC_MASK); - /* wait until it's not in use */ - /* BenH: Is this code really enough ? I would rather check the result - * and eventually retry ... - */ while (openpic_read(addr) & OPENPIC_ACTIVITY); openpic_writefield(addr, mask | OPENPIC_MASK, field | OPENPIC_MASK); } -void __init openpic_init(int main_pic) +#ifdef CONFIG_SMP +/* yes this is right ... bug, feature, you decide! -- tgall */ +u_int openpic_read_IPI(volatile u_int* addr) +{ + u_int val = 0; +#ifdef CONFIG_POWER3 + val = in_be32(addr); +#else + val = in_le32(addr); +#endif + return val; +} + +/* because of the power3 be / le above, this is needed */ +inline void openpic_writefield_IPI(volatile u_int* addr, u_int mask, u_int field) +{ + u_int val = openpic_read_IPI(addr); + openpic_write(addr, (val & ~mask) | (field & mask)); +} + +static inline void openpic_clearfield_IPI(volatile u_int *addr, u_int mask) +{ + openpic_writefield_IPI(addr, mask, 0); +} + +static inline void openpic_setfield_IPI(volatile u_int *addr, u_int mask) +{ + openpic_writefield_IPI(addr, mask, mask); +} + +static void openpic_safe_writefield_IPI(volatile u_int *addr, u_int mask, u_int field) +{ + openpic_setfield_IPI(addr, OPENPIC_MASK); + + /* wait until it's not in use */ + /* BenH: Is this code really enough ? I would rather check the result + * and eventually retry ... + */ + while(openpic_read_IPI(addr) & OPENPIC_ACTIVITY); + + openpic_writefield_IPI(addr, mask | OPENPIC_MASK, field | OPENPIC_MASK); +} +#endif /* CONFIG_SMP */ + +void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, + int programmer_switch_irq) { u_int t, i; u_int timerfreq; const char *version; - if (!OpenPIC) - panic("No OpenPIC found"); + if (!OpenPIC_Addr) { + printk("No OpenPIC found !\n"); + return; + } + OpenPIC = (volatile struct OpenPIC *)OpenPIC_Addr; if ( ppc_md.progress ) ppc_md.progress("openpic enter",0x122); @@ -194,179 +252,180 @@ void __init openpic_init(int main_pic) OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT) + 1; NumSources = ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK) >> OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1; - if ( _machine != _MACH_Pmac ) - { - printk("OpenPIC Version %s (%d CPUs and %d IRQ sources) at %p\n", version, - NumProcessors, NumSources, OpenPIC); - timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency); - printk("OpenPIC timer frequency is "); - if (timerfreq) - printk("%d MHz\n", timerfreq>>20); - else - printk("not set\n"); + printk("OpenPIC Version %s (%d CPUs and %d IRQ sources) at %p\n", + version, NumProcessors, NumSources, OpenPIC); + timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency); + if (timerfreq) + printk("OpenPIC timer frequency is %d.%06d MHz\n", + timerfreq / 1000000, timerfreq % 1000000); + + if (!main_pic) + return; + + open_pic_irq_offset = offset; + chrp_int_ack_special = (volatile unsigned char*)chrp_ack; + + /* Initialize timer interrupts */ + if ( ppc_md.progress ) ppc_md.progress("openpic timer",0x3ba); + for (i = 0; i < OPENPIC_NUM_TIMERS; i++) { + /* Disabled, Priority 0 */ + openpic_inittimer(i, 0, OPENPIC_VEC_TIMER+i+offset); + /* No processor */ + openpic_maptimer(i, 0); } - - if ( main_pic ) - { - /* Initialize timer interrupts */ - if ( ppc_md.progress ) ppc_md.progress("openpic timer",0x3ba); - for (i = 0; i < OPENPIC_NUM_TIMERS; i++) { - /* Disabled, Priority 0 */ - openpic_inittimer(i, 0, OPENPIC_VEC_TIMER+i); - /* No processor */ - openpic_maptimer(i, 0); - } - - /* Initialize IPI interrupts */ - if ( ppc_md.progress ) ppc_md.progress("openpic ipi",0x3bb); - for (i = 0; i < OPENPIC_NUM_IPI; i++) { - /* Disabled, Priority 8 */ - openpic_initipi(i, 8, OPENPIC_VEC_IPI+i); - } - find_ISUs(); - if ( _machine != _MACH_Pmac ) - { - /* Initialize external interrupts */ - if ( ppc_md.progress ) ppc_md.progress("openpic ext",0x3bc); - /* SIOint (8259 cascade) is special */ - openpic_initirq(0, 8, open_pic_irq_offset, 1, 1); - openpic_mapirq(0, 1<<0); - for (i = 1; i < NumSources; i++) { - /* Enabled, Priority 8 */ - openpic_initirq(i, 8, open_pic_irq_offset+i, 0, - i < OpenPIC_NumInitSenses ? OpenPIC_InitSenses[i] : 1); - /* Processor 0 */ - openpic_mapirq(i, 1<<0); - } - } - else - { - /* Prevent any interrupt from occuring during initialisation. - * Hum... I believe this is not necessary, Apple does that in - * Darwin's PowerExpress code. - */ - openpic_set_priority(0, 0xf); - - /* First disable all interrupts and map them to CPU 0 */ - for (i = 0; i < NumSources; i++) { - openpic_disable_irq(i); - openpic_mapirq(i, 1<<0); - } - - /* If we use the device tree, then lookup all interrupts and - * initialize them according to sense infos found in the tree - */ - if (use_of_interrupt_tree) { - struct device_node* np = find_all_nodes(); - while(np) { - int j, pri; - pri = strcmp(np->name, "programmer-switch") ? 2 : 7; - for (j=0;j<np->n_intrs;j++) { - openpic_initirq(np->intrs[j].line, - pri, - np->intrs[j].line, - 0, - np->intrs[j].sense); - if (np->intrs[j].sense) - irq_desc[np->intrs[j].line].status = IRQ_LEVEL; - } - np = np->next; - } - } - } - - /* Initialize the spurious interrupt */ - if ( ppc_md.progress ) ppc_md.progress("openpic spurious",0x3bd); - openpic_set_spurious(OPENPIC_VEC_SPURIOUS); - if ( !(_machine & (_MACH_gemini|_MACH_Pmac)) ) - { - if (request_irq(IRQ_8259_CASCADE, no_action, SA_INTERRUPT, - "82c59 cascade", NULL)) - printk("Unable to get OpenPIC IRQ 0 for cascade\n"); - } - openpic_set_priority(0, 0); - openpic_disable_8259_pass_through(); + +#ifdef CONFIG_SMP + /* Initialize IPI interrupts */ + if ( ppc_md.progress ) ppc_md.progress("openpic ipi",0x3bb); + for (i = 0; i < OPENPIC_NUM_IPI; i++) { + /* Disabled, Priority 10..13 */ + openpic_initipi(i, 10+i, OPENPIC_VEC_IPI+i+offset); + /* IPIs are per-CPU */ + irq_desc[OPENPIC_VEC_IPI+i+offset].status |= IRQ_PER_CPU; + irq_desc[OPENPIC_VEC_IPI+i+offset].handler = &open_pic_ipi; + } +#endif + + find_ISUs(); + + /* Initialize external interrupts */ + if (ppc_md.progress) ppc_md.progress("openpic ext",0x3bc); + + openpic_set_priority(0xf); + + /* SIOint (8259 cascade) is special */ + if (offset) { + openpic_initirq(0, 8, offset, 1, 1); + openpic_mapirq(0, 1<<0); + } + + /* Init all external sources */ + for (i = 1; i < NumSources; i++) { + int pri, sense; + + /* the bootloader may have left it enabled (bad !) */ + openpic_disable_irq(i+offset); + + pri = (i == programmer_switch_irq)? 9: 8; + sense = (i < OpenPIC_NumInitSenses)? OpenPIC_InitSenses[i]: 1; + if (sense) + irq_desc[i+offset].status = IRQ_LEVEL; + + /* Enabled, Priority 8 or 9 */ + openpic_initirq(i, pri, i+offset, !sense, sense); + /* Processor 0 */ + openpic_mapirq(i, 1<<0); } - if ( ppc_md.progress ) ppc_md.progress("openpic exit",0x222); + + /* Init descriptors */ + for (i = offset; i < NumSources + offset; i++) + irq_desc[i].handler = &open_pic; + + /* Initialize the spurious interrupt */ + if (ppc_md.progress) ppc_md.progress("openpic spurious",0x3bd); + openpic_set_spurious(OPENPIC_VEC_SPURIOUS+offset); + + /* Initialize the cascade */ + if (offset) { + if (request_irq(offset, no_action, SA_INTERRUPT, + "82c59 cascade", NULL)) + printk("Unable to get OpenPIC IRQ 0 for cascade\n"); + } + openpic_set_priority(0); + openpic_disable_8259_pass_through(); + + if (ppc_md.progress) ppc_md.progress("openpic exit",0x222); +} + +#ifdef CONFIG_POWER3 +void openpic_setup_ISU(int isu_num, unsigned long addr) +{ + if (isu_num >= OPENPIC_MAX_ISU) + return; + ISU[isu_num] = (OpenPIC_SourcePtr) ioremap(addr, 0x400); + if (isu_num >= NumISUs) + NumISUs = isu_num + 1; } +#endif void find_ISUs(void) { -#ifdef CONFIG_PPC64BRIDGE - /* hardcode this for now since the IBM 260 is the only thing with - * a distributed openpic right now. -- Cort +#ifdef CONFIG_POWER3 + /* Use /interrupt-controller/reg and + * /interrupt-controller/interrupt-ranges from OF device tree + * the ISU array is setup in chrp_pci.c in ibm_add_bridges + * as a result + * -- tgall + */ + + /* basically each ISU is a bus, and this assumes that + * open_pic_isu_count interrupts per bus are possible + * ISU == Interrupt Source */ - ISU = (OpenPIC_Source *)0xfeff7c00; - NumSources = 0x10; + NumSources = NumISUs * 0x10; + #else /* for non-distributed OpenPIC implementations it's in the IDU -- Cort */ - ISU = (OpenPIC_Source *)OpenPIC->Source; + ISU[0] = (OpenPIC_Source *)OpenPIC->Source; #endif } -void openpic_reset(void) +static inline void openpic_reset(void) { openpic_setfield(&OpenPIC->Global.Global_Configuration0, OPENPIC_CONFIG_RESET); } -void openpic_enable_8259_pass_through(void) +static inline void openpic_enable_8259_pass_through(void) { openpic_clearfield(&OpenPIC->Global.Global_Configuration0, OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE); } -void openpic_disable_8259_pass_through(void) +static void openpic_disable_8259_pass_through(void) { openpic_setfield(&OpenPIC->Global.Global_Configuration0, OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE); } -#ifndef __i386__ /* * Find out the current interrupt */ -u_int openpic_irq(u_int cpu) +static u_int openpic_irq(void) { u_int vec; + DECL_THIS_CPU; - check_arg_cpu(cpu); + CHECK_THIS_CPU; vec = openpic_readfield(&OpenPIC->THIS_CPU.Interrupt_Acknowledge, OPENPIC_VECTOR_MASK); return vec; } -#endif -#ifndef __powerpc__ -void openpic_eoi(void) -#else -void openpic_eoi(u_int cpu) -#endif +static void openpic_eoi(void) { - check_arg_cpu(cpu); + DECL_THIS_CPU; + + CHECK_THIS_CPU; openpic_write(&OpenPIC->THIS_CPU.EOI, 0); /* Handle PCI write posting */ (void)openpic_read(&OpenPIC->THIS_CPU.EOI); } -#ifndef __powerpc__ -u_int openpic_get_priority(void) -#else -u_int openpic_get_priority(u_int cpu) -#endif +static inline u_int openpic_get_priority(void) { + DECL_THIS_CPU; + CHECK_THIS_CPU; return openpic_readfield(&OpenPIC->THIS_CPU.Current_Task_Priority, OPENPIC_CURRENT_TASK_PRIORITY_MASK); } -#ifndef __powerpc__ -void openpic_set_priority(u_int pri) -#else -void openpic_set_priority(u_int cpu, u_int pri) -#endif +static void openpic_set_priority(u_int pri) { + DECL_THIS_CPU; + CHECK_THIS_CPU; check_arg_pri(pri); openpic_writefield(&OpenPIC->THIS_CPU.Current_Task_Priority, @@ -376,24 +435,43 @@ void openpic_set_priority(u_int cpu, u_int pri) /* * Get/set the spurious vector */ -u_int openpic_get_spurious(void) +static inline u_int openpic_get_spurious(void) { return openpic_readfield(&OpenPIC->Global.Spurious_Vector, OPENPIC_VECTOR_MASK); } -void openpic_set_spurious(u_int vec) +static void openpic_set_spurious(u_int vec) { check_arg_vec(vec); openpic_writefield(&OpenPIC->Global.Spurious_Vector, OPENPIC_VECTOR_MASK, vec); } +#ifdef CONFIG_SMP +/* + * Convert a cpu mask from logical to physical cpu numbers. + */ +static inline u32 physmask(u32 cpumask) +{ + int i; + u32 mask = 0; + + for (i = 0; i < smp_num_cpus; ++i, cpumask >>= 1) + mask |= (cpumask & 1) << smp_hw_index[i]; + return mask; +} +#else +#define physmask(cpumask) (cpumask) +#endif + void openpic_init_processor(u_int cpumask) { - openpic_write(&OpenPIC->Global.Processor_Initialization, cpumask); + openpic_write(&OpenPIC->Global.Processor_Initialization, + physmask(cpumask)); } +#ifdef CONFIG_SMP /* * Initialize an interprocessor interrupt (and disable it) * @@ -401,35 +479,55 @@ void openpic_init_processor(u_int cpumask) * pri: interrupt source priority * vec: the vector it will produce */ -void openpic_initipi(u_int ipi, u_int pri, u_int vec) +static void __init openpic_initipi(u_int ipi, u_int pri, u_int vec) { - check_arg_timer(ipi); + check_arg_ipi(ipi); check_arg_pri(pri); check_arg_vec(vec); - openpic_safe_writefield(&OpenPIC->Global.IPI_Vector_Priority(ipi), + openpic_safe_writefield_IPI(&OpenPIC->Global.IPI_Vector_Priority(ipi), OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK, (pri << OPENPIC_PRIORITY_SHIFT) | vec); } /* * Send an IPI to one or more CPUs + * + * Externally called, however, it takes an IPI number (0...OPENPIC_NUM_IPI) + * and not a system-wide interrupt number */ -#ifndef __powerpc__ void openpic_cause_IPI(u_int ipi, u_int cpumask) -#else -void openpic_cause_IPI(u_int cpu, u_int ipi, u_int cpumask) -#endif { + DECL_THIS_CPU; + CHECK_THIS_CPU; check_arg_ipi(ipi); - openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), cpumask); + openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), + physmask(cpumask)); } -void openpic_enable_IPI(u_int ipi) +void openpic_request_IPIs(void) { - check_arg_ipi(ipi); - openpic_clearfield(&OpenPIC->Global.IPI_Vector_Priority(ipi), - OPENPIC_MASK); + int i; + + /* + * Make sure this matches what is defined in smp.c for + * smp_message_{pass|recv}() or what shows up in + * /proc/interrupts will be wrong!!! --Troy */ + + if (OpenPIC == NULL) + return; + + request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset, + openpic_ipi_action, 0, "IPI0 (call function)", 0); + request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+1, + openpic_ipi_action, 0, "IPI1 (reschedule)", 0); + request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+2, + openpic_ipi_action, 0, "IPI2 (invalidate tlb)", 0); + request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+3, + openpic_ipi_action, 0, "IPI3 (xmon break)", 0); + + for ( i = 0; i < OPENPIC_NUM_IPI ; i++ ) + openpic_enable_ipi(OPENPIC_VEC_IPI+open_pic_irq_offset+i); } /* @@ -437,21 +535,31 @@ void openpic_enable_IPI(u_int ipi) * * Get IPI's working and start taking interrupts. * -- Cort - */ -void do_openpic_setup_cpu(void) + */ +static spinlock_t openpic_setup_lock __initdata = SPIN_LOCK_UNLOCKED; + +void __init do_openpic_setup_cpu(void) { int i; - - for ( i = 0; i < OPENPIC_NUM_IPI ; i++ ) - openpic_enable_IPI(i); -#if 0 - /* let the openpic know we want intrs */ - for ( i = 0; i < NumSources ; i++ ) - openpic_mapirq(i, openpic_read(ISU[i].Destination) - | (1<<smp_processor_id()) ); -#endif - openpic_set_priority(smp_processor_id(), 0); + u32 msk = 1 << smp_hw_index[smp_processor_id()]; + + spin_lock(&openpic_setup_lock); + +#ifdef CONFIG_IRQ_ALL_CPUS + /* let the openpic know we want intrs. default affinity + * is 0xffffffff until changed via /proc + * That's how it's done on x86. If we want it differently, then + * we should make sure we also change the default values of irq_affinity + * in irq.c. + */ + for (i = 0; i < NumSources ; i++) + openpic_mapirq(i, openpic_read(&GET_ISU(i).Destination) | msk); +#endif /* CONFIG_IRQ_ALL_CPUS */ + openpic_set_priority(0); + + spin_unlock(&openpic_setup_lock); } +#endif /* CONFIG_SMP */ /* * Initialize a timer interrupt (and disable it) @@ -460,7 +568,7 @@ void do_openpic_setup_cpu(void) * pri: interrupt source priority * vec: the vector it will produce */ -void openpic_inittimer(u_int timer, u_int pri, u_int vec) +static void __init openpic_inittimer(u_int timer, u_int pri, u_int vec) { check_arg_timer(timer); check_arg_pri(pri); @@ -473,37 +581,99 @@ void openpic_inittimer(u_int timer, u_int pri, u_int vec) /* * Map a timer interrupt to one or more CPUs */ -void openpic_maptimer(u_int timer, u_int cpumask) +static void __init openpic_maptimer(u_int timer, u_int cpumask) { check_arg_timer(timer); - openpic_write(&OpenPIC->Global.Timer[timer].Destination, cpumask); + openpic_write(&OpenPIC->Global.Timer[timer].Destination, + physmask(cpumask)); } + +/* + * + * All functions below take an offset'ed irq argument + * + */ + + /* - * Enable/disable an interrupt source + * Enable/disable an external interrupt source + * + * Externally called, irq is an offseted system-wide interrupt number */ -void openpic_enable_irq(u_int irq) +static void openpic_enable_irq(u_int irq) { check_arg_irq(irq); - openpic_clearfield(&ISU[irq - open_pic_irq_offset].Vector_Priority, OPENPIC_MASK); + + /* + * Never want to disable a timer or ipi irq + * (only want to disable irqs within an ISU). + */ + if (((irq >= OPENPIC_VEC_IPI+open_pic_irq_offset) && + (irq < OPENPIC_VEC_IPI+open_pic_irq_offset+OPENPIC_NUM_IPI)) || + ((irq >= OPENPIC_VEC_TIMER+open_pic_irq_offset) && + (irq < OPENPIC_VEC_TIMER+open_pic_irq_offset+OPENPIC_NUM_TIMERS))) + { + /* silently ignore the enable of the timer or ipi irq. */ + return; + } + + + openpic_clearfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK); /* make sure mask gets to controller before we return to user */ do { mb(); /* sync is probably useless here */ - } while(openpic_readfield(&ISU[irq - open_pic_irq_offset].Vector_Priority, + } while(openpic_readfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK)); } -void openpic_disable_irq(u_int irq) +static void openpic_disable_irq(u_int irq) { + u32 vp; + check_arg_irq(irq); - openpic_setfield(&ISU[irq - open_pic_irq_offset].Vector_Priority, OPENPIC_MASK); + /* + * Never want to disable a timer or ipi irq + * (only want to disable irqs within an ISU). + */ + if (((irq >= OPENPIC_VEC_IPI+open_pic_irq_offset) && + (irq < OPENPIC_VEC_IPI+open_pic_irq_offset+OPENPIC_NUM_IPI)) || + ((irq >= OPENPIC_VEC_TIMER+open_pic_irq_offset) && + (irq < OPENPIC_VEC_TIMER+open_pic_irq_offset+OPENPIC_NUM_TIMERS))) + { + panic("openpic_disable_irq - disabling non-ISU irq"); + } + + + openpic_setfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK); /* make sure mask gets to controller before we return to user */ do { mb(); /* sync is probably useless here */ - } while(!openpic_readfield(&ISU[irq - open_pic_irq_offset].Vector_Priority, - OPENPIC_MASK)); + vp = openpic_readfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, + OPENPIC_MASK | OPENPIC_ACTIVITY); + } while((vp & OPENPIC_ACTIVITY) && !(vp & OPENPIC_MASK)); } +#ifdef CONFIG_SMP +/* + * Enable/disable an IPI interrupt source + * + * Externally called, irq is an offseted system-wide interrupt number + */ +void openpic_enable_ipi(u_int irq) +{ + irq -= (OPENPIC_VEC_IPI+open_pic_irq_offset); + check_arg_ipi(irq); + openpic_clearfield_IPI(&OpenPIC->Global.IPI_Vector_Priority(irq), OPENPIC_MASK); + +} +void openpic_disable_ipi(u_int irq) +{ + /* NEVER disable an IPI... that's just plain wrong! */ +} + +#endif + /* * Initialize an interrupt source (and disable it!) * @@ -513,12 +683,9 @@ void openpic_disable_irq(u_int irq) * pol: polarity (1 for positive, 0 for negative) * sense: 1 for level, 0 for edge */ -void openpic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense) +static void openpic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense) { - check_arg_irq(irq); - check_arg_pri(pri); - check_arg_vec(vec); - openpic_safe_writefield(&ISU[irq].Vector_Priority, + openpic_safe_writefield(&GET_ISU(irq).Vector_Priority, OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK | OPENPIC_SENSE_MASK | OPENPIC_POLARITY_MASK, (pri << OPENPIC_PRIORITY_SHIFT) | vec | @@ -530,10 +697,9 @@ void openpic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense) /* * Map an interrupt source to one or more CPUs */ -void openpic_mapirq(u_int irq, u_int cpumask) +static void openpic_mapirq(u_int irq, u_int physmask) { - check_arg_irq(irq); - openpic_write(&ISU[irq].Destination, cpumask); + openpic_write(&GET_ISU(irq).Destination, physmask); } /* @@ -541,10 +707,92 @@ void openpic_mapirq(u_int irq, u_int cpumask) * * sense: 1 for level, 0 for edge */ -void openpic_set_sense(u_int irq, int sense) +static inline void openpic_set_sense(u_int irq, int sense) { - check_arg_irq(irq); - openpic_safe_writefield(&ISU[irq].Vector_Priority, + openpic_safe_writefield(&GET_ISU(irq).Vector_Priority, OPENPIC_SENSE_LEVEL, (sense ? OPENPIC_SENSE_LEVEL : 0)); } + +/* No spinlocks, should not be necessary with the OpenPIC + * (1 register = 1 interrupt and we have the desc lock). + */ +static void openpic_ack_irq(unsigned int irq_nr) +{ +#if 1 /* masking should be unnecessary, but I still get spurrious */ + openpic_disable_irq(irq_nr); +#endif + if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0) + openpic_eoi(); +} + +static void openpic_end_irq(unsigned int irq_nr) +{ + if ((irq_desc[irq_nr].status & IRQ_LEVEL) != 0) + openpic_eoi(); + +#if 1 /* masking should be unnecessary, but I still get spurrious */ + if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + openpic_enable_irq(irq_nr); +#endif +} + +static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask) +{ + openpic_mapirq(irq_nr - open_pic_irq_offset, physmask(cpumask)); +} + +#ifdef CONFIG_SMP +static void openpic_ack_ipi(unsigned int irq_nr) +{ +} + +static void openpic_end_ipi(unsigned int irq_nr) +{ + /* IPIs are marked IRQ_PER_CPU. This has the side effect of + * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from + * applying to them. We EOI them late to avoid re-entering. + * however, I'm wondering if we could simply let them have the + * SA_INTERRUPT flag and let them execute with all interrupts OFF. + * This would have the side effect of either running cross-CPU + * functions with interrupts off, or we can re-enable them explicitely + * with a __sti() in smp_call_function_interrupt(), since + * smp_call_function() is protected by a spinlock. + * Or maybe we shouldn't set the IRQ_PER_CPU flag on cross-CPU + * function calls IPI at all but that would make a special case. + */ + openpic_eoi(); +} + +static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs) +{ + smp_message_recv(cpl-OPENPIC_VEC_IPI-open_pic_irq_offset, regs); +} + +#endif /* CONFIG_SMP */ + +/* This one may be merged with PReP and CHRP */ +int +openpic_get_irq(struct pt_regs *regs) +{ + extern int i8259_irq(int cpu); + + int irq = openpic_irq(); + + /* Management of the cascade should be moved out of here */ + if (open_pic_irq_offset && irq == open_pic_irq_offset) + { + /* + * This magic address generates a PCI IACK cycle. + */ + if ( chrp_int_ack_special ) + irq = *chrp_int_ack_special; + else + irq = i8259_irq( smp_processor_id() ); + openpic_eoi(); + } + if (irq == OPENPIC_VEC_SPURIOUS + open_pic_irq_offset) + irq = -1; + return irq; +} + diff --git a/arch/ppc/kernel/open_pic.h b/arch/ppc/kernel/open_pic.h index 3e51ffba3..cf924ba3a 100644 --- a/arch/ppc/kernel/open_pic.h +++ b/arch/ppc/kernel/open_pic.h @@ -1,11 +1,45 @@ +/* + * arch/ppc/kernel/open_pic.h -- OpenPIC Interrupt Handling + * + * Copyright (C) 1997 Geert Uytterhoeven + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + */ + #ifndef _PPC_KERNEL_OPEN_PIC_H #define _PPC_KERNEL_OPEN_PIC_H +#include <linux/config.h> + +#define OPENPIC_SIZE 0x40000 + +/* OpenPIC IRQ controller structure */ extern struct hw_interrupt_type open_pic; -void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs); -void openpic_enable_IPI(u_int ipi); -void do_openpic_setup_cpu(void); +/* OpenPIC IPI controller structure */ +#ifdef CONFIG_SMP +extern struct hw_interrupt_type open_pic_ipi; +#endif /* CONFIG_SMP */ + +extern u_int OpenPIC_NumInitSenses; +extern u_char *OpenPIC_InitSenses; +extern void* OpenPIC_Addr; + +/* Exported functions */ +extern void openpic_init(int, int, unsigned char *, int); +extern void openpic_request_IPIs(void); +extern void do_openpic_setup_cpu(void); +extern int openpic_get_irq(struct pt_regs *regs); +extern void openpic_init_processor(u_int cpumask); +extern void openpic_setup_ISU(int isu_num, unsigned long addr); +extern void openpic_cause_IPI(u_int ipi, u_int cpumask); -extern int open_pic_irq_offset; +extern inline int openpic_to_irq(int irq) +{ + return irq += NUM_8259_INTERRUPTS; +} +/*extern int open_pic_irq_offset;*/ #endif /* _PPC_KERNEL_OPEN_PIC_H */ diff --git a/arch/ppc/kernel/open_pic_defs.h b/arch/ppc/kernel/open_pic_defs.h new file mode 100644 index 000000000..fed4dd1cc --- /dev/null +++ b/arch/ppc/kernel/open_pic_defs.h @@ -0,0 +1,328 @@ +/* + * linux/openpic.h -- OpenPIC definitions + * + * Copyright (C) 1997 Geert Uytterhoeven + * + * This file is based on the following documentation: + * + * The Open Programmable Interrupt Controller (PIC) + * Register Interface Specification Revision 1.2 + * + * Issue Date: October 1995 + * + * Issued jointly by Advanced Micro Devices and Cyrix Corporation + * + * AMD is a registered trademark of Advanced Micro Devices, Inc. + * Copyright (C) 1995, Advanced Micro Devices, Inc. and Cyrix, Inc. + * All Rights Reserved. + * + * To receive a copy of this documentation, send an email to openpic@amd.com. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#ifndef _LINUX_OPENPIC_H +#define _LINUX_OPENPIC_H + +#ifdef __KERNEL__ + +#include <linux/config.h> + + /* + * OpenPIC supports up to 2048 interrupt sources and up to 32 processors + */ + +#define OPENPIC_MAX_SOURCES 2048 +#define OPENPIC_MAX_PROCESSORS 32 +#define OPENPIC_MAX_ISU 16 + +#define OPENPIC_NUM_TIMERS 4 +#define OPENPIC_NUM_IPI 4 +#define OPENPIC_NUM_PRI 16 +#define OPENPIC_NUM_VECTORS 256 + + + /* + * Non-offset'ed vector numbers + */ + +#define OPENPIC_VEC_TIMER 64 /* and up */ +#define OPENPIC_VEC_IPI 72 /* and up */ +#define OPENPIC_VEC_SPURIOUS 127 + + + /* + * OpenPIC Registers are 32 bits and aligned on 128 bit boundaries + */ + +typedef struct _OpenPIC_Reg { + u_int Reg; /* Little endian! */ + char Pad[0xc]; +} OpenPIC_Reg; + + + /* + * Per Processor Registers + */ + +typedef struct _OpenPIC_Processor { + /* + * Private Shadow Registers (for SLiC backwards compatibility) + */ + u_int IPI0_Dispatch_Shadow; /* Write Only */ + char Pad1[0x4]; + u_int IPI0_Vector_Priority_Shadow; /* Read/Write */ + char Pad2[0x34]; + /* + * Interprocessor Interrupt Command Ports + */ + OpenPIC_Reg _IPI_Dispatch[OPENPIC_NUM_IPI]; /* Write Only */ + /* + * Current Task Priority Register + */ + OpenPIC_Reg _Current_Task_Priority; /* Read/Write */ + char Pad3[0x10]; + /* + * Interrupt Acknowledge Register + */ + OpenPIC_Reg _Interrupt_Acknowledge; /* Read Only */ + /* + * End of Interrupt (EOI) Register + */ + OpenPIC_Reg _EOI; /* Read/Write */ + char Pad5[0xf40]; +} OpenPIC_Processor; + + + /* + * Timer Registers + */ + +typedef struct _OpenPIC_Timer { + OpenPIC_Reg _Current_Count; /* Read Only */ + OpenPIC_Reg _Base_Count; /* Read/Write */ + OpenPIC_Reg _Vector_Priority; /* Read/Write */ + OpenPIC_Reg _Destination; /* Read/Write */ +} OpenPIC_Timer; + + + /* + * Global Registers + */ + +typedef struct _OpenPIC_Global { + /* + * Feature Reporting Registers + */ + OpenPIC_Reg _Feature_Reporting0; /* Read Only */ + OpenPIC_Reg _Feature_Reporting1; /* Future Expansion */ + /* + * Global Configuration Registers + */ + OpenPIC_Reg _Global_Configuration0; /* Read/Write */ + OpenPIC_Reg _Global_Configuration1; /* Future Expansion */ + /* + * Vendor Specific Registers + */ + OpenPIC_Reg _Vendor_Specific[4]; + /* + * Vendor Identification Register + */ + OpenPIC_Reg _Vendor_Identification; /* Read Only */ + /* + * Processor Initialization Register + */ + OpenPIC_Reg _Processor_Initialization; /* Read/Write */ + /* + * IPI Vector/Priority Registers + */ + OpenPIC_Reg _IPI_Vector_Priority[OPENPIC_NUM_IPI]; /* Read/Write */ + /* + * Spurious Vector Register + */ + OpenPIC_Reg _Spurious_Vector; /* Read/Write */ + /* + * Global Timer Registers + */ + OpenPIC_Reg _Timer_Frequency; /* Read/Write */ + OpenPIC_Timer Timer[OPENPIC_NUM_TIMERS]; + char Pad1[0xee00]; +} OpenPIC_Global; + + + /* + * Interrupt Source Registers + */ + +typedef struct _OpenPIC_Source { + OpenPIC_Reg _Vector_Priority; /* Read/Write */ + OpenPIC_Reg _Destination; /* Read/Write */ +} OpenPIC_Source, *OpenPIC_SourcePtr; + + + /* + * OpenPIC Register Map + */ + +struct OpenPIC { + char Pad1[0x1000]; + /* + * Global Registers + */ + OpenPIC_Global Global; + /* + * Interrupt Source Configuration Registers + */ + OpenPIC_Source Source[OPENPIC_MAX_SOURCES]; + /* + * Per Processor Registers + */ + OpenPIC_Processor Processor[OPENPIC_MAX_PROCESSORS]; +}; + +extern volatile struct OpenPIC *OpenPIC; + + + /* + * Current Task Priority Register + */ + +#define OPENPIC_CURRENT_TASK_PRIORITY_MASK 0x0000000f + + /* + * Who Am I Register + */ + +#define OPENPIC_WHO_AM_I_ID_MASK 0x0000001f + + /* + * Feature Reporting Register 0 + */ + +#define OPENPIC_FEATURE_LAST_SOURCE_MASK 0x07ff0000 +#define OPENPIC_FEATURE_LAST_SOURCE_SHIFT 16 +#define OPENPIC_FEATURE_LAST_PROCESSOR_MASK 0x00001f00 +#define OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT 8 +#define OPENPIC_FEATURE_VERSION_MASK 0x000000ff + + /* + * Global Configuration Register 0 + */ + +#define OPENPIC_CONFIG_RESET 0x80000000 +#define OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE 0x20000000 +#define OPENPIC_CONFIG_BASE_MASK 0x000fffff + + /* + * Vendor Identification Register + */ + +#define OPENPIC_VENDOR_ID_STEPPING_MASK 0x00ff0000 +#define OPENPIC_VENDOR_ID_STEPPING_SHIFT 16 +#define OPENPIC_VENDOR_ID_DEVICE_ID_MASK 0x0000ff00 +#define OPENPIC_VENDOR_ID_DEVICE_ID_SHIFT 8 +#define OPENPIC_VENDOR_ID_VENDOR_ID_MASK 0x000000ff + + /* + * Vector/Priority Registers + */ + +#define OPENPIC_MASK 0x80000000 +#define OPENPIC_ACTIVITY 0x40000000 /* Read Only */ +#define OPENPIC_PRIORITY_MASK 0x000f0000 +#define OPENPIC_PRIORITY_SHIFT 16 +#define OPENPIC_VECTOR_MASK 0x000000ff + + + /* + * Interrupt Source Registers + */ + +#define OPENPIC_POLARITY_POSITIVE 0x00800000 +#define OPENPIC_POLARITY_NEGATIVE 0x00000000 +#define OPENPIC_POLARITY_MASK 0x00800000 +#define OPENPIC_SENSE_LEVEL 0x00400000 +#define OPENPIC_SENSE_EDGE 0x00000000 +#define OPENPIC_SENSE_MASK 0x00400000 + + + /* + * Timer Registers + */ + +#define OPENPIC_COUNT_MASK 0x7fffffff +#define OPENPIC_TIMER_TOGGLE 0x80000000 +#define OPENPIC_TIMER_COUNT_INHIBIT 0x80000000 + + + /* + * Aliases to make life simpler + */ + +/* Per Processor Registers */ +#define IPI_Dispatch(i) _IPI_Dispatch[i].Reg +#define Current_Task_Priority _Current_Task_Priority.Reg +#define Interrupt_Acknowledge _Interrupt_Acknowledge.Reg +#define EOI _EOI.Reg + +/* Global Registers */ +#define Feature_Reporting0 _Feature_Reporting0.Reg +#define Feature_Reporting1 _Feature_Reporting1.Reg +#define Global_Configuration0 _Global_Configuration0.Reg +#define Global_Configuration1 _Global_Configuration1.Reg +#define Vendor_Specific(i) _Vendor_Specific[i].Reg +#define Vendor_Identification _Vendor_Identification.Reg +#define Processor_Initialization _Processor_Initialization.Reg +#define IPI_Vector_Priority(i) _IPI_Vector_Priority[i].Reg +#define Spurious_Vector _Spurious_Vector.Reg +#define Timer_Frequency _Timer_Frequency.Reg + +/* Timer Registers */ +#define Current_Count _Current_Count.Reg +#define Base_Count _Base_Count.Reg +#define Vector_Priority _Vector_Priority.Reg +#define Destination _Destination.Reg + +/* Interrupt Source Registers */ +#define Vector_Priority _Vector_Priority.Reg +#define Destination _Destination.Reg + + /* + * Local (static) OpenPIC Operations + */ + + +/* Global Operations */ +static void openpic_reset(void); +static void openpic_enable_8259_pass_through(void); +static void openpic_disable_8259_pass_through(void); +static u_int openpic_irq(void); +static void openpic_eoi(void); +static u_int openpic_get_priority(void); +static void openpic_set_priority(u_int pri); +static u_int openpic_get_spurious(void); +static void openpic_set_spurious(u_int vector); + +#ifdef CONFIG_SMP +/* Interprocessor Interrupts */ +static void openpic_initipi(u_int ipi, u_int pri, u_int vector); +static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs); +#endif + +/* Timer Interrupts */ +static void openpic_inittimer(u_int timer, u_int pri, u_int vector); +static void openpic_maptimer(u_int timer, u_int cpumask); + +/* Interrupt Sources */ +static void openpic_enable_irq(u_int irq); +static void openpic_disable_irq(u_int irq); +static void openpic_initirq(u_int irq, u_int pri, u_int vector, int polarity, + int is_level); +static void openpic_mapirq(u_int irq, u_int cpumask); +static void openpic_set_sense(u_int irq, int sense); + +#endif /* __KERNEL__ */ + +#endif /* _LINUX_OPENPIC_H */ diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 6d6f775f2..1e503fae4 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -3,15 +3,16 @@ * Common pmac/prep/chrp pci routines. -- Cort */ +#include <linux/config.h> #include <linux/kernel.h> #include <linux/pci.h> #include <linux/delay.h> #include <linux/string.h> #include <linux/init.h> -#include <linux/openpic.h> #include <linux/capability.h> #include <linux/sched.h> #include <linux/errno.h> +#include <linux/bootmem.h> #include <asm/processor.h> #include <asm/io.h> @@ -25,7 +26,7 @@ #include "pci.h" -#undef DEBUG +#define DEBUG #ifdef DEBUG #define DBG(x...) printk(x) @@ -37,54 +38,44 @@ unsigned long isa_io_base = 0; unsigned long isa_mem_base = 0; unsigned long pci_dram_offset = 0; -struct pci_fixup pcibios_fixups[] = { - { 0 } -}; +static u8* pci_to_OF_bus_map; -int generic_pcibios_read_byte(struct pci_dev *dev, int where, u8 *val) -{ - return ppc_md.pcibios_read_config_byte(dev->bus->number,dev->devfn,where,val); -} -int generic_pcibios_read_word(struct pci_dev *dev, int where, u16 *val) -{ - return ppc_md.pcibios_read_config_word(dev->bus->number,dev->devfn,where,val); -} -int generic_pcibios_read_dword(struct pci_dev *dev, int where, u32 *val) -{ - return ppc_md.pcibios_read_config_dword(dev->bus->number,dev->devfn,where,val); -} -int generic_pcibios_write_byte(struct pci_dev *dev, int where, u8 val) -{ - return ppc_md.pcibios_write_config_byte(dev->bus->number,dev->devfn,where,val); -} -int generic_pcibios_write_word(struct pci_dev *dev, int where, u16 val) -{ - return ppc_md.pcibios_write_config_word(dev->bus->number,dev->devfn,where,val); -} -int generic_pcibios_write_dword(struct pci_dev *dev, int where, u32 val) -{ - return ppc_md.pcibios_write_config_dword(dev->bus->number,dev->devfn,where,val); -} +static void pcibios_fixup_resources(struct pci_dev* dev); +#ifdef CONFIG_ALL_PPC +static void pcibios_fixup_cardbus(struct pci_dev* dev); +#endif -struct pci_ops generic_pci_ops = -{ - generic_pcibios_read_byte, - generic_pcibios_read_word, - generic_pcibios_read_dword, - generic_pcibios_write_byte, - generic_pcibios_write_word, - generic_pcibios_write_dword -}; +/* By default, we don't re-assign bus numbers. We do this only on + * some pmacs + */ +int pci_assign_all_busses; + +struct pci_controller* hose_head; +struct pci_controller** hose_tail = &hose_head; +static int pci_bus_count; +struct pci_fixup pcibios_fixups[] = { + { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources }, +#ifdef CONFIG_ALL_PPC + /* We should add per-machine fixup support in xxx_setup.c or xxx_pci.c */ + { PCI_FIXUP_FINAL, PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1211, pcibios_fixup_cardbus }, +#endif /* CONFIG_ALL_PPC */ + { 0 } +}; -void pcibios_update_resource(struct pci_dev *dev, struct resource *root, +void +pcibios_update_resource(struct pci_dev *dev, struct resource *root, struct resource *res, int resource) { u32 new, check; int reg; - - new = res->start | (res->flags & PCI_REGION_FLAG_MASK); + struct pci_controller* hose = dev->sysdata; + + new = res->start; + if (hose && res->flags & IORESOURCE_MEM) + new -= hose->pci_mem_offset; + new |= (res->flags & PCI_REGION_FLAG_MASK); if (resource < 6) { reg = PCI_BASE_ADDRESS_0 + 4*resource; } else if (resource == PCI_ROM_RESOURCE) { @@ -104,6 +95,62 @@ void pcibios_update_resource(struct pci_dev *dev, struct resource *root, } } +static void +pcibios_fixup_resources(struct pci_dev* dev) +{ + struct pci_controller* hose = + (struct pci_controller *)dev->sysdata; + int i; + if (!hose) { + printk("No hose for PCI dev %x.%x !\n", dev->bus->number, dev->devfn >> 3); + return; + } + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + struct resource *res = dev->resource + i; + if (!res->start) + continue; + if (res->flags & IORESOURCE_MEM) { + res->start += hose->pci_mem_offset; + res->end += hose->pci_mem_offset; +#ifdef DEBUG + printk("Fixup mem res, dev: %x.%x, res_start: %lx->%lx\n", + dev->bus->number, dev->devfn>>3, res->start-hose->pci_mem_offset, + res->start); +#endif + } + + if ((res->flags & IORESOURCE_IO) + && (unsigned long) hose->io_base_virt != isa_io_base) { + unsigned long offs = (unsigned long) hose->io_base_virt - isa_io_base; + res->start += offs; + res->end += offs; + printk("Fixup IO res, dev: %x.%x, res_start: %lx->%lx\n", + dev->bus->number, dev->devfn>>3, + res->start - offs, res->start); + } + } +} + +#ifdef CONFIG_ALL_PPC +static void +pcibios_fixup_cardbus(struct pci_dev* dev) +{ + /* + * Fix the interrupt routing on the TI1211 chip on the 1999 + * G3 powerbook, which doesn't get initialized properly by OF. + */ + if (dev->vendor == PCI_VENDOR_ID_TI + && dev->device == PCI_DEVICE_ID_TI_1211) { + u32 val; + /* 0x8c == TI122X_IRQMUX, 2 says to route the INTA + signal out the MFUNC0 pin */ + if (pci_read_config_dword(dev, 0x8c, &val) == 0 + && val == 0) + pci_write_config_dword(dev, 0x8c, 2); + } +} +#endif /* CONFIG_ALL_PPC */ + /* * We need to avoid collisions with `mirrored' VGA ports * and other strange ISA hardware, so we always want the @@ -172,7 +219,8 @@ pcibios_align_resource(void *data, struct resource *res, unsigned long size) * as well. */ -static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) +static void __init +pcibios_allocate_bus_resources(struct list_head *bus_list) { struct list_head *ln; struct pci_bus *bus; @@ -197,7 +245,8 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) } } -static void __init pcibios_allocate_resources(int pass) +static void __init +pcibios_allocate_resources(int pass) { struct pci_dev *dev; int idx, disabled; @@ -250,7 +299,8 @@ static void __init pcibios_allocate_resources(int pass) } } -static void __init pcibios_assign_resources(void) +static void __init +pcibios_assign_resources(void) { struct pci_dev *dev; int idx; @@ -278,7 +328,9 @@ static void __init pcibios_assign_resources(void) * the BIOS forgot to do so or because we have decided the old * address was unusable for some reason. */ - if (!r->start && r->end) + if (!r->start && r->end && + (!ppc_md.pcibios_enable_device_hook || + !ppc_md.pcibios_enable_device_hook(dev, 1))) pci_assign_resource(dev, idx); } @@ -293,7 +345,8 @@ static void __init pcibios_assign_resources(void) } -int pcibios_enable_resources(struct pci_dev *dev) +int +pcibios_enable_resources(struct pci_dev *dev) { u16 cmd, old_cmd; int idx; @@ -321,18 +374,267 @@ int pcibios_enable_resources(struct pci_dev *dev) return 0; } +struct pci_controller * __init +pcibios_alloc_controller(void) +{ + struct pci_controller *hose; + + hose = (struct pci_controller *)alloc_bootmem(sizeof(*hose)); + memset(hose, 0, sizeof(struct pci_controller)); + + *hose_tail = hose; + hose_tail = &hose->next; + + return hose; +} +static void +make_one_node_map(struct device_node* node, u8 pci_bus) +{ + int *bus_range; + int len; + + if (pci_bus >= pci_bus_count) + return; + bus_range = (int *) get_property(node, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s\n", + node->full_name); + return; + } + pci_to_OF_bus_map[pci_bus] = bus_range[0]; + + for (node=node->child; node != 0;node = node->sibling) { + struct pci_dev* dev; + unsigned int *class_code, *reg; + + class_code = (unsigned int *) get_property(node, "class-code", 0); + if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && + (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) + continue; + reg = (unsigned int *)get_property(node, "reg", 0); + if (!reg) + continue; + dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff)); + if (!dev || !dev->subordinate) + continue; + make_one_node_map(node, dev->subordinate->number); + } +} + +void +pcibios_make_OF_bus_map(void) +{ + int i; + struct pci_controller* hose; + u8* of_prop_map; + + pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL); + if (!pci_to_OF_bus_map) { + printk(KERN_ERR "Can't allocate OF bus map !\n"); + return; + } + + /* We fill the bus map with invalid values, that helps + * debugging. + */ + for (i=0; i<pci_bus_count; i++) + pci_to_OF_bus_map[i] = 0xff; + + /* For each hose, we begin searching bridges */ + for(hose=hose_head; hose; hose=hose->next) { + struct device_node* node; + node = (struct device_node *)hose->arch_data; + if (!node) + continue; + make_one_node_map(node, hose->first_busno); + } + of_prop_map = get_property(find_path_device("/"), "pci-OF-bus-map", 0); + if (of_prop_map) + memcpy(of_prop_map, pci_to_OF_bus_map, pci_bus_count); +#ifdef DEBUG + printk("PCI->OF bus map:\n"); + for (i=0; i<pci_bus_count; i++) { + if (pci_to_OF_bus_map[i] == 0xff) + continue; + printk("%d -> %d\n", i, pci_to_OF_bus_map[i]); + } +#endif +} -void __init pcibios_init(void) +static struct device_node* +scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn) { + struct device_node* sub_node; + + for (; node != 0;node = node->sibling) { + unsigned int *class_code, *reg; + + reg = (unsigned int *) get_property(node, "reg", 0); + if (reg && ((reg[0] >> 8) & 0xff) == dev_fn + && ((reg[0] >> 16) & 0xff) == bus) + return node; + + /* For PCI<->PCI bridges or CardBus bridges, we go down */ + class_code = (unsigned int *) get_property(node, "class-code", 0); + if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && + (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) + continue; + sub_node = scan_OF_childs_for_device(node->child, bus, dev_fn); + if (sub_node) + return sub_node; + } + return NULL; +} + +/* + * Scans the OF tree for a device node matching a PCI device + */ +struct device_node* +pci_device_to_OF_node(struct pci_dev *dev) +{ + struct pci_controller *hose; + struct device_node *node; + int bus; + + if (!have_of) + return NULL; + + /* Lookup the hose */ + bus = dev->bus->number; + hose = pci_bus_to_hose(bus); + if (!hose) + return NULL; + + /* Check it has an OF node associated */ + node = (struct device_node *) hose->arch_data; + if (!node) + return NULL; + + /* Fixup bus number according to what OF think it is. */ + if (pci_to_OF_bus_map) + bus = pci_to_OF_bus_map[bus]; + if (bus == 0xff) + return NULL; + + /* Now, lookup childs of the hose */ + return scan_OF_childs_for_device(node->child, bus, dev->devfn); +} + +/* This routine is meant to be used early during boot, when the + * PCI bus numbers have not yet been assigned, and you need to + * issue PCI config cycles to an OF device. + * It could also be used to "fix" RTAS config cycles if you want + * to set pci_assign_all_busses to 1 and still use RTAS for PCI + * config cycles. + */ +struct pci_controller* +pci_find_hose_for_OF_device(struct device_node* node) +{ + if (!have_of) + return NULL; + while(node) { + struct pci_controller* hose; + for (hose=hose_head;hose;hose=hose->next) + if (hose->arch_data == node) + return hose; + node=node->parent; + } + return NULL; +} + +/* + * Returns the PCI device matching a given OF node + */ +int +pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn) +{ + unsigned int *reg; + int i; + + if (!have_of) + return -ENODEV; + reg = (unsigned int *) get_property(node, "reg", 0); + if (!reg) + return -ENODEV; + *bus = (reg[0] >> 16) & 0xff; + for (i=0; pci_to_OF_bus_map && i<pci_bus_count; i++) + if (pci_to_OF_bus_map[i] == *bus) { + *bus = i; + break; + } + *devfn = ((reg[0] >> 8) & 0xff); + return 0; +} + +void __init +pcibios_init(void) +{ + struct pci_controller *hose; + struct pci_bus *bus; + int next_busno; + printk("PCI: Probing PCI hardware\n"); - pci_scan_bus(0, &generic_pci_ops, NULL); + + /* Scan all of the recorded PCI controllers. */ + for (next_busno = 0, hose = hose_head; hose; hose = hose->next) { + if (pci_assign_all_busses) + hose->first_busno = next_busno; + hose->last_busno = 0xff; + bus = pci_scan_bus(hose->first_busno, hose->ops, hose); + hose->bus = bus; + hose->last_busno = bus->subordinate; + if (pci_assign_all_busses || next_busno <= hose->last_busno) + next_busno = hose->last_busno+1; + } + pci_bus_count = next_busno; + + /* OpenFirmware based machines need a map of OF bus + * numbers vs. kernel bus numbers since we may have to + * remap them. + */ + if (pci_assign_all_busses && have_of) + pcibios_make_OF_bus_map(); + + /* Call machine dependant fixup */ if (ppc_md.pcibios_fixup) ppc_md.pcibios_fixup(); + + /* Allocate and assign resources */ pcibios_allocate_bus_resources(&pci_root_buses); pcibios_allocate_resources(0); pcibios_allocate_resources(1); pcibios_assign_resources(); + +#ifdef CONFIG_BLK_DEV_IDE + /* OF fails to initialize IDE controllers on macs + * (and maybe other machines) + * + * This late fixup is done here since I want it to happen after + * resource assignement, and there's no "late-init" arch hook + * + * Ideally, this should be moved to the IDE layer, but we need + * to check specifically with Andre Hedrick how to do it cleanly + * since the common IDE code seem to care about the fact that the + * BIOS may have disabled a controller. + * + * -- BenH + */ + if (_machine == _MACH_Pmac) { + struct pci_dev *dev; + pci_for_each_dev(dev) + { + if ((dev->class >> 16) == PCI_BASE_CLASS_STORAGE) + pci_enable_device(dev); + } + } +#endif /* CONFIG_BLK_DEV_IDE */ +} + +int __init +pcibios_assign_all_busses(void) +{ + return pci_assign_all_busses; } void __init @@ -344,9 +646,16 @@ pcibios_fixup_pbus_ranges(struct pci_bus * bus, struct pbus_set_ranges_data * ra ranges->mem_end -= bus->resource[1]->start; } +unsigned long resource_fixup(struct pci_dev * dev, struct resource * res, + unsigned long start, unsigned long size) +{ + return start; +} void __init pcibios_fixup_bus(struct pci_bus *bus) { + pci_read_bridge_bases(bus); + if ( ppc_md.pcibios_fixup_bus ) ppc_md.pcibios_fixup_bus(bus); } @@ -370,6 +679,10 @@ int pcibios_enable_device(struct pci_dev *dev) int idx; struct resource *r; + if (ppc_md.pcibios_enable_device_hook) + if (ppc_md.pcibios_enable_device_hook(dev, 0)) + return -EINVAL; + pci_read_config_word(dev, PCI_COMMAND, &cmd); old_cmd = cmd; for (idx=0; idx<6; idx++) { @@ -391,37 +704,99 @@ int pcibios_enable_device(struct pci_dev *dev) return 0; } -void * -pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical) +struct pci_controller* +pci_bus_to_hose(int bus) { - if (!ppc_md.pci_dev_io_base) { - /* Please, someone fix this for non-pmac machines, we - * need either the virtual or physical PCI IO base - */ - return 0; - } - return ppc_md.pci_dev_io_base(bus, devfn, physical); + struct pci_controller* hose = hose_head; + + for (; hose; hose = hose->next) + if (bus >= hose->first_busno && bus <= hose->last_busno) + return hose; + return NULL; } -void * -pci_dev_mem_base(unsigned char bus, unsigned char devfn) +void* +pci_bus_io_base(unsigned int bus) { - /* Default memory base is 0 (1:1 mapping) */ - if (!ppc_md.pci_dev_mem_base) { - /* Please, someone fix this for non-pmac machines.*/ + struct pci_controller *hose; + + hose = pci_bus_to_hose(bus); + if (!hose) + return NULL; + return hose->io_base_virt; +} + +unsigned long +pci_bus_io_base_phys(unsigned int bus) +{ + struct pci_controller *hose; + + hose = pci_bus_to_hose(bus); + if (!hose) return 0; - } - return ppc_md.pci_dev_mem_base(bus, devfn); + return hose->io_base_phys; } -/* Returns the root-bridge number (Uni-N number) of a device */ -int -pci_dev_root_bridge(unsigned char bus, unsigned char devfn) +unsigned long +pci_bus_mem_base_phys(unsigned int bus) { - /* Defaults to 0 */ - if (!ppc_md.pci_dev_root_bridge) + struct pci_controller *hose; + + hose = pci_bus_to_hose(bus); + if (!hose) return 0; - return ppc_md.pci_dev_root_bridge(bus, devfn); + return hose->pci_mem_offset; +} + +#ifdef CONFIG_POWER4 +extern unsigned long pci_address_offset(int, unsigned int); +#endif /* CONFIG_POWER4 */ + +unsigned long +pci_resource_to_bus(struct pci_dev *pdev, struct resource *res) +{ + /* Hack alert again ! See comments in chrp_pci.c + */ +#ifdef CONFIG_POWER4 + unsigned long offset = pci_address_offset(pdev->bus->number, res->flags); + return res->start - offset; +#else /* CONFIG_POWER4 */ + struct pci_controller* hose = + (struct pci_controller *)pdev->sysdata; + if (hose && res->flags & IORESOURCE_MEM) + return res->start - hose->pci_mem_offset; + /* We may want to do something with IOs here... */ + return res->start; +#endif +} + +/* Obsolete functions. Should be removed once the symbios driver + * is fixed + */ +unsigned long +pci_phys_to_bus(unsigned long pa, int busnr) +{ +#ifdef CONFIG_POWER4 + return pa - pci_address_offset(busnr, IORESOURCE_MEM); +#else /* CONFIG_POWER4 */ + struct pci_controller* hose = pci_bus_to_hose(busnr); + if (!hose) + return pa; + return pa - hose->pci_mem_offset; +#endif +} + +unsigned long +pci_bus_to_phys(unsigned int ba, int busnr) +{ +#ifdef CONFIG_POWER4 + return ba + pci_address_offset(dev->bus->number, IORESOURCE_MEM); +#else /* CONFIG_POWER4 */ + struct pci_controller* hose = pci_bus_to_hose(busnr); + if (!hose) + return ba; + return ba + hose->pci_mem_offset; +#endif } /* Provide information on locations of various I/O regions in physical @@ -430,23 +805,93 @@ pci_dev_root_bridge(unsigned char bus, unsigned char devfn) * Note that the returned IO or memory base is a physical address */ -asmlinkage long +long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) { + struct pci_controller* hose = pci_bus_to_hose(bus); long result = -EOPNOTSUPP; + + if (!hose) + return -ENODEV; switch (which) { case IOBASE_BRIDGE_NUMBER: - return (long)pci_dev_root_bridge(bus, devfn); + return (long)hose->first_busno; case IOBASE_MEMORY: - return (long)pci_dev_mem_base(bus, devfn); + return (long)hose->pci_mem_offset; case IOBASE_IO: - result = (long)pci_dev_io_base(bus, devfn, 1); - if (result == 0) - result = -EOPNOTSUPP; - break; + return (long)hose->io_base_phys; + case IOBASE_ISA_IO: + return (long)isa_io_base; + case IOBASE_ISA_MEM: + return (long)isa_mem_base; } return result; } +/* + * Null PCI config access functions, for the case when we can't + * find a hose. + */ +#define NULL_PCI_OP(rw, size, type) \ +static int \ +null_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + return PCIBIOS_DEVICE_NOT_FOUND; \ +} + +NULL_PCI_OP(read, byte, u8 *) +NULL_PCI_OP(read, word, u16 *) +NULL_PCI_OP(read, dword, u32 *) +NULL_PCI_OP(write, byte, u8) +NULL_PCI_OP(write, word, u16) +NULL_PCI_OP(write, dword, u32) + +static struct pci_ops null_pci_ops = +{ + null_read_config_byte, + null_read_config_word, + null_read_config_dword, + null_write_config_byte, + null_write_config_word, + null_write_config_dword +}; + +/* + * These functions are used early on before PCI scanning is done + * and all of the pci_dev and pci_bus structures have been created. + */ +static struct pci_dev * +fake_pci_dev(struct pci_controller *hose, int busnr, int devfn) +{ + static struct pci_dev dev; + static struct pci_bus bus; + + if (hose == 0) { + hose = pci_bus_to_hose(busnr); + if (hose == 0) + printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr); + } + dev.bus = &bus; + dev.sysdata = hose; + dev.devfn = devfn; + bus.number = busnr; + bus.ops = hose? hose->ops: &null_pci_ops; + return &dev; +} + +#define EARLY_PCI_OP(rw, size, type) \ +int early_##rw##_config_##size(struct pci_controller *hose, int bus, \ + int devfn, int offset, type value) \ +{ \ + return pci_##rw##_config_##size(fake_pci_dev(hose, bus, devfn), \ + offset, value); \ +} + +EARLY_PCI_OP(read, byte, u8 *) +EARLY_PCI_OP(read, word, u16 *) +EARLY_PCI_OP(read, dword, u32 *) +EARLY_PCI_OP(write, byte, u8) +EARLY_PCI_OP(write, word, u16) +EARLY_PCI_OP(write, dword, u32) diff --git a/arch/ppc/kernel/pci.h b/arch/ppc/kernel/pci.h index d79eb0f4a..07a64d9f3 100644 --- a/arch/ppc/kernel/pci.h +++ b/arch/ppc/kernel/pci.h @@ -2,47 +2,23 @@ #ifndef __PPC_KERNEL_PCI_H__ #define __PPC_KERNEL_PCI_H__ +/* Configure those in your xxx_init() or xxx_setup_arch() function */ extern unsigned long isa_io_base; extern unsigned long isa_mem_base; extern unsigned long pci_dram_offset; -extern unsigned int *pci_config_address; -extern unsigned char *pci_config_data; +/* Set this to 1 if you want the kernel to re-assign all PCI + * bus numbers + */ +extern int pci_assign_all_busses; -void fix_intr(struct device_node *node, struct pci_dev *dev); -#if 0 -#define decl_config_access_method(name) \ -struct pci_ops name##_pci_ops = { \ - name##_pcibios_read_config_byte, \ - name##_pcibios_read_config_word, \ - name##_pcibios_read_config_dword, \ - name##_pcibios_write_config_byte, \ - name##_pcibios_write_config_word, \ - name##_pcibios_write_config_dword \ -} -#endif +extern struct pci_controller* pcibios_alloc_controller(void); +extern struct pci_controller* pci_find_hose_for_OF_device( + struct device_node* node); -#define decl_config_access_method(name) \ -extern int name##_pcibios_read_config_byte(unsigned char bus, \ - unsigned char dev_fn, unsigned char offset, unsigned char *val); \ -extern int name##_pcibios_read_config_word(unsigned char bus, \ - unsigned char dev_fn, unsigned char offset, unsigned short *val); \ -extern int name##_pcibios_read_config_dword(unsigned char bus, \ - unsigned char dev_fn, unsigned char offset, unsigned int *val); \ -extern int name##_pcibios_write_config_byte(unsigned char bus, \ - unsigned char dev_fn, unsigned char offset, unsigned char val); \ -extern int name##_pcibios_write_config_word(unsigned char bus, \ - unsigned char dev_fn, unsigned char offset, unsigned short val); \ -extern int name##_pcibios_write_config_dword(unsigned char bus, \ - unsigned char dev_fn, unsigned char offset, unsigned int val) - -#define set_config_access_method(name) \ - ppc_md.pcibios_read_config_byte = name##_pcibios_read_config_byte; \ - ppc_md.pcibios_read_config_word = name##_pcibios_read_config_word; \ - ppc_md.pcibios_read_config_dword = name##_pcibios_read_config_dword; \ - ppc_md.pcibios_write_config_byte = name##_pcibios_write_config_byte; \ - ppc_md.pcibios_write_config_word = name##_pcibios_write_config_word; \ - ppc_md.pcibios_write_config_dword = name##_pcibios_write_config_dword +extern void setup_indirect_pci(struct pci_controller* hose, + u32 cfg_addr, u32 cfg_data); +extern void setup_grackle(struct pci_controller *hose, unsigned io_space_size); #endif /* __PPC_KERNEL_PCI_H__ */ diff --git a/arch/ppc/kernel/pmac_pci.c b/arch/ppc/kernel/pmac_pci.c index 8f7b3d7c2..9e1fffb49 100644 --- a/arch/ppc/kernel/pmac_pci.c +++ b/arch/ppc/kernel/pmac_pci.c @@ -27,23 +27,14 @@ #include "pci.h" -struct bridge_data **bridges, *bridge_list; -static int max_bus; - -struct uninorth_data { - struct device_node* node; - volatile unsigned int* cfg_addr; - volatile unsigned int* cfg_data; - void* iobase; - unsigned long iobase_phys; -}; - -static struct uninorth_data uninorth_bridges[3]; -static int uninorth_count; -static int uninorth_default = -1; +#undef DEBUG static void add_bridges(struct device_node *dev); +/* XXX Could be per-controller, but I don't think we risk anything by + * assuming we won't have both UniNorth and Bandit */ +static int has_uninorth; + /* * Magic constants for enabling cache coherency in the bandit/PSX bridge. */ @@ -56,477 +47,201 @@ static void add_bridges(struct device_node *dev); #define BANDIT_MAGIC 0x50 #define BANDIT_COHERENT 0x40 -/* Obsolete, should be replaced by pmac_pci_dev_io_base() (below) */ -__pmac -void *pci_io_base(unsigned int bus) -{ - struct bridge_data *bp; - - if (bus > max_bus || (bp = bridges[bus]) == 0) - return 0; - return bp->io_base; -} - -__pmac -int pci_device_loc(struct device_node *dev, unsigned char *bus_ptr, - unsigned char *devfn_ptr) +static int __init +fixup_one_level_bus_range(struct device_node *node, int higher) { - unsigned int *reg; - int len; + for (; node != 0;node = node->sibling) { + int * bus_range; + unsigned int *class_code; + int len; - reg = (unsigned int *) get_property(dev, "reg", &len); - if (reg == 0 || len < 5 * sizeof(unsigned int)) { - /* doesn't look like a PCI device */ - *bus_ptr = 0xff; - *devfn_ptr = 0xff; - return -1; + /* For PCI<->PCI bridges or CardBus bridges, we go down */ + class_code = (unsigned int *) get_property(node, "class-code", 0); + if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && + (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) + continue; + bus_range = (int *) get_property(node, "bus-range", &len); + if (bus_range != NULL && len > 2 * sizeof(int)) { + if (bus_range[1] > higher) + higher = bus_range[1]; + } + higher = fixup_one_level_bus_range(node->child, higher); } - *bus_ptr = reg[0] >> 16; - *devfn_ptr = reg[0] >> 8; - return 0; + return higher; } -/* This routines figures out on which root bridge a given PCI device - * is attached. +/* This routine fixes the "bus-range" property of all bridges in the + * system since they tend to have their "last" member wrong on macs + * + * Note that the bus numbers manipulated here are OF bus numbers, they + * are not Linux bus numbers. */ -__pmac -int -pmac_pci_dev_root_bridge(unsigned char bus, unsigned char dev_fn) +static void __init +fixup_bus_range(struct device_node *bridge) { - struct device_node *node, *bridge_node; - int bridge = uninorth_default; - - if (uninorth_count == 0) - return 0; - if (bus == 0 && PCI_SLOT(dev_fn) < 11) - return 0; + int * bus_range; + int len; - /* We look for the OF device corresponding to this bus/devfn pair. If we - * don't find it, we default to the external PCI */ - bridge_node = NULL; - node = find_pci_device_OFnode(bus, dev_fn & 0xf8); - if (node) { - /* note: we don't stop on the first occurence since we need to go - * up to the root bridge */ - do { - if (node->type && !strcmp(node->type, "pci") - && device_is_compatible(node, "uni-north")) - bridge_node = node; - node=node->parent; - } while (node); - } - if (bridge_node) { - int i; - for (i=0;i<uninorth_count;i++) - if (uninorth_bridges[i].node == bridge_node) { - bridge = i; - break; - } - } - - if (bridge == -1) { - printk(KERN_WARNING "pmac_pci: no default bridge !\n"); - return 0; - } - - return bridge; -} - -__pmac -void * -pmac_pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical) -{ - int bridge = -1; - if (uninorth_count != 0) - bridge = pmac_pci_dev_root_bridge(bus, devfn); - if (bridge == -1) { - struct bridge_data *bp; - - if (bus > max_bus || (bp = bridges[bus]) == 0) - return 0; - return physical ? (void *) bp->io_base_phys : bp->io_base; + /* Lookup the "bus-range" property for the hose */ + bus_range = (int *) get_property(bridge, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s\n", + bridge->full_name); + return; } - return physical ? (void *) uninorth_bridges[bridge].iobase_phys - : uninorth_bridges[bridge].iobase; -} - -__pmac -void * -pmac_pci_dev_mem_base(unsigned char bus, unsigned char devfn) -{ - return 0; + bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]); } -/* This function only works for bus 0, uni-N uses a different mecanism for - * other busses (see below) +/* + * Apple MacRISC (UniNorth, Bandit) PCI controllers. + * + * The "Bandit" version is present in all early PCI PowerMacs, + * and up to the first ones using Grackle. Some machines may + * have 2 bandit controllers (2 PCI busses). + * + * The "UniNorth" version is present in all Core99 machines + * (iBook, G4, new IMacs, and all the recent Apple machines). + * It contains 3 controllers in one ASIC. */ -#define UNI_N_CFA0(devfn, off) \ + +#define MACRISC_CFA0(devfn, off) \ ((1 << (unsigned long)PCI_SLOT(dev_fn)) \ | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \ | (((unsigned long)(off)) & 0xFCUL)) -/* This one is for type 1 config accesses */ -#define UNI_N_CFA1(bus, devfn, off) \ +#define MACRISC_CFA1(bus, devfn, off) \ ((((unsigned long)(bus)) << 16) \ |(((unsigned long)(devfn)) << 8) \ |(((unsigned long)(off)) & 0xFCUL) \ |1UL) -__pmac static -unsigned int -uni_north_access_data(unsigned char bus, unsigned char dev_fn, - unsigned char offset) +static unsigned int __pmac +macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset) { - int bridge; unsigned int caddr; - - bridge = pmac_pci_dev_root_bridge(bus, dev_fn); - if (bus == 0) - caddr = UNI_N_CFA0(dev_fn, offset); - else - caddr = UNI_N_CFA1(bus, dev_fn, offset); - - if (bridge == -1) { - printk(KERN_WARNING "pmac_pci: no default bridge !\n"); - return 0; - } - - /* Uninorth will return garbage if we don't read back the value ! */ - out_le32(uninorth_bridges[bridge].cfg_addr, caddr); - (void)in_le32(uninorth_bridges[bridge].cfg_addr); - /* Yes, offset is & 7, not & 3 ! */ - return (unsigned int)(uninorth_bridges[bridge].cfg_data) + (offset & 0x07); -} - -__pmac -int uni_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) -{ - unsigned int addr; - - *val = 0xff; - addr = uni_north_access_data(bus, dev_fn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - *val = in_8((volatile unsigned char*)addr); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int uni_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) -{ - unsigned int addr; - - *val = 0xffff; - addr = uni_north_access_data(bus, dev_fn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - *val = in_le16((volatile unsigned short*)addr); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int uni_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) -{ - unsigned int addr; - *val = 0xffff; - addr = uni_north_access_data(bus, dev_fn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - *val = in_le32((volatile unsigned int*)addr); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int uni_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) -{ - unsigned int addr; - - addr = uni_north_access_data(bus, dev_fn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - out_8((volatile unsigned char *)addr, val); - (void)in_8((volatile unsigned char *)addr); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int uni_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) -{ - unsigned int addr; - - addr = uni_north_access_data(bus, dev_fn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le16((volatile unsigned short *)addr, val); - (void)in_le16((volatile unsigned short *)addr); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int uni_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) -{ - unsigned int addr; - - addr = uni_north_access_data(bus, dev_fn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32((volatile unsigned int *)addr, val); - (void)in_le32((volatile unsigned int *)addr); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int pmac_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) -{ - struct bridge_data *bp; - - *val = 0xff; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if (bus == bp->bus_number) { - if (dev_fn < (11 << 3)) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32(bp->cfg_addr, - (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8) - + (offset & ~3)); - } else { - /* Bus number once again taken into consideration. - * Change applied from 2.1.24. This makes devices located - * behind PCI-PCI bridges visible. - * -Ranjit Deshpande, 01/20/99 - */ - out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1); - } - udelay(2); - *val = in_8(bp->cfg_data + (offset & 3)); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int pmac_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) -{ - struct bridge_data *bp; - - *val = 0xffff; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 1) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == bp->bus_number) { - if (dev_fn < (11 << 3)) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32(bp->cfg_addr, - (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8) - + (offset & ~3)); - } else { - /* See pci_read_config_byte */ - out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1); - } - udelay(2); - *val = in_le16((volatile unsigned short *)(bp->cfg_data + (offset & 3))); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int pmac_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) -{ - struct bridge_data *bp; - - *val = 0xffffffff; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 3) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == bp->bus_number) { - if (dev_fn < (11 << 3)) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32(bp->cfg_addr, - (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8) - + offset); - } else { - /* See pci_read_config_byte */ - out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + offset + 1); - } - udelay(2); - *val = in_le32((volatile unsigned int *)bp->cfg_data); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int pmac_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) -{ - struct bridge_data *bp; - - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if (bus == bp->bus_number) { +#ifdef DEBUG +// printk("macrisc_config_access(hose: 0x%08lx, bus: 0x%x, devfb: 0x%x, offset: 0x%x)\n", +// hose, bus, dev_fn, offset); +#endif + if (bus == hose->first_busno) { if (dev_fn < (11 << 3)) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32(bp->cfg_addr, - (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8) - + (offset & ~3)); - } else { - /* See pci_read_config_byte */ - out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1); - } - udelay(2); - out_8(bp->cfg_data + (offset & 3), val); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int pmac_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) -{ - struct bridge_data *bp; + return 0; + caddr = MACRISC_CFA0(dev_fn, offset); + } else + caddr = MACRISC_CFA1(bus, dev_fn, offset); + + /* Uninorth will return garbage if we don't read back the value ! */ + do { + out_le32(hose->cfg_addr, caddr); + } while(in_le32(hose->cfg_addr) != caddr); + + offset &= has_uninorth ? 0x07 : 0x03; + return (unsigned int)(hose->cfg_data) + (unsigned int)offset; +} + +#define cfg_read(val, addr, type, op, op2) \ + *val = op((type)(addr)) +#define cfg_write(val, addr, type, op, op2) \ + op((type *)(addr), (val)); (void) op2((type *)(addr)) + +#define cfg_read_bad(val, size) *val = bad_##size; +#define cfg_write_bad(val, size) + +#define bad_byte 0xff +#define bad_word 0xffff +#define bad_dword 0xffffffffU + +#define MACRISC_PCI_OP(rw, size, type, op, op2) \ +static int __pmac \ +macrisc_##rw##_config_##size(struct pci_dev *dev, int off, type val) \ +{ \ + struct pci_controller *hose = dev->sysdata; \ + unsigned int addr; \ + \ + addr = macrisc_cfg_access(hose, dev->bus->number, dev->devfn, off); \ + if (!addr) { \ + cfg_##rw##_bad(val, size) \ + return PCIBIOS_DEVICE_NOT_FOUND; \ + } \ + cfg_##rw(val, addr, type, op, op2); \ + return PCIBIOS_SUCCESSFUL; \ +} + +MACRISC_PCI_OP(read, byte, u8 *, in_8, x) +MACRISC_PCI_OP(read, word, u16 *, in_le16, x) +MACRISC_PCI_OP(read, dword, u32 *, in_le32, x) +MACRISC_PCI_OP(write, byte, u8, out_8, in_8) +MACRISC_PCI_OP(write, word, u16, out_le16, in_le16) +MACRISC_PCI_OP(write, dword, u32, out_le32, in_le32) + +static struct pci_ops macrisc_pci_ops = +{ + macrisc_read_config_byte, + macrisc_read_config_word, + macrisc_read_config_dword, + macrisc_write_config_byte, + macrisc_write_config_word, + macrisc_write_config_dword +}; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 1) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == bp->bus_number) { - if (dev_fn < (11 << 3)) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32(bp->cfg_addr, - (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8) - + (offset & ~3)); - } else { - /* See pci_read_config_byte */ - out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1); - } - udelay(2); - out_le16((volatile unsigned short *)(bp->cfg_data + (offset & 3)), val); - return PCIBIOS_SUCCESSFUL; -} -__pmac -int pmac_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) +/* + * Apple "Chaos" PCI controller. + * + * This controller is present on some first generation "PowerSurge" + * machines (8500, 8600, ...). It's a very weird beast and will die + * in flames if we try to probe the config space. + * The long-term solution is to provide a config space "emulation" + * based on what we find in OF device tree + */ + +static int chaos_config_read_byte(struct pci_dev *dev, int offset, u8 *val) { - struct bridge_data *bp; - - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 3) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == bp->bus_number) { - if (dev_fn < (11 << 3)) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32(bp->cfg_addr, - (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8) - + offset); - } else { - /* See pci_read_config_byte */ - out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1); - } - udelay(2); - out_le32((volatile unsigned int *)bp->cfg_data, val); - return PCIBIOS_SUCCESSFUL; + return PCIBIOS_DEVICE_NOT_FOUND; } -#define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \ - | (((o) & ~3) << 24)) - -int grackle_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) +static int chaos_config_read_word(struct pci_dev *dev, int offset, u16 *val) { - struct bridge_data *bp; - - *val = 0xff; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset)); - *val = in_8(bp->cfg_data + (offset & 3)); - return PCIBIOS_SUCCESSFUL; + return PCIBIOS_DEVICE_NOT_FOUND; } -int grackle_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) +static int chaos_config_read_dword(struct pci_dev *dev, int offset, u32 *val) { - struct bridge_data *bp; - - *val = 0xffff; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 1) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset)); - *val = in_le16((volatile unsigned short *)(bp->cfg_data + (offset&3))); - return PCIBIOS_SUCCESSFUL; + return PCIBIOS_DEVICE_NOT_FOUND; } -int grackle_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) +static int chaos_config_write_byte(struct pci_dev *dev, int offset, u8 val) { - struct bridge_data *bp; - - *val = 0xffffffff; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 3) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset)); - *val = in_le32((volatile unsigned int *)bp->cfg_data); - return PCIBIOS_SUCCESSFUL; + return PCIBIOS_DEVICE_NOT_FOUND; } -int grackle_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) +static int chaos_config_write_word(struct pci_dev *dev, int offset, u16 val) { - struct bridge_data *bp; - - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset)); - out_8(bp->cfg_data + (offset & 3), val); - return PCIBIOS_SUCCESSFUL; + return PCIBIOS_DEVICE_NOT_FOUND; } -int grackle_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) +static int chaos_config_write_dword(struct pci_dev *dev, int offset, u32 val) { - struct bridge_data *bp; - - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 1) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset)); - out_le16((volatile unsigned short *)(bp->cfg_data + (offset&3)), val); - return PCIBIOS_SUCCESSFUL; + return PCIBIOS_DEVICE_NOT_FOUND; } -int grackle_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) +static struct pci_ops chaos_pci_ops = { - struct bridge_data *bp; + chaos_config_read_byte, + chaos_config_read_word, + chaos_config_read_dword, + chaos_config_write_byte, + chaos_config_write_word, + chaos_config_write_dword +}; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 1) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset)); - out_le32((volatile unsigned int *)bp->cfg_data, val); - return PCIBIOS_SUCCESSFUL; -} /* * For a bandit bridge, turn on cache coherency if necessary. - * N.B. we can't use pcibios_*_config_* here because bridges[] - * is not initialized yet. + * N.B. we could clean this up using the hose ops directly. */ -static void __init init_bandit(struct bridge_data *bp) +static void __init init_bandit(struct pci_controller *bp) { unsigned int vendev, magic; int rev; @@ -543,8 +258,8 @@ static void __init init_bandit(struct bridge_data *bp) rev = in_8(bp->cfg_data); if (rev != BANDIT_REVID) printk(KERN_WARNING - "Unknown revision %d for bandit at %p\n", - rev, bp->io_base); + "Unknown revision %d for bandit at %08lx\n", + rev, bp->io_base_phys); } else if (vendev != (BANDIT_DEVID_2 << 16) + APPLE_VENDID) { printk(KERN_WARNING "bandit isn't? (%x)\n", vendev); return; @@ -555,8 +270,8 @@ static void __init init_bandit(struct bridge_data *bp) udelay(2); rev = in_8(bp->cfg_data); if (rev != BANDIT_REVID) - printk(KERN_WARNING "Unknown revision %d for bandit at %p\n", - rev, bp->io_base); + printk(KERN_WARNING "Unknown revision %d for bandit at %08lx\n", + rev, bp->io_base_phys); /* read the word at offset 0x50 */ out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + BANDIT_MAGIC); @@ -567,16 +282,71 @@ static void __init init_bandit(struct bridge_data *bp) magic |= BANDIT_COHERENT; udelay(2); out_le32((volatile unsigned int *)bp->cfg_data, magic); - printk(KERN_INFO "Cache coherency enabled for bandit/PSX at %p\n", - bp->io_base); + printk(KERN_INFO "Cache coherency enabled for bandit/PSX at %08lx\n", + bp->io_base_phys); +} + + +/* + * Tweak the PCI-PCI bridge chip on the blue & white G3s. + */ +static void __init +init_p2pbridge(void) +{ + struct device_node *p2pbridge; + struct pci_controller* hose; + u8 bus, devfn; + u16 val; + + /* XXX it would be better here to identify the specific + PCI-PCI bridge chip we have. */ + if ((p2pbridge = find_devices("pci-bridge")) == 0 + || p2pbridge->parent == NULL + || strcmp(p2pbridge->parent->name, "pci") != 0) + return; + if (pci_device_from_OF_node(p2pbridge, &bus, &devfn) < 0) { +#ifdef DEBUG + printk("Can't find PCI infos for PCI<->PCI bridge\n"); +#endif + return; + } + /* Warning: At this point, we have not yet renumbered all busses. + * So we must use OF walking to find out hose + */ + hose = pci_find_hose_for_OF_device(p2pbridge); + if (!hose) { +#ifdef DEBUG + printk("Can't find hose for PCI<->PCI bridge\n"); +#endif + return; + } + if (early_read_config_word(hose, bus, devfn, + PCI_BRIDGE_CONTROL, &val) < 0) { + printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n"); + return; + } + val &= ~PCI_BRIDGE_CTL_MASTER_ABORT; + early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val); } +void __init +pmac_find_bridges(void) +{ + add_bridges(find_devices("bandit")); + add_bridges(find_devices("chaos")); + add_bridges(find_devices("pci")); + init_p2pbridge(); +} + +#define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \ + | (((o) & ~3) << 24)) + #define GRACKLE_PICR1_STG 0x00000040 #define GRACKLE_PICR1_LOOPSNOOP 0x00000010 /* N.B. this is called before bridges is initialized, so we can't use grackle_pcibios_{read,write}_config_dword. */ -static inline void grackle_set_stg(struct bridge_data *bp, int enable) +static inline void grackle_set_stg(struct pci_controller* bp, int enable) { unsigned int val; @@ -586,9 +356,10 @@ static inline void grackle_set_stg(struct bridge_data *bp, int enable) (val & ~GRACKLE_PICR1_STG); out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); out_le32((volatile unsigned int *)bp->cfg_data, val); + (void)in_le32((volatile unsigned int *)bp->cfg_data); } -static inline void grackle_set_loop_snoop(struct bridge_data *bp, int enable) +static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable) { unsigned int val; @@ -598,25 +369,68 @@ static inline void grackle_set_loop_snoop(struct bridge_data *bp, int enable) (val & ~GRACKLE_PICR1_LOOPSNOOP); out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); out_le32((volatile unsigned int *)bp->cfg_data, val); + (void)in_le32((volatile unsigned int *)bp->cfg_data); } +static void __init +setup_uninorth(struct pci_controller* hose, struct reg_property* addr) +{ + pci_assign_all_busses = 1; + has_uninorth = 1; + hose->ops = ¯isc_pci_ops; + hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); + hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); + hose->io_base_phys = addr->address; + /* is 0x10000 enough for io space ? */ + hose->io_base_virt = (void *)ioremap(addr->address, 0x10000); + + /* XXX This is the bridge with the PCI expansion bus. We route + * legacy IOs to it. + */ + if (addr->address == 0xf2000000) + isa_io_base = (unsigned long)hose->io_base_virt; +} -void __init pmac_find_bridges(void) +static void __init +setup_bandit(struct pci_controller* hose, struct reg_property* addr) { - int bus; - struct bridge_data *bridge; + hose->ops = ¯isc_pci_ops; + hose->cfg_addr = (volatile unsigned int *) + ioremap(addr->address + 0x800000, 0x1000); + hose->cfg_data = (volatile unsigned char *) + ioremap(addr->address + 0xc00000, 0x1000); + hose->io_base_phys = addr->address; + hose->io_base_virt = (void *) ioremap(addr->address, 0x10000); + init_bandit(hose); +} - bridge_list = 0; - max_bus = 0; - add_bridges(find_devices("bandit")); - add_bridges(find_devices("chaos")); - add_bridges(find_devices("pci")); - bridges = (struct bridge_data **) - alloc_bootmem((max_bus + 1) * sizeof(struct bridge_data *)); - memset(bridges, 0, (max_bus + 1) * sizeof(struct bridge_data *)); - for (bridge = bridge_list; bridge != NULL; bridge = bridge->next) - for (bus = bridge->bus_number; bus <= bridge->max_bus; ++bus) - bridges[bus] = bridge; +static void __init +setup_chaos(struct pci_controller* hose, struct reg_property* addr) +{ + /* assume a `chaos' bridge */ + hose->ops = &chaos_pci_ops; + hose->cfg_addr = (volatile unsigned int *) + ioremap(addr->address + 0x800000, 0x1000); + hose->cfg_data = (volatile unsigned char *) + ioremap(addr->address + 0xc00000, 0x1000); + hose->io_base_phys = addr->address; + hose->io_base_virt = (void *) ioremap(addr->address, 0x10000); +} + +void __init +setup_grackle(struct pci_controller *hose, unsigned io_space_size) +{ + setup_indirect_pci(hose, 0xfec00000, 0xfee00000); + hose->io_base_phys = 0xfe000000; + hose->io_base_virt = (void *) ioremap(0xfe000000, io_space_size); + pci_dram_offset = 0; + isa_mem_base = 0xfd000000; + isa_io_base = (unsigned long) hose->io_base_virt; + if (machine_is_compatible("AAPL,PowerBook1998")) + grackle_set_loop_snoop(hose, 1); +#if 0 /* Disabled for now, HW problems ??? */ + grackle_set_stg(hose, 1); +#endif } /* @@ -626,11 +440,12 @@ void __init pmac_find_bridges(void) */ static void __init add_bridges(struct device_node *dev) { - int *bus_range; int len; - struct bridge_data *bp; + struct pci_controller *hose; struct reg_property *addr; - + char* disp_name; + int *bus_range; + for (; dev != NULL; dev = dev->next) { addr = (struct reg_property *) get_property(dev, "reg", &len); if (addr == NULL || len < sizeof(*addr)) { @@ -640,108 +455,52 @@ static void __init add_bridges(struct device_node *dev) } bus_range = (int *) get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s\n", - dev->full_name); - continue; - } - if (bus_range[1] == bus_range[0]) - printk(KERN_INFO "PCI bus %d", bus_range[0]); - else - printk(KERN_INFO "PCI buses %d..%d", bus_range[0], - bus_range[1]); - printk(" controlled by %s at %x\n", dev->name, addr->address); - if (device_is_compatible(dev, "uni-north")) { - int i = uninorth_count++; - uninorth_bridges[i].cfg_addr = ioremap(addr->address + 0x800000, 0x1000); - uninorth_bridges[i].cfg_data = ioremap(addr->address + 0xc00000, 0x1000); - uninorth_bridges[i].node = dev; - uninorth_bridges[i].iobase_phys = addr->address; - /* is 0x10000 enough for io space ? */ - uninorth_bridges[i].iobase = (void *)ioremap(addr->address, 0x10000); - /* XXX This is the bridge with the PCI expansion bus. This is also the - * address of the bus that will receive type 1 config accesses and io - * accesses. Appears to be correct for iMac DV and G4 Sawtooth too. - * That means that we cannot do io cycles on the AGP bus nor the internal - * ethernet/fw bus. Fortunately, they appear not to be needed on iMac DV - * and G4 neither. - */ - if (addr->address == 0xf2000000) - uninorth_default = i; - else - continue; + printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", + dev->full_name); } - bp = (struct bridge_data *) alloc_bootmem(sizeof(*bp)); + hose = pcibios_alloc_controller(); + if (!hose) + continue; + hose->arch_data = dev; + hose->first_busno = bus_range ? bus_range[0] : 0; + hose->last_busno = bus_range ? bus_range[1] : 0xff; + + disp_name = NULL; if (device_is_compatible(dev, "uni-north")) { - bp->cfg_addr = 0; - bp->cfg_data = 0; - bp->io_base = uninorth_bridges[uninorth_count-1].iobase; - bp->io_base_phys = uninorth_bridges[uninorth_count-1].iobase_phys; + setup_uninorth(hose, addr); + disp_name = "UniNorth"; } else if (strcmp(dev->name, "pci") == 0) { /* XXX assume this is a mpc106 (grackle) */ - bp->cfg_addr = (volatile unsigned int *) - ioremap(0xfec00000, 0x1000); - bp->cfg_data = (volatile unsigned char *) - ioremap(0xfee00000, 0x1000); - bp->io_base_phys = 0xfe000000; - bp->io_base = (void *) ioremap(0xfe000000, 0x20000); - if (machine_is_compatible("AAPL,PowerBook1998")) - grackle_set_loop_snoop(bp, 1); -#if 0 /* Disabled for now, HW problems ??? */ - grackle_set_stg(bp, 1); -#endif - } else { - /* a `bandit' or `chaos' bridge */ - bp->cfg_addr = (volatile unsigned int *) - ioremap(addr->address + 0x800000, 0x1000); - bp->cfg_data = (volatile unsigned char *) - ioremap(addr->address + 0xc00000, 0x1000); - bp->io_base_phys = addr->address; - bp->io_base = (void *) ioremap(addr->address, 0x10000); + setup_grackle(hose, 0x20000); + disp_name = "Grackle (MPC106)"; + } else if (strcmp(dev->name, "bandit") == 0) { + setup_bandit(hose, addr); + disp_name = "Bandit"; + } else if (strcmp(dev->name, "chaos") == 0) { + setup_chaos(hose, addr); + disp_name = "Chaos"; } + printk(KERN_INFO "Found %s PCI host bridge at 0x%08x. Firmware bus number: %d->%d\n", + disp_name, addr->address, hose->first_busno, hose->last_busno); +#ifdef DEBUG + printk(" ->Hose at 0x%08lx, cfg_addr=0x%08lx,cfg_data=0x%08lx\n", + hose, hose->cfg_addr, hose->cfg_data); +#endif + + /* Setup a default isa_io_base */ if (isa_io_base == 0) - isa_io_base = (unsigned long) bp->io_base; - bp->bus_number = bus_range[0]; - bp->max_bus = bus_range[1]; - bp->next = bridge_list; - bp->node = dev; - bridge_list = bp; - if (bp->max_bus > max_bus) - max_bus = bp->max_bus; - - if (strcmp(dev->name, "bandit") == 0) - init_bandit(bp); - } -} - -/* Recursively searches any node that is of type PCI-PCI bridge. Without - * this, the old code would miss children of P2P bridges and hence not - * fix IRQ's for cards located behind P2P bridges. - * - Ranjit Deshpande, 01/20/99 - */ -void __init -fix_intr(struct device_node *node, struct pci_dev *dev) -{ - unsigned int *reg, *class_code; + isa_io_base = (unsigned long)hose->io_base_virt; - for (; node != 0;node = node->sibling) { - class_code = (unsigned int *) get_property(node, "class-code", 0); - if(class_code && (*class_code >> 8) == PCI_CLASS_BRIDGE_PCI) - fix_intr(node->child, dev); - reg = (unsigned int *) get_property(node, "reg", 0); - if (reg == 0 || ((reg[0] >> 8) & 0xff) != dev->devfn) - continue; - /* this is the node, see if it has interrupts */ - if (node->n_intrs > 0) - dev->irq = node->intrs[0].line; - break; + /* Fixup "bus-range" OF property */ + fixup_bus_range(dev); } } -void __init -pmac_pcibios_fixup(void) -{ - struct pci_dev *dev; +static void +pcibios_fixup_OF_interrupts(void) +{ + struct pci_dev* dev; /* * FIXME: This is broken: We should not assign IRQ's to IRQless @@ -757,44 +516,43 @@ pmac_pcibios_fixup(void) * should find the device node and se if it has an * AAPL,interrupts property. */ - struct bridge_data *bp = bridges[dev->bus->number]; unsigned char pin; + struct device_node* node; - if (pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin) || - !pin) + if (pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin) || !pin) continue; /* No interrupt generated -> no fixup */ - /* We iterate all instances of uninorth for now */ - if (uninorth_count && dev->bus->number == 0) { - int i; - for (i=0;i<uninorth_count;i++) - fix_intr(uninorth_bridges[i].node->child, dev); - } else - fix_intr(bp->node->child, dev); + node = pci_device_to_OF_node(dev); + if (!node) { + printk("No OF node for device %x:%x\n", dev->bus->number, dev->devfn >> 3); + continue; + } + /* this is the node, see if it has interrupts */ + if (node->n_intrs > 0) + dev->irq = node->intrs[0].line; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); } } void __init -pmac_setup_pci_ptrs(void) +pmac_pcibios_fixup(void) { - struct device_node* np; + /* Fixup interrupts according to OF tree */ + pcibios_fixup_OF_interrupts(); +} - np = find_devices("pci"); - if (np != 0) - { - if (device_is_compatible(np, "uni-north")) - { - /* looks like an Core99 powermac */ - set_config_access_method(uni); - } else - { - /* looks like a G3 powermac */ - set_config_access_method(grackle); - } - } else - { - set_config_access_method(pmac); +/* We don't want to enable USB controllers absent from the OF tree + * (iBook second controller) + */ +int +pmac_pci_enable_device_hook(struct pci_dev *dev, int initial) +{ + if (dev->vendor == PCI_VENDOR_ID_APPLE + && dev->device == PCI_DEVICE_ID_APPLE_KL_USB) { + struct device_node* node; + node = pci_device_to_OF_node(dev); + if (!node) + return -EINVAL; } - - ppc_md.pcibios_fixup = pmac_pcibios_fixup; + return 0; } diff --git a/arch/ppc/kernel/pmac_pic.c b/arch/ppc/kernel/pmac_pic.c index efd767482..a9a1777ca 100644 --- a/arch/ppc/kernel/pmac_pic.c +++ b/arch/ppc/kernel/pmac_pic.c @@ -4,14 +4,15 @@ #include <linux/sched.h> #include <linux/signal.h> #include <linux/pci.h> -#include <linux/openpic.h> #include <asm/init.h> #include <asm/io.h> #include <asm/smp.h> #include <asm/prom.h> #include <asm/pci-bridge.h> + #include "pmac_pic.h" +#include "open_pic.h" /* pmac */struct pmac_irq_hw { unsigned int flag; @@ -30,16 +31,14 @@ static volatile struct pmac_irq_hw *pmac_irq_hw[4] = { static int max_irqs; static int max_real_irqs; -static int has_openpic = 0; +static int pmac_has_openpic; + +spinlock_t pmac_pic_lock = SPIN_LOCK_UNLOCKED; + #define GATWICK_IRQ_POOL_SIZE 10 static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; -extern int pmac_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val); -extern int pmac_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val); - /* * Mark an irq as "lost". This is only used on the pmac * since it can lose interrupts (see pmac_set_irq_mask). @@ -51,48 +50,11 @@ void __pmac __no_use_set_lost(unsigned long irq_nr) atomic_inc(&ppc_n_lost_interrupts); } -static void pmac_openpic_mask_irq(unsigned int irq_nr) -{ - openpic_disable_irq(irq_nr); -} - -static void pmac_openpic_unmask_irq(unsigned int irq_nr) -{ - openpic_enable_irq(irq_nr); -} - -static void pmac_openpic_ack_irq(unsigned int irq_nr) -{ - if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0) - openpic_eoi(smp_processor_id()); - openpic_disable_irq(irq_nr); -} - -static void pmac_openpic_end_irq(unsigned int irq_nr) -{ - if ((irq_desc[irq_nr].status & IRQ_LEVEL) != 0) - openpic_eoi(smp_processor_id()); - openpic_enable_irq(irq_nr); -} - -struct hw_interrupt_type pmac_open_pic = { - " OpenPIC ", - NULL, - NULL, - pmac_openpic_unmask_irq, - pmac_openpic_mask_irq, - /* Theorically, the mask&ack should be NULL for OpenPIC. However, doing - * so shows tons of bogus interrupts coming in. - */ - pmac_openpic_ack_irq, - pmac_openpic_end_irq, - NULL -}; - static void __pmac pmac_mask_and_ack_irq(unsigned int irq_nr) { unsigned long bit = 1UL << (irq_nr & 0x1f); int i = irq_nr >> 5; + unsigned long flags; if ((unsigned)irq_nr >= max_irqs) return; @@ -100,6 +62,7 @@ static void __pmac pmac_mask_and_ack_irq(unsigned int irq_nr) clear_bit(irq_nr, ppc_cached_irq_mask); if (test_and_clear_bit(irq_nr, ppc_lost_interrupts)) atomic_dec(&ppc_n_lost_interrupts); + spin_lock_irqsave(&pmac_pic_lock, flags); out_le32(&pmac_irq_hw[i]->ack, bit); out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]); out_le32(&pmac_irq_hw[i]->ack, bit); @@ -108,16 +71,19 @@ static void __pmac pmac_mask_and_ack_irq(unsigned int irq_nr) interrupts */ mb(); } while(in_le32(&pmac_irq_hw[i]->flag) & bit); + spin_unlock_irqrestore(&pmac_pic_lock, flags); } static void __pmac pmac_set_irq_mask(unsigned int irq_nr) { unsigned long bit = 1UL << (irq_nr & 0x1f); int i = irq_nr >> 5; + unsigned long flags; if ((unsigned)irq_nr >= max_irqs) return; + spin_lock_irqsave(&pmac_pic_lock, flags); /* enable unmasked interrupts */ out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]); @@ -137,6 +103,7 @@ static void __pmac pmac_set_irq_mask(unsigned int irq_nr) && (ld_le32(&pmac_irq_hw[i]->level) & bit) && !(ld_le32(&pmac_irq_hw[i]->flag) & bit)) __set_lost((ulong)irq_nr); + spin_unlock_irqrestore(&pmac_pic_lock, flags); } static void __pmac pmac_mask_irq(unsigned int irq_nr) @@ -152,6 +119,15 @@ static void __pmac pmac_unmask_irq(unsigned int irq_nr) pmac_set_irq_mask(irq_nr); } +static void __pmac pmac_end_irq(unsigned int irq_nr) +{ + if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + set_bit(irq_nr, ppc_cached_irq_mask); + pmac_set_irq_mask(irq_nr); + } +} + + struct hw_interrupt_type pmac_pic = { " PMAC-PIC ", NULL, @@ -159,7 +135,7 @@ struct hw_interrupt_type pmac_pic = { pmac_unmask_irq, pmac_mask_irq, pmac_mask_and_ack_irq, - pmac_unmask_irq, + pmac_end_irq, NULL }; @@ -170,7 +146,7 @@ struct hw_interrupt_type gatwick_pic = { pmac_unmask_irq, pmac_mask_irq, pmac_mask_and_ack_irq, - pmac_unmask_irq, + pmac_end_irq, NULL }; @@ -204,35 +180,22 @@ pmac_get_irq(struct pt_regs *regs) unsigned long bits = 0; #ifdef CONFIG_SMP - void pmac_smp_message_recv(struct pt_regs *); + void psurge_smp_message_recv(struct pt_regs *); - /* IPI's are a hack on the powersurge -- Cort */ - if ( smp_processor_id() != 0 ) - { - pmac_smp_message_recv(regs); + /* IPI's are a hack on the powersurge -- Cort */ + if ( smp_processor_id() != 0 ) { + psurge_smp_message_recv(regs); return -2; /* ignore, already handled */ } #endif /* CONFIG_SMP */ - - if (has_openpic) { - irq = openpic_irq(smp_processor_id()); - if (irq == OPENPIC_VEC_SPURIOUS) - /* We get those when doing polled ADB requests, - * using -2 is a temp hack to disable the printk - */ - irq = -2; /*-1; */ - } - else - { - for (irq = max_real_irqs; (irq -= 32) >= 0; ) { - int i = irq >> 5; - bits = ld_le32(&pmac_irq_hw[i]->flag) - | ppc_lost_interrupts[i]; - if (bits == 0) - continue; - irq += __ilog2(bits); - break; - } + for (irq = max_real_irqs; (irq -= 32) >= 0; ) { + int i = irq >> 5; + bits = ld_le32(&pmac_irq_hw[i]->flag) + | ppc_lost_interrupts[i]; + if (bits == 0) + continue; + irq += __ilog2(bits); + break; } return irq; @@ -336,11 +299,16 @@ static void __init enable_second_ohare(void) addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40); pmac_irq_hw[1] = (volatile struct pmac_irq_hw *)(addr + 0x20); max_irqs = 64; - if (pci_device_loc(irqctrler, &bus, &devfn) == 0) { - pmac_pcibios_read_config_word(bus, devfn, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - cmd &= ~PCI_COMMAND_IO; - pmac_pcibios_write_config_word(bus, devfn, PCI_COMMAND, cmd); + if (pci_device_from_OF_node(irqctrler, &bus, &devfn) == 0) { + struct pci_controller* hose = pci_find_hose_for_OF_device(irqctrler); + if (!hose) + printk(KERN_ERR "Can't find PCI hose for OHare2 !\n"); + else { + early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + cmd &= ~PCI_COMMAND_IO; + early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd); + } } second_irq = irqctrler->intrs[0].line; @@ -378,20 +346,26 @@ pmac_pic_init(void) printk("PowerMac using OpenPIC irq controller\n"); if (irqctrler->n_addrs > 0) { + int nmi_irq = -1; + unsigned char senses[NR_IRQS]; #ifdef CONFIG_XMON struct device_node* pswitch; -#endif /* CONFIG_XMON */ - OpenPIC = (volatile struct OpenPIC *) - ioremap(irqctrler->addrs[0].address, - irqctrler->addrs[0].size); - for ( i = 0 ; i < NR_IRQS ; i++ ) - irq_desc[i].handler = &pmac_open_pic; - openpic_init(1); - has_openpic = 1; -#ifdef CONFIG_XMON + pswitch = find_devices("programmer-switch"); if (pswitch && pswitch->n_intrs) - request_irq(pswitch->intrs[0].line, xmon_irq, 0, + nmi_irq = pswitch->intrs[0].line; +#endif /* CONFIG_XMON */ + prom_get_irq_senses(senses, 0, NR_IRQS); + OpenPIC_InitSenses = senses; + OpenPIC_NumInitSenses = NR_IRQS; + ppc_md.get_irq = openpic_get_irq; + OpenPIC_Addr = ioremap(irqctrler->addrs[0].address, + irqctrler->addrs[0].size); + openpic_init(1, 0, 0, nmi_irq); + pmac_has_openpic = 1; +#ifdef CONFIG_XMON + if (nmi_irq >= 0) + request_irq(nmi_irq, xmon_irq, 0, "NMI - XMON", 0); #endif /* CONFIG_XMON */ return; diff --git a/arch/ppc/kernel/pmac_setup.c b/arch/ppc/kernel/pmac_setup.c index b5bf03abc..e7be1114e 100644 --- a/arch/ppc/kernel/pmac_setup.c +++ b/arch/ppc/kernel/pmac_setup.c @@ -47,6 +47,7 @@ #include <linux/cuda.h> #include <linux/pmu.h> +#include <asm/processor.h> #include <asm/init.h> #include <asm/prom.h> #include <asm/system.h> @@ -73,7 +74,8 @@ extern unsigned long pmac_get_rtc_time(void); extern int pmac_set_rtc_time(unsigned long nowtime); extern void pmac_read_rtc_time(void); extern void pmac_calibrate_decr(void); -extern void pmac_setup_pci_ptrs(void); +extern void pmac_pcibios_fixup(void); +extern void pmac_find_bridges(void); extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode); extern int mackbd_getkeycode(unsigned int scancode); @@ -99,9 +101,7 @@ extern char pckbd_unexpected_up(unsigned char keycode); extern int keyboard_sends_linux_keycodes; extern void pmac_nvram_update(void); -extern void *pmac_pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical); -extern void *pmac_pci_dev_mem_base(unsigned char bus, unsigned char devfn); -extern int pmac_pci_dev_root_bridge(unsigned char bus, unsigned char devfn); +extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial); unsigned char drive_info; @@ -119,13 +119,34 @@ extern int pmac_newworld; extern void zs_kgdb_hook(int tty_num); static void ohare_init(void); -static void init_p2pbridge(void); #ifdef CONFIG_BOOTX_TEXT void pmac_progress(char *s, unsigned short hex); #endif sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN; +#ifdef CONFIG_SMP +volatile static long int core99_l2_cache; +void core99_init_l2(void) +{ + int cpu = smp_processor_id(); + + if ( (_get_PVR() >> 16) != 8 && (_get_PVR() >> 16) != 12 ) + return; + + if (cpu == 0){ + core99_l2_cache = _get_L2CR(); + printk("CPU0: L2CR is %lx\n", core99_l2_cache); + } else { + printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR()); + _set_L2CR(0); + _set_L2CR(core99_l2_cache); + printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache); + } +} +#endif /* CONFIG_SMP */ + + __pmac int pmac_get_cpuinfo(char *buffer) @@ -250,7 +271,7 @@ pmac_setup_arch(void) struct device_node *cpu; int *fp; - /* Set loops_per_sec to a half-way reasonable value, + /* Set loops_per_jiffy to a half-way reasonable value, for use until calibrate_delay gets called. */ cpu = find_type_devices("cpu"); if (cpu != 0) { @@ -263,13 +284,13 @@ pmac_setup_arch(void) case 10: /* mach V (604ev5) */ case 12: /* G4 */ case 20: /* 620 */ - loops_per_sec = *fp; + loops_per_jiffy = *fp / HZ; break; default: /* 601, 603, etc. */ - loops_per_sec = *fp / 2; + loops_per_jiffy = *fp / (2*HZ); } } else - loops_per_sec = 50000000; + loops_per_jiffy = 50000000 / HZ; } /* this area has the CPU identification register @@ -278,8 +299,8 @@ pmac_setup_arch(void) __ioremap(0xffc00000, 0x400000, pgprot_val(PAGE_READONLY)); ohare_init(); + /* Lookup PCI hosts */ pmac_find_bridges(); - init_p2pbridge(); /* Checks "l2cr-value" property in the registry */ if ( (_get_PVR() >> 16) == 8 || (_get_PVR() >> 16) == 12 ) { @@ -303,6 +324,11 @@ pmac_setup_arch(void) ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000) ? "enabled" : "disabled"); +#ifdef CONFIG_SMP + /* somewhat of a hack */ + core99_init_l2(); +#endif + #ifdef CONFIG_KGDB zs_kgdb_hook(0); #endif @@ -330,32 +356,6 @@ pmac_setup_arch(void) ROOT_DEV = to_kdev_t(DEFAULT_ROOT_DEVICE); } -/* - * Tweak the PCI-PCI bridge chip on the blue & white G3s. - */ -static void __init init_p2pbridge(void) -{ - struct device_node *p2pbridge; - unsigned char bus, devfn; - unsigned short val; - - /* XXX it would be better here to identify the specific - PCI-PCI bridge chip we have. */ - if ((p2pbridge = find_devices("pci-bridge")) == 0 - || p2pbridge->parent == NULL - || strcmp(p2pbridge->parent->name, "pci") != 0) - return; - if (pci_device_loc(p2pbridge, &bus, &devfn) < 0) - return; - if (ppc_md.pcibios_read_config_word(bus, devfn, PCI_BRIDGE_CONTROL, &val) < 0) { - printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n"); - return; - } - val &= ~PCI_BRIDGE_CTL_MASTER_ABORT; - ppc_md.pcibios_write_config_word(bus, devfn, PCI_BRIDGE_CONTROL, val); - ppc_md.pcibios_read_config_word(bus, devfn, PCI_BRIDGE_CONTROL, &val); -} - static void __init ohare_init(void) { /* @@ -448,7 +448,7 @@ kdev_t __init find_ide_boot(void) void __init find_boot_device(void) { -#ifdef CONFIG_SCSI +#if defined(CONFIG_SCSI) && defined(CONFIG_BLK_DEV_SD) if (boot_host != NULL) { boot_dev = sd_find_target(boot_host, boot_target); if (boot_dev != 0) @@ -493,7 +493,9 @@ pmac_restart(char *cmd) struct adb_request req; #endif /* CONFIG_ADB_CUDA */ +#ifdef CONFIG_NVRAM pmac_nvram_update(); +#endif switch (sys_ctrler) { #ifdef CONFIG_ADB_CUDA @@ -509,7 +511,7 @@ pmac_restart(char *cmd) pmu_restart(); break; #endif /* CONFIG_ADB_PMU */ - default: + default: ; } } @@ -520,7 +522,9 @@ pmac_power_off(void) struct adb_request req; #endif /* CONFIG_ADB_CUDA */ +#ifdef CONFIG_NVRAM pmac_nvram_update(); +#endif switch (sys_ctrler) { #ifdef CONFIG_ADB_CUDA @@ -536,7 +540,7 @@ pmac_power_off(void) pmu_shutdown(); break; #endif /* CONFIG_ADB_PMU */ - default: + default: ; } } @@ -566,17 +570,19 @@ pmac_ide_outsw(ide_ioreg_t port, void *buf, int ns) int pmac_ide_default_irq(ide_ioreg_t base) { - return 0; -} - #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) -extern ide_ioreg_t pmac_ide_get_base(int index); + extern int pmac_ide_get_irq(ide_ioreg_t base); + return pmac_ide_get_irq(base); +#else + return 0; #endif +} ide_ioreg_t pmac_ide_default_io_base(int index) { #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) + extern ide_ioreg_t pmac_ide_get_base(int index); return pmac_ide_get_base(index); #else return 0; @@ -586,7 +592,14 @@ pmac_ide_default_io_base(int index) int pmac_ide_check_region(ide_ioreg_t from, unsigned int extent) { - return 0; + /* + * We only do the check_region if `from' looks like a genuine + * I/O port number. If it actually refers to a memory-mapped + * register, it should be OK. + */ + if (from < ~_IO_BASE) + return 0; + return check_region(from, extent); } void @@ -594,24 +607,16 @@ pmac_ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name) { + if (from < ~_IO_BASE) + request_region(from, extent, name); } void pmac_ide_release_region(ide_ioreg_t from, unsigned int extent) { -} - -/* Convert the shorts/longs in hd_driveid from little to big endian; - * chars are endian independant, of course, but strings need to be flipped. - * (Despite what it says in drivers/block/ide.h, they come up as little - * endian...) - * - * Changes to linux/hdreg.h may require changes here. */ -void -pmac_ide_fix_driveid(struct hd_driveid *id) -{ - ppc_generic_ide_fix_driveid(id); + if (from < ~_IO_BASE) + release_region(from, extent); } #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) @@ -632,8 +637,6 @@ void __init pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { - pmac_setup_pci_ptrs(); - /* isa_io_base gets set in pmac_find_bridges */ isa_mem_base = PMAC_ISA_MEM_BASE; pci_dram_offset = PMAC_PCI_DRAM_OFFSET; @@ -646,8 +649,11 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.get_cpuinfo = pmac_get_cpuinfo; ppc_md.irq_cannonicalize = NULL; ppc_md.init_IRQ = pmac_pic_init; - ppc_md.get_irq = pmac_get_irq; + ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */ ppc_md.init = pmac_init2; + + ppc_md.pcibios_fixup = pmac_pcibios_fixup; + ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook; ppc_md.restart = pmac_restart; ppc_md.power_off = pmac_power_off; @@ -658,12 +664,8 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.get_rtc_time = pmac_get_rtc_time; ppc_md.calibrate_decr = pmac_calibrate_decr; - ppc_md.pci_dev_io_base = pmac_pci_dev_io_base; - ppc_md.pci_dev_mem_base = pmac_pci_dev_mem_base; - ppc_md.pci_dev_root_bridge = pmac_pci_dev_root_bridge; - #ifdef CONFIG_VT -#ifdef CONFIG_INPUT_ADBHID +#ifdef CONFIG_INPUT ppc_md.kbd_init_hw = mac_hid_init_hw; ppc_md.kbd_translate = mac_hid_kbd_translate; ppc_md.kbd_unexpected_up = mac_hid_kbd_unexpected_up; @@ -682,35 +684,33 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, } #endif /* CONFIG_MAGIC_SYSRQ */ #elif defined(CONFIG_ADB_KEYBOARD) - ppc_md.kbd_setkeycode = mackbd_setkeycode; - ppc_md.kbd_getkeycode = mackbd_getkeycode; - ppc_md.kbd_translate = mackbd_translate; - ppc_md.kbd_unexpected_up = mackbd_unexpected_up; - ppc_md.kbd_leds = mackbd_leds; - ppc_md.kbd_init_hw = mackbd_init_hw; + ppc_md.kbd_setkeycode = mackbd_setkeycode; + ppc_md.kbd_getkeycode = mackbd_getkeycode; + ppc_md.kbd_translate = mackbd_translate; + ppc_md.kbd_unexpected_up = mackbd_unexpected_up; + ppc_md.kbd_leds = mackbd_leds; + ppc_md.kbd_init_hw = mackbd_init_hw; #ifdef CONFIG_MAGIC_SYSRQ - ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate; + ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate; SYSRQ_KEY = 0x69; #endif /* CONFIG_MAGIC_SYSRQ */ #endif /* CONFIG_INPUT_ADBHID/CONFIG_ADB_KEYBOARD */ #endif /* CONFIG_VT */ #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) - ppc_ide_md.insw = pmac_ide_insw; - ppc_ide_md.outsw = pmac_ide_outsw; - ppc_ide_md.default_irq = pmac_ide_default_irq; - ppc_ide_md.default_io_base = pmac_ide_default_io_base; - ppc_ide_md.ide_check_region = pmac_ide_check_region; - ppc_ide_md.ide_request_region = pmac_ide_request_region; - ppc_ide_md.ide_release_region = pmac_ide_release_region; - ppc_ide_md.fix_driveid = pmac_ide_fix_driveid; - ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports; - - ppc_ide_md.io_base = _IO_BASE; /* actually too early for this :-( */ -#endif + ppc_ide_md.insw = pmac_ide_insw; + ppc_ide_md.outsw = pmac_ide_outsw; + ppc_ide_md.default_irq = pmac_ide_default_irq; + ppc_ide_md.default_io_base = pmac_ide_default_io_base; + ppc_ide_md.ide_check_region = pmac_ide_check_region; + ppc_ide_md.ide_request_region = pmac_ide_request_region; + ppc_ide_md.ide_release_region = pmac_ide_release_region; + ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid; + ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports; +#endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */ #ifdef CONFIG_BOOTX_TEXT ppc_md.progress = pmac_progress; -#endif +#endif /* CONFIG_BOOTX_TEXT */ if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0); } @@ -727,5 +727,5 @@ pmac_progress(char *s, unsigned short hex) prom_drawstring(s); prom_drawchar('\n'); } -#endif CONFIG_BOOTX_TEXT +#endif /* CONFIG_BOOTX_TEXT */ diff --git a/arch/ppc/kernel/pmac_time.c b/arch/ppc/kernel/pmac_time.c index 00b6302a7..46d067e81 100644 --- a/arch/ppc/kernel/pmac_time.c +++ b/arch/ppc/kernel/pmac_time.c @@ -114,7 +114,7 @@ unsigned long pmac_get_rtc_time(void) + (req.reply[3] << 8) + req.reply[4]; return now - RTC_OFFSET; #endif /* CONFIG_ADB_PMU */ - default: + default: ; } return 0; } @@ -135,7 +135,7 @@ int pmac_set_rtc_time(unsigned long nowtime) return 0; while (!req.complete) cuda_poll(); -// if (req.reply_len != 7) + if ((req.reply_len != 3) && (req.reply_len != 7)) printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n", req.reply_len); return 1; diff --git a/arch/ppc/kernel/ppc_asm.h b/arch/ppc/kernel/ppc_asm.h index 42b8c9c39..59c377c4d 100644 --- a/arch/ppc/kernel/ppc_asm.h +++ b/arch/ppc/kernel/ppc_asm.h @@ -50,7 +50,7 @@ */ #define LVX(r,a,b) .long (31<<26)+((r)<<21)+((a)<<16)+((b)<<11)+(103<<1) #define STVX(r,a,b) .long (31<<26)+((r)<<21)+((a)<<16)+((b)<<11)+(231<<1) -#define MFVSCR(r) .long (4<<26)+((r)<<21)+(1540<<1) +#define MFVSCR(r) .long (4<<26)+((r)<<21)+(770<<1) #define MTVSCR(r) .long (4<<26)+((r)<<11)+(802<<1) #define SAVE_VR(n,b,base) li b,THREAD_VR0+(16*(n)); STVX(n,b,base) @@ -66,9 +66,13 @@ #define REST_16VR(n,b,base) REST_8VR(n,b,base); REST_8VR(n+8,b,base) #define REST_32VR(n,b,base) REST_16VR(n,b,base); REST_16VR(n+16,b,base) +#ifdef CONFIG_PPC601_SYNC_FIX #define SYNC \ sync; \ isync +#else +#define SYNC +#endif /* * This instruction is not implemented on the PPC 603 or 601; however, on diff --git a/arch/ppc/kernel/ppc_htab.c b/arch/ppc/kernel/ppc_htab.c index 32f99ce0e..9768f2890 100644 --- a/arch/ppc/kernel/ppc_htab.c +++ b/arch/ppc/kernel/ppc_htab.c @@ -555,10 +555,7 @@ int proc_dol2crvec(ctl_table *table, int write, struct file *filp, break; buffer += len; left -= len; - _set_L2CR(0); _set_L2CR(val); - while ( _get_L2CR() & 0x1 ) - /* wait for invalidate to finish */; } else { p = buf; diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 827e37540..6de2d94fe 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -12,6 +12,7 @@ #include <linux/console.h> #include <linux/irq.h> #include <linux/pci.h> +#include <linux/delay.h> #include <asm/page.h> #include <asm/semaphore.h> @@ -40,6 +41,7 @@ #include <asm/backlight.h> #ifdef CONFIG_SMP #include <asm/smplock.h> +#include <asm/smp.h> #endif /* CONFIG_SMP */ #include <asm/time.h> @@ -53,9 +55,10 @@ extern void MachineCheckException(struct pt_regs *regs); extern void AlignmentException(struct pt_regs *regs); extern void ProgramCheckException(struct pt_regs *regs); extern void SingleStepException(struct pt_regs *regs); -extern int sys_sigreturn(struct pt_regs *regs); extern void do_lost_interrupts(unsigned long); extern int do_signal(sigset_t *, struct pt_regs *); +extern int pmac_newworld; +extern int sys_sigreturn(struct pt_regs *regs); long long __ashrdi3(long long, int); long long __ashldi3(long long, int); @@ -98,10 +101,6 @@ EXPORT_SYMBOL(_prep_type); EXPORT_SYMBOL(ucSystemType); #endif #endif -#ifdef CONFIG_PCI -EXPORT_SYMBOL(pci_dev_io_base); -EXPORT_SYMBOL(pci_dev_mem_base); -#endif #if !__INLINE_BITOPS EXPORT_SYMBOL(set_bit); @@ -125,6 +124,7 @@ EXPORT_SYMBOL(strlen); EXPORT_SYMBOL(strnlen); EXPORT_SYMBOL(strcmp); EXPORT_SYMBOL(strncmp); +EXPORT_SYMBOL(strcasecmp); /* EXPORT_SYMBOL(csum_partial); already in net/netsyms.c */ EXPORT_SYMBOL(csum_partial_copy_generic); @@ -202,6 +202,10 @@ EXPORT_SYMBOL(_read_lock); EXPORT_SYMBOL(_read_unlock); EXPORT_SYMBOL(_write_lock); EXPORT_SYMBOL(_write_unlock); +EXPORT_SYMBOL(smp_call_function); +EXPORT_SYMBOL(smp_hw_index); +EXPORT_SYMBOL(smp_num_cpus); +EXPORT_SYMBOL(synchronize_irq); #endif #ifndef CONFIG_MACH_SPECIFIC @@ -234,12 +238,14 @@ EXPORT_SYMBOL(pmu_enable_irled); #ifdef CONFIG_PMAC_BACKLIGHT EXPORT_SYMBOL(get_backlight_level); EXPORT_SYMBOL(set_backlight_level); +EXPORT_SYMBOL(set_backlight_enable); +EXPORT_SYMBOL(register_backlight_controller); #endif /* CONFIG_PMAC_BACKLIGHT */ -#if defined(CONFIG_ALL_PPC) EXPORT_SYMBOL_NOVERS(sys_ctrler); #ifndef CONFIG_MACH_SPECIFIC EXPORT_SYMBOL_NOVERS(have_of); #endif /* CONFIG_MACH_SPECIFIC */ +#if defined(CONFIG_ALL_PPC) EXPORT_SYMBOL(find_devices); EXPORT_SYMBOL(find_type_devices); EXPORT_SYMBOL(find_compatible_devices); @@ -247,18 +253,29 @@ EXPORT_SYMBOL(find_path_device); EXPORT_SYMBOL(find_phandle); EXPORT_SYMBOL(device_is_compatible); EXPORT_SYMBOL(machine_is_compatible); -EXPORT_SYMBOL(find_pci_device_OFnode); EXPORT_SYMBOL(find_all_nodes); EXPORT_SYMBOL(get_property); -EXPORT_SYMBOL(pci_io_base); -EXPORT_SYMBOL(pci_device_loc); +EXPORT_SYMBOL(pci_bus_io_base); +EXPORT_SYMBOL(pci_bus_io_base_phys); +EXPORT_SYMBOL(pci_bus_mem_base_phys); +EXPORT_SYMBOL(pci_device_to_OF_node); +EXPORT_SYMBOL(pci_device_from_OF_node); +EXPORT_SYMBOL(pci_bus_to_hose); +EXPORT_SYMBOL(pci_resource_to_bus); +EXPORT_SYMBOL(pci_phys_to_bus); +EXPORT_SYMBOL(pci_bus_to_phys); +EXPORT_SYMBOL(pmac_newworld); EXPORT_SYMBOL(feature_set); EXPORT_SYMBOL(feature_clear); EXPORT_SYMBOL(feature_test); EXPORT_SYMBOL(feature_set_gmac_power); +EXPORT_SYMBOL(feature_set_gmac_phy_reset); EXPORT_SYMBOL(feature_set_usb_power); EXPORT_SYMBOL(feature_set_firewire_power); #endif /* defined(CONFIG_ALL_PPC) */ +#if defined(CONFIG_BOOTX_TEXT) +EXPORT_SYMBOL(bootx_update_display); +#endif #if defined(CONFIG_SCSI) && defined(CONFIG_ALL_PPC) EXPORT_SYMBOL(note_scsi_host); #endif @@ -286,6 +303,7 @@ EXPORT_SYMBOL(abs); EXPORT_SYMBOL(screen_info); #endif +EXPORT_SYMBOL(__delay); EXPORT_SYMBOL(int_control); EXPORT_SYMBOL(timer_interrupt_intercept); EXPORT_SYMBOL(timer_interrupt); @@ -300,6 +318,10 @@ EXPORT_SYMBOL(console_lock); #ifdef CONFIG_XMON EXPORT_SYMBOL(xmon); #endif +EXPORT_SYMBOL(__up); +EXPORT_SYMBOL(__down); +EXPORT_SYMBOL(__down_interruptible); +EXPORT_SYMBOL(__down_trylock); EXPORT_SYMBOL(down_read_failed); EXPORT_SYMBOL(down_write_failed); @@ -324,6 +346,12 @@ EXPORT_SYMBOL(do_softirq); EXPORT_SYMBOL(next_mmu_context); EXPORT_SYMBOL(set_context); EXPORT_SYMBOL(mmu_context_overflow); +#if !defined(CONFIG_8xx) && !defined(CONFIG_4xx) +extern long *intercept_table; +EXPORT_SYMBOL(intercept_table); +#endif +extern long *ret_from_intercept; +EXPORT_SYMBOL(ret_from_intercept); #ifdef CONFIG_MOL extern ulong mol_interface[]; diff --git a/arch/ppc/kernel/prep_nvram.c b/arch/ppc/kernel/prep_nvram.c index c3dcdea07..3d34a853f 100644 --- a/arch/ppc/kernel/prep_nvram.c +++ b/arch/ppc/kernel/prep_nvram.c @@ -16,19 +16,9 @@ #include <asm/machdep.h> #include <asm/prep_nvram.h> -/* - * Allow for a maximum of 32K of PReP NvRAM data - */ -#define MAX_PREP_NVRAM 0x8000 static char nvramData[MAX_PREP_NVRAM]; static NVRAM_MAP *nvram=(NVRAM_MAP *)&nvramData[0]; -#define PREP_NVRAM_AS0 0x74 -#define PREP_NVRAM_AS1 0x75 -#define PREP_NVRAM_DATA 0x77 - -unsigned char *rs_pcNvRAM; - unsigned char __prep prep_nvram_read_val(int addr) { outb(addr, PREP_NVRAM_AS0); @@ -44,20 +34,6 @@ void __prep prep_nvram_write_val(int addr, outb(val, PREP_NVRAM_DATA); } -/* - * Most Radstone boards have NvRAM memory mapped at offset 8M in ISA space - */ -unsigned char __prep rs_nvram_read_val(int addr) -{ - return rs_pcNvRAM[addr]; -} - -void __prep rs_nvram_write_val(int addr, - unsigned char val) -{ - rs_pcNvRAM[addr]=val; -} - void __init init_prep_nvram(void) { unsigned char *nvp; @@ -65,16 +41,6 @@ void __init init_prep_nvram(void) int nvramSize; /* - * I'm making the assumption that 32k will always cover the - * nvramsize. If this isn't the case please let me know and we can - * map the header, then get the size from the header, then map - * the whole size. -- Cort - */ - if ( _prep_type == _PREP_Radstone ) - rs_pcNvRAM = (unsigned char *)ioremap(_ISA_MEM_BASE+0x00800000, - 32<<10); - request_region(PREP_NVRAM_AS0, 0x8, "PReP NVRAM"); - /* * The following could fail if the NvRAM were corrupt but * we expect the boot firmware to have checked its checksum * before boot diff --git a/arch/ppc/kernel/prep_pci.c b/arch/ppc/kernel/prep_pci.c index fd14fc483..2f556d83d 100644 --- a/arch/ppc/kernel/prep_pci.c +++ b/arch/ppc/kernel/prep_pci.c @@ -7,11 +7,11 @@ * The motherboard routes/maps will disappear shortly. -- Cort */ +#include <linux/config.h> #include <linux/types.h> #include <linux/pci.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/openpic.h> #include <asm/init.h> #include <asm/byteorder.h> @@ -25,6 +25,7 @@ #include <asm/machdep.h> #include "pci.h" +#include "open_pic.h" #define MAX_DEVNR 22 @@ -39,9 +40,6 @@ unsigned char *Motherboard_routes; /* Used for Motorola to store system config register */ static unsigned long *ProcInfo; -extern int chrp_get_irq(struct pt_regs *); -extern void chrp_post_irq(struct pt_regs* regs, int); - /* Tables for known hardware */ /* Motorola PowerStackII - Utah */ @@ -534,128 +532,45 @@ static char Nobis_pci_IRQ_routes[] __prepdata = { #define CFGPTR(dev) (0x80800000 | (1<<(dev>>3)) | ((dev&7)<<8) | offset) #define DEVNO(dev) (dev>>3) -__prep -int -prep_pcibios_read_config_dword (unsigned char bus, - unsigned char dev, unsigned char offset, unsigned int *val) -{ - unsigned long _val; - unsigned long *ptr; - - if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR)) - { - *val = 0xFFFFFFFF; - return PCIBIOS_DEVICE_NOT_FOUND; - } else - { - ptr = (unsigned long *)CFGPTR(dev); - _val = le32_to_cpu(*ptr); - } - *val = _val; - return PCIBIOS_SUCCESSFUL; -} - -__prep -int -prep_pcibios_read_config_word (unsigned char bus, - unsigned char dev, unsigned char offset, unsigned short *val) -{ - unsigned short _val; - unsigned short *ptr; - - if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR)) - { - *val = 0xFFFF; - return PCIBIOS_DEVICE_NOT_FOUND; - } else - { - ptr = (unsigned short *)CFGPTR(dev); - _val = le16_to_cpu(*ptr); - } - *val = _val; - return PCIBIOS_SUCCESSFUL; -} - -__prep -int -prep_pcibios_read_config_byte (unsigned char bus, - unsigned char dev, unsigned char offset, unsigned char *val) -{ - unsigned char _val; - unsigned char *ptr; - - if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR)) - { - *val = 0xFF; - return PCIBIOS_DEVICE_NOT_FOUND; - } else - { - ptr = (unsigned char *)CFGPTR(dev); - _val = *ptr; - } - *val = _val; - return PCIBIOS_SUCCESSFUL; -} - -__prep -int -prep_pcibios_write_config_dword (unsigned char bus, - unsigned char dev, unsigned char offset, unsigned int val) -{ - unsigned long _val; - unsigned long *ptr; - - _val = le32_to_cpu(val); - if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR)) - { - return PCIBIOS_DEVICE_NOT_FOUND; - } else - { - ptr = (unsigned long *)CFGPTR(dev); - *ptr = _val; - } - return PCIBIOS_SUCCESSFUL; +#define cfg_read(val, addr, type, op) *val = op((type)(addr)) +#define cfg_write(val, addr, type, op) op((type *)(addr), (val)) + +#define cfg_read_bad(val, size) *val = bad_##size; +#define cfg_write_bad(val, size) + +#define bad_byte 0xff +#define bad_word 0xffff +#define bad_dword 0xffffffffU + +#define PREP_PCI_OP(rw, size, type, op) \ +static int __prep \ +prep_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + if ((dev->bus->number != 0) || (DEVNO(dev->devfn) > MAX_DEVNR)) \ + { \ + cfg_##rw##_bad(val, size) \ + return PCIBIOS_DEVICE_NOT_FOUND; \ + } \ + cfg_##rw(val, CFGPTR(dev->devfn), type, op); \ + return PCIBIOS_SUCCESSFUL; \ } -__prep -int -prep_pcibios_write_config_word (unsigned char bus, - unsigned char dev, unsigned char offset, unsigned short val) -{ - unsigned short _val; - unsigned short *ptr; - - _val = le16_to_cpu(val); - if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR)) - { - return PCIBIOS_DEVICE_NOT_FOUND; - } else - { - ptr = (unsigned short *)CFGPTR(dev); - *ptr = _val; - } - return PCIBIOS_SUCCESSFUL; -} +PREP_PCI_OP(read, byte, u8 *, in_8) +PREP_PCI_OP(read, word, u16 *, in_le16) +PREP_PCI_OP(read, dword, u32 *, in_le32) +PREP_PCI_OP(write, byte, u8, out_8) +PREP_PCI_OP(write, word, u16, out_le16) +PREP_PCI_OP(write, dword, u32, out_le32) -__prep -int -prep_pcibios_write_config_byte (unsigned char bus, - unsigned char dev, unsigned char offset, unsigned char val) +static struct pci_ops prep_pci_ops = { - unsigned char _val; - unsigned char *ptr; - - _val = val; - if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR)) - { - return PCIBIOS_DEVICE_NOT_FOUND; - } else - { - ptr = (unsigned char *)CFGPTR(dev); - *ptr = _val; - } - return PCIBIOS_SUCCESSFUL; -} + prep_read_config_byte, + prep_read_config_word, + prep_read_config_dword, + prep_write_config_byte, + prep_write_config_word, + prep_write_config_dword +}; #define MOTOROLA_CPUTYPE_REG 0x800 #define MOTOROLA_BASETYPE_REG 0x803 @@ -685,7 +600,8 @@ static u_char mvme2600_openpic_initsenses[] __initdata = { #define MOT_HAWK_PRESENT 0x2 int prep_keybd_present = 1; -int MotMPIC = 0; +int MotMPIC; +int mot_multi; int __init raven_init(void) { @@ -695,18 +611,18 @@ int __init raven_init(void) /* Check to see if the Raven chip exists. */ if ( _prep_type != _PREP_Motorola) { - OpenPIC = NULL; + OpenPIC_Addr = NULL; return 0; } /* Check to see if this board is a type that might have a Raven. */ if ((inb(MOTOROLA_CPUTYPE_REG) & 0xF0) != 0xE0) { - OpenPIC = NULL; + OpenPIC_Addr = NULL; return 0; } /* Check the first PCI device to see if it is a Raven. */ - pcibios_read_config_dword(0, 0, PCI_VENDOR_ID, &devid); + early_read_config_dword(0, 0, 0, PCI_VENDOR_ID, &devid); switch (devid & 0xffff0000) { case MPIC_RAVEN_ID: @@ -716,33 +632,37 @@ int __init raven_init(void) MotMPIC = MOT_HAWK_PRESENT; break; default: - OpenPIC = NULL; + OpenPIC_Addr = NULL; return 0; } /* Read the memory base register. */ - pcibios_read_config_dword(0, 0, PCI_BASE_ADDRESS_1, &pci_membase); + early_read_config_dword(0, 0, 0, PCI_BASE_ADDRESS_1, &pci_membase); if (pci_membase == 0) { - OpenPIC = NULL; + OpenPIC_Addr = NULL; return 0; } /* Map the Raven MPIC registers to virtual memory. */ - OpenPIC = (struct OpenPIC *)ioremap(pci_membase+0xC0000000, 0x22000); + OpenPIC_Addr = ioremap(pci_membase+0xC0000000, 0x22000); OpenPIC_InitSenses = mvme2600_openpic_initsenses; OpenPIC_NumInitSenses = sizeof(mvme2600_openpic_initsenses); - ppc_md.get_irq = chrp_get_irq; - ppc_md.post_irq = chrp_post_irq; + ppc_md.get_irq = openpic_get_irq; /* If raven is present on Motorola store the system config register * for later use. */ ProcInfo = (unsigned long *)ioremap(0xfef80400, 4); + /* Indicate to system if this is a multiprocessor board */ + if (!(*ProcInfo & MOT_PROC2_BIT)) { + mot_multi = 1; + } + /* This is a hack. If this is a 2300 or 2400 mot board then there is * no keyboard controller and we have to indicate that. */ @@ -898,72 +818,8 @@ unsigned long __init prep_route_pci_interrupts(void) outb(pl_id|CAROLINA_IRQ_EDGE_MASK_HI, 0x04d1); pl_id=inb(0x04d1); /*printk("Hi mask now %#0x\n", pl_id);*/ - } else if ( _prep_type == _PREP_Radstone ) - { - unsigned char ucElcrM, ucElcrS; - - /* - * Set up edge/level - */ - switch(ucSystemType) - { - case RS_SYS_TYPE_PPC1: - { - if(ucBoardRevMaj<5) - { - ucElcrS=ELCRS_INT15_LVL; - } - else - { - ucElcrS=ELCRS_INT9_LVL | - ELCRS_INT11_LVL | - ELCRS_INT14_LVL | - ELCRS_INT15_LVL; - } - ucElcrM=ELCRM_INT5_LVL | ELCRM_INT7_LVL; - break; - } - - case RS_SYS_TYPE_PPC1a: - { - ucElcrS=ELCRS_INT9_LVL | - ELCRS_INT11_LVL | - ELCRS_INT14_LVL | - ELCRS_INT15_LVL; - ucElcrM=ELCRM_INT5_LVL; - break; - } - - case RS_SYS_TYPE_PPC2: - case RS_SYS_TYPE_PPC2a: - case RS_SYS_TYPE_PPC2ep: - case RS_SYS_TYPE_PPC4: - case RS_SYS_TYPE_PPC4a: - default: - { - ucElcrS=ELCRS_INT9_LVL | - ELCRS_INT10_LVL | - ELCRS_INT11_LVL | - ELCRS_INT14_LVL | - ELCRS_INT15_LVL; - ucElcrM=ELCRM_INT5_LVL | - ELCRM_INT7_LVL; - break; - } - } - - /* - * Write edge/level selection - */ - outb(ucElcrS, ISA8259_S_ELCR); - outb(ucElcrM, ISA8259_M_ELCR); - - /* - * Radstone boards have PCI interrupts all set up - * so leave well alone - */ - return 0; - } else + } + else { printk("No known machine pci routing!\n"); return -1; @@ -987,16 +843,10 @@ prep_pcibios_fixup(void) extern unsigned char *Motherboard_routes; unsigned char i; - if ( _prep_type == _PREP_Radstone ) - { - printk("Radstone boards require no PCI fixups\n"); - return; - } - prep_route_pci_interrupts(); printk("Setting PCI interrupts for a \"%s\"\n", Motherboard_map_name); - if (OpenPIC) { + if (OpenPIC_Addr) { /* PCI interrupts are controlled by the OpenPIC */ pci_for_each_dev(dev) { if (dev->bus->number == 0) { @@ -1018,7 +868,12 @@ prep_pcibios_fixup(void) for ( i = 0 ; i <= 5 ; i++ ) { - if ( dev->resource[i].start > 0x10000000 ) + /* + * Relocate PCI I/O resources if necessary so the + * standard 256MB BAT covers them. + */ + if ( (pci_resource_flags(dev, i) & IORESOURCE_IO) && + (dev->resource[i].start > 0x10000000) ) { printk("Relocating PCI address %lx -> %lx\n", dev->resource[i].start, @@ -1029,6 +884,8 @@ prep_pcibios_fixup(void) pci_write_config_dword(dev, PCI_BASE_ADDRESS_0+(i*0x4), dev->resource[i].start ); + dev->resource[i].end = + (dev->resource[i].end & 0x00FFFFFF) | 0x01000000; } } #if 0 @@ -1043,49 +900,50 @@ prep_pcibios_fixup(void) } } -decl_config_access_method(indirect); - void __init -prep_setup_pci_ptrs(void) +prep_find_bridges(void) { - PPC_DEVICE *hostbridge; - - printk("PReP architecture\n"); - if ( _prep_type == _PREP_Radstone ) - { - pci_config_address = (unsigned *)0x80000cf8; - pci_config_data = (char *)0x80000cfc; - set_config_access_method(indirect); - } - else - { - hostbridge = residual_find_device(PROCESSORDEVICE, NULL, - BridgeController, PCIBridge, -1, 0); - if (hostbridge && - hostbridge->DeviceId.Interface == PCIBridgeIndirect) { - PnP_TAG_PACKET * pkt; - set_config_access_method(indirect); - pkt = PnP_find_large_vendor_packet( + struct pci_controller* hose; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + hose->pci_mem_offset = PREP_ISA_MEM_BASE; + + printk("PReP architecture\n"); + { +#ifdef CONFIG_PREP_RESIDUAL + PPC_DEVICE *hostbridge; + + hostbridge = residual_find_device(PROCESSORDEVICE, NULL, + BridgeController, PCIBridge, -1, 0); + if (hostbridge && + hostbridge->DeviceId.Interface == PCIBridgeIndirect) { + PnP_TAG_PACKET * pkt; + pkt = PnP_find_large_vendor_packet( res->DevicePnPHeap+hostbridge->AllocatedOffset, 3, 0); - if(pkt) + if(pkt) { #define p pkt->L4_Pack.L4_Data.L4_PPCPack - pci_config_address= (unsigned *)ld_le32((unsigned *) p.PPCData); - pci_config_data= (unsigned char *)ld_le32((unsigned *) (p.PPCData+8)); - } + setup_indirect_pci(hose, + ld_le32((unsigned *) (p.PPCData)), + ld_le32((unsigned *) (p.PPCData+8))); + } else { - pci_config_address= (unsigned *) 0x80000cf8; - pci_config_data= (unsigned char *) 0x80000cfc; - } - } + setup_indirect_pci(hose, 0x80000cf8, 0x80000cfc); + } + } else +#endif /* CONFIG_PREP_RESIDUAL */ { - set_config_access_method(prep); - } - - } + hose->ops = &prep_pci_ops; + } + } ppc_md.pcibios_fixup = prep_pcibios_fixup; } diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c index 6e30462aa..64ad519cb 100644 --- a/arch/ppc/kernel/prep_setup.c +++ b/arch/ppc/kernel/prep_setup.c @@ -32,7 +32,6 @@ #include <linux/console.h> #include <linux/timex.h> #include <linux/pci.h> -#include <linux/openpic.h> #include <linux/ide.h> #include <asm/init.h> @@ -48,8 +47,9 @@ #include <asm/prep_nvram.h> #include <asm/raven.h> #include <asm/keyboard.h> - +#include <asm/vga.h> #include <asm/time.h> + #include "local_irq.h" #include "i8259.h" #include "open_pic.h" @@ -84,7 +84,7 @@ extern void pckbd_leds(unsigned char leds); extern void pckbd_init_hw(void); extern unsigned char pckbd_sysrq_xlate[128]; -extern void prep_setup_pci_ptrs(void); +extern void prep_find_bridges(void); extern char saved_command_line[256]; int _prep_type; @@ -101,23 +101,23 @@ unsigned long empty_zero_page[1024]; extern PTE *Hash, *Hash_end; extern unsigned long Hash_size, Hash_mask; extern int probingmem; -extern unsigned long loops_per_sec; +extern unsigned long loops_per_jiffy; #ifdef CONFIG_BLK_DEV_RAM extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */ extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */ extern int rd_image_start; /* starting block # of image */ #endif -#ifdef CONFIG_VGA_CONSOLE -unsigned long vgacon_remap_base; -#endif int __prep prep_get_cpuinfo(char *buffer) { extern char *Motherboard_map_name; - int len, i; - + int len; +#ifdef CONFIG_PREP_RESIDUAL + int i; +#endif + #ifdef CONFIG_SMP #define CD(X) (cpu_data[n].X) #else @@ -190,7 +190,10 @@ prep_get_cpuinfo(char *buffer) } -no_l2: +no_l2: +#ifndef CONFIG_PREP_RESIDUAL + return len; +#else if ( res->ResidualLength == 0 ) return len; @@ -205,8 +208,8 @@ no_l2: res->Memories[i].SIMMSize); } len += sprintf(buffer+len,"\n"); - return len; +#endif } void __init @@ -214,11 +217,16 @@ prep_setup_arch(void) { extern char cmd_line[]; unsigned char reg; +#if 0 /* unused?? */ unsigned char ucMothMemType; unsigned char ucEquipPres1; +#endif /* init to some ~sane value until calibrate_delay() runs */ - loops_per_sec = 50000000; + loops_per_jiffy = 50000000; + + /* Lookup PCI host bridges */ + prep_find_bridges(); /* Set up floppy in PS/2 mode */ outb(0x09, SIO_CONFIG_RA); @@ -247,41 +255,6 @@ prep_setup_arch(void) *(unsigned char *)(0x8000081c) |= 3; ROOT_DEV = to_kdev_t(0x0802); /* sda2 */ break; - case _PREP_Radstone: - ROOT_DEV = to_kdev_t(0x0801); /* sda1 */ - - /* - * Determine system type - */ - ucMothMemType=inb(0x866); - ucEquipPres1=inb(0x80c); - - ucSystemType=((ucMothMemType&0x03)<<1) | - ((ucEquipPres1&0x80)>>7); - ucSystemType^=7; - - /* - * Determine board revision for use by - * rev. specific code - */ - ucBoardRev=inb(0x854); - ucBoardRevMaj=ucBoardRev>>5; - ucBoardRevMin=ucBoardRev&0x1f; - - /* - * Most Radstone boards have memory mapped NvRAM - */ - if((ucSystemType==RS_SYS_TYPE_PPC1) && (ucBoardRevMaj<5)) - { - ppc_md.nvram_read_val = prep_nvram_read_val; - ppc_md.nvram_write_val = prep_nvram_write_val; - } - else - { - ppc_md.nvram_read_val = rs_nvram_read_val; - ppc_md.nvram_write_val = rs_nvram_write_val; - } - break; } /* Read in NVRAM data */ @@ -341,12 +314,6 @@ prep_setup_arch(void) #endif /* CONFIG_SOUND_CS4232 */ /*print_residual_device_info();*/ - request_region(0x20,0x20,"pic1"); - request_region(0xa0,0x20,"pic2"); - request_region(0x00,0x20,"dma1"); - request_region(0x40,0x20,"timer"); - request_region(0x80,0x10,"dma page reg"); - request_region(0xc0,0x20,"dma2"); raven_init(); @@ -365,6 +332,7 @@ prep_setup_arch(void) */ void __init prep_res_calibrate_decr(void) { +#ifdef CONFIG_PREP_RESIDUAL unsigned long freq, divisor=4; freq = res->VitalProductData.ProcessorBusHz; @@ -372,6 +340,7 @@ void __init prep_res_calibrate_decr(void) (freq/divisor)/1000000, (freq/divisor)%1000000); tb_ticks_per_jiffy = freq / HZ / divisor; tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); +#endif } /* @@ -585,15 +554,16 @@ prep_setup_residual(char *buffer) { int len = 0; - /* PREP's without residual data will give incorrect values here */ len += sprintf(len+buffer, "clock\t\t: "); +#ifdef CONFIG_PREP_RESIDUAL if ( res->ResidualLength ) len += sprintf(len+buffer, "%ldMHz\n", (res->VitalProductData.ProcessorHz > 1024) ? res->VitalProductData.ProcessorHz>>20 : res->VitalProductData.ProcessorHz); else +#endif /* CONFIG_PREP_RESIDUAL */ len += sprintf(len+buffer, "???\n"); return len; @@ -640,19 +610,11 @@ prep_init_IRQ(void) { int i; - if (OpenPIC != NULL) { - for ( i = 16 ; i < 36 ; i++ ) - irq_desc[i].handler = &open_pic; - openpic_init(1); - } - - for ( i = 0 ; i < 16 ; i++ ) + if (OpenPIC_Addr != NULL) + openpic_init(1, NUM_8259_INTERRUPTS, 0, -1); + for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ ) irq_desc[i].handler = &i8259_pic; - i8259_init(); -#ifdef CONFIG_SMP - request_irq(openpic_to_irq(OPENPIC_VEC_SPURIOUS), openpic_ipi_action, - 0, "IPI0", 0); -#endif /* CONFIG_SMP */ + i8259_init(); } #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) @@ -708,19 +670,14 @@ prep_ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name) { - request_region(from, extent, name); + request_region(from, extent, name); } void __prep prep_ide_release_region(ide_ioreg_t from, unsigned int extent) { - release_region(from, extent); -} - -void __prep -prep_ide_fix_driveid(struct hd_driveid *id) -{ + release_region(from, extent); } void __init @@ -743,17 +700,52 @@ prep_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl } #endif +unsigned long *MotSave_SmpIar; +unsigned char *MotSave_CpusState[2]; + +void __init +prep_init2(void) +{ +#ifdef CONFIG_NVRAM + request_region(PREP_NVRAM_AS0, 0x8, "nvram"); +#endif + request_region(0x20,0x20,"pic1"); + request_region(0xa0,0x20,"pic2"); + request_region(0x00,0x20,"dma1"); + request_region(0x40,0x20,"timer"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xc0,0x20,"dma2"); +} + void __init prep_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { +#ifdef CONFIG_PREP_RESIDUAL + RESIDUAL *old_res = (RESIDUAL *)(r3 + KERNELBASE); + /* make a copy of residual data */ if ( r3 ) { memcpy((void *)res,(void *)(r3+KERNELBASE), sizeof(RESIDUAL)); + + /* These need to be saved for the Motorola Prep + * MVME4600 and Dual MTX boards. + */ + MotSave_SmpIar = &old_res->VitalProductData.SmpIar; + MotSave_CpusState[0] = &old_res->Cpus[0].CpuState; + MotSave_CpusState[1] = &old_res->Cpus[1].CpuState; } +#endif + /* Copy cmd_line parameters */ + if ( r6) + { + *(char *)(r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *)(r6 + KERNELBASE)); + } + isa_io_base = PREP_ISA_IO_BASE; isa_mem_base = PREP_ISA_MEM_BASE; pci_dram_offset = PREP_PCI_DRAM_OFFSET; @@ -762,29 +754,19 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5, DMA_MODE_WRITE = 0x48; /* figure out what kind of prep workstation we are */ +#ifdef CONFIG_PREP_RESIDUAL if ( res->ResidualLength != 0 ) { if ( !strncmp(res->VitalProductData.PrintableModel,"IBM",3) ) _prep_type = _PREP_IBM; - else if (!strncmp(res->VitalProductData.PrintableModel, - "Radstone",8)) - { - extern char *Motherboard_map_name; - - _prep_type = _PREP_Radstone; - Motherboard_map_name= - res->VitalProductData.PrintableModel; - } - else - _prep_type = _PREP_Motorola; + _prep_type = _PREP_Motorola; } else /* assume motorola if no residual (netboot?) */ +#endif { _prep_type = _PREP_Motorola; } - prep_setup_pci_ptrs(); - ppc_md.setup_arch = prep_setup_arch; ppc_md.setup_residual = prep_setup_residual; ppc_md.get_cpuinfo = prep_get_cpuinfo; @@ -792,40 +774,14 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.init_IRQ = prep_init_IRQ; /* this gets changed later on if we have an OpenPIC -- Cort */ ppc_md.get_irq = prep_get_irq; - ppc_md.init = NULL; + ppc_md.init = prep_init2; ppc_md.restart = prep_restart; ppc_md.power_off = prep_power_off; ppc_md.halt = prep_halt; ppc_md.time_init = NULL; - if (_prep_type == _PREP_Radstone) { - /* - * We require a direct restart as port 92 does not work on - * all Radstone boards - */ - ppc_md.restart = prep_direct_restart; - /* - * The RTC device used varies according to board type - */ - if(((ucSystemType==RS_SYS_TYPE_PPC1) && (ucBoardRevMaj>=5)) || - (ucSystemType==RS_SYS_TYPE_PPC1a)) - { - ppc_md.set_rtc_time = mk48t59_set_rtc_time; - ppc_md.get_rtc_time = mk48t59_get_rtc_time; - ppc_md.time_init = mk48t59_init; - } - else - { - ppc_md.set_rtc_time = mc146818_set_rtc_time; - ppc_md.get_rtc_time = mc146818_get_rtc_time; - } - /* - * Determine the decrementer rate from the residual data - */ - ppc_md.calibrate_decr = prep_res_calibrate_decr; - } - else if (_prep_type == _PREP_IBM) { + if (_prep_type == _PREP_IBM) { ppc_md.set_rtc_time = mc146818_set_rtc_time; ppc_md.get_rtc_time = mc146818_get_rtc_time; ppc_md.calibrate_decr = prep_calibrate_decr; @@ -845,7 +801,7 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_ide_md.ide_check_region = prep_ide_check_region; ppc_ide_md.ide_request_region = prep_ide_request_region; ppc_ide_md.ide_release_region = prep_ide_release_region; - ppc_ide_md.fix_driveid = prep_ide_fix_driveid; + ppc_ide_md.fix_driveid = NULL; ppc_ide_md.ide_init_hwif = prep_ide_init_hwif_ports; #endif ppc_ide_md.io_base = _IO_BASE; diff --git a/arch/ppc/kernel/proc_rtas.c b/arch/ppc/kernel/proc_rtas.c new file mode 100644 index 000000000..2e8144204 --- /dev/null +++ b/arch/ppc/kernel/proc_rtas.c @@ -0,0 +1,784 @@ +/* + * arch/ppc/kernel/proc_rtas.c + * Copyright (C) 2000 Tilmann Bitterberg + * (tilmann@bitterberg.de) + * + * RTAS (Runtime Abstraction Services) stuff + * Intention is to provide a clean user interface + * to use the RTAS. + * + * TODO: + * Split off a header file and maybe move it to a different + * location. Write Documentation on what the /proc/rtas/ entries + * actually do. + */ + +#include <linux/errno.h> +#include <linux/sched.h> +#include <linux/proc_fs.h> +#include <linux/stat.h> +#include <linux/ctype.h> +#include <linux/time.h> +#include <linux/string.h> + +#include <asm/uaccess.h> +#include <asm/bitops.h> +#include <asm/processor.h> +#include <asm/io.h> +#include <asm/prom.h> +#include <asm/machdep.h> /* for ppc_md */ +#include <asm/time.h> + +/* Token for Sensors */ +#define KEY_SWITCH 0x0001 +#define ENCLOSURE_SWITCH 0x0002 +#define THERMAL_SENSOR 0x0003 +#define LID_STATUS 0x0004 +#define POWER_SOURCE 0x0005 +#define BATTERY_VOLTAGE 0x0006 +#define BATTERY_REMAINING 0x0007 +#define BATTERY_PERCENTAGE 0x0008 +#define EPOW_SENSOR 0x0009 +#define BATTERY_CYCLESTATE 0x000a +#define BATTERY_CHARGING 0x000b + +/* IBM specific sensors */ +#define IBM_SURVEILLANCE 0x2328 /* 9000 */ +#define IBM_FANRPM 0x2329 /* 9001 */ +#define IBM_VOLTAGE 0x232a /* 9002 */ +#define IBM_DRCONNECTOR 0x232b /* 9003 */ +#define IBM_POWERSUPPLY 0x232c /* 9004 */ +#define IBM_INTQUEUE 0x232d /* 9005 */ + +/* Status return values */ +#define SENSOR_CRITICAL_HIGH 13 +#define SENSOR_WARNING_HIGH 12 +#define SENSOR_NORMAL 11 +#define SENSOR_WARNING_LOW 10 +#define SENSOR_CRITICAL_LOW 9 +#define SENSOR_SUCCESS 0 +#define SENSOR_HW_ERROR -1 +#define SENSOR_BUSY -2 +#define SENSOR_NOT_EXIST -3 +#define SENSOR_DR_ENTITY -9000 + +/* Location Codes */ +#define LOC_SCSI_DEV_ADDR 'A' +#define LOC_SCSI_DEV_LOC 'B' +#define LOC_CPU 'C' +#define LOC_DISKETTE 'D' +#define LOC_ETHERNET 'E' +#define LOC_FAN 'F' +#define LOC_GRAPHICS 'G' +/* reserved / not used 'H' */ +#define LOC_IO_ADAPTER 'I' +/* reserved / not used 'J' */ +#define LOC_KEYBOARD 'K' +#define LOC_LCD 'L' +#define LOC_MEMORY 'M' +#define LOC_NV_MEMORY 'N' +#define LOC_MOUSE 'O' +#define LOC_PLANAR 'P' +#define LOC_OTHER_IO 'Q' +#define LOC_PARALLEL 'R' +#define LOC_SERIAL 'S' +#define LOC_DEAD_RING 'T' +#define LOC_RACKMOUNTED 'U' /* for _u_nit is rack mounted */ +#define LOC_VOLTAGE 'V' +#define LOC_SWITCH_ADAPTER 'W' +#define LOC_OTHER 'X' +#define LOC_FIRMWARE 'Y' +#define LOC_SCSI 'Z' + +/* Tokens for indicators */ +#define TONE_FREQUENCY 0x0001 /* 0 - 1000 (HZ)*/ +#define TONE_VOLUME 0x0002 /* 0 - 100 (%) */ +#define SYSTEM_POWER_STATE 0x0003 +#define WARNING_LIGHT 0x0004 +#define DISK_ACTIVITY_LIGHT 0x0005 +#define HEX_DISPLAY_UNIT 0x0006 +#define BATTERY_WARNING_TIME 0x0007 +#define CONDITION_CYCLE_REQUEST 0x0008 +#define SURVEILLANCE_INDICATOR 0x2328 /* 9000 */ +#define DR_ACTION 0x2329 /* 9001 */ +#define DR_INDICATOR 0x232a /* 9002 */ +/* 9003 - 9004: Vendor specific */ +#define GLOBAL_INTERRUPT_QUEUE 0x232d /* 9005 */ +/* 9006 - 9999: Vendor specific */ + +/* other */ +#define MAX_SENSORS 17 /* I only know of 17 sensors */ +#define MAX_LINELENGTH 256 +#define SENSOR_PREFIX "ibm,sensor-" +#define cel_to_fahr(x) ((x*9/5)+32) + + +/* Globals */ +static struct proc_dir_entry *proc_rtas; +static struct rtas_sensors sensors; +static struct device_node *rtas; +static unsigned long power_on_time = 0; /* Save the time the user set */ +static char progress_led[MAX_LINELENGTH]; + +static unsigned long rtas_tone_frequency = 1000; +static unsigned long rtas_tone_volume = 0; + +/* ****************STRUCTS******************************************* */ +struct individual_sensor { + unsigned int token; + unsigned int quant; +}; + +struct rtas_sensors { + struct individual_sensor sensor[MAX_SENSORS]; + unsigned int quant; +}; + +/* ****************************************************************** */ +/* Declarations */ +static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off, + int count, int *eof, void *data); +static ssize_t ppc_rtas_clock_read(struct file * file, char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_progress_read(struct file * file, char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_progress_write(struct file * file, const char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf, + size_t count, loff_t *ppos); + +static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf, + size_t count, loff_t *ppos); + +struct file_operations ppc_rtas_poweron_operations = { + read: ppc_rtas_poweron_read, + write: ppc_rtas_poweron_write +}; +struct file_operations ppc_rtas_progress_operations = { + read: ppc_rtas_progress_read, + write: ppc_rtas_progress_write +}; + +struct file_operations ppc_rtas_clock_operations = { + read: ppc_rtas_clock_read, + write: ppc_rtas_clock_write +}; + +struct file_operations ppc_rtas_tone_freq_operations = { + read: ppc_rtas_tone_freq_read, + write: ppc_rtas_tone_freq_write +}; +struct file_operations ppc_rtas_tone_volume_operations = { + read: ppc_rtas_tone_volume_read, + write: ppc_rtas_tone_volume_write +}; + +int ppc_rtas_find_all_sensors (void); +int ppc_rtas_process_sensor(struct individual_sensor s, int state, + int error, char * buf); +char * ppc_rtas_process_error(int error); +int get_location_code(struct individual_sensor s, char * buf); +int check_location_string (char *c, char * buf); +int check_location (char *c, int idx, char * buf); + +/* ****************************************************************** */ +/* MAIN */ +/* ****************************************************************** */ +void proc_rtas_init(void) +{ + struct proc_dir_entry *entry; + + rtas = find_devices("rtas"); + if ((rtas == 0) || (_machine != _MACH_chrp)) { + return; + } + + proc_rtas = proc_mkdir("rtas", 0); + if (proc_rtas == 0) + return; + + /* /proc/rtas entries */ + + entry = create_proc_entry("progress", S_IRUGO|S_IWUSR, proc_rtas); + if (entry) entry->proc_fops = &ppc_rtas_progress_operations; + + entry = create_proc_entry("clock", S_IRUGO|S_IWUSR, proc_rtas); + if (entry) entry->proc_fops = &ppc_rtas_clock_operations; + + entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, proc_rtas); + if (entry) entry->proc_fops = &ppc_rtas_poweron_operations; + + create_proc_read_entry("sensors", S_IRUGO, proc_rtas, + ppc_rtas_sensor_read, NULL); + + entry = create_proc_entry("frequency", S_IWUSR|S_IRUGO, proc_rtas); + if (entry) entry->proc_fops = &ppc_rtas_tone_freq_operations; + + entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, proc_rtas); + if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations; +} + +/* ****************************************************************** */ +/* POWER-ON-TIME */ +/* ****************************************************************** */ +static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + struct rtc_time tm; + unsigned long nowtime; + char *dest; + int error; + + nowtime = simple_strtoul(buf, &dest, 10); + if (*dest != '\0' && *dest != '\n') { + printk("ppc_rtas_poweron_write: Invalid time\n"); + return count; + } + power_on_time = nowtime; /* save the time */ + + to_tm(nowtime, &tm); + + error = call_rtas("set-time-for-power-on", 7, 1, NULL, + tm.tm_year, tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec, 0 /* nano */); + if (error != 0) + printk(KERN_WARNING "error: setting poweron time returned: %s\n", + ppc_rtas_process_error(error)); + return count; +} +/* ****************************************************************** */ +static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + int n; + if (power_on_time == 0) + n = sprintf(buf, "Power on time not set\n"); + else + n = sprintf(buf, "%lu\n", power_on_time); + + if (*ppos >= strlen(buf)) + return 0; + if (n > strlen(buf) - *ppos) + n = strlen(buf) - *ppos; + if (n > count) + n = count; + *ppos += n; + return n; +} + +/* ****************************************************************** */ +/* PROGRESS */ +/* ****************************************************************** */ +static ssize_t ppc_rtas_progress_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + unsigned long hex; + + strcpy(progress_led, buf); /* save the string */ + /* Lets see if the user passed hexdigits */ + hex = simple_strtoul(buf, NULL, 10); + + ppc_md.progress ((char *)buf, hex); + return count; + + /* clear the line */ /* ppc_md.progress(" ", 0xffff);*/ +} +/* ****************************************************************** */ +static ssize_t ppc_rtas_progress_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + int n = 0; + if (progress_led != NULL) + n = sprintf (buf, "%s\n", progress_led); + if (*ppos >= strlen(buf)) + return 0; + if (n > strlen(buf) - *ppos) + n = strlen(buf) - *ppos; + if (n > count) + n = count; + *ppos += n; + return n; +} + +/* ****************************************************************** */ +/* CLOCK */ +/* ****************************************************************** */ +static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + struct rtc_time tm; + unsigned long nowtime; + char *dest; + int error; + + nowtime = simple_strtoul(buf, &dest, 10); + if (*dest != '\0' && *dest != '\n') { + printk("ppc_rtas_clock_write: Invalid time\n"); + return count; + } + + to_tm(nowtime, &tm); + error = call_rtas("set-time-of-day", 7, 1, NULL, + tm.tm_year, tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec, 0); + if (error != 0) + printk(KERN_WARNING "error: setting the clock returned: %s\n", + ppc_rtas_process_error(error)); + return count; +} +/* ****************************************************************** */ +static ssize_t ppc_rtas_clock_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + unsigned int year, mon, day, hour, min, sec; + unsigned long *ret = kmalloc(4*8, GFP_KERNEL); + int n, error; + + error = call_rtas("get-time-of-day", 0, 8, ret); + + year = ret[0]; mon = ret[1]; day = ret[2]; + hour = ret[3]; min = ret[4]; sec = ret[5]; + + if (error != 0){ + printk(KERN_WARNING "error: reading the clock returned: %s\n", + ppc_rtas_process_error(error)); + n = sprintf (buf, "0"); + } else { + n = sprintf (buf, "%lu\n", mktime(year, mon, day, hour, min, sec)); + } + kfree(ret); + + if (*ppos >= strlen(buf)) + return 0; + if (n > strlen(buf) - *ppos) + n = strlen(buf) - *ppos; + if (n > count) + n = count; + *ppos += n; + return n; +} + +/* ****************************************************************** */ +/* SENSOR STUFF */ +/* ****************************************************************** */ +static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off, + int count, int *eof, void *data) +{ + int i,j,n; + unsigned long ret; + int state, error; + char buffer[MAX_LINELENGTH*MAX_SENSORS]; /* May not be enough */ + + if (count < 0) + return -EINVAL; + + n = sprintf ( buffer , "RTAS (RunTime Abstraction Services) Sensor Information\n"); + n += sprintf ( buffer+n, "Sensor\t\tValue\t\tCondition\tLocation\n"); + n += sprintf ( buffer+n, "********************************************************\n"); + + if (ppc_rtas_find_all_sensors() != 0) { + n += sprintf ( buffer+n, "\nNo sensors are available\n"); + goto return_string; + } + + for (i=0; i<sensors.quant; i++) { + j = sensors.sensor[i].quant; + /* A sensor may have multiple instances */ + while (j >= 0) { + error = call_rtas("get-sensor-state", 2, 2, &ret, + sensors.sensor[i].token, sensors.sensor[i].quant-j); + state = (int) ret; + n += ppc_rtas_process_sensor(sensors.sensor[i], state, error, buffer+n ); + n += sprintf (buffer+n, "\n"); + j--; + } /* while */ + } /* for */ + +return_string: + if (off >= strlen(buffer)) { + *eof = 1; + return 0; + } + if (n > strlen(buffer) - off) + n = strlen(buffer) - off; + if (n > count) + n = count; + else + *eof = 1; + memcpy(buf, buffer + off, n); + *start = buf; + return n; +} + +/* ****************************************************************** */ + +int ppc_rtas_find_all_sensors (void) +{ + unsigned long *utmp; + int len, i, j; + + utmp = (unsigned long *) get_property(rtas, "rtas-sensors", &len); + if (utmp == NULL) { + printk (KERN_ERR "error: could not get rtas-sensors\n"); + return 1; + } + + sensors.quant = len / 8; /* int + int */ + + for (i=0, j=0; j<sensors.quant; i+=2, j++) { + sensors.sensor[j].token = utmp[i]; + sensors.sensor[j].quant = utmp[i+1]; + } + return 0; +} + +/* ****************************************************************** */ +/* + * Builds a string of what rtas returned + */ +char * ppc_rtas_process_error(int error) +{ + switch (error) { + case SENSOR_CRITICAL_HIGH: + return "(critical high)"; + case SENSOR_WARNING_HIGH: + return "(warning high)"; + case SENSOR_NORMAL: + return "(normal)"; + case SENSOR_WARNING_LOW: + return "(warning low)"; + case SENSOR_CRITICAL_LOW: + return "(critical low)"; + case SENSOR_SUCCESS: + return "(read ok)"; + case SENSOR_HW_ERROR: + return "(hardware error)"; + case SENSOR_BUSY: + return "(busy)"; + case SENSOR_NOT_EXIST: + return "(non existant)"; + case SENSOR_DR_ENTITY: + return "(dr entity removed)"; + default: + return "(UNKNOWN)"; + } +} + +/* ****************************************************************** */ +/* + * Builds a string out of what the sensor said + */ + +int ppc_rtas_process_sensor(struct individual_sensor s, int state, + int error, char * buf) +{ + /* Defined return vales */ + const char * key_switch[] = { "Off\t", "Normal\t", "Secure\t", "Mainenance" }; + const char * enclosure_switch[] = { "Closed", "Open" }; + const char * lid_status[] = { " ", "Open", "Closed" }; + const char * power_source[] = { "AC\t", "Battery", "AC & Battery" }; + const char * battery_remaining[] = { "Very Low", "Low", "Mid", "High" }; + const char * epow_sensor[] = { + "EPOW Reset", "Cooling warning", "Power warning", + "System shutdown", "System halt", "EPOW main enclosure", + "EPOW power off" }; + const char * battery_cyclestate[] = { "None", "In progress", "Requested" }; + const char * battery_charging[] = { "Charging", "Discharching", "No current flow" }; + const char * ibm_drconnector[] = { "Empty", "Present" }; + const char * ibm_intqueue[] = { "Disabled", "Enabled" }; + + int have_strings = 0; + int temperature = 0; + int unknown = 0; + int n = 0; + + /* What kind of sensor do we have here? */ + switch (s.token) { + case KEY_SWITCH: + n += sprintf(buf+n, "Key switch:\t"); + n += sprintf(buf+n, "%s\t", key_switch[state]); + have_strings = 1; + break; + case ENCLOSURE_SWITCH: + n += sprintf(buf+n, "Enclosure switch:\t"); + n += sprintf(buf+n, "%s\t", enclosure_switch[state]); + have_strings = 1; + break; + case THERMAL_SENSOR: + n += sprintf(buf+n, "Temp. (°C/°F):\t"); + temperature = 1; + break; + case LID_STATUS: + n += sprintf(buf+n, "Lid status:\t"); + n += sprintf(buf+n, "%s\t", lid_status[state]); + have_strings = 1; + break; + case POWER_SOURCE: + n += sprintf(buf+n, "Power source:\t"); + n += sprintf(buf+n, "%s\t", power_source[state]); + have_strings = 1; + break; + case BATTERY_VOLTAGE: + n += sprintf(buf+n, "Battery voltage:\t"); + break; + case BATTERY_REMAINING: + n += sprintf(buf+n, "Battery remaining:\t"); + n += sprintf(buf+n, "%s\t", battery_remaining[state]); + have_strings = 1; + break; + case BATTERY_PERCENTAGE: + n += sprintf(buf+n, "Battery percentage:\t"); + break; + case EPOW_SENSOR: + n += sprintf(buf+n, "EPOW Sensor:\t"); + n += sprintf(buf+n, "%s\t", epow_sensor[state]); + have_strings = 1; + break; + case BATTERY_CYCLESTATE: + n += sprintf(buf+n, "Battery cyclestate:\t"); + n += sprintf(buf+n, "%s\t", battery_cyclestate[state]); + have_strings = 1; + break; + case BATTERY_CHARGING: + n += sprintf(buf+n, "Battery Charging:\t"); + n += sprintf(buf+n, "%s\t", battery_charging[state]); + have_strings = 1; + break; + case IBM_SURVEILLANCE: + n += sprintf(buf+n, "Surveillance:\t"); + break; + case IBM_FANRPM: + n += sprintf(buf+n, "Fan (rpm):\t"); + break; + case IBM_VOLTAGE: + n += sprintf(buf+n, "Voltage (mv):\t"); + break; + case IBM_DRCONNECTOR: + n += sprintf(buf+n, "DR connector:\t"); + n += sprintf(buf+n, "%s\t", ibm_drconnector[state]); + have_strings = 1; + break; + case IBM_POWERSUPPLY: + n += sprintf(buf+n, "Powersupply:\t"); + break; + case IBM_INTQUEUE: + n += sprintf(buf+n, "Interrupt queue:\t"); + n += sprintf(buf+n, "%s\t", ibm_intqueue[state]); + have_strings = 1; + break; + default: + n += sprintf(buf+n, "Unkown sensor (type %d), ignoring it\n", + s.token); + unknown = 1; + have_strings = 1; + break; + } + if (have_strings == 0) { + if (temperature) { + n += sprintf(buf+n, "%4d /%4d\t", state, cel_to_fahr(state)); + } else + n += sprintf(buf+n, "%10d\t", state); + } + if (unknown == 0) { + n += sprintf ( buf+n, "%s\t", ppc_rtas_process_error(error)); + n += get_location_code(s, buf+n); + } + return n; +} + +/* ****************************************************************** */ + +int check_location (char *c, int idx, char * buf) +{ + int n = 0; + + switch (*(c+idx)) { + case LOC_PLANAR: + n += sprintf ( buf, "Planar #%c", *(c+idx+1)); + break; + case LOC_CPU: + n += sprintf ( buf, "CPU #%c", *(c+idx+1)); + break; + case LOC_FAN: + n += sprintf ( buf, "Fan #%c", *(c+idx+1)); + break; + case LOC_RACKMOUNTED: + n += sprintf ( buf, "Rack #%c", *(c+idx+1)); + break; + case LOC_VOLTAGE: + n += sprintf ( buf, "Voltage #%c", *(c+idx+1)); + break; + case LOC_LCD: + n += sprintf ( buf, "LCD #%c", *(c+idx+1)); + break; + case '.': + n += sprintf ( buf, "- %c", *(c+idx+1)); + default: + n += sprintf ( buf, "Unknown location"); + break; + } + return n; +} + + +/* ****************************************************************** */ +/* + * Format: + * ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ] + * the '.' may be an abbrevation + */ +int check_location_string (char *c, char *buf) +{ + int n=0,i=0; + + while (c[i]) { + if (isalpha(c[i]) || c[i] == '.') { + n += check_location(c, i, buf+n); + } + else if (c[i] == '/' || c[i] == '-') + n += sprintf(buf+n, " at "); + i++; + } + return n; +} + + +/* ****************************************************************** */ + +int get_location_code(struct individual_sensor s, char * buffer) +{ + char rstr[512], tmp[10], tmp2[10]; + int n=0, i=0, llen, len; + /* char *buf = kmalloc(MAX_LINELENGTH, GFP_KERNEL); */ + char *ret; + + static int pos = 0; /* remember position where buffer was */ + + /* construct the sensor number like 0003 */ + /* fill with zeros */ + n = sprintf(tmp, "%d", s.token); + len = strlen(tmp); + while (strlen(tmp) < 4) + n += sprintf (tmp+n, "0"); + + /* invert the string */ + while (tmp[i]) { + if (i<len) + tmp2[4-len+i] = tmp[i]; + else + tmp2[3-i] = tmp[i]; + i++; + } + tmp2[4] = '\0'; + + sprintf (rstr, SENSOR_PREFIX"%s", tmp2); + + ret = (char *) get_property(rtas, rstr, &llen); + + n=0; + if (ret[0] == '\0') + n += sprintf ( buffer+n, "--- ");/* does not have a location */ + else { + char t[50]; + ret += pos; + + n += check_location_string(ret, buffer + n); + n += sprintf ( buffer+n, " "); + /* see how many characters we have printed */ + sprintf ( t, "%s ", ret); + + pos += strlen(t); + if (pos >= llen) pos=0; + } + return n; +} +/* ****************************************************************** */ +/* INDICATORS - Tone Frequency */ +/* ****************************************************************** */ +static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + unsigned long freq; + char *dest; + int error; + freq = simple_strtoul(buf, &dest, 10); + if (*dest != '\0' && *dest != '\n') { + printk("ppc_rtas_tone_freq_write: Invalid tone freqency\n"); + return count; + } + if (freq < 0) freq = 0; + rtas_tone_frequency = freq; /* save it for later */ + error = call_rtas("set-indicator", 3, 1, NULL, + TONE_FREQUENCY, 0, freq); + if (error != 0) + printk(KERN_WARNING "error: setting tone frequency returned: %s\n", + ppc_rtas_process_error(error)); + return count; +} +/* ****************************************************************** */ +static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + int n; + n = sprintf(buf, "%lu\n", rtas_tone_frequency); + + if (*ppos >= strlen(buf)) + return 0; + if (n > strlen(buf) - *ppos) + n = strlen(buf) - *ppos; + if (n > count) + n = count; + *ppos += n; + return n; +} +/* ****************************************************************** */ +/* INDICATORS - Tone Volume */ +/* ****************************************************************** */ +static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + unsigned long volume; + char *dest; + int error; + volume = simple_strtoul(buf, &dest, 10); + if (*dest != '\0' && *dest != '\n') { + printk("ppc_rtas_tone_volume_write: Invalid tone volume\n"); + return count; + } + if (volume < 0) volume = 0; + if (volume > 100) volume = 100; + + rtas_tone_volume = volume; /* save it for later */ + error = call_rtas("set-indicator", 3, 1, NULL, + TONE_VOLUME, 0, volume); + if (error != 0) + printk(KERN_WARNING "error: setting tone volume returned: %s\n", + ppc_rtas_process_error(error)); + return count; +} +/* ****************************************************************** */ +static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + int n; + n = sprintf(buf, "%lu\n", rtas_tone_volume); + + if (*ppos >= strlen(buf)) + return 0; + if (n > strlen(buf) - *ppos) + n = strlen(buf) - *ppos; + if (n > count) + n = count; + *ppos += n; + return n; +} diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index a200b1c78..c4c76adec 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -222,16 +222,17 @@ _switch_to(struct task_struct *prev, struct task_struct *new, giveup_fpu(prev); #ifdef CONFIG_ALTIVEC /* - * If the previous thread 1) has some altivec regs it wants saved - * (has bits in vrsave set) and 2) used altivec in the last quantum + * If the previous thread used altivec in the last quantum * (thus changing altivec regs) then save them. + * We used to check the VRSAVE register but not all apps + * set it, so we don't rely on it now (and in fact we need + * to save & restore VSCR even if VRSAVE == 0). -- paulus * * On SMP we always save/restore altivec regs just to avoid the * complexity of changing processors. * -- Cort */ - if ( (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)) && - prev->thread.vrsave ) + if ((prev->thread.regs && (prev->thread.regs->msr & MSR_VEC))) giveup_altivec(prev); #endif /* CONFIG_ALTIVEC */ current_set[smp_processor_id()] = new; @@ -251,13 +252,15 @@ void show_regs(struct pt_regs * regs) { int i; - printk("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx\n", - regs->nip, regs->xer, regs->link, regs,regs->trap); + printk("NIP: %08lX XER: %08lX LR: %08lX SP: %08lX REGS: %p TRAP: %04lx\n", + regs->nip, regs->xer, regs->link, regs->gpr[1], regs,regs->trap); printk("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n", regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0, regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0, regs->msr&MSR_IR ? 1 : 0, regs->msr&MSR_DR ? 1 : 0); + if (regs->trap == 0x300 || regs->trap == 0x600) + printk("DAR: %08lX, DSISR: %08lX\n", regs->dar, regs->dsisr); printk("TASK = %p[%d] '%s' ", current, current->pid, current->comm); printk("Last syscall: %ld ", current->thread.last_syscall); @@ -285,7 +288,7 @@ void show_regs(struct pt_regs * regs) printk("\n"); } } -out: +out: ; } void exit_thread(void) diff --git a/arch/ppc/kernel/prom.c b/arch/ppc/kernel/prom.c index 5494f2f52..f3b39c222 100644 --- a/arch/ppc/kernel/prom.c +++ b/arch/ppc/kernel/prom.c @@ -28,10 +28,11 @@ #include <asm/smp.h> #include <asm/bootx.h> #include <asm/system.h> -#include <asm/gemini.h> #include <asm/mmu.h> #include <asm/pgtable.h> #include <asm/bitops.h> +/* for openpic_to_irq */ +#include "open_pic.h" #ifdef CONFIG_FB #include <asm/linux_logo.h> @@ -95,26 +96,28 @@ static interpret_func interpret_root_props; #define FB_MAX 8 #endif char *prom_display_paths[FB_MAX] __initdata = { 0, }; -unsigned int prom_num_displays = 0; -char *of_stdout_device = 0; +unsigned int prom_num_displays __initdata = 0; +char *of_stdout_device __initdata = 0; +ihandle prom_disp_node __initdata = 0; -prom_entry prom = 0; -ihandle prom_chosen = 0, prom_stdout = 0, prom_disp_node = 0; +prom_entry prom __initdata = 0; +ihandle prom_chosen __initdata = 0; +ihandle prom_stdout __initdata = 0; extern char *klimit; -char *bootpath = 0; -char *bootdevice = 0; +char *bootpath; +char *bootdevice; -unsigned int rtas_data = 0; /* physical pointer */ -unsigned int rtas_entry = 0; /* physical pointer */ -unsigned int rtas_size = 0; -unsigned int old_rtas = 0; +unsigned int rtas_data; /* physical pointer */ +unsigned int rtas_entry; /* physical pointer */ +unsigned int rtas_size; +unsigned int old_rtas; /* Set for a newworld machine */ -int use_of_interrupt_tree = 0; -int pmac_newworld = 0; +int use_of_interrupt_tree; +int pmac_newworld; -static struct device_node *allnodes = 0; +static struct device_node *allnodes; #ifdef CONFIG_BOOTX_TEXT @@ -134,13 +137,12 @@ static void draw_byte_32(unsigned char *bits, unsigned long *base, int rb); static void draw_byte_16(unsigned char *bits, unsigned long *base, int rb); static void draw_byte_8(unsigned char *bits, unsigned long *base, int rb); -/* We want those in data, not BSS */ -static long g_loc_X = 0; -static long g_loc_Y = 0; -static long g_max_loc_X = 0; -static long g_max_loc_Y = 0; +static int g_loc_X; +static int g_loc_Y; +static int g_max_loc_X; +static int g_max_loc_Y; -unsigned long disp_BAT[2] = {0, 0}; +unsigned long disp_BAT[2] __initdata = {0, 0}; #define cmapsz (16*256) @@ -173,10 +175,10 @@ extern unsigned long reloc_offset(void); void phys_call_rtas(int, int, int, ...); extern char cmd_line[512]; /* XXX */ -boot_infos_t *boot_infos = 0; /* init it so it's in data segment not bss */ +boot_infos_t *boot_infos; #ifdef CONFIG_BOOTX_TEXT -boot_infos_t *disp_bi = 0; -boot_infos_t fake_bi = {0,}; +boot_infos_t *disp_bi; +boot_infos_t fake_bi; #endif unsigned long dev_tree_size; @@ -195,10 +197,6 @@ unsigned long dev_tree_size; * OF calls should be done within prom_init(), and prom_init() * and all routines called within it must be careful to relocate * references as necessary. - * - * Note that the bss is cleared *after* prom_init runs, so we have - * to make sure that any static or extern variables it accesses - * are put in the data segment. */ #define PTRRELOC(x) ((typeof(x))((unsigned long)(x) + offset)) #define PTRUNRELOC(x) ((typeof(x))((unsigned long)(x) - offset)) @@ -618,6 +616,11 @@ prom_init(int r3, int r4, prom_entry pp) char *p, *d; int prom_version = 0; unsigned long phys; + extern char __bss_start, _end; + + /* First zero the BSS -- use memset, some arches don't have + * caches on yet */ + memset_io(PTRRELOC(&__bss_start),0 , &_end - &__bss_start); /* Default */ phys = offset + KERNELBASE; @@ -948,34 +951,6 @@ check_display(unsigned long mem) if ((int) call_prom(RELOC("package-to-path"), 3, 1, node, path, 255) < 0) continue; - prom_print(RELOC("opening display ")); - prom_print(path); - ih = call_prom(RELOC("open"), 1, 1, path); - if (ih == 0 || ih == (ihandle) -1) { - prom_print(RELOC("... failed\n")); - continue; - } - prom_print(RELOC("... ok\n")); - - if (RELOC(prom_disp_node) == 0) - RELOC(prom_disp_node) = node; - - /* Setup a useable color table when the appropriate - * method is available. Should update this to set-colors */ - for (i = 0; i < 32; i++) - if (prom_set_color(ih, i, RELOC(default_colors)[i*3], - RELOC(default_colors)[i*3+1], - RELOC(default_colors)[i*3+2]) != 0) - break; - -#ifdef CONFIG_FB - for (i = 0; i < LINUX_LOGO_COLORS; i++) - if (prom_set_color(ih, i + 32, - RELOC(linux_logo_red)[i], - RELOC(linux_logo_green)[i], - RELOC(linux_logo_blue)[i]) != 0) - break; -#endif /* CONFIG_FB */ /* * If this display is the device that OF is using for stdout, @@ -990,9 +965,44 @@ check_display(unsigned long mem) = RELOC(prom_display_paths[i-1]); } RELOC(prom_display_paths[i]) = PTRUNRELOC(path); + if (i == 0) + RELOC(prom_disp_node) = node; if (RELOC(prom_num_displays) >= FB_MAX) break; } + + /* + * Open the first display and set its colormap. + */ + if (RELOC(prom_num_displays) > 0) { + path = PTRRELOC(RELOC(prom_display_paths[0])); + prom_print(RELOC("opening display ")); + prom_print(path); + ih = call_prom(RELOC("open"), 1, 1, path); + if (ih == 0 || ih == (ihandle) -1) { + prom_print(RELOC("... failed\n")); + } else { + prom_print(RELOC("... ok\n")); + + /* Setup a useable color table when the appropriate + * method is available. Should update this to set-colors */ + for (i = 0; i < 32; i++) + if (prom_set_color(ih, i, RELOC(default_colors)[i*3], + RELOC(default_colors)[i*3+1], + RELOC(default_colors)[i*3+2]) != 0) + break; + +#ifdef CONFIG_FB + for (i = 0; i < LINUX_LOGO_COLORS; i++) + if (prom_set_color(ih, i + 32, + RELOC(linux_logo_red)[i], + RELOC(linux_logo_green)[i], + RELOC(linux_logo_blue)[i]) != 0) + break; +#endif /* CONFIG_FB */ + } + } + return ALIGN(mem); } @@ -1277,7 +1287,7 @@ finish_node(struct device_node *np, unsigned long mem_start, if (!strcmp(np->name, "display")) np->name = get_property(np, "compatible", 0); - if (!strcmp(np->name, "device-tree")) + if (np->parent == NULL) ifunc = interpret_root_props; else if (np->type == 0) ifunc = NULL; @@ -1370,7 +1380,7 @@ finish_node_interrupts(struct device_node *np, unsigned long mem_start) np->intrs[i].line = *interrupts++; if (cvt_irq) np->intrs[i].line = openpic_to_irq(np->intrs[i].line); - np->intrs[i].sense = 0; + np->intrs[i].sense = 1; if (isize > 1) np->intrs[i].sense = *interrupts++; for (j=2; j<isize; j++) @@ -1540,7 +1550,7 @@ interpret_pci_props(struct device_node *np, unsigned long mem_start, for (i = 0; (ml -= cell_size) >= 0; ++i) { if (imp->addr.a_hi == devfn) { np->intrs[np->n_intrs].line = imp->intr; - np->intrs[np->n_intrs].sense = 0; /* FIXME */ + np->intrs[np->n_intrs].sense = 1; /* FIXME */ ++np->n_intrs; } imp = (struct pci_intr_map *)(((unsigned int)imp) @@ -1561,7 +1571,7 @@ interpret_pci_props(struct device_node *np, unsigned long mem_start, mem_start += np->n_intrs * sizeof(struct interrupt_info); for (i = 0; i < np->n_intrs; ++i) { np->intrs[i].line = *ip++; - np->intrs[i].sense = 0; + np->intrs[i].sense = 1; } } @@ -1614,7 +1624,7 @@ interpret_dbdma_props(struct device_node *np, unsigned long mem_start, mem_start += np->n_intrs * sizeof(struct interrupt_info); for (i = 0; i < np->n_intrs; ++i) { np->intrs[i].line = *ip++; - np->intrs[i].sense = 0; + np->intrs[i].sense = 1; } } @@ -1675,7 +1685,7 @@ interpret_macio_props(struct device_node *np, unsigned long mem_start, if (keylargo) np->intrs[i].sense = *ip++; else - np->intrs[i].sense = 0; + np->intrs[i].sense = 1; } } else { /* CHRP machines */ @@ -1771,7 +1781,7 @@ interpret_root_props(struct device_node *np, unsigned long mem_start, mem_start += np->n_intrs * sizeof(struct interrupt_info); for (i = 0; i < np->n_intrs; ++i) { np->intrs[i].line = *ip++; - np->intrs[i].sense = 0; + np->intrs[i].sense = 1; } } @@ -1779,6 +1789,30 @@ interpret_root_props(struct device_node *np, unsigned long mem_start, } /* + * Work out the sense (active-low level / active-high edge) + * of each interrupt from the device tree. + */ +void __init +prom_get_irq_senses(unsigned char *senses, int off, int max) +{ + struct device_node *np; + int i, j; + + /* default to level-triggered */ + memset(senses, 1, max - off); + if (!use_of_interrupt_tree) + return; + + for (np = allnodes; np != 0; np = np->allnext) { + for (j = 0; j < np->n_intrs; j++) { + i = np->intrs[j].line; + if (i >= off && i < max) + senses[i-off] = np->intrs[j].sense; + } + } +} + +/* * Construct and return a list of the device_nodes with a given name. */ __openfirmware @@ -1818,39 +1852,6 @@ find_type_devices(const char *type) return head; } -/* Finds a device node given its PCI bus number, device number - * and function number - */ -__openfirmware -struct device_node * -find_pci_device_OFnode(unsigned char bus, unsigned char dev_fn) -{ - struct device_node* np; - unsigned int *reg; - int l; - - for (np = allnodes; np != 0; np = np->allnext) { - int in_macio = 0; - struct device_node* parent = np->parent; - while(parent) { - char *pname = (char *)get_property(parent, "name", &l); - if (pname && strcmp(pname, "mac-io") == 0) { - in_macio = 1; - break; - } - parent = parent->parent; - } - if (in_macio) - continue; - reg = (unsigned int *) get_property(np, "reg", &l); - if (reg == 0 || l < sizeof(struct reg_property)) - continue; - if (((reg[0] >> 8) & 0xff) == dev_fn && ((reg[0] >> 16) & 0xff) == bus) - break; - } - return np; -} - /* * Returns all nodes linked together */ @@ -1983,6 +1984,21 @@ get_property(struct device_node *np, const char *name, int *lenp) return 0; } +/* + * Add a property to a node + */ +__openfirmware +void +prom_add_property(struct device_node* np, struct property* prop) +{ + struct property **next = &np->properties; + + prop->next = NULL; + while (*next) + next = &(*next)->next; + *next = prop; +} + #if 0 __openfirmware void diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 6bafa57c1..58fb87e9c 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -12,6 +12,7 @@ #include <linux/delay.h> #include <linux/blk.h> #include <linux/ide.h> +#include <linux/bootmem.h> #include <asm/init.h> #include <asm/residual.h> @@ -71,12 +72,6 @@ extern void apus_init(unsigned long r3, unsigned long r6, unsigned long r7); -extern void gemini_init(unsigned long r3, - unsigned long r4, - unsigned long r5, - unsigned long r6, - unsigned long r7); - #ifdef CONFIG_XMON extern void xmon_map_scc(void); #endif @@ -106,6 +101,10 @@ int have_of = 0; unsigned long SYSRQ_KEY; #endif /* CONFIG_MAGIC_SYSRQ */ +#ifdef CONFIG_VGA_CONSOLE +unsigned long vgacon_remap_base; +#endif + struct machdep_calls ppc_md; /* @@ -377,9 +376,9 @@ int get_cpuinfo(char *buffer) len += sprintf(len+buffer, "revision\t: %hd.%hd\n", maj, min); len += sprintf(buffer+len, "bogomips\t: %lu.%02lu\n", - (CD(loops_per_sec)+2500)/500000, - (CD(loops_per_sec)+2500)/5000 % 100); - bogosum += CD(loops_per_sec); + (CD(loops_per_jiffy)+2500)/(500000/HZ), + (CD(loops_per_jiffy)+2500)/(5000/HZ) % 100); + bogosum += CD(loops_per_jiffy); } #ifdef CONFIG_SMP @@ -549,11 +548,6 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5, apus_init(r3, r4, r5, r6, r7); break; #endif -#ifdef CONFIG_GEMINI - case _MACH_gemini: - gemini_init(r3, r4, r5, r6, r7); - break; -#endif default: printk("Unknown machine type in identify_machine!\n"); } @@ -673,13 +667,14 @@ __setup("l2cr=", ppc_setup_l2cr); void __init ppc_init(void) { /* clear the progress line */ - if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); + if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); if (ppc_md.init != NULL) { ppc_md.init(); } } +/* Warning, IO base is not yet inited */ void __init setup_arch(char **cmdline_p) { extern int panic_timeout; @@ -688,7 +683,7 @@ void __init setup_arch(char **cmdline_p) extern void do_init_bootmem(void); /* so udelay does something sensible, assume <= 1000 bogomips */ - loops_per_sec = 500000000; + loops_per_jiffy = 500000000 / HZ; #ifdef CONFIG_ALL_PPC feature_init(); @@ -743,10 +738,34 @@ void __init setup_arch(char **cmdline_p) ppc_md.setup_arch(); if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); +#ifdef CONFIG_PCI + /* We create the "pci-OF-bus-map" property now so it appear in the + * /proc device tree + */ + if (have_of) { + struct property* of_prop; + + of_prop = (struct property*)alloc_bootmem(sizeof(struct property) + 256); + if (of_prop && find_path_device("/")) { + memset(of_prop, -1, sizeof(struct property) + 256); + of_prop->name = "pci-OF-bus-map"; + of_prop->length = 256; + of_prop->value = (unsigned char *)&of_prop[1]; + prom_add_property(find_path_device("/"), of_prop); + } + } +#endif /* CONFIG_PCI */ + paging_init(); sort_exception_table(); } +/* Convert the shorts/longs in hd_driveid from little to big endian; + * chars are endian independant, of course, but strings need to be flipped. + * (Despite what it says in drivers/block/ide.h, they come up as little + * endian...) + * + * Changes to linux/hdreg.h may require changes here. */ void ppc_generic_ide_fix_driveid(struct hd_driveid *id) { int i; diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c index dd3d1ae1b..fe16fae25 100644 --- a/arch/ppc/kernel/signal.c +++ b/arch/ppc/kernel/signal.c @@ -53,8 +53,6 @@ #define MSR_USERCHANGE (MSR_FE0 | MSR_FE1) int do_signal(sigset_t *oldset, struct pt_regs *regs); -extern int sys_wait4(pid_t pid, unsigned long *stat_addr, - int options, unsigned long *ru); int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) { diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c index fb7f38444..7edf7209d 100644 --- a/arch/ppc/kernel/smp.c +++ b/arch/ppc/kernel/smp.c @@ -1,6 +1,4 @@ /* - * $Id: smp.c,v 1.68 1999/09/17 19:38:05 cort Exp $ - * * Smp support for ppc. * * Written by Cort Dougan (cort@cs.nmt.edu) borrowing a great @@ -8,8 +6,11 @@ * * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu> * - * Support for PReP (Motorola MTX/MVME) SMP by Troy Benjegerdes - * (troy@microux.com, hozer@drgw.net) + * Support for PReP (Motorola MTX/MVME) and Macintosh G4 SMP + * by Troy Benjegerdes (hozer@drgw.net) + * + * Support for DayStar quad CPU cards + * Copyright (C) XLR8, Inc. 1994-2000 */ #include <linux/config.h> @@ -23,7 +24,6 @@ #define __KERNEL_SYSCALLS__ #include <linux/unistd.h> #include <linux/init.h> -#include <linux/openpic.h> #include <linux/spinlock.h> #include <asm/ptrace.h> @@ -37,47 +37,97 @@ #include <asm/io.h> #include <asm/prom.h> #include <asm/smp.h> -#include <asm/gemini.h> - +#include <asm/residual.h> +#include <asm/feature.h> #include <asm/time.h> + #include "open_pic.h" int smp_threads_ready; volatile int smp_commenced; int smp_num_cpus = 1; +int smp_tb_synchronized; struct cpuinfo_PPC cpu_data[NR_CPUS]; struct klock_info_struct klock_info = { KLOCK_CLEAR, 0 }; -volatile unsigned char active_kernel_processor = NO_PROC_ID; /* Processor holding kernel spinlock */ -volatile unsigned long ipi_count; +atomic_t ipi_recv; +atomic_t ipi_sent; spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED; unsigned int prof_multiplier[NR_CPUS]; unsigned int prof_counter[NR_CPUS]; cycles_t cacheflush_time; +static int max_cpus __initdata = NR_CPUS; -/* this has to go in the data section because it is accessed from prom_init */ int smp_hw_index[NR_CPUS]; /* all cpu mappings are 1-1 -- Cort */ volatile unsigned long cpu_callin_map[NR_CPUS]; +#define TB_SYNC_PASSES 4 +volatile unsigned long __initdata tb_sync_flag = 0; +volatile unsigned long __initdata tb_offset = 0; + int start_secondary(void *); extern int cpu_idle(void *unused); -u_int openpic_read(volatile u_int *addr); void smp_call_function_interrupt(void); void smp_message_pass(int target, int msg, unsigned long data, int wait); +extern void __secondary_start_psurge(void); +extern void __secondary_start_psurge2(void); /* Temporary horrible hack */ +extern void __secondary_start_psurge3(void); /* Temporary horrible hack */ + +/* Addresses for powersurge registers */ +#define HAMMERHEAD_BASE 0xf8000000 +#define HHEAD_CONFIG 0x90 +#define HHEAD_SEC_INTR 0xc0 + /* register for interrupting the primary processor on the powersurge */ /* N.B. this is actually the ethernet ROM! */ -#define PSURGE_PRI_INTR 0xf3019000 -/* register for interrupting the secondary processor on the powersurge */ -#define PSURGE_SEC_INTR 0xf80000c0 +#define PSURGE_PRI_INTR 0xf3019000 + /* register for storing the start address for the secondary processor */ -#define PSURGE_START 0xf2800000 +/* N.B. this is the PCI config space address register for the 1st bridge */ +#define PSURGE_START 0xf2800000 + +/* Daystar/XLR8 4-CPU card */ +#define PSURGE_QUAD_REG_ADDR 0xf8800000 + +#define PSURGE_QUAD_IRQ_SET 0 +#define PSURGE_QUAD_IRQ_CLR 1 +#define PSURGE_QUAD_IRQ_PRIMARY 2 +#define PSURGE_QUAD_CKSTOP_CTL 3 +#define PSURGE_QUAD_PRIMARY_ARB 4 +#define PSURGE_QUAD_BOARD_ID 6 +#define PSURGE_QUAD_WHICH_CPU 7 +#define PSURGE_QUAD_CKSTOP_RDBK 8 +#define PSURGE_QUAD_RESET_CTL 11 + +#define PSURGE_QUAD_OUT(r, v) (out_8((u8 *)(quad_base+((r)<<2)+1), (v))) +#define PSURGE_QUAD_IN(r) (in_8((u8 *)(quad_base+((r)<<2)+1)) & 0x0f) +#define PSURGE_QUAD_BIS(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) | (v))) +#define PSURGE_QUAD_BIC(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) & ~(v))) + /* virtual addresses for the above */ -volatile u32 *psurge_pri_intr; -volatile u32 *psurge_sec_intr; -volatile u32 *psurge_start; +static volatile u8 *hhead_base; +static volatile u32 *quad_base; +static volatile u32 *psurge_pri_intr; +static volatile u8 *psurge_sec_intr; +static volatile u32 *psurge_start; + +/* what sort of powersurge board we have */ +static int psurge_type; + +/* values for psurge_type */ +#define PSURGE_DUAL 0 +#define PSURGE_QUAD_OKEE 1 +#define PSURGE_QUAD_COTTON 2 +#define PSURGE_QUAD_ICEGRASS 3 -/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. */ +/* l2 cache stuff for dual G4 macs */ +extern void core99_init_l2(void); + +/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. + * + * Make sure this matches openpic_request_IPIs in open_pic.c, or what shows up + * in /proc/interrupts will be wrong!!! --Troy */ #define PPC_MSG_CALL_FUNCTION 0 #define PPC_MSG_RESCHEDULE 1 #define PPC_MSG_INVALIDATE_TLB 2 @@ -85,10 +135,577 @@ volatile u32 *psurge_start; static inline void set_tb(unsigned int upper, unsigned int lower) { + mtspr(SPRN_TBWL, 0); mtspr(SPRN_TBWU, upper); mtspr(SPRN_TBWL, lower); } +/* + * Set and clear IPIs for powersurge. + */ +static inline void psurge_set_ipi(int cpu) +{ + if (cpu == 0) + in_be32(psurge_pri_intr); + else if (psurge_type == PSURGE_DUAL) + out_8(psurge_sec_intr, 0); + else + PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_SET, 1 << cpu); +} + +static inline void psurge_clr_ipi(int cpu) +{ + if (cpu > 0) { + if (psurge_type == PSURGE_DUAL) + out_8(psurge_sec_intr, ~0); + else + PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, 1 << cpu); + } +} + +/* + * On powersurge (old SMP powermac architecture) we don't have + * separate IPIs for separate messages like openpic does. Instead + * we have a bitmap for each processor, where a 1 bit means that + * the corresponding message is pending for that processor. + * Ideally each cpu's entry would be in a different cache line. + * -- paulus. + */ +static unsigned long psurge_smp_message[NR_CPUS]; + +void psurge_smp_message_recv(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + int msg; + + /* clear interrupt */ + psurge_clr_ipi(cpu); + + if (smp_num_cpus < 2) + return; + + /* make sure there is a message there */ + for (msg = 0; msg < 4; msg++) + if (test_and_clear_bit(msg, &psurge_smp_message[cpu])) + smp_message_recv(msg, regs); +} + +void +psurge_primary_intr(int irq, void *d, struct pt_regs *regs) +{ + psurge_smp_message_recv(regs); +} + +static void +smp_psurge_message_pass(int target, int msg, unsigned long data, int wait) +{ + int i; + + if (smp_num_cpus < 2) + return; + + for (i = 0; i < smp_num_cpus; i++) { + if (target == MSG_ALL + || (target == MSG_ALL_BUT_SELF && i != smp_processor_id()) + || target == i) { + set_bit(msg, &psurge_smp_message[i]); + psurge_set_ipi(i); + } + } +} + +/* + * Determine a quad card presence. We read the board ID register, we + * for the data bus to change to something else, and we read it again. + * It it's stable, then the register probably exist (ugh !) + */ +static int __init psurge_quad_probe(void) +{ + int type; + unsigned int i; + + type = PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID); + if (type < PSURGE_QUAD_OKEE || type > PSURGE_QUAD_ICEGRASS + || type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID)) + return PSURGE_DUAL; + + /* looks OK, try a slightly more rigorous test */ + /* bogus is not necessarily cacheline-aligned, + though I don't suppose that really matters. -- paulus */ + for (i = 0; i < 100; i++) { + volatile u32 bogus[8]; + bogus[(0+i)%8] = 0x00000000; + bogus[(1+i)%8] = 0x55555555; + bogus[(2+i)%8] = 0xFFFFFFFF; + bogus[(3+i)%8] = 0xAAAAAAAA; + bogus[(4+i)%8] = 0x33333333; + bogus[(5+i)%8] = 0xCCCCCCCC; + bogus[(6+i)%8] = 0xCCCCCCCC; + bogus[(7+i)%8] = 0x33333333; + wmb(); + asm volatile("dcbf 0,%0" : : "r" (bogus) : "memory"); + mb(); + if (type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID)) + return PSURGE_DUAL; + } + return type; +} + +static void __init psurge_quad_init(void) +{ + int procbits; + + if (ppc_md.progress) ppc_md.progress("psurge_quad_init", 0x351); + procbits = ~PSURGE_QUAD_IN(PSURGE_QUAD_WHICH_CPU); + if (psurge_type == PSURGE_QUAD_ICEGRASS) + PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits); + else + PSURGE_QUAD_BIC(PSURGE_QUAD_CKSTOP_CTL, procbits); + mdelay(33); + out_8(psurge_sec_intr, ~0); + PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, procbits); + PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits); + if (psurge_type != PSURGE_QUAD_ICEGRASS) + PSURGE_QUAD_BIS(PSURGE_QUAD_CKSTOP_CTL, procbits); + PSURGE_QUAD_BIC(PSURGE_QUAD_PRIMARY_ARB, procbits); + mdelay(33); + PSURGE_QUAD_BIC(PSURGE_QUAD_RESET_CTL, procbits); + mdelay(33); + PSURGE_QUAD_BIS(PSURGE_QUAD_PRIMARY_ARB, procbits); + mdelay(33); +} + +static int __init smp_psurge_probe(void) +{ + int i, ncpus; + + /* We don't do SMP on the PPC601 -- paulus */ + if ((_get_PVR() >> 16) == 1) + return 1; + + /* + * The powersurge cpu board can be used in the generation + * of powermacs that have a socket for an upgradeable cpu card, + * including the 7500, 8500, 9500, 9600. + * The device tree doesn't tell you if you have 2 cpus because + * OF doesn't know anything about the 2nd processor. + * Instead we look for magic bits in magic registers, + * in the hammerhead memory controller in the case of the + * dual-cpu powersurge board. -- paulus. + */ + if (find_devices("hammerhead") == NULL) + return 1; + + hhead_base = ioremap(HAMMERHEAD_BASE, 0x800); + quad_base = ioremap(PSURGE_QUAD_REG_ADDR, 1024); + psurge_sec_intr = hhead_base + HHEAD_SEC_INTR; + + psurge_type = psurge_quad_probe(); + if (psurge_type != PSURGE_DUAL) { + psurge_quad_init(); + /* I believe we could "count" CPUs by counting 1 bits + * in procbits on a quad board. For now, we assume 4, + * non-present CPUs will just be seen as "stuck". + * (hope they are the higher-numbered ones -- paulus) + */ + ncpus = 4; + } else { + iounmap((void *) quad_base); + if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) { + /* not a dual-cpu card */ + iounmap((void *) hhead_base); + return 1; + } + ncpus = 2; + } + + psurge_start = ioremap(PSURGE_START, 4); + psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); + + /* this is not actually strictly necessary -- paulus. */ + for (i = 1; i < ncpus; ++i) + smp_hw_index[i] = i; + + if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352); + + return ncpus; +} + +static void __init smp_psurge_kick_cpu(int nr) +{ + void (*start)(void) = __secondary_start_psurge; + + if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353); + + /* setup entry point of secondary processor */ + switch (nr) { + case 2: + start = __secondary_start_psurge2; + break; + case 3: + start = __secondary_start_psurge3; + break; + } + + out_be32(psurge_start, __pa(start)); + mb(); + + psurge_set_ipi(nr); + udelay(10); + psurge_clr_ipi(nr); + + if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354); +} + +/* + * With the dual-cpu powersurge board, the decrementers and timebases + * of both cpus are frozen after the secondary cpu is started up, + * until we give the secondary cpu another interrupt. This routine + * uses this to get the timebases synchronized. + * -- paulus. + */ +static void __init psurge_dual_sync_tb(int cpu_nr) +{ + static volatile int sec_tb_reset = 0; + int t; + + set_dec(tb_ticks_per_jiffy); + set_tb(0, 0); + last_jiffy_stamp(cpu_nr) = 0; + + if (cpu_nr > 0) { + mb(); + sec_tb_reset = 1; + return; + } + + /* wait for the secondary to have reset its TB before proceeding */ + for (t = 10000000; t > 0 && !sec_tb_reset; --t) + ; + + /* now interrupt the secondary, starting both TBs */ + psurge_set_ipi(1); + + smp_tb_synchronized = 1; +} + +static void +smp_psurge_setup_cpu(int cpu_nr) +{ + + if (cpu_nr == 0) { + if (smp_num_cpus < 2) + return; + /* reset the entry point so if we get another intr we won't + * try to startup again */ + out_be32(psurge_start, 0x100); + if (request_irq(30, psurge_primary_intr, 0, "primary IPI", 0)) + printk(KERN_ERR "Couldn't get primary IPI interrupt"); + } + + if (psurge_type == PSURGE_DUAL) + psurge_dual_sync_tb(cpu_nr); +} + + +static void +smp_openpic_message_pass(int target, int msg, unsigned long data, int wait) +{ + /* make sure we're sending something that translates to an IPI */ + if ( msg > 0x3 ){ + printk("SMP %d: smp_message_pass: unknown msg %d\n", + smp_processor_id(), msg); + return; + } + switch ( target ) + { + case MSG_ALL: + openpic_cause_IPI(msg, 0xffffffff); + break; + case MSG_ALL_BUT_SELF: + openpic_cause_IPI(msg, + 0xffffffff & ~(1 << smp_hw_index[smp_processor_id()])); + + break; + default: + openpic_cause_IPI(msg, smp_hw_index[1<<target]); + break; + } +} + +static int +smp_core99_probe(void) +{ + struct device_node *cpus; + int *pp; + int i, ncpus = 1; + + if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345); +#if 0 /* Paulus method.. doesn't seem to work on earlier dual G4's??*/ + cpus = find_devices("cpus"); + if (cpus != 0) { + pp = (int *) get_property(cpus, "#cpus", NULL); + if (pp != NULL) + ncpus = *pp; + } +#else /* My original method -- Troy <hozer@drgw.net> */ + + cpus = find_type_devices("cpu"); + if (cpus){ + for ( ncpus = 1; cpus->next; cpus = cpus->next ){ + ncpus++; + } + } +#endif + printk("smp_core99_probe: OF reports %d cpus\n", ncpus); + if (ncpus > 1) { + openpic_request_IPIs(); + for (i = 1; i < ncpus; ++i) + smp_hw_index[i] = i; + } + + return ncpus; +} + +static void +smp_core99_kick_cpu(int nr) +{ + unsigned long save_int; + unsigned long flags; + volatile unsigned long *vector + = ((volatile unsigned long *)(KERNELBASE+0x500)); + + if (nr != 1) + return; + if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346); + + local_irq_save(flags); + local_irq_disable(); + + /* Save EE vector */ + save_int = *vector; + + /* Setup fake EE vector that does + * b __secondary_start_psurge - KERNELBASE + */ + *vector = 0x48000002 + + ((unsigned long)__secondary_start_psurge - KERNELBASE); + + /* flush data cache and inval instruction cache */ + flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); + + /* Put some life in our friend */ + feature_core99_kick_cpu1(); + + /* FIXME: We wait a bit for the CPU to take the exception, I should + * instead wait for the entry code to set something for me. Well, + * ideally, all that crap will be done in prom.c and the CPU left + * in a RAM-based wait loop like CHRP. + */ + mdelay(1); + + /* Restore our exception vector */ + *vector = save_int; + flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); + + local_irq_restore(flags); + if (ppc_md.progress) ppc_md.progress("smp_core99_probe done", 0x347); +} + +static void +smp_core99_setup_cpu(int cpu_nr) +{ + /* Setup openpic */ + do_openpic_setup_cpu(); + + /* Setup L2 */ + if (cpu_nr != 0) + core99_init_l2(); + else + if (ppc_md.progress) ppc_md.progress("core99_setup_cpu 0 done", 0x349); +} + +static int +smp_chrp_probe(void) +{ + extern unsigned long smp_chrp_cpu_nr; + + if (smp_chrp_cpu_nr > 1) + openpic_request_IPIs(); + + return smp_chrp_cpu_nr; +} + +static void +smp_chrp_kick_cpu(int nr) +{ + *(unsigned long *)KERNELBASE = nr; + asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory"); +} + +static void +smp_chrp_setup_cpu(int cpu_nr) +{ + static atomic_t ready = ATOMIC_INIT(1); + static volatile int frozen = 0; + + if (cpu_nr == 0) { + /* wait for all the others */ + while (atomic_read(&ready) < smp_num_cpus) + barrier(); + atomic_set(&ready, 1); + /* freeze the timebase */ + call_rtas("freeze-time-base", 0, 1, NULL); + mb(); + frozen = 1; + /* XXX assumes this is not a 601 */ + set_tb(0, 0); + last_jiffy_stamp(0) = 0; + while (atomic_read(&ready) < smp_num_cpus) + barrier(); + /* thaw the timebase again */ + call_rtas("thaw-time-base", 0, 1, NULL); + mb(); + frozen = 0; + smp_tb_synchronized = 1; + } else { + atomic_inc(&ready); + while (!frozen) + barrier(); + set_tb(0, 0); + last_jiffy_stamp(0) = 0; + mb(); + atomic_inc(&ready); + while (frozen) + barrier(); + } + + if (OpenPIC_Addr) + do_openpic_setup_cpu(); +} + +#ifdef CONFIG_POWER4 +static void +smp_xics_message_pass(int target, int msg, unsigned long data, int wait) +{ + /* for now, only do reschedule messages + since we only have one IPI */ + if (msg != PPC_MSG_RESCHEDULE) + return; + for (i = 0; i < smp_num_cpus; ++i) { + if (target == MSG_ALL || target == i + || (target == MSG_ALL_BUT_SELF + && i != smp_processor_id())) + xics_cause_IPI(i); + } +} + +static int +smp_xics_probe(void) +{ + return smp_chrp_cpu_nr; +} + +static void +smp_xics_setup_cpu(int cpu_nr) +{ + if (cpu_nr > 0) + xics_setup_cpu(); +} +#endif /* CONFIG_POWER4 */ + +static int +smp_prep_probe(void) +{ + extern int mot_multi; + + if (mot_multi) { + openpic_request_IPIs(); + smp_hw_index[1] = 1; + return 2; + } + + return 1; +} + +static void +smp_prep_kick_cpu(int nr) +{ + extern unsigned long *MotSave_SmpIar; + extern unsigned char *MotSave_CpusState[2]; + + *MotSave_SmpIar = (unsigned long)__secondary_start_psurge - KERNELBASE; + *MotSave_CpusState[1] = CPU_GOOD; + printk("CPU1 reset, waiting\n"); +} + +static void +smp_prep_setup_cpu(int cpu_nr) +{ + if (OpenPIC_Addr) + do_openpic_setup_cpu(); +} + +static struct smp_ops_t { + void (*message_pass)(int target, int msg, unsigned long data, int wait); + int (*probe)(void); + void (*kick_cpu)(int nr); + void (*setup_cpu)(int nr); + +} *smp_ops; + +#define smp_message_pass(t,m,d,w) \ + do { if (smp_ops) \ + atomic_inc(&ipi_sent); \ + smp_ops->message_pass((t),(m),(d),(w)); \ + } while(0) + + +/* PowerSurge-style Macs */ +static struct smp_ops_t psurge_smp_ops = { + smp_psurge_message_pass, + smp_psurge_probe, + smp_psurge_kick_cpu, + smp_psurge_setup_cpu, +}; + +/* Core99 Macs (dual G4s) */ +static struct smp_ops_t core99_smp_ops = { + smp_openpic_message_pass, + smp_core99_probe, + smp_core99_kick_cpu, + smp_core99_setup_cpu, +}; + +/* CHRP with openpic */ +static struct smp_ops_t chrp_smp_ops = { + smp_openpic_message_pass, + smp_chrp_probe, + smp_chrp_kick_cpu, + smp_chrp_setup_cpu, +}; + +#ifdef CONFIG_POWER4 +/* CHRP with new XICS interrupt controller */ +static struct smp_ops_t xics_smp_ops = { + smp_xics_message_pass, + smp_xics_probe, + smp_chrp_kick_cpu, + smp_xics_setup_cpu, +}; +#endif /* CONFIG_POWER4 */ + +/* PReP (MTX) */ +static struct smp_ops_t prep_smp_ops = { + smp_openpic_message_pass, + smp_prep_probe, + smp_prep_kick_cpu, + smp_prep_setup_cpu, +}; + +/* + * Common functions + */ void smp_local_timer_interrupt(struct pt_regs * regs) { int cpu = smp_processor_id(); @@ -101,7 +718,7 @@ void smp_local_timer_interrupt(struct pt_regs * regs) void smp_message_recv(int msg, struct pt_regs *regs) { - ipi_count++; + atomic_inc(&ipi_recv); switch( msg ) { case PPC_MSG_CALL_FUNCTION: @@ -126,47 +743,6 @@ void smp_message_recv(int msg, struct pt_regs *regs) } /* - * As it is now, if we're sending two message at the same time - * we have race conditions on Pmac. The PowerSurge doesn't easily - * allow us to send IPI messages so we put the messages in - * smp_message[]. - * - * This is because don't have several IPI's on the PowerSurge even though - * we do on the chrp. It would be nice to use actual IPI's such as with - * openpic rather than this. - * -- Cort - */ -int pmac_smp_message[NR_CPUS]; -void pmac_smp_message_recv(struct pt_regs *regs) -{ - int cpu = smp_processor_id(); - int msg; - - /* clear interrupt */ - if (cpu == 1) - out_be32(psurge_sec_intr, ~0); - - if (smp_num_cpus < 2) - return; - - /* make sure there is a message there */ - msg = pmac_smp_message[cpu]; - if (msg == 0) - return; - - /* reset message */ - pmac_smp_message[cpu] = 0; - - smp_message_recv(msg - 1, regs); -} - -void -pmac_primary_intr(int irq, void *d, struct pt_regs *regs) -{ - pmac_smp_message_recv(regs); -} - -/* * 750's don't broadcast tlb invalidates so * we have to emulate that behavior. * -- Cort @@ -220,7 +796,7 @@ void smp_send_stop(void) */ static spinlock_t call_lock = SPIN_LOCK_UNLOCKED; -static volatile struct call_data_struct { +static struct call_data_struct { void (*func) (void *info); void *info; atomic_t started; @@ -317,87 +893,9 @@ void smp_call_function_interrupt(void) atomic_inc(&call_data->finished); } -void smp_message_pass(int target, int msg, unsigned long data, int wait) -{ - if ( !(_machine & (_MACH_Pmac|_MACH_chrp|_MACH_prep|_MACH_gemini)) ) - return; - - switch (_machine) { - case _MACH_Pmac: - /* - * IPI's on the Pmac are a hack but without reasonable - * IPI hardware SMP on Pmac is a hack. - * - * We assume here that the msg is not -1. If it is, - * the recipient won't know the message was destined - * for it. -- Cort - */ - if (smp_processor_id() == 0) { - /* primary cpu */ - if (target == 1 || target == MSG_ALL_BUT_SELF - || target == MSG_ALL) { - pmac_smp_message[1] = msg + 1; - /* interrupt secondary processor */ - out_be32(psurge_sec_intr, ~0); - out_be32(psurge_sec_intr, 0); - } - } else { - /* secondary cpu */ - if (target == 0 || target == MSG_ALL_BUT_SELF - || target == MSG_ALL) { - pmac_smp_message[0] = msg + 1; - /* interrupt primary processor */ - in_be32(psurge_pri_intr); - } - } - if (target == smp_processor_id() || target == MSG_ALL) { - /* sending a message to ourself */ - /* XXX maybe we shouldn't do this if ints are off */ - smp_message_recv(msg, NULL); - } - break; - case _MACH_chrp: - case _MACH_prep: - case _MACH_gemini: -#ifndef CONFIG_POWER4 - /* make sure we're sending something that translates to an IPI */ - if ( msg > 0x3 ) - break; - switch ( target ) - { - case MSG_ALL: - openpic_cause_IPI(smp_processor_id(), msg, 0xffffffff); - break; - case MSG_ALL_BUT_SELF: - openpic_cause_IPI(smp_processor_id(), msg, - 0xffffffff & ~(1 << smp_processor_id())); - break; - default: - openpic_cause_IPI(smp_processor_id(), msg, 1<<target); - break; - } -#else /* CONFIG_POWER4 */ - /* for now, only do reschedule messages - since we only have one IPI */ - if (msg != PPC_MSG_RESCHEDULE) - break; - for (i = 0; i < smp_num_cpus; ++i) { - if (target == MSG_ALL || target == i - || (target == MSG_ALL_BUT_SELF - && i != smp_processor_id())) - xics_cause_IPI(i); - } -#endif /* CONFIG_POWER4 */ - break; - } -} - void __init smp_boot_cpus(void) { extern struct task_struct *current_set[NR_CPUS]; - extern unsigned long smp_chrp_cpu_nr; - extern void __secondary_start_psurge(void); - extern void __secondary_start_chrp(void); int i, cpu_nr; struct task_struct *p; unsigned long a; @@ -411,7 +909,6 @@ void __init smp_boot_cpus(void) * cpu 0, the master -- Cort */ cpu_callin_map[0] = 1; - active_kernel_processor = 0; current->processor = 0; init_idle(); @@ -427,41 +924,40 @@ void __init smp_boot_cpus(void) */ cacheflush_time = 5 * 1024; - if ( !(_machine & (_MACH_Pmac|_MACH_chrp|_MACH_gemini)) ) - { - printk("SMP not supported on this machine.\n"); - return; - } - - switch ( _machine ) - { + /* To be later replaced by some arch-specific routine */ + switch(_machine) { case _MACH_Pmac: - /* assume powersurge board - 2 processors -- Cort */ - cpu_nr = 2; - psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); - psurge_sec_intr = ioremap(PSURGE_SEC_INTR, 4); - psurge_start = ioremap(PSURGE_START, 4); + /* Check for Core99 */ + if (find_devices("uni-n")) + smp_ops = &core99_smp_ops; + else + smp_ops = &psurge_smp_ops; break; case _MACH_chrp: - if (OpenPIC) - for ( i = 0; i < 4 ; i++ ) - openpic_enable_IPI(i); - cpu_nr = smp_chrp_cpu_nr; +#ifndef CONFIG_POWER4 + smp_ops = &chrp_smp_ops; +#else + smp_ops = &xics_smp_ops; +#endif /* CONFIG_POWER4 */ break; - case _MACH_gemini: - for ( i = 0; i < 4 ; i++ ) - openpic_enable_IPI(i); - cpu_nr = (readb(GEMINI_CPUSTAT) & GEMINI_CPU_COUNT_MASK)>>2; - cpu_nr = (cpu_nr == 0) ? 4 : cpu_nr; + case _MACH_prep: + smp_ops = &prep_smp_ops; break; + default: + printk("SMP not supported on this machine.\n"); + return; } + + /* Probe arch for CPUs */ + cpu_nr = smp_ops->probe(); /* * only check for cpus we know exist. We keep the callin map * with cpus at the bottom -- Cort */ - for ( i = 1 ; i < cpu_nr; i++ ) - { + if (cpu_nr > max_cpus) + cpu_nr = max_cpus; + for (i = 1; i < cpu_nr; i++) { int c; struct pt_regs regs; @@ -487,25 +983,7 @@ void __init smp_boot_cpus(void) asm volatile("sync"); /* wake up cpus */ - switch ( _machine ) - { - case _MACH_Pmac: - /* setup entry point of secondary processor */ - out_be32(psurge_start, __pa(__secondary_start_psurge)); - /* interrupt secondary to begin executing code */ - out_be32(psurge_sec_intr, ~0); - udelay(1); - out_be32(psurge_sec_intr, 0); - break; - case _MACH_chrp: - *(unsigned long *)KERNELBASE = i; - asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory"); - break; - case _MACH_gemini: - openpic_init_processor( 1<<i ); - openpic_init_processor( 0 ); - break; - } + smp_ops->kick_cpu(i); /* * wait to see if the cpu made a callin (is actually up). @@ -517,40 +995,108 @@ void __init smp_boot_cpus(void) if ( cpu_callin_map[i] ) { + char buf[32]; + sprintf(buf, "found cpu %d", i); + if (ppc_md.progress) ppc_md.progress(buf, 0x350+i); printk("Processor %d found.\n", i); smp_num_cpus++; } else { + char buf[32]; + sprintf(buf, "didn't find cpu %d", i); + if (ppc_md.progress) ppc_md.progress(buf, 0x360+i); printk("Processor %d is stuck.\n", i); } } - if (OpenPIC && (_machine & (_MACH_gemini|_MACH_chrp|_MACH_prep))) - do_openpic_setup_cpu(); + /* Setup CPU 0 last (important) */ + smp_ops->setup_cpu(0); +} - if ( _machine == _MACH_Pmac ) - { - /* reset the entry point so if we get another intr we won't - * try to startup again */ - out_be32(psurge_start, 0x100); - if (request_irq(30, pmac_primary_intr, 0, "primary IPI", 0)) - printk(KERN_ERR "Couldn't get primary IPI interrupt"); - /* - * The decrementers of both cpus are frozen at this point - * until we give the secondary cpu another interrupt. - * We set them both to decrementer_count and then send - * the interrupt. This should get the decrementers - * synchronized. - * -- paulus. - */ - set_dec(tb_ticks_per_jiffy); - if ((_get_PVR() >> 16) != 1) { - set_tb(0, 0); /* set timebase if not 601 */ - last_jiffy_stamp(0) = 0; +void __init smp_software_tb_sync(int cpu) +{ +#define PASSES 4 /* 4 passes.. */ + int pass; + int i, j; + + /* stop - start will be the number of timebase ticks it takes for cpu0 + * to send a message to all others and the first reponse to show up. + * + * ASSUMPTION: this time is similiar for all cpus + * ASSUMPTION: the time to send a one-way message is ping/2 + */ + register unsigned long start = 0; + register unsigned long stop = 0; + register unsigned long temp = 0; + + if (smp_num_cpus < 2) { + smp_tb_synchronized = 1; + return; + } + + /* This code need fixing on >2 CPUs --BenH/paulus */ + if (smp_num_cpus > 2) { + smp_tb_synchronized = 0; + return; + } + + set_tb(0, 0); + + /* multiple passes to get in l1 cache.. */ + for (pass = 2; pass < 2+PASSES; pass++){ + if (cpu == 0){ + mb(); + for (i = j = 1; i < smp_num_cpus; i++, j++){ + /* skip stuck cpus */ + while (!cpu_callin_map[j]) + ++j; + while (cpu_callin_map[j] != pass) + barrier(); + } + mb(); + tb_sync_flag = pass; + start = get_tbl(); /* start timing */ + while (tb_sync_flag) + mb(); + stop = get_tbl(); /* end timing */ + /* theoretically, the divisor should be 2, but + * I get better results on my dual mtx. someone + * please report results on other smp machines.. + */ + tb_offset = (stop-start)/4; + mb(); + tb_sync_flag = pass; + udelay(10); + mb(); + tb_sync_flag = 0; + mb(); + set_tb(0,0); + mb(); + } else { + cpu_callin_map[cpu] = pass; + mb(); + while (!tb_sync_flag) + mb(); /* wait for cpu0 */ + mb(); + tb_sync_flag = 0; /* send response for timing */ + mb(); + while (!tb_sync_flag) + mb(); + temp = tb_offset; /* make sure offset is loaded */ + while (tb_sync_flag) + mb(); + set_tb(0,temp); /* now, set the timebase */ + mb(); } - out_be32(psurge_sec_intr, ~0); - udelay(1); - out_be32(psurge_sec_intr, 0); } + if (cpu == 0) { + smp_tb_synchronized = 1; + printk("smp_software_tb_sync: %d passes, final offset: %ld\n", + PASSES, tb_offset); + } + /* so time.c doesn't get confused */ + set_dec(tb_ticks_per_jiffy); + last_jiffy_stamp(cpu) = 0; + cpu_callin_map[cpu] = 1; } void __init smp_commence(void) @@ -558,8 +1104,48 @@ void __init smp_commence(void) /* * Lets the callin's below out of their loop. */ + if (ppc_md.progress) ppc_md.progress("smp_commence", 0x370); wmb(); smp_commenced = 1; + /* if the smp_ops->setup_cpu function has not already synched the + * timebases with a nicer hardware-based method, do so now + * + * I am open to suggestions for improvements to this method + * -- Troy <hozer@drgw.net> + * + * NOTE: if you are debugging, set smp_tb_synchronized for now + * since if this code runs pretty early and needs all cpus that + * reported in in smp_callin_map to be working + * + * NOTE2: this code doesn't seem to work on > 2 cpus. -- paulus + */ + if (!smp_tb_synchronized) { + unsigned long flags; + __save_and_cli(flags); + smp_software_tb_sync(0); + __restore_flags(flags); + } +} + +void __init smp_callin(void) +{ + int cpu = current->processor; + + smp_store_cpu_info(cpu); + set_dec(tb_ticks_per_jiffy); + cpu_callin_map[cpu] = 1; + + smp_ops->setup_cpu(cpu); + + init_idle(); + + while(!smp_commenced) + barrier(); + /* see smp_commence for more info */ + if (!smp_tb_synchronized){ + smp_software_tb_sync(cpu); + } + __sti(); } /* intel needs this */ @@ -576,37 +1162,6 @@ int __init start_secondary(void *unused) return cpu_idle(NULL); } -void __init smp_callin(void) -{ - smp_store_cpu_info(current->processor); - set_dec(tb_ticks_per_jiffy); - if (_machine == _MACH_Pmac && (_get_PVR() >> 16) != 1) { - set_tb(0, 0); /* set timebase if not 601 */ - last_jiffy_stamp(current->processor) = 0; - } - init_idle(); - cpu_callin_map[current->processor] = 1; - -#ifndef CONFIG_POWER4 - /* - * Each processor has to do this and this is the best - * place to stick it for now. - * -- Cort - */ - if (OpenPIC && _machine & (_MACH_gemini|_MACH_chrp|_MACH_prep)) - do_openpic_setup_cpu(); -#else - xics_setup_cpu(); -#endif /* CONFIG_POWER4 */ -#ifdef CONFIG_GEMINI - if ( _machine == _MACH_gemini ) - gemini_init_l2(); -#endif - while(!smp_commenced) - barrier(); - __sti(); -} - void __init smp_setup(char *str, int *ints) { } @@ -621,6 +1176,14 @@ void __init smp_store_cpu_info(int id) struct cpuinfo_PPC *c = &cpu_data[id]; /* assume bogomips are same for everything */ - c->loops_per_sec = loops_per_sec; + c->loops_per_jiffy = loops_per_jiffy; c->pvr = _get_PVR(); } + +static int __init maxcpus(char *str) +{ + get_option(&str, &max_cpus); + return 1; +} + +__setup("maxcpus=", maxcpus); diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c index f71c8cbbf..5b36cedcc 100644 --- a/arch/ppc/kernel/time.c +++ b/arch/ppc/kernel/time.c @@ -67,7 +67,12 @@ #include <asm/time.h> -void smp_local_timer_interrupt(struct pt_regs *); +#ifdef CONFIG_SMP +extern void smp_local_timer_interrupt(struct pt_regs *); +extern int smp_tb_synchronized; +#endif /* CONFIG_SMP */ + +extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz); /* keep track of when we need to update the rtc */ time_t last_rtc_update; @@ -97,6 +102,36 @@ static inline int tb_delta(unsigned *jiffy_stamp) { return delta; } +extern unsigned long prof_cpu_mask; +extern unsigned int * prof_buffer; +extern unsigned long prof_len; +extern unsigned long prof_shift; +extern char _stext; + +static inline void ppc_do_profile (unsigned long nip) +{ + if (!prof_buffer) + return; + + /* + * Only measure the CPUs specified by /proc/irq/prof_cpu_mask. + * (default is all CPUs.) + */ + if (!((1<<smp_processor_id()) & prof_cpu_mask)) + return; + + nip -= (unsigned long) &_stext; + nip >>= prof_shift; + /* + * Don't ignore out-of-bounds EIP values silently, + * put them into the last histogram slot, so if + * present, they will show up as a sharp peak. + */ + if (nip > prof_len-1) + nip = prof_len-1; + atomic_inc((atomic_t *)&prof_buffer[nip]); +} + /* * timer_interrupt - gets called when the decrementer overflows, * with interrupts disabled. @@ -110,6 +145,9 @@ int timer_interrupt(struct pt_regs * regs) hardirq_enter(cpu); + if (!user_mode(regs)) + ppc_do_profile(instruction_pointer(regs)); + do { jiffy_stamp += tb_ticks_per_jiffy; if (smp_processor_id()) continue; @@ -151,7 +189,7 @@ int timer_interrupt(struct pt_regs * regs) #ifdef CONFIG_SMP smp_local_timer_interrupt(regs); -#endif +#endif /* CONFIG_SMP */ if (ppc_md.heartbeat && !ppc_md.heartbeat_count--) ppc_md.heartbeat(); @@ -176,7 +214,7 @@ void do_gettimeofday(struct timeval *tv) /* As long as timebases are not in sync, gettimeofday can only * have jiffy resolution on SMP. */ - if (_machine != _MACH_Pmac) + if (!smp_tb_synchronized) delta = 0; #endif /* CONFIG_SMP */ lost_ticks = jiffies - wall_jiffies; diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 3b7473dda..8bd9ebded 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -65,21 +65,37 @@ int (*debugger_dabr_match)(struct pt_regs *regs); void (*debugger_fault_handler)(struct pt_regs *regs); #endif #endif + /* * Trap & Exception support */ + +spinlock_t oops_lock = SPIN_LOCK_UNLOCKED; + +void die(const char * str, struct pt_regs * fp, long err) +{ + console_verbose(); + spin_lock_irq(&oops_lock); + printk("Oops: %s, sig: %ld\n", str, err); + show_regs(fp); + print_backtrace((unsigned long *)fp->gpr[1]); + spin_unlock_irq(&oops_lock); + /* do_exit() should take care of panic'ing from an interrupt + * context so we don't handle it here + */ + do_exit(err); +} + void _exception(int signr, struct pt_regs *regs) { if (!user_mode(regs)) { - show_regs(regs); #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) debugger(regs); #endif - print_backtrace((unsigned long *)regs->gpr[1]); - panic("Exception in kernel pc %lx signal %d",regs->nip,signr); + die("Exception in kernel mode", regs, signr); } force_sig(signr, current); } @@ -98,7 +114,7 @@ MachineCheckException(struct pt_regs *regs) #if defined(CONFIG_8xx) && defined(CONFIG_PCI) /* the qspan pci read routines can cause machine checks -- Cort */ - bad_page_fault(regs, regs->dar); + bad_page_fault(regs, regs->dar, SIGBUS); return; #endif #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) @@ -151,12 +167,10 @@ MachineCheckException(struct pt_regs *regs) default: printk("Unknown values in msr\n"); } - show_regs(regs); #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) debugger(regs); #endif - print_backtrace((unsigned long *)regs->gpr[1]); - panic("machine check"); + die("machine check", regs, SIGBUS); } void @@ -217,13 +231,13 @@ emulate_instruction(struct pt_regs *regs) uint rd; uint retval; - retval = EFAULT; + retval = EINVAL; if (!user_mode(regs)) return retval; if (get_user(instword, (uint *)(regs->nip))) - return retval; + return EFAULT; /* Emulate the mfspr rD, PVR. */ @@ -337,12 +351,10 @@ SoftwareEmulation(struct pt_regs *regs) int errcode; if (!user_mode(regs)) { - show_regs(regs); #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) debugger(regs); #endif - print_backtrace((unsigned long *)regs->gpr[1]); - panic("Kernel Mode Software FPU Emulation"); + die("Kernel Mode Software FPU Emulation", regs, SIGFPE); } #ifdef CONFIG_MATH_EMULATION diff --git a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile index 1e973940c..b6f99174b 100644 --- a/arch/ppc/lib/Makefile +++ b/arch/ppc/lib/Makefile @@ -9,6 +9,6 @@ O_TARGET := lib.o obj-y := checksum.o string.o strcase.o -obj-$(CONFIG_SMP) := locks.o +obj-$(CONFIG_SMP) += locks.o include $(TOPDIR)/Rules.make diff --git a/arch/ppc/lib/locks.c b/arch/ppc/lib/locks.c index 60d8576da..a5b0a40a8 100644 --- a/arch/ppc/lib/locks.c +++ b/arch/ppc/lib/locks.c @@ -58,8 +58,9 @@ void _spin_unlock(spinlock_t *lp) { #ifdef DEBUG_LOCKS if ( !lp->lock ) - printk("_spin_unlock(%p): no lock cpu %d %s/%d\n", lp, - smp_processor_id(),current->comm,current->pid); + printk("_spin_unlock(%p): no lock cpu %d curr PC %p %s/%d\n", + lp, smp_processor_id(), __builtin_return_address(0), + current->comm, current->pid); if ( lp->owner_cpu != smp_processor_id() ) printk("_spin_unlock(%p): cpu %d trying clear of cpu %d pc %lx val %lx\n", lp, smp_processor_id(), (int)lp->owner_cpu, diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c index b6da2cdfc..97bb6dbc1 100644 --- a/arch/ppc/mm/fault.c +++ b/arch/ppc/mm/fault.c @@ -48,7 +48,7 @@ unsigned long pte_errors = 0; /* updated by do_page_fault() */ unsigned int probingmem = 0; extern void die_if_kernel(char *, struct pt_regs *, long); -void bad_page_fault(struct pt_regs *, unsigned long); +void bad_page_fault(struct pt_regs *, unsigned long, int sig); void do_page_fault(struct pt_regs *, unsigned long, unsigned long); /* @@ -96,7 +96,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, #endif /* CONFIG_XMON || CONFIG_KGDB */ if (in_interrupt() || mm == NULL) { - bad_page_fault(regs, address); + bad_page_fault(regs, address, SIGSEGV); return; } down(&mm->mmap_sem); @@ -182,7 +182,7 @@ bad_area: return; } - bad_page_fault(regs, address); + bad_page_fault(regs, address, SIGSEGV); return; /* @@ -194,7 +194,7 @@ out_of_memory: printk("VM: killing process %s\n", current->comm); if (user_mode(regs)) do_exit(SIGKILL); - bad_page_fault(regs, address); + bad_page_fault(regs, address, SIGKILL); return; do_sigbus: @@ -205,7 +205,7 @@ do_sigbus: info.si_addr = (void *)address; force_sig_info (SIGBUS, &info, current); if (!user_mode(regs)) - bad_page_fault(regs, address); + bad_page_fault(regs, address, SIGBUS); } /* @@ -214,8 +214,10 @@ do_sigbus: * in traps.c. */ void -bad_page_fault(struct pt_regs *regs, unsigned long address) +bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) { + extern void die(const char *,struct pt_regs *,long); + unsigned long fixup; /* Are we prepared to handle this fault? */ @@ -225,14 +227,11 @@ bad_page_fault(struct pt_regs *regs, unsigned long address) } /* kernel has accessed a bad area */ - show_regs(regs); #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) if (debugger_kernel_faults) debugger(regs); #endif - print_backtrace( (unsigned long *)regs->gpr[1] ); - panic("kernel access of bad area pc %lx lr %lx address %lX tsk %s/%d", - regs->nip,regs->link,address,current->comm,current->pid); + die("kernel access of bad area", regs, sig); } #ifdef CONFIG_8xx diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index c3d77a67e..839b618d0 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -34,7 +34,6 @@ #include <linux/vmalloc.h> #include <linux/init.h> #include <linux/delay.h> -#include <linux/openpic.h> #include <linux/bootmem.h> #include <linux/highmem.h> #ifdef CONFIG_BLK_DEV_INITRD @@ -62,7 +61,6 @@ #include <asm/machdep.h> #include <asm/setup.h> #include <asm/amigahw.h> -#include <asm/gemini.h> #include "mem_pieces.h" @@ -70,15 +68,17 @@ #include "4xx_tlb.h" #endif -#define MAX_LOW_MEM (640 << 20) +#define MAX_LOW_MEM (512 << 20) #define PGTOKB(pages) (((pages) * PAGE_SIZE) >> 10) int prom_trashed; atomic_t next_mmu_context; +rwlock_t context_overflow_lock __cacheline_aligned = RW_LOCK_UNLOCKED; unsigned long *end_of_DRAM; unsigned long total_memory; unsigned long total_lowmem; +unsigned long ram_phys_base; int mem_init_done; int init_bootmem_done; int boot_mapsize; @@ -114,7 +114,6 @@ static void *MMU_get_page(void); unsigned long prep_find_end_of_memory(void); unsigned long pmac_find_end_of_memory(void); unsigned long apus_find_end_of_memory(void); -unsigned long gemini_find_end_of_memory(void); extern unsigned long find_end_of_memory(void); #ifdef CONFIG_8xx unsigned long m8xx_find_end_of_memory(void); @@ -127,14 +126,13 @@ unsigned long m8260_find_end_of_memory(void); #endif /* CONFIG_8260 */ static void mapin_ram(void); void map_page(unsigned long va, unsigned long pa, int flags); -void set_phys_avail(struct mem_pieces *mp); +void set_phys_avail(unsigned long total_ram); extern void die_if_kernel(char *,struct pt_regs *,long); extern char _start[], _end[]; extern char _stext[], etext[]; extern struct task_struct *current_set[NR_CPUS]; -struct mem_pieces phys_mem; char *klimit = _end; struct mem_pieces phys_avail; @@ -199,6 +197,8 @@ int __map_without_bats; /* max amount of RAM to use */ unsigned long __max_memory; +/* max amount of low RAM to map in */ +unsigned long __max_low_memory = MAX_LOW_MEM; void __bad_pte(pmd_t *pmd) { @@ -399,8 +399,8 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags) * If the address lies within the first 16 MB, assume it's in ISA * memory space */ - if (p < 16*1024*1024) - p += _ISA_MEM_BASE; + if ( p < 16*1024*1024 ) + p += _ISA_MEM_BASE; /* * Don't allow anybody to remap normal RAM that we're using. @@ -437,7 +437,11 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags) return NULL; v = VMALLOC_VMADDR(area->addr); } else { +#ifndef CONFIG_HIGHMEM if (p >= ioremap_base) +#else + if (p >= ioremap_base && p < PKMAP_BASE) +#endif /* CONFIG_HIGHMEM */ v = p; else v = (ioremap_bot -= size); @@ -491,16 +495,13 @@ unsigned long iopa(unsigned long addr) void map_page(unsigned long va, unsigned long pa, int flags) { - pmd_t *pd, oldpd; + pmd_t *pd; pte_t *pg; /* Use upper 10 bits of VA to index the first level map */ pd = pmd_offset(pgd_offset_k(va), va); - oldpd = *pd; /* Use middle 10 bits of VA to index the second-level map */ pg = pte_alloc(pd, va); - if (pmd_none(oldpd) && mem_init_done) - set_pgdir(va, *(pgd_t *)pd); set_pte(pg, mk_pte_phys(pa & PAGE_MASK, __pgprot(flags))); if (mem_init_done) flush_hash_page(0, va); @@ -532,6 +533,8 @@ local_flush_tlb_all(void) * 0xd0000000 on 64-bit machines. */ flush_hash_segments(0xd, 0xffffff); #else + /* this could cause problems on SMP with nobats -- paulus */ + /* XXX no hash_table_lock? interesting -- paulus */ __clear_user(Hash, Hash_size); _tlbia(); #ifdef CONFIG_SMP @@ -548,6 +551,27 @@ local_flush_tlb_all(void) void local_flush_tlb_mm(struct mm_struct *mm) { + if (mm->context == 0) { + /* don't try to reassign a new context to the kernel */ + /* + * This could cause problems on SMP if we aren't using + * the BATs (e.g. on POWER4 or if the nobats option is used). + * The problem scenario is that one cpu is doing + * flush_hash_page or similar when another cpu clears + * out the HPTEs which map the flush_hash_page text + * and the hash table. hash_page will then deadlock. + * We need some way to have "protected" HPTEs or else + * do all hash-table manipulation with the MMU off. + * -- paulus. + */ +#ifdef CONFIG_PPC64BRIDGE + flush_hash_segments(0xd, 0xf); +#else + flush_hash_segments(0xc, 0xf); +#endif CONFIG_PPC64BRIDGE + _tlbia(); + return; + } mm->context = NO_CONTEXT; if (mm == current->mm) activate_mm(mm, mm); @@ -581,16 +605,18 @@ local_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long e { start &= PAGE_MASK; - if (end - start > 20 * PAGE_SIZE) - { - flush_tlb_mm(mm); - return; + if (mm->context != 0) { + if (end > TASK_SIZE) + end = TASK_SIZE; + if (end - start > 20 * PAGE_SIZE) { + flush_tlb_mm(mm); + return; + } } - for (; start < end && start < TASK_SIZE; start += PAGE_SIZE) - { + for (; start < end; start += PAGE_SIZE) flush_hash_page(mm->context, start); - } + #ifdef CONFIG_SMP smp_send_tlb_invalidate(0); #endif @@ -608,23 +634,36 @@ mmu_context_overflow(void) struct task_struct *tsk; printk(KERN_DEBUG "mmu_context_overflow\n"); - read_lock(&tasklist_lock); - for_each_task(tsk) { - if (tsk->mm) - tsk->mm->context = NO_CONTEXT; - } - read_unlock(&tasklist_lock); - flush_hash_segments(0x10, 0xffffff); + /* acquire the write lock for context overflow */ + write_lock (&context_overflow_lock); + /* recheck if overflow still exists */ + if (atomic_read(&next_mmu_context) == LAST_CONTEXT) { + read_lock(&tasklist_lock); + for_each_task(tsk) { + if (tsk->mm) + tsk->mm->context = NO_CONTEXT; + } + read_unlock(&tasklist_lock); + flush_hash_segments(0x10, 0xffffff); #ifdef CONFIG_SMP - smp_send_tlb_invalidate(0); + smp_send_tlb_invalidate(0); #endif - atomic_set(&next_mmu_context, 0); + atomic_set(&next_mmu_context, 0); + } + write_unlock (&context_overflow_lock); /* make sure current always has a context */ - current->mm->context = MUNGE_CONTEXT(atomic_inc_return(&next_mmu_context)); - /* The PGD is only a placeholder. It is only used on - * 8xx processors. - */ - set_context(current->mm->context, current->mm->pgd); + /* need to check to assure current task has an mm */ + /* - idle thread does not have an MM */ + if (current->mm) { + current->mm->context = MUNGE_CONTEXT(atomic_inc_return(&next_mmu_context)); + set_context(current->mm->context, current->mm->pgd); + } +} +#else /* CONFIG_8xx */ +void +mmu_context_overflow(void) +{ + atomic_set(&next_mmu_context, -1); } #endif /* CONFIG_8xx */ @@ -727,22 +766,20 @@ void __init setbat(int index, unsigned long virt, unsigned long phys, static void __init mapin_ram(void) { - int i; unsigned long v, p, s, f; #if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) && !defined(CONFIG_POWER4) if (!__map_without_bats) { - unsigned long tot, mem_base, bl, done; + unsigned long tot, bl, done; unsigned long max_size = (256<<20); unsigned long align; /* Set up BAT2 and if necessary BAT3 to cover RAM. */ - mem_base = __pa(KERNELBASE); /* Make sure we don't map a block larger than the smallest alignment of the physical address. */ - /* alignment of mem_base */ - align = ~(mem_base-1) & mem_base; + /* alignment of ram_phys_base */ + align = ~(ram_phys_base-1) & ram_phys_base; /* set BAT block size to MIN(max_size, align) */ if (align && align < max_size) max_size = align; @@ -753,7 +790,7 @@ static void __init mapin_ram(void) break; } - setbat(2, KERNELBASE, mem_base, bl, RAM_PAGE); + setbat(2, KERNELBASE, ram_phys_base, bl, RAM_PAGE); done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1; if ((done < tot) && !bat_addrs[3].limit) { /* use BAT3 to cover a bit more */ @@ -761,41 +798,35 @@ static void __init mapin_ram(void) for (bl = 128<<10; bl < max_size; bl <<= 1) if (bl * 2 > tot) break; - setbat(3, KERNELBASE+done, mem_base+done, bl, + setbat(3, KERNELBASE+done, ram_phys_base+done, bl, RAM_PAGE); } } #endif /* !CONFIG_4xx && !CONFIG_8xx && !CONFIG_POWER4 */ - for (i = 0; i < phys_mem.n_regions; ++i) { - v = (ulong)__va(phys_mem.regions[i].address); - p = phys_mem.regions[i].address; - if (p >= total_lowmem) - break; - for (s = 0; s < phys_mem.regions[i].size; s += PAGE_SIZE) { - /* On the MPC8xx, we want the page shared so we - * don't get ASID compares on kernel space. - */ - f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED; + v = KERNELBASE; + p = ram_phys_base; + for (s = 0; s < total_lowmem; s += PAGE_SIZE) { + /* On the MPC8xx, we want the page shared so we + * don't get ASID compares on kernel space. + */ + f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED; #if defined(CONFIG_KGDB) || defined(CONFIG_XMON) - /* Allows stub to set breakpoints everywhere */ - f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE; + /* Allows stub to set breakpoints everywhere */ + f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE; #else - if ((char *) v < _stext || (char *) v >= etext) - f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE; + if ((char *) v < _stext || (char *) v >= etext) + f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE; #ifndef CONFIG_8xx - else - /* On the powerpc (not 8xx), no user access - forces R/W kernel access */ - f |= _PAGE_USER; + else + /* On the powerpc (not 8xx), no user access + forces R/W kernel access */ + f |= _PAGE_USER; #endif /* CONFIG_8xx */ #endif /* CONFIG_KGDB */ - map_page(v, p, f); - v += PAGE_SIZE; - p += PAGE_SIZE; - if (p >= total_lowmem) - break; - } + map_page(v, p, f); + v += PAGE_SIZE; + p += PAGE_SIZE; } } @@ -922,27 +953,64 @@ MMU_init(void) mtspr(SPRN_DCCR, 0x80000000); /* 128 MB of data space at 0x0. */ mtspr(SPRN_ICCR, 0x80000000); /* 128 MB of instr. space at 0x0. */ } -#else - /* How about ppc_md.md_find_end_of_memory instead of these - * ifdefs? -- Dan. - */ -#ifdef CONFIG_BOOTX_TEXT -extern boot_infos_t *disp_bi; + +#elif defined(CONFIG_8xx) +void __init MMU_init(void) +{ + if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111); + + total_memory = total_lowmem = m8xx_find_end_of_memory(); +#ifdef CONFIG_HIGHMEM + if (total_lowmem > MAX_LOW_MEM) { + total_lowmem = MAX_LOW_MEM; + mem_pieces_remove(&phys_avail, total_lowmem, + total_memory - total_lowmem, 0); + } +#endif /* CONFIG_HIGHMEM */ + end_of_DRAM = __va(total_lowmem); + set_phys_avail(total_lowmem); + + /* Map in all of RAM starting at KERNELBASE */ + mapin_ram(); + + /* Now map in some of the I/O space that is generically needed + * or shared with multiple devices. + * All of this fits into the same 4Mbyte region, so it only + * requires one page table page. + */ + ioremap(IMAP_ADDR, IMAP_SIZE); +#ifdef CONFIG_MBX + ioremap(NVRAM_ADDR, NVRAM_SIZE); + ioremap(MBX_CSR_ADDR, MBX_CSR_SIZE); + ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE); + + /* Map some of the PCI/ISA I/O space to get the IDE interface. + */ + ioremap(PCI_ISA_IO_ADDR, 0x4000); + ioremap(PCI_IDE_ADDR, 0x4000); +#endif +#ifdef CONFIG_RPXLITE + ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE); + ioremap(HIOX_CSR_ADDR, HIOX_CSR_SIZE); +#endif +#ifdef CONFIG_RPXCLASSIC + ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE); + ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE); #endif + if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211); +} + +#else /* not 4xx or 8xx */ void __init MMU_init(void) { if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111); -#ifndef CONFIG_8xx + if (have_of) total_memory = pmac_find_end_of_memory(); #ifdef CONFIG_APUS else if (_machine == _MACH_apus ) total_memory = apus_find_end_of_memory(); #endif -#ifdef CONFIG_GEMINI - else if ( _machine == _MACH_gemini ) - total_memory = gemini_find_end_of_memory(); -#endif /* CONFIG_GEMINI */ #if defined(CONFIG_8260) else total_memory = m8260_find_end_of_memory(); @@ -950,16 +1018,17 @@ void __init MMU_init(void) else /* prep */ total_memory = prep_find_end_of_memory(); #endif - + if (__max_memory && total_memory > __max_memory) + total_memory = __max_memory; total_lowmem = total_memory; -#ifdef CONFIG_HIGHMEM - if (total_lowmem > MAX_LOW_MEM) { - total_lowmem = MAX_LOW_MEM; - mem_pieces_remove(&phys_avail, total_lowmem, - total_memory - total_lowmem, 0); - } + if (total_lowmem > __max_low_memory) { + total_lowmem = __max_low_memory; +#ifndef CONFIG_HIGHMEM + total_memory = total_lowmem; #endif /* CONFIG_HIGHMEM */ + } end_of_DRAM = __va(total_lowmem); + set_phys_avail(total_lowmem); if ( ppc_md.progress ) ppc_md.progress("MMU:hash init", 0x300); hash_init(); @@ -991,12 +1060,15 @@ void __init MMU_init(void) ioremap_base = 0xf0000000; break; case _MACH_chrp: - setbat(0, 0xf8000000, 0xf8000000, 0x08000000, IO_PAGE); -#ifdef CONFIG_PPC64BRIDGE - setbat(1, 0x80000000, 0xc0000000, 0x10000000, IO_PAGE); -#else - setbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE); - setbat(3, 0x90000000, 0x90000000, 0x10000000, IO_PAGE); + /* + * The code below tends to get removed, please don't take it out. + * The F50 needs this mapping and it you take it out I'll track you + * down and slap your hands. If it causes problems please email me. + * -- Cort <cort@fsmlabs.com> + */ +#ifndef CONFIG_POWER3 + setbat(0, 0x80000000, 0x80000000, 0x10000000, IO_PAGE); + setbat(1, 0x90000000, 0x90000000, 0x10000000, IO_PAGE); #endif break; case _MACH_Pmac: @@ -1008,10 +1080,6 @@ void __init MMU_init(void) /* Map chip and ZorroII memory */ setbat(1, zTwoBase, 0x00000000, 0x01000000, IO_PAGE); break; - case _MACH_gemini: - setbat(0, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE); - setbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE); - break; case _MACH_8260: /* Map the IMMR, plus anything else we can cover * in that upper space according to the memory controller @@ -1025,46 +1093,7 @@ void __init MMU_init(void) } ioremap_bot = ioremap_base; #endif /* CONFIG_POWER4 */ -#else /* CONFIG_8xx */ - - total_memory = total_lowmem = m8xx_find_end_of_memory(); -#ifdef CONFIG_HIGHMEM - if (total_lowmem > MAX_LOW_MEM) { - total_lowmem = MAX_LOW_MEM; - mem_pieces_remove(&phys_avail, total_lowmem, - total_memory - total_lowmem, 0); - } -#endif /* CONFIG_HIGHMEM */ - end_of_DRAM = __va(total_lowmem); - - /* Map in all of RAM starting at KERNELBASE */ - mapin_ram(); - - /* Now map in some of the I/O space that is generically needed - * or shared with multiple devices. - * All of this fits into the same 4Mbyte region, so it only - * requires one page table page. - */ - ioremap(IMAP_ADDR, IMAP_SIZE); -#ifdef CONFIG_MBX - ioremap(NVRAM_ADDR, NVRAM_SIZE); - ioremap(MBX_CSR_ADDR, MBX_CSR_SIZE); - ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE); - /* Map some of the PCI/ISA I/O space to get the IDE interface. - */ - ioremap(PCI_ISA_IO_ADDR, 0x4000); - ioremap(PCI_IDE_ADDR, 0x4000); -#endif -#ifdef CONFIG_RPXLITE - ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE); - ioremap(HIOX_CSR_ADDR, HIOX_CSR_SIZE); -#endif -#ifdef CONFIG_RPXCLASSIC - ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE); - ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE); -#endif -#endif /* CONFIG_8xx */ if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211); #ifdef CONFIG_BOOTX_TEXT /* Must be done last, or ppc_md.progress will die */ @@ -1189,7 +1218,8 @@ void __init mem_init(void) #if defined(CONFIG_ALL_PPC) /* mark the RTAS pages as reserved */ if ( rtas_data ) - for (addr = rtas_data; addr < PAGE_ALIGN(rtas_data+rtas_size) ; + for (addr = (ulong)__va(rtas_data); + addr < PAGE_ALIGN((ulong)__va(rtas_data)+rtas_size) ; addr += PAGE_SIZE) SetPageReserved(virt_to_page(addr)); #endif /* defined(CONFIG_ALL_PPC) */ @@ -1249,7 +1279,7 @@ void __init mem_init(void) unsigned long __init pmac_find_end_of_memory(void) { unsigned long a, total; - unsigned long ram_limit = 0xe0000000 - KERNELBASE; + struct mem_pieces phys_mem; memory_node = find_devices("memory"); if (memory_node == NULL) { @@ -1260,8 +1290,7 @@ unsigned long __init pmac_find_end_of_memory(void) /* * Find out where physical memory is, and check that it * starts at 0 and is contiguous. It seems that RAM is - * always physically contiguous on Power Macintoshes, - * because MacOS can't cope if it isn't. + * always physically contiguous on Power Macintoshes. * * Supporting discontiguous physical memory isn't hard, * it just makes the virtual <-> physical mapping functions @@ -1274,23 +1303,14 @@ unsigned long __init pmac_find_end_of_memory(void) a = phys_mem.regions[0].address; if (a != 0) panic("RAM doesn't start at physical address 0"); - if (__max_memory == 0 || __max_memory > ram_limit) - __max_memory = ram_limit; - if (phys_mem.regions[0].size >= __max_memory) { - phys_mem.regions[0].size = __max_memory; - phys_mem.n_regions = 1; - } total = phys_mem.regions[0].size; - + if (phys_mem.n_regions > 1) { printk("RAM starting at 0x%x is not contiguous\n", phys_mem.regions[1].address); printk("Using RAM from 0 to 0x%lx\n", total-1); - phys_mem.n_regions = 1; } - set_phys_avail(&phys_mem); - return total; } #endif /* CONFIG_ALL_PPC */ @@ -1305,7 +1325,11 @@ unsigned long __init pmac_find_end_of_memory(void) unsigned long __init prep_find_end_of_memory(void) { unsigned long total; +#ifdef CONFIG_PREP_RESIDUAL total = res->TotalMemory; +#else + total = 0; +#endif if (total == 0 ) { @@ -1317,33 +1341,11 @@ unsigned long __init prep_find_end_of_memory(void) total = 0x02000000; printk("Ramsize default to be %ldM\n", total>>20); } - mem_pieces_append(&phys_mem, 0, total); - set_phys_avail(&phys_mem); return (total); } #endif /* defined(CONFIG_ALL_PPC) */ - -#if defined(CONFIG_GEMINI) -unsigned long __init gemini_find_end_of_memory(void) -{ - unsigned long total; - unsigned char reg; - - reg = readb(GEMINI_MEMCFG); - total = ((1<<((reg & 0x7) - 1)) * - (8<<((reg >> 3) & 0x7))); - total *= (1024*1024); - phys_mem.regions[0].address = 0; - phys_mem.regions[0].size = total; - phys_mem.n_regions = 1; - - set_phys_avail(&phys_mem); - return phys_mem.regions[0].size; -} -#endif /* defined(CONFIG_GEMINI) */ - #ifdef CONFIG_8260 /* * Same hack as 8xx. @@ -1355,12 +1357,7 @@ unsigned long __init m8260_find_end_of_memory(void) binfo = (bd_t *)__res; - phys_mem.regions[0].address = 0; - phys_mem.regions[0].size = binfo->bi_memsize; - phys_mem.n_regions = 1; - - set_phys_avail(&phys_mem); - return phys_mem.regions[0].size; + return binfo->bi_memsize; } #endif /* CONFIG_8260 */ @@ -1369,6 +1366,7 @@ unsigned long __init m8260_find_end_of_memory(void) unsigned long __init apus_find_end_of_memory(void) { int shadow = 0; + unsigned long total; /* The memory size reported by ADOS excludes the 512KB reserved for PPC exception registers and possibly 512KB @@ -1394,43 +1392,28 @@ unsigned long __init apus_find_end_of_memory(void) memory[0].size = ((size+0x001fffff) & 0xffe00000); } - /* Now register the memory block. */ - mem_pieces_append(&phys_mem, memory[0].addr, memory[0].size); - set_phys_avail(&phys_mem); + total = memory[0].size; /* Remove the memory chunks that are controlled by special Phase5 hardware. */ - { - unsigned long top = memory[0].addr + memory[0].size; - /* Remove the upper 512KB if it contains a shadow of - the ADOS ROM. FIXME: It might be possible to - disable this shadow HW. Check the booter - (ppc_boot.c) */ - if (shadow) - { - top -= HARDWARE_MAPPED_SIZE; - mem_pieces_remove(&phys_avail, top, - HARDWARE_MAPPED_SIZE, 0); - } - - /* Remove the upper 512KB where the PPC exception - vectors are mapped. */ - top -= HARDWARE_MAPPED_SIZE; -#if 0 - /* This would be neat, but it breaks on A3000 machines!? */ - mem_pieces_remove(&phys_avail, top, 16384, 0); -#else - mem_pieces_remove(&phys_avail, top, HARDWARE_MAPPED_SIZE, 0); -#endif + /* Remove the upper 512KB if it contains a shadow of + the ADOS ROM. FIXME: It might be possible to + disable this shadow HW. Check the booter + (ppc_boot.c) */ + if (shadow) + total -= HARDWARE_MAPPED_SIZE; - } + /* Remove the upper 512KB where the PPC exception + vectors are mapped. */ + total -= HARDWARE_MAPPED_SIZE; /* Linux/APUS only handles one block of memory -- the one on the PowerUP board. Other system memory is horrible slow in comparison. The user can use other memory for swapping using the z2ram device. */ - return memory[0].addr + memory[0].size; + ram_phys_base = memory[0].addr; + return total; } #endif /* CONFIG_APUS */ @@ -1440,12 +1423,11 @@ unsigned long __init apus_find_end_of_memory(void) static void __init hash_init(void) { int Hash_bits, mb, mb2; - unsigned int hmask, ramsize, h; + unsigned int hmask, h; extern unsigned int hash_page_patch_A[], hash_page_patch_B[], hash_page_patch_C[], hash_page[]; - ramsize = (ulong)end_of_DRAM - KERNELBASE; #ifdef CONFIG_PPC64BRIDGE /* The hash table has already been allocated and initialized in prom.c */ @@ -1464,7 +1446,7 @@ static void __init hash_init(void) * Allow 64k of hash table for every 16MB of memory, * up to a maximum of 2MB. */ - for (h = 64<<10; h < ramsize / 256 && h < (2<<20); h *= 2) + for (h = 64<<10; h < total_memory / 256 && h < (2<<20); h *= 2) ; Hash_size = h; Hash_mask = (h >> 6) - 1; @@ -1498,8 +1480,8 @@ static void __init hash_init(void) Hash = 0; #endif /* CONFIG_PPC64BRIDGE */ - printk("Total memory = %dMB; using %ldkB for hash table (at %p)\n", - ramsize >> 20, Hash_size >> 10, Hash); + printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n", + total_memory >> 20, Hash_size >> 10, Hash); if ( Hash_size ) { if ( ppc_md.progress ) ppc_md.progress("hash:patch", 0x345); @@ -1560,12 +1542,7 @@ unsigned long __init m8xx_find_end_of_memory(void) binfo = (bd_t *)__res; - phys_mem.regions[0].address = 0; - phys_mem.regions[0].size = binfo->bi_memsize; - phys_mem.n_regions = 1; - - set_phys_avail(&phys_mem); - return phys_mem.regions[0].address + phys_mem.regions[0].size; + return binfo->bi_memsize; } #endif /* !CONFIG_4xx && !CONFIG_8xx */ @@ -1582,20 +1559,16 @@ oak_find_end_of_memory(void) unsigned long *ret; bd_t *bip = (bd_t *)__res; - phys_mem.regions[0].address = 0; - phys_mem.regions[0].size = bip->bi_memsize; - phys_mem.n_regions = 1; - - set_phys_avail(&phys_mem); - return (phys_mem.regions[0].address + phys_mem.regions[0].size); + return bip->bi_memsize; } #endif /* - * Set phys_avail to phys_mem less the kernel text/data/bss. + * Set phys_avail to the amount of physical memory, + * less the kernel text/data/bss. */ void __init -set_phys_avail(struct mem_pieces *mp) +set_phys_avail(unsigned long total_memory) { unsigned long kstart, ksize; @@ -1604,7 +1577,9 @@ set_phys_avail(struct mem_pieces *mp) * physical memory. */ - phys_avail = *mp; + phys_avail.regions[0].address = 0; + phys_avail.regions[0].size = total_memory; + phys_avail.n_regions = 1; /* * Map out the kernel text/data/bss from the available physical diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c index 499c5b6c8..611b1e069 100644 --- a/arch/ppc/xmon/start.c +++ b/arch/ppc/xmon/start.c @@ -14,6 +14,10 @@ #include <asm/bootx.h> #include <asm/feature.h> #include <asm/processor.h> +#include <asm/delay.h> +#ifdef CONFIG_SMP +#include <asm/bitops.h> +#endif static volatile unsigned char *sccc, *sccd; unsigned long TXRDY, RXRDY; @@ -22,10 +26,10 @@ extern void prom_drawchar(char); extern void prom_drawstring(const char *str); static int xmon_expect(const char *str, unsigned int timeout); -static int console = 0; -static int use_screen = 1; /* default */ -static int via_modem = 0; -static int xmon_use_sccb = 0; +static int console; +static int use_screen; +static int via_modem = 1; +static int xmon_use_sccb; static struct device_node *macio_node; #define TB_SPEED 25000000 @@ -53,28 +57,32 @@ xmon_map_scc(void) use_screen = 0; - if ( _machine == _MACH_Pmac ) - { + if (_machine == _MACH_Pmac) { struct device_node *np; unsigned long addr; #ifdef CONFIG_BOOTX_TEXT extern boot_infos_t *disp_bi; + /* see if there is a keyboard in the device tree + with a parent of type "adb" */ + for (np = find_devices("keyboard"); np; np = np->next) + if (np->parent && np->parent->type + && strcmp(np->parent->type, "adb") == 0) + break; + /* needs to be hacked if xmon_printk is to be used from within find_via_pmu() */ #ifdef CONFIG_ADB_PMU - if (!via_modem && disp_bi && find_via_pmu()) { - prom_drawstring("xmon uses screen and keyboard\n"); + if (np != NULL && disp_bi && find_via_pmu()) use_screen = 1; - } #endif #ifdef CONFIG_ADB_CUDA - if (!via_modem && disp_bi ) { - prom_drawstring("xmon uses screen and keyboard\n"); + if (np != NULL && disp_bi && find_via_cuda()) use_screen = 1; - } -#endif #endif + if (use_screen) + prom_drawstring("xmon uses screen and keyboard\n"); +#endif /* CONFIG_BOOTX_TEXT */ #ifdef CHRP_ESCC addr = 0xc1013020; @@ -93,15 +101,6 @@ xmon_map_scc(void) sccc = base + (addr & ~PAGE_MASK); sccd = sccc + 0x10; } - else if ( _machine & _MACH_gemini ) - { - /* should already be mapped by the kernel boot */ - sccc = (volatile unsigned char *) 0xffeffb0d; - sccd = (volatile unsigned char *) 0xffeffb08; - TXRDY = 0x20; - RXRDY = 1; - console = 1; - } else { /* should already be mapped by the kernel boot */ @@ -140,12 +139,22 @@ xmon_write(void *handle, void *ptr, int nb) char *p = ptr; int i, c, ct; +#ifdef CONFIG_SMP + static unsigned long xmon_write_lock; + int lock_wait = 1000000; + int locked; + + while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0) + if (--lock_wait == 0) + break; +#endif + #ifdef CONFIG_BOOTX_TEXT if (use_screen) { /* write it on the screen */ for (i = 0; i < nb; ++i) prom_drawchar(*p++); - return nb; + goto out; } #endif if (!scc_initialized) @@ -166,8 +175,15 @@ xmon_write(void *handle, void *ptr, int nb) } buf_access(); *sccd = c; + eieio(); } - return i; + + out: +#ifdef CONFIG_SMP + if (!locked) + clear_bit(0, &xmon_write_lock); +#endif + return nb; } int xmon_wants_key; diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c index 49c3be834..65082d458 100644 --- a/arch/ppc/xmon/xmon.c +++ b/arch/ppc/xmon/xmon.c @@ -406,6 +406,7 @@ cmds(struct pt_regs *excp) break; case 'M': print_sysmap(); + break; case 'S': super_regs(); break; @@ -795,6 +796,8 @@ print_sysmap(void) extern char *sysmap; if ( sysmap ) printf("System.map: \n%s", sysmap); + else + printf("No System.map\n"); } void |