1/*	$OpenBSD: pbr.S,v 1.3 2022/12/08 02:11:27 guenther Exp $	*/
2/*	$NetBSD: pbr.S,v 1.1 2006/09/01 21:26:19 uwe Exp $	*/
3
4/*-
5 * Copyright (c) 2005 NONAKA Kimihiro
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <machine/asm.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
38ENTRY(start)
39	bra	start0
40	 .byte	0x11			/* 0x4f11: cmp/pz r15... */
41	.asciz	"OpenBSD"
42
43	. = start + 0x0b		/* move to start of BPB */
44
45	. = start + 0x1c		/* skip BPB */
46start0:
47	mova	pbr_end, r0
48	mov.w	pbr_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	#XXBOOT_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	#4, r8			/* r8: partition loop counter */
79loop_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	#0xa6, r0
96#endif
97	bf	next_part
98
99found:
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
113next_part:
114	dt	r8
115	bf/s	loop_part
116	 add	#16, r12
117
118ptn_error:
119	/* no OpenBSD partition found */
120	mova	ERR_PTN, r0
121error:
122	bsr	message_crlf
123	 mov	r0, r4
12499:	bra	99b
125	 nop
126
127read_error:
128	bra	error
129	 mova	ERR_READ, r0
130
131magic_error:
132	bra	error
133	 mova	ERR_NO_XXBOOT, r0
134
135message_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
145read_sectors_lba:
146	mov	#2, r0
147	trapa	#0x3f
148	tst	r0, r0
149	bf	read_error
150	rts
151	 nop
152
153boot_lba:
154	mov	#0x40, r4		/* LBA */
155	mov	r9, r5			/* LBA # */
156	mov	r10, r6			/* buffer address */
157	bsr	read_sectors_lba
158	 mov	#XXBOOT_SECTORS, r7	/* number of sectors */
159
160pbr_read_ok:
161	mov.l	.L.xxboot_magic1, r1
162	mov.l	.L.xxboot_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.xxboot_start, r13
173	jmp	@r13			/* jump to xxboot */
174	 mov	r9, r4			/* pass sector address to xxboot */
175
176
177	.align	1
178pbr_size:	.word	pbr_end - start
179	.align	1
180stack_offset:	.word	0x1000
181	.align	1
182part_offset:	.word	0x1be
183	.align	1
184magic_offset:	.word	0x1fe
185
186	.align	2
187.L.xxboot_magic1:
188	.long	0x20031125
189.L.xxboot_magic:
190	.long	xxboot_magic
191.L.xxboot_start:
192	.long	xxboot_start
193
194	.align	2
195crlf:		.asciz	"\r\n"
196
197	.align	2
198ERR_READ:	.asciz  "Disk read"
199	.align	2
200ERR_NO_XXBOOT:	.asciz  "Not a xxboot image"
201	.align	2
202ERR_PTN:	.asciz  "No OpenBSD partition"
203
204
205	. = start + 0x1fe
206magic:
207	.word	0xaa55
208pbr_end:
209
210	.global	ptn_disklabel
211ptn_disklabel:
212	.fill	512
213