Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
 */
146
TEXT	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
 
182
clrbss:
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
 
198
TEXT	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
 */
211
TEXT	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
 
228
TEXT	firmware(SB), $0
229
 
230
	MOVW	$(PROM+0x18), R1 /**/
231
/*	MOVW	$(PROM+0x00), R1 /**/
232
	JMP	(R1)
233
 
234
TEXT	splhi(SB), $0
235
 
236
	MOVW	M(STATUS), R1
237
	AND	$~IEC, R1, R2
238
	MOVW	R2, M(STATUS)
239
	NOOP
240
	RET
241
 
242
TEXT	spllo(SB), $0
243
 
244
	MOVW	M(STATUS), R1
245
	OR	$IEC, R1, R2
246
	MOVW	R2, M(STATUS)
247
	NOOP
248
	RET
249
 
250
TEXT	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
 
261
TEXT	wbflush(SB), $-4
262
 
263
	MOVW	$WBFLUSH, R1
264
	MOVW	0(R1), R1
265
	RET
266
 
267
TEXT	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
 
275
TEXT	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
 
283
TEXT	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
 
295
TEXT	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
312
index:
313
	TLBWI
314
	NOOP
315
	JAL	splx(SB)
316
	RET
317
 
318
TEXT	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
 
332
TEXT	tlbp(SB), $0
333
	TLBP
334
	NOOP
335
	MOVW	M(INDEX), R1
336
	RET
337
 
338
TEXT	tlbvirt(SB), $0
339
	TLBP
340
	NOOP
341
	MOVW	M(TLBVIRT), R1
342
	RET
343
 
344
 
345
TEXT	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
 
361
TEXT	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
 
373
TEXT	vector80(SB), $-4
374
 
375
	MOVW	$exception(SB), R26
376
	JMP	(R26)
377
 
378
TEXT	exception(SB), $-4
379
 
380
	MOVW	M(STATUS), R26
381
	AND	$KUP, R26
382
	BEQ	R26, waskernel
383
 
384
wasuser:
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
 
426
notsys:
427
	JAL	trap(SB)
428
 
429
restore:
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
 
438
waskernel:
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
 
450
TEXT	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)
497
return:
498
	RET
499
 
500
TEXT	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
 
538
TEXT	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
 
544
TEXT	clrfpintr(SB), $0
545
	MOVW	FCR31, R1
546
	MOVW	R1, R2
547
	AND	$~(0x3F<<12), R2
548
	MOVW	R2, FCR31
549
	RET
550
 
551
TEXT	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
 
578
TEXT	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
 */
611
TEXT 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
 
628
TEXT icflush0(SB), $-4
629
 
630
	MOVW	R1, M(STATUS)		/* swap and isolate cache, splhi */
631
	MOVW	$icflush1(SB), R2
632
	JMP	(R2)
633
 
634
TEXT 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
 
660
TEXT 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
 
667
TEXT 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