1/* 2 * Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Copyright 2005, Ingo Weinhold, bonefish@users.sf.net. 4 * Copyright 2007, Haiku, Inc. All Rights Reserved. 5 * Distributed under the terms of the MIT license. 6 * 7 * Author: 8 * François Revol, revol@free.fr. 9 */ 10 11/** This file contains the boot floppy and BFS boot block entry points for 12 * the stage 2 boot loader. 13 * x86 ahead: 14 * The floppy entry point is at offset 0. It's loaded at 0x07c0:0x000. It 15 * will load the rest of the loader to 0x1000:0x0200 and execute it. 16 * The BFS boot block will load the whole stage 2 loader to 0x1000:0x0000 17 * and will then jump to 0x1000:0x0200 as its entry point. 18 * This code will then switch to protected mode and will directly call 19 * the entry function of the embedded ELF part of the loader. 20 */ 21 22/* 23 * generate boot floppy: 24 * cd src/system/boot/platform/atari_m68k/ ; make fixup_tos_floppy_chksum; cd - 25 * dd if=generated/objects/haiku/m68k/release/system/boot/haiku_loader of=~/floppy.img bs=512 count=20 conv=notrunc 26 * src/system/boot/platform/atari_m68k/fixup_tos_floppy_chksum ~/floppy.img 27 * generate .prg: 28 * generated.m68k/cross-tools/bin/m68k-unknown-haiku-ld -o haiku.prg -T src/system/ldscripts/m68k/boot_prg_atari_m68k.ld generated/objects/haiku/m68k/release/system/boot/boot_loader_atari_m68k 29 */ 30 31/* 32 * references : 33 * http://ftp.netbsd.org/pub/NetBSD/NetBSD-release-3-0/src/sys/arch/atari/stand/xxboot/fdboot/fdboot.S 34 */ 35 36#include "atari_memory_map.h" 37#include "toscalls.h" 38 39// 1 enabled verbose output 40//#define DEBUG 1 41 42#define GLOBAL(x) .globl x ; x 43#define FUNCTION(x) .global x; .type x,@function; x 44 45#define DRIVE_RETRIES 3 46 // when the drive reading fails for some reason, it will 47 // retry this many times until it will report a failure 48 49 50#define SECTSIZE 512 51 52//.text 53_bs_entry: 54/* main entry point, both from the floppy boot and .prg */ 55 bra.s real_entry 56 57//FAT lookalike to avoid nasty things from happening 58// http://alive.atari.org/alive10/btmania.php 59// MS-DOS values : 60// http://support.microsoft.com/kb/75131/en 61// http://alumnus.caltech.edu/~pje/dosfiles.html 62 .ascii "Haiku " 63 .byte 0xbe, 0x50, 0x38 // id 64 //LITTLE ENDIAN! 65 .byte 0x00, 0x02 //BPS 66 .byte 0x02 //SPC 67 //.byte 0x00 //??? 68 .byte 0x00, 0x02 //RES - number of reserved sectors 69 .byte 0x00 //NFATS 70 .byte 0x00, 0x00 //NDIRS 71 .byte 0x40, 0x0b //NSECTS 72 .byte 0xf0 //MEDIA 73 .byte 0x05, 0x00 //SPF 74_fat_spt: 75 .byte 0x12, 0x00 //SPT 76 .byte 0x02, 0x00 //NSIDES 77 .byte 0x00, 0x00 //NHID 78 // we're done 79 80sNumSectors: 81 // this location will contain the length of the boot loader as 82 // written by the "makeflop" command in 512 byte blocks 83 // 0x180 is the allowed maximum, as the zipped TAR with the 84 // kernel and the boot module might start at offset 192 kB 85 //.word 0x0300 //0x0180 86 .word BOOT_ARCHIVE_IMAGE_OFFSET*2 87 88real_entry: 89 90// save the regs to return safely, like the NetBSD loader does: 91// http://ftp.netbsd.org/pub/NetBSD/NetBSD-release-3-0/src/sys/arch/atari/stand/xxboot/fdboot/fdboot.S 92 movem.l %d1-%d7/%a0-%a6,-(%sp) 93 94 lea str,%a0 95 bsr puts 96 97 // first, determine if .prg (user) or bootsect (super) 98 // Super() 99 move.l #SUP_INQUIRE,-(%sp) 100 move.w #0x20,-(%sp) 101 trap #GEMDOS_TRAP 102 addq.l #6,%sp 103 104 cmp.l #SUP_USER,%d0 105 bne floppy_start 106 bra prg_start 107 108/* 109 * floppy boot support code 110 */ 111 112floppy_start: 113 lea label_floppy,%a0 114 bsr puts 115 //bra floppy_start 116 117 // no interrupt 118 //or.w #0x0700,%sr 119 120 //XXX: check for enough RAM 121 122 // load the rest 123 //move.w sNumSectors,%d2 124 // load at base + this code. 125 //move.l #(ATARI_ZBEOS_BASE+512),%a2 126 //move.l %a2,%d0 127 //bsr putx 128 bsr load_sectors 129 tst.w %d0 130 bne load_failed 131floppy_done: 132 // setup stack 133 move.l #ATARI_ZBEOS_STACK_END,%sp 134 //jmp ATARI_ZBEOS_BASE+512 135 136 move.b #ATARI_BOOT_DRVAPI_FLOPPY,ATARI_ZBEOS_BASE + gBootDriveAPI - _bs_entry 137 move.w TOSVAR_bootdev,%d0 138 // XXX: use uint16 ?? 139 move.b %d0,ATARI_ZBEOS_BASE + gBootDriveID - _bs_entry 140 move.b #1,ATARI_ZBEOS_BASE + gBootedFromImage - _bs_entry 141 142 lea msg_j1,%a0 143 bsr puts 144 move.l #0,%d0 145 146 jmp _start 147 148load_failed: 149 //bra _exit 150 151spin: 152 //bra spin 153_exit: /* */ 154 lea failure_string,%a0 155 bsr puts 156 bsr getc 157 158 movem.l (%sp)+,%d1-%d7/%a0-%a6 159 rts 160 //rts 161 162/** Loads %d2 sectors from floppy disk, starting at head XXX %dh, sector %cx. 163 * The data is loaded to %a2. 164 */ 165 166load_sectors: 167 168#if 0 169 /* it seems to skip 9 every 9 sectors, buggy side handling ? */ 170 // Rwabs 171 //move.l #1,-(%sp) 172 move.w #0,-(%sp) // A: 173 //move.w #2,-(%sp) // C: 174 //move.w #-1,-(%sp) // 2nd sector 175 move.w #1,-(%sp) // 2nd sector 176 move.w %d2,-(%sp) 177 move.l %a2,-(%sp) 178 //move.w #RW_READ+RW_NOTRANSLATE,-(%sp) 179 move.w #RW_READ+RW_NOMEDIACH,-(%sp) 180 move.w #4,-(%sp) 181 trap #13 182 add.l #14,%sp 183#endif 184#if 0 185 // d2: 186 187 //move.w %d2,-(%sp) 188 move.w #1,-(%sp) // count 189 move.w #0,-(%sp) // sideno 190 move.w #0,-(%sp) // trackno 191 move.w #1,-(%sp) // sectno 192 move.w TOSVAR_bootdev,-(%sp) // devno 193 clr.l -(%sp) // filler 194 //move.w #0,-(%sp) 195 //move.l %a2,-(%sp) 196 move.l #ATARI_ZBEOS_BASE,-(%sp) 197 move.w #8,-(%sp) // floprd 198 trap #XBIOS_TRAP 199 add.l #20,%sp 200#endif 201 202 //bsr putx 203 //rts 204 205 /* 206 * %d3: remaining sects 207 * %d4: sectno 208 * %d5: trackno 209 * %d6: sideno 210 * %d7: sect / track 211 * %a5: buffer 212 * 213 */ 214 // load the rest 215 216 // XXX: the NetBSD loader probes it, but trying to asserts ARAnyM 217 clr.l %d7 218 move.b _fat_spt,%d7 // sect/track 219 //move.w #0,%d7 // sect/track 220 move.w #0,%d6 // sideno 221 move.w #0,%d5 // trackno 222 move.w #1,%d4 // sectno 223 move.w sNumSectors,%d3 // remainder 224 move.l #ATARI_ZBEOS_BASE,%a5 225read_sectors_loop: 226 bsr.s read_sect 227 bne read_sectors_fail 228 moveq #'.',%d0 229 bsr putc 230 subq.w #1,%d3 // remainder-- 231 bne.s read_sectors_next 232 bsr putcrlf 233 clr.l %d0 234 rts 235 236 // compute next track/side/sector 237read_sectors_next: 238#if 0 //DEBUG 239 // [TRAK][SIDE] 240 move.w %d5,%d0 241 swap %d0 242 move.w %d6,%d0 243 bsr putx 244 // [SECT][S/TK] 245 move.w %d4,%d0 246 swap %d0 247 move.w %d7,%d0 248 bsr putx 249 //bsr getc 250#endif //!DEBUG 251 add.l #SECTSIZE,%a5 252 addq.w #1,%d4 // sectno++ 253 cmp.w %d7,%d4 // if (sectno == spt) 254 bne.s .rs2 // { 255 addq.w #1,%d6 // sideno++ ; 256 cmp.w #2,%d6 // if (sideno == 2) { 257 bne .rs1 258 clr.w %d6 // sideno = 0 ; 259 addq.w #1,%d5 // trackno++ ; 260 bsr putcrlf 261 262.rs1: // } 263 clr.w %d4 // sectno = 0 ; 264.rs2: // } 265 266 bra.s read_sectors_loop 267 268read_sectors_fail: 269 tst.w %d7 // s/t 270 bne read_sectors_fail2 271 move.w %d4,%d0 272 bsr putx 273 move.w %d4,%d7 274 clr.w %d4 275 //add.w #1, 276 bra.s read_sectors_next 277read_sectors_fail2: 278 moveq #1,%d0 279 rts 280 281 282read_sect: /* read 1 sector */ 283 /* 284 * %d4: sectno 285 * %d5: trackno 286 * %d6: sideno 287 * %d7: remaining count 288 * %a5: buffer 289 * 290 */ 291#if 1 292 //move.w %d2,-(%sp) 293 //move.w #1,-(%sp) // count 294 //move.w #0,-(%sp) // sideno 295 //move.w #0,-(%sp) // trackno 296 //move.w #2,-(%sp) // sectno 297 move.w #1,-(%sp) 298 movem.w %d4-%d6,-(%sp) 299 move.w TOSVAR_bootdev,-(%sp) // devno 300 clr.l -(%sp) // filler 301 move.l %a5,-(%sp) 302 move.w #8,-(%sp) // floprd 303 trap #XBIOS_TRAP 304 add.l #20,%sp 305 tst.l %d0 306 307#endif 308 rts 309 310floppy_end: 311// .org FAILURE_STRING 312failure_string: 313// .string " Loading failed! Press key to reboot.\r\n" 314 .string " Loading failed! Press key.\r\n" 315// .string "FAIL" 316 317// .org DOT_STRING 318// .string "." 319 320 321 322 323putx: 324 movem.l %d0-%d2/%a0-%a2,-(%sp) 325 move.l #8-1,%d2 326 move.l %d0,%d1 327putxloop: 328 move.l %d1,%d0 329 lsl.l #4,%d1 330 //swap %d0 331 //lsr.l #8,%d0 332 //lsr.l #4,%d0 333 rol.l #4,%d0 334 and.l #0x0f,%d0 335 cmp.b #9,%d0 336 ble putx0 337 add.b #'a'-'0'-10,%d0 338 //bra putxdisp 339putx0: 340 add.b #'0',%d0 341putxdisp: 342 bsr putc 343 dbf %d2,putxloop 344 bsr putcrlf 345 movem.l (%sp)+,%d0-%d2/%a0-%a2 346 rts 347 348 349puts: 350.loopt: 351 move.b (%a0)+,%d0 352 beq .strout 353 bsr putc 354 bra .loopt 355.strout: 356putcrlf: 357 move.b #'\r',%d0 358 bsr putc 359 move.b #'\n',%d0 360 bsr putc 361 rts 362 363 364/* prints the char in d0.b to the console */ 365putc: 366 movem.l %d0-%d2/%a0-%a2,-(%sp) 367 move.w %d0,-(%sp) 368 move.w #DEV_CON,-(%sp) // DEV_CON 369 move.w #3,-(%sp) // Bconout 370 trap #BIOS_TRAP 371 add.l #6,%sp 372 movem.l (%sp)+,%d0-%d2/%a0-%a2 373 rts 374 375/* waits for a key */ 376getc: 377 movem.l %d1-%d2/%a0-%a2,-(%sp) 378 move.w #DEV_CON,-(%sp) // DEV_CON 379 move.w #2,-(%sp) // Bconin 380 trap #BIOS_TRAP 381 add.l #4,%sp 382 movem.l (%sp)+,%d1-%d2/%a0-%a2 383 rts 384 385str: 386 .string "Haiku!" 387label_prg: 388 .string "P" //"RG boot" 389label_floppy: 390 .string "F" //"loppy boot" 391h4: 392 .string "H4" 393h5: 394 .string "H5" 395msg_j1: 396 .string "Jumping to haiku_loader." 397 398shell_end: 399 //.fill (0x01fe - shell_end), 1, 0x55 400 .org 0x01fe 401 .word 0xaa55-1 // will be replaced by the one calculated by the build. 402 // we make sure PCs don't try to execute it. 403 // this bumps the "start" label to offset 0x0200 as 404 // expected by the BFS boot loader, and also marks 405 // this block as valid boot block for the BIOS 406 407//XXX: put bfs_start here 408 409/* 410 * \AUTO\HAIKU.PRG and ARAnyM BOOTSTRAP() support code 411 */ 412 413prg_start: 414 lea label_prg,%a0 415 bsr puts 416 417 // .prg: 418 // we need to switch to supervisor mode anyway 419 move.l #SUP_SET,-(%sp) 420 move.w #0x20,-(%sp) 421 trap #1 422 addq.l #6,%sp 423 move.l %d0,saved_super_stack 424 425#if 0 426 //_membot 427 move.l #0x432,%a0 428 move.l (%a0),%d0 429 bsr putx 430 431 //_memtop 432 move.l #0x436,%a0 433 move.l (%a0),%d0 434 bsr putx 435 436 //_v_bas_ad 437 move.l #0x44e,%a0 438 move.l (%a0),%d0 439 bsr putx 440#endif 441 // disable interrupts 442 //or.w #0x0700,%sr 443 444 // setup stack 445 move.l #ATARI_ZBEOS_STACK_END,%sp 446 447 lea h5,%a0 448 bsr puts 449 lea _bs_entry,%a0 450 move.l %a0,%d0 451 bsr putx 452 453 // copy the rest of the prg 454 455 // load counter 456 clr.l %d0 457 move.w sNumSectors,%d0 458 sub.w #1,%d0 459 // load addresses 460 lea _bs_entry,%a0 461 move.l #ATARI_ZBEOS_BASE,%a1 462 463 464nextsect: 465 move.l #512/4-1,%d1 466copysect_loop: 467 move.l (%a0)+,(%a1)+ 468 dbf %d1,copysect_loop 469 //bsr putx 470 dbf %d0,nextsect 471 472 lea msg_j1,%a0 473 bsr puts 474 // all done 475super_done: 476 // XXX: copy the rest ! 477 move.b #ATARI_BOOT_DRVAPI_FLOPPY,ATARI_ZBEOS_BASE + gBootDriveAPI - _bs_entry 478 move.b #0,ATARI_ZBEOS_BASE + gBootDriveID - _bs_entry 479 move.b #1,ATARI_ZBEOS_BASE + gBootedFromImage - _bs_entry 480 481 move.l #0,%d0 482 483 //jmp ATARI_ZBEOS_BASE+512 484 jmp _start 485 486saved_super_stack: 487 .long 0 488 489GLOBAL(gBootedFromImage): 490 .byte 0 491 492GLOBAL(gBootDriveAPI): 493 .byte ATARI_BOOT_DRVAPI_UNKNOWN 494 495GLOBAL(gBootDriveID): 496 .byte 0 497 498GLOBAL(gBootPartitionOffset): 499 .long 0 500 501