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