Namespace classes
This commit is contained in:
@ -1,305 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* B L U E S C R E E N *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* Beschreibung: Ein Bluescreen, falls eine x86 Exception auftritt. Evt. *
|
||||
* ist der Stack und oder Heap kaputt, weswegen hier nicht *
|
||||
* kout etc. verwendet wird. *
|
||||
* *
|
||||
* Autor: Michael Schoettner, 11.12.2018 *
|
||||
*****************************************************************************/
|
||||
#include "kernel/system/Globals.h"
|
||||
|
||||
// in startup.asm
|
||||
extern "C" {
|
||||
// CR2 auslesen
|
||||
uint32_t get_page_fault_address();
|
||||
|
||||
// 1st level interrupt handler in startup.asm sichert Zeiger auf Stackframe
|
||||
// unmittelbar nach dem Interrupt und nachdem alle Register mit PUSHAD
|
||||
// gesichert wurden
|
||||
// |-------------|
|
||||
// | EFLAGS |
|
||||
// |-------------|
|
||||
// | CS |
|
||||
// |-------------|
|
||||
// | EIP |
|
||||
// |-------------|
|
||||
// | [ErrorCode] |
|
||||
// |-------------|
|
||||
// | EAX |
|
||||
// |-------------|
|
||||
// | ECX |
|
||||
// |-------------|
|
||||
// | EDX |
|
||||
// |-------------|
|
||||
// | EBX |
|
||||
// |-------------|
|
||||
// | ESP |
|
||||
// |-------------|
|
||||
// | EBP |
|
||||
// |-------------|
|
||||
// | ESI |
|
||||
// |-------------|
|
||||
// | EDI |
|
||||
// |-------------| <-- int_esp
|
||||
|
||||
void get_int_esp(uint32_t** esp);
|
||||
}
|
||||
|
||||
void break_on_bluescreen() {
|
||||
|
||||
/* wenn auf diese Methode ein breakpoint in GDB gesetzt wird
|
||||
so kann man sich mithilfe des Hex-Dumps umsehen
|
||||
*/
|
||||
}
|
||||
|
||||
// Cursor-Position
|
||||
uint8_t bs_xpos = 0;
|
||||
uint8_t bs_ypos = 0;
|
||||
|
||||
/*****************************************************************************
|
||||
* Funktion: bs_clear *
|
||||
*---------------------------------------------------------------------------*
|
||||
* Beschreibung: Bildschirm loeschen. *
|
||||
*****************************************************************************/
|
||||
void bs_clear() {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
auto* ptr = reinterpret_cast<uint16_t*>(0xb8000);
|
||||
|
||||
for (x = 0; x < 80; x++) {
|
||||
for (y = 0; y < 25; y++) {
|
||||
*(ptr + y * 80 + x) = static_cast<uint16_t>(0x1F00);
|
||||
}
|
||||
}
|
||||
|
||||
bs_xpos = 0;
|
||||
bs_ypos = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Funktion: bs_lf *
|
||||
*---------------------------------------------------------------------------*
|
||||
* Beschreibung: Zeilenvorschub. *
|
||||
*****************************************************************************/
|
||||
void bs_lf() {
|
||||
bs_ypos++;
|
||||
bs_xpos = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Funktion: bs_print_char *
|
||||
*---------------------------------------------------------------------------*
|
||||
* Beschreibung: Ein Zeichen ausgeben. *
|
||||
*****************************************************************************/
|
||||
void bs_print_char(char c) {
|
||||
auto* ptr = reinterpret_cast<uint8_t*>(0xb8000);
|
||||
|
||||
*(ptr + bs_ypos * 80 * 2 + bs_xpos * 2) = c;
|
||||
bs_xpos++;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Funktion: bs_print_string *
|
||||
*---------------------------------------------------------------------------*
|
||||
* Beschreibung: Eine Zeichenkette ausgeben. *
|
||||
*****************************************************************************/
|
||||
void bs_print_string(char* str) {
|
||||
|
||||
while (*str != '\0') {
|
||||
bs_print_char(*str);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Funktion: bs_printHexDigit *
|
||||
*---------------------------------------------------------------------------*
|
||||
* Beschreibung: Ein Hex-Zeichen ausgeben. *
|
||||
*****************************************************************************/
|
||||
void bs_printHexDigit(int c) {
|
||||
if (c < 10) {
|
||||
bs_print_char('0' + static_cast<uint8_t>(c));
|
||||
} else {
|
||||
bs_print_char('A' + static_cast<uint8_t>(c - 10));
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Funktion: bs_print_uintHex *
|
||||
*---------------------------------------------------------------------------*
|
||||
* Beschreibung: Integer ausgeben. *
|
||||
*****************************************************************************/
|
||||
void bs_print_uintHex(uint32_t c) {
|
||||
for (int i = 28; i >= 0; i = i - 4) {
|
||||
bs_printHexDigit((c >> i) & 0xF);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Funktion: bs_printReg *
|
||||
*---------------------------------------------------------------------------*
|
||||
* Beschreibung: String mit Integer ausgeben. Wird verwendet um ein *
|
||||
* Register auszugeben. *
|
||||
*****************************************************************************/
|
||||
void bs_printReg(char* str, uint32_t value) {
|
||||
bs_print_string(str);
|
||||
bs_print_uintHex(value);
|
||||
bs_print_string(" \0");
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Funktion: bs_dump *
|
||||
*---------------------------------------------------------------------------*
|
||||
* Beschreibung: Hauptroutine des Bluescreens. *
|
||||
*****************************************************************************/
|
||||
void bs_dump(uint8_t exceptionNr) {
|
||||
uint32_t* int_esp;
|
||||
uint32_t* sptr;
|
||||
uint32_t faultAdress;
|
||||
uint8_t has_error_code = 0;
|
||||
|
||||
bs_clear();
|
||||
bs_print_string("HHUos crashed with Exception \0");
|
||||
|
||||
// Exception mit Error-Code?
|
||||
if ((exceptionNr >= 8 && exceptionNr <= 14) || exceptionNr == 17 || exceptionNr == 30) {
|
||||
has_error_code = 1;
|
||||
}
|
||||
|
||||
// Liegt ein Page-Fault vor?
|
||||
if (exceptionNr == 14) {
|
||||
faultAdress = get_page_fault_address();
|
||||
// Zugriff auf Seite 0 ? -> Null-Ptr. Exception
|
||||
if ((faultAdress & 0xFFFFF000) == 0) {
|
||||
exceptionNr = 0x1B;
|
||||
}
|
||||
}
|
||||
|
||||
bs_print_uintHex(exceptionNr);
|
||||
bs_print_string(" (\0");
|
||||
|
||||
// Spruch ausgeben
|
||||
switch (exceptionNr) {
|
||||
case 0x00: bs_print_string("Divide Error\0"); break;
|
||||
case 0x01: bs_print_string("Debug Exception\0"); break;
|
||||
case 0x02: bs_print_string("NMI\0"); break;
|
||||
case 0x03: bs_print_string("Breakpoint Exception\0"); break;
|
||||
case 0x04: bs_print_string("Into Exception\0"); break;
|
||||
case 0x05: bs_print_string("Index out of range Exception\0"); break;
|
||||
case 0x06: bs_print_string("Invalid Opcode\0"); break;
|
||||
case 0x08: bs_print_string("Double Fault\0"); break;
|
||||
case 0x0D: bs_print_string("General Protection Error\0"); break;
|
||||
case 0x0E: bs_print_string("Page Fault\0"); break;
|
||||
case 0x18: bs_print_string("Stack invalid\0"); break;
|
||||
case 0x19: bs_print_string("Return missing\0"); break;
|
||||
case 0x1A: bs_print_string("Type Test Failed\0"); break;
|
||||
case 0x1B: bs_print_string("Null pointer exception\0"); break;
|
||||
case 0x1C: bs_print_string("MAGIC.StackTest failed\0"); break;
|
||||
case 0x1D: bs_print_string("Memory-Panic\0"); break;
|
||||
case 0x1E: bs_print_string("Pageload failed\0"); break;
|
||||
case 0x1F: bs_print_string("Stack overflow\0"); break;
|
||||
default: bs_print_string("unknown\0");
|
||||
}
|
||||
bs_print_string(")\0");
|
||||
bs_lf();
|
||||
|
||||
// Zeiger auf int_esp ueber startup.asm beschaffen (Stack-Layout siehe Anfang dieser Datei)
|
||||
get_int_esp(&int_esp);
|
||||
|
||||
// wir müssen den Inhalt auslesen und das als Zeiger verwenden, um den Stack auszulesen
|
||||
sptr = reinterpret_cast<uint32_t*>(*int_esp);
|
||||
|
||||
bs_lf();
|
||||
|
||||
// wichtigste Register ausgeben
|
||||
|
||||
// Exception mit Error-Code?
|
||||
bs_printReg("EIP=\0", *(sptr + 8 + has_error_code));
|
||||
bs_printReg("EBP=\0", *(sptr + 2));
|
||||
bs_printReg("ESP=\0", *(sptr + 3));
|
||||
bs_printReg(" CS=\0", *(sptr + 9 + has_error_code));
|
||||
bs_lf();
|
||||
|
||||
// verbleibende nicht-fluechtige Register ausgeben
|
||||
bs_printReg("EBX=\0", *(sptr + 4));
|
||||
bs_printReg("ESI=\0", *(sptr + 1));
|
||||
bs_printReg("EDI=\0", *(sptr));
|
||||
bs_lf();
|
||||
|
||||
// verbleibende fluechtige Register ausgeben
|
||||
bs_printReg("EDX=\0", *(sptr + 5));
|
||||
bs_printReg("ECX=\0", *(sptr + 6));
|
||||
bs_printReg("EAX=\0", *(sptr + 7));
|
||||
bs_printReg("EFL=\0", *(sptr + 10));
|
||||
bs_lf();
|
||||
|
||||
// Pagefault oder Null-Pointer?
|
||||
if (exceptionNr == 14 || exceptionNr == 0x1B) {
|
||||
bs_lf();
|
||||
bs_print_string("Fault address = \0");
|
||||
bs_print_uintHex(faultAdress);
|
||||
bs_lf();
|
||||
|
||||
bs_print_string("Last useable address = \0");
|
||||
bs_print_uintHex(total_mem - 1);
|
||||
|
||||
bs_lf();
|
||||
}
|
||||
|
||||
// Exception mit Error-Code?
|
||||
if (has_error_code == 1) {
|
||||
uint32_t error_nr = *(sptr + 8);
|
||||
|
||||
if (exceptionNr == 14) {
|
||||
if (error_nr == 3) {
|
||||
bs_print_string("Error: write access to read-only page.\0");
|
||||
} else if (error_nr == 2) {
|
||||
bs_print_string("Error: read access to not-present page.\0");
|
||||
} else if (error_nr == 0) {
|
||||
bs_print_string("Error: access to a not-present page.\0");
|
||||
} else {
|
||||
bs_print_string("Error code = \0");
|
||||
bs_print_uintHex(error_nr);
|
||||
}
|
||||
bs_lf();
|
||||
} else {
|
||||
bs_print_string("Error code = \0");
|
||||
bs_print_uintHex(error_nr);
|
||||
bs_lf();
|
||||
}
|
||||
}
|
||||
|
||||
// Calling stack ...
|
||||
bs_lf();
|
||||
bs_print_string("Calling Stack:\0");
|
||||
bs_lf();
|
||||
int x = 0;
|
||||
auto* ebp = reinterpret_cast<uint32_t*>(*(sptr + 2));
|
||||
uint32_t raddr;
|
||||
|
||||
// solange eip > 1 MB && ebp < 128 MB, max. Aufruftiefe 10
|
||||
while (*ebp > 0x100000 && *ebp < 0x8000000 && x < 10) {
|
||||
|
||||
raddr = *(ebp + 1);
|
||||
bs_printReg(" raddr=\0", raddr);
|
||||
bs_lf();
|
||||
|
||||
// dynamische Kette -> zum Aufrufer
|
||||
ebp = reinterpret_cast<uint32_t*>(*ebp);
|
||||
|
||||
x++;
|
||||
}
|
||||
if (x == 0) {
|
||||
bs_print_string(" empty\0");
|
||||
bs_lf();
|
||||
}
|
||||
bs_lf();
|
||||
|
||||
// nur falls gdb benutzt werden soll
|
||||
break_on_bluescreen();
|
||||
|
||||
bs_print_string("System halted\0");
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* B L U E S C R E E N *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* Beschreibung: Ein Bluescreen, falls eine x86 Exception auftritt. Evt. *
|
||||
* ist der Stack und oder Heap kaputt, weswegen hier nicht *
|
||||
* kout etc. verwendet wird. *
|
||||
* *
|
||||
* Autor: Michael Schoettner, 2.2.2017 *
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef Bluescreen_include__
|
||||
#define Bluescreen_include__
|
||||
|
||||
// dump blue screen (will not return)
|
||||
void bs_dump(uint8_t exceptionNr);
|
||||
|
||||
#endif
|
||||
@ -12,9 +12,11 @@
|
||||
#ifndef ISR_include__
|
||||
#define ISR_include__
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
class ISR {
|
||||
public:
|
||||
ISR(const ISR& copy) = delete; // Verhindere Kopieren
|
||||
ISR(const ISR ©) = delete; // Verhindere Kopieren
|
||||
|
||||
// virtual ~ISR() = default;
|
||||
|
||||
@ -24,4 +26,6 @@ public:
|
||||
virtual void trigger() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
#include "IntDispatcher.h"
|
||||
#include "device/cpu/CPU.h"
|
||||
#include "kernel/system/Globals.h"
|
||||
#include "kernel/interrupt/Bluescreen.h"
|
||||
#include "kernel/exception//Bluescreen.h"
|
||||
|
||||
extern "C" void int_disp(uint8_t vector);
|
||||
|
||||
@ -35,16 +35,18 @@ void int_disp(uint8_t vector) {
|
||||
|
||||
if (vector < 32) {
|
||||
bs_dump(vector);
|
||||
CPU::halt();
|
||||
Device::CPU::halt();
|
||||
}
|
||||
|
||||
if (intdis.report(vector) < 0) {
|
||||
kout << "Panic: unexpected interrupt " << vector;
|
||||
kout << " - processor halted." << endl;
|
||||
CPU::halt();
|
||||
if (Kernel::intdis.report(vector) < 0) {
|
||||
Kernel::kout << "Panic: unexpected interrupt " << vector;
|
||||
Kernel::kout << " - processor halted." << endl;
|
||||
Device::CPU::halt();
|
||||
}
|
||||
}
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
/*****************************************************************************
|
||||
* Methode: IntDispatcher::assign *
|
||||
*---------------------------------------------------------------------------*
|
||||
@ -56,7 +58,7 @@ void int_disp(uint8_t vector) {
|
||||
* *
|
||||
* Rueckgabewert: 0 = Erfolg, -1 = Fehler *
|
||||
*****************************************************************************/
|
||||
int IntDispatcher::assign(uint8_t vector, ISR& isr) {
|
||||
int IntDispatcher::assign(uint8_t vector, ISR &isr) {
|
||||
|
||||
/* hier muss Code eingefuegt werden */
|
||||
|
||||
@ -89,7 +91,7 @@ int IntDispatcher::report(uint8_t vector) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ISR* isr = map[vector];
|
||||
ISR *isr = map[vector];
|
||||
|
||||
if (isr == nullptr) {
|
||||
log.error() << "No ISR registered for vector " << vector << endl;
|
||||
@ -107,3 +109,5 @@ int IntDispatcher::report(uint8_t vector) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -14,18 +14,22 @@
|
||||
#define IntDispatcher_include__
|
||||
|
||||
#include "ISR.h"
|
||||
#include "lib/util/Array.h"
|
||||
#include "kernel/log/Logger.h"
|
||||
#include "lib/container//Array.h"
|
||||
#include "lib/stream/Logger.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
class IntDispatcher {
|
||||
private:
|
||||
NamedLogger log;
|
||||
|
||||
enum { size = 256 };
|
||||
bse::array<ISR*, size> map;
|
||||
enum {
|
||||
size = 256
|
||||
};
|
||||
Container::array<ISR *, size> map;
|
||||
|
||||
public:
|
||||
IntDispatcher(const IntDispatcher& copy) = delete; // Verhindere Kopieren
|
||||
IntDispatcher(const IntDispatcher ©) = delete; // Verhindere Kopieren
|
||||
|
||||
// Vektor-Nummern
|
||||
enum {
|
||||
@ -36,16 +40,18 @@ public:
|
||||
|
||||
// Initialisierung der ISR map mit einer Default-ISR.
|
||||
IntDispatcher() : log("IntDis") {
|
||||
for (ISR*& slot : map) {
|
||||
for (ISR *&slot: map) {
|
||||
slot = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Registrierung einer ISR. (Rueckgabewert: 0 = Erfolg, -1 = Fehler)
|
||||
int assign(uint8_t vector, ISR& isr);
|
||||
int assign(uint8_t vector, ISR &isr);
|
||||
|
||||
// ISR fuer 'vector' ausfuehren
|
||||
int report(uint8_t vector);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user