[FREELDR] Simplify the PrintText() and FrLdrBugCheckWithMessage() routines by using...
[reactos.git] / boot / freeldr / freeldr / arch / i386 / i386bug.c
index 260e39d..f946396 100644 (file)
@@ -1,7 +1,6 @@
 
 #include <freeldr.h>
 
-#define NDEBUG
 #include <debug.h>
 
 typedef struct _FRAME
@@ -10,75 +9,91 @@ typedef struct _FRAME
     void *Address;
 } FRAME;
 
-char *i386ExceptionDescriptionText[] =
+static const CHAR *i386ExceptionDescriptionText[] =
 {
     "Exception 00: DIVIDE BY ZERO\n\n",
-       "Exception 01: DEBUG EXCEPTION\n\n",
-       "Exception 02: NON-MASKABLE INTERRUPT EXCEPTION\n\n",
-       "Exception 03: BREAKPOINT (INT 3)\n\n",
-       "Exception 04: OVERFLOW\n\n",
-       "Exception 05: BOUND EXCEPTION\n\n",
-       "Exception 06: INVALID OPCODE\n\n",
-       "Exception 07: FPU NOT AVAILABLE\n\n",
-       "Exception 08: DOUBLE FAULT\n\n",
-       "Exception 09: COPROCESSOR SEGMENT OVERRUN\n\n",
-       "Exception 0A: INVALID TSS\n\n",
-       "Exception 0B: SEGMENT NOT PRESENT\n\n",
-       "Exception 0C: STACK EXCEPTION\n\n",
-       "Exception 0D: GENERAL PROTECTION FAULT\n\n",
-       "Exception 0E: PAGE FAULT\n\n",
-       "Exception 0F: Reserved\n\n",
-       "Exception 10: COPROCESSOR ERROR\n\n",
-       "Exception 11: ALIGNMENT CHECK\n\n",
-       "Exception 12: MACHINE CHECK\n\n"
+    "Exception 01: DEBUG EXCEPTION\n\n",
+    "Exception 02: NON-MASKABLE INTERRUPT EXCEPTION\n\n",
+    "Exception 03: BREAKPOINT (INT 3)\n\n",
+    "Exception 04: OVERFLOW\n\n",
+    "Exception 05: BOUND EXCEPTION\n\n",
+    "Exception 06: INVALID OPCODE\n\n",
+    "Exception 07: FPU NOT AVAILABLE\n\n",
+    "Exception 08: DOUBLE FAULT\n\n",
+    "Exception 09: COPROCESSOR SEGMENT OVERRUN\n\n",
+    "Exception 0A: INVALID TSS\n\n",
+    "Exception 0B: SEGMENT NOT PRESENT\n\n",
+    "Exception 0C: STACK EXCEPTION\n\n",
+    "Exception 0D: GENERAL PROTECTION FAULT\n\n",
+    "Exception 0E: PAGE FAULT\n\n",
+    "Exception 0F: Reserved\n\n",
+    "Exception 10: COPROCESSOR ERROR\n\n",
+    "Exception 11: ALIGNMENT CHECK\n\n",
+    "Exception 12: MACHINE CHECK\n\n"
 };
 
-#define SCREEN_ATTR 0x1f
-void
-i386PrintChar(char chr, ULONG x, ULONG y)
-{
-       MachVideoPutChar(chr, SCREEN_ATTR, x, y);
-}
+#define SCREEN_ATTR 0x1F    // Bright white on blue background
 
 /* Used to store the current X and Y position on the screen */
-ULONG i386_ScreenPosX = 0;
-ULONG i386_ScreenPosY = 0;
+static ULONG i386_ScreenPosX = 0;
+static ULONG i386_ScreenPosY = 0;
 
-void
-i386PrintText(char *pszText)
+#if 0
+static void
+i386PrintChar(CHAR chr, ULONG x, ULONG y)
 {
-    char chr;
-    while (1)
-    {
-        chr = *pszText++;
+    MachVideoPutChar(chr, SCREEN_ATTR, x, y);
+}
+#endif
+
+static void
+i386PrintText(CHAR *pszText)
+{
+    ULONG Width, Unused;
 
-        if (chr == 0) break;
-        if (chr == '\n')
+    MachVideoGetDisplaySize(&Width, &Unused, &Unused);
+
+    for (; *pszText != ANSI_NULL; ++pszText)
+    {
+        if (*pszText == '\n')
         {
-            i386_ScreenPosY++;
             i386_ScreenPosX = 0;
+            ++i386_ScreenPosY;
             continue;
         }
 
-        MachVideoPutChar(chr, SCREEN_ATTR, i386_ScreenPosX, i386_ScreenPosY);
-        i386_ScreenPosX++;
+        MachVideoPutChar(*pszText, SCREEN_ATTR, i386_ScreenPosX, i386_ScreenPosY);
+        if (++i386_ScreenPosX >= Width)
+        {
+            i386_ScreenPosX = 0;
+            ++i386_ScreenPosY;
+        }
+    // FIXME: Implement vertical screen scrolling if we are at the end of the screen.
     }
 }
 
-void
-PrintText(const char *format, ...)
+static void
+PrintTextV(const CHAR *Format, va_list args)
+{
+    CHAR Buffer[512];
+
+    _vsnprintf(Buffer, sizeof(Buffer), Format, args);
+    Buffer[sizeof(Buffer) - 1] = ANSI_NULL;
+
+    i386PrintText(Buffer);
+}
+
+static void
+PrintText(const CHAR *Format, ...)
 {
     va_list argptr;
-    char buffer[256];
 
-    va_start(argptr, format);
-    _vsnprintf(buffer, sizeof(buffer), format, argptr);
-    buffer[sizeof(buffer) - 1] = 0;
+    va_start(argptr, Format);
+    PrintTextV(Format, argptr);
     va_end(argptr);
-    i386PrintText(buffer);
 }
 
-void
+static void
 i386PrintFrames(PKTRAP_FRAME TrapFrame)
 {
     FRAME *Frame;
@@ -86,11 +101,11 @@ i386PrintFrames(PKTRAP_FRAME TrapFrame)
     PrintText("Frames:\n");
 #ifdef _M_IX86
     for (Frame = (FRAME*)TrapFrame->Ebp;
-         Frame != 0 && (ULONG_PTR)Frame < STACK32ADDR;
+         Frame != 0 && (ULONG_PTR)Frame < STACKADDR;
          Frame = Frame->Next)
 #else
     for (Frame = (FRAME*)TrapFrame->TrapFrame;
-         Frame != 0 && (ULONG_PTR)Frame < STACK32ADDR;
+         Frame != 0 && (ULONG_PTR)Frame < STACKADDR;
          Frame = Frame->Next)
 #endif
     {
@@ -102,15 +117,15 @@ void
 NTAPI
 i386PrintExceptionText(ULONG TrapIndex, PKTRAP_FRAME TrapFrame, PKSPECIAL_REGISTERS Special)
 {
-       PUCHAR InstructionPointer;
+    PUCHAR InstructionPointer;
 
-       MachVideoClearScreen(SCREEN_ATTR);
-       i386_ScreenPosX = 0;
-       i386_ScreenPosY = 0;
+    MachVideoHideShowTextCursor(FALSE);
+    MachVideoClearScreen(SCREEN_ATTR);
+    i386_ScreenPosX = 0;
+    i386_ScreenPosY = 0;
 
-    PrintText("An error occured in FreeLoader\n"
-              VERSION"\n"
-                 "Report this error to the ReactOS Development mailing list <ros-dev@reactos.org>\n\n"
+    PrintText("An error occured in " VERSION "\n"
+              "Report this error on the ReactOS Bug Tracker: https://jira.reactos.org\n\n"
               "0x%02lx: %s\n", TrapIndex, i386ExceptionDescriptionText[TrapIndex]);
 #ifdef _M_IX86
     PrintText("EAX: %.8lx        ESP: %.8lx        CR0: %.8lx        DR0: %.8lx\n",
@@ -138,8 +153,8 @@ i386PrintExceptionText(ULONG TrapIndex, PKTRAP_FRAME TrapFrame, PKSPECIAL_REGIST
     PrintText("SS: %.4lx        LDTR: %.4lx TR: %.4lx\n\n",
               TrapFrame->HardwareSegSs, Special->Ldtr, Special->Idtr.Limit);
 
-       i386PrintFrames(TrapFrame);                                             // Display frames
-       InstructionPointer = (PUCHAR)TrapFrame->Eip;
+    i386PrintFrames(TrapFrame);                        // Display frames
+    InstructionPointer = (PUCHAR)TrapFrame->Eip;
 #else
     PrintText("RAX: %.8lx        R8:  %.8lx        R12: %.8lx        RSI: %.8lx\n",
               TrapFrame->Rax, TrapFrame->R8, 0, TrapFrame->Rsi);
@@ -162,22 +177,47 @@ i386PrintExceptionText(ULONG TrapIndex, PKTRAP_FRAME TrapFrame, PKSPECIAL_REGIST
               TrapFrame->SegGs, Special->Idtr.Base, Special->Idtr.Limit);
     PrintText("SS: %.4lx        LDTR: %.4lx TR: %.4lx\n\n",
               TrapFrame->SegSs, Special->Ldtr, Special->Idtr.Limit);
-       InstructionPointer = (PUCHAR)TrapFrame->Rip;
+    InstructionPointer = (PUCHAR)TrapFrame->Rip;
 #endif
-    PrintText("\nInstructionstream: %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x \n",
+    PrintText("\nInstruction stream: %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x \n",
               InstructionPointer[0], InstructionPointer[1],
               InstructionPointer[2], InstructionPointer[3],
               InstructionPointer[4], InstructionPointer[5],
               InstructionPointer[6], InstructionPointer[7]);
 }
 
-char *BugCodeStrings[] =
+VOID
+FrLdrBugCheckWithMessage(
+    ULONG BugCode,
+    PCHAR File,
+    ULONG Line,
+    PSTR Format,
+    ...)
 {
-    "TEST_BUGCHECK",
-    "MISSING_HARDWARE_REQUIREMENTS",
-};
+    va_list argptr;
+
+    MachVideoHideShowTextCursor(FALSE);
+    MachVideoClearScreen(SCREEN_ATTR);
+    i386_ScreenPosX = 0;
+    i386_ScreenPosY = 0;
 
-ULONG_PTR BugCheckInfo[5];
+    PrintText("A problem has been detected and FreeLoader boot has been aborted.\n\n");
+
+    PrintText("%ld: %s\n\n", BugCode, BugCodeStrings[BugCode]);
+
+    if (File)
+    {
+        PrintText("Location: %s:%ld\n\n", File, Line);
+    }
+
+    va_start(argptr, Format);
+    PrintTextV(Format, argptr);
+    va_end(argptr);
+
+    _disable();
+    __halt();
+    for (;;);
+}
 
 void
 NTAPI
@@ -186,6 +226,7 @@ FrLdrBugCheckEx(
     PCHAR File,
     ULONG Line)
 {
+    MachVideoHideShowTextCursor(FALSE);
     MachVideoClearScreen(SCREEN_ATTR);
     i386_ScreenPosX = 0;
     i386_ScreenPosY = 0;
@@ -202,6 +243,8 @@ FrLdrBugCheckEx(
     PrintText("Bug Information:\n    %p\n    %p\n    %p\n    %p\n    %p\n\n",
               BugCheckInfo[0], BugCheckInfo[1], BugCheckInfo[2], BugCheckInfo[3], BugCheckInfo[4]);
 
+    _disable();
+    __halt();
     for (;;);
 }
 
@@ -211,4 +254,3 @@ FrLdrBugCheck(ULONG BugCode)
 {
     FrLdrBugCheckEx(BugCode, 0, 0);
 }
-