xref: /inferno-os/os/boot/rpcg/archrpcg.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth #include	"u.h"
2*74a4d8c2SCharles.Forsyth #include	"lib.h"
3*74a4d8c2SCharles.Forsyth #include	"mem.h"
4*74a4d8c2SCharles.Forsyth #include	"dat.h"
5*74a4d8c2SCharles.Forsyth #include	"fns.h"
6*74a4d8c2SCharles.Forsyth #include	"io.h"
7*74a4d8c2SCharles.Forsyth 
8*74a4d8c2SCharles.Forsyth #include	"archrpcg.h"
9*74a4d8c2SCharles.Forsyth #include "etherif.h"
10*74a4d8c2SCharles.Forsyth 
11*74a4d8c2SCharles.Forsyth /*
12*74a4d8c2SCharles.Forsyth  * board-specific support for the RPCG RXLite
13*74a4d8c2SCharles.Forsyth  */
14*74a4d8c2SCharles.Forsyth 
15*74a4d8c2SCharles.Forsyth enum {
16*74a4d8c2SCharles.Forsyth 	SYSMHZ =	66,	/* target frequency */
17*74a4d8c2SCharles.Forsyth 
18*74a4d8c2SCharles.Forsyth 	/* sccr */
19*74a4d8c2SCharles.Forsyth 	RTSEL = IBIT(8),	/* =0, select main oscillator (OSCM); =1, select external crystal (EXTCLK) */
20*74a4d8c2SCharles.Forsyth 	RTDIV = IBIT(7),	/* =0, divide by 4; =1, divide by 512 */
21*74a4d8c2SCharles.Forsyth 	CRQEN = IBIT(9),	/* =1, switch to high frequency when CPM active */
22*74a4d8c2SCharles.Forsyth 	PRQEN = IBIT(10),	/* =1, switch to high frequency when interrupt pending */
23*74a4d8c2SCharles.Forsyth 
24*74a4d8c2SCharles.Forsyth 	/* plprcr */
25*74a4d8c2SCharles.Forsyth 	CSRC = IBIT(21),	/* =0, clock is DFNH; =1, clock is DFNL */
26*74a4d8c2SCharles.Forsyth };
27*74a4d8c2SCharles.Forsyth 
28*74a4d8c2SCharles.Forsyth static	char	flashsig[] = "RPXsignature=1.0\nNAME=qbrpcg\nSTART=FFC20100\nVERSION=1.1\n";
29*74a4d8c2SCharles.Forsyth static	char*	geteeprom(char*);
30*74a4d8c2SCharles.Forsyth 
31*74a4d8c2SCharles.Forsyth /*
32*74a4d8c2SCharles.Forsyth  * called early in main.c, after machinit:
33*74a4d8c2SCharles.Forsyth  * using board and architecture specific registers, initialise
34*74a4d8c2SCharles.Forsyth  * 8xx registers that need it and complete initialisation of the Mach structure.
35*74a4d8c2SCharles.Forsyth  */
36*74a4d8c2SCharles.Forsyth void
archinit(void)37*74a4d8c2SCharles.Forsyth archinit(void)
38*74a4d8c2SCharles.Forsyth {
39*74a4d8c2SCharles.Forsyth 	IMM *io;
40*74a4d8c2SCharles.Forsyth 	int mf, t;
41*74a4d8c2SCharles.Forsyth 	ulong v;
42*74a4d8c2SCharles.Forsyth 
43*74a4d8c2SCharles.Forsyth 	v = getimmr() & 0xFFFF;
44*74a4d8c2SCharles.Forsyth 	switch(v>>8){
45*74a4d8c2SCharles.Forsyth 	case 0x00:	t = 0x86000; break;
46*74a4d8c2SCharles.Forsyth 	case 0x20:	t = 0x82300; break;
47*74a4d8c2SCharles.Forsyth 	case 0x21:	t = 0x823a0; break;
48*74a4d8c2SCharles.Forsyth 	default:	t = 0; break;
49*74a4d8c2SCharles.Forsyth 	}
50*74a4d8c2SCharles.Forsyth 	m->cputype = t;
51*74a4d8c2SCharles.Forsyth 	m->bcsr = KADDR(BCSRMEM);
52*74a4d8c2SCharles.Forsyth 	io = m->iomem;
53*74a4d8c2SCharles.Forsyth 	m->clockgen = 8*MHz;
54*74a4d8c2SCharles.Forsyth 	mf = (io->plprcr >> 20)+1;	/* use timing set by bootstrap */
55*74a4d8c2SCharles.Forsyth 	m->cpuhz = m->clockgen*mf;
56*74a4d8c2SCharles.Forsyth 	m->bcsr[0] = DisableColTest | DisableFullDplx | DisableUSB | HighSpdUSB | LedOff;	/* first write enables bcsr regs */
57*74a4d8c2SCharles.Forsyth return;
58*74a4d8c2SCharles.Forsyth 	io->plprcrk = KEEP_ALIVE_KEY;
59*74a4d8c2SCharles.Forsyth 	io->plprcr &= ~CSRC;	/* general system clock is DFNH */
60*74a4d8c2SCharles.Forsyth /*	io->mptpr = 0x0800;	/* memory prescaler = 8 for refresh */
61*74a4d8c2SCharles.Forsyth 	/* use memory refresh time set by RPXLite monitor */
62*74a4d8c2SCharles.Forsyth 	io->plprcrk = ~KEEP_ALIVE_KEY;
63*74a4d8c2SCharles.Forsyth }
64*74a4d8c2SCharles.Forsyth 
65*74a4d8c2SCharles.Forsyth void
cpuidprint(void)66*74a4d8c2SCharles.Forsyth cpuidprint(void)
67*74a4d8c2SCharles.Forsyth {
68*74a4d8c2SCharles.Forsyth 	int t, v;
69*74a4d8c2SCharles.Forsyth 
70*74a4d8c2SCharles.Forsyth 	print("Inferno bootstrap\n");
71*74a4d8c2SCharles.Forsyth 	print("PVR: ");
72*74a4d8c2SCharles.Forsyth 	t = getpvr()>>16;
73*74a4d8c2SCharles.Forsyth 	switch(t){
74*74a4d8c2SCharles.Forsyth 	case 0x01:	print("MPC601"); break;
75*74a4d8c2SCharles.Forsyth 	case 0x03:	print("MPC603"); break;
76*74a4d8c2SCharles.Forsyth 	case 0x04:	print("MPC604"); break;
77*74a4d8c2SCharles.Forsyth 	case 0x06:	print("MPC603e"); break;
78*74a4d8c2SCharles.Forsyth 	case 0x07:	print("MPC603e-v7"); break;
79*74a4d8c2SCharles.Forsyth 	case 0x50:	print("MPC8xx"); break;
80*74a4d8c2SCharles.Forsyth 	default:	print("PowerPC version #%x", t); break;
81*74a4d8c2SCharles.Forsyth 	}
82*74a4d8c2SCharles.Forsyth 	print(", revision #%lux\n", getpvr()&0xffff);
83*74a4d8c2SCharles.Forsyth 	print("IMMR: ");
84*74a4d8c2SCharles.Forsyth 	v = getimmr() & 0xFFFF;
85*74a4d8c2SCharles.Forsyth 	switch(v>>8){
86*74a4d8c2SCharles.Forsyth 	case 0x00:	print("MPC860/821"); break;
87*74a4d8c2SCharles.Forsyth 	case 0x20:	print("MPC823"); break;
88*74a4d8c2SCharles.Forsyth 	case 0x21:	print("MPC823A"); break;
89*74a4d8c2SCharles.Forsyth 	default:	print("Type #%lux", v>>8); break;
90*74a4d8c2SCharles.Forsyth 	}
91*74a4d8c2SCharles.Forsyth 	print(", mask #%lux\n", v&0xFF);
92*74a4d8c2SCharles.Forsyth 	print("options: #%lux\n", archoptionsw());
93*74a4d8c2SCharles.Forsyth 	print("bcsr: %8.8lux\n", m->bcsr[0]);
94*74a4d8c2SCharles.Forsyth 	print("PLPRCR=%8.8lux SCCR=%8.8lux\n", m->iomem->plprcr, m->iomem->sccr);
95*74a4d8c2SCharles.Forsyth 	print("%lud MHz system\n", m->cpuhz/MHz);
96*74a4d8c2SCharles.Forsyth 	print("\n");
97*74a4d8c2SCharles.Forsyth //print("%s\n", geteeprom("EA"));
98*74a4d8c2SCharles.Forsyth print("BR0=%8.8lux OR0=%8.8lux\n", m->iomem->memc[0].base, m->iomem->memc[0].option);
99*74a4d8c2SCharles.Forsyth print("MPTPR=%8.8lux\n", m->iomem->mptpr);
100*74a4d8c2SCharles.Forsyth }
101*74a4d8c2SCharles.Forsyth 
102*74a4d8c2SCharles.Forsyth static	char*	defplan9ini[2] = {
103*74a4d8c2SCharles.Forsyth 	/* 860/821 */
104*74a4d8c2SCharles.Forsyth 	"ether0=type=SCC port=1 ea=0010ec000051\r\n"
105*74a4d8c2SCharles.Forsyth 	"vgasize=640x480x8\r\n"
106*74a4d8c2SCharles.Forsyth 	"kernelpercent=40\r\n"
107*74a4d8c2SCharles.Forsyth 	"console=0\r\nbaud=9600\r\n",
108*74a4d8c2SCharles.Forsyth 
109*74a4d8c2SCharles.Forsyth 	/* 823 */
110*74a4d8c2SCharles.Forsyth 	"ether0=type=SCC port=2 ea=0010ec000051\r\n"
111*74a4d8c2SCharles.Forsyth 	"vgasize=640x480x8\r\n"
112*74a4d8c2SCharles.Forsyth 	"kernelpercent=40\r\n"
113*74a4d8c2SCharles.Forsyth 	"console=0\r\nbaud=9600\r\n",
114*74a4d8c2SCharles.Forsyth };
115*74a4d8c2SCharles.Forsyth 
116*74a4d8c2SCharles.Forsyth char *
archconfig(void)117*74a4d8c2SCharles.Forsyth archconfig(void)
118*74a4d8c2SCharles.Forsyth {
119*74a4d8c2SCharles.Forsyth 	print("Using default configuration\n");
120*74a4d8c2SCharles.Forsyth 	return defplan9ini[MPCMODEL(m->cputype) == 0x823];
121*74a4d8c2SCharles.Forsyth }
122*74a4d8c2SCharles.Forsyth 
123*74a4d8c2SCharles.Forsyth /*
124*74a4d8c2SCharles.Forsyth  * provide value for #r/switch (devrtc.c)
125*74a4d8c2SCharles.Forsyth  */
126*74a4d8c2SCharles.Forsyth int
archoptionsw(void)127*74a4d8c2SCharles.Forsyth archoptionsw(void)
128*74a4d8c2SCharles.Forsyth {
129*74a4d8c2SCharles.Forsyth 	return (m->bcsr[0]&DipSwitchMask)>>4;
130*74a4d8c2SCharles.Forsyth }
131*74a4d8c2SCharles.Forsyth 
132*74a4d8c2SCharles.Forsyth /*
133*74a4d8c2SCharles.Forsyth  * invoked by clock.c:/^clockintr
134*74a4d8c2SCharles.Forsyth  */
135*74a4d8c2SCharles.Forsyth static void
twinkle(void)136*74a4d8c2SCharles.Forsyth twinkle(void)
137*74a4d8c2SCharles.Forsyth {
138*74a4d8c2SCharles.Forsyth 	if(m->ticks%MS2TK(1000) == 0)
139*74a4d8c2SCharles.Forsyth 		m->bcsr[0] ^= LedOff;
140*74a4d8c2SCharles.Forsyth }
141*74a4d8c2SCharles.Forsyth 
142*74a4d8c2SCharles.Forsyth void	(*archclocktick)(void) = twinkle;
143*74a4d8c2SCharles.Forsyth 
144*74a4d8c2SCharles.Forsyth /*
145*74a4d8c2SCharles.Forsyth  * for flash.c:/^flashreset
146*74a4d8c2SCharles.Forsyth  * retrieve flash type, virtual base and length and return 0;
147*74a4d8c2SCharles.Forsyth  * return -1 on error (no flash)
148*74a4d8c2SCharles.Forsyth  */
149*74a4d8c2SCharles.Forsyth int
archflashreset(char * type,void ** addr,long * length)150*74a4d8c2SCharles.Forsyth archflashreset(char *type, void **addr, long *length)
151*74a4d8c2SCharles.Forsyth {
152*74a4d8c2SCharles.Forsyth 	if((m->iomem->memc[BOOTCS].base & 1) == 0)
153*74a4d8c2SCharles.Forsyth 		return -1;		/* shouldn't happen */
154*74a4d8c2SCharles.Forsyth 	strcpy(type, "AMD29F0x0");
155*74a4d8c2SCharles.Forsyth 	*addr = KADDR(FLASHMEM);
156*74a4d8c2SCharles.Forsyth 	*length = 4*1024*1024;
157*74a4d8c2SCharles.Forsyth 	return 0;
158*74a4d8c2SCharles.Forsyth }
159*74a4d8c2SCharles.Forsyth 
160*74a4d8c2SCharles.Forsyth int
archether(int ctlrno,Card * ether)161*74a4d8c2SCharles.Forsyth archether(int ctlrno, Card *ether)
162*74a4d8c2SCharles.Forsyth {
163*74a4d8c2SCharles.Forsyth 	char *ea;
164*74a4d8c2SCharles.Forsyth 
165*74a4d8c2SCharles.Forsyth 	if(ctlrno > 0)
166*74a4d8c2SCharles.Forsyth 		return -1;
167*74a4d8c2SCharles.Forsyth 	strcpy(ether->type, "SCC");
168*74a4d8c2SCharles.Forsyth 	ether->port = 2;
169*74a4d8c2SCharles.Forsyth 	ea = geteeprom("EA");
170*74a4d8c2SCharles.Forsyth 	if(ea != nil)
171*74a4d8c2SCharles.Forsyth 		parseether(ether->ea, ea);
172*74a4d8c2SCharles.Forsyth 	return 1;
173*74a4d8c2SCharles.Forsyth }
174*74a4d8c2SCharles.Forsyth 
175*74a4d8c2SCharles.Forsyth /*
176*74a4d8c2SCharles.Forsyth  * enable the clocks for the given SCC ether and reveal them to the caller.
177*74a4d8c2SCharles.Forsyth  * do anything else required to prepare the transceiver (eg, set full-duplex, reset loopback).
178*74a4d8c2SCharles.Forsyth  */
179*74a4d8c2SCharles.Forsyth int
archetherenable(int cpmid,int * rcs,int * tcs)180*74a4d8c2SCharles.Forsyth archetherenable(int cpmid, int *rcs, int *tcs)
181*74a4d8c2SCharles.Forsyth {
182*74a4d8c2SCharles.Forsyth 	IMM *io;
183*74a4d8c2SCharles.Forsyth 
184*74a4d8c2SCharles.Forsyth 	switch(cpmid){
185*74a4d8c2SCharles.Forsyth 	default:
186*74a4d8c2SCharles.Forsyth 		/* no other SCCs are wired for ether on RPXLite*/
187*74a4d8c2SCharles.Forsyth 		return -1;
188*74a4d8c2SCharles.Forsyth 
189*74a4d8c2SCharles.Forsyth 	case SCC2ID:
190*74a4d8c2SCharles.Forsyth 		io = ioplock();
191*74a4d8c2SCharles.Forsyth 		m->bcsr[0] |= EnableEnet;
192*74a4d8c2SCharles.Forsyth 		io->papar |= SIBIT(6)|SIBIT(4);	/* enable CLK2 and CLK4 */
193*74a4d8c2SCharles.Forsyth 		io->padir &= ~(SIBIT(6)|SIBIT(4));
194*74a4d8c2SCharles.Forsyth 		*rcs = CLK4;
195*74a4d8c2SCharles.Forsyth 		*tcs = CLK2;
196*74a4d8c2SCharles.Forsyth 		iopunlock();
197*74a4d8c2SCharles.Forsyth 		break;
198*74a4d8c2SCharles.Forsyth 	}
199*74a4d8c2SCharles.Forsyth 	return 0;
200*74a4d8c2SCharles.Forsyth }
201*74a4d8c2SCharles.Forsyth 
202*74a4d8c2SCharles.Forsyth void
archetherdisable(int id)203*74a4d8c2SCharles.Forsyth archetherdisable(int id)
204*74a4d8c2SCharles.Forsyth {
205*74a4d8c2SCharles.Forsyth 	USED(id);
206*74a4d8c2SCharles.Forsyth 	m->bcsr[0] &= ~EnableEnet;
207*74a4d8c2SCharles.Forsyth }
208*74a4d8c2SCharles.Forsyth 
209*74a4d8c2SCharles.Forsyth /*
210*74a4d8c2SCharles.Forsyth  * do anything extra required to enable the UART on the given CPM port
211*74a4d8c2SCharles.Forsyth  */
212*74a4d8c2SCharles.Forsyth void
archenableuart(int id,int irda)213*74a4d8c2SCharles.Forsyth archenableuart(int id, int irda)
214*74a4d8c2SCharles.Forsyth {
215*74a4d8c2SCharles.Forsyth 	USED(id, irda);
216*74a4d8c2SCharles.Forsyth }
217*74a4d8c2SCharles.Forsyth 
218*74a4d8c2SCharles.Forsyth /*
219*74a4d8c2SCharles.Forsyth  * do anything extra required to disable the UART on the given CPM port
220*74a4d8c2SCharles.Forsyth  */
221*74a4d8c2SCharles.Forsyth void
archdisableuart(int id)222*74a4d8c2SCharles.Forsyth archdisableuart(int id)
223*74a4d8c2SCharles.Forsyth {
224*74a4d8c2SCharles.Forsyth 	USED(id);
225*74a4d8c2SCharles.Forsyth }
226*74a4d8c2SCharles.Forsyth 
227*74a4d8c2SCharles.Forsyth /*
228*74a4d8c2SCharles.Forsyth  * enable/disable the LCD panel's backlight
229*74a4d8c2SCharles.Forsyth  */
230*74a4d8c2SCharles.Forsyth void
archbacklight(int on)231*74a4d8c2SCharles.Forsyth archbacklight(int on)
232*74a4d8c2SCharles.Forsyth {
233*74a4d8c2SCharles.Forsyth 	USED(on);
234*74a4d8c2SCharles.Forsyth }
235*74a4d8c2SCharles.Forsyth 
236*74a4d8c2SCharles.Forsyth static char*
geteeprom(char * s)237*74a4d8c2SCharles.Forsyth geteeprom(char *s)
238*74a4d8c2SCharles.Forsyth {
239*74a4d8c2SCharles.Forsyth 	static int init;
240*74a4d8c2SCharles.Forsyth 	static char res[64];
241*74a4d8c2SCharles.Forsyth 	static uchar eeprom[257];
242*74a4d8c2SCharles.Forsyth 	uchar *l, *p;
243*74a4d8c2SCharles.Forsyth 	int i, j;
244*74a4d8c2SCharles.Forsyth 
245*74a4d8c2SCharles.Forsyth 	if(!init){
246*74a4d8c2SCharles.Forsyth 		i2csetup();
247*74a4d8c2SCharles.Forsyth 		if(i2crecv(0xa8|1|(0<<8), eeprom, 128) < 0 ||
248*74a4d8c2SCharles.Forsyth 		   i2crecv(0xa8|1|(128<<8), eeprom+128, 128) < 0){
249*74a4d8c2SCharles.Forsyth 			print("i2c failed\n");
250*74a4d8c2SCharles.Forsyth 			return nil;
251*74a4d8c2SCharles.Forsyth 		}
252*74a4d8c2SCharles.Forsyth 		if(0){
253*74a4d8c2SCharles.Forsyth 			print("eeprom:\n");
254*74a4d8c2SCharles.Forsyth 			for(i=0; i<16; i++){for(j=0; j<16; j++)print(" %2.2ux[%c]", eeprom[i*16+j], eeprom[i*16+j]); print("\n");}
255*74a4d8c2SCharles.Forsyth 		}
256*74a4d8c2SCharles.Forsyth 		eeprom[256] = 0xFF;
257*74a4d8c2SCharles.Forsyth 		init = 1;
258*74a4d8c2SCharles.Forsyth 	}
259*74a4d8c2SCharles.Forsyth 	for(l = eeprom; *l != 0xFF && *l != '\n';){
260*74a4d8c2SCharles.Forsyth 		p = l;
261*74a4d8c2SCharles.Forsyth 		while(*l != '\n' && *l != 0xFF && *l != '=')
262*74a4d8c2SCharles.Forsyth 			l++;
263*74a4d8c2SCharles.Forsyth 		if(*l == '='){
264*74a4d8c2SCharles.Forsyth 			if(l-p == strlen(s) && strncmp(s, (char*)p, strlen(s)) == 0){
265*74a4d8c2SCharles.Forsyth 				p = l+1;
266*74a4d8c2SCharles.Forsyth 				while(*l != '\n' && *l != 0xFF)
267*74a4d8c2SCharles.Forsyth 					l++;
268*74a4d8c2SCharles.Forsyth 				memmove(res, p, l-p);
269*74a4d8c2SCharles.Forsyth 				res[l-p] = 0;
270*74a4d8c2SCharles.Forsyth 				return res;
271*74a4d8c2SCharles.Forsyth 			}
272*74a4d8c2SCharles.Forsyth 		}
273*74a4d8c2SCharles.Forsyth 		while(*l != '\n' && *l != 0xFF)
274*74a4d8c2SCharles.Forsyth 			l++;
275*74a4d8c2SCharles.Forsyth 		if(*l == '\n')
276*74a4d8c2SCharles.Forsyth 			l++;
277*74a4d8c2SCharles.Forsyth 	}
278*74a4d8c2SCharles.Forsyth 	return nil;
279*74a4d8c2SCharles.Forsyth }
280