core, bios: Move __syslinux_shuffler_size to assembly
[syslinux/sherbszt.git] / diag / mbr / handoff.S
blobab8582b76a9259c9c0099f9e61cd67006deaf4b4
1 /* -----------------------------------------------------------------------
2  *
3  *   Copyright 2010-2011 Gene Cumm
4  *
5  *   Portions from mbr.S:
6  *   Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
7  *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
8  *
9  *   Permission is hereby granted, free of charge, to any person
10  *   obtaining a copy of this software and associated documentation
11  *   files (the "Software"), to deal in the Software without
12  *   restriction, including without limitation the rights to use,
13  *   copy, modify, merge, publish, distribute, sublicense, and/or
14  *   sell copies of the Software, and to permit persons to whom
15  *   the Software is furnished to do so, subject to the following
16  *   conditions:
17  *
18  *   The above copyright notice and this permission notice shall
19  *   be included in all copies or substantial portions of the Software.
20  *
21  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23  *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24  *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25  *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26  *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28  *   OTHER DEALINGS IN THE SOFTWARE.
29  *
30  * ----------------------------------------------------------------------- */
33  * handoff.S: MBR/VBR-like codeblock to display handoff data
34  *
35  * Displays the values of DL, DS, SI, the contents of [DS:SI] (16 bytes),
36  * the values of ES, DI, the contents of [ES:DI] (4 bytes), scans memory for
37  * $PnP then reports a boot failure.
38  *
39  * This should (hopefully) be only 8086 code
40  */
43  * Install instructions (assuming your target is /dev/dev; file or block device):
44  *
45  * MBR:
46  * dd conv=notrunc bs=440 count=1 if=handoff.bin of=/dev/dev
47  *
48  * VBR/PBR (should work for FAT12/16/32, ext[234]fs, btrfs):
49  * echo -en "\0353\0130\0220" |dd conv=notrunc bs=1 count=3 of=/dev/dev
50  * dd conv=notrunc bs=2 count=210 seek=45 if=handoff.bin of=/dev/dev
51  */
53 // #define DEBUG_MARKER1        /* Insert markers in binary */
54 // #define DEBUG_START  /* Print entry addresses at start */
55 // #define DEBUG_LOADE  /* movw versus pop */
56 #define DEBUG_PNP       /* Scan for $PnP and show address */
57 #define DEBUG_PAK       /* Press Any Key before boot fail */
58 // #define DEBUG_ENTRY_REG      /* Store (manually as pusha is 80186) registers */
59 // #define DEBUG_FDT    /* Print the floppy descriptor table; INT 1Eh*/
61 #ifdef DEBUG_MARKER1
62         .macro ASCII_MARKER1 s:vararg
63         .ascii  \s
64         .endm
65 #else   /* DEBUG_MARKER1 */
66         .macro ASCII_MARKER1 s:vararg
67         .endm
68 #endif  /* DEBUG_MARKER1 */
70 #ifdef DEBUG_LOADE
71         .macro LOADE r:req, t:req
72         movw    (es_\r), %\t
73         .endm
74 #else   /* DEBUG_LOADE */
75         .macro LOADE r:req, t:req
76         popw %\t
77         .endm
78 #endif  /* DEBUG_LOADE */
80         .code16
81         .text
83 entry           = 0x7c00
84 stack           = (entry)
85 e_start         = (stack)
86 e_ax            = (e_start-2)
87 e_ss            = (e_ax-2)
88 e_sp            = (e_ss-2)
89 e_bot           = (e_ss)
90 /* Doubtful this will be used */
91 e0_beg          = (e_bot)
92 e0_ax           = (e0_beg-2)
93 e0_cx           = (e0_ax-2)
94 e0_dx           = (e0_cx-2)
95 e0_bx           = (e0_dx-2)
96 e0_sp           = (e0_bx-2)
97 e0_bp           = (e0_sp-2)
98 e0_si           = (e0_bp-2)
99 e0_di           = (e0_si-2)
100 e0_ds           = (e0_di-2)
101 e0_es           = (e0_ds-2)
102 e0_bot          = (e0_es)
103 es_beg          = (e0_bot)      /* Original register values from entry point */
104 es_di           = (es_beg-2)
105 es_es           = (es_di-2)
106 es_si           = (es_es-2)
107 es_ds           = (es_si-2)
108 es_bot          = (es_ds)
110 BIOS_page       = 0x462
112 int_1e          = (4*0x1e)
113 int_1e_seg      = (int_1e)
114 int_1e_off      = (int_1e+2)
116         .globl  _start
117 _start:
118         cli
119 #ifdef DEBUG_ENTRY_REG
120         movw    %ax, e_ax
121         movw    %ss, e_ss
122         movw    %sp, e_sp
123 #endif /* DEBUG_ENTRY_REG */
124         xorw    %ax, %ax
125         movw    %ax, %ss
126 #ifdef DEBUG_ENTRY_REG
127         movw    $e0_beg, %sp
128         /* pushaw */            /* 80186 */
129         pushw   %ax
130         pushw   %cx
131         pushw   %dx
132         pushw   %bx
133         pushw   %sp
134         pushw   %bp
135         pushw   %si
136         pushw   %di
137         pushw   %ds
138         pushw   %es
139 #else /* DEBUG_ENTRY_REG */
140         movw    $es_beg, %sp
141 #endif /* DEBUG_ENTRY_REG */
142         pushw   %di             /* es:di -> $PnP header */
143         pushw   %es
144         pushw   %si
145         pushw   %ds
146         sti
147         cld
148         pushw   %cs
149         popw    %ds
151 #ifdef DEBUG_START
152         pushw   %dx
153         call    crlf
154         movw    $(_start),%dx   /* 0x0600 mbr.ld .text address */
155         call    wrhexw
156         call    crlf
157         call    caddr
158 caddr:
159         popw    %dx
160         subw    $(caddr - _start), %dx
161         call    wrhexw
162         call    crlf
163         popw    %dx
164 #endif  /* DEBUG_START */
166         /* write DL */
167 pr_dl:  call    wrstr
168         .ascii  "DL: \0"
169         call    wrhexb
170         /* DS */
171 pr_ds:  call    wrstr
172         .ascii  "  DS: \0"
173         LOADE   ds, dx
174         pushw   %dx
175         popw    %es
176         call    wrhexw
177         /* SI */
178 pr_si:  call    wrstr
179         .ascii  "  SI: \0"
180         LOADE   si, dx
181         pushw   %dx
182         popw    %di
183         call    wrhexw
184         call    crlf
185         /* DS:SI */
186         movw    $16, %cx
187         call    wrhexbses
188         call    crlf
190         /* ES */
191 pr_es:  call    wrstr
192         .ascii  "ES: \0"
193         LOADE   es, dx
194         pushw   %dx
195         popw    %es
196         call    wrhexw
197 pr_di:  call    wrstr
198         .ascii  "  DI: \0"
199         LOADE   di, dx
200         pushw   %dx
201         popw    %di
202         call    wrhexw
203         call    crlf
204         /* ES:DI */     /* %es:0(%di) */
205         movw    $4, %cx
206         call    wrhexbses
208 #ifdef DEBUG_PNP
209         subw    $4, %si
210         es lodsw
211         cmpw    $0x5024, %ax
212         jne     scn_pnp
213         es lodsw
214         cmpw    $0x506E, %ax
215         jne     scn_pnp
216         call    wrstr
217         .ascii  " =$PnP\0"
218 scn_pnp:
219         call    crlf
220         /* $PnP Scan */
221         movw    $0xf000, %dx
222         pushw   %dx
223         popw    %es
224         movw    $0, %si
225         movw    $0x1000, %cx
226         /* 0x506E5024 */
227         movw    $0x5024, %dx
228         movw    $0x506E, %bx
229 ch_pnp: es lodsw        /* Check for $PnP */
230         cmpw    %dx, %ax
231         jne     ch_pnp_l
232         es lodsw
233         cmpw    %bx, %ax
234         je      pr_pnp
235 ch_pnp_l:               /* Check $PnP failed; loop to next address */
236         addw    $14, %si
237         andw    $0xFFF0, %si
238         loopw   ch_pnp
239         jmp     pnp_end
240 pr_pnp:
241         pushw   %si
242         call    wrstr
243         .ascii  "$PnP-\0"
244         movw    %es, %dx
245         call    wrhexw
246         movb    $':, %al
247         call    wrchr
248         popw    %dx
249         andw    $0xFFF0, %dx
250         call    wrhexw
251 #endif  /* DEBUG_PNP */
252         call    crlf
253 pnp_end:
255 #ifdef DEBUG_FDT
256         /* INT 1Eh: Floppy Parameter Table Pointer */
257 pr_1e:  call    wrstr
258         .ascii  "INT 1Eh: \0"
259         mov     $int_1e,%bx
260         les     (%bx),%di
261         pushw   %es
262         popw    %dx
263         call    wrhexw
264         movb    $':, %al
265         call    wrchr
266         pushw   %di
267         popw    %dx
268         call    wrhexw
269         call    crlf
270         /* [INT 1Eh] */
271         movw    $14, %cx
272         call    wrhexbses
273         call    crlf
274 #endif  /* DEBUG_FDT */
276 end:
277         jmp     bootfail
279         ASCII_MARKER1   "wc"
280 wrchr:
281         movb    $0x0e, %ah
282         movb    (BIOS_page), %bh
283         movb    $0x07, %bl
284         int     $0x10           /* May destroy %bp */
285         ret
287         ASCII_MARKER1   "ws"
288 wrstr:
289         pop     %si
290 wrstr_l:
291         lodsb
292         cmpb    $0, %al
293         je      wrstr_d
294         call    wrchr
295         jmp     wrstr_l
296 wrstr_d:
297         push    %si
298         ret
300 crlf:
301         call    wrstr
302         .ascii  "\r\n\0"
303         ret
305         ASCII_MARKER1   "hx"
306 wrhexn:
307         and     $0x0F, %al
308         cmpb    $10, %al
309         jae     .alph
310         addb    $'0, %al
311         jmp     .wc
312 .alph:
313         addb    $('A - 10), %al
314 .wc:
315         call wrchr
316         ret
318 wrhexb:
319         pushw   %cx
320         movb    %dl, %al
321         pushw   %ax
322         movb    $4, %cl
323         rorw    %cl, %ax
324         call    wrhexn
325         popw    %ax
326         call    wrhexn
327         popw    %cx
328         ret
330 wrhexw:
331         pushw   %cx
332         movb    $8, %cl
333         rorw    %cl, %dx
334         call wrhexb
335         rorw    %cl, %dx
336         call wrhexb
337         popw    %cx
338         ret
340         ASCII_MARKER1   "HE"
341 wrhexbses:
342         pushw   %di
343         popw    %si
344 wrhexbses_l:
345         movb    $' , %al
346         call    wrchr
347         es lodsb
348         movw    %ax, %dx
349         call    wrhexb
350         loop    wrhexbses_l
351         ret
353 data:
354         ASCII_MARKER1   "bf"
355 bootfail:
356 #ifdef DEBUG_PAK
357         call wrstr
358         .ascii  "\r\n\r\nPress any key\r\n\0"
359         xor     %ax, %ax
360         int     $0x16
361 #endif
362         int     $0x18           /* Boot failure */
363 die:
364         hlt
365         jmp     die