Magellan Linux

Annotation of /trunk/mkinitrd-magellan/isolinux/bcopyxx.inc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1133 - (hide annotations) (download)
Thu Aug 19 09:50:43 2010 UTC (13 years, 8 months ago) by niro
File size: 6584 byte(s)
-updated to isolinux-3.86
1 niro 1133 ;; -----------------------------------------------------------------------
2     ;;
3     ;; Copyright 1994-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., 53 Temple Place Ste 330,
9     ;; Boston MA 02111-1307, USA; either version 2 of the License, or
10     ;; (at your option) any later version; incorporated herein by reference.
11     ;;
12     ;; -----------------------------------------------------------------------
13    
14     ;;
15     ;; bcopy32xx.inc
16     ;;
17    
18    
19     ;
20     ; 32-bit bcopy routine
21     ;
22     ; This is the actual 32-bit portion of the bcopy and shuffle and boot
23     ; routines. ALL THIS CODE NEEDS TO BE POSITION-INDEPENDENT, with the
24     ; sole exception being the actual relocation code at the beginning of
25     ; pm_shuffle_boot.
26     ;
27     ; It also really needs to live all in a single segment, for the
28     ; address calculcations to actually work.
29     ;
30    
31     bits 32
32     section .bcopyxx
33     align 16
34     bcopyxx_start equ $
35     ;
36     ; pm_bcopy:
37     ;
38     ; This is the protected-mode core of the "bcopy" routine.
39     ; Try to do aligned transfers; if the src and dst are relatively
40     ; misaligned, align the dst.
41     ;
42     ; ECX is guaranteed to not be zero on entry.
43     ;
44     ; Clobbers ESI, EDI, ECX.
45     ;
46    
47     pm_bcopy:
48     push ebx
49     push edx
50     push eax
51    
52     cmp esi,-1
53     je .bzero
54    
55     cmp esi,edi ; If source < destination, we might
56     jb .reverse ; have to copy backwards
57    
58     .forward:
59     ; Initial alignment
60     mov edx,edi
61     shr edx,1
62     jnc .faa1
63     movsb
64     dec ecx
65     .faa1:
66     mov al,cl
67     cmp ecx,2
68     jb .f_tiny
69    
70     shr edx,1
71     jnc .faa2
72     movsw
73     sub ecx,2
74     .faa2:
75    
76     ; Bulk transfer
77     mov al,cl ; Save low bits
78     shr ecx,2 ; Convert to dwords
79     rep movsd ; Do our business
80     ; At this point ecx == 0
81    
82     test al,2
83     jz .fab2
84     movsw
85     .fab2:
86     .f_tiny:
87     test al,1
88     jz .fab1
89     movsb
90     .fab1:
91     .done:
92     pop eax
93     pop edx
94     pop ebx
95     ret
96    
97     .reverse:
98     std ; Reverse copy
99    
100     lea esi,[esi+ecx-1] ; Point to final byte
101     lea edi,[edi+ecx-1]
102    
103     ; Initial alignment
104     mov edx,edi
105     shr edx,1
106     jc .raa1
107     movsb
108     dec ecx
109     .raa1:
110    
111     dec esi
112     dec edi
113     mov al,cl
114     cmp ecx,2
115     jb .r_tiny
116     shr edx,1
117     jc .raa2
118     movsw
119     sub ecx,2
120     .raa2:
121    
122     ; Bulk copy
123     sub esi,2
124     sub edi,2
125     mov al,cl ; Save low bits
126     shr ecx,2
127     rep movsd
128    
129     ; Final alignment
130     .r_final:
131     add esi,2
132     add edi,2
133     test al,2
134     jz .rab2
135     movsw
136     .rab2:
137     .r_tiny:
138     inc esi
139     inc edi
140     test al,1
141     jz .rab1
142     movsb
143     .rab1:
144     cld
145     jmp short .done
146    
147     .bzero:
148     xor eax,eax
149    
150     ; Initial alignment
151     mov edx,edi
152     shr edx,1
153     jnc .zaa1
154     stosb
155     dec ecx
156     .zaa1:
157    
158     mov bl,cl
159     cmp ecx,2
160     jb .z_tiny
161     shr edx,1
162     jnc .zaa2
163     stosw
164     sub ecx,2
165     .zaa2:
166    
167     ; Bulk
168     mov bl,cl ; Save low bits
169     shr ecx,2
170     rep stosd
171    
172     test bl,2
173     jz .zab2
174     stosw
175     .zab2:
176     .z_tiny:
177     test bl,1
178     jz .zab1
179     stosb
180     .zab1:
181     jmp short .done
182    
183     ;
184     ; shuffle_and_boot:
185     ;
186     ; This routine is used to shuffle memory around, followed by
187     ; invoking an entry point somewhere in low memory. This routine
188     ; can clobber any memory outside the bcopy special area.
189     ;
190     ; IMPORTANT: This routine does not set up any registers.
191     ; It is the responsibility of the caller to generate an appropriate entry
192     ; stub; *especially* when going to real mode.
193     ;
194     ; Inputs:
195     ; ESI -> Pointer to list of (dst, src, len) pairs(*)
196     ; EDI -> Pointer to safe area for list + shuffler
197     ; (must not overlap this code nor the RM stack)
198     ; ECX -> Byte count of list area (for initial copy)
199     ;
200     ; If src == -1: then the memory pointed to by (dst, len) is bzeroed;
201     ; this is handled inside the bcopy routine.
202     ;
203     ; If len == 0: this marks the end of the list; dst indicates
204     ; the entry point and src the mode (0 = pm, 1 = rm)
205     ;
206     pm_shuffle:
207     mov ebx,edi ; EBX <- descriptor list
208     lea edx,[edi+ecx+15] ; EDX <- where to relocate our code to
209     and edx,~15 ; Align 16 to benefit the GDT
210     call pm_bcopy
211     mov edi,edx
212     mov esi,bcopyxx_start
213     mov ecx,bcopyxx_dwords
214     lea eax,[edx+.safe-bcopyxx_start] ; Resume point
215     ; Relocate this code
216     rep movsd
217     jmp eax ; Jump to safe location
218     .safe:
219     ; Give ourselves a safe stack
220     lea esp,[edx+bcopyxx_stack+bcopyxx_end-bcopyxx_start]
221     add edx,bcopy_gdt-bcopyxx_start
222     mov [edx+2],edx ; GDT self-pointer
223     lgdt [edx] ; Switch to local GDT
224    
225     ; Now for the actual shuffling...
226     .loop:
227     mov edi,[ebx]
228     mov esi,[ebx+4]
229     mov ecx,[ebx+8]
230     add ebx,12
231     jecxz .done
232     call pm_bcopy
233     jmp .loop
234     .done:
235     push ecx ; == 0, for cleaning the flags register
236     and esi,esi
237     jz pm_shuffle_real_mode
238     popfd ; Clean the flags
239     jmp edi ; Protected mode entry
240    
241     ; We have a real-mode entry point, so we need to return
242     ; to real mode. Note: EDX already points to the GDT.
243     pm_shuffle_real_mode:
244     mov eax,edi
245     mov [edx+PM_CS16+2],ax
246     mov [edx+PM_DS16+2],ax
247     shr eax,16
248     mov [edx+PM_CS16+4],al
249     mov [edx+PM_CS16+7],ah
250     mov [edx+PM_DS16+4],al
251     mov [edx+PM_DS16+7],ah
252     mov eax,cr0
253     and al,~1
254     popfd ; Clean the flags
255     ; No flag-changing instructions below...
256     mov dx,PM_DS16
257     mov ds,edx
258     mov es,edx
259     mov fs,edx
260     mov gs,edx
261     mov ss,edx
262     jmp PM_CS16:0
263    
264     align 16
265     ; GDT descriptor entry
266     %macro desc 1
267     bcopy_gdt.%1:
268     PM_%1 equ bcopy_gdt.%1-bcopy_gdt
269     %endmacro
270    
271     bcopy_gdt:
272     dw bcopy_gdt_size-1 ; Null descriptor - contains GDT
273     dd bcopy_gdt ; pointer for LGDT instruction
274     dw 0
275    
276     ; TSS segment to keep Intel VT happy. Intel VT is
277     ; unhappy about anything that doesn't smell like a
278     ; full-blown 32-bit OS.
279     desc TSS
280     dw 104-1, DummyTSS ; 08h 32-bit task state segment
281     dd 00008900h ; present, dpl 0, 104 bytes @DummyTSS
282    
283     desc CS16
284     dd 0000ffffh ; 10h Code segment, use16, readable,
285     dd 00009b00h ; present, dpl 0, cover 64K
286     desc DS16
287     dd 0000ffffh ; 18h Data segment, use16, read/write,
288     dd 00009300h ; present, dpl 0, cover 64K
289     desc CS32
290     dd 0000ffffh ; 20h Code segment, use32, readable,
291     dd 00cf9b00h ; present, dpl 0, cover all 4G
292     desc DS32
293     dd 0000ffffh ; 28h Data segment, use32, read/write,
294     dd 00cf9300h ; present, dpl 0, cover all 4G
295    
296     bcopy_gdt_size: equ $-bcopy_gdt
297    
298     alignz 4
299     bcopyxx_end equ $ ; *Must* be dword-aligned!
300     bcopyxx_len equ $-bcopyxx_start
301     bcopyxx_dwords equ bcopyxx_len >> 2
302    
303     bcopyxx_stack equ 128 ; We want this much stack
304     ; The +15 is for alignment
305     bcopyxx_safe equ bcopyxx_len + bcopyxx_stack + 15
306    
307     ;
308     ; Space for a dummy task state segment. It should never be actually
309     ; accessed, but just in case it is, point to a chunk of memory that
310     ; has a chance to not be used for anything real...
311     ;
312     DummyTSS equ 0x580
313    
314     bits 16
315     section .text