xref: /plan9/sys/src/cmd/va/l.s (revision 3e12c5d1bb89fc02707907988834ef147769ddaf)
1/*
2 * Memory and machine-specific definitions.  Used in C and assembler.
3 */
4
5/*
6 * Sizes
7 */
8
9#define	BI2BY		8			/* bits per byte */
10#define BI2WD		32			/* bits per word */
11#define	BY2WD		4			/* bytes per word */
12#define	BY2PG		4096			/* bytes per page */
13#define	WD2PG		(BY2PG/BY2WD)		/* words per page */
14#define	PGSHIFT		12			/* log(BY2PG) */
15
16#define	MAXMACH		4			/* max # cpus system can run */
17
18/*
19 * Time
20 */
21#define	MS2HZ		50			/* millisec per clock tick */
22#define	TK2SEC(t)	((t)/20)		/* ticks to seconds */
23#define	TK2MS(t)	((t)*MS2HZ)		/* ticks to milliseconds */
24#define	MS2TK(t)	((t)/MS2HZ)		/* milliseconds to ticks */
25
26/*
27 * CP0 registers
28 */
29
30#define INDEX		0
31#define RANDOM		1
32#define TLBPHYS		2
33#define CONTEXT		4
34#define BADVADDR	8
35#define TLBVIRT		10
36#define STATUS		12
37#define CAUSE		13
38#define EPC		14
39#define	PRID		15
40
41/*
42 * M(STATUS) bits
43 */
44#define IEC		0x00000001
45#define KUC		0x00000002
46#define IEP		0x00000004
47#define KUP		0x00000008
48#define INTMASK		0x0000ff00
49#define SW0		0x00000100
50#define SW1		0x00000200
51#define INTR0		0x00000400
52#define INTR1		0x00000800
53#define INTR2		0x00001000
54#define INTR3		0x00002000
55#define INTR4		0x00004000
56#define INTR5		0x00008000
57#define ISC		0x00010000
58#define SWC		0x00020000
59#define CU1		0x20000000
60
61/*
62 * Traps
63 */
64
65#define	UTLBMISS	(KSEG0+0x00)
66#define	EXCEPTION	(KSEG0+0x80)
67
68/*
69 * Magic registers
70 */
71
72#define	MACH		25		/* R25 is m-> */
73#define	USER		24		/* R24 is u-> */
74#define	MPID		0xBF000000	/* long; low 3 bits identify mp bus slot */
75#define WBFLUSH		0xBC000000	/* D-CACHE data; used for write buffer flush */
76
77/*
78 * Fundamental addresses
79 */
80
81#define	MACHADDR	0x80014000
82#define	USERADDR	0xC0000000
83#define	UREGADDR	(USERADDR+BY2PG-4-0xA0)
84/*
85 * MMU
86 */
87
88#define	KUSEG	0x00000000
89#define KSEG0	0x80000000
90#define KSEG1	0xA0000000
91#define	KSEG2	0xC0000000
92#define	KSEGM	0xE0000000	/* mask to check which seg */
93
94#define	PTEGLOBL	(1<<8)
95#define	PTEVALID	(1<<9)
96#define	PTEWRITE	(1<<10)
97#define	PTEPID(n)	((n)<<6)
98
99#define	NTLBPID	64	/* number of pids */
100#define	NTLB	64	/* number of entries */
101#define	TLBROFF	8	/* offset of first randomly indexed entry */
102
103/*
104 * Address spaces
105 */
106
107#define	UZERO	KUSEG			/* base of user address space */
108#define	UTZERO	(UZERO+BY2PG)		/* first address in user text */
109#define	USTKTOP	KZERO			/* byte just beyond user stack */
110#define	TSTKTOP	(USERADDR+100*BY2PG)	/* top of temporary stack */
111#define	KZERO	KSEG0			/* base of kernel address space */
112#define	KTZERO	(KSEG0+0x20000)		/* first address in kernel text */
113#define	USTACKSIZE	(4*1024*1024)	/* size of user stack */
114/*
115 * Exception codes
116 */
117#define	CINT	 0		/* external interrupt */
118#define	CTLBM	 1		/* TLB modification */
119#define	CTLBL	 2		/* TLB miss (load or fetch) */
120#define	CTLBS	 3		/* TLB miss (store) */
121#define	CADREL	 4		/* address error (load or fetch) */
122#define	CADRES	 5		/* address error (store) */
123#define	CBUSI	 6		/* bus error (fetch) */
124#define	CBUSD	 7		/* bus error (data load or store) */
125#define	CSYS	 8		/* system call */
126#define	CBRK	 9		/* breakpoint */
127#define	CRES	10		/* reserved instruction */
128#define	CCPU	11		/* coprocessor unusable */
129#define	COVF	12		/* arithmetic overflow */
130#define	CUNK13	13		/* undefined 13 */
131#define	CUNK14	14		/* undefined 14 */
132#define	CUNK15	15		/* undefined 15 */
133
134#define	NSEG	5
135
136#define SP		R29
137
138#define PROM		(KSEG1+0x1FC00000)
139#define	NOOP		NOR R0,R0
140#define	WAIT		NOOP; NOOP
141
142/*
143 * Boot first processor
144 *   - why is the processor number loaded from R0 ?????
145 */
146TEXT	start(SB), $-4
147
148	MOVW	$setR30(SB), R30
149	MOVW	$(CU1|INTR5|INTR4|INTR3|INTR2|INTR1|SW1|SW0), R1
150	MOVW	R1, M(STATUS)
151	WAIT
152
153	MOVW	$(0x1C<<7), R1
154	MOVW	R1, FCR31	/* permit only inexact and underflow */
155	NOOP
156	MOVD	$0.5, F26
157	SUBD	F26, F26, F24
158	ADDD	F26, F26, F28
159	ADDD	F28, F28, F30
160
161	MOVD	F24, F0
162	MOVD	F24, F2
163	MOVD	F24, F4
164	MOVD	F24, F6
165	MOVD	F24, F8
166	MOVD	F24, F10
167	MOVD	F24, F12
168	MOVD	F24, F14
169	MOVD	F24, F16
170	MOVD	F24, F18
171	MOVD	F24, F20
172	MOVD	F24, F22
173
174	MOVW	$MACHADDR, R(MACH)
175	ADDU	$(BY2PG-4), R(MACH), SP
176	MOVW	$0, R(USER)
177	MOVW	R0, 0(R(MACH))
178
179	MOVW	$edata(SB), R1
180	MOVW	$end(SB), R2
181
182clrbss:
183	MOVB	$0, (R1)
184	ADDU	$1, R1
185	BNE	R1, R2, clrbss
186
187	MOVW	R4, _argc(SB)
188	MOVW	R5, _argv(SB)
189	MOVW	R6, _env(SB)
190	JAL	main(SB)
191	JMP	(R0)
192
193/*
194 * Take first processor into user mode
195 * 	- argument is stack pointer to user
196 */
197
198TEXT	touser(SB), $-4
199
200	MOVW	M(STATUS), R1
201	OR	$(KUP|IEP), R1
202	MOVW	R1, M(STATUS)
203	NOOP
204	MOVW	0(FP), SP
205	MOVW	$(UTZERO+32), R26	/* header appears in text */
206	RFE	(R26)
207
208/*
209 * Bring subsequent processors on line
210 */
211TEXT	newstart(SB), $0
212
213	MOVW	$setR30(SB), R30
214	MOVW	$(INTR5|INTR4|INTR3|INTR2|INTR1|SW1|SW0), R1
215	MOVW	R1, M(STATUS)
216	NOOP
217	MOVW	$MACHADDR, R(MACH)
218	MOVB	(MPID+3), R1
219	AND	$7, R1
220	SLL	$PGSHIFT, R1, R2
221	ADDU	R2, R(MACH)
222	ADDU	$(BY2PG-4), R(MACH), SP
223	MOVW	$0, R(USER)
224	MOVW	R1, 0(R(MACH))
225	JAL	online(SB)
226	JMP	(R0)
227
228TEXT	firmware(SB), $0
229
230	MOVW	$(PROM+0x18), R1 /**/
231/*	MOVW	$(PROM+0x00), R1 /**/
232	JMP	(R1)
233
234TEXT	splhi(SB), $0
235
236	MOVW	M(STATUS), R1
237	AND	$~IEC, R1, R2
238	MOVW	R2, M(STATUS)
239	NOOP
240	RET
241
242TEXT	spllo(SB), $0
243
244	MOVW	M(STATUS), R1
245	OR	$IEC, R1, R2
246	MOVW	R2, M(STATUS)
247	NOOP
248	RET
249
250TEXT	splx(SB), $0
251
252	MOVW	0(FP), R1
253	MOVW	M(STATUS), R2
254	AND	$IEC, R1
255	AND	$~IEC, R2
256	OR	R2, R1
257	MOVW	R1, M(STATUS)
258	NOOP
259	RET
260
261TEXT	wbflush(SB), $-4
262
263	MOVW	$WBFLUSH, R1
264	MOVW	0(R1), R1
265	RET
266
267TEXT	setlabel(SB), $0
268
269	MOVW	0(FP), R2
270	MOVW	$0, R1
271	MOVW	R31, 0(R2)
272	MOVW	R29, 4(R2)
273	RET
274
275TEXT	gotolabel(SB), $0
276
277	MOVW	0(FP), R2
278	MOVW	$1, R1
279	MOVW	0(R2), R31
280	MOVW	4(R2), R29
281	RET
282
283TEXT	gotopc(SB), $8
284
285	MOVW	0(FP), R7		/* save arguments for later */
286	MOVW	_argc(SB), R4
287	MOVW	_argv(SB), R5
288	MOVW	_env(SB), R6
289	MOVW	R0, 4(SP)
290	MOVW	$(64*1024), R1
291	MOVW	R1, 8(SP)
292	JAL	icflush(SB)
293	JMP	(R7)
294
295TEXT	puttlb(SB), $4
296
297	JAL	splhi(SB)
298	MOVW	0(FP), R2
299	MOVW	4(FP), R3
300	MOVW	R1, 4(SP)
301	MOVW	R2, M(TLBVIRT)
302	MOVW	R3, M(TLBPHYS)
303	NOOP
304	TLBP
305	NOOP
306	MOVW	M(INDEX), R4
307	BGEZ	R4, index
308	TLBWR
309	NOOP
310	JAL	splx(SB)
311	RET
312index:
313	TLBWI
314	NOOP
315	JAL	splx(SB)
316	RET
317
318TEXT	puttlbx(SB), $0
319
320	MOVW	0(FP), R4
321	MOVW	4(FP), R2
322	MOVW	8(FP), R3
323	SLL	$8, R4
324	MOVW	R2, M(TLBVIRT)
325	MOVW	R3, M(TLBPHYS)
326	MOVW	R4, M(INDEX)
327	NOOP
328	TLBWI
329	NOOP
330	RET
331
332TEXT	tlbp(SB), $0
333	TLBP
334	NOOP
335	MOVW	M(INDEX), R1
336	RET
337
338TEXT	tlbvirt(SB), $0
339	TLBP
340	NOOP
341	MOVW	M(TLBVIRT), R1
342	RET
343
344
345TEXT	gettlb(SB), $0
346
347	MOVW	0(FP), R3
348	MOVW	4(FP), R4
349	SLL	$8, R3
350	MOVW	R3, M(INDEX)
351	NOOP
352	TLBR
353	NOOP
354	MOVW	M(TLBVIRT), R1
355	MOVW	M(TLBPHYS), R2
356	NOOP
357	MOVW	R1, 0(R4)
358	MOVW	R2, 4(R4)
359	RET
360
361TEXT	gettlbvirt(SB), $0
362
363	MOVW	0(FP), R3
364	SLL	$8, R3
365	MOVW	R3, M(INDEX)
366	NOOP
367	TLBR
368	NOOP
369	MOVW	M(TLBVIRT), R1
370	NOOP
371	RET
372
373TEXT	vector80(SB), $-4
374
375	MOVW	$exception(SB), R26
376	JMP	(R26)
377
378TEXT	exception(SB), $-4
379
380	MOVW	M(STATUS), R26
381	AND	$KUP, R26
382	BEQ	R26, waskernel
383
384wasuser:
385	MOVW	SP, R26
386		/*
387		 * set kernel sp: ureg - ureg* - pc
388		 * done in 2 steps because R30 is not set
389		 * and the loader will make a literal
390		 */
391	MOVW	$((UREGADDR-2*BY2WD) & 0xffff0000), SP
392	OR	$((UREGADDR-2*BY2WD) & 0xffff), SP
393	MOVW	R26, 0x10(SP)			/* user SP */
394	MOVW	R31, 0x28(SP)
395	MOVW	R30, 0x2C(SP)
396	MOVW	M(CAUSE), R26
397	MOVW	R(MACH), 0x3C(SP)
398	MOVW	R(USER), 0x40(SP)
399	AND	$(0xF<<2), R26
400	SUB	$(CSYS<<2), R26
401
402	JAL	saveregs(SB)
403
404	MOVW	$setR30(SB), R30
405	SUBU	$(UREGADDR-2*BY2WD-USERADDR), SP, R(USER)
406	MOVW	$MPID, R1
407	MOVB	3(R1), R1
408	MOVW	$MACHADDR, R(MACH)		/* locn of mach 0 */
409	AND	$7, R1
410	SLL	$PGSHIFT, R1
411	ADDU	R1, R(MACH)			/* add offset for mach # */
412
413	BNE	R26, notsys
414
415	JAL	syscall(SB)
416
417	MOVW	0x28(SP), R31
418	MOVW	0x08(SP), R26
419	MOVW	0x2C(SP), R30
420	MOVW	R26, M(STATUS)
421	NOOP
422	MOVW	0x0C(SP), R26		/* old pc */
423	MOVW	0x10(SP), SP
424	RFE	(R26)
425
426notsys:
427	JAL	trap(SB)
428
429restore:
430	JAL	restregs(SB)
431	MOVW	0x28(SP), R31
432	MOVW	0x2C(SP), R30
433	MOVW	0x3C(SP), R(MACH)
434	MOVW	0x40(SP), R(USER)
435	MOVW	0x10(SP), SP
436	RFE	(R26)
437
438waskernel:
439	MOVW	$1, R26			/* not sys call */
440	MOVW	SP, -0x90(SP)		/* drop this if possible */
441	SUB	$0xA0, SP
442	MOVW	R31, 0x28(SP)
443	JAL	saveregs(SB)
444	JAL	trap(SB)
445	JAL	restregs(SB)
446	MOVW	0x28(SP), R31
447	ADD	$0xA0, SP
448	RFE	(R26)
449
450TEXT	saveregs(SB), $-4
451	MOVW	R1, 0x9C(SP)
452	MOVW	R2, 0x98(SP)
453	ADDU	$8, SP, R1
454	MOVW	R1, 0x04(SP)		/* arg to base of regs */
455	MOVW	M(STATUS), R1
456	MOVW	M(EPC), R2
457	MOVW	R1, 0x08(SP)
458	MOVW	R2, 0x0C(SP)
459
460	BEQ	R26, return		/* sys call, don't save */
461
462	MOVW	M(CAUSE), R1
463	MOVW	M(BADVADDR), R2
464	MOVW	R1, 0x14(SP)
465	MOVW	M(TLBVIRT), R1
466	MOVW	R2, 0x18(SP)
467	MOVW	R1, 0x1C(SP)
468	MOVW	HI, R1
469	MOVW	LO, R2
470	MOVW	R1, 0x20(SP)
471	MOVW	R2, 0x24(SP)
472					/* LINK,SB,SP missing */
473	MOVW	R28, 0x30(SP)
474					/* R27, R26 not saved */
475					/* R25, R24 missing */
476	MOVW	R23, 0x44(SP)
477	MOVW	R22, 0x48(SP)
478	MOVW	R21, 0x4C(SP)
479	MOVW	R20, 0x50(SP)
480	MOVW	R19, 0x54(SP)
481	MOVW	R18, 0x58(SP)
482	MOVW	R17, 0x5C(SP)
483	MOVW	R16, 0x60(SP)
484	MOVW	R15, 0x64(SP)
485	MOVW	R14, 0x68(SP)
486	MOVW	R13, 0x6C(SP)
487	MOVW	R12, 0x70(SP)
488	MOVW	R11, 0x74(SP)
489	MOVW	R10, 0x78(SP)
490	MOVW	R9, 0x7C(SP)
491	MOVW	R8, 0x80(SP)
492	MOVW	R7, 0x84(SP)
493	MOVW	R6, 0x88(SP)
494	MOVW	R5, 0x8C(SP)
495	MOVW	R4, 0x90(SP)
496	MOVW	R3, 0x94(SP)
497return:
498	RET
499
500TEXT	restregs(SB), $-4
501					/* LINK,SB,SP missing */
502	MOVW	0x30(SP), R28
503					/* R27, R26 not saved */
504					/* R25, R24 missing */
505	MOVW	0x44(SP), R23
506	MOVW	0x48(SP), R22
507	MOVW	0x4C(SP), R21
508	MOVW	0x50(SP), R20
509	MOVW	0x54(SP), R19
510	MOVW	0x58(SP), R18
511	MOVW	0x5C(SP), R17
512	MOVW	0x60(SP), R16
513	MOVW	0x64(SP), R15
514	MOVW	0x68(SP), R14
515	MOVW	0x6C(SP), R13
516	MOVW	0x70(SP), R12
517	MOVW	0x74(SP), R11
518	MOVW	0x78(SP), R10
519	MOVW	0x7C(SP), R9
520	MOVW	0x80(SP), R8
521	MOVW	0x84(SP), R7
522	MOVW	0x88(SP), R6
523	MOVW	0x8C(SP), R5
524	MOVW	0x90(SP), R4
525	MOVW	0x94(SP), R3
526	MOVW	0x24(SP), R2
527	MOVW	0x20(SP), R1
528	MOVW	R2, LO
529	MOVW	R1, HI
530	MOVW	0x08(SP), R1
531	MOVW	0x98(SP), R2
532	MOVW	R1, M(STATUS)
533	NOOP
534	MOVW	0x9C(SP), R1
535	MOVW	0x0C(SP), R26		/* old pc */
536	RET
537
538TEXT	rfnote(SB), $0
539	MOVW	0(FP), R26		/* 1st arg is &uregpointer */
540	SUBU	$(BY2WD), R26, SP	/* pc hole */
541	BNE	R26, restore
542
543
544TEXT	clrfpintr(SB), $0
545	MOVW	FCR31, R1
546	MOVW	R1, R2
547	AND	$~(0x3F<<12), R2
548	MOVW	R2, FCR31
549	RET
550
551TEXT	savefpregs(SB), $0
552	MOVW	M(STATUS), R3
553	MOVW	0(FP), R1
554	MOVW	FCR31, R2
555
556	MOVD	F0, 0x00(R1)
557	MOVD	F2, 0x08(R1)
558	MOVD	F4, 0x10(R1)
559	MOVD	F6, 0x18(R1)
560	MOVD	F8, 0x20(R1)
561	MOVD	F10, 0x28(R1)
562	MOVD	F12, 0x30(R1)
563	MOVD	F14, 0x38(R1)
564	MOVD	F16, 0x40(R1)
565	MOVD	F18, 0x48(R1)
566	MOVD	F20, 0x50(R1)
567	MOVD	F22, 0x58(R1)
568	MOVD	F24, 0x60(R1)
569	MOVD	F26, 0x68(R1)
570	MOVD	F28, 0x70(R1)
571	MOVD	F30, 0x78(R1)
572
573	MOVW	R2, 0x80(R1)
574	AND	$~CU1, R3
575	MOVW	R3, M(STATUS)
576	RET
577
578TEXT	restfpregs(SB), $0
579
580	MOVW	M(STATUS), R3
581	MOVW	0(FP), R1
582	OR	$CU1, R3
583	MOVW	R3, M(STATUS)
584	MOVW	0x80(R1), R2
585
586	MOVD	0x00(R1), F0
587	MOVD	0x08(R1), F2
588	MOVD	0x10(R1), F4
589	MOVD	0x18(R1), F6
590	MOVD	0x20(R1), F8
591	MOVD	0x28(R1), F10
592	MOVD	0x30(R1), F12
593	MOVD	0x38(R1), F14
594	MOVD	0x40(R1), F16
595	MOVD	0x48(R1), F18
596	MOVD	0x50(R1), F20
597	MOVD	0x58(R1), F22
598	MOVD	0x60(R1), F24
599	MOVD	0x68(R1), F26
600	MOVD	0x70(R1), F28
601	MOVD	0x78(R1), F30
602
603	MOVW	R2, FCR31
604	AND	$~CU1, R3
605	MOVW	R3, M(STATUS)
606	RET
607
608/*
609 *  we avoid using R4, R5, R6, and R7 so gotopc can call us without saving them
610 */
611TEXT icflush(SB), $-4			/* icflush(physaddr, nbytes) */
612
613	MOVW	M(STATUS), R10
614	MOVW	0(FP), R8
615	MOVW	4(FP), R9
616	MOVW	$KSEG0, R3
617	OR	R3, R8
618	MOVW	$0, M(STATUS)
619	MOVW	$WBFLUSH, R1		/* wbflush */
620	MOVW	0(R1), R1
621	NOOP
622	MOVW	$KSEG1, R3
623	MOVW	$icflush0(SB), R2	/* make sure PC is in uncached address space */
624	MOVW	$(SWC|ISC), R1
625	OR	R3, R2
626	JMP	(R2)
627
628TEXT icflush0(SB), $-4
629
630	MOVW	R1, M(STATUS)		/* swap and isolate cache, splhi */
631	MOVW	$icflush1(SB), R2
632	JMP	(R2)
633
634TEXT icflush1(SB), $-4
635
636_icflush1:
637	MOVBU	R0, 0x00(R8)
638	MOVBU	R0, 0x04(R8)
639	MOVBU	R0, 0x08(R8)
640	MOVBU	R0, 0x0C(R8)
641	MOVBU	R0, 0x10(R8)
642	MOVBU	R0, 0x14(R8)
643	MOVBU	R0, 0x18(R8)
644	MOVBU	R0, 0x1C(R8)
645	MOVBU	R0, 0x20(R8)
646	MOVBU	R0, 0x24(R8)
647	MOVBU	R0, 0x28(R8)
648	MOVBU	R0, 0x2C(R8)
649	MOVBU	R0, 0x30(R8)
650	MOVBU	R0, 0x34(R8)
651	MOVBU	R0, 0x38(R8)
652	MOVBU	R0, 0x3C(R8)
653	SUB	$0x40, R9
654	ADD	$0x40, R8
655	BGTZ	R9, _icflush1
656	MOVW	$icflush2(SB), R2	/* make sure PC is in uncached address space */
657	OR	R3, R2
658	JMP	(R2)
659
660TEXT icflush2(SB), $-4
661
662	MOVW	$0, M(STATUS)		/* swap back caches, de-isolate them, and stay splhi */
663	NOOP				/* +++ */
664	MOVW	R10, M(STATUS)
665	RET
666
667TEXT dcflush(SB), $-4			/* dcflush(physaddr, nbytes) */
668
669	MOVW	M(STATUS), R6
670	MOVW	0(FP), R4
671	MOVW	4(FP), R5
672	MOVW	$KSEG0, R3
673	OR	R3, R4
674	MOVW	$0, M(STATUS)
675	MOVW	$WBFLUSH, R1
676	MOVW	0(R1), R1
677	NOOP
678	MOVW	$ISC, R1
679	MOVW	R1, M(STATUS)
680_dcflush0:
681	MOVBU	R0, 0x00(R4)
682	MOVBU	R0, 0x04(R4)
683	MOVBU	R0, 0x08(R4)
684	MOVBU	R0, 0x0C(R4)
685	MOVBU	R0, 0x10(R4)
686	MOVBU	R0, 0x14(R4)
687	MOVBU	R0, 0x18(R4)
688	MOVBU	R0, 0x1C(R4)
689	MOVBU	R0, 0x20(R4)
690	MOVBU	R0, 0x24(R4)
691	MOVBU	R0, 0x28(R4)
692	MOVBU	R0, 0x2C(R4)
693	MOVBU	R0, 0x30(R4)
694	MOVBU	R0, 0x34(R4)
695	MOVBU	R0, 0x38(R4)
696	MOVBU	R0, 0x3C(R4)
697	SUB	$0x40, R5
698	ADD	$0x40, R4
699	BGTZ	R5, _dcflush0
700	MOVW	$0, M(STATUS)
701	NOOP				/* +++ */
702	MOVW	R6, M(STATUS)
703	RET
704