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