/* First stage loader bootstrap for both v0, v2 and SUNW,Ultra's IEEE 1275 PROM Copyright (C) 1996,1997,1998 Jakub Jelinek This program 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 2 of the License, or (at your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define BLOCK_START 0x3dc #define promvec %l5 #define buffer %l0 #define fd %l6 #define stdouth %l7 #define promvers %l7 #define dest %l4 .text .align 4 .global _start, letter_here, digit_here _start: bootmain: tst %o4 be sparc_v8 sethi %hi(0x4000), buffer or buffer, (BLOCK_START + 3 * 512), %i5 sethi %hi(0x10000), dest mov %o4, promvec add buffer, %lo(chosen), %o1 call prom11 add buffer, %lo(finddevice), %o0 ldx [dest + 32], fd call getprop add buffer, %lo(stdout), %o0 lduw [dest + 256], stdouth call putchar mov 'S', %o0 call getprop add buffer, %lo(bootpath), %o0 add dest, 256, %o0 mov ':', %o4 2: ldub [%o0], %o3 brz,pn %o3, 3f cmp %o3, %o4 bne,a,pt %icc, 2b inc %o0 3: stb %o4, [%o0] letter_here: mov 0xDD, %o4 stb %o4, [%o0 + 1] stb %g0, [%o0 + 2] add dest, 256, %o1 call prom11 add buffer, %lo(open), %o0 ldx [dest + 32], fd or buffer, BLOCK_START, %l1 mov %l1, %l2 5: lduw [%l2], %l3 add %l2, 4, %l2 brz,pn %l3, 7f sll %l3, 9, %o3 srl %l3, 23, %o2 call rwprom31 add buffer, %lo(seek), %o0 ldx [dest + 48], %o0 brlz,pn %o0, 9f mov 512, %o3 mov %l1, %o2 call rwprom31 add buffer, %lo(read), %o0 ldx [dest + 48], %o0 cmp %o0, 512 bne,pn %icc, 9f cmp %l1, %i5 bne,pt %xcc, 5b add %l1, 512, %l1 call putchar mov 'I', %o0 ba,pt %xcc, 5b add dest, 1024, %l1 7: mov fd, %o1 call prom11 add buffer, %lo(close), %o0 ldub [dest + 1024 + 0x08], %o0 cmp %o0, 'L' bne,a,pn %icc, 10f add buffer, %lo(exit), %o0 call putchar flush dest + 1024 jmpl dest + 1024, %g0 mov promvec, %o4 putchar: stb %o0, [buffer] mov stdouth, %o1 mov buffer, %o2 mov 1, %o3 ba,pt %xcc, prom31 add buffer, %lo(write), %o0 9: add buffer, %lo(exit), %o0 10: call prom11 getprop: stx %o0, [dest + 32] add dest, 256, %o0 stx %o0, [dest + 40] mov 1024, %o0 stx %o0, [dest + 48] mov fd, %o1 add buffer, %lo(getprops), %o0 mov 4, %o2 stx %o2, [dest + 8] 2: ba,pt %xcc, 1f prom11: mov 1, %o2 stx %o2, [dest + 8] 1: stx %o0, [dest] stx %o2, [dest + 16] stx %o1, [dest + 24] jmpl promvec + %g0, %g0 mov dest, %o0 rwprom31: mov fd, %o1 prom31: mov 3, %o4 stx %o4, [dest + 8] stx %o2, [dest + 32] ba,pt %xcc, 2b stx %o3, [dest + 40] finddevice: .asciz "finddevice" getprops: .asciz "getprop" bootpath: .asciz "bootpath" stdout: .asciz "stdout" open: .asciz "open" close: .asciz "close" seek: .asciz "seek" read: .asciz "read" write: .asciz "write" chosen: .asciz "/chosen" exit: .asciz "exit" .align 512 sparc_v8: mov %o0, promvec ld [promvec+4], promvers sethi %hi(0x4000), buffer sethi %hi(0x10000), dest call putchar_v8 mov 'S', %o0 tst promvers bne,a 1f ld [promvec+136], %o0 ! pv_v2bootargs.bootpath ld [promvec+128], %o0 ld [%o0], %o3 ! o3 = *pv_v0bootargs lduh [%o3+132], %o1 ! 'sd', 'fd' or whatever sll %o1, 8, %o1 or %o1, '(', %o1 sll %o1, 8, %o1 ld [%o3+136], %o0 ! controler id (hope it is less than 10) add %o0, '0', %o0 or %o1, %o0, %o2 mov ',', %o1 sll %o1, 8, %o1 ld [%o3+140], %o4 ! unit id (again, hope nobody uses wide on v0 prom) add %o4, '0', %o4 or %o4, %o1, %o4 sll %o4, 16, %o4 or %o4, %o1, %o4 digit_here: or %o4, 0xDD, %o3 std %o2, [buffer + 0x400] ! put the 'sd(i,j,k' somewhere... mov ')', %o2 sll %o2, 8, %o2 sth %o2, [buffer + 0x408] ! put there the rest ')\0' as well... b 4f ld [promvec+36], %o1 ! pv_v0devops.v0_devopen 1: ld [promvec+172], %o1 ld [%o0], %o0 add buffer, 0x400, %o2 mov ':', %o4 2: ldub [%o0], %o3 tst %o3 be 3f cmp %o3, %o4 be 3f stb %o3, [%o2] add %o2, 1, %o2 b 2b add %o0, 1, %o0 3: stb %o4, [%o2] ldub [buffer + (letter_here - _start + 3)], %o4 stb %o4, [%o2 + 1] stb %g0, [%o2 + 2] 4: call %o1 add buffer, 0x400, %o0 mov %o0, fd or buffer, BLOCK_START, %l1 mov %l1, %l2 5: ld [%l2], %l3 add %l2, 4, %l2 tst %l3 be 7f tst promvers bne 6f ld [promvec+44], %o4 ! pv_v0devops.v0_rdblkdev mov 1, %o1 mov %l3, %o2 mov %l1, %o3 call %o4 mov fd, %o0 cmp %o0, 1 b,a 0f 6: ld [promvec+188], %o4 ! pv_v2devops.v2_dev_seek mov %g0, %o1 sll %l3, 9, %o2 call %o4 mov fd, %o0 cmp %o0, -1 be 9f ld [promvec+180], %o4 ! pv_v2devops.v2_dev_read mov 512, %o2 mov %l1, %o1 call %o4 mov fd, %o0 cmp %o0, 512 0: bne 9f cmp %l1, %i5 bne 5b add %l1, 512, %l1 call putchar_v8 mov 'I', %o0 b 5b mov dest, %l1 7: ldub [dest + 0x08], %o0 cmp %o0, 'L' bne 9f nop call putchar_v8 ld [promvec+176], %l1 ! pv_v2devops.v2_dev_close tst promvers be,a 8f ld [promvec+40], %l1 ! pv_v0devops.v0_dev_close 8: call %l1 mov fd, %o0 clr %o4 ! we are not an Ultra jmpl dest + %g0, %g0 mov promvec, %o0 9: ld [promvec+116], %g1 jmpl %g1 + %g0, %g0 putchar_v8: tst promvers bne 1f ld [promvec+92], %o1 ! pv_nbputchar jmpl %o1 + %g0, %g0 or buffer, (BLOCK_START + 3 * 512), %i5 1: stb %o0, [buffer] ld [promvec+148], %o0 ! pv_v2bootargs.fd_stdout ld [promvec+184], %o3 ! pv_v2devops.v2_dev_write mov buffer, %o1 ld [%o0], %o0 mov 1, %o2 jmpl %o3 + %g0, %g0 or buffer, (BLOCK_START + 3 * 512), %i5