--- /dev/null
+\r
+#include "core.h"\r
+\r
+bool Error_Output_Enable_SerialPort = False;\r
+bool Error_Output_Enable_Display_TextMode = False;\r
+uint Error_Output_Enable_Display_GraphicMode = False;\r
+\r
+void *Error_Output_Display_GraphicMode_VRAM = 0;\r
+uint Error_Output_Display_GraphicMode_Lines = 0;\r
+uint Error_Output_Display_GraphicMode_ResolutionX = 0;\r
+uint Error_Output_Display_GraphicMode_UsedLines = 0;\r
+\r
+uchar *cpu_exceptions[0x20] = {\r
+ "Divided by zero.",\r
+ "Debug.",\r
+ "Nonmaskable interrupt.",\r
+ "Breakpoint.",\r
+ "Overflow.",\r
+ "Outside BOUND.",\r
+ "Invalid opcode.",\r
+ "Disable Device.",\r
+ "Double fault.",\r
+ "Coprocessor Segment Overrun.",\r
+ "Invalid task status segment.",\r
+ "Segment not present.",\r
+ "Stack Segment Fault.",\r
+ "General Protection Exception.",\r
+ "Page fault.",\r
+ "Reserved.",\r
+ "Floating point error.",\r
+ "Alignment Check.",\r
+ "Machine Check.",\r
+ "SIMD floating-point exception.",\r
+ "Reserved.",\r
+ "Reserved.",\r
+ "Reserved.",\r
+ "Reserved.",\r
+ "Reserved.",\r
+ "Reserved.",\r
+ "Reserved.",\r
+ "Reserved.",\r
+ "Reserved.",\r
+ "Reserved.",\r
+ "Reserved.",\r
+ "Reserved."\r
+};\r
+\r
+uchar *cpu_exception_infos[16] = {\r
+ "EDI ",\r
+ "ESI ",\r
+ "EBP ",\r
+ "ESP ",\r
+ "EBX ",\r
+ "EDX ",\r
+ "ECX ",\r
+ "EAX ",\r
+ "DS ",\r
+ "ES ",\r
+ "ERRORCODE",\r
+ "EIP ",\r
+ "CS ",\r
+ "EFLAGS ",\r
+ "User ESP ",\r
+ "User SS "\r
+};\r
+\r
+uint Error_Report(uint error_no, ...)\r
+{\r
+ uint *retaddr, *va_args;\r
+\r
+ retaddr = &error_no - 1;\r
+ va_args = &error_no + 1;\r
+\r
+ if(error_no <= ERROR_CPU_EXCEPTIONS){\r
+ #ifdef CHNOSPROJECT_DEBUG\r
+ if(error_no == ERROR_CPU_EXCEPTION_01){\r
+ Debug_ExceptionHandler((uint *)*va_args);\r
+ return 0;\r
+ }\r
+ #endif\r
+ Error_Put_String("Exception 0x%02X:%s", error_no, cpu_exceptions[error_no]);\r
+ if(error_no == ERROR_CPU_EXCEPTION_00){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_01){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_02){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_03){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_04){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_05){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_06){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_07){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_08){\r
+ Error_CPU_Exception_Put_Registers_With_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_09){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_0A){\r
+ Error_CPU_Exception_Put_Registers_With_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_0B){\r
+ Error_CPU_Exception_Put_Registers_With_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_0C){\r
+ Error_CPU_Exception_Put_Registers_With_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_0D){\r
+ Error_CPU_Exception_Put_Registers_With_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_0E){\r
+ Error_CPU_Exception_Put_Registers_With_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_0F){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_10){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_11){\r
+ Error_CPU_Exception_Put_Registers_With_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_12){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_13){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_14){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_15){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_16){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_17){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_18){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_19){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_1A){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_1B){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_1C){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_1D){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_1E){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ } else if(error_no == ERROR_CPU_EXCEPTION_1F){\r
+ Error_CPU_Exception_Put_Registers_Without_ErrorCode((uint *)*va_args);\r
+ }\r
+ Error_Abort();\r
+ } else{\r
+ Error_Put_String("[0x%08X]Error:0x%08X ", *retaddr, error_no);\r
+ if(error_no == ERROR_NO_MORE_SEGMENT){\r
+ Error_Put_String("No More Segment Descriptor(requested at 0x%08X).", *va_args);\r
+ Error_Abort();\r
+ } else if(error_no == ERROR_NOT_ENOUGH_FREE_MEMORY){\r
+ Error_Put_String("No More Free Memory(Control:0x%08X Request Size:0x%08X).", *va_args, *(va_args + 1));\r
+ } else if(error_no == ERROR_MEMORY_FREE_RANGE_OVERLAPPED){\r
+ Error_Put_String("Memory Free Range Overlapped(Control:0x%08X TagIndex:%u).", *va_args, *(va_args + 1));\r
+ } else if(error_no == ERROR_NO_MORE_FREE_TAG){\r
+ Error_Put_String("No More Free Tag(Control:0x%08X).", *va_args);\r
+ } else if(error_no == ERROR_INVALID_FREE_MEMORY_INDEX){\r
+ Error_Put_String("Invalid Free Memory Index(Control:0x%08X TagIndex:%u).", *va_args, *(va_args + 1));\r
+ } else if(error_no == ERROR_FIFO_BUFFER_OVERFLOW){\r
+ Error_Put_String("FIFO Buffer Overflow(FIFO:0x%08X).", *va_args);\r
+ } else{\r
+ Error_Put_String("Unknown Error Number.");\r
+ Error_Abort();\r
+ }\r
+ }\r
+ Error_Put_String("Continue.");\r
+ Error_Output_Display_GraphicMode_UsedLines = 0;\r
+ return 0;\r
+}\r
+\r
+void Error_Abort(void)\r
+{\r
+ Error_Put_String("Abort.");\r
+ IO_CLI();\r
+ for(;;){\r
+ IO_HLT();\r
+ }\r
+}\r
+\r
+void Error_Set_Enable_SerialPort(bool serial)\r
+{\r
+ Error_Output_Enable_SerialPort = serial;\r
+ return;\r
+}\r
+\r
+void Error_Set_Enable_Display_TextMode(bool tdisp)\r
+{\r
+ Error_Output_Enable_Display_TextMode = tdisp;\r
+ return;\r
+}\r
+\r
+void Error_Set_Enable_Display_GraphicMode(bool gdisp, void *vram, uint xsize, uint lines)\r
+{\r
+ Error_Output_Enable_Display_GraphicMode = gdisp;\r
+ Error_Output_Display_GraphicMode_VRAM = vram;\r
+ Error_Output_Display_GraphicMode_ResolutionX = xsize;\r
+ Error_Output_Display_GraphicMode_Lines = lines;\r
+ Error_Output_Display_GraphicMode_UsedLines = 0;\r
+ return;\r
+}\r
+\r
+int Error_Put_String(const uchar format[], ...)\r
+{\r
+ int i;\r
+ uchar s[256];\r
+\r
+ i = vsnprintf(s, sizeof(s), format, (uint *)(&format + 1));\r
+ if(Error_Output_Enable_Display_GraphicMode){\r
+ if(Error_Output_Display_GraphicMode_Lines > Error_Output_Display_GraphicMode_UsedLines){\r
+ Drawing_Fill_Rectangle(Error_Output_Display_GraphicMode_VRAM, Error_Output_Display_GraphicMode_ResolutionX, 0xc6c6c6, 0, Error_Output_Display_GraphicMode_UsedLines << 4, Error_Output_Display_GraphicMode_ResolutionX - 1, (Error_Output_Display_GraphicMode_UsedLines << 4) + 16 - 1);\r
+ Drawing_Put_String(Error_Output_Display_GraphicMode_VRAM, Error_Output_Display_GraphicMode_ResolutionX, 0, Error_Output_Display_GraphicMode_UsedLines << 4, 0xffffff, s);\r
+ Error_Output_Display_GraphicMode_UsedLines++;\r
+ }\r
+ }\r
+ if(Error_Output_Enable_SerialPort){\r
+ SerialPort_Send(s);\r
+ SerialPort_Send("\n");\r
+ }\r
+ if(Error_Output_Enable_Display_TextMode){\r
+ TextMode_Put_String(s, white);\r
+ TextMode_Put_String("\n", white);\r
+ }\r
+ return i;\r
+}\r
+\r
+void Error_CPU_Exception_Put_Registers_With_ErrorCode(uint *esp)\r
+{\r
+ uint i;\r
+\r
+ IO_SegmentDescriptor *gdt;\r
+\r
+ gdt = (IO_SegmentDescriptor *)ADR_GDT;\r
+\r
+ Error_Put_String("#PUSHAD by _asm_CPU_ExceptionHandler");\r
+ for(i = 0; i < 4; i++){\r
+ Error_Put_String("%s:0x%08X %s:0x%08X", cpu_exception_infos[i << 1], esp[i << 1], cpu_exception_infos[(i << 1) + 1], esp[(i << 1) + 1]);\r
+ }\r
+\r
+ Error_Put_String("#PUSH by _asm_CPU_ExceptionHandler");\r
+ for(; i < 5; i++){\r
+ Error_Put_String("%s:0x%08X %s:0x%08X", cpu_exception_infos[i << 1], esp[i << 1], cpu_exception_infos[(i << 1) + 1], esp[(i << 1) + 1]);\r
+ }\r
+\r
+ Error_Put_String("#PUSH by CPU");\r
+ for(; i < 8; i++){\r
+ Error_Put_String("%s:0x%08X %s:0x%08X", cpu_exception_infos[i << 1], esp[i << 1], cpu_exception_infos[(i << 1) + 1], esp[(i << 1) + 1]);\r
+ }\r
+\r
+ Error_Put_String("#Control Registers");\r
+ Error_Put_String("CR0 = 0x%08X", Load_CR0());\r
+ Error_Put_String("CR2 = 0x%08X", Load_CR2());\r
+ Error_Put_String("CR3 = 0x%08X", Load_CR3());\r
+ Error_Put_String("CR4 = 0x%08X", Load_CR4());\r
+\r
+ Error_Put_String("Opcode[0x%X:0x%X]:0x%X", SegmentDescriptor_Get_Base(&gdt[esp[0x0c] >> 3]), esp[0x0b], ((uchar *)(SegmentDescriptor_Get_Base(&gdt[esp[0x0c] >> 3])))[esp[0x0b]]);\r
+ return;\r
+}\r
+\r
+void Error_CPU_Exception_Put_Registers_Without_ErrorCode(uint *esp)\r
+{\r
+ uint i;\r
+\r
+ IO_SegmentDescriptor *gdt;\r
+\r
+ gdt = (IO_SegmentDescriptor *)ADR_GDT;\r
+\r
+ Error_Put_String("#PUSHAD by _asm_CPU_ExceptionHandler");\r
+ for(i = 0; i < 4; i++){\r
+ Error_Put_String("%s:0x%08X %s:0x%08X", cpu_exception_infos[i << 1], esp[i << 1], cpu_exception_infos[(i << 1) + 1], esp[(i << 1) + 1]);\r
+ }\r
+\r
+ Error_Put_String("#PUSH by _asm_CPU_ExceptionHandler");\r
+ for(; i < 5; i++){\r
+ Error_Put_String("%s:0x%08X %s:0x%08X", cpu_exception_infos[i << 1], esp[i << 1], cpu_exception_infos[(i << 1) + 1], esp[(i << 1) + 1]);\r
+ }\r
+\r
+ Error_Put_String("#PUSH by CPU");\r
+ Error_Put_String("%s:0x%08X", cpu_exception_infos[(i << 1) + 1], esp[i << 1]);\r
+ i++;\r
+ for(; i < 8; i++){\r
+ Error_Put_String("%s:0x%08X %s:0x%08X", cpu_exception_infos[i << 1], esp[(i << 1) - 1], cpu_exception_infos[(i << 1) + 1], esp[i << 1]);\r
+ }\r
+\r
+ Error_Put_String("#Control Registers");\r
+ Error_Put_String("CR0 = 0x%08X", Load_CR0());\r
+ Error_Put_String("CR2 = 0x%08X", Load_CR2());\r
+ Error_Put_String("CR3 = 0x%08X", Load_CR3());\r
+\r
+ Error_Put_String("Opcode[0x%X:0x%X]:0x%X", SegmentDescriptor_Get_Base(&gdt[esp[0x0b] >> 3]), esp[0x0a], ((uchar *)(SegmentDescriptor_Get_Base(&gdt[esp[0x0b] >> 3])))[esp[0x0a]]);\r
+ return;\r
+}\r