Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / arch / i386 / prefix / bootpart.S
1 FILE_LICENCE ( GPL2_OR_LATER )
2
3 #define BOOT_SEG        0x07c0
4 #define EXEC_SEG        0x0100
5 #define STACK_SEG       0x0200
6 #define STACK_SIZE      0x2000
7         
8         .text
9         .arch i386
10         .section ".prefix", "awx", @progbits
11         .code16
12
13 /*
14  * Find active partition
15  *
16  * Parameters:
17  *   %dl        : BIOS drive number
18  *   %bp        : Active partition handler routine
19  */
20 find_active_partition:
21         /* Set up stack at STACK_SEG:STACK_SIZE */
22         movw    $STACK_SEG, %ax
23         movw    %ax, %ss
24         movw    $STACK_SIZE, %sp
25
26         /* Relocate self to EXEC_SEG */
27         pushw   $BOOT_SEG
28         popw    %ds
29         pushw   $EXEC_SEG
30         popw    %es
31         xorw    %si, %si
32         xorw    %di, %di
33         movw    $0x200, %cx
34         rep movsb
35         ljmp    $EXEC_SEG, $1f
36 1:      pushw   %ds
37         popw    %es
38         pushw   %cs
39         popw    %ds
40
41         /* Check for LBA extensions */
42         movb    $0x41, %ah
43         movw    $0x55aa, %bx
44         stc
45         int     $0x13
46         jc      1f
47         cmpw    $0xaa55, %bx
48         jne     1f
49         movw    $read_lba, read_sectors
50 1:      
51         /* Read and process root partition table */
52         xorb    %dh, %dh
53         movw    $0x0001, %cx
54         xorl    %esi, %esi
55         xorl    %edi, %edi
56         call    process_table
57
58         /* Print failure message */
59         movw    $10f, %si
60         jmp     boot_error
61 10:     .asciz  "Could not locate active partition\r\n"
62
63 /*
64  * Print failure message and boot next device
65  *
66  * Parameters:
67  *   %si        : Failure string
68  */
69 boot_error:
70         cld
71         movw    $0x0007, %bx
72         movb    $0x0e, %ah
73 1:      lodsb
74         testb   %al, %al
75         je      99f
76         int     $0x10
77         jmp     1b
78 99:     /* Boot next device */
79         int     $0x18
80
81 /*
82  * Process partition table
83  *
84  * Parameters:
85  *   %dl        : BIOS drive number
86  *   %dh        : Head
87  *   %cl        : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
88  *   %ch        : Low eight bits of cylinder
89  *   %esi:%edi  : LBA address
90  *   %bp        : Active partition handler routine
91  *
92  * Returns:
93  *   CF set on error
94  */
95 process_table:
96         pushal
97         call    read_boot_sector
98         jc      99f
99         movw    $446, %bx
100 1:      call    process_partition
101         addw    $16, %bx
102         cmpw    $510, %bx
103         jne     1b
104 99:     popal
105         ret
106
107 /*
108  * Process partition
109  *
110  * Parameters:
111  *   %dl        : BIOS drive number
112  *   %dh        : Head
113  *   %cl        : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
114  *   %ch        : Low eight bits of cylinder
115  *   %esi:%edi  : LBA address
116  *   %bx        : Offset within partition table
117  *   %bp        : Active partition handler routine
118  */
119 process_partition:
120         pushal
121         /* Load C/H/S values from partition entry */
122         movb    %es:1(%bx), %dh
123         movw    %es:2(%bx), %cx
124         /* Update LBA address from partition entry */
125         addl    %es:8(%bx), %edi
126         adcl    $0, %esi
127         /* Check active flag */
128         testb   $0x80, %es:(%bx)
129         jz      1f
130         call    read_boot_sector
131         jc      99f
132         jmp     *%bp
133 1:      /* Check for extended partition */
134         movb    %es:4(%bx), %al
135         cmpb    $0x05, %al
136         je      2f
137         cmpb    $0x0f, %al
138         je      2f
139         cmpb    $0x85, %al
140         jne     99f
141 2:      call    process_table
142 99:     popal
143         /* Reload original partition table */
144         call    read_boot_sector
145         ret
146
147 /*
148  * Read single sector to %es:0000 and verify 0x55aa signature
149  *
150  * Parameters:
151  *   %dl        : BIOS drive number
152  *   %dh        : Head
153  *   %cl        : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
154  *   %ch        : Low eight bits of cylinder
155  *   %esi:%edi  : LBA address
156  *
157  * Returns:
158  *   CF set on error
159  */
160 read_boot_sector:
161         pushw   %ax
162         movw    $1, %ax
163         call    *read_sectors
164         jc      99f
165         cmpw    $0xaa55, %es:(510)
166         je      99f
167         stc     
168 99:     popw    %ax
169         ret
170         
171 /*
172  * Read sectors to %es:0000
173  *
174  * Parameters:
175  *   %dl        : BIOS drive number
176  *   %dh        : Head
177  *   %cl        : Sector (bits 0-5), high two bits of cylinder (bits 6-7)
178  *   %ch        : Low eight bits of cylinder
179  *   %esi:%edi  : LBA address
180  *   %ax        : Number of sectors (max 127)
181  *
182  * Returns:
183  *   CF set on error
184  */
185 read_sectors:   .word   read_chs
186
187 read_chs:
188         /* Read sectors using C/H/S address */
189         pushal
190         xorw    %bx, %bx
191         movb    $0x02, %ah
192         stc
193         int     $0x13
194         sti
195         popal
196         ret
197
198 read_lba:
199         /* Read sectors using LBA address */
200         pushal
201         movw    %ax, (lba_desc + 2)
202         pushw   %es
203         popw    (lba_desc + 6)
204         movl    %edi, (lba_desc + 8)
205         movl    %esi, (lba_desc + 12)
206         movw    $lba_desc, %si
207         movb    $0x42, %ah
208         int     $0x13
209         popal
210         ret
211
212 lba_desc:
213         .byte   0x10
214         .byte   0
215         .word   1
216         .word   0x0000
217         .word   0x0000
218         .long   0, 0