2008-07-17 23:16:08 +04:00
/*
2005-04-17 02:20:36 +04:00
* idprom . c : Routines to load the idprom into kernel addresses and
* interpret the data contained within .
*
* Copyright ( C ) 1995 David S . Miller ( davem @ caip . rutgers . edu )
* Sun3 / 3 x models added by David Monro ( davidm @ psrg . cs . usyd . edu . au )
*/
2006-10-11 20:28:27 +04:00
# include <linux/module.h>
2005-04-17 02:20:36 +04:00
# include <linux/kernel.h>
# include <linux/types.h>
# include <linux/init.h>
# include <linux/string.h>
# include <asm/oplib.h>
# include <asm/idprom.h>
# include <asm/machines.h> /* Fun with Sun released architectures. */
struct idprom * idprom ;
2006-10-11 20:28:27 +04:00
EXPORT_SYMBOL ( idprom ) ;
2005-04-17 02:20:36 +04:00
static struct idprom idprom_buffer ;
/* Here is the master table of Sun machines which use some implementation
* of the Sparc CPU and have a meaningful IDPROM machtype value that we
* know about . See asm - sparc / machines . h for empirical constants .
*/
2008-07-17 23:16:27 +04:00
static struct Sun_Machine_Models Sun_Machines [ NUM_SUN_MACHINES ] = {
2005-04-17 02:20:36 +04:00
/* First, Sun3's */
{ . name = " Sun 3/160 Series " , . id_machtype = ( SM_SUN3 | SM_3_160 ) } ,
{ . name = " Sun 3/50 " , . id_machtype = ( SM_SUN3 | SM_3_50 ) } ,
{ . name = " Sun 3/260 Series " , . id_machtype = ( SM_SUN3 | SM_3_260 ) } ,
{ . name = " Sun 3/110 Series " , . id_machtype = ( SM_SUN3 | SM_3_110 ) } ,
{ . name = " Sun 3/60 " , . id_machtype = ( SM_SUN3 | SM_3_60 ) } ,
{ . name = " Sun 3/E " , . id_machtype = ( SM_SUN3 | SM_3_E ) } ,
/* Now, Sun3x's */
{ . name = " Sun 3/460 Series " , . id_machtype = ( SM_SUN3X | SM_3_460 ) } ,
{ . name = " Sun 3/80 " , . id_machtype = ( SM_SUN3X | SM_3_80 ) } ,
/* Then, Sun4's */
// { .name = "Sun 4/100 Series", .id_machtype = (SM_SUN4 | SM_4_110) },
// { .name = "Sun 4/200 Series", .id_machtype = (SM_SUN4 | SM_4_260) },
// { .name = "Sun 4/300 Series", .id_machtype = (SM_SUN4 | SM_4_330) },
// { .name = "Sun 4/400 Series", .id_machtype = (SM_SUN4 | SM_4_470) },
/* And now, Sun4c's */
// { .name = "Sun4c SparcStation 1", .id_machtype = (SM_SUN4C | SM_4C_SS1) },
// { .name = "Sun4c SparcStation IPC", .id_machtype = (SM_SUN4C | SM_4C_IPC) },
// { .name = "Sun4c SparcStation 1+", .id_machtype = (SM_SUN4C | SM_4C_SS1PLUS) },
// { .name = "Sun4c SparcStation SLC", .id_machtype = (SM_SUN4C | SM_4C_SLC) },
// { .name = "Sun4c SparcStation 2", .id_machtype = (SM_SUN4C | SM_4C_SS2) },
// { .name = "Sun4c SparcStation ELC", .id_machtype = (SM_SUN4C | SM_4C_ELC) },
// { .name = "Sun4c SparcStation IPX", .id_machtype = (SM_SUN4C | SM_4C_IPX) },
/* Finally, early Sun4m's */
// { .name = "Sun4m SparcSystem600", .id_machtype = (SM_SUN4M | SM_4M_SS60) },
// { .name = "Sun4m SparcStation10/20", .id_machtype = (SM_SUN4M | SM_4M_SS50) },
// { .name = "Sun4m SparcStation5", .id_machtype = (SM_SUN4M | SM_4M_SS40) },
/* One entry for the OBP arch's which are sun4d, sun4e, and newer sun4m's */
// { .name = "Sun4M OBP based system", .id_machtype = (SM_SUN4M_OBP | 0x0) }
} ;
static void __init display_system_type ( unsigned char machtype )
{
register int i ;
for ( i = 0 ; i < NUM_SUN_MACHINES ; i + + ) {
if ( Sun_Machines [ i ] . id_machtype = = machtype ) {
if ( machtype ! = ( SM_SUN4M_OBP | 0x00 ) )
printk ( " TYPE: %s \n " , Sun_Machines [ i ] . name ) ;
else {
#if 0
prom_getproperty ( prom_root_node , " banner-name " ,
sysname , sizeof ( sysname ) ) ;
printk ( " TYPE: %s \n " , sysname ) ;
# endif
}
return ;
}
}
prom_printf ( " IDPROM: Bogus id_machtype value, 0x%x \n " , machtype ) ;
prom_halt ( ) ;
}
void sun3_get_model ( unsigned char * model )
{
register int i ;
for ( i = 0 ; i < NUM_SUN_MACHINES ; i + + ) {
if ( Sun_Machines [ i ] . id_machtype = = idprom - > id_machtype ) {
strcpy ( model , Sun_Machines [ i ] . name ) ;
return ;
}
}
}
/* Calculate the IDPROM checksum (xor of the data bytes). */
static unsigned char __init calc_idprom_cksum ( struct idprom * idprom )
{
unsigned char cksum , i , * ptr = ( unsigned char * ) idprom ;
for ( i = cksum = 0 ; i < = 0x0E ; i + + )
cksum ^ = * ptr + + ;
return cksum ;
}
/* Create a local IDPROM copy, verify integrity, and display information. */
void __init idprom_init ( void )
{
prom_get_idprom ( ( char * ) & idprom_buffer , sizeof ( idprom_buffer ) ) ;
idprom = & idprom_buffer ;
if ( idprom - > id_format ! = 0x01 ) {
prom_printf ( " IDPROM: Unknown format type! \n " ) ;
prom_halt ( ) ;
}
if ( idprom - > id_cksum ! = calc_idprom_cksum ( idprom ) ) {
prom_printf ( " IDPROM: Checksum failure (nvram=%x, calc=%x)! \n " ,
idprom - > id_cksum , calc_idprom_cksum ( idprom ) ) ;
prom_halt ( ) ;
}
display_system_type ( idprom - > id_machtype ) ;
printk ( " Ethernet address: %x:%x:%x:%x:%x:%x \n " ,
idprom - > id_ethaddr [ 0 ] , idprom - > id_ethaddr [ 1 ] ,
idprom - > id_ethaddr [ 2 ] , idprom - > id_ethaddr [ 3 ] ,
idprom - > id_ethaddr [ 4 ] , idprom - > id_ethaddr [ 5 ] ) ;
}