Initial import of kqemu-1.4.0pre1
[kqemu.git] / common / i386 / nexus_asm.S
blob0d79f4682aeab1493c1d2c3c2c635a8ef4eb849b
1 /*
2  * KQEMU
3  *
4  * Copyright (C) 2004-2008 Fabrice Bellard
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * version 2 as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /* entry / exit from monitor code */
20 #include "monitor_def.h"
21 #include "kqemu_int.h"
22         
23 .globl ASM_NAME(kernel2monitor)
24 .globl ASM_NAME(monitor2kernel)
25 .globl ASM_NAME(kernel2monitor_jmp_offset)
26 .globl ASM_NAME(monitor2kernel_jmp_offset)
27 .global _start
28         
29 _start:
30         .long ASM_NAME(kernel2monitor) - _start
31         .long ASM_NAME(interrupt_table) - _start
32         .long ASM_NAME(kernel2monitor_jmp_offset) - _start
33         .long ASM_NAME(monitor2kernel_jmp_offset) - _start
34         .long ASM_NAME(monitor_exec) - _start
36  * Assumptions when entering kernel2monitor:      
37  * %ss, %ds, %es, %cs are 4G flat 32 bit segments
38  * IRQ disabled        
39  */
40 ASM_NAME(kernel2monitor):
41         pushl %ebp
42         movl %esp, %ebp
43         pushl %ebx
44         pushl %esi
45         pushl %edi
46                                         
47         pushl %ds
48         pushl %es
50         movl 8(%ebp), %ebx
51         
52         str  KQEMU_STATE_kernel_tr_sel(%ebx)
53         sidt KQEMU_STATE_kernel_idt(%ebx)
54         sgdt KQEMU_STATE_kernel_gdt(%ebx)
55         sldt KQEMU_STATE_kernel_ldt_sel(%ebx)
56         movw %cs, KQEMU_STATE_kernel_cs_sel(%ebx)
57         
58         movw %ss, KQEMU_STATE_kernel_ss_sel(%ebx)
59         movl %esp, KQEMU_STATE_kernel_esp(%ebx)
61         movl %cr0, %eax
62         movl %eax, KQEMU_STATE_kernel_cr0(%ebx)
63         movl %cr3, %eax
64         movl %eax, KQEMU_STATE_kernel_cr3(%ebx)
65         movl %cr4, %eax
66         movl %eax, KQEMU_STATE_kernel_cr4(%ebx)
68         /* switch to the monitor address space (we switch %cr4 first
69            to disable global pages) */
70         movl %eax, %ecx
71         testl $CPUID_PGE, KQEMU_STATE_cpuid_features(%ebx)
72         je 1f
73         orl $CR4_PGE_MASK, %ecx
75         andl $~(CR4_PGE_MASK), %eax
76         movl %eax, %cr4
77         
78         movl KQEMU_STATE_monitor_cr3(%ebx), %eax
79         movl KQEMU_STATE_monitor_data_vaddr(%ebx), %ebx
80         movl %eax, %cr3
81         movl %ecx, %cr4
82                  
83         lidt KQEMU_STATE_monitor_idt(%ebx)
84         lgdt KQEMU_STATE_monitor_gdt(%ebx)
86         ljmp *KQEMU_STATE_monitor_jmp(%ebx)
87 ASM_NAME(kernel2monitor_jmp_offset):
89         lldt KQEMU_STATE_monitor_ldt_sel(%ebx)
91         /* load the TR desc cache without modifying the GDT */
92         movw KQEMU_STATE_monitor_tr_sel(%ebx), %ax
93         movl %eax, %ecx
94         andl $0xfff8, %ecx
95         addl (KQEMU_STATE_monitor_gdt + 2)(%ebx), %ecx
96         movl (%ecx), %esi
97         movl 4(%ecx), %edi
98         movl KQEMU_STATE_tr_desc_cache(%ebx), %edx
99         movl %edx, (%ecx)
100         movl KQEMU_STATE_tr_desc_cache + 4(%ebx), %edx
101         movl %edx, 4(%ecx)
102         ltr %ax
103         movl %esi, (%ecx)
104         movl %edi, 4(%ecx)
105                                         
106         movw KQEMU_STATE_monitor_ds_sel(%ebx), %ax
107         movw %ax, %ss
108         movw %ax, %es
109         movw %ax, %ds
111         movl KQEMU_STATE_monitor_esp(%ebx), %esp
113         /* load debug register if needed */
114         movl KQEMU_STATE_monitor_dr7(%ebx), %eax
115         testl %eax, %eax
116         je 2f
117         movl %eax, %dr7
119         
120         popl %edi
121         popl %esi
122         popl %ebx
123         popl %ebp
124         ret
127  * Assumptions when entering monitor2kernel:
128  * IRQ disabled
129  */
130 ASM_NAME(monitor2kernel):
131         pushl %ebp
132         movl %esp, %ebp
133         pushl %ebx
134         pushl %esi
135         pushl %edi
137         movl 8(%ebp), %ebx
138         
139         movl %esp, KQEMU_STATE_monitor_esp(%ebx)
141         /* clear the debug register if needed */
142         movl KQEMU_STATE_monitor_dr7(%ebx), %eax
143         testl %eax, %eax
144         je 2f
145         xor %eax, %eax
146         movl %eax, %dr7
149         movl KQEMU_STATE_nexus_kaddr(%ebx), %eax
150         addl $monitor2kernel_jmp_offset1 - _start, %eax
151         jmp *%eax
152 monitor2kernel_jmp_offset1:     
153         
154         /* restore %cr4 */
155         movl KQEMU_STATE_kernel_cr4(%ebx), %ecx
156         movl %ecx, %eax
157         andl $~CR4_PGE_MASK, %eax
158         movl %eax, %cr4
159         
160         /* switch address space */
161         movl KQEMU_STATE_kernel_cr3(%ebx), %eax
162         movl KQEMU_STATE_monitor_data_kaddr(%ebx), %ebx
163         movl %eax, %cr3
164         movl %ecx, %cr4
166         lidt KQEMU_STATE_kernel_idt(%ebx)
167         lgdt KQEMU_STATE_kernel_gdt(%ebx)
168         lldt KQEMU_STATE_kernel_ldt_sel(%ebx)
170         ljmp *KQEMU_STATE_kernel_jmp(%ebx)
171 ASM_NAME(monitor2kernel_jmp_offset):
173         /* restore TR and clear BUSY bit */
174         movw KQEMU_STATE_kernel_tr_sel(%ebx), %ax
175         movl %eax, %ecx
176         andl $0xfff8, %ecx
177         addl (KQEMU_STATE_kernel_gdt + 2)(%ebx), %ecx
178         andl $0xfffffdff, 4(%ecx)
179         ltr %ax
181         /* cr0 needs to be restored because of the TS and AM bits */
182         movl KQEMU_STATE_kernel_cr0(%ebx), %eax
183         movl %eax, %cr0
185         lss KQEMU_STATE_kernel_esp(%ebx), %esp
187         popl %es
188         popl %ds
189         
190         popl %edi
191         popl %esi
192         popl %ebx
193         popl %ebp
194         ret