|
|
1.1 root 1: / This file contains assembly-language implementations of processor priority-
2: / level manipulation functions that would be in-lined using GCC or typical
3: / MS-DOS tools. See "spl.c" for routine documentation.
4:
5: .unixorder
6: .include struct.inc
7: .include pl.inc
8:
9: / Because the DDI/DKI processor-priority manipulation system I have chosen
10: / to implement uses interrupt masks, we need access to a reasonable amount
11: / of per-CPU global information...
12: /
13: / The current abstract IPL.
14: / The current mask for the 'plbase' abstract IPL.
15: / The table of additional masks for abstract IPLs.
16: /
17: / This implementation is for Coherent, uniprocessor only. To make life easier
18: / for this code we have put the relevant parts of the "ddi_cpu_data" structure
19: / at the front. Coherent 'as' has no structure facility, so we use .set
20: / Wouldn't this be easier if there was a .struct facility that knew about
21: / the COFF/ABI structure alignment rules?
22:
23: / struct defcpu {
24: .struct defer
25: .member df_tab,ptr
26: .member df_read,uchar
27: .member df_max,uchar
28: .member df_write,uchar
29: .member df_rlock,uchar
30: .member df_wlock,ptr
31: .ends defer
32: / };
33: .typedef defer_t,defer
34:
35: / struct dcdata {
36: .struct dcdata
37: .member dc_cpu_id,uint
38: .member dc_base_mask,ulong
39: .member dc_int_level,uchar
40: .member dc_user_level,uchar
41: .member dc_ipl,uchar
42: .member dc_defint,defer_t
43: .member dc_defproc,defer_t
44: .ends dcdata
45: / };
46: .typedef dcdata_t,dcdata
47: / struct dgdata {
48: / member offsets
49: .struct dgdata
50: .member dg_defint,defer_t
51: .ends dgdata
52: / };
53: .typedef dgdata_t,dgdata
54:
55: cpu .define __ddi_cpu_data
56: glob .define __ddi_global_data
57:
58: .extern cpu,dcdata_t
59: .extern glob,dgdata_t
60:
61: .set PICM,0x21
62: .set SPICM,0xA1
63:
64: .globl _masktab / array of longs
65:
66: .text
67:
68: .globl splbase
69: .globl spltimeout
70: .globl spldisk
71: .globl splstr
72: .globl splhi
73: .globl splx
74: .globl splraise
75: .globl splcmp
76: .globl __SET_BASE_MASK
77: .globl __CHEAP_DISABLE_INTS
78: .globl __CHEAP_ENABLE_INTS
79: .globl DDI_BASE_SLAVE_MASK
80: .globl DDI_BASE_MASTER_MASK
81:
82: / pl_t splbase (void)
83: splbase: mov $plbase, %ecx
84: jmp setnew
85:
86: spltimeout: mov $pltimeout, %ecx
87: jmp setnew
88:
89: spldisk: mov $pldisk, %ecx
90: jmp setnew
91:
92: splstr: mov $plstr, %ecx
93: jmp setnew
94:
95: splhi: mov $plhi, %ecx
96: jmp setnew
97:
98: / pl_t splx (pl_t _newpl)
99: splx:
100: movzxb 4(%esp), %ecx / new pl
101: setnew:
102: movl _masktab(%ecx,4), %eax / new mask
103:
104: / send the mask out to the PICs after including the base mask info.
105: orl cpu+dc_base_mask, %eax
106: outb $PICM
107: xchgb %ah,%al
108: outb $SPICM
109:
110: / swap the new IPL for the old one, and return the old one.
111: movzxb cpu+dc_ipl, %eax
112: movb %cl, cpu+dc_ipl
113:
114: ret
115:
116: / pl_t splraise (pl_t _newpl)
117: splraise:
118: movzxb 4(%esp), %ecx / new pl
119:
120: cmpb cpu+dc_ipl, %cl
121: jg setnew
122:
123: movzxb cpu+dc_ipl, %eax / just return old
124: ret
125:
126: / int splcmp (pl_t l, pl_t r)
127: splcmp: movzxb 4(%esp), %eax / left
128: sub 4(%esp), %eax / - right
129: jz l_eq_r / if eq, %eax == 0
130: / take advantage of 80x86 mov not changing condition codes.
131: mov $-1, %eax
132: jl l_lt_r / if <, %eax == -1
133: mov $1, %eax / if >, %eax == 1
134: l_eq_r:
135: l_lt_r:
136: ret
137:
138: / void __SET_BASE_MASK (intmask_t newmask)
139: __SET_BASE_MASK:
140: mov 4(%esp), %eax / new mask
141: mov %eax, cpu+dc_base_mask / store it
142: outb $PICM / mask low
143: mov %ah, %al
144: outb $SPICM / mask high
145: ret
146:
147: / void __CHEAP_DISABLE_INTS (void)
148: __CHEAP_DISABLE_INTS:
149: cli
150: ret
151:
152: / void __CHEAP_ENABLE_INTS (void)
153: __CHEAP_ENABLE_INTS:
154: sti
155: ret
156:
157: / These function should only be called from base level, so that we don't
158: / have to iterate over all kinds of junk to work out what the real mask
159: / level should be. This condition is trivially satisfied at the moment because
160: / these are only called by a Coherent's functions, which aren't protected by
161: / any kind of spl... (), just (possibly) an sphi ()/spl ().
162:
163: / void DDI_BASE_MASTER_MASK (uchar_t mask)
164: DDI_BASE_MASTER_MASK:
165: mov 4(%esp), %al
166: mov %al, cpu+dc_base_mask
167: outb $PICM
168: ret
169:
170: / void DDI_BASE_SLAVE_MASK (uchar_t mask)
171: DDI_BASE_SLAVE_MASK:
172: mov 4(%esp), %al
173: mov %al, cpu+dc_base_mask+1
174: outb $SPICM
175: ret
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.