diff options
Diffstat (limited to 'arch/i386/boot/edd.S')
-rw-r--r-- | arch/i386/boot/edd.S | 231 |
1 files changed, 0 insertions, 231 deletions
diff --git a/arch/i386/boot/edd.S b/arch/i386/boot/edd.S deleted file mode 100644 index 34321368011a..000000000000 --- a/arch/i386/boot/edd.S +++ /dev/null | |||
@@ -1,231 +0,0 @@ | |||
1 | /* | ||
2 | * BIOS Enhanced Disk Drive support | ||
3 | * Copyright (C) 2002, 2003, 2004 Dell, Inc. | ||
4 | * by Matt Domsch <Matt_Domsch@dell.com> October 2002 | ||
5 | * conformant to T13 Committee www.t13.org | ||
6 | * projects 1572D, 1484D, 1386D, 1226DT | ||
7 | * disk signature read by Matt Domsch <Matt_Domsch@dell.com> | ||
8 | * and Andrew Wilks <Andrew_Wilks@dell.com> September 2003, June 2004 | ||
9 | * legacy CHS retrieval by Patrick J. LoPresti <patl@users.sourceforge.net> | ||
10 | * March 2004 | ||
11 | * Command line option parsing, Matt Domsch, November 2004 | ||
12 | */ | ||
13 | |||
14 | #include <linux/edd.h> | ||
15 | #include <asm/setup.h> | ||
16 | |||
17 | #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) | ||
18 | |||
19 | # It is assumed that %ds == INITSEG here | ||
20 | |||
21 | movb $0, (EDD_MBR_SIG_NR_BUF) | ||
22 | movb $0, (EDDNR) | ||
23 | |||
24 | # Check the command line for options: | ||
25 | # edd=of disables EDD completely (edd=off) | ||
26 | # edd=sk skips the MBR test (edd=skipmbr) | ||
27 | # edd=on re-enables EDD (edd=on) | ||
28 | |||
29 | pushl %esi | ||
30 | movw $edd_mbr_sig_start, %di # Default to edd=on | ||
31 | |||
32 | movl %cs:(cmd_line_ptr), %esi | ||
33 | andl %esi, %esi | ||
34 | jz old_cl # Old boot protocol? | ||
35 | |||
36 | # Convert to a real-mode pointer in fs:si | ||
37 | movl %esi, %eax | ||
38 | shrl $4, %eax | ||
39 | movw %ax, %fs | ||
40 | andw $0xf, %si | ||
41 | jmp have_cl_pointer | ||
42 | |||
43 | # Old-style boot protocol? | ||
44 | old_cl: | ||
45 | push %ds # aka INITSEG | ||
46 | pop %fs | ||
47 | |||
48 | cmpw $0xa33f, (0x20) | ||
49 | jne done_cl # No command line at all? | ||
50 | movw (0x22), %si # Pointer relative to INITSEG | ||
51 | |||
52 | # fs:si has the pointer to the command line now | ||
53 | have_cl_pointer: | ||
54 | |||
55 | # Loop through kernel command line one byte at a time. Just in | ||
56 | # case the loader is buggy and failed to null-terminate the command line | ||
57 | # terminate if we get close enough to the end of the segment that we | ||
58 | # cannot fit "edd=XX"... | ||
59 | cl_atspace: | ||
60 | cmpw $-5, %si # Watch for segment wraparound | ||
61 | jae done_cl | ||
62 | movl %fs:(%si), %eax | ||
63 | andb %al, %al # End of line? | ||
64 | jz done_cl | ||
65 | cmpl $EDD_CL_EQUALS, %eax | ||
66 | jz found_edd_equals | ||
67 | cmpb $0x20, %al # <= space consider whitespace | ||
68 | ja cl_skipword | ||
69 | incw %si | ||
70 | jmp cl_atspace | ||
71 | |||
72 | cl_skipword: | ||
73 | cmpw $-5, %si # Watch for segment wraparound | ||
74 | jae done_cl | ||
75 | movb %fs:(%si), %al # End of string? | ||
76 | andb %al, %al | ||
77 | jz done_cl | ||
78 | cmpb $0x20, %al | ||
79 | jbe cl_atspace | ||
80 | incw %si | ||
81 | jmp cl_skipword | ||
82 | |||
83 | found_edd_equals: | ||
84 | # only looking at first two characters after equals | ||
85 | # late overrides early on the command line, so keep going after finding something | ||
86 | movw %fs:4(%si), %ax | ||
87 | cmpw $EDD_CL_OFF, %ax # edd=of | ||
88 | je do_edd_off | ||
89 | cmpw $EDD_CL_SKIP, %ax # edd=sk | ||
90 | je do_edd_skipmbr | ||
91 | cmpw $EDD_CL_ON, %ax # edd=on | ||
92 | je do_edd_on | ||
93 | jmp cl_skipword | ||
94 | do_edd_skipmbr: | ||
95 | movw $edd_start, %di | ||
96 | jmp cl_skipword | ||
97 | do_edd_off: | ||
98 | movw $edd_done, %di | ||
99 | jmp cl_skipword | ||
100 | do_edd_on: | ||
101 | movw $edd_mbr_sig_start, %di | ||
102 | jmp cl_skipword | ||
103 | |||
104 | done_cl: | ||
105 | popl %esi | ||
106 | jmpw *%di | ||
107 | |||
108 | # Read the first sector of each BIOS disk device and store the 4-byte signature | ||
109 | edd_mbr_sig_start: | ||
110 | movb $0x80, %dl # from device 80 | ||
111 | movw $EDD_MBR_SIG_BUF, %bx # store buffer ptr in bx | ||
112 | edd_mbr_sig_read: | ||
113 | movl $0xFFFFFFFF, %eax | ||
114 | movl %eax, (%bx) # assume failure | ||
115 | pushw %bx | ||
116 | movb $READ_SECTORS, %ah | ||
117 | movb $1, %al # read 1 sector | ||
118 | movb $0, %dh # at head 0 | ||
119 | movw $1, %cx # cylinder 0, sector 0 | ||
120 | pushw %es | ||
121 | pushw %ds | ||
122 | popw %es | ||
123 | movw $EDDBUF, %bx # disk's data goes into EDDBUF | ||
124 | pushw %dx # work around buggy BIOSes | ||
125 | stc # work around buggy BIOSes | ||
126 | int $0x13 | ||
127 | sti # work around buggy BIOSes | ||
128 | popw %dx | ||
129 | popw %es | ||
130 | popw %bx | ||
131 | jc edd_mbr_sig_done # on failure, we're done. | ||
132 | cmpb $0, %ah # some BIOSes do not set CF | ||
133 | jne edd_mbr_sig_done # on failure, we're done. | ||
134 | movl (EDDBUF+EDD_MBR_SIG_OFFSET), %eax # read sig out of the MBR | ||
135 | movl %eax, (%bx) # store success | ||
136 | incb (EDD_MBR_SIG_NR_BUF) # note that we stored something | ||
137 | incb %dl # increment to next device | ||
138 | addw $4, %bx # increment sig buffer ptr | ||
139 | cmpb $EDD_MBR_SIG_MAX, (EDD_MBR_SIG_NR_BUF) # Out of space? | ||
140 | jb edd_mbr_sig_read # keep looping | ||
141 | edd_mbr_sig_done: | ||
142 | |||
143 | # Do the BIOS Enhanced Disk Drive calls | ||
144 | # This consists of two calls: | ||
145 | # int 13h ah=41h "Check Extensions Present" | ||
146 | # int 13h ah=48h "Get Device Parameters" | ||
147 | # int 13h ah=08h "Legacy Get Device Parameters" | ||
148 | # | ||
149 | # A buffer of size EDDMAXNR*(EDDEXTSIZE+EDDPARMSIZE) is reserved for our use | ||
150 | # in the boot_params at EDDBUF. The first four bytes of which are | ||
151 | # used to store the device number, interface support map and version | ||
152 | # results from fn41. The next four bytes are used to store the legacy | ||
153 | # cylinders, heads, and sectors from fn08. The following 74 bytes are used to | ||
154 | # store the results from fn48. Starting from device 80h, fn41, then fn48 | ||
155 | # are called and their results stored in EDDBUF+n*(EDDEXTSIZE+EDDPARMIZE). | ||
156 | # Then the pointer is incremented to store the data for the next call. | ||
157 | # This repeats until either a device doesn't exist, or until EDDMAXNR | ||
158 | # devices have been stored. | ||
159 | # The one tricky part is that ds:si always points EDDEXTSIZE bytes into | ||
160 | # the structure, and the fn41 and fn08 results are stored at offsets | ||
161 | # from there. This removes the need to increment the pointer for | ||
162 | # every store, and leaves it ready for the fn48 call. | ||
163 | # A second one-byte buffer, EDDNR, in the boot_params stores | ||
164 | # the number of BIOS devices which exist, up to EDDMAXNR. | ||
165 | # In setup.c, copy_edd() stores both boot_params buffers away | ||
166 | # for later use, as they would get overwritten otherwise. | ||
167 | # This code is sensitive to the size of the structs in edd.h | ||
168 | edd_start: | ||
169 | # %ds points to the bootsector | ||
170 | # result buffer for fn48 | ||
171 | movw $EDDBUF+EDDEXTSIZE, %si # in ds:si, fn41 results | ||
172 | # kept just before that | ||
173 | movb $0x80, %dl # BIOS device 0x80 | ||
174 | |||
175 | edd_check_ext: | ||
176 | movb $CHECKEXTENSIONSPRESENT, %ah # Function 41 | ||
177 | movw $EDDMAGIC1, %bx # magic | ||
178 | int $0x13 # make the call | ||
179 | jc edd_done # no more BIOS devices | ||
180 | |||
181 | cmpw $EDDMAGIC2, %bx # is magic right? | ||
182 | jne edd_next # nope, next... | ||
183 | |||
184 | movb %dl, %ds:-8(%si) # store device number | ||
185 | movb %ah, %ds:-7(%si) # store version | ||
186 | movw %cx, %ds:-6(%si) # store extensions | ||
187 | incb (EDDNR) # note that we stored something | ||
188 | |||
189 | edd_get_device_params: | ||
190 | movw $EDDPARMSIZE, %ds:(%si) # put size | ||
191 | movw $0x0, %ds:2(%si) # work around buggy BIOSes | ||
192 | movb $GETDEVICEPARAMETERS, %ah # Function 48 | ||
193 | int $0x13 # make the call | ||
194 | # Don't check for fail return | ||
195 | # it doesn't matter. | ||
196 | edd_get_legacy_chs: | ||
197 | xorw %ax, %ax | ||
198 | movw %ax, %ds:-4(%si) | ||
199 | movw %ax, %ds:-2(%si) | ||
200 | # Ralf Brown's Interrupt List says to set ES:DI to | ||
201 | # 0000h:0000h "to guard against BIOS bugs" | ||
202 | pushw %es | ||
203 | movw %ax, %es | ||
204 | movw %ax, %di | ||
205 | pushw %dx # legacy call clobbers %dl | ||
206 | movb $LEGACYGETDEVICEPARAMETERS, %ah # Function 08 | ||
207 | int $0x13 # make the call | ||
208 | jc edd_legacy_done # failed | ||
209 | movb %cl, %al # Low 6 bits are max | ||
210 | andb $0x3F, %al # sector number | ||
211 | movb %al, %ds:-1(%si) # Record max sect | ||
212 | movb %dh, %ds:-2(%si) # Record max head number | ||
213 | movb %ch, %al # Low 8 bits of max cyl | ||
214 | shr $6, %cl | ||
215 | movb %cl, %ah # High 2 bits of max cyl | ||
216 | movw %ax, %ds:-4(%si) | ||
217 | |||
218 | edd_legacy_done: | ||
219 | popw %dx | ||
220 | popw %es | ||
221 | movw %si, %ax # increment si | ||
222 | addw $EDDPARMSIZE+EDDEXTSIZE, %ax | ||
223 | movw %ax, %si | ||
224 | |||
225 | edd_next: | ||
226 | incb %dl # increment to next device | ||
227 | cmpb $EDDMAXNR, (EDDNR) # Out of space? | ||
228 | jb edd_check_ext # keep looping | ||
229 | |||
230 | edd_done: | ||
231 | #endif | ||