; This is designed to be serial-line downloaded to cdcode. ; ; Our memory map: ; ; [8c000000,8c010000) Stack (r15 set by cdcode) ; [8c010000,8c01????) cdcode ; [8c020000,8c02????) Us ; This code is heavy on the magic numbers. All the other BBA-driving ; code I've found is at least as bad. :-( .include "regs.s" .include "maple-bits.s" ; Layout within the gapspci bridge bounce buffer area. . = 0x01840000 rxbuff_bounce: .space 16384 + 16 txbuff_bounce: .space 2000 . = 0x8c020000 .sz any .pr any SETS.L #main,r0 jmp @r0 nop SETCONST ; Our "data segment". .align 4 rxcfg: .space 4 MAC: .space 6 ; The only things startup.s sets up that cdcode hasn't already done for ; us are (1) fpscr and (2) clearing bss. We don't have bss because we ; aren't linked by a conventional linker, and we don't use floating ; point so we don't care about fpscr. We do, however, need to set up ; the VBR. We also save r10-r14 against returning to cdcode. .align 2 main: mov.l r14,@-r15 mov.l r13,@-r15 mov.l r12,@-r15 mov.l r11,@-r15 mov.l r10,@-r15 ldc r14,gbr stc sr,r1 SETS.L #~[SR_FD|SR_RB|SR_BL],r2 and r2,r1 ldc r1,sr ; Note that r0-r7 may have just changed if we switched banks. mov #0,r1 lds r1,fpscr .sz 0 .pr 0 SETS.L #intvec,r0 ldc r0,vbr ; Real code begins here. ; Make sure all interrupts are blocked. stc sr,r0 or #0xf0,r0 ldc r0,sr ; Set up the PCI bridge. bsr init_gapspci nop bt fail ; Initialize the Ethernet itself. bsr init_ether nop bt fail bsr await_link nop bsr init_ether nop bt fail bsr await_link nop bsr send_packet nop bsr recv_packet nop bra done nop failmsg: .asciz "Setup failed"(13,10) .align 2 fail: SETS.L #failmsg,r1 bsr putstr nop done: bsr putchar mov #13,r1 bsr putchar mov #10,r1 mov.l @r15+,r10 mov.l @r15+,r11 lds r11,pr mov.l @r15+,r12 mov.l @r15+,r13 mov.l @r15+,r14 rts nop ; This exists because there's a substantial delay from us turning the ; chip on to the switch's link light coming on. (I'm assuming it ; can't communicate until then.) Eventually we'll want to wait until ; the chip says it has link, but for now we just loop two hundred ; million times. nap_a_bit: sts pr,r2 bsr putchar mov #'<,r1 SETS.L #200000000,r0 1: dt r0 bf 1b lds r2,pr bra putchar mov #'>,r1 g2_lock: ; This is conceptually what NetBSD and libronin call G2_LOCK(). ; It returns a cookie in r0 which needs to be passed to ; g2_unlock. ; ; This saves and restores all other registers it uses. ; mov.l r1,@-r15 stc sr,r0 mov.l r0,@-r15 .if @IS_UB[SR_IMASK_MASK<