|
|
1.1 root 1: /*
2: * Copyright (c) 1988 University of Utah.
3: * Copyright (c) 1980, 1990 The Regents of the University of California.
4: * All rights reserved.
5: *
6: * This code is derived from software contributed to Berkeley by
7: * the Systems Programming Group of the University of Utah Computer
8: * Science Department.
9: *
10: * Redistribution is only permitted until one year after the first shipment
11: * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
12: * binary forms are permitted provided that: (1) source distributions retain
13: * this entire copyright notice and comment, and (2) distributions including
14: * binaries display the following acknowledgement: This product includes
15: * software developed by the University of California, Berkeley and its
16: * contributors'' in the documentation or other materials provided with the
17: * distribution and in all advertising materials mentioning features or use
18: * of this software. Neither the name of the University nor the names of
19: * its contributors may be used to endorse or promote products derived from
20: * this software without specific prior written permission.
21: * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
22: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
23: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
24: *
25: * from: Utah $Hdr: locore.s 1.47 89/10/08$
26: *
27: * @(#)locore.s 7.3 (Berkeley) 6/22/90
28: */
29:
30: .text
31: /*
32: * This is where we wind up if the kernel jumps to location 0.
33: * (i.e. a bogus PC) This is known to immediately follow the vector
34: * table and is hence at 0x400 (see reset vector in vectors.s).
35: */
36: .globl _panic
37: pea Ljmp0panic
38: jbsr _panic
39: /* NOTREACHED */
40: Ljmp0panic:
41: .asciz "kernel jump to zero"
42: .even
43:
44: /*
45: * Do a dump.
46: * Called by auto-restart.
47: */
48: .globl _dumpsys
49: .globl _doadump
50: _doadump:
51: jbsr _dumpsys
52: jbsr _doboot
53: /*NOTREACHED*/
54:
55: /*
56: * Trap/interrupt vector routines
57: */
58:
59: .globl _trap, _nofault, _longjmp
60: _buserr:
61: tstl _nofault | device probe?
62: jeq _addrerr | no, handle as usual
63: movl _nofault,sp@- | yes,
64: jbsr _longjmp | longjmp(nofault)
65: _addrerr:
66: clrw sp@- | pad SR to longword
67: moveml #0xFFFF,sp@- | save user registers
68: movl usp,a0 | save the user SP
69: movl a0,sp@(60) | in the savearea
70: lea sp@(64),a1 | grab base of HW berr frame
71: movw a1@(12),d0 | grab SSW for fault processing
72: btst #12,d0 | RB set?
73: jeq LbeX0 | no, test RC
74: bset #14,d0 | yes, must set FB
75: movw d0,a1@(12) | for hardware too
76: LbeX0:
77: btst #13,d0 | RC set?
78: jeq LbeX1 | no, skip
79: bset #15,d0 | yes, must set FC
80: movw d0,a1@(12) | for hardware too
81: LbeX1:
82: btst #8,d0 | data fault?
83: jeq Lbe0 | no, check for hard cases
84: movl a1@(18),d1 | fault address is as given in frame
85: jra Lbe10 | thats it
86: Lbe0:
87: btst #4,a1@(8) | long (type B) stack frame?
88: jne Lbe4 | yes, go handle
89: movl a1@(4),d1 | no, can use save PC
90: btst #14,d0 | FB set?
91: jeq Lbe3 | no, try FC
92: addql #4,d1 | yes, adjust address
93: jra Lbe10 | done
94: Lbe3:
95: btst #15,d0 | FC set?
96: jeq Lbe10 | no, done
97: addql #2,d1 | yes, adjust address
98: jra Lbe10 | done
99: Lbe4:
100: movl a1@(38),d1 | long format, use stage B address
101: btst #15,d0 | FC set?
102: jeq Lbe10 | no, all done
103: subql #2,d1 | yes, adjust address
104: Lbe10:
105: movl d1,sp@- | push fault VA
106: movw d0,sp@- | and SSW
107: clrw sp@- | padded to longword
108: movw a1@(8),d0 | get frame format/vector offset
109: andw #0x0FFF,d0 | clear out frame format
110: cmpw #12,d0 | address error vector?
111: jeq Lisaerr | yes, go to it
112: #if defined(HP330) || defined(HP360) || defined(HP370)
113: tstl _mmutype | HP MMU?
114: jeq Lbehpmmu | yes, skip
115: movl d1,a0 | fault address
116: .long 0xf0109e11 | ptestr #1,a0@,#7
117: .long 0xf0176200 | pmove psr,sp@
118: btst #7,sp@ | bus error bit set?
119: jeq Lismerr | no, must be MMU fault
120: clrw sp@ | yes, re-clear pad word
121: jra Lisberr | and process as normal bus error
122: Lbehpmmu:
123: #endif
124: #if defined(HP320) || defined(HP350)
125: lea _IObase+MMUSTAT,a0 | no, get addr of MMU status
126: movl a0@,d0 | read status
127: btst #3,d0 | MMU fault?
128: jeq Lisberr | no, just a non-MMU bus error so skip
129: andl #~MMU_FAULT,a0@ | yes, clear fault bits
130: movw d0,sp@ | pass MMU stat in upper half of code
131: #endif
132: Lismerr:
133: movl #T_MMUFLT,sp@- | show that we are an MMU fault
134: jra Lbexit | and deal with it
135: Lisaerr:
136: movl #T_ADDRERR,sp@- | mark address error
137: jra Lbexit | and deal with it
138: Lisberr:
139: movl #T_BUSERR,sp@- | mark bus error
140: Lbexit:
141: jbsr _trap | handle the error
142: lea sp@(12),sp | pop value args
143: movl sp@(60),a0 | restore user SP
144: movl a0,usp | from save area
145: moveml sp@+,#0x7FFF | restore most user regs
146: addql #4,sp | toss SSP
147: tstw sp@+ | do we need to clean up stack?
148: jeq rei | no, just continue
149: btst #7,sp@(6) | type 9/10/11 frame?
150: jeq rei | no, nothing to do
151: btst #5,sp@(6) | type 9?
152: jne Lbex1 | no, skip
153: movw sp@,sp@(12) | yes, push down SR
154: movl sp@(2),sp@(14) | and PC
155: clrw sp@(18) | and mark as type 0 frame
156: lea sp@(12),sp | clean the excess
157: jra rei | all done
158: Lbex1:
159: btst #4,sp@(6) | type 10?
160: jne Lbex2 | no, skip
161: movw sp@,sp@(24) | yes, push down SR
162: movl sp@(2),sp@(26) | and PC
163: clrw sp@(30) | and mark as type 0 frame
164: lea sp@(24),sp | clean the excess
165: jra rei | all done
166: Lbex2:
167: movw sp@,sp@(84) | type 11, push down SR
168: movl sp@(2),sp@(86) | and PC
169: clrw sp@(90) | and mark as type 0 frame
170: lea sp@(84),sp | clean the excess
171: jra rei | all done
172:
173: _illinst:
174: clrw sp@-
175: moveml #0xFFFF,sp@-
176: moveq #T_ILLINST,d0
177: jra _fault
178:
179: _zerodiv:
180: clrw sp@-
181: moveml #0xFFFF,sp@-
182: moveq #T_ZERODIV,d0
183: jra _fault
184:
185: _chkinst:
186: clrw sp@-
187: moveml #0xFFFF,sp@-
188: moveq #T_CHKINST,d0
189: jra _fault
190:
191: _trapvinst:
192: clrw sp@-
193: moveml #0xFFFF,sp@-
194: moveq #T_TRAPVINST,d0
195: jra _fault
196:
197: _privinst:
198: clrw sp@-
199: moveml #0xFFFF,sp@-
200: moveq #T_PRIVINST,d0
201: jra _fault
202:
203: _coperr:
204: clrw sp@-
205: moveml #0xFFFF,sp@-
206: moveq #T_COPERR,d0
207: jra _fault
208:
209: _fmterr:
210: clrw sp@-
211: moveml #0xFFFF,sp@-
212: moveq #T_FMTERR,d0
213: jra _fault
214:
215: _fptrap:
216: #ifdef FPCOPROC
217: clrw sp@- | pad SR to longword
218: moveml #0xFFFF,sp@- | save user registers
219: movl usp,a0 | and save
220: movl a0,sp@(60) | the user stack pointer
221: clrl sp@- | no VA arg
222: lea _u+PCB_FPCTX,a0 | address of FP savearea
223: .word 0xf310 | fsave a0@
224: tstb a0@ | null state frame?
225: jeq Lfptnull | yes, safe
226: clrw d0 | no, need to tweak BIU
227: movb a0@(1),d0 | get frame size
228: bset #3,a0@(0,d0:w) | set exc_pend bit of BIU
229: Lfptnull:
230: .word 0xf227,0xa800 | fmovem fpsr,sp@- (code arg)
231: .word 0xf350 | frestore a0@
232: movl #T_FPERR,sp@- | push type arg
233: jbsr _trap | call trap
234: lea sp@(12),sp | pop value args
235: movl sp@(60),a0 | restore
236: movl a0,usp | user SP
237: moveml sp@+,#0x7FFF | and remaining user registers
238: addql #6,sp | pop SSP and align word
239: jra rei | all done
240: #else
241: jra _badtrap | treat as an unexpected trap
242: #endif
243:
244: .globl _fault
245: _fault:
246: movl usp,a0 | get and save
247: movl a0,sp@(60) | the user stack pointer
248: clrl sp@- | no VA arg
249: clrl sp@- | or code arg
250: movl d0,sp@- | push trap type
251: jbsr _trap | handle trap
252: lea sp@(12),sp | pop value args
253: movl sp@(60),a0 | restore
254: movl a0,usp | user SP
255: moveml sp@+,#0x7FFF | restore most user regs
256: addql #6,sp | pop SP and pad word
257: jra rei | all done
258:
259: .globl _straytrap
260: _badtrap:
261: clrw sp@-
262: moveml #0xC0C0,sp@-
263: movw sp@(24),sp@-
264: clrw sp@-
265: jbsr _straytrap
266: addql #4,sp
267: moveml sp@+,#0x0303
268: addql #2,sp
269: jra rei
270:
271: .globl _syscall
272: _trap0:
273: clrw sp@- | pad SR to longword
274: moveml #0xFFFF,sp@- | save user registers
275: movl usp,a0 | save the user SP
276: movl a0,sp@(60) | in the savearea
277: movl d0,sp@- | push syscall number
278: jbsr _syscall | handle it
279: addql #4,sp | pop syscall arg
280: movl sp@(60),a0 | grab and restore
281: movl a0,usp | user SP
282: moveml sp@+,#0x7FFF | restore most registers
283: addql #6,sp | pop SSP and align word
284: jra rei | all done
285:
286: /*
287: * Routines for traps 1 and 2. The meaning of the two traps depends
288: * on whether we are an HPUX compatible process or a native 4.3 process.
289: * Our native 4.3 implementation uses trap 1 as sigreturn() and trap 2
290: * as a breakpoint trap. HPUX uses trap 1 for a breakpoint, so we have
291: * to make adjustments so that trap 2 is used for sigreturn.
292: */
293: _trap1:
294: btst #PCB_TRCB,_u+PCB_FLAGS+1| being traced by an HPUX process?
295: jeq sigreturn | no, trap1 is sigreturn
296: jra _trace | yes, trap1 is breakpoint
297:
298: _trap2:
299: btst #PCB_TRCB,_u+PCB_FLAGS+1| being traced by an HPUX process?
300: jeq _trace | no, trap2 is breakpoint
301: jra sigreturn | yes, trap2 is sigreturn
302:
303: /*
304: * Trap 15 is used for:
305: * - KGDB traps
306: * - trace traps for SUN binaries (not fully supported yet)
307: * We just pass it on and let trap() sort it all out
308: */
309: _trap15:
310: clrw sp@-
311: moveml #0xFFFF,sp@-
312: moveq #T_TRAP15,d0
313: jra _fault
314:
315: /*
316: * Hit a breakpoint (trap 1 or 2) instruction.
317: * Push the code and treat as a normal fault.
318: */
319: _trace:
320: clrw sp@-
321: moveml #0xFFFF,sp@-
322: moveq #T_TRACE,d0
323: jra _fault
324:
325: /*
326: * The sigreturn() syscall comes here. It requires special handling
327: * because we must open a hole in the stack to fill in the (possibly much
328: * larger) original stack frame.
329: */
330: sigreturn:
331: lea sp@(-84),sp | leave enough space for largest frame
332: movl sp@(84),sp@ | move up current 8 byte frame
333: movl sp@(88),sp@(4)
334: movw #0xFFFF,sp@- | default: must clean stack
335: moveml #0xFFFF,sp@- | save user registers
336: movl usp,a0 | save the user SP
337: movl a0,sp@(60) | in the savearea
338: movl #SYS_sigreturn,sp@- | push syscall number
339: jbsr _syscall | handle it
340: addql #4,sp | pop syscall#
341: movl sp@(60),a0 | grab and restore
342: movl a0,usp | user SP
343: lea sp@(64),a1 | pointer to HW frame
344: tstw a1@+ | do we need to clean up stack?
345: jeq Lsigr1 | no, just continue
346: movb a1@(6),d0 | grab format byte
347: lsrb #4,d0 | get rid of excess
348: cmpb #10,d0 | type 10 frame?
349: jne Lsigr2 | no, continue
350: movw #32,d1 | yes, frame size is 32 bytes
351: jra Lsigrcp | go to it
352: Lsigr2:
353: cmpb #9,d0 | type 9?
354: jne Lsigr3 | no, continue
355: movw #20,d1 | yes, frame size is 20 bytes
356: jra Lsigrcp | go to it
357: Lsigr3:
358: cmpb #2,d0 | type 2?
359: jne Lsigr4 | no, continue
360: movw #12,d1 | yes, frame size is 12 bytes
361: jra Lsigrcp | go to it
362: Lsigr4:
363: movw #8,d1 | must be type 0/1, size is 8 bytes
364: Lsigrcp:
365: lea a1@(92),a0 | destination
366: addw d1,a1 | source
367: lsrw #1,d1 | convert to word count
368: subqw #1,d1 | minus 1 for dbf
369: Lsigrlp:
370: movw a1@-,a0@- | copy a word
371: dbf d1,Lsigrlp | continue
372: movl a0,a1 | new HW frame base
373: Lsigr1:
374: movl a1,sp@(60) | new SP value
375: moveml sp@+,#0x7FFF | restore user registers
376: movl sp@,sp | and our SP
377: jra rei | all done
378:
379: /*
380: * Interrupt handlers.
381: * All DIO device interrupts are auto-vectored. Most can be configured
382: * to interrupt in the range IPL3 to IPL5. Here are our assignments:
383: *
384: * Level 0: Spurious: ignored.
385: * Level 1: HIL
386: * Level 2:
387: * Level 3: Internal HP-IB
388: * Level 4: "Fast" HP-IBs, SCSI
389: * Level 5: DMA, Ethernet, Built-in RS232
390: * Level 6: Clock
391: * Level 7: Non-maskable: parity errors, RESET key
392: */
393: .globl _hilint, _intrhand, _hardclock, _nmihand
394:
395: _spurintr:
396: addql #1,_intrcnt+0
397: addql #1,_cnt+V_INTR
398: jra rei
399:
400: _lev1intr:
401: addql #1,_intrcnt+4
402: clrw sp@-
403: moveml #0xC0C0,sp@-
404: jbsr _hilint
405: moveml sp@+,#0x0303
406: addql #2,sp
407: addql #1,_cnt+V_INTR
408: jra rei
409:
410: /* check for DMA first to reduce overhead */
411: _lev5intr:
412: clrw sp@-
413: moveml #0xC0C0,sp@-
414: jbsr _dmaintr
415: tstl d0
416: jeq Lnotdma
417: addql #1,_intrcnt+24
418: moveml sp@+,#0x0303
419: addql #2,sp
420: addql #1,_cnt+V_INTR
421: jra rei
422:
423: _lev2intr:
424: _lev3intr:
425: _lev4intr:
426: clrw sp@-
427: moveml #0xC0C0,sp@-
428: Lnotdma:
429: lea _intrcnt,a0
430: movw sp@(24),d0 | use vector offset
431: andw #0xfff,d0 | sans frame type
432: addql #1,a0@(-0x60,d0:w) | to increment apropos counter
433: movw sr,sp@- | push current SR value
434: clrw sp@- | padded to longword
435: jbsr _intrhand | handle interrupt
436: addql #4,sp | pop SR
437: moveml sp@+,#0x0303
438: addql #2,sp
439: addql #1,_cnt+V_INTR
440: jra rei
441:
442: _lev6intr:
443: clrw sp@-
444: moveml #0xC0C0,sp@-
445: #ifdef DEBUG
446: .globl _panicstr, _regdump, _panic
447: tstl timebomb | set to go off?
448: jeq Lnobomb | no, skip it
449: subql #1,timebomb | decrement
450: jne Lnobomb | not ready to go off
451: moveml sp@+,#0x0303 | temporarily restore regs
452: jra Luseours | go die
453: Lnobomb:
454: cmpl #_u+NBPG+NBPG,sp | our we still in stack page?
455: jcc Lstackok | yes, continue normally
456: tstl _panicstr | have we paniced?
457: jne Lstackok | yes, do not re-panic
458: moveml sp@+,#0x0303 | no, temporarily restore regs
459: cmpl #_u+NBPG+0x400,sp | our we safely in redzone?
460: jcc Luseours | yes, panic with this stack
461: lea tmpstk,sp | no, switch to tmpstk
462: Luseours:
463: moveml #0xFFFF,sp@- | push all registers
464: movl sp,a0 | remember this spot
465: movl #256,sp@- | longword count
466: movl a0,sp@- | and reg pointer
467: jbsr _regdump | dump core
468: addql #8,sp | pop params
469: movl #Lstkrip,sp@- | push panic message
470: jbsr _panic | ES and D
471: Lstkrip:
472: .asciz "k-stack overflow"
473: .even
474: Lstackok:
475: #endif
476: movb _IObase+CLKSR,d0 | read clock status
477: #ifdef PROFTIMER
478: .globl _profon
479: tstb _profon | profile clock on?
480: jeq Ltimer1 | no, then must be timer1 interrupt
481: btst #2,d0 | timer3 interrupt?
482: jeq Ltimer1 | no, must be timer1
483: movb _IObase+CLKMSB3,d1 | clear timer3 interrupt
484: lea sp@(16),a1 | get pointer to PS
485: #ifdef GPROF
486: .globl _profclock
487: movl d0,sp@- | save status so jsr will not clobber
488: movl a1@,sp@- | push padded PS
489: movl a1@(4),sp@- | push PC
490: jbsr _profclock | profclock(pc, ps)
491: addql #8,sp | pop params
492: #else
493: btst #5,a1@(2) | saved PS in user mode?
494: jne Lttimer1 | no, go check timer1
495: tstl _u+U_PROFSCALE | process being profiled?
496: jeq Lttimer1 | no, go check timer1
497: movl d0,sp@- | save status so jsr will not clobber
498: movl #1,sp@-
499: movl #_u+U_PROF,sp@-
500: movl a1@(4),sp@-
501: jbsr _addupc | addupc(pc, &u.u_prof, 1)
502: lea sp@(12),sp | pop params
503: #endif
504: addql #1,_intrcnt+32 | add another profile clock interrupt
505: movl sp@+,d0 | get saved clock status
506: Lttimer1:
507: btst #0,d0 | timer1 interrupt?
508: jeq Ltimend | no, check state of kernel profiling
509: Ltimer1:
510: #endif
511: movb _IObase+CLKMSB1,d1 | clear timer1 interrupt
512: lea sp@(16),a1 | get pointer to PS
513: movl a1@,sp@- | push padded PS
514: movl a1@(4),sp@- | push PC
515: jbsr _hardclock | call generic clock int routine
516: addql #8,sp | pop params
517: addql #1,_intrcnt+28 | add another system clock interrupt
518: #ifdef PROFTIMER
519: Ltimend:
520: #ifdef GPROF
521: .globl _profiling, _startprofclock
522: tstl _profiling | kernel profiling desired?
523: jne Ltimdone | no, all done
524: bset #7,_profon | mark continuous timing
525: jne Ltimdone | was already enabled, all done
526: jbsr _startprofclock | else turn it on
527: Ltimdone:
528: #endif
529: #endif
530: moveml sp@+,#0x0303 | restore scratch regs
531: addql #2,sp | pop pad word
532: addql #1,_cnt+V_INTR | chalk up another interrupt
533: jra rei | all done
534:
535: _lev7intr:
536: #ifdef PROFTIMER
537: addql #1,_intrcnt+36
538: #else
539: addql #1,_intrcnt+32
540: #endif
541: clrw sp@- | pad SR to longword
542: moveml #0xFFFF,sp@- | save registers
543: movl usp,a0 | and save
544: movl a0,sp@(60) | the user stack pointer
545: jbsr _nmihand | call handler
546: movl sp@(60),a0 | restore
547: movl a0,usp | user SP
548: moveml sp@+,#0x7FFF | and remaining registers
549: addql #6,sp | pop SSP and align word
550: jra rei | all done
551:
552: /*
553: * Emulation of VAX REI instruction.
554: *
555: * This code deals with checking for and servicing ASTs
556: * (profiling, scheduling) and software interrupts (network, softclock).
557: * We check for ASTs first, just like the VAX. To avoid excess overhead
558: * the T_ASTFLT handling code will also check for software interrupts so we
559: * do not have to do it here.
560: *
561: * This code is complicated by the fact that sendsig may have been called
562: * necessitating a stack cleanup. A cleanup should only be needed at this
563: * point for coprocessor mid-instruction frames (type 9), but we also test
564: * for bus error frames (type 10 and 11).
565: */
566: .comm _ssir,1
567: rei:
568: #ifdef DEBUG
569: tstl _panicstr | have we paniced?
570: jne Ldorte | yes, do not make matters worse
571: #endif
572: btst #PCB_ASTB,_u+PCB_FLAGS+1| AST pending?
573: jeq Lchksir | no, go check for SIR
574: btst #5,sp@ | yes, are we returning to user mode?
575: jne Lchksir | no, go check for SIR
576: clrw sp@- | pad SR to longword
577: moveml #0xFFFF,sp@- | save all registers
578: movl usp,a1 | including
579: movl a1,sp@(60) | the users SP
580: clrl sp@- | VA == none
581: clrl sp@- | code == none
582: movl #T_ASTFLT,sp@- | type == async system trap
583: jbsr _trap | go handle it
584: lea sp@(12),sp | pop value args
585: movl sp@(60),a0 | restore
586: movl a0,usp | user SP
587: moveml sp@+,#0x7FFF | and all remaining registers
588: addql #4,sp | toss SSP
589: tstw sp@+ | do we need to clean up stack?
590: jeq Ldorte | no, just continue
591: btst #7,sp@(6) | type 9/10/11 frame?
592: jeq Ldorte | no, nothing to do
593: btst #5,sp@(6) | type 9?
594: jne Last1 | no, skip
595: movw sp@,sp@(12) | yes, push down SR
596: movl sp@(2),sp@(14) | and PC
597: clrw sp@(18) | and mark as type 0 frame
598: lea sp@(12),sp | clean the excess
599: jra Ldorte | all done
600: Last1:
601: btst #4,sp@(6) | type 10?
602: jne Last2 | no, skip
603: movw sp@,sp@(24) | yes, push down SR
604: movl sp@(2),sp@(26) | and PC
605: clrw sp@(30) | and mark as type 0 frame
606: lea sp@(24),sp | clean the excess
607: jra Ldorte | all done
608: Last2:
609: movw sp@,sp@(84) | type 11, push down SR
610: movl sp@(2),sp@(86) | and PC
611: clrw sp@(90) | and mark as type 0 frame
612: lea sp@(84),sp | clean the excess
613: jra Ldorte | all done
614: Lchksir:
615: tstb _ssir | SIR pending?
616: jeq Ldorte | no, all done
617: movl d0,sp@- | need a scratch register
618: movw sp@(4),d0 | get SR
619: andw #PSL_IPL7,d0 | mask all but IPL
620: jne Lnosir | came from interrupt, no can do
621: movl sp@+,d0 | restore scratch register
622: Lgotsir:
623: movw #SPL1,sr | prevent others from servicing int
624: tstb _ssir | too late?
625: jeq Ldorte | yes, oh well...
626: clrw sp@- | pad SR to longword
627: moveml #0xFFFF,sp@- | save all registers
628: movl usp,a1 | including
629: movl a1,sp@(60) | the users SP
630: clrl sp@- | VA == none
631: clrl sp@- | code == none
632: movl #T_SSIR,sp@- | type == software interrupt
633: jbsr _trap | go handle it
634: lea sp@(12),sp | pop value args
635: movl sp@(60),a0 | restore
636: movl a0,usp | user SP
637: moveml sp@+,#0x7FFF | and all remaining registers
638: addql #6,sp | pop SSP and align word
639: rte
640: Lnosir:
641: movl sp@+,d0 | restore scratch register
642: Ldorte:
643: rte | real return
644:
645: /*
646: * System page table
647: * Mbmap, Usrptmap, and Usriomap are enlarged by CLSIZE entries
648: * as they are managed by resource maps starting with index 1 or CLSIZE.
649: * Usrptmap is allocated last so that we can also use the pad space up
650: * to eSysmap. (no point in wasting it!)
651: */
652: #define vaddr(x) x-_Sysmap/4*NBPG
653: #define SYSMAP(mname,vname,size) \
654: .globl _/**/mname,_/**/vname; \
655: _/**/mname: \
656: .space size*4; \
657: _/**/vname = vaddr(_/**/mname)
658: #define ADDMAP(npte) .space npte*4
659:
660: .data
661: SYSMAP(Sysmap ,Sysbase ,SYSPTSIZE )
662: SYSMAP(Forkmap ,forkutl ,UPAGES )
663: SYSMAP(Xswapmap ,xswaputl ,UPAGES )
664: SYSMAP(Xswap2map,xswap2utl ,UPAGES )
665: SYSMAP(Swapmap ,swaputl ,UPAGES )
666: SYSMAP(Pushmap ,pushutl ,UPAGES )
667: SYSMAP(Vfmap ,vfutl ,UPAGES )
668: SYSMAP(CMAP1 ,CADDR1 ,1 )
669: SYSMAP(CMAP2 ,CADDR2 ,1 )
670: SYSMAP(mmap ,vmmap ,1 )
671: SYSMAP(msgbufmap,msgbuf ,MSGBUFPTECNT )
672: SYSMAP(Umap ,u ,UPAGES )
673: SYSMAP(Mbmap ,mbutl ,NMBCLUSTERS*MCLBYTES/NBPG+CLSIZE )
674: /*
675: * This is the map used by the kernel memory allocator.
676: * It is expanded as necessary by the special features
677: * that use it.
678: *
679: * XXX: NEED way to compute kmem size from maxusers,
680: * device complement
681: */
682: SYSMAP(kmempt ,kmembase ,NKMEMCLUSTERS*CLSIZE )
683: #ifdef SYSVSHM
684: ADDMAP( SHMMAXPGS )
685: #endif
686: #ifdef GPROF
687: ADDMAP( 768*1024/NBPG )
688: #endif
689: SYSMAP(ekmempt ,kmemlimit ,0 )
690: SYSMAP(IOmap ,IObase ,IOMAPSIZE ) /* map DIO space */
691: SYSMAP(eIOmap ,IOlimit ,0 )
692: #if defined(HP360) || defined(HP370)
693: SYSMAP(Grfmap ,grfregs ,1024 ) /* 340 @ SC132 */
694: #endif
695: SYSMAP(Usriomap ,usrio ,USRIOSIZE+CLSIZE ) /* for PHYSIO */
696: SYSMAP(Usrptmap ,usrpt ,USRPTSIZE+CLSIZE )
697: . = . + NBPG - 1 & -NBPG /* align to page boundry */
698: eSysmap:
699:
700: /*
701: * System segment table. 1 page is sufficient to map the entire
702: * 4Gb address space. (funny how that works out...)
703: */
704: .globl _Sysseg
705: _Sysseg:
706: .space NBPG
707: eSysseg:
708:
709: .globl _Syssize, _Usrptsize
710: _Syssize = eSysmap-_Sysmap/4
711: _Usrptsize = eSysmap-_Usrptmap/4
712:
713: /*
714: * Initialization
715: *
716: * A5 contains physical load point from boot
717: * VBR contains zero from ROM. Exceptions will continue to vector
718: * through ROM until MMU is turned on at which time they will vector
719: * through our table (vectors.s).
720: */
721: .comm _lowram,4
722:
723: .text
724: .globl _edata
725: .globl _etext,_end
726: .globl start
727: start:
728: movw #PSL_HIGHIPL,sr | no interrupts
729: lea _lowram,a0
730: addl a5,a0
731: movl a5,a0@ | store start of physical memory
732: movl #CACHE_OFF,d0
733: movc d0,cacr | clear and disable on-chip cache(s)
734:
735: /* determine our CPU/MMU combo - check for all regardless of kernel config */
736: movl #0x200,d0 | data freeze bit
737: movc d0,cacr | only exists on 68030
738: movc cacr,d0 | read it back
739: tstl d0 | zero?
740: jeq Lis68020 | yes, we have 68020
741: lea _mmutype,a0 | no, we have 68030
742: addl a5,a0
743: movl #-1,a0@ | set to reflect 68030 PMMU
744: lea _machineid,a0
745: addl a5,a0
746: movl #0x80,IOBASE+MMUCMD | set magic cookie
747: movl IOBASE+MMUCMD,d0 | read it back
748: btst #7,d0 | cookie still on?
749: jeq Lnot370 | no, 360 or 375
750: movl #0,IOBASE+MMUCMD | clear magic cookie
751: movl IOBASE+MMUCMD,d0 | read it back
752: btst #7,d0 | still on?
753: jeq Lisa370 | no, must be a 370
754: movl #5,a0@ | yes, must be a 340
755: jra Lstart1
756: Lnot370:
757: movl #3,a0@ | type is at least a 360
758: movl #0,IOBASE+MMUCMD | clear magic cookie2
759: movl IOBASE+MMUCMD,d0 | read it back
760: btst #16,d0 | still on?
761: jeq Lstart1 | no, must be a 360
762: movl #6,a0@ | yes, must be a 345/375
763: jra Lhaspac
764: Lisa370:
765: movl #4,a0@ | set to 370
766: Lhaspac:
767: lea _ectype,a0
768: addl a5,a0
769: movl #-1,a0@ | also has a physical address cache
770: jra Lstart1
771: Lis68020:
772: movl #1,IOBASE+MMUCMD | a 68020, write HP MMU location
773: movl IOBASE+MMUCMD,d0 | read it back
774: btst #0,d0 | non-zero?
775: jne Lishpmmu | yes, we have HP MMU
776: lea _mmutype,a0
777: addl a5,a0
778: movl #1,a0@ | no, we have PMMU
779: lea _machineid,a0
780: addl a5,a0
781: movl #1,a0@ | and 330 CPU
782: jra Lstart1
783: Lishpmmu:
784: lea _ectype,a0 | 320 or 350
785: addl a5,a0
786: movl #1,a0@ | both have a virtual address cache
787: movl #0x80,IOBASE+MMUCMD | set magic cookie
788: movl IOBASE+MMUCMD,d0 | read it back
789: btst #7,d0 | cookie still on?
790: jeq Lstart1 | no, just a 320
791: lea _machineid,a0
792: addl a5,a0
793: movl #2,a0@ | yes, a 350
794:
795: Lstart1:
796: movl #0,IOBASE+MMUCMD | clear out MMU again
797: /* initialize source/destination control registers for movs */
798: moveq #FC_USERD,d0 | user space
799: movc d0,sfc | as source
800: movc d0,dfc | and destination of transfers
801: /* initialize proc. 0 (system) page table */
802: movl #_Sysmap,a0 | SYSPT map addr
803: addl a5,a0 | relocate
804: /* text pages are read-only */
805: clrl d0 | assume load at VA 0
806: movl a5,d1 | get load PA
807: andl #PG_FRAME,d1 | convert to a page frame
808: orl #PG_RO+PG_V,d1 | mark as valid and RO
809: movl #_etext,a1 | go til end of text
810: Lispt1:
811: movl d1,a0@+ | load PTE
812: addl #NBPG,d1 | increment page frame number
813: addl #NBPG,d0 | and address counter
814: cmpl a1,d0 | done yet?
815: jcs Lispt1 | no, keep going
816: /* data and bss are read/write */
817: andl #PG_FRAME,d1 | mask out old prot bits
818: orl #PG_RW+PG_V,d1 | mark as valid and RW
819: movl #_end,a1 | go til end of data/bss
820: Lispt2:
821: movl d1,a0@+ | load PTE
822: addl #NBPG,d1 | increment page frame number
823: addl #NBPG,d0 | and address counter
824: cmpl a1,d0 | done yet?
825: jcs Lispt2 | no, keep going
826: /* invalidate remainder of system page table */
827: movl #eSysmap,a1 | end of map
828: addl a5,a1 | relocate
829: Lispt3:
830: movl #PG_NV,a0@+ | invalidate PTE
831: cmpl a1,a0 | done yet?
832: jcs Lispt3 | no, keep going
833: /* go back and initialize IOmap */
834: movl #_IOmap,a0 | IO map addr
835: addl a5,a0 | relocate
836: movl #_eIOmap,a1 | end of map
837: addl a5,a1 | relocate
838: movl #IOBASE,d1 | physical IO base
839: andl #PG_FRAME,d1 | mask to frame number
840: orl #PG_RW+PG_CI+PG_V,d1 | mark valid, RW and CI
841: Lispt4:
842: movl d1,a0@+ | load PTE
843: addl #NBPG,d1 | increment page frame number
844: cmpl a1,a0 | done yet?
845: jcs Lispt4 | no, keep going
846: /* initialize proc. 0 (system) segment table */
847: movl #_Sysseg,a0 | segment table
848: addl a5,a0 | relocate
849: movl #eSysmap-_Sysmap/NBPG*4,a1 | bytes of PTEs for Sysmap
850: addl a0,a1 | make an end count
851: movl #_Sysmap,d1 | system PT addr
852: addl a5,d1 | relocate
853: andl #SG_FRAME,d1 | mask to frame number
854: orl #SG_RW+SG_V,d1 | mark as RW and valid
855: Lispt5:
856: movl d1,a0@+ | load STE
857: addl #NBPG,d1 | increment page frame number
858: cmpl a1,a0 | done yet?
859: jcs Lispt5 | no, keep going
860: /* invalidate the unused part */
861: movl #eSysseg,a1 | end of segment table
862: addl a5,a1 | relocate
863: Lispt6:
864: movl #SG_NV,a0@+ | invalidate STE
865: cmpl a1,a0 | done yet?
866: jcs Lispt6 | no, keep going
867:
868: /*
869: * Setup page table for process 0.
870: *
871: * We set up page table access for the kernel via Usrptmap (usrpt)
872: * and access to the u-area itself via Umap (u). First page beyond
873: * kernel BSS (d0) is used for proc0 page table. Next UPAGES pages
874: * following are for u-area.
875: */
876: addl a5,d0 | relocate PT address
877: movl d0,d1
878: andl #PG_FRAME,d1 | mask to page frame number
879: orl #PG_RW+PG_V,d1 | RW and valid
880: movl #_Usrptmap,a1 | get PT map address
881: addl a5,a1 | relocate
882: movl d1,a1@ | validate PTE for proc0 PT
883: movl d0,a0 | base of proc0 PT
884: addl #NBPG,d0 | plus one page yields
885: movl d0,a2 | base of u-area
886: /* invalidate entire page table */
887: Liudot1:
888: movl #PG_NV,a0@+ | invalidate PTE
889: cmpl a2,a0 | done yet?
890: jcs Liudot1 | no, keep going
891: /* now go back and validate u-area PTEs */
892: subl #HIGHPAGES*4,a0 | base of PTEs for u-area (p_addr)
893: movl a0,a1
894: addl #UPAGES*4,a1 | end of PTEs for u-area
895: movl d0,d1 | get base of u-area
896: andl #PG_FRAME,d1 | mask to page frame number
897: orl #PG_RW+PG_V,d1 | add valid and writable
898: movl #_Umap,a3 | address of u
899: addl a5,a3 | relocate
900: Liudot2:
901: movl d1,a0@+ | validate p_addr PTE
902: movl d1,a3@+ | validate u PTE
903: addl #NBPG,d1 | to next page
904: cmpl a1,a0 | done yet?
905: jcs Liudot2 | no, keep going
906: /* clear process 0 u-area */
907: addl #NBPG*UPAGES,d0 | end of u-area
908: Lclru1:
909: clrl a2@+ | clear
910: cmpl d0,a2 | done yet?
911: jcs Lclru1 | no, keep going
912: movl a2,a4 | save addr of first avail page
913:
914: /*
915: * Prepare to enable MMU.
916: * Since the kernel is not mapped logical == physical we must insure
917: * that when the MMU is turned on, all prefetched addresses (including
918: * the PC) are valid. In order guarentee that, we map the last page of
919: * memory logical == physical and load up that page with enough code to
920: * defeat the prefetch, then we execute the jump back to here.
921: *
922: * Is this all really necessary, or am I paranoid??
923: */
924: movl #_Sysseg,d1 | system segment table addr
925: addl a5,d1 | relocate
926: lea _mmutype,a0
927: addl a5,a0
928: tstl a0@ | HP MMU?
929: jeq Lhpmmu2 | yes, skip
930: lea _protorp,a0
931: addl a5,a0
932: movl #0x80000202,a0@ | nolimit + share global + 4 byte PTEs
933: movl d1,a0@(4) | + segtable address
934: .long 0xf0104800 | pmove a0@,srp
935: movl #0x80000002,a0@ | reinit upper half for CRP loads
936: jra Lstploaddone | done
937: Lhpmmu2:
938: moveq #PGSHIFT,d2
939: lsrl d2,d1 | convert to page frame
940: movl d1,IOBASE+MMUSSTP | load in sysseg table register
941: Lstploaddone:
942: movl #eSysseg-4,a1 | last entry in sysseg table
943: addl a5,a1 | relocate
944: movl d0,d1 | use page after proc0 u for tmp PT
945: andl #SG_FRAME,d1 | mask to page frame
946: orl #SG_RW+SG_V,d1 | mark valid and writable
947: movl d1,a1@ | load in segment table
948: movl d0,a1 | page table address
949: addl #NBPG-4,a1 | move to last entry
950: movl #MAXADDR,d1 | address of last page of memory
951: movl d1,a2
952: andl #PG_FRAME,d1 | mask to page frame
953: orl #PG_RW+PG_V,d1 | mark valid and writable
954: movl d1,a1@ | store PTE in table
955: movl #Lhighcode,a1 | addr of high code
956: addl a5,a1 | relocate
957: movl #Lehighcode,a3 | end addr
958: addl a5,a3 | relocate
959: Lcodecopy:
960: movw a1@+,a2@+ | copy a word
961: cmpl a3,a1 | done yet?
962: jcs Lcodecopy | no, keep going
963: jmp MAXADDR | go for it!
964:
965: Lhighcode:
966: lea _mmutype,a0
967: addl a5,a0
968: tstl a0@ | HP MMU?
969: jeq Lhpmmu3 | yes, skip
970: movl #MMU_IEN+MMU_FPE,IOBASE+MMUCMD | enable 68881 and i-cache
971: movl #0x82c0aa00,a2@ | value to load TC with
972: .long 0xf0124000 | pmove a2@,tc
973: jmp Lenab1
974: Lhpmmu3:
975: movl #0,IOBASE+MMUCMD | clear external cache
976: movl #MMU_ENAB,IOBASE+MMUCMD | turn on MMU
977: jmp Lenab1 | jmp to mapped code
978: Lehighcode:
979:
980: /*
981: * Should be running mapped from this point on
982: */
983: Lenab1:
984: /* while the ROM scratch page is mapped, check for internal HP-IB in SYSFLAG */
985: btst #5,0xfffffed2 | internal HP-IB?
986: jeq Linitmem | yes, have HP-IB continue normally
987: clrl _internalhpib | no, clear associated address
988: /* init mem sizes */
989: Linitmem:
990: movl #MAXADDR,d1 | last page
991: moveq #PGSHIFT,d2
992: lsrl d2,d1 | convert to page (click) number
993: movl d1,_maxmem | save as maxmem
994: movl _lowram,d0 | lowram value from ROM via boot
995: lsrl d2,d0 | convert to page number
996: subl d0,d1 | compute amount of RAM present
997: movl d1,_freemem | save as freemem
998: movl d1,_physmem | and physmem
999: /* initialize (slightly) the pcb */
1000: movl #_u,a1 | proc0 u-area
1001: movl a1,sp
1002: addl #UPAGES*NBPG-4,sp | set kernel stack to end of u-area
1003: movl #USRSTACK-4,a2
1004: movl a2,usp | init user SP
1005: movl #_usrpt,a1@(PCB_P0BR) | p0br: SVA of text/data user PT
1006: clrl a1@(PCB_P0LR) | p0lr: 0 (does not really exist)
1007: movl #_usrpt+NBPG,d0 | addr of end of PT
1008: subl #P1PAGES*4,d0 | backup size of P1 region
1009: movl d0,a1@(PCB_P1BR) | p1br: P1PAGES from end of PT
1010: movl #P1PAGES-HIGHPAGES,a1@(PCB_P1LR) | p1lr: vax style
1011: movl #CLSIZE,a1@(PCB_SZPT) | page table size
1012: clrw a1@(PCB_FLAGS) | clear flags
1013: #ifdef FPCOPROC
1014: clrl a1@(PCB_FPCTX) | ensure null FP context
1015: movl a1,sp@-
1016: jbsr _m68881_restore | restore it (does not kill a1)
1017: addql #4,sp
1018: #endif
1019: addl #PCB_SIGC,a1 | address of proc0 sig trampoline code
1020: movl #Lsigcode,a2 | address of sig trampoline proto
1021: Lsigc:
1022: movw a2@+,a1@+ | copy
1023: cmpl #Lesigcode,a2 | done yet?
1024: jcs Lsigc | no, keep going
1025: /* flush TLB and turn on caches */
1026: movl #PG_NV,eSysseg-4 | invalidate last page
1027: jbsr _TBIA | invalidate TLB
1028: movl #CACHE_ON,d0
1029: movc d0,cacr | clear cache(s)
1030: tstl _ectype
1031: jeq Lnocache0
1032: orl #MMU_CEN,_IObase+MMUCMD | turn on external cache
1033: Lnocache0:
1034: /* final setup for C code */
1035: movw #PSL_LOWIPL,sr | lower SPL
1036: movl d7,_boothowto | save reboot flags
1037: movl d6,_bootdev | and boot device
1038: movl a4,d1 | addr of first available RAM
1039: moveq #PGSHIFT,d2
1040: lsrl d2,d1 | convert to click
1041: movl d1,sp@- | param to main
1042: jbsr _main | main(firstaddr)
1043: addql #4,sp
1044: /* proc[1] == init now running here;
1045: * create a null exception frame and return to user mode in icode
1046: */
1047: clrw sp@- | vector offset/frame type
1048: clrl sp@- | return to icode location 0
1049: movw #PSL_USER,sp@- | in user mode
1050: rte
1051:
1052: /*
1053: * Signal "trampoline" code (18 bytes). Invoked from RTE setup by sendsig().
1054: *
1055: * Stack looks like:
1056: *
1057: * sp+0 -> signal number
1058: * sp+4 signal specific code
1059: * sp+8 pointer to signal context frame (scp)
1060: * sp+12 address of handler
1061: * sp+16 saved hardware state
1062: * .
1063: * .
1064: * scp+0-> beginning of signal context frame
1065: */
1066: Lsigcode:
1067: movl sp@(12),a0 | signal handler addr (4 bytes)
1068: jsr a0@ | call signal handler (2 bytes)
1069: addql #4,sp | pop signo (2 bytes)
1070: trap #1 | special syscall entry (2 bytes)
1071: movl d0,sp@(4) | save errno (4 bytes)
1072: moveq #1,d0 | syscall == exit (2 bytes)
1073: trap #0 | exit(errno) (2 bytes)
1074: Lesigcode:
1075:
1076: /*
1077: * Icode is copied out to process 1 to exec init.
1078: * If the exec fails, process 1 exits.
1079: */
1080: argv1 = argv-_icode
1081: init1 = init-_icode
1082: .globl _icode,_initflags,_szicode
1083: _icode:
1084: movl #argv1,sp@-
1085: movl #init1,sp@-
1086: clrl sp@-
1087: moveq #SYS_execv,d0
1088: trap #0
1089: moveq #SYS_exit,d0
1090: trap #0
1091:
1092: init:
1093: .asciz "/sbin/init"
1094: .even
1095: _initflags:
1096: .long 0
1097: argv:
1098: .long init+6-_icode
1099: .long _initflags-_icode
1100: .long 0
1101: _szicode:
1102: .long _szicode-_icode
1103:
1104: /*
1105: * Primitives
1106: */
1107:
1108: #ifdef GPROF
1109: #ifdef __GNUC__
1110: #define ENTRY(name) \
1111: .globl _/**/name; _/**/name: link a6,#0; jbsr mcount; unlk a6
1112: #define ALTENTRY(name, rname) \
1113: ENTRY(name); jra rname+12
1114: #else
1115: #define ENTRY(name) \
1116: .globl _/**/name; _/**/name: jbsr mcount
1117: #define ALTENTRY(name, rname) \
1118: ENTRY(name); jra rname+6
1119: #endif
1120: #else
1121: #define ENTRY(name) \
1122: .globl _/**/name; _/**/name:
1123: #define ALTENTRY(name, rname) \
1124: .globl _/**/name; _/**/name:
1125: #endif
1126:
1127: /*
1128: * update profiling information for the user
1129: * addupc(pc, &u.u_prof, ticks)
1130: */
1131: ENTRY(addupc)
1132: movl a2,sp@- | scratch register
1133: movl sp@(12),a2 | get &u.u_prof
1134: movl sp@(8),d0 | get user pc
1135: subl a2@(8),d0 | pc -= pr->pr_off
1136: jlt Lauexit | less than 0, skip it
1137: movl a2@(12),d1 | get pr->pr_scale
1138: lsrl #1,d0 | pc /= 2
1139: lsrl #1,d1 | scale /= 2
1140: mulul d1,d0 | pc /= scale
1141: moveq #14,d1
1142: lsrl d1,d0 | pc >>= 14
1143: bclr #0,d0 | pc &= ~1
1144: cmpl a2@(4),d0 | too big for buffer?
1145: jge Lauexit | yes, screw it
1146: addl a2@,d0 | no, add base
1147: movl d0,sp@- | push address
1148: jbsr _fusword | grab old value
1149: movl sp@+,a0 | grab address back
1150: cmpl #-1,d0 | access ok
1151: jeq Lauerror | no, skip out
1152: addw sp@(18),d0 | add tick to current value
1153: movl d0,sp@- | push value
1154: movl a0,sp@- | push address
1155: jbsr _susword | write back new value
1156: addql #8,sp | pop params
1157: tstl d0 | fault?
1158: jeq Lauexit | no, all done
1159: Lauerror:
1160: clrl a2@(12) | clear scale (turn off prof)
1161: Lauexit:
1162: movl sp@+,a2 | restore scratch reg
1163: rts
1164:
1165: /*
1166: * copyinstr(fromaddr, toaddr, maxlength, &lencopied)
1167: *
1168: * Copy a null terminated string from the user address space into
1169: * the kernel address space.
1170: * NOTE: maxlength must be < 64K
1171: */
1172: ENTRY(copyinstr)
1173: movl sp@(4),a0 | a0 = fromaddr
1174: movl sp@(8),a1 | a1 = toaddr
1175: moveq #0,d0
1176: movw sp@(14),d0 | d0 = maxlength
1177: jlt Lcisflt1 | negative count, error
1178: jeq Lcisdone | zero count, all done
1179: movl #Lcisflt1,_u+PCB_ONFAULT | set up to catch faults
1180: subql #1,d0 | set up for dbeq
1181: Lcisloop:
1182: movsb a0@+,d1 | grab a byte
1183: movb d1,a1@+ | copy it
1184: dbeq d0,Lcisloop | if !null and more, continue
1185: jne Lcisflt2 | ran out of room, error
1186: moveq #0,d0 | got a null, all done
1187: Lcisdone:
1188: tstl sp@(16) | return length desired?
1189: jeq Lcisret | no, just return
1190: subl sp@(4),a0 | determine how much was copied
1191: movl sp@(16),a1 | return location
1192: movl a0,a1@ | stash it
1193: Lcisret:
1194: clrl _u+PCB_ONFAULT | clear fault addr
1195: rts
1196: Lcisflt1:
1197: moveq #EFAULT,d0 | copy fault
1198: jra Lcisdone
1199: Lcisflt2:
1200: moveq #ENOENT,d0 | ran out of space
1201: jra Lcisdone
1202:
1203: /*
1204: * copyoutstr(fromaddr, toaddr, maxlength, &lencopied)
1205: *
1206: * Copy a null terminated string from the kernel
1207: * address space to the user address space.
1208: * NOTE: maxlength must be < 64K
1209: */
1210: ENTRY(copyoutstr)
1211: movl sp@(4),a0 | a0 = fromaddr
1212: movl sp@(8),a1 | a1 = toaddr
1213: moveq #0,d0
1214: movw sp@(14),d0 | d0 = maxlength
1215: jlt Lcosflt1 | negative count, error
1216: jeq Lcosdone | zero count, all done
1217: movl #Lcosflt1,_u+PCB_ONFAULT| set up to catch faults
1218: subql #1,d0 | set up for dbeq
1219: Lcosloop:
1220: movb a0@+,d1 | grab a byte
1221: movsb d1,a1@+ | copy it
1222: dbeq d0,Lcosloop | if !null and more, continue
1223: jne Lcosflt2 | ran out of room, error
1224: moveq #0,d0 | got a null, all done
1225: Lcosdone:
1226: tstl sp@(16) | return length desired?
1227: jeq Lcosret | no, just return
1228: subl sp@(4),a0 | determine how much was copied
1229: movl sp@(16),a1 | return location
1230: movl a0,a1@ | stash it
1231: Lcosret:
1232: clrl _u+PCB_ONFAULT | clear fault addr
1233: rts
1234: Lcosflt1:
1235: moveq #EFAULT,d0 | copy fault
1236: jra Lcosdone
1237: Lcosflt2:
1238: moveq #ENOENT,d0 | ran out of space
1239: jra Lcosdone
1240:
1241: /*
1242: * copystr(fromaddr, toaddr, maxlength, &lencopied)
1243: *
1244: * Copy a null terminated string from one point to another in
1245: * the kernel address space.
1246: * NOTE: maxlength must be < 64K
1247: */
1248: ENTRY(copystr)
1249: movl sp@(4),a0 | a0 = fromaddr
1250: movl sp@(8),a1 | a1 = toaddr
1251: moveq #0,d0
1252: movw sp@(14),d0 | d0 = maxlength
1253: jlt Lcsflt1 | negative count, error
1254: jeq Lcsdone | zero count, all done
1255: movl #Lcsflt1,_u+PCB_ONFAULT | set up to catch faults
1256: subql #1,d0 | set up for dbeq
1257: Lcsloop:
1258: movb a0@+,a1@+ | copy a byte
1259: dbeq d0,Lcsloop | if !null and more, continue
1260: jne Lcsflt2 | ran out of room, error
1261: moveq #0,d0 | got a null, all done
1262: Lcsdone:
1263: tstl sp@(16) | return length desired?
1264: jeq Lcsret | no, just return
1265: subl sp@(4),a0 | determine how much was copied
1266: movl sp@(16),a1 | return location
1267: movl a0,a1@ | stash it
1268: Lcsret:
1269: clrl _u+PCB_ONFAULT | clear fault addr
1270: rts
1271: Lcsflt1:
1272: moveq #EFAULT,d0 | copy fault
1273: jra Lcsdone
1274: Lcsflt2:
1275: moveq #ENOENT,d0 | ran out of space
1276: jra Lcsdone
1277:
1278: /*
1279: * Copyin(from, to, len)
1280: *
1281: * Copy specified amount of data from user space into the kernel.
1282: * NOTE: len must be < 64K
1283: */
1284: ENTRY(copyin)
1285: movl d2,sp@- | scratch register
1286: movl #Lciflt,_u+PCB_ONFAULT | catch faults
1287: movl sp@(16),d2 | check count
1288: jlt Lciflt | negative, error
1289: jeq Lcidone | zero, done
1290: movl sp@(8),a0 | src address
1291: movl sp@(12),a1 | dest address
1292: movl a0,d0
1293: btst #0,d0 | src address odd?
1294: jeq Lcieven | no, go check dest
1295: movsb a0@+,d1 | yes, get a byte
1296: movb d1,a1@+ | put a byte
1297: subql #1,d2 | adjust count
1298: jeq Lcidone | exit if done
1299: Lcieven:
1300: movl a1,d0
1301: btst #0,d0 | dest address odd?
1302: jne Lcibyte | yes, must copy by bytes
1303: movl d2,d0 | no, get count
1304: lsrl #2,d0 | convert to longwords
1305: jeq Lcibyte | no longwords, copy bytes
1306: subql #1,d0 | set up for dbf
1307: Lcilloop:
1308: movsl a0@+,d1 | get a long
1309: movl d1,a1@+ | put a long
1310: dbf d0,Lcilloop | til done
1311: andl #3,d2 | what remains
1312: jeq Lcidone | all done
1313: Lcibyte:
1314: subql #1,d2 | set up for dbf
1315: Lcibloop:
1316: movsb a0@+,d1 | get a byte
1317: movb d1,a1@+ | put a byte
1318: dbf d2,Lcibloop | til done
1319: Lcidone:
1320: moveq #0,d0 | success
1321: Lciexit:
1322: clrl _u+PCB_ONFAULT | reset fault catcher
1323: movl sp@+,d2 | restore scratch reg
1324: rts
1325: Lciflt:
1326: moveq #EFAULT,d0 | got a fault
1327: jra Lciexit
1328:
1329: /*
1330: * Copyout(from, to, len)
1331: *
1332: * Copy specified amount of data from kernel to the user space
1333: * NOTE: len must be < 64K
1334: */
1335: ENTRY(copyout)
1336: movl d2,sp@- | scratch register
1337: movl #Lcoflt,_u+PCB_ONFAULT | catch faults
1338: movl sp@(16),d2 | check count
1339: jlt Lcoflt | negative, error
1340: jeq Lcodone | zero, done
1341: movl sp@(8),a0 | src address
1342: movl sp@(12),a1 | dest address
1343: movl a0,d0
1344: btst #0,d0 | src address odd?
1345: jeq Lcoeven | no, go check dest
1346: movb a0@+,d1 | yes, get a byte
1347: movsb d1,a1@+ | put a byte
1348: subql #1,d2 | adjust count
1349: jeq Lcodone | exit if done
1350: Lcoeven:
1351: movl a1,d0
1352: btst #0,d0 | dest address odd?
1353: jne Lcobyte | yes, must copy by bytes
1354: movl d2,d0 | no, get count
1355: lsrl #2,d0 | convert to longwords
1356: jeq Lcobyte | no longwords, copy bytes
1357: subql #1,d0 | set up for dbf
1358: Lcolloop:
1359: movl a0@+,d1 | get a long
1360: movsl d1,a1@+ | put a long
1361: dbf d0,Lcolloop | til done
1362: andl #3,d2 | what remains
1363: jeq Lcodone | all done
1364: Lcobyte:
1365: subql #1,d2 | set up for dbf
1366: Lcobloop:
1367: movb a0@+,d1 | get a byte
1368: movsb d1,a1@+ | put a byte
1369: dbf d2,Lcobloop | til done
1370: Lcodone:
1371: moveq #0,d0 | success
1372: Lcoexit:
1373: clrl _u+PCB_ONFAULT | reset fault catcher
1374: movl sp@+,d2 | restore scratch reg
1375: rts
1376: Lcoflt:
1377: moveq #EFAULT,d0 | got a fault
1378: jra Lcoexit
1379:
1380: /*
1381: * non-local gotos
1382: */
1383: ALTENTRY(savectx, _setjmp)
1384: ENTRY(setjmp)
1385: movl sp@(4),a0 | savearea pointer
1386: moveml #0xFCFC,a0@ | save d2-d7/a2-a7
1387: movl sp@,a0@(48) | and return address
1388: moveq #0,d0 | return 0
1389: rts
1390:
1391: ENTRY(qsetjmp)
1392: movl sp@(4),a0 | savearea pointer
1393: lea a0@(40),a0 | skip regs we do not save
1394: movl a6,a0@+ | save FP
1395: movl sp,a0@+ | save SP
1396: movl sp@,a0@ | and return address
1397: moveq #0,d0 | return 0
1398: rts
1399:
1400: ENTRY(longjmp)
1401: movl sp@(4),a0
1402: moveml a0@+,#0xFCFC
1403: movl a0@,sp@
1404: moveq #1,d0
1405: rts
1406:
1407: /*
1408: * The following primitives manipulate the run queues.
1409: * _whichqs tells which of the 32 queues _qs
1410: * have processes in them. Setrq puts processes into queues, Remrq
1411: * removes them from queues. The running process is on no queue,
1412: * other processes are on a queue related to p->p_pri, divided by 4
1413: * actually to shrink the 0-127 range of priorities into the 32 available
1414: * queues.
1415: */
1416:
1417: .globl _whichqs,_qs,_cnt,_panic
1418: .comm _noproc,4
1419: .comm _runrun,4
1420:
1421: /*
1422: * Setrq(p)
1423: *
1424: * Call should be made at spl6(), and p->p_stat should be SRUN
1425: */
1426: ENTRY(setrq)
1427: movl sp@(4),a0
1428: tstl a0@(P_RLINK)
1429: jeq Lset1
1430: movl #Lset2,sp@-
1431: jbsr _panic
1432: Lset1:
1433: clrl d0
1434: movb a0@(P_PRI),d0
1435: lsrb #2,d0
1436: movl _whichqs,d1
1437: bset d0,d1
1438: movl d1,_whichqs
1439: lslb #3,d0
1440: addl #_qs,d0
1441: movl d0,a0@(P_LINK)
1442: movl d0,a1
1443: movl a1@(P_RLINK),a0@(P_RLINK)
1444: movl a0,a1@(P_RLINK)
1445: movl a0@(P_RLINK),a1
1446: movl a0,a1@(P_LINK)
1447: rts
1448:
1449: Lset2:
1450: .asciz "setrq"
1451: .even
1452:
1453: /*
1454: * Remrq(p)
1455: *
1456: * Call should be made at spl6().
1457: */
1458: ENTRY(remrq)
1459: movl sp@(4),a0
1460: clrl d0
1461: movb a0@(P_PRI),d0
1462: lsrb #2,d0
1463: movl _whichqs,d1
1464: bclr d0,d1
1465: jne Lrem1
1466: movl #Lrem3,sp@-
1467: jbsr _panic
1468: Lrem1:
1469: movl d1,_whichqs
1470: movl a0@(P_LINK),a1
1471: movl a0@(P_RLINK),a1@(P_RLINK)
1472: movl a0@(P_RLINK),a1
1473: movl a0@(P_LINK),a1@(P_LINK)
1474: movl #_qs,a1
1475: movl d0,d1
1476: lslb #3,d1
1477: addl d1,a1
1478: cmpl a1@(P_LINK),a1
1479: jeq Lrem2
1480: movl _whichqs,d1
1481: bset d0,d1
1482: movl d1,_whichqs
1483: Lrem2:
1484: clrl a0@(P_RLINK)
1485: rts
1486:
1487: Lrem3:
1488: .asciz "remrq"
1489: Lsw0:
1490: .asciz "swtch"
1491: .even
1492:
1493: /*
1494: * When no processes are on the runq, Swtch branches to idle
1495: * to wait for something to come ready.
1496: */
1497: .globl Idle
1498: Idle:
1499: idle:
1500: movw #PSL_LOWIPL,sr
1501: tstl _whichqs
1502: jne Lsw1
1503: stop #PSL_LOWIPL
1504: jra idle
1505:
1506: Lbadsw:
1507: movl #Lsw0,sp@-
1508: jbsr _panic
1509: /*NOTREACHED*/
1510:
1511: /*
1512: * Swtch()
1513: */
1514: ENTRY(swtch)
1515: movw sr,_u+PCB_PS
1516: movl #1,_noproc
1517: addql #1,_cnt+V_SWTCH
1518: Lsw1:
1519: clrl d0
1520: movl _whichqs,d1
1521: Lswchk:
1522: btst d0,d1
1523: jne Lswfnd
1524: addqb #1,d0
1525: cmpb #32,d0
1526: jne Lswchk
1527: jra idle
1528: Lswfnd:
1529: movw #PSL_HIGHIPL,sr
1530: movl _whichqs,d1
1531: bclr d0,d1
1532: jeq Lsw1
1533: movl d1,_whichqs
1534: movl d0,d1
1535: lslb #3,d1
1536: addl #_qs,d1
1537: movl d1,a1
1538: cmpl a1@(P_LINK),a1
1539: jeq Lbadsw
1540: movl a1@(P_LINK),a0
1541: movl a0@(P_LINK),a1@(P_LINK)
1542: movl a0@(P_LINK),a1
1543: movl a0@(P_RLINK),a1@(P_RLINK)
1544: cmpl a0@(P_LINK),d1
1545: jeq Lsw2
1546: movl _whichqs,d1
1547: bset d0,d1
1548: movl d1,_whichqs
1549: Lsw2:
1550: clrl _noproc
1551: clrl _runrun
1552: tstl a0@(P_WCHAN)
1553: jne Lbadsw
1554: cmpb #SRUN,a0@(P_STAT)
1555: jne Lbadsw
1556: clrl a0@(P_RLINK)
1557: movl a0@(P_ADDR),d0
1558: jra Lres0
1559:
1560: /*
1561: * Resume(p_addr)
1562: *
1563: * NOTE: on the PMMU we attempt to avoid flushing the entire TAC.
1564: * The effort involved in selective flushing may not be worth it,
1565: * maybe we should just flush the whole thing?
1566: */
1567: ENTRY(resume)
1568: movw sr,_u+PCB_PS
1569: movl sp@(4),d0
1570: Lres0:
1571: lea _u,a1 | &u
1572: movl usp,a0 | grab USP
1573: movl a0,a1@(PCB_USP) | and save it
1574: moveml #0xFCFC,a1@(PCB_REGS) | save non-scratch registers
1575: #ifdef FPCOPROC
1576: lea a1@(PCB_FPCTX),a0 | pointer to FP save area
1577: .word 0xf310 | fsave a0@
1578: tstb a0@ | null state frame?
1579: jeq Lresnofpsave | yes, all done
1580: .word 0xf228,0xf0ff,0x00d8 | fmovem fp0-fp7,a0@(216)
1581: .word 0xf228,0xbc00,0x0138 | fmovem fpcr/fpsr/fpiar,a0@(312)
1582: Lresnofpsave:
1583: #endif
1584: #ifdef PROFTIMER
1585: movw #SPL6,sr | protect against clock interrupts
1586: bclr #0,_profon | clear user profiling bit, was set?
1587: jeq Lskipoff | no, clock off or doing kernel only
1588: #ifdef GPROF
1589: tstb _profon | kernel profiling also enabled?
1590: jlt Lskipoff | yes, nothing more to do
1591: #endif
1592: movb #0,_IObase+CLKCR2 | no, just user, select CR3
1593: movb #0,_IObase+CLKCR3 | and turn it off
1594: Lskipoff:
1595: #endif
1596: movl _CMAP2,a1@(PCB_CMAP2) | save temporary map PTE
1597: movw #PSL_HIGHIPL,sr | go crit while changing PTEs
1598: lea tmpstk,sp | now goto a tmp stack for NMI
1599: movl d0,a0 | address of new context
1600: lea _Umap,a1 | address of PTEs for u
1601: moveq #UPAGES-1,d0 | sizeof u
1602: Lres1:
1603: movl a0@+,d1 | get PTE
1604: andl #~PG_PROT,d1 | mask out old protection
1605: orl #PG_RW+PG_V,d1 | ensure valid and writable
1606: movl d1,a1@+ | load it up
1607: dbf d0,Lres1 | til done
1608: lea _u,a1 | reload &u
1609: movl #CACHE_CLR,d0
1610: movc d0,cacr | invalidate cache(s)
1611: #if defined(HP330) || defined(HP360) || defined(HP370)
1612: tstl _mmutype | HP MMU?
1613: jeq Lhpmmu4 | yes, skip
1614: jmi Lnot68851a | must flush all on 68030 MMU
1615: #ifdef DEBUG
1616: tstl fullflush | 68851, conservative?
1617: jne Lnot68851a | yes, go flush all
1618: #endif
1619: .long 0xf0003494 | no, pflushs #4,#4 (flush super side)
1620: jra Lres2
1621: Lnot68851a:
1622: .long 0xf0002400 | pflusha
1623: Lres2:
1624: movl a1@(PCB_USTP),d0 | get USTP
1625: moveq #PGSHIFT,d1
1626: lsll d1,d0 | convert to addr
1627: lea _protorp,a0 | CRP prototype
1628: movl d0,a0@(4) | stash USTP
1629: .long 0xf0104C00 | pmove a0@,crp
1630: jra Lcxswdone | thats it
1631: Lhpmmu4:
1632: #endif
1633: #if defined(HP320) || defined(HP350)
1634: movl _IObase+MMUTBINVAL,d1 | invalidate TLB
1635: tstl _ectype | got external VAC?
1636: jle Lnocache1 | no, skip
1637: movl #_IObase+MMUCMD,a0 | addr of MMU command register
1638: andl #~MMU_CEN,a0@ | toggle cache enable
1639: orl #MMU_CEN,a0@ | to clear data cache
1640: Lnocache1:
1641: movl a1@(PCB_USTP),_IObase+MMUUSTP | context switch
1642: #endif
1643: Lcxswdone:
1644: movl a1@(U_PROCP),a0 | u.u_procp
1645: bclr #SPTECHGB-24,a0@(P_FLAG)| clear SPTECHG bit
1646: #if defined(HP330)
1647: jeq Lnot68851b | if set need to flush user TLB
1648: tstl _mmutype | 68851 PMMU?
1649: jle Lnot68851b | no, skip
1650: .long 0xf0003490 | pflushs #0,#4
1651: Lnot68851b:
1652: #endif
1653: movl a1@(PCB_CMAP2),_CMAP2 | reload tmp map
1654: moveml a1@(PCB_REGS),#0xFCFC | and registers
1655: movl a1@(PCB_USP),a0
1656: movl a0,usp | and USP
1657: #ifdef PROFTIMER
1658: tstl a1@(U_PROFSCALE) | process being profiled?
1659: jeq Lskipon | no, do nothing
1660: orb #1,_profon | turn on user profiling bit
1661: #ifdef GPROF
1662: jlt Lskipon | already profiling kernel, all done
1663: #endif
1664: lea _IObase+CLKMSB3,a0 | address timer 3 counter
1665: movl _profint,d1 | profiling interval
1666: subql #1,d1 | adjusted
1667: movepw d1,a0@(0) | set interval
1668: movb #0,_IObase+CLKCR2 | select CR3
1669: movb #64,_IObase+CLKCR3 | turn it on
1670: Lskipon:
1671: #endif
1672: #ifdef FPCOPROC
1673: lea a1@(PCB_FPCTX),a0 | pointer to FP save area
1674: tstb a0@ | null state frame?
1675: jeq Lresfprest | yes, easy
1676: .word 0xf228,0x9c00,0x0138 | fmovem a0@(312),fpcr/fpsr/fpiar
1677: .word 0xf228,0xd0ff,0x00d8 | fmovem a0@(216),fp0-fp7
1678: Lresfprest:
1679: .word 0xf350 | frestore a0@
1680: #endif
1681: tstl a1@(PCB_SSWAP) | do an alternate return?
1682: jne Lres3 | yes, go reload regs
1683: movw a1@(PCB_PS),sr | no, restore PS
1684: rts
1685: Lres3:
1686: movl a1@(PCB_SSWAP),a0 | addr of saved context
1687: clrl a1@(PCB_SSWAP) | clear flag
1688: moveml a0@+,#0x7CFC | restore registers
1689: movl a0@+,a1 | and SP
1690: cmpl sp,a1 | paranoia...
1691: jge Lres4 | ...must be popping, yes?
1692: lea tmpstk,sp | no! set up a legit stack
1693: movl #Lres5,sp@- | push a panic message
1694: jbsr _panic | and panic
1695: /* NOTREACHED */
1696: Lres4:
1697: movl a1,sp | restore SP
1698: movl a0@,sp@ | and PC
1699: moveq #1,d0 | arrange for non-zero return
1700: movw #PSL_LOWIPL,sr | lower SPL
1701: rts
1702:
1703: Lres5:
1704: .asciz "ldctx"
1705: .even
1706:
1707: /*
1708: * {fu,su},{byte,sword,word}
1709: */
1710: ALTENTRY(fuiword, _fuword)
1711: ENTRY(fuword)
1712: movl sp@(4),d0 | address to read
1713: btst #0,d0 | is it odd?
1714: jne Lfserr | yes, a fault
1715: movl #Lfserr,_u+PCB_ONFAULT | where to return to on a fault
1716: movl d0,a0
1717: movsl a0@,d0 | do read from user space
1718: jra Lfsdone
1719:
1720: ENTRY(fusword)
1721: movl sp@(4),d0
1722: btst #0,d0 | is address odd?
1723: jne Lfserr | yes, a fault
1724: movl #Lfserr,_u+PCB_ONFAULT | where to return to on a fault
1725: movl d0,a0 | address to read
1726: moveq #0,d0
1727: movsw a0@,d0 | do read from user space
1728: jra Lfsdone
1729:
1730: ALTENTRY(fuibyte, _fubyte)
1731: ENTRY(fubyte)
1732: movl #Lfserr,_u+PCB_ONFAULT | where to return to on a fault
1733: movl sp@(4),a0 | address to read
1734: moveq #0,d0
1735: movsb a0@,d0 | do read from user space
1736: jra Lfsdone
1737:
1738: Lfserr:
1739: moveq #-1,d0 | error indicator
1740: Lfsdone:
1741: clrl _u+PCB_ONFAULT | clear fault address
1742: rts
1743:
1744: ALTENTRY(suiword, _suword)
1745: ENTRY(suword)
1746: movl sp@(4),d0 | address to write
1747: btst #0,d0 | is it odd?
1748: jne Lfserr | yes, a fault
1749: movl #Lfserr,_u+PCB_ONFAULT | where to return to on a fault
1750: movl d0,a0 | address to write
1751: movl sp@(8),d0 | value to put there
1752: movsl d0,a0@ | do write to user space
1753: moveq #0,d0 | indicate no fault
1754: jra Lfsdone
1755:
1756: ENTRY(susword)
1757: movl sp@(4),d0 | address to write
1758: btst #0,d0 | is it odd?
1759: jne Lfserr | yes, a fault
1760: movl #Lfserr,_u+PCB_ONFAULT | where to return to on a fault
1761: movl d0,a0 | address to write
1762: movw sp@(10),d0 | value to put there
1763: movsw d0,a0@ | do write to user space
1764: moveq #0,d0 | indicate no fault
1765: jra Lfsdone
1766:
1767: ALTENTRY(suibyte, _subyte)
1768: ENTRY(subyte)
1769: movl #Lfserr,_u+PCB_ONFAULT | where to return to on a fault
1770: movl sp@(4),a0 | address to write
1771: movb sp@(11),d0 | value to put there
1772: movsb d0,a0@ | do write to user space
1773: moveq #0,d0 | indicate no fault
1774: jra Lfsdone
1775:
1776: /*
1777: * Copy 1 relocation unit (NBPG bytes)
1778: * from user virtual address to physical address
1779: */
1780: ENTRY(copyseg)
1781: movl sp@(8),d0 | destination page number
1782: moveq #PGSHIFT,d1
1783: lsll d1,d0 | convert to address
1784: orl #PG_CI+PG_RW+PG_V,d0 | make sure valid and writable
1785: movl d0,_CMAP2 | load in page table
1786: movl #_CADDR2,sp@- | destination kernel VA
1787: jbsr _TBIS | invalidate any old mapping
1788: addql #4,sp
1789: movl #_CADDR2,a1 | destination addr
1790: movl sp@(4),a0 | source addr
1791: movl #NBPG/4-1,d0 | count
1792: movl #Lcpydone,_u+PCB_ONFAULT | where to go on a fault
1793: Lcpyloop:
1794: movsl a0@+,d1 | read longword
1795: movl d1,a1@+ | write longword
1796: dbf d0,Lcpyloop | continue until done
1797: Lcpydone:
1798: clrl _u+PCB_ONFAULT | clear error catch
1799: rts
1800:
1801: /*
1802: * zero out physical memory
1803: * specified in relocation units (NBPG bytes)
1804: */
1805: ENTRY(clearseg)
1806: movl sp@(4),d0 | destination page number
1807: moveq #PGSHIFT,d1
1808: lsll d1,d0 | convert to address
1809: orl #PG_CI+PG_RW+PG_V,d0 | make sure valid and writable
1810: movl d0,_CMAP1 | load in page map
1811: movl #_CADDR1,sp@- | destination kernel VA
1812: jbsr _TBIS | invalidate any old mapping
1813: addql #4,sp
1814: movl #_CADDR1,a1 | destination addr
1815: movl #NBPG/4-1,d0 | count
1816: /* simple clear loop is fastest on 68020 */
1817: Lclrloop:
1818: clrl a1@+ | clear a longword
1819: dbf d0,Lclrloop | continue til done
1820: rts
1821:
1822: /*
1823: * Invalidate entire TLB.
1824: */
1825: ENTRY(TBIA)
1826: __TBIA:
1827: #if defined(HP330) || defined(HP360) || defined(HP370)
1828: tstl _mmutype | HP MMU?
1829: jeq Lhpmmu6 | yes, skip
1830: .long 0xf0002400 | no, pflusha
1831: #if defined(HP360) || defined(HP370)
1832: jpl Lmc68851a | 68851 implies no d-cache
1833: movl #DC_CLEAR,d0
1834: movc d0,cacr | invalidate on-chip d-cache
1835: Lmc68851a:
1836: #endif
1837: rts
1838: Lhpmmu6:
1839: #endif
1840: #if defined(HP320) || defined(HP350)
1841: movl _IObase+MMUTBINVAL,sp@- | do not ask me, this
1842: addql #4,sp | is how hpux does it
1843: jra __DCIA | XXX: invalidate entire cache
1844: #endif
1845: rts
1846:
1847: /*
1848: * Invalidate any TLB entry for given VA (TB Invalidate Single)
1849: */
1850: ENTRY(TBIS)
1851: #ifdef DEBUG
1852: tstl fullflush | being conservative?
1853: jne __TBIA | yes, flush entire TLB
1854: #endif
1855: #if defined(HP330) || defined(HP360) || defined(HP370)
1856: tstl _mmutype | HP MMU?
1857: jeq Lhpmmu5 | yes, skip
1858: movl sp@(4),a0 | get addr to flush
1859: #if defined(HP360) || defined(HP370)
1860: jpl Lmc68851b | is 68851?
1861: .long 0xf0103810 | pflush #0,#0,a0@
1862: movl #DC_CLEAR,d0
1863: movc d0,cacr | invalidate on-chip data cache
1864: rts
1865: Lmc68851b:
1866: #endif
1867: .long 0xf0103c10 | pflushs #0,#0,a0@
1868: rts
1869: Lhpmmu5:
1870: #endif
1871: #if defined(HP320) || defined(HP350)
1872: movl sp@(4),d0 | VA to invalidate
1873: bclr #0,d0 | ensure even
1874: movl d0,a0
1875: movw sr,d1 | go critical
1876: movw #PSL_HIGHIPL,sr | while in purge space
1877: moveq #FC_PURGE,d0 | change address space
1878: movc d0,dfc | for destination
1879: moveq #0,d0 | zero to invalidate?
1880: movsl d0,a0@ | hit it
1881: moveq #FC_USERD,d0 | back to old
1882: movc d0,dfc | address space
1883: movw d1,sr | restore IPL
1884: #endif
1885: rts
1886:
1887: /*
1888: * Invalidate supervisor side of TLB
1889: */
1890: ENTRY(TBIAS)
1891: #ifdef DEBUG
1892: tstl fullflush | being conservative?
1893: jne __TBIA | yes, flush everything
1894: #endif
1895: #if defined(HP330) || defined(HP360) || defined(HP370)
1896: tstl _mmutype | HP MMU?
1897: jeq Lhpmmu7 | yes, skip
1898: #if defined(HP360) || defined(HP370)
1899: jpl Lmc68851c | 68851?
1900: .long 0xf0003094 | pflush #4,#4
1901: movl #DC_CLEAR,d0
1902: movc d0,cacr | invalidate on-chip d-cache
1903: rts
1904: Lmc68851c:
1905: #endif
1906: .long 0xf0003494 | pflushs #4,#4
1907: rts
1908: Lhpmmu7:
1909: #endif
1910: #if defined(HP320) || defined(HP350)
1911: movl #0x8000,d0 | more
1912: movl d0,_IObase+MMUTBINVAL | HP magic
1913: jra __DCIS | XXX: invalidate entire sup. cache
1914: #endif
1915: rts
1916:
1917: /*
1918: * Invalidate user side of TLB
1919: */
1920: ENTRY(TBIAU)
1921: #ifdef DEBUG
1922: tstl fullflush | being conservative?
1923: jne __TBIA | yes, flush everything
1924: #endif
1925: #if defined(HP330) || defined(HP360) || defined(HP370)
1926: tstl _mmutype | HP MMU?
1927: jeq Lhpmmu8 | yes, skip
1928: #if defined(HP360) || defined(HP370)
1929: jpl Lmc68851d | 68851?
1930: .long 0xf0003090 | pflush #0,#4
1931: movl #DC_CLEAR,d0
1932: movc d0,cacr | invalidate on-chip d-cache
1933: rts
1934: Lmc68851d:
1935: #endif
1936: .long 0xf0003490 | pflushs #0,#4
1937: rts
1938: Lhpmmu8:
1939: #endif
1940: #if defined(HP320) || defined(HP350)
1941: moveq #0,d0 | more
1942: movl d0,_IObase+MMUTBINVAL | HP magic
1943: jra __DCIU | XXX: invalidate entire user cache
1944: #endif
1945: rts
1946:
1947: /*
1948: * Invalidate instruction cache
1949: */
1950: ENTRY(ICIA)
1951: movl #IC_CLEAR,d0
1952: movc d0,cacr | invalidate i-cache
1953: rts
1954:
1955: /*
1956: * Invalidate data cache.
1957: * HP external cache allows for invalidation of user/supervisor portions.
1958: */
1959: ENTRY(DCIA)
1960: __DCIA:
1961: #if defined(HP360) || defined(HP370)
1962: movl #DC_CLEAR,d0
1963: movc d0,cacr | invalidate on-chip d-cache
1964: #endif
1965: #if defined(HP320) || defined(HP350)
1966: tstl _ectype | got external VAC?
1967: jle Lnocache2 | no, all done
1968: movl #_IObase+MMUCMD,a0 | MMU control reg
1969: andl #~MMU_CEN,a0@ | disable cache
1970: orl #MMU_CEN,a0@ | reenable cache
1971: Lnocache2:
1972: #endif
1973: rts
1974:
1975: ENTRY(DCIS)
1976: __DCIS:
1977: #if defined(HP360) || defined(HP370)
1978: movl #DC_CLEAR,d0
1979: movc d0,cacr | invalidate on-chip d-cache
1980: #endif
1981: #if defined(HP320) || defined(HP350)
1982: tstl _ectype | got external VAC?
1983: jle Lnocache3 | no, all done
1984: movl _IObase+MMUSSTP,d0 | read the supervisor STP
1985: movl d0,_IObase+MMUSSTP | write it back
1986: Lnocache3:
1987: #endif
1988: rts
1989:
1990: ENTRY(DCIU)
1991: __DCIU:
1992: #if defined(HP360) || defined(HP370)
1993: movl #DC_CLEAR,d0
1994: movc d0,cacr | invalidate on-chip d-cache
1995: #endif
1996: #if defined(HP320) || defined(HP350)
1997: tstl _ectype | got external VAC?
1998: jle Lnocache4 | no, all done
1999: movl _IObase+MMUUSTP,d0 | read the user STP
2000: movl d0,_IObase+MMUUSTP | write it back
2001: Lnocache4:
2002: #endif
2003: rts
2004:
2005: #if defined(HP370)
2006: ENTRY(PCIA)
2007: tstl _ectype | got external PAC?
2008: jge Lnocache6 | no, all done
2009: movl #_IObase+MMUCMD,a0 | MMU control reg
2010: andl #~MMU_CEN,a0@ | disable cache
2011: orl #MMU_CEN,a0@ | reenable cache
2012: Lnocache6:
2013: rts
2014: #endif
2015:
2016: ENTRY(ecacheon)
2017: tstl _ectype
2018: jeq Lnocache7
2019: movl #_IObase+MMUCMD,a0
2020: orl #MMU_CEN,a0@
2021: Lnocache7:
2022: rts
2023:
2024: ENTRY(ecacheoff)
2025: tstl _ectype
2026: jeq Lnocache8
2027: movl #_IObase+MMUCMD,a0
2028: andl #~MMU_CEN,a0@
2029: Lnocache8:
2030: rts
2031:
2032: .globl _getsfc, _getdfc
2033: _getsfc:
2034: movc sfc,d0
2035: rts
2036: _getdfc:
2037: movc dfc,d0
2038: rts
2039:
2040: /*
2041: * Load a new user segment table pointer.
2042: */
2043: ENTRY(loadustp)
2044: #if defined(HP330) || defined(HP360) || defined(HP370)
2045: tstl _mmutype | HP MMU?
2046: jeq Lhpmmu9 | yes, skip
2047: movl sp@(4),d0 | new USTP
2048: moveq #PGSHIFT,d1
2049: lsll d1,d0 | convert to addr
2050: lea _protorp,a0 | CRP prototype
2051: movl d0,a0@(4) | stash USTP
2052: .long 0xf0104C00 | pmove a0@,crp
2053: movl #DC_CLEAR,d0
2054: movc d0,cacr | invalidate on-chip d-cache
2055: rts | since pmove flushes TLB
2056: Lhpmmu9:
2057: #endif
2058: #if defined(HP320) || defined(HP350)
2059: movl sp@(4),_IObase+MMUUSTP | load a new USTP
2060: #endif
2061: rts
2062:
2063: /*
2064: * Flush any hardware context associated with given USTP.
2065: * Only does something for HP330 where we must flush RPT
2066: * and ATC entries in PMMU.
2067: */
2068: ENTRY(flushustp)
2069: #if defined(HP330)
2070: tstl _mmutype | 68851 PMMU?
2071: jle Lnot68851 | no, nothing to do
2072: movl sp@(4),d0 | get USTP to flush
2073: moveq #PGSHIFT,d1
2074: lsll d1,d0 | convert to address
2075: movl d0,_protorp+4 | stash USTP
2076: .long 0xf039a000,_protorp | pflushr _protorp
2077: Lnot68851:
2078: #endif
2079: rts
2080:
2081: ENTRY(ploadw)
2082: #if defined(HP330) || defined(HP360) || defined(HP370)
2083: movl sp@(4),a0 | address to load
2084: .long 0xf0102011 | pload #1,a0@
2085: #endif
2086: rts
2087:
2088: /*
2089: * Set processor priority level calls. Most could (should) be replaced
2090: * by inline asm expansions. However, SPL0 and SPLX require special
2091: * handling. If we are returning to the base processor priority (SPL0)
2092: * we need to check for our emulated software interrupts.
2093: */
2094:
2095: ENTRY(spl0)
2096: moveq #0,d0
2097: movw sr,d0 | get old SR for return
2098: movw #PSL_LOWIPL,sr | restore new SR
2099: jra Lsplsir
2100:
2101: ENTRY(splx)
2102: moveq #0,d0
2103: movw sr,d0 | get current SR for return
2104: movw sp@(6),d1 | get new value
2105: movw d1,sr | restore new SR
2106: andw #PSL_IPL7,d1 | mask all but PSL_IPL
2107: jne Lspldone | non-zero, all done
2108: Lsplsir:
2109: tstb _ssir | software interrupt pending?
2110: jeq Lspldone | no, all done
2111: subql #4,sp | make room for RTE frame
2112: movl sp@(4),sp@(2) | position return address
2113: clrw sp@(6) | set frame type 0
2114: movw #PSL_LOWIPL,sp@ | and new SR
2115: jra Lgotsir | go handle it
2116: Lspldone:
2117: rts
2118:
2119: ALTENTRY(splsoftclock, _spl1)
2120: ALTENTRY(splnet, _spl1)
2121: ENTRY(spl1)
2122: moveq #0,d0
2123: movw sr,d0
2124: movw #SPL1,sr
2125: rts
2126:
2127: ENTRY(spl2)
2128: moveq #0,d0
2129: movw sr,d0
2130: movw #SPL2,sr
2131: rts
2132:
2133: ENTRY(spl3)
2134: moveq #0,d0
2135: movw sr,d0
2136: movw #SPL3,sr
2137: rts
2138:
2139: ENTRY(spl4)
2140: moveq #0,d0
2141: movw sr,d0
2142: movw #SPL4,sr
2143: rts
2144:
2145: ALTENTRY(splimp, _spl5)
2146: ALTENTRY(splbio, _spl5)
2147: ALTENTRY(spltty, _spl5)
2148: ENTRY(spl5)
2149: moveq #0,d0
2150: movw sr,d0
2151: movw #SPL5,sr
2152: rts
2153:
2154: ALTENTRY(splclock, _spl6)
2155: ENTRY(spl6)
2156: moveq #0,d0
2157: movw sr,d0
2158: movw #SPL6,sr
2159: rts
2160:
2161: ALTENTRY(splhigh, _spl7)
2162: ENTRY(spl7)
2163: moveq #0,d0
2164: movw sr,d0
2165: movw #PSL_HIGHIPL,sr
2166: rts
2167:
2168: #ifdef GPROF
2169: /*
2170: * Special versions of splhigh and splx called by mcount().
2171: * Note that __splx does not check for software interrupts.
2172: */
2173: .globl __splhigh, __splx
2174: __splhigh:
2175: moveq #0,d0
2176: movw sr,d0
2177: movw #PSL_HIGHIPL,sr
2178: rts
2179:
2180: __splx:
2181: moveq #0,d0
2182: movw sr,d0 | get current SR for return
2183: movw sp@(6),d1 | get new value
2184: movw d1,sr | restore new SR
2185: rts
2186: #endif
2187:
2188: ENTRY(_insque)
2189: movw sr,d0
2190: movw #PSL_HIGHIPL,sr | atomic
2191: movl sp@(8),a0 | where to insert (after)
2192: movl sp@(4),a1 | element to insert (e)
2193: movl a0@,a1@ | e->next = after->next
2194: movl a0,a1@(4) | e->prev = after
2195: movl a1,a0@ | after->next = e
2196: movl a1@,a0
2197: movl a1,a0@(4) | e->next->prev = e
2198: movw d0,sr
2199: rts
2200:
2201: ENTRY(_remque)
2202: movw sr,d0
2203: movw #PSL_HIGHIPL,sr | atomic
2204: movl sp@(4),a0 | element to remove (e)
2205: movl a0@,a1
2206: movl a0@(4),a0
2207: movl a0,a1@(4) | e->next->prev = e->prev
2208: movl a1,a0@ | e->prev->next = e->next
2209: movw d0,sr
2210: rts
2211:
2212: ALTENTRY(blkclr, _bzero)
2213: ENTRY(bzero)
2214: movl sp@(4),a0
2215: movl sp@(8),d0
2216: jeq 1$
2217: movl a0,d1
2218: btst #0,d1
2219: jeq 2$
2220: clrb a0@+
2221: subql #1,d0
2222: jeq 1$
2223: 2$:
2224: movl d0,d1
2225: andl #31,d0
2226: lsrl #5,d1
2227: jeq 3$
2228: 4$:
2229: clrl a0@+; clrl a0@+; clrl a0@+; clrl a0@+;
2230: clrl a0@+; clrl a0@+; clrl a0@+; clrl a0@+;
2231: subql #1,d1
2232: jne 4$
2233: tstl d0
2234: jeq 1$
2235: 3$:
2236: clrb a0@+
2237: subql #1,d0
2238: jne 3$
2239: 1$:
2240: rts
2241:
2242: /*
2243: * strlen(str)
2244: */
2245: ENTRY(strlen)
2246: moveq #-1,d0
2247: movl sp@(4),a0 | string
2248: Lslloop:
2249: addql #1,d0 | increment count
2250: tstb a0@+ | null?
2251: jne Lslloop | no, keep going
2252: rts
2253:
2254: /*
2255: * bcmp(s1, s2, len)
2256: *
2257: * WARNING! This guy only works with counts up to 64K
2258: */
2259: ENTRY(bcmp)
2260: movl sp@(4),a0 | string 1
2261: movl sp@(8),a1 | string 2
2262: moveq #0,d0
2263: movw sp@(14),d0 | length
2264: jeq Lcmpdone | if zero, nothing to do
2265: subqw #1,d0 | set up for DBcc loop
2266: Lcmploop:
2267: cmpmb a0@+,a1@+ | equal?
2268: dbne d0,Lcmploop | yes, keep going
2269: addqw #1,d0 | +1 gives zero on match
2270: Lcmpdone:
2271: rts
2272:
2273: /*
2274: * {ov}bcopy(from, to, len)
2275: *
2276: * Works for counts up to 128K.
2277: */
2278: ALTENTRY(ovbcopy, _bcopy)
2279: ENTRY(bcopy)
2280: movl sp@(12),d0 | get count
2281: jeq Lcpyexit | if zero, return
2282: movl sp@(4),a0 | src address
2283: movl sp@(8),a1 | dest address
2284: cmpl a1,a0 | src before dest?
2285: jlt Lcpyback | yes, copy backwards (avoids overlap)
2286: movl a0,d1
2287: btst #0,d1 | src address odd?
2288: jeq Lcfeven | no, go check dest
2289: movb a0@+,a1@+ | yes, copy a byte
2290: subql #1,d0 | update count
2291: jeq Lcpyexit | exit if done
2292: Lcfeven:
2293: movl a1,d1
2294: btst #0,d1 | dest address odd?
2295: jne Lcfbyte | yes, must copy by bytes
2296: movl d0,d1 | no, get count
2297: lsrl #2,d1 | convert to longwords
2298: jeq Lcfbyte | no longwords, copy bytes
2299: subql #1,d1 | set up for dbf
2300: Lcflloop:
2301: movl a0@+,a1@+ | copy longwords
2302: dbf d1,Lcflloop | til done
2303: andl #3,d0 | get remaining count
2304: jeq Lcpyexit | done if none
2305: Lcfbyte:
2306: subql #1,d0 | set up for dbf
2307: Lcfbloop:
2308: movb a0@+,a1@+ | copy bytes
2309: dbf d0,Lcfbloop | til done
2310: Lcpyexit:
2311: rts
2312: Lcpyback:
2313: addl d0,a0 | add count to src
2314: addl d0,a1 | add count to dest
2315: movl a0,d1
2316: btst #0,d1 | src address odd?
2317: jeq Lcbeven | no, go check dest
2318: movb a0@-,a1@- | yes, copy a byte
2319: subql #1,d0 | update count
2320: jeq Lcpyexit | exit if done
2321: Lcbeven:
2322: movl a1,d1
2323: btst #0,d1 | dest address odd?
2324: jne Lcbbyte | yes, must copy by bytes
2325: movl d0,d1 | no, get count
2326: lsrl #2,d1 | convert to longwords
2327: jeq Lcbbyte | no longwords, copy bytes
2328: subql #1,d1 | set up for dbf
2329: Lcblloop:
2330: movl a0@-,a1@- | copy longwords
2331: dbf d1,Lcblloop | til done
2332: andl #3,d0 | get remaining count
2333: jeq Lcpyexit | done if none
2334: Lcbbyte:
2335: subql #1,d0 | set up for dbf
2336: Lcbbloop:
2337: movb a0@-,a1@- | copy bytes
2338: dbf d0,Lcbbloop | til done
2339: rts
2340:
2341: /*
2342: * Emulate fancy VAX string operations:
2343: * scanc(count, startc, table, mask)
2344: * skpc(mask, count, startc)
2345: * locc(mask, count, startc)
2346: */
2347: ENTRY(scanc)
2348: movl sp@(4),d0 | get length
2349: jeq Lscdone | nothing to do, return
2350: movl sp@(8),a0 | start of scan
2351: movl sp@(12),a1 | table to compare with
2352: movb sp@(19),d1 | and mask to use
2353: movw d2,sp@- | need a scratch register
2354: clrw d2 | clear it out
2355: subqw #1,d0 | adjust for dbra
2356: Lscloop:
2357: movb a0@+,d2 | get character
2358: movb a1@(0,d2:w),d2 | get table entry
2359: andb d1,d2 | mask it
2360: dbne d0,Lscloop | keep going til no more or non-zero
2361: addqw #1,d0 | overshot by one
2362: movw sp@+,d2 | restore scratch
2363: Lscdone:
2364: rts
2365:
2366: ENTRY(skpc)
2367: movl sp@(8),d0 | get length
2368: jeq Lskdone | nothing to do, return
2369: movb sp@(7),d1 | mask to use
2370: movl sp@(12),a0 | where to start
2371: subqw #1,d0 | adjust for dbcc
2372: Lskloop:
2373: cmpb a0@+,d1 | compate with mask
2374: dbne d0,Lskloop | keep going til no more or zero
2375: addqw #1,d0 | overshot by one
2376: Lskdone:
2377: rts
2378:
2379: ENTRY(locc)
2380: movl sp@(8),d0 | get length
2381: jeq Llcdone | nothing to do, return
2382: movb sp@(7),d1 | mask to use
2383: movl sp@(12),a0 | where to start
2384: subqw #1,d0 | adjust for dbcc
2385: Llcloop:
2386: cmpb a0@+,d1 | compate with mask
2387: dbeq d0,Llcloop | keep going til no more or non-zero
2388: addqw #1,d0 | overshot by one
2389: Llcdone:
2390: rts
2391:
2392: /*
2393: * Emulate VAX FFS (find first set) instruction.
2394: */
2395: ENTRY(ffs)
2396: moveq #-1,d0
2397: movl sp@(4),d1
2398: beq Lffsdone
2399: Lffsloop:
2400: addql #1,d0
2401: btst d0,d1
2402: beq Lffsloop
2403: Lffsdone:
2404: addql #1,d0
2405: rts
2406:
2407: #ifdef FPCOPROC
2408: /*
2409: * Save and restore 68881 state.
2410: * Pretty awful looking since our assembler does not
2411: * recognize FP mnemonics.
2412: */
2413: ENTRY(m68881_save)
2414: movl sp@(4),a0 | save area pointer
2415: .word 0xf310 | fsave a0@
2416: tstb a0@ | null state frame?
2417: jeq Lm68881sdone | yes, all done
2418: .word 0xf228,0xf0ff,0x00d8 | fmovem fp0-fp7,a0@(216)
2419: .word 0xf228,0xbc00,0x0138 | fmovem fpcr/fpsr/fpiar,a0@(312)
2420: Lm68881sdone:
2421: rts
2422:
2423: ENTRY(m68881_restore)
2424: movl sp@(4),a0 | save area pointer
2425: tstb a0@ | null state frame?
2426: jeq Lm68881rdone | yes, easy
2427: .word 0xf228,0x9c00,0x0138 | fmovem a0@(312),fpcr/fpsr/fpiar
2428: .word 0xf228,0xd0ff,0x00d8 | fmovem a0@(216),fp0-fp7
2429: Lm68881rdone:
2430: .word 0xf350 | frestore a0@
2431: rts
2432: #endif
2433:
2434: /*
2435: * Handle the nitty-gritty of rebooting the machine.
2436: * Basically we just turn off the MMU and jump to the appropriate ROM routine.
2437: * Note that we must be running in an address range that is mapped one-to-one
2438: * logical to physical so that the PC is still valid immediately after the MMU
2439: * is turned off.
2440: */
2441: .globl _doboot
2442: _doboot:
2443: movl #CACHE_OFF,d0
2444: movc d0,cacr | disable on-chip cache(s)
2445: #if defined(HP320) || defined(HP350) || defined(HP370)
2446: tstl _ectype
2447: jeq Lnocache5
2448: andl #~MMU_CEN,_IObase+MMUCMD| disable external cache
2449: Lnocache5:
2450: #endif
2451: /* one-to-one map the last page of memory */
2452: movl #MAXADDR,d0 | last page of RAM used to pass params
2453: orl #PG_RW+PG_V,d0 | create a PTE
2454: movl d0,_mmap | to access that page
2455: jbsr _TBIA | invalidate TLB
2456: movl #MAXADDR,d0 | last page of RAM is also used
2457: orl #SG_RW+SG_V,d0 | as the page table for itself
2458: movl d0,eSysseg-4 | (ok since it needs only last word)
2459: movl _vmmap+NBPG-4,d2 | save old contents
2460: movl _mmap,_vmmap+NBPG-4 | store PTE in new page table
2461: jbsr _TBIA | invalidate again
2462: lea MAXADDR,a0 | can now access last page
2463: movl _boothowto,a0@+ | store howto
2464: movl _bootdev,a0@+ | and devtype
2465: lea Lbootcode,a1 | start of boot code
2466: lea Lebootcode,a3 | end of boot code
2467: Lbootcopy:
2468: movw a1@+,a0@+ | copy a word
2469: cmpl a3,a1 | done yet?
2470: jcs Lbootcopy | no, keep going
2471: jmp MAXADDR+8 | jump to last page
2472:
2473: Lbootcode:
2474: lea MAXADDR+0x800,sp | physical SP in case of NMI
2475: #if defined(HP330) || defined(HP360) || defined(HP370)
2476: tstl _mmutype | HP MMU?
2477: jeq LhpmmuB | yes, skip
2478: movl #0,a0@ | value for pmove to TC (turn off MMU)
2479: .long 0xf0104000 | pmove a0@,tc
2480: movl d2,MAXADDR+NBPG-4 | restore old high page contents
2481: jmp 0x1A4 | goto REQ_REBOOT
2482: LhpmmuB:
2483: #endif
2484: #if defined(HP320) || defined(HP350)
2485: movl #0xFFFF0000,_IObase+MMUCMD | totally disable MMU
2486: movl d2,MAXADDR+NBPG-4 | restore old high page contents
2487: jmp 0x1A4 | goto REQ_REBOOT
2488: #endif
2489: Lebootcode:
2490:
2491: .data
2492: .space NBPG
2493: tmpstk:
2494: .globl _machineid
2495: _machineid:
2496: .long 0 | default to 320
2497: .globl _mmutype,_protorp
2498: _mmutype:
2499: .long 0 | default to HP MMU
2500: _protorp:
2501: .long 0,0 | prototype root pointer
2502: .globl _ectype
2503: _ectype:
2504: .long 0 | external cache type, default to none
2505: .globl _cold
2506: _cold:
2507: .long 1 | cold start flag
2508: #ifdef DEBUG
2509: .globl fullflush
2510: fullflush:
2511: .long 0
2512: .globl timebomb
2513: timebomb:
2514: .long 0
2515: #endif
2516: /* interrupt counters */
2517: .globl _intrcnt,_eintrcnt,_intrnames,_eintrnames
2518: _intrnames:
2519: .asciz "spur"
2520: .asciz "hil"
2521: .asciz "lev2"
2522: .asciz "lev3"
2523: .asciz "lev4"
2524: .asciz "lev5"
2525: .asciz "dma"
2526: .asciz "clock"
2527: #ifdef PROFTIMER
2528: .asciz "pclock"
2529: #endif
2530: .asciz "nmi"
2531: _eintrnames:
2532: .even
2533: _intrcnt:
2534: #ifdef PROFTIMER
2535: .long 0,0,0,0,0,0,0,0,0,0
2536: #else
2537: .long 0,0,0,0,0,0,0,0,0
2538: #endif
2539: _eintrcnt:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.