Home | History | Annotate | Line # | Download | only in bootxx
      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