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