#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" #if 0 void dbg_log_char (unsigned ch): if !dbg_cap: return Capability::Context c for unsigned i = 0; i < 4; ++i: c.cap[i].reset () 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. #else void delay (unsigned ms): for unsigned t = 0; t < 8000 * ms; ++t: GPIO_GPDIR (0) = GPIO_GPDIR (0) void set_leds (bool a, bool b): gpio_as_output (GPIO_NUM_PORT, GPIO_NUM) gpio_as_output (GPIO_CAPS_PORT, GPIO_CAPS) if a: GPIO_GPDR (GPIO_NUM_PORT) &= ~(1 << GPIO_NUM) else: GPIO_GPDR (GPIO_NUM_PORT) |= 1 << GPIO_NUM if b: GPIO_GPDR (GPIO_CAPS_PORT) &= ~(1 << GPIO_CAPS) else: GPIO_GPDR (GPIO_CAPS_PORT) |= 1 << GPIO_CAPS void dbg_log_char (unsigned ch): void dbg_log (char const *str): void dbg_log_num (unsigned num): void send (unsigned n): for unsigned i = 0; i < 32; ++i: bool v = n & (1 << 31) set_leds (v, !v) delay (350) set_leds (false, false) delay (150) n <<= 1 set_leds (true, true) delay (50) set_leds (false, false) delay (50) void panic_impl (unsigned n, unsigned line, char const *name, char const *message): unsigned epc cp0_get (CP0_EPC, epc) send (epc) while true: send (n) #endif