1 |
1624 |
jcastillo |
/* $Id: idprom.c,v 1.1 2005-12-20 09:50:43 jcastillo Exp $
|
2 |
|
|
* idprom.c: Routines to load the idprom into kernel addresses and
|
3 |
|
|
* interpret the data contained within.
|
4 |
|
|
*
|
5 |
|
|
* Because they use the IDPROM's machine type field, some of the
|
6 |
|
|
* virtual address cache probings on the sun4c are done here.
|
7 |
|
|
*
|
8 |
|
|
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
9 |
|
|
*/
|
10 |
|
|
|
11 |
|
|
#include <linux/kernel.h>
|
12 |
|
|
#include <linux/types.h>
|
13 |
|
|
|
14 |
|
|
#include <asm/oplib.h>
|
15 |
|
|
#include <asm/idprom.h>
|
16 |
|
|
#include <asm/machines.h> /* Fun with Sun released architectures. */
|
17 |
|
|
#include <asm/system.h> /* For halt() macro */
|
18 |
|
|
|
19 |
|
|
struct idp_struct *idprom;
|
20 |
|
|
static struct idp_struct idprom_buff;
|
21 |
|
|
|
22 |
|
|
/* Here is the master table of Sun machines which use some implementation
|
23 |
|
|
* of the Sparc CPU and have a meaningful IDPROM machtype value that we
|
24 |
|
|
* know about. See asm-sparc/machines.h for empirical constants.
|
25 |
|
|
*/
|
26 |
|
|
struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES] = {
|
27 |
|
|
/* First, Sun4's */
|
28 |
|
|
{ "Sun 4/100 Series", (SM_SUN4 | SM_4_110) },
|
29 |
|
|
{ "Sun 4/200 Series", (SM_SUN4 | SM_4_260) },
|
30 |
|
|
{ "Sun 4/300 Series", (SM_SUN4 | SM_4_330) },
|
31 |
|
|
{ "Sun 4/400 Series", (SM_SUN4 | SM_4_470) },
|
32 |
|
|
/* Now, Sun4c's */
|
33 |
|
|
{ "Sun4c SparcStation 1", (SM_SUN4C | SM_4C_SS1) },
|
34 |
|
|
{ "Sun4c SparcStation IPC", (SM_SUN4C | SM_4C_IPC) },
|
35 |
|
|
{ "Sun4c SparcStation 1+", (SM_SUN4C | SM_4C_SS1PLUS) },
|
36 |
|
|
{ "Sun4c SparcStation SLC", (SM_SUN4C | SM_4C_SLC) },
|
37 |
|
|
{ "Sun4c SparcStation 2", (SM_SUN4C | SM_4C_SS2) },
|
38 |
|
|
{ "Sun4c SparcStation ELC", (SM_SUN4C | SM_4C_ELC) },
|
39 |
|
|
{ "Sun4c SparcStation IPX", (SM_SUN4C | SM_4C_IPX) },
|
40 |
|
|
/* Finally, early Sun4m's */
|
41 |
|
|
{ "Sun4m SparcSystem600", (SM_SUN4M | SM_4M_SS60) },
|
42 |
|
|
{ "Sun4m SparcStation10", (SM_SUN4M | SM_4M_SS50) },
|
43 |
|
|
{ "Sun4m SparcStation5", (SM_SUN4M | SM_4M_SS40) },
|
44 |
|
|
/* One entry for the OBP arch's which are sun4d, sun4e, and newer sun4m's */
|
45 |
|
|
{ "Sun4M OBP based system", (SM_SUN4M_OBP | 0x0) } };
|
46 |
|
|
|
47 |
|
|
void
|
48 |
|
|
sparc_display_systype(unsigned char machtyp)
|
49 |
|
|
{
|
50 |
|
|
char system_name[128];
|
51 |
|
|
int i;
|
52 |
|
|
|
53 |
|
|
for(i = 0; i<NUM_SUN_MACHINES; i++) {
|
54 |
|
|
if(Sun_Machines[i].id_machtype == machtyp) {
|
55 |
|
|
if(machtyp!=(SM_SUN4M_OBP | 0x0)) {
|
56 |
|
|
printk("TYPE: %s\n", Sun_Machines[i].name);
|
57 |
|
|
break;
|
58 |
|
|
} else {
|
59 |
|
|
prom_getproperty(prom_root_node, "banner-name",
|
60 |
|
|
system_name, sizeof(system_name));
|
61 |
|
|
printk("TYPE: %s\n", system_name);
|
62 |
|
|
break;
|
63 |
|
|
}
|
64 |
|
|
}
|
65 |
|
|
}
|
66 |
|
|
if(i == NUM_SUN_MACHINES)
|
67 |
|
|
printk("Uh oh, IDPROM had bogus id_machtype value <%x>\n", machtyp);
|
68 |
|
|
return;
|
69 |
|
|
}
|
70 |
|
|
|
71 |
|
|
void
|
72 |
|
|
get_idprom(void)
|
73 |
|
|
{
|
74 |
|
|
prom_getidp((char *) &idprom_buff, sizeof(idprom_buff));
|
75 |
|
|
|
76 |
|
|
idprom = &idprom_buff;
|
77 |
|
|
|
78 |
|
|
sparc_display_systype(idprom->id_machtype);
|
79 |
|
|
|
80 |
|
|
printk("Ethernet address: %x:%x:%x:%x:%x:%x\n",
|
81 |
|
|
idprom->id_eaddr[0], idprom->id_eaddr[1], idprom->id_eaddr[2],
|
82 |
|
|
idprom->id_eaddr[3], idprom->id_eaddr[4], idprom->id_eaddr[5]);
|
83 |
|
|
|
84 |
|
|
return;
|
85 |
|
|
}
|
86 |
|
|
|
87 |
|
|
/* find_vac_size() returns the number of bytes in the VAC (virtual
|
88 |
|
|
* address cache) on this machine.
|
89 |
|
|
*/
|
90 |
|
|
|
91 |
|
|
int
|
92 |
|
|
find_vac_size(void)
|
93 |
|
|
{
|
94 |
|
|
int vac_prop_len;
|
95 |
|
|
int vacsize = 0;
|
96 |
|
|
|
97 |
|
|
vac_prop_len = prom_getproplen(prom_root_node, "vac-size");
|
98 |
|
|
if(vac_prop_len != -1) {
|
99 |
|
|
vacsize = prom_getint(prom_root_node, "vac-size");
|
100 |
|
|
return vacsize;
|
101 |
|
|
} else {
|
102 |
|
|
switch(idprom->id_machtype) {
|
103 |
|
|
case (SM_SUN4C | SM_4C_SS1): /* SparcStation1 */
|
104 |
|
|
case (SM_SUN4C | SM_4C_IPC): /* SparcStation IPX */
|
105 |
|
|
case (SM_SUN4C | SM_4C_SS1PLUS): /* SparcStation1+ */
|
106 |
|
|
case (SM_SUN4C | SM_4C_SLC): /* SparcStation SLC */
|
107 |
|
|
case (SM_SUN4C | SM_4C_SS2): /* SparcStation2 Cache-Chip BUG! */
|
108 |
|
|
case (SM_SUN4C | SM_4C_ELC): /* SparcStation ELC */
|
109 |
|
|
case (SM_SUN4C | SM_4C_IPX): /* SparcStation IPX */
|
110 |
|
|
return 65536;
|
111 |
|
|
default:
|
112 |
|
|
printk("find_vac_size: Can't determine size of VAC, bailing out...\n");
|
113 |
|
|
halt();
|
114 |
|
|
break;
|
115 |
|
|
};
|
116 |
|
|
};
|
117 |
|
|
return -1;
|
118 |
|
|
}
|
119 |
|
|
|
120 |
|
|
/* find_vac_linesize() returns the size in bytes of the VAC linesize */
|
121 |
|
|
|
122 |
|
|
int
|
123 |
|
|
find_vac_linesize(void)
|
124 |
|
|
{
|
125 |
|
|
int vac_prop_len;
|
126 |
|
|
|
127 |
|
|
vac_prop_len = prom_getproplen(prom_root_node, "vac-linesize");
|
128 |
|
|
|
129 |
|
|
if(vac_prop_len != -1)
|
130 |
|
|
return prom_getint(prom_root_node, "vac-linesize");
|
131 |
|
|
else {
|
132 |
|
|
switch(idprom->id_machtype) {
|
133 |
|
|
case (SM_SUN4C | SM_4C_SS1): /* SparcStation1 */
|
134 |
|
|
case (SM_SUN4C | SM_4C_IPC): /* SparcStation IPC */
|
135 |
|
|
case (SM_SUN4C | SM_4C_SS1PLUS): /* SparcStation1+ */
|
136 |
|
|
case (SM_SUN4C | SM_4C_SLC): /* SparcStation SLC */
|
137 |
|
|
return 16;
|
138 |
|
|
case (SM_SUN4C | SM_4C_SS2): /* SparcStation2 Cache-Chip BUG! */
|
139 |
|
|
case (SM_SUN4C | SM_4C_ELC): /* SparcStation ELC */
|
140 |
|
|
case (SM_SUN4C | SM_4C_IPX): /* SparcStation IPX */
|
141 |
|
|
return 32;
|
142 |
|
|
default:
|
143 |
|
|
printk("find_vac_linesize: Can't determine VAC linesize, bailing out...\n");
|
144 |
|
|
halt();
|
145 |
|
|
break;
|
146 |
|
|
};
|
147 |
|
|
};
|
148 |
|
|
return -1;
|
149 |
|
|
}
|
150 |
|
|
|
151 |
|
|
int
|
152 |
|
|
find_vac_hwflushes(void)
|
153 |
|
|
{
|
154 |
|
|
register int len;
|
155 |
|
|
int tmp1, tmp2;
|
156 |
|
|
|
157 |
|
|
/* Sun 4/75 has typo in prom_node, it's a dash instead of an underscore
|
158 |
|
|
* in the property name. :-(
|
159 |
|
|
*/
|
160 |
|
|
len = prom_getproperty(prom_root_node, "vac_hwflush",
|
161 |
|
|
(char *) &tmp1, sizeof(int));
|
162 |
|
|
if(len != 4) tmp1=0;
|
163 |
|
|
|
164 |
|
|
len = prom_getproperty(prom_root_node, "vac-hwflush",
|
165 |
|
|
(char *) &tmp2, sizeof(int));
|
166 |
|
|
if(len != 4) tmp2=0;
|
167 |
|
|
|
168 |
|
|
return (tmp1|tmp2);
|
169 |
|
|
}
|
170 |
|
|
|