#pypp 0 // Iris: micro-kernel for a capability-based operating system. // panic.ccp: Stop running and try to notify the user of the problem. // Copyright 2009 Bas Wijnen // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #define ARCH #include "kernel.hh" void dbg_log_char (unsigned ch): if !dbg_cap: return Capability::Context c for unsigned i = 0; i < 4; ++i: c.cap[i] = NULL c.copy[i] = false c.data[i] = 0 c.data[0] = ch dbg_cap->invoke (&c) if dbg_cap->target->owner: current = dbg_cap->target->owner void dbg_log (char const *str): while *str: dbg_log_char (*str++) void dbg_log_num (unsigned num): char const *encode = "0123456789abcdef" for unsigned i = 0; i < 8; ++i: dbg_log_char (encode[(num >> (4 * (7 - i))) & 0xf]) return void panic_impl (unsigned n, unsigned line, char const *name, char const *message): Thread *who = current // Stop all threads. while first_scheduled: first_scheduled->unrun () for Receiver *r = first_alarm; r; r = r->next_alarm: if r->owner: r->owner->unrun () for unsigned i = 0; i < 32; ++i: if arch_interrupt_receiver[i] && arch_interrupt_receiver[i]->owner: arch_interrupt_receiver[i]->owner->unrun () // If a log capability is registered, run its owner. if dbg_cap && dbg_cap->target->owner: dbg_cap->target->owner->run () // Use the (now running) log thread to display the message. dbg_log ("Panic: current = ") dbg_log_num ((unsigned)who) if who: dbg_log_char ('@') dbg_log_num ((unsigned)who->pc) dbg_log ("; ") dbg_log (name) dbg_log_char (':') dbg_log_num (line) dbg_log (": ") dbg_log (message) dbg_log_char ('/') dbg_log_num (n) dbg_log_char ('\n') // If no log capability is registered, the machine just hangs.