236 lines
4.2 KiB
ArmAsm
236 lines
4.2 KiB
ArmAsm
#define ASSEMBLY 1
|
|
|
|
.text
|
|
|
|
#include "convert.h"
|
|
|
|
.globl _start
|
|
.proc _start
|
|
_start:
|
|
alloc loc0=ar.pfs,1,2,3,0 /* in, local, out, rotating */
|
|
mov loc1=rp
|
|
mov r14=ip /* Get the address of _start, I'm in the first bundle */
|
|
movl r15=@gprel(_start)
|
|
;;
|
|
sub gp=r14,r15 /* gp = _start - @gprel(_start), current value of gp */
|
|
;;
|
|
mov out0=in0
|
|
mov out1=r28
|
|
add out2=@gprel(params),gp
|
|
br.call.sptk.few rp=convert_params
|
|
|
|
|
|
mov r28=r8
|
|
add r15=@gprel(entry), gp
|
|
;;
|
|
ld8 r16=[r15]
|
|
;;
|
|
mov b1=r16
|
|
mov ar.pfs=loc0
|
|
mov rp=loc1
|
|
;;
|
|
br.cond.sptk.few b1
|
|
|
|
.size _start, . - _start
|
|
.endp _start
|
|
|
|
|
|
#if 0
|
|
|
|
/* Base Address */
|
|
#define UART_BASE 0x00000000f8030000
|
|
#define UART_BAUD 9600
|
|
|
|
/* Data */
|
|
#define UART_RBR 0x00
|
|
#define UART_TBR 0x00
|
|
/* Control */
|
|
#define UART_IER 0x01
|
|
#define UART_IIR 0x02
|
|
#define UART_FCR 0x02
|
|
#define UART_LCR 0x03
|
|
#define UART_MCR 0x04
|
|
|
|
#define UART_DLL 0x00
|
|
#define UART_DLM 0x01
|
|
/* Status */
|
|
#define UART_LSR 0x05
|
|
#define UART_MSR 0x06
|
|
#define UART_SCR 0x07
|
|
|
|
#define UART_PHYS_BASE (0x8000000000000000|UART_BASE)
|
|
#define UART_DIV (115200/UART_BAUD)
|
|
#define UART_DIV_LO (UART_DIV&0xFF)
|
|
#define UART_DIV_HI ((UART_DIV >> 8)&0xFF)
|
|
|
|
#if ((115200%UART_BAUD) != 0)
|
|
#error Bad uart baud rate
|
|
#endif
|
|
|
|
/* NOTE: As these are debugging functions, they do not consume any
|
|
* space on the register stack, and instead rely entirely on
|
|
* scratch registers for the registers they use.
|
|
*/
|
|
uart_init:
|
|
/* set the UART_BASE */
|
|
movl r31=UART_PHYS_BASE
|
|
;;
|
|
|
|
/* disable interrupts */
|
|
add r30=UART_IER,r31
|
|
mov r29=0x00
|
|
;;
|
|
st1 [r30]=r29
|
|
|
|
/* enable fifos */
|
|
add r30=UART_FCR,r31
|
|
mov r29=0x01
|
|
;;
|
|
st1 [r30]=r29
|
|
|
|
/* Set Baud Rate Divisor to UART_BAUD */
|
|
add r30=UART_LCR,r31
|
|
mov r29=0x83
|
|
;;
|
|
st1 [r30]=r29
|
|
|
|
add r30=UART_DLL,r31
|
|
mov r29=UART_DIV_LO
|
|
;;
|
|
st1 [r30]=r29
|
|
|
|
add r30=UART_DLM,r31
|
|
mov r29=UART_DIV_HI
|
|
;;
|
|
st1 [r30]=r29
|
|
|
|
add r30=UART_LCR,r31
|
|
mov r29=0x03
|
|
;;
|
|
st1 [r30]=r29
|
|
|
|
br.ret.sptk.few rp
|
|
|
|
.proc uart_tx_byte
|
|
.globl uart_tx_byte
|
|
uart_tx_byte:
|
|
/* set the UART_PHYS_BASE */
|
|
movl r31=UART_PHYS_BASE
|
|
;;
|
|
__uart_tx_byte:
|
|
/* Wait until the UART can hold another byte */
|
|
add r30=UART_LSR,r31
|
|
;;
|
|
9: ld1.acq.nta r29=[r30]
|
|
;;
|
|
and r29=0x20,r29
|
|
;;
|
|
cmp.eq p63,p0=0,r29
|
|
(p63) br.cond.sptk.few 9b
|
|
|
|
/* Transmit the byte */
|
|
add r30=UART_TBR,r31
|
|
;;
|
|
st1.rel.nta [r30]=r32
|
|
;;
|
|
|
|
/* Wait until the UART is empty to be certain the byte is flushed */
|
|
add r30=UART_LSR,r31
|
|
;;
|
|
9: ld1.acq.nta r29=[r30]
|
|
;;
|
|
and r29=0x40,r29
|
|
;;
|
|
cmp.eq p63,p0=0,r29
|
|
(p63) br.cond.sptk.few 9b
|
|
;;
|
|
br.ret.sptk.few rp
|
|
.endp uart_tx_byte
|
|
|
|
__uart_tx_hex_char:
|
|
cmp.ltu p62,p63=9,r32
|
|
;;
|
|
(p63) add r32=48,r32 /* digits*/
|
|
(p62) add r32=55,r32 /* letters */
|
|
br.cond.sptk.few __uart_tx_byte
|
|
|
|
uart_tx_hex64:
|
|
/* set the UART_bASE */
|
|
movl r31=UART_PHYS_BASE
|
|
/* skip r28 */
|
|
mov r27=rp
|
|
mov r26=ar.pfs
|
|
mov r25=r32
|
|
;;
|
|
extr.u r32=r25,60,4
|
|
br.call.sptk.few rp=__uart_tx_hex_char
|
|
;;
|
|
extr.u r32=r25,56,4
|
|
br.call.sptk.few rp=__uart_tx_hex_char
|
|
;;
|
|
extr.u r32=r25,52,4
|
|
br.call.sptk.few rp=__uart_tx_hex_char
|
|
;;
|
|
extr.u r32=r25,48,4
|
|
br.call.sptk.few rp=__uart_tx_hex_char
|
|
;;
|
|
extr.u r32=r25,44,4
|
|
br.call.sptk.few rp=__uart_tx_hex_char
|
|
;;
|
|
extr.u r32=r25,40,4
|
|
br.call.sptk.few rp=__uart_tx_hex_char
|
|
;;
|
|
extr.u r32=r25,36,4
|
|
br.call.sptk.few rp=__uart_tx_hex_char
|
|
;;
|
|
extr.u r32=r25,32,4
|
|
br.call.sptk.few rp=__uart_tx_hex_char
|
|
;;
|
|
extr.u r32=r25,28,4
|
|
br.call.sptk.few rp=__uart_tx_hex_char
|
|
;;
|
|
extr.u r32=r25,24,4
|
|
br.call.sptk.few rp=__uart_tx_hex_char
|
|
;;
|
|
extr.u r32=r25,20,4
|
|
br.call.sptk.few rp=__uart_tx_hex_char
|
|
;;
|
|
extr.u r32=r25,16,4
|
|
br.call.sptk.few rp=__uart_tx_hex_char
|
|
;;
|
|
extr.u r32=r25,12,4
|
|
br.call.sptk.few rp=__uart_tx_hex_char
|
|
;;
|
|
extr.u r32=r25,8,4
|
|
br.call.sptk.few rp=__uart_tx_hex_char
|
|
;;
|
|
extr.u r32=r25,4,4
|
|
br.call.sptk.few rp=__uart_tx_hex_char
|
|
;;
|
|
extr.u r32=r25,0,4
|
|
br.call.sptk.few rp=__uart_tx_hex_char
|
|
;;
|
|
mov ar.pfs = r26
|
|
mov rp = r27
|
|
;;
|
|
br.ret.sptk.few rp
|
|
#endif
|
|
|
|
.section ".trailer", "a"
|
|
/* Constants set at build time, these are at the very end of my image */
|
|
.balign 16
|
|
.global params
|
|
params:
|
|
convert_magic:
|
|
.quad CONVERT_MAGIC
|
|
entry:
|
|
.quad 0
|
|
initrd_start:
|
|
.quad 0
|
|
initrd_size:
|
|
.quad 0
|
|
cmdline:
|
|
.asciz "BOOT_IMAGE=head.S console=ttyS0 ip=dhcp root=/dev/nfs"
|
|
.org cmdline + 1024, 0
|
|
cmdline_end:
|