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