diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-02-15 02:15:32 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-02-15 02:15:32 +0000 |
commit | 86464aed71025541805e7b1515541aee89879e33 (patch) | |
tree | e01a457a4912a8553bc65524aa3125d51f29f810 /arch/ppc | |
parent | 88f99939ecc6a95a79614574cb7d95ffccfc3466 (diff) |
Merge with Linux 2.2.1.
Diffstat (limited to 'arch/ppc')
42 files changed, 1043 insertions, 347 deletions
diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c index 8c3401d6f..126b724be 100644 --- a/arch/ppc/8xx_io/enet.c +++ b/arch/ppc/8xx_io/enet.c @@ -1,4 +1,5 @@ /* + * $Id: enet.c,v 1.8 1998/11/15 19:58:07 cort Exp $ * Ethernet driver for Motorola MPC8xx. * Copyright (c) 1997 Dan Malek (dmalek@jlc.net) * @@ -657,7 +658,7 @@ __initfunc(int cpm_enet_init(void)) cp = cpmp; /* Get pointer to Communication Processor */ - immap = (immap_t *)MBX_IMAP_ADDR; /* and to internal registers */ + immap = (immap_t *)IMAP_ADDR; /* and to internal registers */ /* Allocate some private information. */ @@ -719,11 +720,11 @@ __initfunc(int cpm_enet_init(void)) * These are relative offsets in the DP ram address space. * Initialize base addresses for the buffer descriptors. */ - i = mbx_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE); + i = m8xx_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE); ep->sen_genscc.scc_rbase = i; cep->rx_bd_base = (cbd_t *)&cp->cp_dpmem[i]; - i = mbx_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE); + i = m8xx_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE); ep->sen_genscc.scc_tbase = i; cep->tx_bd_base = (cbd_t *)&cp->cp_dpmem[i]; @@ -912,4 +913,3 @@ __initfunc(int cpm_enet_init(void)) return 0; } - diff --git a/arch/ppc/8xx_io/uart.c b/arch/ppc/8xx_io/uart.c index fdbd0c796..94901245f 100644 --- a/arch/ppc/8xx_io/uart.c +++ b/arch/ppc/8xx_io/uart.c @@ -1692,7 +1692,7 @@ static void rs_8xx_wait_until_sent(struct tty_struct *tty, int timeout) schedule_timeout(char_time); if (signal_pending(current)) break; - if (timeout && ((orig_jiffies + timeout) < jiffies)) + if (timeout && time_after(jiffies, orig_jiffies + timeout)) break; bdp = info->tx_cur; } while (bdp->cbd_sc & BD_SC_READY); diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index cd98b4513..990b24b84 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -16,8 +16,6 @@ KERNELLOAD =0xc0000000 ifeq ($(shell uname -m),ppc) CHECKS = checks -else -CROSS_COMPILE = ppc-linux-elf- endif ASFLAGS = diff --git a/arch/ppc/amiga/amiints.c b/arch/ppc/amiga/amiints.c index 690173cc9..e8f72f298 100644 --- a/arch/ppc/amiga/amiints.c +++ b/arch/ppc/amiga/amiints.c @@ -19,7 +19,7 @@ * - IRQ_FLG_SLOW: handler is inserted at bottom of list and before * they're executed irq level is set to the previous * one, but handlers don't need to be reentrant, if - * reentrance occured, slow handlers will be just + * reentrance occurred, slow handlers will be just * called again. * The whole interrupt handling for CIAs is moved to cia.c * /Roman Zippel @@ -396,7 +396,7 @@ void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server) for (;;) { for (; node; node = node->next) node->handler(irq, node->dev_id, fp); - /* if reentrance occured, serve slow handlers again */ + /* if reentrance occurred, serve slow handlers again */ custom.intena = ami_intena_vals[irq]; if (!server->reentrance) { server->count--; diff --git a/arch/ppc/amiga/bootinfo.c b/arch/ppc/amiga/bootinfo.c index f24a0c5b8..7639de68e 100644 --- a/arch/ppc/amiga/bootinfo.c +++ b/arch/ppc/amiga/bootinfo.c @@ -17,8 +17,8 @@ extern char cmd_line[CL_SIZE]; int num_memory = 0; -extern struct mem_info memory[NUM_MEMINFO]; -extern struct mem_info ramdisk; +struct mem_info memory[NUM_MEMINFO]; +struct mem_info ramdisk; extern int amiga_parse_bootinfo(const struct bi_record *); extern int atari_parse_bootinfo(const struct bi_record *); diff --git a/arch/ppc/amiga/config.c b/arch/ppc/amiga/config.c index f79172390..2335adfb9 100644 --- a/arch/ppc/amiga/config.c +++ b/arch/ppc/amiga/config.c @@ -742,7 +742,7 @@ static void amiga_savekmsg_init(void) static void amiga_serial_putc(char c) { custom.serdat = (unsigned char)c | 0x100; - iobarrier (); + iobarrier_rw (); while (!(custom.serdatr & 0x2000)) ; } diff --git a/arch/ppc/apus_defconfig b/arch/ppc/apus_defconfig index 1e9499a9c..c9f900cfe 100644 --- a/arch/ppc/apus_defconfig +++ b/arch/ppc/apus_defconfig @@ -14,6 +14,7 @@ CONFIG_PMAC=y # CONFIG_ALL_PPC is not set # CONFIG_APUS is not set # CONFIG_MBX is not set +# CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y # diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile index fde1ad4c6..da4945fd7 100644 --- a/arch/ppc/boot/Makefile +++ b/arch/ppc/boot/Makefile @@ -48,6 +48,9 @@ OBJECTS += mbxtty.o CFLAGS += -DCONFIG_MBX else OBJECTS += vreset.o kbd.o + ifeq ($(CONFIG_SERIAL_CONSOLE),y) + OBJECTS += ns16550.o + endif endif all: zImage diff --git a/arch/ppc/boot/misc.c b/arch/ppc/boot/misc.c index 42cb533da..470e1e4a9 100644 --- a/arch/ppc/boot/misc.c +++ b/arch/ppc/boot/misc.c @@ -1,7 +1,7 @@ /* * misc.c * - * $Id: misc.c,v 1.52 1998/09/19 01:21:24 cort Exp $ + * $Id: misc.c,v 1.53 1998/12/15 17:40:15 cort Exp $ * * Adapted for PowerPC by Gary Thomas * @@ -12,7 +12,7 @@ #include <linux/types.h> #include "../coffboot/zlib.h" #include "asm/residual.h" -#include <elf.h> +#include <linux/elf.h> #include <linux/config.h> #include <asm/page.h> #include <asm/processor.h> @@ -23,6 +23,10 @@ #ifdef CONFIG_FADS #include <asm/fads.h> #endif +#if defined(CONFIG_SERIAL_CONSOLE) && !defined(CONFIG_MBX) +#include "ns16550.h" +struct NS16550 *com_port; +#endif /* CONFIG_SERIAL_CONSOLE */ /* * Please send me load/board info and such data for hardware not @@ -42,6 +46,7 @@ char *end_avail; * save here and pass to the kernel (command line and board info). * On the MBX we grab some known memory holes to hold this information. */ +char cmd_preset[] = "console=tty0 console=ttyS0,9600n8"; char cmd_buf[256]; char *cmd_line = cmd_buf; @@ -108,12 +113,19 @@ static void scroll() tstc(void) { +#if defined(CONFIG_SERIAL_CONSOLE) && !defined(CONFIG_MBX) + return (CRT_tstc() || NS16550_tstc(com_port)); +#else return (CRT_tstc() ); +#endif /* CONFIG_SERIAL_CONSOLE */ } getc(void) { while (1) { +#if defined(CONFIG_SERIAL_CONSOLE) && !defined(CONFIG_MBX) + if (NS16550_tstc(com_port)) return (NS16550_getc(com_port)); +#endif /* CONFIG_SERIAL_CONSOLE */ if (CRT_tstc()) return (CRT_getc()); } } @@ -123,6 +135,11 @@ putc(const char c) { int x,y; +#if defined(CONFIG_SERIAL_CONSOLE) && !defined(CONFIG_MBX) + NS16550_putc(com_port, c); + if ( c == '\n' ) NS16550_putc(com_port, '\r'); +#endif /* CONFIG_SERIAL_CONSOLE */ + x = orig_x; y = orig_y; @@ -162,12 +179,21 @@ void puts(const char *s) y = orig_y; while ( ( c = *s++ ) != '\0' ) { +#if defined(CONFIG_SERIAL_CONSOLE) && !defined(CONFIG_MBX) + NS16550_putc(com_port, c); + if ( c == '\n' ) NS16550_putc(com_port, '\r'); +#endif /* CONFIG_SERIAL_CONSOLE */ + if ( c == '\n' ) { x = 0; if ( ++y >= lines ) { scroll(); y--; } + } else if (c == '\b') { + if (x > 0) { + x--; + } } else { vidmem [ ( x + cols * y ) * 2 ] = c; if ( ++x >= cols ) { @@ -358,6 +384,10 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, R _put_MSR(_get_MSR() & ~0x0030); vga_init(0xC0000000); +#if defined(CONFIG_SERIAL_CONSOLE) && !defined(CONFIG_MBX) + com_port = (struct NS16550 *)NS16550_init(0); +#endif /* CONFIG_SERIAL_CONSOLE */ + if (residual) memcpy(hold_residual,residual,sizeof(RESIDUAL)); #else /* CONFIG_MBX */ @@ -510,6 +540,8 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, R puts("\nLinux/PPC load: "); timer = 0; cp = cmd_line; + memcpy (cmd_line, cmd_preset, sizeof(cmd_preset)); + while ( *cp ) putc(*cp++); while (timer++ < 5*1000) { if (tstc()) { while ((ch = getc()) != '\n' && ch != '\r') { diff --git a/arch/ppc/boot/ns16550.c b/arch/ppc/boot/ns16550.c new file mode 100644 index 000000000..db0b94d03 --- /dev/null +++ b/arch/ppc/boot/ns16550.c @@ -0,0 +1,56 @@ +/* + * COM1 NS16550 support + */ + +#include "ns16550.h" +typedef struct NS16550 *NS16550_t; + +const NS16550_t COM_PORTS[] = { (NS16550_t) COM1, + (NS16550_t) COM2, + (NS16550_t) COM3, + (NS16550_t) COM4 }; + +volatile struct NS16550 * +NS16550_init(int chan) +{ + volatile struct NS16550 *com_port; + volatile unsigned char xx; + com_port = (struct NS16550 *) COM_PORTS[chan]; + /* See if port is present */ + com_port->lcr = 0x00; + com_port->ier = 0xFF; +#if 0 + if (com_port->ier != 0x0F) return ((struct NS16550 *)0); +#endif + com_port->ier = 0x00; + com_port->lcr = 0x80; /* Access baud rate */ + com_port->dll = 0xc; /* 9600 baud */ + com_port->dlm = 0xc >> 8; + com_port->lcr = 0x03; /* 8 data, 1 stop, no parity */ + com_port->mcr = 0x03; /* RTS/DTR */ + com_port->fcr = 0x07; /* Clear & enable FIFOs */ + return (com_port); +} + + +NS16550_putc(volatile struct NS16550 *com_port, unsigned char c) +{ + volatile int i; + while ((com_port->lsr & LSR_THRE) == 0) ; + com_port->thr = c; +} + +unsigned char +NS16550_getc(volatile struct NS16550 *com_port) +{ + while ((com_port->lsr & LSR_DR) == 0) ; + return (com_port->rbr); +} + +NS16550_tstc(volatile struct NS16550 *com_port) +{ + return ((com_port->lsr & LSR_DR) != 0); +} + + + diff --git a/arch/ppc/boot/ns16550.h b/arch/ppc/boot/ns16550.h new file mode 100644 index 000000000..4baf4c1c5 --- /dev/null +++ b/arch/ppc/boot/ns16550.h @@ -0,0 +1,34 @@ +/* + * NS16550 Serial Port + */ + +struct NS16550 + { + unsigned char rbr; /* 0 */ + unsigned char ier; /* 1 */ + unsigned char fcr; /* 2 */ + unsigned char lcr; /* 3 */ + unsigned char mcr; /* 4 */ + unsigned char lsr; /* 5 */ + unsigned char msr; /* 6 */ + unsigned char scr; /* 7 */ + }; + +#define thr rbr +#define iir fcr +#define dll rbr +#define dlm ier + +#define LSR_DR 0x01 /* Data ready */ +#define LSR_OE 0x02 /* Overrun */ +#define LSR_PE 0x04 /* Parity error */ +#define LSR_FE 0x08 /* Framing error */ +#define LSR_BI 0x10 /* Break */ +#define LSR_THRE 0x20 /* Xmit holding register empty */ +#define LSR_TEMT 0x40 /* Xmitter empty */ +#define LSR_ERR 0x80 /* Error */ + +#define COM1 0x800003F8 +#define COM2 0x800002F8 +#define COM3 0x800003F8 +#define COM4 0x80000388 diff --git a/arch/ppc/chrp_defconfig b/arch/ppc/chrp_defconfig index dcaf4b2d5..9141b2d90 100644 --- a/arch/ppc/chrp_defconfig +++ b/arch/ppc/chrp_defconfig @@ -14,6 +14,7 @@ CONFIG_CHRP=y # CONFIG_ALL_PPC is not set # CONFIG_APUS is not set # CONFIG_MBX is not set +# CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y # diff --git a/arch/ppc/coffboot/Makefile b/arch/ppc/coffboot/Makefile index 72a6df455..4669d2228 100644 --- a/arch/ppc/coffboot/Makefile +++ b/arch/ppc/coffboot/Makefile @@ -3,18 +3,6 @@ # # Paul Mackerras January 1997 -# PowerPC (cross) tools -ifneq ($(shell uname -m),ppc) -CROSS_COMPILE =powerpc-eabi- -endif - - -# PowerPC (cross) tools -ifneq ($(shell uname -m),ppc) -#CROSS_COMPILE =powerpc-eabi- -CROSS_COMPILE =ppc-linux-elf- -endif - HOSTCC = gcc HOSTCFLAGS = -O -I$(TOPDIR)/include diff --git a/arch/ppc/common_defconfig b/arch/ppc/common_defconfig index 916af99f1..f58965709 100644 --- a/arch/ppc/common_defconfig +++ b/arch/ppc/common_defconfig @@ -14,6 +14,7 @@ CONFIG_6xx=y CONFIG_ALL_PPC=y # CONFIG_APUS is not set # CONFIG_MBX is not set +# CONFIG_SMP is not set # # General setup @@ -45,9 +46,9 @@ CONFIG_ADBMOUSE=y CONFIG_BLK_DEV_IDE_PMAC=y CONFIG_PROC_DEVICETREE=y # CONFIG_KGDB is not set -CONFIG_XMON=y +# CONFIG_XMON is not set # CONFIG_TOTALMP is not set -# CONFIG_BOOTX_TEXT is not set +CONFIG_BOOTX_TEXT=y # # Plug and Play support @@ -113,6 +114,10 @@ CONFIG_SKB_LARGE=y # CONFIG_NET_FASTROUTE is not set # CONFIG_NET_HW_FLOWCONTROL is not set # CONFIG_CPU_IS_SLOW is not set + +# +# QoS and/or fair queueing +# # CONFIG_NET_SCHED is not set # @@ -132,6 +137,7 @@ CONFIG_BLK_DEV_SR_VENDOR=y # SCSI low-level drivers # # 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 @@ -139,14 +145,16 @@ CONFIG_BLK_DEV_SR_VENDOR=y # 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_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_EATA 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_NCR53C406A is not set # CONFIG_SCSI_NCR53C7xx is not set CONFIG_SCSI_NCR53C8XX=y @@ -170,7 +178,7 @@ CONFIG_SCSI_NCR53C8XX_IOMAPPED=y # CONFIG_SCSI_DEBUG is not set CONFIG_SCSI_MESH=y CONFIG_SCSI_MESH_SYNC_RATE=5 -CONFIG_SCSI_MAC53C94=m +CONFIG_SCSI_MAC53C94=y # # Network device support @@ -188,6 +196,7 @@ CONFIG_BMAC=y # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_RTL8139 is not set # CONFIG_YELLOWFIN is not set +# CONFIG_ACENIC is not set # CONFIG_NET_ISA is not set CONFIG_NET_EISA=y CONFIG_PCNET32=m @@ -219,6 +228,7 @@ CONFIG_SLIP=m # CONFIG_TR is not set # CONFIG_SHAPER is not set # CONFIG_HOSTESS_SV11 is not set +# CONFIG_COSA is not set # # Amateur Radio support @@ -239,14 +249,31 @@ CONFIG_SLIP=m # Console drivers # CONFIG_DUMMY_CONSOLE=y -# CONFIG_FB_OF is not set +CONFIG_FB_OF=y +CONFIG_FB_CONTROL=y +CONFIG_FB_PLATINUM=y +CONFIG_FB_VALKYRIE=y +CONFIG_FB_ATY=y +CONFIG_FB_IMSTT=y +CONFIG_FB_CT65550=y +# CONFIG_FB_S3TRIO is not set # CONFIG_FB_MATROX is not set +CONFIG_FB_ATY=y # 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 is not set +CONFIG_FBCON_FONTS=y CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y +# CONFIG_FONT_SUN8x16 is not set +CONFIG_FONT_SUN12x22=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set # # Character devices @@ -258,6 +285,10 @@ CONFIG_SERIAL=m # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_UNIX98_PTYS is not set CONFIG_MOUSE=y + +# +# Mice +# # CONFIG_ATIXL_BUSMOUSE is not set # CONFIG_BUSMOUSE is not set # CONFIG_MS_BUSMOUSE is not set @@ -266,9 +297,17 @@ CONFIG_PSMOUSE=y # CONFIG_PC110_PAD is not set # CONFIG_QIC02_TAPE is not set # CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set # CONFIG_RTC is not set + +# +# Video For Linux +# # CONFIG_VIDEO_DEV is not set -# CONFIG_NVRAM is not set + +# +# Joystick support +# # CONFIG_JOYSTICK is not set # @@ -280,36 +319,46 @@ CONFIG_PSMOUSE=y # Filesystems # # CONFIG_QUOTA is not set -# CONFIG_MINIX_FS is not set -CONFIG_EXT2_FS=y -CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +CONFIG_HFS_FS=y CONFIG_FAT_FS=m CONFIG_MSDOS_FS=m # CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS 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_HPFS_FS is not set CONFIG_PROC_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set CONFIG_NFS_FS=y -CONFIG_NFSD=y +CONFIG_NFSD=m # CONFIG_NFSD_SUN is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y -# CONFIG_CODA_FS is not set # CONFIG_SMB_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_AFFS_FS is not set -CONFIG_HFS_FS=y -# CONFIG_ROMFS_FS is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_UFS_FS is not set +# CONFIG_NCP_FS is not set + +# +# Partition Types +# # CONFIG_BSD_DISKLABEL is not set +CONFIG_MAC_PARTITION=y # CONFIG_SMD_DISKLABEL is not set # CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_ADFS_FS is not set -# CONFIG_QNX4FS_FS is not set -CONFIG_MAC_PARTITION=y +# CONFIG_UNIXWARE_DISKLABEL is not set CONFIG_NLS=y # @@ -340,6 +389,7 @@ CONFIG_NLS=y # CONFIG_NLS_ISO8859_7 is not set # CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_15 is not set # CONFIG_NLS_KOI8_R is not set # @@ -368,6 +418,7 @@ CONFIG_SOUND_OSS=y # CONFIG_SOUND_OPL3SA2 is not set # CONFIG_SOUND_MAUI is not set # CONFIG_SOUND_SGALAXY is not set +# CONFIG_SOUND_AD1816 is not set # CONFIG_SOUND_OPL3SA1 is not set # CONFIG_SOUND_SOFTOSS is not set # CONFIG_SOUND_YM3812 is not set diff --git a/arch/ppc/config.in b/arch/ppc/config.in index 59223a45c..b15e90afd 100644 --- a/arch/ppc/config.in +++ b/arch/ppc/config.in @@ -22,6 +22,9 @@ choice 'Machine Type' \ if [ "$CONFIG_ALL_PPC" != "y" ];then define_bool CONFIG_MACH_SPECIFIC y fi + +bool 'Symmetric multi-processing support' CONFIG_SMP + endmenu if [ "$CONFIG_MBX" = "y" ];then @@ -164,7 +167,6 @@ endmenu source drivers/char/Config.in source fs/Config.in -source fs/nls/Config.in mainmenu_option next_comment comment 'Sound' diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig index ae1303bb4..811d599c0 100644 --- a/arch/ppc/defconfig +++ b/arch/ppc/defconfig @@ -15,6 +15,7 @@ CONFIG_PMAC=y # CONFIG_APUS is not set # CONFIG_MBX is not set CONFIG_MACH_SPECIFIC=y +# CONFIG_SMP is not set # # General setup @@ -137,6 +138,10 @@ CONFIG_ATALK=m # CONFIG_NET_FASTROUTE is not set # CONFIG_NET_HW_FLOWCONTROL is not set # CONFIG_CPU_IS_SLOW is not set + +# +# QoS and/or fair queueing +# # CONFIG_NET_SCHED is not set # @@ -164,6 +169,7 @@ CONFIG_SCSI_CONSTANTS=y # SCSI low-level drivers # # 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 @@ -174,14 +180,16 @@ CONFIG_AIC7XXX_RESET_DELAY=15 # 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_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_EATA 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_NCR53C406A is not set # CONFIG_SCSI_NCR53C7xx is not set # CONFIG_SCSI_NCR53C8XX is not set @@ -218,6 +226,7 @@ CONFIG_BMAC=y # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_RTL8139 is not set # CONFIG_YELLOWFIN is not set +# CONFIG_ACENIC is not set # CONFIG_NET_ISA is not set CONFIG_NET_EISA=y # CONFIG_PCNET32 is not set @@ -225,7 +234,7 @@ CONFIG_NET_EISA=y # CONFIG_APRICOT is not set # CONFIG_CS89x0 is not set CONFIG_DE4X5=y -CONFIG_DEC_ELCP=m +# CONFIG_DEC_ELCP is not set # CONFIG_DGRS is not set # CONFIG_EEXPRESS_PRO100 is not set # CONFIG_LNE390 is not set @@ -253,6 +262,7 @@ CONFIG_PPP=y # CONFIG_TR is not set # CONFIG_SHAPER is not set # CONFIG_HOSTESS_SV11 is not set +# CONFIG_COSA is not set # # Amateur Radio support @@ -282,6 +292,7 @@ CONFIG_FB_IMSTT=y CONFIG_FB_CT65550=y # CONFIG_FB_S3TRIO is not set # CONFIG_FB_MATROX is not set +CONFIG_FB_ATY=y # CONFIG_FB_VIRTUAL is not set # CONFIG_FBCON_ADVANCED is not set CONFIG_FBCON_CFB8=y @@ -303,7 +314,7 @@ CONFIG_FONT_SUN12x22=y # CONFIG_VT=y CONFIG_VT_CONSOLE=y -CONFIG_SERIAL=m +# CONFIG_SERIAL is not set # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set CONFIG_UNIX98_PTYS=y @@ -311,9 +322,17 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_MOUSE is not set # CONFIG_QIC02_TAPE is not set # CONFIG_WATCHDOG is not set +CONFIG_NVRAM=y # CONFIG_RTC is not set + +# +# Video For Linux +# # CONFIG_VIDEO_DEV is not set -CONFIG_NVRAM=y + +# +# Joystick support +# # CONFIG_JOYSTICK is not set # @@ -325,37 +344,47 @@ CONFIG_NVRAM=y # Filesystems # # CONFIG_QUOTA is not set -# CONFIG_MINIX_FS is not set -CONFIG_EXT2_FS=y -CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set +CONFIG_AUTOFS_FS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +CONFIG_HFS_FS=y CONFIG_FAT_FS=m CONFIG_MSDOS_FS=m # CONFIG_UMSDOS_FS is not set CONFIG_VFAT_FS=m +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set CONFIG_NFS_FS=y CONFIG_NFSD=y # CONFIG_NFSD_SUN is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y -# CONFIG_CODA_FS is not set # CONFIG_SMB_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_AFFS_FS is not set -CONFIG_HFS_FS=y -# CONFIG_ROMFS_FS is not set -CONFIG_AUTOFS_FS=y -# CONFIG_UFS_FS is not set +# CONFIG_NCP_FS is not set + +# +# Partition Types +# # CONFIG_BSD_DISKLABEL is not set +CONFIG_MAC_PARTITION=y # CONFIG_SMD_DISKLABEL is not set # CONFIG_SOLARIS_X86_PARTITION is not set -CONFIG_DEVPTS_FS=y -# CONFIG_ADFS_FS is not set -# CONFIG_QNX4FS_FS is not set -CONFIG_MAC_PARTITION=y +# CONFIG_UNIXWARE_DISKLABEL is not set CONFIG_NLS=y # @@ -386,6 +415,7 @@ CONFIG_NLS_CODEPAGE_437=y # CONFIG_NLS_ISO8859_7 is not set # CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_15 is not set # CONFIG_NLS_KOI8_R is not set # diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 4846d5ebb..d047c2086 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -15,8 +15,7 @@ OX_OBJS := ppc_ksyms.o setup.o O_OBJS := traps.o irq.o idle.o time.o process.o signal.o syscalls.o misc.o \ - bitops.o ptrace.o align.o ppc_htab.o feature.o - + bitops.o ptrace.o align.o ppc_htab.o ifdef CONFIG_PCI O_OBJS += pci.o endif @@ -33,15 +32,17 @@ else ifeq ($(CONFIG_APUS),y) O_OBJS += apus_setup.o prom.o openpic.o else +ifneq ($(CONFIG_MBX),y) O_OBJS += prep_time.o pmac_time.o chrp_time.o \ pmac_setup.o pmac_support.o \ prep_pci.o pmac_pci.o chrp_pci.o \ - residual.o prom.o openpic.o + residual.o prom.o openpic.o feature.o OX_OBJS += chrp_setup.o prep_setup.o endif endif +endif -ifdef SMP +ifdef CONFIG_SMP O_OBJS += smp.o endif diff --git a/arch/ppc/kernel/apus_setup.c b/arch/ppc/kernel/apus_setup.c index 93c2fe2d1..c3a81ad3e 100644 --- a/arch/ppc/kernel/apus_setup.c +++ b/arch/ppc/kernel/apus_setup.c @@ -329,9 +329,9 @@ unsigned long mm_ptov (unsigned long paddr) int i; for (i = 0; i < kmap_chunk_count;){ - unsigned long virt = kmap_chunks[i++]; - unsigned long size = kmap_chunks[i++]; unsigned long phys = kmap_chunks[i++]; + unsigned long size = kmap_chunks[i++]; + unsigned long virt = kmap_chunks[i++]; if (paddr >= phys && paddr < (phys + size)){ ret = virt + paddr - phys; diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index 4c528beb8..d7b791387 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S @@ -1,7 +1,7 @@ /* * arch/ppc/kernel/head.S * - * $Id: head.S,v 1.111 1998/11/10 01:10:32 paulus Exp $ + * $Id: head.S,v 1.114 1998/12/28 10:28:45 paulus Exp $ * * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) @@ -148,6 +148,10 @@ _start: * r4: virtual address of boot_infos_t * r5: 0 * + * APUS + * r3: 'APUS' + * Linux/m68k style BootInfo structure at &_end. + * * PREP * This is jumped to on prep systems right after the kernel is relocated * to its proper place in memory by the boot loader. The expected layout @@ -528,9 +532,10 @@ HardwareInterrupt: stw r3,(_CCR+4)(r21); #endif - addi r3,r1,STACK_FRAME_OVERHEAD; - li r20,MSR_KERNEL; - bl transfer_to_handler; + addi r3,r1,STACK_FRAME_OVERHEAD + li r20,MSR_KERNEL + li r4,0 + bl transfer_to_handler .long do_IRQ; .long int_return @@ -1195,18 +1200,34 @@ stack_ovf: * physical address of the hash table are known. These definitions * of Hash_base and Hash_bits below are just an example. */ -/* - * Note that the 603s won't come here, since the 603 - * loads tlb directly into the tlb from the linux tables, while - * others (601, 604, etc.) call hash_page() to load entries from - * the linux tables into the hash table. -- Cort - */ Hash_base = 0x180000 Hash_bits = 12 /* e.g. 256kB hash table */ Hash_msk = (((1 << Hash_bits) - 1) * 64) - + + .globl hash_table_lock +hash_table_lock: +.long 0 + .globl hash_page hash_page: +#ifdef __SMP__ + lis r2,hash_table_lock@h + ori r2,r2,hash_table_lock@l + tophys(r2,r2,r6) + lis r6,100000000@h + mtctr r6 + lwz r0,PROCESSOR-TSS(r5) + or r0,r0,r6 +10: lwarx r6,0,r2 + cmpi 0,r6,0 + bne- 12f + stwcx. r0,0,r2 + beq+ 11f +12: cmpw r6,r0 + bdnzf 2,10b + tw 31,31,31 +11: +#endif /* Get PTE (linux-style) and check access */ lwz r5,PG_TABLES(r5) tophys(r5,r5,r2) /* convert to phys addr */ @@ -1253,6 +1274,9 @@ hash_page_patch_A: li r2,8 /* PTEs/group */ bne 10f /* no PTE: go look for an empty slot */ tlbie r3 /* invalidate TLB entry */ +#ifdef __SMP__ + tlbsync +#endif /* Search the primary PTEG for a PTE whose 1st word matches r5 */ mtctr r2 @@ -1297,7 +1321,6 @@ hash_page_patch_C: bdnzf 2,2b beq+ found_empty -#if 1 /* * Choose an arbitrary slot in the primary PTEG to overwrite. * Since both the primary and secondary PTEGs are full, and we @@ -1313,26 +1336,6 @@ hash_page_patch_C: andi. r2,r2,0x38 stw r2,next_slot@l(0) add r3,r4,r2 -#else - /* now, allow 2nd hash as well as 1st */ - lwz r2,next_slot@l(0) - addi r2,r2,8 - andi. r2,r2,0x78 - stw r2,next_slot@l(0) - cmpi 0,0,r2,0x38 /* if it's the 2nd hash */ - bgt second_evict -first_evict: - xori r5,r5,0x40 /* clear H bit again */ - add r3,r4,r2 - b 11f -second_evict: - .globl hash_page_patch_D -hash_page_patch_D: - xoris r3,r4,Hash_msk>>16 /* compute secondary hash */ - xori r3,r3,0xffc0 - subi r2,r2,0x40 - addi r3,r3,r2 -#endif 11: /* update counter of evicted pages */ lis r2,htab_evicts@h @@ -1372,6 +1375,13 @@ found_slot: addi r3,r3,1 stw r3,0(r2) +#ifdef __SMP__ + lis r2,hash_table_lock@ha + tophys(r2,r2,r6) + li r0,0 + stw r0,hash_table_lock@l(r2) +#endif + /* Return from the exception */ lwz r3,_CCR(r21) lwz r4,_LINK(r21) @@ -1392,6 +1402,12 @@ found_slot: rfi hash_page_out: +#ifdef __SMP__ + lis r2,hash_table_lock@ha + tophys(r2,r2,r6) + li r0,0 + stw r0,hash_table_lock@l(r2) +#endif blr next_slot: .long 0 @@ -1709,6 +1725,9 @@ start_here: 2: SYNC /* Force all PTE updates to finish */ tlbia /* Clear all TLB entries */ +#ifdef __SMP__ + tlbsync +#endif #ifndef CONFIG_8xx mtspr SDR1,r6 li r0,16 /* load up segment register values */ @@ -1980,16 +1999,13 @@ _GLOBAL(_switch) /* FALL THROUGH into int_return */ #ifdef __SMP__ - /* drop scheduler_lock since we weren't called by schedule() */ + /* call schedule_tail if this is the first time for a child process */ lwz r5,TSS_SMP_FORK_RET(r4) cmpi 0,r5,0 beq+ int_return li r3,0 - lis r5,scheduler_lock@ha stw r3,TSS_SMP_FORK_RET(r4) - stw r3,scheduler_lock@l+4(r5) /* owner_pc */ - stw r3,scheduler_lock@l+8(r5) /* owner_cpu */ - stw r3,scheduler_lock@l(r5) /* lock */ + bl schedule_tail #endif /* __SMP__ */ /* @@ -2089,6 +2105,7 @@ _GLOBAL(fake_interrupt) li r0,0x0fac stw r0,TRAP(r1) addi r3,r1,STACK_FRAME_OVERHEAD + li r4,1 bl do_IRQ addi r1,r1,INT_FRAME_SIZE+STACK_UNDERHEAD lwz r0,4(r1) @@ -2206,8 +2223,31 @@ _GLOBAL(flush_hash_segments) rlwinm r0,r0,16,27,31 lis r9,PVR_603_LIKE@h rlwnm. r0,r9,r0,0,0 - bne 99f + beq+ 99f + tlbia + isync + blr +99: #endif /* NO_RELOAD_HTAB */ +#ifdef __SMP__ + /* Note - we had better not do anything which could generate + a hash table miss while we have the hash table locked, + or we'll get a deadlock. -paulus */ + mfmsr r10 + sync + rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ + mtmsr r0 + SYNC + lis r9,hash_table_lock@h + ori r9,r9,hash_table_lock@l + lwz r8,PROCESSOR(r2) + oris r8,r8,8 +10: lwarx r6,0,r9 + cmpi 0,r6,0 + bne- 10b + stwcx. r8,0,r9 + bne- 10b +#endif rlwinm r3,r3,7,1,24 /* put VSID lower limit in position */ oris r3,r3,0x8000 /* set V bit */ rlwinm r4,r4,7,1,24 /* put VSID upper limit in position */ @@ -2229,8 +2269,16 @@ _GLOBAL(flush_hash_segments) stw r0,0(r5) /* invalidate entry */ 2: bdnz 1b /* continue with loop */ sync -99: tlbia + tlbia isync +#ifdef __SMP__ + tlbsync + lis r3,hash_table_lock@ha + li r0,0 + stw r0,hash_table_lock@l(r3) + mtmsr r10 + SYNC +#endif blr /* @@ -2244,8 +2292,31 @@ _GLOBAL(flush_hash_page) rlwinm r0,r0,16,27,31 lis r9,PVR_603_LIKE@h rlwnm. r0,r9,r0,0,0 - bne 99f + beq+ 99f + tlbie r4 /* in hw tlb too */ + isync + blr +99: #endif /* NO_RELOAD_HTAB */ +#ifdef __SMP__ + /* Note - we had better not do anything which could generate + a hash table miss while we have the hash table locked, + or we'll get a deadlock. -paulus */ + mfmsr r10 + sync + rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ + mtmsr r0 + SYNC + lis r9,hash_table_lock@h + ori r9,r9,hash_table_lock@l + lwz r8,PROCESSOR(r2) + oris r8,r8,9 +10: lwarx r6,0,r9 + cmpi 0,r6,0 + bne- 10b + stwcx. r8,0,r9 + bne- 10b +#endif rlwinm r3,r3,11,1,20 /* put context into vsid */ rlwimi r3,r4,11,21,24 /* put top 4 bits of va into vsid */ oris r3,r3,0x8000 /* set V (valid) bit */ @@ -2278,10 +2349,19 @@ _GLOBAL(flush_hash_page) 3: li r0,0 stw r0,0(r7) /* invalidate entry */ 4: sync -99: tlbie r4 /* in hw tlb too */ + tlbie r4 /* in hw tlb too */ isync +#ifdef __SMP__ + tlbsync + lis r3,hash_table_lock@h + li r0,0 + stw r0,hash_table_lock@l(r3) + mtmsr r10 + SYNC +#endif blr #endif /* CONFIG_8xx */ + /* * This routine is just here to keep GCC happy - sigh... */ diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c index b6c338946..af163699b 100644 --- a/arch/ppc/kernel/idle.c +++ b/arch/ppc/kernel/idle.c @@ -1,5 +1,5 @@ /* - * $Id: idle.c,v 1.56 1998/10/13 19:14:36 paulus Exp $ + * $Id: idle.c,v 1.57 1998/12/28 10:28:46 paulus Exp $ * * Idle daemon for PowerPC. Idle daemon will handle any action * that needs to be taken when the system becomes idle. @@ -41,26 +41,25 @@ unsigned long powersave_nap = 0; int idled(void *unused) { - int ret = -EPERM; - + /* endless loop with no priority at all */ + current->priority = 0; + current->counter = -100; for (;;) { __sti(); - /* endless loop with no priority at all */ - current->priority = 0; - current->counter = 0; - 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(); - run_task_queue(&tq_scheduler); - schedule(); + +#ifdef __SMP__ + if (current->need_resched) +#endif + schedule(); } - ret = 0; - return ret; + return 0; } #ifdef __SMP__ diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c index a180e5f0a..f4a7c7143 100644 --- a/arch/ppc/kernel/irq.c +++ b/arch/ppc/kernel/irq.c @@ -1,4 +1,6 @@ /* + * $Id: irq.c,v 1.91 1998/12/28 10:28:47 paulus Exp $ + * * arch/ppc/kernel/irq.c * * Derived from arch/i386/kernel/irq.c @@ -6,6 +8,7 @@ * Adapted from arch/i386 by Gary Thomas * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * Updated and modified by Cort Dougan (cort@cs.nmt.edu) + * Copyright (C) 1996 Cort Dougan * Adapted for Power Macintosh by Paul Mackerras * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). @@ -309,14 +312,14 @@ static void __openfirmware chrp_unmask_irq(unsigned int irq_nr) static void mbx_mask_irq(unsigned int irq_nr) { cached_irq_mask[0] &= ~(1 << (31-irq_nr)); - ((immap_t *)MBX_IMAP_ADDR)->im_siu_conf.sc_simask = + ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = cached_irq_mask[0]; } static void mbx_unmask_irq(unsigned int irq_nr) { cached_irq_mask[0] |= (1 << (31-irq_nr)); - ((immap_t *)MBX_IMAP_ADDR)->im_siu_conf.sc_simask = + ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = cached_irq_mask[0]; } #endif /* CONFIG_8xx */ @@ -454,7 +457,6 @@ static inline void wait_on_bh(void) } -#define MAXCOUNT 100000000 static inline void wait_on_irq(int cpu) { int count = MAXCOUNT; @@ -507,7 +509,7 @@ static inline void wait_on_irq(int cpu) void synchronize_bh(void) { if (atomic_read(&global_bh_count) && !in_interrupt()) - wait_on_bh(); + wait_on_bh(); } @@ -529,6 +531,8 @@ void synchronize_irq(void) static inline void get_irqlock(int cpu) { + unsigned int loops = MAXCOUNT; + if (test_and_set_bit(0,&global_irq_lock)) { /* do we already hold the lock? */ if ((unsigned char) cpu == global_irq_holder) @@ -536,12 +540,17 @@ static inline void get_irqlock(int cpu) /* Uhhuh.. Somebody else got it. Wait.. */ do { do { - + if (loops-- == 0) { + printk("get_irqlock(%d) waiting, global_irq_holder=%d\n", cpu, global_irq_holder); +#ifdef CONFIG_XMON + xmon(0); +#endif + } } while (test_bit(0,&global_irq_lock)); } while (test_and_set_bit(0,&global_irq_lock)); } /* - * We also to make sure that nobody else is running + * We also need to make sure that nobody else is running * in an interrupt context. */ wait_on_irq(cpu); @@ -637,7 +646,7 @@ void __global_restore_flags(unsigned long flags) #endif /* __SMP__ */ -asmlinkage void do_IRQ(struct pt_regs *regs) +asmlinkage void do_IRQ(struct pt_regs *regs, int isfake) { int irq; unsigned long bits; @@ -656,9 +665,14 @@ asmlinkage void do_IRQ(struct pt_regs *regs) #ifdef __SMP__ if ( cpu != 0 ) { - if (!atomic_read(&n_lost_interrupts)) + if (!isfake) { extern void smp_message_recv(void); +#ifdef CONFIG_XMON + static int xmon_2nd; + if (xmon_2nd) + xmon(regs); +#endif smp_message_recv(); goto out; } @@ -666,6 +680,25 @@ asmlinkage void do_IRQ(struct pt_regs *regs) mess with the controller from the second cpu -- Cort */ goto out; } + + { + unsigned int loops = MAXCOUNT; + while (test_bit(0, &global_irq_lock)) { + if (smp_processor_id() == global_irq_holder) { + printk("uh oh, interrupt while we hold global irq lock!\n"); +#ifdef CONFIG_XMON + xmon(0); +#endif + break; + } + if (loops-- == 0) { + printk("do_IRQ waiting for irq lock (holder=%d)\n", global_irq_holder); +#ifdef CONFIG_XMON + xmon(0); +#endif + } + } + } #endif /* __SMP__ */ switch ( _machine ) @@ -799,9 +832,13 @@ apus_out: } if (irq < 0) { - printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n", - irq, regs->nip); - spurious_interrupts++; + /* we get here with Gatwick but the 'bogus' isn't correct in that case -- Cort */ + if ( irq != second_irq ) + { + printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n", + irq, regs->nip); + spurious_interrupts++; + } goto out; } @@ -809,7 +846,7 @@ apus_out: /* For MPC8xx, read the SIVEC register and shift the bits down * to get the irq number. */ - bits = ((immap_t *)MBX_IMAP_ADDR)->im_siu_conf.sc_sivec; + bits = ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec; irq = bits >> 26; #endif /* CONFIG_8xx */ mask_and_ack_irq(irq); @@ -1089,17 +1126,6 @@ __initfunc(void init_IRQ(void)) */ if ( _prep_type == _PREP_IBM ) irq_mode2 |= 0xa0; - /* - * Sound on the Powerstack reportedly needs to be edge triggered - */ - if ( _prep_type == _PREP_Motorola ) - { - irq_mode2 &= ~0x04L; - irq_mode2 = 0xca; - outb( irq_mode1 , 0x4d0 ); - outb( irq_mode2 , 0x4d1 ); - } - } break; #ifdef CONFIG_APUS @@ -1116,8 +1142,7 @@ __initfunc(void init_IRQ(void)) /* This routine will fix some missing interrupt values in the device tree * on the gatwick mac-io controller used by some PowerBooks */ -__pmac -static void pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base) +static void __init pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base) { struct device_node *node; static struct interrupt_info int_pool[4]; diff --git a/arch/ppc/kernel/mbx_setup.c b/arch/ppc/kernel/mbx_setup.c index 9d26e27d1..90647dcd9 100644 --- a/arch/ppc/kernel/mbx_setup.c +++ b/arch/ppc/kernel/mbx_setup.c @@ -1,4 +1,6 @@ /* + * $Id: mbx_setup.c,v 1.5 1998/12/29 18:55:07 cort Exp $ + * * linux/arch/ppc/kernel/setup.c * * Copyright (C) 1995 Linus Torvalds @@ -51,17 +53,27 @@ extern int rd_image_start; /* starting block # of image */ extern char saved_command_line[256]; extern unsigned long find_available_memory(void); -extern void mbx_cpm_reset(uint); - +extern void m8xx_cpm_reset(uint); -void mbx_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq) +/* this really does make things cleaner -- Cort */ +void __init powermac_init(void) { +} - *p = 0; - *irq = 0; +void __init adbdev_init(void) +{ +} - if (base != 0) /* Only map the first ATA flash drive */ - return; +void __init mbx_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq) +{ + ide_ioreg_t port = base; + int i = 8; + + while (i--) + *p++ = port++; + *p++ = base + 0x206; + if (irq != NULL) + *irq = 0; #ifdef ATA_FLASH base = (unsigned long) ioremap(PCMCIA_MEM_ADDR, 0x200); for (i = 0; i < 8; ++i) @@ -88,7 +100,7 @@ mbx_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p)) /* Reset the Communication Processor Module. */ - mbx_cpm_reset(cpm_page); + m8xx_cpm_reset(cpm_page); #ifdef notdef ROOT_DEV = to_kdev_t(0x0301); /* hda1 */ diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index f13508d96..e4589b1e0 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -383,6 +383,177 @@ _GLOBAL(_set_THRM3) mtspr THRM3,r3 blr +_GLOBAL(_get_PVR) + mfspr r3,PVR + blr +/* + L2CR functions + Copyright © 1997-1998 by PowerLogix R & D, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* + Thur, Dec. 12, 1998. + - First public release, contributed by PowerLogix. + + Author: Terry Greeniaus (tgree@phys.ualberta.ca) + Please e-mail updates to this file to me, thanks! +*/ + +_GLOBAL(_set_L2CR) + /* Usage: + + When setting the L2CR register, you must do a few special things. If you are enabling the + cache, you must perform a global invalidate. If you are disabling the cache, you must + flush the cache contents first. This routine takes care of doing these things. When first + enabling the cache, make sure you pass in the L2CR you want, as well as passing in the + global invalidate bit set. A global invalidate will only be performed if the L2I bit is set + in applyThis. When enabling the cache, you should also set the L2E bit in applyThis. If you + want to modify the L2CR contents after the cache has been enabled, the recommended + procedure is to first call __setL2CR(0) to disable the cache and then call it again with + the new values for L2CR. Examples: + + _setL2CR(0) - disables the cache + _setL2CR(0xB3A04000) - enables my G3 upgrade card: + - L2E set to turn on the cache + - L2SIZ set to 1MB + - L2CLK set to 1:1 + - L2RAM set to pipelined syncronous late-write + - L2I set to perform a global invalidation + - L2OH set to 0.5 nS + - L2DF set because this upgrade card requires it + + A similar call should work for your card. You need to know the correct setting for your + card and then place them in the fields I have outlined above. Other fields support optional + features, such as L2DO which caches only data, or L2TS which causes cache pushes from + the L1 cache to go to the L2 cache instead of to main memory. + */ + + /* Make sure this is a 750 chip */ + mfspr r4,PVR + rlwinm r4,r4,16,16,31 + cmplwi r4,0x0008 + beq thisIs750 + li r3,-1 + blr + +thisIs750: + /* Get the current enable bit of the L2CR into r4 */ + mfspr r4,L2CR + rlwinm r4,r4,0,0,0 + + /* 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 */ + rlwinm r3,r3,0,1,31 /* Turn off the enable bit */ + or r3,r3,r4 /* Keep the enable bit the same as it was for now. */ + bne dontDisableCache /* Only disable the cache if L2CRApply has the enable bit off */ + +disableCache: + /* Disable the cache. First, we turn off data relocation. */ + mfmsr r7 + rlwinm r4,r7,0,28,26 /* Turn off DR bit */ + rlwinm r4,r4,0,17,15 /* Turn off EE bit - an external exception while we are flushing + the cache is fatal (comment this line and see!) */ + sync + mtmsr r4 + sync + + /* + 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 + mtctr r4 + li r4,0 +loadLoop: + lwzx r0,r0,r4 + addi r4,r4,0x0020 /* Go to start of next cache line */ + bdnz loadLoop + + /* Now, flush the first 2MB of memory */ + lis r4,0x0001 + mtctr r4 + li r4,0 + sync +flushLoop: + dcbf r0,r4 + addi r4,r4,0x0020 /* Go to start of next cache line */ + bdnz flushLoop + + /* Turn off the L2CR enable bit. */ + rlwinm r3,r3,0,1,31 + + /* Reenable data relocation. */ + sync + mtmsr r7 + sync + +dontDisableCache: + /* Set up the L2CR configuration bits */ + sync + mtspr L2CR,r3 + sync + cmplwi r6,0 + beq noInval + + /* Perform a global invalidation */ + oris r3,r3,0x0020 + sync + mtspr 1017,r3 + sync +invalCompleteLoop: /* Wait for the invalidation to complete */ + mfspr r3,1017 + rlwinm. r4,r3,0,31,31 + bne invalCompleteLoop + + rlwinm r3,r3,0,11,9; /* Turn off the L2I bit */ + sync + mtspr L2CR,r3 + sync + +noInval: + /* See if we need to enable the cache */ + cmplwi r5,0 + beqlr + +enableCache: + /* Enable the cache */ + oris r3,r3,0x8000 + mtspr L2CR,r3 + sync + blr + +_GLOBAL(_get_L2CR) + /* Make sure this is a 750 chip */ + mfspr r3,PVR + rlwinm r3,r3,16,16,31 + cmplwi r3,0x0008 + li r3,0 + bnelr + + /* Return the L2CR contents */ + mfspr r3,L2CR + blr + +/* --- End of PowerLogix code --- + */ + +/* _GLOBAL(_get_L2CR) mfspr r3,L2CR blr @@ -391,9 +562,7 @@ _GLOBAL(_set_L2CR) mtspr L2CR,r3 blr -_GLOBAL(_get_PVR) - mfspr r3,PVR - blr +*/ /* * These are used in the alignment trap handler when emulating @@ -441,16 +610,6 @@ _GLOBAL(__kernel_thread) bnelr /* return if parent */ mtlr r4 /* fn addr in lr */ mr r3,r5 /* load arg and call fn */ -#if 0/*def __SMP__*/ - /* drop scheduler_lock since schedule() called us */ - lis r4,scheduler_lock@ha - li r5,0 - stw r5,scheduler_lock@l+4(r4) /* owner_pc */ - stw r5,scheduler_lock@l+8(r4) /* owner_cpu */ - stw r5,scheduler_lock@l(r4) - sync - isync -#endif /* __SMP__ */ blrl li r0,__NR_exit /* exit after child exits */ li r3,0 diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 359446f4f..1dfa3a6c8 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -1,5 +1,5 @@ /* - * $Id: pci.c,v 1.39 1998/10/13 20:59:04 cort Exp $ + * $Id: pci.c,v 1.43 1998/12/29 18:55:11 cort Exp $ * Common pmac/prep/chrp pci routines. -- Cort */ @@ -123,8 +123,8 @@ __initfunc(void pcibios_init(void)) __initfunc(void setup_pci_ptrs(void)) { - PPC_DEVICE *hostbridge; #ifndef CONFIG_MBX + PPC_DEVICE *hostbridge; switch (_machine) { case _MACH_prep: hostbridge=residual_find_device(PROCESSORDEVICE, NULL, @@ -188,13 +188,8 @@ __initfunc(void pcibios_fixup(void)) extern struct bridge_data **bridges; extern unsigned char *Motherboard_map; extern unsigned char *Motherboard_routes; - - /* - * FIXME: This is broken: We should not assign IRQ's to IRQless - * devices (look at PCI_INTERRUPT_PIN) and we also should - * honor the existence of multi-function devices where - * different functions have different interrupt pins. [mj] - */ + unsigned char i; +#ifndef CONFIG_MBX switch (_machine ) { case _MACH_prep: @@ -208,6 +203,21 @@ __initfunc(void pcibios_fixup(void)) */ unsigned char d = PCI_SLOT(dev->devfn); dev->irq = Motherboard_routes[Motherboard_map[d]]; + for ( i = 0 ; i <= 5 ; i++ ) + { + if ( dev->base_address[i] > 0x10000000 ) + { + printk("Relocating PCI address %x -> %x\n", + dev->base_address[i], + (dev->base_address[i] & 0x00FFFFFF) + | 0x01000000); + dev->base_address[i] = + (dev->base_address[i] & 0x00FFFFFF) | 0x01000000; + pci_write_config_dword(dev, + PCI_BASE_ADDRESS_0+(i*0x4), + dev->base_address[i] ); + } + } #if 0 /* * If we have residual data and if it knows about this @@ -255,6 +265,11 @@ __initfunc(void pcibios_fixup(void)) } break; } +#else /* CONFIG_MBX */ + for(dev=pci_devices; dev; dev=dev->next) + { + } +#endif /* CONFIG_MBX */ } __initfunc(void pcibios_fixup_bus(struct pci_bus *bus)) diff --git a/arch/ppc/kernel/ppc_htab.c b/arch/ppc/kernel/ppc_htab.c index 3aa0534ea..30123c076 100644 --- a/arch/ppc/kernel/ppc_htab.c +++ b/arch/ppc/kernel/ppc_htab.c @@ -1,5 +1,5 @@ /* - * $Id: ppc_htab.c,v 1.25 1998/08/26 10:28:26 davem Exp $ + * $Id: ppc_htab.c,v 1.26 1998/12/10 00:24:23 cort Exp $ * * PowerPC hash table management proc entry. Will show information * about the current hash table and will allow changes to it. @@ -569,6 +569,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 */; diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index ea5f6db0d..1b7753dd0 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -25,6 +25,7 @@ #include <asm/pci-bridge.h> #include <asm/irq.h> #include <asm/feature.h> +#include <asm/spinlock.h> #define __KERNEL_SYSCALLS__ #include <linux/unistd.h> @@ -32,7 +33,7 @@ extern void transfer_to_handler(void); extern void int_return(void); extern void syscall_trace(void); -extern void do_IRQ(struct pt_regs *regs); +extern void do_IRQ(struct pt_regs *regs, int isfake); extern void MachineCheckException(struct pt_regs *regs); extern void AlignmentException(struct pt_regs *regs); extern void ProgramCheckException(struct pt_regs *regs); @@ -156,6 +157,19 @@ EXPORT_SYMBOL(_get_PVR); EXPORT_SYMBOL(giveup_fpu); EXPORT_SYMBOL(flush_icache_range); EXPORT_SYMBOL(xchg_u32); +#ifdef __SMP__ +EXPORT_SYMBOL(__global_cli); +EXPORT_SYMBOL(__global_sti); +EXPORT_SYMBOL(__global_save_flags); +EXPORT_SYMBOL(__global_restore_flags); +EXPORT_SYMBOL(_spin_lock); +EXPORT_SYMBOL(_spin_unlock); +EXPORT_SYMBOL(spin_trylock); +EXPORT_SYMBOL(_read_lock); +EXPORT_SYMBOL(_read_unlock); +EXPORT_SYMBOL(_write_lock); +EXPORT_SYMBOL(_write_unlock); +#endif #ifndef CONFIG_MACH_SPECIFIC EXPORT_SYMBOL(_machine); @@ -180,12 +194,15 @@ EXPORT_SYMBOL(find_compatible_devices); EXPORT_SYMBOL(find_path_device); EXPORT_SYMBOL(find_phandle); EXPORT_SYMBOL(get_property); +EXPORT_SYMBOL(device_is_compatible); EXPORT_SYMBOL(pci_io_base); EXPORT_SYMBOL(pci_device_loc); EXPORT_SYMBOL(feature_set); EXPORT_SYMBOL(feature_clear); EXPORT_SYMBOL(feature_test); +#ifdef CONFIG_SCSI EXPORT_SYMBOL(note_scsi_host); +#endif EXPORT_SYMBOL(kd_mksound); #ifdef CONFIG_PMAC EXPORT_SYMBOL(nvram_read_byte); diff --git a/arch/ppc/kernel/prep_pci.c b/arch/ppc/kernel/prep_pci.c index b7d94d208..b48f7a1fc 100644 --- a/arch/ppc/kernel/prep_pci.c +++ b/arch/ppc/kernel/prep_pci.c @@ -1,5 +1,5 @@ /* - * $Id: prep_pci.c,v 1.23 1998/10/21 10:52:24 cort Exp $ + * $Id: prep_pci.c,v 1.24 1998/12/10 02:39:51 cort Exp $ * PReP pci functions. * Originally by Gary Thomas * rewritten and updated by Cort Dougan (cort@cs.nmt.edu) @@ -107,7 +107,7 @@ static char Omaha_pci_IRQ_routes[] __prepdata = }; /* Motorola PowerStack */ -static char Blackhawk_pci_IRQ_map[16] __prepdata = +static char Blackhawk_pci_IRQ_map[19] __prepdata = { 0, /* Slot 0 - unused */ 0, /* Slot 1 - unused */ @@ -125,6 +125,9 @@ static char Blackhawk_pci_IRQ_map[16] __prepdata = 0, /* Slot 13 - unused */ 1, /* Slot 14 - Ethernet */ 0, /* Slot 15 - unused */ + 1, /* Slot P7 */ + 2, /* Slot P6 */ + 3, /* Slot P5 */ }; static char Blackhawk_pci_IRQ_routes[] __prepdata = @@ -132,7 +135,7 @@ static char Blackhawk_pci_IRQ_routes[] __prepdata = 0, /* Line 0 - Unused */ 9, /* Line 1 */ 11, /* Line 2 */ - 14, /* Line 3 */ + 15, /* Line 3 */ 15 /* Line 4 */ }; @@ -226,6 +229,7 @@ static char ibm8xx_pci_IRQ_map[23] __prepdata = { 0, /* Slot 21 - unused */ 2, /* Slot 22 - PCI slot 1 PCIINTx# (See below) */ }; + static char ibm8xx_pci_IRQ_routes[] __prepdata = { 0, /* Line 0 - unused */ 13, /* Line 1 */ @@ -440,6 +444,8 @@ __initfunc(unsigned long route_pci_interrupts(void)) if ( _prep_type == _PREP_Motorola) { + unsigned short irq_mode; + switch (inb(0x800) & 0xF0) { case 0x10: /* MVME16xx */ @@ -474,6 +480,14 @@ __initfunc(unsigned long route_pci_interrupts(void)) Motherboard_routes = Blackhawk_pci_IRQ_routes; break; } + /* AJF adjust level/edge control according to routes */ + irq_mode = 0; + for (i = 1; i <= 4; i++) + { + irq_mode |= ( 1 << Motherboard_routes[i] ); + } + outb( irq_mode & 0xff, 0x4d0 ); + outb( (irq_mode >> 8) & 0xff, 0x4d1 ); } else if ( _prep_type == _PREP_IBM ) { unsigned char pl_id; diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c index e596f9ea5..72752e11f 100644 --- a/arch/ppc/kernel/prep_setup.c +++ b/arch/ppc/kernel/prep_setup.c @@ -189,11 +189,6 @@ prep_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p)) /* Enable L2. Assume we don't need to flush -- Cort*/ *(unsigned char *)(0x8000081c) = *(unsigned char *)(0x8000081c)|3; - /* make the serial port the console */ - /* strcat(cmd_line,"console=ttyS0,9600n8"); */ - /* use the normal console but send output to the serial port, too */ - /*strcat(cmd_line,"console=tty0 console=ttyS0,9600n8");*/ - sprintf(cmd_line,"%s console=tty0 console=ttyS0,9600n8", cmd_line); printk("Boot arguments: %s\n", cmd_line); #ifdef CONFIG_SOUND_CS4232 diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index 5ea55cee9..ebe64a429 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -1,4 +1,6 @@ /* + * $Id: process.c,v 1.70 1999/01/07 16:28:59 cort Exp $ + * * linux/arch/ppc/kernel/process.c * * Derived from "arch/i386/kernel/process.c" @@ -180,13 +182,6 @@ switch_to(struct task_struct *prev, struct task_struct *new) if ( prev->tss.regs->msr & MSR_FP ) smp_giveup_fpu(prev); - /* be noisy about processor changes for debugging -- Cort */ - if ( (new->last_processor != NO_PROC_ID) && - (new->last_processor != new->processor) ) - printk("switch_to(): changing cpu's %d -> %d %s/%d\n", - new->last_processor,new->processor, - new->comm,new->pid); - prev->last_processor = prev->processor; current_set[smp_processor_id()] = new; #endif /* __SMP__ */ @@ -236,6 +231,19 @@ void show_regs(struct pt_regs * regs) out: } +void instruction_dump (unsigned long *pc) +{ + int i; + + if((((unsigned long) pc) & 3)) + return; + + printk("Instruction DUMP:"); + for(i = -3; i < 6; i++) + printk("%c%08lx%c",i?' ':'<',pc[i],i?' ':'>'); + printk("\n"); +} + void exit_thread(void) { if (last_task_used_math == current) @@ -450,6 +458,7 @@ print_backtrace(unsigned long *sp) printk("\n"); } +#if 0 /* * Low level print for debugging - Cort */ @@ -537,3 +546,4 @@ __initfunc(void ll_puts(const char *s)) orig_x = x; orig_y = y; } +#endif diff --git a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c index 62b2b03af..e2c6b13a0 100644 --- a/arch/ppc/kernel/ptrace.c +++ b/arch/ppc/kernel/ptrace.c @@ -362,7 +362,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) case PTRACE_PEEKDATA: { unsigned long tmp; + down(&child->mm->mmap_sem); ret = read_long(child, addr, &tmp); + up(&child->mm->mmap_sem); if (ret < 0) goto out; ret = verify_area(VERIFY_WRITE, (void *) data, sizeof(long)); @@ -410,7 +412,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) /* If I and D space are separate, this will have to be fixed. */ case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKEDATA: + down(&child->mm->mmap_sem); ret = write_long(child,addr,data); + up(&child->mm->mmap_sem); goto out; case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 706c1dde2..50cd70889 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -1,5 +1,5 @@ /* - * $Id: setup.c,v 1.117 1998/11/09 19:55:53 geert Exp $ + * $Id: setup.c,v 1.122 1998/12/31 20:51:19 cort Exp $ * Common prep/pmac/chrp boot and setup code. */ @@ -35,7 +35,7 @@ extern unsigned long m68k_machtype; extern int parse_bootinfo(const struct bi_record *); extern char _end[]; #ifdef CONFIG_APUS -struct mem_info ramdisk; +extern struct mem_info ramdisk; unsigned long isa_io_base; unsigned long isa_mem_base; unsigned long pci_dram_offset; @@ -259,6 +259,9 @@ void ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq) break; } #endif +#if defined(CONFIG_MBX) + mbx_ide_init_hwif_ports(p,base,irq); +#endif } EXPORT_SYMBOL(ide_init_hwif_ports); #endif @@ -464,9 +467,9 @@ int get_cpuinfo(char *buffer) * Find out what kind of machine we're on and save any data we need * from the early boot process (devtree is copied on pmac by prom_init() ) */ -__initfunc(unsigned long +unsigned long __init identify_machine(unsigned long r3, unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7)) + unsigned long r6, unsigned long r7) { extern void setup_pci_ptrs(void); @@ -491,6 +494,9 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5, char *model; have_of = 1; + + /* prom_init has already been called from __start */ + finish_device_tree(); /* ask the OF info if we're a chrp or pmac */ model = get_property(find_path_device("/"), "device_type", NULL); if ( model && !strncmp("chrp",model,4) ) @@ -510,8 +516,10 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5, if ( have_of ) { +#ifdef CONFIG_MACH_SPECIFIC /* prom_init has already been called from __start */ finish_device_tree(); +#endif /* CONFIG_MACH_SPECIFIC */ /* * If we were booted via quik, r3 points to the physical * address of the command-line parameters. @@ -665,7 +673,7 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5, #else /* CONFIG_MBX */ if ( r3 ) - memcpy( (void *)&res,(void *)(r3+KERNELBASE), sizeof(bd_t) ); + memcpy( (void *)res,(void *)(r3+KERNELBASE), sizeof(bd_t) ); #ifdef CONFIG_PCI setup_pci_ptrs(); @@ -693,9 +701,22 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5, extern int __map_without_bats; __map_without_bats = 1; } + return 0; } +/* Checks "l2cr=xxxx" command-line option */ +void ppc_setup_l2cr(char *str, int *ints) +{ + if ( (_get_PVR() >> 16) == 8) + { + unsigned long val = simple_strtoul(str, NULL, 0); + printk(KERN_INFO "l2cr set to %lx\n", val); + _set_L2CR(0); + _set_L2CR(val); + } +} + __initfunc(void setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * memory_end_p)) { diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c index 75445925f..ba505e133 100644 --- a/arch/ppc/kernel/smp.c +++ b/arch/ppc/kernel/smp.c @@ -1,5 +1,5 @@ /* - * $Id: smp.c,v 1.36 1998/10/08 01:17:48 cort Exp $ + * $Id: smp.c,v 1.39 1998/12/28 10:28:51 paulus Exp $ * * Smp support for ppc. * @@ -43,6 +43,7 @@ spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED; unsigned int prof_multiplier[NR_CPUS]; unsigned int prof_counter[NR_CPUS]; int first_cpu_booted = 0; +cycles_t cacheflush_time; /* all cpu mappings are 1-1 -- Cort */ int cpu_number_map[NR_CPUS] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,}; @@ -144,7 +145,14 @@ void smp_message_recv(void) void smp_send_reschedule(int cpu) { - smp_message_pass(cpu, MSG_RESCHEDULE, 0, 0); + /* This is only used if `cpu' is running an idle task, + so it will reschedule itself anyway... */ + /*smp_message_pass(cpu, MSG_RESCHEDULE, 0, 0);*/ +} + +void smp_send_stop(void) +{ + smp_message_pass(MSG_ALL_BUT_SELF, MSG_STOP_CPU, 0, 0); } spinlock_t mesg_pass_lock = SPIN_LOCK_UNLOCKED; @@ -152,7 +160,7 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait) { if ( _machine != _MACH_Pmac ) return; - /*printk("SMP %d: sending smp message\n", current->processor);*/ +printk("SMP %d: sending smp message %x\n", current->processor, msg); if (smp_processor_id() ) printk("pass from cpu 1\n"); spin_lock(&mesg_pass_lock); #define OTHER (~smp_processor_id() & 1) @@ -179,17 +187,18 @@ if (smp_processor_id() ) printk("pass from cpu 1\n"); spin_unlock(&mesg_pass_lock); } -__initfunc(void smp_boot_cpus(void)) +void __init smp_boot_cpus(void) { extern struct task_struct *current_set[NR_CPUS]; extern void __secondary_start(void); int i; struct task_struct *p; - + unsigned long a; + printk("Entering SMP Mode...\n"); first_cpu_booted = 1; - dcbf(&first_cpu_booted); + /*dcbf(&first_cpu_booted);*/ for (i = 0; i < NR_CPUS; i++) { prof_counter[i] = 1; @@ -200,7 +209,13 @@ __initfunc(void smp_boot_cpus(void)) smp_store_cpu_info(0); active_kernel_processor = 0; current->processor = 0; - + + /* + * XXX very rough, assumes 20 bus cycles to read a cache line, + * timebase increments every 4 bus cycles, 32kB L1 data cache. + */ + cacheflush_time = 5 * 1024; + if ( _machine != _MACH_Pmac ) { printk("SMP not supported on this machine.\n"); @@ -213,10 +228,16 @@ __initfunc(void smp_boot_cpus(void)) if ( !p ) panic("No idle task for secondary processor\n"); p->processor = 1; + p->has_cpu = 1; current_set[1] = p; /* need to flush here since secondary bat's aren't setup */ - dcbf((void *)¤t_set[1]); + /* XXX ??? */ + for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32) + asm volatile("dcbf 0,%0" : : "r" (a) : "memory"); + asm volatile("sync"); + + /*dcbf((void *)¤t_set[1]);*/ /* setup entry point of secondary processor */ *(volatile unsigned long *)(0xf2800000) = (unsigned long)__secondary_start-KERNELBASE; @@ -238,7 +259,7 @@ __initfunc(void smp_boot_cpus(void)) if(cpu_callin_map[1]) { printk("Processor %d found.\n", smp_num_cpus); smp_num_cpus++; -#if 0 /* this sync's the decr's, but we don't want this now -- Cort */ +#if 1 /* this sync's the decr's, but we don't want this now -- Cort */ set_dec(decrementer_count); #endif } else { @@ -251,19 +272,17 @@ __initfunc(void smp_boot_cpus(void)) smp_message_pass(1,0xf0f0, 0, 0); } -__initfunc(void smp_commence(void)) +void __init smp_commence(void) { printk("SMP %d: smp_commence()\n",current->processor); /* * Lets the callin's below out of their loop. */ - local_flush_tlb_all(); smp_commenced = 1; - local_flush_tlb_all(); } /* intel needs this */ -__initfunc(void initialize_secondary(void)) +void __init initialize_secondary(void) { } @@ -275,33 +294,34 @@ asmlinkage int __init start_secondary(void *unused) return cpu_idle(NULL); } -__initfunc(void smp_callin(void)) +void __init smp_callin(void) { printk("SMP %d: smp_callin()\n",current->processor); smp_store_cpu_info(current->processor); set_dec(decrementer_count); - +#if 0 current->mm->mmap->vm_page_prot = PAGE_SHARED; current->mm->mmap->vm_start = PAGE_OFFSET; current->mm->mmap->vm_end = init_task.mm->mmap->vm_end; - - cpu_callin_map[current->processor] = current->processor; +#endif + cpu_callin_map[current->processor] = 1; while(!smp_commenced) barrier(); __sti(); + printk("SMP %d: smp_callin done\n", current->processor); } -__initfunc(void smp_setup(char *str, int *ints)) +void __init smp_setup(char *str, int *ints) { printk("SMP %d: smp_setup()\n",current->processor); } -__initfunc(int setup_profiling_timer(unsigned int multiplier)) +int __init setup_profiling_timer(unsigned int multiplier) { return 0; } -__initfunc(void smp_store_cpu_info(int id)) +void __init smp_store_cpu_info(int id) { struct cpuinfo_PPC *c = &cpu_data[id]; diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c index 8bada0e69..32f60a236 100644 --- a/arch/ppc/kernel/time.c +++ b/arch/ppc/kernel/time.c @@ -1,5 +1,5 @@ /* - * $Id: time.c,v 1.36 1998/10/10 12:16:08 geert Exp $ + * $Id: time.c,v 1.39 1998/12/28 10:28:51 paulus Exp $ * Common time routines among all ppc machines. * * Written by Cort Dougan (cort@cs.nmt.edu) to merge @@ -17,6 +17,9 @@ * This is then divided by 4, providing a 8192 Hz clock into the PIT. * Since it is not possible to get a nice 100 Hz clock out of this, without * creating a software PLL, I have set HZ to 128. -- Dan + * + * 1997-09-10 Updated NTP code according to technical memorandum Jan '96 + * "A Kernel Model for Precision Timekeeping" by Dave Mills */ #include <linux/config.h> @@ -78,6 +81,26 @@ void timer_interrupt(struct pt_regs * regs) unsigned dcache_locked = unlock_dcache(); hardirq_enter(cpu); +#ifdef __SMP__ + { + unsigned int loops = 100000000; + while (test_bit(0, &global_irq_lock)) { + if (smp_processor_id() == global_irq_holder) { + printk("uh oh, interrupt while we hold global irq lock!\n"); +#ifdef CONFIG_XMON + xmon(0); +#endif + break; + } + if (loops-- == 0) { + printk("do_IRQ waiting for irq lock (holder=%d)\n", global_irq_holder); +#ifdef CONFIG_XMON + xmon(0); +#endif + } + } + } +#endif /* __SMP__ */ while ((dval = get_dec()) < 0) { /* @@ -133,9 +156,9 @@ void timebase_interrupt(int irq, void * dev, struct pt_regs * regs) static int mbx_set_rtc_time(unsigned long time) { - ((immap_t *)MBX_IMAP_ADDR)->im_sitk.sitk_rtck = KAPWR_KEY; - ((immap_t *)MBX_IMAP_ADDR)->im_sit.sit_rtc = time; - ((immap_t *)MBX_IMAP_ADDR)->im_sitk.sitk_rtck = ~KAPWR_KEY; + ((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = KAPWR_KEY; + ((immap_t *)IMAP_ADDR)->im_sit.sit_rtc = time; + ((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = ~KAPWR_KEY; return(0); } #endif /* CONFIG_MBX */ @@ -150,12 +173,15 @@ void do_gettimeofday(struct timeval *tv) save_flags(flags); cli(); *tv = xtime; + /* XXX we don't seem to have the decrementers synced properly yet */ +#ifndef __SMP__ tv->tv_usec += (decrementer_count - get_dec()) * count_period_num / count_period_den; if (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; tv->tv_sec++; } +#endif restore_flags(flags); } @@ -172,6 +198,11 @@ void do_settimeofday(struct timeval *tv) xtime.tv_sec = tv->tv_sec; xtime.tv_usec = tv->tv_usec - frac_tick; set_dec(frac_tick * count_period_den / count_period_num); + time_adjust = 0; /* stop active adjtime() */ + time_status |= STA_UNSYNC; + time_state = TIME_ERROR; /* p. 24, (a) */ + time_maxerror = NTP_PHASE_LIMIT; + time_esterror = NTP_PHASE_LIMIT; restore_flags(flags); } @@ -227,13 +258,13 @@ __initfunc(void time_init(void)) * modify these registers we have to write the key value to * the key location associated with the register. */ - ((immap_t *)MBX_IMAP_ADDR)->im_sitk.sitk_tbscrk = KAPWR_KEY; - ((immap_t *)MBX_IMAP_ADDR)->im_sitk.sitk_rtcsck = KAPWR_KEY; + ((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk = KAPWR_KEY; + ((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck = KAPWR_KEY; /* Disable the RTC one second and alarm interrupts. */ - ((immap_t *)MBX_IMAP_ADDR)->im_sit.sit_rtcsc &= + ((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc &= ~(RTCSC_SIE | RTCSC_ALE); /* Enabling the decrementer also enables the timebase interrupts @@ -241,7 +272,7 @@ __initfunc(void time_init(void)) * we have to enable the timebase). The decrementer interrupt * is wired into the vector table, nothing to do here for that. */ - ((immap_t *)MBX_IMAP_ADDR)->im_sit.sit_tbscr = + ((immap_t *)IMAP_ADDR)->im_sit.sit_tbscr = ((mk_int_int_mask(DEC_INTERRUPT) << 8) | (TBSCR_TBF | TBSCR_TBE)); if (request_irq(DEC_INTERRUPT, timebase_interrupt, 0, "tbint", NULL) != 0) @@ -249,7 +280,7 @@ __initfunc(void time_init(void)) /* Get time from the RTC. */ - xtime.tv_sec = ((immap_t *)MBX_IMAP_ADDR)->im_sit.sit_rtc; + xtime.tv_sec = ((immap_t *)IMAP_ADDR)->im_sit.sit_rtc; xtime.tv_usec = 0; #endif /* CONFIG_MBX */ @@ -343,10 +374,10 @@ __initfunc(void prep_calibrate_decr_handler(int irq, void *dev, struct pt_regs * */ __initfunc(void mbx_calibrate_decr(void)) { - bd_t *binfo = (bd_t *)&res; + bd_t *binfo = (bd_t *)res; int freq, fp, divisor; - if ((((immap_t *)MBX_IMAP_ADDR)->im_clkrst.car_sccr & 0x02000000) == 0) + if ((((immap_t *)IMAP_ADDR)->im_clkrst.car_sccr & 0x02000000) == 0) printk("WARNING: Wrong decrementer source clock.\n"); /* The manual says the frequency is in Hz, but it is really diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index af02252f9..fa5184af2 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -79,6 +79,7 @@ _exception(int signr, struct pt_regs *regs) debugger(regs); #endif print_backtrace((unsigned long *)regs->gpr[1]); + instruction_dump((unsigned long *)regs->nip); panic("Exception in kernel pc %lx signal %d",regs->nip,signr); } force_sig(signr, current); @@ -126,6 +127,7 @@ MachineCheckException(struct pt_regs *regs) debugger(regs); #endif print_backtrace((unsigned long *)regs->gpr[1]); + instruction_dump((unsigned long *)regs->nip); panic("machine check"); } _exception(SIGSEGV, regs); @@ -219,6 +221,7 @@ StackOverflow(struct pt_regs *regs) #endif show_regs(regs); print_backtrace((unsigned long *)regs->gpr[1]); + instruction_dump((unsigned long *)regs->nip); panic("kernel stack overflow"); } diff --git a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile index 4cc49de17..8ca9a3cd5 100644 --- a/arch/ppc/lib/Makefile +++ b/arch/ppc/lib/Makefile @@ -8,7 +8,7 @@ O_TARGET = lib.o O_OBJS = checksum.o string.o strcase.o -ifdef SMP +ifdef CONFIG_SMP O_OBJS += locks.o endif diff --git a/arch/ppc/lib/locks.c b/arch/ppc/lib/locks.c index 073e7076c..2d2a2d8c0 100644 --- a/arch/ppc/lib/locks.c +++ b/arch/ppc/lib/locks.c @@ -1,5 +1,5 @@ /* - * $Id: locks.c,v 1.20 1998/10/08 01:17:32 cort Exp $ + * $Id: locks.c,v 1.21 1998/12/28 10:28:53 paulus Exp $ * * Locks for smp ppc * @@ -18,7 +18,7 @@ #define DEBUG_LOCKS 1 #undef INIT_STUCK -#define INIT_STUCK 0xffffffff +#define INIT_STUCK 200000000 /*0xffffffff*/ void _spin_lock(spinlock_t *lock) { @@ -76,9 +76,9 @@ void _spin_unlock(spinlock_t *lp) lp->owner_pc,lp->lock); #endif /* DEBUG_LOCKS */ lp->owner_pc = lp->owner_cpu = 0; - eieio(); - lp->lock = 0; - eieio(); + eieio(); /* actually I believe eieio only orders */ + lp->lock = 0; /* non-cacheable accesses (on 604 at least) */ + eieio(); /* - paulus. */ } /* diff --git a/arch/ppc/mbx_defconfig b/arch/ppc/mbx_defconfig index e0b94ce6a..54035b866 100644 --- a/arch/ppc/mbx_defconfig +++ b/arch/ppc/mbx_defconfig @@ -14,15 +14,17 @@ CONFIG_8xx=y # CONFIG_ALL_PPC is not set # CONFIG_APUS is not set CONFIG_MBX=y -CONFIG_SERIAL_CONSOLE=y +CONFIG_SMP=n CONFIG_MACH_SPECIFIC=y +CONFIG_SERIAL_CONSOLE=y # # General setup # -# CONFIG_EXPERIMENTAL is not set +CONFIG_EXPERIMENTAL=y # CONFIG_MODULES is not set CONFIG_PCI=y +# CONFIG_PCI_QUIRKS is not set CONFIG_PCI_OLD_PROC=y CONFIG_NET=y # CONFIG_SYSCTL is not set @@ -33,13 +35,19 @@ CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_BINFMT_JAVA is not set # CONFIG_PARPORT is not set +# CONFIG_VGA_CONSOLE is not set +# CONFIG_FB is not set +# CONFIG_PMAC_PBOOK is not set # CONFIG_MAC_KEYBOARD is not set # CONFIG_MAC_FLOPPY is not set # CONFIG_MAC_SERIAL is not set +# CONFIG_ADBMOUSE is not set +# CONFIG_BLK_DEV_IDE_PMAC is not set # CONFIG_PROC_DEVICETREE is not set # CONFIG_KGDB is not set # CONFIG_XMON is not set -CONFIG_VGA_CONSOLE=y +# CONFIG_TOTALMP is not set +# CONFIG_BOOTX_TEXT is not set # # Plug and Play support @@ -47,7 +55,7 @@ CONFIG_VGA_CONSOLE=y # CONFIG_PNP is not set # -# Floppy, IDE, and other block devices +# Block devices # # CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_IDE is not set @@ -84,8 +92,19 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_RARP is not set CONFIG_IP_NOSR=y # CONFIG_SKB_LARGE is not set +# CONFIG_IPV6 is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_BRIDGE is not set +# CONFIG_LLC 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 +# CONFIG_CPU_IS_SLOW is not set +# CONFIG_NET_SCHED is not set # # SCSI support @@ -100,22 +119,26 @@ CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_EQUALIZER is not set CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC 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_RTL8139 is not set +# CONFIG_YELLOWFIN is not set # CONFIG_NET_ISA is not set # CONFIG_NET_EISA is not set # CONFIG_NET_POCKET is not set # CONFIG_FDDI is not set +# CONFIG_HIPPI is not set # CONFIG_DLCI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set # CONFIG_NET_RADIO is not set # CONFIG_TR is not set -# CONFIG_WAN_DRIVERS is not set -# CONFIG_LAPBETHER is not set -# CONFIG_X25_ASY is not set +# CONFIG_SHAPER is not set +# CONFIG_HOSTESS_SV11 is not set # # Amateur Radio support @@ -133,6 +156,32 @@ CONFIG_NET_ETHERNET=y # CONFIG_CD_NO_IDESCSI is not set # +# Console drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_UNIX98_PTYS is not set +# CONFIG_MOUSE is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_WATCHDOG is not set +# CONFIG_RTC is not set +# CONFIG_VIDEO_DEV is not set +# CONFIG_NVRAM is not set +# CONFIG_JOYSTICK is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set + +# # Filesystems # # CONFIG_QUOTA is not set @@ -159,31 +208,15 @@ CONFIG_LOCKD=y # CONFIG_ROMFS_FS is not set # CONFIG_AUTOFS_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_SMD_DISKLABEL is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_ADFS_FS is not set +# CONFIG_QNX4FS_FS is not set # CONFIG_MAC_PARTITION is not set # CONFIG_NLS is not set # -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL is not set -# CONFIG_SERIAL_EXTENDED is not set -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_MOUSE is not set -# CONFIG_QIC02_TAPE is not set -# CONFIG_WATCHDOG is not set -# CONFIG_RTC is not set -# CONFIG_VIDEO_DEV is not set -# CONFIG_NVRAM is not set -# CONFIG_JOYSTICK is not set -# CONFIG_MISC_RADIO is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_FTAPE is not set - -# # Sound # # CONFIG_SOUND is not set diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c index b45f4e6f4..42e2918b1 100644 --- a/arch/ppc/mm/fault.c +++ b/arch/ppc/mm/fault.c @@ -89,6 +89,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, printk("page fault in interrupt handler, addr=%lx\n", address); show_regs(regs); + instruction_dump((unsigned long *)regs->nip); #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) if (debugger_kernel_faults) debugger(regs); @@ -174,6 +175,7 @@ bad_page_fault(struct pt_regs *regs, unsigned long address) /* kernel has accessed a bad area */ show_regs(regs); print_backtrace( (unsigned long *)regs->gpr[1] ); + instruction_dump((unsigned long *)regs->nip); #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) if (debugger_kernel_faults) debugger(regs); diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index 44104fd4e..b80d4c21c 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -1,5 +1,5 @@ /* - * $Id: init.c,v 1.130 1998/11/10 10:09:20 paulus Exp $ + * $Id: init.c,v 1.139 1998/12/29 19:53:49 cort Exp $ * * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) @@ -55,7 +55,7 @@ /* END APUS includes */ int prom_trashed; -int next_mmu_context; +atomic_t next_mmu_context; unsigned long *end_of_DRAM; int mem_init_done; extern pgd_t swapper_pg_dir[]; @@ -71,7 +71,8 @@ unsigned long ioremap_base; unsigned long ioremap_bot; unsigned long avail_start; struct pgtable_cache_struct quicklists; -struct mem_info memory[NUM_MEMINFO]; +extern int num_memory; +extern struct mem_info memory[NUM_MEMINFO]; extern boot_infos_t *boot_infos; void MMU_init(void); @@ -89,6 +90,27 @@ void map_page(struct task_struct *, unsigned long va, extern void die_if_kernel(char *,struct pt_regs *,long); extern void show_net_buffers(void); + +/* + * The following stuff defines a data structure for representing + * areas of memory as an array of (address, length) pairs, and + * procedures for manipulating them. + */ +#define MAX_MEM_REGIONS 32 + +struct mem_pieces { + int n_regions; + struct reg_property regions[MAX_MEM_REGIONS]; +}; +struct mem_pieces phys_mem; +struct mem_pieces phys_avail; +struct mem_pieces prom_mem; + +static void remove_mem_piece(struct mem_pieces *, unsigned, unsigned, int); +void *find_mem_piece(unsigned, unsigned); +static void print_mem_pieces(struct mem_pieces *); +static void append_mem_piece(struct mem_pieces *, unsigned, unsigned); + extern struct task_struct *current_set[NR_CPUS]; PTE *Hash, *Hash_end; @@ -529,38 +551,19 @@ mmu_context_overflow(void) } read_unlock(&tasklist_lock); flush_hash_segments(0x10, 0xffffff); - next_mmu_context = 0; + atomic_set(&next_mmu_context, 0); /* make sure current always has a context */ - current->mm->context = MUNGE_CONTEXT(++next_mmu_context); + current->mm->context = MUNGE_CONTEXT(atomic_inc_return(&next_mmu_context)); set_context(current->mm->context); #else /* We set the value to -1 because it is pre-incremented before * before use. */ - next_mmu_context = -1; + atomic_set(&next_mmu_context, -1); #endif } /* - * The following stuff defines a data structure for representing - * areas of memory as an array of (address, length) pairs, and - * procedures for manipulating them. - */ -#define MAX_MEM_REGIONS 32 - -struct mem_pieces { - int n_regions; - struct reg_property regions[MAX_MEM_REGIONS]; -}; -struct mem_pieces phys_mem; -struct mem_pieces phys_avail; -struct mem_pieces prom_mem; - -static void remove_mem_piece(struct mem_pieces *, unsigned, unsigned, int); -void *find_mem_piece(unsigned, unsigned); -static void print_mem_pieces(struct mem_pieces *); - -/* * Scan a region for a piece of a given size with the required alignment. */ __initfunc(void * @@ -653,14 +656,26 @@ __initfunc(static void print_mem_pieces(struct mem_pieces *mp)) printk("\n"); } +/* + * Add some memory to an array of pieces + */ +__initfunc(static void + append_mem_piece(struct mem_pieces *mp, unsigned start, unsigned size)) +{ + struct reg_property *rp; + if (mp->n_regions >= MAX_MEM_REGIONS) + return; + rp = &mp->regions[mp->n_regions++]; + rp->address = start; + rp->size = size; +} #ifndef CONFIG_8xx static void hash_init(void); static void get_mem_prop(char *, struct mem_pieces *); static void sort_mem_pieces(struct mem_pieces *); static void coalesce_mem_pieces(struct mem_pieces *); -static void append_mem_piece(struct mem_pieces *, unsigned, unsigned); __initfunc(static void sort_mem_pieces(struct mem_pieces *mp)) { @@ -703,21 +718,6 @@ __initfunc(static void coalesce_mem_pieces(struct mem_pieces *mp)) } /* - * Add some memory to an array of pieces - */ -__initfunc(static void - append_mem_piece(struct mem_pieces *mp, unsigned start, unsigned size)) -{ - struct reg_property *rp; - - if (mp->n_regions >= MAX_MEM_REGIONS) - return; - rp = &mp->regions[mp->n_regions++]; - rp->address = start; - rp->size = size; -} - -/* * Read in a property describing some pieces of memory. */ @@ -963,8 +963,10 @@ __initfunc(void MMU_init(void)) #ifndef CONFIG_8xx if (have_of) end_of_DRAM = pmac_find_end_of_memory(); +#ifdef CONFIG_APUS else if (_machine == _MACH_apus ) end_of_DRAM = apus_find_end_of_memory(); +#endif else /* prep */ end_of_DRAM = prep_find_end_of_memory(); @@ -1023,8 +1025,10 @@ __initfunc(void MMU_init(void)) */ ioremap(NVRAM_ADDR, NVRAM_SIZE); ioremap(MBX_CSR_ADDR, MBX_CSR_SIZE); - ioremap(MBX_IMAP_ADDR, MBX_IMAP_SIZE); + ioremap(IMAP_ADDR, IMAP_SIZE); ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE); + /* ide needs to be able to get at PCI space -- Cort */ + ioremap(0x80000000, 0x4000); #endif /* CONFIG_8xx */ } @@ -1189,7 +1193,7 @@ __initfunc(unsigned long *mbx_find_end_of_memory(void)) volatile memctl8xx_t *mcp; unsigned long *ret; - binfo = (bd_t *)&res; + binfo = (bd_t *)res; /* * The MBX does weird things with the mmaps for ram. @@ -1200,11 +1204,13 @@ __initfunc(unsigned long *mbx_find_end_of_memory(void)) * In fact, it might be the best idea to just read the DRAM * config registers and set the mem areas accordingly. */ - mcp = (memctl8xx_t *)(&(((immap_t *)MBX_IMAP_ADDR)->im_memctl)); + mcp = (memctl8xx_t *)(&(((immap_t *)IMAP_ADDR)->im_memctl)); + append_mem_piece(&phys_mem, 0, binfo->bi_memsize); +#if 0 phys_mem.regions[0].address = 0; - phys_mem.regions[0].size = binfo->bi_memsize; - + phys_mem.regions[0].size = binfo->bi_memsize; phys_mem.n_regions = 1; +#endif ret = __va(phys_mem.regions[0].address+ phys_mem.regions[0].size); @@ -1293,7 +1299,7 @@ __initfunc(unsigned long *pmac_find_end_of_memory(void)) /* * This finds the amount of physical ram and does necessary * setup for prep. This is pretty architecture specific so - * this will likely stay seperate from the pmac. + * this will likely stay separate from the pmac. * -- Cort */ __initfunc(unsigned long *prep_find_end_of_memory(void)) @@ -1322,6 +1328,7 @@ __initfunc(unsigned long *prep_find_end_of_memory(void)) return (__va(total)); } +#ifdef CONFIG_APUS #define HARDWARE_MAPPED_SIZE (512*1024) __initfunc(unsigned long *apus_find_end_of_memory(void)) { @@ -1381,15 +1388,22 @@ __initfunc(unsigned long *apus_find_end_of_memory(void)) /* Remove the upper 512KB where the PPC exception vectors are mapped. */ top -= HARDWARE_MAPPED_SIZE; - remove_mem_piece(&phys_avail, top, - HARDWARE_MAPPED_SIZE, 0); +#if 0 + /* This would be neat, but it breaks on A3000 machines!? */ + remove_mem_piece(&phys_avail, top, 16384, 0); +#else + remove_mem_piece(&phys_avail, top, HARDWARE_MAPPED_SIZE, 0); +#endif + } - /* FIXME:APUS: Only handles one block of memory! Problem is - that the VTOP/PTOV code in head.S would be a mess if it had - to handle more than one block. */ + /* 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 __va(memory[0].addr + memory[0].size); } +#endif /* CONFIG_APUS */ /* * Initialize the hash table and patch the instructions in head.S. @@ -1400,7 +1414,7 @@ __initfunc(static void hash_init(void)) unsigned long h, ramsize; extern unsigned int hash_page_patch_A[], hash_page_patch_B[], - hash_page_patch_C[]; + hash_page_patch_C[], hash_page[]; /* * Allow 64k of hash table for every 16MB of memory, @@ -1475,7 +1489,17 @@ __initfunc(static void hash_init(void)) flush_icache_range((unsigned long) b(hash_page_patch_A), (unsigned long) b(hash_page_patch_C + 1)); } - else + else { Hash_end = 0; + /* + * Put a blr (procedure return) instruction at the + * start of hash_page, since we can still get DSI + * exceptions on a 603. + */ + *b(hash_page) = 0x4e800020; + flush_icache_range((unsigned long) b(hash_page), + (unsigned long) b(hash_page + 1)); + } } #endif /* ndef CONFIG_8xx */ + diff --git a/arch/ppc/pmac_defconfig b/arch/ppc/pmac_defconfig index ae1303bb4..811d599c0 100644 --- a/arch/ppc/pmac_defconfig +++ b/arch/ppc/pmac_defconfig @@ -15,6 +15,7 @@ CONFIG_PMAC=y # CONFIG_APUS is not set # CONFIG_MBX is not set CONFIG_MACH_SPECIFIC=y +# CONFIG_SMP is not set # # General setup @@ -137,6 +138,10 @@ CONFIG_ATALK=m # CONFIG_NET_FASTROUTE is not set # CONFIG_NET_HW_FLOWCONTROL is not set # CONFIG_CPU_IS_SLOW is not set + +# +# QoS and/or fair queueing +# # CONFIG_NET_SCHED is not set # @@ -164,6 +169,7 @@ CONFIG_SCSI_CONSTANTS=y # SCSI low-level drivers # # 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 @@ -174,14 +180,16 @@ CONFIG_AIC7XXX_RESET_DELAY=15 # 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_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_EATA 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_NCR53C406A is not set # CONFIG_SCSI_NCR53C7xx is not set # CONFIG_SCSI_NCR53C8XX is not set @@ -218,6 +226,7 @@ CONFIG_BMAC=y # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_RTL8139 is not set # CONFIG_YELLOWFIN is not set +# CONFIG_ACENIC is not set # CONFIG_NET_ISA is not set CONFIG_NET_EISA=y # CONFIG_PCNET32 is not set @@ -225,7 +234,7 @@ CONFIG_NET_EISA=y # CONFIG_APRICOT is not set # CONFIG_CS89x0 is not set CONFIG_DE4X5=y -CONFIG_DEC_ELCP=m +# CONFIG_DEC_ELCP is not set # CONFIG_DGRS is not set # CONFIG_EEXPRESS_PRO100 is not set # CONFIG_LNE390 is not set @@ -253,6 +262,7 @@ CONFIG_PPP=y # CONFIG_TR is not set # CONFIG_SHAPER is not set # CONFIG_HOSTESS_SV11 is not set +# CONFIG_COSA is not set # # Amateur Radio support @@ -282,6 +292,7 @@ CONFIG_FB_IMSTT=y CONFIG_FB_CT65550=y # CONFIG_FB_S3TRIO is not set # CONFIG_FB_MATROX is not set +CONFIG_FB_ATY=y # CONFIG_FB_VIRTUAL is not set # CONFIG_FBCON_ADVANCED is not set CONFIG_FBCON_CFB8=y @@ -303,7 +314,7 @@ CONFIG_FONT_SUN12x22=y # CONFIG_VT=y CONFIG_VT_CONSOLE=y -CONFIG_SERIAL=m +# CONFIG_SERIAL is not set # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set CONFIG_UNIX98_PTYS=y @@ -311,9 +322,17 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_MOUSE is not set # CONFIG_QIC02_TAPE is not set # CONFIG_WATCHDOG is not set +CONFIG_NVRAM=y # CONFIG_RTC is not set + +# +# Video For Linux +# # CONFIG_VIDEO_DEV is not set -CONFIG_NVRAM=y + +# +# Joystick support +# # CONFIG_JOYSTICK is not set # @@ -325,37 +344,47 @@ CONFIG_NVRAM=y # Filesystems # # CONFIG_QUOTA is not set -# CONFIG_MINIX_FS is not set -CONFIG_EXT2_FS=y -CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set +CONFIG_AUTOFS_FS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +CONFIG_HFS_FS=y CONFIG_FAT_FS=m CONFIG_MSDOS_FS=m # CONFIG_UMSDOS_FS is not set CONFIG_VFAT_FS=m +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set CONFIG_NFS_FS=y CONFIG_NFSD=y # CONFIG_NFSD_SUN is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y -# CONFIG_CODA_FS is not set # CONFIG_SMB_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_AFFS_FS is not set -CONFIG_HFS_FS=y -# CONFIG_ROMFS_FS is not set -CONFIG_AUTOFS_FS=y -# CONFIG_UFS_FS is not set +# CONFIG_NCP_FS is not set + +# +# Partition Types +# # CONFIG_BSD_DISKLABEL is not set +CONFIG_MAC_PARTITION=y # CONFIG_SMD_DISKLABEL is not set # CONFIG_SOLARIS_X86_PARTITION is not set -CONFIG_DEVPTS_FS=y -# CONFIG_ADFS_FS is not set -# CONFIG_QNX4FS_FS is not set -CONFIG_MAC_PARTITION=y +# CONFIG_UNIXWARE_DISKLABEL is not set CONFIG_NLS=y # @@ -386,6 +415,7 @@ CONFIG_NLS_CODEPAGE_437=y # CONFIG_NLS_ISO8859_7 is not set # CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_15 is not set # CONFIG_NLS_KOI8_R is not set # diff --git a/arch/ppc/prep_defconfig b/arch/ppc/prep_defconfig index 41db35a4a..14b4ea4a0 100644 --- a/arch/ppc/prep_defconfig +++ b/arch/ppc/prep_defconfig @@ -14,6 +14,7 @@ CONFIG_PREP=y # CONFIG_ALL_PPC is not set # CONFIG_APUS is not set # CONFIG_MBX is not set +# CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y # diff --git a/arch/ppc/vmlinux.lds b/arch/ppc/vmlinux.lds index f5c61bd6e..e322d138b 100644 --- a/arch/ppc/vmlinux.lds +++ b/arch/ppc/vmlinux.lds @@ -64,6 +64,9 @@ SECTIONS __ex_table : { *(__ex_table) } __stop___ex_table = .; + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + . = ALIGN(4096); __init_begin = .; .text.init : { *(.text.init) } |