1/* $NetBSD: pbr.S,v 1.1 2006/09/01 21:26:19 uwe 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#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 /* 0x4e11: cmp/pz r14... */ 41 .ascii "NetBSD20" 42 43 . = _C_LABEL(start) + MBR_BPB_OFFSET /* move to start of BPB */ 44 45 . = _C_LABEL(start) + MBR_AFTERBPB /* skip BPB */ 46start0: 47 mova mbr_end, r0 48 mov.w mbr_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 #BOOTXX_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 #MBR_PART_COUNT, 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 #MBR_PTYPE_NETBSD, 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 /* Not found NetBSD partition */ 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_BOOTXX, 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 #BOOTXX_SECTORS, r7 /* number of sectors */ 159 160pbr_read_ok: 161 mov.l .L.bootxx_magic1, r1 162 mov.l .L.bootxx_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.bootxx_start, r13 173 jmp @r13 /* jump to bootxx */ 174 mov r9, r4 /* pass sector address to bootxx */ 175 176 177 .align 1 178mbr_size: .word mbr_end - _C_LABEL(start) 179 .align 1 180stack_offset: .word 0x1000 181 .align 1 182part_offset: .word MBR_PART_OFFSET 183 .align 1 184magic_offset: .word MBR_MAGIC_OFFSET 185 186 .align 2 187.L.bootxx_magic1: 188 .long LANDISK_BOOT_MAGIC_1 189.L.bootxx_magic: 190 .long _C_LABEL(bootxx_magic) 191.L.bootxx_start: 192 .long _C_LABEL(bootxx_start) 193 194 .align 2 195crlf: .asciz "\r\n" 196 197 .align 2 198ERR_READ: .asciz "Disk read" 199 .align 2 200ERR_NO_BOOTXX: .asciz "Not a bootxx image" 201 .align 2 202ERR_PTN: .asciz "No NetBSD partition" 203 204 205/* space for mbr_dsn */ 206 . = _C_LABEL(start) + MBR_DSN_OFFSET 207 .long 0 208 209/* mbr_bootsel_magic */ 210 . = _C_LABEL(start) + MBR_BS_MAGIC_OFFSET 211 .word 0 212 213/* 214 * MBR partition table 215 */ 216 . = _C_LABEL(start) + MBR_PART_OFFSET 217_pbr_part0: 218 .byte 0, 0, 0, 0, 0, 0, 0, 0 219 .byte 0, 0, 0, 0, 0, 0, 0, 0 220_pbr_part1: 221 .byte 0, 0, 0, 0, 0, 0, 0, 0 222 .byte 0, 0, 0, 0, 0, 0, 0, 0 223_pbr_part2: 224 .byte 0, 0, 0, 0, 0, 0, 0, 0 225 .byte 0, 0, 0, 0, 0, 0, 0, 0 226_pbr_part3: 227 .byte 0, 0, 0, 0, 0, 0, 0, 0 228 .byte 0, 0, 0, 0, 0, 0, 0, 0 229 230 . = _C_LABEL(start) + MBR_MAGIC_OFFSET 231magic: 232 .word MBR_MAGIC 233mbr_end: 234