xref: /linux/arch/sparc/kernel/idprom.c (revision 498495dba268b20e8eadd7fe93c140c68b6cc9d2)
1*b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2680e58f8SSam Ravnborg /*
3680e58f8SSam Ravnborg  * idprom.c: Routines to load the idprom into kernel addresses and
4680e58f8SSam Ravnborg  *           interpret the data contained within.
5680e58f8SSam Ravnborg  *
6680e58f8SSam Ravnborg  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
7680e58f8SSam Ravnborg  */
8680e58f8SSam Ravnborg 
9680e58f8SSam Ravnborg #include <linux/kernel.h>
10680e58f8SSam Ravnborg #include <linux/types.h>
11680e58f8SSam Ravnborg #include <linux/init.h>
12066bcacaSPaul Gortmaker #include <linux/export.h>
13c7f5d105SDavid S. Miller #include <linux/etherdevice.h>
14680e58f8SSam Ravnborg 
15680e58f8SSam Ravnborg #include <asm/oplib.h>
16680e58f8SSam Ravnborg #include <asm/idprom.h>
17680e58f8SSam Ravnborg 
18680e58f8SSam Ravnborg struct idprom *idprom;
196943f3daSSam Ravnborg EXPORT_SYMBOL(idprom);
206943f3daSSam Ravnborg 
21680e58f8SSam Ravnborg static struct idprom idprom_buffer;
22680e58f8SSam Ravnborg 
23680e58f8SSam Ravnborg #ifdef CONFIG_SPARC32
24680e58f8SSam Ravnborg #include <asm/machines.h>  /* Fun with Sun released architectures. */
25680e58f8SSam Ravnborg 
26680e58f8SSam Ravnborg /* Here is the master table of Sun machines which use some implementation
27680e58f8SSam Ravnborg  * of the Sparc CPU and have a meaningful IDPROM machtype value that we
28680e58f8SSam Ravnborg  * know about.  See asm-sparc/machines.h for empirical constants.
29680e58f8SSam Ravnborg  */
3058fa4dcbSDavid S. Miller static struct Sun_Machine_Models Sun_Machines[] = {
3158fa4dcbSDavid S. Miller /* First, Leon */
320fd7ef1fSKonrad Eisele { .name = "Leon3 System-on-a-Chip",  .id_machtype = (M_LEON | M_LEON3_SOC) },
33680e58f8SSam Ravnborg /* Finally, early Sun4m's */
34680e58f8SSam Ravnborg { .name = "Sun4m SparcSystem600",    .id_machtype = (SM_SUN4M | SM_4M_SS60) },
35680e58f8SSam Ravnborg { .name = "Sun4m SparcStation10/20", .id_machtype = (SM_SUN4M | SM_4M_SS50) },
36680e58f8SSam Ravnborg { .name = "Sun4m SparcStation5",     .id_machtype = (SM_SUN4M | SM_4M_SS40) },
37680e58f8SSam Ravnborg /* One entry for the OBP arch's which are sun4d, sun4e, and newer sun4m's */
38680e58f8SSam Ravnborg { .name = "Sun4M OBP based system",  .id_machtype = (SM_SUN4M_OBP | 0x0) } };
39680e58f8SSam Ravnborg 
display_system_type(unsigned char machtype)40680e58f8SSam Ravnborg static void __init display_system_type(unsigned char machtype)
41680e58f8SSam Ravnborg {
42680e58f8SSam Ravnborg 	char sysname[128];
43680e58f8SSam Ravnborg 	register int i;
44680e58f8SSam Ravnborg 
4558fa4dcbSDavid S. Miller 	for (i = 0; i < ARRAY_SIZE(Sun_Machines); i++) {
46680e58f8SSam Ravnborg 		if (Sun_Machines[i].id_machtype == machtype) {
47680e58f8SSam Ravnborg 			if (machtype != (SM_SUN4M_OBP | 0x00) ||
48680e58f8SSam Ravnborg 			    prom_getproperty(prom_root_node, "banner-name",
49680e58f8SSam Ravnborg 					     sysname, sizeof(sysname)) <= 0)
50680e58f8SSam Ravnborg 				printk(KERN_WARNING "TYPE: %s\n",
51680e58f8SSam Ravnborg 				       Sun_Machines[i].name);
52680e58f8SSam Ravnborg 			else
53680e58f8SSam Ravnborg 				printk(KERN_WARNING "TYPE: %s\n", sysname);
54680e58f8SSam Ravnborg 			return;
55680e58f8SSam Ravnborg 		}
56680e58f8SSam Ravnborg 	}
57680e58f8SSam Ravnborg 
58680e58f8SSam Ravnborg 	prom_printf("IDPROM: Warning, bogus id_machtype value, 0x%x\n", machtype);
59680e58f8SSam Ravnborg }
60680e58f8SSam Ravnborg #else
display_system_type(unsigned char machtype)61680e58f8SSam Ravnborg static void __init display_system_type(unsigned char machtype)
62680e58f8SSam Ravnborg {
63680e58f8SSam Ravnborg }
64680e58f8SSam Ravnborg #endif
65c7f5d105SDavid S. Miller 
arch_get_platform_mac_address(void)66c7f5d105SDavid S. Miller unsigned char *arch_get_platform_mac_address(void)
67c7f5d105SDavid S. Miller {
68c7f5d105SDavid S. Miller 	return idprom->id_ethaddr;
69c7f5d105SDavid S. Miller }
70c7f5d105SDavid S. Miller 
71680e58f8SSam Ravnborg /* Calculate the IDPROM checksum (xor of the data bytes). */
calc_idprom_cksum(struct idprom * idprom)72680e58f8SSam Ravnborg static unsigned char __init calc_idprom_cksum(struct idprom *idprom)
73680e58f8SSam Ravnborg {
74680e58f8SSam Ravnborg 	unsigned char cksum, i, *ptr = (unsigned char *)idprom;
75680e58f8SSam Ravnborg 
76680e58f8SSam Ravnborg 	for (i = cksum = 0; i <= 0x0E; i++)
77680e58f8SSam Ravnborg 		cksum ^= *ptr++;
78680e58f8SSam Ravnborg 
79680e58f8SSam Ravnborg 	return cksum;
80680e58f8SSam Ravnborg }
81680e58f8SSam Ravnborg 
82680e58f8SSam Ravnborg /* Create a local IDPROM copy, verify integrity, and display information. */
idprom_init(void)83680e58f8SSam Ravnborg void __init idprom_init(void)
84680e58f8SSam Ravnborg {
85680e58f8SSam Ravnborg 	prom_get_idprom((char *) &idprom_buffer, sizeof(idprom_buffer));
86680e58f8SSam Ravnborg 
87680e58f8SSam Ravnborg 	idprom = &idprom_buffer;
88680e58f8SSam Ravnborg 
89680e58f8SSam Ravnborg 	if (idprom->id_format != 0x01)
90680e58f8SSam Ravnborg 		prom_printf("IDPROM: Warning, unknown format type!\n");
91680e58f8SSam Ravnborg 
92680e58f8SSam Ravnborg 	if (idprom->id_cksum != calc_idprom_cksum(idprom))
93680e58f8SSam Ravnborg 		prom_printf("IDPROM: Warning, checksum failure (nvram=%x, calc=%x)!\n",
94680e58f8SSam Ravnborg 			    idprom->id_cksum, calc_idprom_cksum(idprom));
95680e58f8SSam Ravnborg 
96680e58f8SSam Ravnborg 	display_system_type(idprom->id_machtype);
97680e58f8SSam Ravnborg 
98e3c6d4eeSDavid S. Miller 	printk(KERN_WARNING "Ethernet address: %pM\n", idprom->id_ethaddr);
99680e58f8SSam Ravnborg }
100