1c01ea72aSGeoff Levand /* 2540270d8SGeoff Levand * spu hypervisor abstraction for direct hardware access. 3540270d8SGeoff Levand * 4540270d8SGeoff Levand * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 5540270d8SGeoff Levand * Copyright 2006 Sony Corp. 6540270d8SGeoff Levand * 7540270d8SGeoff Levand * This program is free software; you can redistribute it and/or modify 8540270d8SGeoff Levand * it under the terms of the GNU General Public License as published by 9540270d8SGeoff Levand * the Free Software Foundation; version 2 of the License. 10540270d8SGeoff Levand * 11540270d8SGeoff Levand * This program is distributed in the hope that it will be useful, 12540270d8SGeoff Levand * but WITHOUT ANY WARRANTY; without even the implied warranty of 13540270d8SGeoff Levand * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14540270d8SGeoff Levand * GNU General Public License for more details. 15540270d8SGeoff Levand * 16540270d8SGeoff Levand * You should have received a copy of the GNU General Public License 17540270d8SGeoff Levand * along with this program; if not, write to the Free Software 18540270d8SGeoff Levand * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19c01ea72aSGeoff Levand */ 20540270d8SGeoff Levand 21e28b0031SGeoff Levand #include <linux/interrupt.h> 22e28b0031SGeoff Levand #include <linux/list.h> 23c01ea72aSGeoff Levand #include <linux/module.h> 24e28b0031SGeoff Levand #include <linux/ptrace.h> 25e28b0031SGeoff Levand #include <linux/slab.h> 26e28b0031SGeoff Levand #include <linux/wait.h> 27e28b0031SGeoff Levand #include <linux/mm.h> 28e28b0031SGeoff Levand #include <linux/io.h> 29e28b0031SGeoff Levand #include <linux/mutex.h> 30e28b0031SGeoff Levand #include <linux/device.h> 317a214200SLuke Browning #include <linux/sched.h> 32c01ea72aSGeoff Levand 33c01ea72aSGeoff Levand #include <asm/spu.h> 34540270d8SGeoff Levand #include <asm/spu_priv1.h> 35e28b0031SGeoff Levand #include <asm/firmware.h> 36e28b0031SGeoff Levand #include <asm/prom.h> 37c01ea72aSGeoff Levand 38a91942aeSGeoff Levand #include "interrupt.h" 39e28b0031SGeoff Levand #include "spu_priv1_mmio.h" 40e28b0031SGeoff Levand 41540270d8SGeoff Levand static void int_mask_and(struct spu *spu, int class, u64 mask) 42c01ea72aSGeoff Levand { 43c01ea72aSGeoff Levand u64 old_mask; 44c01ea72aSGeoff Levand 45c9868fe0SIshizaki Kou old_mask = in_be64(&spu->priv1->int_mask_RW[class]); 46c9868fe0SIshizaki Kou out_be64(&spu->priv1->int_mask_RW[class], old_mask & mask); 47c01ea72aSGeoff Levand } 48c01ea72aSGeoff Levand 49540270d8SGeoff Levand static void int_mask_or(struct spu *spu, int class, u64 mask) 50c01ea72aSGeoff Levand { 51c01ea72aSGeoff Levand u64 old_mask; 52c01ea72aSGeoff Levand 53c9868fe0SIshizaki Kou old_mask = in_be64(&spu->priv1->int_mask_RW[class]); 54c9868fe0SIshizaki Kou out_be64(&spu->priv1->int_mask_RW[class], old_mask | mask); 55c01ea72aSGeoff Levand } 56c01ea72aSGeoff Levand 57540270d8SGeoff Levand static void int_mask_set(struct spu *spu, int class, u64 mask) 58c01ea72aSGeoff Levand { 59c9868fe0SIshizaki Kou out_be64(&spu->priv1->int_mask_RW[class], mask); 60c01ea72aSGeoff Levand } 61c01ea72aSGeoff Levand 62540270d8SGeoff Levand static u64 int_mask_get(struct spu *spu, int class) 63c01ea72aSGeoff Levand { 64c9868fe0SIshizaki Kou return in_be64(&spu->priv1->int_mask_RW[class]); 65c01ea72aSGeoff Levand } 66c01ea72aSGeoff Levand 67540270d8SGeoff Levand static void int_stat_clear(struct spu *spu, int class, u64 stat) 68c01ea72aSGeoff Levand { 69c9868fe0SIshizaki Kou out_be64(&spu->priv1->int_stat_RW[class], stat); 70c01ea72aSGeoff Levand } 71c01ea72aSGeoff Levand 72540270d8SGeoff Levand static u64 int_stat_get(struct spu *spu, int class) 73c01ea72aSGeoff Levand { 74c9868fe0SIshizaki Kou return in_be64(&spu->priv1->int_stat_RW[class]); 75c01ea72aSGeoff Levand } 76c01ea72aSGeoff Levand 77a91942aeSGeoff Levand static void cpu_affinity_set(struct spu *spu, int cpu) 78c01ea72aSGeoff Levand { 797a214200SLuke Browning u64 target; 807a214200SLuke Browning u64 route; 817a214200SLuke Browning 827a214200SLuke Browning if (nr_cpus_node(spu->node)) { 8386c6f274SRusty Russell const struct cpumask *spumask = cpumask_of_node(spu->node), 8486c6f274SRusty Russell *cpumask = cpumask_of_node(cpu_to_node(cpu)); 857a214200SLuke Browning 8686c6f274SRusty Russell if (!cpumask_intersects(spumask, cpumask)) 877a214200SLuke Browning return; 887a214200SLuke Browning } 897a214200SLuke Browning 907a214200SLuke Browning target = iic_get_target_id(cpu); 917a214200SLuke Browning route = target << 48 | target << 32 | target << 16; 92c9868fe0SIshizaki Kou out_be64(&spu->priv1->int_route_RW, route); 93c01ea72aSGeoff Levand } 94c01ea72aSGeoff Levand 95540270d8SGeoff Levand static u64 mfc_dar_get(struct spu *spu) 96c01ea72aSGeoff Levand { 97c9868fe0SIshizaki Kou return in_be64(&spu->priv1->mfc_dar_RW); 98c01ea72aSGeoff Levand } 99c01ea72aSGeoff Levand 100540270d8SGeoff Levand static u64 mfc_dsisr_get(struct spu *spu) 101c01ea72aSGeoff Levand { 102c9868fe0SIshizaki Kou return in_be64(&spu->priv1->mfc_dsisr_RW); 103c01ea72aSGeoff Levand } 104c01ea72aSGeoff Levand 105540270d8SGeoff Levand static void mfc_dsisr_set(struct spu *spu, u64 dsisr) 106c01ea72aSGeoff Levand { 107c9868fe0SIshizaki Kou out_be64(&spu->priv1->mfc_dsisr_RW, dsisr); 108c01ea72aSGeoff Levand } 109c01ea72aSGeoff Levand 11024f43b33SMasato Noguchi static void mfc_sdr_setup(struct spu *spu) 111c01ea72aSGeoff Levand { 112c9868fe0SIshizaki Kou out_be64(&spu->priv1->mfc_sdr_RW, mfspr(SPRN_SDR1)); 113c01ea72aSGeoff Levand } 114c01ea72aSGeoff Levand 115540270d8SGeoff Levand static void mfc_sr1_set(struct spu *spu, u64 sr1) 116c01ea72aSGeoff Levand { 117c9868fe0SIshizaki Kou out_be64(&spu->priv1->mfc_sr1_RW, sr1); 118c01ea72aSGeoff Levand } 119c01ea72aSGeoff Levand 120540270d8SGeoff Levand static u64 mfc_sr1_get(struct spu *spu) 121c01ea72aSGeoff Levand { 122c9868fe0SIshizaki Kou return in_be64(&spu->priv1->mfc_sr1_RW); 123c01ea72aSGeoff Levand } 124c01ea72aSGeoff Levand 125540270d8SGeoff Levand static void mfc_tclass_id_set(struct spu *spu, u64 tclass_id) 126c01ea72aSGeoff Levand { 127c9868fe0SIshizaki Kou out_be64(&spu->priv1->mfc_tclass_id_RW, tclass_id); 128c01ea72aSGeoff Levand } 129c01ea72aSGeoff Levand 130540270d8SGeoff Levand static u64 mfc_tclass_id_get(struct spu *spu) 131c01ea72aSGeoff Levand { 132c9868fe0SIshizaki Kou return in_be64(&spu->priv1->mfc_tclass_id_RW); 133c01ea72aSGeoff Levand } 134c01ea72aSGeoff Levand 135540270d8SGeoff Levand static void tlb_invalidate(struct spu *spu) 136c01ea72aSGeoff Levand { 137c9868fe0SIshizaki Kou out_be64(&spu->priv1->tlb_invalidate_entry_W, 0ul); 138c01ea72aSGeoff Levand } 139c01ea72aSGeoff Levand 140540270d8SGeoff Levand static void resource_allocation_groupID_set(struct spu *spu, u64 id) 141c01ea72aSGeoff Levand { 142c9868fe0SIshizaki Kou out_be64(&spu->priv1->resource_allocation_groupID_RW, id); 143c01ea72aSGeoff Levand } 144c01ea72aSGeoff Levand 145540270d8SGeoff Levand static u64 resource_allocation_groupID_get(struct spu *spu) 146c01ea72aSGeoff Levand { 147c9868fe0SIshizaki Kou return in_be64(&spu->priv1->resource_allocation_groupID_RW); 148c01ea72aSGeoff Levand } 149c01ea72aSGeoff Levand 150540270d8SGeoff Levand static void resource_allocation_enable_set(struct spu *spu, u64 enable) 151c01ea72aSGeoff Levand { 152c9868fe0SIshizaki Kou out_be64(&spu->priv1->resource_allocation_enable_RW, enable); 153c01ea72aSGeoff Levand } 154c01ea72aSGeoff Levand 155540270d8SGeoff Levand static u64 resource_allocation_enable_get(struct spu *spu) 156c01ea72aSGeoff Levand { 157c9868fe0SIshizaki Kou return in_be64(&spu->priv1->resource_allocation_enable_RW); 158c01ea72aSGeoff Levand } 159540270d8SGeoff Levand 160540270d8SGeoff Levand const struct spu_priv1_ops spu_priv1_mmio_ops = 161540270d8SGeoff Levand { 162540270d8SGeoff Levand .int_mask_and = int_mask_and, 163540270d8SGeoff Levand .int_mask_or = int_mask_or, 164540270d8SGeoff Levand .int_mask_set = int_mask_set, 165540270d8SGeoff Levand .int_mask_get = int_mask_get, 166540270d8SGeoff Levand .int_stat_clear = int_stat_clear, 167540270d8SGeoff Levand .int_stat_get = int_stat_get, 168a91942aeSGeoff Levand .cpu_affinity_set = cpu_affinity_set, 169540270d8SGeoff Levand .mfc_dar_get = mfc_dar_get, 170540270d8SGeoff Levand .mfc_dsisr_get = mfc_dsisr_get, 171540270d8SGeoff Levand .mfc_dsisr_set = mfc_dsisr_set, 17224f43b33SMasato Noguchi .mfc_sdr_setup = mfc_sdr_setup, 173540270d8SGeoff Levand .mfc_sr1_set = mfc_sr1_set, 174540270d8SGeoff Levand .mfc_sr1_get = mfc_sr1_get, 175540270d8SGeoff Levand .mfc_tclass_id_set = mfc_tclass_id_set, 176540270d8SGeoff Levand .mfc_tclass_id_get = mfc_tclass_id_get, 177540270d8SGeoff Levand .tlb_invalidate = tlb_invalidate, 178540270d8SGeoff Levand .resource_allocation_groupID_set = resource_allocation_groupID_set, 179540270d8SGeoff Levand .resource_allocation_groupID_get = resource_allocation_groupID_get, 180540270d8SGeoff Levand .resource_allocation_enable_set = resource_allocation_enable_set, 181540270d8SGeoff Levand .resource_allocation_enable_get = resource_allocation_enable_get, 182540270d8SGeoff Levand }; 183