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