|
|	execute NetBSD kernel
|
|	written by ITOH Yasufumi
|	public domain
|
|	$NetBSD: execkern.S,v 1.4 2011/02/21 02:31:58 itohy Exp $

#include <machine/asm.h>
#include "execkern.h"

#define MFP		0x00E88000	/* MFP */
#define MFP_IERA	(MFP+0x07)	/* (B) interrupt enable reg A */
#define MFP_IERB	(MFP+0x09)	/* (B) interrupt enable reg B */
#define MFP_RSR		(MFP+0x2B)	/* (B) USART receiver status reg */

#ifndef SRAM_MEMSZ
#define SRAM		0x00ED0000	/* SRAM start addr */
#define SRAM_MEMSZ	(SRAM + 8)	/* (L) size of main memory */
#endif

|	a3+0	load address
|
|	a3+4	section #1 image top address
|	a3+8	section #1 size
|	a3+12	section #1 gap size
|	  :	  :
|	a3+n-12	section #XK_NSEC image top address
|	a3+n-8	section #XK_NSEC size
|	a3+n-4	section #XK_NSEC gap size
|
|	a3+n	(reserved) (d5)
|	a3+n+4	bootdev (d6)
|	a3+n+8	boothowto (d7)
|	a3+n+12	entry address (absolute address)

#ifndef XK_NO_C_INTERFACE
	.text
	.even
ENTRY_NOPROFILE(exec_kernel)
	addql	#4,%sp
	moveal	%sp@+,%a3		| struct execkern_arg *
#endif

	moveal	%a3@+,%a1		| load address
	movel	%a1,%d3

	|
	| copy image
	|

	movel	#XK_NSEC-1,%d2
Lloop:
	moveal	%a3@+,%a0		| section image address
	movel	%a3@+,%d0		| section size
	movel	%d0,%d1
	jbsr	copy
	movel	%a3@+,%d0		| section gap
	jbsr	clear

	dbra	%d2,Lloop

	| stop MFP interrupts (for compatibility)
	clrb	MFP_IERA
	clrb	MFP_IERB
	clrb	MFP_RSR

	|
	| execute kernel
	| start(load_addr, mem_max, kernel_end)
	|
	movel	%a1,%d0
	addql	#3,%d0
	andib	#0xFC,%d0
	subl	%d3,%d0
	movel	%d0,%sp@-		| arg #3 (end of kernel)
	movel	SRAM_MEMSZ,%sp@-	| arg #2 (RAM size from SRAM)
	movel	%d3,%sp@-		| arg #1 (load address)

#if 0
	movel	%a3@+,%d5		| (reserved)
	movel	%a3@+,%d6		| boot device
	movel	%a3@+,%d7		| boot howto

	movel	%a3@+,%a0		| entry address
#else	/* optimized */
	moveml	%a3@+,%d5-%d7/%a0
#endif

	| clear unused registers
	moveq	#0,%d0
	moveq	#0,%d1
	moveq	#0,%d2
	moveq	#0,%d3
	moveq	#0,%d4
	moveal	%d0,%a1
	moveal	%d0,%a2
	moveal	%d0,%a3
	moveal	%d0,%a4
	moveal	%d0,%a5
	moveal	%d0,%a6

	jsr	%a0@			| execute NetBSD kernel
	| NOTREACHED

	| ??? returned from kernel -- issue software reset
	subal	%a1,%a1
	moveml	0x00ff0000,#0x0101	| get RESET vectors (%d0: ssp, %a0: pc)
	moveml	#0x0101,%a1@		| put them at 0x00000000 (for Xellent)
	.long	0x4E7B9801		| movec	%a1,%vbr
	jmp	%a0@			| go to reset address


|
| utility routines
|

| copy %d0 bytes from higher (%a0) to lower (%a1) address
1:	moveb	%a0@+,%a1@+
copy:	subql	#1,%d0
	bpls	1b
	rts

| clear %d0 bytes at %a1
| do nothing if %d0 is zero
1:	clrb	%a1@+
clear:	subql	#1,%d0
	bpls	1b
	rts
