mbr.S revision 1.1.2.2 1 /* $NetBSD: mbr.S,v 1.1.2.2 2006/09/03 15:23:20 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 ENTRY(start)
33 mova mbr_end, r0
34 mov r0, r11 /* r11: relocate address */
35
36 mov.w mbr_size, r2
37 sub r2, r0
38 mov r0, r10 /* r10: loaded address */
39
40 mov.w stack_offset, r1
41 add r1, r0
42 mov r0, r15 /* r15: stack pointer */
43
44 /* relocate code */
45 mova jmp_start, r0
46 mov r0, r13
47 add r2, r13 /* calc jump address */
48
49 mov r10, r0
50 mov r11, r1
51 1: mov.b @r0+, r3
52 dt r2
53 mov.b r3, @r1
54 bf/s 1b
55 add #1, r1
56
57 jmp @r13
58 nop
59
60 .align 2
61 jmp_start:
62 /* enable cache */
63 mov #0, r4
64 mov #6, r0
65 trapa #0x3f
66
67 #ifndef NO_BANNER
68 /* print banner */
69 mova banner, r0
70 bsr message_crlf
71 mov r0, r4
72 #endif
73
74 /* search bootable partition */
75 mov.w part_offset, r12
76 add r11, 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 cmp/eq #MBR_PTYPE_UNUSED, r0
81 bt next_part
82
83 /* check active partition */
84 mov.b @(0, r12), r0
85 cmp/eq #0x80, r0
86 bf next_part
87
88 /* found bootable partition */
89 mov.w @(8, r12), r0 /* load unaligned 32bit data */
90 mov r0, r1
91 mov.w @(10, r12), r0
92 extu.w r1, r1
93 shll16 r0
94 or r1, r0
95
96 mov r0, r3
97 mova found_sector, r0
98 bra boot_lba
99 mov.l r3, @r0
100
101 next_part:
102 dt r8
103 bf/s loop_part
104 add #16, r12
105
106 noos_error:
107 /* Not found bootable partition */
108 mova ERR_NOOS, r0
109 error:
110 bsr message_crlf
111 mov r0, r4
112 99: bra 99b
113 nop
114
115 read_error:
116 bra error
117 mova ERR_READ, r0
118
119 message_crlf:
120 mov #32, r0
121 trapa #0x3f
122 mova crlf, r0
123 mov r0, r4
124 mov #32, r0
125 trapa #0x3f
126 rts
127 nop
128
129 read_sector_lba:
130 mov #1, r7
131 mov #2, r0
132 trapa #0x3f
133 tst r0, r0
134 bf read_error
135 rts
136 nop
137
138 boot_lba:
139 /* read PBR sector */
140 mova found_sector, r0
141 mov #0x40, r4
142 mov.l @r0, r5
143 bsr read_sector_lba
144 mov r10, r6
145
146 /* flush cache */
147 mov #0, r4
148 mov #6, r0
149 trapa #0x3f
150
151 /* check signature */
152 mov.b @(0, r10), r0
153 tst r0, r0
154 bt noos_error /* first byte non-zero */
155 mov.w magic_offset, r0
156 mov.w @(r0, r10), r1
157 mov.w magic, r2
158 cmp/eq r1, r2
159 bf noos_error /* magic */
160
161 /* now jump to PBR */
162 mov r10, r0
163 jmp @r10
164 nop
165
166
167 .align 1
168 mbr_size: .word mbr_end - _C_LABEL(start)
169 .align 1
170 stack_offset: .word 0x1000
171 .align 1
172 part_offset: .word MBR_PART_OFFSET
173 .align 1
174 magic_offset: .word MBR_MAGIC_OFFSET
175
176 .align 2
177 found_sector: .long 0
178
179 #ifndef NO_BANNER
180 .align 2
181 banner: .asciz "\r\nNetBSD MBR boot"
182 #endif
183 .align 2
184 crlf: .asciz "\r\n"
185
186 .align 2
187 ERR_INVPART: .asciz "No active partition"
188 .align 2
189 ERR_READ: .asciz "Disk read error"
190 .align 2
191 ERR_NOOS: .asciz "No operating system"
192
193
194 /* space for mbr_dsn */
195 . = _C_LABEL(start) + MBR_DSN_OFFSET
196 .long 0
197
198 /* mbr_bootsel_magic */
199 . = _C_LABEL(start) + MBR_BS_MAGIC_OFFSET
200 .word MBR_BS_MAGIC
201
202 /*
203 * MBR partition table
204 */
205 . = _C_LABEL(start) + MBR_PART_OFFSET
206 _pbr_part0:
207 .byte 0, 0, 0, 0, 0, 0, 0, 0
208 .byte 0, 0, 0, 0, 0, 0, 0, 0
209 _pbr_part1:
210 .byte 0, 0, 0, 0, 0, 0, 0, 0
211 .byte 0, 0, 0, 0, 0, 0, 0, 0
212 _pbr_part2:
213 .byte 0, 0, 0, 0, 0, 0, 0, 0
214 .byte 0, 0, 0, 0, 0, 0, 0, 0
215 _pbr_part3:
216 .byte 0, 0, 0, 0, 0, 0, 0, 0
217 .byte 0, 0, 0, 0, 0, 0, 0, 0
218
219 . = _C_LABEL(start) + MBR_MAGIC_OFFSET
220 magic:
221 .word MBR_MAGIC
222 mbr_end:
223