1*0da5724dSToomas Soome /* 2*0da5724dSToomas Soome * Copyright 2026 Edgecast Cloud LLC. 3*0da5724dSToomas Soome * Copyright (c) 2016 The FreeBSD Foundation 4*0da5724dSToomas Soome * All rights reserved. 5*0da5724dSToomas Soome * Copyright (c) 1996 6*0da5724dSToomas Soome * Matthias Drochner. All rights reserved. 7*0da5724dSToomas Soome * 8*0da5724dSToomas Soome * This software was developed by Konstantin Belousov under sponsorship 9*0da5724dSToomas Soome * from the FreeBSD Foundation. 10*0da5724dSToomas Soome * 11*0da5724dSToomas Soome * Redistribution and use in source and binary forms, with or without 12*0da5724dSToomas Soome * modification, are permitted provided that the following conditions 13*0da5724dSToomas Soome * are met: 14*0da5724dSToomas Soome * 1. Redistributions of source code must retain the above copyright 15*0da5724dSToomas Soome * notice, this list of conditions and the following disclaimer. 16*0da5724dSToomas Soome * 2. Redistributions in binary form must reproduce the above copyright 17*0da5724dSToomas Soome * notice, this list of conditions and the following disclaimer in the 18*0da5724dSToomas Soome * documentation and/or other materials provided with the distribution. 19*0da5724dSToomas Soome * 20*0da5724dSToomas Soome * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21*0da5724dSToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22*0da5724dSToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23*0da5724dSToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24*0da5724dSToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25*0da5724dSToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26*0da5724dSToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27*0da5724dSToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28*0da5724dSToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29*0da5724dSToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30*0da5724dSToomas Soome * SUCH DAMAGE. 31*0da5724dSToomas Soome */ 32*0da5724dSToomas Soome 33*0da5724dSToomas Soome #include <sys/cdefs.h> 34*0da5724dSToomas Soome 35*0da5724dSToomas Soome #include <stand.h> 36*0da5724dSToomas Soome #include <btxv86.h> 37*0da5724dSToomas Soome #include <common/bootargs.h> 38*0da5724dSToomas Soome 39*0da5724dSToomas Soome /* 40*0da5724dSToomas Soome * loader is laid out as: 41*0da5724dSToomas Soome * physical address 0xa000 42*0da5724dSToomas Soome * text data bss _end stack space <free mem from 0x413> 43*0da5724dSToomas Soome */ 44*0da5724dSToomas Soome extern char _end[]; 45*0da5724dSToomas Soome 46*0da5724dSToomas Soome struct frame { 47*0da5724dSToomas Soome struct frame *fr_savfp; 48*0da5724dSToomas Soome uintptr_t fr_savpc; 49*0da5724dSToomas Soome }; 50*0da5724dSToomas Soome 51*0da5724dSToomas Soome static void 52*0da5724dSToomas Soome stack_trace(struct frame *fp, uintptr_t pc) 53*0da5724dSToomas Soome { 54*0da5724dSToomas Soome char buf[80]; 55*0da5724dSToomas Soome uintptr_t freemem = *(uint16_t *)PTOV(0x413) << 10; 56*0da5724dSToomas Soome uintptr_t stack_start; 57*0da5724dSToomas Soome 58*0da5724dSToomas Soome /* 59*0da5724dSToomas Soome * stack start is at freemem - __base - ARGSPACE. 60*0da5724dSToomas Soome */ 61*0da5724dSToomas Soome stack_start = (uintptr_t)PTOV(freemem - ARGSPACE); 62*0da5724dSToomas Soome 63*0da5724dSToomas Soome printf("Stack trace:\n"); 64*0da5724dSToomas Soome pager_open(); 65*0da5724dSToomas Soome while (fp != NULL || pc != 0) { 66*0da5724dSToomas Soome struct frame *nfp; 67*0da5724dSToomas Soome 68*0da5724dSToomas Soome (void) snprintf(buf, sizeof (buf), 69*0da5724dSToomas Soome "FP 0x%08x: loader PC 0x%08x\n", 70*0da5724dSToomas Soome (uintptr_t)fp, pc); 71*0da5724dSToomas Soome if (pager_output(buf)) 72*0da5724dSToomas Soome break; 73*0da5724dSToomas Soome 74*0da5724dSToomas Soome if (fp == NULL) 75*0da5724dSToomas Soome break; 76*0da5724dSToomas Soome 77*0da5724dSToomas Soome nfp = fp->fr_savfp; 78*0da5724dSToomas Soome if (nfp != NULL && nfp <= fp) { 79*0da5724dSToomas Soome printf("FP 0x%08x: loop detected, stopping trace\n", 80*0da5724dSToomas Soome (uintptr_t)nfp); 81*0da5724dSToomas Soome break; 82*0da5724dSToomas Soome } 83*0da5724dSToomas Soome fp = nfp; 84*0da5724dSToomas Soome if ((char *)fp < _end || 85*0da5724dSToomas Soome (uintptr_t)fp + sizeof (*fp) > stack_start) 86*0da5724dSToomas Soome break; 87*0da5724dSToomas Soome 88*0da5724dSToomas Soome pc = fp->fr_savpc; 89*0da5724dSToomas Soome } 90*0da5724dSToomas Soome pager_close(); 91*0da5724dSToomas Soome } 92*0da5724dSToomas Soome 93*0da5724dSToomas Soome void 94*0da5724dSToomas Soome panic_action(void) 95*0da5724dSToomas Soome { 96*0da5724dSToomas Soome struct frame *fp; 97*0da5724dSToomas Soome uintptr_t eip; 98*0da5724dSToomas Soome 99*0da5724dSToomas Soome __asm __volatile("movl %%ebp,%0" : "=r" (fp)); 100*0da5724dSToomas Soome 101*0da5724dSToomas Soome if (fp != NULL) { 102*0da5724dSToomas Soome eip = fp->fr_savpc; 103*0da5724dSToomas Soome stack_trace(fp, eip); 104*0da5724dSToomas Soome } 105*0da5724dSToomas Soome printf("--> Press a key on the console to reboot <--\n"); 106*0da5724dSToomas Soome getchar(); 107*0da5724dSToomas Soome printf("Rebooting...\n"); 108*0da5724dSToomas Soome exit(1); 109*0da5724dSToomas Soome } 110