/* * Copyright (c) 2003-2004 The Regents of The University of Michigan * Copyright (c) 1993 The Hewlett-Packard Development Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer; * redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution; * neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Debug Monitor Entry code */ #include "fromHudsonOsf.h" .extern myAlphaAccess .text /* return address and padding to octaword align */ #define STARTFRM 16 .globl _start .ent _start, 0 _start: _entry: br t0, 2f # get the current PC 2: ldgp gp, 0(t0) # init gp /* Processor 0 start stack frame is begining of physical memory (0) Other processors spin here waiting to get their stacks from Processor 0, then they can progress as normal. */ call_pal PAL_WHAMI_ENTRY beq v0, cpuz ldq t3, m5AlphaAccess addq t3,0x70,t3 # *** If offset in console alpha access struct changes # This must be changed as well! bis zero,8,t4 mulq t4,v0,t4 addq t3,t4,t3 ldah a0, 3(zero) # load arg0 with 65536*3 cpuwait: .long 0x6000002 # jsr quiesceNs ldq t4, 0(t3) beq t4, cpuwait bis t4,t4,sp cpuz: bis sp,sp,s0 /* save sp */ slave: lda v0,(8*1024)(sp) /* end of page */ subq zero, 1, t0 sll t0, 42, t0 bis t0, v0, sp lda sp, -STARTFRM(sp) # Create a stack frame stq ra, 0(sp) # Place return address on the stack .mask 0x84000000, -8 .frame sp, STARTFRM, ra /* * Enable the Floating Point Unit */ lda a0, 1(zero) call_pal PAL_WRFEN_ENTRY /* * Every good C program has a main() */ /* If stack pointer was 0, then this is CPU0*/ beq s0,master call_pal PAL_WHAMI_ENTRY bis v0,v0,a0 jsr ra, SlaveLoop master: jsr ra, main /* * The Debug Monitor should never return. * However, just incase... */ ldgp gp, 0(ra) bsr zero, _exit .end _start .globl _exit .ent _exit, 0 _exit: ldq ra, 0(sp) # restore return address lda sp, STARTFRM(sp) # prune back the stack ret zero, (ra) # Back from whence we came .end _exit .globl cServe .ent cServe 2 cServe: .option O1 .frame sp, 0, ra call_pal PAL_CSERVE_ENTRY ret zero, (ra) .end cServe .globl wrfen .ent wrfen 2 wrfen: .option O1 .frame sp, 0, ra call_pal PAL_WRFEN_ENTRY ret zero, (ra) .end wrfen .globl consoleCallback .ent consoleCallback 2 consoleCallback: br t0, 2f # get the current PC 2: ldgp gp, 0(t0) # init gp lda sp,-64(sp) stq ra,0(sp) jsr CallBackDispatcher ldq ra,0(sp) lda sp,64(sp) ret zero,(ra) .end consoleCallback .globl consoleFixup .ent consoleFixup 2 consoleFixup: br t0, 2f # get the current PC 2: ldgp gp, 0(t0) # init gp lda sp,-64(sp) stq ra,0(sp) jsr CallBackFixup ldq ra,0(sp) lda sp,64(sp) ret zero,(ra) .end consoleFixup .globl SpinLock .ent SpinLock 2 SpinLock: 1: ldq_l a1,0(a0) # interlock complete lock state subl ra,3,v0 # get calling addr[31:0] + 1 blbs a1,2f # branch if lock is busy stq_c v0,0(a0) # attempt to acquire lock beq v0,2f # branch if lost atomicity mb # ensure memory coherence ret zero,(ra) # return to caller (v0 is 1) 2: br zero,1b .end SpinLock .globl loadContext .ent loadContext 2 loadContext: .option O1 .frame sp, 0, ra call_pal PAL_SWPCTX_ENTRY ret zero, (ra) .end loadContext .globl SlaveSpin # Very carefully spin wait .ent SlaveSpin 2 # and swap context without SlaveSpin: # using any stack space .option O1 .frame sp, 0, ra mov a0, t0 # cpu number mov a1, t1 # cpu rpb pointer (virtual) mov a2, t2 # what to spin on ldah a0, 3(zero) # load arg0 with 65536 test: .long 0x6000002 # jsr quiesceNs # wait 65us*3 ldl t3, 0(t2) beq t3, test zapnot t1,0x1f,a0 # make rpb physical call_pal PAL_SWPCTX_ENTRY # switch to pcb mov t0, a0 # setup args for SlaveCmd mov t1, a1 jsr SlaveCmd # call SlaveCmd ret zero, (ra) # Should never be reached .end SlaveSpin