|
|
1.1 root 1: .globl entry, __switch_context, __exit_context, halt, init_exceptions
2:
3: .text
4: .align 4
5:
6: /*
7: * Entry point
8: * We start execution from here.
9: * It is assumed that CPU is in 32-bit protected mode and
10: * all segments are 4GB and base zero (flat model).
11: */
12: entry:
13: /* Save boot context and switch to our main context.
14: * Main context is statically defined in C.
15: */
16: pushl %cs
17: call __switch_context
18:
19: /* We get here when the main context switches back to
20: * the boot context.
21: * Return to previous bootloader.
22: */
23: ret
24:
25: /*
26: * Switch execution context
27: * This saves registers, segments, and GDT in the stack, then
28: * switches the stack, and restores everything from the new stack.
29: * This function takes no argument. New stack pointer is
30: * taken from global variable __context, and old stack pointer
31: * is also saved to __context. This way we can just jump to
32: * this routine to get back to the original context.
33: *
34: * Call this routine with lcall or pushl %cs; call.
35: */
36: __switch_context:
37: /* Save everything in current stack */
38: pushfl /* 56 */
39: pushl %ds /* 52 */
40: pushl %es /* 48 */
41: pushl %fs /* 44 */
42: pushl %gs /* 40 */
43: pushal /* 8 */
44: subl $8, %esp
45: movw %ss, (%esp) /* 0 */
46: sgdt 2(%esp) /* 2 */
47:
48: #if 0
49: /* Swap %cs and %eip on the stack, so lret will work */
50: movl 60(%esp), %eax
51: xchgl %eax, 64(%esp)
52: movl %eax, 60(%esp)
53: #endif
54:
55: /* At this point we don't know if we are on flat segment
56: * or relocated. So compute the address offset from %eip.
57: * Assuming CS.base==DS.base==SS.base.
58: */
59: call 1f
60: 1: popl %ebx
61: subl $1b, %ebx
62:
63: /* Interrupts are not allowed... */
64: cli
65:
66: /* Current context pointer is our stack pointer */
67: movl %esp, %esi
68:
69: /* Normalize the ctx pointer */
70: subl %ebx, %esi
71:
72: /* Swap it with new value */
73: xchgl %esi, __context(%ebx)
74:
75: /* Adjust new ctx pointer for current address offset */
76: addl %ebx, %esi
77:
78: /* Load new %ss and %esp to temporary */
79: movzwl (%esi), %edx
80: movl 20(%esi), %eax
81:
82: /* Load new GDT */
83: lgdt 2(%esi)
84:
85: /* Load new stack segment with new GDT */
86: movl %edx, %ss
87:
88: /* Set new stack pointer, but we have to adjust it because
89: * pushal saves %esp value before pushal, and we want the value
90: * after pushal.
91: */
92: leal -32(%eax), %esp
93:
94: /* Load the rest from new stack */
95: popal
96: popl %gs
97: popl %fs
98: popl %es
99: popl %ds
100: popfl
101:
102: /* Finally, load new %cs and %eip */
103: lret
104:
105: __exit_context:
106: /* Get back to the original context */
107: pushl %cs
108: call __switch_context
109:
110: /* We get here if the other context attempt to switch to this
111: * dead context. This should not happen. */
112:
113: halt:
114: cli
115: hlt
116: jmp halt
117:
118: /*
119: * initialize exception handler. All exceptions end up in the same
120: * C function.
121: */
122:
123: init_exceptions:
124: pushl %ebx
125: pushl %edi
126:
127: /* Initialize the Interrupt Descriptor table */
128: leal _idt, %edi
129: leal vec0, %ebx
130: movl $(0x08 << 16), %eax /* cs selector */
131:
132: 1: movw %bx, %ax
133: movl %ebx, %edx
134: movw $0x8E00, %dx /* Interrupt gate - dpl=0, present */
135: movl %eax, 0(%edi)
136: movl %edx, 4(%edi)
137: addl $6, %ebx
138: addl $8, %edi
139: cmpl $_idt_end, %edi
140: jne 1b
141:
142: /* Load the Interrupt descriptor table */
143: lidt idtarg
144:
145: movl $0, %eax
146: popl %edi
147: popl %ebx
148: ret
149:
150: vec0:
151: pushl $0 /* error code */
152: pushl $0 /* vector */
153: jmp int_hand
154: vec1:
155: pushl $0 /* error code */
156: pushl $1 /* vector */
157: jmp int_hand
158:
159: vec2:
160: pushl $0 /* error code */
161: pushl $2 /* vector */
162: jmp int_hand
163:
164: vec3:
165: pushl $0 /* error code */
166: pushl $3 /* vector */
167: jmp int_hand
168:
169: vec4:
170: pushl $0 /* error code */
171: pushl $4 /* vector */
172: jmp int_hand
173:
174: vec5:
175: pushl $0 /* error code */
176: pushl $5 /* vector */
177: jmp int_hand
178:
179: vec6:
180: pushl $0 /* error code */
181: pushl $6 /* vector */
182: jmp int_hand
183: vec7:
184: pushl $0 /* error code */
185: pushl $7 /* vector */
186: jmp int_hand
187:
188: vec8:
189: /* error code */
190: pushl $8 /* vector */
191: jmp int_hand
192: .word 0x9090
193:
194: vec9:
195: pushl $0 /* error code */
196: pushl $9 /* vector */
197: jmp int_hand
198:
199: vec10:
200: /* error code */
201: pushl $10 /* vector */
202: jmp int_hand
203: .word 0x9090
204:
205: vec11:
206: /* error code */
207: pushl $11 /* vector */
208: jmp int_hand
209: .word 0x9090
210:
211: vec12:
212: /* error code */
213: pushl $12 /* vector */
214: jmp int_hand
215: .word 0x9090
216:
217: vec13:
218: /* error code */
219: pushl $13 /* vector */
220: jmp int_hand
221: .word 0x9090
222:
223: vec14:
224: /* error code */
225: pushl $14 /* vector */
226: jmp int_hand
227: .word 0x9090
228:
229: vec15:
230: pushl $0 /* error code */
231: pushl $15 /* vector */
232: jmp int_hand
233:
234: vec16:
235: pushl $0 /* error code */
236: pushl $16 /* vector */
237: jmp int_hand
238:
239: vec17:
240: /* error code */
241: pushl $17 /* vector */
242: jmp int_hand
243: .word 0x9090
244:
245: vec18:
246: pushl $0 /* error code */
247: pushl $18 /* vector */
248: jmp int_hand
249:
250: vec19:
251: pushl $0 /* error code */
252: pushl $19 /* vector */
253: jmp int_hand
254:
255: __divide_error:
256: pushl $0 /* error code */
257: pushl $20 /* vector */
258: jmp int_hand
259: .global __divide_error
260:
261: int_hand:
262: /* At this point on the stack there is:
263: * 0(%esp) vector
264: * 4(%esp) error code
265: * 8(%esp) eip
266: * 12(%esp) cs
267: * 16(%esp) eflags
268: */
269: pushl %edi
270: pushl %esi
271: pushl %ebp
272: /* Original stack pointer */
273: leal 32(%esp), %ebp
274: pushl %ebp
275: pushl %ebx
276: pushl %edx
277: pushl %ecx
278: pushl %eax
279:
280: pushl %esp /* Pointer to structure on the stack */
281:
282: call x86_exception
283: pop %eax /* Drop the pointer */
284:
285: popl %eax
286: popl %ecx
287: popl %edx
288: popl %ebx
289: popl %ebp /* Ignore saved %esp value */
290: popl %ebp
291: popl %esi
292: popl %edi
293:
294: addl $8, %esp /* pop of the vector and error code */
295:
296: iret
297:
298: idtarg:
299: .word _idt_end - _idt - 1 /* limit */
300: .long _idt
301: .word 0
302: _idt:
303: .fill 20, 8, 0 # idt is unitiailzed
304: _idt_end:
305:
306: .globl arch_nvram_size, arch_nvram_get, arch_nvram_put
307: arch_nvram_size:
308: xor %eax, %eax
309: ret
310:
311: arch_nvram_get:
312: ret
313:
314: arch_nvram_put:
315: ret
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.