1 | /* ----------------------------------------------------------------------- |
---|
2 | * |
---|
3 | * Copyright 2003-2009 H. Peter Anvin - All Rights Reserved |
---|
4 | * Copyright 2009 Intel Corporation; author: H. Peter Anvin |
---|
5 | * |
---|
6 | * This program is free software; you can redistribute it and/or modify |
---|
7 | * it under the terms of the GNU General Public License as published by |
---|
8 | * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, |
---|
9 | * Boston MA 02110-1301, USA; either version 2 of the License, or |
---|
10 | * (at your option) any later version; incorporated herein by reference. |
---|
11 | * |
---|
12 | * ----------------------------------------------------------------------- */ |
---|
13 | |
---|
14 | /* |
---|
15 | * Simple stub to get us to the right point in the 32-bit code; |
---|
16 | * this module must be linked first |
---|
17 | */ |
---|
18 | |
---|
19 | .section ".init", "ax" |
---|
20 | .globl _start |
---|
21 | _start: |
---|
22 | /* Zero the bss */ |
---|
23 | cld |
---|
24 | movl $__bss_start, %edi |
---|
25 | movl $__bss_end, %ecx |
---|
26 | subl %edi, %ecx |
---|
27 | xorl %eax, %eax |
---|
28 | shrl $2, %ecx |
---|
29 | rep ; stosl |
---|
30 | |
---|
31 | /* Set up the protected-mode IDT and the interrupt jump buffers */ |
---|
32 | movl $idt, %edi |
---|
33 | movl $ijb, %eax |
---|
34 | movl $0xee000000, %ebx /* Interrupt gate */ |
---|
35 | movw %cs, %bx /* Target segment */ |
---|
36 | |
---|
37 | /* Make the IDT */ |
---|
38 | movl $256, %ecx |
---|
39 | 1: |
---|
40 | stosl |
---|
41 | stosl |
---|
42 | movl %ebx, -6(%edi) |
---|
43 | addl $8, %eax |
---|
44 | loop 1b |
---|
45 | |
---|
46 | /* |
---|
47 | * Each entry in the interrupt jump buffer contains the following |
---|
48 | * instructions: |
---|
49 | * |
---|
50 | * 60 pushal |
---|
51 | * b0xx movb $xx, %al # interrupt number |
---|
52 | * e9xxxxxxxx jmp handle_interrupt |
---|
53 | */ |
---|
54 | movl $0xe900b060, %eax |
---|
55 | movl $256, %ecx |
---|
56 | 1: |
---|
57 | movl %eax, (%edi) |
---|
58 | addl $(1 << 16), %eax |
---|
59 | movl $handle_interrupt-8, %edx |
---|
60 | subl %edi, %edx |
---|
61 | movl %edx, 4(%edi) |
---|
62 | addl $8, %edi |
---|
63 | loop 1b |
---|
64 | |
---|
65 | #if __SIZEOF_POINTER__ == 4 |
---|
66 | lidtl idt_ptr |
---|
67 | #elif __SIZEOF_POINTER__ == 8 |
---|
68 | lidt idt_ptr |
---|
69 | #else |
---|
70 | #error "unsupported architecture" |
---|
71 | #endif |
---|
72 | |
---|
73 | /* Save arguments, switch stacks */ |
---|
74 | movl %esp, %eax /* Pointer to arguments */ |
---|
75 | movl $__stack_end, %esp |
---|
76 | |
---|
77 | call setup |
---|
78 | jmp *(rm_args) /* First argument is return */ |
---|
79 | |
---|
80 | .section ".text","ax" |
---|
81 | .globl intcall |
---|
82 | .type intcall, @function |
---|
83 | intcall: |
---|
84 | jmp *(rm_args+1*4) /* Intcall is argument 1 */ |
---|
85 | .size intcall, .-intcall |
---|
86 | |
---|
87 | .type handle_interrupt, @function |
---|
88 | handle_interrupt: |
---|
89 | jmp *(rm_args+4*4) /* Interrupt pointer is argument 4 */ |
---|
90 | .size handle_interrupt, .-handle_interrupt |
---|
91 | |
---|
92 | .section ".rodata","a" |
---|
93 | idt_ptr: |
---|
94 | .word 8*256-1 |
---|
95 | .long idt |
---|
96 | .word 0 |
---|
97 | |
---|
98 | .section ".bss.large","aw" |
---|
99 | .balign 2048 |
---|
100 | idt: |
---|
101 | .space 8*256 |
---|
102 | ijb: |
---|
103 | .space 8*256 |
---|
104 | |
---|
105 | __stack: |
---|
106 | .space 65536 |
---|
107 | __stack_end: |
---|