diff options
45 files changed, 560 insertions, 543 deletions
diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index 797738c09f75..8561bd3a7a13 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile @@ -29,10 +29,10 @@ HEAD := arch/ppc64/kernel/head.o core-y += arch/ppc64/kernel/ arch/ppc64/mm/ arch/ppc64/lib/ core-$(CONFIG_XMON) += arch/ppc64/xmon/ -MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot +makeboot = $(call descend,arch/ppc64/boot,$(1)) ifdef CONFIG_PPC_PSERIES -BOOT_TARGETS = zImage znetboot.initrd zImage.initrd +BOOT_TARGETS = zImage zImage.initrd endif ifdef CONFIG_PPC_ISERIES @@ -40,22 +40,14 @@ BOOT_TARGETS = vmlinux.sminitrd vmlinux.initrd vmlinux.sm endif $(BOOT_TARGETS): vmlinux - @$(MAKEBOOT) $@ - -znetboot: vmlinux -ifdef CONFIG_SMP - cp -f vmlinux /tftpboot/vmlinux.smp -else - cp -f vmlinux /tftpboot/vmlinux -endif - @$(MAKEBOOT) $@ + @$(call makeboot,arch/ppc64/boot/$@) %_config: arch/ppc64/configs/%_defconfig rm -f .config arch/ppc64/defconfig cp -f arch/ppc64/configs/$(@:config=defconfig) arch/ppc64/defconfig archclean: - @$(MAKEBOOT) clean + @$(call makeboot,clean) archmrproper: @@ -74,3 +66,4 @@ include/asm-$(ARCH)/offsets.h: include/asm-$(ARCH)/offsets.h.tmp CLEAN_FILES += include/asm-$(ARCH)/offsets.h.tmp \ include/asm-$(ARCH)/offsets.h + diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile index f0d3db8a3344..06f4532b4ecb 100644 --- a/arch/ppc64/boot/Makefile +++ b/arch/ppc64/boot/Makefile @@ -38,85 +38,64 @@ CFLAGS = $(CPPFLAGS) -O -fno-builtin -DSTDC_HEADERS LD_ARGS = -Ttext 0x00400000 -e _start OBJCOPYFLAGS := -S -O binary -OBJS = crt0.o start.o main.o zlib.o image.o imagesize.o -#LIBS = $(TOPDIR)/lib/lib.a -LIBS = - -ifeq ($(CONFIG_SMP),y) -TFTPIMAGE=/tftpboot/zImage.chrp.smp -else -TFTPIMAGE=/tftpboot/zImage.chrp -endif - - -ifeq ($(CONFIG_PPC_ISERIES),y) -all: vmlinux.sm -else -all: $(TOPDIR)/zImage -endif - - -znetboot: zImage - cp zImage $(TFTPIMAGE) - +OBJS = $(addprefix $(obj)/,crt0.o start.o main.o zlib.o image.o imagesize.o) ifeq ($(CONFIG_PPC_ISERIES),y) -addSystemMap: addSystemMap.c - $(HOSTCC) $(HOSTCFLAGS) -o addSystemMap addSystemMap.c +boot: vmlinux.sm -vmlinux.sm: $(TOPDIR)/vmlinux addSystemMap - ./addSystemMap $(TOPDIR)/System.map $(TOPDIR)/vmlinux vmlinux.sm +$(obj)/addSystemMap: $(obj)/addSystemMap.c + $(HOSTCC) $(HOSTCFLAGS) -o $@ $< +$(obj)/vmlinux.sm: vmlinux $(obj)/addSystemMap + $(obj)/addSystemMap System.map vmlinux $(obj)/vmlinux.sm -addRamDisk: addRamDisk.c - $(HOSTCC) $(HOSTCFLAGS) -o addRamDisk addRamDisk.c +$(obj)/addRamDisk: $(obj)/addRamDisk.c + $(HOSTCC) $(HOSTCFLAGS) -o $@ $< -vmlinux.initrd: $(TOPDIR)/vmlinux addRamDisk ramdisk.image.gz $(TOPDIR)/System.map - ./addRamDisk ramdisk.image.gz $(TOPDIR)/System.map $(TOPDIR)/vmlinux vmlinux.initrd +$(obj)/vmlinux.initrd: vmlinux $(obj)/addRamDisk $(obj)/ramdisk.image.gz System.map + $(obj)/addRamDisk $(obj)/ramdisk.image.gz System.map vmlinux $(obj)/vmlinux.initrd -vmlinux.sminitrd: vmlinux.sm addRamDisk ramdisk.image.gz $(TOPDIR)/System.map - ./addRamDisk ramdisk.image.gz $(TOPDIR)/System.map vmlinux.sm vmlinux.sminitrd +$(obj)/vmlinux.sminitrd: $(obj)/vmlinux.sm $(obj)/addRamDisk $(obj)/ramdisk.image.gz System.map + $(obj)/addRamDisk $(obj)/ramdisk.image.gz System.map $(obj)/vmlinux.sm $(obj)/vmlinux.sminitrd +else +boot: zImage endif +$(obj)/piggyback: $(obj)/piggyback.c + $(HOSTCC) $(HOSTCFLAGS) -DKERNELBASE=$(KERNELBASE) -o $@ $< -znetboot.initrd: zImage.initrd - cp zImage.initrd $(TFTPIMAGE) +$(obj)/addnote: $(obj)/addnote.c + $(HOSTCC) $(HOSTCFLAGS) -o $@ $< -floppy: zImage - mcopy zImage a:zImage +$(obj)/image.o: $(obj)/piggyback $(obj)/vmlinux.gz + $(obj)/piggyback $(obj)/image < $(obj)/vmlinux.gz | $(BOOTAS) -o $@ -piggyback: piggyback.c - $(HOSTCC) $(HOSTCFLAGS) -DKERNELBASE=$(KERNELBASE) -o piggyback piggyback.c +$(obj)/sysmap.o: $(obj)/piggyback System.map + $(obj)/piggyback $(obj)/sysmap < System.map | $(BOOTAS) -o $(obj)/sysmap.o -addnote: addnote.c - $(HOSTCC) $(HOSTCFLAGS) -o addnote addnote.c +$(obj)/initrd.o: $(obj)/ramdisk.image.gz $(obj)/piggyback + $(obj)/piggyback $(obj)/initrd < $(obj)/ramdisk.image.gz | $(BOOTAS) -o $(obj)/initrd.o -image.o: piggyback vmlinux.gz - ./piggyback image < vmlinux.gz | $(BOOTAS) -o image.o - -sysmap.o: piggyback ../../../System.map - ./piggyback sysmap < ../../../System.map | $(BOOTAS) -o sysmap.o - -initrd.o: ramdisk.image.gz piggyback - ./piggyback initrd < ramdisk.image.gz | $(BOOTAS) -o initrd.o - -zImage: $(OBJS) no_initrd.o addnote - $(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) no_initrd.o $(LIBS) - ./addnote $@ +$(obj)/zImage: $(OBJS) $(obj)/no_initrd.o $(obj)/addnote + $(BOOTLD) $(LD_ARGS) -T $(obj)/zImage.lds -o $@ $(OBJS) $(obj)/no_initrd.o + $(obj)/addnote $@ -zImage.initrd: $(OBJS) initrd.o addnote - $(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) initrd.o $(LIBS) +$(obj)/zImage.initrd: $(OBJS) $(obj)/initrd.o $(obj)/addnote + $(BOOTLD) $(LD_ARGS) -T $(obj)/zImage.lds -o $@ $(OBJS) $(obj)/initrd.o ./addnote $@ -vmlinux.gz: $(TOPDIR)/vmlinux - $(OBJCOPY) $(OBJCOPYFLAGS) $(TOPDIR)/vmlinux vmlinux - ls -l vmlinux | awk '{printf "/* generated -- do not edit! */\nint uncompressed_size = %d;\n", $$5}' > imagesize.c - $(CROSS_COMPILE)nm -n $(TOPDIR)/vmlinux | tail -1 | awk '{printf "long vmlinux_end = 0x%s;\n", substr($$1,8)}' >> imagesize.c - gzip -vf9 vmlinux +$(obj)/vmlinux.gz: vmlinux + $(OBJCOPY) $(OBJCOPYFLAGS) vmlinux $(obj)/vmlinux + ls -l $(obj)/vmlinux | awk '{printf "/* generated -- do not edit! */\nint uncompressed_size = %d;\n", $$5}' > $(obj)/imagesize.c + $(CROSS_COMPILE)nm -n vmlinux | tail -1 | awk '{printf "long vmlinux_end = 0x%s;\n", substr($$1,8)}' >> $(obj)/imagesize.c + gzip -vf9 $(obj)/vmlinux -imagesize.c: vmlinux.gz +$(obj)/imagesize.c: $(obj)/vmlinux.gz clean: - rm -f piggyback note addnote $(OBJS) zImage zImage.initrd vmlinux.gz no_initrd.o imagesize.c addSystemMap vmlinux.sm addRamDisk vmlinux.initrd vmlinux.sminitrd + @rm -f $(OBJS) + @rm -f $(addprefix $(obj)/,piggyback note addnote zImage \ + zImage.initrd vmlinux.gz no_initrd.o imagesize.c addSystemMap \ + vmlinux.sm addRamDisk vmlinux.initrd vmlinux.sminitrd) diff --git a/arch/ppc64/boot/piggyback.c b/arch/ppc64/boot/piggyback.c index 31a2697151ac..235c7a87269c 100644 --- a/arch/ppc64/boot/piggyback.c +++ b/arch/ppc64/boot/piggyback.c @@ -8,6 +8,7 @@ */ #include <stdio.h> #include <unistd.h> +#include <string.h> extern long ce_exec_config[]; @@ -17,20 +18,28 @@ int main(int argc, char *argv[]) unsigned int cksum, val; unsigned char *lp; unsigned char buf[8192]; + char *varname; if (argc != 2) { fprintf(stderr, "usage: %s name <in-file >out-file\n", argv[0]); exit(1); } + + varname = strrchr(argv[1], '/'); + if (varname) + varname++; + else + varname = argv[1]; + fprintf(stdout, "#\n"); fprintf(stdout, "# Miscellaneous data structures:\n"); fprintf(stdout, "# WARNING - this file is automatically generated!\n"); fprintf(stdout, "#\n"); fprintf(stdout, "\n"); fprintf(stdout, "\t.data\n"); - fprintf(stdout, "\t.globl %s_data\n", argv[1]); - fprintf(stdout, "%s_data:\n", argv[1]); + fprintf(stdout, "\t.globl %s_data\n", varname); + fprintf(stdout, "%s_data:\n", varname); pos = 0; cksum = 0; while ((len = read(0, buf, sizeof(buf))) > 0) @@ -64,8 +73,8 @@ int main(int argc, char *argv[]) } pos += len; } - fprintf(stdout, "\t.globl %s_len\n", argv[1]); - fprintf(stdout, "%s_len:\t.long\t0x%x\n", argv[1], pos); + fprintf(stdout, "\t.globl %s_len\n", varname); + fprintf(stdout, "%s_len:\t.long\t0x%x\n", varname, pos); fflush(stdout); fclose(stdout); fprintf(stderr, "cksum = %x\n", cksum); diff --git a/arch/ppc64/config.in b/arch/ppc64/config.in index ec1e5539b0ff..2d4ddf69c839 100644 --- a/arch/ppc64/config.in +++ b/arch/ppc64/config.in @@ -7,6 +7,7 @@ define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y define_bool CONFIG_GENERIC_ISA_DMA y define_bool CONFIG_HAVE_DEC_LOCK y +define_bool CONFIG_EARLY_PRINTK y source init/Config.in @@ -21,7 +22,7 @@ define_bool CONFIG_PPC64 y bool 'Symmetric multi-processing support' CONFIG_SMP if [ "$CONFIG_SMP" = "y" ]; then bool ' Distribute interrupts on all CPUs by default' CONFIG_IRQ_ALL_CPUS - int 'Maximum number of CPUs (2-64)' CONFIG_NR_CPUS 64 + int 'Maximum number of CPUs (2-64)' CONFIG_NR_CPUS 32 if [ "$CONFIG_PPC_PSERIES" = "y" ]; then bool ' Hardware multithreading' CONFIG_HMT bool ' Discontiguous Memory Support' CONFIG_DISCONTIGMEM diff --git a/arch/ppc64/defconfig b/arch/ppc64/defconfig index 514854ba1070..b18b88fc3378 100644 --- a/arch/ppc64/defconfig +++ b/arch/ppc64/defconfig @@ -40,7 +40,7 @@ CONFIG_IRQ_ALL_CPUS=y # CONFIG_DISCONTIGMEM is not set # CONFIG_PREEMPT is not set # CONFIG_RTAS_FLASH is not set -CONFIG_NR_CPUS=64 +CONFIG_NR_CPUS=32 # # General setup @@ -132,6 +132,7 @@ CONFIG_CHR_DEV_SG=y # CONFIG_BLK_DEV_3W_XXXX_RAID is not set # CONFIG_SCSI_7000FASST is not set # CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_DPT_I2O is not set @@ -228,6 +229,12 @@ CONFIG_NET_IPIP=y # CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y CONFIG_IPV6=m + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=m +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set # CONFIG_LLC is not set @@ -287,6 +294,11 @@ CONFIG_VORTEX=y # CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set # CONFIG_NET_ISA is not set CONFIG_NET_PCI=y @@ -312,6 +324,7 @@ CONFIG_E100=y # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set # CONFIG_VIA_RHINE_MMIO is not set @@ -356,11 +369,6 @@ CONFIG_E1000=y # CONFIG_WAN is not set # -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set - -# # Amateur Radio support # # CONFIG_HAMRADIO is not set @@ -412,9 +420,6 @@ CONFIG_SOUND_GAMEPORT=y # CONFIG_GAMEPORT_CS461x is not set CONFIG_SERIO=y CONFIG_SERIO_I8042=y -CONFIG_I8042_REG_BASE=60 -CONFIG_I8042_KBD_IRQ=1 -CONFIG_I8042_AUX_IRQ=12 # CONFIG_SERIO_SERPORT is not set # CONFIG_SERIO_CT82C710 is not set # CONFIG_SERIO_PARKBD is not set @@ -520,6 +525,7 @@ CONFIG_HVC_CONSOLE=y # CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set +# CONFIG_SCx200_GPIO is not set CONFIG_RAW_DRIVER=y # @@ -582,6 +588,9 @@ CONFIG_EXT2_FS=y # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set # CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_QUOTA is not set # # Network File Systems diff --git a/arch/ppc64/kernel/chrp_setup.c b/arch/ppc64/kernel/chrp_setup.c index 3a6d1735ee60..d814047f679b 100644 --- a/arch/ppc64/kernel/chrp_setup.c +++ b/arch/ppc64/kernel/chrp_setup.c @@ -158,7 +158,6 @@ chrp_setup_arch(void) for (openpic = 0; n > 0; --n) openpic = (openpic << 32) + *opprop++; printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic); - udbg_printf("OpenPIC addr: %lx\n", openpic); OpenPIC_Addr = __ioremap(openpic, 0x40000, _PAGE_NO_CACHE); } @@ -175,7 +174,9 @@ chrp_init2(void) * -- tibit */ chrp_request_regions(); - ppc_md.progress(UTS_RELEASE, 0x7777); + /* Manually leave the kernel version on the panel. */ + ppc_md.progress("Linux ppc64\n", 0); + ppc_md.progress(UTS_RELEASE, 0); } /* Initialize firmware assisted non-maskable interrupts if @@ -268,7 +269,6 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.progress = chrp_progress; - ppc_md.progress("Linux ppc64\n", 0x0); } void @@ -280,10 +280,7 @@ chrp_progress(char *s, unsigned short hex) static int display_character, set_indicator; static int max_width; - if (hex) - udbg_printf("<chrp_progress> %s\n", s); - - if (!rtas.base || (naca->platform != PLATFORM_PSERIES)) + if (!rtas.base) return; if (max_width == 0) { diff --git a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c index c50efc097d68..8e6d358ad0d3 100644 --- a/arch/ppc64/kernel/eeh.c +++ b/arch/ppc64/kernel/eeh.c @@ -156,8 +156,9 @@ void eeh_init(void) ibm_set_eeh_option = rtas_token("ibm,set-eeh-option"); ibm_set_slot_reset = rtas_token("ibm,set-slot-reset"); ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state"); - if (ibm_set_eeh_option != RTAS_UNKNOWN_SERVICE) - eeh_implemented = 1; + + if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE) + return; if (eeh_force_off > eeh_force_on) { /* User is forcing EEH off. Be noisy if it is implemented. */ diff --git a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S index a80937380ced..6a6ec98acaa8 100644 --- a/arch/ppc64/kernel/entry.S +++ b/arch/ppc64/kernel/entry.S @@ -124,7 +124,7 @@ _GLOBAL(DoSyscall) addi r9,r1,STACK_FRAME_OVERHEAD blrl /* Call handler */ _GLOBAL(ret_from_syscall_1) -20: std r3,RESULT(r1) /* Save result */ + std r3,RESULT(r1) /* Save result */ #ifdef SHOW_SYSCALLS #ifdef SHOW_SYSCALLS_TASK ld r10, PACACURRENT(13) @@ -195,7 +195,7 @@ _GLOBAL(ret_from_syscall_1) addi r9,r1,STACK_FRAME_OVERHEAD blrl /* Call handler */ _GLOBAL(ret_from_syscall_2) -58: std r3,RESULT(r1) /* Save result */ + std r3,RESULT(r1) /* Save result */ std r3,GPR0(r1) /* temporary gross hack to make strace work */ li r10,-_LAST_ERRNO cmpl 0,r3,r10 @@ -240,9 +240,9 @@ _GLOBAL(ppc64_rt_sigreturn) bne- 81f cmpi 0,r3,0 bge .ret_from_except - b 20b + b .ret_from_syscall_1 81: cmpi 0,r3,0 - blt 58b + blt .ret_from_syscall_2 bl .do_syscall_trace b .ret_from_except diff --git a/arch/ppc64/kernel/ioctl32.c b/arch/ppc64/kernel/ioctl32.c index 28d090cd7d14..9fdf196acf3b 100644 --- a/arch/ppc64/kernel/ioctl32.c +++ b/arch/ppc64/kernel/ioctl32.c @@ -3725,6 +3725,39 @@ mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg) return ((0 == ret) ? 0 : -EFAULT); } +/* Fix sizeof(sizeof()) breakage */ +#define BLKELVGET_32 _IOR(0x12,106,int) +#define BLKELVSET_32 _IOW(0x12,107,int) +#define BLKBSZGET_32 _IOR(0x12,112,int) +#define BLKBSZSET_32 _IOW(0x12,113,int) +#define BLKGETSIZE64_32 _IOR(0x12,114,int) + +static int do_blkelvget(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + return sys_ioctl(fd, BLKELVGET, arg); +} + +static int do_blkelvset(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + return sys_ioctl(fd, BLKELVSET, arg); +} + +static int do_blkbszget(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + return sys_ioctl(fd, BLKBSZGET, arg); +} + +static int do_blkbszset(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + return sys_ioctl(fd, BLKBSZSET, arg); +} + +static int do_blkgetsize64(unsigned int fd, unsigned int cmd, + unsigned long arg) +{ + return sys_ioctl(fd, BLKGETSIZE64, arg); +} + struct ioctl_trans { unsigned long cmd; unsigned long handler; @@ -3843,10 +3876,6 @@ COMPATIBLE_IOCTL(BLKRRPART), COMPATIBLE_IOCTL(BLKFLSBUF), COMPATIBLE_IOCTL(BLKSECTSET), COMPATIBLE_IOCTL(BLKSSZGET), -COMPATIBLE_IOCTL(BLKBSZGET), -COMPATIBLE_IOCTL(BLKBSZSET), -COMPATIBLE_IOCTL(BLKGETSIZE64), - /* RAID */ COMPATIBLE_IOCTL(RAID_VERSION), COMPATIBLE_IOCTL(GET_ARRAY_INFO), @@ -4316,9 +4345,6 @@ COMPATIBLE_IOCTL(DRM_IOCTL_LOCK), COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK), COMPATIBLE_IOCTL(DRM_IOCTL_FINISH), #endif /* DRM */ -/* elevator */ -COMPATIBLE_IOCTL(BLKELVGET), -COMPATIBLE_IOCTL(BLKELVSET), /* Big W */ /* WIOC_GETSUPPORT not yet implemented -E */ COMPATIBLE_IOCTL(WDIOC_GETSTATUS), @@ -4541,6 +4567,14 @@ HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk), HANDLE_IOCTL(USBDEVFS_REAPURB32, do_usbdevfs_reapurb), HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb), HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal), +/* take care of sizeof(sizeof()) breakage */ +/* elevator */ +HANDLE_IOCTL(BLKELVGET_32, do_blkelvget), +HANDLE_IOCTL(BLKELVSET_32, do_blkelvset), +/* block stuff */ +HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget), +HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset), +HANDLE_IOCTL(BLKGETSIZE64_32, do_blkgetsize64), }; unsigned long ioctl32_hash_table[1024]; diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index 869babb6805a..79159b798f00 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S @@ -587,7 +587,7 @@ _GLOBAL(sys_call_table32) .llong .sys32_settimeofday .llong .sys32_getgroups /* 80 */ .llong .sys32_setgroups - .llong .ppc32_select + .llong .sys_ni_syscall /* old select syscall */ .llong .sys_symlink .llong .sys_ni_syscall /* old lstat syscall */ .llong .sys32_readlink /* 85 */ @@ -705,7 +705,7 @@ _GLOBAL(sys_call_table32) .llong .sys_fstat64 .llong .sys32_pciconfig_read .llong .sys32_pciconfig_write - .llong .sys_ni_syscall /* 200 - reserved for sys_pciconfig_iobase */ + .llong .sys_ni_syscall /* 200 - old pciconfig_iobase */ .llong .sys_ni_syscall /* reserved for MacOnLinux */ .llong .sys_getdents64 .llong .sys_pivot_root @@ -830,7 +830,7 @@ _GLOBAL(sys_call_table) .llong .sys_settimeofday .llong .sys_getgroups /* 80 */ .llong .sys_setgroups - .llong .sys_select + .llong .sys_ni_syscall /* old select syscall */ .llong .sys_symlink .llong .sys_ni_syscall /* old lstat syscall */ .llong .sys_readlink /* 85 */ @@ -857,7 +857,7 @@ _GLOBAL(sys_call_table) .llong .sys_newstat .llong .sys_newlstat .llong .sys_newfstat - .llong .sys_uname + .llong .sys_ni_syscall /* old uname syscall */ .llong .sys_ni_syscall /* 110 old iopl syscall */ .llong .sys_vhangup .llong .sys_ni_syscall /* old idle syscall */ @@ -948,7 +948,7 @@ _GLOBAL(sys_call_table) .llong .sys_ni_syscall /* 32bit only fstat64 */ .llong .sys_ni_syscall /* 32bit only pciconfig_read */ .llong .sys_ni_syscall /* 32bit only pciconfig_write */ - .llong .sys_ni_syscall /* 200 - reserved - sys_pciconfig_iobase */ + .llong .sys_ni_syscall /* 200 - old pciconfig_iobase */ .llong .sys_ni_syscall /* reserved for MacOnLinux */ .llong .sys_getdents64 .llong .sys_pivot_root diff --git a/arch/ppc64/kernel/open_pic.c b/arch/ppc64/kernel/open_pic.c index d17745252d64..3ab7887b453b 100644 --- a/arch/ppc64/kernel/open_pic.c +++ b/arch/ppc64/kernel/open_pic.c @@ -289,7 +289,7 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, } OpenPIC = (volatile struct OpenPIC *)OpenPIC_Addr; - ppc_md.progress("openpic enter",0x122); + ppc64_boot_msg(0x20, "OpenPic Init"); t = openpic_read(&OpenPIC->Global.Feature_Reporting0); switch (t & OPENPIC_FEATURE_VERSION_MASK) { @@ -326,7 +326,7 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, find_ISUs(); /* Initialize timer interrupts */ - ppc_md.progress("openpic timer",0x3ba); + ppc64_boot_msg(0x21, "OpenPic Timer"); for (i = 0; i < OPENPIC_NUM_TIMERS; i++) { /* Disabled, Priority 0 */ openpic_inittimer(i, 0, openpic_vec_timer+i); @@ -336,7 +336,7 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, #ifdef CONFIG_SMP /* Initialize IPI interrupts */ - ppc_md.progress("openpic ipi",0x3bb); + ppc64_boot_msg(0x22, "OpenPic IPI"); openpic_test_broken_IPI(); for (i = 0; i < OPENPIC_NUM_IPI; i++) { /* Disabled, Priority 10..13 */ @@ -348,7 +348,7 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, #endif /* Initialize external interrupts */ - ppc_md.progress("openpic ext",0x3bc); + ppc64_boot_msg(0x23, "OpenPic Ext"); openpic_set_priority(0xf); @@ -381,7 +381,7 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, irq_desc[i].handler = &open_pic; /* Initialize the spurious interrupt */ - ppc_md.progress("openpic spurious",0x3bd); + ppc64_boot_msg(0x24, "OpenPic Spurious"); openpic_set_spurious(openpic_vec_spurious); /* Initialize the cascade */ @@ -393,7 +393,7 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, openpic_set_priority(0); openpic_disable_8259_pass_through(); - ppc_md.progress("openpic exit",0x222); + ppc64_boot_msg(0x25, "OpenPic Done"); } void openpic_setup_ISU(int isu_num, unsigned long addr) @@ -573,7 +573,7 @@ void openpic_request_IPIs(void) * Get IPI's working and start taking interrupts. * -- Cort */ -static spinlock_t openpic_setup_lock __initdata = SPIN_LOCK_UNLOCKED; +static spinlock_t openpic_setup_lock __devinitdata = SPIN_LOCK_UNLOCKED; void __devinit do_openpic_setup_cpu(void) { diff --git a/arch/ppc64/kernel/pSeries_lpar.c b/arch/ppc64/kernel/pSeries_lpar.c index 1a9f2bcf9964..4dcad927356d 100644 --- a/arch/ppc64/kernel/pSeries_lpar.c +++ b/arch/ppc64/kernel/pSeries_lpar.c @@ -310,6 +310,8 @@ void pSeries_lpar_mm_init(void); */ void pSeriesLP_init_early(void) { + struct device_node *np; + pSeries_lpar_mm_init(); ppc_md.tce_build = tce_build_pSeriesLP; @@ -324,29 +326,21 @@ void pSeriesLP_init_early(void) * Leave all the interfaces NULL. */ - if (0 /*naca->serialPortAddr */) { - void *comport = (void *)__ioremap(naca->serialPortAddr, 16, _PAGE_NO_CACHE); - udbg_init_uart(comport); - ppc_md.udbg_putc = udbg_putc; - ppc_md.udbg_getc = udbg_getc; - ppc_md.udbg_getc_poll = udbg_getc_poll; - } else { - /* lookup the first virtual terminal number in case we don't have a com port. - * Zero is probably correct in case someone calls udbg before the init. - * The property is a pair of numbers. The first is the starting termno (the - * one we use) and the second is the number of terminals. - */ - u32 *termno; - struct device_node *np = find_path_device("/rtas"); - if (np) { - termno = (u32 *)get_property(np, "ibm,termno", 0); - if (termno) - vtermno = termno[0]; - } - ppc_md.udbg_putc = udbg_putcLP; - ppc_md.udbg_getc = udbg_getcLP; - ppc_md.udbg_getc_poll = udbg_getc_pollLP; + /* lookup the first virtual terminal number in case we don't have a + * com port. Zero is probably correct in case someone calls udbg + * before the init. The property is a pair of numbers. The first + * is the starting termno (the one we use) and the second is the + * number of terminals. + */ + np = find_path_device("/rtas"); + if (np) { + u32 *termno = (u32 *)get_property(np, "ibm,termno", 0); + if (termno) + vtermno = termno[0]; } + ppc_md.udbg_putc = udbg_putcLP; + ppc_md.udbg_getc = udbg_getcLP; + ppc_md.udbg_getc_poll = udbg_getc_pollLP; } int hvc_get_chars(int index, char *buf, int count) diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c index 568137b63b23..feb23c36f5f8 100644 --- a/arch/ppc64/kernel/pci.c +++ b/arch/ppc64/kernel/pci.c @@ -392,6 +392,7 @@ pcibios_init(void) iSeries_pcibios_init(); #endif + //ppc64_boot_msg(0x40, "PCI Probe"); printk("PCI: Probing PCI hardware\n"); PPCDBG(PPCDBG_BUSWALK,"PCI: Probing PCI hardware\n"); @@ -431,7 +432,9 @@ pcibios_init(void) printk("PCI: Probing PCI hardware done\n"); PPCDBG(PPCDBG_BUSWALK,"PCI: Probing PCI hardware done.\n"); + //ppc64_boot_msg(0x41, "PCI Done"); + return 0; } subsys_initcall(pcibios_init); @@ -729,36 +732,6 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, return ret; } -/* Provide information on locations of various I/O regions in physical - * memory. Do this on a per-card basis so that we choose the right - * root bridge. - * Note that the returned IO or memory base is a physical address - */ - -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)hose->first_busno; - case IOBASE_MEMORY: - return (long)hose->pci_mem_offset; - case IOBASE_IO: - 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; -} /************************************************************************/ /* Formats the device information and location for service. */ /* - Pass in pci_dev* pointer to the device. */ diff --git a/arch/ppc64/kernel/pci.h b/arch/ppc64/kernel/pci.h index 350ab477bcc8..0ae984923faa 100644 --- a/arch/ppc64/kernel/pci.h +++ b/arch/ppc64/kernel/pci.h @@ -64,23 +64,6 @@ void iSeries_pcibios_init_early(void); void pSeries_pcibios_init_early(void); void pSeries_pcibios_init(void); -/* Get a device_node from a pci_dev. This code must be fast except in the case - * where the sysdata is incorrect and needs to be fixed up (hopefully just once) - */ -static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev) -{ - struct device_node *dn = (struct device_node *)(dev->sysdata); - if (dn->devfn == dev->devfn && dn->busno == dev->bus->number) - return dn; /* fast path. sysdata is good */ - else - return fetch_dev_dn(dev); -} -/* Use this macro after the PCI bus walk for max performance when it - * is known that sysdata is correct. - */ -#define PCI_GET_DN(dev) ((struct device_node *)((dev)->sysdata)) - - /******************************************************************* * Platform configuration flags.. (Live in pci.c) *******************************************************************/ diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c index f90d2167e4aa..962779ec9969 100644 --- a/arch/ppc64/kernel/process.c +++ b/arch/ppc64/kernel/process.c @@ -43,6 +43,7 @@ #include <asm/ppcdebug.h> #include <asm/machdep.h> #include <asm/iSeries/HvCallHpt.h> +#include <asm/hardirq.h> struct task_struct *last_task_used_math = NULL; @@ -455,6 +456,10 @@ unsigned long get_wchan(struct task_struct *p) return 0; if (count > 0) { ip = *(unsigned long *)(sp + 16); + /* + * XXX we mask the upper 32 bits until procps + * gets fixed. + */ if (ip < first_sched || ip >= last_sched) return (ip & 0xFFFFFFFF); } @@ -485,3 +490,8 @@ void show_trace_task(struct task_struct *p) } while (count++ < 16); printk("\n"); } + +void dump_stack(void) +{ + show_stack(NULL); +} diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index d9999e27c2af..05fff76757ce 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c @@ -620,6 +620,7 @@ prom_initialize_lmb(unsigned long mem) return mem; } +static char hypertas_funcs[1024]; static void __init prom_instantiate_rtas(void) @@ -636,7 +637,6 @@ prom_instantiate_rtas(void) #endif prom_rtas = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/rtas")); if (prom_rtas != (ihandle) -1) { - char hypertas_funcs[1024]; int rc; if ((rc = call_prom(RELOC("getprop"), diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index baae57356218..8e72e5959b2c 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c @@ -21,6 +21,8 @@ #include <linux/ide.h> #include <linux/seq_file.h> #include <linux/ioport.h> +#include <linux/console.h> +#include <linux/version.h> #include <linux/tty.h> #include <linux/root_dev.h> #include <asm/io.h> @@ -116,6 +118,23 @@ void ppcdbg_initialize(void) { _naca->debug_switch = PPC_DEBUG_DEFAULT; /* | PPCDBG_BUSWALK | PPCDBG_PHBINIT | PPCDBG_MM | PPCDBG_MMINIT | PPCDBG_TCEINIT | PPCDBG_TCE */; } +static struct console udbg_console = { + name: "udbg", + write: udbg_console_write, + flags: CON_PRINTBUFFER, + index: -1, +}; + +static int early_console_initialized; + +void __init disable_early_printk(void) +{ + if (!early_console_initialized) + return; + unregister_console(&udbg_console); + early_console_initialized = 0; +} + /* * Do some initial setup of the system. The paramters are those which * were passed in from the bootloader. @@ -162,62 +181,31 @@ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5, #endif } - udbg_puts("\n-----------------------------------------------------\n"); - udbg_puts("Naca Info...\n\n"); - udbg_puts("naca = 0x"); - udbg_puthex((unsigned long)naca); - udbg_putc('\n'); - - udbg_puts("naca->physicalMemorySize = 0x"); - udbg_puthex(naca->physicalMemorySize); - udbg_putc('\n'); - - udbg_puts("naca->dCacheL1LineSize = 0x"); - udbg_puthex(naca->dCacheL1LineSize); - udbg_putc('\n'); - - udbg_puts("naca->dCacheL1LogLineSize = 0x"); - udbg_puthex(naca->dCacheL1LogLineSize); - udbg_putc('\n'); - - udbg_puts("naca->dCacheL1LinesPerPage = 0x"); - udbg_puthex(naca->dCacheL1LinesPerPage); - udbg_putc('\n'); - - udbg_puts("naca->iCacheL1LineSize = 0x"); - udbg_puthex(naca->iCacheL1LineSize); - udbg_putc('\n'); - - udbg_puts("naca->iCacheL1LogLineSize = 0x"); - udbg_puthex(naca->iCacheL1LogLineSize); - udbg_putc('\n'); - - udbg_puts("naca->iCacheL1LinesPerPage = 0x"); - udbg_puthex(naca->iCacheL1LinesPerPage); - udbg_putc('\n'); - - udbg_puts("naca->pftSize = 0x"); - udbg_puthex(naca->pftSize); - udbg_putc('\n'); - - udbg_puts("naca->serialPortAddr = 0x"); - udbg_puthex(naca->serialPortAddr); - udbg_putc('\n'); - - udbg_puts("naca->interrupt_controller = 0x"); - udbg_puthex(naca->interrupt_controller); - udbg_putc('\n'); - - udbg_printf("\nHTAB Info ...\n\n"); - udbg_puts("htab_data.htab = 0x"); - udbg_puthex((unsigned long)htab_data.htab); - udbg_putc('\n'); - udbg_puts("htab_data.num_ptegs = 0x"); - udbg_puthex(htab_data.htab_num_ptegs); - udbg_putc('\n'); + if (naca->platform & PLATFORM_PSERIES) { + early_console_initialized = 1; + register_console(&udbg_console); + } - udbg_puts("\n-----------------------------------------------------\n"); + printk("Starting Linux PPC64 %s\n", UTS_RELEASE); + printk("-----------------------------------------------------\n"); + printk("naca = 0x%p\n", naca); +#if 0 + printk("naca->processorCount = 0x%x\n", naca->processorCount); +#endif + printk("naca->physicalMemorySize = 0x%lx\n", naca->physicalMemorySize); + printk("naca->dCacheL1LineSize = 0x%x\n", naca->dCacheL1LineSize); + printk("naca->dCacheL1LogLineSize = 0x%x\n", naca->dCacheL1LogLineSize); + printk("naca->dCacheL1LinesPerPage = 0x%x\n", naca->dCacheL1LinesPerPage); + printk("naca->iCacheL1LineSize = 0x%x\n", naca->iCacheL1LineSize); + printk("naca->iCacheL1LogLineSize = 0x%x\n", naca->iCacheL1LogLineSize); + printk("naca->iCacheL1LinesPerPage = 0x%x\n", naca->iCacheL1LinesPerPage); + printk("naca->pftSize = 0x%lx\n", naca->pftSize); + printk("naca->debug_switch = 0x%lx\n", naca->debug_switch); + printk("naca->interrupt_controller = 0x%d\n", naca->interrupt_controller); + printk("htab_data.htab = 0x%p\n", htab_data.htab); + printk("htab_data.num_ptegs = 0x%lx\n", htab_data.htab_num_ptegs); + printk("-----------------------------------------------------\n"); if (naca->platform & PLATFORM_PSERIES) { finish_device_tree(); @@ -411,7 +399,6 @@ void parse_cmd_line(unsigned long r3, unsigned long r4, unsigned long r5, } __max_memory = maxmem; } - ppc_md.progress("id mach: done", 0x200); } @@ -492,7 +479,6 @@ void __init ppc64_calibrate_delay(void) printk("Calibrating delay loop... %lu.%02lu BogoMips\n", loops_per_jiffy/(500000/HZ), loops_per_jiffy/(5000/HZ) % 100); - } extern void (*calibrate_delay)(void); @@ -511,13 +497,13 @@ void __init setup_arch(char **cmdline_p) calibrate_delay = ppc64_calibrate_delay; + ppc64_boot_msg(0x12, "Setup Arch"); #ifdef CONFIG_XMON xmon_map_scc(); if (strstr(cmd_line, "xmon")) xmon(0); #endif /* CONFIG_XMON */ - ppc_md.progress("setup_arch:enter", 0x3eab); /* * Set cache line size based on type of cpu as a default. @@ -541,13 +527,59 @@ void __init setup_arch(char **cmdline_p) /* set up the bootmem stuff with available memory */ do_init_bootmem(); - ppc_md.progress("setup_arch:bootmem", 0x3eab); ppc_md.setup_arch(); paging_init(); sort_exception_table(); - ppc_md.progress("setup_arch: exit", 0x3eab); + ppc64_boot_msg(0x15, "Setup Done"); +} + +/* ToDo: do something useful if ppc_md is not yet setup. */ +#define PPC64_LINUX_FUNCTION 0x0f000000 +#define PPC64_IPL_MESSAGE 0xc0000000 +#define PPC64_TERM_MESSAGE 0xb0000000 +#define PPC64_ATTN_MESSAGE 0xa0000000 +#define PPC64_DUMP_MESSAGE 0xd0000000 + +static void ppc64_do_msg(unsigned int src, const char *msg) +{ + if (ppc_md.progress) { + char buf[32]; + + sprintf(buf, "%08x \n", src); + ppc_md.progress(buf, 0); + sprintf(buf, "%-16s", msg); + ppc_md.progress(buf, 0); + } +} + +/* Print a boot progress message. */ +void ppc64_boot_msg(unsigned int src, const char *msg) +{ + ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_IPL_MESSAGE|src, msg); + printk("[boot]%04x %s\n", src, msg); +} + +/* Print a termination message (print only -- does not stop the kernel) */ +void ppc64_terminate_msg(unsigned int src, const char *msg) +{ + ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_TERM_MESSAGE|src, msg); + printk("[terminate]%04x %s\n", src, msg); +} + +/* Print something that needs attention (device error, etc) */ +void ppc64_attention_msg(unsigned int src, const char *msg) +{ + ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_ATTN_MESSAGE|src, msg); + printk("[attention]%04x %s\n", src, msg); +} + +/* Print a dump progress message. */ +void ppc64_dump_msg(unsigned int src, const char *msg) +{ + ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_DUMP_MESSAGE|src, msg); + printk("[dump]%04x %s\n", src, msg); } int set_spread_lpevents( char * str ) diff --git a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c index b529eb70ae73..d716f8eab4dc 100644 --- a/arch/ppc64/kernel/signal.c +++ b/arch/ppc64/kernel/signal.c @@ -108,11 +108,11 @@ long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7, sigset_t saveset; mask &= _BLOCKABLE; - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sig->siglock); saveset = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sig->siglock); regs->gpr[3] = -EINTR; while (1) { @@ -144,11 +144,11 @@ long sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sig->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sig->siglock); regs->gpr[3] = -EINTR; while (1) { @@ -213,7 +213,7 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, struct pt_regs *regs) { struct rt_sigframe *rt_sf; - struct sigcontext_struct sigctx; + struct sigcontext sigctx; struct sigregs *sr; elf_gregset_t saved_regs; /* an array of ELF_NGREG unsigned longs */ sigset_t set; @@ -225,10 +225,10 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, || copy_from_user(&st, &rt_sf->uc.uc_stack, sizeof(st))) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sig->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sig->siglock); if (regs->msr & MSR_FP) giveup_fpu(current); @@ -331,12 +331,12 @@ long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, unsigned long r8, struct pt_regs *regs) { - struct sigcontext_struct *sc, sigctx; + struct sigcontext *sc, sigctx; struct sigregs *sr; elf_gregset_t saved_regs; /* an array of ELF_NGREG unsigned longs */ sigset_t set; - sc = (struct sigcontext_struct *)(regs->gpr[1] + __SIGNAL_FRAMESIZE); + sc = (struct sigcontext *)(regs->gpr[1] + __SIGNAL_FRAMESIZE); if (copy_from_user(&sigctx, sc, sizeof(sigctx))) goto badframe; @@ -345,10 +345,10 @@ long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, set.sig[1] = sigctx._unused[3]; #endif sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sig->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sig->siglock); if (regs->msr & MSR_FP) giveup_fpu(current); @@ -391,7 +391,7 @@ static void setup_frame(struct pt_regs *regs, struct sigregs *frame, struct funct_descr_entry * funct_desc_ptr; unsigned long temp_ptr; - struct sigcontext_struct *sc = (struct sigcontext_struct *)newsp; + struct sigcontext *sc = (struct sigcontext *)newsp; if (verify_area(VERIFY_WRITE, frame, sizeof(*frame))) goto badframe; @@ -440,7 +440,7 @@ badframe: static void handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset, struct pt_regs * regs, unsigned long *newspp, unsigned long frame) { - struct sigcontext_struct *sc; + struct sigcontext *sc; struct rt_sigframe *rt_sf; struct k_sigaction *ka = ¤t->sig->action[sig-1]; @@ -481,7 +481,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset, } else { /* Put a sigcontext on the stack */ *newspp -= sizeof(*sc); - sc = (struct sigcontext_struct *)*newspp; + sc = (struct sigcontext *)*newspp; if (verify_area(VERIFY_WRITE, sc, sizeof(*sc))) goto badframe; @@ -499,11 +499,11 @@ static void handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset, ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sig->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); sigaddset(¤t->blocked,sig); recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sig->siglock); } return; diff --git a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c index e4cfe53666f9..ed54b7b0d4d7 100644 --- a/arch/ppc64/kernel/signal32.c +++ b/arch/ppc64/kernel/signal32.c @@ -218,14 +218,14 @@ long sys32_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, unsigned long r8, struct pt_regs *regs) { - struct sigcontext32_struct *sc, sigctx; + struct sigcontext32 *sc, sigctx; struct sigregs32 *sr; int ret; elf_gregset_t32 saved_regs; /* an array of ELF_NGREG unsigned ints (32 bits) */ sigset_t set; int i; - sc = (struct sigcontext32_struct *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32); + sc = (struct sigcontext32 *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32); if (copy_from_user(&sigctx, sc, sizeof(sigctx))) goto badframe; @@ -235,10 +235,10 @@ long sys32_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, */ set.sig[0] = sigctx.oldmask + ((long)(sigctx._unused[3]) << 32); sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sig->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sig->siglock); if (regs->msr & MSR_FP ) giveup_fpu(current); /* Last stacked signal - restore registers */ @@ -315,8 +315,7 @@ badframe: static void setup_frame32(struct pt_regs *regs, struct sigregs32 *frame, unsigned int newsp) { - struct sigcontext32_struct *sc = - (struct sigcontext32_struct *)(u64)newsp; + struct sigcontext32 *sc = (struct sigcontext32 *)(u64)newsp; int i; if (verify_area(VERIFY_WRITE, frame, sizeof(*frame))) @@ -430,7 +429,7 @@ long sys32_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, struct pt_regs * regs) { struct rt_sigframe_32 *rt_sf; - struct sigcontext32_struct sigctx; + struct sigcontext32 sigctx; struct sigregs32 *sr; int ret; elf_gregset_t32 saved_regs; /* an array of 32 bit register values */ @@ -455,10 +454,10 @@ long sys32_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, */ sigdelsetmask(&set, ~_BLOCKABLE); /* update the current based on the sigmask found in the rt_stackframe */ - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sig->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sig->siglock); /* If currently owning the floating point - give them up */ if (regs->msr & MSR_FP) @@ -842,11 +841,11 @@ int sys32_rt_sigsuspend(sigset32_t* unewset, size_t sigsetsize, int p3, sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sig->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sig->siglock); regs->gpr[3] = -EINTR; while (1) { @@ -958,7 +957,7 @@ static void handle_signal32(unsigned long sig, siginfo_t *info, sigset_t *oldset, struct pt_regs * regs, unsigned int *newspp, unsigned int frame) { - struct sigcontext32_struct *sc; + struct sigcontext32 *sc; struct rt_sigframe_32 *rt_sf; struct k_sigaction *ka = ¤t->sig->action[sig-1]; @@ -1000,7 +999,7 @@ static void handle_signal32(unsigned long sig, siginfo_t *info, } else { /* Put a sigcontext on the stack */ *newspp -= sizeof(*sc); - sc = (struct sigcontext32_struct *)(u64)*newspp; + sc = (struct sigcontext32 *)(u64)*newspp; if (verify_area(VERIFY_WRITE, sc, sizeof(*sc))) goto badframe; /* @@ -1019,11 +1018,11 @@ static void handle_signal32(unsigned long sig, siginfo_t *info, ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sig->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); sigaddset(¤t->blocked,sig); recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sig->siglock); } return; diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c index d59b3638bacb..ef9697ca142e 100644 --- a/arch/ppc64/kernel/smp.c +++ b/arch/ppc64/kernel/smp.c @@ -1,6 +1,4 @@ /* - * - * * SMP support for ppc. * * Written by Cort Dougan (cort@cs.nmt.edu) borrowing a great @@ -449,6 +447,9 @@ static struct call_data_struct { int wait; } *call_data; +/* delay of at least 8 seconds on 1GHz cpu */ +#define SMP_CALL_TIMEOUT (1UL << (30 + 3)) + /* * This function sends a 'generic call function' IPI to all other CPUs * in the system. @@ -469,7 +470,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, { struct call_data_struct data; int ret = -1, cpus = num_online_cpus()-1; - int timeout; + unsigned long timeout; if (!cpus) return 0; @@ -483,47 +484,44 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, spin_lock(&call_lock); call_data = &data; + wmb(); /* Send a message to all other CPUs and wait for them to respond */ smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION, 0, 0); /* Wait for response */ - timeout = 8000000; + timeout = SMP_CALL_TIMEOUT; while (atomic_read(&data.started) != cpus) { HMT_low(); if (--timeout == 0) { - printk("smp_call_function on cpu %d: other cpus not responding (%d)\n", - smp_processor_id(), atomic_read(&data.started)); -#ifdef CONFIG_XMON - xmon(0); -#endif -#ifdef CONFIG_PPC_ISERIES - HvCall_terminateMachineSrc(); -#endif + if (debugger) + debugger(0); + printk("smp_call_function on cpu %d: other cpus not " + "responding (%d)\n", smp_processor_id(), + atomic_read(&data.started)); goto out; } - barrier(); - udelay(1); } if (wait) { - timeout = 1000000; + timeout = SMP_CALL_TIMEOUT; while (atomic_read(&data.finished) != cpus) { HMT_low(); if (--timeout == 0) { - printk("smp_call_function on cpu %d: other cpus not finishing (%d/%d)\n", - smp_processor_id(), atomic_read(&data.finished), atomic_read(&data.started)); -#ifdef CONFIG_PPC_ISERIES - HvCall_terminateMachineSrc(); -#endif + if (debugger) + debugger(0); + printk("smp_call_function on cpu %d: other " + "cpus not finishing (%d/%d)\n", + smp_processor_id(), + atomic_read(&data.finished), + atomic_read(&data.started)); goto out; } - barrier(); - udelay(1); } } + ret = 0; - out: +out: HMT_medium(); spin_unlock(&call_lock); return ret; diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c index 2abb55adca76..cc6b9e4845f4 100644 --- a/arch/ppc64/kernel/sys_ppc32.c +++ b/arch/ppc64/kernel/sys_ppc32.c @@ -2361,11 +2361,15 @@ static long do_sys32_semctl(int first, int second, int third, void *uptr) set_fs(old_fs); } break; + default: + err = -EINVAL; } out: return err; } +#define MAXBUF (64*1024) + static int do_sys32_msgsnd(int first, int second, int third, void *uptr) { @@ -2374,14 +2378,14 @@ do_sys32_msgsnd(int first, int second, int third, void *uptr) mm_segment_t old_fs; int err; - if (second < 0) + if (second < 0 || (second >= MAXBUF-sizeof(struct msgbuf))) return -EINVAL; - p = kmalloc(second + sizeof(struct msgbuf) + 4, GFP_USER); + p = kmalloc(second + sizeof(struct msgbuf), GFP_USER); if (!p) return -ENOMEM; err = get_user(p->mtype, &up->mtype); - err |= __copy_from_user(p->mtext, &up->mtext, second); + err |= copy_from_user(p->mtext, &up->mtext, second); if (err) { err = -EFAULT; goto out; @@ -2404,35 +2408,35 @@ do_sys32_msgrcv(int first, int second, int msgtyp, int third, mm_segment_t old_fs; int err; - if (second < 0) + if (second < 0 || (second >= MAXBUF-sizeof(struct msgbuf))) return -EINVAL; if (!version) { - struct ipc_kludge *uipck = (struct ipc_kludge *)uptr; - struct ipc_kludge ipck; + struct ipc_kludge_32 *uipck = (struct ipc_kludge_32 *)uptr; + struct ipc_kludge_32 ipck; err = -EINVAL; if (!uptr) goto out; err = -EFAULT; - if (copy_from_user(&ipck, uipck, sizeof(struct ipc_kludge))) + if (copy_from_user(&ipck, uipck, sizeof(struct ipc_kludge_32))) goto out; uptr = (void *)A(ipck.msgp); msgtyp = ipck.msgtyp; } err = -ENOMEM; - p = kmalloc(second + sizeof (struct msgbuf) + 4, GFP_USER); + p = kmalloc(second + sizeof (struct msgbuf), GFP_USER); if (!p) goto out; old_fs = get_fs(); set_fs(KERNEL_DS); - err = sys_msgrcv(first, p, second + 4, msgtyp, third); + err = sys_msgrcv(first, p, second, msgtyp, third); set_fs(old_fs); if (err < 0) goto free_then_out; up = (struct msgbuf32 *)uptr; if (put_user(p->mtype, &up->mtype) || - __copy_to_user(&up->mtext, p->mtext, err)) + copy_to_user(&up->mtext, p->mtext, err)) err = -EFAULT; free_then_out: kfree(p); @@ -2559,7 +2563,7 @@ do_sys32_shmat(int first, int second, int third, int version, void *uptr) static int do_sys32_shmctl(int first, int second, void *uptr) { - int err = -EFAULT, err2; + int err = -EINVAL, err2; mm_segment_t old_fs; switch (second & (~IPC_64)) { diff --git a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c index 84936c897540..9337deeb6a17 100644 --- a/arch/ppc64/kernel/syscalls.c +++ b/arch/ppc64/kernel/syscalls.c @@ -41,7 +41,6 @@ #include <asm/ipc.h> #include <asm/semaphore.h> #include <asm/ppcdebug.h> - #include <asm/time.h> extern unsigned long wall_jiffies; @@ -83,8 +82,7 @@ sys_ipc (uint call, int first, int second, long third, void *ptr, long fifth) if (!ptr) break; - if ((ret = verify_area (VERIFY_READ, ptr, sizeof(long))) - || (ret = get_user(fourth.__pad, (void **)ptr))) + if ((ret = get_user(fourth.__pad, (void **)ptr))) break; ret = sys_semctl (first, second, third, fourth); break; @@ -99,13 +97,12 @@ sys_ipc (uint call, int first, int second, long third, void *ptr, long fifth) if (!ptr) break; - if ((ret = verify_area (VERIFY_READ, ptr, sizeof(tmp))) - || (ret = copy_from_user(&tmp, + if ((ret = copy_from_user(&tmp, (struct ipc_kludge *) ptr, - sizeof (tmp)))) + sizeof (tmp)) ? -EFAULT : 0)) break; - ret = sys_msgrcv (first, (struct msgbuf *)(unsigned long)tmp.msgp, - second, tmp.msgtyp, third); + ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, + third); break; } default: @@ -124,10 +121,6 @@ sys_ipc (uint call, int first, int second, long third, void *ptr, long fifth) switch (version) { default: { ulong raddr; - - if ((ret = verify_area(VERIFY_WRITE, (ulong*) third, - sizeof(ulong)))) - break; ret = sys_shmat (first, (char *) ptr, second, &raddr); if (ret) break; @@ -218,7 +211,6 @@ asmlinkage int sys_uname(struct old_utsname * name) return err; } - asmlinkage time_t sys64_time(time_t* tloc) { time_t secs; diff --git a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c index d87c4ca84d8f..c80efc0bc4eb 100644 --- a/arch/ppc64/kernel/traps.c +++ b/arch/ppc64/kernel/traps.c @@ -127,11 +127,10 @@ void SystemResetException(struct pt_regs *regs) { if (fwnmi_active) { - unsigned long *r3 = __va(regs->gpr[3]); /* for FWNMI debug */ - struct rtas_error_log *errlog; - - udbg_printf("FWNMI is active with save area at %016lx\n", r3); - errlog = FWNMI_get_errinfo(regs); + struct rtas_error_log *errhdr = FWNMI_get_errinfo(regs); + if (errhdr) { + /* XXX Should look at FWNMI information */ + } FWNMI_release_errinfo(); } diff --git a/arch/ppc64/kernel/udbg.c b/arch/ppc64/kernel/udbg.c index 7d852fdae4bf..e9a534a42406 100644 --- a/arch/ppc64/kernel/udbg.c +++ b/arch/ppc64/kernel/udbg.c @@ -52,8 +52,6 @@ struct NS16550 { volatile struct NS16550 *udbg_comport; -spinlock_t udbg_lock = SPIN_LOCK_UNLOCKED; - void udbg_init_uart(void *comport) { @@ -84,9 +82,6 @@ udbg_putc(unsigned char c) /* wait for idle */; udbg_comport->thr = '\r'; eieio(); } - } else if (naca->platform == PLATFORM_ISERIES_LPAR) { - /* ToDo: switch this via ppc_md */ - printk("%c", c); } } @@ -161,6 +156,12 @@ udbg_read(char *buf, int buflen) { } void +udbg_console_write(struct console *con, const char *s, unsigned int n) +{ + udbg_write(s, n); +} + +void udbg_puthex(unsigned long val) { int i, nibbles = sizeof(val)*2; @@ -190,16 +191,13 @@ udbg_printSP(const char *s) void udbg_printf(const char *fmt, ...) { - unsigned long flags; unsigned char buf[256]; va_list args; va_start(args, fmt); - spin_lock_irqsave(&udbg_lock, flags); vsprintf(buf, fmt, args); udbg_puts(buf); - spin_unlock_irqrestore(&udbg_lock, flags); va_end(args); } @@ -208,7 +206,6 @@ udbg_printf(const char *fmt, ...) void udbg_ppcdbg(unsigned long debug_flags, const char *fmt, ...) { - unsigned long flags; unsigned long active_debugs = debug_flags & naca->debug_switch; if ( active_debugs ) { @@ -216,7 +213,6 @@ udbg_ppcdbg(unsigned long debug_flags, const char *fmt, ...) unsigned char buf[256]; unsigned long i, len = 0; - spin_lock_irqsave(&udbg_lock, flags); for(i=0; i < PPCDBG_NUM_FLAGS ;i++) { if (((1U << i) & active_debugs) && trace_names[i]) { @@ -237,7 +233,6 @@ udbg_ppcdbg(unsigned long debug_flags, const char *fmt, ...) va_start(ap, fmt); vsprintf(buf, fmt, ap); udbg_puts(buf); - spin_unlock_irqrestore(&udbg_lock, flags); va_end(ap); } diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c index 9350a75dbe77..d928cbefbccb 100644 --- a/arch/ppc64/kernel/xics.c +++ b/arch/ppc64/kernel/xics.c @@ -23,6 +23,7 @@ #include "i8259.h" #include "xics.h" #include <asm/ppcdebug.h> +#include <asm/machdep.h> void xics_enable_irq(u_int irq); void xics_disable_irq(u_int irq); @@ -296,6 +297,8 @@ xics_init_IRQ( void ) struct device_node *np; uint *ireg, ilen, indx=0; + ppc64_boot_msg(0x20, "XICS Init"); + ibm_get_xive = rtas_token("ibm,get-xive"); ibm_set_xive = rtas_token("ibm,set-xive"); ibm_int_off = rtas_token("ibm,int-off"); @@ -413,6 +416,7 @@ nextnode: request_irq(XICS_IPI + XICS_IRQ_OFFSET, xics_ipi_action, 0, "IPI", 0); irq_desc[XICS_IPI+XICS_IRQ_OFFSET].status |= IRQ_PER_CPU; #endif + ppc64_boot_msg(0x21, "XICS Done"); } void xics_isa_init(void) diff --git a/arch/ppc64/lib/copyuser.S b/arch/ppc64/lib/copyuser.S index bc2f0fe06bf9..c12d9a6ce2e7 100644 --- a/arch/ppc64/lib/copyuser.S +++ b/arch/ppc64/lib/copyuser.S @@ -253,14 +253,16 @@ _GLOBAL(__copy_tofrom_user) addi r4,r4,1 bne 1b blr -3: srdi r9,r5,3 +3: cmpldi cr1,r5,8 + srdi r9,r5,3 andi. r5,r5,7 + blt cr1,93f mtctr r9 91: std r0,0(r4) addi r4,r4,8 bdnz 91b - beqlr - mtctr r5 +93: beqlr + mtctr r5 92: stb r0,0(r4) addi r4,r4,1 bdnz 92b diff --git a/arch/ppc64/mm/extable.c b/arch/ppc64/mm/extable.c index c6799105ba0e..90e343b3b7cf 100644 --- a/arch/ppc64/mm/extable.c +++ b/arch/ppc64/mm/extable.c @@ -1,5 +1,5 @@ /* - * linux/arch/ppc/mm/extable.c + * linux/arch/ppc64/mm/extable.c * * from linux/arch/i386/mm/extable.c * @@ -11,6 +11,7 @@ #include <linux/config.h> #include <linux/module.h> +#include <linux/spinlock.h> #include <asm/uaccess.h> extern struct exception_table_entry __start___ex_table[]; @@ -19,8 +20,7 @@ extern struct exception_table_entry __stop___ex_table[]; /* * The exception table needs to be sorted because we use the macros * which put things into the exception table in a variety of segments - * such as the prep, pmac, chrp, etc. segments as well as the init - * segment and the main kernel text segment. + * as well as the init segment and the main kernel text segment. */ static inline void sort_ex_table(struct exception_table_entry *start, @@ -56,43 +56,48 @@ search_one_table(const struct exception_table_entry *first, const struct exception_table_entry *last, unsigned long value) { - while (first <= last) { + while (first <= last) { const struct exception_table_entry *mid; long diff; mid = (last - first) / 2 + first; diff = mid->insn - value; - if (diff == 0) - return mid->fixup; - else if (diff < 0) - first = mid+1; - else - last = mid-1; - } - return 0; + if (diff == 0) + return mid->fixup; + else if (diff < 0) + first = mid+1; + else + last = mid-1; + } + return 0; } +extern spinlock_t modlist_lock; + unsigned long search_exception_table(unsigned long addr) { - unsigned long ret; + unsigned long ret = 0; #ifndef CONFIG_MODULES /* There is only the kernel to search. */ ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr); - if (ret) return ret; + return ret; #else + unsigned long flags; /* The kernel is the last "module" -- no need to treat it special. */ struct module *mp; + + spin_lock_irqsave(&modlist_lock, flags); for (mp = module_list; mp != NULL; mp = mp->next) { - if (mp->ex_table_start == NULL) + if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING))) continue; ret = search_one_table(mp->ex_table_start, mp->ex_table_end - 1, addr); if (ret) - return ret; + break; } + spin_unlock_irqrestore(&modlist_lock, flags); + return ret; #endif - - return 0; } diff --git a/arch/ppc64/mm/fault.c b/arch/ppc64/mm/fault.c index 7fc7b7896b26..7ec46d3357ef 100644 --- a/arch/ppc64/mm/fault.c +++ b/arch/ppc64/mm/fault.c @@ -27,6 +27,7 @@ #include <linux/mman.h> #include <linux/mm.h> #include <linux/interrupt.h> +#include <linux/smp_lock.h> #include <asm/page.h> #include <asm/pgtable.h> @@ -67,11 +68,19 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, #ifdef CONFIG_DEBUG_KERNEL if (debugger_fault_handler && (regs->trap == 0x300 || - regs->trap == 0x380)) { + regs->trap == 0x380)) { debugger_fault_handler(regs); return; } +#endif + + /* On an SLB miss we can only check for a valid exception entry */ + if (regs->trap == 0x380) { + bad_page_fault(regs, address, SIGSEGV); + return; + } +#ifdef CONFIG_DEBUG_KERNEL if (error_code & 0x00400000) { /* DABR match */ if (debugger_dabr_match(regs)) @@ -79,7 +88,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, } #endif - if (in_interrupt() || mm == NULL) { + if (in_atomic() || mm == NULL) { bad_page_fault(regs, address, SIGSEGV); return; } diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c index d65ffd675845..541f75310339 100644 --- a/arch/ppc64/mm/init.c +++ b/arch/ppc64/mm/init.c @@ -411,7 +411,7 @@ void __init mm_init_ppc64(void) struct paca_struct *lpaca; unsigned long guard_page, index; - ppc_md.progress("MM:init", 0); + ppc64_boot_msg(0x100, "MM Init"); /* Reserve all contexts < FIRST_USER_CONTEXT for kernel use. * The range of contexts [FIRST_USER_CONTEXT, NUM_USER_CONTEXT) @@ -432,7 +432,7 @@ void __init mm_init_ppc64(void) ppc_md.hpte_updateboltedpp(PP_RXRX, guard_page); } - ppc_md.progress("MM:exit", 0x211); + ppc64_boot_msg(0x100, "MM Init Done"); } /* diff --git a/arch/ppc64/xmon/xmon.c b/arch/ppc64/xmon/xmon.c index 82df7a1b4b04..d324bb0297bb 100644 --- a/arch/ppc64/xmon/xmon.c +++ b/arch/ppc64/xmon/xmon.c @@ -49,11 +49,6 @@ static u_int bus_error_jmp[100]; #define setjmp xmon_setjmp #define longjmp xmon_longjmp -#define memlist_entry list_entry -#define memlist_next(x) ((x)->next) -#define memlist_prev(x) ((x)->prev) - - /* Max number of stack frames we are willing to produce on a backtrace. */ #define MAXFRAMECOUNT 50 @@ -120,6 +115,7 @@ static void cacheflush(void); static void cpu_cmd(void); #endif /* CONFIG_SMP */ static void csum(void); +static void bootcmds(void); static void mem_translate(void); static void mem_check(void); static void mem_find_real(void); @@ -141,6 +137,14 @@ pte_t *find_linux_pte(pgd_t *pgdir, unsigned long va); /* from htab.c */ #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3]) +#define isxdigit(c) (('0' <= (c) && (c) <= '9') \ + || ('a' <= (c) && (c) <= 'f') \ + || ('A' <= (c) && (c) <= 'F')) +#define isalnum(c) (('0' <= (c) && (c) <= '9') \ + || ('a' <= (c) && (c) <= 'z') \ + || ('A' <= (c) && (c) <= 'Z')) +#define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0) + static char *help_string = "\ Commands:\n\ b show breakpoints\n\ @@ -170,14 +174,14 @@ Commands:\n\ t print backtrace\n\ T Enable/Disable PPCDBG flags\n\ x exit monitor\n\ - z reboot\n\ - Z halt\n\ "; static int xmon_trace[NR_CPUS]; #define SSTEP 1 /* stepping because of 's' command */ #define BRSTEP 2 /* stepping over breakpoint */ +static struct pt_regs *xmon_regs[NR_CPUS]; + /* * Stuff for reading and writing memory safely */ @@ -312,6 +316,7 @@ xmon(struct pt_regs *excp) msr = get_msr(); set_msrd(msr & ~MSR_EE); /* disable interrupts */ + xmon_regs[smp_processor_id()] = excp; excprint(excp); #ifdef CONFIG_SMP if (test_and_set_bit(smp_processor_id(), &cpus_in_xmon)) @@ -340,6 +345,7 @@ xmon(struct pt_regs *excp) xmon_trace[smp_processor_id()] = 0; insert_bpts(); } + xmon_regs[smp_processor_id()] = 0; #ifdef CONFIG_SMP clear_bit(0, &got_xmon); clear_bit(smp_processor_id(), &cpus_in_xmon); @@ -347,85 +353,6 @@ xmon(struct pt_regs *excp) set_msrd(msr); /* restore interrupt enable */ } -/* Code can call this to get a backtrace and continue. */ -void -xmon_backtrace(const char *fmt, ...) -{ - va_list ap; - struct pt_regs regs; - - - /* Ok, grab regs as they are now. - This won't do a particularily good job because the - prologue has already been executed. - ToDo: We could reach back into the callers save - area to do a better job of representing the - caller's state. - */ - asm volatile ("std 0,0(%0)\n\ - std 1,8(%0)\n\ - std 2,16(%0)\n\ - std 3,24(%0)\n\ - std 4,32(%0)\n\ - std 5,40(%0)\n\ - std 6,48(%0)\n\ - std 7,56(%0)\n\ - std 8,64(%0)\n\ - std 9,72(%0)\n\ - std 10,80(%0)\n\ - std 11,88(%0)\n\ - std 12,96(%0)\n\ - std 13,104(%0)\n\ - std 14,112(%0)\n\ - std 15,120(%0)\n\ - std 16,128(%0)\n\ - std 17,136(%0)\n\ - std 18,144(%0)\n\ - std 19,152(%0)\n\ - std 20,160(%0)\n\ - std 21,168(%0)\n\ - std 22,176(%0)\n\ - std 23,184(%0)\n\ - std 24,192(%0)\n\ - std 25,200(%0)\n\ - std 26,208(%0)\n\ - std 27,216(%0)\n\ - std 28,224(%0)\n\ - std 29,232(%0)\n\ - std 30,240(%0)\n\ - std 31,248(%0)" : : "b" (®s)); - /* Fetch the link reg for this stack frame. - NOTE: the prev printf fills in the lr. */ - regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2]; - regs.msr = get_msr(); - regs.ctr = get_ctr(); - regs.xer = get_xer(); - regs.ccr = get_cr(); - regs.trap = 0; - - va_start(ap, fmt); - xmon_vfprintf(stdout, fmt, ap); - xmon_putc('\n', stdout); - va_end(ap); - take_input("\n"); - backtrace(®s); -} - -/* Call this to poll for ^C during busy operations. - * Returns true if the user has hit ^C. - */ -int -xmon_interrupted(void) -{ - int ret = xmon_read_poll(); - if (ret == 3) { - printf("\n^C interrupted.\n"); - return 1; - } - return 0; -} - - void xmon_irq(int irq, void *d, struct pt_regs *regs) { @@ -604,14 +531,6 @@ cmds(struct pt_regs *excp) cmd = inchar(); } switch (cmd) { - case 'z': - printf("Rebooting machine now..."); - machine_restart(NULL); - break; - case 'Z': - printf("Halting machine now..."); - machine_halt(); - break; case 'm': cmd = inchar(); switch (cmd) { @@ -695,6 +614,8 @@ cmds(struct pt_regs *excp) cpu_cmd(); break; #endif /* CONFIG_SMP */ + case 'z': + bootcmds(); case 'T': debug_trace(); break; @@ -713,6 +634,19 @@ cmds(struct pt_regs *excp) } } +static void bootcmds(void) +{ + int cmd; + + cmd = inchar(); + if (cmd == 'r') + ppc_md.restart(NULL); + else if (cmd == 'h') + ppc_md.halt(); + else if (cmd == 'p') + ppc_md.power_off(); +} + #ifdef CONFIG_SMP static void cpu_cmd(void) { @@ -968,7 +902,9 @@ const char *getvecname(unsigned long vec) case 0x100: ret = "(System Reset)"; break; case 0x200: ret = "(Machine Check)"; break; case 0x300: ret = "(Data Access)"; break; + case 0x380: ret = "(Data SLB Access)"; break; case 0x400: ret = "(Instruction Access)"; break; + case 0x480: ret = "(Instruction SLB Access)"; break; case 0x500: ret = "(Hardware Interrupt)"; break; case 0x600: ret = "(Alignment)"; break; case 0x700: ret = "(Program Check)"; break; @@ -1116,7 +1052,7 @@ excprint(struct pt_regs *fp) printf(" sp: %lx\n", fp->gpr[1]); printf(" msr: %lx\n", fp->msr); - if (fp->trap == 0x300 || fp->trap == 0x600) { + if (fp->trap == 0x300 || fp->trap == 0x380 || fp->trap == 0x600) { printf(" dar: %lx\n", fp->dar); printf(" dsisr: %lx\n", fp->dsisr); } @@ -1292,34 +1228,6 @@ super_regs() scannl(); } -#if 0 -static void -openforth() -{ - int c; - char *p; - char cmd[1024]; - int args[5]; - extern int (*prom_entry)(int *); - - p = cmd; - c = skipbl(); - while (c != '\n') { - *p++ = c; - c = inchar(); - } - *p = 0; - args[0] = (int) "interpret"; - args[1] = 1; - args[2] = 1; - args[3] = (int) cmd; - (*prom_entry)(args); - printf("\n"); - if (args[4] != 0) - printf("error %x\n", args[4]); -} -#endif - #ifndef CONFIG_PPC64BRIDGE static void dump_hash_table_seg(unsigned seg, unsigned start, unsigned end) @@ -1534,7 +1442,18 @@ static char *fault_chars[] = { "--", "**", "##" }; static void handle_fault(struct pt_regs *regs) { - fault_type = regs->trap == 0x200? 0: regs->trap == 0x300? 1: 2; + switch (regs->trap) { + case 0x200: + fault_type = 0; + break; + case 0x300: + case 0x380: + fault_type = 1; + break; + default: + fault_type = 2; + } + longjmp(bus_error_jmp, 1); } @@ -2007,6 +1926,16 @@ skipbl() return c; } +#define N_PTREGS 44 +static char *regnames[N_PTREGS] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", + "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "mq", + "trap", "dar", "dsisr", "res" +}; + int scanhex(vp) unsigned long *vp; @@ -2015,6 +1944,36 @@ unsigned long *vp; unsigned long v; c = skipbl(); + if (c == '%') { + /* parse register name */ + char regname[8]; + int i; + + for (i = 0; i < sizeof(regname) - 1; ++i) { + c = inchar(); + if (!isalnum(c)) { + termch = c; + break; + } + regname[i] = c; + } + regname[i] = 0; + for (i = 0; i < N_PTREGS; ++i) { + if (strcmp(regnames[i], regname) == 0) { + unsigned long *rp = (unsigned long *) + xmon_regs[smp_processor_id()]; + if (rp == NULL) { + printf("regs not available\n"); + return 0; + } + *vp = rp[i]; + return 1; + } + } + printf("invalid register name '%%%s'\n", regname); + return 0; + } + d = hexdigit(c); if( d == EOF ){ termch = c; diff --git a/include/asm-ppc64/hardirq.h b/include/asm-ppc64/hardirq.h index ebec1d7707b0..7fe87eabbc7f 100644 --- a/include/asm-ppc64/hardirq.h +++ b/include/asm-ppc64/hardirq.h @@ -82,7 +82,7 @@ typedef struct { #define irq_enter() (preempt_count() += HARDIRQ_OFFSET) #if CONFIG_PREEMPT -# define in_atomic() (preempt_count() != kernel_locked()) +# define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked()) # define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1) #else # define in_atomic() (preempt_count() != 0) @@ -112,6 +112,4 @@ do { \ print_backtrace(_get_SP()); \ } while (0) -#define dump_stack() show_stack() - #endif /* __ASM_HARDIRQ_H */ diff --git a/include/asm-ppc64/hw_irq.h b/include/asm-ppc64/hw_irq.h index 6fbf1b3d4e35..24b6d172ec60 100644 --- a/include/asm-ppc64/hw_irq.h +++ b/include/asm-ppc64/hw_irq.h @@ -36,7 +36,10 @@ extern void __no_lpq_restore_flags(unsigned long); #else #define local_save_flags(flags) ((flags) = mfmsr()) -#define local_irq_restore(flags) __mtmsrd((flags), 1) +#define local_irq_restore(flags) do { \ + __asm__ __volatile__("": : :"memory"); \ + __mtmsrd((flags), 1); \ +} while(0) static inline void local_irq_disable(void) { diff --git a/include/asm-ppc64/ipc.h b/include/asm-ppc64/ipc.h index 2fb2c4d4ccbb..f4e1841af35d 100644 --- a/include/asm-ppc64/ipc.h +++ b/include/asm-ppc64/ipc.h @@ -4,7 +4,7 @@ /* * These are used to wrap system calls on PowerPC. * - * See arch/ppc/kernel/syscalls.c for ugly details.. + * See arch/ppc64/kernel/syscalls.c for ugly details.. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -12,8 +12,8 @@ * 2 of the License, or (at your option) any later version. */ struct ipc_kludge { - u32 msgp; - s32 msgtyp; + struct msgbuf *msgp; + long msgtyp; }; #define SEMOP 1 diff --git a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h index e88c49cbd154..9f3120a42664 100644 --- a/include/asm-ppc64/machdep.h +++ b/include/asm-ppc64/machdep.h @@ -119,5 +119,20 @@ struct machdep_calls { extern struct machdep_calls ppc_md; extern char cmd_line[512]; +/* Functions to produce codes on the leds. + * The SRC code should be unique for the message category and should + * be limited to the lower 24 bits (the upper 8 are set by these funcs), + * and (for boot & dump) should be sorted numerically in the order + * the events occur. + */ +/* Print a boot progress message. */ +void ppc64_boot_msg(unsigned int src, const char *msg); +/* Print a termination message (print only -- does not stop the kernel) */ +void ppc64_terminate_msg(unsigned int src, const char *msg); +/* Print something that needs attention (device error, etc) */ +void ppc64_attention_msg(unsigned int src, const char *msg); +/* Print a dump progress message. */ +void ppc64_dump_msg(unsigned int src, const char *msg); + #endif /* _PPC64_MACHDEP_H */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h index 2a0ff33a7da5..9235e73b76a2 100644 --- a/include/asm-ppc64/pci-bridge.h +++ b/include/asm-ppc64/pci-bridge.h @@ -79,5 +79,23 @@ struct pci_controller { int pci_device_loc(struct device_node *dev, unsigned char *bus_ptr, unsigned char *devfn_ptr); +struct device_node *fetch_dev_dn(struct pci_dev *dev); + +/* Get a device_node from a pci_dev. This code must be fast except in the case + * where the sysdata is incorrect and needs to be fixed up (hopefully just once) + */ +static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev) +{ + struct device_node *dn = (struct device_node *)(dev->sysdata); + if (dn->devfn == dev->devfn && dn->busno == dev->bus->number) + return dn; /* fast path. sysdata is good */ + else + return fetch_dev_dn(dev); +} +/* Use this macro after the PCI bus walk for max performance when it + * is known that sysdata is correct. + */ +#define PCI_GET_DN(dev) ((struct device_node *)((dev)->sysdata)) + #endif #endif /* __KERNEL__ */ diff --git a/include/asm-ppc64/posix_types.h b/include/asm-ppc64/posix_types.h index 03101116097f..eb84e2a478b2 100644 --- a/include/asm-ppc64/posix_types.h +++ b/include/asm-ppc64/posix_types.h @@ -11,19 +11,10 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#if 0 -# define DRENG_TYPES -#endif -#ifdef DRENG_TYPES typedef unsigned long __kernel_dev_t; typedef unsigned long __kernel_ino_t; typedef unsigned long __kernel_nlink_t; -#else -typedef unsigned int __kernel_dev_t; -typedef unsigned int __kernel_ino_t; -typedef unsigned int __kernel_nlink_t; -#endif typedef unsigned int __kernel_mode_t; typedef long __kernel_off_t; typedef long long __kernel_loff_t; diff --git a/include/asm-ppc64/ppc32.h b/include/asm-ppc64/ppc32.h index cb9d182ad995..2f84579b2b4c 100644 --- a/include/asm-ppc64/ppc32.h +++ b/include/asm-ppc64/ppc32.h @@ -43,25 +43,24 @@ typedef __kernel_fsid_t __kernel_fsid_t32; }) /* These are here to support 32-bit syscalls on a 64-bit kernel. */ -typedef unsigned int __kernel_size_t32; -typedef int __kernel_ssize_t32; -typedef int __kernel_ptrdiff_t32; -typedef int __kernel_time_t32; -typedef int __kernel_clock_t32; -typedef int __kernel_pid_t32; -typedef unsigned short __kernel_ipc_pid_t32; -typedef unsigned int __kernel_uid_t32; -typedef unsigned int __kernel_gid_t32; -typedef unsigned int __kernel_dev_t32; -typedef unsigned int __kernel_ino_t32; -typedef unsigned int __kernel_mode_t32; -typedef unsigned int __kernel_umode_t32; -typedef short __kernel_nlink_t32; -typedef int __kernel_daddr_t32; -typedef int __kernel_off_t32; -typedef unsigned int __kernel_caddr_t32; -typedef int __kernel_loff_t32; -/* typedef __kernel_fsid_t __kernel_fsid_t32; */ +typedef unsigned int __kernel_size_t32; +typedef int __kernel_ssize_t32; +typedef int __kernel_ptrdiff_t32; +typedef int __kernel_time_t32; +typedef int __kernel_clock_t32; +typedef int __kernel_pid_t32; +typedef unsigned short __kernel_ipc_pid_t32; +typedef unsigned int __kernel_uid_t32; +typedef unsigned int __kernel_gid_t32; +typedef unsigned int __kernel_dev_t32; +typedef unsigned int __kernel_ino_t32; +typedef unsigned int __kernel_mode_t32; +typedef unsigned int __kernel_umode_t32; +typedef short __kernel_nlink_t32; +typedef int __kernel_daddr_t32; +typedef int __kernel_off_t32; +typedef unsigned int __kernel_caddr_t32; +typedef int __kernel_loff_t32; struct statfs32 { int f_type; @@ -87,12 +86,12 @@ typedef struct siginfo32 { int si_code; union { - int _pad[SI_PAD_SIZE]; + int _pad[SI_PAD_SIZE32]; /* kill() */ struct { __kernel_pid_t32 _pid; /* sender's pid */ - unsigned int _uid; /* sender's uid */ + __kernel_uid_t32 _uid; /* sender's uid */ } _kill; /* POSIX.1b timers */ @@ -104,14 +103,14 @@ typedef struct siginfo32 { /* POSIX.1b signals */ struct { __kernel_pid_t32 _pid; /* sender's pid */ - unsigned int _uid; /* sender's uid */ + __kernel_uid_t32 _uid; /* sender's uid */ sigval_t32 _sigval; } _rt; /* SIGCHLD */ struct { __kernel_pid_t32 _pid; /* which child */ - unsigned int _uid; /* sender's uid */ + __kernel_uid_t32 _uid; /* sender's uid */ int _status; /* exit code */ __kernel_clock_t32 _utime; __kernel_clock_t32 _stime; @@ -119,7 +118,7 @@ typedef struct siginfo32 { /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */ struct { - u32 _addr; /* faulting insn/memory ref. */ + unsigned int _addr; /* faulting insn/memory ref. */ int _trapno; } _sigfault; @@ -153,8 +152,7 @@ typedef struct { } sigset32_t; struct sigaction32 { - unsigned int sa_handler; /* Really a pointer, but need to deal - with 32 bits */ + unsigned int sa_handler; /* Really a pointer, but need to deal with 32 bits */ unsigned int sa_flags; unsigned int sa_restorer; /* Another 32 bit pointer */ sigset32_t sa_mask; /* A 32 bit mask */ @@ -212,7 +210,7 @@ struct __old_kernel_stat32 unsigned int st_ctime; }; -struct sigcontext32_struct { +struct sigcontext32 { unsigned int _unused[4]; int signal; unsigned int handler; @@ -224,9 +222,13 @@ struct ucontext32 { unsigned int uc_flags; unsigned int uc_link; stack_32_t uc_stack; - struct sigcontext32_struct uc_mcontext; + struct sigcontext32 uc_mcontext; sigset_t uc_sigmask; /* mask last for extensibility */ }; +struct ipc_kludge_32 { + unsigned int msgp; + int msgtyp; +}; #endif /* _PPC64_PPC32_H */ diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h index 914382934892..e408ac247385 100644 --- a/include/asm-ppc64/processor.h +++ b/include/asm-ppc64/processor.h @@ -477,7 +477,7 @@ #define PVR_REV(pvr) (((pvr) >> 0) & 0xFFFF) /* Revison field */ /* Processor Version Numbers */ -#define PV_NORTHSTAR 0x0033 +#define PV_NORTHSTAR 0x0033 #define PV_PULSAR 0x0034 #define PV_POWER4 0x0035 #define PV_ICESTAR 0x0036 diff --git a/include/asm-ppc64/semaphore.h b/include/asm-ppc64/semaphore.h index a4408d98ede3..fff2593761d3 100644 --- a/include/asm-ppc64/semaphore.h +++ b/include/asm-ppc64/semaphore.h @@ -77,6 +77,7 @@ static inline void down(struct semaphore * sem) #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); /* * Try to get the semaphore, take the slow path if we fail. @@ -93,6 +94,7 @@ static inline int down_interruptible(struct semaphore * sem) #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif + might_sleep(); if (atomic_dec_return(&sem->count) < 0) ret = __down_interruptible(sem); diff --git a/include/asm-ppc64/sigcontext.h b/include/asm-ppc64/sigcontext.h index 2ec3ea89c059..467be1a3d86b 100644 --- a/include/asm-ppc64/sigcontext.h +++ b/include/asm-ppc64/sigcontext.h @@ -10,9 +10,10 @@ #include <asm/ptrace.h> -struct sigcontext_struct { +struct sigcontext { unsigned long _unused[4]; int signal; + int _pad0; unsigned long handler; unsigned long oldmask; struct pt_regs *regs; diff --git a/include/asm-ppc64/siginfo.h b/include/asm-ppc64/siginfo.h index 3bb578cf3897..4481c731ab27 100644 --- a/include/asm-ppc64/siginfo.h +++ b/include/asm-ppc64/siginfo.h @@ -8,6 +8,9 @@ * 2 of the License, or (at your option) any later version. */ +#define SI_PAD_SIZE ((SI_MAX_SIZE/sizeof(int)) - 4) +#define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3) + #include <asm-generic/siginfo.h> #endif /* _PPC64_SIGINFO_H */ diff --git a/include/asm-ppc64/stat.h b/include/asm-ppc64/stat.h index 5b12701dd858..14f338a7df43 100644 --- a/include/asm-ppc64/stat.h +++ b/include/asm-ppc64/stat.h @@ -27,8 +27,8 @@ struct __old_kernel_stat { struct stat { dev_t st_dev; ino_t st_ino; - mode_t st_mode; nlink_t st_nlink; + mode_t st_mode; uid_t st_uid; gid_t st_gid; dev_t st_rdev; @@ -43,6 +43,7 @@ struct stat { unsigned long __unused3; unsigned long __unused4; unsigned long __unused5; + unsigned long __unused6; }; /* This matches struct stat64 in glibc2.1. */ diff --git a/include/asm-ppc64/thread_info.h b/include/asm-ppc64/thread_info.h index b9e6db3fa0cf..7a52e78711dc 100644 --- a/include/asm-ppc64/thread_info.h +++ b/include/asm-ppc64/thread_info.h @@ -32,11 +32,11 @@ struct thread_info { */ #define INIT_THREAD_INFO(tsk) \ { \ - task: &tsk, \ - exec_domain: &default_exec_domain, \ - flags: 0, \ - cpu: 0, \ - preempt_count: 1, \ + .task = &tsk, \ + .exec_domain = &default_exec_domain, \ + .flags = 0, \ + .cpu = 0, \ + .preempt_count = 1, \ } #define init_thread_info (init_thread_union.thread_info) diff --git a/include/asm-ppc64/ucontext.h b/include/asm-ppc64/ucontext.h index 5d9b8105ce95..09e30c91d24e 100644 --- a/include/asm-ppc64/ucontext.h +++ b/include/asm-ppc64/ucontext.h @@ -13,7 +13,7 @@ struct ucontext { unsigned long uc_flags; struct ucontext *uc_link; stack_t uc_stack; - struct sigcontext_struct uc_mcontext; + struct sigcontext uc_mcontext; sigset_t uc_sigmask; /* mask last for extensibility */ }; diff --git a/include/asm-ppc64/udbg.h b/include/asm-ppc64/udbg.h index 8a5d3383bd9f..cdc306b1711f 100644 --- a/include/asm-ppc64/udbg.h +++ b/include/asm-ppc64/udbg.h @@ -17,6 +17,8 @@ int udbg_getc_poll(void); void udbg_puts(const char *s); int udbg_write(const char *s, int n); int udbg_read(char *buf, int buflen); +struct console; +void udbg_console_write(struct console *con, const char *s, unsigned int n); void udbg_puthex(unsigned long val); void udbg_printSP(const char *s); void udbg_printf(const char *fmt, ...); |
