/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code was written by Alessandro Forin and Neil Pittman
* at Microsoft Research and contributed to The NetBSD Foundation
* by Microsoft Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/* Trivial support for printing stuff on the serial line from C pgms.
*/
#include <mips/asm.h>
#include <mips/cpuregs.h>
#define __ASSEMBLER__ 1
#include <machine/emipsreg.h>
/* PROM_MODE means the user plans to keep this code around while running an OS.
* So we act kind of like PROM code (BIOS?), but we live in RAM.
* So we need to safeguard ourselves against corruptions, some unavoidable.
* Like the overriding of the exception vectors, right where our "start" code is.
*/
/* Does not handle the exception, really.
* But to test interrupts should be enough
*/
.org 0x00000080
NESTED_NOPROFILE(ExceptionHandler,SIZEOF_CXTINFO,$31)
la k1, UserInterruptHandler
lw k1,0(k1)
bne k1,zero,Dispatch
mfc0 k0, MIPS_COP_0_EXC_PC
j k0
nop /* do not! pop status */
#ifdef SECONDARY_BOOTBLOCK
/*
* If this is the program that goes into FLASH we must copy ourselves down to RAM.
* FLASH default on the MLx is at 0xf0000000, DRAM at 0.
*/
addi a0,ra,-8 /* Compensate for the first two instructions */
/* Get the address(relative) of TextStart
*/
bgezal zero, _C_LABEL(MipsStart2) /* Always jumps */
nop
/* All of the static data, since we are at it.
*/
TextStart: /* + 0 */
/* Text start at final link address */
.int start
DataEnd: /* + 4 */
/* Data end == bss start */
.int _edata
/* If a0 != t2 then we are running in Flash but should run in RAM
* In that case copy .text. Otherwise skip to .bss.
*/
beq a0,t2,ZroLoop-4
lw t3, 4(ra) /* _C_LABEL(DataEnd) */
CpyLoop:
/* loop copying 2 words at a time */
lw t4,0(a0)
lw t5,4(a0)
addiu a0,a0,8
sw t4,0(t2)
addiu t2,t2,8
sltu t1,t2,t3
bne t1,zero,CpyLoop
sw t5,-4(t2)
/* zero the bss
*/
lw t4, 8(ra) /* _C_LABEL(BssEnd) */
ZroLoop:
sltu t1,t3,t4
sw zero,0(t3)
bne t1,zero,ZroLoop
addiu t3,t3,4
/* Jump to RAM copy (below)
*/
lw t1, 12(ra) /* _C_LABEL(RelocToRAM) */
jr t1
nop
/*
* Execute from here after copying out of FLASH into RAM
*/
InRAM:
#endif /* SECONDARY_BOOTBLOCK */
/* Get a stack
*/
#ifdef __GP_SUPPORT__
la gp, _C_LABEL (_gp)
#endif
la sp,_end
addiu sp,sp,(8*1024) /* BUGBUG arbitrary */
/* Jump to main
*/
jal main
add a0,sp,zero
/* Load failed, reset the processor and jump back to the origins.
*/
EXPORT(_rtt) /* ahem */
li t0,0x1260ff80 /* NB: On new builds this is a SYS-RESET as well */
mtc0 t0,MIPS_COP_0_STATUS
lui t0,(BRAM_DEFAULT_ADDRESS>>16) /* nb: knows about 16bit chop */
jr t0
nop
or s1,a0,zero
/* Spit all nibbles
*/
li s0,8
PutWordLoop:
srl a0,s1,32-4
li t0,10
sltu t1,a0,t0
bnez t1,$Digit
li a1,'0'
subu a0,a0,t0
li a1,'a'
$Digit:
sll s1,s1,4
jal PutChar
add a0,a0,a1
subu s0,s0,1
bne v0,zero,PutWordDone /* printed ok? */
li v0,-1
/* done yet? */
bne s0,zero,PutWordLoop
nop
/* done
*/
li v0,0
PutWordDone:
lw ra,0(sp)
lw s1,4(sp)
lw s0,8(sp)
jr ra
addiu sp,sp,12
END(PutWord)
/* int Puts(char *String);
* Returns: 0 if ok, -1 otherwise
*/
NESTED(Puts,8,$31)
subu sp,sp,8
sw s0,4(sp)
sw ra,0(sp)
or s0,a0,zero
/* Spit all chars until zero
*/
PutsLoop:
lbu a0,0(s0)
addiu s0,s0,1
beq a0,zero,PutsDoneOk
nop
jal PutChar
nop
beq v0,zero,PutsLoop
nop
/* Timed out
*/
b PutsDone
li v0,-1
/* done
*/
PutsDoneOk:
li v0,0
PutsDone:
lw ra,0(sp)
lw s0,4(sp)
jr ra
addiu sp,sp,8
END(Puts)
/* int GetChar(void);
* Returns: a non-negative value if ok, -1 otherwise
*/
LEAF(GetChar)
lui t0,(USART_DEFAULT_ADDRESS>>16) /* nb: knows about 16bit chop */
lui t1,1000 /* n*65k spins max */
RxNotReady:
lw t4,USARTST(t0) /* ChannelStatus */
andi t4,t4,USI_RXRDY
bgtz t4,$GotByte
subu t1,t1,1
/* still ok to spin? */
bgtz t1,RxNotReady
nop
/* Timed out
*/
jr ra
li v0,-1
/* Gottabyte
*/
$GotByte:
lw v0,USARTRX(t0) /* RxData */
jr ra
andi v0,0xff
END(GetChar)
/* int PutChar(UINT8 v);
* Returns: 0 if ok, -1 otherwise
*/
LEAF(PutChar)
lui t0,(USART_DEFAULT_ADDRESS>>16) /* nb: knows about 16bit chop */
lui t1,1000 /* n*65k spins max */
li v0,0
TxNotReady:
lw t4,USARTST(t0) /* ChannelStatus */
andi t4,t4,USI_TXRDY
bgtz t4,TxReady
subu t1,t1,1
/* still ok to spin? */
bgtz t1,TxNotReady
nop
/* Timed out
*/
jr ra
li v0,-1
/* Send it
*/
TxReady:
jr ra
sw a0,USARTTX(t0)
END(PutChar)
/* Second arg is a function to call with the first arg:
* void switch_stack_and_call(void *arg, void (*function)(void *));
*/
LEAF(switch_stack_and_call)
/* Get a stack and jump. It would be a very bad idea to return but..
*/
lui sp,%hi(_end)
addiu sp,%lo(_end)
jr a1
addiu sp,sp,(2*1024) /* BUGBUG arbitrary */