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 .
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; version 2 of the License .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
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>
2006-01-04 20:31:30 +01:00
# include <linux/module.h>
2006-11-23 00:46:49 +01:00
# include <linux/ptrace.h>
# include <linux/slab.h>
# include <linux/wait.h>
# include <linux/mm.h>
# include <linux/io.h>
# include <linux/mutex.h>
# include <linux/device.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>
# include <asm/prom.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
{
2006-06-19 20:33:30 +02:00
u64 target = iic_get_target_id ( cpu ) ;
u64 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 ,
} ;