#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: