1/* 2 * Copyright 2008-2011, François Revol, revol@free.fr. All rights reserved. 3 * Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 4 * Copyright 2005, Ingo Weinhold, bonefish@users.sf.net. 5 * Copyright 2007, Haiku, Inc. All Rights Reserved. 6 * Distributed under the terms of the MIT license. 7 */ 8 9/** This file contains the boot floppy, .PRG and BFS boot block entry points 10 * for the stage 2 boot loader. All 3 entry points load and relocate the 11 * loader so that it ends up being at ATARI_ZBEOS_BASE. 12 * This file is built as PIC so it works wherever it is executed. 13 * Some arithmetic is thus needed to set variables in the relocated code. 14 * The loader .PRG file is created from the bootloader by a custom ldscript. 15 * 16 * Known load addresses: 17 * floppy: 0x00a34c (EmuTOS in ARAnyM) 18 * .prg: 0x03543e (depends on the TOS memory) 19 * BFS: is set in the MBR code. 20 * 21 * The floppy and .PRG code is entered at _bs_entry, which jumps further on 22 * to skip some fake FAT descriptor. 23 * It first determines which way it was loaded (floppy boot happens in 24 * supervisor mode, while .PRG are loaded as user code), and jumps to 25 * the specific part. 26 * 27 * The floppy code comes first as it must be in the first sector, 28 * and loads the rest of the loader at ATARI_ZBEOS_BASE+0x200, 29 * sets up the new stack and jumps to _start after setting some variables. 30 * The end of the floppy code contains a placeholder for a checksum which 31 * is calculated at build-time by the <build>fixup_tos_floppy_chksum tool. 32 * 33 * The .PRG code switches to supervisor mode, copies the whole loader 34 * which is already in memory to ATARI_ZBEOS_BASE. It then sets up the new 35 * stack and some variables and jumps to _start. 36 * 37 * The BFS code is yet to be fully written. 38 */ 39 40/* 41 * references : 42 * http://ftp.netbsd.org/pub/NetBSD/NetBSD-release-3-0/src/sys/arch/atari/stand/xxboot/fdboot/fdboot.S 43 */ 44 45#include "atari_memory_map.h" 46#include "toscalls.h" 47 48// 1 enabled verbose output 49//#define DEBUG 1 50 51#define GLOBAL(x) .globl x ; x 52#define FUNCTION(x) .global x; .type x,@function; x 53 54#define DRIVE_RETRIES 3 55 // when the drive reading fails for some reason, it will 56 // retry this many times until it will report a failure 57 58 59#define SECTSIZE 512 60 61//.text 62_bs_entry: 63/* main entry point, both from the floppy boot and .prg */ 64 bra.s real_entry 65 66//FAT lookalike to avoid nasty things from happening 67// http://alive.atari.org/alive10/btmania.php 68// MS-DOS values : 69// http://support.microsoft.com/kb/75131/en 70// http://alumnus.caltech.edu/~pje/dosfiles.html 71 .ascii "Haiku " 72 .byte 0xbe, 0x50, 0x38 // id 73 //LITTLE ENDIAN! 74 .byte 0x00, 0x02 //BPS 75 .byte 0x02 //SPC 76 //.byte 0x00 //??? 77 .byte 0x00, 0x02 //RES - number of reserved sectors 78 .byte 0x00 //NFATS 79 .byte 0x00, 0x00 //NDIRS 80 .byte 0x40, 0x0b //NSECTS 81 .byte 0xf0 //MEDIA 82 .byte 0x05, 0x00 //SPF 83_fat_spt: 84 .byte 0x12, 0x00 //SPT 85 .byte 0x02, 0x00 //NSIDES 86 .byte 0x00, 0x00 //NHID 87 // we're done 88 89sNumSectors: 90 // This location will contain the max length of the boot loader 91 // as written by the build system in 512 byte blocks and depends 92 // on the offset of the zipped TAR with the kernel and the boot 93 // modules will start at offset BOOT_ARCHIVE_IMAGE_OFFSET kB. 94 .word BOOT_ARCHIVE_IMAGE_OFFSET*2 95 96real_entry: 97 98// save the regs to return safely, like the NetBSD loader does: 99// http://ftp.netbsd.org/pub/NetBSD/NetBSD-release-3-0/src/sys/arch/atari/stand/xxboot/fdboot/fdboot.S 100 movem.l %d1-%d7/%a0-%a6,-(%sp) 101 102//DEBUG: determine load location 103// lea _bs_entry(%pc),%a0 104// move.l %a0,%d0 105// bsr putx 106 107 lea str,%a0 108 bsr puts 109 110 // first, determine if .prg (user) or bootsect (super) 111 // Super(SUP_INQUIRE) 112 move.l #SUP_INQUIRE,-(%sp) 113 move.w #0x20,-(%sp) 114 trap #GEMDOS_TRAP 115 addq.l #6,%sp 116 117 cmp.l #SUP_USER,%d0 118 bne floppy_start 119 bra prg_start 120 121/* 122 * floppy boot support code 123 */ 124 125floppy_start: 126 //lea label_floppy,%a0 127 //bsr puts 128 129 bsr load_sectors 130 tst.w %d0 131 bne load_failed 132 133floppy_done: 134 move.b #ATARI_BOOT_DRVAPI_FLOPPY,ATARI_ZBEOS_BASE + gBootDriveAPI - _bs_entry 135 move.w TOSVAR_bootdev,%d0 136 // XXX: use uint16 ?? 137 move.b %d0,ATARI_ZBEOS_BASE + gBootDriveID - _bs_entry 138 move.b #1,ATARI_ZBEOS_BASE + gBootedFromImage - _bs_entry 139 140 141all_done: 142 143 // setup stack 144 move.l #ATARI_ZBEOS_STACK_END,%sp 145 146 // say goodbye to TOS 147 lea msg_j1,%a0 148 bsr puts 149 150 //bra spin 151 // say hello to haiku_loader 152 jmp _start 153 154load_failed: 155 //bra _exit 156 157spin: 158 bra spin 159_exit: /* */ 160 lea failure_string,%a0 161 bsr puts 162 bsr getc 163 164 movem.l (%sp)+,%d1-%d7/%a0-%a6 165 rts 166 //rts 167 168/** Loads %d2 sectors from floppy disk, starting at head XXX %dh, sector %cx. 169 * The data is loaded to %a2. 170 */ 171 172load_sectors: 173 174 /* 175 * %d3: remaining sects 176 * %d4: sectno 177 * %d5: trackno 178 * %d6: sideno 179 * %d7: sect / track 180 * %a5: buffer 181 * 182 */ 183 // load the rest 184 185 // XXX: the NetBSD loader probes it, but trying to asserts ARAnyM 186 clr.l %d7 187 move.b _fat_spt,%d7 // sect/track 188 //move.w #0,%d7 // sect/track 189 move.w #0,%d6 // sideno 190 move.w #0,%d5 // trackno 191 move.w #1,%d4 // sectno 192 move.w sNumSectors,%d3 // remainder 193 move.l #ATARI_ZBEOS_BASE,%a5 194read_sectors_loop: 195 bsr.s read_sect 196 bne read_sectors_fail 197 moveq #'.',%d0 198 bsr putc 199 subq.w #1,%d3 // remainder-- 200 bne.s read_sectors_next 201 bsr putcrlf 202 clr.l %d0 203 rts 204 205 // compute next track/side/sector 206read_sectors_next: 207 add.l #SECTSIZE,%a5 208 addq.w #1,%d4 // sectno++ 209 cmp.w %d7,%d4 // if (sectno == spt) 210 bne.s .rs2 // { 211 addq.w #1,%d6 // sideno++ ; 212 cmp.w #2,%d6 // if (sideno == 2) { 213 bne .rs1 214 clr.w %d6 // sideno = 0 ; 215 addq.w #1,%d5 // trackno++ ; 216 bsr putcrlf 217 218.rs1: // } 219 clr.w %d4 // sectno = 0 ; 220.rs2: // } 221 222 bra.s read_sectors_loop 223 224read_sectors_fail: 225 tst.w %d7 // s/t 226 bne read_sectors_fail2 227 move.w %d4,%d0 228 bsr putx 229 move.w %d4,%d7 230 clr.w %d4 231 //add.w #1, 232 bra.s read_sectors_next 233read_sectors_fail2: 234 moveq #1,%d0 235 rts 236 237 238read_sect: /* read 1 sector */ 239 /* 240 * %d4: sectno 241 * %d5: trackno 242 * %d6: sideno 243 * %d7: remaining count 244 * %a5: buffer 245 * 246 */ 247 248 move.w #1,-(%sp) 249 movem.w %d4-%d6,-(%sp) 250 move.w TOSVAR_bootdev,-(%sp) // devno 251 clr.l -(%sp) // filler 252 move.l %a5,-(%sp) 253 move.w #8,-(%sp) // floprd 254 trap #XBIOS_TRAP 255 add.l #20,%sp 256 tst.l %d0 257 rts 258 259floppy_end: 260// .org FAILURE_STRING 261failure_string: 262// .string " Loading failed! Press key to reboot.\r\n" 263 .string " Loading failed! Press key.\r\n" 264// .string "FAIL" 265 266 267 268putx: 269 movem.l %d0-%d2/%a0-%a2,-(%sp) 270 move.l #8-1,%d2 271 move.l %d0,%d1 272putxloop: 273 move.l %d1,%d0 274 lsl.l #4,%d1 275 rol.l #4,%d0 276 and.l #0x0f,%d0 277 cmp.b #9,%d0 278 ble putx0 279 add.b #'a'-'0'-10,%d0 280putx0: 281 add.b #'0',%d0 282putxdisp: 283 bsr putc 284 dbf %d2,putxloop 285 bsr putcrlf 286 movem.l (%sp)+,%d0-%d2/%a0-%a2 287 rts 288 289 290puts: 291.loopt: 292 move.b (%a0)+,%d0 293 beq .strout 294 bsr putc 295 bra .loopt 296.strout: 297putcrlf: 298 move.b #'\r',%d0 299 bsr putc 300 move.b #'\n',%d0 301 bsr putc 302 rts 303 304 305/* prints the char in d0.b to the console */ 306putc: 307 movem.l %d0-%d2/%a0-%a2,-(%sp) 308 move.w %d0,-(%sp) 309 move.w #DEV_CON,-(%sp) // DEV_CON 310 move.w #3,-(%sp) // Bconout 311 trap #BIOS_TRAP 312 add.l #6,%sp 313 movem.l (%sp)+,%d0-%d2/%a0-%a2 314 rts 315 316/* waits for a key */ 317getc: 318 movem.l %d1-%d2/%a0-%a2,-(%sp) 319 move.w #DEV_CON,-(%sp) // DEV_CON 320 move.w #2,-(%sp) // Bconin 321 trap #BIOS_TRAP 322 add.l #4,%sp 323 movem.l (%sp)+,%d1-%d2/%a0-%a2 324 rts 325 326str: 327 .string "Haiku!" 328//label_prg: 329// .string "P" //"RG boot" 330//label_floppy: 331// .string "F" //"loppy boot" 332msg_j1: 333 .string "Jumping to haiku_loader." 334 335shell_end: 336 //.fill (0x01fe - shell_end), 1, 0x55 337 .org 0x01fe 338boot_code_checksum: 339 .word 0xaa55-1 // will be replaced by the one calculated by the build. 340 // we make sure PCs don't try to execute it. 341 // this bumps the "start" label to offset 0x0200 as 342 // expected by the BFS boot loader, and also marks 343 // this block as valid boot block for the BIOS 344 345 346//XXX: put bfs_start here 347bfs_start: 348 //FIXME:write BFS code 349 350 351/* 352 * \AUTO\HAIKU.PRG and ARAnyM BOOTSTRAP() support code 353 */ 354 355prg_start: 356 //lea label_prg,%a0 357 //bsr puts 358 359 // .prg: 360 // we need to switch to supervisor mode anyway 361 move.l #SUP_SET,-(%sp) 362 move.w #0x20,-(%sp) 363 trap #1 364 addq.l #6,%sp 365 move.l %d0,saved_super_stack 366 367 // disable interrupts 368 //or.w #0x0700,%sr 369 370 // copy the rest of the prg 371 372 // load counter 373 clr.l %d0 374 move.w sNumSectors,%d0 375 sub.w #1,%d0 376 // load addresses 377 lea _bs_entry,%a0 378 move.l #ATARI_ZBEOS_BASE,%a1 379 380 381nextsect: 382 move.l #512/4-1,%d1 383copysect_loop: 384 move.l (%a0)+,(%a1)+ 385 dbf %d1,copysect_loop 386 //bsr putx 387 dbf %d0,nextsect 388 389super_done: 390 // XXX: copy the rest ! 391 392 // XXX: force floppy boot for testing to get the kernel tgz for now 393 move.b #ATARI_BOOT_DRVAPI_FLOPPY,ATARI_ZBEOS_BASE + gBootDriveAPI - _bs_entry 394 move.b #0,ATARI_ZBEOS_BASE + gBootDriveID - _bs_entry 395 move.b #1,ATARI_ZBEOS_BASE + gBootedFromImage - _bs_entry 396 397 // all done, go to _start 398 bra all_done 399 400saved_super_stack: 401 .long 0 402 403GLOBAL(gBootedFromImage): 404 .byte 0 405 406GLOBAL(gBootDriveAPI): 407 .byte ATARI_BOOT_DRVAPI_UNKNOWN 408 409GLOBAL(gBootDriveID): 410 .byte 0 411 412GLOBAL(gBootPartitionOffset): 413 .long 0 414 415