4 * (C) Copyright IBM Corp. 2005
6 * Author: Mark Nutter <mnutter@us.ibm.com>
8 * Host-side part of SPU context switch sequence outlined in
9 * Synergistic Processor Element, Book IV.
11 * A fully premptive switch of an SPE is very expensive in terms
12 * of time and system resources. SPE Book IV indicates that SPE
13 * allocation should follow a "serially reusable device" model,
14 * in which the SPE is assigned a task until it completes. When
15 * this is not possible, this sequence may be used to premptively
16 * save, and then later (optionally) restore the context of a
17 * program executing on an SPE.
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2, or (at your option)
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 #include <linux/config.h>
36 #include <linux/module.h>
37 #include <linux/errno.h>
38 #include <linux/sched.h>
39 #include <linux/kernel.h>
41 #include <linux/vmalloc.h>
42 #include <linux/smp.h>
43 #include <linux/smp_lock.h>
44 #include <linux/stddef.h>
45 #include <linux/unistd.h>
49 #include <asm/spu_csa.h>
50 #include <asm/mmu_context.h>
52 #include "spu_save_dump.h"
53 #include "spu_restore_dump.h"
56 * spu_save - SPU context save, with locking.
57 * @prev: pointer to SPU context save area, to be saved.
58 * @spu: pointer to SPU iomem structure.
60 * Acquire locks, perform the save operation then return.
62 int spu_save(struct spu_state *prev, struct spu *spu)
70 * spu_restore - SPU context restore, with harvest and locking.
71 * @new: pointer to SPU context save area, to be restored.
72 * @spu: pointer to SPU iomem structure.
74 * Perform harvest + restore, as we may not be coming
75 * from a previous succesful save operation, and the
76 * hardware state is unknown.
78 int spu_restore(struct spu_state *new, struct spu *spu)
86 * spu_switch - SPU context switch (save + restore).
87 * @prev: pointer to SPU context save area, to be saved.
88 * @new: pointer to SPU context save area, to be restored.
89 * @spu: pointer to SPU iomem structure.
91 * Perform save, then restore. Only harvest if the
92 * save fails, as cleanup is otherwise not needed.
94 int spu_switch(struct spu_state *prev, struct spu_state *new, struct spu *spu)
101 static void init_prob(struct spu_state *csa)
103 csa->spu_chnlcnt_RW[9] = 1;
104 csa->spu_chnlcnt_RW[21] = 16;
105 csa->spu_chnlcnt_RW[23] = 1;
106 csa->spu_chnlcnt_RW[28] = 1;
107 csa->spu_chnlcnt_RW[30] = 1;
108 csa->prob.spu_runcntl_RW = SPU_RUNCNTL_STOP;
111 static void init_priv1(struct spu_state *csa)
113 /* Enable decode, relocate, tlbie response, master runcntl. */
114 csa->priv1.mfc_sr1_RW = MFC_STATE1_LOCAL_STORAGE_DECODE_MASK |
115 MFC_STATE1_MASTER_RUN_CONTROL_MASK |
116 MFC_STATE1_PROBLEM_STATE_MASK |
117 MFC_STATE1_RELOCATE_MASK | MFC_STATE1_BUS_TLBIE_MASK;
119 /* Set storage description. */
120 csa->priv1.mfc_sdr_RW = mfspr(SPRN_SDR1);
122 /* Enable OS-specific set of interrupts. */
123 csa->priv1.int_mask_class0_RW = CLASS0_ENABLE_DMA_ALIGNMENT_INTR |
124 CLASS0_ENABLE_INVALID_DMA_COMMAND_INTR |
125 CLASS0_ENABLE_SPU_ERROR_INTR;
126 csa->priv1.int_mask_class1_RW = CLASS1_ENABLE_SEGMENT_FAULT_INTR |
127 CLASS1_ENABLE_STORAGE_FAULT_INTR;
128 csa->priv1.int_mask_class2_RW = CLASS2_ENABLE_MAILBOX_INTR |
129 CLASS2_ENABLE_SPU_STOP_INTR | CLASS2_ENABLE_SPU_HALT_INTR;
132 static void init_priv2(struct spu_state *csa)
134 csa->priv2.spu_lslr_RW = LS_ADDR_MASK;
135 csa->priv2.mfc_control_RW = MFC_CNTL_RESUME_DMA_QUEUE |
136 MFC_CNTL_NORMAL_DMA_QUEUE_OPERATION |
137 MFC_CNTL_DMA_QUEUES_EMPTY_MASK;
141 * spu_alloc_csa - allocate and initialize an SPU context save area.
143 * Allocate and initialize the contents of an SPU context save area.
144 * This includes enabling address translation, interrupt masks, etc.,
145 * as appropriate for the given OS environment.
147 * Note that storage for the 'lscsa' is allocated separately,
148 * as it is by far the largest of the context save regions,
149 * and may need to be pinned or otherwise specially aligned.
151 void spu_init_csa(struct spu_state *csa)
153 struct spu_lscsa *lscsa;
157 memset(csa, 0, sizeof(struct spu_state));
159 lscsa = vmalloc(sizeof(struct spu_lscsa));
163 memset(lscsa, 0, sizeof(struct spu_lscsa));
171 void spu_fini_csa(struct spu_state *csa)