1/*        $NetBSD: biosboot.S,v 1.8 2011/01/05 23:13:01 jakllsch Exp $          */
2
3/*-
4 * Copyright (c) 2003 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by David Laight.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <machine/asm.h>
33#include <sys/bootblock.h>
34
35/*
36 * Code linked to 0x1000:0 and (usually) read from /boot by bootxx code
37 *
38 * On entry:
39 *        %dl                           BIOS drive number
40 *        %ecx:%ebx           Sector number of NetBSD partition
41 *        %ds:%si                       Boot parameter block (patched by installboot)
42 *        %cs                           0x1000
43 *        %ds, %es, %ss                 All zero
44 *        %sp                           near 0xfffc
45 */
46
47          .text
48          .code16
49ENTRY(boot_start)
50          jmp       boot_start_1
51          .balign   4
52ENTRY(boot_magic)
53          .long     X86_BOOT_MAGIC_2    /* checked for by bootxx code */
54ENTRY(boot_params)
55          .long     boot_start_1 - boot_params
56#include <boot_params.S>
57          . = boot_start + 0x80                   /* space for patchable variables */
58boot_start_1:
59
60#if 0
61          /* Allow for boot_start not being %cs:0 */
62          call      2f
632:        pop       %cx
64          sub       $2b, %cx            /* %ax is offset */
65          test      $0xf, %cx           /* check code seg aligned */
66          jz        3f
67          lret                                    /* not playing if not */
683:        mov       %cs, %ax
69          shr       $4, %cx
70          add       %cx, %ax            /* segment staring at boot_start */
71          push      %ax
72          push      $4f
73          lret
744:
75#endif
76
77          mov       %cs, %ax
78          mov       %ax, %es
79
80          movl      %ecx, %ebp                    /* move LBA out of the way */
81
82          /* Grab boot_params patched into bootxx by installboot */
83          cmpl      $X86_BOOT_MAGIC_1,-4(%si)     /* sanity check ptr */
84          jne       2f
85          mov       $boot_params, %di
86          movl      (%si),%ecx
87          cmp       $boot_start_1 - boot_params, %cx
88          jbe       1f
89          mov       $boot_start_1 - boot_params, %cx
901:        cld
91          rep
92          movsb
932:
94
95          mov       %ax, %ds
96          movl      $_end, %eax                   /* top of bss */
97          shr       $4, %eax            /* as a segment */
98          add       $0x1001, %ax                  /* and + 64k */
99          mov       %ax, %ss            /* for stack */
100          mov       $0xfffc, %sp                  /* %sp at top of it */
101
102          call      gdt_fixup
103
104          calll     real_to_prot
105          .code32
106
107          movl      $_end, %ecx                   /* zero bss */
108          movl      $__bss_start, %edi
109          subl      %edi, %ecx
110          shr       $2, %ecx            /* _end and __bss_start are aligned */
111          xor       %eax, %eax
112          rep
113          stosl
114
115          testb     $X86_BP_FLAGS_LBA64VALID, boot_params+4
116          jnz       1f
117          xorl      %ebp, %ebp                    /* high part of LBA is not valid */
1181:
119
120          movzbl    %dl, %edx
121          push      %ebp                          /* high 32 bits of first sector */
122          push      %ebx                          /* first sector of bios partition */
123          push      %edx                          /* bios disk */
124          call      _C_LABEL(boot2)               /* C bootstrap code */
125          addl      $12, %esp
126          call      prot_to_real
127          .code16
128
129boot_fail:
130          push      %ax
131          movw      $1f, %si
132          call      message
133          pop       %si
134          call      message
135          jmp       loopstop
1361:        .asciz    "Boot2 failed: "
137
138ENTRY(_rtt)
139          .code32
140          call      prot_to_real
141          .code16
142loopstop:
143          movb      $0x86, %ah                    /* delay for about a second */
144          movw      $16, %cx
145          int       $0x15
146          int       $0x18                         /* might be a boot fail entry */
1471:        sti
148          hlt
149          jmp       1b
150