|
|
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
132: moveq #31,d1
133: clrl d0
134: movb a0@(P_PRI),d0 | get the priority
135: lsrl #2,d0 | divide by 4
136: subl d0,d1
137: lea _qs,a1
138: movl a1@(4,d1:l:8),a1| qs[d1].ph_rlink, 8 == sizeof (qs[0])
139: movl a1@,a0@ | insque(p, blah)
140: movl a1,a0@(4)
141: movl a0,a1@
142: movl a0@,a1
143: movl a0,a1@(4)
144: bfset _whichqs{d0:#1} | set appropriate bit in whichqs
145: rts
146: 1:
147: pea 2f
148: jsr _panic
149:
150: 2: .asciz "setrq"
151: .even
152:
153: /*
154: * remrq(p), using semi-fancy 68020 instructions
155: *
156: * Call should be made at spl6().
157: */
158: ENTRY(remrq)
159: movl sp@(4),a0
160: clrl d0
161: movb a0@(P_PRI),d0
162: lsrl #2,d0 | divide by 4
163: bftst _whichqs{d0:#1}
164: jeq 1f
165: movl a0@,a1 | remque(p);
166: movl a0@(4),a0
167: movl a1,a0@
168: movl a0,a1@(4)
169: cmpl a0,a1
170: jne 2f | queue not empty
171: bfclr _whichqs{d0:#1} | queue empty, clear the bit
172: 2:
173: movl sp@(4),a0
174: clrl a0@(P_RLINK)
175: rts
176: 1:
177: pea 3f
178: jsr _panic
179:
180: 3: .asciz "remrq"
181: .even
182:
183: /*
184: * swtch(), using semi-fancy 68020 instructions
185: */
186: ENTRY(swtch)
187: movw sr,sp@- | save processor priority
188: movl #1,_noproc
189: clrl _runrun
190: bclr #AST_SCHED_BIT-24,_u+PCB_P0LR
191: 2:
192: bfffo _whichqs{#0:#32},d0 | test if any bit on
193: cmpl #32,d0
194: jne 3f | found one
195: stop #SR_LOW | must allow interrupts here
196:
197: .globl idle
198: idle: | wait here for interrupts
199: jra 2b | try again
200:
201: 3:
202: movw #SR_HIGH,sr | lock out all so _whichqs == _qs
203: moveq #31,d1
204: subl d0,d1
205: bfclr _whichqs{d0:#1}
206: jeq 2b | proc moved via lbolt interrupt
207: lea _qs,a0
208: movl a0@(0,d1:l:8),a0| get qs[d1].ph_link = p = highest pri process
209: movl a0,d1 | save it
210: movl a0@,a1 | remque(p);
211: cmpl a0,a1 | is queue empty?
212: jne 4f
213: 8:
214: pea 9f
215: jsr _panic
216: 9:
217: .asciz "swtch"
218: .even
219: 4:
220: movl a0@(4),a0
221: movl a1,a0@
222: movl a0,a1@(4)
223: cmpl a0,a1
224: jeq 5f | queue empty
225: bfset _whichqs{d0:#1} | queue not empty, set appropriate bit
226: 5:
227: movl d1,a0 | restore p
228: clrl _noproc
229: tstl a0@(P_WCHAN) || firewalls
230: jne 8b ||
231: cmpb #SRUN,a0@(P_STAT) ||
232: jne 8b ||
233: clrl a0@(P_RLINK) ||
234: addql #1,_cnt+V_SWTCH
235: movl a0,sp@-
236: jsr _resume
237: addqw #4,sp
238: movw sp@+,sr | restore processor priority
239: rts
240:
241:
242: /*
243: * fpprocp is the pointer to the proc structure whose external
244: * state (i.e. registers) was last loaded into the 68881.
245: */
246: .data
247: .globl _fpprocp
248: _fpprocp: .long 0 | struct proc *fpprocp;
249: .text
250:
251: /*
252: * masterprocp is the pointer to the proc structure for the currently
253: * mapped u area. It is used to set up the mapping for the u area
254: * by the debugger since the u area is not in the Sysmap.
255: */
256: .data
257: .globl _masterprocp
258: _masterprocp: .long 0 | struct proc *masterprocp;
259: .text
260:
261: /*
262: * resume(p)
263: *
264: * Assumes that there is only one real page to worry about (UPAGES = 1),
265: * that the kernel stack starts below the u area in the middle of
266: * a page, that the redzone is below that and is always marked
267: * for no access across all contexts, the default sfc and dfs are
268: * set to FC_MAP, and that we are running on the u area kernel stack
269: * when we are called.
270: */
271: SAVREGS = 0xFCFC
272: ENTRY(resume)
273: tstw _fppstate | is fpp present and enabled?
274: jle 1f | branch if not
275: fsave _u+U_FP_ISTATE | save internal state
276: tstw _u+U_FP_ISTATE | test for null state
277: jeq 1f | branch if so
278: fmovem fpc/fps/fpi,_u+U_FPS_CTRL | save control registers
279: fmovem fp0-fp7,_u+U_FPS_REGS | save fp data registers
280: movl _masterprocp,_fpprocp | remember whose regs are still loaded
281: 1:
282: movl sp@,_u+PCB_REGS | save return pc in pcb
283: movl sp@(4),a0 | a0 contains proc pointer
284: movw sr,_u+PCB_SR+2 | save the current psw in u area
285: orw #SR_INTPRI,sr | mask interrupts
286: moveml #SAVREGS,_u+PCB_REGS+4 | save data/address regs
287: movl a0,_masterprocp | set proc pointer for new process
288: lea eintstack,sp | use the interrupt stack
289: moveq #KCONTEXT,d0
290: movsb d0,CONTEXTBASE | invalidate context
291: lea U_MAPVAL,a1 | a1 has address used to access pme for u area
292: movl a0@(P_ADDR),a2 | get p_addr (address of pte's), a2 is scratch
293: movl a2@,d0 | get u pte
294: movsl d0,a1@ | and set pme
295: /*
296: * Check to see if we already have context. If so and
297: * SPTECHG bit is not on then set up the next context.
298: */
299: tstl a0@(P_CTX) | check p->p_ctx
300: jeq 1f | if zero, skip ahead
301: btst #SPTECHG_BIT-24,a0@(P_FLAG) | check (p->p_flag & SPTECHG)
302: jne 1f | if SPTECHG bit is on, skip ahead
303: movl a0@(P_CTX),a1
304: movw a1@(CTX_CONTEXT),d0 | get context number in d0
305: movsb d0,CONTEXTBASE | set up the context
306: 1:
307: tstw _fppstate | is fpp present and enabled?
308: jle 1f | branch if not
309: tstw _u+U_FP_ISTATE | test for null state
310: jeq 0f | branch if so
311: cmpl _fpprocp,a0 | check if we were last proc using fpp
312: beq 0f | if so, jump and skip loading ext regs
313: fmovem _u+U_FPS_REGS:w,fp0-fp7 | restore fp data registers
314: fmovem _u+U_FPS_CTRL,fpc/fps/fpi | restore control registers
315: 0:
316: frestore _u+U_FP_ISTATE | restore internal state
317: 1:
318: moveml _u+PCB_REGS+4,#SAVREGS | restore data/address regs
319: | Note: we just changed stacks
320: movw _u+PCB_SR+2,sr
321: tstl _u+PCB_SSWAP
322: jeq 1f
323: movl _u+PCB_SSWAP,sp@(4) | blech...
324: clrl _u+PCB_SSWAP
325: movw #SR_LOW,sr
326: jmp _longjmp
327: 1:
328: rts
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.