diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-07-18 22:00:54 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-18 22:00:54 +0200 |
commit | bb2c018b09b681d43f5e08124b83e362647ea82b (patch) | |
tree | d794902c78f9fdd04ed88a4b8d451ed6f9292ec0 /arch/powerpc/platforms/cell | |
parent | Merge branch 'linus' into cpus4096 (diff) | |
parent | Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/gi... (diff) | |
download | linux-bb2c018b09b681d43f5e08124b83e362647ea82b.tar.xz linux-bb2c018b09b681d43f5e08124b83e362647ea82b.zip |
Merge branch 'linus' into cpus4096
Conflicts:
drivers/acpi/processor_throttling.c
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/powerpc/platforms/cell')
-rw-r--r-- | arch/powerpc/platforms/cell/axon_msi.c | 76 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/beat_htab.c | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/iommu.c | 8 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/ras.c | 22 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spider-pic.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/context.c | 12 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/file.c | 203 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/inode.c | 47 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/sched.c | 9 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/spufs.h | 19 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/sputrace.c | 8 |
11 files changed, 295 insertions, 115 deletions
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index c39f5c225f2e..896548ba1ca1 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -14,6 +14,7 @@ #include <linux/pci.h> #include <linux/msi.h> #include <linux/of_platform.h> +#include <linux/debugfs.h> #include <asm/dcr.h> #include <asm/machdep.h> @@ -69,8 +70,19 @@ struct axon_msic { dma_addr_t fifo_phys; dcr_host_t dcr_host; u32 read_offset; +#ifdef DEBUG + u32 __iomem *trigger; +#endif }; +#ifdef DEBUG +void axon_msi_debug_setup(struct device_node *dn, struct axon_msic *msic); +#else +static inline void axon_msi_debug_setup(struct device_node *dn, + struct axon_msic *msic) { } +#endif + + static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val) { pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n); @@ -346,7 +358,14 @@ static int axon_msi_probe(struct of_device *device, goto out_free_msic; } - msic->irq_host = irq_alloc_host(of_node_get(dn), IRQ_HOST_MAP_NOMAP, + virq = irq_of_parse_and_map(dn, 0); + if (virq == NO_IRQ) { + printk(KERN_ERR "axon_msi: irq parse and map failed for %s\n", + dn->full_name); + goto out_free_fifo; + } + + msic->irq_host = irq_alloc_host(dn, IRQ_HOST_MAP_NOMAP, NR_IRQS, &msic_host_ops, 0); if (!msic->irq_host) { printk(KERN_ERR "axon_msi: couldn't allocate irq_host for %s\n", @@ -356,13 +375,6 @@ static int axon_msi_probe(struct of_device *device, msic->irq_host->host_data = msic; - virq = irq_of_parse_and_map(dn, 0); - if (virq == NO_IRQ) { - printk(KERN_ERR "axon_msi: irq parse and map failed for %s\n", - dn->full_name); - goto out_free_host; - } - set_irq_data(virq, msic); set_irq_chained_handler(virq, axon_msi_cascade); pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq); @@ -381,12 +393,12 @@ static int axon_msi_probe(struct of_device *device, ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs; ppc_md.msi_check_device = axon_msi_check_device; + axon_msi_debug_setup(dn, msic); + printk(KERN_DEBUG "axon_msi: setup MSIC on %s\n", dn->full_name); return 0; -out_free_host: - kfree(msic->irq_host); out_free_fifo: dma_free_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES, msic->fifo_virt, msic->fifo_phys); @@ -418,3 +430,47 @@ static int __init axon_msi_init(void) return of_register_platform_driver(&axon_msi_driver); } subsys_initcall(axon_msi_init); + + +#ifdef DEBUG +static int msic_set(void *data, u64 val) +{ + struct axon_msic *msic = data; + out_le32(msic->trigger, val); + return 0; +} + +static int msic_get(void *data, u64 *val) +{ + *val = 0; + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(fops_msic, msic_get, msic_set, "%llu\n"); + +void axon_msi_debug_setup(struct device_node *dn, struct axon_msic *msic) +{ + char name[8]; + u64 addr; + + addr = of_translate_address(dn, of_get_property(dn, "reg", NULL)); + if (addr == OF_BAD_ADDR) { + pr_debug("axon_msi: couldn't translate reg property\n"); + return; + } + + msic->trigger = ioremap(addr, 0x4); + if (!msic->trigger) { + pr_debug("axon_msi: ioremap failed\n"); + return; + } + + snprintf(name, sizeof(name), "msic_%d", of_node_to_nid(dn)); + + if (!debugfs_create_file(name, 0600, powerpc_debugfs_root, + msic, &fops_msic)) { + pr_debug("axon_msi: debugfs_create_file failed!\n"); + return; + } +} +#endif /* DEBUG */ diff --git a/arch/powerpc/platforms/cell/beat_htab.c b/arch/powerpc/platforms/cell/beat_htab.c index 81467ff055c8..2e67bd840e01 100644 --- a/arch/powerpc/platforms/cell/beat_htab.c +++ b/arch/powerpc/platforms/cell/beat_htab.c @@ -112,7 +112,7 @@ static long beat_lpar_hpte_insert(unsigned long hpte_group, if (!(vflags & HPTE_V_BOLTED)) DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r); - if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE)) + if (rflags & _PAGE_NO_CACHE) hpte_r &= ~_PAGE_COHERENT; spin_lock(&beat_htab_lock); @@ -334,7 +334,7 @@ static long beat_lpar_hpte_insert_v3(unsigned long hpte_group, if (!(vflags & HPTE_V_BOLTED)) DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r); - if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE)) + if (rflags & _PAGE_NO_CACHE) hpte_r &= ~_PAGE_COHERENT; /* insert into not-volted entry */ diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 45646b2b4af4..eeacb3a52ca1 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -540,7 +540,7 @@ static unsigned long cell_dma_direct_offset; static unsigned long dma_iommu_fixed_base; struct dma_mapping_ops dma_iommu_fixed_ops; -static void cell_dma_dev_setup_iommu(struct device *dev) +static struct iommu_table *cell_get_iommu_table(struct device *dev) { struct iommu_window *window; struct cbe_iommu *iommu; @@ -555,11 +555,11 @@ static void cell_dma_dev_setup_iommu(struct device *dev) printk(KERN_ERR "iommu: missing iommu for %s (node %d)\n", archdata->of_node ? archdata->of_node->full_name : "?", archdata->numa_node); - return; + return NULL; } window = list_entry(iommu->windows.next, struct iommu_window, list); - archdata->dma_data = &window->table; + return &window->table; } static void cell_dma_dev_setup_fixed(struct device *dev); @@ -572,7 +572,7 @@ static void cell_dma_dev_setup(struct device *dev) if (get_dma_ops(dev) == &dma_iommu_fixed_ops) cell_dma_dev_setup_fixed(dev); else if (get_pci_dma_ops() == &dma_iommu_ops) - cell_dma_dev_setup_iommu(dev); + archdata->dma_data = cell_get_iommu_table(dev); else if (get_pci_dma_ops() == &dma_direct_ops) archdata->dma_data = (void *)cell_dma_direct_offset; else diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c index 655704ad03cf..505f9b9bdf0c 100644 --- a/arch/powerpc/platforms/cell/ras.c +++ b/arch/powerpc/platforms/cell/ras.c @@ -17,6 +17,7 @@ #include <asm/reg.h> #include <asm/io.h> #include <asm/prom.h> +#include <asm/kexec.h> #include <asm/machdep.h> #include <asm/rtas.h> #include <asm/cell-regs.h> @@ -226,6 +227,11 @@ static int cbe_ptcal_notify_reboot(struct notifier_block *nb, return cbe_ptcal_disable(); } +static void cbe_ptcal_crash_shutdown(void) +{ + cbe_ptcal_disable(); +} + static struct notifier_block cbe_ptcal_reboot_notifier = { .notifier_call = cbe_ptcal_notify_reboot }; @@ -241,12 +247,20 @@ int __init cbe_ptcal_init(void) return -ENODEV; ret = register_reboot_notifier(&cbe_ptcal_reboot_notifier); - if (ret) { - printk(KERN_ERR "Can't disable PTCAL, so not enabling\n"); - return ret; - } + if (ret) + goto out1; + + ret = crash_shutdown_register(&cbe_ptcal_crash_shutdown); + if (ret) + goto out2; return cbe_ptcal_enable(); + +out2: + unregister_reboot_notifier(&cbe_ptcal_reboot_notifier); +out1: + printk(KERN_ERR "Can't disable PTCAL, so not enabling\n"); + return ret; } arch_initcall(cbe_ptcal_init); diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c index 3f4b4aef756d..4e5655624ae8 100644 --- a/arch/powerpc/platforms/cell/spider-pic.c +++ b/arch/powerpc/platforms/cell/spider-pic.c @@ -300,7 +300,7 @@ static void __init spider_init_one(struct device_node *of_node, int chip, panic("spider_pic: can't map registers !"); /* Allocate a host */ - pic->host = irq_alloc_host(of_node_get(of_node), IRQ_HOST_MAP_LINEAR, + pic->host = irq_alloc_host(of_node, IRQ_HOST_MAP_LINEAR, SPIDER_SRC_COUNT, &spider_host_ops, SPIDER_IRQ_INVALID); if (pic->host == NULL) diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c index 177735f79317..6653ddbed048 100644 --- a/arch/powerpc/platforms/cell/spufs/context.c +++ b/arch/powerpc/platforms/cell/spufs/context.c @@ -130,17 +130,17 @@ void spu_unmap_mappings(struct spu_context *ctx) if (ctx->local_store) unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1); if (ctx->mfc) - unmap_mapping_range(ctx->mfc, 0, 0x1000, 1); + unmap_mapping_range(ctx->mfc, 0, SPUFS_MFC_MAP_SIZE, 1); if (ctx->cntl) - unmap_mapping_range(ctx->cntl, 0, 0x1000, 1); + unmap_mapping_range(ctx->cntl, 0, SPUFS_CNTL_MAP_SIZE, 1); if (ctx->signal1) - unmap_mapping_range(ctx->signal1, 0, PAGE_SIZE, 1); + unmap_mapping_range(ctx->signal1, 0, SPUFS_SIGNAL_MAP_SIZE, 1); if (ctx->signal2) - unmap_mapping_range(ctx->signal2, 0, PAGE_SIZE, 1); + unmap_mapping_range(ctx->signal2, 0, SPUFS_SIGNAL_MAP_SIZE, 1); if (ctx->mss) - unmap_mapping_range(ctx->mss, 0, 0x1000, 1); + unmap_mapping_range(ctx->mss, 0, SPUFS_MSS_MAP_SIZE, 1); if (ctx->psmap) - unmap_mapping_range(ctx->psmap, 0, 0x20000, 1); + unmap_mapping_range(ctx->psmap, 0, SPUFS_PS_MAP_SIZE, 1); mutex_unlock(&ctx->mapping_lock); } diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index c81341ff75b5..99c73066b82f 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -238,11 +238,13 @@ spufs_mem_write(struct file *file, const char __user *buffer, return size; } -static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int +spufs_mem_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct spu_context *ctx = vma->vm_file->private_data; - unsigned long pfn, offset, addr0 = address; + unsigned long address = (unsigned long)vmf->virtual_address; + unsigned long pfn, offset; + #ifdef CONFIG_SPU_FS_64K_LS struct spu_state *csa = &ctx->csa; int psize; @@ -260,15 +262,15 @@ static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct *vma, } #endif /* CONFIG_SPU_FS_64K_LS */ - offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); + offset = vmf->pgoff << PAGE_SHIFT; if (offset >= LS_SIZE) - return NOPFN_SIGBUS; + return VM_FAULT_SIGBUS; - pr_debug("spufs_mem_mmap_nopfn address=0x%lx -> 0x%lx, offset=0x%lx\n", - addr0, address, offset); + pr_debug("spufs_mem_mmap_fault address=0x%lx, offset=0x%lx\n", + address, offset); if (spu_acquire(ctx)) - return NOPFN_REFAULT; + return VM_FAULT_NOPAGE; if (ctx->state == SPU_STATE_SAVED) { vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) @@ -283,12 +285,12 @@ static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct *vma, spu_release(ctx); - return NOPFN_REFAULT; + return VM_FAULT_NOPAGE; } static struct vm_operations_struct spufs_mem_mmap_vmops = { - .nopfn = spufs_mem_mmap_nopfn, + .fault = spufs_mem_mmap_fault, }; static int spufs_mem_mmap(struct file *file, struct vm_area_struct *vma) @@ -351,20 +353,19 @@ static const struct file_operations spufs_mem_fops = { #endif }; -static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma, - unsigned long address, +static int spufs_ps_fault(struct vm_area_struct *vma, + struct vm_fault *vmf, unsigned long ps_offs, unsigned long ps_size) { struct spu_context *ctx = vma->vm_file->private_data; - unsigned long area, offset = address - vma->vm_start; + unsigned long area, offset = vmf->pgoff << PAGE_SHIFT; int ret = 0; - spu_context_nospu_trace(spufs_ps_nopfn__enter, ctx); + spu_context_nospu_trace(spufs_ps_fault__enter, ctx); - offset += vma->vm_pgoff << PAGE_SHIFT; if (offset >= ps_size) - return NOPFN_SIGBUS; + return VM_FAULT_SIGBUS; /* * Because we release the mmap_sem, the context may be destroyed while @@ -378,7 +379,7 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma, * pages to hand out to the user, but we don't want to wait * with the mmap_sem held. * It is possible to drop the mmap_sem here, but then we need - * to return NOPFN_REFAULT because the mappings may have + * to return VM_FAULT_NOPAGE because the mappings may have * hanged. */ if (spu_acquire(ctx)) @@ -386,14 +387,15 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma, if (ctx->state == SPU_STATE_SAVED) { up_read(¤t->mm->mmap_sem); - spu_context_nospu_trace(spufs_ps_nopfn__sleep, ctx); + spu_context_nospu_trace(spufs_ps_fault__sleep, ctx); ret = spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE); - spu_context_trace(spufs_ps_nopfn__wake, ctx, ctx->spu); + spu_context_trace(spufs_ps_fault__wake, ctx, ctx->spu); down_read(¤t->mm->mmap_sem); } else { area = ctx->spu->problem_phys + ps_offs; - vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT); - spu_context_trace(spufs_ps_nopfn__insert, ctx, ctx->spu); + vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, + (area + offset) >> PAGE_SHIFT); + spu_context_trace(spufs_ps_fault__insert, ctx, ctx->spu); } if (!ret) @@ -401,18 +403,18 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma, refault: put_spu_context(ctx); - return NOPFN_REFAULT; + return VM_FAULT_NOPAGE; } #if SPUFS_MMAP_4K -static unsigned long spufs_cntl_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int spufs_cntl_mmap_fault(struct vm_area_struct *vma, + struct vm_fault *vmf) { - return spufs_ps_nopfn(vma, address, 0x4000, 0x1000); + return spufs_ps_fault(vma, vmf, 0x4000, SPUFS_CNTL_MAP_SIZE); } static struct vm_operations_struct spufs_cntl_mmap_vmops = { - .nopfn = spufs_cntl_mmap_nopfn, + .fault = spufs_cntl_mmap_fault, }; /* @@ -1097,23 +1099,23 @@ static ssize_t spufs_signal1_write(struct file *file, const char __user *buf, return 4; } -static unsigned long spufs_signal1_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int +spufs_signal1_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { -#if PAGE_SIZE == 0x1000 - return spufs_ps_nopfn(vma, address, 0x14000, 0x1000); -#elif PAGE_SIZE == 0x10000 +#if SPUFS_SIGNAL_MAP_SIZE == 0x1000 + return spufs_ps_fault(vma, vmf, 0x14000, SPUFS_SIGNAL_MAP_SIZE); +#elif SPUFS_SIGNAL_MAP_SIZE == 0x10000 /* For 64k pages, both signal1 and signal2 can be used to mmap the whole * signal 1 and 2 area */ - return spufs_ps_nopfn(vma, address, 0x10000, 0x10000); + return spufs_ps_fault(vma, vmf, 0x10000, SPUFS_SIGNAL_MAP_SIZE); #else #error unsupported page size #endif } static struct vm_operations_struct spufs_signal1_mmap_vmops = { - .nopfn = spufs_signal1_mmap_nopfn, + .fault = spufs_signal1_mmap_fault, }; static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma) @@ -1234,23 +1236,23 @@ static ssize_t spufs_signal2_write(struct file *file, const char __user *buf, } #if SPUFS_MMAP_4K -static unsigned long spufs_signal2_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int +spufs_signal2_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { -#if PAGE_SIZE == 0x1000 - return spufs_ps_nopfn(vma, address, 0x1c000, 0x1000); -#elif PAGE_SIZE == 0x10000 +#if SPUFS_SIGNAL_MAP_SIZE == 0x1000 + return spufs_ps_fault(vma, vmf, 0x1c000, SPUFS_SIGNAL_MAP_SIZE); +#elif SPUFS_SIGNAL_MAP_SIZE == 0x10000 /* For 64k pages, both signal1 and signal2 can be used to mmap the whole * signal 1 and 2 area */ - return spufs_ps_nopfn(vma, address, 0x10000, 0x10000); + return spufs_ps_fault(vma, vmf, 0x10000, SPUFS_SIGNAL_MAP_SIZE); #else #error unsupported page size #endif } static struct vm_operations_struct spufs_signal2_mmap_vmops = { - .nopfn = spufs_signal2_mmap_nopfn, + .fault = spufs_signal2_mmap_fault, }; static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma) @@ -1362,14 +1364,14 @@ DEFINE_SPUFS_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get, spufs_signal2_type_set, "%llu\n", SPU_ATTR_ACQUIRE); #if SPUFS_MMAP_4K -static unsigned long spufs_mss_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int +spufs_mss_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - return spufs_ps_nopfn(vma, address, 0x0000, 0x1000); + return spufs_ps_fault(vma, vmf, 0x0000, SPUFS_MSS_MAP_SIZE); } static struct vm_operations_struct spufs_mss_mmap_vmops = { - .nopfn = spufs_mss_mmap_nopfn, + .fault = spufs_mss_mmap_fault, }; /* @@ -1424,14 +1426,14 @@ static const struct file_operations spufs_mss_fops = { .mmap = spufs_mss_mmap, }; -static unsigned long spufs_psmap_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int +spufs_psmap_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - return spufs_ps_nopfn(vma, address, 0x0000, 0x20000); + return spufs_ps_fault(vma, vmf, 0x0000, SPUFS_PS_MAP_SIZE); } static struct vm_operations_struct spufs_psmap_mmap_vmops = { - .nopfn = spufs_psmap_mmap_nopfn, + .fault = spufs_psmap_mmap_fault, }; /* @@ -1484,14 +1486,14 @@ static const struct file_operations spufs_psmap_fops = { #if SPUFS_MMAP_4K -static unsigned long spufs_mfc_mmap_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int +spufs_mfc_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - return spufs_ps_nopfn(vma, address, 0x3000, 0x1000); + return spufs_ps_fault(vma, vmf, 0x3000, SPUFS_MFC_MAP_SIZE); } static struct vm_operations_struct spufs_mfc_mmap_vmops = { - .nopfn = spufs_mfc_mmap_nopfn, + .fault = spufs_mfc_mmap_fault, }; /* @@ -2553,22 +2555,74 @@ void spu_switch_log_notify(struct spu *spu, struct spu_context *ctx, wake_up(&ctx->switch_log->wait); } -struct tree_descr spufs_dir_contents[] = { +static int spufs_show_ctx(struct seq_file *s, void *private) +{ + struct spu_context *ctx = s->private; + u64 mfc_control_RW; + + mutex_lock(&ctx->state_mutex); + if (ctx->spu) { + struct spu *spu = ctx->spu; + struct spu_priv2 __iomem *priv2 = spu->priv2; + + spin_lock_irq(&spu->register_lock); + mfc_control_RW = in_be64(&priv2->mfc_control_RW); + spin_unlock_irq(&spu->register_lock); + } else { + struct spu_state *csa = &ctx->csa; + + mfc_control_RW = csa->priv2.mfc_control_RW; + } + + seq_printf(s, "%c flgs(%lx) sflgs(%lx) pri(%d) ts(%d) spu(%02d)" + " %c %lx %lx %lx %lx %x %x\n", + ctx->state == SPU_STATE_SAVED ? 'S' : 'R', + ctx->flags, + ctx->sched_flags, + ctx->prio, + ctx->time_slice, + ctx->spu ? ctx->spu->number : -1, + !list_empty(&ctx->rq) ? 'q' : ' ', + ctx->csa.class_0_pending, + ctx->csa.class_0_dar, + ctx->csa.class_1_dsisr, + mfc_control_RW, + ctx->ops->runcntl_read(ctx), + ctx->ops->status_read(ctx)); + + mutex_unlock(&ctx->state_mutex); + + return 0; +} + +static int spufs_ctx_open(struct inode *inode, struct file *file) +{ + return single_open(file, spufs_show_ctx, SPUFS_I(inode)->i_ctx); +} + +static const struct file_operations spufs_ctx_fops = { + .open = spufs_ctx_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +struct spufs_tree_descr spufs_dir_contents[] = { { "capabilities", &spufs_caps_fops, 0444, }, - { "mem", &spufs_mem_fops, 0666, }, - { "regs", &spufs_regs_fops, 0666, }, + { "mem", &spufs_mem_fops, 0666, LS_SIZE, }, + { "regs", &spufs_regs_fops, 0666, sizeof(struct spu_reg128[128]), }, { "mbox", &spufs_mbox_fops, 0444, }, { "ibox", &spufs_ibox_fops, 0444, }, { "wbox", &spufs_wbox_fops, 0222, }, - { "mbox_stat", &spufs_mbox_stat_fops, 0444, }, - { "ibox_stat", &spufs_ibox_stat_fops, 0444, }, - { "wbox_stat", &spufs_wbox_stat_fops, 0444, }, + { "mbox_stat", &spufs_mbox_stat_fops, 0444, sizeof(u32), }, + { "ibox_stat", &spufs_ibox_stat_fops, 0444, sizeof(u32), }, + { "wbox_stat", &spufs_wbox_stat_fops, 0444, sizeof(u32), }, { "signal1", &spufs_signal1_fops, 0666, }, { "signal2", &spufs_signal2_fops, 0666, }, { "signal1_type", &spufs_signal1_type, 0666, }, { "signal2_type", &spufs_signal2_type, 0666, }, { "cntl", &spufs_cntl_fops, 0666, }, - { "fpcr", &spufs_fpcr_fops, 0666, }, + { "fpcr", &spufs_fpcr_fops, 0666, sizeof(struct spu_reg128), }, { "lslr", &spufs_lslr_ops, 0444, }, { "mfc", &spufs_mfc_fops, 0666, }, { "mss", &spufs_mss_fops, 0666, }, @@ -2578,29 +2632,31 @@ struct tree_descr spufs_dir_contents[] = { { "decr_status", &spufs_decr_status_ops, 0666, }, { "event_mask", &spufs_event_mask_ops, 0666, }, { "event_status", &spufs_event_status_ops, 0444, }, - { "psmap", &spufs_psmap_fops, 0666, }, + { "psmap", &spufs_psmap_fops, 0666, SPUFS_PS_MAP_SIZE, }, { "phys-id", &spufs_id_ops, 0666, }, { "object-id", &spufs_object_id_ops, 0666, }, - { "mbox_info", &spufs_mbox_info_fops, 0444, }, - { "ibox_info", &spufs_ibox_info_fops, 0444, }, - { "wbox_info", &spufs_wbox_info_fops, 0444, }, - { "dma_info", &spufs_dma_info_fops, 0444, }, - { "proxydma_info", &spufs_proxydma_info_fops, 0444, }, + { "mbox_info", &spufs_mbox_info_fops, 0444, sizeof(u32), }, + { "ibox_info", &spufs_ibox_info_fops, 0444, sizeof(u32), }, + { "wbox_info", &spufs_wbox_info_fops, 0444, sizeof(u32), }, + { "dma_info", &spufs_dma_info_fops, 0444, + sizeof(struct spu_dma_info), }, + { "proxydma_info", &spufs_proxydma_info_fops, 0444, + sizeof(struct spu_proxydma_info)}, { "tid", &spufs_tid_fops, 0444, }, { "stat", &spufs_stat_fops, 0444, }, { "switch_log", &spufs_switch_log_fops, 0444 }, {}, }; -struct tree_descr spufs_dir_nosched_contents[] = { +struct spufs_tree_descr spufs_dir_nosched_contents[] = { { "capabilities", &spufs_caps_fops, 0444, }, - { "mem", &spufs_mem_fops, 0666, }, + { "mem", &spufs_mem_fops, 0666, LS_SIZE, }, { "mbox", &spufs_mbox_fops, 0444, }, { "ibox", &spufs_ibox_fops, 0444, }, { "wbox", &spufs_wbox_fops, 0222, }, - { "mbox_stat", &spufs_mbox_stat_fops, 0444, }, - { "ibox_stat", &spufs_ibox_stat_fops, 0444, }, - { "wbox_stat", &spufs_wbox_stat_fops, 0444, }, + { "mbox_stat", &spufs_mbox_stat_fops, 0444, sizeof(u32), }, + { "ibox_stat", &spufs_ibox_stat_fops, 0444, sizeof(u32), }, + { "wbox_stat", &spufs_wbox_stat_fops, 0444, sizeof(u32), }, { "signal1", &spufs_signal1_nosched_fops, 0222, }, { "signal2", &spufs_signal2_nosched_fops, 0222, }, { "signal1_type", &spufs_signal1_type, 0666, }, @@ -2609,7 +2665,7 @@ struct tree_descr spufs_dir_nosched_contents[] = { { "mfc", &spufs_mfc_fops, 0666, }, { "cntl", &spufs_cntl_fops, 0666, }, { "npc", &spufs_npc_ops, 0666, }, - { "psmap", &spufs_psmap_fops, 0666, }, + { "psmap", &spufs_psmap_fops, 0666, SPUFS_PS_MAP_SIZE, }, { "phys-id", &spufs_id_ops, 0666, }, { "object-id", &spufs_object_id_ops, 0666, }, { "tid", &spufs_tid_fops, 0444, }, @@ -2617,6 +2673,11 @@ struct tree_descr spufs_dir_nosched_contents[] = { {}, }; +struct spufs_tree_descr spufs_dir_debug_contents[] = { + { ".ctx", &spufs_ctx_fops, 0444, }, + {}, +}; + struct spufs_coredump_reader spufs_coredump_read[] = { { "regs", __spufs_regs_read, NULL, sizeof(struct spu_reg128[128])}, { "fpcr", __spufs_fpcr_read, NULL, sizeof(struct spu_reg128) }, diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index f407b2471855..7123472801d9 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -42,10 +42,19 @@ #include "spufs.h" +struct spufs_sb_info { + int debug; +}; + static struct kmem_cache *spufs_inode_cache; char *isolated_loader; static int isolated_loader_size; +static struct spufs_sb_info *spufs_get_sb_info(struct super_block *sb) +{ + return sb->s_fs_info; +} + static struct inode * spufs_alloc_inode(struct super_block *sb) { @@ -109,7 +118,7 @@ spufs_setattr(struct dentry *dentry, struct iattr *attr) static int spufs_new_file(struct super_block *sb, struct dentry *dentry, const struct file_operations *fops, int mode, - struct spu_context *ctx) + size_t size, struct spu_context *ctx) { static struct inode_operations spufs_file_iops = { .setattr = spufs_setattr, @@ -125,6 +134,7 @@ spufs_new_file(struct super_block *sb, struct dentry *dentry, ret = 0; inode->i_op = &spufs_file_iops; inode->i_fop = fops; + inode->i_size = size; inode->i_private = SPUFS_I(inode)->i_ctx = get_spu_context(ctx); d_add(dentry, inode); out: @@ -177,7 +187,7 @@ static int spufs_rmdir(struct inode *parent, struct dentry *dir) return simple_rmdir(parent, dir); } -static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files, +static int spufs_fill_dir(struct dentry *dir, struct spufs_tree_descr *files, int mode, struct spu_context *ctx) { struct dentry *dentry, *tmp; @@ -189,7 +199,7 @@ static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files, if (!dentry) goto out; ret = spufs_new_file(dir->d_sb, dentry, files->ops, - files->mode & mode, ctx); + files->mode & mode, files->size, ctx); if (ret) goto out; files++; @@ -279,6 +289,13 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags, if (ret) goto out_free_ctx; + if (spufs_get_sb_info(dir->i_sb)->debug) + ret = spufs_fill_dir(dentry, spufs_dir_debug_contents, + mode, ctx); + + if (ret) + goto out_free_ctx; + d_instantiate(dentry, inode); dget(dentry); dir->i_nlink++; @@ -639,18 +656,19 @@ out: /* File system initialization */ enum { - Opt_uid, Opt_gid, Opt_mode, Opt_err, + Opt_uid, Opt_gid, Opt_mode, Opt_debug, Opt_err, }; static match_table_t spufs_tokens = { - { Opt_uid, "uid=%d" }, - { Opt_gid, "gid=%d" }, - { Opt_mode, "mode=%o" }, - { Opt_err, NULL }, + { Opt_uid, "uid=%d" }, + { Opt_gid, "gid=%d" }, + { Opt_mode, "mode=%o" }, + { Opt_debug, "debug" }, + { Opt_err, NULL }, }; static int -spufs_parse_options(char *options, struct inode *root) +spufs_parse_options(struct super_block *sb, char *options, struct inode *root) { char *p; substring_t args[MAX_OPT_ARGS]; @@ -678,6 +696,9 @@ spufs_parse_options(char *options, struct inode *root) return 0; root->i_mode = option | S_IFDIR; break; + case Opt_debug: + spufs_get_sb_info(sb)->debug = 1; + break; default: return 0; } @@ -736,7 +757,7 @@ spufs_create_root(struct super_block *sb, void *data) SPUFS_I(inode)->i_ctx = NULL; ret = -EINVAL; - if (!spufs_parse_options(data, inode)) + if (!spufs_parse_options(sb, data, inode)) goto out_iput; ret = -ENOMEM; @@ -754,6 +775,7 @@ out: static int spufs_fill_super(struct super_block *sb, void *data, int silent) { + struct spufs_sb_info *info; static struct super_operations s_ops = { .alloc_inode = spufs_alloc_inode, .destroy_inode = spufs_destroy_inode, @@ -765,11 +787,16 @@ spufs_fill_super(struct super_block *sb, void *data, int silent) save_mount_options(sb, data); + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + sb->s_maxbytes = MAX_LFS_FILESIZE; sb->s_blocksize = PAGE_CACHE_SIZE; sb->s_blocksize_bits = PAGE_CACHE_SHIFT; sb->s_magic = SPUFS_MAGIC; sb->s_op = &s_ops; + sb->s_fs_info = info; return spufs_create_root(sb, data); } diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index e929e70a84e3..34654743363d 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -899,7 +899,8 @@ static noinline void spusched_tick(struct spu_context *ctx) spu_add_to_rq(ctx); } else { spu_context_nospu_trace(spusched_tick__newslice, ctx); - ctx->time_slice++; + if (!ctx->time_slice) + ctx->time_slice++; } out: spu_release(ctx); @@ -993,6 +994,7 @@ void spuctx_switch_state(struct spu_context *ctx, struct timespec ts; struct spu *spu; enum spu_utilization_state old_state; + int node; ktime_get_ts(&ts); curtime = timespec_to_ns(&ts); @@ -1014,6 +1016,11 @@ void spuctx_switch_state(struct spu_context *ctx, spu->stats.times[old_state] += delta; spu->stats.util_state = new_state; spu->stats.tstamp = curtime; + node = spu->node; + if (old_state == SPU_UTIL_USER) + atomic_dec(&cbe_spu_info[node].busy_spus); + if (new_state == SPU_UTIL_USER); + atomic_inc(&cbe_spu_info[node].busy_spus); } } diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index 454c277c1457..8ae8ef9dfc22 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -32,6 +32,13 @@ #include <asm/spu_csa.h> #include <asm/spu_info.h> +#define SPUFS_PS_MAP_SIZE 0x20000 +#define SPUFS_MFC_MAP_SIZE 0x1000 +#define SPUFS_CNTL_MAP_SIZE 0x1000 +#define SPUFS_CNTL_MAP_SIZE 0x1000 +#define SPUFS_SIGNAL_MAP_SIZE PAGE_SIZE +#define SPUFS_MSS_MAP_SIZE 0x1000 + /* The magic number for our file system */ enum { SPUFS_MAGIC = 0x23c9b64e, @@ -228,8 +235,16 @@ struct spufs_inode_info { #define SPUFS_I(inode) \ container_of(inode, struct spufs_inode_info, vfs_inode) -extern struct tree_descr spufs_dir_contents[]; -extern struct tree_descr spufs_dir_nosched_contents[]; +struct spufs_tree_descr { + const char *name; + const struct file_operations *ops; + int mode; + size_t size; +}; + +extern struct spufs_tree_descr spufs_dir_contents[]; +extern struct spufs_tree_descr spufs_dir_nosched_contents[]; +extern struct spufs_tree_descr spufs_dir_debug_contents[]; /* system call implementation */ extern struct spufs_calls spufs_calls; diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.c b/arch/powerpc/platforms/cell/spufs/sputrace.c index 53202422ba72..8c0e95766a62 100644 --- a/arch/powerpc/platforms/cell/spufs/sputrace.c +++ b/arch/powerpc/platforms/cell/spufs/sputrace.c @@ -182,10 +182,10 @@ struct spu_probe spu_probes[] = { { "spu_yield__enter", "ctx %p", spu_context_nospu_event }, { "spu_deactivate__enter", "ctx %p", spu_context_nospu_event }, { "__spu_deactivate__unload", "ctx %p spu %p", spu_context_event }, - { "spufs_ps_nopfn__enter", "ctx %p", spu_context_nospu_event }, - { "spufs_ps_nopfn__sleep", "ctx %p", spu_context_nospu_event }, - { "spufs_ps_nopfn__wake", "ctx %p spu %p", spu_context_event }, - { "spufs_ps_nopfn__insert", "ctx %p spu %p", spu_context_event }, + { "spufs_ps_fault__enter", "ctx %p", spu_context_nospu_event }, + { "spufs_ps_fault__sleep", "ctx %p", spu_context_nospu_event }, + { "spufs_ps_fault__wake", "ctx %p spu %p", spu_context_event }, + { "spufs_ps_fault__insert", "ctx %p spu %p", spu_context_event }, { "spu_acquire_saved__enter", "ctx %p", spu_context_nospu_event }, { "destroy_spu_context__enter", "ctx %p", spu_context_nospu_event }, { "spufs_stop_callback__enter", "ctx %p spu %p", spu_context_event }, |