20#include "pedigree/kernel/Log.h"
21#include "pedigree/kernel/Service.h"
22#include "pedigree/kernel/ServiceFeatures.h"
23#include "pedigree/kernel/ServiceManager.h"
24#include "pedigree/kernel/debugger/DebuggerIO.h"
25#include "pedigree/kernel/debugger/LocalIO.h"
26#include "pedigree/kernel/debugger/SerialIO.h"
27#include "pedigree/kernel/graphics/GraphicsService.h"
28#include "pedigree/kernel/linker/KernelElf.h"
29#include "pedigree/kernel/machine/Display.h"
30#include "pedigree/kernel/machine/Machine.h"
31#include "pedigree/kernel/machine/Serial.h"
32#include "pedigree/kernel/panic.h"
33#include "pedigree/kernel/processor/Processor.h"
34#include "pedigree/kernel/processor/types.h"
35#include "pedigree/kernel/utilities/StaticString.h"
36#include "pedigree/kernel/utilities/String.h"
37#include "pedigree/kernel/utilities/utility.h"
44static size_t newlineCount(
const char* pString) {
46 while (*pString !=
'\0')
47 if (*pString++ ==
'\n')
54static void _panic(
const char* msg,
DebuggerIO* pScreen) {
58 panic_output.append(
"PANIC: ");
59 panic_output.append(msg);
62 pScreen->
drawString(panic_output, 0, 0, DebuggerIO::Red, DebuggerIO::Black);
64 size_t nLines = newlineCount(panic_output) + 2;
70 size_t iEntry = 0, iUsedEntries = 0;
73 (pScreen->getHeight() - nLines) + 1;
74 bool bPrintThisLine =
false;
84 Line.append(entry.timestamp, 10, 8,
'0');
86 Line.append(entry.str);
89 bPrintThisLine =
true;
93 level = entry.severity;
99 Line.append(entry.timestamp, 10, 8,
'0');
101 Line.append(entry.str);
104 bPrintThisLine =
true;
109 if (bPrintThisLine ==
true) {
111 pScreen->
drawString(Line, nLines + iUsedEntries, 0, DebuggerIO::White, DebuggerIO::Black);
112 bPrintThisLine =
false;
119 fprintf(stderr,
"panic: %s\n", msg);
128 if (terminalShutdown && !terminalTlbFailure) {
129 shutdownFailure.append(
"Shutdown failed. Filesystems may be unclean.\nPhase: ");
130 shutdownFailure.append(Machine::shutdownPhaseName());
131 shutdownFailure.append(
"\nReason: ");
132 shutdownFailure.append(msg);
137 if (Machine::instance().getNumSerial()) {
140 serial->write_str(
"PANIC: ");
141 serial->write_str(msg);
142 serial->write_str(
"\r\n");
146 bool processorsStopped =
true;
148 if (terminalTlbFailure) {
151 if (!processorsStopped) {
154 }
while (!processorsStopped);
158 if (!processorsStopped && !terminalTlbFailure && !terminalShutdown) {
159 ERROR_NOLOCK(
"panic: not all other processors stopped");
163 if (terminalShutdown && !terminalTlbFailure) {
166 if (processorsStopped) {
168 }
else if (Machine::instance().getNumSerial()) {
169 Machine::instance().
getSerial(0)->write_str(shutdownFailure);
170 Machine::instance().
getSerial(0)->write_str(
"\r\n");
176 if (terminalTlbFailure) {
179 SerialIO serialIO(Machine::instance().getSerial(0));
180 serialIO.
drawString(
"PANIC: ", 0, 0, DebuggerIO::Red, DebuggerIO::Black);
181 serialIO.
drawString(msg, 0, 7, DebuggerIO::Red, DebuggerIO::Black);
187 if (processorsStopped) {
188 static String graphicsService(
"graphics");
192 ByteSet(¶ms, 0,
sizeof(params));
193 params.wantTextMode =
false;
197 bool bSuccess =
false;
198 if (ServiceManager::instance().tryGetService(graphicsService, pService, pFeatures) &&
204 if (bSuccess && params.providerFound && !params.providerResult.
bTextModes &&
205 params.providerResult.pDisplay) {
213 SerialIO serialIO(Machine::instance().getSerial(0));
218 if (Machine::instance().getNumVga())
220 static LocalIO localIO(Machine::instance().getVga(0), Machine::instance().getKeyboard());
221#if DONT_LOG_TO_SERIAL
222 pInterfaces[0] = &localIO;
225 pInterfaces[0] = &localIO;
226 pInterfaces[1] = &serialIO;
230#if !DONT_LOG_TO_SERIAL
232 pInterfaces[0] = &serialIO;
237 for (
int nIFace = 0; nIFace < nInterfaces; nIFace++)
238 _panic(msg, pInterfaces[nIFace]);
virtual void drawString(const char *str, size_t row, size_t col, Colour foreColour, Colour backColour)=0
virtual bool setScreenMode(ScreenMode sm)
static KernelElf & instance()
size_t getStaticEntryCount() const
const StaticLogEntry & getStaticEntry(size_t n) const
size_t getDynamicEntryCount() const
static EXPORTED_PUBLIC Log & instance()
const DynamicLogEntry & getDynamicEntry(size_t n) const
virtual Serial * getSerial(size_t n)=0
virtual MUST_USE_RESULT bool stopAllOtherProcessors()
void displayShutdownMessage(const char *message)
static bool tlbInvalidationTerminal()
static void setInterrupts(bool bEnable)
void drawString(const char *str, size_t row, size_t col, DebuggerIO::Colour foreColour, DebuggerIO::Colour backColour)
virtual bool provides(Type service)
virtual bool serve(ServiceFeatures::Type type, void *pData, size_t dataLen)=0
void panic(const char *msg)