diff --git a/[refs] b/[refs] index 5b9814a80c68..3ccc34db6cff 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 76babde121d2ffef04ca692ce64ef9f8a9866086 +refs/heads/master: 008652b337364ee994a0cd71d88a0fe9f00fc7ca diff --git a/trunk/Documentation/powerpc/booting-without-of.txt b/trunk/Documentation/powerpc/booting-without-of.txt index 217e51768b87..ee551c6ea235 100644 --- a/trunk/Documentation/powerpc/booting-without-of.txt +++ b/trunk/Documentation/powerpc/booting-without-of.txt @@ -719,11 +719,6 @@ address which can extend beyond that limit. - model : this is your board name/model - #address-cells : address representation for "root" devices - #size-cells: the size representation for "root" devices - - device_type : This property shouldn't be necessary. However, if - you decide to create a device_type for your root node, make sure it - is _not_ "chrp" unless your platform is a pSeries or PAPR compliant - one for 64-bit, or a CHRP-type machine for 32-bit as this will - matched by the kernel this way. Additionally, some recommended properties are: diff --git a/trunk/arch/mips/kernel/irixsig.c b/trunk/arch/mips/kernel/irixsig.c index 8150f071f80a..08273a2a501d 100644 --- a/trunk/arch/mips/kernel/irixsig.c +++ b/trunk/arch/mips/kernel/irixsig.c @@ -603,7 +603,7 @@ asmlinkage int irix_waitsys(int type, int pid, /* move to end of parent's list to avoid starvation */ write_lock_irq(&tasklist_lock); remove_parent(p); - add_parent(p); + add_parent(p, p->parent); write_unlock_irq(&tasklist_lock); retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; if (retval) @@ -643,7 +643,7 @@ asmlinkage int irix_waitsys(int type, int pid, write_lock_irq(&tasklist_lock); remove_parent(p); p->parent = p->real_parent; - add_parent(p); + add_parent(p, p->parent); do_notify_parent(p, SIGCHLD); write_unlock_irq(&tasklist_lock); } else diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 2cdc35ce8045..a433b7126d33 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -491,7 +491,7 @@ config PPC601_SYNC_FIX If in doubt, say Y here. config TAU - bool "On-chip CPU temperature sensor support" + bool "Thermal Management Support" depends on 6xx help G3 and G4 processors have an on-chip temperature sensor called the @@ -500,7 +500,7 @@ config TAU on-die temperature in /proc/cpuinfo if the cpu supports it. Unfortunately, on some chip revisions, this sensor is very inaccurate - and in many cases, does not work at all, so don't assume the cpu + and in some cases, does not work at all, so don't assume the cpu temp is actually what /proc/cpuinfo says it is. config TAU_INT diff --git a/trunk/arch/powerpc/Kconfig.debug b/trunk/arch/powerpc/Kconfig.debug index 8d48e9e7162a..9254806f7032 100644 --- a/trunk/arch/powerpc/Kconfig.debug +++ b/trunk/arch/powerpc/Kconfig.debug @@ -110,6 +110,11 @@ config SERIAL_TEXT_DEBUG depends on 4xx || LOPEC || MV64X60 || PPLUS || PRPMC800 || \ PPC_GEN550 || PPC_MPC52xx +config PPC_OCP + bool + depends on IBM_OCP || XILINX_OCP + default y + choice prompt "Early debugging (dangerous)" bool diff --git a/trunk/arch/powerpc/Makefile b/trunk/arch/powerpc/Makefile index 6ec84d37a337..829e017b8a54 100644 --- a/trunk/arch/powerpc/Makefile +++ b/trunk/arch/powerpc/Makefile @@ -129,8 +129,13 @@ core-y += arch/powerpc/kernel/ \ arch/powerpc/lib/ \ arch/powerpc/sysdev/ \ arch/powerpc/platforms/ -core-$(CONFIG_MATH_EMULATION) += arch/powerpc/math-emu/ +core-$(CONFIG_PPC32) += arch/ppc/kernel/ +core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/ core-$(CONFIG_XMON) += arch/powerpc/xmon/ +core-$(CONFIG_APUS) += arch/ppc/amiga/ +drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/ +drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/ +drivers-$(CONFIG_CPM2) += arch/ppc/8260_io/ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ diff --git a/trunk/arch/powerpc/configs/cell_defconfig b/trunk/arch/powerpc/configs/cell_defconfig index fe22e54ab2b0..3c2acab63736 100644 --- a/trunk/arch/powerpc/configs/cell_defconfig +++ b/trunk/arch/powerpc/configs/cell_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16 -# Thu Mar 23 20:48:09 2006 +# Linux kernel version: 2.6.16-rc6 +# Wed Mar 15 16:19:48 2006 # CONFIG_PPC64=y CONFIG_64BIT=y @@ -30,7 +30,6 @@ CONFIG_POWER4=y CONFIG_PPC_FPU=y CONFIG_ALTIVEC=y CONFIG_PPC_STD_MMU=y -CONFIG_VIRT_CPU_ACCOUNTING=y CONFIG_SMP=y CONFIG_NR_CPUS=4 @@ -52,8 +51,7 @@ CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y +# CONFIG_IKCONFIG is not set # CONFIG_CPUSETS is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y @@ -87,7 +85,7 @@ CONFIG_MODULE_UNLOAD=y CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y +# CONFIG_KMOD is not set CONFIG_STOP_MACHINE=y # @@ -132,8 +130,7 @@ CONFIG_CELL_IIC=y # # Cell Broadband Engine options # -CONFIG_SPU_FS=m -CONFIG_SPUFS_MMAP=y +CONFIG_SPU_FS=y # # Kernel options @@ -147,7 +144,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_PREEMPT_BKL=y CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=m +# CONFIG_BINFMT_MISC is not set CONFIG_FORCE_MAX_ZONEORDER=13 # CONFIG_IOMMU_VMERGE is not set CONFIG_KEXEC=y @@ -158,16 +155,13 @@ CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_SELECT_MEMORY_MODEL=y -# CONFIG_FLATMEM_MANUAL is not set +CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set -CONFIG_SPARSEMEM_MANUAL=y -CONFIG_SPARSEMEM=y -CONFIG_HAVE_MEMORY_PRESENT=y +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPARSEMEM_EXTREME=y -# CONFIG_MEMORY_HOTPLUG is not set CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_MIGRATION=y # CONFIG_PPC_64K_PAGES is not set CONFIG_SCHED_SMT=y CONFIG_PROC_DEVICETREE=y @@ -238,7 +232,6 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_IP_VS is not set CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set -# CONFIG_IPV6_ROUTER_PREF is not set CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m @@ -251,7 +244,25 @@ CONFIG_NETFILTER=y # Core Netfilter Configuration # # CONFIG_NETFILTER_NETLINK is not set -# CONFIG_NETFILTER_XTABLES is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m # # IP: Netfilter Configuration @@ -267,13 +278,51 @@ CONFIG_IP_NF_IRC=m CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_AMANDA=m # CONFIG_IP_NF_PPTP is not set -# CONFIG_IP_NF_H323 is not set CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_HASHLIMIT=m +CONFIG_IP_NF_MATCH_POLICY=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m # # IPv6: Netfilter Configuration (EXPERIMENTAL) # # CONFIG_IP6_NF_QUEUE is not set +# CONFIG_IP6_NF_IPTABLES is not set # # DCCP Configuration (EXPERIMENTAL) @@ -306,6 +355,7 @@ CONFIG_IP_NF_QUEUE=m # QoS and/or fair queueing # # CONFIG_NET_SCHED is not set +CONFIG_NET_CLS_ROUTE=y # # Network testing @@ -358,7 +408,7 @@ CONFIG_FW_LOADER=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_NBD=y # CONFIG_BLK_DEV_SX8 is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 @@ -434,23 +484,7 @@ CONFIG_IDEDMA_AUTO=y # # Multi-device support (RAID and LVM) # -CONFIG_MD=y -CONFIG_BLK_DEV_MD=m -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -# CONFIG_MD_RAID10 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_RAID6 is not set -# CONFIG_MD_MULTIPATH is not set -# CONFIG_MD_FAULTY is not set -CONFIG_BLK_DEV_DM=m -CONFIG_DM_CRYPT=m -CONFIG_DM_SNAPSHOT=m -CONFIG_DM_MIRROR=m -CONFIG_DM_ZERO=m -CONFIG_DM_MULTIPATH=m -# CONFIG_DM_MULTIPATH_EMC is not set +# CONFIG_MD is not set # # Fusion MPT device support @@ -514,7 +548,7 @@ CONFIG_MII=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set CONFIG_E1000=m -CONFIG_E1000_NAPI=y +# CONFIG_E1000_NAPI is not set # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set @@ -526,7 +560,7 @@ CONFIG_SKGE=m # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set -CONFIG_SPIDER_NET=m +CONFIG_SPIDER_NET=y # CONFIG_MV643XX_ETH is not set # @@ -644,8 +678,6 @@ CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y # CONFIG_LEGACY_PTYS is not set -CONFIG_HVC_DRIVER=y -CONFIG_HVC_RTAS=y # # IPMI @@ -662,13 +694,14 @@ CONFIG_WATCHDOG=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_WATCHDOG_RTAS=y +# CONFIG_WATCHDOG_RTAS is not set # # PCI-based Watchdog Cards # # CONFIG_PCIPCWATCHDOG is not set # CONFIG_WDTPCI is not set +# CONFIG_RTC is not set CONFIG_GEN_RTC=y # CONFIG_GEN_RTC_X is not set # CONFIG_DTLK is not set @@ -800,7 +833,6 @@ CONFIG_DUMMY_CONSOLE=y # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y # CONFIG_USB is not set # @@ -820,14 +852,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # InfiniBand support # -CONFIG_INFINIBAND=y -CONFIG_INFINIBAND_USER_MAD=m -CONFIG_INFINIBAND_USER_ACCESS=m -CONFIG_INFINIBAND_MTHCA=m -CONFIG_INFINIBAND_MTHCA_DEBUG=y -CONFIG_INFINIBAND_IPOIB=m -CONFIG_INFINIBAND_IPOIB_DEBUG=y -CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y +# CONFIG_INFINIBAND is not set # # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) @@ -1012,6 +1037,10 @@ CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m # # Instrumentation Support @@ -1029,7 +1058,7 @@ CONFIG_LOG_BUF_SHIFT=15 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_SPINLOCK is not set CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_KOBJECT is not set diff --git a/trunk/arch/powerpc/configs/mpc8540_ads_defconfig b/trunk/arch/powerpc/configs/mpc8540_ads_defconfig index 7f0780f1aa39..2a8290ee15c6 100644 --- a/trunk/arch/powerpc/configs/mpc8540_ads_defconfig +++ b/trunk/arch/powerpc/configs/mpc8540_ads_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16 -# Mon Mar 27 23:37:36 2006 +# Linux kernel version: +# Sat Jan 14 15:57:54 2006 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -9,7 +9,6 @@ CONFIG_PPC_MERGE=y CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y @@ -19,7 +18,6 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y CONFIG_PPC_UDBG_16550=y # CONFIG_GENERIC_TBSYNC is not set -CONFIG_DEFAULT_UIMAGE=y # # Processor support @@ -44,6 +42,7 @@ CONFIG_SPE=y # Code maturity level options # CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 @@ -59,7 +58,6 @@ CONFIG_SYSVIPC=y CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EMBEDDED=y @@ -74,6 +72,10 @@ CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -88,8 +90,6 @@ CONFIG_BASE_SMALL=0 # Block layer # # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set # # IO Schedulers @@ -183,7 +183,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -221,11 +220,6 @@ CONFIG_TCP_CONG_BIC=y # SCTP Configuration (EXPERIMENTAL) # # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set @@ -235,6 +229,11 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -487,12 +486,6 @@ CONFIG_GEN_RTC=y # # CONFIG_I2C is not set -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - # # Dallas's 1-wire bus # @@ -503,13 +496,16 @@ CONFIG_GEN_RTC=y # CONFIG_HWMON=y # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_F71805F is not set # CONFIG_HWMON_DEBUG_CHIP is not set # # Misc devices # +# +# Multimedia Capabilities Port drivers +# + # # Multimedia devices # @@ -535,7 +531,6 @@ CONFIG_HWMON=y # # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' @@ -556,7 +551,7 @@ CONFIG_HWMON=y # # -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# SN Devices # # @@ -608,6 +603,7 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set # CONFIG_CONFIGFS_FS is not set # @@ -662,7 +658,6 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set # @@ -700,8 +695,6 @@ CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set -# CONFIG_UNWIND_INFO is not set -CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUGGER is not set # CONFIG_BDI_SWITCH is not set diff --git a/trunk/arch/powerpc/kernel/Makefile b/trunk/arch/powerpc/kernel/Makefile index 0cc0995b81b0..80e9fe2632b8 100644 --- a/trunk/arch/powerpc/kernel/Makefile +++ b/trunk/arch/powerpc/kernel/Makefile @@ -12,12 +12,12 @@ endif obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ irq.o align.o signal_32.o pmc.o vdso.o \ - init_task.o process.o systbl.o idle.o + init_task.o process.o systbl.o obj-y += vdso32/ obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ signal_64.o ptrace32.o \ paca.o cpu_setup_power4.o \ - firmware.o sysfs.o + firmware.o sysfs.o idle_64.o obj-$(CONFIG_PPC64) += vdso64/ obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_POWER4) += idle_power4.o @@ -34,11 +34,6 @@ obj-$(CONFIG_IBMEBUS) += ibmebus.o obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o -obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o -obj-$(CONFIG_TAU) += tau_6xx.o -obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o -obj32-$(CONFIG_MODULES) += module_32.o -obj-$(CONFIG_E500) += perfmon_fsl_booke.o ifeq ($(CONFIG_PPC_MERGE),y) @@ -56,6 +51,7 @@ obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o obj-$(CONFIG_MODULES) += ppc_ksyms.o obj-$(CONFIG_BOOTX_TEXT) += btext.o +obj-$(CONFIG_6xx) += idle_6xx.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o @@ -81,7 +77,6 @@ smpobj-$(CONFIG_SMP) += smp.o endif -obj-$(CONFIG_PPC32) += $(obj32-y) obj-$(CONFIG_PPC64) += $(obj64-y) extra-$(CONFIG_PPC_FPU) += fpu.o diff --git a/trunk/arch/powerpc/kernel/asm-offsets.c b/trunk/arch/powerpc/kernel/asm-offsets.c index 54b48f330051..882889b15926 100644 --- a/trunk/arch/powerpc/kernel/asm-offsets.c +++ b/trunk/arch/powerpc/kernel/asm-offsets.c @@ -105,6 +105,8 @@ int main(void) DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size)); DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size)); DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page)); + DEFINE(PLATFORM_LPAR, PLATFORM_LPAR); + /* paca */ DEFINE(PACA_SIZE, sizeof(struct paca_struct)); DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index)); diff --git a/trunk/arch/powerpc/kernel/entry_32.S b/trunk/arch/powerpc/kernel/entry_32.S index b3a979467225..4827ca1ec89b 100644 --- a/trunk/arch/powerpc/kernel/entry_32.S +++ b/trunk/arch/powerpc/kernel/entry_32.S @@ -135,10 +135,10 @@ transfer_to_handler: mfspr r11,SPRN_HID0 mtcr r11 BEGIN_FTR_SECTION - bt- 8,4f /* Check DOZE */ + bt- 8,power_save_6xx_restore /* Check DOZE */ END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) BEGIN_FTR_SECTION - bt- 9,4f /* Check NAP */ + bt- 9,power_save_6xx_restore /* Check NAP */ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #endif /* CONFIG_6xx */ .globl transfer_to_handler_cont @@ -157,10 +157,6 @@ transfer_to_handler_cont: SYNC RFI /* jump to handler, enable MMU */ -#ifdef CONFIG_6xx -4: b power_save_6xx_restore -#endif - /* * On kernel stack overflow, load up an initial stack pointer * and call StackOverflow(regs), which should not return. diff --git a/trunk/arch/powerpc/kernel/entry_64.S b/trunk/arch/powerpc/kernel/entry_64.S index 19ad5c6b1818..1060155d84c3 100644 --- a/trunk/arch/powerpc/kernel/entry_64.S +++ b/trunk/arch/powerpc/kernel/entry_64.S @@ -617,12 +617,6 @@ _GLOBAL(enter_rtas) mfsrr1 r10 std r10,_SRR1(r1) - /* Temporary workaround to clear CR until RTAS can be modified to - * ignore all bits. - */ - li r0,0 - mtcr r0 - /* There is no way it is acceptable to get here with interrupts enabled, * check it with the asm equivalent of WARN_ON */ diff --git a/trunk/arch/powerpc/kernel/firmware.c b/trunk/arch/powerpc/kernel/firmware.c index 0bfe9061720a..4d37a3cb80f6 100644 --- a/trunk/arch/powerpc/kernel/firmware.c +++ b/trunk/arch/powerpc/kernel/firmware.c @@ -14,9 +14,7 @@ */ #include -#include #include -unsigned long powerpc_firmware_features; -EXPORT_SYMBOL_GPL(powerpc_firmware_features); +unsigned long ppc64_firmware_features; diff --git a/trunk/arch/powerpc/kernel/head_64.S b/trunk/arch/powerpc/kernel/head_64.S index a5ae04a57c78..35084f3a841b 100644 --- a/trunk/arch/powerpc/kernel/head_64.S +++ b/trunk/arch/powerpc/kernel/head_64.S @@ -1544,11 +1544,7 @@ _STATIC(__boot_from_prom) mr r28,r6 mr r27,r7 - /* - * Align the stack to 16-byte boundary - * Depending on the size and layout of the ELF sections in the initial - * boot binary, the stack pointer will be unalignet on PowerMac - */ + /* Align the stack to 16-byte boundary for broken yaboot */ rldicr r1,r1,0,59 /* Make sure we are running in 64 bits mode */ @@ -1851,6 +1847,21 @@ _STATIC(start_here_multiplatform) bl .__save_cpu_setup sync + /* Setup a valid physical PACA pointer in SPRG3 for early_setup + * note that boot_cpuid can always be 0 nowadays since there is + * nowhere it can be initialized differently before we reach this + * code + */ + LOAD_REG_IMMEDIATE(r27, boot_cpuid) + add r27,r27,r26 + lwz r27,0(r27) + + LOAD_REG_IMMEDIATE(r24, paca) /* Get base vaddr of paca array */ + mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */ + add r13,r13,r24 /* for this processor. */ + add r13,r13,r26 /* convert to physical addr */ + mtspr SPRN_SPRG3,r13 + /* Do very early kernel initializations, including initial hash table, * stab and slb setup before we turn on relocation. */ @@ -1919,17 +1930,6 @@ _STATIC(start_here_common) /* Not reached */ BUG_OPCODE -/* Put the paca pointer into r13 and SPRG3 */ -_GLOBAL(setup_boot_paca) - LOAD_REG_IMMEDIATE(r3, boot_cpuid) - lwz r3,0(r3) - LOAD_REG_IMMEDIATE(r4, paca) /* Get base vaddr of paca array */ - mulli r3,r3,PACA_SIZE /* Calculate vaddr of right paca */ - add r13,r3,r4 /* for this processor. */ - mtspr SPRN_SPRG3,r13 - - blr - /* * We put a few things here that have to be page-aligned. * This stuff goes at the beginning of the bss, which is page-aligned. diff --git a/trunk/arch/powerpc/kernel/idle.c b/trunk/arch/powerpc/kernel/idle_64.c similarity index 65% rename from trunk/arch/powerpc/kernel/idle.c rename to trunk/arch/powerpc/kernel/idle_64.c index e9f321d74d85..b879d3057ef8 100644 --- a/trunk/arch/powerpc/kernel/idle.c +++ b/trunk/arch/powerpc/kernel/idle_64.c @@ -2,17 +2,13 @@ * Idle daemon for PowerPC. Idle daemon will handle any action * that needs to be taken when the system becomes idle. * - * Originally written by Cort Dougan (cort@cs.nmt.edu). - * Subsequent 32-bit hacking by Tom Rini, Armin Kuster, - * Paul Mackerras and others. + * Originally Written by Cort Dougan (cort@cs.nmt.edu) * * iSeries supported added by Mike Corrigan * * Additional shared processor, SMT, and firmware support * Copyright (c) 2003 Dave Engebretsen * - * 32-bit and 64-bit versions merged by Paul Mackerras - * * 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 @@ -33,43 +29,18 @@ #include #include -#ifdef CONFIG_HOTPLUG_CPU -#define cpu_should_die() (cpu_is_offline(smp_processor_id()) && \ - system_state == SYSTEM_RUNNING) -#else -#define cpu_should_die() 0 -#endif +extern void power4_idle(void); -/* - * The body of the idle task. - */ -void cpu_idle(void) +void default_idle(void) { - if (ppc_md.idle_loop) - ppc_md.idle_loop(); /* doesn't return */ - + unsigned int cpu = smp_processor_id(); set_thread_flag(TIF_POLLING_NRFLAG); - while (1) { - ppc64_runlatch_off(); - while (!need_resched() && !cpu_should_die()) { - if (ppc_md.power_save) { - clear_thread_flag(TIF_POLLING_NRFLAG); - /* - * smp_mb is so clearing of TIF_POLLING_NRFLAG - * is ordered w.r.t. need_resched() test. - */ - smp_mb(); - local_irq_disable(); - - /* check again after disabling irqs */ - if (!need_resched() && !cpu_should_die()) - ppc_md.power_save(); - - local_irq_enable(); - set_thread_flag(TIF_POLLING_NRFLAG); + while (1) { + if (!need_resched()) { + while (!need_resched() && !cpu_is_offline(cpu)) { + ppc64_runlatch_off(); - } else { /* * Go into low thread priority and possibly * low power mode. @@ -77,18 +48,46 @@ void cpu_idle(void) HMT_low(); HMT_very_low(); } + + HMT_medium(); } - HMT_medium(); ppc64_runlatch_on(); - if (cpu_should_die()) - cpu_die(); preempt_enable_no_resched(); schedule(); preempt_disable(); + if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) + cpu_die(); } } +void native_idle(void) +{ + while (1) { + ppc64_runlatch_off(); + + if (!need_resched()) + power4_idle(); + + if (need_resched()) { + ppc64_runlatch_on(); + preempt_enable_no_resched(); + schedule(); + preempt_disable(); + } + + if (cpu_is_offline(smp_processor_id()) && + system_state == SYSTEM_RUNNING) + cpu_die(); + } +} + +void cpu_idle(void) +{ + BUG_ON(NULL == ppc_md.idle_loop); + ppc_md.idle_loop(); +} + int powersave_nap; #ifdef CONFIG_SYSCTL diff --git a/trunk/arch/powerpc/kernel/idle_6xx.S b/trunk/arch/powerpc/kernel/idle_6xx.S index 12a4efbaa08f..444fdcc769f1 100644 --- a/trunk/arch/powerpc/kernel/idle_6xx.S +++ b/trunk/arch/powerpc/kernel/idle_6xx.S @@ -87,6 +87,19 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) cmpwi 0,r3,0 beqlr + /* Clear MSR:EE */ + mfmsr r7 + rlwinm r0,r7,0,17,15 + mtmsr r0 + + /* Check current_thread_info()->flags */ + rlwinm r4,r1,0,0,18 + lwz r4,TI_FLAGS(r4) + andi. r0,r4,_TIF_NEED_RESCHED + beq 1f + mtmsr r7 /* out of line this ? */ + blr +1: /* Some pre-nap cleanups needed on some CPUs */ andis. r0,r3,HID0_NAP@h beq 2f @@ -144,8 +157,7 @@ BEGIN_FTR_SECTION DSSALL sync END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) - mfmsr r7 - ori r7,r7,MSR_EE + ori r7,r7,MSR_EE /* Could be ommited (already set) */ oris r7,r7,MSR_POW@h sync isync @@ -208,6 +220,8 @@ _GLOBAL(nap_save_msscr0) _GLOBAL(nap_save_hid1) .space 4*NR_CPUS +_GLOBAL(powersave_nap) + .long 0 _GLOBAL(powersave_lowspeed) .long 0 diff --git a/trunk/arch/powerpc/kernel/idle_power4.S b/trunk/arch/powerpc/kernel/idle_power4.S index 6dad1c02496e..c16b4afab582 100644 --- a/trunk/arch/powerpc/kernel/idle_power4.S +++ b/trunk/arch/powerpc/kernel/idle_power4.S @@ -1,5 +1,11 @@ /* - * This file contains the power_save function for 970-family CPUs. + * This file contains the power_save function for 6xx & 7xxx CPUs + * rewritten in assembler + * + * Warning ! This code assumes that if your machine has a 750fx + * it will have PLL 1 set to low speed mode (used during NAP/DOZE). + * if this is not the case some additional changes will have to + * be done to check a runtime var (a bit like powersave-nap) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -20,23 +26,49 @@ .text +/* + * Here is the power_save_6xx function. This could eventually be + * split into several functions & changing the function pointer + * depending on the various features. + */ _GLOBAL(power4_idle) BEGIN_FTR_SECTION blr END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP) + /* We must dynamically check for the NAP feature as it + * can be cleared by CPU init after the fixups are done + */ + LOAD_REG_ADDRBASE(r3,cur_cpu_spec) + ld r4,ADDROFF(cur_cpu_spec)(r3) + ld r4,CPU_SPEC_FEATURES(r4) + andi. r0,r4,CPU_FTR_CAN_NAP + beqlr /* Now check if user or arch enabled NAP mode */ LOAD_REG_ADDRBASE(r3,powersave_nap) lwz r4,ADDROFF(powersave_nap)(r3) cmpwi 0,r4,0 beqlr + /* Clear MSR:EE */ + mfmsr r7 + li r4,0 + ori r4,r4,MSR_EE + andc r0,r7,r4 + mtmsrd r0 + + /* Check current_thread_info()->flags */ + clrrdi r4,r1,THREAD_SHIFT + ld r4,TI_FLAGS(r4) + andi. r0,r4,_TIF_NEED_RESCHED + beq 1f + mtmsrd r7 /* out of line this ? */ + blr +1: /* Go to NAP now */ BEGIN_FTR_SECTION DSSALL sync END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) - mfmsr r7 - ori r7,r7,MSR_EE oris r7,r7,MSR_POW@h sync isync diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index bb5c9501234c..771a59cbd213 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -379,7 +379,7 @@ void irq_ctx_init(void) struct thread_info *tp; int i; - for_each_possible_cpu(i) { + for_each_cpu(i) { memset((void *)softirq_ctx[i], 0, THREAD_SIZE); tp = softirq_ctx[i]; tp->cpu = i; diff --git a/trunk/arch/powerpc/kernel/legacy_serial.c b/trunk/arch/powerpc/kernel/legacy_serial.c index 6e67b5b49ba1..c7a799a09516 100644 --- a/trunk/arch/powerpc/kernel/legacy_serial.c +++ b/trunk/arch/powerpc/kernel/legacy_serial.c @@ -37,7 +37,7 @@ static int legacy_serial_console = -1; static int __init add_legacy_port(struct device_node *np, int want_index, int iotype, phys_addr_t base, phys_addr_t taddr, unsigned long irq, - upf_t flags) + unsigned int flags) { u32 *clk, *spd, clock = BASE_BAUD * 16; int index; @@ -113,7 +113,7 @@ static int __init add_legacy_soc_port(struct device_node *np, { phys_addr_t addr; u32 *addrp; - upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; + unsigned int flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; /* We only support ports that have a clock frequency properly * encoded in the device-tree. @@ -236,23 +236,6 @@ static int __init add_legacy_pci_port(struct device_node *np, } #endif -static void __init setup_legacy_serial_console(int console) -{ - struct legacy_serial_info *info = - &legacy_serial_infos[console]; - void __iomem *addr; - - if (info->taddr == 0) - return; - addr = ioremap(info->taddr, 0x1000); - if (addr == NULL) - return; - if (info->speed == 0) - info->speed = udbg_probe_uart_speed(addr, info->clock); - DBG("default console speed = %d\n", info->speed); - udbg_init_uart(addr, info->speed, info->clock); -} - /* * This is called very early, as part of setup_system() or eventually * setup_arch(), basically before anything else in this file. This function @@ -335,8 +318,25 @@ void __init find_legacy_serial_ports(void) #endif DBG("legacy_serial_console = %d\n", legacy_serial_console); - if (legacy_serial_console >= 0) - setup_legacy_serial_console(legacy_serial_console); + + /* udbg is 64 bits only for now, that will change soon though ... */ + while (legacy_serial_console >= 0) { + struct legacy_serial_info *info = + &legacy_serial_infos[legacy_serial_console]; + void __iomem *addr; + + if (info->taddr == 0) + break; + addr = ioremap(info->taddr, 0x1000); + if (addr == NULL) + break; + if (info->speed == 0) + info->speed = udbg_probe_uart_speed(addr, info->clock); + DBG("default console speed = %d\n", info->speed); + udbg_init_uart(addr, info->speed, info->clock); + break; + } + DBG(" <- find_legacy_serial_port()\n"); } diff --git a/trunk/arch/powerpc/kernel/lparcfg.c b/trunk/arch/powerpc/kernel/lparcfg.c index 1b73508ecb2b..e789fef4eb8a 100644 --- a/trunk/arch/powerpc/kernel/lparcfg.c +++ b/trunk/arch/powerpc/kernel/lparcfg.c @@ -56,7 +56,7 @@ static unsigned long get_purr(void) unsigned long sum_purr = 0; int cpu; - for_each_possible_cpu(cpu) { + for_each_cpu(cpu) { sum_purr += lppaca[cpu].emulated_time_base; #ifdef PURR_DEBUG @@ -222,7 +222,7 @@ static unsigned long get_purr(void) int cpu; struct cpu_usage *cu; - for_each_possible_cpu(cpu) { + for_each_cpu(cpu) { cu = &per_cpu(cpu_usage_array, cpu); sum_purr += cu->current_tb; } diff --git a/trunk/arch/powerpc/kernel/nvram_64.c b/trunk/arch/powerpc/kernel/nvram_64.c index ada50aa5b600..fd7db8d542db 100644 --- a/trunk/arch/powerpc/kernel/nvram_64.c +++ b/trunk/arch/powerpc/kernel/nvram_64.c @@ -160,7 +160,7 @@ static int dev_nvram_ioctl(struct inode *inode, struct file *file, case IOC_NVRAM_GET_OFFSET: { int part, offset; - if (!machine_is(powermac)) + if (_machine != PLATFORM_POWERMAC) return -EINVAL; if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0) return -EFAULT; @@ -174,9 +174,8 @@ static int dev_nvram_ioctl(struct inode *inode, struct file *file, return 0; } #endif /* CONFIG_PPC_PMAC */ - default: - return -EINVAL; } + return -EINVAL; } struct file_operations nvram_fops = { @@ -444,7 +443,7 @@ static int nvram_setup_partition(void) * in our nvram, as Apple defined partitions use pretty much * all of the space */ - if (machine_is(powermac)) + if (_machine == PLATFORM_POWERMAC) return -ENOSPC; /* see if we have an OS partition that meets our needs. diff --git a/trunk/arch/powerpc/kernel/paca.c b/trunk/arch/powerpc/kernel/paca.c index f505a8827e3e..5d1b708086bd 100644 --- a/trunk/arch/powerpc/kernel/paca.c +++ b/trunk/arch/powerpc/kernel/paca.c @@ -56,11 +56,14 @@ struct lppaca lppaca[] = { * processors. The processor VPD array needs one entry per physical * processor (not thread). */ -#define PACA_INIT_COMMON(number) \ +#define PACA_INIT_COMMON(number, start, asrr, asrv) \ .lppaca_ptr = &lppaca[number], \ .lock_token = 0x8000, \ .paca_index = (number), /* Paca Index */ \ .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \ + .stab_real = (asrr), /* Real pointer to segment table */ \ + .stab_addr = (asrv), /* Virt pointer to segment table */ \ + .cpu_start = (start), /* Processor start */ \ .hw_cpu_id = 0xffff, #ifdef CONFIG_PPC_ISERIES @@ -69,20 +72,30 @@ struct lppaca lppaca[] = { #define PACA_INIT(number) \ { \ - PACA_INIT_COMMON(number) \ + PACA_INIT_COMMON(number, 0, 0, 0) \ + PACA_INIT_ISERIES(number) \ +} + +#define BOOTCPU_PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 1, 0, (u64)&initial_stab) \ PACA_INIT_ISERIES(number) \ } #else #define PACA_INIT(number) \ { \ - PACA_INIT_COMMON(number) \ + PACA_INIT_COMMON(number, 0, 0, 0) \ } +#define BOOTCPU_PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, (u64)&initial_stab) \ +} #endif struct paca_struct paca[] = { - PACA_INIT(0), + BOOTCPU_PACA_INIT(0), #if NR_CPUS > 1 PACA_INIT( 1), PACA_INIT( 2), PACA_INIT( 3), #if NR_CPUS > 4 diff --git a/trunk/arch/powerpc/kernel/pci_32.c b/trunk/arch/powerpc/kernel/pci_32.c index b129d2e4b759..704c846b2b0f 100644 --- a/trunk/arch/powerpc/kernel/pci_32.c +++ b/trunk/arch/powerpc/kernel/pci_32.c @@ -787,7 +787,7 @@ pci_busdev_to_OF_node(struct pci_bus *bus, int devfn) * fix has to be done by making the remapping per-host and always * filling the pci_to_OF map. --BenH */ - if (machine_is(powermac) && busnr >= 0xf0) + if (_machine == _MACH_Pmac && busnr >= 0xf0) busnr -= 0xf0; else #endif @@ -1728,7 +1728,7 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) * (bus 0 is HT root), we return the AGP one instead. */ #ifdef CONFIG_PPC_PMAC - if (machine_is(powermac) && machine_is_compatible("MacRISC4")) + if (_machine == _MACH_Pmac && machine_is_compatible("MacRISC4")) if (bus == 0) bus = 0xf0; #endif /* CONFIG_PPC_PMAC */ diff --git a/trunk/arch/powerpc/kernel/pci_64.c b/trunk/arch/powerpc/kernel/pci_64.c index 4c4449be81ce..ba92bab7cc2c 100644 --- a/trunk/arch/powerpc/kernel/pci_64.c +++ b/trunk/arch/powerpc/kernel/pci_64.c @@ -78,7 +78,6 @@ int global_phb_number; /* Global phb counter */ /* Cached ISA bridge dev. */ struct pci_dev *ppc64_isabridge_dev = NULL; -EXPORT_SYMBOL_GPL(ppc64_isabridge_dev); static void fixup_broken_pcnet32(struct pci_dev* dev) { diff --git a/trunk/arch/powerpc/kernel/proc_ppc64.c b/trunk/arch/powerpc/kernel/proc_ppc64.c index 3c2cf661f6d9..7ba42a405f41 100644 --- a/trunk/arch/powerpc/kernel/proc_ppc64.c +++ b/trunk/arch/powerpc/kernel/proc_ppc64.c @@ -23,7 +23,6 @@ #include #include -#include #include #include #include @@ -52,7 +51,7 @@ static int __init proc_ppc64_create(void) if (!root) return 1; - if (!machine_is(pseries) && !machine_is(cell)) + if (!(platform_is_pseries() || _machine == PLATFORM_CELL)) return 0; if (!proc_mkdir("rtas", root)) diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index 706090c99f47..f698aa77127e 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -45,7 +45,6 @@ #include #include #include -#include #ifdef CONFIG_PPC64 #include #endif @@ -363,11 +362,7 @@ static void show_instructions(struct pt_regs *regs) if (!(i % 8)) printk("\n"); - /* We use __get_user here *only* to avoid an OOPS on a - * bad address because the pc *should* only be a - * kernel address. - */ - if (BAD_PC(pc) || __get_user(instr, (unsigned int __user *)pc)) { + if (BAD_PC(pc) || __get_user(instr, (unsigned int *)pc)) { printk("XXXXXXXX "); } else { if (regs->nip == pc) @@ -770,7 +765,7 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, return error; } -int validate_sp(unsigned long sp, struct task_struct *p, +static int validate_sp(unsigned long sp, struct task_struct *p, unsigned long nbytes) { unsigned long stack_page = (unsigned long)task_stack_page(p); @@ -808,8 +803,6 @@ int validate_sp(unsigned long sp, struct task_struct *p, #define FRAME_MARKER 2 #endif -EXPORT_SYMBOL(validate_sp); - unsigned long get_wchan(struct task_struct *p) { unsigned long ip, sp; diff --git a/trunk/arch/powerpc/kernel/prom.c b/trunk/arch/powerpc/kernel/prom.c index 4336390bcf34..d63cd562d9d5 100644 --- a/trunk/arch/powerpc/kernel/prom.c +++ b/trunk/arch/powerpc/kernel/prom.c @@ -383,14 +383,14 @@ static int __devinit finish_node_interrupts(struct device_node *np, /* Apple uses bits in there in a different way, let's * only keep the real sense bit on macs */ - if (machine_is(powermac)) + if (_machine == PLATFORM_POWERMAC) sense &= 0x1; np->intrs[intrcount].sense = map_mpic_senses[sense]; } #ifdef CONFIG_PPC64 /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */ - if (machine_is(powermac) && ic && ic->parent) { + if (_machine == PLATFORM_POWERMAC && ic && ic->parent) { char *name = get_property(ic->parent, "name", NULL); if (name && !strcmp(name, "u3")) np->intrs[intrcount].line += 128; @@ -570,18 +570,6 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node, return rc; } -unsigned long __init of_get_flat_dt_root(void) -{ - unsigned long p = ((unsigned long)initial_boot_params) + - initial_boot_params->off_dt_struct; - - while(*((u32 *)p) == OF_DT_NOP) - p += 4; - BUG_ON (*((u32 *)p) != OF_DT_BEGIN_NODE); - p += 4; - return _ALIGN(p + strlen((char *)p) + 1, 4); -} - /** * This function can be used within scan_flattened_dt callback to get * access to properties @@ -624,25 +612,6 @@ void* __init of_get_flat_dt_prop(unsigned long node, const char *name, } while(1); } -int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) -{ - const char* cp; - unsigned long cplen, l; - - cp = of_get_flat_dt_prop(node, "compatible", &cplen); - if (cp == NULL) - return 0; - while (cplen > 0) { - if (strncasecmp(cp, compat, strlen(compat)) == 0) - return 1; - l = strlen(cp) + 1; - cp += l; - cplen -= l; - } - - return 0; -} - static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, unsigned long align) { @@ -717,7 +686,7 @@ static unsigned long __init unflatten_dt_node(unsigned long mem, #ifdef DEBUG if ((strlen(p) + l + 1) != allocl) { DBG("%s: p: %d, l: %d, a: %d\n", - pathp, (int)strlen(p), l, allocl); + pathp, strlen(p), l, allocl); } #endif p += strlen(p); @@ -885,73 +854,35 @@ void __init unflatten_device_tree(void) DBG(" <- unflatten_device_tree()\n"); } + static int __init early_init_dt_scan_cpus(unsigned long node, - const char *uname, int depth, - void *data) + const char *uname, int depth, void *data) { - static int logical_cpuid = 0; - char *type = of_get_flat_dt_prop(node, "device_type", NULL); -#ifdef CONFIG_ALTIVEC u32 *prop; -#endif - u32 *intserv; - int i, nthreads; - unsigned long len; - int found = 0; + unsigned long size; + char *type = of_get_flat_dt_prop(node, "device_type", &size); /* We are scanning "cpu" nodes only */ if (type == NULL || strcmp(type, "cpu") != 0) return 0; - /* Get physical cpuid */ - intserv = of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", &len); - if (intserv) { - nthreads = len / sizeof(int); - } else { - intserv = of_get_flat_dt_prop(node, "reg", NULL); - nthreads = 1; - } - - /* - * Now see if any of these threads match our boot cpu. - * NOTE: This must match the parsing done in smp_setup_cpu_maps. - */ - for (i = 0; i < nthreads; i++) { - /* - * version 2 of the kexec param format adds the phys cpuid of - * booted proc. + boot_cpuid = 0; + boot_cpuid_phys = 0; + if (initial_boot_params && initial_boot_params->version >= 2) { + /* version 2 of the kexec param format adds the phys cpuid + * of booted proc. */ - if (initial_boot_params && initial_boot_params->version >= 2) { - if (intserv[i] == - initial_boot_params->boot_cpuid_phys) { - found = 1; - break; - } - } else { - /* - * Check if it's the boot-cpu, set it's hw index now, - * unfortunately this format did not support booting - * off secondary threads. - */ - if (of_get_flat_dt_prop(node, + boot_cpuid_phys = initial_boot_params->boot_cpuid_phys; + } else { + /* Check if it's the boot-cpu, set it's hw index now */ + if (of_get_flat_dt_prop(node, "linux,boot-cpu", NULL) != NULL) { - found = 1; - break; - } + prop = of_get_flat_dt_prop(node, "reg", NULL); + if (prop != NULL) + boot_cpuid_phys = *prop; } - -#ifdef CONFIG_SMP - /* logical cpu id is always 0 on UP kernels */ - logical_cpuid++; -#endif - } - - if (found) { - DBG("boot cpu: logical %d physical %d\n", logical_cpuid, - intserv[i]); - boot_cpuid = logical_cpuid; - set_hard_smp_processor_id(boot_cpuid, intserv[i]); } + set_hard_smp_processor_id(0, boot_cpuid_phys); #ifdef CONFIG_ALTIVEC /* Check if we have a VMX and eventually update CPU features */ @@ -970,10 +901,16 @@ static int __init early_init_dt_scan_cpus(unsigned long node, #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_PPC_PSERIES - if (nthreads > 1) + /* + * Check for an SMT capable CPU and set the CPU feature. We do + * this by looking at the size of the ibm,ppc-interrupt-server#s + * property + */ + prop = (u32 *)of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", + &size); + cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT; + if (prop && ((size / sizeof(u32)) > 1)) cur_cpu_spec->cpu_features |= CPU_FTR_SMT; - else - cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT; #endif return 0; @@ -982,6 +919,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node, static int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, int depth, void *data) { + u32 *prop; unsigned long *lprop; unsigned long l; char *p; @@ -992,6 +930,14 @@ static int __init early_init_dt_scan_chosen(unsigned long node, (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) return 0; + /* get platform type */ + prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL); + if (prop == NULL) + return 0; +#ifdef CONFIG_PPC_MULTIPLATFORM + _machine = *prop; +#endif + #ifdef CONFIG_PPC64 /* check if iommu is forced on or off */ if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL) @@ -1018,15 +964,15 @@ static int __init early_init_dt_scan_chosen(unsigned long node, * set of RTAS infos now if available */ { - u64 *basep, *entryp, *sizep; + u64 *basep, *entryp; basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL); entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL); - sizep = of_get_flat_dt_prop(node, "linux,rtas-size", NULL); - if (basep && entryp && sizep) { + prop = of_get_flat_dt_prop(node, "linux,rtas-size", NULL); + if (basep && entryp && prop) { rtas.base = *basep; rtas.entry = *entryp; - rtas.size = *sizep; + rtas.size = *prop; } } #endif /* CONFIG_PPC_RTAS */ @@ -1055,13 +1001,25 @@ static int __init early_init_dt_scan_chosen(unsigned long node, if (strstr(cmd_line, "mem=")) { char *p, *q; + unsigned long maxmem = 0; for (q = cmd_line; (p = strstr(q, "mem=")) != 0; ) { q = p + 4; if (p > cmd_line && p[-1] != ' ') continue; - memory_limit = memparse(q, &q); + maxmem = simple_strtoul(q, &q, 0); + if (*q == 'k' || *q == 'K') { + maxmem <<= 10; + ++q; + } else if (*q == 'm' || *q == 'M') { + maxmem <<= 20; + ++q; + } else if (*q == 'g' || *q == 'G') { + maxmem <<= 30; + ++q; + } } + memory_limit = maxmem; } /* break now */ @@ -1797,7 +1755,7 @@ static int of_finish_dynamic_node(struct device_node *node) /* We don't support that function on PowerMac, at least * not yet */ - if (machine_is(powermac)) + if (_machine == PLATFORM_POWERMAC) return -ENODEV; /* fix up new node's linux_phandle field */ diff --git a/trunk/arch/powerpc/kernel/prom_init.c b/trunk/arch/powerpc/kernel/prom_init.c index d66c5e77fcff..813c2cd194c2 100644 --- a/trunk/arch/powerpc/kernel/prom_init.c +++ b/trunk/arch/powerpc/kernel/prom_init.c @@ -180,16 +180,6 @@ static unsigned long __initdata prom_tce_alloc_start; static unsigned long __initdata prom_tce_alloc_end; #endif -/* Platforms codes are now obsolete in the kernel. Now only used within this - * file and ultimately gone too. Feel free to change them if you need, they - * are not shared with anything outside of this file anymore - */ -#define PLATFORM_PSERIES 0x0100 -#define PLATFORM_PSERIES_LPAR 0x0101 -#define PLATFORM_LPAR 0x0001 -#define PLATFORM_POWERMAC 0x0400 -#define PLATFORM_GENERIC 0x0500 - static int __initdata of_platform; static char __initdata prom_cmd_line[COMMAND_LINE_SIZE]; @@ -407,11 +397,6 @@ static void __init __attribute__((noreturn)) prom_panic(const char *reason) reason = PTRRELOC(reason); #endif prom_print(reason); - /* Do not call exit because it clears the screen on pmac - * it also causes some sort of double-fault on early pmacs */ - if (RELOC(of_platform) == PLATFORM_POWERMAC) - asm("trap\n"); - /* ToDo: should put up an SRC here on p/iSeries */ call_prom("exit", 0, 0); @@ -1502,10 +1487,7 @@ static int __init prom_find_machine_type(void) int len, i = 0; #ifdef CONFIG_PPC64 phandle rtas; - int x; #endif - - /* Look for a PowerMac */ len = prom_getprop(_prom->root, "compatible", compat, sizeof(compat)-1); if (len > 0) { @@ -1518,36 +1500,28 @@ static int __init prom_find_machine_type(void) if (strstr(p, RELOC("Power Macintosh")) || strstr(p, RELOC("MacRISC"))) return PLATFORM_POWERMAC; +#ifdef CONFIG_PPC64 + if (strstr(p, RELOC("Momentum,Maple"))) + return PLATFORM_MAPLE; + if (strstr(p, RELOC("IBM,CPB"))) + return PLATFORM_CELL; +#endif i += sl + 1; } } #ifdef CONFIG_PPC64 - /* If not a mac, try to figure out if it's an IBM pSeries or any other - * PAPR compliant platform. We assume it is if : - * - /device_type is "chrp" (please, do NOT use that for future - * non-IBM designs ! - * - it has /rtas - */ - len = prom_getprop(_prom->root, "model", - compat, sizeof(compat)-1); - if (len <= 0) - return PLATFORM_GENERIC; - compat[len] = 0; - if (strcmp(compat, "chrp")) - return PLATFORM_GENERIC; - /* Default to pSeries. We need to know if we are running LPAR */ rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); - if (!PHANDLE_VALID(rtas)) - return PLATFORM_GENERIC; - x = prom_getproplen(rtas, "ibm,hypertas-functions"); - if (x != PROM_ERROR) { - prom_printf("Hypertas detected, assuming LPAR !\n"); - return PLATFORM_PSERIES_LPAR; + if (PHANDLE_VALID(rtas)) { + int x = prom_getproplen(rtas, "ibm,hypertas-functions"); + if (x != PROM_ERROR) { + prom_printf("Hypertas detected, assuming LPAR !\n"); + return PLATFORM_PSERIES_LPAR; + } } return PLATFORM_PSERIES; #else - return PLATFORM_GENERIC; + return PLATFORM_CHRP; #endif } @@ -2055,6 +2029,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, { struct prom_t *_prom; unsigned long hdr; + u32 getprop_rval; unsigned long offset = reloc_offset(); #ifdef CONFIG_PPC32 @@ -2085,12 +2060,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, */ prom_init_stdout(); - /* - * Get default machine type. At this point, we do not differentiate - * between pSeries SMP and pSeries LPAR - */ - RELOC(of_platform) = prom_find_machine_type(); - /* Bail if this is a kdump kernel. */ if (PHYSICAL_START > 0) prom_panic("Error: You can't boot a kdump kernel from OF!\n"); @@ -2100,6 +2069,15 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, */ prom_check_initrd(r3, r4); + /* + * Get default machine type. At this point, we do not differentiate + * between pSeries SMP and pSeries LPAR + */ + RELOC(of_platform) = prom_find_machine_type(); + getprop_rval = RELOC(of_platform); + prom_setprop(_prom->chosen, "/chosen", "linux,platform", + &getprop_rval, sizeof(getprop_rval)); + #ifdef CONFIG_PPC_PSERIES /* * On pSeries, inform the firmware about our capabilities diff --git a/trunk/arch/powerpc/kernel/rtas-proc.c b/trunk/arch/powerpc/kernel/rtas-proc.c index 456286cf1d14..1f03fb28cc0a 100644 --- a/trunk/arch/powerpc/kernel/rtas-proc.c +++ b/trunk/arch/powerpc/kernel/rtas-proc.c @@ -257,7 +257,7 @@ static int __init proc_rtas_init(void) { struct proc_dir_entry *entry; - if (!machine_is(pseries)) + if (_machine != PLATFORM_PSERIES && _machine != PLATFORM_PSERIES_LPAR) return 1; rtas_node = of_find_node_by_name(NULL, "rtas"); diff --git a/trunk/arch/powerpc/kernel/rtas.c b/trunk/arch/powerpc/kernel/rtas.c index 06636c927a7e..b5b2add7ad1e 100644 --- a/trunk/arch/powerpc/kernel/rtas.c +++ b/trunk/arch/powerpc/kernel/rtas.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -33,7 +32,6 @@ #include #include #include -#include struct rtas_t rtas = { .lock = SPIN_LOCK_UNLOCKED @@ -593,7 +591,7 @@ static void rtas_percpu_suspend_me(void *info) data->waiting = 0; data->args->args[data->args->nargs] = rtas_call(ibm_suspend_me_token, 0, 1, NULL); - for_each_possible_cpu(i) + for_each_cpu(i) plpar_hcall_norets(H_PROD,i); } else { data->waiting = -EBUSY; @@ -626,7 +624,7 @@ static int rtas_ibm_suspend_me(struct rtas_args *args) /* Prod each CPU. This won't hurt, and will wake * anyone we successfully put to sleep with H_Join */ - for_each_possible_cpu(i) + for_each_cpu(i) plpar_hcall_norets(H_PROD, i); return data.waiting; @@ -769,7 +767,7 @@ void __init rtas_initialize(void) * the stop-self token if any */ #ifdef CONFIG_PPC64 - if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR)) { + if (_machine == PLATFORM_PSERIES_LPAR) { rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX); ibm_suspend_me_token = rtas_token("ibm,suspend-me"); } diff --git a/trunk/arch/powerpc/kernel/setup-common.c b/trunk/arch/powerpc/kernel/setup-common.c index c607f3b9ca17..c1d62bf11f29 100644 --- a/trunk/arch/powerpc/kernel/setup-common.c +++ b/trunk/arch/powerpc/kernel/setup-common.c @@ -9,9 +9,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ - -#undef DEBUG - #include #include #include @@ -44,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -60,6 +56,8 @@ #include "setup.h" +#undef DEBUG + #ifdef DEBUG #include #define DBG(fmt...) udbg_printf(fmt) @@ -67,12 +65,10 @@ #define DBG(fmt...) #endif -/* The main machine-dep calls structure - */ -struct machdep_calls ppc_md; -EXPORT_SYMBOL(ppc_md); -struct machdep_calls *machine_id; -EXPORT_SYMBOL(machine_id); +#ifdef CONFIG_PPC_MULTIPLATFORM +int _machine = 0; +EXPORT_SYMBOL(_machine); +#endif unsigned long klimit = (unsigned long) _end; @@ -172,8 +168,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); #endif /* CONFIG_SMP && CONFIG_PPC32 */ seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq); - if (ppc_md.name) - seq_printf(m, "platform\t: %s\n", ppc_md.name); + if (ppc_md.show_cpuinfo != NULL) ppc_md.show_cpuinfo(m); @@ -357,13 +352,12 @@ void __init check_for_initrd(void) * must be called before using this. * * While we're here, we may as well set the "physical" cpu ids in the paca. - * - * NOTE: This must match the parsing done in early_init_dt_scan_cpus. */ void __init smp_setup_cpu_maps(void) { struct device_node *dn = NULL; int cpu = 0; + int swap_cpuid = 0; while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { int *intserv; @@ -382,17 +376,30 @@ void __init smp_setup_cpu_maps(void) for (j = 0; j < nthreads && cpu < NR_CPUS; j++) { cpu_set(cpu, cpu_present_map); set_hard_smp_processor_id(cpu, intserv[j]); + + if (intserv[j] == boot_cpuid_phys) + swap_cpuid = cpu; cpu_set(cpu, cpu_possible_map); cpu++; } } + /* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that + * boot cpu is logical 0. + */ + if (boot_cpuid_phys != get_hard_smp_processor_id(0)) { + u32 tmp; + tmp = get_hard_smp_processor_id(0); + set_hard_smp_processor_id(0, boot_cpuid_phys); + set_hard_smp_processor_id(swap_cpuid, tmp); + } + #ifdef CONFIG_PPC64 /* * On pSeries LPAR, we need to know how many cpus * could possibly be added to this partition. */ - if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) && + if (_machine == PLATFORM_PSERIES_LPAR && (dn = of_find_node_by_path("/rtas"))) { int num_addr_cell, num_size_cell, maxcpus; unsigned int *ireg; @@ -431,7 +438,7 @@ void __init smp_setup_cpu_maps(void) /* * Do the sibling map; assume only two threads per processor. */ - for_each_possible_cpu(cpu) { + for_each_cpu(cpu) { cpu_set(cpu, cpu_sibling_map[cpu]); if (cpu_has_feature(CPU_FTR_SMT)) cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); @@ -461,34 +468,3 @@ static int __init early_xmon(char *p) } early_param("xmon", early_xmon); #endif - -void probe_machine(void) -{ - extern struct machdep_calls __machine_desc_start; - extern struct machdep_calls __machine_desc_end; - - /* - * Iterate all ppc_md structures until we find the proper - * one for the current machine type - */ - DBG("Probing machine type ...\n"); - - for (machine_id = &__machine_desc_start; - machine_id < &__machine_desc_end; - machine_id++) { - DBG(" %s ...", machine_id->name); - memcpy(&ppc_md, machine_id, sizeof(struct machdep_calls)); - if (ppc_md.probe()) { - DBG(" match !\n"); - break; - } - DBG("\n"); - } - /* What can we do if we didn't find ? */ - if (machine_id >= &__machine_desc_end) { - DBG("No suitable machine found !\n"); - for (;;); - } - - printk(KERN_INFO "Using %s machine description\n", ppc_md.name); -} diff --git a/trunk/arch/powerpc/kernel/setup_32.c b/trunk/arch/powerpc/kernel/setup_32.c index a72bf5dceeee..dc2770df25b3 100644 --- a/trunk/arch/powerpc/kernel/setup_32.c +++ b/trunk/arch/powerpc/kernel/setup_32.c @@ -53,6 +53,9 @@ extern void platform_init(void); extern void bootx_init(unsigned long r4, unsigned long phys); +extern void ppc6xx_idle(void); +extern void power4_idle(void); + boot_infos_t *boot_infos; struct ide_machdep_calls ppc_ide_md; @@ -67,6 +70,10 @@ unsigned int DMA_MODE_WRITE; int have_of = 1; #ifdef CONFIG_PPC_MULTIPLATFORM +extern void prep_init(void); +extern void pmac_init(void); +extern void chrp_init(void); + dev_t boot_dev; #endif /* CONFIG_PPC_MULTIPLATFORM */ @@ -78,6 +85,9 @@ unsigned long SYSRQ_KEY = 0x54; unsigned long vgacon_remap_base; #endif +struct machdep_calls ppc_md; +EXPORT_SYMBOL(ppc_md); + /* * These are used in binfmt_elf.c to put aux entries on the stack * for each elf executable being started. @@ -101,7 +111,7 @@ unsigned long __init early_init(unsigned long dt_ptr) /* First zero the BSS -- use memset_io, some platforms don't have * caches on yet */ - memset_io((void __iomem *)PTRRELOC(&__bss_start), 0, _end - __bss_start); + memset_io(PTRRELOC(&__bss_start), 0, _end - __bss_start); /* * Identify the CPU type and fix up code sections @@ -113,6 +123,48 @@ unsigned long __init early_init(unsigned long dt_ptr) return KERNELBASE + offset; } +#ifdef CONFIG_PPC_MULTIPLATFORM +/* + * The PPC_MULTIPLATFORM version of platform_init... + */ +void __init platform_init(void) +{ + /* if we didn't get any bootinfo telling us what we are... */ + if (_machine == 0) { + /* prep boot loader tells us if we're prep or not */ + if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) ) + _machine = _MACH_prep; + } + +#ifdef CONFIG_PPC_PREP + /* not much more to do here, if prep */ + if (_machine == _MACH_prep) { + prep_init(); + return; + } +#endif + +#ifdef CONFIG_ADB + if (strstr(cmd_line, "adb_sync")) { + extern int __adb_probe_sync; + __adb_probe_sync = 1; + } +#endif /* CONFIG_ADB */ + + switch (_machine) { +#ifdef CONFIG_PPC_PMAC + case _MACH_Pmac: + pmac_init(); + break; +#endif +#ifdef CONFIG_PPC_CHRP + case _MACH_chrp: + chrp_init(); + break; +#endif + } +} +#endif /* * Find out what kind of machine we're on and save any data we need @@ -138,17 +190,11 @@ void __init machine_init(unsigned long dt_ptr, unsigned long phys) strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line)); #endif /* CONFIG_CMDLINE */ -#ifdef CONFIG_PPC_MULTIPLATFORM - probe_machine(); -#else - /* Base init based on machine type. Obsoloete, please kill ! */ + /* Base init based on machine type */ platform_init(); -#endif #ifdef CONFIG_6xx - if (cpu_has_feature(CPU_FTR_CAN_DOZE) || - cpu_has_feature(CPU_FTR_CAN_NAP)) - ppc_md.power_save = ppc6xx_idle; + ppc_md.power_save = ppc6xx_idle; #endif if (ppc_md.progress) @@ -226,7 +272,7 @@ int __init ppc_init(void) if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); /* register CPU devices */ - for_each_possible_cpu(i) + for_each_cpu(i) register_cpu(&cpu_devices[i], i, NULL); /* call platform init */ @@ -306,6 +352,12 @@ void __init setup_arch(char **cmdline_p) do_init_bootmem(); if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); +#ifdef CONFIG_PPC_OCP + /* Initialize OCP device list */ + ocp_early_init(); + if ( ppc_md.progress ) ppc_md.progress("ocp: exit", 0x3eab); +#endif + #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; #endif @@ -314,4 +366,7 @@ void __init setup_arch(char **cmdline_p) if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); paging_init(); + + /* this is for modules since _machine can be a define -- Cort */ + ppc_md.ppc_machine = _machine; } diff --git a/trunk/arch/powerpc/kernel/setup_64.c b/trunk/arch/powerpc/kernel/setup_64.c index 59aa92cd6fa4..e20c1fae3423 100644 --- a/trunk/arch/powerpc/kernel/setup_64.c +++ b/trunk/arch/powerpc/kernel/setup_64.c @@ -73,6 +73,7 @@ int have_of = 1; int boot_cpuid = 0; +int boot_cpuid_phys = 0; dev_t boot_dev; u64 ppc64_pft_size; @@ -95,6 +96,11 @@ int dcache_bsize; int icache_bsize; int ucache_bsize; +/* The main machine-dep calls structure + */ +struct machdep_calls ppc_md; +EXPORT_SYMBOL(ppc_md); + #ifdef CONFIG_MAGIC_SYSRQ unsigned long SYSRQ_KEY; #endif /* CONFIG_MAGIC_SYSRQ */ @@ -155,6 +161,32 @@ early_param("smt-enabled", early_smt_enabled); #define check_smt_enabled() #endif /* CONFIG_SMP */ +extern struct machdep_calls pSeries_md; +extern struct machdep_calls pmac_md; +extern struct machdep_calls maple_md; +extern struct machdep_calls cell_md; +extern struct machdep_calls iseries_md; + +/* Ultimately, stuff them in an elf section like initcalls... */ +static struct machdep_calls __initdata *machines[] = { +#ifdef CONFIG_PPC_PSERIES + &pSeries_md, +#endif /* CONFIG_PPC_PSERIES */ +#ifdef CONFIG_PPC_PMAC + &pmac_md, +#endif /* CONFIG_PPC_PMAC */ +#ifdef CONFIG_PPC_MAPLE + &maple_md, +#endif /* CONFIG_PPC_MAPLE */ +#ifdef CONFIG_PPC_CELL + &cell_md, +#endif +#ifdef CONFIG_PPC_ISERIES + &iseries_md, +#endif + NULL +}; + /* * Early initialization entry point. This is called by head.S * with MMU translation disabled. We rely on the "feature" of @@ -176,10 +208,13 @@ early_param("smt-enabled", early_smt_enabled); void __init early_setup(unsigned long dt_ptr) { + struct paca_struct *lpaca = get_paca(); + static struct machdep_calls **mach; + /* Enable early debugging if any specified (see udbg.h) */ udbg_early_init(); - DBG(" -> early_setup(), dt_ptr: 0x%lx\n", dt_ptr); + DBG(" -> early_setup()\n"); /* * Do early initializations using the flattened device @@ -188,16 +223,22 @@ void __init early_setup(unsigned long dt_ptr) */ early_init_devtree(__va(dt_ptr)); - /* Now we know the logical id of our boot cpu, setup the paca. */ - setup_boot_paca(); - - /* Fix up paca fields required for the boot cpu */ - get_paca()->cpu_start = 1; - get_paca()->stab_real = __pa((u64)&initial_stab); - get_paca()->stab_addr = (u64)&initial_stab; + /* + * Iterate all ppc_md structures until we find the proper + * one for the current machine type + */ + DBG("Probing machine type for platform %x...\n", _machine); - /* Probe the machine type */ - probe_machine(); + for (mach = machines; *mach; mach++) { + if ((*mach)->probe(_machine)) + break; + } + /* What can we do if we didn't find ? */ + if (*mach == NULL) { + DBG("No suitable machine found !\n"); + for (;;); + } + ppc_md = **mach; #ifdef CONFIG_CRASH_DUMP kdump_setup(); @@ -219,7 +260,7 @@ void __init early_setup(unsigned long dt_ptr) if (cpu_has_feature(CPU_FTR_SLB)) slb_initialize(); else - stab_initialize(get_paca()->stab_real); + stab_initialize(lpaca->stab_real); } DBG(" <- early_setup()\n"); @@ -299,7 +340,7 @@ static void __init initialize_cache_info(void) const char *dc, *ic; /* Then read cache informations */ - if (machine_is(powermac)) { + if (_machine == PLATFORM_POWERMAC) { dc = "d-cache-block-size"; ic = "i-cache-block-size"; } else { @@ -443,6 +484,7 @@ void __init setup_system(void) printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size); printk("ppc64_interrupt_controller = 0x%ld\n", ppc64_interrupt_controller); + printk("platform = 0x%x\n", _machine); printk("physicalMemorySize = 0x%lx\n", lmb_phys_mem_size()); printk("ppc64_caches.dcache_line_size = 0x%x\n", ppc64_caches.dline_size); @@ -474,7 +516,7 @@ static void __init irqstack_early_init(void) * interrupt stacks must be under 256MB, we cannot afford to take * SLB misses on them. */ - for_each_possible_cpu(i) { + for_each_cpu(i) { softirq_ctx[i] = (struct thread_info *) __va(lmb_alloc_base(THREAD_SIZE, THREAD_SIZE, 0x10000000)); @@ -507,7 +549,7 @@ static void __init emergency_stack_init(void) */ limit = min(0x10000000UL, lmb.rmo_size); - for_each_possible_cpu(i) + for_each_cpu(i) paca[i].emergency_sp = __va(lmb_alloc_base(HW_PAGE_SIZE, 128, limit)) + HW_PAGE_SIZE; } @@ -560,6 +602,12 @@ void __init setup_arch(char **cmdline_p) ppc_md.setup_arch(); + /* Use the default idle loop if the platform hasn't provided one. */ + if (NULL == ppc_md.idle_loop) { + ppc_md.idle_loop = default_idle; + printk(KERN_INFO "Using default idle loop\n"); + } + paging_init(); ppc64_boot_msg(0x15, "Setup Done"); } @@ -624,7 +672,7 @@ void __init setup_per_cpu_areas(void) size = PERCPU_ENOUGH_ROOM; #endif - for_each_possible_cpu(i) { + for_each_cpu(i) { ptr = alloc_bootmem_node(NODE_DATA(cpu_to_node(i)), size); if (!ptr) panic("Cannot allocate cpu data for CPU %d\n", i); diff --git a/trunk/arch/powerpc/kernel/signal_32.c b/trunk/arch/powerpc/kernel/signal_32.c index 01e3c08cb550..d7a4e814974d 100644 --- a/trunk/arch/powerpc/kernel/signal_32.c +++ b/trunk/arch/powerpc/kernel/signal_32.c @@ -42,7 +42,6 @@ #include #include -#include #include #include #ifdef CONFIG_PPC64 diff --git a/trunk/arch/powerpc/kernel/signal_64.c b/trunk/arch/powerpc/kernel/signal_64.c index 27f65b95184d..47f910380a6a 100644 --- a/trunk/arch/powerpc/kernel/signal_64.c +++ b/trunk/arch/powerpc/kernel/signal_64.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #define DEBUG_SIG 0 @@ -212,7 +211,7 @@ static inline void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs /* Default to using normal stack */ newsp = regs->gpr[1]; - if ((ka->sa.sa_flags & SA_ONSTACK) && current->sas_ss_size) { + if (ka->sa.sa_flags & SA_ONSTACK) { if (! on_sig_stack(regs->gpr[1])) newsp = (current->sas_ss_sp + current->sas_ss_size); } diff --git a/trunk/arch/powerpc/kernel/smp.c b/trunk/arch/powerpc/kernel/smp.c index 530f7dba0bd2..805eaedbc308 100644 --- a/trunk/arch/powerpc/kernel/smp.c +++ b/trunk/arch/powerpc/kernel/smp.c @@ -362,7 +362,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) smp_space_timers(max_cpus); - for_each_possible_cpu(cpu) + for_each_cpu(cpu) if (cpu != boot_cpuid) smp_create_idle(cpu); } diff --git a/trunk/arch/powerpc/kernel/syscalls.c b/trunk/arch/powerpc/kernel/syscalls.c index 9b69d99a9103..ad895c99813b 100644 --- a/trunk/arch/powerpc/kernel/syscalls.c +++ b/trunk/arch/powerpc/kernel/syscalls.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/powerpc/kernel/sysfs.c b/trunk/arch/powerpc/kernel/sysfs.c index 73560ef6f802..0f0c3a9ae2e5 100644 --- a/trunk/arch/powerpc/kernel/sysfs.c +++ b/trunk/arch/powerpc/kernel/sysfs.c @@ -65,20 +65,20 @@ static int __init smt_setup(void) unsigned int cpu; if (!cpu_has_feature(CPU_FTR_SMT)) - return -ENODEV; + return 1; options = find_path_device("/options"); if (!options) - return -ENODEV; + return 1; val = (unsigned int *)get_property(options, "ibm,smt-snooze-delay", NULL); if (!smt_snooze_cmdline && val) { - for_each_possible_cpu(cpu) + for_each_cpu(cpu) per_cpu(smt_snooze_delay, cpu) = *val; } - return 0; + return 1; } __initcall(smt_setup); @@ -93,7 +93,7 @@ static int __init setup_smt_snooze_delay(char *str) smt_snooze_cmdline = 1; if (get_option(&str, &snooze)) { - for_each_possible_cpu(cpu) + for_each_cpu(cpu) per_cpu(smt_snooze_delay, cpu) = snooze; } @@ -347,7 +347,7 @@ static int __init topology_init(void) register_cpu_notifier(&sysfs_cpu_nb); - for_each_possible_cpu(cpu) { + for_each_cpu(cpu) { struct cpu *c = &per_cpu(cpu_devices, cpu); #ifdef CONFIG_NUMA diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c index 24e3ad756de0..4a27218a086c 100644 --- a/trunk/arch/powerpc/kernel/time.c +++ b/trunk/arch/powerpc/kernel/time.c @@ -261,7 +261,7 @@ void snapshot_timebases(void) if (!cpu_has_feature(CPU_FTR_PURR)) return; - for_each_possible_cpu(cpu) + for_each_cpu(cpu) spin_lock_init(&per_cpu(cpu_purr_data, cpu).lock); on_each_cpu(snapshot_tb_and_purr, NULL, 0, 1); } @@ -751,7 +751,7 @@ void __init smp_space_timers(unsigned int max_cpus) * systems works better if the two threads' timebase interrupts * are staggered by half a jiffy with respect to each other. */ - for_each_possible_cpu(i) { + for_each_cpu(i) { if (i == boot_cpuid) continue; if (i == (boot_cpuid ^ 1)) diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c index 4cbde211eb69..9763faab6739 100644 --- a/trunk/arch/powerpc/kernel/traps.c +++ b/trunk/arch/powerpc/kernel/traps.c @@ -97,6 +97,7 @@ static DEFINE_SPINLOCK(die_lock); int die(const char *str, struct pt_regs *regs, long err) { static int die_counter, crash_dump_start = 0; + int nl = 0; if (debugger(regs)) return 1; @@ -105,7 +106,7 @@ int die(const char *str, struct pt_regs *regs, long err) spin_lock_irq(&die_lock); bust_spinlocks(1); #ifdef CONFIG_PMAC_BACKLIGHT - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { set_backlight_enable(1); set_backlight_level(BACKLIGHT_MAX); } @@ -113,18 +114,46 @@ int die(const char *str, struct pt_regs *regs, long err) printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); #ifdef CONFIG_PREEMPT printk("PREEMPT "); + nl = 1; #endif #ifdef CONFIG_SMP printk("SMP NR_CPUS=%d ", NR_CPUS); + nl = 1; #endif #ifdef CONFIG_DEBUG_PAGEALLOC printk("DEBUG_PAGEALLOC "); + nl = 1; #endif #ifdef CONFIG_NUMA printk("NUMA "); + nl = 1; #endif - printk("%s\n", ppc_md.name ? "" : ppc_md.name); - +#ifdef CONFIG_PPC64 + switch (_machine) { + case PLATFORM_PSERIES: + printk("PSERIES "); + nl = 1; + break; + case PLATFORM_PSERIES_LPAR: + printk("PSERIES LPAR "); + nl = 1; + break; + case PLATFORM_ISERIES_LPAR: + printk("ISERIES LPAR "); + nl = 1; + break; + case PLATFORM_POWERMAC: + printk("POWERMAC "); + nl = 1; + break; + case PLATFORM_CELL: + printk("CELL "); + nl = 1; + break; + } +#endif + if (nl) + printk("\n"); print_modules(); show_regs(regs); bust_spinlocks(0); diff --git a/trunk/arch/powerpc/kernel/vdso.c b/trunk/arch/powerpc/kernel/vdso.c index 573afb68d69e..ec8370368423 100644 --- a/trunk/arch/powerpc/kernel/vdso.c +++ b/trunk/arch/powerpc/kernel/vdso.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -668,13 +667,7 @@ void __init vdso_init(void) vdso_data->version.major = SYSTEMCFG_MAJOR; vdso_data->version.minor = SYSTEMCFG_MINOR; vdso_data->processor = mfspr(SPRN_PVR); - /* - * Fake the old platform number for pSeries and iSeries and add - * in LPAR bit if necessary - */ - vdso_data->platform = machine_is(iseries) ? 0x200 : 0x100; - if (firmware_has_feature(FW_FEATURE_LPAR)) - vdso_data->platform |= 1; + vdso_data->platform = _machine; vdso_data->physicalMemorySize = lmb_phys_mem_size(); vdso_data->dcache_size = ppc64_caches.dsize; vdso_data->dcache_line_size = ppc64_caches.dline_size; diff --git a/trunk/arch/powerpc/kernel/vmlinux.lds.S b/trunk/arch/powerpc/kernel/vmlinux.lds.S index fe79c2584cb0..7fa7b15fd8e6 100644 --- a/trunk/arch/powerpc/kernel/vmlinux.lds.S +++ b/trunk/arch/powerpc/kernel/vmlinux.lds.S @@ -1,11 +1,9 @@ #include #ifdef CONFIG_PPC64 #include -#define PROVIDE32(x) PROVIDE(__unused__##x) #else #define PAGE_SIZE 4096 #define KERNELBASE CONFIG_KERNEL_START -#define PROVIDE32(x) PROVIDE(x) #endif #include @@ -20,42 +18,43 @@ jiffies = jiffies_64 + 4; #endif SECTIONS { - /* Sections to be discarded. */ - /DISCARD/ : { - *(.exitcall.exit) - *(.exit.data) - } - - . = KERNELBASE; - -/* - * Text, read only data and other permanent read-only sections - */ - - /* Text and gots */ - .text : { - *(.text .text.*) - SCHED_TEXT - LOCK_TEXT - KPROBES_TEXT - *(.fixup) - + /* Sections to be discarded. */ + /DISCARD/ : { + *(.exitcall.exit) + *(.exit.data) + } + + . = KERNELBASE; + + /* Read-only sections, merged into text segment: */ + .text : { + *(.text .text.*) + SCHED_TEXT + LOCK_TEXT + KPROBES_TEXT + *(.fixup) #ifdef CONFIG_PPC32 - *(.got1) - __got2_start = .; - *(.got2) - __got2_end = .; -#endif /* CONFIG_PPC32 */ - - . = ALIGN(PAGE_SIZE); - _etext = .; - PROVIDE32 (etext = .); - } + *(.got1) + __got2_start = .; + *(.got2) + __got2_end = .; +#else + . = ALIGN(PAGE_SIZE); + _etext = .; +#endif + } +#ifdef CONFIG_PPC32 + _etext = .; + PROVIDE (etext = .); - /* Read-only data */ - RODATA + RODATA + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + .fixup : { *(.fixup) } +#endif - /* Exception & bug tables */ __ex_table : { __start___ex_table = .; *(__ex_table) @@ -68,172 +67,192 @@ SECTIONS __stop___bug_table = .; } -/* - * Init sections discarded at runtime - */ - . = ALIGN(PAGE_SIZE); - __init_begin = .; - - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } - - /* .exit.text is discarded at runtime, not link time, - * to deal with references from __bug_table - */ - .exit.text : { *(.exit.text) } - - .init.data : { - *(.init.data); - __vtop_table_begin = .; - *(.vtop_fixup); - __vtop_table_end = .; - __ptov_table_begin = .; - *(.ptov_fixup); - __ptov_table_end = .; - } - - . = ALIGN(16); - .init.setup : { - __setup_start = .; - *(.init.setup) - __setup_end = .; - } - - .initcall.init : { - __initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - __initcall_end = .; - } - - .con_initcall.init : { - __con_initcall_start = .; - *(.con_initcall.init) - __con_initcall_end = .; - } - - SECURITY_INIT - - . = ALIGN(8); +#ifdef CONFIG_PPC64 __ftr_fixup : { __start___ftr_fixup = .; *(__ftr_fixup) __stop___ftr_fixup = .; } - . = ALIGN(PAGE_SIZE); - .init.ramfs : { - __initramfs_start = .; - *(.init.ramfs) - __initramfs_end = .; - } + RODATA +#endif #ifdef CONFIG_PPC32 - . = ALIGN(32); -#else - . = ALIGN(128); + /* Read-write section, merged into data segment: */ + . = ALIGN(PAGE_SIZE); + _sdata = .; + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.got.plt) *(.got) + *(.dynamic) + CONSTRUCTORS + } + + . = ALIGN(PAGE_SIZE); + __nosave_begin = .; + .data_nosave : { *(.data.nosave) } + . = ALIGN(PAGE_SIZE); + __nosave_end = .; + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + _edata = .; + PROVIDE (edata = .); + + . = ALIGN(8192); + .data.init_task : { *(.data.init_task) } #endif - .data.percpu : { - __per_cpu_start = .; - *(.data.percpu) - __per_cpu_end = .; - } - . = ALIGN(8); - .machine.desc : { - __machine_desc_start = . ; - *(.machine.desc) - __machine_desc_end = . ; - } - - /* freed after init ends here */ - . = ALIGN(PAGE_SIZE); - __init_end = .; - -/* - * And now the various read/write data - */ - - . = ALIGN(PAGE_SIZE); - _sdata = .; + /* will be freed after init */ + . = ALIGN(PAGE_SIZE); + __init_begin = .; + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } +#ifdef CONFIG_PPC32 + /* .exit.text is discarded at runtime, not link time, + to deal with references from __bug_table */ + .exit.text : { *(.exit.text) } +#endif + .init.data : { + *(.init.data); + __vtop_table_begin = .; + *(.vtop_fixup); + __vtop_table_end = .; + __ptov_table_begin = .; + *(.ptov_fixup); + __ptov_table_end = .; + } + + . = ALIGN(16); + .init.setup : { + __setup_start = .; + *(.init.setup) + __setup_end = .; + } + + .initcall.init : { + __initcall_start = .; + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + __initcall_end = .; + } + + .con_initcall.init : { + __con_initcall_start = .; + *(.con_initcall.init) + __con_initcall_end = .; + } + + SECURITY_INIT #ifdef CONFIG_PPC32 - .data : - { - *(.data) - *(.sdata) - *(.got.plt) *(.got) - } + __start___ftr_fixup = .; + __ftr_fixup : { *(__ftr_fixup) } + __stop___ftr_fixup = .; #else - .data : { - *(.data .data.rel* .toc1) - *(.branch_lt) - } - - .opd : { - *(.opd) - } - - .got : { - __toc_start = .; - *(.got) - *(.toc) - } + . = ALIGN(PAGE_SIZE); + .init.ramfs : { + __initramfs_start = .; + *(.init.ramfs) + __initramfs_end = .; + } #endif - . = ALIGN(PAGE_SIZE); - _edata = .; - PROVIDE32 (edata = .); - - /* The initial task and kernel stack */ #ifdef CONFIG_PPC32 - . = ALIGN(8192); -#else - . = ALIGN(16384); + . = ALIGN(32); #endif - .data.init_task : { - *(.data.init_task) - } + .data.percpu : { + __per_cpu_start = .; + *(.data.percpu) + __per_cpu_end = .; + } - . = ALIGN(PAGE_SIZE); - .data.page_aligned : { - *(.data.page_aligned) - } + . = ALIGN(PAGE_SIZE); +#ifdef CONFIG_PPC64 + . = ALIGN(16384); + __init_end = .; + /* freed after init ends here */ + + /* Read/write sections */ + . = ALIGN(PAGE_SIZE); + . = ALIGN(16384); + _sdata = .; + /* The initial task and kernel stack */ + .data.init_task : { + *(.data.init_task) + } + + . = ALIGN(PAGE_SIZE); + .data.page_aligned : { + *(.data.page_aligned) + } + + .data.cacheline_aligned : { + *(.data.cacheline_aligned) + } + + .data : { + *(.data .data.rel* .toc1) + *(.branch_lt) + } + + .opd : { + *(.opd) + } + + .got : { + __toc_start = .; + *(.got) + *(.toc) + . = ALIGN(PAGE_SIZE); + _edata = .; + } + + . = ALIGN(PAGE_SIZE); +#else + __initramfs_start = .; + .init.ramfs : { + *(.init.ramfs) + } + __initramfs_end = .; - .data.cacheline_aligned : { - *(.data.cacheline_aligned) - } + . = ALIGN(4096); + __init_end = .; - . = ALIGN(PAGE_SIZE); - __data_nosave : { - __nosave_begin = .; - *(.data.nosave) - . = ALIGN(PAGE_SIZE); - __nosave_end = .; - } + . = ALIGN(4096); + _sextratext = .; + _eextratext = .; -/* - * And finally the bss - */ - - .bss : { - __bss_start = .; - *(.sbss) *(.scommon) - *(.dynbss) - *(.bss) - *(COMMON) - __bss_stop = .; - } + __bss_start = .; +#endif + + .bss : { + __bss_start = .; + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + __bss_stop = .; + } - . = ALIGN(PAGE_SIZE); - _end = . ; - PROVIDE32 (end = .); +#ifdef CONFIG_PPC64 + . = ALIGN(PAGE_SIZE); +#endif + _end = . ; +#ifdef CONFIG_PPC32 + PROVIDE (end = .); +#endif } diff --git a/trunk/arch/powerpc/lib/sstep.c b/trunk/arch/powerpc/lib/sstep.c index c251d9936612..666c2aa55016 100644 --- a/trunk/arch/powerpc/lib/sstep.c +++ b/trunk/arch/powerpc/lib/sstep.c @@ -18,7 +18,7 @@ extern char system_call_common[]; #ifdef CONFIG_PPC64 /* Bits in SRR1 that are copied from MSR */ -#define MSR_MASK 0xffffffff87c0ffffUL +#define MSR_MASK 0xffffffff87c0ffff #else #define MSR_MASK 0x87c0ffff #endif diff --git a/trunk/arch/powerpc/mm/fault.c b/trunk/arch/powerpc/mm/fault.c index 5aea0909a5ec..ec4adcb4bc28 100644 --- a/trunk/arch/powerpc/mm/fault.c +++ b/trunk/arch/powerpc/mm/fault.c @@ -267,29 +267,25 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, #endif #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) pte_t *ptep; - pmd_t *pmdp; /* Since 4xx/Book-E supports per-page execute permission, * we lazily flush dcache to icache. */ ptep = NULL; - if (get_pteptr(mm, address, &ptep, &pmdp)) { - spinlock_t *ptl = pte_lockptr(mm, pmdp); - spin_lock(ptl); - if (pte_present(*ptep)) { - struct page *page = pte_page(*ptep); - - if (!test_bit(PG_arch_1, &page->flags)) { - flush_dcache_icache_page(page); - set_bit(PG_arch_1, &page->flags); - } - pte_update(ptep, 0, _PAGE_HWEXEC); - _tlbie(address); - pte_unmap_unlock(ptep, ptl); - up_read(&mm->mmap_sem); - return 0; + if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) { + struct page *page = pte_page(*ptep); + + if (! test_bit(PG_arch_1, &page->flags)) { + flush_dcache_icache_page(page); + set_bit(PG_arch_1, &page->flags); } - pte_unmap_unlock(ptep, ptl); + pte_update(ptep, 0, _PAGE_HWEXEC); + _tlbie(address); + pte_unmap(ptep); + up_read(&mm->mmap_sem); + return 0; } + if (ptep != NULL) + pte_unmap(ptep); #endif /* a write */ } else if (is_write) { diff --git a/trunk/arch/powerpc/mm/hash_utils_64.c b/trunk/arch/powerpc/mm/hash_utils_64.c index c006d9039633..89b35c181314 100644 --- a/trunk/arch/powerpc/mm/hash_utils_64.c +++ b/trunk/arch/powerpc/mm/hash_utils_64.c @@ -167,7 +167,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, * normal insert callback here. */ #ifdef CONFIG_PPC_ISERIES - if (machine_is(iseries)) + if (_machine == PLATFORM_ISERIES_LPAR) ret = iSeries_hpte_insert(hpteg, va, paddr, tmp_mode, @@ -176,7 +176,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, else #endif #ifdef CONFIG_PPC_PSERIES - if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR)) + if (_machine & PLATFORM_LPAR) ret = pSeries_lpar_hpte_insert(hpteg, va, paddr, tmp_mode, @@ -295,7 +295,8 @@ static void __init htab_init_page_sizes(void) * Not in the device-tree, let's fallback on known size * list for 16M capable GP & GR */ - if (cpu_has_feature(CPU_FTR_16M_PAGE) && !machine_is(iseries)) + if ((_machine != PLATFORM_ISERIES_LPAR) && + cpu_has_feature(CPU_FTR_16M_PAGE)) memcpy(mmu_psize_defs, mmu_psize_defaults_gp, sizeof(mmu_psize_defaults_gp)); found: diff --git a/trunk/arch/powerpc/mm/mem.c b/trunk/arch/powerpc/mm/mem.c index 741dd8802d49..5e435a9c3431 100644 --- a/trunk/arch/powerpc/mm/mem.c +++ b/trunk/arch/powerpc/mm/mem.c @@ -342,7 +342,7 @@ void __init mem_init(void) #ifdef CONFIG_NEED_MULTIPLE_NODES for_each_online_node(nid) { if (NODE_DATA(nid)->node_spanned_pages != 0) { - printk("freeing bootmem node %d\n", nid); + printk("freeing bootmem node %x\n", nid); totalram_pages += free_all_bootmem_node(NODE_DATA(nid)); } diff --git a/trunk/arch/powerpc/mm/numa.c b/trunk/arch/powerpc/mm/numa.c index 0a335f34974c..e89b22aa539e 100644 --- a/trunk/arch/powerpc/mm/numa.c +++ b/trunk/arch/powerpc/mm/numa.c @@ -756,7 +756,6 @@ int hot_add_scn_to_nid(unsigned long scn_addr) struct device_node *memory = NULL; nodemask_t nodes; int default_nid = any_online_node(NODE_MASK_ALL); - int nid; if (!numa_enabled || (min_common_depth < 0)) return default_nid; @@ -791,7 +790,6 @@ int hot_add_scn_to_nid(unsigned long scn_addr) goto ha_new_range; } BUG(); /* section address should be found above */ - return 0; /* Temporary code to ensure that returned node is not empty */ got_nid: diff --git a/trunk/arch/powerpc/mm/pgtable_32.c b/trunk/arch/powerpc/mm/pgtable_32.c index 90628601fac7..d296eb6b4545 100644 --- a/trunk/arch/powerpc/mm/pgtable_32.c +++ b/trunk/arch/powerpc/mm/pgtable_32.c @@ -372,7 +372,7 @@ void __init io_block_mapping(unsigned long virt, phys_addr_t phys, * the PTE pointer is unmodified if PTE is not found. */ int -get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp) +get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep) { pgd_t *pgd; pmd_t *pmd; @@ -387,8 +387,6 @@ get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp) if (pte) { retval = 1; *ptep = pte; - if (pmdp) - *pmdp = pmd; /* XXX caller needs to do pte_unmap, yuck */ } } @@ -426,7 +424,7 @@ unsigned long iopa(unsigned long addr) mm = &init_mm; pa = 0; - if (get_pteptr(mm, addr, &pte, NULL)) { + if (get_pteptr(mm, addr, &pte)) { pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK); pte_unmap(pte); } diff --git a/trunk/arch/powerpc/mm/stab.c b/trunk/arch/powerpc/mm/stab.c index 4a9291d9fef8..91d25fb27f89 100644 --- a/trunk/arch/powerpc/mm/stab.c +++ b/trunk/arch/powerpc/mm/stab.c @@ -239,7 +239,7 @@ void stabs_alloc(void) if (cpu_has_feature(CPU_FTR_SLB)) return; - for_each_possible_cpu(cpu) { + for_each_cpu(cpu) { unsigned long newstab; if (cpu == 0) diff --git a/trunk/arch/powerpc/oprofile/Makefile b/trunk/arch/powerpc/oprofile/Makefile index f5f9859a8338..554cd7c75321 100644 --- a/trunk/arch/powerpc/oprofile/Makefile +++ b/trunk/arch/powerpc/oprofile/Makefile @@ -6,7 +6,7 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ oprofilefs.o oprofile_stats.o \ timer_int.o ) -oprofile-y := $(DRIVER_OBJS) common.o backtrace.o +oprofile-y := $(DRIVER_OBJS) common.o oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o oprofile-$(CONFIG_PPC32) += op_model_7450.o diff --git a/trunk/arch/powerpc/oprofile/backtrace.c b/trunk/arch/powerpc/oprofile/backtrace.c deleted file mode 100644 index 75f57bc96b40..000000000000 --- a/trunk/arch/powerpc/oprofile/backtrace.c +++ /dev/null @@ -1,126 +0,0 @@ -/** - * Copyright (C) 2005 Brian Rogan , IBM - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. -**/ - -#include -#include -#include -#include - -#define STACK_SP(STACK) *(STACK) - -#define STACK_LR64(STACK) *((unsigned long *)(STACK) + 2) -#define STACK_LR32(STACK) *((unsigned int *)(STACK) + 1) - -#ifdef CONFIG_PPC64 -#define STACK_LR(STACK) STACK_LR64(STACK) -#else -#define STACK_LR(STACK) STACK_LR32(STACK) -#endif - -static unsigned int user_getsp32(unsigned int sp, int is_first) -{ - unsigned int stack_frame[2]; - - if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame))) - return 0; - - /* - * The most likely reason for this is that we returned -EFAULT, - * which means that we've done all that we can do from - * interrupt context. - */ - if (__copy_from_user_inatomic(stack_frame, (void *)(long)sp, - sizeof(stack_frame))) - return 0; - - if (!is_first) - oprofile_add_trace(STACK_LR32(stack_frame)); - - /* - * We do not enforce increasing stack addresses here because - * we may transition to a different stack, eg a signal handler. - */ - return STACK_SP(stack_frame); -} - -#ifdef CONFIG_PPC64 -static unsigned long user_getsp64(unsigned long sp, int is_first) -{ - unsigned long stack_frame[3]; - - if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame))) - return 0; - - if (__copy_from_user_inatomic(stack_frame, (void *)sp, - sizeof(stack_frame))) - return 0; - - if (!is_first) - oprofile_add_trace(STACK_LR64(stack_frame)); - - return STACK_SP(stack_frame); -} -#endif - -static unsigned long kernel_getsp(unsigned long sp, int is_first) -{ - unsigned long *stack_frame = (unsigned long *)sp; - - if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD)) - return 0; - - if (!is_first) - oprofile_add_trace(STACK_LR(stack_frame)); - - /* - * We do not enforce increasing stack addresses here because - * we might be transitioning from an interrupt stack to a kernel - * stack. validate_sp() is designed to understand this, so just - * use it. - */ - return STACK_SP(stack_frame); -} - -void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth) -{ - unsigned long sp = regs->gpr[1]; - int first_frame = 1; - - /* We ditch the top stackframe so need to loop through an extra time */ - depth += 1; - - if (!user_mode(regs)) { - while (depth--) { - sp = kernel_getsp(sp, first_frame); - if (!sp) - break; - first_frame = 0; - } - } else { -#ifdef CONFIG_PPC64 - if (!test_thread_flag(TIF_32BIT)) { - while (depth--) { - sp = user_getsp64(sp, first_frame); - if (!sp) - break; - first_frame = 0; - } - - return; - } -#endif - - while (depth--) { - sp = user_getsp32(sp, first_frame); - if (!sp) - break; - first_frame = 0; - } - } -} diff --git a/trunk/arch/powerpc/oprofile/common.c b/trunk/arch/powerpc/oprofile/common.c index 5b1de7e8041e..cc2535be3a73 100644 --- a/trunk/arch/powerpc/oprofile/common.c +++ b/trunk/arch/powerpc/oprofile/common.c @@ -117,10 +117,18 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root) oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel); oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user); +#ifdef CONFIG_PPC64 + oprofilefs_create_ulong(sb, root, "backtrace_spinlocks", + &sys.backtrace_spinlocks); +#endif /* Default to tracing both kernel and user */ sys.enable_kernel = 1; sys.enable_user = 1; +#ifdef CONFIG_PPC64 + /* Turn on backtracing through spinlocks by default */ + sys.backtrace_spinlocks = 1; +#endif return 0; } @@ -160,7 +168,6 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) ops->shutdown = op_powerpc_shutdown; ops->start = op_powerpc_start; ops->stop = op_powerpc_stop; - ops->backtrace = op_powerpc_backtrace; printk(KERN_INFO "oprofile: using %s performance monitoring.\n", ops->cpu_type); diff --git a/trunk/arch/powerpc/oprofile/op_model_7450.c b/trunk/arch/powerpc/oprofile/op_model_7450.c index e0491c3c71f1..32abfdbb0eb1 100644 --- a/trunk/arch/powerpc/oprofile/op_model_7450.c +++ b/trunk/arch/powerpc/oprofile/op_model_7450.c @@ -176,13 +176,13 @@ static void fsl7450_handle_interrupt(struct pt_regs *regs, mtmsr(mfmsr() | MSR_PMM); pc = mfspr(SPRN_SIAR); - is_kernel = is_kernel_addr(pc); + is_kernel = (pc >= KERNELBASE); for (i = 0; i < NUM_CTRS; ++i) { val = ctr_read(i); if (val < 0) { if (oprofile_running && ctr[i].enabled) { - oprofile_add_ext_sample(pc, regs, i, is_kernel); + oprofile_add_pc(pc, is_kernel, i); ctr_write(i, reset_value[i]); } else { ctr_write(i, 0); diff --git a/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c b/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c index 93d63e62662f..26539cda6023 100644 --- a/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c +++ b/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c @@ -154,13 +154,13 @@ static void fsl_booke_handle_interrupt(struct pt_regs *regs, mtmsr(mfmsr() | MSR_PMM); pc = regs->nip; - is_kernel = is_kernel_addr(pc); + is_kernel = (pc >= KERNELBASE); for (i = 0; i < num_counters; ++i) { val = ctr_read(i); if (val < 0) { if (oprofile_running && ctr[i].enabled) { - oprofile_add_ext_sample(pc, regs, i, is_kernel); + oprofile_add_pc(pc, is_kernel, i); ctr_write(i, reset_value[i]); } else { ctr_write(i, 0); diff --git a/trunk/arch/powerpc/oprofile/op_model_power4.c b/trunk/arch/powerpc/oprofile/op_model_power4.c index 4c2beab1fdc1..4b06e53eb9b4 100644 --- a/trunk/arch/powerpc/oprofile/op_model_power4.c +++ b/trunk/arch/powerpc/oprofile/op_model_power4.c @@ -25,14 +25,18 @@ static unsigned long reset_value[OP_MAX_COUNTER]; static int oprofile_running; static int mmcra_has_sihv; -/* Unfortunately these bits vary between CPUs */ -static unsigned long mmcra_sihv = MMCRA_SIHV; -static unsigned long mmcra_sipr = MMCRA_SIPR; /* mmcr values are set in power4_reg_setup, used in power4_cpu_setup */ static u32 mmcr0_val; static u64 mmcr1_val; -static u64 mmcra_val; +static u32 mmcra_val; + +/* + * Since we do not have an NMI, backtracing through spinlocks is + * only a best guess. In light of this, allow it to be disabled at + * runtime. + */ +static int backtrace_spinlocks; static void power4_reg_setup(struct op_counter_config *ctr, struct op_system_config *sys, @@ -59,6 +63,8 @@ static void power4_reg_setup(struct op_counter_config *ctr, mmcr1_val = sys->mmcr1; mmcra_val = sys->mmcra; + backtrace_spinlocks = sys->backtrace_spinlocks; + for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) reset_value[i] = 0x80000000UL - ctr[i].count; @@ -191,6 +197,25 @@ static void __attribute_used__ kernel_unknown_bucket(void) { } +static unsigned long check_spinlock_pc(struct pt_regs *regs, + unsigned long profile_pc) +{ + unsigned long pc = instruction_pointer(regs); + + /* + * If both the SIAR (sampled instruction) and the perfmon exception + * occurred in a spinlock region then we account the sample to the + * calling function. This isnt 100% correct, we really need soft + * IRQ disable so we always get the perfmon exception at the + * point at which the SIAR is set. + */ + if (backtrace_spinlocks && in_lock_functions(pc) && + in_lock_functions(profile_pc)) + return regs->link; + else + return profile_pc; +} + /* * On GQ and newer the MMCRA stores the HV and PR bits at the time * the SIAR was sampled. We use that to work out if the SIAR was sampled in @@ -203,17 +228,17 @@ static unsigned long get_pc(struct pt_regs *regs) /* Cant do much about it */ if (!mmcra_has_sihv) - return pc; + return check_spinlock_pc(regs, pc); mmcra = mfspr(SPRN_MMCRA); /* Were we in the hypervisor? */ - if (firmware_has_feature(FW_FEATURE_LPAR) && (mmcra & mmcra_sihv)) + if (firmware_has_feature(FW_FEATURE_LPAR) && (mmcra & MMCRA_SIHV)) /* function descriptor madness */ return *((unsigned long *)hypervisor_bucket); /* We were in userspace, nothing to do */ - if (mmcra & mmcra_sipr) + if (mmcra & MMCRA_SIPR) return pc; #ifdef CONFIG_PPC_RTAS @@ -232,7 +257,7 @@ static unsigned long get_pc(struct pt_regs *regs) /* function descriptor madness */ return *((unsigned long *)kernel_unknown_bucket); - return pc; + return check_spinlock_pc(regs, pc); } static int get_kernel(unsigned long pc) @@ -243,7 +268,7 @@ static int get_kernel(unsigned long pc) is_kernel = is_kernel_addr(pc); } else { unsigned long mmcra = mfspr(SPRN_MMCRA); - is_kernel = ((mmcra & mmcra_sipr) == 0); + is_kernel = ((mmcra & MMCRA_SIPR) == 0); } return is_kernel; @@ -268,7 +293,7 @@ static void power4_handle_interrupt(struct pt_regs *regs, val = ctr_read(i); if (val < 0) { if (oprofile_running && ctr[i].enabled) { - oprofile_add_ext_sample(pc, regs, i, is_kernel); + oprofile_add_pc(pc, is_kernel, i); ctr_write(i, reset_value[i]); } else { ctr_write(i, 0); diff --git a/trunk/arch/powerpc/oprofile/op_model_rs64.c b/trunk/arch/powerpc/oprofile/op_model_rs64.c index 042f8f4867ad..5c909ee609fe 100644 --- a/trunk/arch/powerpc/oprofile/op_model_rs64.c +++ b/trunk/arch/powerpc/oprofile/op_model_rs64.c @@ -175,13 +175,10 @@ static void rs64_handle_interrupt(struct pt_regs *regs, struct op_counter_config *ctr) { unsigned int mmcr0; - int is_kernel; int val; int i; unsigned long pc = mfspr(SPRN_SIAR); - is_kernel = is_kernel_addr(pc); - /* set the PMM bit (see comment below) */ mtmsrd(mfmsr() | MSR_PMM); @@ -189,7 +186,7 @@ static void rs64_handle_interrupt(struct pt_regs *regs, val = ctr_read(i); if (val < 0) { if (ctr[i].enabled) { - oprofile_add_ext_sample(pc, regs, i, is_kernel); + oprofile_add_pc(pc, is_kernel_addr(pc), i); ctr_write(i, reset_value[i]); } else { ctr_write(i, 0); diff --git a/trunk/arch/powerpc/platforms/85xx/Kconfig b/trunk/arch/powerpc/platforms/85xx/Kconfig index 06e371282f57..d3d0ff745e84 100644 --- a/trunk/arch/powerpc/platforms/85xx/Kconfig +++ b/trunk/arch/powerpc/platforms/85xx/Kconfig @@ -7,7 +7,6 @@ choice config MPC8540_ADS bool "Freescale MPC8540 ADS" - select DEFAULT_UIMAGE help This option enables support for the MPC 8540 ADS board diff --git a/trunk/arch/powerpc/platforms/cell/Kconfig b/trunk/arch/powerpc/platforms/cell/Kconfig index c2a3db8edb0c..3157071e241c 100644 --- a/trunk/arch/powerpc/platforms/cell/Kconfig +++ b/trunk/arch/powerpc/platforms/cell/Kconfig @@ -10,9 +10,4 @@ config SPU_FS Units on machines implementing the Broadband Processor Architecture. -config SPUFS_MMAP - bool - depends on SPU_FS && SPARSEMEM && !PPC_64K_PAGES - default y - endmenu diff --git a/trunk/arch/powerpc/platforms/cell/Makefile b/trunk/arch/powerpc/platforms/cell/Makefile index e570bad06394..3b998a393e3f 100644 --- a/trunk/arch/powerpc/platforms/cell/Makefile +++ b/trunk/arch/powerpc/platforms/cell/Makefile @@ -6,11 +6,5 @@ obj-$(CONFIG_SPU_FS) += spu-base.o spufs/ spu-base-y += spu_base.o spu_priv1.o -# needed only when building loadable spufs.ko -spufs-modular-$(CONFIG_SPU_FS) += spu_syscalls.o -obj-y += $(spufs-modular-m) - -# always needed in kernel -spufs-builtin-$(CONFIG_SPU_FS) += spu_callbacks.o -obj-y += $(spufs-builtin-y) $(spufs-builtin-m) - +builtin-spufs-$(CONFIG_SPU_FS) += spu_syscalls.o +obj-y += $(builtin-spufs-m) diff --git a/trunk/arch/powerpc/platforms/cell/interrupt.c b/trunk/arch/powerpc/platforms/cell/interrupt.c index 978be1c30c1b..63aa52acf441 100644 --- a/trunk/arch/powerpc/platforms/cell/interrupt.c +++ b/trunk/arch/powerpc/platforms/cell/interrupt.c @@ -63,24 +63,7 @@ static DEFINE_PER_CPU(struct iic, iic); void iic_local_enable(void) { - struct iic *iic = &__get_cpu_var(iic); - u64 tmp; - - /* - * There seems to be a bug that is present in DD2.x CPUs - * and still only partially fixed in DD3.1. - * This bug causes a value written to the priority register - * not to make it there, resulting in a system hang unless we - * write it again. - * Masking with 0xf0 is done because the Cell BE does not - * implement the lower four bits of the interrupt priority, - * they always read back as zeroes, although future CPUs - * might implement different bits. - */ - do { - out_be64(&iic->regs->prio, 0xff); - tmp = in_be64(&iic->regs->prio); - } while ((tmp & 0xf0) != 0xf0); + out_be64(&__get_cpu_var(iic).regs->prio, 0xff); } void iic_local_disable(void) @@ -140,7 +123,7 @@ static int iic_external_get_irq(struct iic_pending_bits pending) pending.class != 2) break; irq = IIC_EXT_OFFSET - + spider_get_irq(node) + + spider_get_irq(pending.prio + node * IIC_NODE_STRIDE) + node * IIC_NODE_STRIDE; break; case 0x01 ... 0x04: @@ -191,98 +174,38 @@ int iic_get_irq(struct pt_regs *regs) return irq; } -/* hardcoded part to be compatible with older firmware */ - -static int setup_iic_hardcoded(void) +static int setup_iic(int cpu, struct iic *iic) { struct device_node *np; - int nodeid, cpu; + int nodeid = cpu / 2; unsigned long regs; - struct iic *iic; - for_each_cpu(cpu) { - iic = &per_cpu(iic, cpu); - nodeid = cpu/2; - - for (np = of_find_node_by_type(NULL, "cpu"); - np; - np = of_find_node_by_type(np, "cpu")) { - if (nodeid == *(int *)get_property(np, "node-id", NULL)) - break; - } - - if (!np) { - printk(KERN_WARNING "IIC: CPU %d not found\n", cpu); - iic->regs = NULL; - iic->target_id = 0xff; - return -ENODEV; - } - - regs = *(long *)get_property(np, "iic", NULL); - - /* hack until we have decided on the devtree info */ - regs += 0x400; - if (cpu & 1) - regs += 0x20; - - printk(KERN_INFO "IIC for CPU %d at %lx\n", cpu, regs); - iic->regs = ioremap(regs, sizeof(struct iic_regs)); - iic->target_id = (nodeid << 4) + ((cpu & 1) ? 0xf : 0xe); + for (np = of_find_node_by_type(NULL, "cpu"); + np; + np = of_find_node_by_type(np, "cpu")) { + if (nodeid == *(int *)get_property(np, "node-id", NULL)) + break; } - return 0; -} - -static int setup_iic(void) -{ - struct device_node *dn; - unsigned long *regs; - char *compatible; - unsigned *np, found = 0; - struct iic *iic = NULL; - - for (dn = NULL; (dn = of_find_node_by_name(dn, "interrupt-controller"));) { - compatible = (char *)get_property(dn, "compatible", NULL); - - if (!compatible) { - printk(KERN_WARNING "no compatible property found !\n"); - continue; - } - - if (strstr(compatible, "IBM,CBEA-Internal-Interrupt-Controller")) - regs = (unsigned long *)get_property(dn,"reg", NULL); - else - continue; - - if (!regs) - printk(KERN_WARNING "IIC: no reg property\n"); - - np = (unsigned int *)get_property(dn, "ibm,interrupt-server-ranges", NULL); - - if (!np) { - printk(KERN_WARNING "IIC: CPU association not found\n"); - iic->regs = NULL; - iic->target_id = 0xff; - return -ENODEV; - } - - iic = &per_cpu(iic, np[0]); - iic->regs = ioremap(regs[0], sizeof(struct iic_regs)); - iic->target_id = ((np[0] & 2) << 3) + ((np[0] & 1) ? 0xf : 0xe); - printk("IIC for CPU %d at %lx mapped to %p\n", np[0], regs[0], iic->regs); + if (!np) { + printk(KERN_WARNING "IIC: CPU %d not found\n", cpu); + iic->regs = NULL; + iic->target_id = 0xff; + return -ENODEV; + } - iic = &per_cpu(iic, np[1]); - iic->regs = ioremap(regs[2], sizeof(struct iic_regs)); - iic->target_id = ((np[1] & 2) << 3) + ((np[1] & 1) ? 0xf : 0xe); - printk("IIC for CPU %d at %lx mapped to %p\n", np[1], regs[2], iic->regs); + regs = *(long *)get_property(np, "iic", NULL); - found++; - } + /* hack until we have decided on the devtree info */ + regs += 0x400; + if (cpu & 1) + regs += 0x20; - if (found) - return 0; - else - return -ENODEV; + printk(KERN_DEBUG "IIC for CPU %d at %lx\n", cpu, regs); + iic->regs = __ioremap(regs, sizeof(struct iic_regs), + _PAGE_NO_CACHE); + iic->target_id = (nodeid << 4) + ((cpu & 1) ? 0xf : 0xe); + return 0; } #ifdef CONFIG_SMP @@ -360,12 +283,10 @@ void iic_init_IRQ(void) int cpu, irq_offset; struct iic *iic; - if (setup_iic() < 0) - setup_iic_hardcoded(); - irq_offset = 0; - for_each_possible_cpu(cpu) { + for_each_cpu(cpu) { iic = &per_cpu(iic, cpu); + setup_iic(cpu, iic); if (iic->regs) out_be64(&iic->regs->prio, 0xff); } diff --git a/trunk/arch/powerpc/platforms/cell/interrupt.h b/trunk/arch/powerpc/platforms/cell/interrupt.h index 799f77d98f96..a14bd38791c0 100644 --- a/trunk/arch/powerpc/platforms/cell/interrupt.h +++ b/trunk/arch/powerpc/platforms/cell/interrupt.h @@ -57,7 +57,7 @@ extern void iic_local_disable(void); extern u8 iic_get_target_id(int cpu); extern void spider_init_IRQ(void); -extern int spider_get_irq(int node); +extern int spider_get_irq(unsigned long int_pending); #endif #endif /* ASM_CELL_PIC_H */ diff --git a/trunk/arch/powerpc/platforms/cell/iommu.c b/trunk/arch/powerpc/platforms/cell/iommu.c index a49ceb799a8e..46e7cb9c3e64 100644 --- a/trunk/arch/powerpc/platforms/cell/iommu.c +++ b/trunk/arch/powerpc/platforms/cell/iommu.c @@ -289,7 +289,7 @@ static void cell_do_map_iommu(struct cell_iommu *iommu, ioc_base = iommu->mapped_base; ioc_mmio_base = iommu->mapped_mmio_base; - for (real_address = 0, io_address = map_start; + for (real_address = 0, io_address = 0; io_address <= map_start + map_size; real_address += io_page_size, io_address += io_page_size) { ioste = get_iost_entry(fake_iopt, io_address, io_page_size); @@ -302,7 +302,7 @@ static void cell_do_map_iommu(struct cell_iommu *iommu, set_iopt_cache(ioc_mmio_base, get_ioc_hash_1way(ioste, io_address), get_ioc_tag(ioste, io_address), - get_iopt_entry(real_address, ioid, IOPT_PROT_RW)); + get_iopt_entry(real_address-map_start, ioid, IOPT_PROT_RW)); } } @@ -344,8 +344,8 @@ static int cell_map_iommu_hardcoded(int num_nodes) /* node 0 */ iommu = &cell_iommus[0]; - iommu->mapped_base = ioremap(0x20000511000, 0x1000); - iommu->mapped_mmio_base = ioremap(0x20000510000, 0x1000); + iommu->mapped_base = __ioremap(0x20000511000, 0x1000, _PAGE_NO_CACHE); + iommu->mapped_mmio_base = __ioremap(0x20000510000, 0x1000, _PAGE_NO_CACHE); enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base); @@ -357,8 +357,8 @@ static int cell_map_iommu_hardcoded(int num_nodes) /* node 1 */ iommu = &cell_iommus[1]; - iommu->mapped_base = ioremap(0x30000511000, 0x1000); - iommu->mapped_mmio_base = ioremap(0x30000510000, 0x1000); + iommu->mapped_base = __ioremap(0x30000511000, 0x1000, _PAGE_NO_CACHE); + iommu->mapped_mmio_base = __ioremap(0x30000510000, 0x1000, _PAGE_NO_CACHE); enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base); @@ -407,8 +407,8 @@ static int cell_map_iommu(void) iommu->base = *base; iommu->mmio_base = *mmio_base; - iommu->mapped_base = ioremap(*base, 0x1000); - iommu->mapped_mmio_base = ioremap(*mmio_base, 0x1000); + iommu->mapped_base = __ioremap(*base, 0x1000, _PAGE_NO_CACHE); + iommu->mapped_mmio_base = __ioremap(*mmio_base, 0x1000, _PAGE_NO_CACHE); enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base); diff --git a/trunk/arch/powerpc/platforms/cell/pervasive.c b/trunk/arch/powerpc/platforms/cell/pervasive.c index 7eed8c624517..e0e051c675dd 100644 --- a/trunk/arch/powerpc/platforms/cell/pervasive.c +++ b/trunk/arch/powerpc/platforms/cell/pervasive.c @@ -203,7 +203,7 @@ static int __init cbe_find_pmd_mmio(int cpu, struct cbe_pervasive *p) pr_debug("pervasive area for CPU %d at %lx, size %x\n", cpu, real_address, size); - p->regs = ioremap(real_address, size); + p->regs = __ioremap(real_address, size, _PAGE_NO_CACHE); p->thread = thread; return 0; } @@ -217,7 +217,7 @@ void __init cell_pervasive_init(void) if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO)) return; - for_each_possible_cpu(cpu) { + for_each_cpu(cpu) { p = &cbe_pervasive[cpu]; ret = cbe_find_pmd_mmio(cpu, p); if (ret) diff --git a/trunk/arch/powerpc/platforms/cell/setup.c b/trunk/arch/powerpc/platforms/cell/setup.c index dac5d0365fde..fec8e65b36ea 100644 --- a/trunk/arch/powerpc/platforms/cell/setup.c +++ b/trunk/arch/powerpc/platforms/cell/setup.c @@ -195,13 +195,9 @@ static void __init cell_init_early(void) } -static int __init cell_probe(void) +static int __init cell_probe(int platform) { - /* XXX This is temporary, the Cell maintainer will come up with - * more appropriate detection logic - */ - unsigned long root = of_get_flat_dt_root(); - if (!of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) + if (platform != PLATFORM_CELL) return 0; return 1; @@ -216,8 +212,7 @@ static int cell_check_legacy_ioport(unsigned int baseport) return -ENODEV; } -define_machine(cell) { - .name = "Cell", +struct machdep_calls __initdata cell_md = { .probe = cell_probe, .setup_arch = cell_setup_arch, .init_early = cell_init_early, diff --git a/trunk/arch/powerpc/platforms/cell/spider-pic.c b/trunk/arch/powerpc/platforms/cell/spider-pic.c index 55cbdd77a62d..e74132188bdf 100644 --- a/trunk/arch/powerpc/platforms/cell/spider-pic.c +++ b/trunk/arch/powerpc/platforms/cell/spider-pic.c @@ -84,11 +84,10 @@ static void __iomem *spider_get_irq_config(int irq) static void spider_enable_irq(unsigned int irq) { - int nodeid = (irq / IIC_NODE_STRIDE) * 0x10; void __iomem *cfg = spider_get_irq_config(irq); irq = spider_get_nr(irq); - out_be32(cfg, (in_be32(cfg) & ~0xf0)| 0x3107000eu | nodeid); + out_be32(cfg, in_be32(cfg) | 0x3107000eu); out_be32(cfg + 4, in_be32(cfg + 4) | 0x00020000u | irq); } @@ -132,108 +131,61 @@ static struct hw_interrupt_type spider_pic = { .end = spider_end_irq, }; -int spider_get_irq(int node) + +int spider_get_irq(unsigned long int_pending) { + void __iomem *regs = spider_get_pic(int_pending); unsigned long cs; - void __iomem *regs = spider_pics[node]; - - cs = in_be32(regs + TIR_CS) >> 24; + int irq; - if (cs == 63) - return -1; - else - return cs; -} + cs = in_be32(regs + TIR_CS); -/* hardcoded part to be compatible with older firmware */ + irq = cs >> 24; + if (irq != 63) + return irq; -void spider_init_IRQ_hardcoded(void) + return -1; +} + +void spider_init_IRQ(void) { int node; + struct device_node *dn; + unsigned int *property; long spiderpic; - long pics[] = { 0x24000008000, 0x34000008000 }; int n; - pr_debug("%s(%d): Using hardcoded defaults\n", __FUNCTION__, __LINE__); +/* FIXME: detect multiple PICs as soon as the device tree has them */ + for (node = 0; node < 1; node++) { + dn = of_find_node_by_path("/"); + n = prom_n_addr_cells(dn); + property = (unsigned int *) get_property(dn, + "platform-spider-pic", NULL); - for (node = 0; node < num_present_cpus()/2; node++) { - spiderpic = pics[node]; + if (!property) + continue; + for (spiderpic = 0; n > 0; --n) + spiderpic = (spiderpic << 32) + *property++; printk(KERN_DEBUG "SPIDER addr: %lx\n", spiderpic); - spider_pics[node] = ioremap(spiderpic, 0x800); + spider_pics[node] = __ioremap(spiderpic, 0x800, _PAGE_NO_CACHE); for (n = 0; n < IIC_NUM_EXT; n++) { int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE; get_irq_desc(irq)->handler = &spider_pic; - } /* do not mask any interrupts because of level */ out_be32(spider_pics[node] + TIR_MSK, 0x0); - + /* disable edge detection clear */ /* out_be32(spider_pics[node] + TIR_EDC, 0x0); */ - + /* enable interrupt packets to be output */ out_be32(spider_pics[node] + TIR_PIEN, in_be32(spider_pics[node] + TIR_PIEN) | 0x1); - + /* Enable the interrupt detection enable bit. Do this last! */ out_be32(spider_pics[node] + TIR_DEN, - in_be32(spider_pics[node] + TIR_DEN) | 0x1); - } -} - -void spider_init_IRQ(void) -{ - long spider_reg; - struct device_node *dn; - char *compatible; - int n, node = 0; - - for (dn = NULL; (dn = of_find_node_by_name(dn, "interrupt-controller"));) { - compatible = (char *)get_property(dn, "compatible", NULL); + in_be32(spider_pics[node] +TIR_DEN) | 0x1); - if (!compatible) - continue; - - if (strstr(compatible, "CBEA,platform-spider-pic")) - spider_reg = *(long *)get_property(dn,"reg", NULL); - else if (strstr(compatible, "sti,platform-spider-pic")) { - spider_init_IRQ_hardcoded(); - return; - } else - continue; - - if (!spider_reg) - printk("interrupt controller does not have reg property !\n"); - - n = prom_n_addr_cells(dn); - - if ( n != 2) - printk("reg property with invalid number of elements \n"); - - spider_pics[node] = ioremap(spider_reg, 0x800); - - printk("SPIDER addr: %lx with %i addr_cells mapped to %p\n", - spider_reg, n, spider_pics[node]); - - for (n = 0; n < IIC_NUM_EXT; n++) { - int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE; - get_irq_desc(irq)->handler = &spider_pic; } - - /* do not mask any interrupts because of level */ - out_be32(spider_pics[node] + TIR_MSK, 0x0); - - /* disable edge detection clear */ - /* out_be32(spider_pics[node] + TIR_EDC, 0x0); */ - - /* enable interrupt packets to be output */ - out_be32(spider_pics[node] + TIR_PIEN, - in_be32(spider_pics[node] + TIR_PIEN) | 0x1); - - /* Enable the interrupt detection enable bit. Do this last! */ - out_be32(spider_pics[node] + TIR_DEN, - in_be32(spider_pics[node] + TIR_DEN) | 0x1); - - node++; } } diff --git a/trunk/arch/powerpc/platforms/cell/spu_base.c b/trunk/arch/powerpc/platforms/cell/spu_base.c index 269dda4fd0b4..a8fa1eeeb174 100644 --- a/trunk/arch/powerpc/platforms/cell/spu_base.c +++ b/trunk/arch/powerpc/platforms/cell/spu_base.c @@ -111,7 +111,7 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea) extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap); //XXX static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr) { - pr_debug("%s, %lx, %lx\n", __FUNCTION__, dsisr, ea); + pr_debug("%s\n", __FUNCTION__); /* Handle kernel space hash faults immediately. User hash faults need to be deferred to process context. */ @@ -168,7 +168,7 @@ static int __spu_trap_halt(struct spu *spu) static int __spu_trap_tag_group(struct spu *spu) { pr_debug("%s\n", __FUNCTION__); - spu->mfc_callback(spu); + /* wake_up(&spu->dma_wq); */ return 0; } @@ -242,8 +242,6 @@ spu_irq_class_1(int irq, void *data, struct pt_regs *regs) spu_mfc_dsisr_set(spu, 0ul); spu_int_stat_clear(spu, 1, stat); spin_unlock(&spu->register_lock); - pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat, - dar, dsisr); if (stat & 1) /* segment fault */ __spu_trap_data_seg(spu, dar); @@ -486,13 +484,14 @@ int spu_irq_class_1_bottom(struct spu *spu) ea = spu->dar; dsisr = spu->dsisr; - if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)) { + if (dsisr & MFC_DSISR_PTE_NOT_FOUND) { access = (_PAGE_PRESENT | _PAGE_USER); access |= (dsisr & MFC_DSISR_ACCESS_PUT) ? _PAGE_RW : 0UL; if (hash_page(ea, access, 0x300) != 0) error |= CLASS1_ENABLE_STORAGE_FAULT_INTR; } - if (error & CLASS1_ENABLE_STORAGE_FAULT_INTR) { + if ((error & CLASS1_ENABLE_STORAGE_FAULT_INTR) || + (dsisr & MFC_DSISR_ACCESS_DENIED)) { if ((ret = spu_handle_mm_fault(spu)) != 0) error |= CLASS1_ENABLE_STORAGE_FAULT_INTR; else @@ -569,11 +568,6 @@ static int __init spu_map_device(struct spu *spu, struct device_node *spe) if (!spu->local_store) goto out; - prop = get_property(spe, "problem", NULL); - if (!prop) - goto out_unmap; - spu->problem_phys = *(unsigned long *)prop; - spu->problem= map_spe_prop(spe, "problem"); if (!spu->problem) goto out_unmap; @@ -638,7 +632,6 @@ static int __init create_spu(struct device_node *spe) spu->ibox_callback = NULL; spu->wbox_callback = NULL; spu->stop_callback = NULL; - spu->mfc_callback = NULL; mutex_lock(&spu_mutex); spu->number = number++; diff --git a/trunk/arch/powerpc/platforms/cell/spu_callbacks.c b/trunk/arch/powerpc/platforms/cell/spu_callbacks.c deleted file mode 100644 index 3a4245c926ad..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spu_callbacks.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * System call callback functions for SPUs - */ - -#define DEBUG - -#include -#include -#include - -#include -#include -#include - -/* - * This table defines the system calls that an SPU can call. - * It is currently a subset of the 64 bit powerpc system calls, - * with the exact semantics. - * - * The reasons for disabling some of the system calls are: - * 1. They interact with the way SPU syscalls are handled - * and we can't let them execute ever: - * restart_syscall, exit, for, execve, ptrace, ... - * 2. They are deprecated and replaced by other means: - * uselib, pciconfig_*, sysfs, ... - * 3. They are somewhat interacting with the system in a way - * we don't want an SPU to: - * reboot, init_module, mount, kexec_load - * 4. They are optional and we can't rely on them being - * linked into the kernel. Unfortunately, the cond_syscall - * helper does not work here as it does not add the necessary - * opd symbols: - * mbind, mq_open, ipc, ... - */ - -void *spu_syscall_table[] = { - [__NR_restart_syscall] sys_ni_syscall, /* sys_restart_syscall */ - [__NR_exit] sys_ni_syscall, /* sys_exit */ - [__NR_fork] sys_ni_syscall, /* ppc_fork */ - [__NR_read] sys_read, - [__NR_write] sys_write, - [__NR_open] sys_open, - [__NR_close] sys_close, - [__NR_waitpid] sys_waitpid, - [__NR_creat] sys_creat, - [__NR_link] sys_link, - [__NR_unlink] sys_unlink, - [__NR_execve] sys_ni_syscall, /* sys_execve */ - [__NR_chdir] sys_chdir, - [__NR_time] sys_time, - [__NR_mknod] sys_mknod, - [__NR_chmod] sys_chmod, - [__NR_lchown] sys_lchown, - [__NR_break] sys_ni_syscall, - [__NR_oldstat] sys_ni_syscall, - [__NR_lseek] sys_lseek, - [__NR_getpid] sys_getpid, - [__NR_mount] sys_ni_syscall, /* sys_mount */ - [__NR_umount] sys_ni_syscall, - [__NR_setuid] sys_setuid, - [__NR_getuid] sys_getuid, - [__NR_stime] sys_stime, - [__NR_ptrace] sys_ni_syscall, /* sys_ptrace */ - [__NR_alarm] sys_alarm, - [__NR_oldfstat] sys_ni_syscall, - [__NR_pause] sys_ni_syscall, /* sys_pause */ - [__NR_utime] sys_ni_syscall, /* sys_utime */ - [__NR_stty] sys_ni_syscall, - [__NR_gtty] sys_ni_syscall, - [__NR_access] sys_access, - [__NR_nice] sys_nice, - [__NR_ftime] sys_ni_syscall, - [__NR_sync] sys_sync, - [__NR_kill] sys_kill, - [__NR_rename] sys_rename, - [__NR_mkdir] sys_mkdir, - [__NR_rmdir] sys_rmdir, - [__NR_dup] sys_dup, - [__NR_pipe] sys_pipe, - [__NR_times] sys_times, - [__NR_prof] sys_ni_syscall, - [__NR_brk] sys_brk, - [__NR_setgid] sys_setgid, - [__NR_getgid] sys_getgid, - [__NR_signal] sys_ni_syscall, /* sys_signal */ - [__NR_geteuid] sys_geteuid, - [__NR_getegid] sys_getegid, - [__NR_acct] sys_ni_syscall, /* sys_acct */ - [__NR_umount2] sys_ni_syscall, /* sys_umount */ - [__NR_lock] sys_ni_syscall, - [__NR_ioctl] sys_ioctl, - [__NR_fcntl] sys_fcntl, - [__NR_mpx] sys_ni_syscall, - [__NR_setpgid] sys_setpgid, - [__NR_ulimit] sys_ni_syscall, - [__NR_oldolduname] sys_ni_syscall, - [__NR_umask] sys_umask, - [__NR_chroot] sys_chroot, - [__NR_ustat] sys_ni_syscall, /* sys_ustat */ - [__NR_dup2] sys_dup2, - [__NR_getppid] sys_getppid, - [__NR_getpgrp] sys_getpgrp, - [__NR_setsid] sys_setsid, - [__NR_sigaction] sys_ni_syscall, - [__NR_sgetmask] sys_sgetmask, - [__NR_ssetmask] sys_ssetmask, - [__NR_setreuid] sys_setreuid, - [__NR_setregid] sys_setregid, - [__NR_sigsuspend] sys_ni_syscall, - [__NR_sigpending] sys_ni_syscall, - [__NR_sethostname] sys_sethostname, - [__NR_setrlimit] sys_setrlimit, - [__NR_getrlimit] sys_ni_syscall, - [__NR_getrusage] sys_getrusage, - [__NR_gettimeofday] sys_gettimeofday, - [__NR_settimeofday] sys_settimeofday, - [__NR_getgroups] sys_getgroups, - [__NR_setgroups] sys_setgroups, - [__NR_select] sys_ni_syscall, - [__NR_symlink] sys_symlink, - [__NR_oldlstat] sys_ni_syscall, - [__NR_readlink] sys_readlink, - [__NR_uselib] sys_ni_syscall, /* sys_uselib */ - [__NR_swapon] sys_ni_syscall, /* sys_swapon */ - [__NR_reboot] sys_ni_syscall, /* sys_reboot */ - [__NR_readdir] sys_ni_syscall, - [__NR_mmap] sys_mmap, - [__NR_munmap] sys_munmap, - [__NR_truncate] sys_truncate, - [__NR_ftruncate] sys_ftruncate, - [__NR_fchmod] sys_fchmod, - [__NR_fchown] sys_fchown, - [__NR_getpriority] sys_getpriority, - [__NR_setpriority] sys_setpriority, - [__NR_profil] sys_ni_syscall, - [__NR_statfs] sys_ni_syscall, /* sys_statfs */ - [__NR_fstatfs] sys_ni_syscall, /* sys_fstatfs */ - [__NR_ioperm] sys_ni_syscall, - [__NR_socketcall] sys_socketcall, - [__NR_syslog] sys_syslog, - [__NR_setitimer] sys_setitimer, - [__NR_getitimer] sys_getitimer, - [__NR_stat] sys_newstat, - [__NR_lstat] sys_newlstat, - [__NR_fstat] sys_newfstat, - [__NR_olduname] sys_ni_syscall, - [__NR_iopl] sys_ni_syscall, - [__NR_vhangup] sys_vhangup, - [__NR_idle] sys_ni_syscall, - [__NR_vm86] sys_ni_syscall, - [__NR_wait4] sys_wait4, - [__NR_swapoff] sys_ni_syscall, /* sys_swapoff */ - [__NR_sysinfo] sys_sysinfo, - [__NR_ipc] sys_ni_syscall, /* sys_ipc */ - [__NR_fsync] sys_fsync, - [__NR_sigreturn] sys_ni_syscall, - [__NR_clone] sys_ni_syscall, /* ppc_clone */ - [__NR_setdomainname] sys_setdomainname, - [__NR_uname] ppc_newuname, - [__NR_modify_ldt] sys_ni_syscall, - [__NR_adjtimex] sys_adjtimex, - [__NR_mprotect] sys_mprotect, - [__NR_sigprocmask] sys_ni_syscall, - [__NR_create_module] sys_ni_syscall, - [__NR_init_module] sys_ni_syscall, /* sys_init_module */ - [__NR_delete_module] sys_ni_syscall, /* sys_delete_module */ - [__NR_get_kernel_syms] sys_ni_syscall, - [__NR_quotactl] sys_ni_syscall, /* sys_quotactl */ - [__NR_getpgid] sys_getpgid, - [__NR_fchdir] sys_fchdir, - [__NR_bdflush] sys_bdflush, - [__NR_sysfs] sys_ni_syscall, /* sys_sysfs */ - [__NR_personality] ppc64_personality, - [__NR_afs_syscall] sys_ni_syscall, - [__NR_setfsuid] sys_setfsuid, - [__NR_setfsgid] sys_setfsgid, - [__NR__llseek] sys_llseek, - [__NR_getdents] sys_getdents, - [__NR__newselect] sys_select, - [__NR_flock] sys_flock, - [__NR_msync] sys_msync, - [__NR_readv] sys_readv, - [__NR_writev] sys_writev, - [__NR_getsid] sys_getsid, - [__NR_fdatasync] sys_fdatasync, - [__NR__sysctl] sys_ni_syscall, /* sys_sysctl */ - [__NR_mlock] sys_mlock, - [__NR_munlock] sys_munlock, - [__NR_mlockall] sys_mlockall, - [__NR_munlockall] sys_munlockall, - [__NR_sched_setparam] sys_sched_setparam, - [__NR_sched_getparam] sys_sched_getparam, - [__NR_sched_setscheduler] sys_sched_setscheduler, - [__NR_sched_getscheduler] sys_sched_getscheduler, - [__NR_sched_yield] sys_sched_yield, - [__NR_sched_get_priority_max] sys_sched_get_priority_max, - [__NR_sched_get_priority_min] sys_sched_get_priority_min, - [__NR_sched_rr_get_interval] sys_sched_rr_get_interval, - [__NR_nanosleep] sys_nanosleep, - [__NR_mremap] sys_mremap, - [__NR_setresuid] sys_setresuid, - [__NR_getresuid] sys_getresuid, - [__NR_query_module] sys_ni_syscall, - [__NR_poll] sys_poll, - [__NR_nfsservctl] sys_ni_syscall, /* sys_nfsservctl */ - [__NR_setresgid] sys_setresgid, - [__NR_getresgid] sys_getresgid, - [__NR_prctl] sys_prctl, - [__NR_rt_sigreturn] sys_ni_syscall, /* ppc64_rt_sigreturn */ - [__NR_rt_sigaction] sys_ni_syscall, /* sys_rt_sigaction */ - [__NR_rt_sigprocmask] sys_ni_syscall, /* sys_rt_sigprocmask */ - [__NR_rt_sigpending] sys_ni_syscall, /* sys_rt_sigpending */ - [__NR_rt_sigtimedwait] sys_ni_syscall, /* sys_rt_sigtimedwait */ - [__NR_rt_sigqueueinfo] sys_ni_syscall, /* sys_rt_sigqueueinfo */ - [__NR_rt_sigsuspend] sys_ni_syscall, /* sys_rt_sigsuspend */ - [__NR_pread64] sys_pread64, - [__NR_pwrite64] sys_pwrite64, - [__NR_chown] sys_chown, - [__NR_getcwd] sys_getcwd, - [__NR_capget] sys_capget, - [__NR_capset] sys_capset, - [__NR_sigaltstack] sys_ni_syscall, /* sys_sigaltstack */ - [__NR_sendfile] sys_sendfile64, - [__NR_getpmsg] sys_ni_syscall, - [__NR_putpmsg] sys_ni_syscall, - [__NR_vfork] sys_ni_syscall, /* ppc_vfork */ - [__NR_ugetrlimit] sys_getrlimit, - [__NR_readahead] sys_readahead, - [192] sys_ni_syscall, - [193] sys_ni_syscall, - [194] sys_ni_syscall, - [195] sys_ni_syscall, - [196] sys_ni_syscall, - [197] sys_ni_syscall, - [__NR_pciconfig_read] sys_ni_syscall, /* sys_pciconfig_read */ - [__NR_pciconfig_write] sys_ni_syscall, /* sys_pciconfig_write */ - [__NR_pciconfig_iobase] sys_ni_syscall, /* sys_pciconfig_iobase */ - [__NR_multiplexer] sys_ni_syscall, - [__NR_getdents64] sys_getdents64, - [__NR_pivot_root] sys_pivot_root, - [204] sys_ni_syscall, - [__NR_madvise] sys_madvise, - [__NR_mincore] sys_mincore, - [__NR_gettid] sys_gettid, - [__NR_tkill] sys_tkill, - [__NR_setxattr] sys_setxattr, - [__NR_lsetxattr] sys_lsetxattr, - [__NR_fsetxattr] sys_fsetxattr, - [__NR_getxattr] sys_getxattr, - [__NR_lgetxattr] sys_lgetxattr, - [__NR_fgetxattr] sys_fgetxattr, - [__NR_listxattr] sys_listxattr, - [__NR_llistxattr] sys_llistxattr, - [__NR_flistxattr] sys_flistxattr, - [__NR_removexattr] sys_removexattr, - [__NR_lremovexattr] sys_lremovexattr, - [__NR_fremovexattr] sys_fremovexattr, - [__NR_futex] sys_futex, - [__NR_sched_setaffinity] sys_sched_setaffinity, - [__NR_sched_getaffinity] sys_sched_getaffinity, - [__NR_tuxcall] sys_ni_syscall, - [226] sys_ni_syscall, - [__NR_io_setup] sys_io_setup, - [__NR_io_destroy] sys_io_destroy, - [__NR_io_getevents] sys_io_getevents, - [__NR_io_submit] sys_io_submit, - [__NR_io_cancel] sys_io_cancel, - [__NR_set_tid_address] sys_ni_syscall, /* sys_set_tid_address */ - [__NR_fadvise64] sys_fadvise64, - [__NR_exit_group] sys_ni_syscall, /* sys_exit_group */ - [__NR_lookup_dcookie] sys_ni_syscall, /* sys_lookup_dcookie */ - [__NR_epoll_create] sys_epoll_create, - [__NR_epoll_ctl] sys_epoll_ctl, - [__NR_epoll_wait] sys_epoll_wait, - [__NR_remap_file_pages] sys_remap_file_pages, - [__NR_timer_create] sys_timer_create, - [__NR_timer_settime] sys_timer_settime, - [__NR_timer_gettime] sys_timer_gettime, - [__NR_timer_getoverrun] sys_timer_getoverrun, - [__NR_timer_delete] sys_timer_delete, - [__NR_clock_settime] sys_clock_settime, - [__NR_clock_gettime] sys_clock_gettime, - [__NR_clock_getres] sys_clock_getres, - [__NR_clock_nanosleep] sys_clock_nanosleep, - [__NR_swapcontext] sys_ni_syscall, /* ppc64_swapcontext */ - [__NR_tgkill] sys_tgkill, - [__NR_utimes] sys_utimes, - [__NR_statfs64] sys_statfs64, - [__NR_fstatfs64] sys_fstatfs64, - [254] sys_ni_syscall, - [__NR_rtas] ppc_rtas, - [256] sys_ni_syscall, - [257] sys_ni_syscall, - [258] sys_ni_syscall, - [__NR_mbind] sys_ni_syscall, /* sys_mbind */ - [__NR_get_mempolicy] sys_ni_syscall, /* sys_get_mempolicy */ - [__NR_set_mempolicy] sys_ni_syscall, /* sys_set_mempolicy */ - [__NR_mq_open] sys_ni_syscall, /* sys_mq_open */ - [__NR_mq_unlink] sys_ni_syscall, /* sys_mq_unlink */ - [__NR_mq_timedsend] sys_ni_syscall, /* sys_mq_timedsend */ - [__NR_mq_timedreceive] sys_ni_syscall, /* sys_mq_timedreceive */ - [__NR_mq_notify] sys_ni_syscall, /* sys_mq_notify */ - [__NR_mq_getsetattr] sys_ni_syscall, /* sys_mq_getsetattr */ - [__NR_kexec_load] sys_ni_syscall, /* sys_kexec_load */ - [__NR_add_key] sys_ni_syscall, /* sys_add_key */ - [__NR_request_key] sys_ni_syscall, /* sys_request_key */ - [__NR_keyctl] sys_ni_syscall, /* sys_keyctl */ - [__NR_waitid] sys_ni_syscall, /* sys_waitid */ - [__NR_ioprio_set] sys_ni_syscall, /* sys_ioprio_set */ - [__NR_ioprio_get] sys_ni_syscall, /* sys_ioprio_get */ - [__NR_inotify_init] sys_ni_syscall, /* sys_inotify_init */ - [__NR_inotify_add_watch] sys_ni_syscall, /* sys_inotify_add_watch */ - [__NR_inotify_rm_watch] sys_ni_syscall, /* sys_inotify_rm_watch */ - [__NR_spu_run] sys_ni_syscall, /* sys_spu_run */ - [__NR_spu_create] sys_ni_syscall, /* sys_spu_create */ - [__NR_pselect6] sys_ni_syscall, /* sys_pselect */ - [__NR_ppoll] sys_ni_syscall, /* sys_ppoll */ - [__NR_unshare] sys_unshare, -}; - -long spu_sys_callback(struct spu_syscall_block *s) -{ - long (*syscall)(u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6); - - BUILD_BUG_ON(ARRAY_SIZE(spu_syscall_table) != __NR_syscalls); - - syscall = spu_syscall_table[s->nr_ret]; - - if (s->nr_ret >= __NR_syscalls) { - pr_debug("%s: invalid syscall #%ld", __FUNCTION__, s->nr_ret); - return -ENOSYS; - } - -#ifdef DEBUG - print_symbol(KERN_DEBUG "SPU-syscall %s:", (unsigned long)syscall); - printk("syscall%ld(%lx, %lx, %lx, %lx, %lx, %lx)\n", - s->nr_ret, - s->parm[0], s->parm[1], s->parm[2], - s->parm[3], s->parm[4], s->parm[5]); -#endif - - return syscall(s->parm[0], s->parm[1], s->parm[2], - s->parm[3], s->parm[4], s->parm[5]); -} -EXPORT_SYMBOL_GPL(spu_sys_callback); diff --git a/trunk/arch/powerpc/platforms/cell/spufs/backing_ops.c b/trunk/arch/powerpc/platforms/cell/spufs/backing_ops.c index f1d35ddc9df3..a5c489a53c61 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/backing_ops.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/backing_ops.c @@ -285,49 +285,6 @@ static void spu_backing_runcntl_stop(struct spu_context *ctx) spu_backing_runcntl_write(ctx, SPU_RUNCNTL_STOP); } -static int spu_backing_set_mfc_query(struct spu_context * ctx, u32 mask, - u32 mode) -{ - struct spu_problem_collapsed *prob = &ctx->csa.prob; - int ret; - - spin_lock(&ctx->csa.register_lock); - ret = -EAGAIN; - if (prob->dma_querytype_RW) - goto out; - ret = 0; - /* FIXME: what are the side-effects of this? */ - prob->dma_querymask_RW = mask; - prob->dma_querytype_RW = mode; -out: - spin_unlock(&ctx->csa.register_lock); - - return ret; -} - -static u32 spu_backing_read_mfc_tagstatus(struct spu_context * ctx) -{ - return ctx->csa.prob.dma_tagstatus_R; -} - -static u32 spu_backing_get_mfc_free_elements(struct spu_context *ctx) -{ - return ctx->csa.prob.dma_qstatus_R; -} - -static int spu_backing_send_mfc_command(struct spu_context *ctx, - struct mfc_dma_command *cmd) -{ - int ret; - - spin_lock(&ctx->csa.register_lock); - ret = -EAGAIN; - /* FIXME: set up priv2->puq */ - spin_unlock(&ctx->csa.register_lock); - - return ret; -} - struct spu_context_ops spu_backing_ops = { .mbox_read = spu_backing_mbox_read, .mbox_stat_read = spu_backing_mbox_stat_read, @@ -348,8 +305,4 @@ struct spu_context_ops spu_backing_ops = { .get_ls = spu_backing_get_ls, .runcntl_write = spu_backing_runcntl_write, .runcntl_stop = spu_backing_runcntl_stop, - .set_mfc_query = spu_backing_set_mfc_query, - .read_mfc_tagstatus = spu_backing_read_mfc_tagstatus, - .get_mfc_free_elements = spu_backing_get_mfc_free_elements, - .send_mfc_command = spu_backing_send_mfc_command, }; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/context.c b/trunk/arch/powerpc/platforms/cell/spufs/context.c index 8bb33abfad17..336f238102fd 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/context.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/context.c @@ -27,7 +27,7 @@ #include #include "spufs.h" -struct spu_context *alloc_spu_context(void) +struct spu_context *alloc_spu_context(struct address_space *local_store) { struct spu_context *ctx; ctx = kmalloc(sizeof *ctx, GFP_KERNEL); @@ -47,17 +47,10 @@ struct spu_context *alloc_spu_context(void) init_waitqueue_head(&ctx->ibox_wq); init_waitqueue_head(&ctx->wbox_wq); init_waitqueue_head(&ctx->stop_wq); - init_waitqueue_head(&ctx->mfc_wq); ctx->ibox_fasync = NULL; ctx->wbox_fasync = NULL; - ctx->mfc_fasync = NULL; - ctx->mfc = NULL; - ctx->tagwait = 0; ctx->state = SPU_STATE_SAVED; - ctx->local_store = NULL; - ctx->cntl = NULL; - ctx->signal1 = NULL; - ctx->signal2 = NULL; + ctx->local_store = local_store; ctx->spu = NULL; ctx->ops = &spu_backing_ops; ctx->owner = get_task_mm(current); @@ -75,6 +68,8 @@ void destroy_spu_context(struct kref *kref) ctx = container_of(kref, struct spu_context, kref); down_write(&ctx->state_sema); spu_deactivate(ctx); + ctx->ibox_fasync = NULL; + ctx->wbox_fasync = NULL; up_write(&ctx->state_sema); spu_fini_csa(&ctx->csa); kfree(ctx); @@ -114,16 +109,7 @@ void spu_release(struct spu_context *ctx) void spu_unmap_mappings(struct spu_context *ctx) { - if (ctx->local_store) - unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1); - if (ctx->mfc) - unmap_mapping_range(ctx->mfc, 0, 0x4000, 1); - if (ctx->cntl) - unmap_mapping_range(ctx->cntl, 0, 0x4000, 1); - if (ctx->signal1) - unmap_mapping_range(ctx->signal1, 0, 0x4000, 1); - if (ctx->signal2) - unmap_mapping_range(ctx->signal2, 0, 0x4000, 1); + unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1); } int spu_acquire_runnable(struct spu_context *ctx) diff --git a/trunk/arch/powerpc/platforms/cell/spufs/file.c b/trunk/arch/powerpc/platforms/cell/spufs/file.c index 366185e92667..dfa649c9b956 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/file.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/file.c @@ -20,8 +20,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#undef DEBUG - #include #include #include @@ -41,10 +39,8 @@ static int spufs_mem_open(struct inode *inode, struct file *file) { struct spufs_inode_info *i = SPUFS_I(inode); - struct spu_context *ctx = i->i_ctx; - file->private_data = ctx; - file->f_mapping = inode->i_mapping; - ctx->local_store = inode->i_mapping; + file->private_data = i->i_ctx; + file->f_mapping = i->i_ctx->local_store; return 0; } @@ -88,7 +84,7 @@ spufs_mem_write(struct file *file, const char __user *buffer, return ret; } -#ifdef CONFIG_SPUFS_MMAP +#ifdef CONFIG_SPARSEMEM static struct page * spufs_mem_mmap_nopage(struct vm_area_struct *vma, unsigned long address, int *type) @@ -140,113 +136,11 @@ static struct file_operations spufs_mem_fops = { .read = spufs_mem_read, .write = spufs_mem_write, .llseek = generic_file_llseek, -#ifdef CONFIG_SPUFS_MMAP +#ifdef CONFIG_SPARSEMEM .mmap = spufs_mem_mmap, #endif }; -#ifdef CONFIG_SPUFS_MMAP -static struct page *spufs_ps_nopage(struct vm_area_struct *vma, - unsigned long address, - int *type, unsigned long ps_offs) -{ - struct page *page = NOPAGE_SIGBUS; - int fault_type = VM_FAULT_SIGBUS; - struct spu_context *ctx = vma->vm_file->private_data; - unsigned long offset = address - vma->vm_start; - unsigned long area; - int ret; - - offset += vma->vm_pgoff << PAGE_SHIFT; - if (offset >= 0x4000) - goto out; - - ret = spu_acquire_runnable(ctx); - if (ret) - goto out; - - area = ctx->spu->problem_phys + ps_offs; - page = pfn_to_page((area + offset) >> PAGE_SHIFT); - fault_type = VM_FAULT_MINOR; - page_cache_get(page); - - spu_release(ctx); - - out: - if (type) - *type = fault_type; - - return page; -} - -static struct page *spufs_cntl_mmap_nopage(struct vm_area_struct *vma, - unsigned long address, int *type) -{ - return spufs_ps_nopage(vma, address, type, 0x4000); -} - -static struct vm_operations_struct spufs_cntl_mmap_vmops = { - .nopage = spufs_cntl_mmap_nopage, -}; - -/* - * mmap support for problem state control area [0x4000 - 0x4fff]. - * Mapping this area requires that the application have CAP_SYS_RAWIO, - * as these registers require special care when read/writing. - */ -static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma) -{ - if (!(vma->vm_flags & VM_SHARED)) - return -EINVAL; - - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - - vma->vm_flags |= VM_RESERVED; - vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); - - vma->vm_ops = &spufs_cntl_mmap_vmops; - return 0; -} -#endif - -static int spufs_cntl_open(struct inode *inode, struct file *file) -{ - struct spufs_inode_info *i = SPUFS_I(inode); - struct spu_context *ctx = i->i_ctx; - - file->private_data = ctx; - file->f_mapping = inode->i_mapping; - ctx->cntl = inode->i_mapping; - return 0; -} - -static ssize_t -spufs_cntl_read(struct file *file, char __user *buffer, - size_t size, loff_t *pos) -{ - /* FIXME: read from spu status */ - return -EINVAL; -} - -static ssize_t -spufs_cntl_write(struct file *file, const char __user *buffer, - size_t size, loff_t *pos) -{ - /* FIXME: write to runctl bit */ - return -EINVAL; -} - -static struct file_operations spufs_cntl_fops = { - .open = spufs_cntl_open, - .read = spufs_cntl_read, - .write = spufs_cntl_write, -#ifdef CONFIG_SPUFS_MMAP - .mmap = spufs_cntl_mmap, -#endif -}; - static int spufs_regs_open(struct inode *inode, struct file *file) { @@ -607,16 +501,6 @@ static struct file_operations spufs_wbox_stat_fops = { .read = spufs_wbox_stat_read, }; -static int spufs_signal1_open(struct inode *inode, struct file *file) -{ - struct spufs_inode_info *i = SPUFS_I(inode); - struct spu_context *ctx = i->i_ctx; - file->private_data = ctx; - file->f_mapping = inode->i_mapping; - ctx->signal1 = inode->i_mapping; - return nonseekable_open(inode, file); -} - static ssize_t spufs_signal1_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { @@ -657,50 +541,12 @@ static ssize_t spufs_signal1_write(struct file *file, const char __user *buf, return 4; } -#ifdef CONFIG_SPUFS_MMAP -static struct page *spufs_signal1_mmap_nopage(struct vm_area_struct *vma, - unsigned long address, int *type) -{ - return spufs_ps_nopage(vma, address, type, 0x14000); -} - -static struct vm_operations_struct spufs_signal1_mmap_vmops = { - .nopage = spufs_signal1_mmap_nopage, -}; - -static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma) -{ - if (!(vma->vm_flags & VM_SHARED)) - return -EINVAL; - - vma->vm_flags |= VM_RESERVED; - vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); - - vma->vm_ops = &spufs_signal1_mmap_vmops; - return 0; -} -#endif - static struct file_operations spufs_signal1_fops = { - .open = spufs_signal1_open, + .open = spufs_pipe_open, .read = spufs_signal1_read, .write = spufs_signal1_write, -#ifdef CONFIG_SPUFS_MMAP - .mmap = spufs_signal1_mmap, -#endif }; -static int spufs_signal2_open(struct inode *inode, struct file *file) -{ - struct spufs_inode_info *i = SPUFS_I(inode); - struct spu_context *ctx = i->i_ctx; - file->private_data = ctx; - file->f_mapping = inode->i_mapping; - ctx->signal2 = inode->i_mapping; - return nonseekable_open(inode, file); -} - static ssize_t spufs_signal2_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { @@ -743,39 +589,10 @@ static ssize_t spufs_signal2_write(struct file *file, const char __user *buf, return 4; } -#ifdef CONFIG_SPUFS_MMAP -static struct page *spufs_signal2_mmap_nopage(struct vm_area_struct *vma, - unsigned long address, int *type) -{ - return spufs_ps_nopage(vma, address, type, 0x1c000); -} - -static struct vm_operations_struct spufs_signal2_mmap_vmops = { - .nopage = spufs_signal2_mmap_nopage, -}; - -static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma) -{ - if (!(vma->vm_flags & VM_SHARED)) - return -EINVAL; - - /* FIXME: */ - vma->vm_flags |= VM_RESERVED; - vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); - - vma->vm_ops = &spufs_signal2_mmap_vmops; - return 0; -} -#endif - static struct file_operations spufs_signal2_fops = { - .open = spufs_signal2_open, + .open = spufs_pipe_open, .read = spufs_signal2_read, .write = spufs_signal2_write, -#ifdef CONFIG_SPUFS_MMAP - .mmap = spufs_signal2_mmap, -#endif }; static void spufs_signal1_type_set(void *data, u64 val) @@ -824,332 +641,6 @@ static u64 spufs_signal2_type_get(void *data) DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get, spufs_signal2_type_set, "%llu"); -#ifdef CONFIG_SPUFS_MMAP -static struct page *spufs_mfc_mmap_nopage(struct vm_area_struct *vma, - unsigned long address, int *type) -{ - return spufs_ps_nopage(vma, address, type, 0x3000); -} - -static struct vm_operations_struct spufs_mfc_mmap_vmops = { - .nopage = spufs_mfc_mmap_nopage, -}; - -/* - * mmap support for problem state MFC DMA area [0x0000 - 0x0fff]. - * Mapping this area requires that the application have CAP_SYS_RAWIO, - * as these registers require special care when read/writing. - */ -static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma) -{ - if (!(vma->vm_flags & VM_SHARED)) - return -EINVAL; - - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - - vma->vm_flags |= VM_RESERVED; - vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); - - vma->vm_ops = &spufs_mfc_mmap_vmops; - return 0; -} -#endif - -static int spufs_mfc_open(struct inode *inode, struct file *file) -{ - struct spufs_inode_info *i = SPUFS_I(inode); - struct spu_context *ctx = i->i_ctx; - - /* we don't want to deal with DMA into other processes */ - if (ctx->owner != current->mm) - return -EINVAL; - - if (atomic_read(&inode->i_count) != 1) - return -EBUSY; - - file->private_data = ctx; - return nonseekable_open(inode, file); -} - -/* interrupt-level mfc callback function. */ -void spufs_mfc_callback(struct spu *spu) -{ - struct spu_context *ctx = spu->ctx; - - wake_up_all(&ctx->mfc_wq); - - pr_debug("%s %s\n", __FUNCTION__, spu->name); - if (ctx->mfc_fasync) { - u32 free_elements, tagstatus; - unsigned int mask; - - /* no need for spu_acquire in interrupt context */ - free_elements = ctx->ops->get_mfc_free_elements(ctx); - tagstatus = ctx->ops->read_mfc_tagstatus(ctx); - - mask = 0; - if (free_elements & 0xffff) - mask |= POLLOUT; - if (tagstatus & ctx->tagwait) - mask |= POLLIN; - - kill_fasync(&ctx->mfc_fasync, SIGIO, mask); - } -} - -static int spufs_read_mfc_tagstatus(struct spu_context *ctx, u32 *status) -{ - /* See if there is one tag group is complete */ - /* FIXME we need locking around tagwait */ - *status = ctx->ops->read_mfc_tagstatus(ctx) & ctx->tagwait; - ctx->tagwait &= ~*status; - if (*status) - return 1; - - /* enable interrupt waiting for any tag group, - may silently fail if interrupts are already enabled */ - ctx->ops->set_mfc_query(ctx, ctx->tagwait, 1); - return 0; -} - -static ssize_t spufs_mfc_read(struct file *file, char __user *buffer, - size_t size, loff_t *pos) -{ - struct spu_context *ctx = file->private_data; - int ret = -EINVAL; - u32 status; - - if (size != 4) - goto out; - - spu_acquire(ctx); - if (file->f_flags & O_NONBLOCK) { - status = ctx->ops->read_mfc_tagstatus(ctx); - if (!(status & ctx->tagwait)) - ret = -EAGAIN; - else - ctx->tagwait &= ~status; - } else { - ret = spufs_wait(ctx->mfc_wq, - spufs_read_mfc_tagstatus(ctx, &status)); - } - spu_release(ctx); - - if (ret) - goto out; - - ret = 4; - if (copy_to_user(buffer, &status, 4)) - ret = -EFAULT; - -out: - return ret; -} - -static int spufs_check_valid_dma(struct mfc_dma_command *cmd) -{ - pr_debug("queueing DMA %x %lx %x %x %x\n", cmd->lsa, - cmd->ea, cmd->size, cmd->tag, cmd->cmd); - - switch (cmd->cmd) { - case MFC_PUT_CMD: - case MFC_PUTF_CMD: - case MFC_PUTB_CMD: - case MFC_GET_CMD: - case MFC_GETF_CMD: - case MFC_GETB_CMD: - break; - default: - pr_debug("invalid DMA opcode %x\n", cmd->cmd); - return -EIO; - } - - if ((cmd->lsa & 0xf) != (cmd->ea &0xf)) { - pr_debug("invalid DMA alignment, ea %lx lsa %x\n", - cmd->ea, cmd->lsa); - return -EIO; - } - - switch (cmd->size & 0xf) { - case 1: - break; - case 2: - if (cmd->lsa & 1) - goto error; - break; - case 4: - if (cmd->lsa & 3) - goto error; - break; - case 8: - if (cmd->lsa & 7) - goto error; - break; - case 0: - if (cmd->lsa & 15) - goto error; - break; - error: - default: - pr_debug("invalid DMA alignment %x for size %x\n", - cmd->lsa & 0xf, cmd->size); - return -EIO; - } - - if (cmd->size > 16 * 1024) { - pr_debug("invalid DMA size %x\n", cmd->size); - return -EIO; - } - - if (cmd->tag & 0xfff0) { - /* we reserve the higher tag numbers for kernel use */ - pr_debug("invalid DMA tag\n"); - return -EIO; - } - - if (cmd->class) { - /* not supported in this version */ - pr_debug("invalid DMA class\n"); - return -EIO; - } - - return 0; -} - -static int spu_send_mfc_command(struct spu_context *ctx, - struct mfc_dma_command cmd, - int *error) -{ - *error = ctx->ops->send_mfc_command(ctx, &cmd); - if (*error == -EAGAIN) { - /* wait for any tag group to complete - so we have space for the new command */ - ctx->ops->set_mfc_query(ctx, ctx->tagwait, 1); - /* try again, because the queue might be - empty again */ - *error = ctx->ops->send_mfc_command(ctx, &cmd); - if (*error == -EAGAIN) - return 0; - } - return 1; -} - -static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer, - size_t size, loff_t *pos) -{ - struct spu_context *ctx = file->private_data; - struct mfc_dma_command cmd; - int ret = -EINVAL; - - if (size != sizeof cmd) - goto out; - - ret = -EFAULT; - if (copy_from_user(&cmd, buffer, sizeof cmd)) - goto out; - - ret = spufs_check_valid_dma(&cmd); - if (ret) - goto out; - - spu_acquire_runnable(ctx); - if (file->f_flags & O_NONBLOCK) { - ret = ctx->ops->send_mfc_command(ctx, &cmd); - } else { - int status; - ret = spufs_wait(ctx->mfc_wq, - spu_send_mfc_command(ctx, cmd, &status)); - if (status) - ret = status; - } - spu_release(ctx); - - if (ret) - goto out; - - ctx->tagwait |= 1 << cmd.tag; - -out: - return ret; -} - -static unsigned int spufs_mfc_poll(struct file *file,poll_table *wait) -{ - struct spu_context *ctx = file->private_data; - u32 free_elements, tagstatus; - unsigned int mask; - - spu_acquire(ctx); - ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2); - free_elements = ctx->ops->get_mfc_free_elements(ctx); - tagstatus = ctx->ops->read_mfc_tagstatus(ctx); - spu_release(ctx); - - poll_wait(file, &ctx->mfc_wq, wait); - - mask = 0; - if (free_elements & 0xffff) - mask |= POLLOUT | POLLWRNORM; - if (tagstatus & ctx->tagwait) - mask |= POLLIN | POLLRDNORM; - - pr_debug("%s: free %d tagstatus %d tagwait %d\n", __FUNCTION__, - free_elements, tagstatus, ctx->tagwait); - - return mask; -} - -static int spufs_mfc_flush(struct file *file) -{ - struct spu_context *ctx = file->private_data; - int ret; - - spu_acquire(ctx); -#if 0 -/* this currently hangs */ - ret = spufs_wait(ctx->mfc_wq, - ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2)); - if (ret) - goto out; - ret = spufs_wait(ctx->mfc_wq, - ctx->ops->read_mfc_tagstatus(ctx) == ctx->tagwait); -out: -#else - ret = 0; -#endif - spu_release(ctx); - - return ret; -} - -static int spufs_mfc_fsync(struct file *file, struct dentry *dentry, - int datasync) -{ - return spufs_mfc_flush(file); -} - -static int spufs_mfc_fasync(int fd, struct file *file, int on) -{ - struct spu_context *ctx = file->private_data; - - return fasync_helper(fd, file, on, &ctx->mfc_fasync); -} - -static struct file_operations spufs_mfc_fops = { - .open = spufs_mfc_open, - .read = spufs_mfc_read, - .write = spufs_mfc_write, - .poll = spufs_mfc_poll, - .flush = spufs_mfc_flush, - .fsync = spufs_mfc_fsync, - .fasync = spufs_mfc_fasync, -#ifdef CONFIG_SPUFS_MMAP - .mmap = spufs_mfc_mmap, -#endif -}; - static void spufs_npc_set(void *data, u64 val) { struct spu_context *ctx = data; @@ -1292,8 +783,6 @@ struct tree_descr spufs_dir_contents[] = { { "signal2", &spufs_signal2_fops, 0666, }, { "signal1_type", &spufs_signal1_type, 0666, }, { "signal2_type", &spufs_signal2_type, 0666, }, - { "mfc", &spufs_mfc_fops, 0666, }, - { "cntl", &spufs_cntl_fops, 0666, }, { "npc", &spufs_npc_ops, 0666, }, { "fpcr", &spufs_fpcr_fops, 0666, }, { "decr", &spufs_decr_ops, 0666, }, diff --git a/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c b/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c index a13a8b5a014d..5445719bff79 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c @@ -232,59 +232,6 @@ static void spu_hw_runcntl_stop(struct spu_context *ctx) spin_unlock_irq(&ctx->spu->register_lock); } -static int spu_hw_set_mfc_query(struct spu_context * ctx, u32 mask, u32 mode) -{ - struct spu_problem *prob = ctx->spu->problem; - int ret; - - spin_lock_irq(&ctx->spu->register_lock); - ret = -EAGAIN; - if (in_be32(&prob->dma_querytype_RW)) - goto out; - ret = 0; - out_be32(&prob->dma_querymask_RW, mask); - out_be32(&prob->dma_querytype_RW, mode); -out: - spin_unlock_irq(&ctx->spu->register_lock); - return ret; -} - -static u32 spu_hw_read_mfc_tagstatus(struct spu_context * ctx) -{ - return in_be32(&ctx->spu->problem->dma_tagstatus_R); -} - -static u32 spu_hw_get_mfc_free_elements(struct spu_context *ctx) -{ - return in_be32(&ctx->spu->problem->dma_qstatus_R); -} - -static int spu_hw_send_mfc_command(struct spu_context *ctx, - struct mfc_dma_command *cmd) -{ - u32 status; - struct spu_problem *prob = ctx->spu->problem; - - spin_lock_irq(&ctx->spu->register_lock); - out_be32(&prob->mfc_lsa_W, cmd->lsa); - out_be64(&prob->mfc_ea_W, cmd->ea); - out_be32(&prob->mfc_union_W.by32.mfc_size_tag32, - cmd->size << 16 | cmd->tag); - out_be32(&prob->mfc_union_W.by32.mfc_class_cmd32, - cmd->class << 16 | cmd->cmd); - status = in_be32(&prob->mfc_union_W.by32.mfc_class_cmd32); - spin_unlock_irq(&ctx->spu->register_lock); - - switch (status & 0xffff) { - case 0: - return 0; - case 2: - return -EAGAIN; - default: - return -EINVAL; - } -} - struct spu_context_ops spu_hw_ops = { .mbox_read = spu_hw_mbox_read, .mbox_stat_read = spu_hw_mbox_stat_read, @@ -305,8 +252,4 @@ struct spu_context_ops spu_hw_ops = { .get_ls = spu_hw_get_ls, .runcntl_write = spu_hw_runcntl_write, .runcntl_stop = spu_hw_runcntl_stop, - .set_mfc_query = spu_hw_set_mfc_query, - .read_mfc_tagstatus = spu_hw_read_mfc_tagstatus, - .get_mfc_free_elements = spu_hw_get_mfc_free_elements, - .send_mfc_command = spu_hw_send_mfc_command, }; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/inode.c b/trunk/arch/powerpc/platforms/cell/spufs/inode.c index d9554199afa7..5be40aa483fd 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/inode.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/inode.c @@ -241,7 +241,7 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, int mode) inode->i_gid = dir->i_gid; inode->i_mode &= S_ISGID; } - ctx = alloc_spu_context(); + ctx = alloc_spu_context(inode->i_mapping); SPUFS_I(inode)->i_ctx = ctx; if (!ctx) goto out_iput; @@ -442,7 +442,7 @@ static struct file_system_type spufs_type = { .kill_sb = kill_litter_super, }; -static int __init spufs_init(void) +static int spufs_init(void) { int ret; ret = -ENOMEM; @@ -472,7 +472,7 @@ static int __init spufs_init(void) } module_init(spufs_init); -static void __exit spufs_exit(void) +static void spufs_exit(void) { spu_sched_exit(); unregister_spu_syscalls(&spufs_calls); diff --git a/trunk/arch/powerpc/platforms/cell/spufs/run.c b/trunk/arch/powerpc/platforms/cell/spufs/run.c index c04e078c0fe5..18ea8866c61a 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/run.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/run.c @@ -76,90 +76,6 @@ static inline int spu_reacquire_runnable(struct spu_context *ctx, u32 *npc, return 0; } -/* - * SPU syscall restarting is tricky because we violate the basic - * assumption that the signal handler is running on the interrupted - * thread. Here instead, the handler runs on PowerPC user space code, - * while the syscall was called from the SPU. - * This means we can only do a very rough approximation of POSIX - * signal semantics. - */ -int spu_handle_restartsys(struct spu_context *ctx, long *spu_ret, - unsigned int *npc) -{ - int ret; - - switch (*spu_ret) { - case -ERESTARTSYS: - case -ERESTARTNOINTR: - /* - * Enter the regular syscall restarting for - * sys_spu_run, then restart the SPU syscall - * callback. - */ - *npc -= 8; - ret = -ERESTARTSYS; - break; - case -ERESTARTNOHAND: - case -ERESTART_RESTARTBLOCK: - /* - * Restart block is too hard for now, just return -EINTR - * to the SPU. - * ERESTARTNOHAND comes from sys_pause, we also return - * -EINTR from there. - * Assume that we need to be restarted ourselves though. - */ - *spu_ret = -EINTR; - ret = -ERESTARTSYS; - break; - default: - printk(KERN_WARNING "%s: unexpected return code %ld\n", - __FUNCTION__, *spu_ret); - ret = 0; - } - return ret; -} - -int spu_process_callback(struct spu_context *ctx) -{ - struct spu_syscall_block s; - u32 ls_pointer, npc; - char *ls; - long spu_ret; - int ret; - - /* get syscall block from local store */ - npc = ctx->ops->npc_read(ctx); - ls = ctx->ops->get_ls(ctx); - ls_pointer = *(u32*)(ls + npc); - if (ls_pointer > (LS_SIZE - sizeof(s))) - return -EFAULT; - memcpy(&s, ls + ls_pointer, sizeof (s)); - - /* do actual syscall without pinning the spu */ - ret = 0; - spu_ret = -ENOSYS; - npc += 4; - - if (s.nr_ret < __NR_syscalls) { - spu_release(ctx); - /* do actual system call from here */ - spu_ret = spu_sys_callback(&s); - if (spu_ret <= -ERESTARTSYS) { - ret = spu_handle_restartsys(ctx, &spu_ret, &npc); - } - spu_acquire(ctx); - if (ret == -ERESTARTSYS) - return ret; - } - - /* write result, jump over indirect pointer */ - memcpy(ls + ls_pointer, &spu_ret, sizeof (spu_ret)); - ctx->ops->npc_write(ctx, npc); - ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE); - return ret; -} - static inline int spu_process_events(struct spu_context *ctx) { struct spu *spu = ctx->spu; @@ -191,13 +107,6 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx, ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, status)); if (unlikely(ret)) break; - if ((*status & SPU_STATUS_STOPPED_BY_STOP) && - (*status >> SPU_STOP_STATUS_SHIFT == 0x2104)) { - ret = spu_process_callback(ctx); - if (ret) - break; - *status &= ~SPU_STATUS_STOPPED_BY_STOP; - } if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) { ret = spu_reacquire_runnable(ctx, npc, status); if (ret) diff --git a/trunk/arch/powerpc/platforms/cell/spufs/sched.c b/trunk/arch/powerpc/platforms/cell/spufs/sched.c index bf652cd77000..963182fbd1aa 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/sched.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/sched.c @@ -180,7 +180,6 @@ static inline void bind_context(struct spu *spu, struct spu_context *ctx) spu->ibox_callback = spufs_ibox_callback; spu->wbox_callback = spufs_wbox_callback; spu->stop_callback = spufs_stop_callback; - spu->mfc_callback = spufs_mfc_callback; mb(); spu_unmap_mappings(ctx); spu_restore(&ctx->csa, spu); @@ -198,7 +197,6 @@ static inline void unbind_context(struct spu *spu, struct spu_context *ctx) spu->ibox_callback = NULL; spu->wbox_callback = NULL; spu->stop_callback = NULL; - spu->mfc_callback = NULL; spu->mm = NULL; spu->pid = 0; spu->prio = MAX_PRIO; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/spufs.h b/trunk/arch/powerpc/platforms/cell/spufs/spufs.h index 4485738e2102..db2601f0abd5 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/trunk/arch/powerpc/platforms/cell/spufs/spufs.h @@ -43,11 +43,7 @@ struct spu_context { struct spu *spu; /* pointer to a physical SPU */ struct spu_state csa; /* SPU context save area. */ spinlock_t mmio_lock; /* protects mmio access */ - struct address_space *local_store; /* local store mapping. */ - struct address_space *mfc; /* 'mfc' area mappings. */ - struct address_space *cntl; /* 'control' area mappings. */ - struct address_space *signal1; /* 'signal1' area mappings. */ - struct address_space *signal2; /* 'signal2' area mappings. */ + struct address_space *local_store;/* local store backing store */ enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state; struct rw_semaphore state_sema; @@ -59,27 +55,13 @@ struct spu_context { wait_queue_head_t ibox_wq; wait_queue_head_t wbox_wq; wait_queue_head_t stop_wq; - wait_queue_head_t mfc_wq; struct fasync_struct *ibox_fasync; struct fasync_struct *wbox_fasync; - struct fasync_struct *mfc_fasync; - u32 tagwait; struct spu_context_ops *ops; struct work_struct reap_work; u64 flags; }; -struct mfc_dma_command { - int32_t pad; /* reserved */ - uint32_t lsa; /* local storage address */ - uint64_t ea; /* effective address */ - uint16_t size; /* transfer size */ - uint16_t tag; /* command tag */ - uint16_t class; /* class ID */ - uint16_t cmd; /* command opcode */ -}; - - /* SPU context query/set operations. */ struct spu_context_ops { int (*mbox_read) (struct spu_context * ctx, u32 * data); @@ -102,11 +84,6 @@ struct spu_context_ops { char*(*get_ls) (struct spu_context * ctx); void (*runcntl_write) (struct spu_context * ctx, u32 data); void (*runcntl_stop) (struct spu_context * ctx); - int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode); - u32 (*read_mfc_tagstatus)(struct spu_context * ctx); - u32 (*get_mfc_free_elements)(struct spu_context *ctx); - int (*send_mfc_command)(struct spu_context *ctx, - struct mfc_dma_command *cmd); }; extern struct spu_context_ops spu_hw_ops; @@ -129,7 +106,7 @@ long spufs_create_thread(struct nameidata *nd, extern struct file_operations spufs_context_fops; /* context management */ -struct spu_context * alloc_spu_context(void); +struct spu_context * alloc_spu_context(struct address_space *local_store); void destroy_spu_context(struct kref *kref); struct spu_context * get_spu_context(struct spu_context *ctx); int put_spu_context(struct spu_context *ctx); @@ -182,6 +159,5 @@ size_t spu_ibox_read(struct spu_context *ctx, u32 *data); void spufs_ibox_callback(struct spu *spu); void spufs_wbox_callback(struct spu *spu); void spufs_stop_callback(struct spu *spu); -void spufs_mfc_callback(struct spu *spu); #endif diff --git a/trunk/arch/powerpc/platforms/cell/spufs/switch.c b/trunk/arch/powerpc/platforms/cell/spufs/switch.c index 97898d5d34e5..212db28531fa 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/switch.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/switch.c @@ -2145,8 +2145,7 @@ static void init_priv1(struct spu_state *csa) csa->priv1.int_mask_class1_RW = CLASS1_ENABLE_SEGMENT_FAULT_INTR | CLASS1_ENABLE_STORAGE_FAULT_INTR; csa->priv1.int_mask_class2_RW = CLASS2_ENABLE_SPU_STOP_INTR | - CLASS2_ENABLE_SPU_HALT_INTR | - CLASS2_ENABLE_SPU_DMA_TAG_GROUP_COMPLETE_INTR; + CLASS2_ENABLE_SPU_HALT_INTR; } static void init_priv2(struct spu_state *csa) diff --git a/trunk/arch/powerpc/platforms/chrp/chrp.h b/trunk/arch/powerpc/platforms/chrp/chrp.h index 63f0aee4c158..814f54742e0f 100644 --- a/trunk/arch/powerpc/platforms/chrp/chrp.h +++ b/trunk/arch/powerpc/platforms/chrp/chrp.h @@ -8,4 +8,4 @@ extern int chrp_set_rtc_time(struct rtc_time *); extern long chrp_time_init(void); extern void chrp_find_bridges(void); -extern void chrp_event_scan(unsigned long); +extern void chrp_event_scan(void); diff --git a/trunk/arch/powerpc/platforms/chrp/setup.c b/trunk/arch/powerpc/platforms/chrp/setup.c index 23a201718704..8bf4307e323d 100644 --- a/trunk/arch/powerpc/platforms/chrp/setup.c +++ b/trunk/arch/powerpc/platforms/chrp/setup.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -62,10 +61,6 @@ EXPORT_SYMBOL(_chrp_type); struct mpic *chrp_mpic; -/* Used for doing CHRP event-scans */ -DEFINE_PER_CPU(struct timer_list, heartbeat_timer); -unsigned long event_scan_interval; - /* * XXX this should be in xmon.h, but putting it there means xmon.h * has to include (to get irqreturn_t), which @@ -234,6 +229,8 @@ void __init chrp_setup_arch(void) { struct device_node *root = find_path_device ("/"); char *machine = NULL; + struct device_node *device; + unsigned int *p = NULL; /* init to some ~sane value until calibrate_delay() runs */ loops_per_jiffy = 50000000/HZ; @@ -290,11 +287,22 @@ void __init chrp_setup_arch(void) */ sio_init(); - pci_create_OF_bus_map(); + /* Get the event scan rate for the rtas so we know how + * often it expects a heartbeat. -- Cort + */ + device = find_devices("rtas"); + if (device) + p = (unsigned int *) get_property + (device, "rtas-event-scan-rate", NULL); + if (p && *p) { + ppc_md.heartbeat = chrp_event_scan; + ppc_md.heartbeat_reset = HZ / (*p * 30) - 1; + ppc_md.heartbeat_count = 1; + printk("RTAS Event Scan Rate: %u (%lu jiffies)\n", + *p, ppc_md.heartbeat_reset); + } -#ifdef CONFIG_SMP - smp_ops = &chrp_smp_ops; -#endif /* CONFIG_SMP */ + pci_create_OF_bus_map(); /* * Print the banner, then scroll down so boot progress @@ -304,7 +312,7 @@ void __init chrp_setup_arch(void) } void -chrp_event_scan(unsigned long unused) +chrp_event_scan(void) { unsigned char log[1024]; int ret = 0; @@ -312,8 +320,7 @@ chrp_event_scan(unsigned long unused) /* XXX: we should loop until the hardware says no more error logs -- Cort */ rtas_call(rtas_token("event-scan"), 4, 1, &ret, 0xffffffff, 0, __pa(log), 1024); - mod_timer(&__get_cpu_var(heartbeat_timer), - jiffies + event_scan_interval); + ppc_md.heartbeat_count = ppc_md.heartbeat_reset; } /* @@ -458,9 +465,6 @@ void __init chrp_init_IRQ(void) void __init chrp_init2(void) { - struct device_node *device; - unsigned int *p = NULL; - #ifdef CONFIG_NVRAM chrp_nvram_init(); #endif @@ -472,53 +476,12 @@ chrp_init2(void) request_region(0x80,0x10,"dma page reg"); request_region(0xc0,0x20,"dma2"); - /* Get the event scan rate for the rtas so we know how - * often it expects a heartbeat. -- Cort - */ - device = find_devices("rtas"); - if (device) - p = (unsigned int *) get_property - (device, "rtas-event-scan-rate", NULL); - if (p && *p) { - /* - * Arrange to call chrp_event_scan at least *p times - * per minute. We use 59 rather than 60 here so that - * the rate will be slightly higher than the minimum. - * This all assumes we don't do hotplug CPU on any - * machine that needs the event scans done. - */ - unsigned long interval, offset; - int cpu, ncpus; - struct timer_list *timer; - - interval = HZ * 59 / *p; - offset = HZ; - ncpus = num_online_cpus(); - event_scan_interval = ncpus * interval; - for (cpu = 0; cpu < ncpus; ++cpu) { - timer = &per_cpu(heartbeat_timer, cpu); - setup_timer(timer, chrp_event_scan, 0); - timer->expires = jiffies + offset; - add_timer_on(timer, cpu); - offset += interval; - } - printk("RTAS Event Scan Rate: %u (%lu jiffies)\n", - *p, interval); - } - if (ppc_md.progress) ppc_md.progress(" Have fun! ", 0x7777); } -static int __init chrp_probe(void) +void __init chrp_init(void) { - char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(), - "device_type", NULL); - if (dtype == NULL) - return 0; - if (strcmp(dtype, "chrp")) - return 0; - ISA_DMA_THRESHOLD = ~0L; DMA_MODE_READ = 0x44; DMA_MODE_WRITE = 0x48; diff --git a/trunk/arch/powerpc/platforms/iseries/setup.c b/trunk/arch/powerpc/platforms/iseries/setup.c index 6ce8a404ba6b..fa4550611c11 100644 --- a/trunk/arch/powerpc/platforms/iseries/setup.c +++ b/trunk/arch/powerpc/platforms/iseries/setup.c @@ -675,20 +675,18 @@ static void iseries_dedicated_idle(void) void __init iSeries_init_IRQ(void) { } #endif -static int __init iseries_probe(void) +static int __init iseries_probe(int platform) { - unsigned long root = of_get_flat_dt_root(); - if (!of_flat_dt_is_compatible(root, "IBM,iSeries")) + if (PLATFORM_ISERIES_LPAR != platform) return 0; - powerpc_firmware_features |= FW_FEATURE_ISERIES; - powerpc_firmware_features |= FW_FEATURE_LPAR; + ppc64_firmware_features |= FW_FEATURE_ISERIES; + ppc64_firmware_features |= FW_FEATURE_LPAR; return 1; } -define_machine(iseries) { - .name = "iSeries", +struct machdep_calls __initdata iseries_md = { .setup_arch = iSeries_setup_arch, .show_cpuinfo = iSeries_show_cpuinfo, .init_IRQ = iSeries_init_IRQ, @@ -932,6 +930,7 @@ void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size) /* /chosen */ dt_start_node(dt, "chosen"); + dt_prop_u32(dt, "linux,platform", PLATFORM_ISERIES_LPAR); dt_prop_str(dt, "bootargs", cmd_line); if (cmd_mem_limit) dt_prop_u64(dt, "linux,memory-limit", cmd_mem_limit); diff --git a/trunk/arch/powerpc/platforms/maple/setup.c b/trunk/arch/powerpc/platforms/maple/setup.c index 24c0aef4ea39..ec5c1e10c407 100644 --- a/trunk/arch/powerpc/platforms/maple/setup.c +++ b/trunk/arch/powerpc/platforms/maple/setup.c @@ -259,10 +259,9 @@ static void __init maple_progress(char *s, unsigned short hex) /* * Called very early, MMU is off, device-tree isn't unflattened */ -static int __init maple_probe(void) +static int __init maple_probe(int platform) { - unsigned long root = of_get_flat_dt_root(); - if (!of_flat_dt_is_compatible(root, "Momentum,Maple")) + if (platform != PLATFORM_MAPLE) return 0; /* * On U3, the DART (iommu) must be allocated now since it @@ -275,8 +274,7 @@ static int __init maple_probe(void) return 1; } -define_machine(maple_md) { - .name = "Maple", +struct machdep_calls __initdata maple_md = { .probe = maple_probe, .setup_arch = maple_setup_arch, .init_early = maple_init_early, @@ -292,7 +290,7 @@ define_machine(maple_md) { .get_rtc_time = maple_get_rtc_time, .calibrate_decr = generic_calibrate_decr, .progress = maple_progress, - .power_save = power4_idle, + .idle_loop = native_idle, #ifdef CONFIG_KEXEC .machine_kexec = default_machine_kexec, .machine_kexec_prepare = default_machine_kexec_prepare, diff --git a/trunk/arch/powerpc/platforms/powermac/bootx_init.c b/trunk/arch/powerpc/platforms/powermac/bootx_init.c index eacbfd9beabc..fa8b4d7b5ded 100644 --- a/trunk/arch/powerpc/platforms/powermac/bootx_init.c +++ b/trunk/arch/powerpc/platforms/powermac/bootx_init.c @@ -161,7 +161,9 @@ static void __init bootx_dt_add_prop(char *name, void *data, int size, static void __init bootx_add_chosen_props(unsigned long base, unsigned long *mem_end) { - u32 val; + u32 val = _MACH_Pmac; + + bootx_dt_add_prop("linux,platform", &val, 4, mem_end); if (bootx_info->kernelParamsOffset) { char *args = (char *)((unsigned long)bootx_info) + @@ -491,7 +493,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4) && (strcmp(model, "iMac,1") == 0 || strcmp(model, "PowerMac1,1") == 0)) { bootx_printf("iMac,1 detected, shutting down USB \n"); - out_le32((unsigned __iomem *)0x80880008, 1); /* XXX */ + out_le32((unsigned *)0x80880008, 1); /* XXX */ } } diff --git a/trunk/arch/powerpc/platforms/powermac/feature.c b/trunk/arch/powerpc/platforms/powermac/feature.c index a5063cd675c5..e49eddd5042d 100644 --- a/trunk/arch/powerpc/platforms/powermac/feature.c +++ b/trunk/arch/powerpc/platforms/powermac/feature.c @@ -2951,7 +2951,7 @@ static void *pmac_early_vresume_data; void pmac_set_early_video_resume(void (*proc)(void *data), void *data) { - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return; preempt_disable(); pmac_early_vresume_proc = proc; diff --git a/trunk/arch/powerpc/platforms/powermac/low_i2c.c b/trunk/arch/powerpc/platforms/powermac/low_i2c.c index e14f9ac55cf4..87eb6bb7f0e7 100644 --- a/trunk/arch/powerpc/platforms/powermac/low_i2c.c +++ b/trunk/arch/powerpc/platforms/powermac/low_i2c.c @@ -1457,9 +1457,6 @@ int __init pmac_i2c_init(void) return 0; i2c_inited = 1; - if (!machine_is(powermac)) - return 0; - /* Probe keywest-i2c busses */ kw_i2c_probe(); diff --git a/trunk/arch/powerpc/platforms/powermac/nvram.c b/trunk/arch/powerpc/platforms/powermac/nvram.c index 262f967b880a..5fd28995c74c 100644 --- a/trunk/arch/powerpc/platforms/powermac/nvram.c +++ b/trunk/arch/powerpc/platforms/powermac/nvram.c @@ -74,7 +74,7 @@ struct core99_header { * Read and write the non-volatile RAM on PowerMacs and CHRP machines. */ static int nvram_naddrs; -static volatile unsigned char __iomem *nvram_data; +static volatile unsigned char *nvram_data; static int is_core_99; static int core99_bank = 0; static int nvram_partitions[3]; @@ -148,7 +148,7 @@ static ssize_t core99_nvram_size(void) } #ifdef CONFIG_PPC32 -static volatile unsigned char __iomem *nvram_addr; +static volatile unsigned char *nvram_addr; static int nvram_mult; static unsigned char direct_nvram_read_byte(int addr) @@ -285,7 +285,7 @@ static int sm_erase_bank(int bank) int stat, i; unsigned long timeout; - u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE; + u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; DBG("nvram: Sharp/Micron Erasing bank %d...\n", bank); @@ -317,7 +317,7 @@ static int sm_write_bank(int bank, u8* datas) int i, stat = 0; unsigned long timeout; - u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE; + u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; DBG("nvram: Sharp/Micron Writing bank %d...\n", bank); @@ -352,7 +352,7 @@ static int amd_erase_bank(int bank) int i, stat = 0; unsigned long timeout; - u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE; + u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; DBG("nvram: AMD Erasing bank %d...\n", bank); @@ -399,7 +399,7 @@ static int amd_write_bank(int bank, u8* datas) int i, stat = 0; unsigned long timeout; - u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE; + u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; DBG("nvram: AMD Writing bank %d...\n", bank); @@ -597,7 +597,7 @@ int __init pmac_nvram_init(void) } #ifdef CONFIG_PPC32 - if (machine_is(chrp) && nvram_naddrs == 1) { + if (_machine == _MACH_chrp && nvram_naddrs == 1) { nvram_data = ioremap(r1.start, s1); nvram_mult = 1; ppc_md.nvram_read_val = direct_nvram_read_byte; diff --git a/trunk/arch/powerpc/platforms/powermac/pci.c b/trunk/arch/powerpc/platforms/powermac/pci.c index f5d8d15d74fa..de3f30e6b333 100644 --- a/trunk/arch/powerpc/platforms/powermac/pci.c +++ b/trunk/arch/powerpc/platforms/powermac/pci.c @@ -1201,7 +1201,7 @@ void __init pmac_pcibios_after_init(void) #ifdef CONFIG_PPC32 void pmac_pci_fixup_cardbus(struct pci_dev* dev) { - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return; /* * Fix the interrupt routing on the various cardbus bridges @@ -1244,9 +1244,8 @@ void pmac_pci_fixup_pciata(struct pci_dev* dev) * On PowerMacs, we try to switch any PCI ATA controller to * fully native mode */ - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return; - /* Some controllers don't have the class IDE */ if (dev->vendor == PCI_VENDOR_ID_PROMISE) switch(dev->device) { diff --git a/trunk/arch/powerpc/platforms/powermac/pfunc_base.c b/trunk/arch/powerpc/platforms/powermac/pfunc_base.c index a3bd3e728fa3..9b7150f10414 100644 --- a/trunk/arch/powerpc/platforms/powermac/pfunc_base.c +++ b/trunk/arch/powerpc/platforms/powermac/pfunc_base.c @@ -336,8 +336,6 @@ int __init pmac_pfunc_base_install(void) return 0; pfbase_inited = 1; - if (!machine_is(powermac)) - return 0; DBG("Installing base platform functions...\n"); diff --git a/trunk/arch/powerpc/platforms/powermac/setup.c b/trunk/arch/powerpc/platforms/powermac/setup.c index 4d15e396655c..385aab90c4d2 100644 --- a/trunk/arch/powerpc/platforms/powermac/setup.c +++ b/trunk/arch/powerpc/platforms/powermac/setup.c @@ -350,13 +350,6 @@ static void __init pmac_setup_arch(void) smp_ops = &psurge_smp_ops; #endif #endif /* CONFIG_SMP */ - -#ifdef CONFIG_ADB - if (strstr(cmd_line, "adb_sync")) { - extern int __adb_probe_sync; - __adb_probe_sync = 1; - } -#endif /* CONFIG_ADB */ } char *bootpath; @@ -583,6 +576,30 @@ pmac_halt(void) pmac_power_off(); } +#ifdef CONFIG_PPC32 +void __init pmac_init(void) +{ + /* isa_io_base gets set in pmac_pci_init */ + isa_mem_base = PMAC_ISA_MEM_BASE; + pci_dram_offset = PMAC_PCI_DRAM_OFFSET; + ISA_DMA_THRESHOLD = ~0L; + DMA_MODE_READ = 1; + DMA_MODE_WRITE = 2; + + ppc_md = pmac_md; + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +#ifdef CONFIG_BLK_DEV_IDE_PMAC + ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports; + ppc_ide_md.default_io_base = pmac_ide_get_base; +#endif /* CONFIG_BLK_DEV_IDE_PMAC */ +#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */ + + if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0); + +} +#endif + /* * Early initialization. */ @@ -629,12 +646,6 @@ static int __init pmac_declare_of_platform_devices(void) { struct device_node *np; - if (machine_is(chrp)) - return -1; - - if (!machine_is(powermac)) - return 0; - np = of_find_node_by_name(NULL, "valkyrie"); if (np) of_platform_device_create(np, "valkyrie", NULL); @@ -655,15 +666,12 @@ device_initcall(pmac_declare_of_platform_devices); /* * Called very early, MMU is off, device-tree isn't unflattened */ -static int __init pmac_probe(void) +static int __init pmac_probe(int platform) { - unsigned long root = of_get_flat_dt_root(); - - if (!of_flat_dt_is_compatible(root, "Power Macintosh") && - !of_flat_dt_is_compatible(root, "MacRISC")) +#ifdef CONFIG_PPC64 + if (platform != PLATFORM_POWERMAC) return 0; -#ifdef CONFIG_PPC64 /* * On U3, the DART (iommu) must be allocated now since it * has an impact on htab_initialize (due to the large page it @@ -673,23 +681,6 @@ static int __init pmac_probe(void) alloc_dart_table(); #endif -#ifdef CONFIG_PPC32 - /* isa_io_base gets set in pmac_pci_init */ - isa_mem_base = PMAC_ISA_MEM_BASE; - pci_dram_offset = PMAC_PCI_DRAM_OFFSET; - ISA_DMA_THRESHOLD = ~0L; - DMA_MODE_READ = 1; - DMA_MODE_WRITE = 2; - -#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) -#ifdef CONFIG_BLK_DEV_IDE_PMAC - ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports; - ppc_ide_md.default_io_base = pmac_ide_get_base; -#endif /* CONFIG_BLK_DEV_IDE_PMAC */ -#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */ - -#endif /* CONFIG_PPC32 */ - #ifdef CONFIG_PMAC_SMU /* * SMU based G5s need some memory below 2Gb, at least the current @@ -718,8 +709,10 @@ static int pmac_pci_probe_mode(struct pci_bus *bus) } #endif -define_machine(powermac) { - .name = "PowerMac", +struct machdep_calls __initdata pmac_md = { +#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64) + .cpu_die = generic_mach_cpu_die, +#endif .probe = pmac_probe, .setup_arch = pmac_setup_arch, .init_early = pmac_init_early, @@ -740,7 +733,7 @@ define_machine(powermac) { .progress = udbg_progress, #ifdef CONFIG_PPC64 .pci_probe_mode = pmac_pci_probe_mode, - .power_save = power4_idle, + .idle_loop = native_idle, .enable_pmcs = power4_enable_pmcs, #ifdef CONFIG_KEXEC .machine_kexec = default_machine_kexec, @@ -753,7 +746,4 @@ define_machine(powermac) { .pcibios_after_init = pmac_pcibios_after_init, .phys_mem_access_prot = pci_phys_mem_access_prot, #endif -#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64) - .cpu_die = generic_mach_cpu_die, -#endif }; diff --git a/trunk/arch/powerpc/platforms/powermac/time.c b/trunk/arch/powerpc/platforms/powermac/time.c index 890758aa9667..5d9afa1fa02d 100644 --- a/trunk/arch/powerpc/platforms/powermac/time.c +++ b/trunk/arch/powerpc/platforms/powermac/time.c @@ -336,10 +336,10 @@ static struct pmu_sleep_notifier time_sleep_notifier = { */ void __init pmac_calibrate_decr(void) { -#if defined(CONFIG_PM) && defined(CONFIG_ADB_PMU) +#ifdef CONFIG_PM /* XXX why here? */ pmu_register_sleep_notifier(&time_sleep_notifier); -#endif +#endif /* CONFIG_PM */ generic_calibrate_decr(); diff --git a/trunk/arch/powerpc/platforms/powermac/udbg_scc.c b/trunk/arch/powerpc/platforms/powermac/udbg_scc.c index b4fa9f03b461..c4352a8db644 100644 --- a/trunk/arch/powerpc/platforms/powermac/udbg_scc.c +++ b/trunk/arch/powerpc/platforms/powermac/udbg_scc.c @@ -116,7 +116,7 @@ void udbg_scc_init(int force_scc) /* Setup for 57600 8N1 */ if (ch == ch_a) addr += 0x20; - sccc = ioremap(addr & PAGE_MASK, PAGE_SIZE) ; + sccc = (volatile u8 * __iomem) ioremap(addr & PAGE_MASK, PAGE_SIZE) ; sccc += addr & ~PAGE_MASK; sccd = sccc + 0x10; diff --git a/trunk/arch/powerpc/platforms/pseries/eeh.c b/trunk/arch/powerpc/platforms/pseries/eeh.c index 9b2b1cb117b3..2ab9dcdfb415 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh.c @@ -1018,7 +1018,7 @@ static int __init eeh_init_proc(void) { struct proc_dir_entry *e; - if (machine_is(pseries)) { + if (platform_is_pseries()) { e = create_proc_entry("ppc64/eeh", 0, NULL); if (e) e->proc_fops = &proc_eeh_operations; diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_driver.c b/trunk/arch/powerpc/platforms/pseries/eeh_driver.c index cc2495a0cdd5..b811d5ff92fe 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh_driver.c @@ -257,7 +257,6 @@ void handle_eeh_events (struct eeh_event *event) struct pci_bus *frozen_bus; int rc = 0; enum pci_ers_result result = PCI_ERS_RESULT_NONE; - const char *pci_str, *drv_str; frozen_dn = find_device_pe(event->dn); frozen_bus = pcibios_find_pci_bus(frozen_dn); @@ -292,13 +291,6 @@ void handle_eeh_events (struct eeh_event *event) frozen_pdn = PCI_DN(frozen_dn); frozen_pdn->eeh_freeze_count++; - - pci_str = pci_name (frozen_pdn->pcidev); - drv_str = pcid_name (frozen_pdn->pcidev); - if (!pci_str) { - pci_str = pci_name (event->dev); - drv_str = pcid_name (event->dev); - } if (frozen_pdn->eeh_freeze_count > EEH_MAX_ALLOWED_FREEZES) goto hard_fail; @@ -314,7 +306,9 @@ void handle_eeh_events (struct eeh_event *event) eeh_slot_error_detail(frozen_pdn, 1 /* Temporary Error */); printk(KERN_WARNING "EEH: This PCI device has failed %d times since last reboot: %s - %s\n", - frozen_pdn->eeh_freeze_count, drv_str, pci_str); + frozen_pdn->eeh_freeze_count, + pci_name (frozen_pdn->pcidev), + pcid_name(frozen_pdn->pcidev)); /* Walk the various device drivers attached to this slot through * a reset sequence, giving each an opportunity to do what it needs @@ -366,7 +360,9 @@ void handle_eeh_events (struct eeh_event *event) "EEH: PCI device %s - %s has failed %d times \n" "and has been permanently disabled. Please try reseating\n" "this device or replacing it.\n", - drv_str, pci_str, frozen_pdn->eeh_freeze_count); + pci_name (frozen_pdn->pcidev), + pcid_name(frozen_pdn->pcidev), + frozen_pdn->eeh_freeze_count); eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */); diff --git a/trunk/arch/powerpc/platforms/pseries/firmware.c b/trunk/arch/powerpc/platforms/pseries/firmware.c index c01d8f0cbe6d..989f4bc136cb 100644 --- a/trunk/arch/powerpc/platforms/pseries/firmware.c +++ b/trunk/arch/powerpc/platforms/pseries/firmware.c @@ -91,7 +91,7 @@ void __init fw_feature_init(void) continue; /* we have a match */ - powerpc_firmware_features |= + ppc64_firmware_features |= firmware_features_table[i].val; break; } diff --git a/trunk/arch/powerpc/platforms/pseries/hvconsole.c b/trunk/arch/powerpc/platforms/pseries/hvconsole.c index ba6befd96636..138e128a3886 100644 --- a/trunk/arch/powerpc/platforms/pseries/hvconsole.c +++ b/trunk/arch/powerpc/platforms/pseries/hvconsole.c @@ -62,11 +62,6 @@ int hvc_put_chars(uint32_t vtermno, const char *buf, int count) unsigned long *lbuf = (unsigned long *) buf; long ret; - - /* hcall will ret H_PARAMETER if 'count' exceeds firmware max.*/ - if (count > MAX_VIO_PUT_CHARS) - count = MAX_VIO_PUT_CHARS; - ret = plpar_hcall_norets(H_PUT_TERM_CHAR, vtermno, count, lbuf[0], lbuf[1]); if (ret == H_Success) diff --git a/trunk/arch/powerpc/platforms/pseries/pci.c b/trunk/arch/powerpc/platforms/pseries/pci.c index e97e67f5e079..946ad59e3352 100644 --- a/trunk/arch/powerpc/platforms/pseries/pci.c +++ b/trunk/arch/powerpc/platforms/pseries/pci.c @@ -120,7 +120,7 @@ static void fixup_winbond_82c105(struct pci_dev* dev) int i; unsigned int reg; - if (!machine_is(pseries)) + if (!platform_is_pseries()) return; printk("Using INTC for W82c105 IDE controller.\n"); diff --git a/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c b/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c index 6bfacc217085..44abdeb9ca03 100644 --- a/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -28,7 +28,6 @@ #include #include #include -#include static struct pci_bus * find_bus_among_children(struct pci_bus *bus, @@ -153,24 +152,20 @@ pcibios_pci_config_bridge(struct pci_dev *dev) void pcibios_add_pci_devices(struct pci_bus * bus) { - int slotno, num, mode; + int slotno, num; struct pci_dev *dev; struct device_node *dn = pci_bus_to_OF_node(bus); eeh_add_device_tree_early(dn); - mode = PCI_PROBE_NORMAL; - if (ppc_md.pci_probe_mode) - mode = ppc_md.pci_probe_mode(bus); - - if (mode == PCI_PROBE_DEVTREE) { + if (_machine == PLATFORM_PSERIES_LPAR) { /* use ofdt-based probe */ of_scan_bus(dn, bus); if (!list_empty(&bus->devices)) { pcibios_fixup_new_pci_devices(bus, 0); pci_bus_add_devices(bus); } - } else if (mode == PCI_PROBE_NORMAL) { + } else { /* use legacy probe */ slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); diff --git a/trunk/arch/powerpc/platforms/pseries/ras.c b/trunk/arch/powerpc/platforms/pseries/ras.c index 9639c66b453d..b046bcf7443d 100644 --- a/trunk/arch/powerpc/platforms/pseries/ras.c +++ b/trunk/arch/powerpc/platforms/pseries/ras.c @@ -132,7 +132,7 @@ static int __init init_ras_IRQ(void) of_node_put(np); } - return 0; + return 1; } __initcall(init_ras_IRQ); diff --git a/trunk/arch/powerpc/platforms/pseries/reconfig.c b/trunk/arch/powerpc/platforms/pseries/reconfig.c index 1773103354be..5ad90676567a 100644 --- a/trunk/arch/powerpc/platforms/pseries/reconfig.c +++ b/trunk/arch/powerpc/platforms/pseries/reconfig.c @@ -17,9 +17,8 @@ #include #include -#include -#include #include +#include @@ -509,7 +508,7 @@ static int proc_ppc64_create_ofdt(void) { struct proc_dir_entry *ent; - if (!machine_is(pseries)) + if (!platform_is_pseries()) return 0; ent = create_proc_entry("ppc64/ofdt", S_IWUSR, NULL); diff --git a/trunk/arch/powerpc/platforms/pseries/rtasd.c b/trunk/arch/powerpc/platforms/pseries/rtasd.c index fcc4d561a236..a6f628d4c9dc 100644 --- a/trunk/arch/powerpc/platforms/pseries/rtasd.c +++ b/trunk/arch/powerpc/platforms/pseries/rtasd.c @@ -27,7 +27,6 @@ #include #include #include -#include #if 0 #define DEBUG(A...) printk(KERN_ERR A) @@ -482,7 +481,7 @@ static int __init rtas_init(void) { struct proc_dir_entry *entry; - if (!machine_is(pseries)) + if (!platform_is_pseries()) return 0; /* No RTAS */ diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c index b2fbf8ba8fbb..44d5c7fdcd97 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -81,8 +81,8 @@ extern void find_udbg_vterm(void); int fwnmi_active; /* TRUE if an FWNMI handler is present */ -static void pseries_shared_idle_sleep(void); -static void pseries_dedicated_idle_sleep(void); +static void pseries_shared_idle(void); +static void pseries_dedicated_idle(void); struct mpic *pSeries_mpic; @@ -236,13 +236,14 @@ static void __init pSeries_setup_arch(void) vpa_init(boot_cpuid); if (get_lppaca()->shared_proc) { printk(KERN_INFO "Using shared processor idle loop\n"); - ppc_md.power_save = pseries_shared_idle_sleep; + ppc_md.idle_loop = pseries_shared_idle; } else { printk(KERN_INFO "Using dedicated idle loop\n"); - ppc_md.power_save = pseries_dedicated_idle_sleep; + ppc_md.idle_loop = pseries_dedicated_idle; } } else { printk(KERN_INFO "Using default idle loop\n"); + ppc_md.idle_loop = default_idle; } if (firmware_has_feature(FW_FEATURE_LPAR)) @@ -372,123 +373,156 @@ static int pSeries_check_legacy_ioport(unsigned int baseport) /* * Called very early, MMU is off, device-tree isn't unflattened */ +extern struct machdep_calls pSeries_md; -static int __init pSeries_probe_hypertas(unsigned long node, - const char *uname, int depth, - void *data) +static int __init pSeries_probe(int platform) { - if (depth != 1 || - (strcmp(uname, "rtas") != 0 && strcmp(uname, "rtas@0") != 0)) - return 0; - - if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL) - powerpc_firmware_features |= FW_FEATURE_LPAR; - - return 1; -} - -static int __init pSeries_probe(void) -{ - char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(), - "device_type", NULL); - if (dtype == NULL) - return 0; - if (strcmp(dtype, "chrp")) + if (platform != PLATFORM_PSERIES && + platform != PLATFORM_PSERIES_LPAR) return 0; - DBG("pSeries detected, looking for LPAR capability...\n"); - - /* Now try to figure out if we are running on LPAR */ - of_scan_flat_dt(pSeries_probe_hypertas, NULL); + /* if we have some ppc_md fixups for LPAR to do, do + * it here ... + */ - DBG("Machine is%s LPAR !\n", - (powerpc_firmware_features & FW_FEATURE_LPAR) ? "" : " not"); + if (platform == PLATFORM_PSERIES_LPAR) + ppc64_firmware_features |= FW_FEATURE_LPAR; return 1; } - DECLARE_PER_CPU(unsigned long, smt_snooze_delay); -static void pseries_dedicated_idle_sleep(void) -{ - unsigned int cpu = smp_processor_id(); - unsigned long start_snooze; - unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay); +static inline void dedicated_idle_sleep(unsigned int cpu) +{ + struct lppaca *plppaca = &lppaca[cpu ^ 1]; - /* - * Indicate to the HV that we are idle. Now would be - * a good time to find other work to dispatch. - */ - get_lppaca()->idle = 1; + /* Only sleep if the other thread is not idle */ + if (!(plppaca->idle)) { + local_irq_disable(); - /* - * We come in with interrupts disabled, and need_resched() - * has been checked recently. If we should poll for a little - * while, do so. - */ - if (*smt_snooze_delay) { - start_snooze = get_tb() + - *smt_snooze_delay * tb_ticks_per_usec; - local_irq_enable(); + /* + * We are about to sleep the thread and so wont be polling any + * more. + */ + clear_thread_flag(TIF_POLLING_NRFLAG); + smp_mb__after_clear_bit(); + + /* + * SMT dynamic mode. Cede will result in this thread going + * dormant, if the partner thread is still doing work. Thread + * wakes up if partner goes idle, an interrupt is presented, or + * a prod occurs. Returning from the cede enables external + * interrupts. + */ + if (!need_resched()) + cede_processor(); + else + local_irq_enable(); set_thread_flag(TIF_POLLING_NRFLAG); + } else { + /* + * Give the HV an opportunity at the processor, since we are + * not doing any work. + */ + poll_pending(); + } +} - while (get_tb() < start_snooze) { - if (need_resched() || cpu_is_offline(cpu)) - goto out; - ppc64_runlatch_off(); - HMT_low(); - HMT_very_low(); +static void pseries_dedicated_idle(void) +{ + unsigned int cpu = smp_processor_id(); + unsigned long start_snooze; + unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay); + set_thread_flag(TIF_POLLING_NRFLAG); + + while (1) { + /* + * Indicate to the HV that we are idle. Now would be + * a good time to find other work to dispatch. + */ + get_lppaca()->idle = 1; + + if (!need_resched()) { + start_snooze = get_tb() + + *smt_snooze_delay * tb_ticks_per_usec; + + while (!need_resched() && !cpu_is_offline(cpu)) { + ppc64_runlatch_off(); + + /* + * Go into low thread priority and possibly + * low power mode. + */ + HMT_low(); + HMT_very_low(); + + if (*smt_snooze_delay != 0 && + get_tb() > start_snooze) { + HMT_medium(); + dedicated_idle_sleep(cpu); + } + + } + + HMT_medium(); } - HMT_medium(); - clear_thread_flag(TIF_POLLING_NRFLAG); - smp_mb(); - local_irq_disable(); - if (need_resched() || cpu_is_offline(cpu)) - goto out; - } + get_lppaca()->idle = 0; + ppc64_runlatch_on(); - /* - * Cede if the other thread is not idle, so that it can - * go single-threaded. If the other thread is idle, - * we ask the hypervisor if it has pending work it - * wants to do and cede if it does. Otherwise we keep - * polling in order to reduce interrupt latency. - * - * Doing the cede when the other thread is active will - * result in this thread going dormant, meaning the other - * thread gets to run in single-threaded (ST) mode, which - * is slightly faster than SMT mode with this thread at - * very low priority. The cede enables interrupts, which - * doesn't matter here. - */ - if (!lppaca[cpu ^ 1].idle || poll_pending() == H_Pending) - cede_processor(); + preempt_enable_no_resched(); + schedule(); + preempt_disable(); -out: - HMT_medium(); - get_lppaca()->idle = 0; + if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) + cpu_die(); + } } -static void pseries_shared_idle_sleep(void) +static void pseries_shared_idle(void) { - /* - * Indicate to the HV that we are idle. Now would be - * a good time to find other work to dispatch. - */ - get_lppaca()->idle = 1; + unsigned int cpu = smp_processor_id(); - /* - * Yield the processor to the hypervisor. We return if - * an external interrupt occurs (which are driven prior - * to returning here) or if a prod occurs from another - * processor. When returning here, external interrupts - * are enabled. - */ - cede_processor(); + while (1) { + /* + * Indicate to the HV that we are idle. Now would be + * a good time to find other work to dispatch. + */ + get_lppaca()->idle = 1; + + while (!need_resched() && !cpu_is_offline(cpu)) { + local_irq_disable(); + ppc64_runlatch_off(); - get_lppaca()->idle = 0; + /* + * Yield the processor to the hypervisor. We return if + * an external interrupt occurs (which are driven prior + * to returning here) or if a prod occurs from another + * processor. When returning here, external interrupts + * are enabled. + * + * Check need_resched() again with interrupts disabled + * to avoid a race. + */ + if (!need_resched()) + cede_processor(); + else + local_irq_enable(); + + HMT_medium(); + } + + get_lppaca()->idle = 0; + ppc64_runlatch_on(); + + preempt_enable_no_resched(); + schedule(); + preempt_disable(); + + if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) + cpu_die(); + } } static int pSeries_pci_probe_mode(struct pci_bus *bus) @@ -519,8 +553,7 @@ static void pseries_kexec_cpu_down(int crash_shutdown, int secondary) } #endif -define_machine(pseries) { - .name = "pSeries", +struct machdep_calls __initdata pSeries_md = { .probe = pSeries_probe, .setup_arch = pSeries_setup_arch, .init_early = pSeries_init_early, diff --git a/trunk/arch/powerpc/platforms/pseries/xics.c b/trunk/arch/powerpc/platforms/pseries/xics.c index 4864cb32be25..eb86cdb9b802 100644 --- a/trunk/arch/powerpc/platforms/pseries/xics.c +++ b/trunk/arch/powerpc/platforms/pseries/xics.c @@ -500,7 +500,7 @@ void xics_init_IRQ(void) np; np = of_find_node_by_type(np, "cpu")) { ireg = (uint *)get_property(np, "reg", &ilen); - if (ireg && ireg[0] == get_hard_smp_processor_id(boot_cpuid)) { + if (ireg && ireg[0] == boot_cpuid_phys) { ireg = (uint *)get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen); i = ilen / sizeof(int); @@ -541,7 +541,7 @@ void xics_init_IRQ(void) ops = &pSeriesLP_ops; else { #ifdef CONFIG_SMP - for_each_possible_cpu(i) { + for_each_cpu(i) { int hard_id; /* FIXME: Do this dynamically! --RR */ diff --git a/trunk/arch/ppc/Kconfig b/trunk/arch/ppc/Kconfig index e9a8f5d1dfcd..3a3e302b4ea2 100644 --- a/trunk/arch/ppc/Kconfig +++ b/trunk/arch/ppc/Kconfig @@ -61,15 +61,15 @@ config 6xx select PPC_FPU help There are four types of PowerPC chips supported. The more common - types (601, 603, 604, 740, 750, 7400), the older Freescale - (formerly Motorola) embedded versions (821, 823, 850, 855, 860, - 52xx, 82xx, 83xx), the IBM embedded versions (403 and 405) and - the Book E embedded processors from IBM (44x) and Freescale (85xx). - For support for 64-bit processors, set ARCH=powerpc. + types (601, 603, 604, 740, 750, 7400), the Motorola embedded + versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the IBM + embedded versions (403 and 405) and the POWER3 processor. + (For support for more recent 64-bit processors, set ARCH=powerpc.) Unless you are building a kernel for one of the embedded processor - systems, choose 6xx. - Also note that because the 52xx, 82xx, & 83xx family have a 603e - core, specific support for that chipset is asked later on. + systems or a POWER3-based IBM RS/6000, choose 6xx. + Note that the kernel runs in 32-bit mode even on 64-bit chips. + Also note that because the 52xx, 82xx, & 83xx family has a 603e core, + specific support for that chipset is asked later on. config 40x bool "40x" @@ -77,6 +77,10 @@ config 40x config 44x bool "44x" +config POWER3 + select PPC_FPU + bool "POWER3" + config 8xx bool "8xx" @@ -248,9 +252,14 @@ config PPC601_SYNC_FIX source arch/ppc/platforms/4xx/Kconfig source arch/ppc/platforms/85xx/Kconfig +config PPC64BRIDGE + bool + depends on POWER3 + default y + config PPC_STD_MMU bool - depends on 6xx + depends on 6xx || POWER3 default y config NOT_COHERENT_CACHE @@ -525,8 +534,8 @@ endmenu choice prompt "Machine Type" - depends on 6xx - default PPC_PREP + depends on 6xx || POWER3 + default PPC_MULTIPLATFORM ---help--- Linux currently supports several different kinds of PowerPC-based machines: Apple Power Macintoshes and clones (such as the Motorola @@ -536,14 +545,15 @@ choice Platform) machines (including all of the recent IBM RS/6000 and pSeries machines), and several embedded PowerPC systems containing 4xx, 6xx, 7xx, 8xx, 74xx, and 82xx processors. Currently, the - default option is to build a kernel which works on PReP. + default option is to build a kernel which works on PReP and CHRP. - Note that support for Apple and CHRP machines is now only available - with ARCH=powerpc, and has been removed from this menu. If you - wish to build a kernel for an Apple or CHRP machine, exit this - configuration process and re-run it with ARCH=powerpc. + Note that support for Apple machines is now only available with + ARCH=powerpc, and has been removed from this menu. If you wish + to build a kernel for an Apple machine, exit this configuration + process and re-run it with ARCH=powerpc. - Select PReP if configuring for a PReP machine. + Select CHRP/PReP if configuring for an IBM RS/6000 or + pSeries machine, or a PReP machine. Select Gemini if configuring for a Synergy Microsystems' Gemini series Single Board Computer. More information is available at: @@ -552,8 +562,8 @@ choice Select APUS if configuring for a PowerUP Amiga. More information is available at: . -config PPC_PREP - bool "PReP" +config PPC_MULTIPLATFORM + bool "CHRP/PReP" config APUS bool "Amiga-APUS" @@ -705,13 +715,6 @@ config LITE5200 much but it's only been tested on this board version. I think this board is also known as IceCube. -config LITE5200B - bool "Freescale LITE5200B" - depends LITE5200 - help - Support for the LITE5200B dev board for the MPC5200 from Freescale. - This is the new board with 2 PCI slots. - config MPC834x_SYS bool "Freescale MPC834x SYS" help @@ -797,6 +800,25 @@ config CPM2 you wish to build a kernel for a machine with a CPM2 coprocessor on it (826x, 827x, 8560). +config PPC_CHRP + bool "Support for CHRP (Common Hardware Reference Platform) machines" + depends on PPC_MULTIPLATFORM + select PPC_I8259 + select PPC_INDIRECT_PCI + default y + +config PPC_PREP + bool "Support for PReP (PowerPC Reference Platform) machines" + depends on PPC_MULTIPLATFORM + select PPC_I8259 + select PPC_INDIRECT_PCI + default y + +config PPC_OF + bool + depends on PPC_CHRP + default y + config PPC_GEN550 bool depends on SANDPOINT || SPRUCE || PPLUS || \ @@ -955,6 +977,14 @@ source "mm/Kconfig" source "fs/Kconfig.binfmt" +config PROC_DEVICETREE + bool "Support for Open Firmware device tree in /proc" + depends on PPC_OF && PROC_FS + help + This option adds a device-tree directory under /proc which contains + an image of the device tree that the kernel copies from Open + Firmware. If unsure, say Y here. + config PREP_RESIDUAL bool "Support for PReP Residual Data" depends on PPC_PREP @@ -1147,7 +1177,8 @@ menu "Bus options" config ISA bool "Support for ISA-bus hardware" - depends on PPC_PREP + depends on PPC_PREP || PPC_CHRP + select PPC_I8259 help Find out whether you have ISA slots on your motherboard. ISA is the name of a bus system, i.e. the way the CPU talks to the other stuff @@ -1157,18 +1188,18 @@ config ISA config GENERIC_ISA_DMA bool - depends on 6xx && !CPM2 + depends on POWER3 || 6xx && !CPM2 default y config PPC_I8259 bool - default y if 85xx || PPC_PREP + default y if 85xx default n config PPC_INDIRECT_PCI bool depends on PCI - default y if 40x || 44x || 85xx || 83xx || PPC_PREP + default y if 40x || 44x || 85xx || 83xx default n config EISA @@ -1359,7 +1390,7 @@ config CONSISTENT_SIZE config BOOT_LOAD_BOOL bool "Set the boot link/load address" - depends on ADVANCED_OPTIONS && !PPC_PREP + depends on ADVANCED_OPTIONS && !PPC_MULTIPLATFORM help This option allows you to set the initial load address of the zImage or zImage.initrd file. This can be useful if you are on a board diff --git a/trunk/arch/ppc/Kconfig.debug b/trunk/arch/ppc/Kconfig.debug index f94b87740973..8cc75abf3d83 100644 --- a/trunk/arch/ppc/Kconfig.debug +++ b/trunk/arch/ppc/Kconfig.debug @@ -53,6 +53,13 @@ config BDI_SWITCH Unless you are intending to debug the kernel with one of these machines, say N here. +config BOOTX_TEXT + bool "Support for early boot text console (BootX or OpenFirmware only)" + depends PPC_OF + help + Say Y here to see progress messages from the boot firmware in text + mode. Requires either BootX or Open Firmware. + config SERIAL_TEXT_DEBUG bool "Support for early boot texts over serial port" depends on 4xx || LOPEC || MV64X60 || PPLUS || PRPMC800 || \ diff --git a/trunk/arch/ppc/Makefile b/trunk/arch/ppc/Makefile index 0db66dcf0723..9fbdf54ba2be 100644 --- a/trunk/arch/ppc/Makefile +++ b/trunk/arch/ppc/Makefile @@ -40,8 +40,10 @@ ifndef CONFIG_FSL_BOOKE CFLAGS += -mstring endif +cpu-as-$(CONFIG_PPC64BRIDGE) += -Wa,-mppc64bridge cpu-as-$(CONFIG_4xx) += -Wa,-m405 cpu-as-$(CONFIG_6xx) += -Wa,-maltivec +cpu-as-$(CONFIG_POWER4) += -Wa,-maltivec cpu-as-$(CONFIG_E500) += -Wa,-me500 cpu-as-$(CONFIG_E200) += -Wa,-me200 @@ -57,6 +59,8 @@ head-$(CONFIG_4xx) := arch/ppc/kernel/head_4xx.o head-$(CONFIG_44x) := arch/ppc/kernel/head_44x.o head-$(CONFIG_FSL_BOOKE) := arch/ppc/kernel/head_fsl_booke.o +head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o +head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o core-y += arch/ppc/kernel/ arch/powerpc/kernel/ \ @@ -67,7 +71,7 @@ core-y += arch/ppc/kernel/ arch/powerpc/kernel/ \ core-$(CONFIG_4xx) += arch/ppc/platforms/4xx/ core-$(CONFIG_83xx) += arch/ppc/platforms/83xx/ core-$(CONFIG_85xx) += arch/ppc/platforms/85xx/ -core-$(CONFIG_MATH_EMULATION) += arch/powerpc/math-emu/ +core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/ core-$(CONFIG_XMON) += arch/ppc/xmon/ core-$(CONFIG_APUS) += arch/ppc/amiga/ drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/ diff --git a/trunk/arch/ppc/boot/Makefile b/trunk/arch/ppc/boot/Makefile index b739e25d4728..84eec0bef93c 100644 --- a/trunk/arch/ppc/boot/Makefile +++ b/trunk/arch/ppc/boot/Makefile @@ -19,13 +19,14 @@ HOSTCFLAGS += -Iarch/$(ARCH)/boot/include BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd bootdir-y := simple +bootdir-$(CONFIG_PPC_OF) += openfirmware subdir-y := lib common images -subdir-$(CONFIG_PPC_PREP) += of1275 +subdir-$(CONFIG_PPC_MULTIPLATFORM) += of1275 # for cleaning -subdir- += simple +subdir- += simple openfirmware -hostprogs-y := $(addprefix utils/, mkprep mkbugboot mktree) +hostprogs-y := $(addprefix utils/, addnote mknote hack-coff mkprep mkbugboot mktree) PHONY += $(BOOT_TARGETS) $(bootdir-y) diff --git a/trunk/arch/ppc/boot/openfirmware/Makefile b/trunk/arch/ppc/boot/openfirmware/Makefile new file mode 100644 index 000000000000..66b739743759 --- /dev/null +++ b/trunk/arch/ppc/boot/openfirmware/Makefile @@ -0,0 +1,109 @@ +# Makefile for making bootable images on various OpenFirmware machines. +# +# This file is included by the global makefile so that you can add your own +# architecture-specific flags and dependencies. +# +# Paul Mackerras January 1997 +# XCOFF bootable images for PowerMacs +# Geert Uytterhoeven September 1997 +# ELF bootable iamges for CHRP machines. +# Tom Rini January 2001 +# Cleaned up, moved into arch/ppc/boot/pmac +# Tom Rini July/August 2002 +# Merged 'chrp' and 'pmac' into 'openfirmware', and cleaned up the +# rules. + +zImage.initrd znetboot.initrd: del-ramdisk-sec := -R .ramdisk +zImage.initrd znetboot.initrd: initrd := .initrd + + +boot := arch/ppc/boot +common := $(boot)/common +utils := $(boot)/utils +bootlib := $(boot)/lib +of1275 := $(boot)/of1275 +images := $(boot)/images + +CHRP_LD_ARGS := -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00800000 + +COMMONOBJS := start.o misc.o common.o +CHRPOBJS := crt0.o $(COMMONOBJS) chrpmain.o + +targets := $(CHRPOBJS) dummy.o +CHRPOBJS := $(addprefix $(obj)/, $(CHRPOBJS)) + +LIBS := lib/lib.a $(bootlib)/lib.a $(of1275)/lib.a $(common)/lib.a + +ifdef CONFIG_SMP +END := .smp +endif +ifdef CONFIG_PPC64BRIDGE +END += .64 +endif + + +$(images)/ramdisk.image.gz: + @echo ' MISSING $@' + @echo ' RAM disk image must be provided separately' + @/bin/false + +quiet_cmd_genimage = GEN $@ + cmd_genimage = $(OBJCOPY) -R .comment \ + --add-section=.image=$(images)/vmlinux.gz \ + --set-section-flags=.image=contents,alloc,load,readonly,data $< $@ + +targets += image.o +$(obj)/image.o: $(obj)/dummy.o $(images)/vmlinux.gz FORCE + $(call if_changed,genimage) + +# Place the ramdisk in the initrd image. +quiet_cmd_genimage-initrd = GEN $@ + cmd_genimage-initrd = $(OBJCOPY) $< $@ \ + --add-section=.ramdisk=$(images)/ramdisk.image.gz \ + --set-section-flags=.ramdisk=contents,alloc,load,readonly,data +targets += image.initrd.o +$(obj)/image.initrd.o: $(obj)/image.o $(images)/ramdisk.image.gz FORCE + $(call if_changed,genimage-initrd) + + +targets += crt0.o +$(obj)/crt0.o: $(common)/crt0.S FORCE + $(call if_changed_dep,as_o_S) + +quiet_cmd_gen-chrp = CHRP $@ + cmd_gen-chrp = $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) $< $(LIBS) && \ + $(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec) + +$(images)/zImage.chrp: $(obj)/image.o $(CHRPOBJS) $(LIBS) \ + $(srctree)/$(boot)/ld.script + $(call cmd,gen-chrp) +$(images)/zImage.initrd.chrp: $(obj)/image.initrd.o $(CHRPOBJS) $(LIBS) \ + $(srctree)/$(boot)/ld.script + $(call cmd,gen-chrp) + +quiet_cmd_addnote = ADDNOTE $@ + cmd_addnote = cat $< > $@ && $(utils)/addnote $@ +$(images)/zImage.chrp-rs6k $(images)/zImage.initrd.chrp-rs6k: \ + %-rs6k: % + $(call cmd,addnote) + +# The targets used on the make command-line + +PHONY += zImage zImage.initrd +zImage: $(images)/zImage.chrp \ + $(images)/zImage.chrp-rs6k + @echo ' kernel: $@ is ready ($<)' +zImage.initrd: $(images)/zImage.initrd.chrp \ + $(images)/zImage.initrd.chrp-rs6k + @echo ' kernel: $@ is ready ($<)' + +TFTPIMAGE := /tftpboot/zImage + +PHONY += znetboot znetboot.initrd +znetboot: $(images)/zImage.chrp + cp $(images)/zImage.chrp $(TFTPIMAGE).chrp$(END) + @echo ' kernel: $@ is ready ($<)' +znetboot.initrd:$(images)/zImage.initrd.chrp + cp $(images)/zImage.initrd.chrp $(TFTPIMAGE).chrp$(END) + @echo ' kernel: $@ is ready ($<)' + diff --git a/trunk/arch/ppc/boot/openfirmware/chrpmain.c b/trunk/arch/ppc/boot/openfirmware/chrpmain.c new file mode 100644 index 000000000000..245dbd9fc120 --- /dev/null +++ b/trunk/arch/ppc/boot/openfirmware/chrpmain.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include "nonstdio.h" +#include "of1275.h" +#include +#include + +/* Passed from the linker */ +extern char __image_begin, __image_end; +extern char __ramdisk_begin, __ramdisk_end; +extern char _start, _end; + +extern unsigned int heap_max; +extern void flush_cache(void *, unsigned long); +extern void gunzip(void *, int, unsigned char *, int *); +extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach, + unsigned int progend); + +char *avail_ram; +char *begin_avail, *end_avail; +char *avail_high; + +#define RAM_START 0x00000000 +#define RAM_END (64<<20) + +#define BOOT_START ((unsigned long)_start) +#define BOOT_END ((unsigned long)(_end + 0xFFF) & ~0xFFF) + +#define RAM_FREE ((unsigned long)(_end+0x1000)&~0xFFF) +#define PROG_START 0x00010000 +#define PROG_SIZE 0x007f0000 /* 8MB */ + +#define SCRATCH_SIZE (128 << 10) + +static char scratch[SCRATCH_SIZE]; /* 128k of scratch space for gunzip */ + +typedef void (*kernel_start_t)(int, int, void *, unsigned int, unsigned int); + +void +boot(int a1, int a2, void *prom) +{ + unsigned sa, len; + void *dst; + unsigned char *im; + unsigned int initrd_size, initrd_start; + + printf("chrpboot starting: loaded at 0x%p\n\r", &_start); + + initrd_size = &__ramdisk_end - &__ramdisk_begin; + if (initrd_size) { + initrd_start = (RAM_END - initrd_size) & ~0xFFF; + a1 = initrd_start; + a2 = initrd_size; + claim(initrd_start, RAM_END - initrd_start, 0); + printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r", + initrd_start, &__ramdisk_begin, initrd_size); + memcpy((char *)initrd_start, &__ramdisk_begin, initrd_size); + } else { + initrd_start = 0; + initrd_size = 0; + a2 = 0xdeadbeef; + } + + im = &__image_begin; + len = &__image_end - &__image_begin; + /* claim 4MB starting at PROG_START */ + claim(PROG_START, PROG_SIZE - PROG_START, 0); + dst = (void *) PROG_START; + if (im[0] == 0x1f && im[1] == 0x8b) { + avail_ram = scratch; + begin_avail = avail_high = avail_ram; + end_avail = scratch + sizeof(scratch); + printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len); + gunzip(dst, PROG_SIZE - PROG_START, im, &len); + printf("done %u bytes\n\r", len); + printf("%u bytes of heap consumed, max in use %u\n\r", + avail_high - begin_avail, heap_max); + } else { + memmove(dst, im, len); + } + + flush_cache(dst, len); + make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_chrp, + (PROG_START + PROG_SIZE)); + + sa = PROG_START; + printf("start address = 0x%x\n\r", sa); + + (*(kernel_start_t)sa)(a1, a2, prom, initrd_start, initrd_size); + + printf("returned?\n\r"); + + pause(); +} diff --git a/trunk/arch/ppc/boot/openfirmware/common.c b/trunk/arch/ppc/boot/openfirmware/common.c new file mode 100644 index 000000000000..0f46756a903e --- /dev/null +++ b/trunk/arch/ppc/boot/openfirmware/common.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include "nonstdio.h" +#include "of1275.h" +#include +#include +#include +#include + +/* Information from the linker */ + +extern int strcmp(const char *s1, const char *s2); +extern char *avail_ram, *avail_high; +extern char *end_avail; + +unsigned int heap_use, heap_max; + +struct memchunk { + unsigned int size; + struct memchunk *next; +}; + +static struct memchunk *freechunks; + +static void *zalloc(unsigned size) +{ + void *p; + struct memchunk **mpp, *mp; + + size = (size + 7) & -8; + heap_use += size; + if (heap_use > heap_max) + heap_max = heap_use; + for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) { + if (mp->size == size) { + *mpp = mp->next; + return mp; + } + } + p = avail_ram; + avail_ram += size; + if (avail_ram > avail_high) + avail_high = avail_ram; + if (avail_ram > end_avail) { + printf("oops... out of memory\n\r"); + pause(); + } + return p; +} + +#define HEAD_CRC 2 +#define EXTRA_FIELD 4 +#define ORIG_NAME 8 +#define COMMENT 0x10 +#define RESERVED 0xe0 + +void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) +{ + z_stream s; + int r, i, flags; + + /* skip header */ + i = 10; + flags = src[3]; + if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) { + printf("bad gzipped data\n\r"); + exit(); + } + if ((flags & EXTRA_FIELD) != 0) + i = 12 + src[10] + (src[11] << 8); + if ((flags & ORIG_NAME) != 0) + while (src[i++] != 0) + ; + if ((flags & COMMENT) != 0) + while (src[i++] != 0) + ; + if ((flags & HEAD_CRC) != 0) + i += 2; + if (i >= *lenp) { + printf("gunzip: ran out of data in header\n\r"); + exit(); + } + + /* Initialize ourself. */ + s.workspace = zalloc(zlib_inflate_workspacesize()); + r = zlib_inflateInit2(&s, -MAX_WBITS); + if (r != Z_OK) { + printf("zlib_inflateInit2 returned %d\n\r", r); + exit(); + } + s.next_in = src + i; + s.avail_in = *lenp - i; + s.next_out = dst; + s.avail_out = dstlen; + r = zlib_inflate(&s, Z_FINISH); + if (r != Z_OK && r != Z_STREAM_END) { + printf("inflate returned %d msg: %s\n\r", r, s.msg); + exit(); + } + *lenp = s.next_out - (unsigned char *) dst; + zlib_inflateEnd(&s); +} + +/* Make a bi_rec in OF. We need to be passed a name for BI_BOOTLOADER_ID, + * a machine type for BI_MACHTYPE, and the location where the end of the + * bootloader is (PROG_START + PROG_SIZE) + */ +void make_bi_recs(unsigned long addr, char *name, unsigned int mach, + unsigned long progend) +{ + struct bi_record *rec; + + + /* leave a 1MB gap then align to the next 1MB boundary */ + addr = _ALIGN(addr+ (1<<20) - 1, (1<<20)); + /* oldworld machine seem very unhappy about this. -- Tom */ + if (addr >= progend) + claim(addr, 0x1000, 0); + + rec = (struct bi_record *)addr; + rec->tag = BI_FIRST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_BOOTLOADER_ID; + sprintf( (char *)rec->data, name); + rec->size = sizeof(struct bi_record) + strlen(name) + 1; + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_MACHTYPE; + rec->data[0] = mach; + rec->data[1] = 1; + rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_LAST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); +} diff --git a/trunk/arch/ppc/boot/openfirmware/dummy.c b/trunk/arch/ppc/boot/openfirmware/dummy.c new file mode 100644 index 000000000000..31dbf45bf99c --- /dev/null +++ b/trunk/arch/ppc/boot/openfirmware/dummy.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff --git a/trunk/arch/ppc/boot/openfirmware/misc.S b/trunk/arch/ppc/boot/openfirmware/misc.S new file mode 100644 index 000000000000..ab9e897cadd0 --- /dev/null +++ b/trunk/arch/ppc/boot/openfirmware/misc.S @@ -0,0 +1,67 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * + * 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. + */ + .text + +/* + * Use the BAT2 & 3 registers to map the 1st 16MB of RAM to + * the address given as the 1st argument. + */ + .globl setup_bats +setup_bats: + mfpvr 5 + rlwinm 5,5,16,16,31 /* r3 = 1 for 601, 4 for 604 */ + cmpwi 0,5,1 + li 0,0 + bne 4f + mtibatl 3,0 /* invalidate BAT first */ + ori 3,3,4 /* set up BAT registers for 601 */ + li 4,0x7f + mtibatu 2,3 + mtibatl 2,4 + oris 3,3,0x80 + oris 4,4,0x80 + mtibatu 3,3 + mtibatl 3,4 + b 5f +4: mtdbatu 3,0 /* invalidate BATs first */ + mtibatu 3,0 + ori 3,3,0xff /* set up BAT registers for 604 */ + li 4,2 + mtdbatl 2,4 + mtdbatu 2,3 + mtibatl 2,4 + mtibatu 2,3 + oris 3,3,0x80 + oris 4,4,0x80 + mtdbatl 3,4 + mtdbatu 3,3 + mtibatl 3,4 + mtibatu 3,3 +5: sync + isync + blr + +/* + * Flush the dcache and invalidate the icache for a range of addresses. + * + * flush_cache(addr, len) + */ + .global flush_cache +flush_cache: + addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */ + rlwinm. 4,4,27,5,31 + mtctr 4 + beqlr +1: dcbf 0,3 + icbi 0,3 + addi 3,3,0x20 + bdnz 1b + sync + isync + blr diff --git a/trunk/arch/ppc/boot/openfirmware/start.c b/trunk/arch/ppc/boot/openfirmware/start.c new file mode 100644 index 000000000000..1617a26956bf --- /dev/null +++ b/trunk/arch/ppc/boot/openfirmware/start.c @@ -0,0 +1,172 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include "of1275.h" + +extern int strlen(const char *s); +extern void boot(int a1, int a2, void *prom); + +phandle stdin; +phandle stdout; +phandle stderr; + +void printk(char *fmt, ...); + +void +start(int a1, int a2, void *promptr) +{ + ofinit(promptr); + if (ofstdio(&stdin, &stdout, &stderr)) + exit(); + + boot(a1, a2, promptr); + for (;;) + exit(); +} + +int writestring(void *f, char *ptr, int nb) +{ + int w = 0, i; + char *ret = "\r"; + + for (i = 0; i < nb; ++i) { + if (ptr[i] == '\n') { + if (i > w) { + write(f, ptr + w, i - w); + w = i; + } + write(f, ret, 1); + } + } + if (w < nb) + write(f, ptr + w, nb - w); + return nb; +} + +int +putc(int c, void *f) +{ + char ch = c; + + return writestring(f, &ch, 1) == 1? c: -1; +} + +int +putchar(int c) +{ + return putc(c, stdout); +} + +int +fputs(char *str, void *f) +{ + int n = strlen(str); + + return writestring(f, str, n) == n? 0: -1; +} + +int +readchar(void) +{ + char ch; + + for (;;) { + switch (read(stdin, &ch, 1)) { + case 1: + return ch; + case -1: + printk("read(stdin) returned -1\n"); + return -1; + } + } +} + +static char line[256]; +static char *lineptr; +static int lineleft; + +int +getchar(void) +{ + int c; + + if (lineleft == 0) { + lineptr = line; + for (;;) { + c = readchar(); + if (c == -1 || c == 4) + break; + if (c == '\r' || c == '\n') { + *lineptr++ = '\n'; + putchar('\n'); + break; + } + switch (c) { + case 0177: + case '\b': + if (lineptr > line) { + putchar('\b'); + putchar(' '); + putchar('\b'); + --lineptr; + } + break; + case 'U' & 0x1F: + while (lineptr > line) { + putchar('\b'); + putchar(' '); + putchar('\b'); + --lineptr; + } + break; + default: + if (lineptr >= &line[sizeof(line) - 1]) + putchar('\a'); + else { + putchar(c); + *lineptr++ = c; + } + } + } + lineleft = lineptr - line; + lineptr = line; + } + if (lineleft == 0) + return -1; + --lineleft; + return *lineptr++; +} + +extern int vsprintf(char *buf, const char *fmt, va_list args); +static char sprint_buf[1024]; + +void +printk(char *fmt, ...) +{ + va_list args; + int n; + + va_start(args, fmt); + n = vsprintf(sprint_buf, fmt, args); + va_end(args); + writestring(stdout, sprint_buf, n); +} + +int +printf(char *fmt, ...) +{ + va_list args; + int n; + + va_start(args, fmt); + n = vsprintf(sprint_buf, fmt, args); + va_end(args); + writestring(stdout, sprint_buf, n); + return n; +} diff --git a/trunk/arch/ppc/boot/simple/mpc10x_memory.c b/trunk/arch/ppc/boot/simple/mpc10x_memory.c index 8da8f576031d..c24290823f7f 100644 --- a/trunk/arch/ppc/boot/simple/mpc10x_memory.c +++ b/trunk/arch/ppc/boot/simple/mpc10x_memory.c @@ -50,10 +50,10 @@ MPC10X_PCI_OP(read, dword, u32 *, in_le32, 0) * the system. This assumes that the firmware has correctly set up the memory * controller registers. On CONFIG_PPC_PREP, we know we are being called * under a PReP memory map. On all other machines, we assume we are under - * a CHRP memory map. Further, on CONFIG_PPC_PREP we must rename + * a CHRP memory map. Further, on CONFIG_PPC_MULTIPLATFORM we must rename * this function. */ -#ifdef CONFIG_PPC_PREP +#ifdef CONFIG_PPC_MULTIPLATFORM #define get_mem_size mpc10x_get_mem_size #endif unsigned long diff --git a/trunk/arch/ppc/boot/simple/relocate.S b/trunk/arch/ppc/boot/simple/relocate.S index 2533113c1cc5..7efddc507564 100644 --- a/trunk/arch/ppc/boot/simple/relocate.S +++ b/trunk/arch/ppc/boot/simple/relocate.S @@ -194,7 +194,7 @@ start_ldr: /* * Start at the begining. */ -#ifdef CONFIG_PPC_PREP +#ifdef CONFIG_PPC_MULTIPLATFORM li r9,0xc mtlr r9 /* tell kernel we're prep, by putting 0xdeadc0de at KERNELLOAD, diff --git a/trunk/arch/ppc/boot/utils/addnote.c b/trunk/arch/ppc/boot/utils/addnote.c new file mode 100644 index 000000000000..6c52b18f2d04 --- /dev/null +++ b/trunk/arch/ppc/boot/utils/addnote.c @@ -0,0 +1,175 @@ +/* + * Program to hack in a PT_NOTE program header entry in an ELF file. + * This is needed for OF on RS/6000s to load an image correctly. + * Note that OF needs a program header entry for the note, not an + * ELF section. + * + * Copyright 2000 Paul Mackerras. + * + * 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. + * + * Usage: addnote zImage + */ +#include +#include +#include +#include +#include + +char arch[] = "PowerPC"; + +#define N_DESCR 6 +unsigned int descr[N_DESCR] = { +#if 1 + /* values for IBM RS/6000 machines */ + 0xffffffff, /* real-mode = true */ + 0x00c00000, /* real-base, i.e. where we expect OF to be */ + 0xffffffff, /* real-size */ + 0xffffffff, /* virt-base */ + 0xffffffff, /* virt-size */ + 0x4000, /* load-base */ +#else + /* values for longtrail CHRP */ + 0, /* real-mode = false */ + 0xffffffff, /* real-base */ + 0xffffffff, /* real-size */ + 0xffffffff, /* virt-base */ + 0xffffffff, /* virt-size */ + 0x00600000, /* load-base */ +#endif +}; + +unsigned char buf[512]; + +#define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1])) +#define GET_32BE(off) ((GET_16BE(off) << 16) + GET_16BE((off)+2)) + +#define PUT_16BE(off, v) (buf[off] = ((v) >> 8) & 0xff, \ + buf[(off) + 1] = (v) & 0xff) +#define PUT_32BE(off, v) (PUT_16BE((off), (v) >> 16), \ + PUT_16BE((off) + 2, (v))) + +/* Structure of an ELF file */ +#define E_IDENT 0 /* ELF header */ +#define E_PHOFF 28 +#define E_PHENTSIZE 42 +#define E_PHNUM 44 +#define E_HSIZE 52 /* size of ELF header */ + +#define EI_MAGIC 0 /* offsets in E_IDENT area */ +#define EI_CLASS 4 +#define EI_DATA 5 + +#define PH_TYPE 0 /* ELF program header */ +#define PH_OFFSET 4 +#define PH_FILESZ 16 +#define PH_HSIZE 32 /* size of program header */ + +#define PT_NOTE 4 /* Program header type = note */ + +#define ELFCLASS32 1 +#define ELFDATA2MSB 2 + +unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' }; + +int main(int ac, char **av) +{ + int fd, n, i; + int ph, ps, np; + int nnote, ns; + + if (ac != 2) { + fprintf(stderr, "Usage: %s elf-file\n", av[0]); + exit(1); + } + fd = open(av[1], O_RDWR); + if (fd < 0) { + perror(av[1]); + exit(1); + } + + nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4; + + n = read(fd, buf, sizeof(buf)); + if (n < 0) { + perror("read"); + exit(1); + } + + if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0) + goto notelf; + + if (buf[E_IDENT+EI_CLASS] != ELFCLASS32 + || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) { + fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n", + av[1]); + exit(1); + } + + ph = GET_32BE(E_PHOFF); + ps = GET_16BE(E_PHENTSIZE); + np = GET_16BE(E_PHNUM); + if (ph < E_HSIZE || ps < PH_HSIZE || np < 1) + goto notelf; + if (ph + (np + 1) * ps + nnote > n) + goto nospace; + + for (i = 0; i < np; ++i) { + if (GET_32BE(ph + PH_TYPE) == PT_NOTE) { + fprintf(stderr, "%s already has a note entry\n", + av[1]); + exit(0); + } + ph += ps; + } + + /* XXX check that the area we want to use is all zeroes */ + for (i = 0; i < ps + nnote; ++i) + if (buf[ph + i] != 0) + goto nospace; + + /* fill in the program header entry */ + ns = ph + ps; + PUT_32BE(ph + PH_TYPE, PT_NOTE); + PUT_32BE(ph + PH_OFFSET, ns); + PUT_32BE(ph + PH_FILESZ, nnote); + + /* fill in the note area we point to */ + /* XXX we should probably make this a proper section */ + PUT_32BE(ns, strlen(arch) + 1); + PUT_32BE(ns + 4, N_DESCR * 4); + PUT_32BE(ns + 8, 0x1275); + strcpy(&buf[ns + 12], arch); + ns += 12 + strlen(arch) + 1; + for (i = 0; i < N_DESCR; ++i) + PUT_32BE(ns + i * 4, descr[i]); + + /* Update the number of program headers */ + PUT_16BE(E_PHNUM, np + 1); + + /* write back */ + lseek(fd, (long) 0, SEEK_SET); + i = write(fd, buf, n); + if (i < 0) { + perror("write"); + exit(1); + } + if (i < n) { + fprintf(stderr, "%s: write truncated\n", av[1]); + exit(1); + } + + exit(0); + + notelf: + fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]); + exit(1); + + nospace: + fprintf(stderr, "sorry, I can't find space in %s to put the note\n", + av[0]); + exit(1); +} diff --git a/trunk/arch/ppc/boot/utils/hack-coff.c b/trunk/arch/ppc/boot/utils/hack-coff.c new file mode 100644 index 000000000000..5e5a6573a1ef --- /dev/null +++ b/trunk/arch/ppc/boot/utils/hack-coff.c @@ -0,0 +1,84 @@ +/* + * hack-coff.c - hack the header of an xcoff file to fill in + * a few fields needed by the Open Firmware xcoff loader on + * Power Macs but not initialized by objcopy. + * + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include "rs6000.h" + +#define AOUT_MAGIC 0x010b + +#define get_16be(x) ((((unsigned char *)(x))[0] << 8) \ + + ((unsigned char *)(x))[1]) +#define put_16be(x, v) (((unsigned char *)(x))[0] = (v) >> 8, \ + ((unsigned char *)(x))[1] = (v) & 0xff) +#define get_32be(x) ((((unsigned char *)(x))[0] << 24) \ + + (((unsigned char *)(x))[1] << 16) \ + + (((unsigned char *)(x))[2] << 8) \ + + ((unsigned char *)(x))[3]) + +int +main(int ac, char **av) +{ + int fd; + int i, nsect; + int aoutsz; + struct external_filehdr fhdr; + AOUTHDR aout; + struct external_scnhdr shdr; + + if (ac != 2) { + fprintf(stderr, "Usage: hack-coff coff-file\n"); + exit(1); + } + if ((fd = open(av[1], 2)) == -1) { + perror(av[2]); + exit(1); + } + if (read(fd, &fhdr, sizeof(fhdr)) != sizeof(fhdr)) + goto readerr; + i = get_16be(fhdr.f_magic); + if (i != U802TOCMAGIC && i != U802WRMAGIC && i != U802ROMAGIC) { + fprintf(stderr, "%s: not an xcoff file\n", av[1]); + exit(1); + } + aoutsz = get_16be(fhdr.f_opthdr); + if (read(fd, &aout, aoutsz) != aoutsz) + goto readerr; + nsect = get_16be(fhdr.f_nscns); + for (i = 0; i < nsect; ++i) { + if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr)) + goto readerr; + if (strcmp(shdr.s_name, ".text") == 0) { + put_16be(aout.o_snentry, i+1); + put_16be(aout.o_sntext, i+1); + } else if (strcmp(shdr.s_name, ".data") == 0) { + put_16be(aout.o_sndata, i+1); + } else if (strcmp(shdr.s_name, ".bss") == 0) { + put_16be(aout.o_snbss, i+1); + } + } + put_16be(aout.magic, AOUT_MAGIC); + if (lseek(fd, (long) sizeof(struct external_filehdr), 0) == -1 + || write(fd, &aout, aoutsz) != aoutsz) { + fprintf(stderr, "%s: write error\n", av[1]); + exit(1); + } + close(fd); + exit(0); + +readerr: + fprintf(stderr, "%s: read error or file too short\n", av[1]); + exit(1); +} diff --git a/trunk/arch/ppc/boot/utils/mknote.c b/trunk/arch/ppc/boot/utils/mknote.c new file mode 100644 index 000000000000..b9fbb2cbfc8f --- /dev/null +++ b/trunk/arch/ppc/boot/utils/mknote.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) Cort Dougan 1999. + * + * 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. + * + * Generate a note section as per the CHRP specification. + * + */ + +#include +#include + +#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff ); + +int main(void) +{ +/* header */ + /* namesz */ + PL(strlen("PowerPC")+1); + /* descrsz */ + PL(6*4); + /* type */ + PL(0x1275); + /* name */ + printf("PowerPC"); printf("%c", 0); + +/* descriptor */ + /* real-mode */ + PL(0xffffffff); + /* real-base */ + PL(0x00c00000); + /* real-size */ + PL(0xffffffff); + /* virt-base */ + PL(0xffffffff); + /* virt-size */ + PL(0xffffffff); + /* load-base */ + PL(0x4000); + return 0; +} diff --git a/trunk/arch/ppc/configs/prep_defconfig b/trunk/arch/ppc/configs/common_defconfig similarity index 100% rename from trunk/arch/ppc/configs/prep_defconfig rename to trunk/arch/ppc/configs/common_defconfig diff --git a/trunk/arch/ppc/configs/ibmchrp_defconfig b/trunk/arch/ppc/configs/ibmchrp_defconfig new file mode 100644 index 000000000000..27f3e69c1f96 --- /dev/null +++ b/trunk/arch/ppc/configs/ibmchrp_defconfig @@ -0,0 +1,875 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MMU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_GENERIC_NVRAM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +# CONFIG_STANDALONE is not set +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_HOTPLUG is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Processor +# +CONFIG_6xx=y +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_ALTIVEC is not set +# CONFIG_TAU is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_PPC601_SYNC_FIX is not set +CONFIG_PPC_STD_MMU=y + +# +# Platform options +# +CONFIG_PPC_MULTIPLATFORM=y +# CONFIG_APUS is not set +# CONFIG_WILLOW is not set +# CONFIG_PCORE is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_EV64260 is not set +# CONFIG_SPRUCE is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PPLUS is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_PAL4 is not set +# CONFIG_GEMINI is not set +# CONFIG_EST8260 is not set +# CONFIG_SBS8260 is not set +# CONFIG_RPX6 is not set +# CONFIG_TQM8260 is not set +CONFIG_PPC_CHRP=y +CONFIG_PPC_PMAC=y +CONFIG_PPC_PREP=y +CONFIG_PPC_OF=y +CONFIG_PPCBUG_NVRAM=y +# CONFIG_SMP is not set +# CONFIG_PREEMPT is not set +CONFIG_HIGHMEM=y +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=y +CONFIG_PROC_DEVICETREE=y +CONFIG_PPC_RTAS=y +# CONFIG_PREP_RESIDUAL is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Bus options +# +CONFIG_ISA=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +CONFIG_BOOT_LOAD=0x00800000 + +# +# Device Drivers +# + +# +# Generic Driver Options +# + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +CONFIG_BLK_DEV_FD=y +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_CARMEL is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_LBD=y + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_REPORT_LUNS is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_FC_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_QLA6322 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_MESH is not set +# CONFIG_SCSI_MAC53C94 is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Macintosh device drivers +# +# CONFIG_ADB is not set +# CONFIG_ADB_CUDA is not set +# CONFIG_ADB_PMU is not set +# CONFIG_MAC_FLOPPY is not set +# CONFIG_MAC_SERIAL is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_AMANDA=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MAC=m +# CONFIG_IP_NF_MATCH_PKTTYPE is not set +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_COMPAT_IPCHAINS=m +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +CONFIG_IP_NF_TARGET_NOTRACK=m +CONFIG_IP_NF_RAW=m + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_OAKNET is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=y +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_CS89x0 is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_CONSOLE is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +# CONFIG_SERIAL_PMACZILOG is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_NVRAM=y +CONFIG_GEN_RTC=y +# CONFIG_GEN_RTC_X is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +CONFIG_FB_OF=y +# CONFIG_FB_CONTROL is not set +# CONFIG_FB_PLATINUM is not set +# CONFIG_FB_VALKYRIE is not set +# CONFIG_FB_CT65550 is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_S3TRIO is not set +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_RIVA is not set +CONFIG_FB_MATROX=y +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +# CONFIG_FB_MATROX_G450 is not set +CONFIG_FB_MATROX_G100A=y +CONFIG_FB_MATROX_G100=y +# CONFIG_FB_MATROX_MULTIHEAD is not set +# CONFIG_FB_RADEON_OLD is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +CONFIG_FB_3DFX=y +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_PCI_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +CONFIG_DEVFS_FS=y +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_EXPORTFS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_NEC98_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Library routines +# +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set + +# +# Kernel hacking +# +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_BOOTX_TEXT is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set diff --git a/trunk/arch/ppc/configs/pmac_defconfig b/trunk/arch/ppc/configs/pmac_defconfig new file mode 100644 index 000000000000..a2db8b541c9b --- /dev/null +++ b/trunk/arch/ppc/configs/pmac_defconfig @@ -0,0 +1,1591 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.13-rc3 +# Wed Jul 13 14:13:13 2005 +# +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y + +# +# Processor +# +CONFIG_6xx=y +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_E200 is not set +# CONFIG_E500 is not set +CONFIG_PPC_FPU=y +CONFIG_ALTIVEC=y +CONFIG_TAU=y +# CONFIG_TAU_INT is not set +# CONFIG_TAU_AVERAGE is not set +# CONFIG_KEXEC is not set +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_PMAC=y +CONFIG_PPC601_SYNC_FIX=y +CONFIG_PM=y +CONFIG_PPC_STD_MMU=y + +# +# Platform options +# +CONFIG_PPC_MULTIPLATFORM=y +# CONFIG_APUS is not set +# CONFIG_KATANA is not set +# CONFIG_WILLOW is not set +# CONFIG_CPCI690 is not set +# CONFIG_PCORE is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_CHESTNUT is not set +# CONFIG_SPRUCE is not set +# CONFIG_HDPU is not set +# CONFIG_EV64260 is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PPLUS is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_RADSTONE_PPC7D is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_PAL4 is not set +# CONFIG_GEMINI is not set +# CONFIG_EST8260 is not set +# CONFIG_SBC82xx is not set +# CONFIG_SBS8260 is not set +# CONFIG_RPX8260 is not set +# CONFIG_TQM8260 is not set +# CONFIG_ADS8272 is not set +# CONFIG_PQ2FADS is not set +# CONFIG_LITE5200 is not set +# CONFIG_MPC834x_SYS is not set +CONFIG_PPC_CHRP=y +CONFIG_PPC_PMAC=y +CONFIG_PPC_PREP=y +CONFIG_PPC_OF=y +CONFIG_PPCBUG_NVRAM=y +# CONFIG_SMP is not set +# CONFIG_HIGHMEM is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_PROC_DEVICETREE=y +# CONFIG_PREP_RESIDUAL is not set +# CONFIG_CMDLINE_BOOL is not set +# CONFIG_PM_DEBUG is not set +CONFIG_SOFTWARE_SUSPEND=y +CONFIG_PM_STD_PARTITION="" +# CONFIG_SECCOMP is not set +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +# CONFIG_ISA is not set +CONFIG_GENERIC_ISA_DMA=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=m +# CONFIG_PCMCIA_LOAD_CIS is not set +# CONFIG_PCMCIA_IOCTL is not set +CONFIG_CARDBUS=y + +# +# PC-card bridges +# +CONFIG_YENTA=m +# CONFIG_PD6729 is not set +# CONFIG_I82092 is not set +# CONFIG_TCIC is not set +CONFIG_PCCARD_NONSTATIC=m + +# +# Advanced setup +# +CONFIG_ADVANCED_OPTIONS=y +CONFIG_HIGHMEM_START=0xfe000000 +# CONFIG_LOWMEM_SIZE_BOOL is not set +CONFIG_LOWMEM_SIZE=0x30000000 +# CONFIG_KERNEL_START_BOOL is not set +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE_BOOL=y +CONFIG_TASK_SIZE=0xc0000000 +CONFIG_BOOT_LOAD=0x00800000 + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_CT_ACCT=y +CONFIG_IP_NF_CONNTRACK_MARK=y +CONFIG_IP_NF_CT_PROTO_SCTP=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_AMANDA=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_REALM=m +CONFIG_IP_NF_MATCH_SCTP=m +CONFIG_IP_NF_MATCH_COMMENT=m +CONFIG_IP_NF_MATCH_CONNMARK=m +CONFIG_IP_NF_MATCH_HASHLIMIT=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_CLASSIFY=m +CONFIG_IP_NF_TARGET_CONNMARK=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_NOTRACK=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set +CONFIG_NET_CLS_ROUTE=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_RX is not set +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_HAMRADIO is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# Old SIR device drivers +# +# CONFIG_IRPORT_SIR is not set + +# +# Old Serial dongle support +# + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_SIGMATEL_FIR is not set +# CONFIG_NSC_FIR is not set +# CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_FIR is not set +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +# CONFIG_VLSI_FIR is not set +# CONFIG_VIA_FIR is not set +# CONFIG_BT is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +# CONFIG_STANDALONE is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +CONFIG_MAC_FLOPPY=m +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_LBD=y +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDEFLOPPY=y +CONFIG_BLK_DEV_IDESCSI=y +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_IDE_GENERIC is not set +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_SL82C105 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +CONFIG_BLK_DEV_CMD64X=y +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +CONFIG_BLK_DEV_PDC202XX_NEW=y +# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLK_DEV_IDE_PMAC=y +CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y +CONFIG_BLK_DEV_IDEDMA_PMAC=y +CONFIG_BLK_DEV_IDE_PMAC_BLINK=y +# CONFIG_IDE_ARM is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +CONFIG_SCSI_AIC7XXX_OLD=m +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +CONFIG_SCSI_MESH=y +CONFIG_SCSI_MESH_SYNC_RATE=5 +CONFIG_SCSI_MESH_RESET_DELAY_MS=1000 +CONFIG_SCSI_MAC53C94=y + +# +# PCMCIA SCSI adapter support +# +# CONFIG_PCMCIA_AHA152X is not set +# CONFIG_PCMCIA_FDOMAIN is not set +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_QLOGIC is not set +# CONFIG_PCMCIA_SYM53C500 is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set + +# +# IEEE 1394 (FireWire) support +# +CONFIG_IEEE1394=m + +# +# Subsystem Options +# +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +# CONFIG_IEEE1394_OUI_DB is not set +CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y +CONFIG_IEEE1394_CONFIG_ROM_IP1394=y +# CONFIG_IEEE1394_EXPORT_FULL_API is not set + +# +# Device Drivers +# +# CONFIG_IEEE1394_PCILYNX is not set +CONFIG_IEEE1394_OHCI1394=m + +# +# Protocol Drivers +# +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_CMP=m +CONFIG_IEEE1394_AMDTP=m + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Macintosh device drivers +# +CONFIG_ADB=y +CONFIG_ADB_CUDA=y +CONFIG_ADB_PMU=y +CONFIG_PMAC_APM_EMU=y +CONFIG_PMAC_MEDIABAY=y +CONFIG_PMAC_BACKLIGHT=y +CONFIG_ADB_MACIO=y +CONFIG_INPUT_ADBHID=y +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_THERM_WINDTUNNEL=m +CONFIG_THERM_ADT746X=m +# CONFIG_ANSLCD is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_MACE=y +# CONFIG_MACE_AAUI_PORT is not set +CONFIG_BMAC=y +# CONFIG_HAPPYMEAL is not set +CONFIG_SUNGEM=y +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=y +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SKGE is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_MV643XX_ETH is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +# CONFIG_PCMCIA_WAVELAN is not set +# CONFIG_PCMCIA_NETWAVE is not set + +# +# Wireless 802.11 Frequency Hopping cards support +# +# CONFIG_PCMCIA_RAYCS is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +CONFIG_HERMES=m +CONFIG_APPLE_AIRPORT=m +# CONFIG_PLX_HERMES is not set +# CONFIG_TMD_HERMES is not set +# CONFIG_PCI_HERMES is not set +# CONFIG_ATMEL is not set + +# +# Wireless 802.11b Pcmcia/Cardbus cards support +# +CONFIG_PCMCIA_HERMES=m +# CONFIG_AIRO_CS is not set +# CONFIG_PCMCIA_WL3501 is not set + +# +# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support +# +# CONFIG_PRISM54 is not set +CONFIG_NET_WIRELESS=y + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PPP=y +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_BSDCOMP=m +CONFIG_PPPOE=m +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +CONFIG_NETCONSOLE=m + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=m +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_PMACZILOG=y +CONFIG_SERIAL_PMACZILOG_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_NVRAM=y +CONFIG_GEN_RTC=y +# CONFIG_GEN_RTC_X is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +CONFIG_AGP=m +CONFIG_AGP_UNINORTH=m +CONFIG_DRM=m +# CONFIG_DRM_TDFX is not set +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +# CONFIG_DRM_MGA is not set +# CONFIG_DRM_SIS is not set +# CONFIG_DRM_VIA is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_HYDRA is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_ISA is not set +CONFIG_I2C_KEYWEST=m +# CONFIG_I2C_MPC is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set +# CONFIG_I2C_SENSOR is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_M41T00 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +CONFIG_FB_MACMODES=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +CONFIG_FB_OF=y +CONFIG_FB_CONTROL=y +CONFIG_FB_PLATINUM=y +CONFIG_FB_VALKYRIE=y +CONFIG_FB_CT65550=y +# CONFIG_FB_ASILIANT is not set +CONFIG_FB_IMSTT=y +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +CONFIG_FB_MATROX=y +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G=y +# CONFIG_FB_MATROX_I2C is not set +# CONFIG_FB_MATROX_MULTIHEAD is not set +# CONFIG_FB_RADEON_OLD is not set +CONFIG_FB_RADEON=y +CONFIG_FB_RADEON_I2C=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_ATY128=y +CONFIG_FB_ATY=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +# CONFIG_FB_ATY_XL_INIT is not set +CONFIG_FB_ATY_GX=y +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +CONFIG_FB_3DFX=y +CONFIG_FB_3DFX_ACCEL=y +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_DEVICE=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_LCD_DEVICE=y + +# +# Sound +# +CONFIG_SOUND=m +CONFIG_DMASOUND_PMAC=m +CONFIG_DMASOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +CONFIG_SND_DUMMY=m +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# PCI devices +# +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_HDA_INTEL is not set + +# +# ALSA PowerMac devices +# +CONFIG_SND_POWERMAC=m + +# +# USB devices +# +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_USX2Y=m + +# +# PCMCIA devices +# + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +CONFIG_USB_DYNAMIC_MINORS=y +CONFIG_USB_SUSPEND=y +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH_TTY is not set +# CONFIG_USB_MIDI is not set +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# +# CONFIG_USB_STORAGE is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_HID_FF is not set +CONFIG_USB_HIDDEV=y +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set +# CONFIG_USB_EGALAX is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +CONFIG_USB_PEGASUS=m +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_USB_MON is not set + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_AIRPRIME is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP2101 is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +CONFIG_USB_SERIAL_VISOR=m +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OPTION is not set +# CONFIG_USB_SERIAL_OMNINET is not set +CONFIG_USB_EZUSB=y + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# SN Devices +# + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +CONFIG_TMPFS=y +CONFIG_TMPFS_XATTR=y +CONFIG_TMPFS_SECURITY=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_CRAMFS=m +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +# CONFIG_NFSD_V4 is not set +CONFIG_NFSD_TCP=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=m +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m + +# +# Library routines +# +CONFIG_CRC_CCITT=y +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=16 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set +CONFIG_BOOTX_TEXT=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# diff --git a/trunk/arch/ppc/configs/power3_defconfig b/trunk/arch/ppc/configs/power3_defconfig new file mode 100644 index 000000000000..a1ef929bca59 --- /dev/null +++ b/trunk/arch/ppc/configs/power3_defconfig @@ -0,0 +1,1035 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MMU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_GENERIC_NVRAM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +# CONFIG_STANDALONE is not set + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_HOTPLUG is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y +CONFIG_STOP_MACHINE=y + +# +# Processor +# +# CONFIG_6xx is not set +# CONFIG_40x is not set +# CONFIG_44x is not set +CONFIG_POWER3=y +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_CPU_FREQ is not set +CONFIG_PPC64BRIDGE=y +CONFIG_PPC_STD_MMU=y + +# +# Platform options +# +CONFIG_PPC_MULTIPLATFORM=y +# CONFIG_APUS is not set +# CONFIG_WILLOW is not set +# CONFIG_PCORE is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_EV64260 is not set +# CONFIG_SPRUCE is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PPLUS is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_PAL4 is not set +# CONFIG_GEMINI is not set +# CONFIG_EST8260 is not set +# CONFIG_SBS8260 is not set +# CONFIG_RPX6 is not set +# CONFIG_TQM8260 is not set +CONFIG_PPC_CHRP=y +CONFIG_PPC_PMAC=y +CONFIG_PPC_PREP=y +CONFIG_PPC_OF=y +CONFIG_PPCBUG_NVRAM=y +CONFIG_SMP=y +# CONFIG_IRQ_ALL_CPUS is not set +CONFIG_NR_CPUS=32 +# CONFIG_PREEMPT is not set +CONFIG_HIGHMEM=y +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=y +CONFIG_PROC_DEVICETREE=y +CONFIG_PPC_RTAS=y +# CONFIG_PREP_RESIDUAL is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Bus options +# +CONFIG_ISA=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y + +# +# Advanced setup +# +CONFIG_ADVANCED_OPTIONS=y +# CONFIG_HIGHMEM_START_BOOL is not set +CONFIG_HIGHMEM_START=0xfe000000 +# CONFIG_LOWMEM_SIZE_BOOL is not set +CONFIG_LOWMEM_SIZE=0x30000000 +# CONFIG_KERNEL_START_BOOL is not set +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE_BOOL=y +CONFIG_TASK_SIZE=0xc0000000 +CONFIG_BOOT_LOAD=0x00800000 + +# +# Device Drivers +# + +# +# Generic Driver Options +# + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_CML1=m +# CONFIG_PARPORT_SERIAL is not set +CONFIG_PARPORT_PC_FIFO=y +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_OTHER is not set +# CONFIG_PARPORT_1284 is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +CONFIG_BLK_DEV_FD=y +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_CARMEL is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_LBD=y + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_REPORT_LUNS is not set +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y + +# +# SCSI Transport Attributes +# +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_FC_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_NCR53C406A is not set +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_QLA6322 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_MESH is not set +# CONFIG_SCSI_MAC53C94 is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=y +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +CONFIG_MD_RAID5=y +CONFIG_MD_RAID6=y +# CONFIG_MD_MULTIPATH is not set +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=y + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Macintosh device drivers +# +# CONFIG_ADB is not set +# CONFIG_ADB_CUDA is not set +# CONFIG_ADB_PMU is not set +# CONFIG_MAC_FLOPPY is not set +# CONFIG_MAC_SERIAL is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_OAKNET is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=y +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_CS89x0 is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +CONFIG_E100=y +# CONFIG_E100_NAPI is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +CONFIG_E1000=y +# CONFIG_E1000_NAPI is not set +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +CONFIG_GAMEPORT=m +CONFIG_SOUND_GAMEPORT=m +# CONFIG_GAMEPORT_NS558 is not set +# CONFIG_GAMEPORT_L4 is not set +# CONFIG_GAMEPORT_EMU10K1 is not set +# CONFIG_GAMEPORT_VORTEX is not set +# CONFIG_GAMEPORT_FM801 is not set +# CONFIG_GAMEPORT_CS461x is not set +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_PMACZILOG is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_NVRAM=y +CONFIG_GEN_RTC=y +# CONFIG_GEN_RTC_X is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_ALGOPCF=y + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_HYDRA is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_KEYWEST is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +CONFIG_FB_OF=y +# CONFIG_FB_CONTROL is not set +# CONFIG_FB_PLATINUM is not set +# CONFIG_FB_VALKYRIE is not set +# CONFIG_FB_CT65550 is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_S3TRIO is not set +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_RIVA is not set +CONFIG_FB_MATROX=y +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +# CONFIG_FB_MATROX_G450 is not set +CONFIG_FB_MATROX_G100A=y +CONFIG_FB_MATROX_G100=y +CONFIG_FB_MATROX_I2C=y +# CONFIG_FB_MATROX_MAVEN is not set +CONFIG_FB_MATROX_MULTIHEAD=y +# CONFIG_FB_RADEON_OLD is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_PCI_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_DMASOUND_PMAC is not set + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +CONFIG_SND_MPU401_UART=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_DUMMY=m +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# ISA devices +# +# CONFIG_SND_AD1848 is not set +# CONFIG_SND_CS4231 is not set +CONFIG_SND_CS4232=m +# CONFIG_SND_CS4236 is not set +# CONFIG_SND_ES1688 is not set +# CONFIG_SND_ES18XX is not set +# CONFIG_SND_GUSCLASSIC is not set +# CONFIG_SND_GUSEXTREME is not set +# CONFIG_SND_GUSMAX is not set +# CONFIG_SND_INTERWAVE is not set +# CONFIG_SND_INTERWAVE_STB is not set +# CONFIG_SND_OPTI92X_AD1848 is not set +# CONFIG_SND_OPTI92X_CS4231 is not set +# CONFIG_SND_OPTI93X is not set +# CONFIG_SND_SB8 is not set +# CONFIG_SND_SB16 is not set +# CONFIG_SND_SBAWE is not set +# CONFIG_SND_WAVEFRONT is not set +# CONFIG_SND_CMI8330 is not set +# CONFIG_SND_OPL3SA2 is not set +# CONFIG_SND_SGALAXY is not set +# CONFIG_SND_SSCAPE is not set + +# +# PCI devices +# +CONFIG_SND_AC97_CODEC=m +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +CONFIG_SND_CS46XX=m +# CONFIG_SND_CS46XX_NEW_DSP is not set +CONFIG_SND_CS4281=m +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VX222 is not set + +# +# ALSA PowerMac devices +# +# CONFIG_SND_POWERMAC is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_LOCKD=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Library routines +# +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m + +# +# Kernel hacking +# +# CONFIG_DEBUG_KERNEL is not set +CONFIG_BOOTX_TEXT=y + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +# CONFIG_CRYPTO_SERPENT is not set +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set diff --git a/trunk/arch/ppc/kernel/Makefile b/trunk/arch/ppc/kernel/Makefile index 466437f4bcbb..e399bbb969a4 100644 --- a/trunk/arch/ppc/kernel/Makefile +++ b/trunk/arch/ppc/kernel/Makefile @@ -1,24 +1,48 @@ # # Makefile for the linux kernel. # +ifneq ($(CONFIG_PPC_MERGE),y) + extra-$(CONFIG_PPC_STD_MMU) := head.o extra-$(CONFIG_40x) := head_4xx.o extra-$(CONFIG_44x) := head_44x.o extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o extra-$(CONFIG_8xx) := head_8xx.o +extra-$(CONFIG_6xx) += idle_6xx.o extra-y += vmlinux.lds -obj-y := entry.o traps.o time.o misc.o \ +obj-y := entry.o traps.o idle.o time.o misc.o \ setup.o \ ppc_htab.o -obj-$(CONFIG_MODULES) += ppc_ksyms.o +obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o +obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o +obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_RAPIDIO) += rio.o obj-$(CONFIG_KGDB) += ppc-stub.o obj-$(CONFIG_SMP) += smp.o smp-tbsync.o +obj-$(CONFIG_TAU) += temp.o +ifndef CONFIG_E200 +obj-$(CONFIG_FSL_BOOKE) += perfmon_fsl_booke.o +endif obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o ifndef CONFIG_MATH_EMULATION obj-$(CONFIG_8xx) += softemu8xx.o endif + +# These are here while we do the architecture merge + +else +obj-y := idle.o +obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o +obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o +obj-$(CONFIG_MODULES) += module.o +obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o +obj-$(CONFIG_KGDB) += ppc-stub.o +obj-$(CONFIG_TAU) += temp.o +ifndef CONFIG_E200 +obj-$(CONFIG_FSL_BOOKE) += perfmon_fsl_booke.o +endif +endif diff --git a/trunk/arch/powerpc/kernel/cpu_setup_6xx.S b/trunk/arch/ppc/kernel/cpu_setup_6xx.S similarity index 100% rename from trunk/arch/powerpc/kernel/cpu_setup_6xx.S rename to trunk/arch/ppc/kernel/cpu_setup_6xx.S diff --git a/trunk/arch/ppc/kernel/entry.S b/trunk/arch/ppc/kernel/entry.S index 5891ecbdc703..3a2815978488 100644 --- a/trunk/arch/ppc/kernel/entry.S +++ b/trunk/arch/ppc/kernel/entry.S @@ -135,10 +135,10 @@ transfer_to_handler: mfspr r11,SPRN_HID0 mtcr r11 BEGIN_FTR_SECTION - bt- 8,4f /* Check DOZE */ + bt- 8,power_save_6xx_restore /* Check DOZE */ END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) BEGIN_FTR_SECTION - bt- 9,4f /* Check NAP */ + bt- 9,power_save_6xx_restore /* Check NAP */ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #endif /* CONFIG_6xx */ .globl transfer_to_handler_cont @@ -157,10 +157,6 @@ transfer_to_handler_cont: SYNC RFI /* jump to handler, enable MMU */ -#ifdef CONFIG_6xx -4: b power_save_6xx_restore -#endif - /* * On kernel stack overflow, load up an initial stack pointer * and call StackOverflow(regs), which should not return. @@ -930,3 +926,55 @@ END_FTR_SECTION_IFSET(CPU_FTR_601) b 4b .comm ee_restarts,4 + +/* + * PROM code for specific machines follows. Put it + * here so it's easy to add arch-specific sections later. + * -- Cort + */ +#ifdef CONFIG_PPC_OF +/* + * On CHRP, the Run-Time Abstraction Services (RTAS) have to be + * called with the MMU off. + */ +_GLOBAL(enter_rtas) + stwu r1,-INT_FRAME_SIZE(r1) + mflr r0 + stw r0,INT_FRAME_SIZE+4(r1) + lis r4,rtas_data@ha + lwz r4,rtas_data@l(r4) + lis r6,1f@ha /* physical return address for rtas */ + addi r6,r6,1f@l + tophys(r6,r6) + tophys(r7,r1) + lis r8,rtas_entry@ha + lwz r8,rtas_entry@l(r8) + mfmsr r9 + stw r9,8(r1) + LOAD_MSR_KERNEL(r0,MSR_KERNEL) + SYNC /* disable interrupts so SRR0/1 */ + MTMSRD(r0) /* don't get trashed */ + li r9,MSR_KERNEL & ~(MSR_IR|MSR_DR) + mtlr r6 + CLR_TOP32(r7) + mtspr SPRN_SPRG2,r7 + mtspr SPRN_SRR0,r8 + mtspr SPRN_SRR1,r9 + RFI +1: tophys(r9,r1) + lwz r8,INT_FRAME_SIZE+4(r9) /* get return address */ + lwz r9,8(r9) /* original msr value */ + FIX_SRR1(r9,r0) + addi r1,r1,INT_FRAME_SIZE + li r0,0 + mtspr SPRN_SPRG2,r0 + mtspr SPRN_SRR0,r8 + mtspr SPRN_SRR1,r9 + RFI /* return to caller */ + + .globl machine_check_in_rtas +machine_check_in_rtas: + twi 31,0,0 + /* XXX load up BATs and panic */ + +#endif /* CONFIG_PPC_OF */ diff --git a/trunk/arch/ppc/kernel/head.S b/trunk/arch/ppc/kernel/head.S index 01303efeddad..53ea845fb911 100644 --- a/trunk/arch/ppc/kernel/head.S +++ b/trunk/arch/ppc/kernel/head.S @@ -37,6 +37,19 @@ #include #endif +#ifdef CONFIG_PPC64BRIDGE +#define LOAD_BAT(n, reg, RA, RB) \ + ld RA,(n*32)+0(reg); \ + ld RB,(n*32)+8(reg); \ + mtspr SPRN_IBAT##n##U,RA; \ + mtspr SPRN_IBAT##n##L,RB; \ + ld RA,(n*32)+16(reg); \ + ld RB,(n*32)+24(reg); \ + mtspr SPRN_DBAT##n##U,RA; \ + mtspr SPRN_DBAT##n##L,RB; \ + +#else /* CONFIG_PPC64BRIDGE */ + /* 601 only have IBAT; cr0.eq is set on 601 when using this macro */ #define LOAD_BAT(n, reg, RA, RB) \ /* see the comment for clear_bats() -- Cort */ \ @@ -53,6 +66,7 @@ mtspr SPRN_DBAT##n##U,RA; \ mtspr SPRN_DBAT##n##L,RB; \ 1: +#endif /* CONFIG_PPC64BRIDGE */ .text .stabs "arch/ppc/kernel/",N_SO,0,0,0f @@ -115,6 +129,11 @@ _start: .globl __start __start: +/* + * We have to do any OF calls before we map ourselves to KERNELBASE, + * because OF may have I/O devices mapped into that area + * (particularly on CHRP). + */ mr r31,r3 /* save parameters */ mr r30,r4 mr r29,r5 @@ -129,6 +148,14 @@ __start: */ bl early_init +/* + * On POWER4, we first need to tweak some CPU configuration registers + * like real mode cache inhibit or exception base + */ +#ifdef CONFIG_POWER4 + bl __970_cpu_preinit +#endif /* CONFIG_POWER4 */ + #ifdef CONFIG_APUS /* On APUS the __va/__pa constants need to be set to the correct * values before continuing. @@ -142,6 +169,7 @@ __start: */ bl mmu_off __after_mmu_off: +#ifndef CONFIG_POWER4 bl clear_bats bl flush_tlbs @@ -149,6 +177,10 @@ __after_mmu_off: #if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) bl setup_disp_bat #endif +#else /* CONFIG_POWER4 */ + bl reloc_offset + bl initial_mm_power4 +#endif /* CONFIG_POWER4 */ /* * Call setup_cpu for CPU 0 and initialize 6xx Idle @@ -160,11 +192,18 @@ __after_mmu_off: bl reloc_offset bl init_idle_6xx #endif /* CONFIG_6xx */ +#ifdef CONFIG_POWER4 + bl reloc_offset + bl init_idle_power4 +#endif /* CONFIG_POWER4 */ #ifndef CONFIG_APUS /* * We need to run with _start at physical address 0. + * On CHRP, we are loaded at 0x10000 since OF on CHRP uses + * the exception vectors at 0 (and therefore this copy + * overwrites OF's exception vectors with our own). * If the MMU is already turned on, we copy stuff to KERNELBASE, * otherwise we copy it to 0. */ @@ -319,19 +358,51 @@ i##n: \ #endif /* Machine check */ +/* + * On CHRP, this is complicated by the fact that we could get a + * machine check inside RTAS, and we have no guarantee that certain + * critical registers will have the values we expect. The set of + * registers that might have bad values includes all the GPRs + * and all the BATs. We indicate that we are in RTAS by putting + * a non-zero value, the address of the exception frame to use, + * in SPRG2. The machine check handler checks SPRG2 and uses its + * value if it is non-zero. If we ever needed to free up SPRG2, + * we could use a field in the thread_info or thread_struct instead. + * (Other exception handlers assume that r1 is a valid kernel stack + * pointer when we take an exception from supervisor mode.) + * -- paulus. + */ . = 0x200 mtspr SPRN_SPRG0,r10 mtspr SPRN_SPRG1,r11 mfcr r10 +#ifdef CONFIG_PPC_CHRP + mfspr r11,SPRN_SPRG2 + cmpwi 0,r11,0 + bne 7f +#endif /* CONFIG_PPC_CHRP */ EXCEPTION_PROLOG_1 7: EXCEPTION_PROLOG_2 addi r3,r1,STACK_FRAME_OVERHEAD +#ifdef CONFIG_PPC_CHRP + mfspr r4,SPRN_SPRG2 + cmpwi cr1,r4,0 + bne cr1,1f +#endif EXC_XFER_STD(0x200, machine_check_exception) +#ifdef CONFIG_PPC_CHRP +1: b machine_check_in_rtas +#endif /* Data access exception. */ . = 0x300 +#ifdef CONFIG_PPC64BRIDGE + b DataAccess +DataAccessCont: +#else DataAccess: EXCEPTION_PROLOG +#endif /* CONFIG_PPC64BRIDGE */ mfspr r10,SPRN_DSISR andis. r0,r10,0xa470 /* weird error? */ bne 1f /* if not, try to put a PTE */ @@ -343,10 +414,21 @@ DataAccess: mfspr r4,SPRN_DAR EXC_XFER_EE_LITE(0x300, handle_page_fault) +#ifdef CONFIG_PPC64BRIDGE +/* SLB fault on data access. */ + . = 0x380 + b DataSegment +#endif /* CONFIG_PPC64BRIDGE */ + /* Instruction access exception. */ . = 0x400 +#ifdef CONFIG_PPC64BRIDGE + b InstructionAccess +InstructionAccessCont: +#else InstructionAccess: EXCEPTION_PROLOG +#endif /* CONFIG_PPC64BRIDGE */ andis. r0,r9,0x4000 /* no pte found? */ beq 1f /* if so, try to put a PTE */ li r3,0 /* into the hash table */ @@ -356,6 +438,12 @@ InstructionAccess: mr r5,r9 EXC_XFER_EE_LITE(0x400, handle_page_fault) +#ifdef CONFIG_PPC64BRIDGE +/* SLB fault on instruction access. */ + . = 0x480 + b InstructionSegment +#endif /* CONFIG_PPC64BRIDGE */ + /* External interrupt */ EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) @@ -620,9 +708,15 @@ DataStoreTLBMiss: EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception, EXC_XFER_EE) EXCEPTION(0x1400, SMI, SMIException, EXC_XFER_EE) EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE) +#ifdef CONFIG_POWER4 + EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1700, Trap_17, altivec_assist_exception, EXC_XFER_EE) + EXCEPTION(0x1800, Trap_18, TAUException, EXC_XFER_STD) +#else /* !CONFIG_POWER4 */ EXCEPTION(0x1600, Trap_16, altivec_assist_exception, EXC_XFER_EE) EXCEPTION(0x1700, Trap_17, TAUException, EXC_XFER_STD) EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE) +#endif /* CONFIG_POWER4 */ EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE) EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE) EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE) @@ -660,6 +754,28 @@ AltiVecUnavailable: addi r3,r1,STACK_FRAME_OVERHEAD EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception) +#ifdef CONFIG_PPC64BRIDGE +DataAccess: + EXCEPTION_PROLOG + b DataAccessCont + +InstructionAccess: + EXCEPTION_PROLOG + b InstructionAccessCont + +DataSegment: + EXCEPTION_PROLOG + addi r3,r1,STACK_FRAME_OVERHEAD + mfspr r4,SPRN_DAR + stw r4,_DAR(r11) + EXC_XFER_STD(0x380, unknown_exception) + +InstructionSegment: + EXCEPTION_PROLOG + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_STD(0x480, unknown_exception) +#endif /* CONFIG_PPC64BRIDGE */ + #ifdef CONFIG_ALTIVEC /* Note that the AltiVec support is closely modeled after the FP * support. Changes to one are likely to be applicable to the @@ -932,6 +1048,13 @@ __secondary_start_pmac_0: .globl __secondary_start __secondary_start: +#ifdef CONFIG_PPC64BRIDGE + mfmsr r0 + clrldi r0,r0,1 /* make sure it's in 32-bit mode */ + SYNC + MTMSRD(r0) + isync +#endif /* Copy some CPU settings from CPU 0 */ bl __restore_cpu_setup @@ -942,6 +1065,10 @@ __secondary_start: lis r3,-KERNELBASE@h bl init_idle_6xx #endif /* CONFIG_6xx */ +#ifdef CONFIG_POWER4 + lis r3,-KERNELBASE@h + bl init_idle_power4 +#endif /* CONFIG_POWER4 */ /* get current_thread_info and current */ lis r1,secondary_ti@ha @@ -982,12 +1109,12 @@ __secondary_start: * Those generic dummy functions are kept for CPUs not * included in CONFIG_6xx */ -#if !defined(CONFIG_6xx) +#if !defined(CONFIG_6xx) && !defined(CONFIG_POWER4) _GLOBAL(__save_cpu_setup) blr _GLOBAL(__restore_cpu_setup) blr -#endif /* !defined(CONFIG_6xx) */ +#endif /* !defined(CONFIG_6xx) && !defined(CONFIG_POWER4) */ /* @@ -1005,6 +1132,11 @@ load_up_mmu: tophys(r6,r6) lwz r6,_SDR1@l(r6) mtspr SPRN_SDR1,r6 +#ifdef CONFIG_PPC64BRIDGE + /* clear the ASR so we only use the pseudo-segment registers. */ + li r6,0 + mtasr r6 +#endif /* CONFIG_PPC64BRIDGE */ li r0,16 /* load up segment register values */ mtctr r0 /* for context 0 */ lis r3,0x2000 /* Ku = 1, VSID = 0 */ @@ -1013,7 +1145,7 @@ load_up_mmu: addi r3,r3,0x111 /* increment VSID */ addis r4,r4,0x1000 /* address of next segment */ bdnz 3b - +#ifndef CONFIG_POWER4 /* Load the BAT registers with the values set up by MMU_init. MMU_init takes care of whether we're on a 601 or not. */ mfpvr r3 @@ -1026,7 +1158,7 @@ load_up_mmu: LOAD_BAT(1,r3,r4,r5) LOAD_BAT(2,r3,r4,r5) LOAD_BAT(3,r3,r4,r5) - +#endif /* CONFIG_POWER4 */ blr /* @@ -1137,6 +1269,9 @@ _GLOBAL(set_context) li r4,0 isync 3: +#ifdef CONFIG_PPC64BRIDGE + slbie r4 +#endif /* CONFIG_PPC64BRIDGE */ mtsrin r3,r4 addi r3,r3,0x111 /* next VSID */ rlwinm r3,r3,0,8,3 /* clear out any overflow from VSID field */ @@ -1223,6 +1358,7 @@ mmu_off: sync RFI +#ifndef CONFIG_POWER4 /* * Use the first pair of BAT registers to map the 1st 16MB * of RAM to KERNELBASE. From this point on we can't safely @@ -1230,6 +1366,7 @@ mmu_off: */ initial_bats: lis r11,KERNELBASE@h +#ifndef CONFIG_PPC64BRIDGE mfspr r9,SPRN_PVR rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ cmpwi 0,r9,1 @@ -1244,6 +1381,7 @@ initial_bats: mtspr SPRN_IBAT1L,r10 isync blr +#endif /* CONFIG_PPC64BRIDGE */ 4: tophys(r8,r11) #ifdef CONFIG_SMP @@ -1257,6 +1395,11 @@ initial_bats: ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */ #endif /* CONFIG_APUS */ +#ifdef CONFIG_PPC64BRIDGE + /* clear out the high 32 bits in the BAT */ + clrldi r11,r11,32 + clrldi r8,r8,32 +#endif /* CONFIG_PPC64BRIDGE */ mtspr SPRN_DBAT0L,r8 /* N.B. 6xx (not 601) have valid */ mtspr SPRN_DBAT0U,r11 /* bit in upper BAT register */ mtspr SPRN_IBAT0L,r8 @@ -1289,6 +1432,38 @@ setup_disp_bat: #endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */ +#else /* CONFIG_POWER4 */ +/* + * Load up the SDR1 and segment register values now + * since we don't have the BATs. + * Also make sure we are running in 32-bit mode. + */ + +initial_mm_power4: + addis r14,r3,_SDR1@ha /* get the value from _SDR1 */ + lwz r14,_SDR1@l(r14) /* assume hash table below 4GB */ + mtspr SPRN_SDR1,r14 + slbia + lis r4,0x2000 /* set pseudo-segment reg 12 */ + ori r5,r4,0x0ccc + mtsr 12,r5 +#if 0 + ori r5,r4,0x0888 /* set pseudo-segment reg 8 */ + mtsr 8,r5 /* (for access to serial port) */ +#endif +#ifdef CONFIG_BOOTX_TEXT + ori r5,r4,0x0999 /* set pseudo-segment reg 9 */ + mtsr 9,r5 /* (for access to screen) */ +#endif + mfmsr r0 + clrldi r0,r0,1 + sync + mtmsr r0 + isync + blr + +#endif /* CONFIG_POWER4 */ + #ifdef CONFIG_8260 /* Jump into the system reset for the rom. * We first disable the MMU, and then jump to the ROM reset address. diff --git a/trunk/arch/ppc/kernel/idle.c b/trunk/arch/ppc/kernel/idle.c new file mode 100644 index 000000000000..1be3ca5bae40 --- /dev/null +++ b/trunk/arch/ppc/kernel/idle.c @@ -0,0 +1,112 @@ +/* + * Idle daemon for PowerPC. Idle daemon will handle any action + * that needs to be taken when the system becomes idle. + * + * Written by Cort Dougan (cort@cs.nmt.edu). Subsequently hacked + * on by Tom Rini, Armin Kuster, Paul Mackerras and others. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void default_idle(void) +{ + void (*powersave)(void); + + powersave = ppc_md.power_save; + + if (!need_resched()) { + if (powersave != NULL) + powersave(); +#ifdef CONFIG_SMP + else { + set_thread_flag(TIF_POLLING_NRFLAG); + while (!need_resched() && + !cpu_is_offline(smp_processor_id())) + barrier(); + clear_thread_flag(TIF_POLLING_NRFLAG); + } +#endif + } +} + +/* + * The body of the idle task. + */ +void cpu_idle(void) +{ + int cpu = smp_processor_id(); + + for (;;) { + while (!need_resched()) { + if (ppc_md.idle != NULL) + ppc_md.idle(); + else + default_idle(); + } + + if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) + cpu_die(); + preempt_enable_no_resched(); + schedule(); + preempt_disable(); + } +} + +#if defined(CONFIG_SYSCTL) && defined(CONFIG_6xx) +/* + * Register the sysctl to set/clear powersave_nap. + */ +extern int powersave_nap; + +static ctl_table powersave_nap_ctl_table[]={ + { + .ctl_name = KERN_PPC_POWERSAVE_NAP, + .procname = "powersave-nap", + .data = &powersave_nap, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { 0, }, +}; +static ctl_table powersave_nap_sysctl_root[] = { + { 1, "kernel", NULL, 0, 0755, powersave_nap_ctl_table, }, + { 0,}, +}; + +static int __init +register_powersave_nap_sysctl(void) +{ + register_sysctl_table(powersave_nap_sysctl_root, 0); + + return 0; +} + +__initcall(register_powersave_nap_sysctl); +#endif diff --git a/trunk/arch/ppc/kernel/idle_6xx.S b/trunk/arch/ppc/kernel/idle_6xx.S new file mode 100644 index 000000000000..1a2194cf6828 --- /dev/null +++ b/trunk/arch/ppc/kernel/idle_6xx.S @@ -0,0 +1,233 @@ +/* + * This file contains the power_save function for 6xx & 7xxx CPUs + * rewritten in assembler + * + * Warning ! This code assumes that if your machine has a 750fx + * it will have PLL 1 set to low speed mode (used during NAP/DOZE). + * if this is not the case some additional changes will have to + * be done to check a runtime var (a bit like powersave-nap) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#undef DEBUG + + .text + +/* + * Init idle, called at early CPU setup time from head.S for each CPU + * Make sure no rest of NAP mode remains in HID0, save default + * values for some CPU specific registers. Called with r24 + * containing CPU number and r3 reloc offset + */ +_GLOBAL(init_idle_6xx) +BEGIN_FTR_SECTION + mfspr r4,SPRN_HID0 + rlwinm r4,r4,0,10,8 /* Clear NAP */ + mtspr SPRN_HID0, r4 + b 1f +END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) + blr +1: + slwi r5,r24,2 + add r5,r5,r3 +BEGIN_FTR_SECTION + mfspr r4,SPRN_MSSCR0 + addis r6,r5, nap_save_msscr0@ha + stw r4,nap_save_msscr0@l(r6) +END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) +BEGIN_FTR_SECTION + mfspr r4,SPRN_HID1 + addis r6,r5,nap_save_hid1@ha + stw r4,nap_save_hid1@l(r6) +END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX) + blr + +/* + * Here is the power_save_6xx function. This could eventually be + * split into several functions & changing the function pointer + * depending on the various features. + */ +_GLOBAL(ppc6xx_idle) + /* Check if we can nap or doze, put HID0 mask in r3 + */ + lis r3, 0 +BEGIN_FTR_SECTION + lis r3,HID0_DOZE@h +END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) +BEGIN_FTR_SECTION + /* We must dynamically check for the NAP feature as it + * can be cleared by CPU init after the fixups are done + */ + lis r4,cur_cpu_spec@ha + lwz r4,cur_cpu_spec@l(r4) + lwz r4,CPU_SPEC_FEATURES(r4) + andi. r0,r4,CPU_FTR_CAN_NAP + beq 1f + /* Now check if user or arch enabled NAP mode */ + lis r4,powersave_nap@ha + lwz r4,powersave_nap@l(r4) + cmpwi 0,r4,0 + beq 1f + lis r3,HID0_NAP@h +1: +END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) + cmpwi 0,r3,0 + beqlr + + /* Clear MSR:EE */ + mfmsr r7 + rlwinm r0,r7,0,17,15 + mtmsr r0 + + /* Check current_thread_info()->flags */ + rlwinm r4,r1,0,0,18 + lwz r4,TI_FLAGS(r4) + andi. r0,r4,_TIF_NEED_RESCHED + beq 1f + mtmsr r7 /* out of line this ? */ + blr +1: + /* Some pre-nap cleanups needed on some CPUs */ + andis. r0,r3,HID0_NAP@h + beq 2f +BEGIN_FTR_SECTION + /* Disable L2 prefetch on some 745x and try to ensure + * L2 prefetch engines are idle. As explained by errata + * text, we can't be sure they are, we just hope very hard + * that well be enough (sic !). At least I noticed Apple + * doesn't even bother doing the dcbf's here... + */ + mfspr r4,SPRN_MSSCR0 + rlwinm r4,r4,0,0,29 + sync + mtspr SPRN_MSSCR0,r4 + sync + isync + lis r4,KERNELBASE@h + dcbf 0,r4 + dcbf 0,r4 + dcbf 0,r4 + dcbf 0,r4 +END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) +#ifdef DEBUG + lis r6,nap_enter_count@ha + lwz r4,nap_enter_count@l(r6) + addi r4,r4,1 + stw r4,nap_enter_count@l(r6) +#endif +2: +BEGIN_FTR_SECTION + /* Go to low speed mode on some 750FX */ + lis r4,powersave_lowspeed@ha + lwz r4,powersave_lowspeed@l(r4) + cmpwi 0,r4,0 + beq 1f + mfspr r4,SPRN_HID1 + oris r4,r4,0x0001 + mtspr SPRN_HID1,r4 +1: +END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX) + + /* Go to NAP or DOZE now */ + mfspr r4,SPRN_HID0 + lis r5,(HID0_NAP|HID0_SLEEP)@h +BEGIN_FTR_SECTION + oris r5,r5,HID0_DOZE@h +END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) + andc r4,r4,r5 + or r4,r4,r3 +BEGIN_FTR_SECTION + oris r4,r4,HID0_DPM@h /* that should be done once for all */ +END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) + mtspr SPRN_HID0,r4 +BEGIN_FTR_SECTION + DSSALL + sync +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) + ori r7,r7,MSR_EE /* Could be ommited (already set) */ + oris r7,r7,MSR_POW@h + sync + isync + mtmsr r7 + isync + sync + blr + +/* + * Return from NAP/DOZE mode, restore some CPU specific registers, + * we are called with DR/IR still off and r2 containing physical + * address of current. + */ +_GLOBAL(power_save_6xx_restore) + mfspr r11,SPRN_HID0 + rlwinm. r11,r11,0,10,8 /* Clear NAP & copy NAP bit !state to cr1 EQ */ + cror 4*cr1+eq,4*cr0+eq,4*cr0+eq +BEGIN_FTR_SECTION + rlwinm r11,r11,0,9,7 /* Clear DOZE */ +END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) + mtspr SPRN_HID0, r11 + +#ifdef DEBUG + beq cr1,1f + lis r11,(nap_return_count-KERNELBASE)@ha + lwz r9,nap_return_count@l(r11) + addi r9,r9,1 + stw r9,nap_return_count@l(r11) +1: +#endif + + rlwinm r9,r1,0,0,18 + tophys(r9,r9) + lwz r11,TI_CPU(r9) + slwi r11,r11,2 + /* Todo make sure all these are in the same page + * and load r22 (@ha part + CPU offset) only once + */ +BEGIN_FTR_SECTION + beq cr1,1f + addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha + lwz r9,nap_save_msscr0@l(r9) + mtspr SPRN_MSSCR0, r9 + sync + isync +1: +END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) +BEGIN_FTR_SECTION + addis r9,r11,(nap_save_hid1-KERNELBASE)@ha + lwz r9,nap_save_hid1@l(r9) + mtspr SPRN_HID1, r9 +END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX) + b transfer_to_handler_cont + + .data + +_GLOBAL(nap_save_msscr0) + .space 4*NR_CPUS + +_GLOBAL(nap_save_hid1) + .space 4*NR_CPUS + +_GLOBAL(powersave_nap) + .long 0 +_GLOBAL(powersave_lowspeed) + .long 0 + +#ifdef DEBUG +_GLOBAL(nap_enter_count) + .space 4 +_GLOBAL(nap_return_count) + .space 4 +#endif diff --git a/trunk/arch/ppc/kernel/idle_power4.S b/trunk/arch/ppc/kernel/idle_power4.S new file mode 100644 index 000000000000..cc0d535365cd --- /dev/null +++ b/trunk/arch/ppc/kernel/idle_power4.S @@ -0,0 +1,91 @@ +/* + * This file contains the power_save function for 6xx & 7xxx CPUs + * rewritten in assembler + * + * Warning ! This code assumes that if your machine has a 750fx + * it will have PLL 1 set to low speed mode (used during NAP/DOZE). + * if this is not the case some additional changes will have to + * be done to check a runtime var (a bit like powersave-nap) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#undef DEBUG + + .text + +/* + * Init idle, called at early CPU setup time from head.S for each CPU + * So nothing for now. Called with r24 containing CPU number and r3 + * reloc offset + */ + .globl init_idle_power4 +init_idle_power4: + blr + +/* + * Here is the power_save_6xx function. This could eventually be + * split into several functions & changing the function pointer + * depending on the various features. + */ + .globl power4_idle +power4_idle: +BEGIN_FTR_SECTION + blr +END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP) + /* We must dynamically check for the NAP feature as it + * can be cleared by CPU init after the fixups are done + */ + lis r4,cur_cpu_spec@ha + lwz r4,cur_cpu_spec@l(r4) + lwz r4,CPU_SPEC_FEATURES(r4) + andi. r0,r4,CPU_FTR_CAN_NAP + beqlr + /* Now check if user or arch enabled NAP mode */ + lis r4,powersave_nap@ha + lwz r4,powersave_nap@l(r4) + cmpwi 0,r4,0 + beqlr + + /* Clear MSR:EE */ + mfmsr r7 + rlwinm r0,r7,0,17,15 + mtmsr r0 + + /* Check current_thread_info()->flags */ + rlwinm r4,r1,0,0,18 + lwz r4,TI_FLAGS(r4) + andi. r0,r4,_TIF_NEED_RESCHED + beq 1f + mtmsr r7 /* out of line this ? */ + blr +1: + /* Go to NAP now */ +BEGIN_FTR_SECTION + DSSALL + sync +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) + ori r7,r7,MSR_EE /* Could be ommited (already set) */ + oris r7,r7,MSR_POW@h + sync + isync + mtmsr r7 + isync + sync + blr + + .globl powersave_nap +powersave_nap: + .long 0 diff --git a/trunk/arch/powerpc/kernel/l2cr_6xx.S b/trunk/arch/ppc/kernel/l2cr.S similarity index 100% rename from trunk/arch/powerpc/kernel/l2cr_6xx.S rename to trunk/arch/ppc/kernel/l2cr.S diff --git a/trunk/arch/powerpc/kernel/module_32.c b/trunk/arch/ppc/kernel/module.c similarity index 100% rename from trunk/arch/powerpc/kernel/module_32.c rename to trunk/arch/ppc/kernel/module.c diff --git a/trunk/arch/ppc/kernel/pci.c b/trunk/arch/ppc/kernel/pci.c index 809673a36f7a..04d04c5bfdd0 100644 --- a/trunk/arch/ppc/kernel/pci.c +++ b/trunk/arch/ppc/kernel/pci.c @@ -46,6 +46,9 @@ static void pcibios_fixup_resources(struct pci_dev* dev); static void fixup_broken_pcnet32(struct pci_dev* dev); static int reparent_resources(struct resource *parent, struct resource *res); static void fixup_cpc710_pci64(struct pci_dev* dev); +#ifdef CONFIG_PPC_OF +static u8* pci_to_OF_bus_map; +#endif /* By default, we don't re-assign bus numbers. */ @@ -622,13 +625,406 @@ pcibios_alloc_controller(void) return hose; } +#ifdef CONFIG_PPC_OF +/* + * Functions below are used on OpenFirmware machines. + */ +static void +make_one_node_map(struct device_node* node, u8 pci_bus) +{ + int *bus_range; + int len; + + if (pci_bus >= pci_bus_count) + return; + bus_range = (int *) get_property(node, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s, " + "assuming it starts at 0\n", node->full_name); + pci_to_OF_bus_map[pci_bus] = 0; + } else + pci_to_OF_bus_map[pci_bus] = bus_range[0]; + + for (node=node->child; node != 0;node = node->sibling) { + struct pci_dev* dev; + unsigned int *class_code, *reg; + + class_code = (unsigned int *) get_property(node, "class-code", NULL); + if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && + (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) + continue; + reg = (unsigned int *)get_property(node, "reg", NULL); + if (!reg) + continue; + dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff)); + if (!dev || !dev->subordinate) + continue; + make_one_node_map(node, dev->subordinate->number); + } +} + +void +pcibios_make_OF_bus_map(void) +{ + int i; + struct pci_controller* hose; + u8* of_prop_map; + + pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL); + if (!pci_to_OF_bus_map) { + printk(KERN_ERR "Can't allocate OF bus map !\n"); + return; + } + + /* We fill the bus map with invalid values, that helps + * debugging. + */ + for (i=0; inext) { + struct device_node* node; + node = (struct device_node *)hose->arch_data; + if (!node) + continue; + make_one_node_map(node, hose->first_busno); + } + of_prop_map = get_property(find_path_device("/"), "pci-OF-bus-map", NULL); + if (of_prop_map) + memcpy(of_prop_map, pci_to_OF_bus_map, pci_bus_count); +#ifdef DEBUG + printk("PCI->OF bus map:\n"); + for (i=0; i %d\n", i, pci_to_OF_bus_map[i]); + } +#endif +} + +typedef int (*pci_OF_scan_iterator)(struct device_node* node, void* data); + +static struct device_node* +scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* data) +{ + struct device_node* sub_node; + + for (; node != 0;node = node->sibling) { + unsigned int *class_code; + + if (filter(node, data)) + return node; + + /* For PCI<->PCI bridges or CardBus bridges, we go down + * Note: some OFs create a parent node "multifunc-device" as + * a fake root for all functions of a multi-function device, + * we go down them as well. + */ + class_code = (unsigned int *) get_property(node, "class-code", NULL); + if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && + (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) && + strcmp(node->name, "multifunc-device")) + continue; + sub_node = scan_OF_pci_childs(node->child, filter, data); + if (sub_node) + return sub_node; + } + return NULL; +} + +static int +scan_OF_pci_childs_iterator(struct device_node* node, void* data) +{ + unsigned int *reg; + u8* fdata = (u8*)data; + + reg = (unsigned int *) get_property(node, "reg", NULL); + if (reg && ((reg[0] >> 8) & 0xff) == fdata[1] + && ((reg[0] >> 16) & 0xff) == fdata[0]) + return 1; + return 0; +} + +static struct device_node* +scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn) +{ + u8 filter_data[2] = {bus, dev_fn}; + + return scan_OF_pci_childs(node, scan_OF_pci_childs_iterator, filter_data); +} + +/* + * Scans the OF tree for a device node matching a PCI device + */ +struct device_node * +pci_busdev_to_OF_node(struct pci_bus *bus, int devfn) +{ + struct pci_controller *hose; + struct device_node *node; + int busnr; + + if (!have_of) + return NULL; + + /* Lookup the hose */ + busnr = bus->number; + hose = pci_bus_to_hose(busnr); + if (!hose) + return NULL; + + /* Check it has an OF node associated */ + node = (struct device_node *) hose->arch_data; + if (!node) + return NULL; + + /* Fixup bus number according to what OF think it is. */ + if (pci_to_OF_bus_map) + busnr = pci_to_OF_bus_map[busnr]; + if (busnr == 0xff) + return NULL; + + /* Now, lookup childs of the hose */ + return scan_OF_childs_for_device(node->child, busnr, devfn); +} +EXPORT_SYMBOL(pci_busdev_to_OF_node); + +struct device_node* +pci_device_to_OF_node(struct pci_dev *dev) +{ + return pci_busdev_to_OF_node(dev->bus, dev->devfn); +} +EXPORT_SYMBOL(pci_device_to_OF_node); + +/* This routine is meant to be used early during boot, when the + * PCI bus numbers have not yet been assigned, and you need to + * issue PCI config cycles to an OF device. + * It could also be used to "fix" RTAS config cycles if you want + * to set pci_assign_all_buses to 1 and still use RTAS for PCI + * config cycles. + */ +struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node) +{ + if (!have_of) + return NULL; + while(node) { + struct pci_controller* hose; + for (hose=hose_head;hose;hose=hose->next) + if (hose->arch_data == node) + return hose; + node=node->parent; + } + return NULL; +} + +static int +find_OF_pci_device_filter(struct device_node* node, void* data) +{ + return ((void *)node == data); +} + +/* + * Returns the PCI device matching a given OF node + */ +int +pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn) +{ + unsigned int *reg; + struct pci_controller* hose; + struct pci_dev* dev = NULL; + + if (!have_of) + return -ENODEV; + /* Make sure it's really a PCI device */ + hose = pci_find_hose_for_OF_device(node); + if (!hose || !hose->arch_data) + return -ENODEV; + if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child, + find_OF_pci_device_filter, (void *)node)) + return -ENODEV; + reg = (unsigned int *) get_property(node, "reg", NULL); + if (!reg) + return -ENODEV; + *bus = (reg[0] >> 16) & 0xff; + *devfn = ((reg[0] >> 8) & 0xff); + + /* Ok, here we need some tweak. If we have already renumbered + * all busses, we can't rely on the OF bus number any more. + * the pci_to_OF_bus_map is not enough as several PCI busses + * may match the same OF bus number. + */ + if (!pci_to_OF_bus_map) + return 0; + + for_each_pci_dev(dev) + if (pci_to_OF_bus_map[dev->bus->number] == *bus && + dev->devfn == *devfn) { + *bus = dev->bus->number; + pci_dev_put(dev); + return 0; + } + + return -ENODEV; +} +EXPORT_SYMBOL(pci_device_from_OF_node); + +void __init +pci_process_bridge_OF_ranges(struct pci_controller *hose, + struct device_node *dev, int primary) +{ + static unsigned int static_lc_ranges[256] __initdata; + unsigned int *dt_ranges, *lc_ranges, *ranges, *prev; + unsigned int size; + int rlen = 0, orig_rlen; + int memno = 0; + struct resource *res; + int np, na = prom_n_addr_cells(dev); + np = na + 5; + + /* First we try to merge ranges to fix a problem with some pmacs + * that can have more than 3 ranges, fortunately using contiguous + * addresses -- BenH + */ + dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen); + if (!dt_ranges) + return; + /* Sanity check, though hopefully that never happens */ + if (rlen > sizeof(static_lc_ranges)) { + printk(KERN_WARNING "OF ranges property too large !\n"); + rlen = sizeof(static_lc_ranges); + } + lc_ranges = static_lc_ranges; + memcpy(lc_ranges, dt_ranges, rlen); + orig_rlen = rlen; + + /* Let's work on a copy of the "ranges" property instead of damaging + * the device-tree image in memory + */ + ranges = lc_ranges; + prev = NULL; + while ((rlen -= np * sizeof(unsigned int)) >= 0) { + if (prev) { + if (prev[0] == ranges[0] && prev[1] == ranges[1] && + (prev[2] + prev[na+4]) == ranges[2] && + (prev[na+2] + prev[na+4]) == ranges[na+2]) { + prev[na+4] += ranges[na+4]; + ranges[0] = 0; + ranges += np; + continue; + } + } + prev = ranges; + ranges += np; + } + + /* + * The ranges property is laid out as an array of elements, + * each of which comprises: + * cells 0 - 2: a PCI address + * cells 3 or 3+4: a CPU physical address + * (size depending on dev->n_addr_cells) + * cells 4+5 or 5+6: the size of the range + */ + ranges = lc_ranges; + rlen = orig_rlen; + while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) { + res = NULL; + size = ranges[na+4]; + switch ((ranges[0] >> 24) & 0x3) { + case 1: /* I/O space */ + if (ranges[2] != 0) + break; + hose->io_base_phys = ranges[na+2]; + /* limit I/O space to 16MB */ + if (size > 0x01000000) + size = 0x01000000; + hose->io_base_virt = ioremap(ranges[na+2], size); + if (primary) + isa_io_base = (unsigned long) hose->io_base_virt; + res = &hose->io_resource; + res->flags = IORESOURCE_IO; + res->start = ranges[2]; + DBG("PCI: IO 0x%lx -> 0x%lx\n", + res->start, res->start + size - 1); + break; + case 2: /* memory space */ + memno = 0; + if (ranges[1] == 0 && ranges[2] == 0 + && ranges[na+4] <= (16 << 20)) { + /* 1st 16MB, i.e. ISA memory area */ + if (primary) + isa_mem_base = ranges[na+2]; + memno = 1; + } + while (memno < 3 && hose->mem_resources[memno].flags) + ++memno; + if (memno == 0) + hose->pci_mem_offset = ranges[na+2] - ranges[2]; + if (memno < 3) { + res = &hose->mem_resources[memno]; + res->flags = IORESOURCE_MEM; + if(ranges[0] & 0x40000000) + res->flags |= IORESOURCE_PREFETCH; + res->start = ranges[na+2]; + DBG("PCI: MEM[%d] 0x%lx -> 0x%lx\n", memno, + res->start, res->start + size - 1); + } + break; + } + if (res != NULL) { + res->name = dev->full_name; + res->end = res->start + size - 1; + res->parent = NULL; + res->sibling = NULL; + res->child = NULL; + } + ranges += np; + } +} + +/* We create the "pci-OF-bus-map" property now so it appears in the + * /proc device tree + */ +void __init +pci_create_OF_bus_map(void) +{ + struct property* of_prop; + + of_prop = (struct property*) alloc_bootmem(sizeof(struct property) + 256); + if (of_prop && find_path_device("/")) { + memset(of_prop, -1, sizeof(struct property) + 256); + of_prop->name = "pci-OF-bus-map"; + of_prop->length = 256; + of_prop->value = (unsigned char *)&of_prop[1]; + prom_add_property(find_path_device("/"), of_prop); + } +} + +static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct pci_dev *pdev; + struct device_node *np; + + pdev = to_pci_dev (dev); + np = pci_device_to_OF_node(pdev); + if (np == NULL || np->full_name == NULL) + return 0; + return sprintf(buf, "%s", np->full_name); +} +static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL); + +#else /* CONFIG_PPC_OF */ void pcibios_make_OF_bus_map(void) { } +#endif /* CONFIG_PPC_OF */ /* Add sysfs properties */ void pcibios_add_platform_entries(struct pci_dev *pdev) { +#ifdef CONFIG_PPC_OF + device_create_file(&pdev->dev, &dev_attr_devspec); +#endif /* CONFIG_PPC_OF */ } diff --git a/trunk/arch/powerpc/kernel/perfmon_fsl_booke.c b/trunk/arch/ppc/kernel/perfmon_fsl_booke.c similarity index 100% rename from trunk/arch/powerpc/kernel/perfmon_fsl_booke.c rename to trunk/arch/ppc/kernel/perfmon_fsl_booke.c diff --git a/trunk/arch/ppc/kernel/ppc_htab.c b/trunk/arch/ppc/kernel/ppc_htab.c index 75c645043746..9b84bffdefce 100644 --- a/trunk/arch/ppc/kernel/ppc_htab.c +++ b/trunk/arch/ppc/kernel/ppc_htab.c @@ -104,7 +104,7 @@ static char *pmc2_lookup(unsigned long mmcr0) static int ppc_htab_show(struct seq_file *m, void *v) { unsigned long mmcr0 = 0, pmc1 = 0, pmc2 = 0; -#if defined(CONFIG_PPC_STD_MMU) +#if defined(CONFIG_PPC_STD_MMU) && !defined(CONFIG_PPC64BRIDGE) unsigned int kptes = 0, uptes = 0; PTE *ptr; #endif /* CONFIG_PPC_STD_MMU */ @@ -133,6 +133,7 @@ static int ppc_htab_show(struct seq_file *m, void *v) return 0; } +#ifndef CONFIG_PPC64BRIDGE for (ptr = Hash; ptr < Hash_end; ptr++) { unsigned int mctx, vsid; @@ -146,6 +147,7 @@ static int ppc_htab_show(struct seq_file *m, void *v) else uptes++; } +#endif seq_printf(m, "PTE Hash Table Information\n" @@ -153,16 +155,20 @@ static int ppc_htab_show(struct seq_file *m, void *v) "Buckets\t\t: %lu\n" "Address\t\t: %08lx\n" "Entries\t\t: %lu\n" +#ifndef CONFIG_PPC64BRIDGE "User ptes\t: %u\n" "Kernel ptes\t: %u\n" "Percent full\t: %lu%%\n" +#endif , (unsigned long)(Hash_size>>10), (Hash_size/(sizeof(PTE)*8)), (unsigned long)Hash, Hash_size/sizeof(PTE) +#ifndef CONFIG_PPC64BRIDGE , uptes, kptes, ((kptes+uptes)*100) / (Hash_size/sizeof(PTE)) +#endif ); seq_printf(m, diff --git a/trunk/arch/ppc/kernel/ppc_ksyms.c b/trunk/arch/ppc/kernel/ppc_ksyms.c index 865ba74991a9..82adb4601348 100644 --- a/trunk/arch/ppc/kernel/ppc_ksyms.c +++ b/trunk/arch/ppc/kernel/ppc_ksyms.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -29,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -206,6 +208,27 @@ EXPORT_SYMBOL(adb_try_handler_change); EXPORT_SYMBOL(cuda_request); EXPORT_SYMBOL(cuda_poll); #endif /* CONFIG_ADB_CUDA */ +#ifdef CONFIG_PPC_OF +EXPORT_SYMBOL(find_devices); +EXPORT_SYMBOL(find_type_devices); +EXPORT_SYMBOL(find_compatible_devices); +EXPORT_SYMBOL(find_path_device); +EXPORT_SYMBOL(device_is_compatible); +EXPORT_SYMBOL(machine_is_compatible); +EXPORT_SYMBOL(find_all_nodes); +EXPORT_SYMBOL(get_property); +EXPORT_SYMBOL(request_OF_resource); +EXPORT_SYMBOL(release_OF_resource); +EXPORT_SYMBOL(of_find_node_by_name); +EXPORT_SYMBOL(of_find_node_by_type); +EXPORT_SYMBOL(of_find_compatible_node); +EXPORT_SYMBOL(of_find_node_by_path); +EXPORT_SYMBOL(of_find_all_nodes); +EXPORT_SYMBOL(of_get_parent); +EXPORT_SYMBOL(of_get_next_child); +EXPORT_SYMBOL(of_node_get); +EXPORT_SYMBOL(of_node_put); +#endif /* CONFIG_PPC_OF */ #if defined(CONFIG_BOOTX_TEXT) EXPORT_SYMBOL(btext_update_display); #endif @@ -239,6 +262,9 @@ EXPORT_SYMBOL(console_drivers); EXPORT_SYMBOL(xmon); EXPORT_SYMBOL(xmon_printf); #endif +EXPORT_SYMBOL(__up); +EXPORT_SYMBOL(__down); +EXPORT_SYMBOL(__down_interruptible); #if defined(CONFIG_KGDB) || defined(CONFIG_XMON) extern void (*debugger)(struct pt_regs *regs); diff --git a/trunk/arch/ppc/kernel/setup.c b/trunk/arch/ppc/kernel/setup.c index 1f79e84ab464..53e9deacee82 100644 --- a/trunk/arch/ppc/kernel/setup.c +++ b/trunk/arch/ppc/kernel/setup.c @@ -1,5 +1,5 @@ /* - * Common prep boot and setup code. + * Common prep/chrp boot and setup code. */ #include @@ -72,12 +72,17 @@ unsigned long ISA_DMA_THRESHOLD; unsigned int DMA_MODE_READ; unsigned int DMA_MODE_WRITE; -#ifdef CONFIG_PPC_PREP +#ifdef CONFIG_PPC_MULTIPLATFORM +int _machine = 0; +EXPORT_SYMBOL(_machine); + extern void prep_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7); +extern void chrp_init(unsigned long r3, unsigned long r4, + unsigned long r5, unsigned long r6, unsigned long r7); dev_t boot_dev; -#endif /* CONFIG_PPC_PREP */ +#endif /* CONFIG_PPC_MULTIPLATFORM */ int have_of; EXPORT_SYMBOL(have_of); @@ -314,12 +319,72 @@ early_init(int r3, int r4, int r5) identify_cpu(offset, 0); do_cpu_ftr_fixups(offset); +#if defined(CONFIG_PPC_OF) + reloc_got2(offset); + + /* + * don't do anything on prep + * for now, don't use bootinfo because it breaks yaboot 0.5 + * and assume that if we didn't find a magic number, we have OF + */ + if (*(unsigned long *)(0) != 0xdeadc0de) + phys = prom_init(r3, r4, (prom_entry)r5); + + reloc_got2(-offset); +#endif + return phys; } -#ifdef CONFIG_PPC_PREP +#ifdef CONFIG_PPC_OF /* - * The PPC_PREP version of platform_init... + * Assume here that all clock rates are the same in a + * smp system. -- Cort + */ +int +of_show_percpuinfo(struct seq_file *m, int i) +{ + struct device_node *cpu_node; + u32 *fp; + int s; + + cpu_node = find_type_devices("cpu"); + if (!cpu_node) + return 0; + for (s = 0; s < i && cpu_node->next; s++) + cpu_node = cpu_node->next; + fp = (u32 *)get_property(cpu_node, "clock-frequency", NULL); + if (fp) + seq_printf(m, "clock\t\t: %dMHz\n", *fp / 1000000); + return 0; +} + +void __init +intuit_machine_type(void) +{ + char *model; + struct device_node *root; + + /* ask the OF info if we're a chrp or pmac */ + root = find_path_device("/"); + if (root != 0) { + /* assume pmac unless proven to be chrp -- Cort */ + _machine = _MACH_Pmac; + model = get_property(root, "device_type", NULL); + if (model && !strncmp("chrp", model, 4)) + _machine = _MACH_chrp; + else { + model = get_property(root, "model", NULL); + if (model && !strncmp(model, "IBM", 3)) + _machine = _MACH_chrp; + } + } +} +#endif + +#ifdef CONFIG_PPC_MULTIPLATFORM +/* + * The PPC_MULTIPLATFORM version of platform_init... */ void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5, @@ -334,9 +399,161 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, parse_bootinfo(find_bootinfo()); - prep_init(r3, r4, r5, r6, r7); + /* if we didn't get any bootinfo telling us what we are... */ + if (_machine == 0) { + /* prep boot loader tells us if we're prep or not */ + if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) ) + _machine = _MACH_prep; + } + +#ifdef CONFIG_PPC_PREP + /* not much more to do here, if prep */ + if (_machine == _MACH_prep) { + prep_init(r3, r4, r5, r6, r7); + return; + } +#endif + +#ifdef CONFIG_PPC_OF + have_of = 1; + + /* prom_init has already been called from __start */ + if (boot_infos) + relocate_nodes(); + + /* If we aren't PReP, we can find out if we're Pmac + * or CHRP with this. */ + if (_machine == 0) + intuit_machine_type(); + + /* finish_device_tree may need _machine defined. */ + finish_device_tree(); + + /* + * If we were booted via quik, r3 points to the physical + * address of the command-line parameters. + * If we were booted from an xcoff image (i.e. netbooted or + * booted from floppy), we get the command line from the + * bootargs property of the /chosen node. + * If an initial ramdisk is present, r3 and r4 + * are used for initrd_start and initrd_size, + * otherwise they contain 0xdeadbeef. + */ + if (r3 >= 0x4000 && r3 < 0x800000 && r4 == 0) { + strlcpy(cmd_line, (char *)r3 + KERNELBASE, + sizeof(cmd_line)); + } else if (boot_infos != 0) { + /* booted by BootX - check for ramdisk */ + if (boot_infos->kernelParamsOffset != 0) + strlcpy(cmd_line, (char *) boot_infos + + boot_infos->kernelParamsOffset, + sizeof(cmd_line)); +#ifdef CONFIG_BLK_DEV_INITRD + if (boot_infos->ramDisk) { + initrd_start = (unsigned long) boot_infos + + boot_infos->ramDisk; + initrd_end = initrd_start + boot_infos->ramDiskSize; + initrd_below_start_ok = 1; + } +#endif + } else { + struct device_node *chosen; + char *p; + +#ifdef CONFIG_BLK_DEV_INITRD + if (r3 && r4 && r4 != 0xdeadbeef) { + if (r3 < KERNELBASE) + r3 += KERNELBASE; + initrd_start = r3; + initrd_end = r3 + r4; + ROOT_DEV = Root_RAM0; + initrd_below_start_ok = 1; + } +#endif + chosen = find_devices("chosen"); + if (chosen != NULL) { + p = get_property(chosen, "bootargs", NULL); + if (p && *p) { + strlcpy(cmd_line, p, sizeof(cmd_line)); + } + } + } +#ifdef CONFIG_ADB + if (strstr(cmd_line, "adb_sync")) { + extern int __adb_probe_sync; + __adb_probe_sync = 1; + } +#endif /* CONFIG_ADB */ + + switch (_machine) { +#ifdef CONFIG_PPC_CHRP + case _MACH_chrp: + chrp_init(r3, r4, r5, r6, r7); + break; +#endif + } +#endif /* CONFIG_PPC_OF */ } -#endif /* CONFIG_PPC_PREP */ +#endif /* CONFIG_PPC_MULTIPLATFORM */ + +#ifdef CONFIG_PPC_OF +#ifdef CONFIG_SERIAL_CORE_CONSOLE +extern char *of_stdout_device; + +static int __init set_preferred_console(void) +{ + struct device_node *prom_stdout; + char *name; + int offset = 0; + + if (of_stdout_device == NULL) + return -ENODEV; + + /* The user has requested a console so this is already set up. */ + if (strstr(saved_command_line, "console=")) + return -EBUSY; + + prom_stdout = find_path_device(of_stdout_device); + if (!prom_stdout) + return -ENODEV; + + name = (char *)get_property(prom_stdout, "name", NULL); + if (!name) + return -ENODEV; + + if (strcmp(name, "serial") == 0) { + int i; + u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i); + if (i > 8) { + switch (reg[1]) { + case 0x3f8: + offset = 0; + break; + case 0x2f8: + offset = 1; + break; + case 0x898: + offset = 2; + break; + case 0x890: + offset = 3; + break; + default: + /* We dont recognise the serial port */ + return -ENODEV; + } + } + } else if (strcmp(name, "ch-a") == 0) + offset = 0; + else if (strcmp(name, "ch-b") == 0) + offset = 1; + else + return -ENODEV; + return add_preferred_console("ttyS", offset, NULL); +} +console_initcall(set_preferred_console); +#endif /* CONFIG_SERIAL_CORE_CONSOLE */ +#endif /* CONFIG_PPC_OF */ struct bi_record *find_bootinfo(void) { @@ -372,6 +589,23 @@ void parse_bootinfo(struct bi_record *rec) initrd_end = data[0] + data[1] + KERNELBASE; break; #endif /* CONFIG_BLK_DEV_INITRD */ +#ifdef CONFIG_PPC_MULTIPLATFORM + case BI_MACHTYPE: + /* Machine types changed with the merge. Since the + * bootinfo are now deprecated, we can just hard code + * the appropriate conversion here for when we are + * called with yaboot which passes us a machine type + * this way. + */ + switch(data[0]) { + case 1: _machine = _MACH_prep; break; + case 2: _machine = _MACH_Pmac; break; + case 4: _machine = _MACH_chrp; break; + default: + _machine = data[0]; + } + break; +#endif case BI_MEMSIZE: boot_mem_size = data[0]; break; @@ -397,6 +631,9 @@ machine_init(unsigned long r3, unsigned long r4, unsigned long r5, #ifdef CONFIG_6xx ppc_md.power_save = ppc6xx_idle; #endif +#ifdef CONFIG_POWER4 + ppc_md.power_save = power4_idle; +#endif platform_init(r3, r4, r5, r6, r7); @@ -474,7 +711,7 @@ int __init ppc_init(void) if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); /* register CPU devices */ - for_each_possible_cpu(i) + for_each_cpu(i) register_cpu(&cpu_devices[i], i, NULL); /* call platform init */ @@ -562,4 +799,7 @@ void __init setup_arch(char **cmdline_p) if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); paging_init(); + + /* this is for modules since _machine can be a define -- Cort */ + ppc_md.ppc_machine = _machine; } diff --git a/trunk/arch/ppc/kernel/smp.c b/trunk/arch/ppc/kernel/smp.c index f77795a64dae..e55cdda6149a 100644 --- a/trunk/arch/ppc/kernel/smp.c +++ b/trunk/arch/ppc/kernel/smp.c @@ -311,7 +311,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) /* Backup CPU 0 state */ __save_cpu_setup(); - for_each_possible_cpu(cpu) { + for_each_cpu(cpu) { if (cpu == smp_processor_id()) continue; /* create a process for the processor */ diff --git a/trunk/arch/powerpc/kernel/swsusp_32.S b/trunk/arch/ppc/kernel/swsusp.S similarity index 100% rename from trunk/arch/powerpc/kernel/swsusp_32.S rename to trunk/arch/ppc/kernel/swsusp.S diff --git a/trunk/arch/powerpc/kernel/tau_6xx.c b/trunk/arch/ppc/kernel/temp.c similarity index 100% rename from trunk/arch/powerpc/kernel/tau_6xx.c rename to trunk/arch/ppc/kernel/temp.c diff --git a/trunk/arch/ppc/lib/strcase.c b/trunk/arch/ppc/lib/strcase.c index 3b0094cc2b52..36b521091bbc 100644 --- a/trunk/arch/ppc/lib/strcase.c +++ b/trunk/arch/ppc/lib/strcase.c @@ -1,5 +1,4 @@ #include -#include int strcasecmp(const char *s1, const char *s2) { @@ -12,7 +11,7 @@ int strcasecmp(const char *s1, const char *s2) return c1 - c2; } -int strncasecmp(const char *s1, const char *s2, size_t n) +int strncasecmp(const char *s1, const char *s2, int n) { int c1, c2; diff --git a/trunk/arch/powerpc/math-emu/Makefile b/trunk/arch/ppc/math-emu/Makefile similarity index 100% rename from trunk/arch/powerpc/math-emu/Makefile rename to trunk/arch/ppc/math-emu/Makefile diff --git a/trunk/arch/powerpc/math-emu/double.h b/trunk/arch/ppc/math-emu/double.h similarity index 100% rename from trunk/arch/powerpc/math-emu/double.h rename to trunk/arch/ppc/math-emu/double.h diff --git a/trunk/arch/powerpc/math-emu/fabs.c b/trunk/arch/ppc/math-emu/fabs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fabs.c rename to trunk/arch/ppc/math-emu/fabs.c diff --git a/trunk/arch/powerpc/math-emu/fadd.c b/trunk/arch/ppc/math-emu/fadd.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fadd.c rename to trunk/arch/ppc/math-emu/fadd.c diff --git a/trunk/arch/powerpc/math-emu/fadds.c b/trunk/arch/ppc/math-emu/fadds.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fadds.c rename to trunk/arch/ppc/math-emu/fadds.c diff --git a/trunk/arch/powerpc/math-emu/fcmpo.c b/trunk/arch/ppc/math-emu/fcmpo.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fcmpo.c rename to trunk/arch/ppc/math-emu/fcmpo.c diff --git a/trunk/arch/powerpc/math-emu/fcmpu.c b/trunk/arch/ppc/math-emu/fcmpu.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fcmpu.c rename to trunk/arch/ppc/math-emu/fcmpu.c diff --git a/trunk/arch/powerpc/math-emu/fctiw.c b/trunk/arch/ppc/math-emu/fctiw.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fctiw.c rename to trunk/arch/ppc/math-emu/fctiw.c diff --git a/trunk/arch/powerpc/math-emu/fctiwz.c b/trunk/arch/ppc/math-emu/fctiwz.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fctiwz.c rename to trunk/arch/ppc/math-emu/fctiwz.c diff --git a/trunk/arch/powerpc/math-emu/fdiv.c b/trunk/arch/ppc/math-emu/fdiv.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fdiv.c rename to trunk/arch/ppc/math-emu/fdiv.c diff --git a/trunk/arch/powerpc/math-emu/fdivs.c b/trunk/arch/ppc/math-emu/fdivs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fdivs.c rename to trunk/arch/ppc/math-emu/fdivs.c diff --git a/trunk/arch/powerpc/math-emu/fmadd.c b/trunk/arch/ppc/math-emu/fmadd.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fmadd.c rename to trunk/arch/ppc/math-emu/fmadd.c diff --git a/trunk/arch/powerpc/math-emu/fmadds.c b/trunk/arch/ppc/math-emu/fmadds.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fmadds.c rename to trunk/arch/ppc/math-emu/fmadds.c diff --git a/trunk/arch/powerpc/math-emu/fmr.c b/trunk/arch/ppc/math-emu/fmr.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fmr.c rename to trunk/arch/ppc/math-emu/fmr.c diff --git a/trunk/arch/powerpc/math-emu/fmsub.c b/trunk/arch/ppc/math-emu/fmsub.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fmsub.c rename to trunk/arch/ppc/math-emu/fmsub.c diff --git a/trunk/arch/powerpc/math-emu/fmsubs.c b/trunk/arch/ppc/math-emu/fmsubs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fmsubs.c rename to trunk/arch/ppc/math-emu/fmsubs.c diff --git a/trunk/arch/powerpc/math-emu/fmul.c b/trunk/arch/ppc/math-emu/fmul.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fmul.c rename to trunk/arch/ppc/math-emu/fmul.c diff --git a/trunk/arch/powerpc/math-emu/fmuls.c b/trunk/arch/ppc/math-emu/fmuls.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fmuls.c rename to trunk/arch/ppc/math-emu/fmuls.c diff --git a/trunk/arch/powerpc/math-emu/fnabs.c b/trunk/arch/ppc/math-emu/fnabs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fnabs.c rename to trunk/arch/ppc/math-emu/fnabs.c diff --git a/trunk/arch/powerpc/math-emu/fneg.c b/trunk/arch/ppc/math-emu/fneg.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fneg.c rename to trunk/arch/ppc/math-emu/fneg.c diff --git a/trunk/arch/powerpc/math-emu/fnmadd.c b/trunk/arch/ppc/math-emu/fnmadd.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fnmadd.c rename to trunk/arch/ppc/math-emu/fnmadd.c diff --git a/trunk/arch/powerpc/math-emu/fnmadds.c b/trunk/arch/ppc/math-emu/fnmadds.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fnmadds.c rename to trunk/arch/ppc/math-emu/fnmadds.c diff --git a/trunk/arch/powerpc/math-emu/fnmsub.c b/trunk/arch/ppc/math-emu/fnmsub.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fnmsub.c rename to trunk/arch/ppc/math-emu/fnmsub.c diff --git a/trunk/arch/powerpc/math-emu/fnmsubs.c b/trunk/arch/ppc/math-emu/fnmsubs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fnmsubs.c rename to trunk/arch/ppc/math-emu/fnmsubs.c diff --git a/trunk/arch/powerpc/math-emu/fres.c b/trunk/arch/ppc/math-emu/fres.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fres.c rename to trunk/arch/ppc/math-emu/fres.c diff --git a/trunk/arch/powerpc/math-emu/frsp.c b/trunk/arch/ppc/math-emu/frsp.c similarity index 100% rename from trunk/arch/powerpc/math-emu/frsp.c rename to trunk/arch/ppc/math-emu/frsp.c diff --git a/trunk/arch/powerpc/math-emu/frsqrte.c b/trunk/arch/ppc/math-emu/frsqrte.c similarity index 100% rename from trunk/arch/powerpc/math-emu/frsqrte.c rename to trunk/arch/ppc/math-emu/frsqrte.c diff --git a/trunk/arch/powerpc/math-emu/fsel.c b/trunk/arch/ppc/math-emu/fsel.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fsel.c rename to trunk/arch/ppc/math-emu/fsel.c diff --git a/trunk/arch/powerpc/math-emu/fsqrt.c b/trunk/arch/ppc/math-emu/fsqrt.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fsqrt.c rename to trunk/arch/ppc/math-emu/fsqrt.c diff --git a/trunk/arch/powerpc/math-emu/fsqrts.c b/trunk/arch/ppc/math-emu/fsqrts.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fsqrts.c rename to trunk/arch/ppc/math-emu/fsqrts.c diff --git a/trunk/arch/powerpc/math-emu/fsub.c b/trunk/arch/ppc/math-emu/fsub.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fsub.c rename to trunk/arch/ppc/math-emu/fsub.c diff --git a/trunk/arch/powerpc/math-emu/fsubs.c b/trunk/arch/ppc/math-emu/fsubs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fsubs.c rename to trunk/arch/ppc/math-emu/fsubs.c diff --git a/trunk/arch/powerpc/math-emu/lfd.c b/trunk/arch/ppc/math-emu/lfd.c similarity index 100% rename from trunk/arch/powerpc/math-emu/lfd.c rename to trunk/arch/ppc/math-emu/lfd.c diff --git a/trunk/arch/powerpc/math-emu/lfs.c b/trunk/arch/ppc/math-emu/lfs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/lfs.c rename to trunk/arch/ppc/math-emu/lfs.c diff --git a/trunk/arch/powerpc/math-emu/math.c b/trunk/arch/ppc/math-emu/math.c similarity index 100% rename from trunk/arch/powerpc/math-emu/math.c rename to trunk/arch/ppc/math-emu/math.c diff --git a/trunk/arch/powerpc/math-emu/mcrfs.c b/trunk/arch/ppc/math-emu/mcrfs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/mcrfs.c rename to trunk/arch/ppc/math-emu/mcrfs.c diff --git a/trunk/arch/powerpc/math-emu/mffs.c b/trunk/arch/ppc/math-emu/mffs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/mffs.c rename to trunk/arch/ppc/math-emu/mffs.c diff --git a/trunk/arch/powerpc/math-emu/mtfsb0.c b/trunk/arch/ppc/math-emu/mtfsb0.c similarity index 100% rename from trunk/arch/powerpc/math-emu/mtfsb0.c rename to trunk/arch/ppc/math-emu/mtfsb0.c diff --git a/trunk/arch/powerpc/math-emu/mtfsb1.c b/trunk/arch/ppc/math-emu/mtfsb1.c similarity index 100% rename from trunk/arch/powerpc/math-emu/mtfsb1.c rename to trunk/arch/ppc/math-emu/mtfsb1.c diff --git a/trunk/arch/powerpc/math-emu/mtfsf.c b/trunk/arch/ppc/math-emu/mtfsf.c similarity index 100% rename from trunk/arch/powerpc/math-emu/mtfsf.c rename to trunk/arch/ppc/math-emu/mtfsf.c diff --git a/trunk/arch/powerpc/math-emu/mtfsfi.c b/trunk/arch/ppc/math-emu/mtfsfi.c similarity index 100% rename from trunk/arch/powerpc/math-emu/mtfsfi.c rename to trunk/arch/ppc/math-emu/mtfsfi.c diff --git a/trunk/arch/powerpc/math-emu/op-1.h b/trunk/arch/ppc/math-emu/op-1.h similarity index 100% rename from trunk/arch/powerpc/math-emu/op-1.h rename to trunk/arch/ppc/math-emu/op-1.h diff --git a/trunk/arch/powerpc/math-emu/op-2.h b/trunk/arch/ppc/math-emu/op-2.h similarity index 100% rename from trunk/arch/powerpc/math-emu/op-2.h rename to trunk/arch/ppc/math-emu/op-2.h diff --git a/trunk/arch/powerpc/math-emu/op-4.h b/trunk/arch/ppc/math-emu/op-4.h similarity index 100% rename from trunk/arch/powerpc/math-emu/op-4.h rename to trunk/arch/ppc/math-emu/op-4.h diff --git a/trunk/arch/powerpc/math-emu/op-common.h b/trunk/arch/ppc/math-emu/op-common.h similarity index 100% rename from trunk/arch/powerpc/math-emu/op-common.h rename to trunk/arch/ppc/math-emu/op-common.h diff --git a/trunk/arch/powerpc/math-emu/sfp-machine.h b/trunk/arch/ppc/math-emu/sfp-machine.h similarity index 100% rename from trunk/arch/powerpc/math-emu/sfp-machine.h rename to trunk/arch/ppc/math-emu/sfp-machine.h diff --git a/trunk/arch/powerpc/math-emu/single.h b/trunk/arch/ppc/math-emu/single.h similarity index 100% rename from trunk/arch/powerpc/math-emu/single.h rename to trunk/arch/ppc/math-emu/single.h diff --git a/trunk/arch/powerpc/math-emu/soft-fp.h b/trunk/arch/ppc/math-emu/soft-fp.h similarity index 100% rename from trunk/arch/powerpc/math-emu/soft-fp.h rename to trunk/arch/ppc/math-emu/soft-fp.h diff --git a/trunk/arch/powerpc/math-emu/stfd.c b/trunk/arch/ppc/math-emu/stfd.c similarity index 100% rename from trunk/arch/powerpc/math-emu/stfd.c rename to trunk/arch/ppc/math-emu/stfd.c diff --git a/trunk/arch/powerpc/math-emu/stfiwx.c b/trunk/arch/ppc/math-emu/stfiwx.c similarity index 100% rename from trunk/arch/powerpc/math-emu/stfiwx.c rename to trunk/arch/ppc/math-emu/stfiwx.c diff --git a/trunk/arch/powerpc/math-emu/stfs.c b/trunk/arch/ppc/math-emu/stfs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/stfs.c rename to trunk/arch/ppc/math-emu/stfs.c diff --git a/trunk/arch/powerpc/math-emu/types.c b/trunk/arch/ppc/math-emu/types.c similarity index 100% rename from trunk/arch/powerpc/math-emu/types.c rename to trunk/arch/ppc/math-emu/types.c diff --git a/trunk/arch/powerpc/math-emu/udivmodti4.c b/trunk/arch/ppc/math-emu/udivmodti4.c similarity index 100% rename from trunk/arch/powerpc/math-emu/udivmodti4.c rename to trunk/arch/ppc/math-emu/udivmodti4.c diff --git a/trunk/arch/ppc/mm/fault.c b/trunk/arch/ppc/mm/fault.c index 8e08ca32531a..0217188ef465 100644 --- a/trunk/arch/ppc/mm/fault.c +++ b/trunk/arch/ppc/mm/fault.c @@ -202,7 +202,6 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, /* an exec - 4xx/Book-E allows for per-page execute permission */ } else if (TRAP(regs) == 0x400) { pte_t *ptep; - pmd_t *pmdp; #if 0 /* It would be nice to actually enforce the VM execute @@ -216,24 +215,21 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, /* Since 4xx/Book-E supports per-page execute permission, * we lazily flush dcache to icache. */ ptep = NULL; - if (get_pteptr(mm, address, &ptep, &pmdp)) { - spinlock_t *ptl = pte_lockptr(mm, pmdp); - spin_lock(ptl); - if (pte_present(*ptep)) { - struct page *page = pte_page(*ptep); - - if (!test_bit(PG_arch_1, &page->flags)) { - flush_dcache_icache_page(page); - set_bit(PG_arch_1, &page->flags); - } - pte_update(ptep, 0, _PAGE_HWEXEC); - _tlbie(address); - pte_unmap_unlock(ptep, ptl); - up_read(&mm->mmap_sem); - return 0; + if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) { + struct page *page = pte_page(*ptep); + + if (! test_bit(PG_arch_1, &page->flags)) { + flush_dcache_icache_page(page); + set_bit(PG_arch_1, &page->flags); } - pte_unmap_unlock(ptep, ptl); + pte_update(ptep, 0, _PAGE_HWEXEC); + _tlbie(address); + pte_unmap(ptep); + up_read(&mm->mmap_sem); + return 0; } + if (ptep != NULL) + pte_unmap(ptep); #endif /* a read */ } else { diff --git a/trunk/arch/ppc/mm/hashtable.S b/trunk/arch/ppc/mm/hashtable.S index 31d0a924317c..f09fa88db35a 100644 --- a/trunk/arch/ppc/mm/hashtable.S +++ b/trunk/arch/ppc/mm/hashtable.S @@ -74,6 +74,12 @@ _GLOBAL(hash_page_sync) */ .text _GLOBAL(hash_page) +#ifdef CONFIG_PPC64BRIDGE + mfmsr r0 + clrldi r0,r0,1 /* make sure it's in 32-bit mode */ + MTMSRD(r0) + isync +#endif tophys(r7,0) /* gets -KERNELBASE into r7 */ #ifdef CONFIG_SMP addis r8,r7,mmu_hash_lock@h @@ -297,6 +303,7 @@ Hash_base = 0xc0180000 Hash_bits = 12 /* e.g. 256kB hash table */ Hash_msk = (((1 << Hash_bits) - 1) * 64) +#ifndef CONFIG_PPC64BRIDGE /* defines for the PTE format for 32-bit PPCs */ #define PTE_SIZE 8 #define PTEG_SIZE 64 @@ -310,6 +317,21 @@ Hash_msk = (((1 << Hash_bits) - 1) * 64) #define SET_V(r) oris r,r,PTE_V@h #define CLR_V(r,t) rlwinm r,r,0,1,31 +#else +/* defines for the PTE format for 64-bit PPCs */ +#define PTE_SIZE 16 +#define PTEG_SIZE 128 +#define LG_PTEG_SIZE 7 +#define LDPTEu ldu +#define STPTE std +#define CMPPTE cmpd +#define PTE_H 2 +#define PTE_V 1 +#define TST_V(r) andi. r,r,PTE_V +#define SET_V(r) ori r,r,PTE_V +#define CLR_V(r,t) li t,PTE_V; andc r,r,t +#endif /* CONFIG_PPC64BRIDGE */ + #define HASH_LEFT 31-(LG_PTEG_SIZE+Hash_bits-1) #define HASH_RIGHT 31-LG_PTEG_SIZE @@ -327,8 +349,14 @@ BEGIN_FTR_SECTION END_FTR_SECTION_IFSET(CPU_FTR_NEED_COHERENT) /* Construct the high word of the PPC-style PTE (r5) */ +#ifndef CONFIG_PPC64BRIDGE rlwinm r5,r3,7,1,24 /* put VSID in 0x7fffff80 bits */ rlwimi r5,r4,10,26,31 /* put in API (abbrev page index) */ +#else /* CONFIG_PPC64BRIDGE */ + clrlwi r3,r3,8 /* reduce vsid to 24 bits */ + sldi r5,r3,12 /* shift vsid into position */ + rlwimi r5,r4,16,20,24 /* put in API (abbrev page index) */ +#endif /* CONFIG_PPC64BRIDGE */ SET_V(r5) /* set V (valid) bit */ /* Get the address of the primary PTE group in the hash table (r3) */ @@ -512,8 +540,14 @@ _GLOBAL(flush_hash_pages) add r3,r3,r0 /* note code below trims to 24 bits */ /* Construct the high word of the PPC-style PTE (r11) */ +#ifndef CONFIG_PPC64BRIDGE rlwinm r11,r3,7,1,24 /* put VSID in 0x7fffff80 bits */ rlwimi r11,r4,10,26,31 /* put in API (abbrev page index) */ +#else /* CONFIG_PPC64BRIDGE */ + clrlwi r3,r3,8 /* reduce vsid to 24 bits */ + sldi r11,r3,12 /* shift vsid into position */ + rlwimi r11,r4,16,20,24 /* put in API (abbrev page index) */ +#endif /* CONFIG_PPC64BRIDGE */ SET_V(r11) /* set V (valid) bit */ #ifdef CONFIG_SMP diff --git a/trunk/arch/ppc/mm/init.c b/trunk/arch/ppc/mm/init.c index 386e000bcb73..cb1c294fb932 100644 --- a/trunk/arch/ppc/mm/init.c +++ b/trunk/arch/ppc/mm/init.c @@ -412,6 +412,14 @@ void __init mem_init(void) } #endif /* CONFIG_BLK_DEV_INITRD */ +#ifdef CONFIG_PPC_OF + /* mark the RTAS pages as reserved */ + if ( rtas_data ) + for (addr = (ulong)__va(rtas_data); + addr < PAGE_ALIGN((ulong)__va(rtas_data)+rtas_size) ; + addr += PAGE_SIZE) + SetPageReserved(virt_to_page(addr)); +#endif for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory; addr += PAGE_SIZE) { if (!PageReserved(virt_to_page(addr))) @@ -486,6 +494,11 @@ set_phys_avail(unsigned long total_memory) initrd_end - initrd_start, 1); } #endif /* CONFIG_BLK_DEV_INITRD */ +#ifdef CONFIG_PPC_OF + /* remove the RTAS pages from the available memory */ + if (rtas_data) + mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1); +#endif } /* Mark some memory as reserved by removing it from phys_avail. */ diff --git a/trunk/arch/ppc/mm/mmu_context.c b/trunk/arch/ppc/mm/mmu_context.c index b4a4b3f02a1c..a8816e0f6a86 100644 --- a/trunk/arch/ppc/mm/mmu_context.c +++ b/trunk/arch/ppc/mm/mmu_context.c @@ -2,7 +2,7 @@ * This file contains the routines for handling the MMU on those * PowerPC implementations where the MMU substantially follows the * architecture specification. This includes the 6xx, 7xx, 7xxx, - * 8260, and 83xx implementations but excludes the 8xx and 4xx. + * 8260, and POWER3 implementations but excludes the 8xx and 4xx. * -- paulus * * Derived from arch/ppc/mm/init.c: diff --git a/trunk/arch/ppc/mm/pgtable.c b/trunk/arch/ppc/mm/pgtable.c index 706bca8eb144..6ea9185fd120 100644 --- a/trunk/arch/ppc/mm/pgtable.c +++ b/trunk/arch/ppc/mm/pgtable.c @@ -39,7 +39,7 @@ unsigned long ioremap_base; unsigned long ioremap_bot; int io_bat_index; -#if defined(CONFIG_6xx) +#if defined(CONFIG_6xx) || defined(CONFIG_POWER3) #define HAVE_BATS 1 #endif @@ -368,7 +368,7 @@ void __init io_block_mapping(unsigned long virt, phys_addr_t phys, * the PTE pointer is unmodified if PTE is not found. */ int -get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp) +get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep) { pgd_t *pgd; pmd_t *pmd; @@ -383,8 +383,6 @@ get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp) if (pte) { retval = 1; *ptep = pte; - if (pmdp) - *pmdp = pmd; /* XXX caller needs to do pte_unmap, yuck */ } } @@ -422,7 +420,7 @@ unsigned long iopa(unsigned long addr) mm = &init_mm; pa = 0; - if (get_pteptr(mm, addr, &pte, NULL)) { + if (get_pteptr(mm, addr, &pte)) { pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK); pte_unmap(pte); } diff --git a/trunk/arch/ppc/mm/ppc_mmu.c b/trunk/arch/ppc/mm/ppc_mmu.c index 25bb6f3347c1..9a381ed5eb21 100644 --- a/trunk/arch/ppc/mm/ppc_mmu.c +++ b/trunk/arch/ppc/mm/ppc_mmu.c @@ -2,7 +2,7 @@ * This file contains the routines for handling the MMU on those * PowerPC implementations where the MMU substantially follows the * architecture specification. This includes the 6xx, 7xx, 7xxx, - * 8260, and 83xx implementations but excludes the 8xx and 4xx. + * 8260, and POWER3 implementations but excludes the 8xx and 4xx. * -- paulus * * Derived from arch/ppc/mm/init.c: @@ -42,7 +42,11 @@ unsigned long _SDR1; union ubat { /* BAT register values to be loaded */ BAT bat; +#ifdef CONFIG_PPC64BRIDGE + u64 word[2]; +#else u32 word[2]; +#endif } BATS[4][2]; /* 4 pairs of IBAT, DBAT */ struct batrange { /* stores address ranges mapped by BATs */ @@ -79,6 +83,9 @@ unsigned long p_mapped_by_bats(unsigned long pa) unsigned long __init mmu_mapin_ram(void) { +#ifdef CONFIG_POWER4 + return 0; +#else unsigned long tot, bl, done; unsigned long max_size = (256<<20); unsigned long align; @@ -115,6 +122,7 @@ unsigned long __init mmu_mapin_ram(void) } return done; +#endif } /* @@ -197,10 +205,27 @@ void __init MMU_init_hw(void) if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105); +#ifdef CONFIG_PPC64BRIDGE +#define LG_HPTEG_SIZE 7 /* 128 bytes per HPTEG */ +#define SDR1_LOW_BITS (lg_n_hpteg - 11) +#define MIN_N_HPTEG 2048 /* min 256kB hash table */ +#else #define LG_HPTEG_SIZE 6 /* 64 bytes per HPTEG */ #define SDR1_LOW_BITS ((n_hpteg - 1) >> 10) #define MIN_N_HPTEG 1024 /* min 64kB hash table */ +#endif + +#ifdef CONFIG_POWER4 + /* The hash table has already been allocated and initialized + in prom.c */ + n_hpteg = Hash_size >> LG_HPTEG_SIZE; + lg_n_hpteg = __ilog2(n_hpteg); + + /* Remove the hash table from the available memory */ + if (Hash) + reserve_phys_mem(__pa(Hash), Hash_size); +#else /* CONFIG_POWER4 */ /* * Allow 1 HPTE (1/8 HPTEG) for each page of memory. * This is less than the recommended amount, but then @@ -223,6 +248,7 @@ void __init MMU_init_hw(void) Hash = mem_pieces_find(Hash_size, Hash_size); cacheable_memzero(Hash, Hash_size); _SDR1 = __pa(Hash) | SDR1_LOW_BITS; +#endif /* CONFIG_POWER4 */ Hash_end = (PTE *) ((unsigned long)Hash + Hash_size); diff --git a/trunk/arch/ppc/platforms/Makefile b/trunk/arch/ppc/platforms/Makefile index 90c622294423..e8b91a33ce91 100644 --- a/trunk/arch/ppc/platforms/Makefile +++ b/trunk/arch/ppc/platforms/Makefile @@ -2,10 +2,18 @@ # Makefile for the linux kernel. # +# Extra CFLAGS so we don't have to do relative includes +CFLAGS_chrp_setup.o += -Iarch/$(ARCH)/mm + obj-$(CONFIG_APUS) += apus_setup.o ifeq ($(CONFIG_APUS),y) obj-$(CONFIG_PCI) += apus_pci.o endif +obj-$(CONFIG_PPC_CHRP) += chrp_setup.o chrp_time.o chrp_pci.o \ + chrp_pegasos_eth.o +ifeq ($(CONFIG_PPC_CHRP),y) +obj-$(CONFIG_NVRAM) += chrp_nvram.o +endif obj-$(CONFIG_PPC_PREP) += prep_pci.o prep_setup.o obj-$(CONFIG_PREP_RESIDUAL) += residual.o obj-$(CONFIG_PQ2ADS) += pq2ads.o @@ -32,3 +40,7 @@ obj-$(CONFIG_EV64360) += ev64360.o obj-$(CONFIG_MPC86XADS) += mpc866ads_setup.o obj-$(CONFIG_MPC885ADS) += mpc885ads_setup.o obj-$(CONFIG_ADS8272) += mpc8272ads_setup.o + +ifeq ($(CONFIG_SMP),y) +obj-$(CONFIG_PPC_CHRP) += chrp_smp.o +endif diff --git a/trunk/arch/ppc/platforms/chrp_nvram.c b/trunk/arch/ppc/platforms/chrp_nvram.c new file mode 100644 index 000000000000..465ba9b090ef --- /dev/null +++ b/trunk/arch/ppc/platforms/chrp_nvram.c @@ -0,0 +1,83 @@ +/* + * c 2001 PPC 64 Team, IBM Corp + * + * 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. + * + * /dev/nvram driver for PPC + * + */ + +#include +#include +#include +#include +#include +#include +#include + +static unsigned int nvram_size; +static unsigned char nvram_buf[4]; +static DEFINE_SPINLOCK(nvram_lock); + +static unsigned char chrp_nvram_read(int addr) +{ + unsigned long done, flags; + unsigned char ret; + + if (addr >= nvram_size) { + printk(KERN_DEBUG "%s: read addr %d > nvram_size %u\n", + current->comm, addr, nvram_size); + return 0xff; + } + spin_lock_irqsave(&nvram_lock, flags); + if ((call_rtas("nvram-fetch", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done) + ret = 0xff; + else + ret = nvram_buf[0]; + spin_unlock_irqrestore(&nvram_lock, flags); + + return ret; +} + +static void chrp_nvram_write(int addr, unsigned char val) +{ + unsigned long done, flags; + + if (addr >= nvram_size) { + printk(KERN_DEBUG "%s: write addr %d > nvram_size %u\n", + current->comm, addr, nvram_size); + return; + } + spin_lock_irqsave(&nvram_lock, flags); + nvram_buf[0] = val; + if ((call_rtas("nvram-store", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done) + printk(KERN_DEBUG "rtas IO error storing 0x%02x at %d", val, addr); + spin_unlock_irqrestore(&nvram_lock, flags); +} + +void __init chrp_nvram_init(void) +{ + struct device_node *nvram; + unsigned int *nbytes_p, proplen; + + nvram = of_find_node_by_type(NULL, "nvram"); + if (nvram == NULL) + return; + + nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen); + if (nbytes_p == NULL || proplen != sizeof(unsigned int)) + return; + + nvram_size = *nbytes_p; + + printk(KERN_INFO "CHRP nvram contains %u bytes\n", nvram_size); + of_node_put(nvram); + + ppc_md.nvram_read_val = chrp_nvram_read; + ppc_md.nvram_write_val = chrp_nvram_write; + + return; +} diff --git a/trunk/arch/ppc/platforms/chrp_pci.c b/trunk/arch/ppc/platforms/chrp_pci.c new file mode 100644 index 000000000000..c7fe6182bb77 --- /dev/null +++ b/trunk/arch/ppc/platforms/chrp_pci.c @@ -0,0 +1,309 @@ +/* + * CHRP pci routines. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* LongTrail */ +void __iomem *gg2_pci_config_base; + +/* + * The VLSI Golden Gate II has only 512K of PCI configuration space, so we + * limit the bus number to 3 bits + */ + +int gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off, + int len, u32 *val) +{ + volatile void __iomem *cfg_data; + struct pci_controller *hose = bus->sysdata; + + if (bus->number > 7) + return PCIBIOS_DEVICE_NOT_FOUND; + /* + * Note: the caller has already checked that off is + * suitably aligned and that len is 1, 2 or 4. + */ + cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off); + switch (len) { + case 1: + *val = in_8(cfg_data); + break; + case 2: + *val = in_le16(cfg_data); + break; + default: + *val = in_le32(cfg_data); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +int gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off, + int len, u32 val) +{ + volatile void __iomem *cfg_data; + struct pci_controller *hose = bus->sysdata; + + if (bus->number > 7) + return PCIBIOS_DEVICE_NOT_FOUND; + /* + * Note: the caller has already checked that off is + * suitably aligned and that len is 1, 2 or 4. + */ + cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off); + switch (len) { + case 1: + out_8(cfg_data, val); + break; + case 2: + out_le16(cfg_data, val); + break; + default: + out_le32(cfg_data, val); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops gg2_pci_ops = +{ + gg2_read_config, + gg2_write_config +}; + +/* + * Access functions for PCI config space using RTAS calls. + */ +int +rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset, + int len, u32 *val) +{ + struct pci_controller *hose = bus->sysdata; + unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) + | (((bus->number - hose->first_busno) & 0xff) << 16) + | (hose->index << 24); + unsigned long ret = ~0UL; + int rval; + + rval = call_rtas("read-pci-config", 2, 2, &ret, addr, len); + *val = ret; + return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; +} + +int +rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset, + int len, u32 val) +{ + struct pci_controller *hose = bus->sysdata; + unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) + | (((bus->number - hose->first_busno) & 0xff) << 16) + | (hose->index << 24); + int rval; + + rval = call_rtas("write-pci-config", 3, 1, NULL, addr, len, val); + return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops rtas_pci_ops = +{ + rtas_read_config, + rtas_write_config +}; + +volatile struct Hydra __iomem *Hydra = NULL; + +int __init +hydra_init(void) +{ + struct device_node *np; + + np = find_devices("mac-io"); + if (np == NULL || np->n_addrs == 0) + return 0; + Hydra = ioremap(np->addrs[0].address, np->addrs[0].size); + printk("Hydra Mac I/O at %x\n", np->addrs[0].address); + printk("Hydra Feature_Control was %x", + in_le32(&Hydra->Feature_Control)); + out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN | + HYDRA_FC_SCSI_CELL_EN | + HYDRA_FC_SCCA_ENABLE | + HYDRA_FC_SCCB_ENABLE | + HYDRA_FC_ARB_BYPASS | + HYDRA_FC_MPIC_ENABLE | + HYDRA_FC_SLOW_SCC_PCLK | + HYDRA_FC_MPIC_IS_MASTER)); + printk(", now %x\n", in_le32(&Hydra->Feature_Control)); + return 1; +} + +void __init +chrp_pcibios_fixup(void) +{ + struct pci_dev *dev = NULL; + struct device_node *np; + + /* PCI interrupts are controlled by the OpenPIC */ + for_each_pci_dev(dev) { + np = pci_device_to_OF_node(dev); + if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0)) + dev->irq = np->intrs[0].line; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +} + +#define PRG_CL_RESET_VALID 0x00010000 + +static void __init +setup_python(struct pci_controller *hose, struct device_node *dev) +{ + u32 __iomem *reg; + u32 val; + unsigned long addr = dev->addrs[0].address; + + setup_indirect_pci(hose, addr + 0xf8000, addr + 0xf8010); + + /* Clear the magic go-slow bit */ + reg = ioremap(dev->addrs[0].address + 0xf6000, 0x40); + val = in_be32(®[12]); + if (val & PRG_CL_RESET_VALID) { + out_be32(®[12], val & ~PRG_CL_RESET_VALID); + in_be32(®[12]); + } + iounmap(reg); +} + +/* Marvell Discovery II based Pegasos 2 */ +static void __init setup_peg2(struct pci_controller *hose, struct device_node *dev) +{ + struct device_node *root = find_path_device("/"); + struct device_node *rtas; + + rtas = of_find_node_by_name (root, "rtas"); + if (rtas) { + hose->ops = &rtas_pci_ops; + } else { + printk ("RTAS supporting Pegasos OF not found, please upgrade" + " your firmware\n"); + } + pci_assign_all_buses = 1; +} + +void __init +chrp_find_bridges(void) +{ + struct device_node *dev; + int *bus_range; + int len, index = -1; + struct pci_controller *hose; + unsigned int *dma; + char *model, *machine; + int is_longtrail = 0, is_mot = 0, is_pegasos = 0; + struct device_node *root = find_path_device("/"); + + /* + * The PCI host bridge nodes on some machines don't have + * properties to adequately identify them, so we have to + * look at what sort of machine this is as well. + */ + machine = get_property(root, "model", NULL); + if (machine != NULL) { + is_longtrail = strncmp(machine, "IBM,LongTrail", 13) == 0; + is_mot = strncmp(machine, "MOT", 3) == 0; + if (strncmp(machine, "Pegasos2", 8) == 0) + is_pegasos = 2; + else if (strncmp(machine, "Pegasos", 7) == 0) + is_pegasos = 1; + } + for (dev = root->child; dev != NULL; dev = dev->sibling) { + if (dev->type == NULL || strcmp(dev->type, "pci") != 0) + continue; + ++index; + /* The GG2 bridge on the LongTrail doesn't have an address */ + if (dev->n_addrs < 1 && !is_longtrail) { + printk(KERN_WARNING "Can't use %s: no address\n", + dev->full_name); + continue; + } + bus_range = (int *) get_property(dev, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s\n", + dev->full_name); + continue; + } + if (bus_range[1] == bus_range[0]) + printk(KERN_INFO "PCI bus %d", bus_range[0]); + else + printk(KERN_INFO "PCI buses %d..%d", + bus_range[0], bus_range[1]); + printk(" controlled by %s", dev->type); + if (dev->n_addrs > 0) + printk(" at %x", dev->addrs[0].address); + printk("\n"); + + hose = pcibios_alloc_controller(); + if (!hose) { + printk("Can't allocate PCI controller structure for %s\n", + dev->full_name); + continue; + } + hose->arch_data = dev; + hose->first_busno = bus_range[0]; + hose->last_busno = bus_range[1]; + + model = get_property(dev, "model", NULL); + if (model == NULL) + model = ""; + if (device_is_compatible(dev, "IBM,python")) { + setup_python(hose, dev); + } else if (is_mot + || strncmp(model, "Motorola, Grackle", 17) == 0) { + setup_indirect_pci(hose, 0xfec00000, 0xfee00000); + } else if (is_longtrail) { + void __iomem *p = ioremap(GG2_PCI_CONFIG_BASE, 0x80000); + hose->ops = &gg2_pci_ops; + hose->cfg_data = p; + gg2_pci_config_base = p; + } else if (is_pegasos == 1) { + setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc); + } else if (is_pegasos == 2) { + setup_peg2(hose, dev); + } else { + printk("No methods for %s (model %s), using RTAS\n", + dev->full_name, model); + hose->ops = &rtas_pci_ops; + } + + pci_process_bridge_OF_ranges(hose, dev, index == 0); + + /* check the first bridge for a property that we can + use to set pci_dram_offset */ + dma = (unsigned int *) + get_property(dev, "ibm,dma-ranges", &len); + if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) { + pci_dram_offset = dma[2] - dma[3]; + printk("pci_dram_offset = %lx\n", pci_dram_offset); + } + } + + /* Do not fixup interrupts from OF tree on pegasos */ + if (is_pegasos == 0) + ppc_md.pcibios_fixup = chrp_pcibios_fixup; +} diff --git a/trunk/arch/ppc/platforms/chrp_pegasos_eth.c b/trunk/arch/ppc/platforms/chrp_pegasos_eth.c new file mode 100644 index 000000000000..9305c8aa1373 --- /dev/null +++ b/trunk/arch/ppc/platforms/chrp_pegasos_eth.c @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2005 Sven Luther + * Thanks to : + * Dale Farnsworth + * Mark A. Greer + * Nicolas DET + * Benjamin Herrenschmidt + * And anyone else who helped me on this. + */ + +#include +#include +#include +#include +#include +#include + +#define PEGASOS2_MARVELL_REGBASE (0xf1000000) +#define PEGASOS2_MARVELL_REGSIZE (0x00004000) +#define PEGASOS2_SRAM_BASE (0xf2000000) +#define PEGASOS2_SRAM_SIZE (256*1024) + +#define PEGASOS2_SRAM_BASE_ETH0 (PEGASOS2_SRAM_BASE) +#define PEGASOS2_SRAM_BASE_ETH1 (PEGASOS2_SRAM_BASE_ETH0 + (PEGASOS2_SRAM_SIZE / 2) ) + + +#define PEGASOS2_SRAM_RXRING_SIZE (PEGASOS2_SRAM_SIZE/4) +#define PEGASOS2_SRAM_TXRING_SIZE (PEGASOS2_SRAM_SIZE/4) + +#undef BE_VERBOSE + +static struct resource mv643xx_eth_shared_resources[] = { + [0] = { + .name = "ethernet shared base", + .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, + .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + + MV643XX_ETH_SHARED_REGS_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mv643xx_eth_shared_device = { + .name = MV643XX_ETH_SHARED_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), + .resource = mv643xx_eth_shared_resources, +}; + +static struct resource mv643xx_eth0_resources[] = { + [0] = { + .name = "eth0 irq", + .start = 9, + .end = 9, + .flags = IORESOURCE_IRQ, + }, +}; + + +static struct mv643xx_eth_platform_data eth0_pd = { + .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0, + .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, + .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, + + .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH0 + PEGASOS2_SRAM_TXRING_SIZE, + .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE, + .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16, +}; + +static struct platform_device eth0_device = { + .name = MV643XX_ETH_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv643xx_eth0_resources), + .resource = mv643xx_eth0_resources, + .dev = { + .platform_data = ð0_pd, + }, +}; + +static struct resource mv643xx_eth1_resources[] = { + [0] = { + .name = "eth1 irq", + .start = 9, + .end = 9, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct mv643xx_eth_platform_data eth1_pd = { + .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1, + .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, + .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, + + .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH1 + PEGASOS2_SRAM_TXRING_SIZE, + .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE, + .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16, +}; + +static struct platform_device eth1_device = { + .name = MV643XX_ETH_NAME, + .id = 1, + .num_resources = ARRAY_SIZE(mv643xx_eth1_resources), + .resource = mv643xx_eth1_resources, + .dev = { + .platform_data = ð1_pd, + }, +}; + +static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { + &mv643xx_eth_shared_device, + ð0_device, + ð1_device, +}; + +/***********/ +/***********/ +#define MV_READ(offset,val) { val = readl(mv643xx_reg_base + offset); } +#define MV_WRITE(offset,data) writel(data, mv643xx_reg_base + offset) + +static void __iomem *mv643xx_reg_base; + +static int Enable_SRAM(void) +{ + u32 ALong; + + if (mv643xx_reg_base == NULL) + mv643xx_reg_base = ioremap(PEGASOS2_MARVELL_REGBASE, + PEGASOS2_MARVELL_REGSIZE); + + if (mv643xx_reg_base == NULL) + return -ENOMEM; + +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: register remapped from %p to %p\n", + (void *)PEGASOS2_MARVELL_REGBASE, (void *)mv643xx_reg_base); +#endif + + MV_WRITE(MV64340_SRAM_CONFIG, 0); + + MV_WRITE(MV64340_INTEGRATED_SRAM_BASE_ADDR, PEGASOS2_SRAM_BASE >> 16); + + MV_READ(MV64340_BASE_ADDR_ENABLE, ALong); + ALong &= ~(1 << 19); + MV_WRITE(MV64340_BASE_ADDR_ENABLE, ALong); + + ALong = 0x02; + ALong |= PEGASOS2_SRAM_BASE & 0xffff0000; + MV_WRITE(MV643XX_ETH_BAR_4, ALong); + + MV_WRITE(MV643XX_ETH_SIZE_REG_4, (PEGASOS2_SRAM_SIZE-1) & 0xffff0000); + + MV_READ(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong); + ALong &= ~(1 << 4); + MV_WRITE(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong); + +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: register unmapped\n"); + printk("Pegasos II/Marvell MV64361: SRAM at %p, size=%x\n", (void*) PEGASOS2_SRAM_BASE, PEGASOS2_SRAM_SIZE); +#endif + + iounmap(mv643xx_reg_base); + mv643xx_reg_base = NULL; + + return 1; +} + + +/***********/ +/***********/ +int mv643xx_eth_add_pds(void) +{ + int ret = 0; + static struct pci_device_id pci_marvell_mv64360[] = { + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64360) }, + { } + }; + +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: init\n"); +#endif + + if (pci_dev_present(pci_marvell_mv64360)) { + ret = platform_add_devices(mv643xx_eth_pd_devs, + ARRAY_SIZE(mv643xx_eth_pd_devs)); + + if ( Enable_SRAM() < 0) + { + eth0_pd.tx_sram_addr = 0; + eth0_pd.tx_sram_size = 0; + eth0_pd.rx_sram_addr = 0; + eth0_pd.rx_sram_size = 0; + + eth1_pd.tx_sram_addr = 0; + eth1_pd.tx_sram_size = 0; + eth1_pd.rx_sram_addr = 0; + eth1_pd.rx_sram_size = 0; + +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: Can't enable the " + "SRAM\n"); +#endif + } + } + +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: init is over\n"); +#endif + + return ret; +} + +device_initcall(mv643xx_eth_add_pds); diff --git a/trunk/arch/ppc/platforms/chrp_setup.c b/trunk/arch/ppc/platforms/chrp_setup.c new file mode 100644 index 000000000000..f9fd3f4f8e2e --- /dev/null +++ b/trunk/arch/ppc/platforms/chrp_setup.c @@ -0,0 +1,669 @@ +/* + * Copyright (C) 1995 Linus Torvalds + * Adapted from 'alpha' version by Gary Thomas + * Modified by Cort Dougan (cort@cs.nmt.edu) + */ + +/* + * bootup setup stuff.. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mem_pieces.h" + +unsigned long chrp_get_rtc_time(void); +int chrp_set_rtc_time(unsigned long nowtime); +void chrp_calibrate_decr(void); +long chrp_time_init(void); + +void chrp_find_bridges(void); +void chrp_event_scan(void); +void rtas_display_progress(char *, unsigned short); +void rtas_indicator_progress(char *, unsigned short); +void btext_progress(char *, unsigned short); + +extern int of_show_percpuinfo(struct seq_file *, int); + +int _chrp_type; +EXPORT_SYMBOL(_chrp_type); + +/* + * XXX this should be in xmon.h, but putting it there means xmon.h + * has to include (to get irqreturn_t), which + * causes all sorts of problems. -- paulus + */ +extern irqreturn_t xmon_irq(int, void *, struct pt_regs *); + +extern dev_t boot_dev; + +extern PTE *Hash, *Hash_end; +extern unsigned long Hash_size, Hash_mask; +extern int probingmem; +extern unsigned long loops_per_jiffy; +static int max_width; + +#ifdef CONFIG_SMP +extern struct smp_ops_t chrp_smp_ops; +#endif + +static const char *gg2_memtypes[4] = { + "FPM", "SDRAM", "EDO", "BEDO" +}; +static const char *gg2_cachesizes[4] = { + "256 KB", "512 KB", "1 MB", "Reserved" +}; +static const char *gg2_cachetypes[4] = { + "Asynchronous", "Reserved", "Flow-Through Synchronous", + "Pipelined Synchronous" +}; +static const char *gg2_cachemodes[4] = { + "Disabled", "Write-Through", "Copy-Back", "Transparent Mode" +}; + +int +chrp_show_cpuinfo(struct seq_file *m) +{ + int i, sdramen; + unsigned int t; + struct device_node *root; + const char *model = ""; + + root = find_path_device("/"); + if (root) + model = get_property(root, "model", NULL); + seq_printf(m, "machine\t\t: CHRP %s\n", model); + + /* longtrail (goldengate) stuff */ + if (!strncmp(model, "IBM,LongTrail", 13)) { + /* VLSI VAS96011/12 `Golden Gate 2' */ + /* Memory banks */ + sdramen = (in_le32(gg2_pci_config_base + GG2_PCI_DRAM_CTRL) + >>31) & 1; + for (i = 0; i < (sdramen ? 4 : 6); i++) { + t = in_le32(gg2_pci_config_base+ + GG2_PCI_DRAM_BANK0+ + i*4); + if (!(t & 1)) + continue; + switch ((t>>8) & 0x1f) { + case 0x1f: + model = "4 MB"; + break; + case 0x1e: + model = "8 MB"; + break; + case 0x1c: + model = "16 MB"; + break; + case 0x18: + model = "32 MB"; + break; + case 0x10: + model = "64 MB"; + break; + case 0x00: + model = "128 MB"; + break; + default: + model = "Reserved"; + break; + } + seq_printf(m, "memory bank %d\t: %s %s\n", i, model, + gg2_memtypes[sdramen ? 1 : ((t>>1) & 3)]); + } + /* L2 cache */ + t = in_le32(gg2_pci_config_base+GG2_PCI_CC_CTRL); + seq_printf(m, "board l2\t: %s %s (%s)\n", + gg2_cachesizes[(t>>7) & 3], + gg2_cachetypes[(t>>2) & 3], + gg2_cachemodes[t & 3]); + } + return 0; +} + +/* + * Fixes for the National Semiconductor PC78308VUL SuperI/O + * + * Some versions of Open Firmware incorrectly initialize the IRQ settings + * for keyboard and mouse + */ +static inline void __init sio_write(u8 val, u8 index) +{ + outb(index, 0x15c); + outb(val, 0x15d); +} + +static inline u8 __init sio_read(u8 index) +{ + outb(index, 0x15c); + return inb(0x15d); +} + +static void __init sio_fixup_irq(const char *name, u8 device, u8 level, + u8 type) +{ + u8 level0, type0, active; + + /* select logical device */ + sio_write(device, 0x07); + active = sio_read(0x30); + level0 = sio_read(0x70); + type0 = sio_read(0x71); + if (level0 != level || type0 != type || !active) { + printk(KERN_WARNING "sio: %s irq level %d, type %d, %sactive: " + "remapping to level %d, type %d, active\n", + name, level0, type0, !active ? "in" : "", level, type); + sio_write(0x01, 0x30); + sio_write(level, 0x70); + sio_write(type, 0x71); + } +} + +static void __init sio_init(void) +{ + struct device_node *root; + + if ((root = find_path_device("/")) && + !strncmp(get_property(root, "model", NULL), "IBM,LongTrail", 13)) { + /* logical device 0 (KBC/Keyboard) */ + sio_fixup_irq("keyboard", 0, 1, 2); + /* select logical device 1 (KBC/Mouse) */ + sio_fixup_irq("mouse", 1, 12, 2); + } +} + + +static void __init pegasos_set_l2cr(void) +{ + struct device_node *np; + + /* On Pegasos, enable the l2 cache if needed, as the OF forgets it */ + if (_chrp_type != _CHRP_Pegasos) + return; + + /* Enable L2 cache if needed */ + np = find_type_devices("cpu"); + if (np != NULL) { + unsigned int *l2cr = (unsigned int *) + get_property (np, "l2cr", NULL); + if (l2cr == NULL) { + printk ("Pegasos l2cr : no cpu l2cr property found\n"); + return; + } + if (!((*l2cr) & 0x80000000)) { + printk ("Pegasos l2cr : L2 cache was not active, " + "activating\n"); + _set_L2CR(0); + _set_L2CR((*l2cr) | 0x80000000); + } + } +} + +void __init chrp_setup_arch(void) +{ + struct device_node *device; + + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000/HZ; + +#ifdef CONFIG_BLK_DEV_INITRD + /* this is fine for chrp */ + initrd_below_start_ok = 1; + + if (initrd_start) + ROOT_DEV = Root_RAM0; + else +#endif + ROOT_DEV = Root_SDA2; /* sda2 (sda1 is for the kernel) */ + + /* On pegasos, enable the L2 cache if not already done by OF */ + pegasos_set_l2cr(); + + /* Lookup PCI host bridges */ + chrp_find_bridges(); + +#ifndef CONFIG_PPC64BRIDGE + /* + * Temporary fixes for PCI devices. + * -- Geert + */ + hydra_init(); /* Mac I/O */ + +#endif /* CONFIG_PPC64BRIDGE */ + + /* + * Fix the Super I/O configuration + */ + sio_init(); + + /* Get the event scan rate for the rtas so we know how + * often it expects a heartbeat. -- Cort + */ + if ( rtas_data ) { + struct property *p; + device = find_devices("rtas"); + for ( p = device->properties; + p && strncmp(p->name, "rtas-event-scan-rate", 20); + p = p->next ) + /* nothing */ ; + if ( p && *(unsigned long *)p->value ) { + ppc_md.heartbeat = chrp_event_scan; + ppc_md.heartbeat_reset = (HZ/(*(unsigned long *)p->value)*30)-1; + ppc_md.heartbeat_count = 1; + printk("RTAS Event Scan Rate: %lu (%lu jiffies)\n", + *(unsigned long *)p->value, ppc_md.heartbeat_reset ); + } + } + + pci_create_OF_bus_map(); +} + +void +chrp_event_scan(void) +{ + unsigned char log[1024]; + unsigned long ret = 0; + /* XXX: we should loop until the hardware says no more error logs -- Cort */ + call_rtas( "event-scan", 4, 1, &ret, 0xffffffff, 0, + __pa(log), 1024 ); + ppc_md.heartbeat_count = ppc_md.heartbeat_reset; +} + +void +chrp_restart(char *cmd) +{ + printk("RTAS system-reboot returned %d\n", + call_rtas("system-reboot", 0, 1, NULL)); + for (;;); +} + +void +chrp_power_off(void) +{ + /* allow power on only with power button press */ + printk("RTAS power-off returned %d\n", + call_rtas("power-off", 2, 1, NULL,0xffffffff,0xffffffff)); + for (;;); +} + +void +chrp_halt(void) +{ + chrp_power_off(); +} + +/* + * Finds the open-pic node and sets OpenPIC_Addr based on its reg property. + * Then checks if it has an interrupt-ranges property. If it does then + * we have a distributed open-pic, so call openpic_set_sources to tell + * the openpic code where to find the interrupt source registers. + */ +static void __init chrp_find_openpic(void) +{ + struct device_node *np; + int len, i; + unsigned int *iranges; + void __iomem *isu; + + np = find_type_devices("open-pic"); + if (np == NULL || np->n_addrs == 0) + return; + printk(KERN_INFO "OpenPIC at %x (size %x)\n", + np->addrs[0].address, np->addrs[0].size); + OpenPIC_Addr = ioremap(np->addrs[0].address, 0x40000); + if (OpenPIC_Addr == NULL) { + printk(KERN_ERR "Failed to map OpenPIC!\n"); + return; + } + + iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len); + if (iranges == NULL || len < 2 * sizeof(unsigned int)) + return; /* not distributed */ + + /* + * The first pair of cells in interrupt-ranges refers to the + * IDU; subsequent pairs refer to the ISUs. + */ + len /= 2 * sizeof(unsigned int); + if (np->n_addrs < len) { + printk(KERN_ERR "Insufficient addresses for distributed" + " OpenPIC (%d < %d)\n", np->n_addrs, len); + return; + } + if (iranges[1] != 0) { + printk(KERN_INFO "OpenPIC irqs %d..%d in IDU\n", + iranges[0], iranges[0] + iranges[1] - 1); + openpic_set_sources(iranges[0], iranges[1], NULL); + } + for (i = 1; i < len; ++i) { + iranges += 2; + printk(KERN_INFO "OpenPIC irqs %d..%d in ISU at %x (%x)\n", + iranges[0], iranges[0] + iranges[1] - 1, + np->addrs[i].address, np->addrs[i].size); + isu = ioremap(np->addrs[i].address, np->addrs[i].size); + if (isu != NULL) + openpic_set_sources(iranges[0], iranges[1], isu); + else + printk(KERN_ERR "Failed to map OpenPIC ISU at %x!\n", + np->addrs[i].address); + } +} + +#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) +static struct irqaction xmon_irqaction = { + .handler = xmon_irq, + .mask = CPU_MASK_NONE, + .name = "XMON break", +}; +#endif + +void __init chrp_init_IRQ(void) +{ + struct device_node *np; + unsigned long chrp_int_ack = 0; + unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS]; +#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) + struct device_node *kbd; +#endif + + for (np = find_devices("pci"); np != NULL; np = np->next) { + unsigned int *addrp = (unsigned int *) + get_property(np, "8259-interrupt-acknowledge", NULL); + + if (addrp == NULL) + continue; + chrp_int_ack = addrp[prom_n_addr_cells(np)-1]; + break; + } + if (np == NULL) + printk(KERN_ERR "Cannot find PCI interrupt acknowledge address\n"); + + chrp_find_openpic(); + + if (OpenPIC_Addr) { + prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS); + OpenPIC_InitSenses = init_senses; + OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS; + + openpic_init(NUM_8259_INTERRUPTS); + /* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */ + openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade", + i8259_irq); + + } + i8259_init(chrp_int_ack, 0); + +#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) + /* see if there is a keyboard in the device tree + with a parent of type "adb" */ + for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next) + if (kbd->parent && kbd->parent->type + && strcmp(kbd->parent->type, "adb") == 0) + break; + if (kbd) + setup_irq(HYDRA_INT_ADB_NMI, &xmon_irqaction); +#endif +} + +void __init +chrp_init2(void) +{ +#ifdef CONFIG_NVRAM + chrp_nvram_init(); +#endif + + request_region(0x20,0x20,"pic1"); + request_region(0xa0,0x20,"pic2"); + request_region(0x00,0x20,"dma1"); + request_region(0x40,0x20,"timer"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xc0,0x20,"dma2"); + + if (ppc_md.progress) + ppc_md.progress(" Have fun! ", 0x7777); +} + +static struct device_node *memory_node; + +static int __init get_mem_prop(char *name, struct mem_pieces *mp) +{ + struct reg_property *rp; + int i, s; + unsigned int *ip; + int nac = prom_n_addr_cells(memory_node); + int nsc = prom_n_size_cells(memory_node); + + ip = (unsigned int *) get_property(memory_node, name, &s); + if (ip == NULL) { + printk(KERN_ERR "error: couldn't get %s property on /memory\n", + name); + return 0; + } + s /= (nsc + nac) * 4; + rp = mp->regions; + for (i = 0; i < s; ++i, ip += nac+nsc) { + if (nac >= 2 && ip[nac-2] != 0) + continue; + rp->address = ip[nac-1]; + if (nsc >= 2 && ip[nac+nsc-2] != 0) + rp->size = ~0U; + else + rp->size = ip[nac+nsc-1]; + ++rp; + } + mp->n_regions = rp - mp->regions; + + /* Make sure the pieces are sorted. */ + mem_pieces_sort(mp); + mem_pieces_coalesce(mp); + return 1; +} + +static unsigned long __init chrp_find_end_of_memory(void) +{ + unsigned long a, total; + struct mem_pieces phys_mem; + + /* + * Find out where physical memory is, and check that it + * starts at 0 and is contiguous. It seems that RAM is + * always physically contiguous on Power Macintoshes. + * + * Supporting discontiguous physical memory isn't hard, + * it just makes the virtual <-> physical mapping functions + * more complicated (or else you end up wasting space + * in mem_map). + */ + memory_node = find_devices("memory"); + if (memory_node == NULL || !get_mem_prop("reg", &phys_mem) + || phys_mem.n_regions == 0) + panic("No RAM??"); + a = phys_mem.regions[0].address; + if (a != 0) + panic("RAM doesn't start at physical address 0"); + total = phys_mem.regions[0].size; + + if (phys_mem.n_regions > 1) { + printk("RAM starting at 0x%x is not contiguous\n", + phys_mem.regions[1].address); + printk("Using RAM from 0 to 0x%lx\n", total-1); + } + + return total; +} + +void __init +chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + struct device_node *root = find_path_device ("/"); + char *machine = NULL; + +#ifdef CONFIG_BLK_DEV_INITRD + /* take care of initrd if we have one */ + if ( r6 ) + { + initrd_start = r6 + KERNELBASE; + initrd_end = r6 + r7 + KERNELBASE; + } +#endif /* CONFIG_BLK_DEV_INITRD */ + + ISA_DMA_THRESHOLD = ~0L; + DMA_MODE_READ = 0x44; + DMA_MODE_WRITE = 0x48; + isa_io_base = CHRP_ISA_IO_BASE; /* default value */ + ppc_do_canonicalize_irqs = 1; + + if (root) + machine = get_property(root, "model", NULL); + if (machine && strncmp(machine, "Pegasos", 7) == 0) { + _chrp_type = _CHRP_Pegasos; + } else if (machine && strncmp(machine, "IBM", 3) == 0) { + _chrp_type = _CHRP_IBM; + } else if (machine && strncmp(machine, "MOT", 3) == 0) { + _chrp_type = _CHRP_Motorola; + } else { + /* Let's assume it is an IBM chrp if all else fails */ + _chrp_type = _CHRP_IBM; + } + + ppc_md.setup_arch = chrp_setup_arch; + ppc_md.show_percpuinfo = of_show_percpuinfo; + ppc_md.show_cpuinfo = chrp_show_cpuinfo; + + ppc_md.init_IRQ = chrp_init_IRQ; + if (_chrp_type == _CHRP_Pegasos) + ppc_md.get_irq = i8259_irq; + else + ppc_md.get_irq = openpic_get_irq; + + ppc_md.init = chrp_init2; + + ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; + + ppc_md.restart = chrp_restart; + ppc_md.power_off = chrp_power_off; + ppc_md.halt = chrp_halt; + + ppc_md.time_init = chrp_time_init; + ppc_md.set_rtc_time = chrp_set_rtc_time; + ppc_md.get_rtc_time = chrp_get_rtc_time; + ppc_md.calibrate_decr = chrp_calibrate_decr; + + ppc_md.find_end_of_memory = chrp_find_end_of_memory; + + if (rtas_data) { + struct device_node *rtas; + unsigned int *p; + + rtas = find_devices("rtas"); + if (rtas != NULL) { + if (get_property(rtas, "display-character", NULL)) { + ppc_md.progress = rtas_display_progress; + p = (unsigned int *) get_property + (rtas, "ibm,display-line-length", NULL); + if (p) + max_width = *p; + } else if (get_property(rtas, "set-indicator", NULL)) + ppc_md.progress = rtas_indicator_progress; + } + } +#ifdef CONFIG_BOOTX_TEXT + if (ppc_md.progress == NULL && boot_text_mapped) + ppc_md.progress = btext_progress; +#endif + +#ifdef CONFIG_SMP + smp_ops = &chrp_smp_ops; +#endif /* CONFIG_SMP */ + + /* + * Print the banner, then scroll down so boot progress + * can be printed. -- Cort + */ + if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0); +} + +void +rtas_display_progress(char *s, unsigned short hex) +{ + int width; + char *os = s; + + if ( call_rtas( "display-character", 1, 1, NULL, '\r' ) ) + return; + + width = max_width; + while ( *os ) + { + if ( (*os == '\n') || (*os == '\r') ) + width = max_width; + else + width--; + call_rtas( "display-character", 1, 1, NULL, *os++ ); + /* if we overwrite the screen length */ + if ( width == 0 ) + while ( (*os != 0) && (*os != '\n') && (*os != '\r') ) + os++; + } + + /*while ( width-- > 0 )*/ + call_rtas( "display-character", 1, 1, NULL, ' ' ); +} + +void +rtas_indicator_progress(char *s, unsigned short hex) +{ + call_rtas("set-indicator", 3, 1, NULL, 6, 0, hex); +} + +#ifdef CONFIG_BOOTX_TEXT +void +btext_progress(char *s, unsigned short hex) +{ + prom_print(s); + prom_print("\n"); +} +#endif /* CONFIG_BOOTX_TEXT */ diff --git a/trunk/arch/ppc/platforms/chrp_smp.c b/trunk/arch/ppc/platforms/chrp_smp.c new file mode 100644 index 000000000000..97e539557ecb --- /dev/null +++ b/trunk/arch/ppc/platforms/chrp_smp.c @@ -0,0 +1,99 @@ +/* + * Smp support for CHRP machines. + * + * Written by Cort Dougan (cort@cs.nmt.edu) borrowing a great + * deal of code from the sparc and intel versions. + * + * Copyright (C) 1999 Cort Dougan + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern unsigned long smp_chrp_cpu_nr; + +static int __init +smp_chrp_probe(void) +{ + if (smp_chrp_cpu_nr > 1) + openpic_request_IPIs(); + + return smp_chrp_cpu_nr; +} + +static void __devinit +smp_chrp_kick_cpu(int nr) +{ + *(unsigned long *)KERNELBASE = nr; + asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory"); +} + +static void __devinit +smp_chrp_setup_cpu(int cpu_nr) +{ + if (OpenPIC_Addr) + do_openpic_setup_cpu(); +} + +static DEFINE_SPINLOCK(timebase_lock); +static unsigned int timebase_upper = 0, timebase_lower = 0; + +void __devinit +smp_chrp_give_timebase(void) +{ + spin_lock(&timebase_lock); + call_rtas("freeze-time-base", 0, 1, NULL); + timebase_upper = get_tbu(); + timebase_lower = get_tbl(); + spin_unlock(&timebase_lock); + + while (timebase_upper || timebase_lower) + barrier(); + call_rtas("thaw-time-base", 0, 1, NULL); +} + +void __devinit +smp_chrp_take_timebase(void) +{ + while (!(timebase_upper || timebase_lower)) + barrier(); + spin_lock(&timebase_lock); + set_tb(timebase_upper, timebase_lower); + timebase_upper = 0; + timebase_lower = 0; + spin_unlock(&timebase_lock); + printk("CPU %i taken timebase\n", smp_processor_id()); +} + +/* CHRP with openpic */ +struct smp_ops_t chrp_smp_ops = { + .message_pass = smp_openpic_message_pass, + .probe = smp_chrp_probe, + .kick_cpu = smp_chrp_kick_cpu, + .setup_cpu = smp_chrp_setup_cpu, + .give_timebase = smp_chrp_give_timebase, + .take_timebase = smp_chrp_take_timebase, +}; diff --git a/trunk/arch/ppc/platforms/chrp_time.c b/trunk/arch/ppc/platforms/chrp_time.c new file mode 100644 index 000000000000..51e06ad66168 --- /dev/null +++ b/trunk/arch/ppc/platforms/chrp_time.c @@ -0,0 +1,235 @@ +/* + * Copyright (C) 1991, 1992, 1995 Linus Torvalds + * + * Adapted for PowerPC (PReP) by Gary Thomas + * Modified by Cort Dougan (cort@cs.nmt.edu). + * Copied and modified from arch/i386/kernel/time.c + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +extern spinlock_t rtc_lock; + +static int nvram_as1 = NVRAM_AS1; +static int nvram_as0 = NVRAM_AS0; +static int nvram_data = NVRAM_DATA; + +long __init chrp_time_init(void) +{ + struct device_node *rtcs; + int base; + + rtcs = find_compatible_devices("rtc", "pnpPNP,b00"); + if (rtcs == NULL) + rtcs = find_compatible_devices("rtc", "ds1385-rtc"); + if (rtcs == NULL || rtcs->addrs == NULL) + return 0; + base = rtcs->addrs[0].address; + nvram_as1 = 0; + nvram_as0 = base; + nvram_data = base + 1; + + return 0; +} + +int chrp_cmos_clock_read(int addr) +{ + if (nvram_as1 != 0) + outb(addr>>8, nvram_as1); + outb(addr, nvram_as0); + return (inb(nvram_data)); +} + +void chrp_cmos_clock_write(unsigned long val, int addr) +{ + if (nvram_as1 != 0) + outb(addr>>8, nvram_as1); + outb(addr, nvram_as0); + outb(val, nvram_data); + return; +} + +/* + * Set the hardware clock. -- Cort + */ +int chrp_set_rtc_time(unsigned long nowtime) +{ + unsigned char save_control, save_freq_select; + struct rtc_time tm; + + spin_lock(&rtc_lock); + to_tm(nowtime, &tm); + + save_control = chrp_cmos_clock_read(RTC_CONTROL); /* tell the clock it's being set */ + + chrp_cmos_clock_write((save_control|RTC_SET), RTC_CONTROL); + + save_freq_select = chrp_cmos_clock_read(RTC_FREQ_SELECT); /* stop and reset prescaler */ + + chrp_cmos_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); + + tm.tm_year -= 1900; + if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BIN_TO_BCD(tm.tm_sec); + BIN_TO_BCD(tm.tm_min); + BIN_TO_BCD(tm.tm_hour); + BIN_TO_BCD(tm.tm_mon); + BIN_TO_BCD(tm.tm_mday); + BIN_TO_BCD(tm.tm_year); + } + chrp_cmos_clock_write(tm.tm_sec,RTC_SECONDS); + chrp_cmos_clock_write(tm.tm_min,RTC_MINUTES); + chrp_cmos_clock_write(tm.tm_hour,RTC_HOURS); + chrp_cmos_clock_write(tm.tm_mon,RTC_MONTH); + chrp_cmos_clock_write(tm.tm_mday,RTC_DAY_OF_MONTH); + chrp_cmos_clock_write(tm.tm_year,RTC_YEAR); + + /* The following flags have to be released exactly in this order, + * otherwise the DS12887 (popular MC146818A clone with integrated + * battery and quartz) will not reset the oscillator and will not + * update precisely 500 ms later. You won't find this mentioned in + * the Dallas Semiconductor data sheets, but who believes data + * sheets anyway ... -- Markus Kuhn + */ + chrp_cmos_clock_write(save_control, RTC_CONTROL); + chrp_cmos_clock_write(save_freq_select, RTC_FREQ_SELECT); + + spin_unlock(&rtc_lock); + return 0; +} + +unsigned long chrp_get_rtc_time(void) +{ + unsigned int year, mon, day, hour, min, sec; + + do { + sec = chrp_cmos_clock_read(RTC_SECONDS); + min = chrp_cmos_clock_read(RTC_MINUTES); + hour = chrp_cmos_clock_read(RTC_HOURS); + day = chrp_cmos_clock_read(RTC_DAY_OF_MONTH); + mon = chrp_cmos_clock_read(RTC_MONTH); + year = chrp_cmos_clock_read(RTC_YEAR); + } while (sec != chrp_cmos_clock_read(RTC_SECONDS)); + + if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) + || RTC_ALWAYS_BCD) { + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + } + + year += 1900; + if (year < 1970) + year += 100; + return mktime(year, mon, day, hour, min, sec); +} + +/* + * Calibrate the decrementer frequency with the VIA timer 1. + */ +#define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */ + +/* VIA registers */ +#define RS 0x200 /* skip between registers */ +#define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */ +#define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */ +#define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */ +#define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */ +#define ACR (11*RS) /* Auxiliary control register */ +#define IFR (13*RS) /* Interrupt flag register */ + +/* Bits in ACR */ +#define T1MODE 0xc0 /* Timer 1 mode */ +#define T1MODE_CONT 0x40 /* continuous interrupts */ + +/* Bits in IFR and IER */ +#define T1_INT 0x40 /* Timer 1 interrupt */ + +static int __init chrp_via_calibrate_decr(void) +{ + struct device_node *vias; + volatile unsigned char __iomem *via; + int count = VIA_TIMER_FREQ_6 / 100; + unsigned int dstart, dend; + + vias = find_devices("via-cuda"); + if (vias == 0) + vias = find_devices("via"); + if (vias == 0 || vias->n_addrs == 0) + return 0; + via = ioremap(vias->addrs[0].address, vias->addrs[0].size); + + /* set timer 1 for continuous interrupts */ + out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT); + /* set the counter to a small value */ + out_8(&via[T1CH], 2); + /* set the latch to `count' */ + out_8(&via[T1LL], count); + out_8(&via[T1LH], count >> 8); + /* wait until it hits 0 */ + while ((in_8(&via[IFR]) & T1_INT) == 0) + ; + dstart = get_dec(); + /* clear the interrupt & wait until it hits 0 again */ + in_8(&via[T1CL]); + while ((in_8(&via[IFR]) & T1_INT) == 0) + ; + dend = get_dec(); + + tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100); + tb_to_us = mulhwu_scale_factor(dstart - dend, 60000); + + printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n", + tb_ticks_per_jiffy, dstart - dend); + + iounmap(via); + + return 1; +} + +void __init chrp_calibrate_decr(void) +{ + struct device_node *cpu; + unsigned int freq, *fp; + + if (chrp_via_calibrate_decr()) + return; + + /* + * The cpu node should have a timebase-frequency property + * to tell us the rate at which the decrementer counts. + */ + freq = 16666000; /* hardcoded default */ + cpu = find_type_devices("cpu"); + if (cpu != 0) { + fp = (unsigned int *) + get_property(cpu, "timebase-frequency", NULL); + if (fp != 0) + freq = *fp; + } + printk("time_init: decrementer frequency = %u.%.6u MHz\n", + freq/1000000, freq%1000000); + tb_ticks_per_jiffy = freq / HZ; + tb_to_us = mulhwu_scale_factor(freq, 1000000); +} diff --git a/trunk/arch/ppc/platforms/lite5200.c b/trunk/arch/ppc/platforms/lite5200.c index fecbe9adc9e0..5171b53bccb5 100644 --- a/trunk/arch/ppc/platforms/lite5200.c +++ b/trunk/arch/ppc/platforms/lite5200.c @@ -34,7 +34,8 @@ #include #include #include -#include + +#include extern int powersave_nap; @@ -67,53 +68,44 @@ lite5200_show_cpuinfo(struct seq_file *m) } #ifdef CONFIG_PCI -#ifdef CONFIG_LITE5200B -static int -lite5200_map_irq(struct pci_dev *dev, unsigned char idsel, - unsigned char pin) -{ - static char pci_irq_table[][4] = - /* - * PCI IDSEL/INTPIN->INTLINE - * A B C D - */ - { - {MPC52xx_IRQ0, MPC52xx_IRQ1, MPC52xx_IRQ2, MPC52xx_IRQ3}, - {MPC52xx_IRQ1, MPC52xx_IRQ2, MPC52xx_IRQ3, MPC52xx_IRQ0}, - }; - - const long min_idsel = 24, max_idsel = 25, irqs_per_slot = 4; - return PCI_IRQ_TABLE_LOOKUP; -} -#else /* Original Lite */ static int lite5200_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) { return (pin == 1) && (idsel==24) ? MPC52xx_IRQ0 : -1; } #endif -#endif static void __init lite5200_setup_cpu(void) { + struct mpc52xx_cdm __iomem *cdm; struct mpc52xx_gpio __iomem *gpio; struct mpc52xx_intr __iomem *intr; + struct mpc52xx_xlb __iomem *xlb; u32 port_config; u32 intr_ctrl; /* Map zones */ + cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE); gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE); + xlb = ioremap(MPC52xx_PA(MPC52xx_XLB_OFFSET), MPC52xx_XLB_SIZE); intr = ioremap(MPC52xx_PA(MPC52xx_INTR_OFFSET), MPC52xx_INTR_SIZE); - if (!gpio || !intr) { - printk(KERN_ERR __FILE__ ": " - "Error while mapping GPIO/INTR during " - "lite5200_setup_cpu\n"); + if (!cdm || !gpio || !xlb || !intr) { + printk("lite5200.c: Error while mapping CDM/GPIO/XLB/INTR during" + "lite5200_setup_cpu\n"); goto unmap_regs; } + /* Use internal 48 Mhz */ + out_8(&cdm->ext_48mhz_en, 0x00); + out_8(&cdm->fd_enable, 0x01); + if (in_be32(&cdm->rstcfg) & 0x40) /* Assumes 33Mhz clock */ + out_be16(&cdm->fd_counters, 0x0001); + else + out_be16(&cdm->fd_counters, 0x5555); + /* Get port mux config */ port_config = in_be32(&gpio->port_config); @@ -124,29 +116,29 @@ lite5200_setup_cpu(void) port_config &= ~0x00007000; /* Differential mode - USB1 only */ port_config |= 0x00001000; - /* ATA CS is on csb_4/5 */ - port_config &= ~0x03000000; - port_config |= 0x01000000; - /* Commit port config */ out_be32(&gpio->port_config, port_config); - /* IRQ[0-3] setup */ + /* Configure the XLB Arbiter */ + out_be32(&xlb->master_pri_enable, 0xff); + out_be32(&xlb->master_priority, 0x11111111); + + /* Enable ram snooping for 1GB window */ + out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_SNOOP); + out_be32(&xlb->snoop_window, MPC52xx_PCI_TARGET_MEM | 0x1d); + + /* IRQ[0-3] setup : IRQ0 - Level Active Low */ + /* IRQ[1-3] - Level Active High */ intr_ctrl = in_be32(&intr->ctrl); intr_ctrl &= ~0x00ff0000; -#ifdef CONFIG_LITE5200B - /* IRQ[0-3] Level Active Low */ - intr_ctrl |= 0x00ff0000; -#else - /* IRQ0 Level Active Low - * IRQ[1-3] Level Active High */ - intr_ctrl |= 0x00c00000; -#endif + intr_ctrl |= 0x00c00000; out_be32(&intr->ctrl, intr_ctrl); /* Unmap reg zone */ unmap_regs: + if (cdm) iounmap(cdm); if (gpio) iounmap(gpio); + if (xlb) iounmap(xlb); if (intr) iounmap(intr); } @@ -154,8 +146,7 @@ static void __init lite5200_setup_arch(void) { /* CPU & Port mux setup */ - mpc52xx_setup_cpu(); /* Generic */ - lite5200_setup_cpu(); /* Platform specific */ + lite5200_setup_cpu(); #ifdef CONFIG_PCI /* PCI Bridge setup */ diff --git a/trunk/arch/ppc/platforms/prep_setup.c b/trunk/arch/ppc/platforms/prep_setup.c index e86f6156d589..d95c05d9824d 100644 --- a/trunk/arch/ppc/platforms/prep_setup.c +++ b/trunk/arch/ppc/platforms/prep_setup.c @@ -1067,13 +1067,15 @@ prep_map_io(void) static int __init prep_request_io(void) { + if (_machine == _MACH_prep) { #ifdef CONFIG_NVRAM - request_region(PREP_NVRAM_AS0, 0x8, "nvram"); + request_region(PREP_NVRAM_AS0, 0x8, "nvram"); #endif - request_region(0x00,0x20,"dma1"); - request_region(0x40,0x20,"timer"); - request_region(0x80,0x10,"dma page reg"); - request_region(0xc0,0x20,"dma2"); + request_region(0x00,0x20,"dma1"); + request_region(0x40,0x20,"timer"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xc0,0x20,"dma2"); + } return 0; } diff --git a/trunk/arch/ppc/syslib/Makefile b/trunk/arch/ppc/syslib/Makefile index 490749ca88f9..5cb62c6a51c8 100644 --- a/trunk/arch/ppc/syslib/Makefile +++ b/trunk/arch/ppc/syslib/Makefile @@ -38,6 +38,8 @@ endif obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \ ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o obj-$(CONFIG_PCI_QSPAN) += qspan_pci.o +obj-$(CONFIG_PPC_OF) += prom_init.o prom.o +obj-$(CONFIG_PPC_CHRP) += open_pic.o obj-$(CONFIG_PPC_PREP) += open_pic.o todc_time.o obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o obj-$(CONFIG_CPCI690) += todc_time.o pci_auto.o diff --git a/trunk/arch/ppc/syslib/mpc52xx_pci.c b/trunk/arch/ppc/syslib/mpc52xx_pci.c index 5a5a7a9cd248..9ec525f9fe98 100644 --- a/trunk/arch/ppc/syslib/mpc52xx_pci.c +++ b/trunk/arch/ppc/syslib/mpc52xx_pci.c @@ -225,8 +225,7 @@ mpc52xx_pci_fixup_resources(struct pci_dev *dev) /* The PCI Host bridge of MPC52xx has a prefetch memory resource fixed to 1Gb. Doesn't fit in the resource system so we remove it */ if ( (dev->vendor == PCI_VENDOR_ID_MOTOROLA) && - ( dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200 - || dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200B) ) { + (dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200) ) { struct resource *res = &dev->resource[1]; res->start = res->end = res->flags = 0; } diff --git a/trunk/arch/ppc/syslib/mpc52xx_setup.c b/trunk/arch/ppc/syslib/mpc52xx_setup.c index ee6379bb415e..2ee48ce0a517 100644 --- a/trunk/arch/ppc/syslib/mpc52xx_setup.c +++ b/trunk/arch/ppc/syslib/mpc52xx_setup.c @@ -24,8 +24,6 @@ #include #include -#include - extern bd_t __res; static int core_mult[] = { /* CPU Frequency multiplier, taken */ @@ -218,52 +216,6 @@ mpc52xx_calibrate_decr(void) tb_to_us = mulhwu_scale_factor(xlbfreq / divisor, 1000000); } - -void __init -mpc52xx_setup_cpu(void) -{ - struct mpc52xx_cdm __iomem *cdm; - struct mpc52xx_xlb __iomem *xlb; - - /* Map zones */ - cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE); - xlb = ioremap(MPC52xx_PA(MPC52xx_XLB_OFFSET), MPC52xx_XLB_SIZE); - - if (!cdm || !xlb) { - printk(KERN_ERR __FILE__ ": " - "Error while mapping CDM/XLB during " - "mpc52xx_setup_cpu\n"); - goto unmap_regs; - } - - /* Use internal 48 Mhz */ - out_8(&cdm->ext_48mhz_en, 0x00); - out_8(&cdm->fd_enable, 0x01); - if (in_be32(&cdm->rstcfg) & 0x40) /* Assumes 33Mhz clock */ - out_be16(&cdm->fd_counters, 0x0001); - else - out_be16(&cdm->fd_counters, 0x5555); - - /* Configure the XLB Arbiter priorities */ - out_be32(&xlb->master_pri_enable, 0xff); - out_be32(&xlb->master_priority, 0x11111111); - - /* Enable ram snooping for 1GB window */ - out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_SNOOP); - out_be32(&xlb->snoop_window, MPC52xx_PCI_TARGET_MEM | 0x1d); - - /* Disable XLB pipelining */ - /* (cfr errate 292. We could do this only just before ATA PIO - transaction and re-enable it after ...) */ - out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS); - - /* Unmap reg zone */ -unmap_regs: - if (cdm) iounmap(cdm); - if (xlb) iounmap(xlb); -} - - int mpc52xx_match_psc_function(int psc_idx, const char *func) { struct mpc52xx_psc_func *cf = mpc52xx_psc_functions; diff --git a/trunk/arch/ppc/syslib/open_pic.c b/trunk/arch/ppc/syslib/open_pic.c index 70456c8f998c..38e5b93fbe41 100644 --- a/trunk/arch/ppc/syslib/open_pic.c +++ b/trunk/arch/ppc/syslib/open_pic.c @@ -216,7 +216,7 @@ static void openpic_safe_writefield(volatile u_int __iomem *addr, u_int mask, u_int openpic_read_IPI(volatile u_int __iomem * addr) { u_int val = 0; -#if defined(OPENPIC_BIG_ENDIAN) +#if defined(OPENPIC_BIG_ENDIAN) || defined(CONFIG_POWER3) val = in_be32(addr); #else val = in_le32(addr); diff --git a/trunk/arch/ppc/syslib/prom.c b/trunk/arch/ppc/syslib/prom.c new file mode 100644 index 000000000000..482f837fd373 --- /dev/null +++ b/trunk/arch/ppc/syslib/prom.c @@ -0,0 +1,1429 @@ +/* + * Procedures for interfacing to the Open Firmware PROM on + * Power Macintosh computers. + * + * In particular, we are interested in the device tree + * and in using some of its services (exit, write to stdout). + * + * Paul Mackerras August 1996. + * Copyright (C) 1996 Paul Mackerras. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +struct pci_address { + unsigned a_hi; + unsigned a_mid; + unsigned a_lo; +}; + +struct pci_reg_property { + struct pci_address addr; + unsigned size_hi; + unsigned size_lo; +}; + +struct isa_reg_property { + unsigned space; + unsigned address; + unsigned size; +}; + +typedef unsigned long interpret_func(struct device_node *, unsigned long, + int, int); +static interpret_func interpret_pci_props; +static interpret_func interpret_dbdma_props; +static interpret_func interpret_isa_props; +static interpret_func interpret_macio_props; +static interpret_func interpret_root_props; + +extern char *klimit; + +/* Set for a newworld or CHRP machine */ +int use_of_interrupt_tree; +struct device_node *dflt_interrupt_controller; +int num_interrupt_controllers; + +extern unsigned int rtas_entry; /* physical pointer */ + +extern struct device_node *allnodes; + +static unsigned long finish_node(struct device_node *, unsigned long, + interpret_func *, int, int); +static unsigned long finish_node_interrupts(struct device_node *, unsigned long); +static struct device_node *find_phandle(phandle); + +extern void enter_rtas(void *); +void phys_call_rtas(int, int, int, ...); + +extern char cmd_line[512]; /* XXX */ +extern boot_infos_t *boot_infos; +unsigned long dev_tree_size; + +void +phys_call_rtas(int service, int nargs, int nret, ...) +{ + va_list list; + union { + unsigned long words[16]; + double align; + } u; + void (*rtas)(void *, unsigned long); + int i; + + u.words[0] = service; + u.words[1] = nargs; + u.words[2] = nret; + va_start(list, nret); + for (i = 0; i < nargs; ++i) + u.words[i+3] = va_arg(list, unsigned long); + va_end(list); + + rtas = (void (*)(void *, unsigned long)) rtas_entry; + rtas(&u, rtas_data); +} + +/* + * finish_device_tree is called once things are running normally + * (i.e. with text and data mapped to the address they were linked at). + * It traverses the device tree and fills in the name, type, + * {n_}addrs and {n_}intrs fields of each node. + */ +void __init +finish_device_tree(void) +{ + unsigned long mem = (unsigned long) klimit; + struct device_node *np; + + /* All CHRPs now use the interrupt tree */ + for (np = allnodes; np != NULL; np = np->allnext) { + if (get_property(np, "interrupt-parent", NULL)) { + use_of_interrupt_tree = 1; + break; + } + } + + if (use_of_interrupt_tree) { + /* + * We want to find out here how many interrupt-controller + * nodes there are, and if we are booted from BootX, + * we need a pointer to the first (and hopefully only) + * such node. But we can't use find_devices here since + * np->name has not been set yet. -- paulus + */ + int n = 0; + char *name, *ic; + int iclen; + + for (np = allnodes; np != NULL; np = np->allnext) { + ic = get_property(np, "interrupt-controller", &iclen); + name = get_property(np, "name", NULL); + /* checking iclen makes sure we don't get a false + match on /chosen.interrupt_controller */ + if ((name != NULL + && strcmp(name, "interrupt-controller") == 0) + || (ic != NULL && iclen == 0 && strcmp(name, "AppleKiwi"))) { + if (n == 0) + dflt_interrupt_controller = np; + ++n; + } + } + num_interrupt_controllers = n; + } + + mem = finish_node(allnodes, mem, NULL, 1, 1); + dev_tree_size = mem - (unsigned long) allnodes; + klimit = (char *) mem; +} + +static unsigned long __init +finish_node(struct device_node *np, unsigned long mem_start, + interpret_func *ifunc, int naddrc, int nsizec) +{ + struct device_node *child; + int *ip; + + np->name = get_property(np, "name", NULL); + np->type = get_property(np, "device_type", NULL); + + if (!np->name) + np->name = ""; + if (!np->type) + np->type = ""; + + /* get the device addresses and interrupts */ + if (ifunc != NULL) + mem_start = ifunc(np, mem_start, naddrc, nsizec); + + if (use_of_interrupt_tree) + mem_start = finish_node_interrupts(np, mem_start); + + /* Look for #address-cells and #size-cells properties. */ + ip = (int *) get_property(np, "#address-cells", NULL); + if (ip != NULL) + naddrc = *ip; + ip = (int *) get_property(np, "#size-cells", NULL); + if (ip != NULL) + nsizec = *ip; + + if (np->parent == NULL) + ifunc = interpret_root_props; + else if (np->type == 0) + ifunc = NULL; + else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci")) + ifunc = interpret_pci_props; + else if (!strcmp(np->type, "dbdma")) + ifunc = interpret_dbdma_props; + else if (!strcmp(np->type, "mac-io") + || ifunc == interpret_macio_props) + ifunc = interpret_macio_props; + else if (!strcmp(np->type, "isa")) + ifunc = interpret_isa_props; + else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3")) + ifunc = interpret_root_props; + else if (!((ifunc == interpret_dbdma_props + || ifunc == interpret_macio_props) + && (!strcmp(np->type, "escc") + || !strcmp(np->type, "media-bay")))) + ifunc = NULL; + + /* if we were booted from BootX, convert the full name */ + if (boot_infos + && strncmp(np->full_name, "Devices:device-tree", 19) == 0) { + if (np->full_name[19] == 0) { + strcpy(np->full_name, "/"); + } else if (np->full_name[19] == ':') { + char *p = np->full_name + 19; + np->full_name = p; + for (; *p; ++p) + if (*p == ':') + *p = '/'; + } + } + + for (child = np->child; child != NULL; child = child->sibling) + mem_start = finish_node(child, mem_start, ifunc, + naddrc, nsizec); + + return mem_start; +} + +/* + * Find the interrupt parent of a node. + */ +static struct device_node * __init +intr_parent(struct device_node *p) +{ + phandle *parp; + + parp = (phandle *) get_property(p, "interrupt-parent", NULL); + if (parp == NULL) + return p->parent; + p = find_phandle(*parp); + if (p != NULL) + return p; + /* + * On a powermac booted with BootX, we don't get to know the + * phandles for any nodes, so find_phandle will return NULL. + * Fortunately these machines only have one interrupt controller + * so there isn't in fact any ambiguity. -- paulus + */ + if (num_interrupt_controllers == 1) + p = dflt_interrupt_controller; + return p; +} + +/* + * Find out the size of each entry of the interrupts property + * for a node. + */ +static int __init +prom_n_intr_cells(struct device_node *np) +{ + struct device_node *p; + unsigned int *icp; + + for (p = np; (p = intr_parent(p)) != NULL; ) { + icp = (unsigned int *) + get_property(p, "#interrupt-cells", NULL); + if (icp != NULL) + return *icp; + if (get_property(p, "interrupt-controller", NULL) != NULL + || get_property(p, "interrupt-map", NULL) != NULL) { + printk("oops, node %s doesn't have #interrupt-cells\n", + p->full_name); + return 1; + } + } + printk("prom_n_intr_cells failed for %s\n", np->full_name); + return 1; +} + +/* + * Map an interrupt from a device up to the platform interrupt + * descriptor. + */ +static int __init +map_interrupt(unsigned int **irq, struct device_node **ictrler, + struct device_node *np, unsigned int *ints, int nintrc) +{ + struct device_node *p, *ipar; + unsigned int *imap, *imask, *ip; + int i, imaplen, match; + int newintrc = 1, newaddrc = 1; + unsigned int *reg; + int naddrc; + + reg = (unsigned int *) get_property(np, "reg", NULL); + naddrc = prom_n_addr_cells(np); + p = intr_parent(np); + while (p != NULL) { + if (get_property(p, "interrupt-controller", NULL) != NULL) + /* this node is an interrupt controller, stop here */ + break; + imap = (unsigned int *) + get_property(p, "interrupt-map", &imaplen); + if (imap == NULL) { + p = intr_parent(p); + continue; + } + imask = (unsigned int *) + get_property(p, "interrupt-map-mask", NULL); + if (imask == NULL) { + printk("oops, %s has interrupt-map but no mask\n", + p->full_name); + return 0; + } + imaplen /= sizeof(unsigned int); + match = 0; + ipar = NULL; + while (imaplen > 0 && !match) { + /* check the child-interrupt field */ + match = 1; + for (i = 0; i < naddrc && match; ++i) + match = ((reg[i] ^ imap[i]) & imask[i]) == 0; + for (; i < naddrc + nintrc && match; ++i) + match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0; + imap += naddrc + nintrc; + imaplen -= naddrc + nintrc; + /* grab the interrupt parent */ + ipar = find_phandle((phandle) *imap++); + --imaplen; + if (ipar == NULL && num_interrupt_controllers == 1) + /* cope with BootX not giving us phandles */ + ipar = dflt_interrupt_controller; + if (ipar == NULL) { + printk("oops, no int parent %x in map of %s\n", + imap[-1], p->full_name); + return 0; + } + /* find the parent's # addr and intr cells */ + ip = (unsigned int *) + get_property(ipar, "#interrupt-cells", NULL); + if (ip == NULL) { + printk("oops, no #interrupt-cells on %s\n", + ipar->full_name); + return 0; + } + newintrc = *ip; + ip = (unsigned int *) + get_property(ipar, "#address-cells", NULL); + newaddrc = (ip == NULL)? 0: *ip; + imap += newaddrc + newintrc; + imaplen -= newaddrc + newintrc; + } + if (imaplen < 0) { + printk("oops, error decoding int-map on %s, len=%d\n", + p->full_name, imaplen); + return 0; + } + if (!match) { + printk("oops, no match in %s int-map for %s\n", + p->full_name, np->full_name); + return 0; + } + p = ipar; + naddrc = newaddrc; + nintrc = newintrc; + ints = imap - nintrc; + reg = ints - naddrc; + } + if (p == NULL) + printk("hmmm, int tree for %s doesn't have ctrler\n", + np->full_name); + *irq = ints; + *ictrler = p; + return nintrc; +} + +/* + * New version of finish_node_interrupts. + */ +static unsigned long __init +finish_node_interrupts(struct device_node *np, unsigned long mem_start) +{ + unsigned int *ints; + int intlen, intrcells; + int i, j, n, offset; + unsigned int *irq; + struct device_node *ic; + + ints = (unsigned int *) get_property(np, "interrupts", &intlen); + if (ints == NULL) + return mem_start; + intrcells = prom_n_intr_cells(np); + intlen /= intrcells * sizeof(unsigned int); + np->n_intrs = intlen; + np->intrs = (struct interrupt_info *) mem_start; + mem_start += intlen * sizeof(struct interrupt_info); + + for (i = 0; i < intlen; ++i) { + np->intrs[i].line = 0; + np->intrs[i].sense = 1; + n = map_interrupt(&irq, &ic, np, ints, intrcells); + if (n <= 0) + continue; + offset = 0; + /* + * On a CHRP we have an 8259 which is subordinate to + * the openpic in the interrupt tree, but we want the + * openpic's interrupt numbers offsetted, not the 8259's. + * So we apply the offset if the controller is at the + * root of the interrupt tree, i.e. has no interrupt-parent. + * This doesn't cope with the general case of multiple + * cascaded interrupt controllers, but then neither will + * irq.c at the moment either. -- paulus + * The G5 triggers that code, I add a machine test. On + * those machines, we want to offset interrupts from the + * second openpic by 128 -- BenH + */ + if (num_interrupt_controllers > 1 + && ic != NULL + && get_property(ic, "interrupt-parent", NULL) == NULL) + offset = 16; + + np->intrs[i].line = irq[0] + offset; + if (n > 1) + np->intrs[i].sense = irq[1]; + if (n > 2) { + printk("hmmm, got %d intr cells for %s:", n, + np->full_name); + for (j = 0; j < n; ++j) + printk(" %d", irq[j]); + printk("\n"); + } + ints += intrcells; + } + + return mem_start; +} + +/* + * When BootX makes a copy of the device tree from the MacOS + * Name Registry, it is in the format we use but all of the pointers + * are offsets from the start of the tree. + * This procedure updates the pointers. + */ +void __init +relocate_nodes(void) +{ + unsigned long base; + struct device_node *np; + struct property *pp; + +#define ADDBASE(x) (x = (typeof (x))((x)? ((unsigned long)(x) + base): 0)) + + base = (unsigned long) boot_infos + boot_infos->deviceTreeOffset; + allnodes = (struct device_node *)(base + 4); + for (np = allnodes; np != 0; np = np->allnext) { + ADDBASE(np->full_name); + ADDBASE(np->properties); + ADDBASE(np->parent); + ADDBASE(np->child); + ADDBASE(np->sibling); + ADDBASE(np->allnext); + for (pp = np->properties; pp != 0; pp = pp->next) { + ADDBASE(pp->name); + ADDBASE(pp->value); + ADDBASE(pp->next); + } + } +} + +int +prom_n_addr_cells(struct device_node* np) +{ + int* ip; + do { + if (np->parent) + np = np->parent; + ip = (int *) get_property(np, "#address-cells", NULL); + if (ip != NULL) + return *ip; + } while (np->parent); + /* No #address-cells property for the root node, default to 1 */ + return 1; +} + +int +prom_n_size_cells(struct device_node* np) +{ + int* ip; + do { + if (np->parent) + np = np->parent; + ip = (int *) get_property(np, "#size-cells", NULL); + if (ip != NULL) + return *ip; + } while (np->parent); + /* No #size-cells property for the root node, default to 1 */ + return 1; +} + +static unsigned long __init +map_addr(struct device_node *np, unsigned long space, unsigned long addr) +{ + int na; + unsigned int *ranges; + int rlen = 0; + unsigned int type; + + type = (space >> 24) & 3; + if (type == 0) + return addr; + + while ((np = np->parent) != NULL) { + if (strcmp(np->type, "pci") != 0) + continue; + /* PCI bridge: map the address through the ranges property */ + na = prom_n_addr_cells(np); + ranges = (unsigned int *) get_property(np, "ranges", &rlen); + while ((rlen -= (na + 5) * sizeof(unsigned int)) >= 0) { + if (((ranges[0] >> 24) & 3) == type + && ranges[2] <= addr + && addr - ranges[2] < ranges[na+4]) { + /* ok, this matches, translate it */ + addr += ranges[na+2] - ranges[2]; + break; + } + ranges += na + 5; + } + } + return addr; +} + +static unsigned long __init +interpret_pci_props(struct device_node *np, unsigned long mem_start, + int naddrc, int nsizec) +{ + struct address_range *adr; + struct pci_reg_property *pci_addrs; + int i, l, *ip; + + pci_addrs = (struct pci_reg_property *) + get_property(np, "assigned-addresses", &l); + if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) { + i = 0; + adr = (struct address_range *) mem_start; + while ((l -= sizeof(struct pci_reg_property)) >= 0) { + adr[i].space = pci_addrs[i].addr.a_hi; + adr[i].address = map_addr(np, pci_addrs[i].addr.a_hi, + pci_addrs[i].addr.a_lo); + adr[i].size = pci_addrs[i].size_lo; + ++i; + } + np->addrs = adr; + np->n_addrs = i; + mem_start += i * sizeof(struct address_range); + } + + if (use_of_interrupt_tree) + return mem_start; + + ip = (int *) get_property(np, "AAPL,interrupts", &l); + if (ip == 0 && np->parent) + ip = (int *) get_property(np->parent, "AAPL,interrupts", &l); + if (ip == 0) + ip = (int *) get_property(np, "interrupts", &l); + if (ip != 0) { + np->intrs = (struct interrupt_info *) mem_start; + np->n_intrs = l / sizeof(int); + mem_start += np->n_intrs * sizeof(struct interrupt_info); + for (i = 0; i < np->n_intrs; ++i) { + np->intrs[i].line = *ip++; + np->intrs[i].sense = 1; + } + } + + return mem_start; +} + +static unsigned long __init +interpret_dbdma_props(struct device_node *np, unsigned long mem_start, + int naddrc, int nsizec) +{ + struct reg_property *rp; + struct address_range *adr; + unsigned long base_address; + int i, l, *ip; + struct device_node *db; + + base_address = 0; + for (db = np->parent; db != NULL; db = db->parent) { + if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) { + base_address = db->addrs[0].address; + break; + } + } + + rp = (struct reg_property *) get_property(np, "reg", &l); + if (rp != 0 && l >= sizeof(struct reg_property)) { + i = 0; + adr = (struct address_range *) mem_start; + while ((l -= sizeof(struct reg_property)) >= 0) { + adr[i].space = 2; + adr[i].address = rp[i].address + base_address; + adr[i].size = rp[i].size; + ++i; + } + np->addrs = adr; + np->n_addrs = i; + mem_start += i * sizeof(struct address_range); + } + + if (use_of_interrupt_tree) + return mem_start; + + ip = (int *) get_property(np, "AAPL,interrupts", &l); + if (ip == 0) + ip = (int *) get_property(np, "interrupts", &l); + if (ip != 0) { + np->intrs = (struct interrupt_info *) mem_start; + np->n_intrs = l / sizeof(int); + mem_start += np->n_intrs * sizeof(struct interrupt_info); + for (i = 0; i < np->n_intrs; ++i) { + np->intrs[i].line = *ip++; + np->intrs[i].sense = 1; + } + } + + return mem_start; +} + +static unsigned long __init +interpret_macio_props(struct device_node *np, unsigned long mem_start, + int naddrc, int nsizec) +{ + struct reg_property *rp; + struct address_range *adr; + unsigned long base_address; + int i, l, *ip; + struct device_node *db; + + base_address = 0; + for (db = np->parent; db != NULL; db = db->parent) { + if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) { + base_address = db->addrs[0].address; + break; + } + } + + rp = (struct reg_property *) get_property(np, "reg", &l); + if (rp != 0 && l >= sizeof(struct reg_property)) { + i = 0; + adr = (struct address_range *) mem_start; + while ((l -= sizeof(struct reg_property)) >= 0) { + adr[i].space = 2; + adr[i].address = rp[i].address + base_address; + adr[i].size = rp[i].size; + ++i; + } + np->addrs = adr; + np->n_addrs = i; + mem_start += i * sizeof(struct address_range); + } + + if (use_of_interrupt_tree) + return mem_start; + + ip = (int *) get_property(np, "interrupts", &l); + if (ip == 0) + ip = (int *) get_property(np, "AAPL,interrupts", &l); + if (ip != 0) { + np->intrs = (struct interrupt_info *) mem_start; + np->n_intrs = l / sizeof(int); + for (i = 0; i < np->n_intrs; ++i) { + np->intrs[i].line = *ip++; + np->intrs[i].sense = 1; + } + mem_start += np->n_intrs * sizeof(struct interrupt_info); + } + + return mem_start; +} + +static unsigned long __init +interpret_isa_props(struct device_node *np, unsigned long mem_start, + int naddrc, int nsizec) +{ + struct isa_reg_property *rp; + struct address_range *adr; + int i, l, *ip; + + rp = (struct isa_reg_property *) get_property(np, "reg", &l); + if (rp != 0 && l >= sizeof(struct isa_reg_property)) { + i = 0; + adr = (struct address_range *) mem_start; + while ((l -= sizeof(struct reg_property)) >= 0) { + adr[i].space = rp[i].space; + adr[i].address = rp[i].address + + (adr[i].space? 0: _ISA_MEM_BASE); + adr[i].size = rp[i].size; + ++i; + } + np->addrs = adr; + np->n_addrs = i; + mem_start += i * sizeof(struct address_range); + } + + if (use_of_interrupt_tree) + return mem_start; + + ip = (int *) get_property(np, "interrupts", &l); + if (ip != 0) { + np->intrs = (struct interrupt_info *) mem_start; + np->n_intrs = l / (2 * sizeof(int)); + mem_start += np->n_intrs * sizeof(struct interrupt_info); + for (i = 0; i < np->n_intrs; ++i) { + np->intrs[i].line = *ip++; + np->intrs[i].sense = *ip++; + } + } + + return mem_start; +} + +static unsigned long __init +interpret_root_props(struct device_node *np, unsigned long mem_start, + int naddrc, int nsizec) +{ + struct address_range *adr; + int i, l, *ip; + unsigned int *rp; + int rpsize = (naddrc + nsizec) * sizeof(unsigned int); + + rp = (unsigned int *) get_property(np, "reg", &l); + if (rp != 0 && l >= rpsize) { + i = 0; + adr = (struct address_range *) mem_start; + while ((l -= rpsize) >= 0) { + adr[i].space = (naddrc >= 2? rp[naddrc-2]: 2); + adr[i].address = rp[naddrc - 1]; + adr[i].size = rp[naddrc + nsizec - 1]; + ++i; + rp += naddrc + nsizec; + } + np->addrs = adr; + np->n_addrs = i; + mem_start += i * sizeof(struct address_range); + } + + if (use_of_interrupt_tree) + return mem_start; + + ip = (int *) get_property(np, "AAPL,interrupts", &l); + if (ip == 0) + ip = (int *) get_property(np, "interrupts", &l); + if (ip != 0) { + np->intrs = (struct interrupt_info *) mem_start; + np->n_intrs = l / sizeof(int); + mem_start += np->n_intrs * sizeof(struct interrupt_info); + for (i = 0; i < np->n_intrs; ++i) { + np->intrs[i].line = *ip++; + np->intrs[i].sense = 1; + } + } + + return mem_start; +} + +/* + * Work out the sense (active-low level / active-high edge) + * of each interrupt from the device tree. + */ +void __init +prom_get_irq_senses(unsigned char *senses, int off, int max) +{ + struct device_node *np; + int i, j; + + /* default to level-triggered */ + memset(senses, 1, max - off); + if (!use_of_interrupt_tree) + return; + + for (np = allnodes; np != 0; np = np->allnext) { + for (j = 0; j < np->n_intrs; j++) { + i = np->intrs[j].line; + if (i >= off && i < max) { + if (np->intrs[j].sense == 1) + senses[i-off] = (IRQ_SENSE_LEVEL + | IRQ_POLARITY_NEGATIVE); + else + senses[i-off] = (IRQ_SENSE_EDGE + | IRQ_POLARITY_POSITIVE); + } + } + } +} + +/* + * Construct and return a list of the device_nodes with a given name. + */ +struct device_node * +find_devices(const char *name) +{ + struct device_node *head, **prevp, *np; + + prevp = &head; + for (np = allnodes; np != 0; np = np->allnext) { + if (np->name != 0 && strcasecmp(np->name, name) == 0) { + *prevp = np; + prevp = &np->next; + } + } + *prevp = NULL; + return head; +} + +/* + * Construct and return a list of the device_nodes with a given type. + */ +struct device_node * +find_type_devices(const char *type) +{ + struct device_node *head, **prevp, *np; + + prevp = &head; + for (np = allnodes; np != 0; np = np->allnext) { + if (np->type != 0 && strcasecmp(np->type, type) == 0) { + *prevp = np; + prevp = &np->next; + } + } + *prevp = NULL; + return head; +} + +/* + * Returns all nodes linked together + */ +struct device_node * +find_all_nodes(void) +{ + struct device_node *head, **prevp, *np; + + prevp = &head; + for (np = allnodes; np != 0; np = np->allnext) { + *prevp = np; + prevp = &np->next; + } + *prevp = NULL; + return head; +} + +/* Checks if the given "compat" string matches one of the strings in + * the device's "compatible" property + */ +int +device_is_compatible(struct device_node *device, const char *compat) +{ + const char* cp; + int cplen, l; + + cp = (char *) get_property(device, "compatible", &cplen); + if (cp == NULL) + return 0; + while (cplen > 0) { + if (strncasecmp(cp, compat, strlen(compat)) == 0) + return 1; + l = strlen(cp) + 1; + cp += l; + cplen -= l; + } + + return 0; +} + + +/* + * Indicates whether the root node has a given value in its + * compatible property. + */ +int +machine_is_compatible(const char *compat) +{ + struct device_node *root; + + root = find_path_device("/"); + if (root == 0) + return 0; + return device_is_compatible(root, compat); +} + +/* + * Construct and return a list of the device_nodes with a given type + * and compatible property. + */ +struct device_node * +find_compatible_devices(const char *type, const char *compat) +{ + struct device_node *head, **prevp, *np; + + prevp = &head; + for (np = allnodes; np != 0; np = np->allnext) { + if (type != NULL + && !(np->type != 0 && strcasecmp(np->type, type) == 0)) + continue; + if (device_is_compatible(np, compat)) { + *prevp = np; + prevp = &np->next; + } + } + *prevp = NULL; + return head; +} + +/* + * Find the device_node with a given full_name. + */ +struct device_node * +find_path_device(const char *path) +{ + struct device_node *np; + + for (np = allnodes; np != 0; np = np->allnext) + if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0) + return np; + return NULL; +} + +/******* + * + * New implementation of the OF "find" APIs, return a refcounted + * object, call of_node_put() when done. Currently, still lacks + * locking as old implementation, this is beeing done for ppc64. + * + * Note that property management will need some locking as well, + * this isn't dealt with yet + * + *******/ + +/** + * of_find_node_by_name - Find a node by it's "name" property + * @from: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @name: The name string to match against + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_by_name(struct device_node *from, + const char *name) +{ + struct device_node *np = from ? from->allnext : allnodes; + + for (; np != 0; np = np->allnext) + if (np->name != 0 && strcasecmp(np->name, name) == 0) + break; + if (from) + of_node_put(from); + return of_node_get(np); +} + +/** + * of_find_node_by_type - Find a node by it's "device_type" property + * @from: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @name: The type string to match against + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_by_type(struct device_node *from, + const char *type) +{ + struct device_node *np = from ? from->allnext : allnodes; + + for (; np != 0; np = np->allnext) + if (np->type != 0 && strcasecmp(np->type, type) == 0) + break; + if (from) + of_node_put(from); + return of_node_get(np); +} + +/** + * of_find_compatible_node - Find a node based on type and one of the + * tokens in it's "compatible" property + * @from: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @type: The type string to match "device_type" or NULL to ignore + * @compatible: The string to match to one of the tokens in the device + * "compatible" list. + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_compatible_node(struct device_node *from, + const char *type, const char *compatible) +{ + struct device_node *np = from ? from->allnext : allnodes; + + for (; np != 0; np = np->allnext) { + if (type != NULL + && !(np->type != 0 && strcasecmp(np->type, type) == 0)) + continue; + if (device_is_compatible(np, compatible)) + break; + } + if (from) + of_node_put(from); + return of_node_get(np); +} + +/** + * of_find_node_by_path - Find a node matching a full OF path + * @path: The full path to match + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_by_path(const char *path) +{ + struct device_node *np = allnodes; + + for (; np != 0; np = np->allnext) + if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0) + break; + return of_node_get(np); +} + +/** + * of_find_all_nodes - Get next node in global list + * @prev: Previous node or NULL to start iteration + * of_node_put() will be called on it + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_all_nodes(struct device_node *prev) +{ + return of_node_get(prev ? prev->allnext : allnodes); +} + +/** + * of_get_parent - Get a node's parent if any + * @node: Node to get parent + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_get_parent(const struct device_node *node) +{ + return node ? of_node_get(node->parent) : NULL; +} + +/** + * of_get_next_child - Iterate a node childs + * @node: parent node + * @prev: previous child of the parent node, or NULL to get first + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_get_next_child(const struct device_node *node, + struct device_node *prev) +{ + struct device_node *next = prev ? prev->sibling : node->child; + + for (; next != 0; next = next->sibling) + if (of_node_get(next)) + break; + if (prev) + of_node_put(prev); + return next; +} + +/** + * of_node_get - Increment refcount of a node + * @node: Node to inc refcount, NULL is supported to + * simplify writing of callers + * + * Returns the node itself or NULL if gone. Current implementation + * does nothing as we don't yet do dynamic node allocation on ppc32 + */ +struct device_node *of_node_get(struct device_node *node) +{ + return node; +} + +/** + * of_node_put - Decrement refcount of a node + * @node: Node to dec refcount, NULL is supported to + * simplify writing of callers + * + * Current implementation does nothing as we don't yet do dynamic node + * allocation on ppc32 + */ +void of_node_put(struct device_node *node) +{ +} + +/* + * Find the device_node with a given phandle. + */ +static struct device_node * __init +find_phandle(phandle ph) +{ + struct device_node *np; + + for (np = allnodes; np != 0; np = np->allnext) + if (np->node == ph) + return np; + return NULL; +} + +/* + * Find a property with a given name for a given node + * and return the value. + */ +unsigned char * +get_property(struct device_node *np, const char *name, int *lenp) +{ + struct property *pp; + + for (pp = np->properties; pp != 0; pp = pp->next) + if (pp->name != NULL && strcmp(pp->name, name) == 0) { + if (lenp != 0) + *lenp = pp->length; + return pp->value; + } + return NULL; +} + +/* + * Add a property to a node + */ +int +prom_add_property(struct device_node* np, struct property* prop) +{ + struct property **next = &np->properties; + + prop->next = NULL; + while (*next) + next = &(*next)->next; + *next = prop; + + return 0; +} + +/* I quickly hacked that one, check against spec ! */ +static inline unsigned long +bus_space_to_resource_flags(unsigned int bus_space) +{ + u8 space = (bus_space >> 24) & 0xf; + if (space == 0) + space = 0x02; + if (space == 0x02) + return IORESOURCE_MEM; + else if (space == 0x01) + return IORESOURCE_IO; + else { + printk(KERN_WARNING "prom.c: bus_space_to_resource_flags(), space: %x\n", + bus_space); + return 0; + } +} + +static struct resource* +find_parent_pci_resource(struct pci_dev* pdev, struct address_range *range) +{ + unsigned long mask; + int i; + + /* Check this one */ + mask = bus_space_to_resource_flags(range->space); + for (i=0; iresource[i].flags & mask) == mask && + pdev->resource[i].start <= range->address && + pdev->resource[i].end > range->address) { + if ((range->address + range->size - 1) > pdev->resource[i].end) { + /* Add better message */ + printk(KERN_WARNING "PCI/OF resource overlap !\n"); + return NULL; + } + break; + } + } + if (i == DEVICE_COUNT_RESOURCE) + return NULL; + return &pdev->resource[i]; +} + +/* + * Request an OF device resource. Currently handles child of PCI devices, + * or other nodes attached to the root node. Ultimately, put some + * link to resources in the OF node. + */ +struct resource* +request_OF_resource(struct device_node* node, int index, const char* name_postfix) +{ + struct pci_dev* pcidev; + u8 pci_bus, pci_devfn; + unsigned long iomask; + struct device_node* nd; + struct resource* parent; + struct resource *res = NULL; + int nlen, plen; + + if (index >= node->n_addrs) + goto fail; + + /* Sanity check on bus space */ + iomask = bus_space_to_resource_flags(node->addrs[index].space); + if (iomask & IORESOURCE_MEM) + parent = &iomem_resource; + else if (iomask & IORESOURCE_IO) + parent = &ioport_resource; + else + goto fail; + + /* Find a PCI parent if any */ + nd = node; + pcidev = NULL; + while(nd) { + if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn)) + pcidev = pci_find_slot(pci_bus, pci_devfn); + if (pcidev) break; + nd = nd->parent; + } + if (pcidev) + parent = find_parent_pci_resource(pcidev, &node->addrs[index]); + if (!parent) { + printk(KERN_WARNING "request_OF_resource(%s), parent not found\n", + node->name); + goto fail; + } + + res = __request_region(parent, node->addrs[index].address, node->addrs[index].size, NULL); + if (!res) + goto fail; + nlen = strlen(node->name); + plen = name_postfix ? strlen(name_postfix) : 0; + res->name = (const char *)kmalloc(nlen+plen+1, GFP_KERNEL); + if (res->name) { + strcpy((char *)res->name, node->name); + if (plen) + strcpy((char *)res->name+nlen, name_postfix); + } + return res; +fail: + return NULL; +} + +int +release_OF_resource(struct device_node* node, int index) +{ + struct pci_dev* pcidev; + u8 pci_bus, pci_devfn; + unsigned long iomask, start, end; + struct device_node* nd; + struct resource* parent; + struct resource *res = NULL; + + if (index >= node->n_addrs) + return -EINVAL; + + /* Sanity check on bus space */ + iomask = bus_space_to_resource_flags(node->addrs[index].space); + if (iomask & IORESOURCE_MEM) + parent = &iomem_resource; + else if (iomask & IORESOURCE_IO) + parent = &ioport_resource; + else + return -EINVAL; + + /* Find a PCI parent if any */ + nd = node; + pcidev = NULL; + while(nd) { + if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn)) + pcidev = pci_find_slot(pci_bus, pci_devfn); + if (pcidev) break; + nd = nd->parent; + } + if (pcidev) + parent = find_parent_pci_resource(pcidev, &node->addrs[index]); + if (!parent) { + printk(KERN_WARNING "release_OF_resource(%s), parent not found\n", + node->name); + return -ENODEV; + } + + /* Find us in the parent and its childs */ + res = parent->child; + start = node->addrs[index].address; + end = start + node->addrs[index].size - 1; + while (res) { + if (res->start == start && res->end == end && + (res->flags & IORESOURCE_BUSY)) + break; + if (res->start <= start && res->end >= end) + res = res->child; + else + res = res->sibling; + } + if (!res) + return -ENODEV; + + kfree(res->name); + res->name = NULL; + release_resource(res); + kfree(res); + + return 0; +} + +#if 0 +void +print_properties(struct device_node *np) +{ + struct property *pp; + char *cp; + int i, n; + + for (pp = np->properties; pp != 0; pp = pp->next) { + printk(KERN_INFO "%s", pp->name); + for (i = strlen(pp->name); i < 16; ++i) + printk(" "); + cp = (char *) pp->value; + for (i = pp->length; i > 0; --i, ++cp) + if ((i > 1 && (*cp < 0x20 || *cp > 0x7e)) + || (i == 1 && *cp != 0)) + break; + if (i == 0 && pp->length > 1) { + /* looks like a string */ + printk(" %s\n", (char *) pp->value); + } else { + /* dump it in hex */ + n = pp->length; + if (n > 64) + n = 64; + if (pp->length % 4 == 0) { + unsigned int *p = (unsigned int *) pp->value; + + n /= 4; + for (i = 0; i < n; ++i) { + if (i != 0 && (i % 4) == 0) + printk("\n "); + printk(" %08x", *p++); + } + } else { + unsigned char *bp = pp->value; + + for (i = 0; i < n; ++i) { + if (i != 0 && (i % 16) == 0) + printk("\n "); + printk(" %02x", *bp++); + } + } + printk("\n"); + if (pp->length > 64) + printk(" ... (length = %d)\n", + pp->length); + } + } +} +#endif + +static DEFINE_SPINLOCK(rtas_lock); + +/* this can be called after setup -- Cort */ +int +call_rtas(const char *service, int nargs, int nret, + unsigned long *outputs, ...) +{ + va_list list; + int i; + unsigned long s; + struct device_node *rtas; + int *tokp; + union { + unsigned long words[16]; + double align; + } u; + + rtas = find_devices("rtas"); + if (rtas == NULL) + return -1; + tokp = (int *) get_property(rtas, service, NULL); + if (tokp == NULL) { + printk(KERN_ERR "No RTAS service called %s\n", service); + return -1; + } + u.words[0] = *tokp; + u.words[1] = nargs; + u.words[2] = nret; + va_start(list, outputs); + for (i = 0; i < nargs; ++i) + u.words[i+3] = va_arg(list, unsigned long); + va_end(list); + + /* + * RTAS doesn't use floating point. + * Or at least, according to the CHRP spec we enter RTAS + * with FP disabled, and it doesn't change the FP registers. + * -- paulus. + */ + spin_lock_irqsave(&rtas_lock, s); + enter_rtas((void *)__pa(&u)); + spin_unlock_irqrestore(&rtas_lock, s); + + if (nret > 1 && outputs != NULL) + for (i = 0; i < nret-1; ++i) + outputs[i] = u.words[i+nargs+4]; + return u.words[nargs+3]; +} diff --git a/trunk/arch/ppc/syslib/prom_init.c b/trunk/arch/ppc/syslib/prom_init.c new file mode 100644 index 000000000000..df14422ae1c6 --- /dev/null +++ b/trunk/arch/ppc/syslib/prom_init.c @@ -0,0 +1,1011 @@ +/* + * Note that prom_init() and anything called from prom_init() + * may be running at an address that is different from the address + * that it was linked at. References to static data items are + * handled by compiling this file with -mrelocatable-lib. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_LOGO_LINUX_CLUT224 +#include +extern const struct linux_logo logo_linux_clut224; +#endif + +/* + * Properties whose value is longer than this get excluded from our + * copy of the device tree. This way we don't waste space storing + * things like "driver,AAPL,MacOS,PowerPC" properties. But this value + * does need to be big enough to ensure that we don't lose things + * like the interrupt-map property on a PCI-PCI bridge. + */ +#define MAX_PROPERTY_LENGTH 4096 + +#ifndef FB_MAX /* avoid pulling in all of the fb stuff */ +#define FB_MAX 8 +#endif + +#define ALIGNUL(x) (((x) + sizeof(unsigned long)-1) & -sizeof(unsigned long)) + +typedef u32 prom_arg_t; + +struct prom_args { + const char *service; + int nargs; + int nret; + prom_arg_t args[10]; +}; + +struct pci_address { + unsigned a_hi; + unsigned a_mid; + unsigned a_lo; +}; + +struct pci_reg_property { + struct pci_address addr; + unsigned size_hi; + unsigned size_lo; +}; + +struct pci_range { + struct pci_address addr; + unsigned phys; + unsigned size_hi; + unsigned size_lo; +}; + +struct isa_reg_property { + unsigned space; + unsigned address; + unsigned size; +}; + +struct pci_intr_map { + struct pci_address addr; + unsigned dunno; + phandle int_ctrler; + unsigned intr; +}; + +static void prom_exit(void); +static int call_prom(const char *service, int nargs, int nret, ...); +static int call_prom_ret(const char *service, int nargs, int nret, + prom_arg_t *rets, ...); +static void prom_print_hex(unsigned int v); +static int prom_set_color(ihandle ih, int i, int r, int g, int b); +static int prom_next_node(phandle *nodep); +static unsigned long check_display(unsigned long mem); +static void setup_disp_fake_bi(ihandle dp); +static unsigned long copy_device_tree(unsigned long mem_start, + unsigned long mem_end); +static unsigned long inspect_node(phandle node, struct device_node *dad, + unsigned long mem_start, unsigned long mem_end, + struct device_node ***allnextpp); +static void prom_hold_cpus(unsigned long mem); +static void prom_instantiate_rtas(void); +static void * early_get_property(unsigned long base, unsigned long node, + char *prop); + +prom_entry prom __initdata; +ihandle prom_chosen __initdata; +ihandle prom_stdout __initdata; + +static char *prom_display_paths[FB_MAX] __initdata; +static phandle prom_display_nodes[FB_MAX] __initdata; +static unsigned int prom_num_displays __initdata; +static ihandle prom_disp_node __initdata; +char *of_stdout_device __initdata; + +unsigned int rtas_data; /* physical pointer */ +unsigned int rtas_entry; /* physical pointer */ +unsigned int rtas_size; +unsigned int old_rtas; + +boot_infos_t *boot_infos; +char *bootpath; +char *bootdevice; +struct device_node *allnodes; + +extern char *klimit; + +static void __init +prom_exit(void) +{ + struct prom_args args; + + args.service = "exit"; + args.nargs = 0; + args.nret = 0; + prom(&args); + for (;;) /* should never get here */ + ; +} + +static int __init +call_prom(const char *service, int nargs, int nret, ...) +{ + va_list list; + int i; + struct prom_args prom_args; + + prom_args.service = service; + prom_args.nargs = nargs; + prom_args.nret = nret; + va_start(list, nret); + for (i = 0; i < nargs; ++i) + prom_args.args[i] = va_arg(list, prom_arg_t); + va_end(list); + for (i = 0; i < nret; ++i) + prom_args.args[i + nargs] = 0; + prom(&prom_args); + return prom_args.args[nargs]; +} + +static int __init +call_prom_ret(const char *service, int nargs, int nret, prom_arg_t *rets, ...) +{ + va_list list; + int i; + struct prom_args prom_args; + + prom_args.service = service; + prom_args.nargs = nargs; + prom_args.nret = nret; + va_start(list, rets); + for (i = 0; i < nargs; ++i) + prom_args.args[i] = va_arg(list, int); + va_end(list); + for (i = 0; i < nret; ++i) + prom_args.args[i + nargs] = 0; + prom(&prom_args); + for (i = 1; i < nret; ++i) + rets[i-1] = prom_args.args[nargs + i]; + return prom_args.args[nargs]; +} + +void __init +prom_print(const char *msg) +{ + const char *p, *q; + + if (prom_stdout == 0) + return; + + for (p = msg; *p != 0; p = q) { + for (q = p; *q != 0 && *q != '\n'; ++q) + ; + if (q > p) + call_prom("write", 3, 1, prom_stdout, p, q - p); + if (*q != 0) { + ++q; + call_prom("write", 3, 1, prom_stdout, "\r\n", 2); + } + } +} + +static void __init +prom_print_hex(unsigned int v) +{ + char buf[16]; + int i, c; + + for (i = 0; i < 8; ++i) { + c = (v >> ((7-i)*4)) & 0xf; + c += (c >= 10)? ('a' - 10): '0'; + buf[i] = c; + } + buf[i] = ' '; + buf[i+1] = 0; + prom_print(buf); +} + +static int __init +prom_set_color(ihandle ih, int i, int r, int g, int b) +{ + return call_prom("call-method", 6, 1, "color!", ih, i, b, g, r); +} + +static int __init +prom_next_node(phandle *nodep) +{ + phandle node; + + if ((node = *nodep) != 0 + && (*nodep = call_prom("child", 1, 1, node)) != 0) + return 1; + if ((*nodep = call_prom("peer", 1, 1, node)) != 0) + return 1; + for (;;) { + if ((node = call_prom("parent", 1, 1, node)) == 0) + return 0; + if ((*nodep = call_prom("peer", 1, 1, node)) != 0) + return 1; + } +} + +#ifdef CONFIG_POWER4 +/* + * Set up a hash table with a set of entries in it to map the + * first 64MB of RAM. This is used on 64-bit machines since + * some of them don't have BATs. + */ + +static inline void make_pte(unsigned long htab, unsigned int hsize, + unsigned int va, unsigned int pa, int mode) +{ + unsigned int *pteg; + unsigned int hash, i, vsid; + + vsid = ((va >> 28) * 0x111) << 12; + hash = ((va ^ vsid) >> 5) & 0x7fff80; + pteg = (unsigned int *)(htab + (hash & (hsize - 1))); + for (i = 0; i < 8; ++i, pteg += 4) { + if ((pteg[1] & 1) == 0) { + pteg[1] = vsid | ((va >> 16) & 0xf80) | 1; + pteg[3] = pa | mode; + break; + } + } +} + +extern unsigned long _SDR1; +extern PTE *Hash; +extern unsigned long Hash_size; + +static void __init +prom_alloc_htab(void) +{ + unsigned int hsize; + unsigned long htab; + unsigned int addr; + + /* + * Because of OF bugs we can't use the "claim" client + * interface to allocate memory for the hash table. + * This code is only used on 64-bit PPCs, and the only + * 64-bit PPCs at the moment are RS/6000s, and their + * OF is based at 0xc00000 (the 12M point), so we just + * arbitrarily use the 0x800000 - 0xc00000 region for the + * hash table. + * -- paulus. + */ + hsize = 4 << 20; /* POWER4 has no BATs */ + htab = (8 << 20); + call_prom("claim", 3, 1, htab, hsize, 0); + Hash = (void *)(htab + KERNELBASE); + Hash_size = hsize; + _SDR1 = htab + __ilog2(hsize) - 18; + + /* + * Put in PTEs for the first 64MB of RAM + */ + memset((void *)htab, 0, hsize); + for (addr = 0; addr < 0x4000000; addr += 0x1000) + make_pte(htab, hsize, addr + KERNELBASE, addr, + _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX); +#if 0 /* DEBUG stuff mapping the SCC */ + make_pte(htab, hsize, 0x80013000, 0x80013000, + _PAGE_ACCESSED | _PAGE_NO_CACHE | _PAGE_GUARDED | PP_RWXX); +#endif +} +#endif /* CONFIG_POWER4 */ + + +/* + * If we have a display that we don't know how to drive, + * we will want to try to execute OF's open method for it + * later. However, OF will probably fall over if we do that + * we've taken over the MMU. + * So we check whether we will need to open the display, + * and if so, open it now. + */ +static unsigned long __init +check_display(unsigned long mem) +{ + phandle node; + ihandle ih; + int i, j; + char type[16], *path; + static unsigned char default_colors[] = { + 0x00, 0x00, 0x00, + 0x00, 0x00, 0xaa, + 0x00, 0xaa, 0x00, + 0x00, 0xaa, 0xaa, + 0xaa, 0x00, 0x00, + 0xaa, 0x00, 0xaa, + 0xaa, 0xaa, 0x00, + 0xaa, 0xaa, 0xaa, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0xff, + 0x55, 0xff, 0x55, + 0x55, 0xff, 0xff, + 0xff, 0x55, 0x55, + 0xff, 0x55, 0xff, + 0xff, 0xff, 0x55, + 0xff, 0xff, 0xff + }; + const unsigned char *clut; + + prom_disp_node = 0; + + for (node = 0; prom_next_node(&node); ) { + type[0] = 0; + call_prom("getprop", 4, 1, node, "device_type", + type, sizeof(type)); + if (strcmp(type, "display") != 0) + continue; + /* It seems OF doesn't null-terminate the path :-( */ + path = (char *) mem; + memset(path, 0, 256); + if (call_prom("package-to-path", 3, 1, node, path, 255) < 0) + continue; + + /* + * If this display is the device that OF is using for stdout, + * move it to the front of the list. + */ + mem += strlen(path) + 1; + i = prom_num_displays++; + if (of_stdout_device != 0 && i > 0 + && strcmp(of_stdout_device, path) == 0) { + for (; i > 0; --i) { + prom_display_paths[i] + = prom_display_paths[i-1]; + prom_display_nodes[i] + = prom_display_nodes[i-1]; + } + } + prom_display_paths[i] = path; + prom_display_nodes[i] = node; + if (i == 0) + prom_disp_node = node; + if (prom_num_displays >= FB_MAX) + break; + } + + for (j=0; j 0) { + prom_disp_node = prom_display_nodes[j]; + j--; + } else + prom_disp_node = 0; + continue; + } else { + prom_print("... ok\n"); + call_prom("setprop", 4, 1, node, "linux,opened", 0, 0); + + /* + * Setup a usable color table when the appropriate + * method is available. + * Should update this to use set-colors. + */ + clut = default_colors; + for (i = 0; i < 32; i++, clut += 3) + if (prom_set_color(ih, i, clut[0], clut[1], + clut[2]) != 0) + break; + +#ifdef CONFIG_LOGO_LINUX_CLUT224 + clut = PTRRELOC(logo_linux_clut224.clut); + for (i = 0; i < logo_linux_clut224.clutsize; + i++, clut += 3) + if (prom_set_color(ih, i + 32, clut[0], + clut[1], clut[2]) != 0) + break; +#endif /* CONFIG_LOGO_LINUX_CLUT224 */ + } + } + + if (prom_stdout) { + phandle p; + p = call_prom("instance-to-package", 1, 1, prom_stdout); + if (p && p != -1) { + type[0] = 0; + call_prom("getprop", 4, 1, p, "device_type", + type, sizeof(type)); + if (strcmp(type, "display") == 0) + call_prom("setprop", 4, 1, p, "linux,boot-display", + 0, 0); + } + } + + return ALIGNUL(mem); +} + +/* This function will enable the early boot text when doing OF booting. This + * way, xmon output should work too + */ +static void __init +setup_disp_fake_bi(ihandle dp) +{ +#ifdef CONFIG_BOOTX_TEXT + int width = 640, height = 480, depth = 8, pitch; + unsigned address; + struct pci_reg_property addrs[8]; + int i, naddrs; + char name[32]; + char *getprop = "getprop"; + + prom_print("Initializing fake screen: "); + + memset(name, 0, sizeof(name)); + call_prom(getprop, 4, 1, dp, "name", name, sizeof(name)); + name[sizeof(name)-1] = 0; + prom_print(name); + prom_print("\n"); + call_prom(getprop, 4, 1, dp, "width", &width, sizeof(width)); + call_prom(getprop, 4, 1, dp, "height", &height, sizeof(height)); + call_prom(getprop, 4, 1, dp, "depth", &depth, sizeof(depth)); + pitch = width * ((depth + 7) / 8); + call_prom(getprop, 4, 1, dp, "linebytes", + &pitch, sizeof(pitch)); + if (pitch == 1) + pitch = 0x1000; /* for strange IBM display */ + address = 0; + call_prom(getprop, 4, 1, dp, "address", + &address, sizeof(address)); + if (address == 0) { + /* look for an assigned address with a size of >= 1MB */ + naddrs = call_prom(getprop, 4, 1, dp, "assigned-addresses", + addrs, sizeof(addrs)); + naddrs /= sizeof(struct pci_reg_property); + for (i = 0; i < naddrs; ++i) { + if (addrs[i].size_lo >= (1 << 20)) { + address = addrs[i].addr.a_lo; + /* use the BE aperture if possible */ + if (addrs[i].size_lo >= (16 << 20)) + address += (8 << 20); + break; + } + } + if (address == 0) { + prom_print("Failed to get address\n"); + return; + } + } + /* kludge for valkyrie */ + if (strcmp(name, "valkyrie") == 0) + address += 0x1000; + +#ifdef CONFIG_POWER4 +#if CONFIG_TASK_SIZE > 0x80000000 +#error CONFIG_TASK_SIZE cannot be above 0x80000000 with BOOTX_TEXT on G5 +#endif + { + extern boot_infos_t disp_bi; + unsigned long va, pa, i, offset; + va = 0x90000000; + pa = address & 0xfffff000ul; + offset = address & 0x00000fff; + + for (i=0; i<0x4000; i++) { + make_pte((unsigned long)Hash - KERNELBASE, Hash_size, va, pa, + _PAGE_ACCESSED | _PAGE_NO_CACHE | + _PAGE_GUARDED | PP_RWXX); + va += 0x1000; + pa += 0x1000; + } + btext_setup_display(width, height, depth, pitch, 0x90000000 | offset); + disp_bi.dispDeviceBase = (u8 *)address; + } +#else /* CONFIG_POWER4 */ + btext_setup_display(width, height, depth, pitch, address); + btext_prepare_BAT(); +#endif /* CONFIG_POWER4 */ +#endif /* CONFIG_BOOTX_TEXT */ +} + +/* + * Make a copy of the device tree from the PROM. + */ +static unsigned long __init +copy_device_tree(unsigned long mem_start, unsigned long mem_end) +{ + phandle root; + unsigned long new_start; + struct device_node **allnextp; + + root = call_prom("peer", 1, 1, (phandle)0); + if (root == (phandle)0) { + prom_print("couldn't get device tree root\n"); + prom_exit(); + } + allnextp = &allnodes; + mem_start = ALIGNUL(mem_start); + new_start = inspect_node(root, NULL, mem_start, mem_end, &allnextp); + *allnextp = NULL; + return new_start; +} + +static unsigned long __init +inspect_node(phandle node, struct device_node *dad, + unsigned long mem_start, unsigned long mem_end, + struct device_node ***allnextpp) +{ + int l; + phandle child; + struct device_node *np; + struct property *pp, **prev_propp; + char *prev_name, *namep; + unsigned char *valp; + + np = (struct device_node *) mem_start; + mem_start += sizeof(struct device_node); + memset(np, 0, sizeof(*np)); + np->node = node; + **allnextpp = PTRUNRELOC(np); + *allnextpp = &np->allnext; + if (dad != 0) { + np->parent = PTRUNRELOC(dad); + /* we temporarily use the `next' field as `last_child'. */ + if (dad->next == 0) + dad->child = PTRUNRELOC(np); + else + dad->next->sibling = PTRUNRELOC(np); + dad->next = np; + } + + /* get and store all properties */ + prev_propp = &np->properties; + prev_name = ""; + for (;;) { + pp = (struct property *) mem_start; + namep = (char *) (pp + 1); + pp->name = PTRUNRELOC(namep); + if (call_prom("nextprop", 3, 1, node, prev_name, namep) <= 0) + break; + mem_start = ALIGNUL((unsigned long)namep + strlen(namep) + 1); + prev_name = namep; + valp = (unsigned char *) mem_start; + pp->value = PTRUNRELOC(valp); + pp->length = call_prom("getprop", 4, 1, node, namep, + valp, mem_end - mem_start); + if (pp->length < 0) + continue; +#ifdef MAX_PROPERTY_LENGTH + if (pp->length > MAX_PROPERTY_LENGTH) + continue; /* ignore this property */ +#endif + mem_start = ALIGNUL(mem_start + pp->length); + *prev_propp = PTRUNRELOC(pp); + prev_propp = &pp->next; + } + if (np->node != 0) { + /* Add a "linux,phandle" property" */ + pp = (struct property *) mem_start; + *prev_propp = PTRUNRELOC(pp); + prev_propp = &pp->next; + namep = (char *) (pp + 1); + pp->name = PTRUNRELOC(namep); + strcpy(namep, "linux,phandle"); + mem_start = ALIGNUL((unsigned long)namep + strlen(namep) + 1); + pp->value = (unsigned char *) PTRUNRELOC(&np->node); + pp->length = sizeof(np->node); + } + *prev_propp = NULL; + + /* get the node's full name */ + l = call_prom("package-to-path", 3, 1, node, + mem_start, mem_end - mem_start); + if (l >= 0) { + char *p, *ep; + + np->full_name = PTRUNRELOC((char *) mem_start); + *(char *)(mem_start + l) = 0; + /* Fixup an Apple bug where they have bogus \0 chars in the + * middle of the path in some properties + */ + for (p = (char *)mem_start, ep = p + l; p < ep; p++) + if ((*p) == '\0') { + memmove(p, p+1, ep - p); + ep--; + } + mem_start = ALIGNUL(mem_start + l + 1); + } + + /* do all our children */ + child = call_prom("child", 1, 1, node); + while (child != 0) { + mem_start = inspect_node(child, np, mem_start, mem_end, + allnextpp); + child = call_prom("peer", 1, 1, child); + } + + return mem_start; +} + +unsigned long smp_chrp_cpu_nr __initdata = 0; + +/* + * With CHRP SMP we need to use the OF to start the other + * processors so we can't wait until smp_boot_cpus (the OF is + * trashed by then) so we have to put the processors into + * a holding pattern controlled by the kernel (not OF) before + * we destroy the OF. + * + * This uses a chunk of high memory, puts some holding pattern + * code there and sends the other processors off to there until + * smp_boot_cpus tells them to do something. We do that by using + * physical address 0x0. The holding pattern checks that address + * until its cpu # is there, when it is that cpu jumps to + * __secondary_start(). smp_boot_cpus() takes care of setting those + * values. + * + * We also use physical address 0x4 here to tell when a cpu + * is in its holding pattern code. + * + * -- Cort + * + * Note that we have to do this if we have more than one CPU, + * even if this is a UP kernel. Otherwise when we trash OF + * the other CPUs will start executing some random instructions + * and crash the system. -- paulus + */ +static void __init +prom_hold_cpus(unsigned long mem) +{ + extern void __secondary_hold(void); + unsigned long i; + int cpu; + phandle node; + char type[16], *path; + unsigned int reg; + + /* + * XXX: hack to make sure we're chrp, assume that if we're + * chrp we have a device_type property -- Cort + */ + node = call_prom("finddevice", 1, 1, "/"); + if (call_prom("getprop", 4, 1, node, + "device_type", type, sizeof(type)) <= 0) + return; + + /* copy the holding pattern code to someplace safe (0) */ + /* the holding pattern is now within the first 0x100 + bytes of the kernel image -- paulus */ + memcpy((void *)0, _stext, 0x100); + flush_icache_range(0, 0x100); + + /* look for cpus */ + *(unsigned long *)(0x0) = 0; + asm volatile("dcbf 0,%0": : "r" (0) : "memory"); + for (node = 0; prom_next_node(&node); ) { + type[0] = 0; + call_prom("getprop", 4, 1, node, "device_type", + type, sizeof(type)); + if (strcmp(type, "cpu") != 0) + continue; + path = (char *) mem; + memset(path, 0, 256); + if (call_prom("package-to-path", 3, 1, node, path, 255) < 0) + continue; + reg = -1; + call_prom("getprop", 4, 1, node, "reg", ®, sizeof(reg)); + cpu = smp_chrp_cpu_nr++; +#ifdef CONFIG_SMP + smp_hw_index[cpu] = reg; +#endif /* CONFIG_SMP */ + /* XXX: hack - don't start cpu 0, this cpu -- Cort */ + if (cpu == 0) + continue; + prom_print("starting cpu "); + prom_print(path); + *(ulong *)(0x4) = 0; + call_prom("start-cpu", 3, 0, node, + (char *)__secondary_hold - _stext, cpu); + prom_print("..."); + for ( i = 0 ; (i < 10000) && (*(ulong *)(0x4) == 0); i++ ) + ; + if (*(ulong *)(0x4) == cpu) + prom_print("ok\n"); + else { + prom_print("failed: "); + prom_print_hex(*(ulong *)0x4); + prom_print("\n"); + } + } +} + +static void __init +prom_instantiate_rtas(void) +{ + ihandle prom_rtas; + prom_arg_t result; + + prom_rtas = call_prom("finddevice", 1, 1, "/rtas"); + if (prom_rtas == -1) + return; + + rtas_size = 0; + call_prom("getprop", 4, 1, prom_rtas, + "rtas-size", &rtas_size, sizeof(rtas_size)); + prom_print("instantiating rtas"); + if (rtas_size == 0) { + rtas_data = 0; + } else { + /* + * Ask OF for some space for RTAS. + * Actually OF has bugs so we just arbitrarily + * use memory at the 6MB point. + */ + rtas_data = 6 << 20; + prom_print(" at "); + prom_print_hex(rtas_data); + } + + prom_rtas = call_prom("open", 1, 1, "/rtas"); + prom_print("..."); + rtas_entry = 0; + if (call_prom_ret("call-method", 3, 2, &result, + "instantiate-rtas", prom_rtas, rtas_data) == 0) + rtas_entry = result; + if ((rtas_entry == -1) || (rtas_entry == 0)) + prom_print(" failed\n"); + else + prom_print(" done\n"); +} + +/* + * We enter here early on, when the Open Firmware prom is still + * handling exceptions and the MMU hash table for us. + */ +unsigned long __init +prom_init(int r3, int r4, prom_entry pp) +{ + unsigned long mem; + ihandle prom_mmu; + unsigned long offset = reloc_offset(); + int i, l; + char *p, *d; + unsigned long phys; + prom_arg_t result[3]; + char model[32]; + phandle node; + int rc; + + /* Default */ + phys = (unsigned long) &_stext; + + /* First get a handle for the stdout device */ + prom = pp; + prom_chosen = call_prom("finddevice", 1, 1, "/chosen"); + if (prom_chosen == -1) + prom_exit(); + if (call_prom("getprop", 4, 1, prom_chosen, "stdout", + &prom_stdout, sizeof(prom_stdout)) <= 0) + prom_exit(); + + /* Get the full OF pathname of the stdout device */ + mem = (unsigned long) klimit + offset; + p = (char *) mem; + memset(p, 0, 256); + call_prom("instance-to-path", 3, 1, prom_stdout, p, 255); + of_stdout_device = p; + mem += strlen(p) + 1; + + /* Get the boot device and translate it to a full OF pathname. */ + p = (char *) mem; + l = call_prom("getprop", 4, 1, prom_chosen, "bootpath", p, 1<<20); + if (l > 0) { + p[l] = 0; /* should already be null-terminated */ + bootpath = PTRUNRELOC(p); + mem += l + 1; + d = (char *) mem; + *d = 0; + call_prom("canon", 3, 1, p, d, 1<<20); + bootdevice = PTRUNRELOC(d); + mem = ALIGNUL(mem + strlen(d) + 1); + } + + prom_instantiate_rtas(); + +#ifdef CONFIG_POWER4 + /* + * Find out how much memory we have and allocate a + * suitably-sized hash table. + */ + prom_alloc_htab(); +#endif + mem = check_display(mem); + + prom_print("copying OF device tree..."); + mem = copy_device_tree(mem, mem + (1<<20)); + prom_print("done\n"); + + prom_hold_cpus(mem); + + klimit = (char *) (mem - offset); + + node = call_prom("finddevice", 1, 1, "/"); + rc = call_prom("getprop", 4, 1, node, "model", model, sizeof(model)); + if (rc > 0 && !strncmp (model, "Pegasos", 7) + && strncmp (model, "Pegasos2", 8)) { + /* Pegasos 1 has a broken translate method in the OF, + * and furthermore the BATs are mapped 1:1 so the phys + * address calculated above is correct, so let's use + * it directly. + */ + } else if (offset == 0) { + /* If we are already running at 0xc0000000, we assume we were + * loaded by an OF bootloader which did set a BAT for us. + * This breaks OF translate so we force phys to be 0. + */ + prom_print("(already at 0xc0000000) phys=0\n"); + phys = 0; + } else if (call_prom("getprop", 4, 1, prom_chosen, "mmu", + &prom_mmu, sizeof(prom_mmu)) <= 0) { + prom_print(" no MMU found\n"); + } else if (call_prom_ret("call-method", 4, 4, result, "translate", + prom_mmu, &_stext, 1) != 0) { + prom_print(" (translate failed)\n"); + } else { + /* We assume the phys. address size is 3 cells */ + phys = result[2]; + } + + if (prom_disp_node != 0) + setup_disp_fake_bi(prom_disp_node); + + /* Use quiesce call to get OF to shut down any devices it's using */ + prom_print("Calling quiesce ...\n"); + call_prom("quiesce", 0, 0); + + /* Relocate various pointers which will be used once the + kernel is running at the address it was linked at. */ + for (i = 0; i < prom_num_displays; ++i) + prom_display_paths[i] = PTRUNRELOC(prom_display_paths[i]); + +#ifdef CONFIG_SERIAL_CORE_CONSOLE + /* Relocate the of stdout for console autodetection */ + of_stdout_device = PTRUNRELOC(of_stdout_device); +#endif + + prom_print("returning 0x"); + prom_print_hex(phys); + prom_print("from prom_init\n"); + prom_stdout = 0; + + return phys; +} + +/* + * early_get_property is used to access the device tree image prepared + * by BootX very early on, before the pointers in it have been relocated. + */ +static void * __init +early_get_property(unsigned long base, unsigned long node, char *prop) +{ + struct device_node *np = (struct device_node *)(base + node); + struct property *pp; + + for (pp = np->properties; pp != 0; pp = pp->next) { + pp = (struct property *) (base + (unsigned long)pp); + if (strcmp((char *)((unsigned long)pp->name + base), + prop) == 0) { + return (void *)((unsigned long)pp->value + base); + } + } + return NULL; +} + +/* Is boot-info compatible ? */ +#define BOOT_INFO_IS_COMPATIBLE(bi) ((bi)->compatible_version <= BOOT_INFO_VERSION) +#define BOOT_INFO_IS_V2_COMPATIBLE(bi) ((bi)->version >= 2) +#define BOOT_INFO_IS_V4_COMPATIBLE(bi) ((bi)->version >= 4) + +void __init +bootx_init(unsigned long r4, unsigned long phys) +{ + boot_infos_t *bi = (boot_infos_t *) r4; + unsigned long space; + unsigned long ptr, x; + char *model; + + boot_infos = PTRUNRELOC(bi); + if (!BOOT_INFO_IS_V2_COMPATIBLE(bi)) + bi->logicalDisplayBase = NULL; + +#ifdef CONFIG_BOOTX_TEXT + btext_init(bi); + + /* + * Test if boot-info is compatible. Done only in config + * CONFIG_BOOTX_TEXT since there is nothing much we can do + * with an incompatible version, except display a message + * and eventually hang the processor... + * + * I'll try to keep enough of boot-info compatible in the + * future to always allow display of this message; + */ + if (!BOOT_INFO_IS_COMPATIBLE(bi)) { + btext_drawstring(" !!! WARNING - Incompatible version of BootX !!!\n\n\n"); + btext_flushscreen(); + } +#endif /* CONFIG_BOOTX_TEXT */ + + /* New BootX enters kernel with MMU off, i/os are not allowed + here. This hack will have been done by the boostrap anyway. + */ + if (bi->version < 4) { + /* + * XXX If this is an iMac, turn off the USB controller. + */ + model = (char *) early_get_property + (r4 + bi->deviceTreeOffset, 4, "model"); + if (model + && (strcmp(model, "iMac,1") == 0 + || strcmp(model, "PowerMac1,1") == 0)) { + out_le32((unsigned *)0x80880008, 1); /* XXX */ + } + } + + /* Move klimit to enclose device tree, args, ramdisk, etc... */ + if (bi->version < 5) { + space = bi->deviceTreeOffset + bi->deviceTreeSize; + if (bi->ramDisk) + space = bi->ramDisk + bi->ramDiskSize; + } else + space = bi->totalParamsSize; + klimit = PTRUNRELOC((char *) bi + space); + + /* New BootX will have flushed all TLBs and enters kernel with + MMU switched OFF, so this should not be useful anymore. + */ + if (bi->version < 4) { + /* + * Touch each page to make sure the PTEs for them + * are in the hash table - the aim is to try to avoid + * getting DSI exceptions while copying the kernel image. + */ + for (ptr = ((unsigned long) &_stext) & PAGE_MASK; + ptr < (unsigned long)bi + space; ptr += PAGE_SIZE) + x = *(volatile unsigned long *)ptr; + } + +#ifdef CONFIG_BOOTX_TEXT + /* + * Note that after we call btext_prepare_BAT, we can't do + * prom_draw*, flushscreen or clearscreen until we turn the MMU + * on, since btext_prepare_BAT sets disp_bi.logicalDisplayBase + * to a virtual address. + */ + btext_prepare_BAT(); +#endif +} diff --git a/trunk/arch/ppc/xmon/start.c b/trunk/arch/ppc/xmon/start.c index cfc2d6ad464d..ff86b2d814cb 100644 --- a/trunk/arch/ppc/xmon/start.c +++ b/trunk/arch/ppc/xmon/start.c @@ -58,7 +58,7 @@ static struct sysrq_key_op sysrq_xmon_op = void xmon_map_scc(void) { -#ifdef CONFIG_PPC_PREP +#ifdef CONFIG_PPC_MULTIPLATFORM volatile unsigned char *base; #elif defined(CONFIG_GEMINI) diff --git a/trunk/arch/um/kernel/smp.c b/trunk/arch/um/kernel/smp.c index 511116aebaf7..c8d8d0ac1a7f 100644 --- a/trunk/arch/um/kernel/smp.c +++ b/trunk/arch/um/kernel/smp.c @@ -143,6 +143,7 @@ void smp_prepare_cpus(unsigned int maxcpus) idle = idle_thread(cpu); init_idle(idle, cpu); + unhash_process(idle); waittime = 200000000; while (waittime-- && !cpu_isset(cpu, cpu_callin_map)) diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index 889cad07774e..73d30bf01582 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -561,31 +561,14 @@ config TIPAR If unsure, say N. -config HVC_DRIVER - bool - help - Users of pSeries machines that want to utilize the hvc console front-end - module for their backend console driver should select this option. - It will automatically be selected if one of the back-end console drivers - is selected. - - config HVC_CONSOLE bool "pSeries Hypervisor Virtual Console support" depends on PPC_PSERIES - select HVC_DRIVER help pSeries machines when partitioned support a hypervisor virtual console. This driver allows each pSeries partition to have a console which is accessed via the HMC. -config HVC_RTAS - bool "IBM RTAS Console support" - depends on PPC_RTAS - select HVC_DRIVER - help - IBM Console device driver which makes use of RTAS - config HVCS tristate "IBM Hypervisor Virtual Console Server support" depends on PPC_PSERIES diff --git a/trunk/drivers/char/Makefile b/trunk/drivers/char/Makefile index a73cb4956928..b2a11245fa95 100644 --- a/trunk/drivers/char/Makefile +++ b/trunk/drivers/char/Makefile @@ -41,9 +41,7 @@ obj-$(CONFIG_N_HDLC) += n_hdlc.o obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o obj-$(CONFIG_SX) += sx.o generic_serial.o obj-$(CONFIG_RIO) += rio/ generic_serial.o -obj-$(CONFIG_HVC_DRIVER) += hvc_console.o -obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o -obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o +obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o hvc_vio.o hvsi.o obj-$(CONFIG_RAW_DRIVER) += raw.o obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o obj-$(CONFIG_MMTIMER) += mmtimer.o diff --git a/trunk/drivers/char/generic_nvram.c b/trunk/drivers/char/generic_nvram.c index 43ff59816511..1b5e01e6e129 100644 --- a/trunk/drivers/char/generic_nvram.c +++ b/trunk/drivers/char/generic_nvram.c @@ -22,9 +22,6 @@ #include #include #include -#ifdef CONFIG_PPC_PMAC -#include -#endif #define NVRAM_SIZE 8192 @@ -95,7 +92,7 @@ static int nvram_ioctl(struct inode *inode, struct file *file, case IOC_NVRAM_GET_OFFSET: { int part, offset; - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return -EINVAL; if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0) return -EFAULT; diff --git a/trunk/drivers/char/hvc_console.c b/trunk/drivers/char/hvc_console.c index 2b6a56b2bf35..f65b2e14a485 100644 --- a/trunk/drivers/char/hvc_console.c +++ b/trunk/drivers/char/hvc_console.c @@ -39,10 +39,8 @@ #include #include #include - #include - -#include "hvc_console.h" +#include #define HVC_MAJOR 229 #define HVC_MINOR 0 @@ -56,14 +54,17 @@ #define HVC_CLOSE_WAIT (HZ/100) /* 1/10 of a second */ /* - * These sizes are most efficient for vio, because they are the - * native transfer size. We could make them selectable in the - * future to better deal with backends that want other buffer sizes. + * The Linux TTY code does not support dynamic addition of tty derived devices + * so we need to know how many tty devices we might need when space is allocated + * for the tty device. Since this driver supports hotplug of vty adapters we + * need to make sure we have enough allocated. */ +#define HVC_ALLOC_TTY_ADAPTERS 8 + #define N_OUTBUF 16 #define N_INBUF 16 -#define __ALIGNED__ __attribute__((__aligned__(sizeof(long)))) +#define __ALIGNED__ __attribute__((__aligned__(8))) static struct tty_driver *hvc_driver; static struct task_struct *hvc_task; @@ -153,7 +154,7 @@ static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] = void hvc_console_print(struct console *co, const char *b, unsigned count) { - char c[N_OUTBUF] __ALIGNED__; + char c[16] __ALIGNED__; unsigned i = 0, n = 0; int r, donecr = 0, index = co->index; @@ -472,10 +473,8 @@ static void hvc_push(struct hvc_struct *hp) n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf); if (n <= 0) { - if (n == 0) { - hp->do_wakeup = 1; + if (n == 0) return; - } /* throw away output on error; this happens when there is no session connected to the vterm. */ hp->n_outbuf = 0; @@ -487,19 +486,12 @@ static void hvc_push(struct hvc_struct *hp) hp->do_wakeup = 1; } -static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count) +static inline int __hvc_write_kernel(struct hvc_struct *hp, + const unsigned char *buf, int count) { - struct hvc_struct *hp = tty->driver_data; unsigned long flags; int rsize, written = 0; - /* This write was probably executed during a tty close. */ - if (!hp) - return -EPIPE; - - if (hp->count <= 0) - return -EIO; - spin_lock_irqsave(&hp->lock, flags); /* Push pending writes */ @@ -518,8 +510,26 @@ static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count } spin_unlock_irqrestore(&hp->lock, flags); + return written; +} +static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count) +{ + struct hvc_struct *hp = tty->driver_data; + int written; + + /* This write was probably executed during a tty close. */ + if (!hp) + return -EPIPE; + + if (hp->count <= 0) + return -EIO; + + written = __hvc_write_kernel(hp, buf, count); + /* * Racy, but harmless, kick thread if there is still pending data. + * There really is nothing wrong with kicking the thread, even if there + * is no buffered data. */ if (hp->n_outbuf) hvc_kick(); @@ -604,13 +614,6 @@ static int hvc_poll(struct hvc_struct *hp) spin_unlock_irqrestore(&hp->lock, flags); tty_hangup(tty); spin_lock_irqsave(&hp->lock, flags); - } else if ( n == -EAGAIN ) { - /* - * Some back-ends can only ensure a certain min - * num of bytes read, which may be > 'count'. - * Let the tty clear the flip buff to make room. - */ - poll_mask |= HVC_POLL_READ; } break; } @@ -632,7 +635,16 @@ static int hvc_poll(struct hvc_struct *hp) tty_insert_flip_char(tty, buf[i], 0); } + /* + * Account for the total amount read in one loop, and if above + * 64 bytes, we do a quick schedule loop to let the tty grok + * the data and eventually throttle us. + */ read_total += n; + if (read_total >= 64) { + poll_mask |= HVC_POLL_QUICK; + break; + } } throttled: /* Wakeup write queue if necessary */ @@ -755,8 +767,7 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq, * see if this vterm id matches one registered for console. */ for (i=0; i < MAX_NR_HVC_CONSOLES; i++) - if (vtermnos[i] == hp->vtermno && - cons_ops[i] == hp->ops) + if (vtermnos[i] == hp->vtermno) break; /* no matching slot, just use a counter */ @@ -812,38 +823,34 @@ EXPORT_SYMBOL(hvc_remove); * interfaces start to become available. */ int __init hvc_init(void) { - struct tty_driver *drv; - /* We need more than hvc_count adapters due to hotplug additions. */ - drv = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS); - if (!drv) + hvc_driver = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS); + if (!hvc_driver) return -ENOMEM; - drv->owner = THIS_MODULE; - drv->devfs_name = "hvc/"; - drv->driver_name = "hvc"; - drv->name = "hvc"; - drv->major = HVC_MAJOR; - drv->minor_start = HVC_MINOR; - drv->type = TTY_DRIVER_TYPE_SYSTEM; - drv->init_termios = tty_std_termios; - drv->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(drv, &hvc_ops); + hvc_driver->owner = THIS_MODULE; + hvc_driver->devfs_name = "hvc/"; + hvc_driver->driver_name = "hvc"; + hvc_driver->name = "hvc"; + hvc_driver->major = HVC_MAJOR; + hvc_driver->minor_start = HVC_MINOR; + hvc_driver->type = TTY_DRIVER_TYPE_SYSTEM; + hvc_driver->init_termios = tty_std_termios; + hvc_driver->flags = TTY_DRIVER_REAL_RAW; + tty_set_operations(hvc_driver, &hvc_ops); /* Always start the kthread because there can be hotplug vty adapters * added later. */ hvc_task = kthread_run(khvcd, NULL, "khvcd"); if (IS_ERR(hvc_task)) { panic("Couldn't create kthread for console.\n"); - put_tty_driver(drv); + put_tty_driver(hvc_driver); return -EIO; } - if (tty_register_driver(drv)) + if (tty_register_driver(hvc_driver)) panic("Couldn't register hvc console driver\n"); - mb(); - hvc_driver = drv; return 0; } module_init(hvc_init); diff --git a/trunk/drivers/char/hvc_console.h b/trunk/drivers/char/hvc_console.h deleted file mode 100644 index 96b7401319c1..000000000000 --- a/trunk/drivers/char/hvc_console.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * hvc_console.h - * Copyright (C) 2005 IBM Corporation - * - * Author(s): - * Ryan S. Arnold - * - * hvc_console header information: - * moved here from include/asm-powerpc/hvconsole.h - * and drivers/char/hvc_console.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef HVC_CONSOLE_H -#define HVC_CONSOLE_H - -/* - * This is the max number of console adapters that can/will be found as - * console devices on first stage console init. Any number beyond this range - * can't be used as a console device but is still a valid tty device. - */ -#define MAX_NR_HVC_CONSOLES 16 - -/* - * The Linux TTY code does not support dynamic addition of tty derived devices - * so we need to know how many tty devices we might need when space is allocated - * for the tty device. Since this driver supports hotplug of vty adapters we - * need to make sure we have enough allocated. - */ -#define HVC_ALLOC_TTY_ADAPTERS 8 - - -/* implemented by a low level driver */ -struct hv_ops { - int (*get_chars)(uint32_t vtermno, char *buf, int count); - int (*put_chars)(uint32_t vtermno, const char *buf, int count); -}; - -struct hvc_struct; - -/* Register a vterm and a slot index for use as a console (console_init) */ -extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops); - -/* register a vterm for hvc tty operation (module_init or hotplug add) */ -extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq, - struct hv_ops *ops); -/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */ -extern int __devexit hvc_remove(struct hvc_struct *hp); - -#endif // HVC_CONSOLE_H diff --git a/trunk/drivers/char/hvc_rtas.c b/trunk/drivers/char/hvc_rtas.c deleted file mode 100644 index 83364ea63cba..000000000000 --- a/trunk/drivers/char/hvc_rtas.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * IBM RTAS driver interface to hvc_console.c - * - * (C) Copyright IBM Corporation 2001-2005 - * (C) Copyright Red Hat, Inc. 2005 - * - * Author(s): Maximino Augilar - * : Ryan S. Arnold - * : Utz Bacher - * : David Woodhouse - * - * inspired by drivers/char/hvc_console.c - * written by Anton Blanchard and Paul Mackerras - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include "hvc_console.h" - -#define hvc_rtas_cookie 0x67781e15 -struct hvc_struct *hvc_rtas_dev; - -#define RTASCONS_PUT_ATTEMPTS 16 - -static int rtascons_put_char_token = RTAS_UNKNOWN_SERVICE; -static int rtascons_get_char_token = RTAS_UNKNOWN_SERVICE; -static int rtascons_put_delay = 100; -module_param_named(put_delay, rtascons_put_delay, int, 0644); - -static inline int hvc_rtas_write_console(uint32_t vtermno, const char *buf, int count) -{ - int done; - - /* if there is more than one character to be displayed, wait a bit */ - for (done = 0; done < count; done++) { - int result; - result = rtas_call(rtascons_put_char_token, 1, 1, NULL, buf[done]); - if (result) - break; - } - /* the calling routine expects to receive the number of bytes sent */ - return done; -} - -static int hvc_rtas_read_console(uint32_t vtermno, char *buf, int count) -{ - int i; - - for (i = 0; i < count; i++) { - int c, err; - - err = rtas_call(rtascons_get_char_token, 0, 2, &c); - if (err) - break; - - buf[i] = c; - } - - return i; -} - -static struct hv_ops hvc_rtas_get_put_ops = { - .get_chars = hvc_rtas_read_console, - .put_chars = hvc_rtas_write_console, -}; - -static int hvc_rtas_init(void) -{ - struct hvc_struct *hp; - - if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE) - rtascons_put_char_token = rtas_token("put-term-char"); - if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE) - return -EIO; - - if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE) - rtascons_get_char_token = rtas_token("get-term-char"); - if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE) - return -EIO; - - BUG_ON(hvc_rtas_dev); - - /* Allocate an hvc_struct for the console device we instantiated - * earlier. Save off hp so that we can return it on exit */ - hp = hvc_alloc(hvc_rtas_cookie, NO_IRQ, &hvc_rtas_get_put_ops); - if (IS_ERR(hp)) - return PTR_ERR(hp); - hvc_rtas_dev = hp; - return 0; -} -module_init(hvc_rtas_init); - -/* This will tear down the tty portion of the driver */ -static void __exit hvc_rtas_exit(void) -{ - /* Really the fun isn't over until the worker thread breaks down and the - * tty cleans up */ - if (hvc_rtas_dev) - hvc_remove(hvc_rtas_dev); -} -module_exit(hvc_rtas_exit); - -/* This will happen prior to module init. There is no tty at this time? */ -static int hvc_rtas_console_init(void) -{ - rtascons_put_char_token = rtas_token("put-term-char"); - if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE) - return -EIO; - rtascons_get_char_token = rtas_token("get-term-char"); - if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE) - return -EIO; - - hvc_instantiate(hvc_rtas_cookie, 0, &hvc_rtas_get_put_ops ); - add_preferred_console("hvc", 0, NULL); - return 0; -} -console_initcall(hvc_rtas_console_init); diff --git a/trunk/drivers/char/hvc_vio.c b/trunk/drivers/char/hvc_vio.c index 9add81ceb440..f5212eb2b41d 100644 --- a/trunk/drivers/char/hvc_vio.c +++ b/trunk/drivers/char/hvc_vio.c @@ -31,13 +31,10 @@ #include #include - #include #include #include -#include "hvc_console.h" - char hvc_driver_name[] = "hvc_console"; static struct vio_device_id hvc_driver_table[] __devinitdata = { @@ -51,14 +48,6 @@ static int filtered_get_chars(uint32_t vtermno, char *buf, int count) unsigned long got; int i; - /* - * Vio firmware will read up to SIZE_VIO_GET_CHARS at its own discretion - * so we play safe and avoid the situation where got > count which could - * overload the flip buffer. - */ - if (count < SIZE_VIO_GET_CHARS) - return -EAGAIN; - got = hvc_get_chars(vtermno, buf, count); /* diff --git a/trunk/drivers/char/hvcs.c b/trunk/drivers/char/hvcs.c index 327b00c3c45e..f7ac31856572 100644 --- a/trunk/drivers/char/hvcs.c +++ b/trunk/drivers/char/hvcs.c @@ -439,6 +439,7 @@ static int hvcs_io(struct hvcs_struct *hvcsd) char buf[HVCS_BUFF_LEN] __ALIGNED__; unsigned long flags; int got = 0; + int i; spin_lock_irqsave(&hvcsd->lock, flags); diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index 0bfd1b63662e..811dadb9ce3e 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -1094,8 +1094,8 @@ static void do_tty_hangup(void *data) p->signal->tty = NULL; if (!p->signal->leader) continue; - group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); - group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); + send_group_sig_info(SIGHUP, SEND_SIG_PRIV, p); + send_group_sig_info(SIGCONT, SEND_SIG_PRIV, p); if (tty->pgrp > 0) p->signal->tty_old_pgrp = tty->pgrp; } while_each_task_pid(tty->session, PIDTYPE_SID, p); @@ -2672,7 +2672,7 @@ static void __do_SAK(void *arg) tty_hangup(tty); #else struct tty_struct *tty = arg; - struct task_struct *g, *p; + struct task_struct *p; int session; int i; struct file *filp; @@ -2693,18 +2693,8 @@ static void __do_SAK(void *arg) tty->driver->flush_buffer(tty); read_lock(&tasklist_lock); - /* Kill the entire session */ do_each_task_pid(session, PIDTYPE_SID, p) { - printk(KERN_NOTICE "SAK: killed process %d" - " (%s): p->signal->session==tty->session\n", - p->pid, p->comm); - send_sig(SIGKILL, p, 1); - } while_each_task_pid(session, PIDTYPE_SID, p); - /* Now kill any processes that happen to have the - * tty open. - */ - do_each_thread(g, p) { - if (p->signal->tty == tty) { + if (p->signal->tty == tty || session > 0) { printk(KERN_NOTICE "SAK: killed process %d" " (%s): p->signal->session==tty->session\n", p->pid, p->comm); @@ -2731,7 +2721,7 @@ static void __do_SAK(void *arg) rcu_read_unlock(); } task_unlock(p); - } while_each_thread(g, p); + } while_each_task_pid(session, PIDTYPE_SID, p); read_unlock(&tasklist_lock); #endif } diff --git a/trunk/drivers/ide/pci/via82cxxx.c b/trunk/drivers/ide/pci/via82cxxx.c index 3e677c4f8c28..c85b87cb59d1 100644 --- a/trunk/drivers/ide/pci/via82cxxx.c +++ b/trunk/drivers/ide/pci/via82cxxx.c @@ -440,7 +440,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) #if defined(CONFIG_PPC_CHRP) && defined(CONFIG_PPC32) - if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) { + if(_machine == _MACH_chrp && _chrp_type == _CHRP_Pegasos) { hwif->irq = hwif->channel ? 15 : 14; } #endif diff --git a/trunk/drivers/ide/ppc/pmac.c b/trunk/drivers/ide/ppc/pmac.c index 78e30f803671..5013b1285e22 100644 --- a/trunk/drivers/ide/ppc/pmac.c +++ b/trunk/drivers/ide/ppc/pmac.c @@ -1677,7 +1677,7 @@ MODULE_DEVICE_TABLE(pci, pmac_ide_pci_match); void __init pmac_ide_probe(void) { - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return; #ifdef CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST diff --git a/trunk/drivers/ieee1394/dv1394.c b/trunk/drivers/ieee1394/dv1394.c index 85c2d4ca0def..efeaa944bd0a 100644 --- a/trunk/drivers/ieee1394/dv1394.c +++ b/trunk/drivers/ieee1394/dv1394.c @@ -73,7 +73,7 @@ - fix all XXX showstoppers - disable IR/IT DMA interrupts on shutdown - flush pci writes to the card by issuing a read - - character device dispatching + - devfs and character device dispatching (* needs testing with Linux 2.2.x) - switch over to the new kernel DMA API (pci_map_*()) (* needs testing on platforms with IOMMU!) - keep all video_cards in a list (for open() via chardev), set file->private_data = video - dv1394_poll should indicate POLLIN when receiving buffers are available @@ -1096,6 +1096,7 @@ static int do_dv1394_init_default(struct video_card *video) init.api_version = DV1394_API_VERSION; init.n_frames = DV1394_MAX_FRAMES / 4; + /* the following are now set via devfs */ init.channel = video->channel; init.format = video->pal_or_ntsc; init.cip_n = video->cip_n; @@ -1790,6 +1791,8 @@ static int dv1394_open(struct inode *inode, struct file *file) { struct video_card *video = NULL; + /* if the device was opened through devfs, then file->private_data + has already been set to video by devfs */ if (file->private_data) { video = (struct video_card*) file->private_data; @@ -2208,7 +2211,7 @@ static int dv1394_init(struct ti_ohci *ohci, enum pal_or_ntsc format, enum modes video = kzalloc(sizeof(*video), GFP_KERNEL); if (!video) { printk(KERN_ERR "dv1394: cannot allocate video_card\n"); - return -1; + goto err; } video->ohci = ohci; @@ -2263,14 +2266,37 @@ static int dv1394_init(struct ti_ohci *ohci, enum pal_or_ntsc format, enum modes list_add_tail(&video->list, &dv1394_cards); spin_unlock_irqrestore(&dv1394_cards_lock, flags); + if (devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, + IEEE1394_MINOR_BLOCK_DV1394*16 + video->id), + S_IFCHR|S_IRUGO|S_IWUGO, + "ieee1394/dv/host%d/%s/%s", + (video->id>>2), + (video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"), + (video->mode == MODE_RECEIVE ? "in" : "out")) < 0) + goto err_free; + debug_printk("dv1394: dv1394_init() OK on ID %d\n", video->id); + return 0; + + err_free: + kfree(video); + err: + return -1; } static void dv1394_un_init(struct video_card *video) { + char buf[32]; + /* obviously nobody has the driver open at this point */ do_dv1394_shutdown(video, 1); + snprintf(buf, sizeof(buf), "dv/host%d/%s/%s", (video->id >> 2), + (video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"), + (video->mode == MODE_RECEIVE ? "in" : "out") + ); + + devfs_remove("ieee1394/%s", buf); kfree(video); } @@ -2307,6 +2333,9 @@ static void dv1394_remove_host (struct hpsb_host *host) class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2))); + devfs_remove("ieee1394/dv/host%d/NTSC", id); + devfs_remove("ieee1394/dv/host%d/PAL", id); + devfs_remove("ieee1394/dv/host%d", id); } static void dv1394_add_host (struct hpsb_host *host) @@ -2323,6 +2352,9 @@ static void dv1394_add_host (struct hpsb_host *host) class_device_create(hpsb_protocol_class, NULL, MKDEV( IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), NULL, "dv1394-%d", id); + devfs_mk_dir("ieee1394/dv/host%d", id); + devfs_mk_dir("ieee1394/dv/host%d/NTSC", id); + devfs_mk_dir("ieee1394/dv/host%d/PAL", id); dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE); dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT); @@ -2579,8 +2611,10 @@ MODULE_LICENSE("GPL"); static void __exit dv1394_exit_module(void) { hpsb_unregister_protocol(&dv1394_driver); + hpsb_unregister_highlevel(&dv1394_highlevel); cdev_del(&dv1394_cdev); + devfs_remove("ieee1394/dv"); } static int __init dv1394_init_module(void) @@ -2596,12 +2630,15 @@ static int __init dv1394_init_module(void) return ret; } + devfs_mk_dir("ieee1394/dv"); + hpsb_register_highlevel(&dv1394_highlevel); ret = hpsb_register_protocol(&dv1394_driver); if (ret) { printk(KERN_ERR "dv1394: failed to register protocol\n"); hpsb_unregister_highlevel(&dv1394_highlevel); + devfs_remove("ieee1394/dv"); cdev_del(&dv1394_cdev); return ret; } diff --git a/trunk/drivers/ieee1394/ieee1394_core.c b/trunk/drivers/ieee1394/ieee1394_core.c index be6854e25ad4..25ef5a86f5f0 100644 --- a/trunk/drivers/ieee1394/ieee1394_core.c +++ b/trunk/drivers/ieee1394/ieee1394_core.c @@ -58,7 +58,7 @@ MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality."); /* Disable Isochronous Resource Manager functionality */ int hpsb_disable_irm = 0; -module_param_named(disable_irm, hpsb_disable_irm, bool, 0444); +module_param_named(disable_irm, hpsb_disable_irm, bool, 0); MODULE_PARM_DESC(disable_irm, "Disable Isochronous Resource Manager functionality."); @@ -1078,10 +1078,17 @@ static int __init ieee1394_init(void) goto exit_release_kernel_thread; } + /* actually this is a non-fatal error */ + ret = devfs_mk_dir("ieee1394"); + if (ret < 0) { + HPSB_ERR("unable to make devfs dir for device major %d!\n", IEEE1394_MAJOR); + goto release_chrdev; + } + ret = bus_register(&ieee1394_bus_type); if (ret < 0) { HPSB_INFO("bus register failed"); - goto release_chrdev; + goto release_devfs; } for (i = 0; fw_bus_attrs[i]; i++) { @@ -1092,7 +1099,7 @@ static int __init ieee1394_init(void) fw_bus_attrs[i--]); } bus_unregister(&ieee1394_bus_type); - goto release_chrdev; + goto release_devfs; } } @@ -1145,6 +1152,8 @@ static int __init ieee1394_init(void) for (i = 0; fw_bus_attrs[i]; i++) bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]); bus_unregister(&ieee1394_bus_type); +release_devfs: + devfs_remove("ieee1394"); release_chrdev: unregister_chrdev_region(IEEE1394_CORE_DEV, 256); exit_release_kernel_thread: @@ -1182,6 +1191,7 @@ static void __exit ieee1394_cleanup(void) hpsb_cleanup_config_roms(); unregister_chrdev_region(IEEE1394_CORE_DEV, 256); + devfs_remove("ieee1394"); } module_init(ieee1394_init); diff --git a/trunk/drivers/ieee1394/ieee1394_core.h b/trunk/drivers/ieee1394/ieee1394_core.h index e7b55e895f50..b35466023f00 100644 --- a/trunk/drivers/ieee1394/ieee1394_core.h +++ b/trunk/drivers/ieee1394/ieee1394_core.h @@ -3,6 +3,7 @@ #define _IEEE1394_CORE_H #include +#include #include #include #include "hosts.h" @@ -201,12 +202,14 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size, #define IEEE1394_MINOR_BLOCK_RAW1394 0 #define IEEE1394_MINOR_BLOCK_VIDEO1394 1 #define IEEE1394_MINOR_BLOCK_DV1394 2 +#define IEEE1394_MINOR_BLOCK_AMDTP 3 #define IEEE1394_MINOR_BLOCK_EXPERIMENTAL 15 #define IEEE1394_CORE_DEV MKDEV(IEEE1394_MAJOR, 0) #define IEEE1394_RAW1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16) #define IEEE1394_VIDEO1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_VIDEO1394 * 16) #define IEEE1394_DV1394_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16) +#define IEEE1394_AMDTP_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_AMDTP * 16) #define IEEE1394_EXPERIMENTAL_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_EXPERIMENTAL * 16) /* return the index (within a minor number block) of a file */ diff --git a/trunk/drivers/ieee1394/ohci1394.c b/trunk/drivers/ieee1394/ohci1394.c index 19222878aae9..b6b96fa04d62 100644 --- a/trunk/drivers/ieee1394/ohci1394.c +++ b/trunk/drivers/ieee1394/ohci1394.c @@ -544,19 +544,12 @@ static void ohci_initialize(struct ti_ohci *ohci) /* Initialize IR Legacy DMA channel mask */ ohci->ir_legacy_channels = 0; - /* Accept AR requests from all nodes */ - reg_write(ohci, OHCI1394_AsReqFilterHiSet, 0x80000000); - - /* Set the address range of the physical response unit. - * Most controllers do not implement it as a writable register though. - * They will keep a hardwired offset of 0x00010000 and show 0x0 as - * register content. - * To actually enable physical responses is the job of our interrupt - * handler which programs the physical request filter. */ - reg_write(ohci, OHCI1394_PhyUpperBound, 0xffff0000); - - DBGMSG("physUpperBoundOffset=%08x", - reg_read(ohci, OHCI1394_PhyUpperBound)); + /* + * Accept AT requests from all nodes. This probably + * will have to be controlled from the subsystem + * on a per node basis. + */ + reg_write(ohci,OHCI1394_AsReqFilterHiSet, 0x80000000); /* Specify AT retries */ reg_write(ohci, OHCI1394_ATRetries, @@ -579,7 +572,6 @@ static void ohci_initialize(struct ti_ohci *ohci) OHCI1394_reqTxComplete | OHCI1394_isochRx | OHCI1394_isochTx | - OHCI1394_postedWriteErr | OHCI1394_cycleInconsistent); /* Enable link */ @@ -2382,10 +2374,7 @@ static irqreturn_t ohci_irq_handler(int irq, void *dev_id, event &= ~OHCI1394_unrecoverableError; } - if (event & OHCI1394_postedWriteErr) { - PRINT(KERN_ERR, "physical posted write error"); - /* no recovery strategy yet, had to involve protocol drivers */ - } + if (event & OHCI1394_cycleInconsistent) { /* We subscribe to the cycleInconsistent event only to * clear the corresponding event bit... otherwise, @@ -2393,6 +2382,7 @@ static irqreturn_t ohci_irq_handler(int irq, void *dev_id, DBGMSG("OHCI1394_cycleInconsistent"); event &= ~OHCI1394_cycleInconsistent; } + if (event & OHCI1394_busReset) { /* The busReset event bit can't be cleared during the * selfID phase, so we disable busReset interrupts, to @@ -2436,6 +2426,7 @@ static irqreturn_t ohci_irq_handler(int irq, void *dev_id, } event &= ~OHCI1394_busReset; } + if (event & OHCI1394_reqTxComplete) { struct dma_trm_ctx *d = &ohci->at_req_context; DBGMSG("Got reqTxComplete interrupt " @@ -2523,20 +2514,26 @@ static irqreturn_t ohci_irq_handler(int irq, void *dev_id, reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); spin_unlock_irqrestore(&ohci->event_lock, flags); + /* Accept Physical requests from all nodes. */ + reg_write(ohci,OHCI1394_AsReqFilterHiSet, 0xffffffff); + reg_write(ohci,OHCI1394_AsReqFilterLoSet, 0xffffffff); + /* Turn on phys dma reception. * * TODO: Enable some sort of filtering management. */ if (phys_dma) { - reg_write(ohci, OHCI1394_PhyReqFilterHiSet, - 0xffffffff); - reg_write(ohci, OHCI1394_PhyReqFilterLoSet, - 0xffffffff); + reg_write(ohci,OHCI1394_PhyReqFilterHiSet, 0xffffffff); + reg_write(ohci,OHCI1394_PhyReqFilterLoSet, 0xffffffff); + reg_write(ohci,OHCI1394_PhyUpperBound, 0xffff0000); + } else { + reg_write(ohci,OHCI1394_PhyReqFilterHiSet, 0x00000000); + reg_write(ohci,OHCI1394_PhyReqFilterLoSet, 0x00000000); } DBGMSG("PhyReqFilter=%08x%08x", - reg_read(ohci, OHCI1394_PhyReqFilterHiSet), - reg_read(ohci, OHCI1394_PhyReqFilterLoSet)); + reg_read(ohci,OHCI1394_PhyReqFilterHiSet), + reg_read(ohci,OHCI1394_PhyReqFilterLoSet)); hpsb_selfid_complete(host, phyid, isroot); } else @@ -3262,8 +3259,8 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, * fail to report the right length. Anyway, the ohci spec * clearly says it's 2kb, so this shouldn't be a problem. */ ohci_base = pci_resource_start(dev, 0); - if (pci_resource_len(dev, 0) < OHCI1394_REGISTER_SIZE) - PRINT(KERN_WARNING, "PCI resource length of %lx too small!", + if (pci_resource_len(dev, 0) != OHCI1394_REGISTER_SIZE) + PRINT(KERN_WARNING, "Unexpected PCI resource length of %lx!", pci_resource_len(dev, 0)); /* Seems PCMCIA handles this internally. Not sure why. Seems @@ -3529,7 +3526,7 @@ static void ohci1394_pci_remove(struct pci_dev *pdev) static int ohci1394_pci_resume (struct pci_dev *pdev) { #ifdef CONFIG_PPC_PMAC - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { struct device_node *of_node; /* Re-enable 1394 */ @@ -3548,7 +3545,7 @@ static int ohci1394_pci_resume (struct pci_dev *pdev) static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state) { #ifdef CONFIG_PPC_PMAC - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { struct device_node *of_node; /* Disable 1394 */ diff --git a/trunk/drivers/ieee1394/raw1394.c b/trunk/drivers/ieee1394/raw1394.c index f7de546f2ed6..19f26c5c9479 100644 --- a/trunk/drivers/ieee1394/raw1394.c +++ b/trunk/drivers/ieee1394/raw1394.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include "csr1212.h" @@ -2998,6 +2999,9 @@ static int __init init_raw1394(void) goto out_unreg; } + devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), + S_IFCHR | S_IRUSR | S_IWUSR, RAW1394_DEVICE_NAME); + cdev_init(&raw1394_cdev, &raw1394_fops); raw1394_cdev.owner = THIS_MODULE; kobject_set_name(&raw1394_cdev.kobj, RAW1394_DEVICE_NAME); @@ -3019,6 +3023,7 @@ static int __init init_raw1394(void) goto out; out_dev: + devfs_remove(RAW1394_DEVICE_NAME); class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16)); @@ -3034,6 +3039,7 @@ static void __exit cleanup_raw1394(void) MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16)); cdev_del(&raw1394_cdev); + devfs_remove(RAW1394_DEVICE_NAME); hpsb_unregister_highlevel(&raw1394_highlevel); hpsb_unregister_protocol(&raw1394_driver); } diff --git a/trunk/drivers/ieee1394/sbp2.c b/trunk/drivers/ieee1394/sbp2.c index 2c765ca5aa50..eca92eb475a1 100644 --- a/trunk/drivers/ieee1394/sbp2.c +++ b/trunk/drivers/ieee1394/sbp2.c @@ -214,7 +214,6 @@ static u32 global_outstanding_dmas = 0; #endif #define SBP2_ERR(fmt, args...) HPSB_ERR("sbp2: "fmt, ## args) -#define SBP2_DEBUG_ENTER() SBP2_DEBUG("%s", __FUNCTION__) /* * Globals @@ -536,7 +535,7 @@ static struct sbp2_command_info *sbp2util_allocate_command_orb( command->Current_SCpnt = Current_SCpnt; list_add_tail(&command->list, &scsi_id->sbp2_command_orb_inuse); } else { - SBP2_ERR("%s: no orbs available", __FUNCTION__); + SBP2_ERR("sbp2util_allocate_command_orb - No orbs available!"); } spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); return command; @@ -550,7 +549,7 @@ static void sbp2util_free_command_dma(struct sbp2_command_info *command) struct hpsb_host *host; if (!scsi_id) { - SBP2_ERR("%s: scsi_id == NULL", __FUNCTION__); + printk(KERN_ERR "%s: scsi_id == NULL\n", __FUNCTION__); return; } @@ -611,7 +610,7 @@ static int sbp2_probe(struct device *dev) struct unit_directory *ud; struct scsi_id_instance_data *scsi_id; - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_probe"); ud = container_of(dev, struct unit_directory, device); @@ -636,7 +635,7 @@ static int sbp2_remove(struct device *dev) struct scsi_id_instance_data *scsi_id; struct scsi_device *sdev; - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_remove"); ud = container_of(dev, struct unit_directory, device); scsi_id = ud->device.driver_data; @@ -668,7 +667,7 @@ static int sbp2_update(struct unit_directory *ud) { struct scsi_id_instance_data *scsi_id = ud->device.driver_data; - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_update"); if (sbp2_reconnect_device(scsi_id)) { @@ -716,7 +715,7 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud struct Scsi_Host *scsi_host = NULL; struct scsi_id_instance_data *scsi_id = NULL; - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_alloc_device"); scsi_id = kzalloc(sizeof(*scsi_id), GFP_KERNEL); if (!scsi_id) { @@ -750,22 +749,12 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud #ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA /* Handle data movement if physical dma is not - * enabled or not supported on host controller */ - if (!hpsb_register_addrspace(&sbp2_highlevel, ud->ne->host, - &sbp2_physdma_ops, - 0x0ULL, 0xfffffffcULL)) { - SBP2_ERR("failed to register lower 4GB address range"); - goto failed_alloc; - } + * enabled/supportedon host controller */ + hpsb_register_addrspace(&sbp2_highlevel, ud->ne->host, &sbp2_physdma_ops, + 0x0ULL, 0xfffffffcULL); #endif } - /* Prevent unloading of the 1394 host */ - if (!try_module_get(hi->host->driver->owner)) { - SBP2_ERR("failed to get a reference on 1394 host driver"); - goto failed_alloc; - } - scsi_id->hi = hi; list_add_tail(&scsi_id->scsi_list, &hi->scsi_ids); @@ -827,7 +816,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id) struct sbp2scsi_host_info *hi = scsi_id->hi; int error; - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_start_device"); /* Login FIFO DMA */ scsi_id->login_response = @@ -902,6 +891,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id) * allows someone else to login instead. One second makes sense. */ msleep_interruptible(1000); if (signal_pending(current)) { + SBP2_WARN("aborting sbp2_start_device due to event"); sbp2_remove_device(scsi_id); return -EINTR; } @@ -954,7 +944,7 @@ static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id) { struct sbp2scsi_host_info *hi; - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_remove_device"); if (!scsi_id) return; @@ -1025,9 +1015,6 @@ static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id) scsi_id->ud->device.driver_data = NULL; - if (hi) - module_put(hi->host->driver->owner); - SBP2_DEBUG("SBP-2 device removed, SCSI ID = %d", scsi_id->ud->id); kfree(scsi_id); @@ -1086,20 +1073,23 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id) int max_logins; int active_logins; - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_query_logins"); scsi_id->query_logins_orb->reserved1 = 0x0; scsi_id->query_logins_orb->reserved2 = 0x0; scsi_id->query_logins_orb->query_response_lo = scsi_id->query_logins_response_dma; scsi_id->query_logins_orb->query_response_hi = ORB_SET_NODE_ID(hi->host->node_id); + SBP2_DEBUG("sbp2_query_logins: query_response_hi/lo initialized"); scsi_id->query_logins_orb->lun_misc = ORB_SET_FUNCTION(SBP2_QUERY_LOGINS_REQUEST); scsi_id->query_logins_orb->lun_misc |= ORB_SET_NOTIFY(1); scsi_id->query_logins_orb->lun_misc |= ORB_SET_LUN(scsi_id->sbp2_lun); + SBP2_DEBUG("sbp2_query_logins: lun_misc initialized"); scsi_id->query_logins_orb->reserved_resp_length = ORB_SET_QUERY_LOGINS_RESP_LENGTH(sizeof(struct sbp2_query_logins_response)); + SBP2_DEBUG("sbp2_query_logins: reserved_resp_length initialized"); scsi_id->query_logins_orb->status_fifo_hi = ORB_SET_STATUS_FIFO_HI(scsi_id->status_fifo_addr, hi->host->node_id); @@ -1108,19 +1098,25 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id) sbp2util_cpu_to_be32_buffer(scsi_id->query_logins_orb, sizeof(struct sbp2_query_logins_orb)); + SBP2_DEBUG("sbp2_query_logins: orb byte-swapped"); + sbp2util_packet_dump(scsi_id->query_logins_orb, sizeof(struct sbp2_query_logins_orb), "sbp2 query logins orb", scsi_id->query_logins_orb_dma); memset(scsi_id->query_logins_response, 0, sizeof(struct sbp2_query_logins_response)); memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block)); + SBP2_DEBUG("sbp2_query_logins: query_logins_response/status FIFO memset"); + data[0] = ORB_SET_NODE_ID(hi->host->node_id); data[1] = scsi_id->query_logins_orb_dma; sbp2util_cpu_to_be32_buffer(data, 8); atomic_set(&scsi_id->sbp2_login_complete, 0); + SBP2_DEBUG("sbp2_query_logins: prepared to write"); hpsb_node_write(scsi_id->ne, scsi_id->sbp2_management_agent_addr, data, 8); + SBP2_DEBUG("sbp2_query_logins: written"); if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, 2*HZ)) { SBP2_INFO("Error querying logins to SBP-2 device - timed out"); @@ -1169,10 +1165,10 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id) struct sbp2scsi_host_info *hi = scsi_id->hi; quadlet_t data[2]; - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_login_device"); if (!scsi_id->login_orb) { - SBP2_DEBUG("%s: login_orb not alloc'd!", __FUNCTION__); + SBP2_DEBUG("sbp2_login_device: login_orb not alloc'd!"); return -EIO; } @@ -1186,39 +1182,59 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id) /* Set-up login ORB, assume no password */ scsi_id->login_orb->password_hi = 0; scsi_id->login_orb->password_lo = 0; + SBP2_DEBUG("sbp2_login_device: password_hi/lo initialized"); scsi_id->login_orb->login_response_lo = scsi_id->login_response_dma; scsi_id->login_orb->login_response_hi = ORB_SET_NODE_ID(hi->host->node_id); + SBP2_DEBUG("sbp2_login_device: login_response_hi/lo initialized"); scsi_id->login_orb->lun_misc = ORB_SET_FUNCTION(SBP2_LOGIN_REQUEST); scsi_id->login_orb->lun_misc |= ORB_SET_RECONNECT(0); /* One second reconnect time */ scsi_id->login_orb->lun_misc |= ORB_SET_EXCLUSIVE(exclusive_login); /* Exclusive access to device */ scsi_id->login_orb->lun_misc |= ORB_SET_NOTIFY(1); /* Notify us of login complete */ scsi_id->login_orb->lun_misc |= ORB_SET_LUN(scsi_id->sbp2_lun); + SBP2_DEBUG("sbp2_login_device: lun_misc initialized"); scsi_id->login_orb->passwd_resp_lengths = ORB_SET_LOGIN_RESP_LENGTH(sizeof(struct sbp2_login_response)); + SBP2_DEBUG("sbp2_login_device: passwd_resp_lengths initialized"); scsi_id->login_orb->status_fifo_hi = ORB_SET_STATUS_FIFO_HI(scsi_id->status_fifo_addr, hi->host->node_id); scsi_id->login_orb->status_fifo_lo = ORB_SET_STATUS_FIFO_LO(scsi_id->status_fifo_addr); + /* + * Byte swap ORB if necessary + */ sbp2util_cpu_to_be32_buffer(scsi_id->login_orb, sizeof(struct sbp2_login_orb)); + SBP2_DEBUG("sbp2_login_device: orb byte-swapped"); + sbp2util_packet_dump(scsi_id->login_orb, sizeof(struct sbp2_login_orb), "sbp2 login orb", scsi_id->login_orb_dma); + /* + * Initialize login response and status fifo + */ memset(scsi_id->login_response, 0, sizeof(struct sbp2_login_response)); memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block)); + SBP2_DEBUG("sbp2_login_device: login_response/status FIFO memset"); + + /* + * Ok, let's write to the target's management agent register + */ data[0] = ORB_SET_NODE_ID(hi->host->node_id); data[1] = scsi_id->login_orb_dma; sbp2util_cpu_to_be32_buffer(data, 8); atomic_set(&scsi_id->sbp2_login_complete, 0); + SBP2_DEBUG("sbp2_login_device: prepared to write to %08x", + (unsigned int)scsi_id->sbp2_management_agent_addr); hpsb_node_write(scsi_id->ne, scsi_id->sbp2_management_agent_addr, data, 8); + SBP2_DEBUG("sbp2_login_device: written"); /* * Wait for login status (up to 20 seconds)... @@ -1282,7 +1298,7 @@ static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id) quadlet_t data[2]; int error; - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_logout_device"); /* * Set-up logout ORB @@ -1346,7 +1362,7 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id) quadlet_t data[2]; int error; - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_reconnect_device"); /* * Set-up reconnect ORB @@ -1437,11 +1453,17 @@ static int sbp2_set_busy_timeout(struct scsi_id_instance_data *scsi_id) { quadlet_t data; - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_set_busy_timeout"); + /* + * Ok, let's write to the target's busy timeout register + */ data = cpu_to_be32(SBP2_BUSY_TIMEOUT_VALUE); - if (hpsb_node_write(scsi_id->ne, SBP2_BUSY_TIMEOUT_ADDRESS, &data, 4)) - SBP2_ERR("%s error", __FUNCTION__); + + if (hpsb_node_write(scsi_id->ne, SBP2_BUSY_TIMEOUT_ADDRESS, &data, 4)) { + SBP2_ERR("sbp2_set_busy_timeout error"); + } + return 0; } @@ -1460,7 +1482,7 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, firmware_revision, workarounds; int i; - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_parse_unit_directory"); management_agent_addr = 0x0; command_set_spec_id = 0x0; @@ -1593,7 +1615,7 @@ static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id) { struct sbp2scsi_host_info *hi = scsi_id->hi; - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_max_speed_and_size"); /* Initial setting comes from the hosts speed map */ scsi_id->speed_code = @@ -1630,8 +1652,11 @@ static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait) u64 addr; int retval; - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_agent_reset"); + /* + * Ok, let's write to the target's management agent register + */ data = ntohl(SBP2_AGENT_RESET_DATA); addr = scsi_id->sbp2_command_block_agent_addr + SBP2_AGENT_RESET_OFFSET; @@ -1979,7 +2004,11 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id, unsigned int request_bufflen = SCpnt->request_bufflen; struct sbp2_command_info *command; - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_send_command"); +#if (CONFIG_IEEE1394_SBP2_DEBUG >= 2) || defined(CONFIG_IEEE1394_SBP2_PACKET_DUMP) + printk("[scsi command]\n "); + scsi_print_command(SCpnt); +#endif SBP2_DEBUG("SCSI transfer size = %x", request_bufflen); SBP2_DEBUG("SCSI s/g elements = %x", (unsigned int)SCpnt->use_sg); @@ -2019,7 +2048,7 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id, */ static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense_data) { - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_status_to_sense_data"); /* * Ok, it's pretty ugly... ;-) @@ -2053,7 +2082,7 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, { u8 *scsi_buf = SCpnt->request_buffer; - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_check_sbp2_response"); if (SCpnt->cmnd[0] == INQUIRY && (SCpnt->cmnd[1] & 3) == 0) { /* @@ -2084,7 +2113,7 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest struct sbp2_command_info *command; unsigned long flags; - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_handle_status_write"); sbp2util_packet_dump(data, length, "sbp2 status write by device", (u32)addr); @@ -2231,10 +2260,7 @@ static int sbp2scsi_queuecommand(struct scsi_cmnd *SCpnt, struct sbp2scsi_host_info *hi; int result = DID_NO_CONNECT << 16; - SBP2_DEBUG_ENTER(); -#if (CONFIG_IEEE1394_SBP2_DEBUG >= 2) || defined(CONFIG_IEEE1394_SBP2_PACKET_DUMP) - scsi_print_command(SCpnt); -#endif + SBP2_DEBUG("sbp2scsi_queuecommand"); if (!sbp2util_node_is_available(scsi_id)) goto done; @@ -2312,7 +2338,7 @@ static void sbp2scsi_complete_all_commands(struct scsi_id_instance_data *scsi_id struct sbp2_command_info *command; unsigned long flags; - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2scsi_complete_all_commands"); spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); while (!list_empty(&scsi_id->sbp2_command_orb_inuse)) { @@ -2345,7 +2371,7 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, u32 scsi_status, struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) { - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2scsi_complete_command"); /* * Sanity @@ -2371,7 +2397,7 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, */ switch (scsi_status) { case SBP2_SCSI_STATUS_GOOD: - SCpnt->result = DID_OK << 16; + SCpnt->result = DID_OK; break; case SBP2_SCSI_STATUS_BUSY: @@ -2381,11 +2407,16 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, case SBP2_SCSI_STATUS_CHECK_CONDITION: SBP2_DEBUG("SBP2_SCSI_STATUS_CHECK_CONDITION"); - SCpnt->result = CHECK_CONDITION << 1 | DID_OK << 16; + SCpnt->result = CHECK_CONDITION << 1; + + /* + * Debug stuff + */ #if CONFIG_IEEE1394_SBP2_DEBUG >= 1 scsi_print_command(SCpnt); - scsi_print_sense(SBP2_DEVICE_NAME, SCpnt); + scsi_print_sense("bh", SCpnt); #endif + break; case SBP2_SCSI_STATUS_SELECTION_TIMEOUT: @@ -2410,7 +2441,7 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, /* * Take care of any sbp2 response data mucking here (RBC stuff, etc.) */ - if (SCpnt->result == DID_OK << 16) { + if (SCpnt->result == DID_OK) { sbp2_check_sbp2_response(scsi_id, SCpnt); } @@ -2428,8 +2459,6 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, * If a unit attention occurs, return busy status so it gets * retried... it could have happened because of a 1394 bus reset * or hot-plug... - * XXX DID_BUS_BUSY is actually a bad idea because it will defy - * the scsi layer's retry logic. */ #if 0 if ((scsi_status == SBP2_SCSI_STATUS_CHECK_CONDITION) && @@ -2595,7 +2624,7 @@ static int sbp2_module_init(void) { int ret; - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_module_init"); /* Module load debug option to force one command at a time (serializing I/O) */ if (serialize_io) { @@ -2623,7 +2652,7 @@ static int sbp2_module_init(void) static void __exit sbp2_module_exit(void) { - SBP2_DEBUG_ENTER(); + SBP2_DEBUG("sbp2_module_exit"); hpsb_unregister_protocol(&sbp2_driver); diff --git a/trunk/drivers/ieee1394/video1394.c b/trunk/drivers/ieee1394/video1394.c index 4e3bd62c458d..216dbbf1dc8e 100644 --- a/trunk/drivers/ieee1394/video1394.c +++ b/trunk/drivers/ieee1394/video1394.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -1321,6 +1322,9 @@ static void video1394_add_host (struct hpsb_host *host) class_device_create(hpsb_protocol_class, NULL, MKDEV( IEEE1394_MAJOR, minor), NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id); + devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, minor), + S_IFCHR | S_IRUSR | S_IWUSR, + "%s/%d", VIDEO1394_DRIVER_NAME, ohci->host->id); } @@ -1328,9 +1332,12 @@ static void video1394_remove_host (struct hpsb_host *host) { struct ti_ohci *ohci = hpsb_get_hostinfo(&video1394_highlevel, host); - if (ohci) + if (ohci) { class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id)); + devfs_remove("%s/%d", VIDEO1394_DRIVER_NAME, ohci->host->id); + } + return; } @@ -1471,8 +1478,12 @@ static long video1394_compat_ioctl(struct file *f, unsigned cmd, unsigned long a static void __exit video1394_exit_module (void) { hpsb_unregister_protocol(&video1394_driver); + hpsb_unregister_highlevel(&video1394_highlevel); + + devfs_remove(VIDEO1394_DRIVER_NAME); cdev_del(&video1394_cdev); + PRINT_G(KERN_INFO, "Removed " VIDEO1394_DRIVER_NAME " module"); } @@ -1489,12 +1500,15 @@ static int __init video1394_init_module (void) return ret; } + devfs_mk_dir(VIDEO1394_DRIVER_NAME); + hpsb_register_highlevel(&video1394_highlevel); ret = hpsb_register_protocol(&video1394_driver); if (ret) { PRINT_G(KERN_ERR, "video1394: failed to register protocol"); hpsb_unregister_highlevel(&video1394_highlevel); + devfs_remove(VIDEO1394_DRIVER_NAME); cdev_del(&video1394_cdev); return ret; } diff --git a/trunk/drivers/macintosh/adb.c b/trunk/drivers/macintosh/adb.c index 259fd8973ce9..34fcabac5fdb 100644 --- a/trunk/drivers/macintosh/adb.c +++ b/trunk/drivers/macintosh/adb.c @@ -42,7 +42,6 @@ #include #ifdef CONFIG_PPC #include -#include #endif @@ -295,7 +294,7 @@ int __init adb_init(void) int i; #ifdef CONFIG_PPC32 - if (!machine_is(chrp) && !machine_is(powermac)) + if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) ) return 0; #endif #ifdef CONFIG_MAC diff --git a/trunk/drivers/macintosh/adbhid.c b/trunk/drivers/macintosh/adbhid.c index 394334ec5765..f5779a73184d 100644 --- a/trunk/drivers/macintosh/adbhid.c +++ b/trunk/drivers/macintosh/adbhid.c @@ -1206,8 +1206,8 @@ init_ms_a3(int id) static int __init adbhid_init(void) { #ifndef CONFIG_MAC - if (!machine_is(chrp) && !machine_is(powermac)) - return 0; + if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) ) + return 0; #endif led_request.complete = 1; diff --git a/trunk/drivers/macintosh/mediabay.c b/trunk/drivers/macintosh/mediabay.c index 53c1c7909413..8dbf2852bae0 100644 --- a/trunk/drivers/macintosh/mediabay.c +++ b/trunk/drivers/macintosh/mediabay.c @@ -839,8 +839,8 @@ static int __init media_bay_init(void) media_bays[i].cd_index = -1; #endif } - if (!machine_is(powermac)) - return 0; + if (_machine != _MACH_Pmac) + return -ENODEV; macio_register_driver(&media_bay_driver); diff --git a/trunk/drivers/media/video/planb.c b/trunk/drivers/media/video/planb.c index d9e3cada52f4..522e9ddeb089 100644 --- a/trunk/drivers/media/video/planb.c +++ b/trunk/drivers/media/video/planb.c @@ -2156,7 +2156,7 @@ static int find_planb(void) struct pci_dev *pdev; int rc; - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return 0; planb_devices = find_devices("planb"); diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index b5473325bff4..c41dbb0e8f14 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -10531,6 +10531,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) { struct net_device *dev = tp->dev; u32 hi, lo, mac_offset; + int addr_ok = 0; #ifdef CONFIG_SPARC64 if (!tg3_get_macaddr_sparc(tp)) @@ -10560,29 +10561,34 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) dev->dev_addr[3] = (lo >> 16) & 0xff; dev->dev_addr[4] = (lo >> 8) & 0xff; dev->dev_addr[5] = (lo >> 0) & 0xff; - } - /* Next, try NVRAM. */ - else if (!(tp->tg3_flags & TG3_FLG2_SUN_570X) && - !tg3_nvram_read(tp, mac_offset + 0, &hi) && - !tg3_nvram_read(tp, mac_offset + 4, &lo)) { - dev->dev_addr[0] = ((hi >> 16) & 0xff); - dev->dev_addr[1] = ((hi >> 24) & 0xff); - dev->dev_addr[2] = ((lo >> 0) & 0xff); - dev->dev_addr[3] = ((lo >> 8) & 0xff); - dev->dev_addr[4] = ((lo >> 16) & 0xff); - dev->dev_addr[5] = ((lo >> 24) & 0xff); - } - /* Finally just fetch it out of the MAC control regs. */ - else { - hi = tr32(MAC_ADDR_0_HIGH); - lo = tr32(MAC_ADDR_0_LOW); - dev->dev_addr[5] = lo & 0xff; - dev->dev_addr[4] = (lo >> 8) & 0xff; - dev->dev_addr[3] = (lo >> 16) & 0xff; - dev->dev_addr[2] = (lo >> 24) & 0xff; - dev->dev_addr[1] = hi & 0xff; - dev->dev_addr[0] = (hi >> 8) & 0xff; + /* Some old bootcode may report a 0 MAC address in SRAM */ + addr_ok = is_valid_ether_addr(&dev->dev_addr[0]); + } + if (!addr_ok) { + /* Next, try NVRAM. */ + if (!(tp->tg3_flags & TG3_FLG2_SUN_570X) && + !tg3_nvram_read(tp, mac_offset + 0, &hi) && + !tg3_nvram_read(tp, mac_offset + 4, &lo)) { + dev->dev_addr[0] = ((hi >> 16) & 0xff); + dev->dev_addr[1] = ((hi >> 24) & 0xff); + dev->dev_addr[2] = ((lo >> 0) & 0xff); + dev->dev_addr[3] = ((lo >> 8) & 0xff); + dev->dev_addr[4] = ((lo >> 16) & 0xff); + dev->dev_addr[5] = ((lo >> 24) & 0xff); + } + /* Finally just fetch it out of the MAC control regs. */ + else { + hi = tr32(MAC_ADDR_0_HIGH); + lo = tr32(MAC_ADDR_0_LOW); + + dev->dev_addr[5] = lo & 0xff; + dev->dev_addr[4] = (lo >> 8) & 0xff; + dev->dev_addr[3] = (lo >> 16) & 0xff; + dev->dev_addr[2] = (lo >> 24) & 0xff; + dev->dev_addr[1] = hi & 0xff; + dev->dev_addr[0] = (hi >> 8) & 0xff; + } } if (!is_valid_ether_addr(&dev->dev_addr[0])) { diff --git a/trunk/drivers/net/tulip/de4x5.c b/trunk/drivers/net/tulip/de4x5.c index f56094102042..d1a86a080a65 100644 --- a/trunk/drivers/net/tulip/de4x5.c +++ b/trunk/drivers/net/tulip/de4x5.c @@ -4160,7 +4160,7 @@ get_hw_addr(struct net_device *dev) ** If the address starts with 00 a0, we have to bit-reverse ** each byte of the address. */ - if ( machine_is(powermac) && + if ( (_machine & _MACH_Pmac) && (dev->dev_addr[0] == 0) && (dev->dev_addr[1] == 0xa0) ) { diff --git a/trunk/drivers/scsi/mesh.c b/trunk/drivers/scsi/mesh.c index f852421002ef..d6d2125f9044 100644 --- a/trunk/drivers/scsi/mesh.c +++ b/trunk/drivers/scsi/mesh.c @@ -1748,7 +1748,7 @@ static int mesh_host_reset(struct scsi_cmnd *cmd) static void set_mesh_power(struct mesh_state *ms, int state) { - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return; if (state) { pmac_call_feature(PMAC_FTR_MESH_ENABLE, macio_get_of_node(ms->mdev), 0, 1); diff --git a/trunk/drivers/usb/core/hcd-pci.c b/trunk/drivers/usb/core/hcd-pci.c index 0d2193b69235..e0afb5ad29e5 100644 --- a/trunk/drivers/usb/core/hcd-pci.c +++ b/trunk/drivers/usb/core/hcd-pci.c @@ -296,7 +296,7 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) #ifdef CONFIG_PPC_PMAC /* Disable ASIC clocks for USB */ - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { struct device_node *of_node; of_node = pci_device_to_OF_node (dev); @@ -331,7 +331,7 @@ int usb_hcd_pci_resume (struct pci_dev *dev) #ifdef CONFIG_PPC_PMAC /* Reenable ASIC clocks for USB */ - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { struct device_node *of_node; of_node = pci_device_to_OF_node (dev); diff --git a/trunk/drivers/video/aty/aty128fb.c b/trunk/drivers/video/aty/aty128fb.c index f7bbff4ddc6a..821c6da8e42c 100644 --- a/trunk/drivers/video/aty/aty128fb.c +++ b/trunk/drivers/video/aty/aty128fb.c @@ -67,7 +67,6 @@ #include #ifdef CONFIG_PPC_PMAC -#include #include #include #include @@ -1749,7 +1748,7 @@ static int __init aty128_init(struct pci_dev *pdev, const struct pci_device_id * var = default_var; #ifdef CONFIG_PPC_PMAC - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { /* Indicate sleep capability */ if (par->chip_gen == rage_M3) { pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, NULL, 0, 1); @@ -2012,7 +2011,7 @@ static int aty128fb_blank(int blank, struct fb_info *fb) return 0; #ifdef CONFIG_PMAC_BACKLIGHT - if (machine_is(powermac) && blank) + if ((_machine == _MACH_Pmac) && blank) set_backlight_enable(0); #endif /* CONFIG_PMAC_BACKLIGHT */ @@ -2030,7 +2029,7 @@ static int aty128fb_blank(int blank, struct fb_info *fb) aty128_set_lcd_enable(par, par->lcd_on && !blank); } #ifdef CONFIG_PMAC_BACKLIGHT - if (machine_is(powermac) && !blank) + if ((_machine == _MACH_Pmac) && !blank) set_backlight_enable(1); #endif /* CONFIG_PMAC_BACKLIGHT */ return 0; diff --git a/trunk/drivers/video/aty/atyfb_base.c b/trunk/drivers/video/aty/atyfb_base.c index b39e72d5413b..e799fcca365a 100644 --- a/trunk/drivers/video/aty/atyfb_base.c +++ b/trunk/drivers/video/aty/atyfb_base.c @@ -75,7 +75,6 @@ #include "ati_ids.h" #ifdef __powerpc__ -#include #include #include "../macmodes.h" #endif @@ -2519,7 +2518,7 @@ static int __init aty_init(struct fb_info *info, const char *name) memset(&var, 0, sizeof(var)); #ifdef CONFIG_PPC - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { /* * FIXME: The NVRAM stuff should be put in a Mac-specific file, as it * applies to all Mac video cards @@ -2674,7 +2673,7 @@ static int atyfb_blank(int blank, struct fb_info *info) return 0; #ifdef CONFIG_PMAC_BACKLIGHT - if (machine_is(powermac) && blank > FB_BLANK_NORMAL) + if ((_machine == _MACH_Pmac) && blank > FB_BLANK_NORMAL) set_backlight_enable(0); #elif defined(CONFIG_FB_ATY_GENERIC_LCD) if (par->lcd_table && blank > FB_BLANK_NORMAL && @@ -2706,7 +2705,7 @@ static int atyfb_blank(int blank, struct fb_info *info) aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); #ifdef CONFIG_PMAC_BACKLIGHT - if (machine_is(powermac) && blank <= FB_BLANK_NORMAL) + if ((_machine == _MACH_Pmac) && blank <= FB_BLANK_NORMAL) set_backlight_enable(1); #elif defined(CONFIG_FB_ATY_GENERIC_LCD) if (par->lcd_table && blank <= FB_BLANK_NORMAL && diff --git a/trunk/drivers/video/aty/radeon_pm.c b/trunk/drivers/video/aty/radeon_pm.c index c7091761cef4..5886a2f1323e 100644 --- a/trunk/drivers/video/aty/radeon_pm.c +++ b/trunk/drivers/video/aty/radeon_pm.c @@ -20,7 +20,7 @@ #include #ifdef CONFIG_PPC_PMAC -#include +#include #include #include #endif @@ -2745,7 +2745,7 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk) rinfo->pm_mode |= radeon_pm_off; } #if defined(CONFIG_PPC_PMAC) - if (machine_is(powermac) && rinfo->of_node) { + if (_machine == _MACH_Pmac && rinfo->of_node) { if (rinfo->is_mobility && rinfo->pm_reg && rinfo->family <= CHIP_FAMILY_RV250) rinfo->pm_mode |= radeon_pm_d2; diff --git a/trunk/drivers/video/cirrusfb.c b/trunk/drivers/video/cirrusfb.c index 1103010af54a..66d6f2f0a219 100644 --- a/trunk/drivers/video/cirrusfb.c +++ b/trunk/drivers/video/cirrusfb.c @@ -60,8 +60,8 @@ #include #endif #ifdef CONFIG_PPC_PREP -#include -#define isPReP (machine_is(prep)) +#include +#define isPReP (_machine == _MACH_prep) #else #define isPReP 0 #endif diff --git a/trunk/drivers/video/matrox/matroxfb_base.c b/trunk/drivers/video/matrox/matroxfb_base.c index 23c1827b2d0b..951c9974a1d3 100644 --- a/trunk/drivers/video/matrox/matroxfb_base.c +++ b/trunk/drivers/video/matrox/matroxfb_base.c @@ -115,7 +115,6 @@ #include #ifdef CONFIG_PPC_PMAC -#include unsigned char nvram_read_byte(int); static int default_vmode = VMODE_NVRAM; static int default_cmode = CMODE_NVRAM; @@ -1834,7 +1833,7 @@ static int initMatrox2(WPMINFO struct board* b){ /* FIXME: Where to move this?! */ #if defined(CONFIG_PPC_PMAC) #ifndef MODULE - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { struct fb_var_screeninfo var; if (default_vmode <= 0 || default_vmode > VMODE_MAX) default_vmode = VMODE_640_480_60; diff --git a/trunk/drivers/video/nvidia/nvidia.c b/trunk/drivers/video/nvidia/nvidia.c index 093ab9977c7c..6d3e4890cb43 100644 --- a/trunk/drivers/video/nvidia/nvidia.c +++ b/trunk/drivers/video/nvidia/nvidia.c @@ -30,7 +30,6 @@ #include #endif #ifdef CONFIG_PMAC_BACKLIGHT -#include #include #endif @@ -1356,7 +1355,7 @@ static int nvidiafb_blank(int blank, struct fb_info *info) NVWriteCrtc(par, 0x1a, vesa); #ifdef CONFIG_PMAC_BACKLIGHT - if (par->FlatPanel && machine_is(powermac)) { + if (par->FlatPanel && _machine == _MACH_Pmac) { set_backlight_enable(!blank); } #endif @@ -1742,7 +1741,7 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, info->fix.id, par->FbMapSize / (1024 * 1024), info->fix.smem_start); #ifdef CONFIG_PMAC_BACKLIGHT - if (par->FlatPanel && machine_is(powermac)) + if (par->FlatPanel && _machine == _MACH_Pmac) register_backlight_controller(&nvidia_backlight_controller, par, "mnca"); #endif diff --git a/trunk/drivers/video/radeonfb.c b/trunk/drivers/video/radeonfb.c index afb6c2ead599..24982adb3aa2 100644 --- a/trunk/drivers/video/radeonfb.c +++ b/trunk/drivers/video/radeonfb.c @@ -1596,7 +1596,7 @@ static int radeonfb_blank (int blank, struct fb_info *info) return 0; #ifdef CONFIG_PMAC_BACKLIGHT - if (rinfo->dviDisp_type == MT_LCD && machine_is(powermac)) { + if (rinfo->dviDisp_type == MT_LCD && _machine == _MACH_Pmac) { set_backlight_enable(!blank); return 0; } diff --git a/trunk/drivers/video/riva/fbdev.c b/trunk/drivers/video/riva/fbdev.c index 3e9308f0f165..f841f013b96f 100644 --- a/trunk/drivers/video/riva/fbdev.c +++ b/trunk/drivers/video/riva/fbdev.c @@ -49,7 +49,6 @@ #include #endif #ifdef CONFIG_PMAC_BACKLIGHT -#include #include #endif @@ -1248,7 +1247,7 @@ static int rivafb_blank(int blank, struct fb_info *info) CRTCout(par, 0x1a, vesa); #ifdef CONFIG_PMAC_BACKLIGHT - if ( par->FlatPanel && machine_is(powermac)) { + if ( par->FlatPanel && _machine == _MACH_Pmac) { set_backlight_enable(!blank); } #endif @@ -2038,9 +2037,9 @@ static int __devinit rivafb_probe(struct pci_dev *pd, info->fix.smem_len / (1024 * 1024), info->fix.smem_start); #ifdef CONFIG_PMAC_BACKLIGHT - if (default_par->FlatPanel && machine_is(powermac)) - register_backlight_controller(&riva_backlight_controller, - default_par, "mnca"); + if (default_par->FlatPanel && _machine == _MACH_Pmac) + register_backlight_controller(&riva_backlight_controller, + default_par, "mnca"); #endif NVTRACE_LEAVE(); return 0; diff --git a/trunk/fs/direct-io.c b/trunk/fs/direct-io.c index 910a8ed74b5d..9d1d2aa73e42 100644 --- a/trunk/fs/direct-io.c +++ b/trunk/fs/direct-io.c @@ -524,6 +524,8 @@ static int get_more_blocks(struct dio *dio) */ ret = dio->page_errors; if (ret == 0) { + map_bh->b_state = 0; + map_bh->b_size = 0; BUG_ON(dio->block_in_file >= dio->final_block_in_request); fs_startblk = dio->block_in_file >> dio->blkfactor; dio_count = dio->final_block_in_request - dio->block_in_file; @@ -532,9 +534,6 @@ static int get_more_blocks(struct dio *dio) if (dio_count & blkmask) fs_count++; - map_bh->b_state = 0; - map_bh->b_size = fs_count << dio->inode->i_blkbits; - create = dio->rw == WRITE; if (dio->lock_type == DIO_LOCKING) { if (dio->block_in_file < (i_size_read(dio->inode) >> @@ -543,13 +542,13 @@ static int get_more_blocks(struct dio *dio) } else if (dio->lock_type == DIO_NO_LOCKING) { create = 0; } - /* * For writes inside i_size we forbid block creations: only * overwrites are permitted. We fall back to buffered writes * at a higher level for inside-i_size block-instantiating * writes. */ + map_bh->b_size = fs_count << dio->blkbits; ret = (*dio->get_block)(dio->inode, fs_startblk, map_bh, create); } diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 950ebd43cdc3..c7397c46ad6d 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -616,15 +616,6 @@ static int de_thread(struct task_struct *tsk) kmem_cache_free(sighand_cachep, newsighand); return -EAGAIN; } - - /* - * child_reaper ignores SIGKILL, change it now. - * Reparenting needs write_lock on tasklist_lock, - * so it is safe to do it under read_lock. - */ - if (unlikely(current->group_leader == child_reaper)) - child_reaper = current; - zap_other_threads(current); read_unlock(&tasklist_lock); @@ -708,30 +699,22 @@ static int de_thread(struct task_struct *tsk) remove_parent(current); remove_parent(leader); - - /* Become a process group leader with the old leader's pid. - * Note: The old leader also uses thispid until release_task - * is called. Odd but simple and correct. - */ - detach_pid(current, PIDTYPE_PID); - current->pid = leader->pid; - attach_pid(current, PIDTYPE_PID, current->pid); - attach_pid(current, PIDTYPE_PGID, current->signal->pgrp); - attach_pid(current, PIDTYPE_SID, current->signal->session); - list_add_tail(¤t->tasks, &init_task.tasks); + switch_exec_pids(leader, current); current->parent = current->real_parent = leader->real_parent; leader->parent = leader->real_parent = child_reaper; current->group_leader = current; leader->group_leader = leader; - add_parent(current); - add_parent(leader); + add_parent(current, current->parent); + add_parent(leader, leader->parent); if (ptrace) { current->ptrace = ptrace; __ptrace_link(current, parent); } + list_del(¤t->tasks); + list_add_tail(¤t->tasks, &init_task.tasks); current->exit_signal = SIGCHLD; BUG_ON(leader->exit_state != EXIT_ZOMBIE); @@ -768,6 +751,7 @@ static int de_thread(struct task_struct *tsk) /* * Move our state over to newsighand and switch it in. */ + spin_lock_init(&newsighand->siglock); atomic_set(&newsighand->count, 1); memcpy(newsighand->action, oldsighand->action, sizeof(newsighand->action)); @@ -784,7 +768,7 @@ static int de_thread(struct task_struct *tsk) write_unlock_irq(&tasklist_lock); if (atomic_dec_and_test(&oldsighand->count)) - kmem_cache_free(sighand_cachep, oldsighand); + sighand_free(oldsighand); } BUG_ON(!thread_group_leader(current)); diff --git a/trunk/fs/partitions/mac.c b/trunk/fs/partitions/mac.c index 813292f21210..bb22cdd0cb14 100644 --- a/trunk/fs/partitions/mac.c +++ b/trunk/fs/partitions/mac.c @@ -12,7 +12,6 @@ #include "mac.h" #ifdef CONFIG_PPC_PMAC -#include extern void note_bootable_part(dev_t dev, int part, int goodness); #endif @@ -80,7 +79,7 @@ int mac_partition(struct parsed_partitions *state, struct block_device *bdev) * If this is the first bootable partition, tell the * setup code, in case it wants to make this the root. */ - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { int goodness = 0; mac_fix_string(part->processor, 16); diff --git a/trunk/fs/proc/proc_devtree.c b/trunk/fs/proc/proc_devtree.c index abdf068bc27f..596b4b4f1cc8 100644 --- a/trunk/fs/proc/proc_devtree.c +++ b/trunk/fs/proc/proc_devtree.c @@ -52,8 +52,7 @@ static int property_read_proc(char *page, char **start, off_t off, * Add a property to a node */ static struct proc_dir_entry * -__proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp, - const char *name) +__proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp) { struct proc_dir_entry *ent; @@ -61,14 +60,14 @@ __proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp, * Unfortunately proc_register puts each new entry * at the beginning of the list. So we rearrange them. */ - ent = create_proc_read_entry(name, - strncmp(name, "security-", 9) + ent = create_proc_read_entry(pp->name, + strncmp(pp->name, "security-", 9) ? S_IRUGO : S_IRUSR, de, property_read_proc, pp); if (ent == NULL) return NULL; - if (!strncmp(name, "security-", 9)) + if (!strncmp(pp->name, "security-", 9)) ent->size = 0; /* don't leak number of password chars */ else ent->size = pp->length; @@ -79,7 +78,7 @@ __proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp, void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop) { - __proc_device_tree_add_prop(pde, prop, prop->name); + __proc_device_tree_add_prop(pde, prop); } void proc_device_tree_remove_prop(struct proc_dir_entry *pde, @@ -106,69 +105,6 @@ void proc_device_tree_update_prop(struct proc_dir_entry *pde, } } -/* - * Various dodgy firmware might give us nodes and/or properties with - * conflicting names. That's generally ok, except for exporting via /proc, - * so munge names here to ensure they're unique. - */ - -static int duplicate_name(struct proc_dir_entry *de, const char *name) -{ - struct proc_dir_entry *ent; - int found = 0; - - spin_lock(&proc_subdir_lock); - - for (ent = de->subdir; ent != NULL; ent = ent->next) { - if (strcmp(ent->name, name) == 0) { - found = 1; - break; - } - } - - spin_unlock(&proc_subdir_lock); - - return found; -} - -static const char *fixup_name(struct device_node *np, struct proc_dir_entry *de, - const char *name) -{ - char *fixed_name; - int fixup_len = strlen(name) + 2 + 1; /* name + #x + \0 */ - int i = 1, size; - -realloc: - fixed_name = kmalloc(fixup_len, GFP_KERNEL); - if (fixed_name == NULL) { - printk(KERN_ERR "device-tree: Out of memory trying to fixup " - "name \"%s\"\n", name); - return name; - } - -retry: - size = snprintf(fixed_name, fixup_len, "%s#%d", name, i); - size++; /* account for NULL */ - - if (size > fixup_len) { - /* We ran out of space, free and reallocate. */ - kfree(fixed_name); - fixup_len = size; - goto realloc; - } - - if (duplicate_name(de, fixed_name)) { - /* Multiple duplicates. Retry with a different offset. */ - i++; - goto retry; - } - - printk(KERN_WARNING "device-tree: Duplicate name in %s, " - "renamed to \"%s\"\n", np->full_name, fixed_name); - - return fixed_name; -} - /* * Process a node, adding entries for its children and its properties. */ @@ -182,30 +118,37 @@ void proc_device_tree_add_node(struct device_node *np, set_node_proc_entry(np, de); for (child = NULL; (child = of_get_next_child(np, child));) { - /* Use everything after the last slash, or the full name */ p = strrchr(child->full_name, '/'); if (!p) p = child->full_name; else ++p; - - if (duplicate_name(de, p)) - p = fixup_name(np, de, p); - ent = proc_mkdir(p, de); if (ent == 0) break; proc_device_tree_add_node(child, ent); } of_node_put(child); - for (pp = np->properties; pp != 0; pp = pp->next) { - p = pp->name; - - if (duplicate_name(de, p)) - p = fixup_name(np, de, p); + /* + * Yet another Apple device-tree bogosity: on some machines, + * they have properties & nodes with the same name. Those + * properties are quite unimportant for us though, thus we + * simply "skip" them here, but we do have to check. + */ + spin_lock(&proc_subdir_lock); + for (ent = de->subdir; ent != NULL; ent = ent->next) + if (!strcmp(ent->name, pp->name)) + break; + spin_unlock(&proc_subdir_lock); + if (ent != NULL) { + printk(KERN_WARNING "device-tree: property \"%s\" name" + " conflicts with node in %s\n", pp->name, + np->full_name); + continue; + } - ent = __proc_device_tree_add_prop(de, pp, p); + ent = __proc_device_tree_add_prop(de, pp); if (ent == 0) break; } diff --git a/trunk/fs/xfs/linux-2.6/mrlock.h b/trunk/fs/xfs/linux-2.6/mrlock.h index 1b262b790d9c..16b44c3c2362 100644 --- a/trunk/fs/xfs/linux-2.6/mrlock.h +++ b/trunk/fs/xfs/linux-2.6/mrlock.h @@ -79,7 +79,7 @@ static inline void mrdemote(mrlock_t *mrp) * Debug-only routine, without some platform-specific asm code, we can * now only answer requests regarding whether we hold the lock for write * (reader state is outside our visibility, we only track writer state). - * Note: means !ismrlocked would give false positives, so don't do that. + * Note: means !ismrlocked would give false positivies, so don't do that. */ static inline int ismrlocked(mrlock_t *mrp, int type) { diff --git a/trunk/fs/xfs/linux-2.6/xfs_aops.c b/trunk/fs/xfs/linux-2.6/xfs_aops.c index 6cbbd165c60d..c02f7c5b7462 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_aops.c +++ b/trunk/fs/xfs/linux-2.6/xfs_aops.c @@ -372,7 +372,7 @@ static inline int bio_add_buffer(struct bio *bio, struct buffer_head *bh) * assumes that all buffers on the page are started at the same time. * * The fix is two passes across the ioend list - one to start writeback on the - * buffer_heads, and then submit them for I/O on the second pass. + * bufferheads, and then the second one submit them for I/O. */ STATIC void xfs_submit_ioend( @@ -699,7 +699,7 @@ xfs_convert_page( /* * page_dirty is initially a count of buffers on the page before - * EOF and is decremented as we move each into a cleanable state. + * EOF and is decrememted as we move each into a cleanable state. * * Derivation: * @@ -842,7 +842,7 @@ xfs_cluster_write( * page if possible. * The bh->b_state's cannot know if any of the blocks or which block for * that matter are dirty due to mmap writes, and therefore bh uptodate is - * only valid if the page itself isn't completely uptodate. Some layers + * only vaild if the page itself isn't completely uptodate. Some layers * may clear the page dirty flag prior to calling write page, under the * assumption the entire page will be written out; by not writing out the * whole page the page can be reused before all valid dirty data is @@ -892,7 +892,7 @@ xfs_page_state_convert( /* * page_dirty is initially a count of buffers on the page before - * EOF and is decremented as we move each into a cleanable state. + * EOF and is decrememted as we move each into a cleanable state. * * Derivation: * @@ -1223,9 +1223,10 @@ xfs_vm_releasepage( } STATIC int -__xfs_get_blocks( +__xfs_get_block( struct inode *inode, sector_t iblock, + unsigned long blocks, struct buffer_head *bh_result, int create, int direct, @@ -1235,17 +1236,22 @@ __xfs_get_blocks( xfs_iomap_t iomap; xfs_off_t offset; ssize_t size; - int niomap = 1; + int retpbbm = 1; int error; offset = (xfs_off_t)iblock << inode->i_blkbits; - ASSERT(bh_result->b_size >= (1 << inode->i_blkbits)); - size = bh_result->b_size; + if (blocks) + size = (ssize_t) min_t(xfs_off_t, LONG_MAX, + (xfs_off_t)blocks << inode->i_blkbits); + else + size = 1 << inode->i_blkbits; + VOP_BMAP(vp, offset, size, - create ? flags : BMAPI_READ, &iomap, &niomap, error); + create ? flags : BMAPI_READ, &iomap, &retpbbm, error); if (error) return -error; - if (niomap == 0) + + if (retpbbm == 0) return 0; if (iomap.iomap_bn != IOMAP_DADDR_NULL) { @@ -1265,16 +1271,12 @@ __xfs_get_blocks( } } - /* - * If this is a realtime file, data may be on a different device. - * to that pointed to from the buffer_head b_bdev currently. - */ + /* If this is a realtime file, data might be on a new device */ bh_result->b_bdev = iomap.iomap_target->bt_bdev; - /* - * If we previously allocated a block out beyond eof and we are - * now coming back to use it then we will need to flag it as new - * even if it has a disk address. + /* If we previously allocated a block out beyond eof and + * we are now coming back to use it then we will need to + * flag it as new even if it has a disk address. */ if (create && ((!buffer_mapped(bh_result) && !buffer_uptodate(bh_result)) || @@ -1290,24 +1292,26 @@ __xfs_get_blocks( } } - if (direct || size > (1 << inode->i_blkbits)) { + if (blocks) { ASSERT(iomap.iomap_bsize - iomap.iomap_delta > 0); offset = min_t(xfs_off_t, - iomap.iomap_bsize - iomap.iomap_delta, size); - bh_result->b_size = (ssize_t)min_t(xfs_off_t, LONG_MAX, offset); + iomap.iomap_bsize - iomap.iomap_delta, + (xfs_off_t)blocks << inode->i_blkbits); + bh_result->b_size = (u32) min_t(xfs_off_t, UINT_MAX, offset); } return 0; } int -xfs_get_blocks( +xfs_get_block( struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) { - return __xfs_get_blocks(inode, iblock, + return __xfs_get_block(inode, iblock, + bh_result->b_size >> inode->i_blkbits, bh_result, create, 0, BMAPI_WRITE); } @@ -1318,7 +1322,8 @@ xfs_get_blocks_direct( struct buffer_head *bh_result, int create) { - return __xfs_get_blocks(inode, iblock, + return __xfs_get_block(inode, iblock, + bh_result->b_size >> inode->i_blkbits, bh_result, create, 1, BMAPI_WRITE|BMAPI_DIRECT); } @@ -1334,9 +1339,9 @@ xfs_end_io_direct( /* * Non-NULL private data means we need to issue a transaction to * convert a range from unwritten to written extents. This needs - * to happen from process context but aio+dio I/O completion + * to happen from process contect but aio+dio I/O completion * happens from irq context so we need to defer it to a workqueue. - * This is not necessary for synchronous direct I/O, but we do + * This is not nessecary for synchronous direct I/O, but we do * it anyway to keep the code uniform and simpler. * * The core direct I/O code might be changed to always call the @@ -1353,7 +1358,7 @@ xfs_end_io_direct( } /* - * blockdev_direct_IO can return an error even after the I/O + * blockdev_direct_IO can return an error even afer the I/O * completion handler was called. Thus we need to protect * against double-freeing. */ @@ -1400,7 +1405,7 @@ xfs_vm_prepare_write( unsigned int from, unsigned int to) { - return block_prepare_write(page, from, to, xfs_get_blocks); + return block_prepare_write(page, from, to, xfs_get_block); } STATIC sector_t @@ -1417,7 +1422,7 @@ xfs_vm_bmap( VOP_RWLOCK(vp, VRWLOCK_READ); VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error); VOP_RWUNLOCK(vp, VRWLOCK_READ); - return generic_block_bmap(mapping, block, xfs_get_blocks); + return generic_block_bmap(mapping, block, xfs_get_block); } STATIC int @@ -1425,7 +1430,7 @@ xfs_vm_readpage( struct file *unused, struct page *page) { - return mpage_readpage(page, xfs_get_blocks); + return mpage_readpage(page, xfs_get_block); } STATIC int @@ -1435,7 +1440,7 @@ xfs_vm_readpages( struct list_head *pages, unsigned nr_pages) { - return mpage_readpages(mapping, pages, nr_pages, xfs_get_blocks); + return mpage_readpages(mapping, pages, nr_pages, xfs_get_block); } STATIC void diff --git a/trunk/fs/xfs/linux-2.6/xfs_aops.h b/trunk/fs/xfs/linux-2.6/xfs_aops.h index 60716543c68b..795699f121d2 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_aops.h +++ b/trunk/fs/xfs/linux-2.6/xfs_aops.h @@ -41,6 +41,6 @@ typedef struct xfs_ioend { } xfs_ioend_t; extern struct address_space_operations xfs_address_space_operations; -extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int); +extern int xfs_get_block(struct inode *, sector_t, struct buffer_head *, int); #endif /* __XFS_IOPS_H__ */ diff --git a/trunk/fs/xfs/linux-2.6/xfs_export.h b/trunk/fs/xfs/linux-2.6/xfs_export.h index e794ca4efc76..e5b0559700a4 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_export.h +++ b/trunk/fs/xfs/linux-2.6/xfs_export.h @@ -54,7 +54,7 @@ * Note, the NFS filehandle also includes an fsid portion which * may have an inode number in it. That number is hardcoded to * 32bits and there is no way for XFS to intercept it. In - * practice this means when exporting an XFS filesystem with 64bit + * practice this means when exporting an XFS filesytem with 64bit * inodes you should either export the mountpoint (rather than * a subdirectory) or use the "fsid" export option. */ diff --git a/trunk/fs/xfs/linux-2.6/xfs_ioctl32.c b/trunk/fs/xfs/linux-2.6/xfs_ioctl32.c index 251bfe451a3f..b6321abd9a81 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_ioctl32.c +++ b/trunk/fs/xfs/linux-2.6/xfs_ioctl32.c @@ -72,7 +72,7 @@ xfs_ioctl32_flock( copy_in_user(&p->l_pid, &p32->l_pid, sizeof(u32)) || copy_in_user(&p->l_pad, &p32->l_pad, 4*sizeof(u32))) return -EFAULT; - + return (unsigned long)p; } @@ -107,15 +107,11 @@ xfs_ioctl32_bulkstat( #endif STATIC long -xfs_compat_ioctl( - int mode, - struct file *file, - unsigned cmd, - unsigned long arg) +xfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg) { - struct inode *inode = file->f_dentry->d_inode; - vnode_t *vp = vn_from_inode(inode); int error; + struct inode *inode = f->f_dentry->d_inode; + vnode_t *vp = vn_to_inode(inode); switch (cmd) { case XFS_IOC_DIOINFO: @@ -193,7 +189,7 @@ xfs_compat_ioctl( return -ENOIOCTLCMD; } - VOP_IOCTL(vp, inode, file, mode, cmd, (void __user *)arg, error); + VOP_IOCTL(vp, inode, f, mode, cmd, (void __user *)arg, error); VMODIFY(vp); return error; @@ -201,18 +197,18 @@ xfs_compat_ioctl( long xfs_file_compat_ioctl( - struct file *file, + struct file *f, unsigned cmd, unsigned long arg) { - return xfs_compat_ioctl(0, file, cmd, arg); + return xfs_compat_ioctl(0, f, cmd, arg); } long xfs_file_compat_invis_ioctl( - struct file *file, + struct file *f, unsigned cmd, unsigned long arg) { - return xfs_compat_ioctl(IO_INVIS, file, cmd, arg); + return xfs_compat_ioctl(IO_INVIS, f, cmd, arg); } diff --git a/trunk/fs/xfs/linux-2.6/xfs_iops.c b/trunk/fs/xfs/linux-2.6/xfs_iops.c index 149237304fb6..af487437bd7e 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_iops.c +++ b/trunk/fs/xfs/linux-2.6/xfs_iops.c @@ -708,7 +708,7 @@ STATIC void xfs_vn_truncate( struct inode *inode) { - block_truncate_page(inode->i_mapping, inode->i_size, xfs_get_blocks); + block_truncate_page(inode->i_mapping, inode->i_size, xfs_get_block); } STATIC int diff --git a/trunk/fs/xfs/linux-2.6/xfs_lrw.c b/trunk/fs/xfs/linux-2.6/xfs_lrw.c index 84ddf1893894..0169360475c4 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_lrw.c +++ b/trunk/fs/xfs/linux-2.6/xfs_lrw.c @@ -681,7 +681,7 @@ xfs_write( eventsent = 1; /* - * The iolock was dropped and reacquired in XFS_SEND_DATA + * The iolock was dropped and reaquired in XFS_SEND_DATA * so we have to recheck the size when appending. * We will only "goto start;" once, since having sent the * event prevents another call to XFS_SEND_DATA, which is diff --git a/trunk/fs/xfs/linux-2.6/xfs_vfs.h b/trunk/fs/xfs/linux-2.6/xfs_vfs.h index 841200c03092..8fed356db055 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_vfs.h +++ b/trunk/fs/xfs/linux-2.6/xfs_vfs.h @@ -92,7 +92,7 @@ typedef enum { #define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */ #define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */ #define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */ -#define SYNC_QUIESCE 0x0100 /* quiesce filesystem for a snapshot */ +#define SYNC_QUIESCE 0x0100 /* quiesce fileystem for a snapshot */ typedef int (*vfs_mount_t)(bhv_desc_t *, struct xfs_mount_args *, struct cred *); diff --git a/trunk/fs/xfs/quota/xfs_dquot_item.c b/trunk/fs/xfs/quota/xfs_dquot_item.c index 546f48af882a..e4e5f05b841b 100644 --- a/trunk/fs/xfs/quota/xfs_dquot_item.c +++ b/trunk/fs/xfs/quota/xfs_dquot_item.c @@ -221,7 +221,7 @@ xfs_qm_dqunpin_wait( * as possible. * * We must not be holding the AIL_LOCK at this point. Calling incore() to - * search the buffer cache can be a time consuming thing, and AIL_LOCK is a + * search the buffercache can be a time consuming thing, and AIL_LOCK is a * spinlock. */ STATIC void diff --git a/trunk/fs/xfs/quota/xfs_qm.c b/trunk/fs/xfs/quota/xfs_qm.c index 73c1e5e80c07..1fb757ef3f41 100644 --- a/trunk/fs/xfs/quota/xfs_qm.c +++ b/trunk/fs/xfs/quota/xfs_qm.c @@ -289,7 +289,7 @@ xfs_qm_rele_quotafs_ref( /* * This is called at mount time from xfs_mountfs to initialize the quotainfo - * structure and start the global quota manager (xfs_Gqm) if it hasn't done + * structure and start the global quotamanager (xfs_Gqm) if it hasn't done * so already. Note that the superblock has not been read in yet. */ void @@ -807,7 +807,7 @@ xfs_qm_dqattach_one( * Given a udquot and gdquot, attach a ptr to the group dquot in the * udquot as a hint for future lookups. The idea sounds simple, but the * execution isn't, because the udquot might have a group dquot attached - * already and getting rid of that gets us into lock ordering constraints. + * already and getting rid of that gets us into lock ordering contraints. * The process is complicated more by the fact that the dquots may or may not * be locked on entry. */ @@ -1094,10 +1094,10 @@ xfs_qm_sync( } /* * If we can't grab the flush lock then if the caller - * really wanted us to give this our best shot, so + * really wanted us to give this our best shot, * see if we can give a push to the buffer before we wait * on the flush lock. At this point, we know that - * even though the dquot is being flushed, + * eventhough the dquot is being flushed, * it has (new) dirty data. */ xfs_qm_dqflock_pushbuf_wait(dqp); @@ -1491,7 +1491,7 @@ xfs_qm_reset_dqcounts( /* * Do a sanity check, and if needed, repair the dqblk. Don't * output any warnings because it's perfectly possible to - * find uninitialised dquot blks. See comment in xfs_qm_dqcheck. + * find unitialized dquot blks. See comment in xfs_qm_dqcheck. */ (void) xfs_qm_dqcheck(ddq, id+j, type, XFS_QMOPT_DQREPAIR, "xfs_quotacheck"); @@ -1580,7 +1580,7 @@ xfs_qm_dqiterate( error = 0; /* - * This looks racy, but we can't keep an inode lock across a + * This looks racey, but we can't keep an inode lock across a * trans_reserve. But, this gets called during quotacheck, and that * happens only at mount time which is single threaded. */ @@ -1824,7 +1824,7 @@ xfs_qm_dqusage_adjust( * we have to start from the beginning anyway. * Once we're done, we'll log all the dquot bufs. * - * The *QUOTA_ON checks below may look pretty racy, but quotachecks + * The *QUOTA_ON checks below may look pretty racey, but quotachecks * and quotaoffs don't race. (Quotachecks happen at mount time only). */ if (XFS_IS_UQUOTA_ON(mp)) { diff --git a/trunk/fs/xfs/quota/xfs_qm_syscalls.c b/trunk/fs/xfs/quota/xfs_qm_syscalls.c index c55db463bbf2..676884394aae 100644 --- a/trunk/fs/xfs/quota/xfs_qm_syscalls.c +++ b/trunk/fs/xfs/quota/xfs_qm_syscalls.c @@ -912,7 +912,7 @@ xfs_qm_export_dquot( /* * Internally, we don't reset all the timers when quota enforcement - * gets turned off. No need to confuse the user level code, + * gets turned off. No need to confuse the userlevel code, * so return zeroes in that case. */ if (! XFS_IS_QUOTA_ENFORCED(mp)) { diff --git a/trunk/fs/xfs/quota/xfs_trans_dquot.c b/trunk/fs/xfs/quota/xfs_trans_dquot.c index d8e131ec0aa8..3290975d31f7 100644 --- a/trunk/fs/xfs/quota/xfs_trans_dquot.c +++ b/trunk/fs/xfs/quota/xfs_trans_dquot.c @@ -804,7 +804,7 @@ xfs_trans_reserve_quota_bydquots( } /* - * Didn't change anything critical, so, no need to log + * Didnt change anything critical, so, no need to log */ return (0); } diff --git a/trunk/fs/xfs/xfs_acl.c b/trunk/fs/xfs/xfs_acl.c index 2539af34eb63..4ff0f4e41c61 100644 --- a/trunk/fs/xfs/xfs_acl.c +++ b/trunk/fs/xfs/xfs_acl.c @@ -395,7 +395,7 @@ xfs_acl_allow_set( * The access control process to determine the access permission: * if uid == file owner id, use the file owner bits. * if gid == file owner group id, use the file group bits. - * scan ACL for a matching user or group, and use matched entry + * scan ACL for a maching user or group, and use matched entry * permission. Use total permissions of all matching group entries, * until all acl entries are exhausted. The final permission produced * by matching acl entry or entries needs to be & with group permission. diff --git a/trunk/fs/xfs/xfs_ag.h b/trunk/fs/xfs/xfs_ag.h index dc2361dd740a..a96e2ffce0cc 100644 --- a/trunk/fs/xfs/xfs_ag.h +++ b/trunk/fs/xfs/xfs_ag.h @@ -179,7 +179,7 @@ typedef struct xfs_perag { char pagf_init; /* this agf's entry is initialized */ char pagi_init; /* this agi's entry is initialized */ - char pagf_metadata; /* the agf is preferred to be metadata */ + char pagf_metadata; /* the agf is prefered to be metadata */ char pagi_inodeok; /* The agi is ok for inodes */ __uint8_t pagf_levels[XFS_BTNUM_AGF]; /* # of levels in bno & cnt btree */ diff --git a/trunk/fs/xfs/xfs_alloc.c b/trunk/fs/xfs/xfs_alloc.c index 64ee07db0d5e..f4328e1e2a74 100644 --- a/trunk/fs/xfs/xfs_alloc.c +++ b/trunk/fs/xfs/xfs_alloc.c @@ -511,7 +511,7 @@ STATIC void xfs_alloc_trace_busy( char *name, /* function tag string */ char *str, /* additional string */ - xfs_mount_t *mp, /* file system mount point */ + xfs_mount_t *mp, /* file system mount poing */ xfs_agnumber_t agno, /* allocation group number */ xfs_agblock_t agbno, /* a.g. relative block number */ xfs_extlen_t len, /* length of extent */ @@ -1843,7 +1843,7 @@ xfs_alloc_fix_freelist( } else agbp = NULL; - /* If this is a metadata preferred pag and we are user data + /* If this is a metadata prefered pag and we are user data * then try somewhere else if we are not being asked to * try harder at this point */ @@ -2458,7 +2458,7 @@ xfs_free_extent( /* * AG Busy list management * The busy list contains block ranges that have been freed but whose - * transactions have not yet hit disk. If any block listed in a busy + * transacations have not yet hit disk. If any block listed in a busy * list is reused, the transaction that freed it must be forced to disk * before continuing to use the block. * diff --git a/trunk/fs/xfs/xfs_alloc.h b/trunk/fs/xfs/xfs_alloc.h index 2d1f8928b267..3546dea27b7d 100644 --- a/trunk/fs/xfs/xfs_alloc.h +++ b/trunk/fs/xfs/xfs_alloc.h @@ -68,7 +68,7 @@ typedef struct xfs_alloc_arg { xfs_alloctype_t otype; /* original allocation type */ char wasdel; /* set if allocation was prev delayed */ char wasfromfl; /* set if allocation is from freelist */ - char isfl; /* set if is freelist blocks - !acctg */ + char isfl; /* set if is freelist blocks - !actg */ char userdata; /* set if this is user data */ } xfs_alloc_arg_t; diff --git a/trunk/fs/xfs/xfs_attr.c b/trunk/fs/xfs/xfs_attr.c index b6e1e02bbb28..093fac476bda 100644 --- a/trunk/fs/xfs/xfs_attr.c +++ b/trunk/fs/xfs/xfs_attr.c @@ -294,7 +294,7 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen, xfs_trans_ihold(args.trans, dp); /* - * If the attribute list is non-existent or a shortform list, + * If the attribute list is non-existant or a shortform list, * upgrade it to a single-leaf-block attribute list. */ if ((dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) || @@ -1584,7 +1584,7 @@ xfs_attr_node_removename(xfs_da_args_t *args) * Fill in the disk block numbers in the state structure for the buffers * that are attached to the state structure. * This is done so that we can quickly reattach ourselves to those buffers - * after some set of transaction commits have released these buffers. + * after some set of transaction commit's has released these buffers. */ STATIC int xfs_attr_fillstate(xfs_da_state_t *state) @@ -1631,7 +1631,7 @@ xfs_attr_fillstate(xfs_da_state_t *state) /* * Reattach the buffers to the state structure based on the disk block * numbers stored in the state structure. - * This is done after some set of transaction commits have released those + * This is done after some set of transaction commit's has released those * buffers from our grip. */ STATIC int diff --git a/trunk/fs/xfs/xfs_attr_leaf.c b/trunk/fs/xfs/xfs_attr_leaf.c index 9462be86aa14..717682747bd2 100644 --- a/trunk/fs/xfs/xfs_attr_leaf.c +++ b/trunk/fs/xfs/xfs_attr_leaf.c @@ -524,7 +524,7 @@ xfs_attr_shortform_compare(const void *a, const void *b) /* * Copy out entries of shortform attribute lists for attr_list(). - * Shortform attribute lists are not stored in hashval sorted order. + * Shortform atrtribute lists are not stored in hashval sorted order. * If the output buffer is not large enough to hold them all, then we * we have to calculate each entries' hashvalue and sort them before * we can begin returning them to the user. @@ -1541,7 +1541,7 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action) /* * Check for the degenerate case of the block being empty. * If the block is empty, we'll simply delete it, no need to - * coalesce it with a sibling block. We choose (arbitrarily) + * coalesce it with a sibling block. We choose (aribtrarily) * to merge with the forward block unless it is NULL. */ if (count == 0) { diff --git a/trunk/fs/xfs/xfs_behavior.c b/trunk/fs/xfs/xfs_behavior.c index f4fe3715a803..9880adae3938 100644 --- a/trunk/fs/xfs/xfs_behavior.c +++ b/trunk/fs/xfs/xfs_behavior.c @@ -31,7 +31,7 @@ * The behavior chain is ordered based on the 'position' number which * lives in the first field of the ops vector (higher numbers first). * - * Attempts to insert duplicate ops result in an EINVAL return code. + * Attemps to insert duplicate ops result in an EINVAL return code. * Otherwise, return 0 to indicate success. */ int @@ -84,7 +84,7 @@ bhv_insert(bhv_head_t *bhp, bhv_desc_t *bdp) /* * Remove a behavior descriptor from a position in a behavior chain; - * the position is guaranteed not to be the first position. + * the postition is guaranteed not to be the first position. * Should only be called by the bhv_remove() macro. */ void diff --git a/trunk/fs/xfs/xfs_behavior.h b/trunk/fs/xfs/xfs_behavior.h index 1d8ff103201c..2cd89bb5ab10 100644 --- a/trunk/fs/xfs/xfs_behavior.h +++ b/trunk/fs/xfs/xfs_behavior.h @@ -39,7 +39,7 @@ * behaviors is synchronized with operations-in-progress (oip's) so that * the oip's always see a consistent view of the chain. * - * The term "interposition" is used to refer to the act of inserting + * The term "interpostion" is used to refer to the act of inserting * a behavior such that it interposes on (i.e., is inserted in front * of) a particular other behavior. A key example of this is when a * system implementing distributed single system image wishes to @@ -51,7 +51,7 @@ * * Behavior synchronization is logic which is necessary under certain * circumstances that there is no conflict between ongoing operations - * traversing the behavior chain and those dynamically modifying the + * traversing the behavior chain and those dunamically modifying the * behavior chain. Because behavior synchronization adds extra overhead * to virtual operation invocation, we want to restrict, as much as * we can, the requirement for this extra code, to those situations diff --git a/trunk/fs/xfs/xfs_bmap.c b/trunk/fs/xfs/xfs_bmap.c index d384e489705f..2d702e4a74a3 100644 --- a/trunk/fs/xfs/xfs_bmap.c +++ b/trunk/fs/xfs/xfs_bmap.c @@ -3467,6 +3467,113 @@ xfs_bmap_local_to_extents( return error; } +xfs_bmbt_rec_t * /* pointer to found extent entry */ +xfs_bmap_do_search_extents( + xfs_bmbt_rec_t *base, /* base of extent list */ + xfs_extnum_t lastx, /* last extent index used */ + xfs_extnum_t nextents, /* number of file extents */ + xfs_fileoff_t bno, /* block number searched for */ + int *eofp, /* out: end of file found */ + xfs_extnum_t *lastxp, /* out: last extent index */ + xfs_bmbt_irec_t *gotp, /* out: extent entry found */ + xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ +{ + xfs_bmbt_rec_t *ep; /* extent list entry pointer */ + xfs_bmbt_irec_t got; /* extent list entry, decoded */ + int high; /* high index of binary search */ + int low; /* low index of binary search */ + + /* + * Initialize the extent entry structure to catch access to + * uninitialized br_startblock field. + */ + got.br_startoff = 0xffa5a5a5a5a5a5a5LL; + got.br_blockcount = 0xa55a5a5a5a5a5a5aLL; + got.br_state = XFS_EXT_INVALID; + +#if XFS_BIG_BLKNOS + got.br_startblock = 0xffffa5a5a5a5a5a5LL; +#else + got.br_startblock = 0xffffa5a5; +#endif + + if (lastx != NULLEXTNUM && lastx < nextents) + ep = base + lastx; + else + ep = NULL; + prevp->br_startoff = NULLFILEOFF; + if (ep && bno >= (got.br_startoff = xfs_bmbt_get_startoff(ep)) && + bno < got.br_startoff + + (got.br_blockcount = xfs_bmbt_get_blockcount(ep))) + *eofp = 0; + else if (ep && lastx < nextents - 1 && + bno >= (got.br_startoff = xfs_bmbt_get_startoff(ep + 1)) && + bno < got.br_startoff + + (got.br_blockcount = xfs_bmbt_get_blockcount(ep + 1))) { + lastx++; + ep++; + *eofp = 0; + } else if (nextents == 0) + *eofp = 1; + else if (bno == 0 && + (got.br_startoff = xfs_bmbt_get_startoff(base)) == 0) { + ep = base; + lastx = 0; + got.br_blockcount = xfs_bmbt_get_blockcount(ep); + *eofp = 0; + } else { + low = 0; + high = nextents - 1; + /* binary search the extents array */ + while (low <= high) { + XFS_STATS_INC(xs_cmp_exlist); + lastx = (low + high) >> 1; + ep = base + lastx; + got.br_startoff = xfs_bmbt_get_startoff(ep); + got.br_blockcount = xfs_bmbt_get_blockcount(ep); + if (bno < got.br_startoff) + high = lastx - 1; + else if (bno >= got.br_startoff + got.br_blockcount) + low = lastx + 1; + else { + got.br_startblock = xfs_bmbt_get_startblock(ep); + got.br_state = xfs_bmbt_get_state(ep); + *eofp = 0; + *lastxp = lastx; + *gotp = got; + return ep; + } + } + if (bno >= got.br_startoff + got.br_blockcount) { + lastx++; + if (lastx == nextents) { + *eofp = 1; + got.br_startblock = xfs_bmbt_get_startblock(ep); + got.br_state = xfs_bmbt_get_state(ep); + *prevp = got; + ep = NULL; + } else { + *eofp = 0; + xfs_bmbt_get_all(ep, prevp); + ep++; + got.br_startoff = xfs_bmbt_get_startoff(ep); + got.br_blockcount = xfs_bmbt_get_blockcount(ep); + } + } else { + *eofp = 0; + if (ep > base) + xfs_bmbt_get_all(ep - 1, prevp); + } + } + if (ep) { + got.br_startblock = xfs_bmbt_get_startblock(ep); + got.br_state = xfs_bmbt_get_state(ep); + } + *lastxp = lastx; + *gotp = got; + return ep; +} + /* * Search the extent records for the entry containing block bno. * If bno lies in a hole, point to the next entry. If bno lies diff --git a/trunk/fs/xfs/xfs_bmap.h b/trunk/fs/xfs/xfs_bmap.h index f83399c89ce3..011ccaa9a1c0 100644 --- a/trunk/fs/xfs/xfs_bmap.h +++ b/trunk/fs/xfs/xfs_bmap.h @@ -362,6 +362,14 @@ xfs_bmbt_rec_t * xfs_bmap_search_multi_extents(struct xfs_ifork *, xfs_fileoff_t, int *, xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *); +/* + * Search an extent list for the extent which includes block + * bno. + */ +xfs_bmbt_rec_t *xfs_bmap_do_search_extents(xfs_bmbt_rec_t *, + xfs_extnum_t, xfs_extnum_t, xfs_fileoff_t, int *, + xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *); + #endif /* __KERNEL__ */ #endif /* __XFS_BMAP_H__ */ diff --git a/trunk/fs/xfs/xfs_buf_item.c b/trunk/fs/xfs/xfs_buf_item.c index 5fed15682dda..07e2324152b1 100644 --- a/trunk/fs/xfs/xfs_buf_item.c +++ b/trunk/fs/xfs/xfs_buf_item.c @@ -98,12 +98,12 @@ xfs_buf_item_flush_log_debug( } /* - * This function is called to verify that our callers have logged + * This function is called to verify that our caller's have logged * all the bytes that they changed. * * It does this by comparing the original copy of the buffer stored in * the buf log item's bli_orig array to the current copy of the buffer - * and ensuring that all bytes which mismatch are set in the bli_logged + * and ensuring that all bytes which miscompare are set in the bli_logged * array of the buf log item. */ STATIC void diff --git a/trunk/fs/xfs/xfs_cap.h b/trunk/fs/xfs/xfs_cap.h index d0035c6e9514..433ec537f9bd 100644 --- a/trunk/fs/xfs/xfs_cap.h +++ b/trunk/fs/xfs/xfs_cap.h @@ -38,7 +38,7 @@ typedef struct xfs_cap_set { /* * For Linux, we take the bitfields directly from capability.h * and no longer attempt to keep this attribute ondisk compatible - * with IRIX. Since this attribute is only set on executables, + * with IRIX. Since this attribute is only set on exectuables, * it just doesn't make much sense to try. We do use a different * named attribute though, to avoid confusion. */ diff --git a/trunk/fs/xfs/xfs_da_btree.c b/trunk/fs/xfs/xfs_da_btree.c index 8988b9051175..4bae3a76c678 100644 --- a/trunk/fs/xfs/xfs_da_btree.c +++ b/trunk/fs/xfs/xfs_da_btree.c @@ -840,7 +840,7 @@ xfs_da_node_toosmall(xfs_da_state_t *state, int *action) /* * Check for the degenerate case of the block being empty. * If the block is empty, we'll simply delete it, no need to - * coalesce it with a sibling block. We choose (arbitrarily) + * coalesce it with a sibling block. We choose (aribtrarily) * to merge with the forward block unless it is NULL. */ if (count == 0) { diff --git a/trunk/fs/xfs/xfs_dir2_block.c b/trunk/fs/xfs/xfs_dir2_block.c index 972ded595476..bd5cee6aa51a 100644 --- a/trunk/fs/xfs/xfs_dir2_block.c +++ b/trunk/fs/xfs/xfs_dir2_block.c @@ -533,7 +533,7 @@ xfs_dir2_block_getdents( /* * Reached the end of the block. - * Set the offset to a non-existent block 1 and return. + * Set the offset to a nonexistent block 1 and return. */ *eofp = 1; diff --git a/trunk/fs/xfs/xfs_dir2_leaf.c b/trunk/fs/xfs/xfs_dir2_leaf.c index 0f5e2f2ce6ec..08648b18265c 100644 --- a/trunk/fs/xfs/xfs_dir2_leaf.c +++ b/trunk/fs/xfs/xfs_dir2_leaf.c @@ -515,7 +515,7 @@ xfs_dir2_leaf_addname( ASSERT(be32_to_cpu(leaf->ents[highstale].address) == XFS_DIR2_NULL_DATAPTR); /* - * Copy entries down to cover the stale entry + * Copy entries down to copver the stale entry * and make room for the new entry. */ if (highstale - index > 0) diff --git a/trunk/fs/xfs/xfs_dir2_node.c b/trunk/fs/xfs/xfs_dir2_node.c index ac511ab9c52d..af556f16a0c7 100644 --- a/trunk/fs/xfs/xfs_dir2_node.c +++ b/trunk/fs/xfs/xfs_dir2_node.c @@ -830,7 +830,7 @@ xfs_dir2_leafn_rebalance( state->inleaf = 1; blk2->index = 0; cmn_err(CE_ALERT, - "xfs_dir2_leafn_rebalance: picked the wrong leaf? reverting original leaf: " + "xfs_dir2_leafn_rebalance: picked the wrong leaf? reverting orignal leaf: " "blk1->index %d\n", blk1->index); } diff --git a/trunk/fs/xfs/xfs_dir_leaf.c b/trunk/fs/xfs/xfs_dir_leaf.c index 6d711869262f..ee88751c3be6 100644 --- a/trunk/fs/xfs/xfs_dir_leaf.c +++ b/trunk/fs/xfs/xfs_dir_leaf.c @@ -1341,7 +1341,7 @@ xfs_dir_leaf_toosmall(xfs_da_state_t *state, int *action) /* * Check for the degenerate case of the block being empty. * If the block is empty, we'll simply delete it, no need to - * coalesce it with a sibling block. We choose (arbitrarily) + * coalesce it with a sibling block. We choose (aribtrarily) * to merge with the forward block unless it is NULL. */ if (count == 0) { diff --git a/trunk/fs/xfs/xfs_fsops.c b/trunk/fs/xfs/xfs_fsops.c index dfa3527b20a7..56caa88713ab 100644 --- a/trunk/fs/xfs/xfs_fsops.c +++ b/trunk/fs/xfs/xfs_fsops.c @@ -477,7 +477,7 @@ xfs_fs_counts( * * xfs_reserve_blocks is called to set m_resblks * in the in-core mount table. The number of unused reserved blocks - * is kept in m_resblks_avail. + * is kept in m_resbls_avail. * * Reserve the requested number of blocks if available. Otherwise return * as many as possible to satisfy the request. The actual number diff --git a/trunk/fs/xfs/xfs_ialloc.c b/trunk/fs/xfs/xfs_ialloc.c index 4eeb856183b1..0024892841a3 100644 --- a/trunk/fs/xfs/xfs_ialloc.c +++ b/trunk/fs/xfs/xfs_ialloc.c @@ -136,7 +136,7 @@ xfs_ialloc_ag_alloc( int ninodes; /* num inodes per buf */ xfs_agino_t thisino; /* current inode number, for loop */ int version; /* inode version number to use */ - int isaligned = 0; /* inode allocation at stripe unit */ + int isaligned; /* inode allocation at stripe unit */ /* boundary */ args.tp = tp; @@ -152,75 +152,47 @@ xfs_ialloc_ag_alloc( return XFS_ERROR(ENOSPC); args.minlen = args.maxlen = XFS_IALLOC_BLOCKS(args.mp); /* - * First try to allocate inodes contiguous with the last-allocated - * chunk of inodes. If the filesystem is striped, this will fill - * an entire stripe unit with inodes. - */ - agi = XFS_BUF_TO_AGI(agbp); - newino = be32_to_cpu(agi->agi_newino); - if(likely(newino != NULLAGINO)) { - args.agbno = XFS_AGINO_TO_AGBNO(args.mp, newino) + - XFS_IALLOC_BLOCKS(args.mp); - args.fsbno = XFS_AGB_TO_FSB(args.mp, - be32_to_cpu(agi->agi_seqno), args.agbno); - args.type = XFS_ALLOCTYPE_THIS_BNO; - args.mod = args.total = args.wasdel = args.isfl = - args.userdata = args.minalignslop = 0; - args.prod = 1; + * Set the alignment for the allocation. + * If stripe alignment is turned on then align at stripe unit + * boundary. + * If the cluster size is smaller than a filesystem block + * then we're doing I/O for inodes in filesystem block size pieces, + * so don't need alignment anyway. + */ + isaligned = 0; + if (args.mp->m_sinoalign) { + ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN)); + args.alignment = args.mp->m_dalign; + isaligned = 1; + } else if (XFS_SB_VERSION_HASALIGN(&args.mp->m_sb) && + args.mp->m_sb.sb_inoalignmt >= + XFS_B_TO_FSBT(args.mp, XFS_INODE_CLUSTER_SIZE(args.mp))) + args.alignment = args.mp->m_sb.sb_inoalignmt; + else args.alignment = 1; - /* - * Allow space for the inode btree to split. - */ - args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1; - if ((error = xfs_alloc_vextent(&args))) - return error; - } else - args.fsbno = NULLFSBLOCK; + agi = XFS_BUF_TO_AGI(agbp); + /* + * Need to figure out where to allocate the inode blocks. + * Ideally they should be spaced out through the a.g. + * For now, just allocate blocks up front. + */ + args.agbno = be32_to_cpu(agi->agi_root); + args.fsbno = XFS_AGB_TO_FSB(args.mp, be32_to_cpu(agi->agi_seqno), + args.agbno); + /* + * Allocate a fixed-size extent of inodes. + */ + args.type = XFS_ALLOCTYPE_NEAR_BNO; + args.mod = args.total = args.wasdel = args.isfl = args.userdata = + args.minalignslop = 0; + args.prod = 1; + /* + * Allow space for the inode btree to split. + */ + args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1; + if ((error = xfs_alloc_vextent(&args))) + return error; - if (unlikely(args.fsbno == NULLFSBLOCK)) { - /* - * Set the alignment for the allocation. - * If stripe alignment is turned on then align at stripe unit - * boundary. - * If the cluster size is smaller than a filesystem block - * then we're doing I/O for inodes in filesystem block size - * pieces, so don't need alignment anyway. - */ - isaligned = 0; - if (args.mp->m_sinoalign) { - ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN)); - args.alignment = args.mp->m_dalign; - isaligned = 1; - } else if (XFS_SB_VERSION_HASALIGN(&args.mp->m_sb) && - args.mp->m_sb.sb_inoalignmt >= - XFS_B_TO_FSBT(args.mp, - XFS_INODE_CLUSTER_SIZE(args.mp))) - args.alignment = args.mp->m_sb.sb_inoalignmt; - else - args.alignment = 1; - /* - * Need to figure out where to allocate the inode blocks. - * Ideally they should be spaced out through the a.g. - * For now, just allocate blocks up front. - */ - args.agbno = be32_to_cpu(agi->agi_root); - args.fsbno = XFS_AGB_TO_FSB(args.mp, - be32_to_cpu(agi->agi_seqno), args.agbno); - /* - * Allocate a fixed-size extent of inodes. - */ - args.type = XFS_ALLOCTYPE_NEAR_BNO; - args.mod = args.total = args.wasdel = args.isfl = - args.userdata = args.minalignslop = 0; - args.prod = 1; - /* - * Allow space for the inode btree to split. - */ - args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1; - if ((error = xfs_alloc_vextent(&args))) - return error; - } - /* * If stripe alignment is turned on, then try again with cluster * alignment. @@ -1051,7 +1023,7 @@ xfs_difree( rec.ir_freecount++; /* - * When an inode cluster is free, it becomes eligible for removal + * When an inode cluster is free, it becomes elgible for removal */ if ((mp->m_flags & XFS_MOUNT_IDELETE) && (rec.ir_freecount == XFS_IALLOC_INODES(mp))) { diff --git a/trunk/fs/xfs/xfs_iget.c b/trunk/fs/xfs/xfs_iget.c index bb33113eef9f..3ce35a6f700b 100644 --- a/trunk/fs/xfs/xfs_iget.c +++ b/trunk/fs/xfs/xfs_iget.c @@ -509,7 +509,7 @@ xfs_iget( } else { /* * If the inode is not fully constructed due to - * filehandle mismatches wait for the inode to go + * filehandle mistmatches wait for the inode to go * away and try again. * * iget_locked will call __wait_on_freeing_inode diff --git a/trunk/fs/xfs/xfs_inode.c b/trunk/fs/xfs/xfs_inode.c index 48146bdc6bdd..88a517fad07b 100644 --- a/trunk/fs/xfs/xfs_inode.c +++ b/trunk/fs/xfs/xfs_inode.c @@ -160,7 +160,7 @@ xfs_inotobp( xfs_dinode_t *dip; /* - * Call the space management code to find the location of the + * Call the space managment code to find the location of the * inode on disk. */ imap.im_blkno = 0; @@ -837,7 +837,7 @@ xfs_dic2xflags( /* * Given a mount structure and an inode number, return a pointer - * to a newly allocated in-core inode corresponding to the given + * to a newly allocated in-core inode coresponding to the given * inode number. * * Initialize the inode's attributes and extent pointers if it @@ -2723,7 +2723,7 @@ xfs_ipin( /* * Decrement the pin count of the given inode, and wake up * anyone in xfs_iwait_unpin() if the count goes to 0. The - * inode must have been previously pinned with a call to xfs_ipin(). + * inode must have been previoulsy pinned with a call to xfs_ipin(). */ void xfs_iunpin( @@ -3690,7 +3690,7 @@ void xfs_iext_add( xfs_ifork_t *ifp, /* inode fork pointer */ xfs_extnum_t idx, /* index to begin adding exts */ - int ext_diff) /* number of extents to add */ + int ext_diff) /* nubmer of extents to add */ { int byte_diff; /* new bytes being added */ int new_size; /* size of extents after adding */ @@ -4038,7 +4038,7 @@ xfs_iext_remove_indirect( xfs_extnum_t ext_diff; /* extents to remove in current list */ xfs_extnum_t nex1; /* number of extents before idx */ xfs_extnum_t nex2; /* extents after idx + count */ - int nlists; /* entries in indirection array */ + int nlists; /* entries in indirecton array */ int page_idx = idx; /* index in target extent list */ ASSERT(ifp->if_flags & XFS_IFEXTIREC); @@ -4291,9 +4291,9 @@ xfs_iext_bno_to_ext( xfs_filblks_t blockcount = 0; /* number of blocks in extent */ xfs_bmbt_rec_t *ep = NULL; /* pointer to target extent */ xfs_ext_irec_t *erp = NULL; /* indirection array pointer */ - int high; /* upper boundary in search */ + int high; /* upper boundry in search */ xfs_extnum_t idx = 0; /* index of target extent */ - int low; /* lower boundary in search */ + int low; /* lower boundry in search */ xfs_extnum_t nextents; /* number of file extents */ xfs_fileoff_t startoff = 0; /* start offset of extent */ diff --git a/trunk/fs/xfs/xfs_inode_item.c b/trunk/fs/xfs/xfs_inode_item.c index 7497a481b2f5..36aa1fcb90a5 100644 --- a/trunk/fs/xfs/xfs_inode_item.c +++ b/trunk/fs/xfs/xfs_inode_item.c @@ -580,7 +580,7 @@ xfs_inode_item_unpin_remove( * been or is in the process of being flushed, then (ideally) we'd like to * see if the inode's buffer is still incore, and if so give it a nudge. * We delay doing so until the pushbuf routine, though, to avoid holding - * the AIL lock across a call to the blackhole which is the buffer cache. + * the AIL lock across a call to the blackhole which is the buffercache. * Also we don't want to sleep in any device strategy routines, which can happen * if we do the subsequent bawrite in here. */ diff --git a/trunk/fs/xfs/xfs_itable.c b/trunk/fs/xfs/xfs_itable.c index 94068d014f27..32247b6bfee7 100644 --- a/trunk/fs/xfs/xfs_itable.c +++ b/trunk/fs/xfs/xfs_itable.c @@ -272,7 +272,7 @@ xfs_bulkstat( size_t statstruct_size, /* sizeof struct filling */ char __user *ubuffer, /* buffer with inode stats */ int flags, /* defined in xfs_itable.h */ - int *done) /* 1 if there are more stats to get */ + int *done) /* 1 if there're more stats to get */ { xfs_agblock_t agbno=0;/* allocation group block number */ xfs_buf_t *agbp; /* agi header buffer */ @@ -676,7 +676,7 @@ xfs_bulkstat_single( xfs_mount_t *mp, /* mount point for filesystem */ xfs_ino_t *lastinop, /* inode to return */ char __user *buffer, /* buffer with inode stats */ - int *done) /* 1 if there are more stats to get */ + int *done) /* 1 if there're more stats to get */ { int count; /* count value for bulkstat call */ int error; /* return value */ diff --git a/trunk/fs/xfs/xfs_itable.h b/trunk/fs/xfs/xfs_itable.h index 11eb4e1b18c4..047d834ed210 100644 --- a/trunk/fs/xfs/xfs_itable.h +++ b/trunk/fs/xfs/xfs_itable.h @@ -60,7 +60,7 @@ xfs_bulkstat( size_t statstruct_size,/* sizeof struct that we're filling */ char __user *ubuffer,/* buffer with inode stats */ int flags, /* flag to control access method */ - int *done); /* 1 if there are more stats to get */ + int *done); /* 1 if there're more stats to get */ int xfs_bulkstat_single( diff --git a/trunk/fs/xfs/xfs_log.c b/trunk/fs/xfs/xfs_log.c index 32e841d2f26d..9176995160ed 100644 --- a/trunk/fs/xfs/xfs_log.c +++ b/trunk/fs/xfs/xfs_log.c @@ -59,7 +59,7 @@ STATIC xlog_t * xlog_alloc_log(xfs_mount_t *mp, int num_bblks); STATIC int xlog_space_left(xlog_t *log, int cycle, int bytes); STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog); -STATIC void xlog_dealloc_log(xlog_t *log); +STATIC void xlog_unalloc_log(xlog_t *log); STATIC int xlog_write(xfs_mount_t *mp, xfs_log_iovec_t region[], int nentries, xfs_log_ticket_t tic, xfs_lsn_t *start_lsn, @@ -304,7 +304,7 @@ xfs_log_done(xfs_mount_t *mp, if ((ticket->t_flags & XLOG_TIC_PERM_RESERV) == 0 || (flags & XFS_LOG_REL_PERM_RESERV)) { /* - * Release ticket if not permanent reservation or a specific + * Release ticket if not permanent reservation or a specifc * request has been made to release a permanent reservation. */ xlog_trace_loggrant(log, ticket, "xfs_log_done: (non-permanent)"); @@ -511,7 +511,7 @@ xfs_log_mount(xfs_mount_t *mp, vfsp->vfs_flag |= VFS_RDONLY; if (error) { cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error); - xlog_dealloc_log(mp->m_log); + xlog_unalloc_log(mp->m_log); return error; } } @@ -667,7 +667,7 @@ xfs_log_unmount_write(xfs_mount_t *mp) * * Go through the motions of sync'ing and releasing * the iclog, even though no I/O will actually happen, - * we need to wait for other log I/Os that may already + * we need to wait for other log I/O's that may already * be in progress. Do this as a separate section of * code so we'll know if we ever get stuck here that * we're in this odd situation of trying to unmount @@ -704,7 +704,7 @@ xfs_log_unmount_write(xfs_mount_t *mp) void xfs_log_unmount_dealloc(xfs_mount_t *mp) { - xlog_dealloc_log(mp->m_log); + xlog_unalloc_log(mp->m_log); } /* @@ -1492,7 +1492,7 @@ xlog_sync(xlog_t *log, ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1); ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize); - /* account for internal log which doesn't start at block #0 */ + /* account for internal log which does't start at block #0 */ XFS_BUF_SET_ADDR(bp, XFS_BUF_ADDR(bp) + log->l_logBBstart); XFS_BUF_WRITE(bp); if ((error = XFS_bwrite(bp))) { @@ -1506,10 +1506,10 @@ xlog_sync(xlog_t *log, /* - * Deallocate a log structure + * Unallocate a log structure */ void -xlog_dealloc_log(xlog_t *log) +xlog_unalloc_log(xlog_t *log) { xlog_in_core_t *iclog, *next_iclog; xlog_ticket_t *tic, *next_tic; @@ -1539,7 +1539,7 @@ xlog_dealloc_log(xlog_t *log) if ((log->l_ticket_cnt != log->l_ticket_tcnt) && !XLOG_FORCED_SHUTDOWN(log)) { xfs_fs_cmn_err(CE_WARN, log->l_mp, - "xlog_dealloc_log: (cnt: %d, total: %d)", + "xlog_unalloc_log: (cnt: %d, total: %d)", log->l_ticket_cnt, log->l_ticket_tcnt); /* ASSERT(log->l_ticket_cnt == log->l_ticket_tcnt); */ @@ -1562,7 +1562,7 @@ xlog_dealloc_log(xlog_t *log) #endif log->l_mp->m_log = NULL; kmem_free(log, sizeof(xlog_t)); -} /* xlog_dealloc_log */ +} /* xlog_unalloc_log */ /* * Update counters atomically now that memcpy is done. @@ -2829,7 +2829,7 @@ xlog_state_release_iclog(xlog_t *log, /* * We let the log lock go, so it's possible that we hit a log I/O - * error or some other SHUTDOWN condition that marks the iclog + * error or someother SHUTDOWN condition that marks the iclog * as XLOG_STATE_IOERROR before the bwrite. However, we know that * this iclog has consistent data, so we ignore IOERROR * flags after this point. diff --git a/trunk/fs/xfs/xfs_log.h b/trunk/fs/xfs/xfs_log.h index eacb3d4987f2..4b2ac88dbb83 100644 --- a/trunk/fs/xfs/xfs_log.h +++ b/trunk/fs/xfs/xfs_log.h @@ -27,7 +27,7 @@ #ifdef __KERNEL__ /* - * By comparing each component, we don't have to worry about extra + * By comparing each compnent, we don't have to worry about extra * endian issues in treating two 32 bit numbers as one 64 bit number */ static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2) diff --git a/trunk/fs/xfs/xfs_log_recover.c b/trunk/fs/xfs/xfs_log_recover.c index 1f0016b0b4ec..add13f507ed2 100644 --- a/trunk/fs/xfs/xfs_log_recover.c +++ b/trunk/fs/xfs/xfs_log_recover.c @@ -583,7 +583,7 @@ xlog_find_head( * x | x ... | x - 1 | x * Another case that fits this picture would be * x | x + 1 | x ... | x - * In this case the head really is somewhere at the end of the + * In this case the head really is somwhere at the end of the * log, as one of the latest writes at the beginning was * incomplete. * One more case is @@ -2799,7 +2799,7 @@ xlog_recover_do_trans( * we don't need to worry about the block number being * truncated in > 1 TB buffers because in user-land, * we're now n32 or 64-bit so xfs_daddr_t is 64-bits so - * the blknos will get through the user-mode buffer + * the blkno's will get through the user-mode buffer * cache properly. The only bad case is o32 kernels * where xfs_daddr_t is 32-bits but mount will warn us * off a > 1 TB filesystem before we get here. diff --git a/trunk/fs/xfs/xfs_mount.c b/trunk/fs/xfs/xfs_mount.c index 72e7e78bfff8..20e8abc16d18 100644 --- a/trunk/fs/xfs/xfs_mount.c +++ b/trunk/fs/xfs/xfs_mount.c @@ -393,7 +393,7 @@ xfs_initialize_perag( break; } - /* This ag is preferred for inodes */ + /* This ag is prefered for inodes */ pag = &mp->m_perag[index]; pag->pagi_inodeok = 1; if (index < max_metadata) @@ -1728,7 +1728,7 @@ xfs_mount_log_sbunit( * We cannot use the hotcpu_register() function because it does * not allow notifier instances. We need a notifier per filesystem * as we need to be able to identify the filesystem to balance - * the counters out. This is achieved by having a notifier block + * the counters out. This is acheived by having a notifier block * embedded in the xfs_mount_t and doing pointer magic to get the * mount pointer from the notifier block address. */ diff --git a/trunk/fs/xfs/xfs_mount.h b/trunk/fs/xfs/xfs_mount.h index 66cbee79864e..ebd73960e9db 100644 --- a/trunk/fs/xfs/xfs_mount.h +++ b/trunk/fs/xfs/xfs_mount.h @@ -379,7 +379,7 @@ typedef struct xfs_mount { #endif int m_dalign; /* stripe unit */ int m_swidth; /* stripe width */ - int m_sinoalign; /* stripe unit inode alignment */ + int m_sinoalign; /* stripe unit inode alignmnt */ int m_attr_magicpct;/* 37% of the blocksize */ int m_dir_magicpct; /* 37% of the dir blocksize */ __uint8_t m_mk_sharedro; /* mark shared ro on unmount */ diff --git a/trunk/fs/xfs/xfs_quota.h b/trunk/fs/xfs/xfs_quota.h index 4f6a034de7f7..82a08baf437b 100644 --- a/trunk/fs/xfs/xfs_quota.h +++ b/trunk/fs/xfs/xfs_quota.h @@ -31,7 +31,7 @@ typedef __uint32_t xfs_dqid_t; /* - * Even though users may not have quota limits occupying all 64-bits, + * Eventhough users may not have quota limits occupying all 64-bits, * they may need 64-bit accounting. Hence, 64-bit quota-counters, * and quota-limits. This is a waste in the common case, but hey ... */ @@ -246,7 +246,7 @@ typedef struct xfs_qoff_logformat { #ifdef __KERNEL__ /* * This check is done typically without holding the inode lock; - * that may seem racy, but it is harmless in the context that it is used. + * that may seem racey, but it is harmless in the context that it is used. * The inode cannot go inactive as long a reference is kept, and * therefore if dquot(s) were attached, they'll stay consistent. * If, for example, the ownership of the inode changes while diff --git a/trunk/fs/xfs/xfs_trans.c b/trunk/fs/xfs/xfs_trans.c index 8d056cef5d1f..2918956553a5 100644 --- a/trunk/fs/xfs/xfs_trans.c +++ b/trunk/fs/xfs/xfs_trans.c @@ -490,7 +490,7 @@ xfs_trans_mod_sb( case XFS_TRANS_SB_RES_FREXTENTS: /* * The allocation has already been applied to the - * in-core superblock's counter. This should only + * in-core superblocks's counter. This should only * be applied to the on-disk superblock. */ ASSERT(delta < 0); @@ -611,7 +611,7 @@ xfs_trans_apply_sb_deltas( if (whole) /* - * Log the whole thing, the fields are noncontiguous. + * Log the whole thing, the fields are discontiguous. */ xfs_trans_log_buf(tp, bp, 0, sizeof(xfs_sb_t) - 1); else @@ -669,7 +669,7 @@ xfs_trans_unreserve_and_mod_sb( /* * Apply any superblock modifications to the in-core version. * The t_res_fdblocks_delta and t_res_frextents_delta fields are - * explicitly NOT applied to the in-core superblock. + * explicity NOT applied to the in-core superblock. * The idea is that that has already been done. */ if (tp->t_flags & XFS_TRANS_SB_DIRTY) { diff --git a/trunk/fs/xfs/xfs_trans.h b/trunk/fs/xfs/xfs_trans.h index 100d9a4b38ee..e48befa4e337 100644 --- a/trunk/fs/xfs/xfs_trans.h +++ b/trunk/fs/xfs/xfs_trans.h @@ -354,7 +354,7 @@ typedef struct xfs_trans { xfs_lsn_t t_commit_lsn; /* log seq num of end of * transaction. */ struct xfs_mount *t_mountp; /* ptr to fs mount struct */ - struct xfs_dquot_acct *t_dqinfo; /* acctg info for dquots */ + struct xfs_dquot_acct *t_dqinfo; /* accting info for dquots */ xfs_trans_callback_t t_callback; /* transaction callback */ void *t_callarg; /* callback arg */ unsigned int t_flags; /* misc flags */ diff --git a/trunk/fs/xfs/xfs_trans_inode.c b/trunk/fs/xfs/xfs_trans_inode.c index 7c5894d59f81..e341409172d2 100644 --- a/trunk/fs/xfs/xfs_trans_inode.c +++ b/trunk/fs/xfs/xfs_trans_inode.c @@ -272,7 +272,7 @@ xfs_trans_log_inode( * This is to coordinate with the xfs_iflush() and xfs_iflush_done() * routines in the eventual clearing of the ilf_fields bits. * See the big comment in xfs_iflush() for an explanation of - * this coordination mechanism. + * this coorination mechanism. */ flags |= ip->i_itemp->ili_last_fields; ip->i_itemp->ili_format.ilf_fields |= flags; diff --git a/trunk/fs/xfs/xfs_vfsops.c b/trunk/fs/xfs/xfs_vfsops.c index 504d2a80747a..d4ec4dfaf19c 100644 --- a/trunk/fs/xfs/xfs_vfsops.c +++ b/trunk/fs/xfs/xfs_vfsops.c @@ -880,10 +880,10 @@ xfs_statvfs( * determine if they should be flushed sync, async, or * delwri. * SYNC_CLOSE - This flag is passed when the system is being - * unmounted. We should sync and invalidate everything. + * unmounted. We should sync and invalidate everthing. * SYNC_FSDATA - This indicates that the caller would like to make * sure the superblock is safe on disk. We can ensure - * this by simply making sure the log gets flushed + * this by simply makeing sure the log gets flushed * if SYNC_BDFLUSH is set, and by actually writing it * out otherwise. * @@ -908,7 +908,7 @@ xfs_sync( * * This routine supports all of the flags defined for the generic VFS_SYNC * interface as explained above under xfs_sync. In the interests of not - * changing interfaces within the 6.5 family, additional internally- + * changing interfaces within the 6.5 family, additional internallly- * required functions are specified within a separate xflags parameter, * only available by calling this routine. * @@ -1090,7 +1090,7 @@ xfs_sync_inodes( * If this is just vfs_sync() or pflushd() calling * then we can skip inodes for which it looks like * there is nothing to do. Since we don't have the - * inode locked this is racy, but these are periodic + * inode locked this is racey, but these are periodic * calls so it doesn't matter. For the others we want * to know for sure, so we at least try to lock them. */ @@ -1429,7 +1429,7 @@ xfs_sync_inodes( * * This routine supports all of the flags defined for the generic VFS_SYNC * interface as explained above under xfs_sync. In the interests of not - * changing interfaces within the 6.5 family, additional internally- + * changing interfaces within the 6.5 family, additional internallly- * required functions are specified within a separate xflags parameter, * only available by calling this routine. * diff --git a/trunk/fs/xfs/xfs_vnodeops.c b/trunk/fs/xfs/xfs_vnodeops.c index de49601919c1..0f0a64e81db9 100644 --- a/trunk/fs/xfs/xfs_vnodeops.c +++ b/trunk/fs/xfs/xfs_vnodeops.c @@ -848,7 +848,7 @@ xfs_setattr( * If this is a synchronous mount, make sure that the * transaction goes to disk before returning to the user. * This is slightly sub-optimal in that truncates require - * two sync transactions instead of one for wsync filesystems. + * two sync transactions instead of one for wsync filesytems. * One for the truncate and one for the timestamps since we * don't want to change the timestamps unless we're sure the * truncate worked. Truncates are less than 1% of the laddis @@ -1170,7 +1170,7 @@ xfs_fsync( /* * If this inode is on the RT dev we need to flush that - * cache as well. + * cache aswell. */ if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp); @@ -1380,7 +1380,7 @@ xfs_inactive_symlink_rmt( */ ntp = xfs_trans_dup(tp); /* - * Commit the transaction containing extent freeing and EFDs. + * Commit the transaction containing extent freeing and EFD's. * If we get an error on the commit here or on the reserve below, * we need to unlock the inode since the new transaction doesn't * have the inode attached. @@ -2023,7 +2023,7 @@ xfs_create( XFS_QM_DQRELE(mp, gdqp); /* - * Propagate the fact that the vnode changed after the + * Propogate the fact that the vnode changed after the * xfs_inode locks have been released. */ VOP_VNODE_CHANGE(vp, VCHANGE_FLAGS_TRUNCATED, 3); @@ -2370,7 +2370,7 @@ xfs_remove( * for a log reservation. Since we'll have to wait for the * inactive code to complete before returning from xfs_iget, * we need to make sure that we don't have log space reserved - * when we call xfs_iget. Instead we get an unlocked reference + * when we call xfs_iget. Instead we get an unlocked referece * to the inode before getting our log reservation. */ error = xfs_get_dir_entry(dentry, &ip); @@ -3020,7 +3020,7 @@ xfs_rmdir( * for a log reservation. Since we'll have to wait for the * inactive code to complete before returning from xfs_iget, * we need to make sure that we don't have log space reserved - * when we call xfs_iget. Instead we get an unlocked reference + * when we call xfs_iget. Instead we get an unlocked referece * to the inode before getting our log reservation. */ error = xfs_get_dir_entry(dentry, &cdp); diff --git a/trunk/include/asm-powerpc/bug.h b/trunk/include/asm-powerpc/bug.h index f44b529e3298..99817a802ca4 100644 --- a/trunk/include/asm-powerpc/bug.h +++ b/trunk/include/asm-powerpc/bug.h @@ -30,60 +30,34 @@ struct bug_entry *find_bug(unsigned long bugaddr); #ifdef CONFIG_BUG -/* - * BUG_ON() and WARN_ON() do their best to cooperate with compile-time - * optimisations. However depending on the complexity of the condition - * some compiler versions may not produce optimal results. - */ - #define BUG() do { \ __asm__ __volatile__( \ "1: twi 31,0,0\n" \ ".section __bug_table,\"a\"\n" \ - "\t"PPC_LONG" 1b,%0,%1,%2\n" \ + "\t"PPC_LONG" 1b,%0,%1,%2\n" \ ".previous" \ : : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \ } while (0) #define BUG_ON(x) do { \ - if (__builtin_constant_p(x)) { \ - if (x) \ - BUG(); \ - } else { \ - __asm__ __volatile__( \ + __asm__ __volatile__( \ "1: "PPC_TLNEI" %0,0\n" \ ".section __bug_table,\"a\"\n" \ - "\t"PPC_LONG" 1b,%1,%2,%3\n" \ + "\t"PPC_LONG" 1b,%1,%2,%3\n" \ ".previous" \ : : "r" ((long)(x)), "i" (__LINE__), \ "i" (__FILE__), "i" (__FUNCTION__)); \ - } \ -} while (0) - -#define __WARN() do { \ - __asm__ __volatile__( \ - "1: twi 31,0,0\n" \ - ".section __bug_table,\"a\"\n" \ - "\t"PPC_LONG" 1b,%0,%1,%2\n" \ - ".previous" \ - : : "i" (__LINE__ + BUG_WARNING_TRAP), \ - "i" (__FILE__), "i" (__FUNCTION__)); \ } while (0) #define WARN_ON(x) do { \ - if (__builtin_constant_p(x)) { \ - if (x) \ - __WARN(); \ - } else { \ - __asm__ __volatile__( \ + __asm__ __volatile__( \ "1: "PPC_TLNEI" %0,0\n" \ ".section __bug_table,\"a\"\n" \ - "\t"PPC_LONG" 1b,%1,%2,%3\n" \ + "\t"PPC_LONG" 1b,%1,%2,%3\n" \ ".previous" \ : : "r" ((long)(x)), \ "i" (__LINE__ + BUG_WARNING_TRAP), \ "i" (__FILE__), "i" (__FUNCTION__)); \ - } \ } while (0) #define HAVE_ARCH_BUG diff --git a/trunk/include/asm-powerpc/cputable.h b/trunk/include/asm-powerpc/cputable.h index 4321483cce51..fe45f6f3a4be 100644 --- a/trunk/include/asm-powerpc/cputable.h +++ b/trunk/include/asm-powerpc/cputable.h @@ -188,154 +188,153 @@ extern void do_cpu_ftr_fixups(unsigned long offset); !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4) && \ !defined(CONFIG_BOOKE)) -#define CPU_FTRS_PPC601 (CPU_FTR_COMMON | CPU_FTR_601 | CPU_FTR_HPTE_TABLE) -#define CPU_FTRS_603 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \ - CPU_FTR_MAYBE_CAN_NAP) -#define CPU_FTRS_604 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_USE_TB | CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE) -#define CPU_FTRS_740_NOTAU (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \ - CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP) -#define CPU_FTRS_740 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \ - CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP) -#define CPU_FTRS_750 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \ - CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP) -#define CPU_FTRS_750FX1 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \ - CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | \ - CPU_FTR_DUAL_PLL_750FX | CPU_FTR_NO_DPM) -#define CPU_FTRS_750FX2 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \ - CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | \ - CPU_FTR_NO_DPM) -#define CPU_FTRS_750FX (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \ - CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | \ - CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS) -#define CPU_FTRS_750GX (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | \ - CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | \ - CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | \ - CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS) -#define CPU_FTRS_7400_NOTAU (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \ - CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | \ - CPU_FTR_MAYBE_CAN_NAP) -#define CPU_FTRS_7400 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \ - CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | \ - CPU_FTR_MAYBE_CAN_NAP) -#define CPU_FTRS_7450_20 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \ - CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \ - CPU_FTR_NEED_COHERENT) -#define CPU_FTRS_7450_21 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_USE_TB | \ - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \ - CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \ - CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP | \ - CPU_FTR_NEED_COHERENT) -#define CPU_FTRS_7450_23 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_USE_TB | \ - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \ - CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \ - CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_NEED_COHERENT) -#define CPU_FTRS_7455_1 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_USE_TB | \ - CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | \ - CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_HAS_HIGH_BATS | \ - CPU_FTR_NEED_COHERENT) -#define CPU_FTRS_7455_20 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_USE_TB | \ - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \ - CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \ - CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP | \ - CPU_FTR_NEED_COHERENT | CPU_FTR_HAS_HIGH_BATS) -#define CPU_FTRS_7455 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_USE_TB | \ - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \ - CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \ - CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \ - CPU_FTR_NEED_COHERENT) -#define CPU_FTRS_7447_10 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_USE_TB | \ - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \ - CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \ - CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \ - CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC) -#define CPU_FTRS_7447 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_USE_TB | \ - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \ - CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \ - CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \ - CPU_FTR_NEED_COHERENT) -#define CPU_FTRS_7447A (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_USE_TB | \ - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \ - CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \ - CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \ - CPU_FTR_NEED_COHERENT) -#define CPU_FTRS_82XX (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB) -#define CPU_FTRS_G2_LE (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | \ - CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS) -#define CPU_FTRS_E300 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | \ - CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS | \ - CPU_FTR_COMMON) -#define CPU_FTRS_CLASSIC32 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE) -#define CPU_FTRS_POWER3_32 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE) -#define CPU_FTRS_POWER4_32 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_NODSISRALIGN) -#define CPU_FTRS_970_32 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \ - CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_ALTIVEC_COMP | \ - CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN) -#define CPU_FTRS_8XX (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB) -#define CPU_FTRS_40X (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ - CPU_FTR_NODSISRALIGN) -#define CPU_FTRS_44X (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ - CPU_FTR_NODSISRALIGN) -#define CPU_FTRS_E200 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN) -#define CPU_FTRS_E500 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ - CPU_FTR_NODSISRALIGN) -#define CPU_FTRS_E500_2 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ - CPU_FTR_BIG_PHYS | CPU_FTR_NODSISRALIGN) -#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN) +enum { + CPU_FTRS_PPC601 = CPU_FTR_COMMON | CPU_FTR_601 | CPU_FTR_HPTE_TABLE, + CPU_FTRS_603 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | + CPU_FTR_MAYBE_CAN_NAP, + CPU_FTRS_604 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE, + CPU_FTRS_740_NOTAU = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | + CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP, + CPU_FTRS_740 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | + CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP, + CPU_FTRS_750 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | + CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP, + CPU_FTRS_750FX1 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | + CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | + CPU_FTR_DUAL_PLL_750FX | CPU_FTR_NO_DPM, + CPU_FTRS_750FX2 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | + CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | + CPU_FTR_NO_DPM, + CPU_FTRS_750FX = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | + CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | + CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS, + CPU_FTRS_750GX = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | + CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | + CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | + CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS, + CPU_FTRS_7400_NOTAU = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | + CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | + CPU_FTR_MAYBE_CAN_NAP, + CPU_FTRS_7400 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | + CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | + CPU_FTR_MAYBE_CAN_NAP, + CPU_FTRS_7450_20 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | + CPU_FTR_NEED_COHERENT, + CPU_FTRS_7450_21 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | + CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | + CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP | + CPU_FTR_NEED_COHERENT, + CPU_FTRS_7450_23 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | + CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | + CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_NEED_COHERENT, + CPU_FTRS_7455_1 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | + CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | + CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_HAS_HIGH_BATS | + CPU_FTR_NEED_COHERENT, + CPU_FTRS_7455_20 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | + CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | + CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP | + CPU_FTR_NEED_COHERENT | CPU_FTR_HAS_HIGH_BATS, + CPU_FTRS_7455 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | + CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | + CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | + CPU_FTR_NEED_COHERENT, + CPU_FTRS_7447_10 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | + CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | + CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | + CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC, + CPU_FTRS_7447 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | + CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | + CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | + CPU_FTR_NEED_COHERENT, + CPU_FTRS_7447A = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | + CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | + CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | + CPU_FTR_NEED_COHERENT, + CPU_FTRS_82XX = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB, + CPU_FTRS_G2_LE = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | + CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS, + CPU_FTRS_E300 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | + CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS | + CPU_FTR_COMMON, + CPU_FTRS_CLASSIC32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, + CPU_FTRS_POWER3_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, + CPU_FTRS_POWER4_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_NODSISRALIGN, + CPU_FTRS_970_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN, + CPU_FTRS_8XX = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, + CPU_FTRS_40X = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_NODSISRALIGN, + CPU_FTRS_44X = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_NODSISRALIGN, + CPU_FTRS_E200 = CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN, + CPU_FTRS_E500 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_NODSISRALIGN, + CPU_FTRS_E500_2 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_BIG_PHYS | CPU_FTR_NODSISRALIGN, + CPU_FTRS_GENERIC_32 = CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN, #ifdef __powerpc64__ -#define CPU_FTRS_POWER3 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ - CPU_FTR_HPTE_TABLE | CPU_FTR_IABR) -#define CPU_FTRS_RS64 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ - CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | \ - CPU_FTR_MMCRA | CPU_FTR_CTRL) -#define CPU_FTRS_POWER4 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ - CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA) -#define CPU_FTRS_PPC970 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ - CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \ - CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA) -#define CPU_FTRS_POWER5 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ - CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \ - CPU_FTR_MMCRA | CPU_FTR_SMT | \ - CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ - CPU_FTR_MMCRA_SIHV | CPU_FTR_PURR) -#define CPU_FTRS_CELL (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ - CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \ - CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ - CPU_FTR_CTRL | CPU_FTR_PAUSE_ZERO) -#define CPU_FTRS_COMPATIBLE (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ - CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2) + CPU_FTRS_POWER3 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_IABR, + CPU_FTRS_RS64 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | + CPU_FTR_MMCRA | CPU_FTR_CTRL, + CPU_FTRS_POWER4 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA, + CPU_FTRS_PPC970 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | + CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA, + CPU_FTRS_POWER5 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | + CPU_FTR_MMCRA | CPU_FTR_SMT | + CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | + CPU_FTR_MMCRA_SIHV | CPU_FTR_PURR, + CPU_FTRS_CELL = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | + CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | + CPU_FTR_CTRL | CPU_FTR_PAUSE_ZERO, + CPU_FTRS_COMPATIBLE = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2, #endif + CPU_FTRS_POSSIBLE = #ifdef __powerpc64__ -#define CPU_FTRS_POSSIBLE \ - (CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 | \ - CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_CELL | \ - CPU_FTR_CI_LARGE_PAGE) + CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 | + CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_CELL | + CPU_FTR_CI_LARGE_PAGE | #else -enum { - CPU_FTRS_POSSIBLE = #if CLASSIC_PPC CPU_FTRS_PPC601 | CPU_FTRS_603 | CPU_FTRS_604 | CPU_FTRS_740_NOTAU | CPU_FTRS_740 | CPU_FTRS_750 | CPU_FTRS_750FX1 | @@ -369,18 +368,14 @@ enum { #ifdef CONFIG_E500 CPU_FTRS_E500 | CPU_FTRS_E500_2 | #endif - 0, -}; #endif /* __powerpc64__ */ + 0, + CPU_FTRS_ALWAYS = #ifdef __powerpc64__ -#define CPU_FTRS_ALWAYS \ - (CPU_FTRS_POWER3 & CPU_FTRS_RS64 & CPU_FTRS_POWER4 & \ - CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_CELL & \ - CPU_FTRS_POSSIBLE) + CPU_FTRS_POWER3 & CPU_FTRS_RS64 & CPU_FTRS_POWER4 & + CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_CELL & #else -enum { - CPU_FTRS_ALWAYS = #if CLASSIC_PPC CPU_FTRS_PPC601 & CPU_FTRS_603 & CPU_FTRS_604 & CPU_FTRS_740_NOTAU & CPU_FTRS_740 & CPU_FTRS_750 & CPU_FTRS_750FX1 & @@ -414,9 +409,9 @@ enum { #ifdef CONFIG_E500 CPU_FTRS_E500 & CPU_FTRS_E500_2 & #endif +#endif /* __powerpc64__ */ CPU_FTRS_POSSIBLE, }; -#endif /* __powerpc64__ */ static inline int cpu_has_feature(unsigned long feature) { diff --git a/trunk/include/asm-powerpc/firmware.h b/trunk/include/asm-powerpc/firmware.h index 77069df92bf8..ce3788224ed0 100644 --- a/trunk/include/asm-powerpc/firmware.h +++ b/trunk/include/asm-powerpc/firmware.h @@ -82,11 +82,13 @@ enum { /* This is used to identify firmware features which are available * to the kernel. */ -extern unsigned long powerpc_firmware_features; +extern unsigned long ppc64_firmware_features; -#define firmware_has_feature(feature) \ - ((FW_FEATURE_ALWAYS & (feature)) || \ - (FW_FEATURE_POSSIBLE & powerpc_firmware_features & (feature))) +static inline unsigned long firmware_has_feature(unsigned long feature) +{ + return (FW_FEATURE_ALWAYS & feature) || + (FW_FEATURE_POSSIBLE & ppc64_firmware_features & feature); +} extern void system_reset_fwnmi(void); extern void machine_check_fwnmi(void); diff --git a/trunk/include/asm-powerpc/floppy.h b/trunk/include/asm-powerpc/floppy.h index 608164c39efb..e258778ca429 100644 --- a/trunk/include/asm-powerpc/floppy.h +++ b/trunk/include/asm-powerpc/floppy.h @@ -35,7 +35,6 @@ #ifdef CONFIG_PCI #include -#include /* for ppc64_isabridge_dev */ #define fd_dma_setup(addr,size,mode,io) powerpc_fd_dma_setup(addr,size,mode,io) @@ -53,12 +52,12 @@ static __inline__ int powerpc_fd_dma_setup(char *addr, unsigned long size, if (bus_addr && (addr != prev_addr || size != prev_size || dir != prev_dir)) { /* different from last time -- unmap prev */ - pci_unmap_single(ppc64_isabridge_dev, bus_addr, prev_size, prev_dir); + pci_unmap_single(NULL, bus_addr, prev_size, prev_dir); bus_addr = 0; } if (!bus_addr) /* need to map it */ - bus_addr = pci_map_single(ppc64_isabridge_dev, addr, size, dir); + bus_addr = pci_map_single(NULL, addr, size, dir); /* remember this one as prev */ prev_addr = addr; diff --git a/trunk/include/asm-powerpc/hvcall.h b/trunk/include/asm-powerpc/hvcall.h index b72c04f3f551..38ca9ad6110d 100644 --- a/trunk/include/asm-powerpc/hvcall.h +++ b/trunk/include/asm-powerpc/hvcall.h @@ -9,7 +9,6 @@ #define H_Closed 2 /* Resource closed */ #define H_Constrained 4 /* Resource request constrained to max allowed */ #define H_InProgress 14 /* Kind of like busy */ -#define H_Pending 17 /* returned from H_POLL_PENDING */ #define H_Continue 18 /* Returned from H_Join on success */ #define H_LongBusyStartRange 9900 /* Start of long busy range */ #define H_LongBusyOrder1msec 9900 /* Long busy, hint that 1msec is a good time to retry */ diff --git a/trunk/include/asm-powerpc/hvconsole.h b/trunk/include/asm-powerpc/hvconsole.h index 35ea69e8121f..34daf7b9b62f 100644 --- a/trunk/include/asm-powerpc/hvconsole.h +++ b/trunk/include/asm-powerpc/hvconsole.h @@ -24,18 +24,28 @@ #ifdef __KERNEL__ /* - * PSeries firmware will only send/recv up to 16 bytes of character data per - * hcall. + * This is the max number of console adapters that can/will be found as + * console devices on first stage console init. Any number beyond this range + * can't be used as a console device but is still a valid tty device. */ -#define MAX_VIO_PUT_CHARS 16 -#define SIZE_VIO_GET_CHARS 16 +#define MAX_NR_HVC_CONSOLES 16 -/* - * Vio firmware always attempts to fetch MAX_VIO_GET_CHARS chars. The 'count' - * parm is included to conform to put_chars() function pointer template - */ +/* implemented by a low level driver */ +struct hv_ops { + int (*get_chars)(uint32_t vtermno, char *buf, int count); + int (*put_chars)(uint32_t vtermno, const char *buf, int count); +}; extern int hvc_get_chars(uint32_t vtermno, char *buf, int count); extern int hvc_put_chars(uint32_t vtermno, const char *buf, int count); +struct hvc_struct; + +/* Register a vterm and a slot index for use as a console (console_init) */ +extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops); +/* register a vterm for hvc tty operation (module_init or hotplug add) */ +extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq, + struct hv_ops *ops); +/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */ +extern int __devexit hvc_remove(struct hvc_struct *hp); #endif /* __KERNEL__ */ #endif /* _PPC64_HVCONSOLE_H */ diff --git a/trunk/include/asm-powerpc/machdep.h b/trunk/include/asm-powerpc/machdep.h index 5ed847680754..5348b820788c 100644 --- a/trunk/include/asm-powerpc/machdep.h +++ b/trunk/include/asm-powerpc/machdep.h @@ -47,7 +47,6 @@ struct smp_ops_t { #endif struct machdep_calls { - char *name; #ifdef CONFIG_PPC64 void (*hpte_invalidate)(unsigned long slot, unsigned long va, @@ -86,9 +85,9 @@ struct machdep_calls { void (*iommu_dev_setup)(struct pci_dev *dev); void (*iommu_bus_setup)(struct pci_bus *bus); void (*irq_bus_setup)(struct pci_bus *bus); -#endif /* CONFIG_PPC64 */ +#endif - int (*probe)(void); + int (*probe)(int platform); void (*setup_arch)(void); void (*init_early)(void); /* Optional, may be NULL. */ @@ -159,12 +158,6 @@ struct machdep_calls { /* Idle loop for this platform, leave empty for default idle loop */ void (*idle_loop)(void); - /* - * Function for waiting for work with reduced power in idle loop; - * called with interrupts disabled. - */ - void (*power_save)(void); - /* Function to enable performance monitor counters for this platform, called once per cpu. */ void (*enable_pmcs)(void); @@ -177,6 +170,13 @@ struct machdep_calls { May be NULL. */ void (*init)(void); + void (*idle)(void); + void (*power_save)(void); + + void (*heartbeat)(void); + unsigned long heartbeat_reset; + unsigned long heartbeat_count; + void (*setup_io_mappings)(void); void (*early_serial_map)(void); @@ -208,6 +208,8 @@ struct machdep_calls { /* Called at then very end of pcibios_init() */ void (*pcibios_after_init)(void); + /* this is for modules, since _machine can be a define -- Cort */ + int ppc_machine; #endif /* CONFIG_PPC32 */ /* Called to shutdown machine specific hardware not already controlled @@ -240,29 +242,10 @@ struct machdep_calls { #endif /* CONFIG_KEXEC */ }; -extern void power4_idle(void); -extern void ppc6xx_idle(void); +extern void default_idle(void); +extern void native_idle(void); -/* - * ppc_md contains a copy of the machine description structure for the - * current platform. machine_id contains the initial address where the - * description was found during boot. - */ extern struct machdep_calls ppc_md; -extern struct machdep_calls *machine_id; - -#define __machine_desc __attribute__ ((__section__ (".machine.desc"))) - -#define define_machine(name) struct machdep_calls mach_##name __machine_desc = -#define machine_is(name) \ - ({ \ - extern struct machdep_calls mach_##name \ - __attribute__((weak)); \ - machine_id == &mach_##name; \ - }) - -extern void probe_machine(void); - extern char cmd_line[COMMAND_LINE_SIZE]; #ifdef CONFIG_PPC_PMAC diff --git a/trunk/include/asm-powerpc/oprofile_impl.h b/trunk/include/asm-powerpc/oprofile_impl.h index 5b33994cd488..338e6a7cff4a 100644 --- a/trunk/include/asm-powerpc/oprofile_impl.h +++ b/trunk/include/asm-powerpc/oprofile_impl.h @@ -17,6 +17,9 @@ /* Per-counter configuration as set via oprofilefs. */ struct op_counter_config { +#ifdef __powerpc64__ + unsigned long valid; +#endif unsigned long enabled; unsigned long event; unsigned long count; @@ -35,6 +38,9 @@ struct op_system_config { #endif unsigned long enable_kernel; unsigned long enable_user; +#ifdef CONFIG_PPC64 + unsigned long backtrace_spinlocks; +#endif }; /* Per-arch configuration */ @@ -50,12 +56,17 @@ struct op_powerpc_model { int num_counters; }; +#ifdef CONFIG_FSL_BOOKE extern struct op_powerpc_model op_model_fsl_booke; +#else /* Otherwise, it's classic */ + +#ifdef CONFIG_PPC64 extern struct op_powerpc_model op_model_rs64; extern struct op_powerpc_model op_model_power4; -extern struct op_powerpc_model op_model_7450; -#ifndef CONFIG_FSL_BOOKE +#else /* Otherwise, CONFIG_PPC32 */ +extern struct op_powerpc_model op_model_7450; +#endif /* All the classic PPC parts use these */ static inline unsigned int ctr_read(unsigned int i) @@ -123,7 +134,5 @@ static inline void ctr_write(unsigned int i, unsigned int val) } #endif /* !CONFIG_FSL_BOOKE */ -extern void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth); - #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_OPROFILE_IMPL_H */ diff --git a/trunk/include/asm-powerpc/paca.h b/trunk/include/asm-powerpc/paca.h index 706325f99a84..4465b95ebef0 100644 --- a/trunk/include/asm-powerpc/paca.h +++ b/trunk/include/asm-powerpc/paca.h @@ -105,7 +105,5 @@ struct paca_struct { extern struct paca_struct paca[]; -void setup_boot_paca(void); - #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_PACA_H */ diff --git a/trunk/include/asm-powerpc/percpu.h b/trunk/include/asm-powerpc/percpu.h index 184a7a4d2fdf..464301cd0d03 100644 --- a/trunk/include/asm-powerpc/percpu.h +++ b/trunk/include/asm-powerpc/percpu.h @@ -27,7 +27,7 @@ #define percpu_modcopy(pcpudst, src, size) \ do { \ unsigned int __i; \ - for_each_possible_cpu(__i) \ + for_each_cpu(__i) \ memcpy((pcpudst)+__per_cpu_offset(__i), \ (src), (size)); \ } while (0) diff --git a/trunk/include/asm-powerpc/pmac_feature.h b/trunk/include/asm-powerpc/pmac_feature.h index d3599cc9aa74..3221628130c4 100644 --- a/trunk/include/asm-powerpc/pmac_feature.h +++ b/trunk/include/asm-powerpc/pmac_feature.h @@ -305,7 +305,7 @@ extern void pmac_feature_init(void); extern void pmac_set_early_video_resume(void (*proc)(void *data), void *data); extern void pmac_call_early_video_resume(void); -#define PMAC_FTR_DEF(x) ((0x6660000) | (x)) +#define PMAC_FTR_DEF(x) ((_MACH_Pmac << 16) | (x)) /* The AGP driver registers itself here */ extern void pmac_register_agp_pm(struct pci_dev *bridge, diff --git a/trunk/include/asm-powerpc/processor.h b/trunk/include/asm-powerpc/processor.h index 93f83efeb310..1c64a211cf19 100644 --- a/trunk/include/asm-powerpc/processor.h +++ b/trunk/include/asm-powerpc/processor.h @@ -22,6 +22,22 @@ * -- BenH. */ +/* Platforms codes (to be obsoleted) */ +#define PLATFORM_PSERIES 0x0100 +#define PLATFORM_PSERIES_LPAR 0x0101 +#define PLATFORM_ISERIES_LPAR 0x0201 +#define PLATFORM_LPAR 0x0001 +#define PLATFORM_POWERMAC 0x0400 +#define PLATFORM_MAPLE 0x0500 +#define PLATFORM_PREP 0x0600 +#define PLATFORM_CHRP 0x0700 +#define PLATFORM_CELL 0x1000 + +/* Compat platform codes for 32 bits */ +#define _MACH_prep PLATFORM_PREP +#define _MACH_Pmac PLATFORM_POWERMAC +#define _MACH_chrp PLATFORM_CHRP + /* PREP sub-platform types see residual.h for these */ #define _PREP_Motorola 0x01 /* motorola prep */ #define _PREP_Firm 0x02 /* firmworks prep */ @@ -33,14 +49,18 @@ #define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */ #define _CHRP_Pegasos 0x06 /* Genesi/bplan's Pegasos and Pegasos2 */ -#if defined(__KERNEL__) && defined(CONFIG_PPC32) +#ifdef __KERNEL__ +#define platform_is_pseries() (_machine == PLATFORM_PSERIES || \ + _machine == PLATFORM_PSERIES_LPAR) -extern int _chrp_type; +#if defined(CONFIG_PPC_MULTIPLATFORM) +extern int _machine; -#ifdef CONFIG_PPC_PREP +#ifdef CONFIG_PPC32 /* what kind of prep workstation we are */ extern int _prep_type; +extern int _chrp_type; /* * This is used to identify the board type from a given PReP board @@ -50,14 +70,17 @@ extern int _prep_type; extern unsigned char ucBoardRev; extern unsigned char ucBoardRevMaj, ucBoardRevMin; -#endif /* CONFIG_PPC_PREP */ +#endif /* CONFIG_PPC32 */ -#ifndef CONFIG_PPC_MULTIPLATFORM +#elif defined(CONFIG_PPC_ISERIES) +/* + * iSeries is soon to become MULTIPLATFORM hopefully ... + */ +#define _machine PLATFORM_ISERIES_LPAR +#else #define _machine 0 #endif /* CONFIG_PPC_MULTIPLATFORM */ - -#endif /* defined(__KERNEL__) && defined(CONFIG_PPC32) */ - +#endif /* __KERNEL__ */ /* * Default implementation of macro that returns current * instruction pointer ("program counter"). @@ -228,10 +251,6 @@ static inline unsigned long __pack_fe01(unsigned int fpmode) #define cpu_relax() barrier() #endif -/* Check that a certain kernel stack pointer is valid in task_struct p */ -int validate_sp(unsigned long sp, struct task_struct *p, - unsigned long nbytes); - /* * Prefetch macros. */ diff --git a/trunk/include/asm-powerpc/prom.h b/trunk/include/asm-powerpc/prom.h index 97ef1cd71a4d..782e13a070a1 100644 --- a/trunk/include/asm-powerpc/prom.h +++ b/trunk/include/asm-powerpc/prom.h @@ -149,14 +149,12 @@ extern struct device_node *of_node_get(struct device_node *node); extern void of_node_put(struct device_node *node); /* For scanning the flat device-tree at boot time */ -extern int __init of_scan_flat_dt(int (*it)(unsigned long node, - const char *uname, int depth, - void *data), - void *data); -extern void* __init of_get_flat_dt_prop(unsigned long node, const char *name, - unsigned long *size); -extern int __init of_flat_dt_is_compatible(unsigned long node, const char *name); -extern unsigned long __init of_get_flat_dt_root(void); +int __init of_scan_flat_dt(int (*it)(unsigned long node, + const char *uname, int depth, + void *data), + void *data); +void* __init of_get_flat_dt_prop(unsigned long node, const char *name, + unsigned long *size); /* For updating the device tree at runtime */ extern void of_attach_node(struct device_node *); diff --git a/trunk/include/asm-powerpc/reg.h b/trunk/include/asm-powerpc/reg.h index bd467bf5cf5a..72bfe3af0460 100644 --- a/trunk/include/asm-powerpc/reg.h +++ b/trunk/include/asm-powerpc/reg.h @@ -622,10 +622,6 @@ extern void ppc64_runlatch_off(void); extern unsigned long scom970_read(unsigned int address); extern void scom970_write(unsigned int address, unsigned long value); -#else -#define ppc64_runlatch_on() -#define ppc64_runlatch_off() - #endif /* CONFIG_PPC64 */ #define __get_SP() ({unsigned long sp; \ diff --git a/trunk/include/asm-powerpc/smp.h b/trunk/include/asm-powerpc/smp.h index 4a716f707cf6..98581e5a8279 100644 --- a/trunk/include/asm-powerpc/smp.h +++ b/trunk/include/asm-powerpc/smp.h @@ -29,6 +29,7 @@ #endif extern int boot_cpuid; +extern int boot_cpuid_phys; extern void cpu_die(void); @@ -98,7 +99,6 @@ extern void smp_release_cpus(void); #else /* 32-bit */ #ifndef CONFIG_SMP -extern int boot_cpuid_phys; #define get_hard_smp_processor_id(cpu) boot_cpuid_phys #define set_hard_smp_processor_id(cpu, phys) #endif diff --git a/trunk/include/asm-powerpc/spu.h b/trunk/include/asm-powerpc/spu.h index f431d8b0b651..38bacf2f6e0c 100644 --- a/trunk/include/asm-powerpc/spu.h +++ b/trunk/include/asm-powerpc/spu.h @@ -110,7 +110,6 @@ struct spu { char *name; unsigned long local_store_phys; u8 *local_store; - unsigned long problem_phys; struct spu_problem __iomem *problem; struct spu_priv1 __iomem *priv1; struct spu_priv2 __iomem *priv2; @@ -138,7 +137,6 @@ struct spu { void (* wbox_callback)(struct spu *spu); void (* ibox_callback)(struct spu *spu); void (* stop_callback)(struct spu *spu); - void (* mfc_callback)(struct spu *spu); char irq_c0[8]; char irq_c1[8]; @@ -151,14 +149,6 @@ int spu_irq_class_0_bottom(struct spu *spu); int spu_irq_class_1_bottom(struct spu *spu); void spu_irq_setaffinity(struct spu *spu, int cpu); -/* system callbacks from the SPU */ -struct spu_syscall_block { - u64 nr_ret; - u64 parm[6]; -}; -extern long spu_sys_callback(struct spu_syscall_block *s); - -/* syscalls implemented in spufs */ extern struct spufs_calls { asmlinkage long (*create_thread)(const char __user *name, unsigned int flags, mode_t mode); @@ -409,6 +399,7 @@ struct spu_priv1 { #define SPU_GET_REVISION_BITS(vr) (vr & SPU_REVISION_BITS) u8 pad_0x28_0x100[0x100 - 0x28]; /* 0x28 */ + /* Interrupt Area */ u64 int_mask_RW[3]; /* 0x100 */ #define CLASS0_ENABLE_DMA_ALIGNMENT_INTR 0x1L diff --git a/trunk/include/asm-powerpc/syscalls.h b/trunk/include/asm-powerpc/syscalls.h deleted file mode 100644 index c2fe79d4f90f..000000000000 --- a/trunk/include/asm-powerpc/syscalls.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef __ASM_POWERPC_SYSCALLS_H -#define __ASM_POWERPC_SYSCALLS_H -#ifdef __KERNEL__ - -#include -#include -#include -#include - -struct new_utsname; -struct pt_regs; -struct rtas_args; -struct sigaction; - -asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, - unsigned long prot, unsigned long flags, - unsigned long fd, off_t offset); -asmlinkage unsigned long sys_mmap2(unsigned long addr, size_t len, - unsigned long prot, unsigned long flags, - unsigned long fd, unsigned long pgoff); -asmlinkage int sys_execve(unsigned long a0, unsigned long a1, - unsigned long a2, unsigned long a3, unsigned long a4, - unsigned long a5, struct pt_regs *regs); -asmlinkage int sys_clone(unsigned long clone_flags, unsigned long usp, - int __user *parent_tidp, void __user *child_threadptr, - int __user *child_tidp, int p6, struct pt_regs *regs); -asmlinkage int sys_fork(unsigned long p1, unsigned long p2, - unsigned long p3, unsigned long p4, unsigned long p5, - unsigned long p6, struct pt_regs *regs); -asmlinkage int sys_vfork(unsigned long p1, unsigned long p2, - unsigned long p3, unsigned long p4, unsigned long p5, - unsigned long p6, struct pt_regs *regs); -asmlinkage int sys_pipe(int __user *fildes); -asmlinkage long sys_rt_sigaction(int sig, - const struct sigaction __user *act, - struct sigaction __user *oact, size_t sigsetsize); -asmlinkage int sys_ipc(uint call, int first, unsigned long second, - long third, void __user *ptr, long fifth); -asmlinkage long ppc64_personality(unsigned long personality); -asmlinkage int ppc_rtas(struct rtas_args __user *uargs); -asmlinkage time_t sys64_time(time_t __user * tloc); -asmlinkage long ppc_newuname(struct new_utsname __user * name); - -asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, - size_t sigsetsize); - -#ifndef __powerpc64__ -asmlinkage long sys_sigaltstack(const stack_t __user *uss, - stack_t __user *uoss, int r5, int r6, int r7, int r8, - struct pt_regs *regs); -#else /* __powerpc64__ */ -asmlinkage long sys_sigaltstack(const stack_t __user *uss, - stack_t __user *uoss, unsigned long r5, unsigned long r6, - unsigned long r7, unsigned long r8, struct pt_regs *regs); -#endif /* __powerpc64__ */ - -#endif /* __KERNEL__ */ -#endif /* __ASM_POWERPC_SYSCALLS_H */ diff --git a/trunk/include/asm-powerpc/unistd.h b/trunk/include/asm-powerpc/unistd.h index 1e990747dce7..35556993f066 100644 --- a/trunk/include/asm-powerpc/unistd.h +++ b/trunk/include/asm-powerpc/unistd.h @@ -425,7 +425,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6 #include #include #include -#include #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR @@ -461,9 +460,43 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6 * System call prototypes. */ #ifdef __KERNEL_SYSCALLS__ +extern pid_t setsid(void); +extern int write(int fd, const char *buf, off_t count); +extern int read(int fd, char *buf, off_t count); +extern off_t lseek(int fd, off_t offset, int count); +extern int dup(int fd); extern int execve(const char *file, char **argv, char **envp); +extern int open(const char *file, int flag, int mode); +extern int close(int fd); +extern pid_t waitpid(pid_t pid, int *wait_stat, int options); #endif /* __KERNEL_SYSCALLS__ */ +/* + * Functions that implement syscalls. + */ +unsigned long sys_mmap(unsigned long addr, size_t len, unsigned long prot, + unsigned long flags, unsigned long fd, off_t offset); +unsigned long sys_mmap2(unsigned long addr, size_t len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff); +struct pt_regs; +int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, + unsigned long a3, unsigned long a4, unsigned long a5, + struct pt_regs *regs); +int sys_clone(unsigned long clone_flags, unsigned long usp, + int __user *parent_tidp, void __user *child_threadptr, + int __user *child_tidp, int p6, struct pt_regs *regs); +int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3, + unsigned long p4, unsigned long p5, unsigned long p6, + struct pt_regs *regs); +int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3, + unsigned long p4, unsigned long p5, unsigned long p6, + struct pt_regs *regs); +int sys_pipe(int __user *fildes); +struct sigaction; +long sys_rt_sigaction(int sig, const struct sigaction __user *act, + struct sigaction __user *oact, size_t sigsetsize); + /* * "Conditional" syscalls * diff --git a/trunk/include/asm-powerpc/vdso_datapage.h b/trunk/include/asm-powerpc/vdso_datapage.h index 8a94f0eba5e9..7aa92086c3fb 100644 --- a/trunk/include/asm-powerpc/vdso_datapage.h +++ b/trunk/include/asm-powerpc/vdso_datapage.h @@ -55,9 +55,6 @@ struct vdso_data { __u32 minor; /* Minor number 0x14 */ } version; - /* Note about the platform flags: it now only contains the lpar - * bit. The actual platform number is dead and burried - */ __u32 platform; /* Platform flags 0x18 */ __u32 processor; /* Processor type 0x1C */ __u64 processorCount; /* # of physical processors 0x20 */ diff --git a/trunk/include/asm-ppc/machdep.h b/trunk/include/asm-ppc/machdep.h index e1a0a7b213d7..a3e8a45e45a9 100644 --- a/trunk/include/asm-ppc/machdep.h +++ b/trunk/include/asm-ppc/machdep.h @@ -19,18 +19,6 @@ struct pci_dev; struct seq_file; struct file; -/* - * This is for compatibility with ARCH=powerpc. - */ -#define machine_is(x) __MACHINE_IS_##x -#define __MACHINE_IS_powermac 0 -#define __MACHINE_IS_chrp 0 -#ifdef CONFIG_PPC_PREP -#define __MACHINE_IS_prep 1 -#else -#define __MACHINE_IS_prep 0 -#endif - /* We export this macro for external modules like Alsa to know if * ppc_md.feature_call is implemented or not */ @@ -56,7 +44,7 @@ struct machdep_calls { void (*power_off)(void); void (*halt)(void); - void (*idle_loop)(void); + void (*idle)(void); void (*power_save)(void); long (*time_init)(void); /* Optional, may be NULL */ @@ -116,6 +104,9 @@ struct machdep_calls { unsigned long size, pgprot_t vma_prot); + /* this is for modules, since _machine can be a define -- Cort */ + int ppc_machine; + /* Motherboard/chipset features. This is a kind of general purpose * hook used to control some machine specific features (like reset * lines, chip power control, etc...). diff --git a/trunk/include/asm-ppc/mpc52xx.h b/trunk/include/asm-ppc/mpc52xx.h index 7e9842805a28..6167f74635f7 100644 --- a/trunk/include/asm-ppc/mpc52xx.h +++ b/trunk/include/asm-ppc/mpc52xx.h @@ -355,7 +355,6 @@ struct mpc52xx_xlb { u32 snoop_window; /* XLB + 0x70 */ }; -#define MPC52xx_XLB_CFG_PLDIS (1 << 31) #define MPC52xx_XLB_CFG_SNOOP (1 << 15) /* Clock Distribution control */ @@ -428,9 +427,6 @@ extern void mpc52xx_calibrate_decr(void); extern void mpc52xx_find_bridges(void); -extern void mpc52xx_setup_cpu(void); - - /* Matching of PSC function */ struct mpc52xx_psc_func { diff --git a/trunk/include/asm-ppc/pgtable.h b/trunk/include/asm-ppc/pgtable.h index 570b355162fa..e1c62da12e74 100644 --- a/trunk/include/asm-ppc/pgtable.h +++ b/trunk/include/asm-ppc/pgtable.h @@ -837,8 +837,7 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma, */ #define pgtable_cache_init() do { } while (0) -extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, - pmd_t **pmdp); +extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep); #include diff --git a/trunk/include/asm-ppc/prom.h b/trunk/include/asm-ppc/prom.h index adc5ae784924..6d431d6fb022 100644 --- a/trunk/include/asm-ppc/prom.h +++ b/trunk/include/asm-ppc/prom.h @@ -8,19 +8,126 @@ #ifndef _PPC_PROM_H #define _PPC_PROM_H -/* This is used in arch/ppc/mm/mem_pieces.h */ +#include +#include + +typedef u32 phandle; +typedef u32 ihandle; + +struct address_range { + unsigned int space; + unsigned int address; + unsigned int size; +}; + +struct interrupt_info { + int line; + int sense; /* +ve/-ve logic, edge or level, etc. */ +}; + struct reg_property { unsigned int address; unsigned int size; }; +struct property { + char *name; + int length; + unsigned char *value; + struct property *next; +}; + +/* + * Note: don't change this structure for now or you'll break BootX ! + */ +struct device_node { + char *name; + char *type; + phandle node; + int n_addrs; + struct address_range *addrs; + int n_intrs; + struct interrupt_info *intrs; + char *full_name; + struct property *properties; + struct device_node *parent; + struct device_node *child; + struct device_node *sibling; + struct device_node *next; /* next device of same type */ + struct device_node *allnext; /* next in list of all nodes */ +}; + +struct prom_args; +typedef void (*prom_entry)(struct prom_args *); + +/* OBSOLETE: Old style node lookup */ +extern struct device_node *find_devices(const char *name); +extern struct device_node *find_type_devices(const char *type); +extern struct device_node *find_path_device(const char *path); +extern struct device_node *find_compatible_devices(const char *type, + const char *compat); +extern struct device_node *find_all_nodes(void); + +/* New style node lookup */ +extern struct device_node *of_find_node_by_name(struct device_node *from, + const char *name); +extern struct device_node *of_find_node_by_type(struct device_node *from, + const char *type); +extern struct device_node *of_find_compatible_node(struct device_node *from, + const char *type, const char *compat); +extern struct device_node *of_find_node_by_path(const char *path); +extern struct device_node *of_find_all_nodes(struct device_node *prev); +extern struct device_node *of_get_parent(const struct device_node *node); +extern struct device_node *of_get_next_child(const struct device_node *node, + struct device_node *prev); +extern struct device_node *of_node_get(struct device_node *node); +extern void of_node_put(struct device_node *node); + +/* Other Prototypes */ +extern void abort(void); +extern unsigned long prom_init(int, int, prom_entry); +extern void prom_print(const char *msg); +extern void relocate_nodes(void); +extern void finish_device_tree(void); +extern int device_is_compatible(struct device_node *device, const char *); +extern int machine_is_compatible(const char *compat); +extern unsigned char *get_property(struct device_node *node, const char *name, + int *lenp); +extern int prom_add_property(struct device_node* np, struct property* prop); +extern void prom_get_irq_senses(unsigned char *, int, int); +extern int prom_n_addr_cells(struct device_node* np); +extern int prom_n_size_cells(struct device_node* np); + +extern struct resource* +request_OF_resource(struct device_node* node, int index, const char* name_postfix); +extern int release_OF_resource(struct device_node* node, int index); + +extern void print_properties(struct device_node *node); +extern int call_rtas(const char *service, int nargs, int nret, + unsigned long *outputs, ...); + /* - * These macros assist in performing the address calculations that we - * need to do to access data when the kernel is running at an address - * that is different from the address that the kernel is linked at. - * The reloc_offset() function returns the difference between these - * two addresses and the macros simplify the process of adding or - * subtracting this offset to/from pointer values. + * PCI <-> OF matching functions + */ +struct pci_bus; +struct pci_dev; +extern int pci_device_from_OF_node(struct device_node *node, + u8* bus, u8* devfn); +extern struct device_node* pci_busdev_to_OF_node(struct pci_bus *, int); +extern struct device_node* pci_device_to_OF_node(struct pci_dev *); +extern void pci_create_OF_bus_map(void); + +/* + * When we call back to the Open Firmware client interface, we usually + * have to do that before the kernel is relocated to its final location + * (this is because we can't use OF after we have overwritten the + * exception vectors with our exception handlers). These macros assist + * in performing the address calculations that we need to do to access + * data when the kernel is running at an address that is different from + * the address that the kernel is linked at. The reloc_offset() function + * returns the difference between these two addresses and the macros + * simplify the process of adding or subtracting this offset to/from + * pointer values. See arch/ppc/kernel/prom.c for how these are used. */ extern unsigned long reloc_offset(void); extern unsigned long add_reloc_offset(unsigned long); @@ -29,12 +136,45 @@ extern unsigned long sub_reloc_offset(unsigned long); #define PTRRELOC(x) ((typeof(x))add_reloc_offset((unsigned long)(x))) #define PTRUNRELOC(x) ((typeof(x))sub_reloc_offset((unsigned long)(x))) + +/* + * OF address retreival & translation + */ + + +/* Translate an OF address block into a CPU physical address + */ +#define OF_BAD_ADDR ((u64)-1) +extern u64 of_translate_address(struct device_node *np, u32 *addr); + +/* Extract an address from a device, returns the region size and + * the address space flags too. The PCI version uses a BAR number + * instead of an absolute index + */ +extern u32 *of_get_address(struct device_node *dev, int index, + u64 *size, unsigned int *flags); +extern u32 *of_get_pci_address(struct device_node *dev, int bar_no, + u64 *size, unsigned int *flags); + +/* Get an address as a resource. Note that if your address is + * a PIO address, the conversion will fail if the physical address + * can't be internally converted to an IO token with + * pci_address_to_pio(), that is because it's either called to early + * or it can't be matched to any host bridge IO space + */ +extern int of_address_to_resource(struct device_node *dev, int index, + struct resource *r); +extern int of_pci_address_to_resource(struct device_node *dev, int bar, + struct resource *r); + +#ifndef CONFIG_PPC_OF /* - * Fallback definitions since we don't support OF in arch/ppc any more. + * Fallback definitions for builds where we don't have prom.c included. */ #define machine_is_compatible(x) 0 #define of_find_compatible_node(f, t, c) NULL #define get_property(p, n, l) NULL +#endif #endif /* _PPC_PROM_H */ #endif /* __KERNEL__ */ diff --git a/trunk/include/asm-ppc/serial.h b/trunk/include/asm-ppc/serial.h index b74af5461564..485a924e4d06 100644 --- a/trunk/include/asm-ppc/serial.h +++ b/trunk/include/asm-ppc/serial.h @@ -41,10 +41,15 @@ #else /* - * XXX Assume it has PC-style ISA serial ports - true for PReP at least. + * XXX Assume for now it has PC-style ISA serial ports. + * This is true for PReP and CHRP at least. */ #include +#if defined(CONFIG_MAC_SERIAL) +#define SERIAL_DEV_OFFSET ((_machine == _MACH_prep || _machine == _MACH_chrp) ? 0 : 2) +#endif + #endif /* !CONFIG_GEMINI and others */ #endif /* __ASM_SERIAL_H__ */ #endif /* __KERNEL__ */ diff --git a/trunk/include/linux/init_task.h b/trunk/include/linux/init_task.h index 41ecbb847f32..92146f3b7423 100644 --- a/trunk/include/linux/init_task.h +++ b/trunk/include/linux/init_task.h @@ -62,8 +62,6 @@ .posix_timers = LIST_HEAD_INIT(sig.posix_timers), \ .cpu_timers = INIT_CPU_TIMERS(sig.cpu_timers), \ .rlim = INIT_RLIMITS, \ - .pgrp = 1, \ - .session = 1, \ } #define INIT_SIGHAND(sighand) { \ diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index 870fe38378b1..e2ab2ac18d6b 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -773,7 +773,6 @@ #define PCI_DEVICE_ID_MOTOROLA_HAWK 0x4803 #define PCI_DEVICE_ID_MOTOROLA_HARRIER 0x480b #define PCI_DEVICE_ID_MOTOROLA_MPC5200 0x5803 -#define PCI_DEVICE_ID_MOTOROLA_MPC5200B 0x5809 #define PCI_VENDOR_ID_PROMISE 0x105a #define PCI_DEVICE_ID_PROMISE_20265 0x0d30 diff --git a/trunk/include/linux/pid.h b/trunk/include/linux/pid.h index 5b9082cc600f..5b2fcb19d2da 100644 --- a/trunk/include/linux/pid.h +++ b/trunk/include/linux/pid.h @@ -4,6 +4,7 @@ enum pid_type { PIDTYPE_PID, + PIDTYPE_TGID, PIDTYPE_PGID, PIDTYPE_SID, PIDTYPE_MAX @@ -37,6 +38,7 @@ extern struct pid *FASTCALL(find_pid(enum pid_type, int)); extern int alloc_pidmap(void); extern void FASTCALL(free_pidmap(int)); +extern void switch_exec_pids(struct task_struct *leader, struct task_struct *thread); #define do_each_task_pid(who, type, task) \ if ((task = find_task_by_pid_type(type, who))) { \ diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index d04186d8cc68..20b4f0372e44 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -355,8 +355,16 @@ struct sighand_struct { atomic_t count; struct k_sigaction action[_NSIG]; spinlock_t siglock; + struct rcu_head rcu; }; +extern void sighand_free_cb(struct rcu_head *rhp); + +static inline void sighand_free(struct sighand_struct *sp) +{ + call_rcu(&sp->rcu, sighand_free_cb); +} + /* * NOTE! "signal_struct" does not have it's own * locking, because a shared signal_struct always @@ -752,7 +760,6 @@ struct task_struct { /* PID/PID hash table linkage. */ struct pid pids[PIDTYPE_MAX]; - struct list_head thread_group; struct completion *vfork_done; /* for vfork() */ int __user *set_child_tid; /* CLONE_CHILD_SETTID */ @@ -1094,6 +1101,7 @@ extern void force_sig_specific(int, struct task_struct *); extern int send_sig(int, struct task_struct *, int); extern void zap_other_threads(struct task_struct *p); extern int kill_pg(pid_t, int, int); +extern int kill_sl(pid_t, int, int); extern int kill_proc(pid_t, int, int); extern struct sigqueue *sigqueue_alloc(void); extern void sigqueue_free(struct sigqueue *); @@ -1150,8 +1158,10 @@ extern void flush_thread(void); extern void exit_thread(void); extern void exit_files(struct task_struct *); -extern void __cleanup_signal(struct signal_struct *); -extern void __cleanup_sighand(struct sighand_struct *); +extern void exit_signal(struct task_struct *); +extern void __exit_signal(struct task_struct *); +extern void exit_sighand(struct task_struct *); +extern void __exit_sighand(struct task_struct *); extern void exit_itimers(struct signal_struct *); extern NORET_TYPE void do_group_exit(int); @@ -1175,7 +1185,19 @@ extern void wait_task_inactive(task_t * p); #endif #define remove_parent(p) list_del_init(&(p)->sibling) -#define add_parent(p) list_add_tail(&(p)->sibling,&(p)->parent->children) +#define add_parent(p, parent) list_add_tail(&(p)->sibling,&(parent)->children) + +#define REMOVE_LINKS(p) do { \ + if (thread_group_leader(p)) \ + list_del_init(&(p)->tasks); \ + remove_parent(p); \ + } while (0) + +#define SET_LINKS(p) do { \ + if (thread_group_leader(p)) \ + list_add_tail(&(p)->tasks,&init_task.tasks); \ + add_parent(p, (p)->parent); \ + } while (0) #define next_task(p) list_entry((p)->tasks.next, struct task_struct, tasks) #define prev_task(p) list_entry((p)->tasks.prev, struct task_struct, tasks) @@ -1193,22 +1215,20 @@ extern void wait_task_inactive(task_t * p); #define while_each_thread(g, t) \ while ((t = next_thread(t)) != g) -#define thread_group_leader(p) (p->pid == p->tgid) +extern task_t * FASTCALL(next_thread(const task_t *p)); -static inline task_t *next_thread(task_t *p) -{ - return list_entry(rcu_dereference(p->thread_group.next), - task_t, thread_group); -} +#define thread_group_leader(p) (p->pid == p->tgid) static inline int thread_group_empty(task_t *p) { - return list_empty(&p->thread_group); + return list_empty(&p->pids[PIDTYPE_TGID].pid_list); } #define delay_group_leader(p) \ (thread_group_leader(p) && !thread_group_empty(p)) +extern void unhash_process(struct task_struct *p); + /* * Protects ->fs, ->files, ->mm, ->ptrace, ->group_info, ->comm, keyring * subscriptions and synchronises with wait4(). Also used in procfs. Also @@ -1228,15 +1248,6 @@ static inline void task_unlock(struct task_struct *p) spin_unlock(&p->alloc_lock); } -extern struct sighand_struct *lock_task_sighand(struct task_struct *tsk, - unsigned long *flags); - -static inline void unlock_task_sighand(struct task_struct *tsk, - unsigned long *flags) -{ - spin_unlock_irqrestore(&tsk->sighand->siglock, *flags); -} - #ifndef __HAVE_THREAD_FUNCTIONS #define task_thread_info(task) (task)->thread_info diff --git a/trunk/include/linux/signal.h b/trunk/include/linux/signal.h index 162a8fd10b29..b7d093520bb6 100644 --- a/trunk/include/linux/signal.h +++ b/trunk/include/linux/signal.h @@ -249,8 +249,6 @@ static inline void init_sigpending(struct sigpending *sig) INIT_LIST_HEAD(&sig->list); } -extern void flush_sigqueue(struct sigpending *queue); - /* Test if 'sig' is valid signal. Use this instead of testing _NSIG directly */ static inline int valid_signal(unsigned long sig) { diff --git a/trunk/include/linux/slab.h b/trunk/include/linux/slab.h index 3af03b19c983..15e1d9736b1b 100644 --- a/trunk/include/linux/slab.h +++ b/trunk/include/linux/slab.h @@ -210,6 +210,7 @@ extern kmem_cache_t *names_cachep; extern kmem_cache_t *files_cachep; extern kmem_cache_t *filp_cachep; extern kmem_cache_t *fs_cachep; +extern kmem_cache_t *signal_cachep; extern kmem_cache_t *sighand_cachep; extern kmem_cache_t *bio_cachep; diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index bc0ec674d3f4..a8c7efc7a681 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -51,80 +50,15 @@ static void __unhash_process(struct task_struct *p) { nr_threads--; detach_pid(p, PIDTYPE_PID); + detach_pid(p, PIDTYPE_TGID); if (thread_group_leader(p)) { detach_pid(p, PIDTYPE_PGID); detach_pid(p, PIDTYPE_SID); - - list_del_init(&p->tasks); - __get_cpu_var(process_counts)--; - } - list_del_rcu(&p->thread_group); - remove_parent(p); -} - -/* - * This function expects the tasklist_lock write-locked. - */ -static void __exit_signal(struct task_struct *tsk) -{ - struct signal_struct *sig = tsk->signal; - struct sighand_struct *sighand; - - BUG_ON(!sig); - BUG_ON(!atomic_read(&sig->count)); - - rcu_read_lock(); - sighand = rcu_dereference(tsk->sighand); - spin_lock(&sighand->siglock); - - posix_cpu_timers_exit(tsk); - if (atomic_dec_and_test(&sig->count)) - posix_cpu_timers_exit_group(tsk); - else { - /* - * If there is any task waiting for the group exit - * then notify it: - */ - if (sig->group_exit_task && atomic_read(&sig->count) == sig->notify_count) { - wake_up_process(sig->group_exit_task); - sig->group_exit_task = NULL; - } - if (tsk == sig->curr_target) - sig->curr_target = next_thread(tsk); - /* - * Accumulate here the counters for all threads but the - * group leader as they die, so they can be added into - * the process-wide totals when those are taken. - * The group leader stays around as a zombie as long - * as there are other threads. When it gets reaped, - * the exit.c code will add its counts into these totals. - * We won't ever get here for the group leader, since it - * will have been the last reference on the signal_struct. - */ - sig->utime = cputime_add(sig->utime, tsk->utime); - sig->stime = cputime_add(sig->stime, tsk->stime); - sig->min_flt += tsk->min_flt; - sig->maj_flt += tsk->maj_flt; - sig->nvcsw += tsk->nvcsw; - sig->nivcsw += tsk->nivcsw; - sig->sched_time += tsk->sched_time; - sig = NULL; /* Marker for below. */ + if (p->pid) + __get_cpu_var(process_counts)--; } - __unhash_process(tsk); - - tsk->signal = NULL; - tsk->sighand = NULL; - spin_unlock(&sighand->siglock); - rcu_read_unlock(); - - __cleanup_sighand(sighand); - clear_tsk_thread_flag(tsk,TIF_SIGPENDING); - flush_sigqueue(&tsk->pending); - if (sig) { - flush_sigqueue(&sig->shared_pending); - __cleanup_signal(sig); - } + REMOVE_LINKS(p); } void release_task(struct task_struct * p) @@ -133,14 +67,21 @@ void release_task(struct task_struct * p) task_t *leader; struct dentry *proc_dentry; -repeat: +repeat: atomic_dec(&p->user->processes); spin_lock(&p->proc_lock); proc_dentry = proc_pid_unhash(p); write_lock_irq(&tasklist_lock); - ptrace_unlink(p); + if (unlikely(p->ptrace)) + __ptrace_unlink(p); BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children)); __exit_signal(p); + /* + * Note that the fastpath in sys_times depends on __exit_signal having + * updated the counters before a task is removed from the tasklist of + * the process by __unhash_process. + */ + __unhash_process(p); /* * If we are the last non-leader member of the thread @@ -175,6 +116,21 @@ void release_task(struct task_struct * p) goto repeat; } +/* we are using it only for SMP init */ + +void unhash_process(struct task_struct *p) +{ + struct dentry *proc_dentry; + + spin_lock(&p->proc_lock); + proc_dentry = proc_pid_unhash(p); + write_lock_irq(&tasklist_lock); + __unhash_process(p); + write_unlock_irq(&tasklist_lock); + spin_unlock(&p->proc_lock); + proc_pid_flush(proc_dentry); +} + /* * This checks not only the pgrp, but falls back on the pid if no * satisfactory pgrp is found. I dunno - gdb doesn't work correctly @@ -282,10 +238,10 @@ static void reparent_to_init(void) ptrace_unlink(current); /* Reparent to init */ - remove_parent(current); + REMOVE_LINKS(current); current->parent = child_reaper; current->real_parent = child_reaper; - add_parent(current); + SET_LINKS(current); /* Set the exit signal to SIGCHLD so we signal init on exit */ current->exit_signal = SIGCHLD; @@ -582,13 +538,13 @@ static void exit_mm(struct task_struct * tsk) mmput(mm); } -static inline void choose_new_parent(task_t *p, task_t *reaper) +static inline void choose_new_parent(task_t *p, task_t *reaper, task_t *child_reaper) { /* * Make sure we're not reparenting to ourselves and that * the parent is not a zombie. */ - BUG_ON(p == reaper || reaper->exit_state); + BUG_ON(p == reaper || reaper->exit_state >= EXIT_ZOMBIE); p->real_parent = reaper; } @@ -613,9 +569,9 @@ static void reparent_thread(task_t *p, task_t *father, int traced) * anyway, so let go of it. */ p->ptrace = 0; - remove_parent(p); + list_del_init(&p->sibling); p->parent = p->real_parent; - add_parent(p); + list_add_tail(&p->sibling, &p->parent->children); /* If we'd notified the old parent about this child's death, * also notify the new parent. @@ -689,7 +645,7 @@ static void forget_original_parent(struct task_struct * father, if (father == p->real_parent) { /* reparent with a reaper, real father it's us */ - choose_new_parent(p, reaper); + choose_new_parent(p, reaper, child_reaper); reparent_thread(p, father, 0); } else { /* reparent ptraced task to its real parent */ @@ -710,7 +666,7 @@ static void forget_original_parent(struct task_struct * father, } list_for_each_safe(_p, _n, &father->ptrace_children) { p = list_entry(_p,struct task_struct,ptrace_list); - choose_new_parent(p, reaper); + choose_new_parent(p, reaper, child_reaper); reparent_thread(p, father, 1); } } @@ -851,7 +807,7 @@ fastcall NORET_TYPE void do_exit(long code) panic("Aiee, killing interrupt handler!"); if (unlikely(!tsk->pid)) panic("Attempted to kill the idle task!"); - if (unlikely(tsk == child_reaper)) + if (unlikely(tsk->pid == 1)) panic("Attempted to kill init!"); if (unlikely(current->ptrace & PT_TRACE_EXIT)) { @@ -964,6 +920,13 @@ asmlinkage long sys_exit(int error_code) do_exit((error_code&0xff)<<8); } +task_t fastcall *next_thread(const task_t *p) +{ + return pid_task(p->pids[PIDTYPE_TGID].pid_list.next, PIDTYPE_TGID); +} + +EXPORT_SYMBOL(next_thread); + /* * Take down every thread in the group. This is called by fatal signals * as well as by sys_exit_group (below). @@ -978,6 +941,7 @@ do_group_exit(int exit_code) else if (!thread_group_empty(current)) { struct signal_struct *const sig = current->signal; struct sighand_struct *const sighand = current->sighand; + read_lock(&tasklist_lock); spin_lock_irq(&sighand->siglock); if (sig->flags & SIGNAL_GROUP_EXIT) /* Another thread got here before we took the lock. */ @@ -987,6 +951,7 @@ do_group_exit(int exit_code) zap_other_threads(current); } spin_unlock_irq(&sighand->siglock); + read_unlock(&tasklist_lock); } do_exit(exit_code); @@ -1316,7 +1281,7 @@ static int wait_task_stopped(task_t *p, int delayed_group_leader, int noreap, /* move to end of parent's list to avoid starvation */ remove_parent(p); - add_parent(p); + add_parent(p, p->parent); write_unlock_irq(&tasklist_lock); diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index b3f7a1bb5e55..c49bd193b058 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -84,7 +84,7 @@ static kmem_cache_t *task_struct_cachep; #endif /* SLAB cache for signal_struct structures (tsk->signal) */ -static kmem_cache_t *signal_cachep; +kmem_cache_t *signal_cachep; /* SLAB cache for sighand_struct structures (tsk->sighand) */ kmem_cache_t *sighand_cachep; @@ -786,6 +786,14 @@ int unshare_files(void) EXPORT_SYMBOL(unshare_files); +void sighand_free_cb(struct rcu_head *rhp) +{ + struct sighand_struct *sp; + + sp = container_of(rhp, struct sighand_struct, rcu); + kmem_cache_free(sighand_cachep, sp); +} + static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk) { struct sighand_struct *sig; @@ -798,17 +806,12 @@ static inline int copy_sighand(unsigned long clone_flags, struct task_struct * t rcu_assign_pointer(tsk->sighand, sig); if (!sig) return -ENOMEM; + spin_lock_init(&sig->siglock); atomic_set(&sig->count, 1); memcpy(sig->action, current->sighand->action, sizeof(sig->action)); return 0; } -void __cleanup_sighand(struct sighand_struct *sighand) -{ - if (atomic_dec_and_test(&sighand->count)) - kmem_cache_free(sighand_cachep, sighand); -} - static inline int copy_signal(unsigned long clone_flags, struct task_struct * tsk) { struct signal_struct *sig; @@ -878,22 +881,6 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts return 0; } -void __cleanup_signal(struct signal_struct *sig) -{ - exit_thread_group_keys(sig); - kmem_cache_free(signal_cachep, sig); -} - -static inline void cleanup_signal(struct task_struct *tsk) -{ - struct signal_struct *sig = tsk->signal; - - atomic_dec(&sig->live); - - if (atomic_dec_and_test(&sig->count)) - __cleanup_signal(sig); -} - static inline void copy_flags(unsigned long clone_flags, struct task_struct *p) { unsigned long new_flags = p->flags; @@ -1108,7 +1095,6 @@ static task_t *copy_process(unsigned long clone_flags, * We dont wake it up yet. */ p->group_leader = p; - INIT_LIST_HEAD(&p->thread_group); INIT_LIST_HEAD(&p->ptrace_children); INIT_LIST_HEAD(&p->ptrace_list); @@ -1132,6 +1118,16 @@ static task_t *copy_process(unsigned long clone_flags, !cpu_online(task_cpu(p)))) set_task_cpu(p, smp_processor_id()); + /* + * Check for pending SIGKILL! The new thread should not be allowed + * to slip out of an OOM kill. (or normal SIGKILL.) + */ + if (sigismember(¤t->pending.signal, SIGKILL)) { + write_unlock_irq(&tasklist_lock); + retval = -EINTR; + goto bad_fork_cleanup_namespace; + } + /* CLONE_PARENT re-uses the old parent */ if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) p->real_parent = current->real_parent; @@ -1140,23 +1136,6 @@ static task_t *copy_process(unsigned long clone_flags, p->parent = p->real_parent; spin_lock(¤t->sighand->siglock); - - /* - * Process group and session signals need to be delivered to just the - * parent before the fork or both the parent and the child after the - * fork. Restart if a signal comes in before we add the new process to - * it's process group. - * A fatal signal pending means that current will exit, so the new - * thread can't slip out of an OOM kill (or normal SIGKILL). - */ - recalc_sigpending(); - if (signal_pending(current)) { - spin_unlock(¤t->sighand->siglock); - write_unlock_irq(&tasklist_lock); - retval = -ERESTARTNOINTR; - goto bad_fork_cleanup_namespace; - } - if (clone_flags & CLONE_THREAD) { /* * Important: if an exit-all has been started then @@ -1169,9 +1148,17 @@ static task_t *copy_process(unsigned long clone_flags, retval = -EAGAIN; goto bad_fork_cleanup_namespace; } - p->group_leader = current->group_leader; - list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group); + + if (current->signal->group_stop_count > 0) { + /* + * There is an all-stop in progress for the group. + * We ourselves will stop as soon as we check signals. + * Make the new thread part of that group stop too. + */ + current->signal->group_stop_count++; + set_tsk_thread_flag(p, TIF_SIGPENDING); + } if (!cputime_eq(current->signal->it_virt_expires, cputime_zero) || @@ -1194,25 +1181,23 @@ static task_t *copy_process(unsigned long clone_flags, */ p->ioprio = current->ioprio; - if (likely(p->pid)) { - add_parent(p); - if (unlikely(p->ptrace & PT_PTRACED)) - __ptrace_link(p, current->parent); - - if (thread_group_leader(p)) { - p->signal->tty = current->signal->tty; - p->signal->pgrp = process_group(current); - p->signal->session = current->signal->session; - attach_pid(p, PIDTYPE_PGID, process_group(p)); - attach_pid(p, PIDTYPE_SID, p->signal->session); - - list_add_tail(&p->tasks, &init_task.tasks); + SET_LINKS(p); + if (unlikely(p->ptrace & PT_PTRACED)) + __ptrace_link(p, current->parent); + + if (thread_group_leader(p)) { + p->signal->tty = current->signal->tty; + p->signal->pgrp = process_group(current); + p->signal->session = current->signal->session; + attach_pid(p, PIDTYPE_PGID, process_group(p)); + attach_pid(p, PIDTYPE_SID, p->signal->session); + if (p->pid) __get_cpu_var(process_counts)++; - } - attach_pid(p, PIDTYPE_PID, p->pid); - nr_threads++; } + attach_pid(p, PIDTYPE_TGID, p->tgid); + attach_pid(p, PIDTYPE_PID, p->pid); + nr_threads++; total_forks++; spin_unlock(¤t->sighand->siglock); write_unlock_irq(&tasklist_lock); @@ -1227,9 +1212,9 @@ static task_t *copy_process(unsigned long clone_flags, if (p->mm) mmput(p->mm); bad_fork_cleanup_signal: - cleanup_signal(p); + exit_signal(p); bad_fork_cleanup_sighand: - __cleanup_sighand(p->sighand); + exit_sighand(p); bad_fork_cleanup_fs: exit_fs(p); /* blocking */ bad_fork_cleanup_files: @@ -1276,7 +1261,7 @@ task_t * __devinit fork_idle(int cpu) if (!task) return ERR_PTR(-ENOMEM); init_idle(task, cpu); - + unhash_process(task); return task; } @@ -1368,21 +1353,11 @@ long do_fork(unsigned long clone_flags, #define ARCH_MIN_MMSTRUCT_ALIGN 0 #endif -static void sighand_ctor(void *data, kmem_cache_t *cachep, unsigned long flags) -{ - struct sighand_struct *sighand = data; - - if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) - spin_lock_init(&sighand->siglock); -} - void __init proc_caches_init(void) { sighand_cachep = kmem_cache_create("sighand_cache", sizeof(struct sighand_struct), 0, - SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_DESTROY_BY_RCU, - sighand_ctor, NULL); + SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); signal_cachep = kmem_cache_create("signal_cache", sizeof(struct signal_struct), 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); diff --git a/trunk/kernel/kmod.c b/trunk/kernel/kmod.c index 20a997c73c3d..51a892063aaa 100644 --- a/trunk/kernel/kmod.c +++ b/trunk/kernel/kmod.c @@ -170,7 +170,7 @@ static int wait_for_helper(void *data) sa.sa.sa_handler = SIG_IGN; sa.sa.sa_flags = 0; siginitset(&sa.sa.sa_mask, sigmask(SIGCHLD)); - do_sigaction(SIGCHLD, &sa, NULL); + do_sigaction(SIGCHLD, &sa, (struct k_sigaction *)0); allow_signal(SIGCHLD); pid = kernel_thread(____call_usermodehelper, sub_info, SIGCHLD); diff --git a/trunk/kernel/pid.c b/trunk/kernel/pid.c index a9f2dfd006d2..1acc07246991 100644 --- a/trunk/kernel/pid.c +++ b/trunk/kernel/pid.c @@ -217,6 +217,36 @@ task_t *find_task_by_pid_type(int type, int nr) EXPORT_SYMBOL(find_task_by_pid_type); +/* + * This function switches the PIDs if a non-leader thread calls + * sys_execve() - this must be done without releasing the PID. + * (which a detach_pid() would eventually do.) + */ +void switch_exec_pids(task_t *leader, task_t *thread) +{ + __detach_pid(leader, PIDTYPE_PID); + __detach_pid(leader, PIDTYPE_TGID); + __detach_pid(leader, PIDTYPE_PGID); + __detach_pid(leader, PIDTYPE_SID); + + __detach_pid(thread, PIDTYPE_PID); + __detach_pid(thread, PIDTYPE_TGID); + + leader->pid = leader->tgid = thread->pid; + thread->pid = thread->tgid; + + attach_pid(thread, PIDTYPE_PID, thread->pid); + attach_pid(thread, PIDTYPE_TGID, thread->tgid); + attach_pid(thread, PIDTYPE_PGID, thread->signal->pgrp); + attach_pid(thread, PIDTYPE_SID, thread->signal->session); + list_add_tail(&thread->tasks, &init_task.tasks); + + attach_pid(leader, PIDTYPE_PID, leader->pid); + attach_pid(leader, PIDTYPE_TGID, leader->tgid); + attach_pid(leader, PIDTYPE_PGID, leader->signal->pgrp); + attach_pid(leader, PIDTYPE_SID, leader->signal->session); +} + /* * The pid hash table is scaled according to the amount of memory in the * machine. From a minimum of 16 slots up to 4096 slots at one gigabyte or @@ -247,8 +277,16 @@ void __init pidhash_init(void) void __init pidmap_init(void) { + int i; + pidmap_array->page = (void *)get_zeroed_page(GFP_KERNEL); - /* Reserve PID 0. We never call free_pidmap(0) */ set_bit(0, pidmap_array->page); atomic_dec(&pidmap_array->nr_free); + + /* + * Allocate PID 0, and hash it via all PID types: + */ + + for (i = 0; i < PIDTYPE_MAX; i++) + attach_pid(current, i, 0); } diff --git a/trunk/kernel/ptrace.c b/trunk/kernel/ptrace.c index 86a7f6c60cb2..d95a72c9279d 100644 --- a/trunk/kernel/ptrace.c +++ b/trunk/kernel/ptrace.c @@ -35,9 +35,9 @@ void __ptrace_link(task_t *child, task_t *new_parent) if (child->parent == new_parent) return; list_add(&child->ptrace_list, &child->parent->ptrace_children); - remove_parent(child); + REMOVE_LINKS(child); child->parent = new_parent; - add_parent(child); + SET_LINKS(child); } /* @@ -77,9 +77,9 @@ void __ptrace_unlink(task_t *child) child->ptrace = 0; if (!list_empty(&child->ptrace_list)) { list_del_init(&child->ptrace_list); - remove_parent(child); + REMOVE_LINKS(child); child->parent = child->real_parent; - add_parent(child); + SET_LINKS(child); } ptrace_untrace(child); diff --git a/trunk/kernel/signal.c b/trunk/kernel/signal.c index 4922928d91f6..75f7341b0c39 100644 --- a/trunk/kernel/signal.c +++ b/trunk/kernel/signal.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -146,8 +147,6 @@ static kmem_cache_t *sigqueue_cachep; #define sig_kernel_stop(sig) \ (((sig) < SIGRTMIN) && T(sig, SIG_KERNEL_STOP_MASK)) -#define sig_needs_tasklist(sig) ((sig) == SIGCONT) - #define sig_user_defined(t, signr) \ (((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_DFL) && \ ((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_IGN)) @@ -293,7 +292,7 @@ static void __sigqueue_free(struct sigqueue *q) kmem_cache_free(sigqueue_cachep, q); } -void flush_sigqueue(struct sigpending *queue) +static void flush_sigqueue(struct sigpending *queue) { struct sigqueue *q; @@ -308,7 +307,9 @@ void flush_sigqueue(struct sigpending *queue) /* * Flush all pending signals for a task. */ -void flush_signals(struct task_struct *t) + +void +flush_signals(struct task_struct *t) { unsigned long flags; @@ -319,6 +320,109 @@ void flush_signals(struct task_struct *t) spin_unlock_irqrestore(&t->sighand->siglock, flags); } +/* + * This function expects the tasklist_lock write-locked. + */ +void __exit_sighand(struct task_struct *tsk) +{ + struct sighand_struct * sighand = tsk->sighand; + + /* Ok, we're done with the signal handlers */ + tsk->sighand = NULL; + if (atomic_dec_and_test(&sighand->count)) + sighand_free(sighand); +} + +void exit_sighand(struct task_struct *tsk) +{ + write_lock_irq(&tasklist_lock); + rcu_read_lock(); + if (tsk->sighand != NULL) { + struct sighand_struct *sighand = rcu_dereference(tsk->sighand); + spin_lock(&sighand->siglock); + __exit_sighand(tsk); + spin_unlock(&sighand->siglock); + } + rcu_read_unlock(); + write_unlock_irq(&tasklist_lock); +} + +/* + * This function expects the tasklist_lock write-locked. + */ +void __exit_signal(struct task_struct *tsk) +{ + struct signal_struct * sig = tsk->signal; + struct sighand_struct * sighand; + + if (!sig) + BUG(); + if (!atomic_read(&sig->count)) + BUG(); + rcu_read_lock(); + sighand = rcu_dereference(tsk->sighand); + spin_lock(&sighand->siglock); + posix_cpu_timers_exit(tsk); + if (atomic_dec_and_test(&sig->count)) { + posix_cpu_timers_exit_group(tsk); + tsk->signal = NULL; + __exit_sighand(tsk); + spin_unlock(&sighand->siglock); + flush_sigqueue(&sig->shared_pending); + } else { + /* + * If there is any task waiting for the group exit + * then notify it: + */ + if (sig->group_exit_task && atomic_read(&sig->count) == sig->notify_count) { + wake_up_process(sig->group_exit_task); + sig->group_exit_task = NULL; + } + if (tsk == sig->curr_target) + sig->curr_target = next_thread(tsk); + tsk->signal = NULL; + /* + * Accumulate here the counters for all threads but the + * group leader as they die, so they can be added into + * the process-wide totals when those are taken. + * The group leader stays around as a zombie as long + * as there are other threads. When it gets reaped, + * the exit.c code will add its counts into these totals. + * We won't ever get here for the group leader, since it + * will have been the last reference on the signal_struct. + */ + sig->utime = cputime_add(sig->utime, tsk->utime); + sig->stime = cputime_add(sig->stime, tsk->stime); + sig->min_flt += tsk->min_flt; + sig->maj_flt += tsk->maj_flt; + sig->nvcsw += tsk->nvcsw; + sig->nivcsw += tsk->nivcsw; + sig->sched_time += tsk->sched_time; + __exit_sighand(tsk); + spin_unlock(&sighand->siglock); + sig = NULL; /* Marker for below. */ + } + rcu_read_unlock(); + clear_tsk_thread_flag(tsk,TIF_SIGPENDING); + flush_sigqueue(&tsk->pending); + if (sig) { + /* + * We are cleaning up the signal_struct here. + */ + exit_thread_group_keys(sig); + kmem_cache_free(signal_cachep, sig); + } +} + +void exit_signal(struct task_struct *tsk) +{ + atomic_dec(&tsk->signal->live); + + write_lock_irq(&tasklist_lock); + __exit_signal(tsk); + write_unlock_irq(&tasklist_lock); +} + /* * Flush all handlers for a task. */ @@ -591,7 +695,9 @@ static int check_kill_permission(int sig, struct siginfo *info, } /* forward decl */ -static void do_notify_parent_cldstop(struct task_struct *tsk, int why); +static void do_notify_parent_cldstop(struct task_struct *tsk, + int to_self, + int why); /* * Handle magic process-wide effects of stop/continue signals. @@ -641,7 +747,7 @@ static void handle_stop_signal(int sig, struct task_struct *p) p->signal->group_stop_count = 0; p->signal->flags = SIGNAL_STOP_CONTINUED; spin_unlock(&p->sighand->siglock); - do_notify_parent_cldstop(p, CLD_STOPPED); + do_notify_parent_cldstop(p, (p->ptrace & PT_PTRACED), CLD_STOPPED); spin_lock(&p->sighand->siglock); } rm_from_queue(SIG_KERNEL_STOP_MASK, &p->signal->shared_pending); @@ -682,7 +788,7 @@ static void handle_stop_signal(int sig, struct task_struct *p) p->signal->flags = SIGNAL_STOP_CONTINUED; p->signal->group_exit_code = 0; spin_unlock(&p->sighand->siglock); - do_notify_parent_cldstop(p, CLD_CONTINUED); + do_notify_parent_cldstop(p, (p->ptrace & PT_PTRACED), CLD_CONTINUED); spin_lock(&p->sighand->siglock); } else { /* @@ -1014,37 +1120,27 @@ void zap_other_threads(struct task_struct *p) /* * Must be called under rcu_read_lock() or with tasklist_lock read-held. */ -struct sighand_struct *lock_task_sighand(struct task_struct *tsk, unsigned long *flags) -{ - struct sighand_struct *sighand; - - for (;;) { - sighand = rcu_dereference(tsk->sighand); - if (unlikely(sighand == NULL)) - break; - - spin_lock_irqsave(&sighand->siglock, *flags); - if (likely(sighand == tsk->sighand)) - break; - spin_unlock_irqrestore(&sighand->siglock, *flags); - } - - return sighand; -} - int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p) { unsigned long flags; + struct sighand_struct *sp; int ret; +retry: ret = check_kill_permission(sig, info, p); - - if (!ret && sig) { - ret = -ESRCH; - if (lock_task_sighand(p, &flags)) { - ret = __group_send_sig_info(sig, info, p); - unlock_task_sighand(p, &flags); + if (!ret && sig && (sp = rcu_dereference(p->sighand))) { + spin_lock_irqsave(&sp->siglock, flags); + if (p->sighand != sp) { + spin_unlock_irqrestore(&sp->siglock, flags); + goto retry; + } + if ((atomic_read(&sp->count) == 0) || + (atomic_read(&p->usage) == 0)) { + spin_unlock_irqrestore(&sp->siglock, flags); + return -ESRCH; } + ret = __group_send_sig_info(sig, info, p); + spin_unlock_irqrestore(&sp->siglock, flags); } return ret; @@ -1093,7 +1189,7 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid) struct task_struct *p; rcu_read_lock(); - if (unlikely(sig_needs_tasklist(sig))) { + if (unlikely(sig_kernel_stop(sig) || sig == SIGCONT)) { read_lock(&tasklist_lock); acquired_tasklist_lock = 1; } @@ -1309,10 +1405,12 @@ void sigqueue_free(struct sigqueue *q) __sigqueue_free(q); } -int send_sigqueue(int sig, struct sigqueue *q, struct task_struct *p) +int +send_sigqueue(int sig, struct sigqueue *q, struct task_struct *p) { unsigned long flags; int ret = 0; + struct sighand_struct *sh; BUG_ON(!(q->flags & SIGQUEUE_PREALLOC)); @@ -1326,17 +1424,48 @@ int send_sigqueue(int sig, struct sigqueue *q, struct task_struct *p) */ rcu_read_lock(); - if (!likely(lock_task_sighand(p, &flags))) { + if (unlikely(p->flags & PF_EXITING)) { ret = -1; goto out_err; } +retry: + sh = rcu_dereference(p->sighand); + + spin_lock_irqsave(&sh->siglock, flags); + if (p->sighand != sh) { + /* We raced with exec() in a multithreaded process... */ + spin_unlock_irqrestore(&sh->siglock, flags); + goto retry; + } + + /* + * We do the check here again to handle the following scenario: + * + * CPU 0 CPU 1 + * send_sigqueue + * check PF_EXITING + * interrupt exit code running + * __exit_signal + * lock sighand->siglock + * unlock sighand->siglock + * lock sh->siglock + * add(tsk->pending) flush_sigqueue(tsk->pending) + * + */ + + if (unlikely(p->flags & PF_EXITING)) { + ret = -1; + goto out; + } + if (unlikely(!list_empty(&q->list))) { /* * If an SI_TIMER entry is already queue just increment * the overrun count. */ - BUG_ON(q->info.si_code != SI_TIMER); + if (q->info.si_code != SI_TIMER) + BUG(); q->info.si_overrun++; goto out; } @@ -1352,7 +1481,7 @@ int send_sigqueue(int sig, struct sigqueue *q, struct task_struct *p) signal_wake_up(p, sig == SIGKILL); out: - unlock_task_sighand(p, &flags); + spin_unlock_irqrestore(&sh->siglock, flags); out_err: rcu_read_unlock(); @@ -1484,14 +1613,14 @@ void do_notify_parent(struct task_struct *tsk, int sig) spin_unlock_irqrestore(&psig->siglock, flags); } -static void do_notify_parent_cldstop(struct task_struct *tsk, int why) +static void do_notify_parent_cldstop(struct task_struct *tsk, int to_self, int why) { struct siginfo info; unsigned long flags; struct task_struct *parent; struct sighand_struct *sighand; - if (tsk->ptrace & PT_PTRACED) + if (to_self) parent = tsk->parent; else { tsk = tsk->group_leader; @@ -1566,7 +1695,7 @@ static void ptrace_stop(int exit_code, int nostop_code, siginfo_t *info) !(current->ptrace & PT_ATTACHED)) && (likely(current->parent->signal != current->signal) || !unlikely(current->signal->flags & SIGNAL_GROUP_EXIT))) { - do_notify_parent_cldstop(current, CLD_TRAPPED); + do_notify_parent_cldstop(current, 1, CLD_TRAPPED); read_unlock(&tasklist_lock); schedule(); } else { @@ -1615,17 +1744,25 @@ void ptrace_notify(int exit_code) static void finish_stop(int stop_count) { + int to_self; + /* * If there are no other threads in the group, or if there is * a group stop in progress and we are the last to stop, * report to the parent. When ptraced, every thread reports itself. */ - if (stop_count == 0 || (current->ptrace & PT_PTRACED)) { - read_lock(&tasklist_lock); - do_notify_parent_cldstop(current, CLD_STOPPED); - read_unlock(&tasklist_lock); - } + if (stop_count < 0 || (current->ptrace & PT_PTRACED)) + to_self = 1; + else if (stop_count == 0) + to_self = 0; + else + goto out; + + read_lock(&tasklist_lock); + do_notify_parent_cldstop(current, to_self, CLD_STOPPED); + read_unlock(&tasklist_lock); +out: schedule(); /* * Now we don't run again until continued. @@ -1639,10 +1776,12 @@ finish_stop(int stop_count) * Returns nonzero if we've actually stopped and released the siglock. * Returns zero if we didn't stop and still hold the siglock. */ -static int do_signal_stop(int signr) +static int +do_signal_stop(int signr) { struct signal_struct *sig = current->signal; - int stop_count; + struct sighand_struct *sighand = current->sighand; + int stop_count = -1; if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED)) return 0; @@ -1652,37 +1791,86 @@ static int do_signal_stop(int signr) * There is a group stop in progress. We don't need to * start another one. */ + signr = sig->group_exit_code; stop_count = --sig->group_stop_count; - } else { + current->exit_code = signr; + set_current_state(TASK_STOPPED); + if (stop_count == 0) + sig->flags = SIGNAL_STOP_STOPPED; + spin_unlock_irq(&sighand->siglock); + } + else if (thread_group_empty(current)) { + /* + * Lock must be held through transition to stopped state. + */ + current->exit_code = current->signal->group_exit_code = signr; + set_current_state(TASK_STOPPED); + sig->flags = SIGNAL_STOP_STOPPED; + spin_unlock_irq(&sighand->siglock); + } + else { /* * There is no group stop already in progress. - * We must initiate one now. + * We must initiate one now, but that requires + * dropping siglock to get both the tasklist lock + * and siglock again in the proper order. Note that + * this allows an intervening SIGCONT to be posted. + * We need to check for that and bail out if necessary. */ struct task_struct *t; - sig->group_exit_code = signr; + spin_unlock_irq(&sighand->siglock); + + /* signals can be posted during this window */ - stop_count = 0; - for (t = next_thread(current); t != current; t = next_thread(t)) + read_lock(&tasklist_lock); + spin_lock_irq(&sighand->siglock); + + if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED)) { /* - * Setting state to TASK_STOPPED for a group - * stop is always done with the siglock held, - * so this check has no races. + * Another stop or continue happened while we + * didn't have the lock. We can just swallow this + * signal now. If we raced with a SIGCONT, that + * should have just cleared it now. If we raced + * with another processor delivering a stop signal, + * then the SIGCONT that wakes us up should clear it. */ - if (!t->exit_state && - !(t->state & (TASK_STOPPED|TASK_TRACED))) { - stop_count++; - signal_wake_up(t, 0); - } - sig->group_stop_count = stop_count; - } + read_unlock(&tasklist_lock); + return 0; + } - if (stop_count == 0) - sig->flags = SIGNAL_STOP_STOPPED; - current->exit_code = sig->group_exit_code; - __set_current_state(TASK_STOPPED); + if (sig->group_stop_count == 0) { + sig->group_exit_code = signr; + stop_count = 0; + for (t = next_thread(current); t != current; + t = next_thread(t)) + /* + * Setting state to TASK_STOPPED for a group + * stop is always done with the siglock held, + * so this check has no races. + */ + if (!t->exit_state && + !(t->state & (TASK_STOPPED|TASK_TRACED))) { + stop_count++; + signal_wake_up(t, 0); + } + sig->group_stop_count = stop_count; + } + else { + /* A race with another thread while unlocked. */ + signr = sig->group_exit_code; + stop_count = --sig->group_stop_count; + } + + current->exit_code = signr; + set_current_state(TASK_STOPPED); + if (stop_count == 0) + sig->flags = SIGNAL_STOP_STOPPED; + + spin_unlock_irq(&sighand->siglock); + read_unlock(&tasklist_lock); + } - spin_unlock_irq(¤t->sighand->siglock); finish_stop(stop_count); return 1; } @@ -1802,7 +1990,7 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, continue; /* Init gets no signals it doesn't want. */ - if (current == child_reaper) + if (current->pid == 1) continue; if (sig_kernel_stop(signr)) { @@ -2242,7 +2430,8 @@ sys_rt_sigqueueinfo(int pid, int sig, siginfo_t __user *uinfo) return kill_proc_info(sig, &info, pid); } -int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) +int +do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) { struct k_sigaction *k; sigset_t mask; @@ -2268,7 +2457,6 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) if (act) { sigdelsetmask(&act->sa.sa_mask, sigmask(SIGKILL) | sigmask(SIGSTOP)); - *k = *act; /* * POSIX 3.3.1.3: * "Setting a signal action to SIG_IGN for a signal that is @@ -2281,8 +2469,19 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) * be discarded, whether or not it is blocked" */ if (act->sa.sa_handler == SIG_IGN || - (act->sa.sa_handler == SIG_DFL && sig_kernel_ignore(sig))) { + (act->sa.sa_handler == SIG_DFL && + sig_kernel_ignore(sig))) { + /* + * This is a fairly rare case, so we only take the + * tasklist_lock once we're sure we'll need it. + * Now we must do this little unlock and relock + * dance to maintain the lock hierarchy. + */ struct task_struct *t = current; + spin_unlock_irq(&t->sighand->siglock); + read_lock(&tasklist_lock); + spin_lock_irq(&t->sighand->siglock); + *k = *act; sigemptyset(&mask); sigaddset(&mask, sig); rm_from_queue_full(&mask, &t->signal->shared_pending); @@ -2291,7 +2490,12 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) recalc_sigpending_tsk(t); t = next_thread(t); } while (t != current); + spin_unlock_irq(¤t->sighand->siglock); + read_unlock(&tasklist_lock); + return 0; } + + *k = *act; } spin_unlock_irq(¤t->sighand->siglock); diff --git a/trunk/kernel/sys.c b/trunk/kernel/sys.c index 7ef7f6054c28..c93d37f71aef 100644 --- a/trunk/kernel/sys.c +++ b/trunk/kernel/sys.c @@ -1202,24 +1202,69 @@ asmlinkage long sys_times(struct tms __user * tbuf) */ if (tbuf) { struct tms tmp; - struct task_struct *tsk = current; - struct task_struct *t; cputime_t utime, stime, cutime, cstime; - spin_lock_irq(&tsk->sighand->siglock); - utime = tsk->signal->utime; - stime = tsk->signal->stime; - t = tsk; - do { - utime = cputime_add(utime, t->utime); - stime = cputime_add(stime, t->stime); - t = next_thread(t); - } while (t != tsk); +#ifdef CONFIG_SMP + if (thread_group_empty(current)) { + /* + * Single thread case without the use of any locks. + * + * We may race with release_task if two threads are + * executing. However, release task first adds up the + * counters (__exit_signal) before removing the task + * from the process tasklist (__unhash_process). + * __exit_signal also acquires and releases the + * siglock which results in the proper memory ordering + * so that the list modifications are always visible + * after the counters have been updated. + * + * If the counters have been updated by the second thread + * but the thread has not yet been removed from the list + * then the other branch will be executing which will + * block on tasklist_lock until the exit handling of the + * other task is finished. + * + * This also implies that the sighand->siglock cannot + * be held by another processor. So we can also + * skip acquiring that lock. + */ + utime = cputime_add(current->signal->utime, current->utime); + stime = cputime_add(current->signal->utime, current->stime); + cutime = current->signal->cutime; + cstime = current->signal->cstime; + } else +#endif + { - cutime = tsk->signal->cutime; - cstime = tsk->signal->cstime; - spin_unlock_irq(&tsk->sighand->siglock); + /* Process with multiple threads */ + struct task_struct *tsk = current; + struct task_struct *t; + read_lock(&tasklist_lock); + utime = tsk->signal->utime; + stime = tsk->signal->stime; + t = tsk; + do { + utime = cputime_add(utime, t->utime); + stime = cputime_add(stime, t->stime); + t = next_thread(t); + } while (t != tsk); + + /* + * While we have tasklist_lock read-locked, no dying thread + * can be updating current->signal->[us]time. Instead, + * we got their counts included in the live thread loop. + * However, another thread can come in right now and + * do a wait call that updates current->signal->c[us]time. + * To make sure we always see that pair updated atomically, + * we take the siglock around fetching them. + */ + spin_lock_irq(&tsk->sighand->siglock); + cutime = tsk->signal->cutime; + cstime = tsk->signal->cstime; + spin_unlock_irq(&tsk->sighand->siglock); + read_unlock(&tasklist_lock); + } tmp.tms_utime = cputime_to_clock_t(utime); tmp.tms_stime = cputime_to_clock_t(stime); tmp.tms_cutime = cputime_to_clock_t(cutime); diff --git a/trunk/sound/oss/dmasound/dmasound_awacs.c b/trunk/sound/oss/dmasound/dmasound_awacs.c index c8e210326893..3bbc8105e9f1 100644 --- a/trunk/sound/oss/dmasound/dmasound_awacs.c +++ b/trunk/sound/oss/dmasound/dmasound_awacs.c @@ -2814,7 +2814,7 @@ int __init dmasound_awacs_init(void) struct device_node *io = NULL, *info = NULL; int vol, res; - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return -ENODEV; awacs_subframe = 0; diff --git a/trunk/sound/ppc/pmac.c b/trunk/sound/ppc/pmac.c index f0794ef9d1ac..aa57170101fd 100644 --- a/trunk/sound/ppc/pmac.c +++ b/trunk/sound/ppc/pmac.c @@ -869,7 +869,7 @@ static int __init snd_pmac_detect(struct snd_pmac *chip) u32 layout_id = 0; - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return -ENODEV; chip->subframe = 0;