1/* $OpenBSD: mbr.S,v 1.3 2022/12/08 02:11:27 guenther Exp $ */ 2/* $NetBSD: mbr.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 32ENTRY(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 511: 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 61jmp_start: 62 /* enable cache */ 63 mov #0, r4 64 mov #6, r0 65 trapa #0x3f 66 67 /* print banner */ 68 mova banner, r0 69 bsr message 70 mov r0, r4 71 72 /* search bootable partition */ 73 mov.w part_offset, r12 74 add r11, r12 /* r12: pointer to partition entry */ 75 mov #4, r8 /* r8: partition loop counter */ 76loop_part: 77 mov.b @(4, r12), r0 78 cmp/eq #0x00, r0 79 bt next_part 80 81 /* check active partition */ 82 mov.b @(0, r12), r0 83 cmp/eq #0x80, r0 84 bf next_part 85 86 /* found bootable partition */ 87 mov.w @(8, r12), r0 /* load unaligned 32bit data */ 88 mov r0, r1 89 mov.w @(10, r12), r0 90 extu.w r1, r1 91 shll16 r0 92 or r1, r0 93 94 mov r0, r3 95 mova found_sector, r0 96 bra boot_lba 97 mov.l r3, @r0 98 99next_part: 100 dt r8 101 bf/s loop_part 102 add #16, r12 103 104noos_error: 105 /* Not found bootable partition */ 106 mova ERR_NOOS, r0 107error: 108 bsr message 109 mov r0, r4 11099: bra 99b 111 nop 112 113read_error: 114 bra error 115 mova ERR_READ, r0 116 117message: 118 mov #32, r0 119 trapa #0x3f 120 rts 121 nop 122 123read_sector_lba: 124 mov #1, r7 125 mov #2, r0 126 trapa #0x3f 127 tst r0, r0 128 bf read_error 129 rts 130 nop 131 132boot_lba: 133 /* read PBR sector */ 134 mova found_sector, r0 135 mov #0x40, r4 136 mov.l @r0, r5 137 bsr read_sector_lba 138 mov r10, r6 139 140 /* flush cache */ 141 mov #0, r4 142 mov #6, r0 143 trapa #0x3f 144 145 /* check signature */ 146 mov.b @(0, r10), r0 147 tst r0, r0 148 bt noos_error /* first byte non-zero */ 149 mov.w magic_offset, r0 150 mov.w @(r0, r10), r1 151 mov.w magic, r2 152 cmp/eq r1, r2 153 bf noos_error /* magic */ 154 155 /* now jump to PBR */ 156 mov r10, r0 157 jmp @r10 158 nop 159 160 161 .align 1 162mbr_size: .word mbr_end - start 163 .align 1 164stack_offset: .word 0x1000 165 .align 1 166part_offset: .word 0x1be 167 .align 1 168magic_offset: .word 0x1fe 169 170 .align 2 171found_sector: .long 0 172 173 .align 2 174banner: .asciz "\r\nOpenBSD MBR\r\n" 175 176 .align 2 177ERR_INVPART: .asciz "No active partition\r\n" 178 .align 2 179ERR_READ: .asciz "Read error\r\n" 180 .align 2 181ERR_NOOS: .asciz "No O/S\r\n" 182 183 184/* space for mbr_dsn */ 185 . = start + 0x1b4 186 .long 0 187 188/* mbr_bootsel_magic */ 189 . = start + 0x1b8 190 .word 0 191 192/* 193 * MBR partition table 194 */ 195 . = start + 0x1be 196_pbr_part0: 197 .byte 0, 0, 0, 0, 0, 0, 0, 0 198 .byte 0, 0, 0, 0, 0, 0, 0, 0 199_pbr_part1: 200 .byte 0, 0, 0, 0, 0, 0, 0, 0 201 .byte 0, 0, 0, 0, 0, 0, 0, 0 202_pbr_part2: 203 .byte 0, 0, 0, 0, 0, 0, 0, 0 204 .byte 0, 0, 0, 0, 0, 0, 0, 0 205_pbr_part3: 206 .byte 0, 0, 0, 0, 0, 0, 0, 0 207 .byte 0, 0, 0, 0, 0, 0, 0, 0 208 209 . = start + 0x1fe 210magic: 211 .word 0xaa55 212mbr_end: 213