Merge from vendor branch TCPDUMP:
[dragonfly.git] / sys / i386 / boot / biosboot / asm.S
1 /*
2  * Mach Operating System
3  * Copyright (c) 1992, 1991 Carnegie Mellon University
4  * All Rights Reserved.
5  * 
6  * Permission to use, copy, modify and distribute this software and its
7  * documentation is hereby granted, provided that both the copyright
8  * notice and this permission notice appear in all copies of the
9  * software, derivative works or modified versions, and any portions
10  * thereof, and that both notices appear in supporting documentation.
11  * 
12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15  * 
16  * Carnegie Mellon requests users of this software to return to
17  * 
18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
19  *  School of Computer Science
20  *  Carnegie Mellon University
21  *  Pittsburgh PA 15213-3890
22  * 
23  * any improvements or extensions that they make and grant Carnegie Mellon
24  * the rights to redistribute these changes.
25  *
26  *      from: Mach, Revision 2.2  92/04/04  11:34:13  rpd
27  * $FreeBSD: src/sys/i386/boot/biosboot/asm.S,v 1.13 1999/08/28 00:43:11 peter Exp $
28  * $DragonFly: src/sys/i386/boot/biosboot/Attic/asm.S,v 1.2 2003/06/17 04:28:34 dillon Exp $
29  */
30
31
32 /*
33   Copyright 1988, 1989, 1990, 1991, 1992 
34    by Intel Corporation, Santa Clara, California.
35
36                 All Rights Reserved
37
38 Permission to use, copy, modify, and distribute this software and
39 its documentation for any purpose and without fee is hereby
40 granted, provided that the above copyright notice appears in all
41 copies and that both the copyright notice and this permission notice
42 appear in supporting documentation, and that the name of Intel
43 not be used in advertising or publicity pertaining to distribution
44 of the software without specific, written prior permission.
45
46 INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
47 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
48 IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
49 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
50 LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
51 NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
52 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
53 */
54
55         .file "asm.s"
56
57 #include "asm.h"
58
59
60 CR0_PE_ON       =       0x1
61 CR0_PE_OFF      =       0xfffffffe
62
63         .text
64
65 /*
66  *
67  * real_to_prot()
68  *      transfer from real mode to protected mode.
69  */
70
71 ENTRY(real_to_prot)
72         /* guarantee that interrupt is disabled when in prot mode */
73         cli
74
75         /* load the gdtr */
76         addr32
77         data32
78         lgdt    EXT(Gdtr)
79
80         /* set the PE bit of CR0 */
81         mov     %cr0, %eax
82
83         data32
84         or      $CR0_PE_ON, %eax
85         mov     %eax, %cr0 
86
87         /*
88          * make intrasegment jump to flush the processor pipeline and
89          * reload CS register
90          */
91         data32
92         ljmp    $0x18, $xprot
93 xprot:
94
95         /*
96          * we are in USE32 mode now
97          * set up the protected mode segment registers : DS, SS, ES, FS
98          */
99         movw    $0x20, %ax      /* data segment */
100         mov     %ax, %ds        /* gas would waste a prefix byte for movw */
101         mov     %ax, %ss
102         mov     %ax, %es
103         movw    $0x10, %ax      /* flat segment */
104         mov     %ax, %fs
105
106 #ifdef BDE_DEBUGGER
107         /* load idtr so we can debug */
108         lidt    EXT(Idtr_prot)
109 #endif
110
111         ret
112
113 /*
114  *
115  * prot_to_real()
116  *      transfer from protected mode to real mode
117  * 
118  */
119
120 ENTRY(prot_to_real)
121
122         /* Prepare %ax while we're still in a mode that gas understands. */
123         movw    $0x30, %ax
124
125         /* Change to use16 mode. */
126         ljmp    $0x28, $x16
127 x16:
128
129         mov     %ax, %ds
130         mov     %ax, %ss
131         mov     %ax, %es
132         mov     %ax, %fs
133
134         /* clear the PE bit of CR0 */
135         mov     %cr0, %eax
136         data32
137         and     $CR0_PE_OFF, %eax
138         mov     %eax, %cr0
139
140         /*
141          * make intersegment jmp to flush the processor pipeline
142          * and reload CS register
143          */
144         data32
145         ljmp    $BOOTSEG, $xreal
146 xreal:
147
148         /*
149          * we are in real mode now
150          * set up the real mode segment registers : DS, SS, ES, FS
151          */
152         mov     %cs, %ax
153         mov     %ax, %ds
154         mov     %ax, %ss
155         mov     %ax, %es
156         mov     %ax, %fs
157
158 #ifdef BDE_DEBUGGER
159         /* load idtr so we can debug */
160         addr32
161         data32
162         lidt    EXT(Idtr_real)
163 #endif
164
165         data32
166         ret
167
168 /*
169  * startprog(phyaddr)
170  *      start the program on protected mode where phyaddr is the entry point
171  *
172  * XXX This whole mess should go away and we should run the boot code in
173  * flat 32 bit mode with it linked -T BOOTSEG.  See the netboot code for
174  * how this is done.
175  */
176
177 ENTRY(startprog)
178         push    %ebp
179         mov     %esp, %ebp
180         movl    %esp, %eax              /* Use eax as the old stack pointer */
181
182         /* convert the current stack to a 32 bit flat model */
183         movw    $0x10, %bx
184         mov     %bx, %ss
185         addl    $(BOOTSEG<<4),%esp
186         
187         /* copy the arguments from the old stack to the new stack */
188         pushl   0x14(%eax)              /* &bootinfo */
189         pushl   $0                      /* was &nfsdiskless */
190         pushl   $0                      /* was esym */
191         pushl   $0                      /* was cyloffset */
192         pushl   0x10(%eax)              /* bootdev */
193         pushl   0x0C(%eax)              /* howto */
194         movl    $(ourreturn),%ebx
195         addl    $(BOOTSEG<<4),%ebx      /* Fix it up for flat segments */
196         pushl   %ebx                    /* our return address */
197         
198         /* push on our entry address */
199         pushl   $0x08                   /* segment selector */
200         pushl   0x08(%eax)              /* kernel entry address */
201
202         /* convert over the other data segs */
203         movw    $0x10, %bx
204         mov     %bx, %ds
205         mov     %bx, %es
206
207         /* convert the PC (and code seg) */
208         lret
209 ourreturn:
210         /* For now there is not much we can do, just lock in a loop */
211         jmp     ourreturn
212
213 /*
214  * pcpy(src, dst, cnt)
215  *      where src is a virtual address and dst is a physical address
216  */
217
218 ENTRY(pcpy)
219         push    %ebp
220         mov     %esp, %ebp
221         push    %es
222         push    %esi
223         push    %edi
224         push    %ecx
225
226         cld
227
228         /* set %es to point at the flat segment */
229         movw    $0x10, %ax
230         mov     %ax, %es
231
232         mov     0x8(%ebp), %esi         /* source */
233         mov     0xc(%ebp), %edi         /* destination */
234         mov     0x10(%ebp), %ecx        /* count */
235
236         rep
237         movsb
238
239         pop     %ecx
240         pop     %edi
241         pop     %esi
242         pop     %es
243         pop     %ebp
244
245         ret