// SPDX-License-Identifier: GPL-2.01/*2* idprom.c: Routines to load the idprom into kernel addresses and3* interpret the data contained within.4*5* Copyright (C) 1995 David S. Miller ([email protected])6* Sun3/3x models added by David Monro ([email protected])7*/89#include <linux/module.h>10#include <linux/kernel.h>11#include <linux/types.h>12#include <linux/init.h>13#include <linux/string.h>1415#include <asm/oplib.h>16#include <asm/idprom.h>17#include <asm/machines.h> /* Fun with Sun released architectures. */1819#include "sun3.h"2021struct idprom *idprom;22EXPORT_SYMBOL(idprom);2324static struct idprom idprom_buffer;2526/* Here is the master table of Sun machines which use some implementation27* of the Sparc CPU and have a meaningful IDPROM machtype value that we28* know about. See asm-sparc/machines.h for empirical constants.29*/30static struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES] = {31/* First, Sun3's */32{ .name = "Sun 3/160 Series", .id_machtype = (SM_SUN3 | SM_3_160) },33{ .name = "Sun 3/50", .id_machtype = (SM_SUN3 | SM_3_50) },34{ .name = "Sun 3/260 Series", .id_machtype = (SM_SUN3 | SM_3_260) },35{ .name = "Sun 3/110 Series", .id_machtype = (SM_SUN3 | SM_3_110) },36{ .name = "Sun 3/60", .id_machtype = (SM_SUN3 | SM_3_60) },37{ .name = "Sun 3/E", .id_machtype = (SM_SUN3 | SM_3_E) },38/* Now, Sun3x's */39{ .name = "Sun 3/460 Series", .id_machtype = (SM_SUN3X | SM_3_460) },40{ .name = "Sun 3/80", .id_machtype = (SM_SUN3X | SM_3_80) },41/* Then, Sun4's */42// { .name = "Sun 4/100 Series", .id_machtype = (SM_SUN4 | SM_4_110) },43// { .name = "Sun 4/200 Series", .id_machtype = (SM_SUN4 | SM_4_260) },44// { .name = "Sun 4/300 Series", .id_machtype = (SM_SUN4 | SM_4_330) },45// { .name = "Sun 4/400 Series", .id_machtype = (SM_SUN4 | SM_4_470) },46/* And now, Sun4c's */47// { .name = "Sun4c SparcStation 1", .id_machtype = (SM_SUN4C | SM_4C_SS1) },48// { .name = "Sun4c SparcStation IPC", .id_machtype = (SM_SUN4C | SM_4C_IPC) },49// { .name = "Sun4c SparcStation 1+", .id_machtype = (SM_SUN4C | SM_4C_SS1PLUS) },50// { .name = "Sun4c SparcStation SLC", .id_machtype = (SM_SUN4C | SM_4C_SLC) },51// { .name = "Sun4c SparcStation 2", .id_machtype = (SM_SUN4C | SM_4C_SS2) },52// { .name = "Sun4c SparcStation ELC", .id_machtype = (SM_SUN4C | SM_4C_ELC) },53// { .name = "Sun4c SparcStation IPX", .id_machtype = (SM_SUN4C | SM_4C_IPX) },54/* Finally, early Sun4m's */55// { .name = "Sun4m SparcSystem600", .id_machtype = (SM_SUN4M | SM_4M_SS60) },56// { .name = "Sun4m SparcStation10/20", .id_machtype = (SM_SUN4M | SM_4M_SS50) },57// { .name = "Sun4m SparcStation5", .id_machtype = (SM_SUN4M | SM_4M_SS40) },58/* One entry for the OBP arch's which are sun4d, sun4e, and newer sun4m's */59// { .name = "Sun4M OBP based system", .id_machtype = (SM_SUN4M_OBP | 0x0) }60};6162static void __init display_system_type(unsigned char machtype)63{64register int i;6566for (i = 0; i < NUM_SUN_MACHINES; i++) {67if(Sun_Machines[i].id_machtype == machtype) {68if (machtype != (SM_SUN4M_OBP | 0x00))69pr_info("TYPE: %s\n", Sun_Machines[i].name);70else {71#if 072char sysname[128];7374prom_getproperty(prom_root_node, "banner-name",75sysname, sizeof(sysname));76pr_info("TYPE: %s\n", sysname);77#endif78}79return;80}81}8283prom_printf("IDPROM: Bogus id_machtype value, 0x%x\n", machtype);84prom_halt();85}8687void sun3_get_model(char *model)88{89register int i;9091for (i = 0; i < NUM_SUN_MACHINES; i++) {92if(Sun_Machines[i].id_machtype == idprom->id_machtype) {93strcpy(model, Sun_Machines[i].name);94return;95}96}97}9899100101/* Calculate the IDPROM checksum (xor of the data bytes). */102static unsigned char __init calc_idprom_cksum(struct idprom *idprom)103{104unsigned char cksum, i, *ptr = (unsigned char *)idprom;105106for (i = cksum = 0; i <= 0x0E; i++)107cksum ^= *ptr++;108109return cksum;110}111112/* Create a local IDPROM copy, verify integrity, and display information. */113void __init idprom_init(void)114{115prom_get_idprom((char *) &idprom_buffer, sizeof(idprom_buffer));116117idprom = &idprom_buffer;118119if (idprom->id_format != 0x01) {120prom_printf("IDPROM: Unknown format type!\n");121prom_halt();122}123124if (idprom->id_cksum != calc_idprom_cksum(idprom)) {125prom_printf("IDPROM: Checksum failure (nvram=%x, calc=%x)!\n",126idprom->id_cksum, calc_idprom_cksum(idprom));127prom_halt();128}129130display_system_type(idprom->id_machtype);131132pr_info("Ethernet address: %pM\n", idprom->id_ethaddr);133}134135136