2006-02-10 15:47:36 +11:00
/*
* pSeries firmware setup code .
*
* Portions from arch / powerpc / platforms / pseries / setup . c :
* Copyright ( C ) 1995 Linus Torvalds
* Adapted from ' alpha ' version by Gary Thomas
* Modified by Cort Dougan ( cort @ cs . nmt . edu )
* Modified by PPC64 Team , IBM Corp
*
* Portions from arch / powerpc / kernel / firmware . c
* Copyright ( C ) 2001 Ben . Herrenschmidt ( benh @ kernel . crashing . org )
* Modifications for ppc64 :
* Copyright ( C ) 2003 Dave Engebretsen < engebret @ us . ibm . com >
* Copyright ( C ) 2005 Stephen Rothwell , IBM Corporation
*
* Copyright 2006 IBM Corporation .
*
* 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 ; either version
* 2 of the License , or ( at your option ) any later version .
*/
# include <asm/firmware.h>
# include <asm/prom.h>
2007-10-30 06:24:19 +11:00
# include <asm/udbg.h>
2006-02-10 15:47:36 +11:00
2008-05-08 14:27:21 +10:00
# include "pseries.h"
2006-02-10 15:47:36 +11:00
2013-04-24 05:57:18 +00:00
struct hypertas_fw_feature {
2006-02-10 15:47:36 +11:00
unsigned long val ;
char * name ;
2013-04-24 05:57:18 +00:00
} ;
2006-02-10 15:47:36 +11:00
2012-11-06 14:49:15 +00:00
/*
* The names in this table match names in rtas / ibm , hypertas - functions . If the
* entry ends in a ' * ' , only upto the ' * ' is matched . Otherwise the entire
* string must match .
*/
2013-04-24 05:57:18 +00:00
static __initdata struct hypertas_fw_feature
hypertas_fw_features_table [ ] = {
2006-02-10 15:47:36 +11:00
{ FW_FEATURE_PFT , " hcall-pft " } ,
{ FW_FEATURE_TCE , " hcall-tce " } ,
{ FW_FEATURE_SPRG0 , " hcall-sprg0 " } ,
{ FW_FEATURE_DABR , " hcall-dabr " } ,
{ FW_FEATURE_COPY , " hcall-copy " } ,
{ FW_FEATURE_ASR , " hcall-asr " } ,
{ FW_FEATURE_DEBUG , " hcall-debug " } ,
{ FW_FEATURE_PERF , " hcall-perf " } ,
{ FW_FEATURE_DUMP , " hcall-dump " } ,
{ FW_FEATURE_INTERRUPT , " hcall-interrupt " } ,
{ FW_FEATURE_MIGRATE , " hcall-migrate " } ,
{ FW_FEATURE_PERFMON , " hcall-perfmon " } ,
{ FW_FEATURE_CRQ , " hcall-crq " } ,
{ FW_FEATURE_VIO , " hcall-vio " } ,
{ FW_FEATURE_RDMA , " hcall-rdma " } ,
{ FW_FEATURE_LLAN , " hcall-lLAN " } ,
2009-10-11 21:47:34 +00:00
{ FW_FEATURE_BULK_REMOVE , " hcall-bulk " } ,
2006-02-10 15:47:36 +11:00
{ FW_FEATURE_XDABR , " hcall-xdabr " } ,
{ FW_FEATURE_MULTITCE , " hcall-multi-tce " } ,
{ FW_FEATURE_SPLPAR , " hcall-splpar " } ,
2010-11-09 13:24:48 +00:00
{ FW_FEATURE_VPHN , " hcall-vphn " } ,
2012-11-06 16:15:17 +11:00
{ FW_FEATURE_SET_MODE , " hcall-set-mode " } ,
2012-11-06 14:49:16 +00:00
{ FW_FEATURE_BEST_ENERGY , " hcall-best-energy-1* " } ,
2006-02-10 15:47:36 +11:00
} ;
/* Build up the firmware features bitmask using the contents of
* device - tree / ibm , hypertas - functions . Ultimately this functionality may
* be moved into prom . c prom_init ( ) .
*/
2013-04-24 05:57:18 +00:00
void __init fw_hypertas_feature_init ( const char * hypertas , unsigned long len )
2006-02-10 15:47:36 +11:00
{
2007-07-19 07:56:32 +10:00
const char * s ;
int i ;
2006-02-10 15:47:36 +11:00
2013-04-24 05:57:18 +00:00
pr_debug ( " -> fw_hypertas_feature_init() \n " ) ;
2006-02-10 15:47:36 +11:00
for ( s = hypertas ; s < hypertas + len ; s + = strlen ( s ) + 1 ) {
2013-04-24 05:57:18 +00:00
for ( i = 0 ; i < ARRAY_SIZE ( hypertas_fw_features_table ) ; i + + ) {
const char * name = hypertas_fw_features_table [ i ] . name ;
2012-11-06 14:49:15 +00:00
size_t size ;
2013-04-24 05:55:08 +00:00
2012-11-06 14:49:15 +00:00
/*
* If there is a ' * ' at the end of name , only check
* upto there
*/
size = strlen ( name ) ;
if ( size & & name [ size - 1 ] = = ' * ' ) {
if ( strncmp ( name , s , size - 1 ) )
continue ;
} else if ( strcmp ( name , s ) )
2006-02-10 15:47:36 +11:00
continue ;
/* we have a match */
2006-03-27 14:26:25 +11:00
powerpc_firmware_features | =
2013-04-24 05:57:18 +00:00
hypertas_fw_features_table [ i ] . val ;
2006-02-10 15:47:36 +11:00
break ;
}
}
2013-04-24 05:57:18 +00:00
pr_debug ( " <- fw_hypertas_feature_init() \n " ) ;
}
struct vec5_fw_feature {
unsigned long val ;
unsigned int feature ;
} ;
static __initdata struct vec5_fw_feature
vec5_fw_features_table [ ] = {
{ FW_FEATURE_TYPE1_AFFINITY , OV5_TYPE1_AFFINITY } ,
2013-04-24 06:00:35 +00:00
{ FW_FEATURE_PRRN , OV5_PRRN } ,
2013-04-24 05:57:18 +00:00
} ;
void __init fw_vec5_feature_init ( const char * vec5 , unsigned long len )
{
unsigned int index , feat ;
int i ;
pr_debug ( " -> fw_vec5_feature_init() \n " ) ;
for ( i = 0 ; i < ARRAY_SIZE ( vec5_fw_features_table ) ; i + + ) {
index = OV5_INDX ( vec5_fw_features_table [ i ] . feature ) ;
feat = OV5_FEAT ( vec5_fw_features_table [ i ] . feature ) ;
if ( vec5 [ index ] & feat )
powerpc_firmware_features | =
vec5_fw_features_table [ i ] . val ;
}
pr_debug ( " <- fw_vec5_feature_init() \n " ) ;
2006-02-10 15:47:36 +11:00
}