summaryrefslogtreecommitdiffstats
path: root/arch/mips/sgi/kernel/system.c
blob: 543fe82f2764a707dcee4956f3849cf770707357 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/*
 * system.c: Probe the system type using ARCS prom interface library.
 *
 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
 *
 * $Id: system.c,v 1.2 1997/06/28 22:47:45 ralf Exp $
 */
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/string.h>

#include <asm/sgi.h>
#include <asm/sgialib.h>
#include <asm/bootinfo.h>

#ifndef __GOGOGO__
#error "... You're fearless, aren't you?"
#endif

enum sgi_mach sgimach;

struct smatch {
	char *name;
	int type;
};

static struct smatch sgi_mtable[] = {
	{ "SGI-IP4", ip4 },
	{ "SGI-IP5", ip5 },
	{ "SGI-IP6", ip6 },
	{ "SGI-IP7", ip7 },
	{ "SGI-IP9", ip9 },
	{ "SGI-IP12", ip12 },
	{ "SGI-IP15", ip15 },
	{ "SGI-IP17", ip17 },
	{ "SGI-IP19", ip19 },
	{ "SGI-IP20", ip20 },
	{ "SGI-IP21", ip21 },
	{ "SGI-IP22", ip22 },
	{ "SGI-IP25", ip25 },
	{ "SGI-IP26", ip26 },
	{ "SGI-IP28", ip28 },
	{ "SGI-IP30", ip30 },
	{ "SGI-IP32", ip32 }
};

#define NUM_MACHS 17 /* for now */

static struct smatch sgi_cputable[] = {
	{ "MIPS-R2000", CPU_R2000 },
	{ "MIPS-R3000", CPU_R3000 },
	{ "MIPS-R3000A", CPU_R3000A },
	{ "MIPS-R4000", CPU_R4000SC },
	{ "MIPS-R4400", CPU_R4400SC },
	{ "MIPS-R4600", CPU_R4600 },
	{ "MIPS-R8000", CPU_R8000 },
	{ "MIPS-R5000", CPU_R5000 },
	{ "MIPS-R5000A", CPU_R5000A }
};

#define NUM_CPUS 9 /* for now */

static enum sgi_mach string_to_mach(char *s)
{
	int i;

	for(i = 0; i < NUM_MACHS; i++) {
		if(!strcmp(s, sgi_mtable[i].name))
			return (enum sgi_mach) sgi_mtable[i].type;
	}
	prom_printf("\nYeee, could not determine SGI architecture type <%s>\n", s);
	prom_printf("press a key to reboot\n");
	prom_getchar();
	romvec->imode();
	return (enum sgi_mach) 0;
}

static int string_to_cpu(char *s)
{
	int i;

	for(i = 0; i < NUM_CPUS; i++) {
		if(!strcmp(s, sgi_cputable[i].name))
			return sgi_mtable[i].type;
	}
	prom_printf("\nYeee, could not determine MIPS cpu type <%s>\n", s);
	prom_printf("press a key to reboot\n");
	prom_getchar();
	romvec->imode();
	return 0;
}

/*
 * We' call this early before loadmmu().  If we do the other way around
 * the firmware will crash and burn.
 */
void sgi_sysinit(void)
{
	pcomponent *p, *toplev, *cpup = 0;
	int cputype = -1;


	/* The root component tells us what machine architecture we
	 * have here.
	 */
	p = prom_getchild(PROM_NULL_COMPONENT);
	printk("ARCH: %s\n", p->iname);
	sgimach = string_to_mach(p->iname);

	/* Now scan for cpu(s). */
	toplev = p = prom_getchild(p);
	while(p) {
		int ncpus = 0;

		if(p->type == Cpu) {
			if(++ncpus > 1) {
				prom_printf("\nYeee, SGI MP not ready yet\n");
				prom_printf("press a key to reboot\n");
				prom_getchar();
				romvec->imode();
			}
			printk("CPU: %s ", p->iname);
			cpup = p;
			cputype = string_to_cpu(cpup->iname);
		}
		p = prom_getsibling(p);
	}
	if(cputype == -1) {
		prom_printf("\nYeee, could not find cpu ARCS component\n");
		prom_printf("press a key to reboot\n");
		prom_getchar();
		romvec->imode();
	}
	p = prom_getchild(cpup);
	while(p) {
		switch(p->class) {
		case processor:
			switch(p->type) {
			case Fpu:
				printk("FPU<%s> ", p->iname);
				break;

			default:
				break;
			};
			break;

		case cache:
			switch(p->type) {
			case picache:
				printk("ICACHE ");
				break;

			case pdcache:
				printk("DCACHE ");
				break;

			case sccache:
				printk("SCACHE ");
				break;

			default:
				break;

			};
			break;

		default:
			break;
		};
		p = prom_getsibling(p);
	}
	printk("\n");
}