pbr.S revision 1.1.12.2 1 /* $NetBSD: pbr.S,v 1.1.12.2 2006/12/30 20:46:24 yamt Exp $ */
2
3 /*-
4 * Copyright (c) 2005 NONAKA Kimihiro
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <machine/asm.h>
30 #include <sys/bootblock.h>
31
32 #ifdef BOOT_FROM_FAT
33 #define MBR_AFTERBPB 90 /* BPB size in FAT32 partition BR */
34 #else
35 #define MBR_AFTERBPB 62 /* BPB size in floppy master BR */
36 #endif
37
38 ENTRY(start)
39 bra start0
40 .byte 0x11 /* 0x4e11: cmp/pz r14... */
41 .ascii "NetBSD20"
42
43 . = _C_LABEL(start) + MBR_BPB_OFFSET /* move to start of BPB */
44
45 . = _C_LABEL(start) + MBR_AFTERBPB /* skip BPB */
46 start0:
47 mova mbr_end, r0
48 mov.w mbr_size, r2
49 sub r2, r0
50 mov r0, r11 /* r11: own loaded address */
51
52 mov.w stack_offset, r1
53 add r1, r0
54 mov r0, r15 /* r15: stack pointer */
55 mov r0, r10 /* r10: load address */
56
57 /* enable/flush cache */
58 mov #0, r4
59 mov #6, r0
60 trapa #0x3f
61
62 /* Read from start of disk */
63 mov #0x40, r4 /* LBA */
64 mov #0, r5 /* LBA #0 */
65 mov r10, r6 /* buffer address */
66 bsr read_sectors_lba
67 mov #BOOTXX_SECTORS, r7 /* number of sectors */
68
69 mov.l @r11, r1
70 mov.l @r10, r2
71 cmp/eq r1, r2
72 bt/s pbr_read_ok
73 mov #0, r9 /* r9: sector # */
74
75 /* Search bootable partition */
76 mov.w part_offset, r12
77 add r10, r12 /* r12: pointer to partition entry */
78 mov #MBR_PART_COUNT, r8 /* r8: partition loop counter */
79 loop_part:
80 mov.b @(4, r12), r0
81 #ifdef BOOT_FROM_FAT
82 cmp/eq #MBR_PTYPE_FAT12, r0
83 bt found
84 cmp/eq #MBR_PTYPE_FAT16S, r0
85 bt found
86 cmp/eq #MBR_PTYPE_FAT16B, r0
87 bt found
88 cmp/eq #MBR_PTYPE_FAT32, r0
89 bt found
90 cmp/eq #MBR_PTYPE_FAT32L, r0
91 bt found
92 cmp/eq #MBR_PTYPE_FAT16L, r0
93 bt found
94 #else
95 cmp/eq #MBR_PTYPE_NETBSD, r0
96 #endif
97 bf next_part
98
99 found:
100 /* found boot partition */
101 mov.w @(8, r12), r0
102 mov r0, r1
103 mov.w @(10, r12), r0
104 extu.w r1, r1
105 shll16 r0
106 or r1, r0
107 tst r0, r0
108 bt next_part /* start LBA == 0 ? */
109
110 bra boot_lba
111 mov r0, r9
112
113 next_part:
114 dt r8
115 bf/s loop_part
116 add #16, r12
117
118 ptn_error:
119 /* Not found NetBSD partition */
120 mova ERR_PTN, r0
121 error:
122 bsr message_crlf
123 mov r0, r4
124 99: bra 99b
125 nop
126
127 read_error:
128 bra error
129 mova ERR_READ, r0
130
131 magic_error:
132 bra error
133 mova ERR_NO_BOOTXX, r0
134
135 message_crlf:
136 mov #32, r0
137 trapa #0x3f
138 mova crlf, r0
139 mov r0, r4
140 mov #32, r0
141 trapa #0x3f
142 rts
143 nop
144
145 read_sectors_lba:
146 mov #2, r0
147 trapa #0x3f
148 tst r0, r0
149 bf read_error
150 rts
151 nop
152
153 boot_lba:
154 mov #0x40, r4 /* LBA */
155 mov r9, r5 /* LBA # */
156 mov r10, r6 /* buffer address */
157 bsr read_sectors_lba
158 mov #BOOTXX_SECTORS, r7 /* number of sectors */
159
160 pbr_read_ok:
161 mov.l .L.bootxx_magic1, r1
162 mov.l .L.bootxx_magic, r2
163 mov.l @r2, r2
164 cmp/eq r1, r2
165 bf magic_error
166
167 /* flush cache */
168 mov #0, r4
169 mov #6, r0
170 trapa #0x3f
171
172 mov.l .L.bootxx_start, r13
173 jmp @r13 /* jump to bootxx */
174 mov r9, r4 /* pass sector address to bootxx */
175
176
177 .align 1
178 mbr_size: .word mbr_end - _C_LABEL(start)
179 .align 1
180 stack_offset: .word 0x1000
181 .align 1
182 part_offset: .word MBR_PART_OFFSET
183 .align 1
184 magic_offset: .word MBR_MAGIC_OFFSET
185
186 .align 2
187 .L.bootxx_magic1:
188 .long LANDISK_BOOT_MAGIC_1
189 .L.bootxx_magic:
190 .long _C_LABEL(bootxx_magic)
191 .L.bootxx_start:
192 .long _C_LABEL(bootxx_start)
193
194 .align 2
195 crlf: .asciz "\r\n"
196
197 .align 2
198 ERR_READ: .asciz "Disk read"
199 .align 2
200 ERR_NO_BOOTXX: .asciz "Not a bootxx image"
201 .align 2
202 ERR_PTN: .asciz "No NetBSD partition"
203
204
205 /* space for mbr_dsn */
206 . = _C_LABEL(start) + MBR_DSN_OFFSET
207 .long 0
208
209 /* mbr_bootsel_magic */
210 . = _C_LABEL(start) + MBR_BS_MAGIC_OFFSET
211 .word 0
212
213 /*
214 * MBR partition table
215 */
216 . = _C_LABEL(start) + MBR_PART_OFFSET
217 _pbr_part0:
218 .byte 0, 0, 0, 0, 0, 0, 0, 0
219 .byte 0, 0, 0, 0, 0, 0, 0, 0
220 _pbr_part1:
221 .byte 0, 0, 0, 0, 0, 0, 0, 0
222 .byte 0, 0, 0, 0, 0, 0, 0, 0
223 _pbr_part2:
224 .byte 0, 0, 0, 0, 0, 0, 0, 0
225 .byte 0, 0, 0, 0, 0, 0, 0, 0
226 _pbr_part3:
227 .byte 0, 0, 0, 0, 0, 0, 0, 0
228 .byte 0, 0, 0, 0, 0, 0, 0, 0
229
230 . = _C_LABEL(start) + MBR_MAGIC_OFFSET
231 magic:
232 .word MBR_MAGIC
233 mbr_end:
234