include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / arch / powerpc / platforms / ps3 / spu.c
index d1630a0..39a472e 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/mmzone.h>
 #include <linux/io.h>
 #include <linux/mm.h>
@@ -27,7 +28,9 @@
 #include <asm/spu.h>
 #include <asm/spu_priv1.h>
 #include <asm/lv1call.h>
+#include <asm/ps3.h>
 
+#include "../cell/spufs/spufs.h"
 #include "platform.h"
 
 /* spu_management_ops */
@@ -139,9 +142,15 @@ static void _dump_areas(unsigned int spe_id, unsigned long priv2,
        pr_debug("%s:%d: shadow:  %lxh\n", func, line, shadow);
 }
 
+inline u64 ps3_get_spe_id(void *arg)
+{
+       return spu_pdata(arg)->spe_id;
+}
+EXPORT_SYMBOL_GPL(ps3_get_spe_id);
+
 static unsigned long get_vas_id(void)
 {
-       unsigned long id;
+       u64 id;
 
        lv1_get_logical_ppe_id(&id);
        lv1_get_virtual_address_space_id_of_ppe(id, &id);
@@ -152,14 +161,18 @@ static unsigned long get_vas_id(void)
 static int __init construct_spu(struct spu *spu)
 {
        int result;
-       unsigned long unused;
+       u64 unused;
+       u64 problem_phys;
+       u64 local_store_phys;
 
        result = lv1_construct_logical_spe(PAGE_SHIFT, PAGE_SHIFT, PAGE_SHIFT,
                PAGE_SHIFT, PAGE_SHIFT, get_vas_id(), SPE_TYPE_LOGICAL,
-               &spu_pdata(spu)->priv2_addr, &spu->problem_phys,
-               &spu->local_store_phys, &unused,
+               &spu_pdata(spu)->priv2_addr, &problem_phys,
+               &local_store_phys, &unused,
                &spu_pdata(spu)->shadow_addr,
                &spu_pdata(spu)->spe_id);
+       spu->problem_phys = problem_phys;
+       spu->local_store_phys = local_store_phys;
 
        if (result) {
                pr_debug("%s:%d: lv1_construct_logical_spe failed: %s\n",
@@ -178,14 +191,24 @@ static void spu_unmap(struct spu *spu)
        iounmap(spu_pdata(spu)->shadow);
 }
 
+/**
+ * setup_areas - Map the spu regions into the address space.
+ *
+ * The current HV requires the spu shadow regs to be mapped with the
+ * PTE page protection bits set as read-only (PP=3).  This implementation
+ * uses the low level __ioremap() to bypass the page protection settings
+ * inforced by ioremap_flags() to get the needed PTE bits set for the
+ * shadow regs.
+ */
+
 static int __init setup_areas(struct spu *spu)
 {
        struct table {char* name; unsigned long addr; unsigned long size;};
+       static const unsigned long shadow_flags = _PAGE_NO_CACHE | 3;
 
-       spu_pdata(spu)->shadow = ioremap_flags(spu_pdata(spu)->shadow_addr,
-                                              sizeof(struct spe_shadow),
-                                              pgprot_val(PAGE_READONLY) |
-                                              _PAGE_NO_CACHE);
+       spu_pdata(spu)->shadow = __ioremap(spu_pdata(spu)->shadow_addr,
+                                          sizeof(struct spe_shadow),
+                                          shadow_flags);
        if (!spu_pdata(spu)->shadow) {
                pr_debug("%s:%d: ioremap shadow failed\n", __func__, __LINE__);
                goto fail_ioremap;
@@ -419,10 +442,34 @@ static int ps3_init_affinity(void)
        return 0;
 }
 
+/**
+ * ps3_enable_spu - Enable SPU run control.
+ *
+ * An outstanding enhancement for the PS3 would be to add a guard to check
+ * for incorrect access to the spu problem state when the spu context is
+ * disabled.  This check could be implemented with a flag added to the spu
+ * context that would inhibit mapping problem state pages, and a routine
+ * to unmap spu problem state pages.  When the spu is enabled with
+ * ps3_enable_spu() the flag would be set allowing pages to be mapped,
+ * and when the spu is disabled with ps3_disable_spu() the flag would be
+ * cleared and the mapped problem state pages would be unmapped.
+ */
+
+static void ps3_enable_spu(struct spu_context *ctx)
+{
+}
+
+static void ps3_disable_spu(struct spu_context *ctx)
+{
+       ctx->ops->runcntl_stop(ctx);
+}
+
 const struct spu_management_ops spu_management_ps3_ops = {
        .enumerate_spus = ps3_enumerate_spus,
        .create_spu = ps3_create_spu,
        .destroy_spu = ps3_destroy_spu,
+       .enable_spu = ps3_enable_spu,
+       .disable_spu = ps3_disable_spu,
        .init_affinity = ps3_init_affinity,
 };
 
@@ -505,8 +552,6 @@ static void mfc_sr1_set(struct spu *spu, u64 sr1)
        static const u64 allowed = ~(MFC_STATE1_LOCAL_STORAGE_DECODE_MASK
                | MFC_STATE1_PROBLEM_STATE_MASK);
 
-       sr1 |= MFC_STATE1_MASTER_RUN_CONTROL_MASK;
-
        BUG_ON((sr1 & allowed) != (spu_pdata(spu)->cache.sr1 & allowed));
 
        spu_pdata(spu)->cache.sr1 = sr1;