[POWERPC] Only export __mtdcr/__mfdcr if CONFIG_PPC_DCR is set
[safe/jmp/linux-2.6] / include / asm-powerpc / spu.h
index b036385..fdad426 100644 (file)
 
 #ifndef _SPU_H
 #define _SPU_H
-#include <linux/config.h>
-#include <linux/kref.h>
-#include <linux/workqueue.h>
-
-#define LS_ORDER (6)           /* 256 kb */
+#ifdef __KERNEL__
 
-#define LS_SIZE (PAGE_SIZE << LS_ORDER)
+#include <linux/workqueue.h>
+#include <linux/sysdev.h>
+
+#define LS_SIZE (256 * 1024)
+#define LS_ADDR_MASK (LS_SIZE - 1)
+
+#define MFC_PUT_CMD             0x20
+#define MFC_PUTS_CMD            0x28
+#define MFC_PUTR_CMD            0x30
+#define MFC_PUTF_CMD            0x22
+#define MFC_PUTB_CMD            0x21
+#define MFC_PUTFS_CMD           0x2A
+#define MFC_PUTBS_CMD           0x29
+#define MFC_PUTRF_CMD           0x32
+#define MFC_PUTRB_CMD           0x31
+#define MFC_PUTL_CMD            0x24
+#define MFC_PUTRL_CMD           0x34
+#define MFC_PUTLF_CMD           0x26
+#define MFC_PUTLB_CMD           0x25
+#define MFC_PUTRLF_CMD          0x36
+#define MFC_PUTRLB_CMD          0x35
+
+#define MFC_GET_CMD             0x40
+#define MFC_GETS_CMD            0x48
+#define MFC_GETF_CMD            0x42
+#define MFC_GETB_CMD            0x41
+#define MFC_GETFS_CMD           0x4A
+#define MFC_GETBS_CMD           0x49
+#define MFC_GETL_CMD            0x44
+#define MFC_GETLF_CMD           0x46
+#define MFC_GETLB_CMD           0x45
+
+#define MFC_SDCRT_CMD           0x80
+#define MFC_SDCRTST_CMD         0x81
+#define MFC_SDCRZ_CMD           0x89
+#define MFC_SDCRS_CMD           0x8D
+#define MFC_SDCRF_CMD           0x8F
+
+#define MFC_GETLLAR_CMD         0xD0
+#define MFC_PUTLLC_CMD          0xB4
+#define MFC_PUTLLUC_CMD         0xB0
+#define MFC_PUTQLLUC_CMD        0xB8
+#define MFC_SNDSIG_CMD          0xA0
+#define MFC_SNDSIGB_CMD         0xA1
+#define MFC_SNDSIGF_CMD         0xA2
+#define MFC_BARRIER_CMD         0xC0
+#define MFC_EIEIO_CMD           0xC8
+#define MFC_SYNC_CMD            0xCC
+
+#define MFC_MIN_DMA_SIZE_SHIFT  4       /* 16 bytes */
+#define MFC_MAX_DMA_SIZE_SHIFT  14      /* 16384 bytes */
+#define MFC_MIN_DMA_SIZE        (1 << MFC_MIN_DMA_SIZE_SHIFT)
+#define MFC_MAX_DMA_SIZE        (1 << MFC_MAX_DMA_SIZE_SHIFT)
+#define MFC_MIN_DMA_SIZE_MASK   (MFC_MIN_DMA_SIZE - 1)
+#define MFC_MAX_DMA_SIZE_MASK   (MFC_MAX_DMA_SIZE - 1)
+#define MFC_MIN_DMA_LIST_SIZE   0x0008  /*   8 bytes */
+#define MFC_MAX_DMA_LIST_SIZE   0x4000  /* 16K bytes */
+
+#define MFC_TAGID_TO_TAGMASK(tag_id)  (1 << (tag_id & 0x1F))
+
+/* Events for Channels 0-2 */
+#define MFC_DMA_TAG_STATUS_UPDATE_EVENT     0x00000001
+#define MFC_DMA_TAG_CMD_STALL_NOTIFY_EVENT  0x00000002
+#define MFC_DMA_QUEUE_AVAILABLE_EVENT       0x00000008
+#define MFC_SPU_MAILBOX_WRITTEN_EVENT       0x00000010
+#define MFC_DECREMENTER_EVENT               0x00000020
+#define MFC_PU_INT_MAILBOX_AVAILABLE_EVENT  0x00000040
+#define MFC_PU_MAILBOX_AVAILABLE_EVENT      0x00000080
+#define MFC_SIGNAL_2_EVENT                  0x00000100
+#define MFC_SIGNAL_1_EVENT                  0x00000200
+#define MFC_LLR_LOST_EVENT                  0x00000400
+#define MFC_PRIV_ATTN_EVENT                 0x00000800
+#define MFC_MULTI_SRC_EVENT                 0x00001000
+
+/* Flags indicating progress during context switch. */
+#define SPU_CONTEXT_SWITCH_PENDING     0UL
+#define SPU_CONTEXT_SWITCH_ACTIVE      1UL
+
+struct spu_context;
+struct spu_runqueue;
 
 struct spu {
-       char *name;
+       const char *name;
        unsigned long local_store_phys;
        u8 *local_store;
+       unsigned long problem_phys;
        struct spu_problem __iomem *problem;
-       struct spu_priv1 __iomem *priv1;
        struct spu_priv2 __iomem *priv2;
        struct list_head list;
+       struct list_head sched_list;
+       struct list_head full_list;
        int number;
-       u32 isrc;
+       unsigned int irqs[3];
        u32 node;
-       struct kref kref;
+       u64 flags;
+       u64 dar;
+       u64 dsisr;
        size_t ls_size;
        unsigned int slb_replace;
        struct mm_struct *mm;
+       struct spu_context *ctx;
+       struct spu_runqueue *rq;
+       unsigned long long timestamp;
+       pid_t pid;
+       int prio;
        int class_0_pending;
        spinlock_t register_lock;
 
-       u32 stop_code;
-       wait_queue_head_t stop_wq;
-       wait_queue_head_t ibox_wq;
-       wait_queue_head_t wbox_wq;
-       struct fasync_struct *ibox_fasync;
-       struct fasync_struct *wbox_fasync;
+       void (* wbox_callback)(struct spu *spu);
+       void (* ibox_callback)(struct spu *spu);
+       void (* stop_callback)(struct spu *spu);
+       void (* mfc_callback)(struct spu *spu);
+       void (* dma_callback)(struct spu *spu, int type);
 
        char irq_c0[8];
        char irq_c1[8];
        char irq_c2[8];
+
+       void* pdata; /* platform private data */
+       struct sys_device sysdev;
 };
 
 struct spu *spu_alloc(void);
+struct spu *spu_alloc_node(int node);
 void spu_free(struct spu *spu);
-int spu_run(struct spu *spu);
-
-size_t spu_wbox_write(struct spu *spu, u32 data);
-size_t spu_ibox_read(struct spu *spu, u32 *data);
+int spu_irq_class_0_bottom(struct spu *spu);
+int spu_irq_class_1_bottom(struct spu *spu);
+void spu_irq_setaffinity(struct spu *spu, int cpu);
+
+/* system callbacks from the SPU */
+struct spu_syscall_block {
+       u64 nr_ret;
+       u64 parm[6];
+};
+extern long spu_sys_callback(struct spu_syscall_block *s);
 
+/* syscalls implemented in spufs */
 extern struct spufs_calls {
        asmlinkage long (*create_thread)(const char __user *name,
                                        unsigned int flags, mode_t mode);
@@ -75,6 +169,31 @@ extern struct spufs_calls {
        struct module *owner;
 } spufs_calls;
 
+/* coredump calls implemented in spufs */
+struct spu_coredump_calls {
+       asmlinkage int (*arch_notes_size)(void);
+       asmlinkage void (*arch_write_notes)(struct file *file);
+       struct module *owner;
+};
+
+/* return status from spu_run, same as in libspe */
+#define SPE_EVENT_DMA_ALIGNMENT                0x0008  /*A DMA alignment error */
+#define SPE_EVENT_SPE_ERROR            0x0010  /*An illegal instruction error*/
+#define SPE_EVENT_SPE_DATA_SEGMENT     0x0020  /*A DMA segmentation error    */
+#define SPE_EVENT_SPE_DATA_STORAGE     0x0040  /*A DMA storage error */
+#define SPE_EVENT_INVALID_DMA          0x0800  /* Invalid MFC DMA */
+
+/*
+ * Flags for sys_spu_create.
+ */
+#define SPU_CREATE_EVENTS_ENABLED      0x0001
+#define SPU_CREATE_GANG                        0x0002
+#define SPU_CREATE_NOSCHED             0x0004
+#define SPU_CREATE_ISOLATE             0x0008
+
+#define SPU_CREATE_FLAG_ALL            0x000f /* mask of all valid flags */
+
+
 #ifdef CONFIG_SPU_FS_MODULE
 int register_spu_syscalls(struct spufs_calls *calls);
 void unregister_spu_syscalls(struct spufs_calls *calls);
@@ -88,6 +207,33 @@ static inline void unregister_spu_syscalls(struct spufs_calls *calls)
 }
 #endif /* MODULE */
 
+int register_arch_coredump_calls(struct spu_coredump_calls *calls);
+void unregister_arch_coredump_calls(struct spu_coredump_calls *calls);
+
+int spu_add_sysdev_attr(struct sysdev_attribute *attr);
+void spu_remove_sysdev_attr(struct sysdev_attribute *attr);
+
+int spu_add_sysdev_attr_group(struct attribute_group *attrs);
+void spu_remove_sysdev_attr_group(struct attribute_group *attrs);
+
+
+/*
+ * Notifier blocks:
+ *
+ * oprofile can get notified when a context switch is performed
+ * on an spe. The notifer function that gets called is passed
+ * a pointer to the SPU structure as well as the object-id that
+ * identifies the binary running on that SPU now.
+ *
+ * For a context save, the object-id that is passed is zero,
+ * identifying that the kernel will run from that moment on.
+ *
+ * For a context restore, the object-id is the value written
+ * to object-id spufs file from user space and the notifer
+ * function can assume that spu->ctx is valid.
+ */
+int spu_switch_event_register(struct notifier_block * n);
+int spu_switch_event_unregister(struct notifier_block * n);
 
 /*
  * This defines the Local Store, Problem Area and Privlege Area of an SPU.
@@ -148,6 +294,7 @@ struct spu_problem {
        u32 spu_runcntl_RW;                                     /* 0x401c */
 #define SPU_RUNCNTL_STOP       0L
 #define SPU_RUNCNTL_RUNNABLE   1L
+#define SPU_RUNCNTL_ISOLATE    2L
        u8  pad_0x4020_0x4024[0x4];                             /* 0x4020 */
        u32 spu_status_R;                                       /* 0x4024 */
 #define SPU_STOP_STATUS_SHIFT           16
@@ -160,8 +307,8 @@ struct spu_problem {
 #define SPU_STATUS_INVALID_INSTR        0x20
 #define SPU_STATUS_INVALID_CH           0x40
 #define SPU_STATUS_ISOLATED_STATE       0x80
-#define SPU_STATUS_ISOLATED_LOAD_STAUTUS 0x200
-#define SPU_STATUS_ISOLATED_EXIT_STAUTUS 0x400
+#define SPU_STATUS_ISOLATED_LOAD_STATUS 0x200
+#define SPU_STATUS_ISOLATED_EXIT_STATUS 0x400
        u8  pad_0x4028_0x402c[0x4];                             /* 0x4028 */
        u32 spu_spe_R;                                          /* 0x402c */
        u8  pad_0x4030_0x4034[0x4];                             /* 0x4030 */
@@ -294,27 +441,22 @@ struct spu_priv1 {
 #define SPU_GET_REVISION_BITS(vr)      (vr & SPU_REVISION_BITS)
        u8  pad_0x28_0x100[0x100 - 0x28];                       /* 0x28 */
 
-
        /* Interrupt Area */
-       u64 int_mask_class0_RW;                                 /* 0x100 */
+       u64 int_mask_RW[3];                                     /* 0x100 */
 #define CLASS0_ENABLE_DMA_ALIGNMENT_INTR               0x1L
 #define CLASS0_ENABLE_INVALID_DMA_COMMAND_INTR         0x2L
 #define CLASS0_ENABLE_SPU_ERROR_INTR                   0x4L
 #define CLASS0_ENABLE_MFC_FIR_INTR                     0x8L
-       u64 int_mask_class1_RW;                                 /* 0x108 */
 #define CLASS1_ENABLE_SEGMENT_FAULT_INTR               0x1L
 #define CLASS1_ENABLE_STORAGE_FAULT_INTR               0x2L
 #define CLASS1_ENABLE_LS_COMPARE_SUSPEND_ON_GET_INTR   0x4L
 #define CLASS1_ENABLE_LS_COMPARE_SUSPEND_ON_PUT_INTR   0x8L
-       u64 int_mask_class2_RW;                                 /* 0x110 */
 #define CLASS2_ENABLE_MAILBOX_INTR                     0x1L
 #define CLASS2_ENABLE_SPU_STOP_INTR                    0x2L
 #define CLASS2_ENABLE_SPU_HALT_INTR                    0x4L
 #define CLASS2_ENABLE_SPU_DMA_TAG_GROUP_COMPLETE_INTR  0x8L
        u8  pad_0x118_0x140[0x28];                              /* 0x118 */
-       u64 int_stat_class0_RW;                                 /* 0x140 */
-       u64 int_stat_class1_RW;                                 /* 0x148 */
-       u64 int_stat_class2_RW;                                 /* 0x150 */
+       u64 int_stat_RW[3];                                     /* 0x140 */
        u8  pad_0x158_0x180[0x28];                              /* 0x158 */
        u64 int_route_RW;                                       /* 0x180 */
 
@@ -495,4 +637,5 @@ struct spu_priv1 {
        u64 spu_trace_cntl;                                     /* 0x1070 */
 } __attribute__ ((aligned(0x2000)));
 
+#endif /* __KERNEL__ */
 #endif