couple of bits on the x86_64 boot code
[newos.git] / boot / pc / x86_64 / int86.S
blob7b150467f5f42591978ea069285d49b40133a4f0
1 /*
2 ** Copyright 2004, Travis Geiselbrecht. All rights reserved.
3 ** Distributed under the terms of the NewOS License.
4 */
6 #define FUNCTION(x) .global x; .type x,@function; x
8 /* everything between int86_code_start and int86_code_stop gets
9  * copied to 0x7c00 before being called
10  */
11 .globl int86_code_start
12 int86_code_start:
15  * struct regs {
16  *      unsigned int eax;
17  *      unsigned int ebx;
18  *      unsigned int ecx;
19  *      unsigned int edx;
20  *      unsigned int esi;
21  *      unsigned int edi;
22  * };
23  *
24  * void int86(int interrupt, struct regs *r);
25  */
26 FUNCTION(int86):
27         pushal
28         pushfl
30         cli
32         /* copy ourselves to 0x7c00 */
33         movl    $0x7c00,%edi                            /* destination */
34         movl    $int86_code_start,%esi  /* source */
35         movl    $int86_code_stop-int86_code_start,%ecx  /* count */
36         cld
37         rep movsb
39         /* set the idt back to zero */
40         lidt    idt_descriptor
42         /* get the interrupt vector and patch the instruction at the target address */
43         movl    40(%esp),%eax
44         mov             %al,(intinstruction+1-int86_code_start+0x7c00)
46         /* load the regs from the passed-in structure */
47         movl    44(%esp),%ebp                   /* ebp will hold the structure */
48                                                                         /* dont get eax yet */
49         movl    4(%ebp),%ebx
50         movl    8(%ebp),%ecx
51         movl    12(%ebp),%edx
52         movl    16(%ebp),%esi
53         movl    20(%ebp),%edi
54         mov             24(%ebp),%es
55         movl    (%ebp),%ebp                             /* this value will go to %eax before the int call */
57         /* save esp */
58         movl    %esp,saved_esp
60         /* get a new stack */
61         movl    $0x7c00,%esp
63         /* switch down to the low-memory version of this code */
64         jmp             .foo-int86_code_start+0x7c00
65 .foo:
67         /* unset the protected mode and paging bits */
68         movl    %cr0,%eax
69         andl    $0x7ffffffe,%eax
70         movl    %eax,%cr0
72         /* switch into 16-bit code */
73         ljmp    $0x7c0,$real-int86_code_start
74 real:
75 .code16
76         xor             %eax,%eax
77         mov             %ax,%ds
78         mov             %ax,%fs
79         movw    $0xb800,%ax
80         mov             %ax,%gs
82         /* load %eax */
83         movl    %ebp,%eax
85         /* the int call */
86 intinstruction:
87         .byte   0xcd
88         .byte   0
90         /* save the flags (we care about the carry bit) */
91         pushf
93         /* save %eax from the call */
94         mov             %eax,%ebp       
96         /* set the protected mode and paging bit */
97         movl    %cr0,%eax
98         orl             $0x80000001,%eax
99         movl    %eax,%cr0
101 .code32
102         .byte   0x66
103         ljmp    $0x8,$protected
105 protected:
106         mov             $0x10,%ax
107         mov             %ax,%ds
108         mov             %ax,%es
109         mov             %ax,%fs
110         mov             %ax,%gs
112         /* restore the stack */
113         movl    saved_esp,%esp
115         /* save the registers from the call */
116         movl    44(%esp),%eax
117         movl    %ebp,(%eax)
118         movl    %ebx,4(%eax)
119         movl    %ecx,8(%eax)
120         movl    %edx,12(%eax)
121         movl    %esi,16(%eax)
122         movl    %edi,20(%eax)
123         movw    0x7bfe,%cx
124         movw    %cx,24(%eax)
126         popfl
127         popal
129         ret
131 idt_descriptor:
132         .short  0x7ff
133         .long   0x0
135 saved_esp:
136         .long   0
138 .globl int86_code_stop
139 int86_code_stop:
140         .long   0