145 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /* -*-Asm-*- */
 | |
| /*
 | |
|  *  GRUB  --  GRand Unified Bootloader
 | |
|  *  Copyright (C) 2009  Free Software Foundation, Inc.
 | |
|  *
 | |
|  *  GRUB is free software: you can redistribute it and/or modify
 | |
|  *  it under the terms of the GNU General Public License as published by
 | |
|  *  the Free Software Foundation, either version 3 of the License, or
 | |
|  *  (at your option) any later version.
 | |
|  *
 | |
|  *  GRUB is distributed in the hope that it will be useful,
 | |
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|  *  GNU General Public License for more details.
 | |
|  *
 | |
|  *  You should have received a copy of the GNU General Public License
 | |
|  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 | |
|  */
 | |
| 
 | |
| #include <grub/boot.h>
 | |
| #include <grub/machine/boot.h>
 | |
| 
 | |
| 	.text
 | |
| 	.align	4
 | |
| 	.globl	_start
 | |
| _start:
 | |
| 	/* First stage boot block jumps to us here.  */
 | |
| pic_base:
 | |
| 	call	after_info_block
 | |
| 	 mov	%o7, PIC_REG
 | |
| 
 | |
| prom_write_name:		.asciz "write"
 | |
| prom_seek_name:			.asciz "seek"
 | |
| prom_read_name:			.asciz "read"
 | |
| prom_close_name:		.asciz "close"
 | |
| 
 | |
| notification_string:		.asciz "Loading kernel"
 | |
| #define NOTIFICATION_STRING_LEN	14
 | |
| 
 | |
| notification_step:		.asciz "."
 | |
| #define NOTIFICATION_STEP_LEN	1
 | |
| 
 | |
| notification_done:		.asciz "\r\n"
 | |
| #define NOTIFICATION_DONE_LEN	2
 | |
| 
 | |
| 	.align	4
 | |
| 
 | |
| 	/* %o2: message string
 | |
| 	 * %o3: message length
 | |
| 	 */
 | |
| console_write:
 | |
| 	GET_ABS(prom_write_name, %o0)
 | |
| 	mov	STDOUT_NODE_REG, %o1
 | |
| 	/* fallthru */
 | |
| 
 | |
| 	/* %o0: OF call name
 | |
| 	 * %o1: input arg 1
 | |
| 	 * %o2: input arg 2
 | |
| 	 * %o3: input arg 3
 | |
| 	 */
 | |
| prom_call_3_1:
 | |
| 	mov	3, %g1
 | |
| 	mov	1, %o5
 | |
| 	/* fallthru */
 | |
| 
 | |
| 	/* %o0: OF call name
 | |
| 	 * %g1: num inputs
 | |
| 	 * %o5: num outputs
 | |
| 	 * %o1-%o4: inputs
 | |
| 	 */
 | |
| prom_call:
 | |
| 	stx	%o0, [%l1 + 0x00]
 | |
| 	stx	%g1, [%l1 + 0x08]
 | |
| 	stx	%o5, [%l1 + 0x10]
 | |
| 	stx	%o1, [%l1 + 0x18]
 | |
| 	stx	%o2, [%l1 + 0x20]
 | |
| 	stx	%o3, [%l1 + 0x28]
 | |
| 	stx	%o4, [%l1 + 0x30]
 | |
| 	jmpl	CIF_REG, %g0
 | |
| 	 mov	%l1, %o0
 | |
| 
 | |
| 
 | |
| after_info_block:
 | |
| 	sethi	%hi(SCRATCH_PAD), %l1	/* OF argument slots */
 | |
| 
 | |
| 	GET_ABS(notification_string, %o2)
 | |
| 	call	console_write
 | |
| 	 mov	NOTIFICATION_STRING_LEN, %o3
 | |
| 
 | |
| 	GET_ABS(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE, %l2)
 | |
| 	set	GRUB_BOOT_MACHINE_IMAGE_ADDRESS, %l3
 | |
| bootloop:
 | |
| 	lduw	[%l2 + 0x08], %o0
 | |
| 	brz	%o0, bootit
 | |
| 	 lduw	[%l2 + 0x00], %o3
 | |
| 	sllx	%o3, 32, %o3
 | |
| 	lduw	[%l2 + 0x04], %o4
 | |
| 	or	%o3, %o4, %o3
 | |
| 	GET_ABS(prom_seek_name, %o0)
 | |
| 	mov	BOOTDEV_REG, %o1
 | |
| 	clr	%o2
 | |
| 	call	prom_call_3_1
 | |
| 	 sllx	%o3, 9, %o3
 | |
| 
 | |
| 	GET_ABS(prom_read_name, %o0)
 | |
| 	mov	BOOTDEV_REG, %o1
 | |
| 	lduw	[%l2 + 0x08], %o3
 | |
| 	sllx	%o3, 9, %o3
 | |
| 	mov	%l3, %o2
 | |
| 	call	prom_call_3_1
 | |
| 	 add	%l3, %o3, %l3
 | |
| 
 | |
| 	GET_ABS(notification_step, %o2)
 | |
| 	call	console_write
 | |
| 	 mov	NOTIFICATION_STEP_LEN, %o3
 | |
| 
 | |
| 	ba	bootloop
 | |
| 	 sub	%l2, GRUB_BOOT_MACHINE_LIST_SIZE, %l2
 | |
| 
 | |
| bootit:
 | |
| 	GET_ABS(prom_close_name, %o0)
 | |
| 	mov	1, %g1
 | |
| 	mov	0, %o5
 | |
| 	call	prom_call
 | |
| 	 mov	BOOTDEV_REG, %o1
 | |
| 
 | |
| 	GET_ABS(notification_done, %o2)
 | |
| 	call	console_write
 | |
| 	 mov	NOTIFICATION_DONE_LEN, %o3
 | |
| 	sethi	%hi(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o2
 | |
| 	jmpl	%o2 + %lo(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o7
 | |
| 	 mov	CIF_REG, %o0
 | |
| 1:	ba,a	1b
 | |
| 
 | |
| lastlist:
 | |
| 	.word	0
 | |
| 	.word	0
 | |
| 
 | |
| 	. = _start + (0x200 - GRUB_BOOT_MACHINE_LIST_SIZE)
 | |
| blocklist_default_start:
 | |
| 	.word	0
 | |
| 	.word	2
 | |
| blocklist_default_len:
 | |
| 	.word	0
 | |
| firstlist:
 |