diff --git a/sys/arch/sandpoint/stand/altboot/Makefile b/sys/arch/sandpoint/stand/altboot/Makefile index f1969df2e9d6..9ff9bc09b0aa 100644 --- a/sys/arch/sandpoint/stand/altboot/Makefile +++ b/sys/arch/sandpoint/stand/altboot/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.11 2011/05/25 19:26:21 phx Exp $ +# $NetBSD: Makefile,v 1.12 2011/10/30 20:42:09 phx Exp $ S= ${.CURDIR}/../../../.. @@ -8,7 +8,7 @@ NOMAN= # defined SRCS= entry.S main.c brdsetup.c pci.c devopen.c dev_net.c memfs.c SRCS+= nif.c fxp.c tlp.c rge.c skg.c stg.c SRCS+= dsk.c pciide.c siisata.c -SRCS+= vers.c +SRCS+= exception.c vers.c CLEANFILES+= vers.c ${PROG} ${PROG}.bin ${PROG}.img CFLAGS+= -Wall -Wno-main -ffreestanding -msoft-float -mmultiple CFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wpointer-arith diff --git a/sys/arch/sandpoint/stand/altboot/entry.S b/sys/arch/sandpoint/stand/altboot/entry.S index f84d5a4b6539..6223db171971 100644 --- a/sys/arch/sandpoint/stand/altboot/entry.S +++ b/sys/arch/sandpoint/stand/altboot/entry.S @@ -1,4 +1,4 @@ -/* $NetBSD: entry.S,v 1.3 2011/03/13 15:23:43 phx Exp $ */ +/* $NetBSD: entry.S,v 1.4 2011/10/30 20:42:09 phx Exp $ */ #include #include @@ -20,13 +20,20 @@ _start: mr 28,6 mr 29,7 + /* Disable interrupts and everything except the MMU. */ + mfmsr 3 + andi. 3,3,PSL_DR|PSL_IR + mtmsr 3 + isync + /* * U-Boot/PPCBoot forgets to flush the cache when using the "bootm" * command, so we have to do that now. */ lis 11,_start@ha addi 11,11,_start@l - andi. 11,11,~31@l + li 10,-32 + and 11,11,10 lis 12,(_edata+31)@ha addi 12,12,(_edata+31)@l bl syncicache @@ -41,8 +48,8 @@ _start: mfmsr 0 andi. 0,0,PSL_DR beq 2f - lis 5, 0xfec00000@ha /* CONFIG_ADDR of PCI */ - lis 6, 0xfee00000@ha /* CONFIG_DATA of PCI */ + lis 5,0xfec00000@ha /* CONFIG_ADDR of PCI */ + lis 6,0xfee00000@ha /* CONFIG_DATA of PCI */ mfspr 3,SPR_DBAT0U mfspr 4,SPR_DBAT0L bl dbat_sanity_check @@ -104,13 +111,18 @@ _start: b 5b 6: - /* prepare stack at +1MB from _start. */ - lis 1,_start@h - ori 1,1,_start@l - addis 1,1,0x10 - addi 1,1,-4 + /* prepare stack at +1MB from _start, 16-byte aligned */ + lis 1,_start@ha + addi 1,1,_start@l + addis 1,1,0x100000@ha + li 10,-16 + and 1,1,10 + stw 0,0(1) bl brdsetup +#ifdef DEBUG + bl init_vectors +#endif mr 3,30 mr 4,31 mr 5,28 @@ -152,7 +164,7 @@ dbat_sanity_check: */ .globl run run: - mtctr 7 /* hat trick jump to entry point */ + mtctr 7 /* hat trick jump to entry point */ bctr /* @@ -198,38 +210,115 @@ newaltboot_end: /* * reverse endian access to mimic outw/outl/inw/inl */ - .globl out16rb - .globl iohtole16 + .globl out16rb + .globl iohtole16 out16rb: iohtole16: sthbrx 4,0,3 eieio blr - .globl out32rb - .globl iohtole32 + .globl out32rb + .globl iohtole32 out32rb: iohtole32: stwbrx 4,0,3 eieio blr - .global in16rb - .global iole16toh + .globl in16rb + .globl iole16toh in16rb: iole16toh: lhbrx 3,0,3 eieio blr - .global in32rb - .global iole32toh + .globl in32rb + .globl iole32toh in32rb: iole32toh: lwbrx 3,0,3 eieio blr +#ifdef DEBUG + /* + * Call an exception handler, which prints out all information + * about the type of exception, cpu registers, stack frame + * backtrace, etc. + * Use a new stack at 0x2000 and make room for 32 GPRs, and 15 + * special registers. The layout will be: + * 0x00: link area + * 0x10: R0 + * ... + * 0x8c: R31 + * 0x90: CR, XER, LR, CTR + * 0xa0: SRR0, SRR1, DAR, DSISR + * 0xb0: DMISS, DCMP, HASH1, HASH2 + * 0xc0: IMISS, ICMP, RPA + * + */ + .globl trap +trap: + mtsprg1 1 + mfmsr 1 + andis. 1,1,PSL_TGPR@h + beq 1f + andi. 1,1,0xffff /* make sure TGPR is disabled */ + mtmsr 1 + isync + mtsprg1 1 /* and save the real r1 again */ +1: li 1,0x2000-16-(32*4+15*4) + stmw 2,24(1) /* save r2..r31 */ + stw 0,16(1) /* save r0 */ + mfsprg1 3 + stw 3,20(1) /* and finally r1 */ + mfcr 3 + stw 3,0x90(1) + mfxer 3 + stw 3,0x94(1) + mflr 3 + stw 3,0x98(1) + mfctr 3 + stw 3,0x9c(1) + mfsrr0 3 + stw 3,0xa0(1) + mfsrr1 3 + stw 3,0xa4(1) + mfdar 3 + stw 3,0xa8(1) + mfdsisr 3 + stw 3,0xac(1) + mfspr 3,976 + stw 3,0xb0(1) + mfspr 3,977 + stw 3,0xb4(1) + mfspr 3,978 + stw 3,0xb8(1) + mfspr 3,979 + stw 3,0xbc(1) + mfspr 3,980 + stw 3,0xc0(1) + mfspr 3,981 + stw 3,0xc4(1) + mfspr 3,982 + stw 3,0xc8(1) + bl call_handler +call_handler: + lis 11,exception_handler@ha + addi 11,11,exception_handler@l + mtsrr0 11 + li 0,PSL_DR|PSL_IR + mtsrr1 0 + mflr 3 + subi 3,3,call_handler-trap + addi 4,1,16 + rfi + .globl trap_end +trap_end: +#endif + .data #define xBATL(pa, wimg, pp) \ ((pa) | (wimg) | (pp)) diff --git a/sys/arch/sandpoint/stand/altboot/exception.c b/sys/arch/sandpoint/stand/altboot/exception.c new file mode 100644 index 000000000000..a1dd1239d6ce --- /dev/null +++ b/sys/arch/sandpoint/stand/altboot/exception.c @@ -0,0 +1,116 @@ +/* $NetBSD: exception.c,v 1.1 2011/10/30 20:42:09 phx Exp $ */ + +/*- + * Copyright (c) 2011 Frank Wille. + * All rights reserved. + * + * Written by Frank Wille for The NetBSD Project. + * + * 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. + */ + +#include + +#include +#include +#include + +#include "globals.h" + +#ifdef DEBUG +struct cpu_state { + uint32_t gpr[32]; + uint32_t cr, xer, lr, ctr; + uint32_t srr0, srr1, dar, dsisr; + uint32_t dmiss, dcmp, hash1, hash2; + uint32_t imiss, icmp, rpa; +}; + +void init_vectors(void); /* called from early startup */ +void exception_handler(unsigned, struct cpu_state *); + + +void +init_vectors(void) +{ + extern uint8_t trap[], trap_end[]; + uint8_t *exc; + uint32_t *ip; + + /* install exception handlers */ + for (exc = (uint8_t *)0x100; exc <= (uint8_t *)0x1400; exc += 0x100) + memcpy(exc, trap, trap_end - trap); + + /* handle NULL-ptr calls from 0x0 to 0xfc */ + for (ip = 0; ip < (uint32_t *)0x100; ip++) + *ip = 0x48000002 | (uint32_t)trap; + + __syncicache(0, 0x1400); +} + +void +exception_handler(unsigned vector, struct cpu_state *st) +{ + static bool in_exception = false; + uint32_t *fp; + int i; + + if (vector > 0x1400) + printf("\nCALL TO NULL POINTER FROM %08x\n", st->lr - 4); + else + printf("\nEXCEPTION VECTOR %04x\n", vector); + if (in_exception) { + printf("caused in exception handler! Restarting...\n"); + _rtt(); + } + in_exception = true; + + /* register dump */ + printf("\n SRR0=%08x SRR1=%08x DAR=%08x DSISR=%08x\n" + " CR=%08x XER=%08x LR=%08x CTR=%08x\n" + "DMISS=%08x DCMP=%08x HASH1=%08x HASH2=%08x\n" + "IMISS=%08x ICMP=%08x RPA=%08x\n\n", + st->srr0, st->srr1, st->dar, st->dsisr, + st->cr, st->xer, st->lr, st->ctr, + st->dmiss,st->dcmp,st->hash1,st->hash2, + st->imiss,st->icmp,st->rpa); + for (i = 0; i < 32; i++) { + if ((i & 7) == 0) + printf("GPR%02d:", i); + printf("%c%08x", (i & 7) == 4 ? ':' : ' ', st->gpr[i]); + if ((i & 7) == 7) + printf("\n"); + } + + /* V.4-ABI stack frame back trace */ + printf("\nBacktrace:\n"); + i = 0; + fp = (uint32_t *)st->gpr[1]; + while ((fp = *(uint32_t **)fp) != NULL && i++ < 10) + printf("%p: called from %08x\n", fp, *(fp + 1) - 4); + + printf("\nHit any key to reboot.\n"); + (void)getchar(); + _rtt(); +} + +#endif /* DEBUG */