/*
** head.s -- This file contains the initial boot code for the the
**	     Amiga Linux kernel.
**
** Copyright 1993 by Hamish Macdonald
**
** This file is subject to the terms and conditions of the GNU General Public
** License.  See the file README.legal in the main directory of this archive
** for more details.
**
*/


/*
 * Linux startup code.
 *
 * At this point, the boot loader has:
 * Disabled interrupts
 * Disabled caches
 * Put us in supervisor state.
 *
 * The kernel setup code takes the following steps:
 *   Raise interrupt level
 *   Set up a temporary interrupt stack
 *   Enable cache memories
 *   Set up temporary kernel memory mapping.
 *   Jump to memory management initialization (which calls start_kernel)
 *
 * NOTE:  This code will currently only work for 68851 and 68030 systems.
 *	  For the 68040, the early termination page descriptors below
 *	  must be replaced with page table descriptors pointing to
 *	  real page tables allocated, which can presumably be allocated
 *	  after the temporary page directory in chip memory.
 *	  For initial bootstrap purposes, only the kernel memory needs to
 *	  be mapped; i.e. the initial 16M of Amiga "hardware" space does
 *	  not need to be mapped at this point.	mm_init can take care of
 *	  that.
 */

.text
.globl _start

	.even
_start:
/*
 * raise interrupt level
 */
	movew	#0x2700,sr

/* set up temporary kernel interrupt stack (at 0x20000) */
	movel	#0x20000,sp
	addl	#4096,sp

/*
 * Enable instruction cache (burst) and data cache (if there)
 */
	movel	#0x00000919,d0
	movec	d0,cacr

/*
 * Use a temporary page directory at 0x1000 (in chip memory)
 * Clear this temporary page directory
 */
	movel	#0x10000,a1
	moveq	#0,d0
	movel	#1023,d1
1:	movel	d0,a1@+
	dbra	d1,1b
	movel	#0x10000,a1

/*
 * Setup "transparent" mapping of first 16M, using early termination
 * page descriptors.
 */

	movel	#0x00000001,a1@(0)
	movel	#0x00400001,a1@(4)
	movel	#0x00800001,a1@(8)
	movel	#0x00C00001,a1@(12)

/*
 * Setup mapping of kernel space (first 4 Meg)
 * This includes determination of the first physical page of the kernel
 * memory
 */
	lea	pc@(_start),a0
	movel	a0,d0
	addl	#0xfff,d0
	andl	#0xfffff000,d0
	movel	d0,d2		/* save the physical address */
	orib	#0x01,d0	/* change the addr into a page descriptor */
	movel	d0,a1@(1024*3)

/*
 * Setup a transparent mapping of the physical memory we are executing in.
 * The starting physical memory (rounded up to page boundary) is found in D2.
 * Only do this if the physical memory is not in the first 16 Meg, since
 * that is already "transparently" mapped.
 */
	cmpl	#0x01000000,d2
	bcc	1f

	moveq	#22,d3		/* find descriptor index in page directory */
	lsrl	d3,d2
	movel	d0,a1@(d0:l:4)	/* store mapping */

1:

/*
 * and setup Supervisor Root Pointer register to point to page directory
 */
	movel	a1,sp@-
	movel	#0x80000002,sp@-
	pmove	sp@,srp
	addl	#8,sp

/*
 * setup translation register contents
 * and enable translation
 */
	movel	#0x82c0aa00,sp@
	pmove	sp@,tc

/* jump to memory management initialization */
	jmp	_mm_init
