2019-05-27 08:55:15 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2006-01-04 20:31:30 +01:00
/*
2006-06-19 20:33:29 +02:00
* spu hypervisor abstraction for direct hardware access .
*
* ( C ) Copyright IBM Deutschland Entwicklung GmbH 2005
* Copyright 2006 Sony Corp .
2006-01-04 20:31:30 +01:00
*/
2006-06-19 20:33:29 +02:00
2006-11-23 00:46:49 +01:00
# include <linux/interrupt.h>
# include <linux/list.h>
# include <linux/ptrace.h>
# include <linux/wait.h>
# include <linux/mm.h>
# include <linux/io.h>
# include <linux/mutex.h>
# include <linux/device.h>
2008-04-28 14:32:34 +10:00
# include <linux/sched.h>
2006-01-04 20:31:30 +01:00
# include <asm/spu.h>
2006-06-19 20:33:29 +02:00
# include <asm/spu_priv1.h>
2006-11-23 00:46:49 +01:00
# include <asm/firmware.h>
2006-01-04 20:31:30 +01:00
2006-06-19 20:33:30 +02:00
# include "interrupt.h"
2006-11-23 00:46:49 +01:00
# include "spu_priv1_mmio.h"
2006-06-19 20:33:29 +02:00
static void int_mask_and ( struct spu * spu , int class , u64 mask )
2006-01-04 20:31:30 +01:00
{
u64 old_mask ;
2007-02-02 16:45:33 +09:00
old_mask = in_be64 ( & spu - > priv1 - > int_mask_RW [ class ] ) ;
out_be64 ( & spu - > priv1 - > int_mask_RW [ class ] , old_mask & mask ) ;
2006-01-04 20:31:30 +01:00
}
2006-06-19 20:33:29 +02:00
static void int_mask_or ( struct spu * spu , int class , u64 mask )
2006-01-04 20:31:30 +01:00
{
u64 old_mask ;
2007-02-02 16:45:33 +09:00
old_mask = in_be64 ( & spu - > priv1 - > int_mask_RW [ class ] ) ;
out_be64 ( & spu - > priv1 - > int_mask_RW [ class ] , old_mask | mask ) ;
2006-01-04 20:31:30 +01:00
}
2006-06-19 20:33:29 +02:00
static void int_mask_set ( struct spu * spu , int class , u64 mask )
2006-01-04 20:31:30 +01:00
{
2007-02-02 16:45:33 +09:00
out_be64 ( & spu - > priv1 - > int_mask_RW [ class ] , mask ) ;
2006-01-04 20:31:30 +01:00
}
2006-06-19 20:33:29 +02:00
static u64 int_mask_get ( struct spu * spu , int class )
2006-01-04 20:31:30 +01:00
{
2007-02-02 16:45:33 +09:00
return in_be64 ( & spu - > priv1 - > int_mask_RW [ class ] ) ;
2006-01-04 20:31:30 +01:00
}
2006-06-19 20:33:29 +02:00
static void int_stat_clear ( struct spu * spu , int class , u64 stat )
2006-01-04 20:31:30 +01:00
{
2007-02-02 16:45:33 +09:00
out_be64 ( & spu - > priv1 - > int_stat_RW [ class ] , stat ) ;
2006-01-04 20:31:30 +01:00
}
2006-06-19 20:33:29 +02:00
static u64 int_stat_get ( struct spu * spu , int class )
2006-01-04 20:31:30 +01:00
{
2007-02-02 16:45:33 +09:00
return in_be64 ( & spu - > priv1 - > int_stat_RW [ class ] ) ;
2006-01-04 20:31:30 +01:00
}
2006-06-19 20:33:30 +02:00
static void cpu_affinity_set ( struct spu * spu , int cpu )
2006-01-04 20:31:30 +01:00
{
2008-04-28 14:32:34 +10:00
u64 target ;
u64 route ;
if ( nr_cpus_node ( spu - > node ) ) {
2008-12-26 22:23:39 +10:30
const struct cpumask * spumask = cpumask_of_node ( spu - > node ) ,
* cpumask = cpumask_of_node ( cpu_to_node ( cpu ) ) ;
2008-04-28 14:32:34 +10:00
2008-12-26 22:23:39 +10:30
if ( ! cpumask_intersects ( spumask , cpumask ) )
2008-04-28 14:32:34 +10:00
return ;
}
target = iic_get_target_id ( cpu ) ;
route = target < < 48 | target < < 32 | target < < 16 ;
2007-02-02 16:45:33 +09:00
out_be64 ( & spu - > priv1 - > int_route_RW , route ) ;
2006-01-04 20:31:30 +01:00
}
2006-06-19 20:33:29 +02:00
static u64 mfc_dar_get ( struct spu * spu )
2006-01-04 20:31:30 +01:00
{
2007-02-02 16:45:33 +09:00
return in_be64 ( & spu - > priv1 - > mfc_dar_RW ) ;
2006-01-04 20:31:30 +01:00
}
2006-06-19 20:33:29 +02:00
static u64 mfc_dsisr_get ( struct spu * spu )
2006-01-04 20:31:30 +01:00
{
2007-02-02 16:45:33 +09:00
return in_be64 ( & spu - > priv1 - > mfc_dsisr_RW ) ;
2006-01-04 20:31:30 +01:00
}
2006-06-19 20:33:29 +02:00
static void mfc_dsisr_set ( struct spu * spu , u64 dsisr )
2006-01-04 20:31:30 +01:00
{
2007-02-02 16:45:33 +09:00
out_be64 ( & spu - > priv1 - > mfc_dsisr_RW , dsisr ) ;
2006-01-04 20:31:30 +01:00
}
2006-10-24 18:31:14 +02:00
static void mfc_sdr_setup ( struct spu * spu )
2006-01-04 20:31:30 +01:00
{
2007-02-02 16:45:33 +09:00
out_be64 ( & spu - > priv1 - > mfc_sdr_RW , mfspr ( SPRN_SDR1 ) ) ;
2006-01-04 20:31:30 +01:00
}
2006-06-19 20:33:29 +02:00
static void mfc_sr1_set ( struct spu * spu , u64 sr1 )
2006-01-04 20:31:30 +01:00
{
2007-02-02 16:45:33 +09:00
out_be64 ( & spu - > priv1 - > mfc_sr1_RW , sr1 ) ;
2006-01-04 20:31:30 +01:00
}
2006-06-19 20:33:29 +02:00
static u64 mfc_sr1_get ( struct spu * spu )
2006-01-04 20:31:30 +01:00
{
2007-02-02 16:45:33 +09:00
return in_be64 ( & spu - > priv1 - > mfc_sr1_RW ) ;
2006-01-04 20:31:30 +01:00
}
2006-06-19 20:33:29 +02:00
static void mfc_tclass_id_set ( struct spu * spu , u64 tclass_id )
2006-01-04 20:31:30 +01:00
{
2007-02-02 16:45:33 +09:00
out_be64 ( & spu - > priv1 - > mfc_tclass_id_RW , tclass_id ) ;
2006-01-04 20:31:30 +01:00
}
2006-06-19 20:33:29 +02:00
static u64 mfc_tclass_id_get ( struct spu * spu )
2006-01-04 20:31:30 +01:00
{
2007-02-02 16:45:33 +09:00
return in_be64 ( & spu - > priv1 - > mfc_tclass_id_RW ) ;
2006-01-04 20:31:30 +01:00
}
2006-06-19 20:33:29 +02:00
static void tlb_invalidate ( struct spu * spu )
2006-01-04 20:31:30 +01:00
{
2007-02-02 16:45:33 +09:00
out_be64 ( & spu - > priv1 - > tlb_invalidate_entry_W , 0ul ) ;
2006-01-04 20:31:30 +01:00
}
2006-06-19 20:33:29 +02:00
static void resource_allocation_groupID_set ( struct spu * spu , u64 id )
2006-01-04 20:31:30 +01:00
{
2007-02-02 16:45:33 +09:00
out_be64 ( & spu - > priv1 - > resource_allocation_groupID_RW , id ) ;
2006-01-04 20:31:30 +01:00
}
2006-06-19 20:33:29 +02:00
static u64 resource_allocation_groupID_get ( struct spu * spu )
2006-01-04 20:31:30 +01:00
{
2007-02-02 16:45:33 +09:00
return in_be64 ( & spu - > priv1 - > resource_allocation_groupID_RW ) ;
2006-01-04 20:31:30 +01:00
}
2006-06-19 20:33:29 +02:00
static void resource_allocation_enable_set ( struct spu * spu , u64 enable )
2006-01-04 20:31:30 +01:00
{
2007-02-02 16:45:33 +09:00
out_be64 ( & spu - > priv1 - > resource_allocation_enable_RW , enable ) ;
2006-01-04 20:31:30 +01:00
}
2006-06-19 20:33:29 +02:00
static u64 resource_allocation_enable_get ( struct spu * spu )
2006-01-04 20:31:30 +01:00
{
2007-02-02 16:45:33 +09:00
return in_be64 ( & spu - > priv1 - > resource_allocation_enable_RW ) ;
2006-01-04 20:31:30 +01:00
}
2006-06-19 20:33:29 +02:00
const struct spu_priv1_ops spu_priv1_mmio_ops =
{
. int_mask_and = int_mask_and ,
. int_mask_or = int_mask_or ,
. int_mask_set = int_mask_set ,
. int_mask_get = int_mask_get ,
. int_stat_clear = int_stat_clear ,
. int_stat_get = int_stat_get ,
2006-06-19 20:33:30 +02:00
. cpu_affinity_set = cpu_affinity_set ,
2006-06-19 20:33:29 +02:00
. mfc_dar_get = mfc_dar_get ,
. mfc_dsisr_get = mfc_dsisr_get ,
. mfc_dsisr_set = mfc_dsisr_set ,
2006-10-24 18:31:14 +02:00
. mfc_sdr_setup = mfc_sdr_setup ,
2006-06-19 20:33:29 +02:00
. mfc_sr1_set = mfc_sr1_set ,
. mfc_sr1_get = mfc_sr1_get ,
. mfc_tclass_id_set = mfc_tclass_id_set ,
. mfc_tclass_id_get = mfc_tclass_id_get ,
. tlb_invalidate = tlb_invalidate ,
. resource_allocation_groupID_set = resource_allocation_groupID_set ,
. resource_allocation_groupID_get = resource_allocation_groupID_get ,
. resource_allocation_enable_set = resource_allocation_enable_set ,
. resource_allocation_enable_get = resource_allocation_enable_get ,
} ;