diff --git a/[refs] b/[refs] index fc55f09abbc3..7f013fee683e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 5bc977867f36fc36cde43b309b891b2f7b714f52 +refs/heads/master: b676d84e72467a2e31191f41abebd59ab53a06bb diff --git a/trunk/arch/powerpc/configs/ps3_defconfig b/trunk/arch/powerpc/configs/ps3_defconfig index 7994955c29d3..0b5469fb6e0f 100644 --- a/trunk/arch/powerpc/configs/ps3_defconfig +++ b/trunk/arch/powerpc/configs/ps3_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24-rc8 -# Wed Jan 16 14:31:21 2008 +# Linux kernel version: 2.6.24-rc4 +# Tue Dec 4 22:49:57 2007 # CONFIG_PPC64=y @@ -103,7 +103,6 @@ CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set -CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -155,6 +154,7 @@ CONFIG_PPC_PS3=y # CONFIG_PS3_ADVANCED is not set CONFIG_PS3_HTAB_SIZE=20 # CONFIG_PS3_DYNAMIC_DMA is not set +CONFIG_PS3_USE_LPAR_ADDR=y CONFIG_PS3_VUART=y CONFIG_PS3_PS3AV=y CONFIG_PS3_SYS_MANAGER=y @@ -162,7 +162,6 @@ CONFIG_PS3_STORAGE=y CONFIG_PS3_DISK=y CONFIG_PS3_ROM=y CONFIG_PS3_FLASH=y -CONFIG_PS3_LPM=m CONFIG_PPC_CELL=y # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_IBM_CELL_BLADE is not set @@ -226,7 +225,7 @@ CONFIG_HAVE_MEMORY_PRESENT=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y -# CONFIG_SPARSEMEM_VMEMMAP is not set +CONFIG_SPARSEMEM_VMEMMAP=y CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTPLUG_SPARSE=y CONFIG_SPLIT_PTLOCK_CPUS=4 @@ -339,26 +338,7 @@ CONFIG_IPV6_SIT=y # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set -CONFIG_BT=m -CONFIG_BT_L2CAP=m -CONFIG_BT_SCO=m -CONFIG_BT_RFCOMM=m -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=m -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_HIDP=m - -# -# Bluetooth device drivers -# -CONFIG_BT_HCIUSB=m -CONFIG_BT_HCIUSB_SCO=y -# CONFIG_BT_HCIUART is not set -# CONFIG_BT_HCIBCM203X is not set -# CONFIG_BT_HCIBPA10X is not set -# CONFIG_BT_HCIBFUSB is not set -# CONFIG_BT_HCIVHCI is not set +# CONFIG_BT is not set # CONFIG_AF_RXRPC is not set # @@ -686,14 +666,14 @@ CONFIG_LOGO_LINUX_CLUT224=y # # Sound # -CONFIG_SOUND=m +CONFIG_SOUND=y # # Advanced Linux Sound Architecture # -CONFIG_SND=m -CONFIG_SND_TIMER=m -CONFIG_SND_PCM=m +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y # CONFIG_SND_SEQUENCER is not set # CONFIG_SND_MIXER_OSS is not set # CONFIG_SND_PCM_OSS is not set @@ -722,7 +702,7 @@ CONFIG_SND_VERBOSE_PROCFS=y # # ALSA PowerPC devices # -CONFIG_SND_PS3=m +CONFIG_SND_PS3=y CONFIG_SND_PS3_DEFAULT_START_DELAY=2000 # @@ -767,7 +747,7 @@ CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=m +CONFIG_USB=y # CONFIG_USB_DEBUG is not set # @@ -781,13 +761,13 @@ CONFIG_USB_DEVICEFS=y # # USB Host Controller Drivers # -CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set # CONFIG_USB_EHCI_TT_NEWSCHED is not set CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y # CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=m +CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_HCD_PPC_OF is not set # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y @@ -1053,8 +1033,7 @@ CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y CONFIG_INSTRUMENTATION=y -CONFIG_PROFILING=y -CONFIG_OPROFILE=m +# CONFIG_PROFILING is not set # CONFIG_KPROBES is not set # CONFIG_MARKERS is not set diff --git a/trunk/arch/powerpc/kernel/cputable.c b/trunk/arch/powerpc/kernel/cputable.c index f1928af5fcfc..dfb84c86ec40 100644 --- a/trunk/arch/powerpc/kernel/cputable.c +++ b/trunk/arch/powerpc/kernel/cputable.c @@ -1178,8 +1178,8 @@ static struct cpu_spec __initdata cpu_specs[] = { .platform = "ppc405", }, { /* 405EX */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x12910000, + .pvr_mask = 0xffff0004, + .pvr_value = 0x12910004, .cpu_name = "405EX", .cpu_features = CPU_FTRS_40X, .cpu_user_features = PPC_FEATURE_32 | @@ -1189,6 +1189,18 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_4xx, .platform = "ppc405", }, + { /* 405EXr */ + .pvr_mask = 0xffff0004, + .pvr_value = 0x12910000, + .cpu_name = "405EXr", + .cpu_features = CPU_FTRS_40X, + .cpu_user_features = PPC_FEATURE_32 | + PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, + .icache_bsize = 32, + .dcache_bsize = 32, + .machine_check = machine_check_4xx, + .platform = "ppc405", + }, #endif /* CONFIG_40x */ #ifdef CONFIG_44x diff --git a/trunk/arch/powerpc/kernel/crash.c b/trunk/arch/powerpc/kernel/crash.c index 571132ed12c1..77c749a13378 100644 --- a/trunk/arch/powerpc/kernel/crash.c +++ b/trunk/arch/powerpc/kernel/crash.c @@ -32,8 +32,6 @@ #include #include #include -#include -#include #ifdef DEBUG #include @@ -47,11 +45,6 @@ int crashing_cpu = -1; static cpumask_t cpus_in_crash = CPU_MASK_NONE; cpumask_t cpus_in_sr = CPU_MASK_NONE; -#define CRASH_HANDLER_MAX 1 -/* NULL terminated list of shutdown handles */ -static crash_shutdown_t crash_shutdown_handles[CRASH_HANDLER_MAX+1]; -static DEFINE_SPINLOCK(crash_handlers_lock); - #ifdef CONFIG_SMP static atomic_t enter_on_soft_reset = ATOMIC_INIT(0); @@ -292,72 +285,9 @@ static inline void crash_kexec_stop_spus(void) } #endif /* CONFIG_SPU_BASE */ -/* - * Register a function to be called on shutdown. Only use this if you - * can't reset your device in the second kernel. - */ -int crash_shutdown_register(crash_shutdown_t handler) -{ - unsigned int i, rc; - - spin_lock(&crash_handlers_lock); - for (i = 0 ; i < CRASH_HANDLER_MAX; i++) - if (!crash_shutdown_handles[i]) { - /* Insert handle at first empty entry */ - crash_shutdown_handles[i] = handler; - rc = 0; - break; - } - - if (i == CRASH_HANDLER_MAX) { - printk(KERN_ERR "Crash shutdown handles full, " - "not registered.\n"); - rc = 1; - } - - spin_unlock(&crash_handlers_lock); - return rc; -} -EXPORT_SYMBOL(crash_shutdown_register); - -int crash_shutdown_unregister(crash_shutdown_t handler) -{ - unsigned int i, rc; - - spin_lock(&crash_handlers_lock); - for (i = 0 ; i < CRASH_HANDLER_MAX; i++) - if (crash_shutdown_handles[i] == handler) - break; - - if (i == CRASH_HANDLER_MAX) { - printk(KERN_ERR "Crash shutdown handle not found\n"); - rc = 1; - } else { - /* Shift handles down */ - for (; crash_shutdown_handles[i]; i++) - crash_shutdown_handles[i] = - crash_shutdown_handles[i+1]; - rc = 0; - } - - spin_unlock(&crash_handlers_lock); - return rc; -} -EXPORT_SYMBOL(crash_shutdown_unregister); - -static unsigned long crash_shutdown_buf[JMP_BUF_LEN]; - -static int handle_fault(struct pt_regs *regs) -{ - longjmp(crash_shutdown_buf, 1); - return 0; -} - void default_machine_crash_shutdown(struct pt_regs *regs) { - unsigned int i; - int (*old_handler)(struct pt_regs *regs); - + unsigned int irq; /* * This function is only called after the system @@ -371,36 +301,15 @@ void default_machine_crash_shutdown(struct pt_regs *regs) */ hard_irq_disable(); - for_each_irq(i) { - struct irq_desc *desc = irq_desc + i; + for_each_irq(irq) { + struct irq_desc *desc = irq_desc + irq; if (desc->status & IRQ_INPROGRESS) - desc->chip->eoi(i); + desc->chip->eoi(irq); if (!(desc->status & IRQ_DISABLED)) - desc->chip->disable(i); - } - - /* - * Call registered shutdown routines savely. Swap out - * __debugger_fault_handler, and replace on exit. - */ - old_handler = __debugger_fault_handler; - __debugger_fault_handler = handle_fault; - for (i = 0; crash_shutdown_handles[i]; i++) { - if (setjmp(crash_shutdown_buf) == 0) { - /* - * Insert syncs and delay to ensure - * instructions in the dangerous region don't - * leak away from this protected region. - */ - asm volatile("sync; isync"); - /* dangerous region */ - crash_shutdown_handles[i](); - asm volatile("sync; isync"); - } + desc->chip->disable(irq); } - __debugger_fault_handler = old_handler; /* * Make a note of crashing cpu. Will be used in machine_kexec diff --git a/trunk/arch/powerpc/kernel/dma_64.c b/trunk/arch/powerpc/kernel/dma_64.c index 84239076a5b8..14206e3f0819 100644 --- a/trunk/arch/powerpc/kernel/dma_64.c +++ b/trunk/arch/powerpc/kernel/dma_64.c @@ -112,16 +112,10 @@ EXPORT_SYMBOL(dma_iommu_ops); /* * Generic direct DMA implementation * - * This implementation supports a per-device offset that can be applied if - * the address at which memory is visible to devices is not 0. Platform code - * can set archdata.dma_data to an unsigned long holding the offset. By - * default the offset is zero. + * This implementation supports a global offset that can be applied if + * the address at which memory is visible to devices is not 0. */ - -static unsigned long get_dma_direct_offset(struct device *dev) -{ - return (unsigned long)dev->archdata.dma_data; -} +unsigned long dma_direct_offset; static void *dma_direct_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) @@ -130,12 +124,13 @@ static void *dma_direct_alloc_coherent(struct device *dev, size_t size, void *ret; int node = dev->archdata.numa_node; + /* TODO: Maybe use the numa node here too ? */ page = alloc_pages_node(node, flag, get_order(size)); if (page == NULL) return NULL; ret = page_address(page); memset(ret, 0, size); - *dma_handle = virt_to_abs(ret) + get_dma_direct_offset(dev); + *dma_handle = virt_to_abs(ret) | dma_direct_offset; return ret; } @@ -150,7 +145,7 @@ static dma_addr_t dma_direct_map_single(struct device *dev, void *ptr, size_t size, enum dma_data_direction direction) { - return virt_to_abs(ptr) + get_dma_direct_offset(dev); + return virt_to_abs(ptr) | dma_direct_offset; } static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr, @@ -166,7 +161,7 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, int i; for_each_sg(sgl, sg, nents, i) { - sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev); + sg->dma_address = sg_phys(sg) | dma_direct_offset; sg->dma_length = sg->length; } diff --git a/trunk/arch/powerpc/kernel/ibmebus.c b/trunk/arch/powerpc/kernel/ibmebus.c index 2f50bb5d00f9..fd5ae8d17c96 100644 --- a/trunk/arch/powerpc/kernel/ibmebus.c +++ b/trunk/arch/powerpc/kernel/ibmebus.c @@ -198,13 +198,16 @@ int ibmebus_register_driver(struct of_platform_driver *drv) /* If the driver uses devices that ibmebus doesn't know, add them */ ibmebus_create_devices(drv->match_table); - return of_register_driver(drv, &ibmebus_bus_type); + drv->driver.name = drv->name; + drv->driver.bus = &ibmebus_bus_type; + + return driver_register(&drv->driver); } EXPORT_SYMBOL(ibmebus_register_driver); void ibmebus_unregister_driver(struct of_platform_driver *drv) { - of_unregister_driver(drv); + driver_unregister(&drv->driver); } EXPORT_SYMBOL(ibmebus_unregister_driver); diff --git a/trunk/arch/powerpc/kernel/misc.S b/trunk/arch/powerpc/kernel/misc.S index 7b9160220698..74ce0c7a7b1e 100644 --- a/trunk/arch/powerpc/kernel/misc.S +++ b/trunk/arch/powerpc/kernel/misc.S @@ -8,8 +8,6 @@ * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) * - * setjmp/longjmp code 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 @@ -17,8 +15,6 @@ */ #include #include -#include -#include .text @@ -55,64 +51,3 @@ _GLOBAL(kernel_execve) bnslr neg r3,r3 blr - -_GLOBAL(setjmp) - mflr r0 - PPC_STL r0,0(r3) - PPC_STL r1,SZL(r3) - PPC_STL r2,2*SZL(r3) - mfcr r0 - PPC_STL r0,3*SZL(r3) - PPC_STL r13,4*SZL(r3) - PPC_STL r14,5*SZL(r3) - PPC_STL r15,6*SZL(r3) - PPC_STL r16,7*SZL(r3) - PPC_STL r17,8*SZL(r3) - PPC_STL r18,9*SZL(r3) - PPC_STL r19,10*SZL(r3) - PPC_STL r20,11*SZL(r3) - PPC_STL r21,12*SZL(r3) - PPC_STL r22,13*SZL(r3) - PPC_STL r23,14*SZL(r3) - PPC_STL r24,15*SZL(r3) - PPC_STL r25,16*SZL(r3) - PPC_STL r26,17*SZL(r3) - PPC_STL r27,18*SZL(r3) - PPC_STL r28,19*SZL(r3) - PPC_STL r29,20*SZL(r3) - PPC_STL r30,21*SZL(r3) - PPC_STL r31,22*SZL(r3) - li r3,0 - blr - -_GLOBAL(longjmp) - PPC_LCMPI r4,0 - bne 1f - li r4,1 -1: PPC_LL r13,4*SZL(r3) - PPC_LL r14,5*SZL(r3) - PPC_LL r15,6*SZL(r3) - PPC_LL r16,7*SZL(r3) - PPC_LL r17,8*SZL(r3) - PPC_LL r18,9*SZL(r3) - PPC_LL r19,10*SZL(r3) - PPC_LL r20,11*SZL(r3) - PPC_LL r21,12*SZL(r3) - PPC_LL r22,13*SZL(r3) - PPC_LL r23,14*SZL(r3) - PPC_LL r24,15*SZL(r3) - PPC_LL r25,16*SZL(r3) - PPC_LL r26,17*SZL(r3) - PPC_LL r27,18*SZL(r3) - PPC_LL r28,19*SZL(r3) - PPC_LL r29,20*SZL(r3) - PPC_LL r30,21*SZL(r3) - PPC_LL r31,22*SZL(r3) - PPC_LL r0,3*SZL(r3) - mtcrf 0x38,r0 - PPC_LL r0,0(r3) - PPC_LL r1,SZL(r3) - PPC_LL r2,2*SZL(r3) - mtlr r0 - mr r3,r4 - blr diff --git a/trunk/arch/powerpc/kernel/pci_64.c b/trunk/arch/powerpc/kernel/pci_64.c index 52750745edfd..1930f393d01c 100644 --- a/trunk/arch/powerpc/kernel/pci_64.c +++ b/trunk/arch/powerpc/kernel/pci_64.c @@ -357,6 +357,7 @@ void __devinit scan_phb(struct pci_controller *hose) struct pci_bus *bus; struct device_node *node = hose->dn; int i, mode; + struct resource *res; DBG("PCI: Scanning PHB %s\n", node ? node->full_name : ""); @@ -374,10 +375,12 @@ void __devinit scan_phb(struct pci_controller *hose) pcibios_map_io_space(bus); /* Wire up PHB bus resources */ - DBG("PCI: PHB IO resource = %016lx-%016lx [%lx]\n", - hose->io_resource.start, hose->io_resource.end, - hose->io_resource.flags); - bus->resource[0] = &hose->io_resource; + if (hose->io_resource.flags) { + DBG("PCI: PHB IO resource = %016lx-%016lx [%lx]\n", + hose->io_resource.start, hose->io_resource.end, + hose->io_resource.flags); + bus->resource[0] = res = &hose->io_resource; + } for (i = 0; i < 3; ++i) { DBG("PCI: PHB MEM resource %d = %016lx-%016lx [%lx]\n", i, hose->mem_resources[i].start, diff --git a/trunk/arch/powerpc/kernel/ppc_ksyms.c b/trunk/arch/powerpc/kernel/ppc_ksyms.c index aa9ff35b0e63..13ebeb2d71e6 100644 --- a/trunk/arch/powerpc/kernel/ppc_ksyms.c +++ b/trunk/arch/powerpc/kernel/ppc_ksyms.c @@ -59,7 +59,6 @@ extern void single_step_exception(struct pt_regs *regs); extern int sys_sigreturn(struct pt_regs *regs); EXPORT_SYMBOL(clear_pages); -EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(ISA_DMA_THRESHOLD); EXPORT_SYMBOL(DMA_MODE_READ); EXPORT_SYMBOL(DMA_MODE_WRITE); diff --git a/trunk/arch/powerpc/kernel/smp.c b/trunk/arch/powerpc/kernel/smp.c index be35ffae10f0..338950aeb6f6 100644 --- a/trunk/arch/powerpc/kernel/smp.c +++ b/trunk/arch/powerpc/kernel/smp.c @@ -76,8 +76,6 @@ void smp_call_function_interrupt(void); int smt_enabled_at_boot = 1; -static int ipi_fail_ok; - static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL; #ifdef CONFIG_PPC64 @@ -183,13 +181,12 @@ static struct call_data_struct { * If true, wait (atomically) until function has completed on other CPUs. * [RETURNS] 0 on success, else a negative status code. Does not return until * remote CPUs are nearly ready to execute <> or are or have executed. - * is a cpu map of the cpus to send IPI to. * * You must not call this function with disabled interrupts or from a * hardware interrupt handler or from a bottom half handler. */ -static int __smp_call_function_map(void (*func) (void *info), void *info, - int nonatomic, int wait, cpumask_t map) +int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic, + int wait, cpumask_t map) { struct call_data_struct data; int ret = -1, num_cpus; @@ -206,6 +203,8 @@ static int __smp_call_function_map(void (*func) (void *info), void *info, if (wait) atomic_set(&data.finished, 0); + spin_lock(&call_lock); + /* remove 'self' from the map */ if (cpu_isset(smp_processor_id(), map)) cpu_clear(smp_processor_id(), map); @@ -232,8 +231,7 @@ static int __smp_call_function_map(void (*func) (void *info), void *info, printk("smp_call_function on cpu %d: other cpus not " "responding (%d)\n", smp_processor_id(), atomic_read(&data.started)); - if (!ipi_fail_ok) - debugger(NULL); + debugger(NULL); goto out; } } @@ -260,18 +258,14 @@ static int __smp_call_function_map(void (*func) (void *info), void *info, out: call_data = NULL; HMT_medium(); + spin_unlock(&call_lock); return ret; } static int __smp_call_function(void (*func)(void *info), void *info, int nonatomic, int wait) { - int ret; - spin_lock(&call_lock); - ret =__smp_call_function_map(func, info, nonatomic, wait, - cpu_online_map); - spin_unlock(&call_lock); - return ret; + return smp_call_function_map(func,info,nonatomic,wait,cpu_online_map); } int smp_call_function(void (*func) (void *info), void *info, int nonatomic, @@ -284,8 +278,8 @@ int smp_call_function(void (*func) (void *info), void *info, int nonatomic, } EXPORT_SYMBOL(smp_call_function); -int smp_call_function_single(int cpu, void (*func) (void *info), void *info, - int nonatomic, int wait) +int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int nonatomic, + int wait) { cpumask_t map = CPU_MASK_NONE; int ret = 0; @@ -297,11 +291,9 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, return -EINVAL; cpu_set(cpu, map); - if (cpu != get_cpu()) { - spin_lock(&call_lock); - ret = __smp_call_function_map(func, info, nonatomic, wait, map); - spin_unlock(&call_lock); - } else { + if (cpu != get_cpu()) + ret = smp_call_function_map(func,info,nonatomic,wait,map); + else { local_irq_disable(); func(info); local_irq_enable(); @@ -313,22 +305,7 @@ EXPORT_SYMBOL(smp_call_function_single); void smp_send_stop(void) { - int nolock; - - /* It's OK to fail sending the IPI, since the alternative is to - * be stuck forever waiting on the other CPU to take the interrupt. - * - * It's better to at least continue and go through reboot, since this - * function is usually called at panic or reboot time in the first - * place. - */ - ipi_fail_ok = 1; - - /* Don't deadlock in case we got called through panic */ - nolock = !spin_trylock(&call_lock); - __smp_call_function_map(stop_this_cpu, NULL, 1, 0, cpu_online_map); - if (!nolock) - spin_unlock(&call_lock); + __smp_call_function(stop_this_cpu, NULL, 1, 0); } void smp_call_function_interrupt(void) diff --git a/trunk/arch/powerpc/kernel/systbl_chk.c b/trunk/arch/powerpc/kernel/systbl_chk.c index 238aa63ced8f..77824d1cb150 100644 --- a/trunk/arch/powerpc/kernel/systbl_chk.c +++ b/trunk/arch/powerpc/kernel/systbl_chk.c @@ -6,7 +6,7 @@ * Unfortunately, we cannot check for the correct ordering of entries * using SYSX(). * - * Copyright © IBM Corporation + * Copyright © IBM Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/trunk/arch/powerpc/kernel/systbl_chk.sh b/trunk/arch/powerpc/kernel/systbl_chk.sh index 19415e7674a5..367d208301d2 100644 --- a/trunk/arch/powerpc/kernel/systbl_chk.sh +++ b/trunk/arch/powerpc/kernel/systbl_chk.sh @@ -3,7 +3,7 @@ # Just process the CPP output from systbl_chk.c and complain # if anything is out of order. # -# Copyright © 2008 IBM Corporation +# Copyright © 2008 IBM Corporation # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License diff --git a/trunk/arch/powerpc/mm/fault.c b/trunk/arch/powerpc/mm/fault.c index 7b2510799266..10dda224a361 100644 --- a/trunk/arch/powerpc/mm/fault.c +++ b/trunk/arch/powerpc/mm/fault.c @@ -167,8 +167,10 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, if (notify_page_fault(regs)) return 0; - if (unlikely(debugger_fault_handler(regs))) - return 0; + if (trap == 0x300) { + if (debugger_fault_handler(regs)) + return 0; + } /* On a kernel SLB miss we can only check for a valid exception entry */ if (!user_mode(regs) && (address >= TASK_SIZE)) diff --git a/trunk/arch/powerpc/platforms/cell/iommu.c b/trunk/arch/powerpc/platforms/cell/iommu.c index eb2a94b0dc4c..bceb5e13da5c 100644 --- a/trunk/arch/powerpc/platforms/cell/iommu.c +++ b/trunk/arch/powerpc/platforms/cell/iommu.c @@ -310,8 +310,8 @@ static void cell_iommu_setup_hardware(struct cbe_iommu *iommu, unsigned long siz { struct page *page; int ret, i; - unsigned long reg, segments, pages_per_segment, ptab_size, stab_size, - n_pte_pages, xlate_base; + unsigned long reg, segments, pages_per_segment, ptab_size, n_pte_pages; + unsigned long xlate_base; unsigned int virq; if (cell_iommu_find_ioc(iommu->nid, &xlate_base)) @@ -328,8 +328,7 @@ static void cell_iommu_setup_hardware(struct cbe_iommu *iommu, unsigned long siz __FUNCTION__, iommu->nid, segments, pages_per_segment); /* set up the segment table */ - stab_size = segments * sizeof(unsigned long); - page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(stab_size)); + page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0); BUG_ON(!page); iommu->stab = page_address(page); clear_page(iommu->stab); @@ -491,18 +490,15 @@ static struct cbe_iommu *cell_iommu_for_node(int nid) return NULL; } -static unsigned long cell_dma_direct_offset; - static void cell_dma_dev_setup(struct device *dev) { struct iommu_window *window; struct cbe_iommu *iommu; struct dev_archdata *archdata = &dev->archdata; - if (get_pci_dma_ops() == &dma_direct_ops) { - archdata->dma_data = (void *)cell_dma_direct_offset; + /* If we run without iommu, no need to do anything */ + if (get_pci_dma_ops() == &dma_direct_ops) return; - } /* Current implementation uses the first window available in that * node's iommu. We -might- do something smarter later though it may @@ -658,7 +654,7 @@ static int __init cell_iommu_init_disabled(void) /* If we have no Axon, we set up the spider DMA magic offset */ if (of_find_node_by_name(NULL, "axon") == NULL) - cell_dma_direct_offset = SPIDER_DMA_OFFSET; + dma_direct_offset = SPIDER_DMA_OFFSET; /* Now we need to check to see where the memory is mapped * in PCI space. We assume that all busses use the same dma @@ -692,13 +688,10 @@ static int __init cell_iommu_init_disabled(void) return -ENODEV; } - cell_dma_direct_offset += base; - - if (cell_dma_direct_offset != 0) - ppc_md.pci_dma_dev_setup = cell_pci_dma_dev_setup; + dma_direct_offset += base; printk("iommu: disabled, direct DMA offset is 0x%lx\n", - cell_dma_direct_offset); + dma_direct_offset); return 0; } diff --git a/trunk/arch/powerpc/platforms/celleb/iommu.c b/trunk/arch/powerpc/platforms/celleb/iommu.c index 93b0efddd658..41e1e6f8e059 100644 --- a/trunk/arch/powerpc/platforms/celleb/iommu.c +++ b/trunk/arch/powerpc/platforms/celleb/iommu.c @@ -52,8 +52,6 @@ static int __init find_dma_window(u64 *io_space_id, u64 *ioid, return 0; } -static unsigned long celleb_dma_direct_offset; - static void __init celleb_init_direct_mapping(void) { u64 lpar_addr, io_addr; @@ -71,18 +69,7 @@ static void __init celleb_init_direct_mapping(void) ioid, DMA_FLAGS); } - celleb_dma_direct_offset = dma_base; -} - -static void celleb_dma_dev_setup(struct device *dev) -{ - dev->archdata.dma_ops = get_pci_dma_ops(); - dev->archdata.dma_data = (void *)celleb_dma_direct_offset; -} - -static void celleb_pci_dma_dev_setup(struct pci_dev *pdev) -{ - celleb_dma_dev_setup(&pdev->dev); + dma_direct_offset = dma_base; } static int celleb_of_bus_notify(struct notifier_block *nb, @@ -94,7 +81,7 @@ static int celleb_of_bus_notify(struct notifier_block *nb, if (action != BUS_NOTIFY_ADD_DEVICE) return 0; - celleb_dma_dev_setup(dev); + dev->archdata.dma_ops = get_pci_dma_ops(); return 0; } @@ -107,7 +94,6 @@ static int __init celleb_init_iommu(void) { celleb_init_direct_mapping(); set_pci_dma_ops(&dma_direct_ops); - ppc_md.pci_dma_dev_setup = celleb_pci_dma_dev_setup; bus_register_notifier(&of_platform_bus_type, &celleb_of_bus_notifier); return 0; diff --git a/trunk/arch/powerpc/platforms/chrp/pci.c b/trunk/arch/powerpc/platforms/chrp/pci.c index 609c46db4a1b..d51f83aeef7f 100644 --- a/trunk/arch/powerpc/platforms/chrp/pci.c +++ b/trunk/arch/powerpc/platforms/chrp/pci.c @@ -354,7 +354,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, * mode as well. The same fixup must be done to the class-code property in * the IDE node /pci@80000000/ide@C,1 */ -static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide) +static void __devinit chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide) { u8 progif; struct pci_dev *viaisa; @@ -375,4 +375,4 @@ static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide) pci_dev_put(viaisa); } -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata); diff --git a/trunk/arch/powerpc/platforms/chrp/setup.c b/trunk/arch/powerpc/platforms/chrp/setup.c index 116babbaaf81..42a21bab76c8 100644 --- a/trunk/arch/powerpc/platforms/chrp/setup.c +++ b/trunk/arch/powerpc/platforms/chrp/setup.c @@ -256,57 +256,6 @@ static void briq_restart(char *cmd) for(;;); } -/* - * Per default, input/output-device points to the keyboard/screen - * If no card is installed, the built-in serial port is used as a fallback. - * But unfortunately, the firmware does not connect /chosen/{stdin,stdout} - * the the built-in serial node. Instead, a /failsafe node is created. - */ -static void chrp_init_early(void) -{ - struct device_node *node; - const char *property; - - if (strstr(cmd_line, "console=")) - return; - /* find the boot console from /chosen/stdout */ - if (!of_chosen) - return; - node = of_find_node_by_path("/"); - if (!node) - return; - property = of_get_property(node, "model", NULL); - if (!property) - goto out_put; - if (strcmp(property, "Pegasos2")) - goto out_put; - /* this is a Pegasos2 */ - property = of_get_property(of_chosen, "linux,stdout-path", NULL); - if (!property) - goto out_put; - of_node_put(node); - node = of_find_node_by_path(property); - if (!node) - return; - property = of_get_property(node, "device_type", NULL); - if (!property) - goto out_put; - if (strcmp(property, "serial")) - goto out_put; - /* - * The 9pin connector is either /failsafe - * or /pci@80000000/isa@C/serial@i2F8 - * The optional graphics card has also type 'serial' in VGA mode. - */ - property = of_get_property(node, "name", NULL); - if (!property) - goto out_put; - if (!strcmp(property, "failsafe") || !strcmp(property, "serial")) - add_preferred_console("ttyS", 0, NULL); -out_put: - of_node_put(node); -} - void __init chrp_setup_arch(void) { struct device_node *root = of_find_node_by_path("/"); @@ -650,7 +599,6 @@ define_machine(chrp) { .probe = chrp_probe, .setup_arch = chrp_setup_arch, .init = chrp_init2, - .init_early = chrp_init_early, .show_cpuinfo = chrp_show_cpuinfo, .init_IRQ = chrp_init_IRQ, .restart = rtas_restart, diff --git a/trunk/arch/powerpc/platforms/ps3/Kconfig b/trunk/arch/powerpc/platforms/ps3/Kconfig index a5f4e95dfc3d..298f1c9679fb 100644 --- a/trunk/arch/powerpc/platforms/ps3/Kconfig +++ b/trunk/arch/powerpc/platforms/ps3/Kconfig @@ -61,6 +61,17 @@ config PS3_DYNAMIC_DMA This support is mainly for Linux kernel development. If unsure, say N. +config PS3_USE_LPAR_ADDR + depends on PPC_PS3 && EXPERIMENTAL + bool "PS3 use lpar address space" + default y + help + This option is solely for experimentation by experts. Disables + translation of lpar addresses. SPE support currently won't work + without this set to y. + + If you have any doubt, choose the default y. + config PS3_VUART depends on PPC_PS3 tristate @@ -127,17 +138,4 @@ config PS3_FLASH be disabled on the kernel command line using "ps3flash=off", to not allocate this fixed buffer. -config PS3_LPM - tristate "PS3 Logical Performance Monitor support" - depends on PPC_PS3 - help - Include support for the PS3 Logical Performance Monitor. - - This support is required to use the logical performance monitor - of the PS3's LV1 hypervisor. - - If you intend to use the advanced performance monitoring and - profiling support of the Cell processor with programs like - oprofile and perfmon2, then say Y or M, otherwise say N. - endmenu diff --git a/trunk/arch/powerpc/platforms/ps3/device-init.c b/trunk/arch/powerpc/platforms/ps3/device-init.c index 9d251d0ca8c6..fd063fe0c9b3 100644 --- a/trunk/arch/powerpc/platforms/ps3/device-init.c +++ b/trunk/arch/powerpc/platforms/ps3/device-init.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -31,89 +30,6 @@ #include "platform.h" -static int __init ps3_register_lpm_devices(void) -{ - int result; - u64 tmp1; - u64 tmp2; - struct ps3_system_bus_device *dev; - - pr_debug(" -> %s:%d\n", __func__, __LINE__); - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - dev->match_id = PS3_MATCH_ID_LPM; - dev->dev_type = PS3_DEVICE_TYPE_LPM; - - /* The current lpm driver only supports a single BE processor. */ - - result = ps3_repository_read_be_node_id(0, &dev->lpm.node_id); - - if (result) { - pr_debug("%s:%d: ps3_repository_read_be_node_id failed \n", - __func__, __LINE__); - goto fail_read_repo; - } - - result = ps3_repository_read_lpm_privileges(dev->lpm.node_id, &tmp1, - &dev->lpm.rights); - - if (result) { - pr_debug("%s:%d: ps3_repository_read_lpm_privleges failed \n", - __func__, __LINE__); - goto fail_read_repo; - } - - lv1_get_logical_partition_id(&tmp2); - - if (tmp1 != tmp2) { - pr_debug("%s:%d: wrong lpar\n", - __func__, __LINE__); - result = -ENODEV; - goto fail_rights; - } - - if (!(dev->lpm.rights & PS3_LPM_RIGHTS_USE_LPM)) { - pr_debug("%s:%d: don't have rights to use lpm\n", - __func__, __LINE__); - result = -EPERM; - goto fail_rights; - } - - pr_debug("%s:%d: pu_id %lu, rights %lu(%lxh)\n", - __func__, __LINE__, dev->lpm.pu_id, dev->lpm.rights, - dev->lpm.rights); - - result = ps3_repository_read_pu_id(0, &dev->lpm.pu_id); - - if (result) { - pr_debug("%s:%d: ps3_repository_read_pu_id failed \n", - __func__, __LINE__); - goto fail_read_repo; - } - - result = ps3_system_bus_device_register(dev); - - if (result) { - pr_debug("%s:%d ps3_system_bus_device_register failed\n", - __func__, __LINE__); - goto fail_register; - } - - pr_debug(" <- %s:%d\n", __func__, __LINE__); - return 0; - - -fail_register: -fail_rights: -fail_read_repo: - kfree(dev); - pr_debug(" <- %s:%d: failed\n", __func__, __LINE__); - return result; -} - /** * ps3_setup_gelic_device - Setup and register a gelic device instance. * @@ -322,6 +238,166 @@ static int __init ps3_setup_vuart_device(enum ps3_match_id match_id, return result; } +static int ps3stor_wait_for_completion(u64 dev_id, u64 tag, + unsigned int timeout) +{ + int result = -1; + unsigned int retries = 0; + u64 status; + + for (retries = 0; retries < timeout; retries++) { + result = lv1_storage_check_async_status(dev_id, tag, &status); + if (!result) + break; + + msleep(1); + } + + if (result) + pr_debug("%s:%u: check_async_status: %s, status %lx\n", + __func__, __LINE__, ps3_result(result), status); + + return result; +} + +/** + * ps3_storage_wait_for_device - Wait for a storage device to become ready. + * @repo: The repository device to wait for. + * + * Uses the hypervisor's storage device notification mechanism to wait until + * a storage device is ready. The device notification mechanism uses a + * psuedo device (id = -1) to asynchronously notify the guest when storage + * devices become ready. The notification device has a block size of 512 + * bytes. + */ + +static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo) +{ + int error = -ENODEV; + int result; + const u64 notification_dev_id = (u64)-1LL; + const unsigned int timeout = HZ; + u64 lpar; + u64 tag; + void *buf; + enum ps3_notify_type { + notify_device_ready = 0, + notify_region_probe = 1, + notify_region_update = 2, + }; + struct { + u64 operation_code; /* must be zero */ + u64 event_mask; /* OR of 1UL << enum ps3_notify_type */ + } *notify_cmd; + struct { + u64 event_type; /* enum ps3_notify_type */ + u64 bus_id; + u64 dev_id; + u64 dev_type; + u64 dev_port; + } *notify_event; + + pr_debug(" -> %s:%u: (%u:%u:%u)\n", __func__, __LINE__, repo->bus_id, + repo->dev_id, repo->dev_type); + + buf = kzalloc(512, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + lpar = ps3_mm_phys_to_lpar(__pa(buf)); + notify_cmd = buf; + notify_event = buf; + + result = lv1_open_device(repo->bus_id, notification_dev_id, 0); + if (result) { + printk(KERN_ERR "%s:%u: lv1_open_device %s\n", __func__, + __LINE__, ps3_result(result)); + goto fail_free; + } + + /* Setup and write the request for device notification. */ + + notify_cmd->operation_code = 0; /* must be zero */ + notify_cmd->event_mask = 1UL << notify_region_probe; + + result = lv1_storage_write(notification_dev_id, 0, 0, 1, 0, lpar, + &tag); + if (result) { + printk(KERN_ERR "%s:%u: write failed %s\n", __func__, __LINE__, + ps3_result(result)); + goto fail_close; + } + + /* Wait for the write completion */ + + result = ps3stor_wait_for_completion(notification_dev_id, tag, + timeout); + if (result) { + printk(KERN_ERR "%s:%u: write not completed %s\n", __func__, + __LINE__, ps3_result(result)); + goto fail_close; + } + + /* Loop here processing the requested notification events. */ + + while (1) { + memset(notify_event, 0, sizeof(*notify_event)); + + result = lv1_storage_read(notification_dev_id, 0, 0, 1, 0, + lpar, &tag); + if (result) { + printk(KERN_ERR "%s:%u: write failed %s\n", __func__, + __LINE__, ps3_result(result)); + break; + } + + result = ps3stor_wait_for_completion(notification_dev_id, tag, + timeout); + if (result) { + printk(KERN_ERR "%s:%u: read not completed %s\n", + __func__, __LINE__, ps3_result(result)); + break; + } + + pr_debug("%s:%d: notify event (%u:%u:%u): event_type 0x%lx, " + "port %lu\n", __func__, __LINE__, repo->bus_index, + repo->dev_index, repo->dev_type, + notify_event->event_type, notify_event->dev_port); + + if (notify_event->event_type != notify_region_probe || + notify_event->bus_id != repo->bus_id) { + pr_debug("%s:%u: bad notify_event: event %lu, " + "dev_id %lu, dev_type %lu\n", + __func__, __LINE__, notify_event->event_type, + notify_event->dev_id, notify_event->dev_type); + break; + } + + if (notify_event->dev_id == repo->dev_id && + notify_event->dev_type == repo->dev_type) { + pr_debug("%s:%u: device ready (%u:%u:%u)\n", __func__, + __LINE__, repo->bus_index, repo->dev_index, + repo->dev_type); + error = 0; + break; + } + + if (notify_event->dev_id == repo->dev_id && + notify_event->dev_type == PS3_DEV_TYPE_NOACCESS) { + pr_debug("%s:%u: no access: dev_id %u\n", __func__, + __LINE__, repo->dev_id); + break; + } + } + +fail_close: + lv1_close_device(repo->bus_id, notification_dev_id); +fail_free: + kfree(buf); + pr_debug(" <- %s:%u\n", __func__, __LINE__); + return error; +} + static int ps3_setup_storage_dev(const struct ps3_repository_device *repo, enum ps3_match_id match_id) { @@ -373,6 +449,16 @@ static int ps3_setup_storage_dev(const struct ps3_repository_device *repo, goto fail_find_interrupt; } + /* FIXME: Arrange to only do this on a 'cold' boot */ + + result = ps3_storage_wait_for_device(repo); + if (result) { + printk(KERN_ERR "%s:%u: storage_notification failed %d\n", + __func__, __LINE__, result); + result = -ENODEV; + goto fail_probe_notification; + } + for (i = 0; i < num_regions; i++) { unsigned int id; u64 start, size; @@ -408,6 +494,7 @@ static int ps3_setup_storage_dev(const struct ps3_repository_device *repo, fail_device_register: fail_read_region: +fail_probe_notification: fail_find_interrupt: kfree(p); fail_malloc: @@ -572,267 +659,61 @@ static int ps3_register_repository_device( return result; } -static void ps3_find_and_add_device(u64 bus_id, u64 dev_id) -{ - struct ps3_repository_device repo; - int res; - unsigned int retries; - unsigned long rem; - - /* - * On some firmware versions (e.g. 1.90), the device may not show up - * in the repository immediately - */ - for (retries = 0; retries < 10; retries++) { - res = ps3_repository_find_device_by_id(&repo, bus_id, dev_id); - if (!res) - goto found; - - rem = msleep_interruptible(100); - if (rem) - break; - } - pr_warning("%s:%u: device %lu:%lu not found\n", __func__, __LINE__, - bus_id, dev_id); - return; - -found: - if (retries) - pr_debug("%s:%u: device %lu:%lu found after %u retries\n", - __func__, __LINE__, bus_id, dev_id, retries); - - ps3_register_repository_device(&repo); - return; -} - -#define PS3_NOTIFICATION_DEV_ID ULONG_MAX -#define PS3_NOTIFICATION_INTERRUPT_ID 0 - -struct ps3_notification_device { - struct ps3_system_bus_device sbd; - spinlock_t lock; - u64 tag; - u64 lv1_status; - struct completion done; -}; - -enum ps3_notify_type { - notify_device_ready = 0, - notify_region_probe = 1, - notify_region_update = 2, -}; - -struct ps3_notify_cmd { - u64 operation_code; /* must be zero */ - u64 event_mask; /* OR of 1UL << enum ps3_notify_type */ -}; - -struct ps3_notify_event { - u64 event_type; /* enum ps3_notify_type */ - u64 bus_id; - u64 dev_id; - u64 dev_type; - u64 dev_port; -}; - -static irqreturn_t ps3_notification_interrupt(int irq, void *data) -{ - struct ps3_notification_device *dev = data; - int res; - u64 tag, status; - - spin_lock(&dev->lock); - res = lv1_storage_get_async_status(PS3_NOTIFICATION_DEV_ID, &tag, - &status); - if (tag != dev->tag) - pr_err("%s:%u: tag mismatch, got %lx, expected %lx\n", - __func__, __LINE__, tag, dev->tag); - - if (res) { - pr_err("%s:%u: res %d status 0x%lx\n", __func__, __LINE__, res, - status); - } else { - pr_debug("%s:%u: completed, status 0x%lx\n", __func__, - __LINE__, status); - dev->lv1_status = status; - complete(&dev->done); - } - spin_unlock(&dev->lock); - return IRQ_HANDLED; -} - -static int ps3_notification_read_write(struct ps3_notification_device *dev, - u64 lpar, int write) -{ - const char *op = write ? "write" : "read"; - unsigned long flags; - int res; - - init_completion(&dev->done); - spin_lock_irqsave(&dev->lock, flags); - res = write ? lv1_storage_write(dev->sbd.dev_id, 0, 0, 1, 0, lpar, - &dev->tag) - : lv1_storage_read(dev->sbd.dev_id, 0, 0, 1, 0, lpar, - &dev->tag); - spin_unlock_irqrestore(&dev->lock, flags); - if (res) { - pr_err("%s:%u: %s failed %d\n", __func__, __LINE__, op, res); - return -EPERM; - } - pr_debug("%s:%u: notification %s issued\n", __func__, __LINE__, op); - - res = wait_event_interruptible(dev->done.wait, - dev->done.done || kthread_should_stop()); - if (kthread_should_stop()) - res = -EINTR; - if (res) { - pr_debug("%s:%u: interrupted %s\n", __func__, __LINE__, op); - return res; - } - - if (dev->lv1_status) { - pr_err("%s:%u: %s not completed, status 0x%lx\n", __func__, - __LINE__, op, dev->lv1_status); - return -EIO; - } - pr_debug("%s:%u: notification %s completed\n", __func__, __LINE__, op); - - return 0; -} - -static struct task_struct *probe_task; - /** * ps3_probe_thread - Background repository probing at system startup. * * This implementation only supports background probing on a single bus. - * It uses the hypervisor's storage device notification mechanism to wait until - * a storage device is ready. The device notification mechanism uses a - * pseudo device to asynchronously notify the guest when storage devices become - * ready. The notification device has a block size of 512 bytes. */ static int ps3_probe_thread(void *data) { - struct ps3_notification_device dev; - int res; - unsigned int irq; - u64 lpar; - void *buf; - struct ps3_notify_cmd *notify_cmd; - struct ps3_notify_event *notify_event; + struct ps3_repository_device *repo = data; + int result; + unsigned int ms = 250; pr_debug(" -> %s:%u: kthread started\n", __func__, __LINE__); - buf = kzalloc(512, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - lpar = ps3_mm_phys_to_lpar(__pa(buf)); - notify_cmd = buf; - notify_event = buf; - - /* dummy system bus device */ - dev.sbd.bus_id = (u64)data; - dev.sbd.dev_id = PS3_NOTIFICATION_DEV_ID; - dev.sbd.interrupt_id = PS3_NOTIFICATION_INTERRUPT_ID; - - res = lv1_open_device(dev.sbd.bus_id, dev.sbd.dev_id, 0); - if (res) { - pr_err("%s:%u: lv1_open_device failed %s\n", __func__, - __LINE__, ps3_result(res)); - goto fail_free; - } - - res = ps3_sb_event_receive_port_setup(&dev.sbd, PS3_BINDING_CPU_ANY, - &irq); - if (res) { - pr_err("%s:%u: ps3_sb_event_receive_port_setup failed %d\n", - __func__, __LINE__, res); - goto fail_close_device; - } - - spin_lock_init(&dev.lock); - - res = request_irq(irq, ps3_notification_interrupt, IRQF_DISABLED, - "ps3_notification", &dev); - if (res) { - pr_err("%s:%u: request_irq failed %d\n", __func__, __LINE__, - res); - goto fail_sb_event_receive_port_destroy; - } - - /* Setup and write the request for device notification. */ - notify_cmd->operation_code = 0; /* must be zero */ - notify_cmd->event_mask = 1UL << notify_region_probe; - - res = ps3_notification_read_write(&dev, lpar, 1); - if (res) - goto fail_free_irq; - - /* Loop here processing the requested notification events. */ do { try_to_freeze(); - memset(notify_event, 0, sizeof(*notify_event)); - - res = ps3_notification_read_write(&dev, lpar, 0); - if (res) + pr_debug("%s:%u: probing...\n", __func__, __LINE__); + + do { + result = ps3_repository_find_device(repo); + + if (result == -ENODEV) + pr_debug("%s:%u: nothing new\n", __func__, + __LINE__); + else if (result) + pr_debug("%s:%u: find device error.\n", + __func__, __LINE__); + else { + pr_debug("%s:%u: found device (%u:%u:%u)\n", + __func__, __LINE__, repo->bus_index, + repo->dev_index, repo->dev_type); + ps3_register_repository_device(repo); + ps3_repository_bump_device(repo); + ms = 250; + } + } while (!result); + + pr_debug("%s:%u: ms %u\n", __func__, __LINE__, ms); + + if ( ms > 60000) break; - pr_debug("%s:%u: notify event type 0x%lx bus id %lu dev id %lu" - " type %lu port %lu\n", __func__, __LINE__, - notify_event->event_type, notify_event->bus_id, - notify_event->dev_id, notify_event->dev_type, - notify_event->dev_port); + msleep_interruptible(ms); - if (notify_event->event_type != notify_region_probe || - notify_event->bus_id != dev.sbd.bus_id) { - pr_warning("%s:%u: bad notify_event: event %lu, " - "dev_id %lu, dev_type %lu\n", - __func__, __LINE__, notify_event->event_type, - notify_event->dev_id, - notify_event->dev_type); - continue; - } - - ps3_find_and_add_device(dev.sbd.bus_id, notify_event->dev_id); + /* An exponential backoff. */ + ms <<= 1; } while (!kthread_should_stop()); -fail_free_irq: - free_irq(irq, &dev); -fail_sb_event_receive_port_destroy: - ps3_sb_event_receive_port_destroy(&dev.sbd, irq); -fail_close_device: - lv1_close_device(dev.sbd.bus_id, dev.sbd.dev_id); -fail_free: - kfree(buf); - - probe_task = NULL; - pr_debug(" <- %s:%u: kthread finished\n", __func__, __LINE__); return 0; } -/** - * ps3_stop_probe_thread - Stops the background probe thread. - * - */ - -static int ps3_stop_probe_thread(struct notifier_block *nb, unsigned long code, - void *data) -{ - if (probe_task) - kthread_stop(probe_task); - return 0; -} - -static struct notifier_block nb = { - .notifier_call = ps3_stop_probe_thread -}; - /** * ps3_start_probe_thread - Starts the background probe thread. * @@ -842,7 +723,7 @@ static int __init ps3_start_probe_thread(enum ps3_bus_type bus_type) { int result; struct task_struct *task; - struct ps3_repository_device repo; + static struct ps3_repository_device repo; /* must be static */ pr_debug(" -> %s:%d\n", __func__, __LINE__); @@ -865,8 +746,7 @@ static int __init ps3_start_probe_thread(enum ps3_bus_type bus_type) return -ENODEV; } - task = kthread_run(ps3_probe_thread, (void *)repo.bus_id, - "ps3-probe-%u", bus_type); + task = kthread_run(ps3_probe_thread, &repo, "ps3-probe-%u", bus_type); if (IS_ERR(task)) { result = PTR_ERR(task); @@ -875,9 +755,6 @@ static int __init ps3_start_probe_thread(enum ps3_bus_type bus_type) return result; } - probe_task = task; - register_reboot_notifier(&nb); - pr_debug(" <- %s:%d\n", __func__, __LINE__); return 0; } @@ -910,8 +787,6 @@ static int __init ps3_register_devices(void) ps3_register_sound_devices(); - ps3_register_lpm_devices(); - pr_debug(" <- %s:%d\n", __func__, __LINE__); return 0; } diff --git a/trunk/arch/powerpc/platforms/ps3/mm.c b/trunk/arch/powerpc/platforms/ps3/mm.c index 68900476c842..7bb3e1620974 100644 --- a/trunk/arch/powerpc/platforms/ps3/mm.c +++ b/trunk/arch/powerpc/platforms/ps3/mm.c @@ -36,6 +36,11 @@ #endif enum { +#if defined(CONFIG_PS3_USE_LPAR_ADDR) + USE_LPAR_ADDR = 1, +#else + USE_LPAR_ADDR = 0, +#endif #if defined(CONFIG_PS3_DYNAMIC_DMA) USE_DYNAMIC_DMA = 1, #else @@ -132,8 +137,11 @@ static struct map map; unsigned long ps3_mm_phys_to_lpar(unsigned long phys_addr) { BUG_ON(is_kernel_addr(phys_addr)); - return (phys_addr < map.rm.size || phys_addr >= map.total) - ? phys_addr : phys_addr + map.r1.offset; + if (USE_LPAR_ADDR) + return phys_addr; + else + return (phys_addr < map.rm.size || phys_addr >= map.total) + ? phys_addr : phys_addr + map.r1.offset; } EXPORT_SYMBOL(ps3_mm_phys_to_lpar); @@ -301,7 +309,7 @@ static int __init ps3_mm_add_memory(void) BUG_ON(!mem_init_done); - start_addr = map.rm.size; + start_addr = USE_LPAR_ADDR ? map.r1.base : map.rm.size; start_pfn = start_addr >> PAGE_SHIFT; nr_pages = (map.r1.size + PAGE_SIZE - 1) >> PAGE_SHIFT; @@ -351,7 +359,7 @@ static unsigned long dma_sb_lpar_to_bus(struct ps3_dma_region *r, static void __maybe_unused _dma_dump_region(const struct ps3_dma_region *r, const char *func, int line) { - DBG("%s:%d: dev %lu:%lu\n", func, line, r->dev->bus_id, + DBG("%s:%d: dev %u:%u\n", func, line, r->dev->bus_id, r->dev->dev_id); DBG("%s:%d: page_size %u\n", func, line, r->page_size); DBG("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr); @@ -386,7 +394,7 @@ struct dma_chunk { static void _dma_dump_chunk (const struct dma_chunk* c, const char* func, int line) { - DBG("%s:%d: r.dev %lu:%lu\n", func, line, + DBG("%s:%d: r.dev %u:%u\n", func, line, c->region->dev->bus_id, c->region->dev->dev_id); DBG("%s:%d: r.bus_addr %lxh\n", func, line, c->region->bus_addr); DBG("%s:%d: r.page_size %u\n", func, line, c->region->page_size); @@ -650,7 +658,7 @@ static int dma_sb_region_create(struct ps3_dma_region *r) BUG_ON(!r); if (!r->dev->bus_id) { - pr_info("%s:%d: %lu:%lu no dma\n", __func__, __LINE__, + pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__, r->dev->bus_id, r->dev->dev_id); return 0; } @@ -716,7 +724,7 @@ static int dma_sb_region_free(struct ps3_dma_region *r) BUG_ON(!r); if (!r->dev->bus_id) { - pr_info("%s:%d: %lu:%lu no dma\n", __func__, __LINE__, + pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__, r->dev->bus_id, r->dev->dev_id); return 0; } @@ -999,7 +1007,7 @@ static int dma_sb_region_create_linear(struct ps3_dma_region *r) if (r->offset + r->len > map.rm.size) { /* Map (part of) 2nd RAM chunk */ - virt_addr = map.rm.size; + virt_addr = USE_LPAR_ADDR ? map.r1.base : map.rm.size; len = r->len; if (r->offset >= map.rm.size) virt_addr += r->offset - map.rm.size; diff --git a/trunk/arch/powerpc/platforms/ps3/platform.h b/trunk/arch/powerpc/platforms/ps3/platform.h index 235c13ebacd9..01f0c9506e11 100644 --- a/trunk/arch/powerpc/platforms/ps3/platform.h +++ b/trunk/arch/powerpc/platforms/ps3/platform.h @@ -89,11 +89,13 @@ enum ps3_dev_type { PS3_DEV_TYPE_STOR_ROM = TYPE_ROM, /* 5 */ PS3_DEV_TYPE_SB_GPIO = 6, PS3_DEV_TYPE_STOR_FLASH = TYPE_RBC, /* 14 */ + PS3_DEV_TYPE_STOR_DUMMY = 32, + PS3_DEV_TYPE_NOACCESS = 255, }; int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str, u64 *value); -int ps3_repository_read_bus_id(unsigned int bus_index, u64 *bus_id); +int ps3_repository_read_bus_id(unsigned int bus_index, unsigned int *bus_id); int ps3_repository_read_bus_type(unsigned int bus_index, enum ps3_bus_type *bus_type); int ps3_repository_read_bus_num_dev(unsigned int bus_index, @@ -117,7 +119,7 @@ enum ps3_reg_type { int ps3_repository_read_dev_str(unsigned int bus_index, unsigned int dev_index, const char *dev_str, u64 *value); int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index, - u64 *dev_id); + unsigned int *dev_id); int ps3_repository_read_dev_type(unsigned int bus_index, unsigned int dev_index, enum ps3_dev_type *dev_type); int ps3_repository_read_dev_intr(unsigned int bus_index, @@ -136,17 +138,21 @@ int ps3_repository_read_dev_reg(unsigned int bus_index, /* repository bus enumerators */ struct ps3_repository_device { - unsigned int bus_index; - unsigned int dev_index; enum ps3_bus_type bus_type; + unsigned int bus_index; + unsigned int bus_id; enum ps3_dev_type dev_type; - u64 bus_id; - u64 dev_id; + unsigned int dev_index; + unsigned int dev_id; }; +static inline struct ps3_repository_device *ps3_repository_bump_device( + struct ps3_repository_device *repo) +{ + repo->dev_index++; + return repo; +} int ps3_repository_find_device(struct ps3_repository_device *repo); -int ps3_repository_find_device_by_id(struct ps3_repository_device *repo, - u64 bus_id, u64 dev_id); int ps3_repository_find_devices(enum ps3_bus_type bus_type, int (*callback)(const struct ps3_repository_device *repo)); int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from, @@ -180,10 +186,10 @@ int ps3_repository_read_stor_dev_region(unsigned int bus_index, unsigned int dev_index, unsigned int region_index, unsigned int *region_id, u64 *region_start, u64 *region_size); -/* repository logical pu and memory info */ +/* repository pu and memory info */ -int ps3_repository_read_num_pu(u64 *num_pu); -int ps3_repository_read_pu_id(unsigned int pu_index, u64 *pu_id); +int ps3_repository_read_num_pu(unsigned int *num_pu); +int ps3_repository_read_ppe_id(unsigned int *pu_index, unsigned int *ppe_id); int ps3_repository_read_rm_base(unsigned int ppe_id, u64 *rm_base); int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size); int ps3_repository_read_region_total(u64 *region_total); @@ -194,15 +200,9 @@ int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, int ps3_repository_read_num_be(unsigned int *num_be); int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id); -int ps3_repository_read_be_id(u64 node_id, u64 *be_id); int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq); int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq); -/* repository performance monitor info */ - -int ps3_repository_read_lpm_privileges(unsigned int be_index, u64 *lpar, - u64 *rights); - /* repository 'Other OS' area */ int ps3_repository_read_boot_dat_addr(u64 *lpar_addr); diff --git a/trunk/arch/powerpc/platforms/ps3/repository.c b/trunk/arch/powerpc/platforms/ps3/repository.c index 22063adeb38b..1c94824f7b63 100644 --- a/trunk/arch/powerpc/platforms/ps3/repository.c +++ b/trunk/arch/powerpc/platforms/ps3/repository.c @@ -33,7 +33,7 @@ enum ps3_lpar_id { }; #define dump_field(_a, _b) _dump_field(_a, _b, __func__, __LINE__) -static void _dump_field(const char *hdr, u64 n, const char *func, int line) +static void _dump_field(const char *hdr, u64 n, const char* func, int line) { #if defined(DEBUG) char s[16]; @@ -50,8 +50,8 @@ static void _dump_field(const char *hdr, u64 n, const char *func, int line) #define dump_node_name(_a, _b, _c, _d, _e) \ _dump_node_name(_a, _b, _c, _d, _e, __func__, __LINE__) -static void _dump_node_name(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, - u64 n4, const char *func, int line) +static void _dump_node_name (unsigned int lpar_id, u64 n1, u64 n2, u64 n3, + u64 n4, const char* func, int line) { pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id); _dump_field("n1: ", n1, func, line); @@ -63,7 +63,7 @@ static void _dump_node_name(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, #define dump_node(_a, _b, _c, _d, _e, _f, _g) \ _dump_node(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__) static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, - u64 v1, u64 v2, const char *func, int line) + u64 v1, u64 v2, const char* func, int line) { pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id); _dump_field("n1: ", n1, func, line); @@ -165,18 +165,21 @@ int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str, make_first_field("bus", bus_index), make_field(bus_str, 0), 0, 0, - value, NULL); + value, 0); } -int ps3_repository_read_bus_id(unsigned int bus_index, u64 *bus_id) +int ps3_repository_read_bus_id(unsigned int bus_index, unsigned int *bus_id) { int result; + u64 v1; + u64 v2; /* unused */ result = read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), make_field("id", 0), 0, 0, - bus_id, NULL); + &v1, &v2); + *bus_id = v1; return result; } @@ -190,7 +193,7 @@ int ps3_repository_read_bus_type(unsigned int bus_index, make_first_field("bus", bus_index), make_field("type", 0), 0, 0, - &v1, NULL); + &v1, 0); *bus_type = v1; return result; } @@ -205,7 +208,7 @@ int ps3_repository_read_bus_num_dev(unsigned int bus_index, make_first_field("bus", bus_index), make_field("num_dev", 0), 0, 0, - &v1, NULL); + &v1, 0); *num_dev = v1; return result; } @@ -218,20 +221,22 @@ int ps3_repository_read_dev_str(unsigned int bus_index, make_field("dev", dev_index), make_field(dev_str, 0), 0, - value, NULL); + value, 0); } int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index, - u64 *dev_id) + unsigned int *dev_id) { int result; + u64 v1; result = read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), make_field("dev", dev_index), make_field("id", 0), 0, - dev_id, NULL); + &v1, 0); + *dev_id = v1; return result; } @@ -246,14 +251,14 @@ int ps3_repository_read_dev_type(unsigned int bus_index, make_field("dev", dev_index), make_field("type", 0), 0, - &v1, NULL); + &v1, 0); *dev_type = v1; return result; } int ps3_repository_read_dev_intr(unsigned int bus_index, unsigned int dev_index, unsigned int intr_index, - enum ps3_interrupt_type *intr_type, unsigned int *interrupt_id) + enum ps3_interrupt_type *intr_type, unsigned int* interrupt_id) { int result; u64 v1; @@ -282,7 +287,7 @@ int ps3_repository_read_dev_reg_type(unsigned int bus_index, make_field("dev", dev_index), make_field("reg", reg_index), make_field("type", 0), - &v1, NULL); + &v1, 0); *reg_type = v1; return result; } @@ -327,7 +332,7 @@ int ps3_repository_find_device(struct ps3_repository_device *repo) return result; } - pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %lu, num_dev %u\n", + pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %u, num_dev %u\n", __func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id, num_dev); @@ -344,95 +349,47 @@ int ps3_repository_find_device(struct ps3_repository_device *repo) return result; } - result = ps3_repository_read_dev_id(tmp.bus_index, tmp.dev_index, - &tmp.dev_id); - - if (result) { - pr_debug("%s:%d ps3_repository_read_dev_id failed\n", __func__, - __LINE__); - return result; - } - - pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %lu\n", - __func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id); - - *repo = tmp; - return 0; -} - -int ps3_repository_find_device_by_id(struct ps3_repository_device *repo, - u64 bus_id, u64 dev_id) -{ - int result = -ENODEV; - struct ps3_repository_device tmp; - unsigned int num_dev; - - pr_debug(" -> %s:%u: find device by id %lu:%lu\n", __func__, __LINE__, - bus_id, dev_id); + if (tmp.bus_type == PS3_BUS_TYPE_STORAGE) { + /* + * A storage device may show up in the repository before the + * hypervisor has finished probing its type and regions + */ + unsigned int num_regions; + + if (tmp.dev_type == PS3_DEV_TYPE_STOR_DUMMY) { + pr_debug("%s:%u storage device not ready\n", __func__, + __LINE__); + return -ENODEV; + } - for (tmp.bus_index = 0; tmp.bus_index < 10; tmp.bus_index++) { - result = ps3_repository_read_bus_id(tmp.bus_index, - &tmp.bus_id); + result = ps3_repository_read_stor_dev_num_regions(tmp.bus_index, + tmp.dev_index, + &num_regions); if (result) { - pr_debug("%s:%u read_bus_id(%u) failed\n", __func__, - __LINE__, tmp.bus_index); + pr_debug("%s:%d read_stor_dev_num_regions failed\n", + __func__, __LINE__); return result; } - if (tmp.bus_id == bus_id) - goto found_bus; - - pr_debug("%s:%u: skip, bus_id %lu\n", __func__, __LINE__, - tmp.bus_id); + if (!num_regions) { + pr_debug("%s:%u storage device has no regions yet\n", + __func__, __LINE__); + return -ENODEV; + } } - pr_debug(" <- %s:%u: bus not found\n", __func__, __LINE__); - return result; -found_bus: - result = ps3_repository_read_bus_type(tmp.bus_index, &tmp.bus_type); - if (result) { - pr_debug("%s:%u read_bus_type(%u) failed\n", __func__, - __LINE__, tmp.bus_index); - return result; - } + result = ps3_repository_read_dev_id(tmp.bus_index, tmp.dev_index, + &tmp.dev_id); - result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev); if (result) { - pr_debug("%s:%u read_bus_num_dev failed\n", __func__, - __LINE__); + pr_debug("%s:%d ps3_repository_read_dev_id failed\n", __func__, + __LINE__); return result; } - for (tmp.dev_index = 0; tmp.dev_index < num_dev; tmp.dev_index++) { - result = ps3_repository_read_dev_id(tmp.bus_index, - tmp.dev_index, - &tmp.dev_id); - if (result) { - pr_debug("%s:%u read_dev_id(%u:%u) failed\n", __func__, - __LINE__, tmp.bus_index, tmp.dev_index); - return result; - } - - if (tmp.dev_id == dev_id) - goto found_dev; - - pr_debug("%s:%u: skip, dev_id %lu\n", __func__, __LINE__, - tmp.dev_id); - } - pr_debug(" <- %s:%u: dev not found\n", __func__, __LINE__); - return result; - -found_dev: - result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index, - &tmp.dev_type); - if (result) { - pr_debug("%s:%u read_dev_type failed\n", __func__, __LINE__); - return result; - } + pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %u\n", + __func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id); - pr_debug(" <- %s:%u: found: type (%u:%u) index (%u:%u) id (%lu:%lu)\n", - __func__, __LINE__, tmp.bus_type, tmp.dev_type, tmp.bus_index, - tmp.dev_index, tmp.bus_id, tmp.dev_id); *repo = tmp; return 0; } @@ -445,34 +402,50 @@ int __devinit ps3_repository_find_devices(enum ps3_bus_type bus_type, pr_debug(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type); - repo.bus_type = bus_type; - result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index); - if (result) { - pr_debug(" <- %s:%u: bus not found\n", __func__, __LINE__); - return result; - } + for (repo.bus_index = 0; repo.bus_index < 10; repo.bus_index++) { - result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id); - if (result) { - pr_debug("%s:%d read_bus_id(%u) failed\n", __func__, __LINE__, - repo.bus_index); - return result; - } + result = ps3_repository_read_bus_type(repo.bus_index, + &repo.bus_type); - for (repo.dev_index = 0; ; repo.dev_index++) { - result = ps3_repository_find_device(&repo); - if (result == -ENODEV) { - result = 0; - break; - } else if (result) + if (result) { + pr_debug("%s:%d read_bus_type(%u) failed\n", + __func__, __LINE__, repo.bus_index); break; + } + + if (repo.bus_type != bus_type) { + pr_debug("%s:%d: skip, bus_type %u\n", __func__, + __LINE__, repo.bus_type); + continue; + } + + result = ps3_repository_read_bus_id(repo.bus_index, + &repo.bus_id); - result = callback(&repo); if (result) { - pr_debug("%s:%d: abort at callback\n", __func__, - __LINE__); - break; + pr_debug("%s:%d read_bus_id(%u) failed\n", + __func__, __LINE__, repo.bus_index); + continue; } + + for (repo.dev_index = 0; ; repo.dev_index++) { + result = ps3_repository_find_device(&repo); + + if (result == -ENODEV) { + result = 0; + break; + } else if (result) + break; + + result = callback(&repo); + + if (result) { + pr_debug("%s:%d: abort at callback\n", __func__, + __LINE__); + break; + } + } + break; } pr_debug(" <- %s:%d\n", __func__, __LINE__); @@ -588,7 +561,7 @@ int ps3_repository_read_stor_dev_port(unsigned int bus_index, make_first_field("bus", bus_index), make_field("dev", dev_index), make_field("port", 0), - 0, port, NULL); + 0, port, 0); } int ps3_repository_read_stor_dev_blk_size(unsigned int bus_index, @@ -598,7 +571,7 @@ int ps3_repository_read_stor_dev_blk_size(unsigned int bus_index, make_first_field("bus", bus_index), make_field("dev", dev_index), make_field("blk_size", 0), - 0, blk_size, NULL); + 0, blk_size, 0); } int ps3_repository_read_stor_dev_num_blocks(unsigned int bus_index, @@ -608,7 +581,7 @@ int ps3_repository_read_stor_dev_num_blocks(unsigned int bus_index, make_first_field("bus", bus_index), make_field("dev", dev_index), make_field("n_blocks", 0), - 0, num_blocks, NULL); + 0, num_blocks, 0); } int ps3_repository_read_stor_dev_num_regions(unsigned int bus_index, @@ -621,7 +594,7 @@ int ps3_repository_read_stor_dev_num_regions(unsigned int bus_index, make_first_field("bus", bus_index), make_field("dev", dev_index), make_field("n_regs", 0), - 0, &v1, NULL); + 0, &v1, 0); *num_regions = v1; return result; } @@ -638,7 +611,7 @@ int ps3_repository_read_stor_dev_region_id(unsigned int bus_index, make_field("dev", dev_index), make_field("region", region_index), make_field("id", 0), - &v1, NULL); + &v1, 0); *region_id = v1; return result; } @@ -651,7 +624,7 @@ int ps3_repository_read_stor_dev_region_size(unsigned int bus_index, make_field("dev", dev_index), make_field("region", region_index), make_field("size", 0), - region_size, NULL); + region_size, 0); } int ps3_repository_read_stor_dev_region_start(unsigned int bus_index, @@ -662,7 +635,7 @@ int ps3_repository_read_stor_dev_region_start(unsigned int bus_index, make_field("dev", dev_index), make_field("region", region_index), make_field("start", 0), - region_start, NULL); + region_start, 0); } int ps3_repository_read_stor_dev_info(unsigned int bus_index, @@ -711,35 +684,6 @@ int ps3_repository_read_stor_dev_region(unsigned int bus_index, return result; } -/** - * ps3_repository_read_num_pu - Number of logical PU processors for this lpar. - */ - -int ps3_repository_read_num_pu(u64 *num_pu) -{ - *num_pu = 0; - return read_node(PS3_LPAR_ID_CURRENT, - make_first_field("bi", 0), - make_field("pun", 0), - 0, 0, - num_pu, NULL); -} - -/** - * ps3_repository_read_pu_id - Read the logical PU id. - * @pu_index: Zero based index. - * @pu_id: The logical PU id. - */ - -int ps3_repository_read_pu_id(unsigned int pu_index, u64 *pu_id) -{ - return read_node(PS3_LPAR_ID_CURRENT, - make_first_field("bi", 0), - make_field("pu", pu_index), - 0, 0, - pu_id, NULL); -} - int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size) { return read_node(PS3_LPAR_ID_CURRENT, @@ -747,7 +691,7 @@ int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size) make_field("pu", 0), ppe_id, make_field("rm_size", 0), - rm_size, NULL); + rm_size, 0); } int ps3_repository_read_region_total(u64 *region_total) @@ -756,7 +700,7 @@ int ps3_repository_read_region_total(u64 *region_total) make_first_field("bi", 0), make_field("rgntotal", 0), 0, 0, - region_total, NULL); + region_total, 0); } /** @@ -792,7 +736,7 @@ int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved) make_first_field("bi", 0), make_field("spun", 0), 0, 0, - &v1, NULL); + &v1, 0); *num_spu_reserved = v1; return result; } @@ -811,7 +755,7 @@ int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id) make_first_field("bi", 0), make_field("spursvn", 0), 0, 0, - &v1, NULL); + &v1, 0); *num_resource_id = v1; return result; } @@ -824,7 +768,7 @@ int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id) */ int ps3_repository_read_spu_resource_id(unsigned int res_index, - enum ps3_spu_resource_type *resource_type, unsigned int *resource_id) + enum ps3_spu_resource_type* resource_type, unsigned int *resource_id) { int result; u64 v1; @@ -841,14 +785,14 @@ int ps3_repository_read_spu_resource_id(unsigned int res_index, return result; } -static int ps3_repository_read_boot_dat_address(u64 *address) +int ps3_repository_read_boot_dat_address(u64 *address) { return read_node(PS3_LPAR_ID_CURRENT, make_first_field("bi", 0), make_field("boot_dat", 0), make_field("address", 0), 0, - address, NULL); + address, 0); } int ps3_repository_read_boot_dat_size(unsigned int *size) @@ -861,7 +805,7 @@ int ps3_repository_read_boot_dat_size(unsigned int *size) make_field("boot_dat", 0), make_field("size", 0), 0, - &v1, NULL); + &v1, 0); *size = v1; return result; } @@ -876,7 +820,7 @@ int ps3_repository_read_vuart_av_port(unsigned int *port) make_field("vir_uart", 0), make_field("port", 0), make_field("avset", 0), - &v1, NULL); + &v1, 0); *port = v1; return result; } @@ -891,7 +835,7 @@ int ps3_repository_read_vuart_sysmgr_port(unsigned int *port) make_field("vir_uart", 0), make_field("port", 0), make_field("sysmgr", 0), - &v1, NULL); + &v1, 0); *port = v1; return result; } @@ -912,10 +856,6 @@ int ps3_repository_read_boot_dat_info(u64 *lpar_addr, unsigned int *size) : ps3_repository_read_boot_dat_size(size); } -/** - * ps3_repository_read_num_be - Number of physical BE processors in the system. - */ - int ps3_repository_read_num_be(unsigned int *num_be) { int result; @@ -926,17 +866,11 @@ int ps3_repository_read_num_be(unsigned int *num_be) 0, 0, 0, - &v1, NULL); + &v1, 0); *num_be = v1; return result; } -/** - * ps3_repository_read_be_node_id - Read the physical BE processor node id. - * @be_index: Zero based index. - * @node_id: The BE processor node id. - */ - int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id) { return read_node(PS3_LPAR_ID_PME, @@ -944,23 +878,7 @@ int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id) 0, 0, 0, - node_id, NULL); -} - -/** - * ps3_repository_read_be_id - Read the physical BE processor id. - * @node_id: The BE processor node id. - * @be_id: The BE processor id. - */ - -int ps3_repository_read_be_id(u64 node_id, u64 *be_id) -{ - return read_node(PS3_LPAR_ID_PME, - make_first_field("be", 0), - node_id, - 0, - 0, - be_id, NULL); + node_id, 0); } int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq) @@ -970,7 +888,7 @@ int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq) node_id, make_field("clock", 0), 0, - tb_freq, NULL); + tb_freq, 0); } int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq) @@ -979,29 +897,11 @@ int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq) u64 node_id; *tb_freq = 0; - result = ps3_repository_read_be_node_id(be_index, &node_id); + result = ps3_repository_read_be_node_id(0, &node_id); return result ? result : ps3_repository_read_tb_freq(node_id, tb_freq); } -int ps3_repository_read_lpm_privileges(unsigned int be_index, u64 *lpar, - u64 *rights) -{ - int result; - u64 node_id; - - *lpar = 0; - *rights = 0; - result = ps3_repository_read_be_node_id(be_index, &node_id); - return result ? result - : read_node(PS3_LPAR_ID_PME, - make_first_field("be", 0), - node_id, - make_field("lpm", 0), - make_field("priv", 0), - lpar, rights); -} - #if defined(DEBUG) int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo) @@ -1134,7 +1034,7 @@ static int dump_device_info(struct ps3_repository_device *repo, continue; } - pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %lu\n", __func__, + pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %u\n", __func__, __LINE__, repo->bus_index, repo->dev_index, repo->dev_type, repo->dev_id); @@ -1191,7 +1091,7 @@ int ps3_repository_dump_bus_info(void) continue; } - pr_debug("%s:%d bus_%u: bus_type %u, bus_id %lu, num_dev %u\n", + pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n", __func__, __LINE__, repo.bus_index, repo.bus_type, repo.bus_id, num_dev); diff --git a/trunk/arch/powerpc/platforms/ps3/system-bus.c b/trunk/arch/powerpc/platforms/ps3/system-bus.c index 43c493fca2d0..6405f4a36763 100644 --- a/trunk/arch/powerpc/platforms/ps3/system-bus.c +++ b/trunk/arch/powerpc/platforms/ps3/system-bus.c @@ -42,8 +42,8 @@ struct { int gpu; } static usage_hack; -static int ps3_is_device(struct ps3_system_bus_device *dev, u64 bus_id, - u64 dev_id) +static int ps3_is_device(struct ps3_system_bus_device *dev, + unsigned int bus_id, unsigned int dev_id) { return dev->bus_id == bus_id && dev->dev_id == dev_id; } @@ -182,8 +182,8 @@ int ps3_open_hv_device(struct ps3_system_bus_device *dev) case PS3_MATCH_ID_SYSTEM_MANAGER: pr_debug("%s:%d: unsupported match_id: %u\n", __func__, __LINE__, dev->match_id); - pr_debug("%s:%d: bus_id: %lu\n", __func__, __LINE__, - dev->bus_id); + pr_debug("%s:%d: bus_id: %u\n", __func__, + __LINE__, dev->bus_id); BUG(); return -EINVAL; @@ -220,8 +220,8 @@ int ps3_close_hv_device(struct ps3_system_bus_device *dev) case PS3_MATCH_ID_SYSTEM_MANAGER: pr_debug("%s:%d: unsupported match_id: %u\n", __func__, __LINE__, dev->match_id); - pr_debug("%s:%d: bus_id: %lu\n", __func__, __LINE__, - dev->bus_id); + pr_debug("%s:%d: bus_id: %u\n", __func__, + __LINE__, dev->bus_id); BUG(); return -EINVAL; @@ -240,7 +240,7 @@ EXPORT_SYMBOL_GPL(ps3_close_hv_device); static void _dump_mmio_region(const struct ps3_mmio_region* r, const char* func, int line) { - pr_debug("%s:%d: dev %lu:%lu\n", func, line, r->dev->bus_id, + pr_debug("%s:%d: dev %u:%u\n", func, line, r->dev->bus_id, r->dev->dev_id); pr_debug("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr); pr_debug("%s:%d: len %lxh\n", func, line, r->len); @@ -715,7 +715,6 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev) static unsigned int dev_ioc0_count; static unsigned int dev_sb_count; static unsigned int dev_vuart_count; - static unsigned int dev_lpm_count; if (!dev->core.parent) dev->core.parent = &ps3_system_bus; @@ -738,10 +737,6 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev) snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "vuart_%02x", ++dev_vuart_count); break; - case PS3_DEVICE_TYPE_LPM: - snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), - "lpm_%02x", ++dev_lpm_count); - break; default: BUG(); }; diff --git a/trunk/arch/powerpc/xmon/setjmp.S b/trunk/arch/powerpc/xmon/setjmp.S index 04c0b305ad4a..96a91f10e2ec 100644 --- a/trunk/arch/powerpc/xmon/setjmp.S +++ b/trunk/arch/powerpc/xmon/setjmp.S @@ -12,6 +12,67 @@ #include #include +_GLOBAL(xmon_setjmp) + mflr r0 + PPC_STL r0,0(r3) + PPC_STL r1,SZL(r3) + PPC_STL r2,2*SZL(r3) + mfcr r0 + PPC_STL r0,3*SZL(r3) + PPC_STL r13,4*SZL(r3) + PPC_STL r14,5*SZL(r3) + PPC_STL r15,6*SZL(r3) + PPC_STL r16,7*SZL(r3) + PPC_STL r17,8*SZL(r3) + PPC_STL r18,9*SZL(r3) + PPC_STL r19,10*SZL(r3) + PPC_STL r20,11*SZL(r3) + PPC_STL r21,12*SZL(r3) + PPC_STL r22,13*SZL(r3) + PPC_STL r23,14*SZL(r3) + PPC_STL r24,15*SZL(r3) + PPC_STL r25,16*SZL(r3) + PPC_STL r26,17*SZL(r3) + PPC_STL r27,18*SZL(r3) + PPC_STL r28,19*SZL(r3) + PPC_STL r29,20*SZL(r3) + PPC_STL r30,21*SZL(r3) + PPC_STL r31,22*SZL(r3) + li r3,0 + blr + +_GLOBAL(xmon_longjmp) + PPC_LCMPI r4,0 + bne 1f + li r4,1 +1: PPC_LL r13,4*SZL(r3) + PPC_LL r14,5*SZL(r3) + PPC_LL r15,6*SZL(r3) + PPC_LL r16,7*SZL(r3) + PPC_LL r17,8*SZL(r3) + PPC_LL r18,9*SZL(r3) + PPC_LL r19,10*SZL(r3) + PPC_LL r20,11*SZL(r3) + PPC_LL r21,12*SZL(r3) + PPC_LL r22,13*SZL(r3) + PPC_LL r23,14*SZL(r3) + PPC_LL r24,15*SZL(r3) + PPC_LL r25,16*SZL(r3) + PPC_LL r26,17*SZL(r3) + PPC_LL r27,18*SZL(r3) + PPC_LL r28,19*SZL(r3) + PPC_LL r29,20*SZL(r3) + PPC_LL r30,21*SZL(r3) + PPC_LL r31,22*SZL(r3) + PPC_LL r0,3*SZL(r3) + mtcrf 0x38,r0 + PPC_LL r0,0(r3) + PPC_LL r1,SZL(r3) + PPC_LL r2,2*SZL(r3) + mtlr r0 + mr r3,r4 + blr + /* * Grab the register values as they are now. * This won't do a particularily good job because we really diff --git a/trunk/arch/powerpc/xmon/xmon.c b/trunk/arch/powerpc/xmon/xmon.c index a34172ddc468..865e36751f21 100644 --- a/trunk/arch/powerpc/xmon/xmon.c +++ b/trunk/arch/powerpc/xmon/xmon.c @@ -40,7 +40,6 @@ #include #include #include -#include #ifdef CONFIG_PPC64 #include @@ -72,9 +71,12 @@ static unsigned long ncsum = 4096; static int termch; static char tmpstr[128]; +#define JMP_BUF_LEN 23 static long bus_error_jmp[JMP_BUF_LEN]; static int catch_memory_errors; static long *xmon_fault_jmp[NR_CPUS]; +#define setjmp xmon_setjmp +#define longjmp xmon_longjmp /* Breakpoint stuff */ struct bpt { @@ -160,6 +162,8 @@ int xmon_no_auto_backtrace; extern void xmon_enter(void); extern void xmon_leave(void); +extern long setjmp(long *); +extern void longjmp(long *, long); extern void xmon_save_regs(struct pt_regs *); #ifdef CONFIG_PPC64 diff --git a/trunk/drivers/net/ps3_gelic_net.c b/trunk/drivers/net/ps3_gelic_net.c index 055af081e027..0a42bf517465 100644 --- a/trunk/drivers/net/ps3_gelic_net.c +++ b/trunk/drivers/net/ps3_gelic_net.c @@ -58,11 +58,11 @@ static inline struct device *ctodev(struct gelic_net_card *card) { return &card->dev->core; } -static inline u64 bus_id(struct gelic_net_card *card) +static inline unsigned int bus_id(struct gelic_net_card *card) { return card->dev->bus_id; } -static inline u64 dev_id(struct gelic_net_card *card) +static inline unsigned int dev_id(struct gelic_net_card *card) { return card->dev->dev_id; } diff --git a/trunk/drivers/ps3/Makefile b/trunk/drivers/ps3/Makefile index ccea15c11c19..1f5a2d33bf5b 100644 --- a/trunk/drivers/ps3/Makefile +++ b/trunk/drivers/ps3/Makefile @@ -4,4 +4,3 @@ ps3av_mod-objs += ps3av.o ps3av_cmd.o obj-$(CONFIG_PPC_PS3) += sys-manager-core.o obj-$(CONFIG_PS3_SYS_MANAGER) += ps3-sys-manager.o obj-$(CONFIG_PS3_STORAGE) += ps3stor_lib.o -obj-$(CONFIG_PS3_LPM) += ps3-lpm.o diff --git a/trunk/drivers/ps3/ps3-lpm.c b/trunk/drivers/ps3/ps3-lpm.c deleted file mode 100644 index 4c066545d176..000000000000 --- a/trunk/drivers/ps3/ps3-lpm.c +++ /dev/null @@ -1,1248 +0,0 @@ -/* - * PS3 Logical Performance Monitor. - * - * Copyright (C) 2007 Sony Computer Entertainment Inc. - * Copyright 2007 Sony 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; version 2 of the License. - * - * 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 - - -/* BOOKMARK tag macros */ -#define PS3_PM_BOOKMARK_START 0x8000000000000000ULL -#define PS3_PM_BOOKMARK_STOP 0x4000000000000000ULL -#define PS3_PM_BOOKMARK_TAG_KERNEL 0x1000000000000000ULL -#define PS3_PM_BOOKMARK_TAG_USER 0x3000000000000000ULL -#define PS3_PM_BOOKMARK_TAG_MASK_HI 0xF000000000000000ULL -#define PS3_PM_BOOKMARK_TAG_MASK_LO 0x0F00000000000000ULL - -/* CBE PM CONTROL register macros */ -#define PS3_PM_CONTROL_PPU_TH0_BOOKMARK 0x00001000 -#define PS3_PM_CONTROL_PPU_TH1_BOOKMARK 0x00000800 -#define PS3_PM_CONTROL_PPU_COUNT_MODE_MASK 0x000C0000 -#define PS3_PM_CONTROL_PPU_COUNT_MODE_PROBLEM 0x00080000 -#define PS3_WRITE_PM_MASK 0xFFFFFFFFFFFFFFFFULL - -/* CBE PM START STOP register macros */ -#define PS3_PM_START_STOP_PPU_TH0_BOOKMARK_START 0x02000000 -#define PS3_PM_START_STOP_PPU_TH1_BOOKMARK_START 0x01000000 -#define PS3_PM_START_STOP_PPU_TH0_BOOKMARK_STOP 0x00020000 -#define PS3_PM_START_STOP_PPU_TH1_BOOKMARK_STOP 0x00010000 -#define PS3_PM_START_STOP_START_MASK 0xFF000000 -#define PS3_PM_START_STOP_STOP_MASK 0x00FF0000 - -/* CBE PM COUNTER register macres */ -#define PS3_PM_COUNTER_MASK_HI 0xFFFFFFFF00000000ULL -#define PS3_PM_COUNTER_MASK_LO 0x00000000FFFFFFFFULL - -/* BASE SIGNAL GROUP NUMBER macros */ -#define PM_ISLAND2_BASE_SIGNAL_GROUP_NUMBER 0 -#define PM_ISLAND2_SIGNAL_GROUP_NUMBER1 6 -#define PM_ISLAND2_SIGNAL_GROUP_NUMBER2 7 -#define PM_ISLAND3_BASE_SIGNAL_GROUP_NUMBER 7 -#define PM_ISLAND4_BASE_SIGNAL_GROUP_NUMBER 15 -#define PM_SPU_TRIGGER_SIGNAL_GROUP_NUMBER 17 -#define PM_SPU_EVENT_SIGNAL_GROUP_NUMBER 18 -#define PM_ISLAND5_BASE_SIGNAL_GROUP_NUMBER 18 -#define PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER 24 -#define PM_ISLAND7_BASE_SIGNAL_GROUP_NUMBER 49 -#define PM_ISLAND8_BASE_SIGNAL_GROUP_NUMBER 52 -#define PM_SIG_GROUP_SPU 41 -#define PM_SIG_GROUP_SPU_TRIGGER 42 -#define PM_SIG_GROUP_SPU_EVENT 43 -#define PM_SIG_GROUP_MFC_MAX 60 - -/** - * struct ps3_lpm_shadow_regs - Performance monitor shadow registers. - * - * @pm_control: Shadow of the processor's pm_control register. - * @pm_start_stop: Shadow of the processor's pm_start_stop register. - * @pm_interval: Shadow of the processor's pm_interval register. - * @group_control: Shadow of the processor's group_control register. - * @debug_bus_control: Shadow of the processor's debug_bus_control register. - * - * The logical performance monitor provides a write-only interface to - * these processor registers. These shadow variables cache the processor - * register values for reading. - * - * The initial value of the shadow registers at lpm creation is - * PS3_LPM_SHADOW_REG_INIT. - */ - -struct ps3_lpm_shadow_regs { - u64 pm_control; - u64 pm_start_stop; - u64 pm_interval; - u64 group_control; - u64 debug_bus_control; -}; - -#define PS3_LPM_SHADOW_REG_INIT 0xFFFFFFFF00000000ULL - -/** - * struct ps3_lpm_priv - Private lpm device data. - * - * @open: An atomic variable indicating the lpm driver has been opened. - * @rights: The lpm rigths granted by the system policy module. A logical - * OR of enum ps3_lpm_rights. - * @node_id: The node id of a BE prosessor whose performance monitor this - * lpar has the right to use. - * @pu_id: The lv1 id of the logical PU. - * @lpm_id: The lv1 id of this lpm instance. - * @outlet_id: The outlet created by lv1 for this lpm instance. - * @tb_count: The number of bytes of data held in the lv1 trace buffer. - * @tb_cache: Kernel buffer to receive the data from the lv1 trace buffer. - * Must be 128 byte aligned. - * @tb_cache_size: Size of the kernel @tb_cache buffer. Must be 128 byte - * aligned. - * @tb_cache_internal: An unaligned buffer allocated by this driver to be - * used for the trace buffer cache when ps3_lpm_open() is called with a - * NULL tb_cache argument. Otherwise unused. - * @shadow: Processor register shadow of type struct ps3_lpm_shadow_regs. - * @sbd: The struct ps3_system_bus_device attached to this driver. - * - * The trace buffer is a buffer allocated and used internally to the lv1 - * hypervisor to collect trace data. The trace buffer cache is a guest - * buffer that accepts the trace data from the trace buffer. - */ - -struct ps3_lpm_priv { - atomic_t open; - u64 rights; - u64 node_id; - u64 pu_id; - u64 lpm_id; - u64 outlet_id; - u64 tb_count; - void *tb_cache; - u64 tb_cache_size; - void *tb_cache_internal; - struct ps3_lpm_shadow_regs shadow; - struct ps3_system_bus_device *sbd; -}; - -enum { - PS3_LPM_DEFAULT_TB_CACHE_SIZE = 0x4000, -}; - -/** - * lpm_priv - Static instance of the lpm data. - * - * Since the exported routines don't support the notion of a device - * instance we need to hold the instance in this static variable - * and then only allow at most one instance at a time to be created. - */ - -static struct ps3_lpm_priv *lpm_priv; - -static struct device *sbd_core(void) -{ - BUG_ON(!lpm_priv || !lpm_priv->sbd); - return &lpm_priv->sbd->core; -} - -/** - * use_start_stop_bookmark - Enable the PPU bookmark trace. - * - * And it enables PPU bookmark triggers ONLY if the other triggers are not set. - * The start/stop bookmarks are inserted at ps3_enable_pm() and ps3_disable_pm() - * to start/stop LPM. - * - * Used to get good quality of the performance counter. - */ - -enum {use_start_stop_bookmark = 1,}; - -void ps3_set_bookmark(u64 bookmark) -{ - /* - * As per the PPE book IV, to avoid bookmark loss there must - * not be a traced branch within 10 cycles of setting the - * SPRN_BKMK register. The actual text is unclear if 'within' - * includes cycles before the call. - */ - - asm volatile("or 29, 29, 29;"); /* db10cyc */ - mtspr(SPRN_BKMK, bookmark); - asm volatile("or 29, 29, 29;"); /* db10cyc */ -} -EXPORT_SYMBOL_GPL(ps3_set_bookmark); - -void ps3_set_pm_bookmark(u64 tag, u64 incident, u64 th_id) -{ - u64 bookmark; - - bookmark = (get_tb() & 0x00000000FFFFFFFFULL) | - PS3_PM_BOOKMARK_TAG_KERNEL; - bookmark = ((tag << 56) & PS3_PM_BOOKMARK_TAG_MASK_LO) | - (incident << 48) | (th_id << 32) | bookmark; - ps3_set_bookmark(bookmark); -} -EXPORT_SYMBOL_GPL(ps3_set_pm_bookmark); - -/** - * ps3_read_phys_ctr - Read physical counter registers. - * - * Each physical counter can act as one 32 bit counter or as two 16 bit - * counters. - */ - -u32 ps3_read_phys_ctr(u32 cpu, u32 phys_ctr) -{ - int result; - u64 counter0415; - u64 counter2637; - - if (phys_ctr >= NR_PHYS_CTRS) { - dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__, - __LINE__, phys_ctr); - return 0; - } - - result = lv1_set_lpm_counter(lpm_priv->lpm_id, 0, 0, 0, 0, &counter0415, - &counter2637); - if (result) { - dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter failed: " - "phys_ctr %u, %s\n", __func__, __LINE__, phys_ctr, - ps3_result(result)); - return 0; - } - - switch (phys_ctr) { - case 0: - return counter0415 >> 32; - case 1: - return counter0415 & PS3_PM_COUNTER_MASK_LO; - case 2: - return counter2637 >> 32; - case 3: - return counter2637 & PS3_PM_COUNTER_MASK_LO; - default: - BUG(); - } - return 0; -} -EXPORT_SYMBOL_GPL(ps3_read_phys_ctr); - -/** - * ps3_write_phys_ctr - Write physical counter registers. - * - * Each physical counter can act as one 32 bit counter or as two 16 bit - * counters. - */ - -void ps3_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val) -{ - u64 counter0415; - u64 counter0415_mask; - u64 counter2637; - u64 counter2637_mask; - int result; - - if (phys_ctr >= NR_PHYS_CTRS) { - dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__, - __LINE__, phys_ctr); - return; - } - - switch (phys_ctr) { - case 0: - counter0415 = (u64)val << 32; - counter0415_mask = PS3_PM_COUNTER_MASK_HI; - counter2637 = 0x0; - counter2637_mask = 0x0; - break; - case 1: - counter0415 = (u64)val; - counter0415_mask = PS3_PM_COUNTER_MASK_LO; - counter2637 = 0x0; - counter2637_mask = 0x0; - break; - case 2: - counter0415 = 0x0; - counter0415_mask = 0x0; - counter2637 = (u64)val << 32; - counter2637_mask = PS3_PM_COUNTER_MASK_HI; - break; - case 3: - counter0415 = 0x0; - counter0415_mask = 0x0; - counter2637 = (u64)val; - counter2637_mask = PS3_PM_COUNTER_MASK_LO; - break; - default: - BUG(); - } - - result = lv1_set_lpm_counter(lpm_priv->lpm_id, - counter0415, counter0415_mask, - counter2637, counter2637_mask, - &counter0415, &counter2637); - if (result) - dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter failed: " - "phys_ctr %u, val %u, %s\n", __func__, __LINE__, - phys_ctr, val, ps3_result(result)); -} -EXPORT_SYMBOL_GPL(ps3_write_phys_ctr); - -/** - * ps3_read_ctr - Read counter. - * - * Read 16 or 32 bits depending on the current size of the counter. - * Counters 4, 5, 6 & 7 are always 16 bit. - */ - -u32 ps3_read_ctr(u32 cpu, u32 ctr) -{ - u32 val; - u32 phys_ctr = ctr & (NR_PHYS_CTRS - 1); - - val = ps3_read_phys_ctr(cpu, phys_ctr); - - if (ps3_get_ctr_size(cpu, phys_ctr) == 16) - val = (ctr < NR_PHYS_CTRS) ? (val >> 16) : (val & 0xffff); - - return val; -} -EXPORT_SYMBOL_GPL(ps3_read_ctr); - -/** - * ps3_write_ctr - Write counter. - * - * Write 16 or 32 bits depending on the current size of the counter. - * Counters 4, 5, 6 & 7 are always 16 bit. - */ - -void ps3_write_ctr(u32 cpu, u32 ctr, u32 val) -{ - u32 phys_ctr; - u32 phys_val; - - phys_ctr = ctr & (NR_PHYS_CTRS - 1); - - if (ps3_get_ctr_size(cpu, phys_ctr) == 16) { - phys_val = ps3_read_phys_ctr(cpu, phys_ctr); - - if (ctr < NR_PHYS_CTRS) - val = (val << 16) | (phys_val & 0xffff); - else - val = (val & 0xffff) | (phys_val & 0xffff0000); - } - - ps3_write_phys_ctr(cpu, phys_ctr, val); -} -EXPORT_SYMBOL_GPL(ps3_write_ctr); - -/** - * ps3_read_pm07_control - Read counter control registers. - * - * Each logical counter has a corresponding control register. - */ - -u32 ps3_read_pm07_control(u32 cpu, u32 ctr) -{ - return 0; -} -EXPORT_SYMBOL_GPL(ps3_read_pm07_control); - -/** - * ps3_write_pm07_control - Write counter control registers. - * - * Each logical counter has a corresponding control register. - */ - -void ps3_write_pm07_control(u32 cpu, u32 ctr, u32 val) -{ - int result; - static const u64 mask = 0xFFFFFFFFFFFFFFFFULL; - u64 old_value; - - if (ctr >= NR_CTRS) { - dev_dbg(sbd_core(), "%s:%u: ctr too big: %u\n", __func__, - __LINE__, ctr); - return; - } - - result = lv1_set_lpm_counter_control(lpm_priv->lpm_id, ctr, val, mask, - &old_value); - if (result) - dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter_control " - "failed: ctr %u, %s\n", __func__, __LINE__, ctr, - ps3_result(result)); -} -EXPORT_SYMBOL_GPL(ps3_write_pm07_control); - -/** - * ps3_read_pm - Read Other LPM control registers. - */ - -u32 ps3_read_pm(u32 cpu, enum pm_reg_name reg) -{ - int result = 0; - u64 val = 0; - - switch (reg) { - case pm_control: - return lpm_priv->shadow.pm_control; - case trace_address: - return CBE_PM_TRACE_BUF_EMPTY; - case pm_start_stop: - return lpm_priv->shadow.pm_start_stop; - case pm_interval: - return lpm_priv->shadow.pm_interval; - case group_control: - return lpm_priv->shadow.group_control; - case debug_bus_control: - return lpm_priv->shadow.debug_bus_control; - case pm_status: - result = lv1_get_lpm_interrupt_status(lpm_priv->lpm_id, - &val); - if (result) { - val = 0; - dev_dbg(sbd_core(), "%s:%u: lv1 get_lpm_status failed: " - "reg %u, %s\n", __func__, __LINE__, reg, - ps3_result(result)); - } - return (u32)val; - case ext_tr_timer: - return 0; - default: - dev_dbg(sbd_core(), "%s:%u: unknown reg: %d\n", __func__, - __LINE__, reg); - BUG(); - break; - } - - return 0; -} -EXPORT_SYMBOL_GPL(ps3_read_pm); - -/** - * ps3_write_pm - Write Other LPM control registers. - */ - -void ps3_write_pm(u32 cpu, enum pm_reg_name reg, u32 val) -{ - int result = 0; - u64 dummy; - - switch (reg) { - case group_control: - if (val != lpm_priv->shadow.group_control) - result = lv1_set_lpm_group_control(lpm_priv->lpm_id, - val, - PS3_WRITE_PM_MASK, - &dummy); - lpm_priv->shadow.group_control = val; - break; - case debug_bus_control: - if (val != lpm_priv->shadow.debug_bus_control) - result = lv1_set_lpm_debug_bus_control(lpm_priv->lpm_id, - val, - PS3_WRITE_PM_MASK, - &dummy); - lpm_priv->shadow.debug_bus_control = val; - break; - case pm_control: - if (use_start_stop_bookmark) - val |= (PS3_PM_CONTROL_PPU_TH0_BOOKMARK | - PS3_PM_CONTROL_PPU_TH1_BOOKMARK); - if (val != lpm_priv->shadow.pm_control) - result = lv1_set_lpm_general_control(lpm_priv->lpm_id, - val, - PS3_WRITE_PM_MASK, - 0, 0, &dummy, - &dummy); - lpm_priv->shadow.pm_control = val; - break; - case pm_interval: - if (val != lpm_priv->shadow.pm_interval) - result = lv1_set_lpm_interval(lpm_priv->lpm_id, val, - PS3_WRITE_PM_MASK, &dummy); - lpm_priv->shadow.pm_interval = val; - break; - case pm_start_stop: - if (val != lpm_priv->shadow.pm_start_stop) - result = lv1_set_lpm_trigger_control(lpm_priv->lpm_id, - val, - PS3_WRITE_PM_MASK, - &dummy); - lpm_priv->shadow.pm_start_stop = val; - break; - case trace_address: - case ext_tr_timer: - case pm_status: - break; - default: - dev_dbg(sbd_core(), "%s:%u: unknown reg: %d\n", __func__, - __LINE__, reg); - BUG(); - break; - } - - if (result) - dev_err(sbd_core(), "%s:%u: lv1 set_control failed: " - "reg %u, %s\n", __func__, __LINE__, reg, - ps3_result(result)); -} -EXPORT_SYMBOL_GPL(ps3_write_pm); - -/** - * ps3_get_ctr_size - Get the size of a physical counter. - * - * Returns either 16 or 32. - */ - -u32 ps3_get_ctr_size(u32 cpu, u32 phys_ctr) -{ - u32 pm_ctrl; - - if (phys_ctr >= NR_PHYS_CTRS) { - dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__, - __LINE__, phys_ctr); - return 0; - } - - pm_ctrl = ps3_read_pm(cpu, pm_control); - return (pm_ctrl & CBE_PM_16BIT_CTR(phys_ctr)) ? 16 : 32; -} -EXPORT_SYMBOL_GPL(ps3_get_ctr_size); - -/** - * ps3_set_ctr_size - Set the size of a physical counter to 16 or 32 bits. - */ - -void ps3_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size) -{ - u32 pm_ctrl; - - if (phys_ctr >= NR_PHYS_CTRS) { - dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__, - __LINE__, phys_ctr); - return; - } - - pm_ctrl = ps3_read_pm(cpu, pm_control); - - switch (ctr_size) { - case 16: - pm_ctrl |= CBE_PM_16BIT_CTR(phys_ctr); - ps3_write_pm(cpu, pm_control, pm_ctrl); - break; - - case 32: - pm_ctrl &= ~CBE_PM_16BIT_CTR(phys_ctr); - ps3_write_pm(cpu, pm_control, pm_ctrl); - break; - default: - BUG(); - } -} -EXPORT_SYMBOL_GPL(ps3_set_ctr_size); - -static u64 pm_translate_signal_group_number_on_island2(u64 subgroup) -{ - - if (subgroup == 2) - subgroup = 3; - - if (subgroup <= 6) - return PM_ISLAND2_BASE_SIGNAL_GROUP_NUMBER + subgroup; - else if (subgroup == 7) - return PM_ISLAND2_SIGNAL_GROUP_NUMBER1; - else - return PM_ISLAND2_SIGNAL_GROUP_NUMBER2; -} - -static u64 pm_translate_signal_group_number_on_island3(u64 subgroup) -{ - - switch (subgroup) { - case 2: - case 3: - case 4: - subgroup += 2; - break; - case 5: - subgroup = 8; - break; - default: - break; - } - return PM_ISLAND3_BASE_SIGNAL_GROUP_NUMBER + subgroup; -} - -static u64 pm_translate_signal_group_number_on_island4(u64 subgroup) -{ - return PM_ISLAND4_BASE_SIGNAL_GROUP_NUMBER + subgroup; -} - -static u64 pm_translate_signal_group_number_on_island5(u64 subgroup) -{ - - switch (subgroup) { - case 3: - subgroup = 4; - break; - case 4: - subgroup = 6; - break; - default: - break; - } - return PM_ISLAND5_BASE_SIGNAL_GROUP_NUMBER + subgroup; -} - -static u64 pm_translate_signal_group_number_on_island6(u64 subgroup, - u64 subsubgroup) -{ - switch (subgroup) { - case 3: - case 4: - case 5: - subgroup += 1; - break; - default: - break; - } - - switch (subsubgroup) { - case 4: - case 5: - case 6: - subsubgroup += 2; - break; - case 7: - case 8: - case 9: - case 10: - subsubgroup += 4; - break; - case 11: - case 12: - case 13: - subsubgroup += 5; - break; - default: - break; - } - - if (subgroup <= 5) - return (PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER + subgroup); - else - return (PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER + subgroup - + subsubgroup - 1); -} - -static u64 pm_translate_signal_group_number_on_island7(u64 subgroup) -{ - return PM_ISLAND7_BASE_SIGNAL_GROUP_NUMBER + subgroup; -} - -static u64 pm_translate_signal_group_number_on_island8(u64 subgroup) -{ - return PM_ISLAND8_BASE_SIGNAL_GROUP_NUMBER + subgroup; -} - -static u64 pm_signal_group_to_ps3_lv1_signal_group(u64 group) -{ - u64 island; - u64 subgroup; - u64 subsubgroup; - - subgroup = 0; - subsubgroup = 0; - island = 0; - if (group < 1000) { - if (group < 100) { - if (20 <= group && group < 30) { - island = 2; - subgroup = group - 20; - } else if (30 <= group && group < 40) { - island = 3; - subgroup = group - 30; - } else if (40 <= group && group < 50) { - island = 4; - subgroup = group - 40; - } else if (50 <= group && group < 60) { - island = 5; - subgroup = group - 50; - } else if (60 <= group && group < 70) { - island = 6; - subgroup = group - 60; - } else if (70 <= group && group < 80) { - island = 7; - subgroup = group - 70; - } else if (80 <= group && group < 90) { - island = 8; - subgroup = group - 80; - } - } else if (200 <= group && group < 300) { - island = 2; - subgroup = group - 200; - } else if (600 <= group && group < 700) { - island = 6; - subgroup = 5; - subsubgroup = group - 650; - } - } else if (6000 <= group && group < 7000) { - island = 6; - subgroup = 5; - subsubgroup = group - 6500; - } - - switch (island) { - case 2: - return pm_translate_signal_group_number_on_island2(subgroup); - case 3: - return pm_translate_signal_group_number_on_island3(subgroup); - case 4: - return pm_translate_signal_group_number_on_island4(subgroup); - case 5: - return pm_translate_signal_group_number_on_island5(subgroup); - case 6: - return pm_translate_signal_group_number_on_island6(subgroup, - subsubgroup); - case 7: - return pm_translate_signal_group_number_on_island7(subgroup); - case 8: - return pm_translate_signal_group_number_on_island8(subgroup); - default: - dev_dbg(sbd_core(), "%s:%u: island not found: %lu\n", __func__, - __LINE__, group); - BUG(); - break; - } - return 0; -} - -static u64 pm_bus_word_to_ps3_lv1_bus_word(u8 word) -{ - - switch (word) { - case 1: - return 0xF000; - case 2: - return 0x0F00; - case 4: - return 0x00F0; - case 8: - default: - return 0x000F; - } -} - -static int __ps3_set_signal(u64 lv1_signal_group, u64 bus_select, - u64 signal_select, u64 attr1, u64 attr2, u64 attr3) -{ - int ret; - - ret = lv1_set_lpm_signal(lpm_priv->lpm_id, lv1_signal_group, bus_select, - signal_select, attr1, attr2, attr3); - if (ret) - dev_err(sbd_core(), - "%s:%u: error:%d 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", - __func__, __LINE__, ret, lv1_signal_group, bus_select, - signal_select, attr1, attr2, attr3); - - return ret; -} - -int ps3_set_signal(u64 signal_group, u8 signal_bit, u16 sub_unit, - u8 bus_word) -{ - int ret; - u64 lv1_signal_group; - u64 bus_select; - u64 signal_select; - u64 attr1, attr2, attr3; - - if (signal_group == 0) - return __ps3_set_signal(0, 0, 0, 0, 0, 0); - - lv1_signal_group = - pm_signal_group_to_ps3_lv1_signal_group(signal_group); - bus_select = pm_bus_word_to_ps3_lv1_bus_word(bus_word); - - switch (signal_group) { - case PM_SIG_GROUP_SPU_TRIGGER: - signal_select = 1; - signal_select = signal_select << (63 - signal_bit); - break; - case PM_SIG_GROUP_SPU_EVENT: - signal_select = 1; - signal_select = (signal_select << (63 - signal_bit)) | 0x3; - break; - default: - signal_select = 0; - break; - } - - /* - * 0: physical object. - * 1: logical object. - * This parameter is only used for the PPE and SPE signals. - */ - attr1 = 1; - - /* - * This parameter is used to specify the target physical/logical - * PPE/SPE object. - */ - if (PM_SIG_GROUP_SPU <= signal_group && - signal_group < PM_SIG_GROUP_MFC_MAX) - attr2 = sub_unit; - else - attr2 = lpm_priv->pu_id; - - /* - * This parameter is only used for setting the SPE signal. - */ - attr3 = 0; - - ret = __ps3_set_signal(lv1_signal_group, bus_select, signal_select, - attr1, attr2, attr3); - if (ret) - dev_err(sbd_core(), "%s:%u: __ps3_set_signal failed: %d\n", - __func__, __LINE__, ret); - - return ret; -} -EXPORT_SYMBOL_GPL(ps3_set_signal); - -u32 ps3_get_hw_thread_id(int cpu) -{ - return get_hard_smp_processor_id(cpu); -} -EXPORT_SYMBOL_GPL(ps3_get_hw_thread_id); - -/** - * ps3_enable_pm - Enable the entire performance monitoring unit. - * - * When we enable the LPM, all pending writes to counters get committed. - */ - -void ps3_enable_pm(u32 cpu) -{ - int result; - u64 tmp; - int insert_bookmark = 0; - - lpm_priv->tb_count = 0; - - if (use_start_stop_bookmark) { - if (!(lpm_priv->shadow.pm_start_stop & - (PS3_PM_START_STOP_START_MASK - | PS3_PM_START_STOP_STOP_MASK))) { - result = lv1_set_lpm_trigger_control(lpm_priv->lpm_id, - (PS3_PM_START_STOP_PPU_TH0_BOOKMARK_START | - PS3_PM_START_STOP_PPU_TH1_BOOKMARK_START | - PS3_PM_START_STOP_PPU_TH0_BOOKMARK_STOP | - PS3_PM_START_STOP_PPU_TH1_BOOKMARK_STOP), - 0xFFFFFFFFFFFFFFFFULL, &tmp); - - if (result) - dev_err(sbd_core(), "%s:%u: " - "lv1_set_lpm_trigger_control failed: " - "%s\n", __func__, __LINE__, - ps3_result(result)); - - insert_bookmark = !result; - } - } - - result = lv1_start_lpm(lpm_priv->lpm_id); - - if (result) - dev_err(sbd_core(), "%s:%u: lv1_start_lpm failed: %s\n", - __func__, __LINE__, ps3_result(result)); - - if (use_start_stop_bookmark && !result && insert_bookmark) - ps3_set_bookmark(get_tb() | PS3_PM_BOOKMARK_START); -} -EXPORT_SYMBOL_GPL(ps3_enable_pm); - -/** - * ps3_disable_pm - Disable the entire performance monitoring unit. - */ - -void ps3_disable_pm(u32 cpu) -{ - int result; - u64 tmp; - - ps3_set_bookmark(get_tb() | PS3_PM_BOOKMARK_STOP); - - result = lv1_stop_lpm(lpm_priv->lpm_id, &tmp); - - if (result) { - if(result != LV1_WRONG_STATE) - dev_err(sbd_core(), "%s:%u: lv1_stop_lpm failed: %s\n", - __func__, __LINE__, ps3_result(result)); - return; - } - - lpm_priv->tb_count = tmp; - - dev_dbg(sbd_core(), "%s:%u: tb_count %lu (%lxh)\n", __func__, __LINE__, - lpm_priv->tb_count, lpm_priv->tb_count); -} -EXPORT_SYMBOL_GPL(ps3_disable_pm); - -/** - * ps3_lpm_copy_tb - Copy data from the trace buffer to a kernel buffer. - * @offset: Offset in bytes from the start of the trace buffer. - * @buf: Copy destination. - * @count: Maximum count of bytes to copy. - * @bytes_copied: Pointer to a variable that will recieve the number of - * bytes copied to @buf. - * - * On error @buf will contain any successfully copied trace buffer data - * and bytes_copied will be set to the number of bytes successfully copied. - */ - -int ps3_lpm_copy_tb(unsigned long offset, void *buf, unsigned long count, - unsigned long *bytes_copied) -{ - int result; - - *bytes_copied = 0; - - if (!lpm_priv->tb_cache) - return -EPERM; - - if (offset >= lpm_priv->tb_count) - return 0; - - count = min(count, lpm_priv->tb_count - offset); - - while (*bytes_copied < count) { - const unsigned long request = count - *bytes_copied; - u64 tmp; - - result = lv1_copy_lpm_trace_buffer(lpm_priv->lpm_id, offset, - request, &tmp); - if (result) { - dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%lx\n", - __func__, __LINE__, request, offset); - - dev_err(sbd_core(), "%s:%u: lv1_copy_lpm_trace_buffer " - "failed: %s\n", __func__, __LINE__, - ps3_result(result)); - return result == LV1_WRONG_STATE ? -EBUSY : -EINVAL; - } - - memcpy(buf, lpm_priv->tb_cache, tmp); - buf += tmp; - *bytes_copied += tmp; - offset += tmp; - } - dev_dbg(sbd_core(), "%s:%u: copied %lxh bytes\n", __func__, __LINE__, - *bytes_copied); - - return 0; -} -EXPORT_SYMBOL_GPL(ps3_lpm_copy_tb); - -/** - * ps3_lpm_copy_tb_to_user - Copy data from the trace buffer to a user buffer. - * @offset: Offset in bytes from the start of the trace buffer. - * @buf: A __user copy destination. - * @count: Maximum count of bytes to copy. - * @bytes_copied: Pointer to a variable that will recieve the number of - * bytes copied to @buf. - * - * On error @buf will contain any successfully copied trace buffer data - * and bytes_copied will be set to the number of bytes successfully copied. - */ - -int ps3_lpm_copy_tb_to_user(unsigned long offset, void __user *buf, - unsigned long count, unsigned long *bytes_copied) -{ - int result; - - *bytes_copied = 0; - - if (!lpm_priv->tb_cache) - return -EPERM; - - if (offset >= lpm_priv->tb_count) - return 0; - - count = min(count, lpm_priv->tb_count - offset); - - while (*bytes_copied < count) { - const unsigned long request = count - *bytes_copied; - u64 tmp; - - result = lv1_copy_lpm_trace_buffer(lpm_priv->lpm_id, offset, - request, &tmp); - if (result) { - dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%lx\n", - __func__, __LINE__, request, offset); - dev_err(sbd_core(), "%s:%u: lv1_copy_lpm_trace_buffer " - "failed: %s\n", __func__, __LINE__, - ps3_result(result)); - return result == LV1_WRONG_STATE ? -EBUSY : -EINVAL; - } - - result = copy_to_user(buf, lpm_priv->tb_cache, tmp); - - if (result) { - dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%p\n", - __func__, __LINE__, tmp, buf); - dev_err(sbd_core(), "%s:%u: copy_to_user failed: %d\n", - __func__, __LINE__, result); - return -EFAULT; - } - - buf += tmp; - *bytes_copied += tmp; - offset += tmp; - } - dev_dbg(sbd_core(), "%s:%u: copied %lxh bytes\n", __func__, __LINE__, - *bytes_copied); - - return 0; -} -EXPORT_SYMBOL_GPL(ps3_lpm_copy_tb_to_user); - -/** - * ps3_get_and_clear_pm_interrupts - - * - * Clearing interrupts for the entire performance monitoring unit. - * Reading pm_status clears the interrupt bits. - */ - -u32 ps3_get_and_clear_pm_interrupts(u32 cpu) -{ - return ps3_read_pm(cpu, pm_status); -} -EXPORT_SYMBOL_GPL(ps3_get_and_clear_pm_interrupts); - -/** - * ps3_enable_pm_interrupts - - * - * Enabling interrupts for the entire performance monitoring unit. - * Enables the interrupt bits in the pm_status register. - */ - -void ps3_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask) -{ - if (mask) - ps3_write_pm(cpu, pm_status, mask); -} -EXPORT_SYMBOL_GPL(ps3_enable_pm_interrupts); - -/** - * ps3_enable_pm_interrupts - - * - * Disabling interrupts for the entire performance monitoring unit. - */ - -void ps3_disable_pm_interrupts(u32 cpu) -{ - ps3_get_and_clear_pm_interrupts(cpu); - ps3_write_pm(cpu, pm_status, 0); -} -EXPORT_SYMBOL_GPL(ps3_disable_pm_interrupts); - -/** - * ps3_lpm_open - Open the logical performance monitor device. - * @tb_type: Specifies the type of trace buffer lv1 sould use for this lpm - * instance, specified by one of enum ps3_lpm_tb_type. - * @tb_cache: Optional user supplied buffer to use as the trace buffer cache. - * If NULL, the driver will allocate and manage an internal buffer. - * Unused when when @tb_type is PS3_LPM_TB_TYPE_NONE. - * @tb_cache_size: The size in bytes of the user supplied @tb_cache buffer. - * Unused when @tb_cache is NULL or @tb_type is PS3_LPM_TB_TYPE_NONE. - */ - -int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache, - u64 tb_cache_size) -{ - int result; - u64 tb_size; - - BUG_ON(!lpm_priv); - BUG_ON(tb_type != PS3_LPM_TB_TYPE_NONE - && tb_type != PS3_LPM_TB_TYPE_INTERNAL); - - if (tb_type == PS3_LPM_TB_TYPE_NONE && tb_cache) - dev_dbg(sbd_core(), "%s:%u: bad in vals\n", __func__, __LINE__); - - if (!atomic_add_unless(&lpm_priv->open, 1, 1)) { - dev_dbg(sbd_core(), "%s:%u: busy\n", __func__, __LINE__); - return -EBUSY; - } - - /* Note tb_cache needs 128 byte alignment. */ - - if (tb_type == PS3_LPM_TB_TYPE_NONE) { - lpm_priv->tb_cache_size = 0; - lpm_priv->tb_cache_internal = NULL; - lpm_priv->tb_cache = NULL; - } else if (tb_cache) { - if (tb_cache != (void *)_ALIGN_UP((unsigned long)tb_cache, 128) - || tb_cache_size != _ALIGN_UP(tb_cache_size, 128)) { - dev_err(sbd_core(), "%s:%u: unaligned tb_cache\n", - __func__, __LINE__); - result = -EINVAL; - goto fail_align; - } - lpm_priv->tb_cache_size = tb_cache_size; - lpm_priv->tb_cache_internal = NULL; - lpm_priv->tb_cache = tb_cache; - } else { - lpm_priv->tb_cache_size = PS3_LPM_DEFAULT_TB_CACHE_SIZE; - lpm_priv->tb_cache_internal = kzalloc( - lpm_priv->tb_cache_size + 127, GFP_KERNEL); - if (!lpm_priv->tb_cache_internal) { - dev_err(sbd_core(), "%s:%u: alloc internal tb_cache " - "failed\n", __func__, __LINE__); - result = -ENOMEM; - goto fail_malloc; - } - lpm_priv->tb_cache = (void *)_ALIGN_UP( - (unsigned long)lpm_priv->tb_cache_internal, 128); - } - - result = lv1_construct_lpm(lpm_priv->node_id, tb_type, 0, 0, - ps3_mm_phys_to_lpar(__pa(lpm_priv->tb_cache)), - lpm_priv->tb_cache_size, &lpm_priv->lpm_id, - &lpm_priv->outlet_id, &tb_size); - - if (result) { - dev_err(sbd_core(), "%s:%u: lv1_construct_lpm failed: %s\n", - __func__, __LINE__, ps3_result(result)); - result = -EINVAL; - goto fail_construct; - } - - lpm_priv->shadow.pm_control = PS3_LPM_SHADOW_REG_INIT; - lpm_priv->shadow.pm_start_stop = PS3_LPM_SHADOW_REG_INIT; - lpm_priv->shadow.pm_interval = PS3_LPM_SHADOW_REG_INIT; - lpm_priv->shadow.group_control = PS3_LPM_SHADOW_REG_INIT; - lpm_priv->shadow.debug_bus_control = PS3_LPM_SHADOW_REG_INIT; - - dev_dbg(sbd_core(), "%s:%u: lpm_id 0x%lx, outlet_id 0x%lx, " - "tb_size 0x%lx\n", __func__, __LINE__, lpm_priv->lpm_id, - lpm_priv->outlet_id, tb_size); - - return 0; - -fail_construct: - kfree(lpm_priv->tb_cache_internal); - lpm_priv->tb_cache_internal = NULL; -fail_malloc: -fail_align: - atomic_dec(&lpm_priv->open); - return result; -} -EXPORT_SYMBOL_GPL(ps3_lpm_open); - -/** - * ps3_lpm_close - Close the lpm device. - * - */ - -int ps3_lpm_close(void) -{ - dev_dbg(sbd_core(), "%s:%u\n", __func__, __LINE__); - - lv1_destruct_lpm(lpm_priv->lpm_id); - lpm_priv->lpm_id = 0; - - kfree(lpm_priv->tb_cache_internal); - lpm_priv->tb_cache_internal = NULL; - - atomic_dec(&lpm_priv->open); - return 0; -} -EXPORT_SYMBOL_GPL(ps3_lpm_close); - -static int __devinit ps3_lpm_probe(struct ps3_system_bus_device *dev) -{ - dev_dbg(&dev->core, " -> %s:%u\n", __func__, __LINE__); - - if (lpm_priv) { - dev_info(&dev->core, "%s:%u: called twice\n", - __func__, __LINE__); - return -EBUSY; - } - - lpm_priv = kzalloc(sizeof(*lpm_priv), GFP_KERNEL); - - if (!lpm_priv) - return -ENOMEM; - - lpm_priv->sbd = dev; - lpm_priv->node_id = dev->lpm.node_id; - lpm_priv->pu_id = dev->lpm.pu_id; - lpm_priv->rights = dev->lpm.rights; - - dev_info(&dev->core, " <- %s:%u:\n", __func__, __LINE__); - - return 0; -} - -static int ps3_lpm_remove(struct ps3_system_bus_device *dev) -{ - dev_dbg(&dev->core, " -> %s:%u:\n", __func__, __LINE__); - - ps3_lpm_close(); - - kfree(lpm_priv); - lpm_priv = NULL; - - dev_info(&dev->core, " <- %s:%u:\n", __func__, __LINE__); - return 0; -} - -static struct ps3_system_bus_driver ps3_lpm_driver = { - .match_id = PS3_MATCH_ID_LPM, - .core.name = "ps3-lpm", - .core.owner = THIS_MODULE, - .probe = ps3_lpm_probe, - .remove = ps3_lpm_remove, - .shutdown = ps3_lpm_remove, -}; - -static int __init ps3_lpm_init(void) -{ - pr_debug("%s:%d:\n", __func__, __LINE__); - return ps3_system_bus_driver_register(&ps3_lpm_driver); -} - -static void __exit ps3_lpm_exit(void) -{ - pr_debug("%s:%d:\n", __func__, __LINE__); - ps3_system_bus_driver_unregister(&ps3_lpm_driver); -} - -module_init(ps3_lpm_init); -module_exit(ps3_lpm_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("PS3 Logical Performance Monitor Driver"); -MODULE_AUTHOR("Sony Corporation"); -MODULE_ALIAS(PS3_MODULE_ALIAS_LPM); diff --git a/trunk/drivers/ps3/ps3-sys-manager.c b/trunk/drivers/ps3/ps3-sys-manager.c index c3c3aba3ffce..8461b08ab9fb 100644 --- a/trunk/drivers/ps3/ps3-sys-manager.c +++ b/trunk/drivers/ps3/ps3-sys-manager.c @@ -452,7 +452,7 @@ static int ps3_sys_manager_handle_event(struct ps3_system_bus_device *dev) case PS3_SM_EVENT_THERMAL_ALERT: dev_dbg(&dev->core, "%s:%d: THERMAL_ALERT (zone %u)\n", __func__, __LINE__, event.value); - pr_info("PS3 Thermal Alert Zone %u\n", event.value); + printk(KERN_INFO "PS3 Thermal Alert Zone %u\n", event.value); break; case PS3_SM_EVENT_THERMAL_CLEARED: dev_dbg(&dev->core, "%s:%d: THERMAL_CLEARED (zone %u)\n", @@ -488,7 +488,7 @@ static int ps3_sys_manager_handle_cmd(struct ps3_system_bus_device *dev) result = ps3_vuart_read(dev, &cmd, sizeof(cmd)); BUG_ON(result && "need to retry here"); - if (result) + if(result) return result; if (cmd.version != 1) { @@ -521,7 +521,7 @@ static int ps3_sys_manager_handle_msg(struct ps3_system_bus_device *dev) result = ps3_vuart_read(dev, &header, sizeof(struct ps3_sys_manager_header)); - if (result) + if(result) return result; if (header.version != 1) { @@ -589,9 +589,9 @@ static void ps3_sys_manager_final_power_off(struct ps3_system_bus_device *dev) PS3_SM_WAKE_DEFAULT); ps3_sys_manager_send_request_shutdown(dev); - pr_emerg("System Halted, OK to turn off power\n"); + printk(KERN_EMERG "System Halted, OK to turn off power\n"); - while (1) + while(1) ps3_sys_manager_handle_msg(dev); } @@ -626,9 +626,9 @@ static void ps3_sys_manager_final_restart(struct ps3_system_bus_device *dev) PS3_SM_WAKE_DEFAULT); ps3_sys_manager_send_request_shutdown(dev); - pr_emerg("System Halted, OK to turn off power\n"); + printk(KERN_EMERG "System Halted, OK to turn off power\n"); - while (1) + while(1) ps3_sys_manager_handle_msg(dev); } diff --git a/trunk/drivers/ps3/ps3-vuart.c b/trunk/drivers/ps3/ps3-vuart.c index 90c097a7a47a..bb8d5b1eec90 100644 --- a/trunk/drivers/ps3/ps3-vuart.c +++ b/trunk/drivers/ps3/ps3-vuart.c @@ -108,18 +108,18 @@ static struct ps3_vuart_port_priv *to_port_priv( struct ports_bmp { u64 status; u64 unused[3]; -} __attribute__((aligned(32))); +} __attribute__ ((aligned (32))); #define dump_ports_bmp(_b) _dump_ports_bmp(_b, __func__, __LINE__) static void __maybe_unused _dump_ports_bmp( - const struct ports_bmp *bmp, const char *func, int line) + const struct ports_bmp* bmp, const char* func, int line) { pr_debug("%s:%d: ports_bmp: %016lxh\n", func, line, bmp->status); } #define dump_port_params(_b) _dump_port_params(_b, __func__, __LINE__) static void __maybe_unused _dump_port_params(unsigned int port_number, - const char *func, int line) + const char* func, int line) { #if defined(DEBUG) static const char *strings[] = { @@ -363,7 +363,7 @@ int ps3_vuart_disable_interrupt_disconnect(struct ps3_system_bus_device *dev) */ static int ps3_vuart_raw_write(struct ps3_system_bus_device *dev, - const void *buf, unsigned int bytes, unsigned long *bytes_written) + const void* buf, unsigned int bytes, unsigned long *bytes_written) { int result; struct ps3_vuart_port_priv *priv = to_port_priv(dev); @@ -431,7 +431,7 @@ void ps3_vuart_clear_rx_bytes(struct ps3_system_bus_device *dev, int result; struct ps3_vuart_port_priv *priv = to_port_priv(dev); u64 bytes_waiting; - void *tmp; + void* tmp; result = ps3_vuart_get_rx_bytes_waiting(dev, &bytes_waiting); @@ -526,8 +526,9 @@ int ps3_vuart_write(struct ps3_system_bus_device *dev, const void *buf, lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_KERNEL); - if (!lb) + if (!lb) { return -ENOMEM; + } memcpy(lb->data, buf, bytes); lb->head = lb->data; @@ -877,7 +878,7 @@ static int ps3_vuart_handle_port_interrupt(struct ps3_system_bus_device *dev) struct vuart_bus_priv { struct ports_bmp *bmp; unsigned int virq; - struct mutex probe_mutex; + struct semaphore probe_mutex; int use_count; struct ps3_system_bus_device *devices[PORT_COUNT]; } static vuart_bus_priv; @@ -925,8 +926,9 @@ static int ps3_vuart_bus_interrupt_get(void) BUG_ON(vuart_bus_priv.use_count > 2); - if (vuart_bus_priv.use_count != 1) + if (vuart_bus_priv.use_count != 1) { return 0; + } BUG_ON(vuart_bus_priv.bmp); @@ -1015,7 +1017,7 @@ static int ps3_vuart_probe(struct ps3_system_bus_device *dev) return -EINVAL; } - mutex_lock(&vuart_bus_priv.probe_mutex); + down(&vuart_bus_priv.probe_mutex); result = ps3_vuart_bus_interrupt_get(); @@ -1075,7 +1077,7 @@ static int ps3_vuart_probe(struct ps3_system_bus_device *dev) goto fail_probe; } - mutex_unlock(&vuart_bus_priv.probe_mutex); + up(&vuart_bus_priv.probe_mutex); return result; @@ -1088,7 +1090,7 @@ static int ps3_vuart_probe(struct ps3_system_bus_device *dev) fail_busy: ps3_vuart_bus_interrupt_put(); fail_setup_interrupt: - mutex_unlock(&vuart_bus_priv.probe_mutex); + up(&vuart_bus_priv.probe_mutex); dev_dbg(&dev->core, "%s:%d: failed\n", __func__, __LINE__); return result; } @@ -1127,7 +1129,7 @@ static int ps3_vuart_remove(struct ps3_system_bus_device *dev) BUG_ON(!dev); - mutex_lock(&vuart_bus_priv.probe_mutex); + down(&vuart_bus_priv.probe_mutex); dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__, dev->match_id); @@ -1135,7 +1137,7 @@ static int ps3_vuart_remove(struct ps3_system_bus_device *dev) if (!dev->core.driver) { dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__, __LINE__); - mutex_unlock(&vuart_bus_priv.probe_mutex); + up(&vuart_bus_priv.probe_mutex); return 0; } @@ -1158,7 +1160,7 @@ static int ps3_vuart_remove(struct ps3_system_bus_device *dev) priv = NULL; dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); - mutex_unlock(&vuart_bus_priv.probe_mutex); + up(&vuart_bus_priv.probe_mutex); return 0; } @@ -1178,7 +1180,7 @@ static int ps3_vuart_shutdown(struct ps3_system_bus_device *dev) BUG_ON(!dev); - mutex_lock(&vuart_bus_priv.probe_mutex); + down(&vuart_bus_priv.probe_mutex); dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__, dev->match_id); @@ -1186,7 +1188,7 @@ static int ps3_vuart_shutdown(struct ps3_system_bus_device *dev) if (!dev->core.driver) { dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__, __LINE__); - mutex_unlock(&vuart_bus_priv.probe_mutex); + up(&vuart_bus_priv.probe_mutex); return 0; } @@ -1210,7 +1212,7 @@ static int ps3_vuart_shutdown(struct ps3_system_bus_device *dev) dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); - mutex_unlock(&vuart_bus_priv.probe_mutex); + up(&vuart_bus_priv.probe_mutex); return 0; } @@ -1221,7 +1223,7 @@ static int __init ps3_vuart_bus_init(void) if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) return -ENODEV; - mutex_init(&vuart_bus_priv.probe_mutex); + init_MUTEX(&vuart_bus_priv.probe_mutex); return 0; } diff --git a/trunk/include/asm-powerpc/dma-mapping.h b/trunk/include/asm-powerpc/dma-mapping.h index 5eea6dbc0aa2..e974876e18d2 100644 --- a/trunk/include/asm-powerpc/dma-mapping.h +++ b/trunk/include/asm-powerpc/dma-mapping.h @@ -189,6 +189,8 @@ static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, extern struct dma_mapping_ops dma_iommu_ops; extern struct dma_mapping_ops dma_direct_ops; +extern unsigned long dma_direct_offset; + #else /* CONFIG_PPC64 */ #define dma_supported(dev, mask) (1) diff --git a/trunk/include/asm-powerpc/kexec.h b/trunk/include/asm-powerpc/kexec.h index 701857bc8e24..b6f817b8ba3d 100644 --- a/trunk/include/asm-powerpc/kexec.h +++ b/trunk/include/asm-powerpc/kexec.h @@ -123,9 +123,6 @@ struct pt_regs; extern void default_machine_kexec(struct kimage *image); extern int default_machine_kexec_prepare(struct kimage *image); extern void default_machine_crash_shutdown(struct pt_regs *regs); -typedef void (*crash_shutdown_t)(void); -extern int crash_shutdown_register(crash_shutdown_t handler); -extern int crash_shutdown_unregister(crash_shutdown_t handler); extern void machine_kexec_simple(struct kimage *image); extern void crash_kexec_secondary(struct pt_regs *regs); diff --git a/trunk/include/asm-powerpc/ps3.h b/trunk/include/asm-powerpc/ps3.h index 2b693673eff4..f577a16c6728 100644 --- a/trunk/include/asm-powerpc/ps3.h +++ b/trunk/include/asm-powerpc/ps3.h @@ -24,7 +24,6 @@ #include #include #include -#include "cell-pmu.h" union ps3_firmware_version { u64 raw; @@ -318,7 +317,6 @@ enum ps3_match_id { PS3_MATCH_ID_STOR_FLASH = 8, PS3_MATCH_ID_SOUND = 9, PS3_MATCH_ID_GRAPHICS = 10, - PS3_MATCH_ID_LPM = 11, }; #define PS3_MODULE_ALIAS_EHCI "ps3:1" @@ -331,13 +329,11 @@ enum ps3_match_id { #define PS3_MODULE_ALIAS_STOR_FLASH "ps3:8" #define PS3_MODULE_ALIAS_SOUND "ps3:9" #define PS3_MODULE_ALIAS_GRAPHICS "ps3:10" -#define PS3_MODULE_ALIAS_LPM "ps3:11" enum ps3_system_bus_device_type { PS3_DEVICE_TYPE_IOC0 = 1, PS3_DEVICE_TYPE_SB, PS3_DEVICE_TYPE_VUART, - PS3_DEVICE_TYPE_LPM, }; /** @@ -348,17 +344,12 @@ struct ps3_system_bus_device { enum ps3_match_id match_id; enum ps3_system_bus_device_type dev_type; - u64 bus_id; /* SB */ - u64 dev_id; /* SB */ + unsigned int bus_id; /* SB */ + unsigned int dev_id; /* SB */ unsigned int interrupt_id; /* SB */ struct ps3_dma_region *d_region; /* SB, IOC0 */ struct ps3_mmio_region *m_region; /* SB, IOC0*/ unsigned int port_number; /* VUART */ - struct { /* LPM */ - u64 node_id; - u64 pu_id; - u64 rights; - } lpm; /* struct iommu_table *iommu_table; -- waiting for BenH's cleanups */ struct device core; @@ -447,66 +438,5 @@ struct ps3_prealloc { extern struct ps3_prealloc ps3fb_videomemory; extern struct ps3_prealloc ps3flash_bounce_buffer; -/* logical performance monitor */ - -/** - * enum ps3_lpm_rights - Rigths granted by the system policy module. - * - * @PS3_LPM_RIGHTS_USE_LPM: The right to use the lpm. - * @PS3_LPM_RIGHTS_USE_TB: The right to use the internal trace buffer. - */ - -enum ps3_lpm_rights { - PS3_LPM_RIGHTS_USE_LPM = 0x001, - PS3_LPM_RIGHTS_USE_TB = 0x100, -}; - -/** - * enum ps3_lpm_tb_type - Type of trace buffer lv1 should use. - * - * @PS3_LPM_TB_TYPE_NONE: Do not use a trace buffer. - * @PS3_LPM_RIGHTS_USE_TB: Use the lv1 internal trace buffer. Must have - * rights @PS3_LPM_RIGHTS_USE_TB. - */ - -enum ps3_lpm_tb_type { - PS3_LPM_TB_TYPE_NONE = 0, - PS3_LPM_TB_TYPE_INTERNAL = 1, -}; - -int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache, - u64 tb_cache_size); -int ps3_lpm_close(void); -int ps3_lpm_copy_tb(unsigned long offset, void *buf, unsigned long count, - unsigned long *bytes_copied); -int ps3_lpm_copy_tb_to_user(unsigned long offset, void __user *buf, - unsigned long count, unsigned long *bytes_copied); -void ps3_set_bookmark(u64 bookmark); -void ps3_set_pm_bookmark(u64 tag, u64 incident, u64 th_id); -int ps3_set_signal(u64 rtas_signal_group, u8 signal_bit, u16 sub_unit, - u8 bus_word); - -u32 ps3_read_phys_ctr(u32 cpu, u32 phys_ctr); -void ps3_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val); -u32 ps3_read_ctr(u32 cpu, u32 ctr); -void ps3_write_ctr(u32 cpu, u32 ctr, u32 val); - -u32 ps3_read_pm07_control(u32 cpu, u32 ctr); -void ps3_write_pm07_control(u32 cpu, u32 ctr, u32 val); -u32 ps3_read_pm(u32 cpu, enum pm_reg_name reg); -void ps3_write_pm(u32 cpu, enum pm_reg_name reg, u32 val); - -u32 ps3_get_ctr_size(u32 cpu, u32 phys_ctr); -void ps3_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size); - -void ps3_enable_pm(u32 cpu); -void ps3_disable_pm(u32 cpu); -void ps3_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask); -void ps3_disable_pm_interrupts(u32 cpu); - -u32 ps3_get_and_clear_pm_interrupts(u32 cpu); -void ps3_sync_irq(int node); -u32 ps3_get_hw_thread_id(int cpu); -u64 ps3_get_spe_id(void *arg); #endif diff --git a/trunk/include/asm-powerpc/reg.h b/trunk/include/asm-powerpc/reg.h index 2408a29507e5..1f685047c6ff 100644 --- a/trunk/include/asm-powerpc/reg.h +++ b/trunk/include/asm-powerpc/reg.h @@ -553,7 +553,6 @@ #define SPRN_PA6T_BTCR 978 /* Breakpoint and Tagging Control Register */ #define SPRN_PA6T_IMAAT 979 /* Instruction Match Array Action Table */ #define SPRN_PA6T_PCCR 1019 /* Power Counter Control Register */ -#define SPRN_BKMK 1020 /* Cell Bookmark Register */ #define SPRN_PA6T_RPCCR 1021 /* Retire PC Trace Control Register */ diff --git a/trunk/include/asm-powerpc/setjmp.h b/trunk/include/asm-powerpc/setjmp.h deleted file mode 100644 index 279d03a1eec6..000000000000 --- a/trunk/include/asm-powerpc/setjmp.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright © 2008 Michael Neuling IBM Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ -#ifndef _ASM_POWERPC_SETJMP_H -#define _ASM_POWERPC_SETJMP_H - -#define JMP_BUF_LEN 23 - -extern long setjmp(long *); -extern void longjmp(long *, long); - -#endif /* _ASM_POWERPC_SETJMP_H */ diff --git a/trunk/include/asm-powerpc/sparsemem.h b/trunk/include/asm-powerpc/sparsemem.h index e8b493d52b4f..48ad807a0b8a 100644 --- a/trunk/include/asm-powerpc/sparsemem.h +++ b/trunk/include/asm-powerpc/sparsemem.h @@ -10,8 +10,13 @@ */ #define SECTION_SIZE_BITS 24 +#if defined(CONFIG_PS3_USE_LPAR_ADDR) +#define MAX_PHYSADDR_BITS 47 +#define MAX_PHYSMEM_BITS 47 +#else #define MAX_PHYSADDR_BITS 44 #define MAX_PHYSMEM_BITS 44 +#endif #ifdef CONFIG_MEMORY_HOTPLUG extern void create_section_mapping(unsigned long start, unsigned long end);