| /* |
| * 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 |
| |
| |