|
|
1.1 root 1: .data
2: .asciz "@(#)vax.s 1.1 86/02/03 Copyr 1986 Sun Micro"
3: .even
4: .text
5: /*
6: * Copyright (c) 1986 by Sun Microsystems, Inc.
7: */
8:
9: /*
10: * Emulate VAX instructions on the 68020.
11: */
12:
13: #include "../h/param.h"
14: #include "../machine/asm_linkage.h"
15: #include "../machine/mmu.h"
16: #include "../machine/psl.h"
17: #include "assym.s"
18:
19: /*
20: * Macro to raise prio level,
21: * avoid dropping prio if already at high level.
22: * NOTE - Assumes that we are never in "master" mode.
23: */
24: #define RAISE(level) \
25: movw sr,d0; \
26: andw #(SR_SMODE+SR_INTPRI),d0; \
27: cmpw #(SR_SMODE+(/**/level*0x100)),d0; \
28: jge 0f; \
29: movw #(SR_SMODE+(/**/level*0x100)),sr; \
30: 0: rts
31:
32: #define SETPRI(level) \
33: movw sr,d0; \
34: movw #(SR_SMODE+(/**/level*0x100)),sr; \
35: rts
36:
37: ENTRY(splimp)
38: RAISE(3)
39:
40: ENTRY(splnet)
41: RAISE(1)
42:
43: ENTRY(splie)
44: RAISE(3)
45:
46: ENTRY(splclock)
47: RAISE(5)
48:
49: ENTRY(splzs)
50: SETPRI(6)
51:
52: ENTRY(spl7)
53: SETPRI(7)
54:
55: ENTRY2(spl6,spl5)
56: SETPRI(5)
57:
58: ENTRY(spl4)
59: SETPRI(4)
60:
61: ENTRY(spl3)
62: SETPRI(3)
63:
64: ENTRY(spl2)
65: SETPRI(2)
66:
67: ENTRY(spl1)
68: SETPRI(1)
69:
70: ENTRY(spl0)
71: SETPRI(0)
72:
73: ENTRY(splx)
74: movw sr,d0
75: movw sp@(6),sr
76: rts
77:
78: ENTRY(insque)
79: movl sp@(4),a0
80: movl sp@(8),a1
81: movl a1@,a0@
82: movl a1,a0@(4)
83: movl a0,a1@
84: movl a0@,a1
85: movl a0,a1@(4)
86: rts
87:
88: ENTRY(remque)
89: movl sp@(4),a0
90: movl a0@,a1
91: movl a0@(4),a0
92: movl a1,a0@
93: movl a0,a1@(4)
94: rts
95:
96: ENTRY(scanc)
97: movl sp@(8),a0 | string
98: movl sp@(12),a1 | table
99: movl sp@(16),d1 | mask
100: movl d2,sp@-
101: clrw d2
102: movl sp@(8),d0 | len
103: subqw #1,d0 | subtract one for dbxx
104: jmi 1f
105: 2:
106: movb a0@+,d2 | get the byte from the string
107: movb a1@(0,d2:w),d2 | get the corresponding table entry
108: andb d1,d2 | apply the mask
109: dbne d0,2b | check for loop termination
110: 1:
111: addqw #1,d0 | dbxx off by one
112: movl sp@+,d2
113: rts
114:
115: /*
116: * _whichqs tells which of the 32 queues _qs have processes in them
117: * setrq puts processes into queues, remrq removes them from queues
118: * The running process is on no queue, other processes are on a
119: * queue related to p->p_pri, divided by 4 actually to shrink the
120: * 0-127 range of priorities into the 32 available queues.
121: */
122:
123: /*
124: * setrq(p), using semi-fancy 68020 instructions.
125: *
126: * Call should be made at spl6(), and p->p_stat should be SRUN
127: */
128: ENTRY(setrq)
129: movl sp@(4),a0 | get proc pointer
130: tstl a0@(P_RLINK) | firewall: p->p_rlink must be 0
131: jne 1f
1.1.1.2 ! root 132: btst #SPROCIO_BIT-24,a0@(P_FLAG) | if he's getting PROCIO'd,
! 133: jne 3f | we leave him alone
1.1 root 134: moveq #31,d1
135: clrl d0
136: movb a0@(P_PRI),d0 | get the priority
137: lsrl #2,d0 | divide by 4
138: subl d0,d1
139: lea _qs,a1
140: movl a1@(4,d1:l:8),a1| qs[d1].ph_rlink, 8 == sizeof (qs[0])
141: movl a1@,a0@ | insque(p, blah)
142: movl a1,a0@(4)
143: movl a0,a1@
144: movl a0@,a1
145: movl a0,a1@(4)
146: bfset _whichqs{d0:#1} | set appropriate bit in whichqs
1.1.1.2 ! root 147: 3:
1.1 root 148: rts
149: 1:
150: pea 2f
151: jsr _panic
152:
153: 2: .asciz "setrq"
154: .even
155:
156: /*
157: * remrq(p), using semi-fancy 68020 instructions
158: *
159: * Call should be made at spl6().
160: */
161: ENTRY(remrq)
162: movl sp@(4),a0
1.1.1.2 ! root 163: btst #SPROCIO_BIT-24,a0@(P_FLAG) | if he's getting PROCIO'd,
! 164: jne rem2a | we leave him alone
! 165: clrl d0
1.1 root 166: movb a0@(P_PRI),d0
167: lsrl #2,d0 | divide by 4
168: bftst _whichqs{d0:#1}
169: jeq 1f
170: movl a0@,a1 | remque(p);
171: movl a0@(4),a0
172: movl a1,a0@
173: movl a0,a1@(4)
174: cmpl a0,a1
175: jne 2f | queue not empty
176: bfclr _whichqs{d0:#1} | queue empty, clear the bit
177: 2:
178: movl sp@(4),a0
179: clrl a0@(P_RLINK)
1.1.1.2 ! root 180: rem2a:
1.1 root 181: rts
182: 1:
183: pea 3f
184: jsr _panic
185:
186: 3: .asciz "remrq"
187: .even
188:
189: /*
190: * swtch(), using semi-fancy 68020 instructions
191: */
192: ENTRY(swtch)
193: movw sr,sp@- | save processor priority
194: movl #1,_noproc
195: clrl _runrun
196: bclr #AST_SCHED_BIT-24,_u+PCB_P0LR
197: 2:
198: bfffo _whichqs{#0:#32},d0 | test if any bit on
199: cmpl #32,d0
200: jne 3f | found one
201: stop #SR_LOW | must allow interrupts here
202:
203: .globl idle
204: idle: | wait here for interrupts
205: jra 2b | try again
206:
207: 3:
208: movw #SR_HIGH,sr | lock out all so _whichqs == _qs
209: moveq #31,d1
210: subl d0,d1
211: bfclr _whichqs{d0:#1}
212: jeq 2b | proc moved via lbolt interrupt
213: lea _qs,a0
214: movl a0@(0,d1:l:8),a0| get qs[d1].ph_link = p = highest pri process
215: movl a0,d1 | save it
216: movl a0@,a1 | remque(p);
217: cmpl a0,a1 | is queue empty?
218: jne 4f
219: 8:
220: pea 9f
221: jsr _panic
222: 9:
223: .asciz "swtch"
224: .even
225: 4:
226: movl a0@(4),a0
227: movl a1,a0@
228: movl a0,a1@(4)
229: cmpl a0,a1
230: jeq 5f | queue empty
231: bfset _whichqs{d0:#1} | queue not empty, set appropriate bit
232: 5:
233: movl d1,a0 | restore p
234: clrl _noproc
235: tstl a0@(P_WCHAN) || firewalls
236: jne 8b ||
237: cmpb #SRUN,a0@(P_STAT) ||
238: jne 8b ||
239: clrl a0@(P_RLINK) ||
240: addql #1,_cnt+V_SWTCH
241: movl a0,sp@-
242: jsr _resume
243: addqw #4,sp
244: movw sp@+,sr | restore processor priority
245: rts
246:
247:
248: /*
249: * fpprocp is the pointer to the proc structure whose external
250: * state (i.e. registers) was last loaded into the 68881.
251: */
252: .data
253: .globl _fpprocp
254: _fpprocp: .long 0 | struct proc *fpprocp;
255: .text
256:
257: /*
258: * masterprocp is the pointer to the proc structure for the currently
259: * mapped u area. It is used to set up the mapping for the u area
260: * by the debugger since the u area is not in the Sysmap.
261: */
262: .data
263: .globl _masterprocp
264: _masterprocp: .long 0 | struct proc *masterprocp;
265: .text
266:
267: /*
268: * resume(p)
269: *
270: * Assumes that there is only one real page to worry about (UPAGES = 1),
271: * that the kernel stack starts below the u area in the middle of
272: * a page, that the redzone is below that and is always marked
273: * for no access across all contexts, the default sfc and dfs are
274: * set to FC_MAP, and that we are running on the u area kernel stack
275: * when we are called.
276: */
277: SAVREGS = 0xFCFC
278: ENTRY(resume)
279: tstw _fppstate | is fpp present and enabled?
280: jle 1f | branch if not
281: fsave _u+U_FP_ISTATE | save internal state
282: tstw _u+U_FP_ISTATE | test for null state
283: jeq 1f | branch if so
284: fmovem fpc/fps/fpi,_u+U_FPS_CTRL | save control registers
285: fmovem fp0-fp7,_u+U_FPS_REGS | save fp data registers
286: movl _masterprocp,_fpprocp | remember whose regs are still loaded
287: 1:
288: movl sp@,_u+PCB_REGS | save return pc in pcb
289: movl sp@(4),a0 | a0 contains proc pointer
290: movw sr,_u+PCB_SR+2 | save the current psw in u area
291: orw #SR_INTPRI,sr | mask interrupts
292: moveml #SAVREGS,_u+PCB_REGS+4 | save data/address regs
293: movl a0,_masterprocp | set proc pointer for new process
294: lea eintstack,sp | use the interrupt stack
295: moveq #KCONTEXT,d0
296: movsb d0,CONTEXTBASE | invalidate context
297: lea U_MAPVAL,a1 | a1 has address used to access pme for u area
298: movl a0@(P_ADDR),a2 | get p_addr (address of pte's), a2 is scratch
299: movl a2@,d0 | get u pte
300: movsl d0,a1@ | and set pme
301: /*
302: * Check to see if we already have context. If so and
303: * SPTECHG bit is not on then set up the next context.
304: */
305: tstl a0@(P_CTX) | check p->p_ctx
306: jeq 1f | if zero, skip ahead
307: btst #SPTECHG_BIT-24,a0@(P_FLAG) | check (p->p_flag & SPTECHG)
308: jne 1f | if SPTECHG bit is on, skip ahead
309: movl a0@(P_CTX),a1
310: movw a1@(CTX_CONTEXT),d0 | get context number in d0
311: movsb d0,CONTEXTBASE | set up the context
312: 1:
313: tstw _fppstate | is fpp present and enabled?
314: jle 1f | branch if not
315: tstw _u+U_FP_ISTATE | test for null state
316: jeq 0f | branch if so
317: cmpl _fpprocp,a0 | check if we were last proc using fpp
318: beq 0f | if so, jump and skip loading ext regs
319: fmovem _u+U_FPS_REGS:w,fp0-fp7 | restore fp data registers
320: fmovem _u+U_FPS_CTRL,fpc/fps/fpi | restore control registers
321: 0:
322: frestore _u+U_FP_ISTATE | restore internal state
323: 1:
324: moveml _u+PCB_REGS+4,#SAVREGS | restore data/address regs
325: | Note: we just changed stacks
326: movw _u+PCB_SR+2,sr
327: tstl _u+PCB_SSWAP
328: jeq 1f
329: movl _u+PCB_SSWAP,sp@(4) | blech...
330: clrl _u+PCB_SSWAP
331: movw #SR_LOW,sr
332: jmp _longjmp
333: 1:
334: rts
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.