1 .globl entry, __switch_context, __exit_context, halt, init_exceptions
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).
13 /* Save boot context and switch to our main context.
14 * Main context is statically defined in C.
19 /* We get here when the main context switches back to
21 * Return to previous bootloader.
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.
34 * Call this routine with lcall or pushl %cs; call.
37 /* Save everything in current stack */
45 movw %ss, (%esp) /* 0 */
49 /* Swap %cs and %eip on the stack, so lret will work */
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.
63 /* Interrupts are not allowed... */
66 /* Current context pointer is our stack pointer */
69 /* Normalize the ctx pointer */
72 /* Swap it with new value */
73 xchgl %esi, __context(%ebx)
75 /* Adjust new ctx pointer for current address offset */
78 /* Load new %ss and %esp to temporary */
85 /* Load new stack segment with new GDT */
88 /* Set new stack pointer, but we have to adjust it because
89 * pushal saves %esp value before pushal, and we want the value
94 /* Load the rest from new stack */
102 /* Finally, load new %cs and %eip */
106 /* Get back to the original context */
108 call __switch_context
110 /* We get here if the other context attempt to switch to this
111 * dead context. This should not happen. */
119 * initialize exception handler. All exceptions end up in the same
127 /* Initialize the Interrupt Descriptor table */
130 movl $(0x08 << 16), %eax /* cs selector */
134 movw $0x8E00, %dx /* Interrupt gate - dpl=0, present */
142 /* Load the Interrupt descriptor table */
151 pushl $0 /* error code */
152 pushl $0 /* vector */
155 pushl $0 /* error code */
156 pushl $1 /* vector */
160 pushl $0 /* error code */
161 pushl $2 /* vector */
165 pushl $0 /* error code */
166 pushl $3 /* vector */
170 pushl $0 /* error code */
171 pushl $4 /* vector */
175 pushl $0 /* error code */
176 pushl $5 /* vector */
180 pushl $0 /* error code */
181 pushl $6 /* vector */
184 pushl $0 /* error code */
185 pushl $7 /* vector */
190 pushl $8 /* vector */
195 pushl $0 /* error code */
196 pushl $9 /* vector */
201 pushl $10 /* vector */
207 pushl $11 /* vector */
213 pushl $12 /* vector */
219 pushl $13 /* vector */
225 pushl $14 /* vector */
230 pushl $0 /* error code */
231 pushl $15 /* vector */
235 pushl $0 /* error code */
236 pushl $16 /* vector */
241 pushl $17 /* vector */
246 pushl $0 /* error code */
247 pushl $18 /* vector */
251 pushl $0 /* error code */
252 pushl $19 /* vector */
256 pushl $0 /* error code */
257 pushl $20 /* vector */
259 .global __divide_error
262 /* At this point on the stack there is:
272 /* Original stack pointer */
280 pushl %esp /* Pointer to structure on the stack */
283 pop %eax /* Drop the pointer */
289 popl %ebp /* Ignore saved %esp value */
294 addl $8, %esp /* pop of the vector and error code */
299 .word _idt_end - _idt - 1 /* limit */
303 .fill 20, 8, 0 # idt is unitiailzed
306 .globl arch_nvram_size, arch_nvram_get, arch_nvram_put