1 /*
2 * Mach Operating System
3 * Copyright (c) 1991 Carnegie Mellon University
4 * Copyright (c) 1991 IBM Corporation
5 * All Rights Reserved.
6 *
7 * Permission to use, copy, modify and distribute this software and its
8 * documentation is hereby granted, provided that both the copyright
9 * notice and this permission notice appear in all copies of the
10 * software, derivative works or modified versions, and any portions
11 * thereof, and that both notices appear in supporting documentation,
12 * and that the name IBM not be used in advertising or publicity
13 * pertaining to distribution of the software without specific, written
14 * prior permission.
15 *
16 * CARNEGIE MELLON AND IBM ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17 * CONDITION. CARNEGIE MELLON AND IBM DISCLAIM ANY LIABILITY OF ANY KIND FOR
18 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19 *
20 * Carnegie Mellon requests users of this software to return to
21 *
22 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
23 * School of Computer Science
24 * Carnegie Mellon University
25 * Pittsburgh PA 15213-3890
26 *
27 * any improvements or extensions that they make and grant Carnegie Mellon
28 * the rights to redistribute these changes.
29 */
30
31
32 /*
33 * HISTORY
34 * $Log: abioscall.s,v $
35 * Revision 2.2 93/02/04 07:58:44 danner
36 * Defined NO_ABIOS_INTERRUPTS here instead of as a config option.
37 * [93/01/16 chs]
38 *
39 * Set thread stack descriptor base address in abioscall.
40 * [92/03/24 dbg@ibm]
41 *
42 */
43
44 /
45 / call_abios( (u_long) 16_bit far ptr, (u_long) 0, request, anchor ptr, 0, 0);
46 / the last two are reserved areas to store stuff we need..
47 /
48
49 #define LOCORE
50 #include <i386/asm.h>
51 #include "./assym.s"
52
53 #define NO_ABIOS_INTERRUPTS 1
54
55 /
56 / call ABIOS
57 /
58 / check to see if we are running on the interrupt stack
59 / change to the appropriate stack selector and fix esp to be an offset
60 / into that stack selector.
61 / Note: the changing of %esp MUST happen in the instruction following
62 / setting of %ss! Touching the SS disables interrupts for one instruction.
63 .set RET_SAVE,20
64 .set ABIOS_ROUTE,0x14
65 Entry(abios_call)
66 / Save the return address
67 popl %eax
68 mov %eax,RET_SAVE(%esp)
69 #ifdef NO_ABIOS_INTERRUPTS
70 cli / disable interrupts while in ABIOS
71 #endif NO_ABIOS_INTERRUPTS
72 cmpl _int_stack_high,%esp / on an interrupt stack?
73 ja 1f
74
75 / running on interrupt stack
76
77 pushl $(ABIOS_INT_RET<<16) / return to abios_int_return
78 movl $(ABIOS_INT_SS),%eax / switch to 16-bit stack segment
79 movw %ax,%ss
80 subl $_intstack,%esp / change to 16-bit stack pointer
81 data16
82 ljmp ABIOS_ROUTE(%esp) / call abios
83
84 / running on current thread`s kernel stack
85 1:
86 pushl $(ABIOS_TH_RET<<16) / return to abios_th_return
87 movl _active_stacks,%edx / get base of current stack
88 movl %edx,%eax / set in descriptor:
89 movw %ax,_gdt+ABIOS_TH_SS+2 / 15..0
90 shrl $16,%eax
91 movb %al,_gdt+ABIOS_TH_SS+4 / 23..16
92 movb %ah,_gdt+ABIOS_TH_SS+7 / 31..24
93 movl $(ABIOS_TH_SS),%eax / switch to
94 movw %ax,%ss / 16-bit stack segment
95 subl %edx,%esp / change to 16-bit pointer
96 data16
97 ljmp ABIOS_ROUTE(%esp) / call abios
98
99 /
100 / return from ABIOS
101 /
102 / abios_int_return jumps here
103 int_return_here:
104 / now set up data to restore the stack
105 movw %ds,%ax
106 movw %ax,%ss / switch to 32-bit stack segment
107 addl $_intstack,%esp / restore 32-bit pointer
108 #ifdef NO_ABIOS_INTERRUPTS
109 sti / re-enable interrupts
110 #endif NO_ABIOS_INTERRUPTS
111 jmp *RET_SAVE(%esp) / return to caller
112
113 / Cannot return to a gate... so we return to a 16-bit code
114 / segment, which jumps to the 32-bit flat code segment.
115 Entry(abios_int_return)
116 ljmp $(KERNEL_CS),$ int_return_here
117
118 / abios_th_return jumps here
119 th_return_here:
120 / now set up data to restore the stack
121 movw %ds,%ax
122 movw %ax,%ss / switch to 32-bit stack segment
123 addl _active_stacks,%esp / restore 32-bit pointer
124 #ifdef NO_ABIOS_INTERRUPTS
125 sti / re-enable interrupts
126 #endif NO_ABIOS_INTERRUPTS
127 jmp *RET_SAVE(%esp) / return to caller
128
129 / Cannot return to a gate... so we return to a 16-bit code
130 / segment, which jumps to the 32-bit flat code segment.
131 Entry(abios_th_return)
132 ljmp $(KERNEL_CS),$ th_return_here
133
134 #ifdef IDLE_WAIT_TEST
135 /
136 /
137 /
138 / Temparary test code to find out who is trashing registers!!
139 /
140 /
141 /
142 Entry(idle_wait_test)
143 push %ebp
144 movl %esp,%ebp
145 pushal
146 mov 8(%ebp),%ebx
147 movl 12(%ebp),%edi
148 movl 16(%ebp),%esi
149 movl $ 0xaaaaaaaa,%eax
150 movl $ 0xcccccccc,%ecx
151 movl $ 0xdddddddd,%edx
152 1:
153 cmpl $ 0,(%ebx)
154 jnz 2f
155 cmpl $ 0,(%edi)
156 jnz 2f
157 cmpl $ 0,(%esi)
158 jnz 2f
159 cmpl 8(%ebp),%ebx
160 jnz 3f
161 cmpl 12(%ebp),%edi
162 jnz 3f
163 cmpl 16(%ebp),%esi
164 jnz 3f
165 cmpl $ 0xaaaaaaaa,%eax
166 jnz 3f
167 cmpl $ 0xcccccccc,%ecx
168 jnz 3f
169 cmpl $ 0xdddddddd,%edx
170 jnz 3f
171 jmp 1b
172 2:
173 popal
174 pop %ebp
175 ret
176 3:
177 int $ 3
178
179 #endif IDLE_WAIT_TEST
180
181 /*
182 * Allocate a free GDT entry.
183 * Done in assembler to use lock prefix instead of SPL.
184 */
185 .data
186 .globl _gdt_hint
187 _gdt_hint:
188 .long ABIOS_FIRST_AVAIL_SEL
189 .text
190
191 Entry(allocate_gdt)
192 movl _gdt_hint,%eax / start after last used GDT entry
193 movl $(GDTSZ-(ABIOS_FIRST_AVAIL_SEL>>3)),%ecx
194 / set limit on searches
195 alloc_loop:
196 lock
197 btsl $7,_gdt+5(%eax) / test-and-set ACC_P (segment present)
198 jnc alloc_found / found one if bit wasn`t set
199 addl $8,%eax / try next entry
200 cmpl $(GDTSZ<<3),%eax / if at end of table,
201 jb 0f
202 movl $(ABIOS_FIRST_AVAIL_SEL),%eax
203 / reset to beginning
204 0: loop alloc_loop
205
206 movl $0xffff,%eax / no descriptors available
207 ret
208
209 alloc_found: / found one
210 movl %eax,_gdt_hint / set hint
211 ret / return selector
212
213 /*
214 * Free a selector.
215 */
216 Entry(free_gdt)
217 movl 4(%esp),%eax / get selector
218 movl $0,_gdt(%eax) / clear first word
219 lock / clear second word (and present bit)
220 andl $0,_gdt+4(%eax) / with locked instruction
221 movl %eax,_gdt_hint / set hint
222 ret
Cache object: 5b3c9709c2df83550ffafba5791eb317
|