@ -1,7 +1,7 @@
/*
* SGI UltraViolet TLB flush routines .
*
* ( c ) 2008 - 2012 Cliff Wickman < cpw @ sgi . com > , SGI .
* ( c ) 2008 - 2014 Cliff Wickman < cpw @ sgi . com > , SGI .
*
* This code is released under the GNU General Public License version 2 or
* later .
@ -451,7 +451,7 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc)
/*
* The reverse of the above ; converts a duration in ns to a duration in cycles .
*/
*/
static inline unsigned long long ns_2_cycles ( unsigned long long ns )
{
struct cyc2ns_data * data = cyc2ns_read_begin ( ) ;
@ -563,7 +563,7 @@ static int uv1_wait_completion(struct bau_desc *bau_desc,
* UV2 could have an extra bit of status in the ACTIVATION_STATUS_2 register .
* But not currently used .
*/
static unsigned long uv2_read_status ( unsigned long offset , int rshft , int desc )
static unsigned long uv2_3_ read_status ( unsigned long offset , int rshft , int desc )
{
unsigned long descriptor_status ;
@ -606,7 +606,7 @@ int handle_uv2_busy(struct bau_control *bcp)
return FLUSH_GIVEUP ;
}
static int uv2_wait_completion ( struct bau_desc * bau_desc ,
static int uv2_3_ wait_completion ( struct bau_desc * bau_desc ,
unsigned long mmr_offset , int right_shift ,
struct bau_control * bcp , long try )
{
@ -616,7 +616,7 @@ static int uv2_wait_completion(struct bau_desc *bau_desc,
long busy_reps = 0 ;
struct ptc_stats * stat = bcp - > statp ;
descriptor_stat = uv2_read_status ( mmr_offset , right_shift , desc ) ;
descriptor_stat = uv2_3_ read_status ( mmr_offset , right_shift , desc ) ;
/* spin on the status MMR, waiting for it to go idle */
while ( descriptor_stat ! = UV2H_DESC_IDLE ) {
@ -658,8 +658,7 @@ static int uv2_wait_completion(struct bau_desc *bau_desc,
/* not to hammer on the clock */
busy_reps = 0 ;
ttm = get_cycles ( ) ;
if ( ( ttm - bcp - > send_message ) >
bcp - > timeout_interval )
if ( ( ttm - bcp - > send_message ) > bcp - > timeout_interval )
return handle_uv2_busy ( bcp ) ;
}
/*
@ -667,8 +666,7 @@ static int uv2_wait_completion(struct bau_desc *bau_desc,
*/
cpu_relax ( ) ;
}
descriptor_stat = uv2_read_status ( mmr_offset , right_shift ,
desc ) ;
descriptor_stat = uv2_3_read_status ( mmr_offset , right_shift , desc ) ;
}
bcp - > conseccompletes + + ;
return FLUSH_COMPLETE ;
@ -679,8 +677,7 @@ static int uv2_wait_completion(struct bau_desc *bau_desc,
* which register to read and position in that register based on cpu in
* current hub .
*/
static int wait_completion ( struct bau_desc * bau_desc ,
struct bau_control * bcp , long try )
static int wait_completion ( struct bau_desc * bau_desc , struct bau_control * bcp , long try )
{
int right_shift ;
unsigned long mmr_offset ;
@ -695,11 +692,9 @@ static int wait_completion(struct bau_desc *bau_desc,
}
if ( bcp - > uvhub_version = = 1 )
return uv1_wait_completion ( bau_desc , mmr_offset , right_shift ,
bcp , try ) ;
return uv1_wait_completion ( bau_desc , mmr_offset , right_shift , bcp , try ) ;
else
return uv2_wait_completion ( bau_desc , mmr_offset , right_shift ,
bcp , try ) ;
return uv2_3_wait_completion ( bau_desc , mmr_offset , right_shift , bcp , try ) ;
}
/*
@ -888,7 +883,7 @@ int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp,
struct ptc_stats * stat = bcp - > statp ;
struct bau_control * hmaster = bcp - > uvhub_master ;
struct uv1_bau_msg_header * uv1_hdr = NULL ;
struct uv2_bau_msg_header * uv2_hdr = NULL ;
struct uv2_3_ bau_msg_header * uv2_3 _hdr = NULL ;
if ( bcp - > uvhub_version = = 1 ) {
uv1 = 1 ;
@ -902,27 +897,28 @@ int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp,
if ( uv1 )
uv1_hdr = & bau_desc - > header . uv1_hdr ;
else
uv2_hdr = & bau_desc - > header . uv2_hdr ;
/* uv2 and uv3 */
uv2_3_hdr = & bau_desc - > header . uv2_3_hdr ;
do {
if ( try = = 0 ) {
if ( uv1 )
uv1_hdr - > msg_type = MSG_REGULAR ;
else
uv2_hdr - > msg_type = MSG_REGULAR ;
uv2_3_ hdr - > msg_type = MSG_REGULAR ;
seq_number = bcp - > message_number + + ;
} else {
if ( uv1 )
uv1_hdr - > msg_type = MSG_RETRY ;
else
uv2_hdr - > msg_type = MSG_RETRY ;
uv2_3_ hdr - > msg_type = MSG_RETRY ;
stat - > s_retry_messages + + ;
}
if ( uv1 )
uv1_hdr - > sequence = seq_number ;
else
uv2_hdr - > sequence = seq_number ;
uv2_3_ hdr - > sequence = seq_number ;
index = ( 1UL < < AS_PUSH_SHIFT ) | bcp - > uvhub_cpu ;
bcp - > send_message = get_cycles ( ) ;
@ -1080,8 +1076,10 @@ static int set_distrib_bits(struct cpumask *flush_mask, struct bau_control *bcp,
* done . The returned pointer is valid till preemption is re - enabled .
*/
const struct cpumask * uv_flush_tlb_others ( const struct cpumask * cpumask ,
struct mm_struct * mm , unsigned long start ,
unsigned long end , unsigned int cpu )
struct mm_struct * mm ,
unsigned long start ,
unsigned long end ,
unsigned int cpu )
{
int locals = 0 ;
int remotes = 0 ;
@ -1268,6 +1266,7 @@ void uv_bau_message_interrupt(struct pt_regs *regs)
if ( bcp - > uvhub_version = = 2 )
process_uv2_message ( & msgdesc , bcp ) ;
else
/* no error workaround for uv1 or uv3 */
bau_process_message ( & msgdesc , bcp , 1 ) ;
msg + + ;
@ -1325,8 +1324,12 @@ static void __init enable_timeouts(void)
*/
mmr_image | = ( 1L < < SOFTACK_MSHIFT ) ;
if ( is_uv2_hub ( ) ) {
/* do not touch the legacy mode bit */
/* hw bug workaround; do not use extended status */
mmr_image & = ~ ( 1L < < UV2_EXT_SHFT ) ;
} else if ( is_uv3_hub ( ) ) {
mmr_image & = ~ ( 1L < < PREFETCH_HINT_SHFT ) ;
mmr_image | = ( 1L < < SB_STATUS_SHFT ) ;
}
write_mmr_misc_control ( pnode , mmr_image ) ;
}
@ -1692,7 +1695,7 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode)
struct bau_desc * bau_desc ;
struct bau_desc * bd2 ;
struct uv1_bau_msg_header * uv1_hdr ;
struct uv2_bau_msg_header * uv2_hdr ;
struct uv2_3_ bau_msg_header * uv2_3 _hdr ;
struct bau_control * bcp ;
/*
@ -1739,15 +1742,15 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode)
*/
} else {
/*
* BIOS uses legacy mode , but UV2 hardware always
* BIOS uses legacy mode , but uv2 and uv3 hardware always
* uses native mode for selective broadcasts .
*/
uv2_hdr = & bd2 - > header . uv2_hdr ;
uv2_hdr - > swack_flag = 1 ;
uv2_hdr - > base_dest_nasid =
uv2_3_ hdr = & bd2 - > header . uv2_3 _hdr ;
uv2_3_ hdr - > swack_flag = 1 ;
uv2_3_ hdr - > base_dest_nasid =
UV_PNODE_TO_NASID ( base_pnode ) ;
uv2_hdr - > dest_subnodeid = UV_LB_SUBNODEID ;
uv2_hdr - > command = UV_NET_ENDPOINT_INTD ;
uv2_3_ hdr - > dest_subnodeid = UV_LB_SUBNODEID ;
uv2_3_ hdr - > command = UV_NET_ENDPOINT_INTD ;
}
}
for_each_present_cpu ( cpu ) {
@ -1858,6 +1861,7 @@ static int calculate_destination_timeout(void)
ts_ns * = ( mult1 * mult2 ) ;
ret = ts_ns / 1000 ;
} else {
/* same destination timeout for uv2 and uv3 */
/* 4 bits 0/1 for 10/80us base, 3 bits of multiplier */
mmr_image = uv_read_local_mmr ( UVH_LB_BAU_MISC_CONTROL ) ;
mmr_image = ( mmr_image & UV_SA_MASK ) > > UV_SA_SHFT ;
@ -2012,8 +2016,10 @@ static int scan_sock(struct socket_desc *sdp, struct uvhub_desc *bdp,
bcp - > uvhub_version = 1 ;
else if ( is_uv2_hub ( ) )
bcp - > uvhub_version = 2 ;
else if ( is_uv3_hub ( ) )
bcp - > uvhub_version = 3 ;
else {
printk ( KERN_EMERG " uvhub version not 1 or 2 \n " ) ;
printk ( KERN_EMERG " uvhub version not 1, 2 or 3 \n " ) ;
return 1 ;
}
bcp - > uvhub_master = * hmasterp ;
@ -2138,9 +2144,10 @@ static int __init uv_bau_init(void)
}
vector = UV_BAU_MESSAGE ;
for_each_possible_blade ( uvhub )
for_each_possible_blade ( uvhub ) {
if ( uv_blade_nr_possible_cpus ( uvhub ) )
init_uvhub ( uvhub , vector , uv_base_pnode ) ;
}
alloc_intr_gate ( vector , uv_bau_message_intr1 ) ;