BIG refactor (indentation)

This commit is contained in:
Morten Delenk 2016-07-24 12:21:12 +02:00
parent 96d45988be
commit d85ee2dee1
40 changed files with 2097 additions and 2100 deletions

View file

@ -12,76 +12,76 @@ void **farg = (void**)0x1FFFFFFC;
uint32_t *flags = (uint32_t*)0x1FFFFFF4;
namespace MTGosHAL {
void mainRoutine(void*) {
*farg=nullptr;
*fpointer=nullptr;
while(true) {
if(!(*fpointer))
continue;
(*fpointer)(*farg);
*farg=nullptr;
*fpointer=nullptr;
*flags&=~1;
}
while(true) {
if(!(*fpointer))
continue;
(*fpointer)(*farg);
*farg=nullptr;
*fpointer=nullptr;
*flags&=~1;
}
}
void initScreen(void*) {
//top screen lfb size: 0x5dc00
//bottom screen lfb size: 0x4b000
//lfb locations: 0x18000000 (left 1)
//lfb locations: 0x18060000 (left 2)
//lfb locations: 0x180C0000 (right 1)
//lfb locations: 0x18120000 (right 2)
//lfb locations: 0x18180000 (bottom 1)
//lfb locations: 0x181D0000 (bottom 2)
unsigned int *lfbs = (unsigned int*)0x18000000;
for(int i=0;i<475136;i++)
lfbs[i]=0;
unsigned int *fb_init=(unsigned int*)0x10400400;
fb_init[0x70/4]&=~0x7;
fb_init[0x170/4]&=~0x7;
fb_init[0x68/4]=0x18000000; //Left eye
fb_init[0x6C/4]=0x18060000; //Left eye
fb_init[0x90/4]=960;
fb_init[0x94/4]=0x180C0000; //Right eye
fb_init[0x98/4]=0x18120000; //Right eye
fb_init[0x168/4]=0x18180000;
fb_init[0x16C/4]=0x181D0000;
fb_init[0x190/4]=960;
//top screen lfb size: 0x5dc00
//bottom screen lfb size: 0x4b000
//lfb locations: 0x18000000 (left 1)
//lfb locations: 0x18060000 (left 2)
//lfb locations: 0x180C0000 (right 1)
//lfb locations: 0x18120000 (right 2)
//lfb locations: 0x18180000 (bottom 1)
//lfb locations: 0x181D0000 (bottom 2)
unsigned int *lfbs = (unsigned int*)0x18000000;
for(int i=0;i<475136;i++)
lfbs[i]=0;
unsigned int *fb_init=(unsigned int*)0x10400400;
fb_init[0x70/4]&=~0x7;
fb_init[0x170/4]&=~0x7;
fb_init[0x68/4]=0x18000000; //Left eye
fb_init[0x6C/4]=0x18060000; //Left eye
fb_init[0x90/4]=960;
fb_init[0x94/4]=0x180C0000; //Right eye
fb_init[0x98/4]=0x18120000; //Right eye
fb_init[0x168/4]=0x18180000;
fb_init[0x16C/4]=0x181D0000;
fb_init[0x190/4]=960;
}
void testSVC(void*) {
initInterrupts();
asm volatile("svc #1");
initInterrupts();
asm volatile("svc #1");
}
}
struct cpu_info {
unsigned int pc;
unsigned int r12;
unsigned int r11;
unsigned int r10;
unsigned int r9;
unsigned int r8;
unsigned int r7;
unsigned int r6;
unsigned int r5;
unsigned int r4;
unsigned int r3;
unsigned int r2;
unsigned int r1;
unsigned int retAddr;
unsigned int pc;
unsigned int r12;
unsigned int r11;
unsigned int r10;
unsigned int r9;
unsigned int r8;
unsigned int r7;
unsigned int r6;
unsigned int r5;
unsigned int r4;
unsigned int r3;
unsigned int r2;
unsigned int r1;
unsigned int retAddr;
};
extern "C" void handleINT11(uint32_t stack, uint32_t id) {
MTGosHAL::Screen out;
*flags|=1;
out << MTGosHAL::Base::HEXADECIMAL << MTGosHAL::FG_color::RED << "Interrupt! " << (int)stack << "-" << (int)id << "\n";
struct cpu_info *cpu=(struct cpu_info*)stack;
out << "handler addr " << (int) cpu->pc << "\n";
out << "R1 " << (int) cpu->r1 << ", R2 " << (int)cpu->r2 << "\n";
out << "R3 " << (int) cpu->r3 << ", R4 " << (int)cpu->r4 << "\n";
out << "R5 " << (int) cpu->r5 << ", R6 " << (int)cpu->r6 << "\n";
out << "R7 " << (int) cpu->r7 << ", R8 " << (int)cpu->r8 << "\n";
out << "R9 " << (int) cpu->r9 << ", SL " << (int)cpu->r10 << "\n";
out << "FP " << (int) cpu->r11 << ", IP " << (int)cpu->r12 << "\n";
out << "SP " << (int) stack << ", PC " << (int)cpu->retAddr << "\n";
*flags&=~1;
if((id!=1)&&(id!=2)&&(id!=4))
for(;;);
MTGosHAL::Screen out;
*flags|=1;
out << MTGosHAL::Base::HEXADECIMAL << MTGosHAL::FG_color::RED << "Interrupt! " << (int)stack << "-" << (int)id << "\n";
struct cpu_info *cpu=(struct cpu_info*)stack;
out << "handler addr " << (int) cpu->pc << "\n";
out << "R1 " << (int) cpu->r1 << ", R2 " << (int)cpu->r2 << "\n";
out << "R3 " << (int) cpu->r3 << ", R4 " << (int)cpu->r4 << "\n";
out << "R5 " << (int) cpu->r5 << ", R6 " << (int)cpu->r6 << "\n";
out << "R7 " << (int) cpu->r7 << ", R8 " << (int)cpu->r8 << "\n";
out << "R9 " << (int) cpu->r9 << ", SL " << (int)cpu->r10 << "\n";
out << "FP " << (int) cpu->r11 << ", IP " << (int)cpu->r12 << "\n";
out << "SP " << (int) stack << ", PC " << (int)cpu->retAddr << "\n";
*flags&=~1;
if((id!=1)&&(id!=2)&&(id!=4))
for(;;);
}

View file

@ -4,96 +4,96 @@
int x=0, y=0;
extern uint32_t *flags;
namespace MTGosHAL {
FG_color fg=FG_color::WHITE;
BG_color bg=BG_color::BLACK;
uint32_t* toplfb = (uint32_t*)0x18000000;
uint32_t* bottomlfb = (uint32_t*)0x18180000;
int base=10;
FG_color fg=FG_color::WHITE;
BG_color bg=BG_color::BLACK;
uint32_t* toplfb = (uint32_t*)0x18000000;
uint32_t* bottomlfb = (uint32_t*)0x18180000;
int base=10;
void Screen::putChar(char c) {
while(*flags&2); //to prevent garbage to be displayed when ARM9&ARM11 are trying to access it at the same time
*flags|=2;
switch(c) {
case '\n':
x=0; y++;
break;
case '\r':
x=0;
break;
case '\b':
x--;
if(x<0) x=0;
putChar(' ');
x--;
if(x<0) x=0;
break;
case '\0':
break;
default:
for(int lx=0;lx<8;lx++) {
for(int ly=0;ly<8;ly++) {
if(font[(int)((uint8_t)c)][ly]&(1<<lx)) {
if(y>=TOP_SCREEN_HEIGHT)
bottomlfb[CALCXY(x*8+lx,(y-TOP_SCREEN_HEIGHT)*8+ly)]=__builtin_bswap32(static_cast<uint32_t>(fg));
else
toplfb[CALCXY(x*8+lx,(y)*8+ly)]=__builtin_bswap32(static_cast<uint32_t>(fg));
} else {
if(y>=TOP_SCREEN_HEIGHT)
bottomlfb[CALCXY(x*8+lx,(y-TOP_SCREEN_HEIGHT)*8+ly)]=__builtin_bswap32(static_cast<uint32_t>(bg));
else
toplfb[CALCXY(x*8+lx,(y)*8+ly)]=__builtin_bswap32(static_cast<uint32_t>(bg));
}
}
void Screen::putChar(char c) {
while(*flags&2); //to prevent garbage to be displayed when ARM9&ARM11 are trying to access it at the same time
*flags|=2;
switch(c) {
case '\n':
x=0; y++;
break;
case '\r':
x=0;
break;
case '\b':
x--;
if(x<0) x=0;
putChar(' ');
x--;
if(x<0) x=0;
break;
case '\0':
break;
default:
for(int lx=0;lx<8;lx++) {
for(int ly=0;ly<8;ly++) {
if(font[(int)((uint8_t)c)][ly]&(1<<lx)) {
if(y>=TOP_SCREEN_HEIGHT)
bottomlfb[CALCXY(x*8+lx,(y-TOP_SCREEN_HEIGHT)*8+ly)]=__builtin_bswap32(static_cast<uint32_t>(fg));
else
toplfb[CALCXY(x*8+lx,(y)*8+ly)]=__builtin_bswap32(static_cast<uint32_t>(fg));
} else {
if(y>=TOP_SCREEN_HEIGHT)
bottomlfb[CALCXY(x*8+lx,(y-TOP_SCREEN_HEIGHT)*8+ly)]=__builtin_bswap32(static_cast<uint32_t>(bg));
else
toplfb[CALCXY(x*8+lx,(y)*8+ly)]=__builtin_bswap32(static_cast<uint32_t>(bg));
}
}
}
x++;
if(x==(y>=TOP_SCREEN_HEIGHT?BOTTOM_SCREEN_WIDTH:TOP_SCREEN_WIDTH)) {
x=0;
y++;
}
break;
}
x++;
if(x==(y>=TOP_SCREEN_HEIGHT?BOTTOM_SCREEN_WIDTH:TOP_SCREEN_WIDTH)) {
x=0;
y++;
}
break;
if(y>=TOP_SCREEN_HEIGHT+BOTTOM_SCREEN_HEIGHT)
scroll_impl();
*flags&=~2; //Unlock
}
if(y>=TOP_SCREEN_HEIGHT+BOTTOM_SCREEN_HEIGHT)
scroll_impl();
*flags&=~2; //Unlock
}
void Screen::clrscr_impl() {
for(int p=0;p<400*240;p++)
toplfb[p]=__builtin_bswap32(static_cast<uint32_t>(bg));
for(int p=0;p<320*240;p++)
bottomlfb[p]=__builtin_bswap32(static_cast<uint32_t>(bg));
}
void Screen::scroll_impl() {
for(int ly=0;ly<240-8;ly++) {
for(int lx=0;lx<400;lx++) {
toplfb[CALCXY(lx,ly)]=toplfb[CALCXY(lx,ly+8)];
}
void Screen::clrscr_impl() {
for(int p=0;p<400*240;p++)
toplfb[p]=__builtin_bswap32(static_cast<uint32_t>(bg));
for(int p=0;p<320*240;p++)
bottomlfb[p]=__builtin_bswap32(static_cast<uint32_t>(bg));
}
for(int ly=0;ly<8;ly++) {
for(int lx=0;lx<40;lx++) {
toplfb[CALCXY(lx,ly+240-8)]=__builtin_bswap32(static_cast<uint32_t>(bg));
}
for(int lx=40;lx<360;lx++) {
toplfb[CALCXY(lx,ly+240-8)]=bottomlfb[CALCXY(lx-40,ly)];
}
for(int lx=360;lx<400;lx++) {
toplfb[CALCXY(lx,ly+240-8)]=__builtin_bswap32(static_cast<uint32_t>(bg));
}
void Screen::scroll_impl() {
for(int ly=0;ly<240-8;ly++) {
for(int lx=0;lx<400;lx++) {
toplfb[CALCXY(lx,ly)]=toplfb[CALCXY(lx,ly+8)];
}
}
for(int ly=0;ly<8;ly++) {
for(int lx=0;lx<40;lx++) {
toplfb[CALCXY(lx,ly+240-8)]=__builtin_bswap32(static_cast<uint32_t>(bg));
}
for(int lx=40;lx<360;lx++) {
toplfb[CALCXY(lx,ly+240-8)]=bottomlfb[CALCXY(lx-40,ly)];
}
for(int lx=360;lx<400;lx++) {
toplfb[CALCXY(lx,ly+240-8)]=__builtin_bswap32(static_cast<uint32_t>(bg));
}
}
for(int ly=0;ly<240-8;ly++) {
for(int lx=0;lx<320;lx++) {
bottomlfb[CALCXY(lx,ly)]=bottomlfb[CALCXY(lx,ly+8)];
}
}
for(int ly=240-8;ly<240;ly++) {
for(int lx=0;lx<320;lx++) {
bottomlfb[CALCXY(lx,ly)]=__builtin_bswap32(static_cast<uint32_t>(bg));
}
}
y--;
}
for(int ly=0;ly<240-8;ly++) {
for(int lx=0;lx<320;lx++) {
bottomlfb[CALCXY(lx,ly)]=bottomlfb[CALCXY(lx,ly+8)];
}
auto Screen::a11puts(const char *s) -> void {
int i=0;
while(s[i])
putChar(s[i]);
}
for(int ly=240-8;ly<240;ly++) {
for(int lx=0;lx<320;lx++) {
bottomlfb[CALCXY(lx,ly)]=__builtin_bswap32(static_cast<uint32_t>(bg));
}
}
y--;
}
auto Screen::a11puts(const char *s) -> void {
int i=0;
while(s[i])
putChar(s[i]);
}
}

View file

@ -8,67 +8,67 @@ extern unsigned int _a9vectors_end;
extern unsigned int _a11vectors_begin;
extern unsigned int _a11vectors_end;
namespace MTGosHAL {
void mainRoutine(void*);
void initScreen(void*);
void testSVC(void*);
void main() {
*a11farg = 0;
*a11fpointer=&mainRoutine;
while(*a11fpointer);
*a11fpointer=&initScreen;
while(*a11fpointer);
unsigned int * output=(unsigned int*)0x08000000;
Screen out;
out << "Waiting for interrupt...\n";
out << "Copying " << &_a9vectors_end-&_a9vectors_begin << " words...\n";
for(int i=0;i<(&_a9vectors_end-&_a9vectors_begin);i++) {
output[i]=(&_a9vectors_begin)[i];
void mainRoutine(void*);
void initScreen(void*);
void testSVC(void*);
void main() {
*a11farg = 0;
*a11fpointer=&mainRoutine;
while(*a11fpointer);
*a11fpointer=&initScreen;
while(*a11fpointer);
unsigned int * output=(unsigned int*)0x08000000;
Screen out;
out << "Waiting for interrupt...\n";
out << "Copying " << &_a9vectors_end-&_a9vectors_begin << " words...\n";
for(int i=0;i<(&_a9vectors_end-&_a9vectors_begin);i++) {
output[i]=(&_a9vectors_begin)[i];
}
asm volatile("svc #0\n");
out << "Did it work?\nSetting up A11 interrupts\n";
output=(unsigned int*)0x1FF80000;
out << "Copying " << &_a11vectors_end-&_a11vectors_begin << " words...\n";
for(int i=0;i<(&_a11vectors_end-&_a11vectors_begin);i++) {
output[i]=(&_a11vectors_begin)[i];
}
out << "Done!\n";
*a11fpointer=&testSVC;
while(*a11fpointer);
out << "Did it work?\n";
for(;;);
}
asm volatile("svc #0\n");
out << "Did it work?\nSetting up A11 interrupts\n";
output=(unsigned int*)0x1FF80000;
out << "Copying " << &_a11vectors_end-&_a11vectors_begin << " words...\n";
for(int i=0;i<(&_a11vectors_end-&_a11vectors_begin);i++) {
output[i]=(&_a11vectors_begin)[i];
}
out << "Done!\n";
*a11fpointer=&testSVC;
while(*a11fpointer);
out << "Did it work?\n";
for(;;);
}
}
extern "C" void init() {
MTGosHAL::main();
MTGosHAL::main();
}
struct cpu_info {
unsigned int pc;
unsigned int r12;
unsigned int r11;
unsigned int r10;
unsigned int r9;
unsigned int r8;
unsigned int r7;
unsigned int r6;
unsigned int r5;
unsigned int r4;
unsigned int r3;
unsigned int r2;
unsigned int r1;
unsigned int retAddr;
unsigned int pc;
unsigned int r12;
unsigned int r11;
unsigned int r10;
unsigned int r9;
unsigned int r8;
unsigned int r7;
unsigned int r6;
unsigned int r5;
unsigned int r4;
unsigned int r3;
unsigned int r2;
unsigned int r1;
unsigned int retAddr;
};
extern "C" void handleINT9(uint32_t stack, uint32_t id) {
MTGosHAL::Screen out;
out << MTGosHAL::Base::HEXADECIMAL << MTGosHAL::FG_color::RED << "Interrupt! " << (int)stack << "-" << (int)id << "\n";
struct cpu_info *cpu=(struct cpu_info*)stack;
out << "handler addr " << (int) cpu->pc << "\n";
out << "R1 " << (int) cpu->r1 << ", R2 " << (int)cpu->r2 << "\n";
out << "R3 " << (int) cpu->r3 << ", R4 " << (int)cpu->r4 << "\n";
out << "R5 " << (int) cpu->r5 << ", R6 " << (int)cpu->r6 << "\n";
out << "R7 " << (int) cpu->r7 << ", R8 " << (int)cpu->r8 << "\n";
out << "R9 " << (int) cpu->r9 << ", SL " << (int)cpu->r10 << "\n";
out << "FP " << (int) cpu->r11 << ", IP " << (int)cpu->r12 << "\n";
out << "SP " << (int) stack << ", PC " << (int)cpu->retAddr << "\n";
if((id!=1)&&(id!=2)&&(id!=4))
for(;;);
MTGosHAL::Screen out;
out << MTGosHAL::Base::HEXADECIMAL << MTGosHAL::FG_color::RED << "Interrupt! " << (int)stack << "-" << (int)id << "\n";
struct cpu_info *cpu=(struct cpu_info*)stack;
out << "handler addr " << (int) cpu->pc << "\n";
out << "R1 " << (int) cpu->r1 << ", R2 " << (int)cpu->r2 << "\n";
out << "R3 " << (int) cpu->r3 << ", R4 " << (int)cpu->r4 << "\n";
out << "R5 " << (int) cpu->r5 << ", R6 " << (int)cpu->r6 << "\n";
out << "R7 " << (int) cpu->r7 << ", R8 " << (int)cpu->r8 << "\n";
out << "R9 " << (int) cpu->r9 << ", SL " << (int)cpu->r10 << "\n";
out << "FP " << (int) cpu->r11 << ", IP " << (int)cpu->r12 << "\n";
out << "SP " << (int) stack << ", PC " << (int)cpu->retAddr << "\n";
if((id!=1)&&(id!=2)&&(id!=4))
for(;;);
}

View file

@ -5,93 +5,93 @@
//1: puts() lock
extern uint32_t *flags;
namespace MTGosHAL {
auto Screen::puts(const char *s) -> void {
auto Screen::puts(const char *s) -> void {
void(**a11fpointer)(void*)=(void(**)(void*))0x1FFFFFF8;
void **a11farg = (void**)0x1FFFFFFC;
int i=0;
while(s[i]) {
if(*flags&1)
putChar(s[i++]);
else {
while(*a11fpointer);
*a11farg=(void*)((unsigned int)s[i++]);
*a11fpointer=(void(*)(void*))&putChar;
}
if(*flags&1)
putChar(s[i++]);
else {
while(*a11fpointer);
*a11farg=(void*)((unsigned int)s[i++]);
*a11fpointer=(void(*)(void*))&putChar;
}
}
}
auto Screen::clrscr() -> void {
void(**a11fpointer)(void*)=(void(**)(void*))0x1FFFFFF8;
while(*a11fpointer);
*a11fpointer=(void(*)(void*))(clrscr_impl);
}
auto Screen::scroll() -> void {
void(**a11fpointer)(void*)=(void(**)(void*))0x1FFFFFF8;
while(*a11fpointer);
*a11fpointer=(void(*)(void*))(scroll_impl);
}
template <>
auto Screen::operator<<<FG_color>(FG_color fg) -> Screen &{
fg=fg;
return *this;
}
template <>
auto Screen::operator<<<BG_color>(BG_color bg) -> Screen &{
bg=bg;
return *this;
}
auto Screen::setColor(FG_color fg) -> Screen &{
fg=fg;
return *this;
}
auto Screen::setColor(BG_color bg) -> Screen &{
bg=bg;
return *this;
}
auto Screen::setColor(FG_color fg, BG_color bg) -> Screen &{
return (*this).setColor(fg).setColor(bg);
}
}
auto Screen::clrscr() -> void {
void(**a11fpointer)(void*)=(void(**)(void*))0x1FFFFFF8;
while(*a11fpointer);
*a11fpointer=(void(*)(void*))(clrscr_impl);
}
auto Screen::scroll() -> void {
void(**a11fpointer)(void*)=(void(**)(void*))0x1FFFFFF8;
while(*a11fpointer);
*a11fpointer=(void(*)(void*))(scroll_impl);
}
template <>
auto Screen::operator<<<FG_color>(FG_color fg) -> Screen &{
fg=fg;
return *this;
}
template <>
auto Screen::operator<<<BG_color>(BG_color bg) -> Screen &{
bg=bg;
return *this;
}
auto Screen::setColor(FG_color fg) -> Screen &{
fg=fg;
return *this;
}
auto Screen::setColor(BG_color bg) -> Screen &{
bg=bg;
return *this;
}
auto Screen::setColor(FG_color fg, BG_color bg) -> Screen &{
return (*this).setColor(fg).setColor(bg);
}
template <>
auto Screen::operator<<<Base>(Base output) -> Screen & {
base=static_cast<int>(output);
return *this;
}
template <>
auto Screen::operator<<<int>(int op) -> Screen & {
uintptr_t output=op;
const char* chars="0123456789ABCDEF";
char buf[33];
buf[32]='\0';
char* ptr=buf+31;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Screen::operator<<<long int>(long int op) -> Screen & {
uint64_t output=op;
const char* chars="0123456789ABCDEF";
char buf[65];
buf[64]='\0';
char* ptr=buf+63;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Screen::operator<<<char>(char output) -> Screen & {
putChar(output);
return *this;
}
template <>
auto Screen::operator<<<char*>(char* output) -> Screen & {
puts(output);
return *this;
}
auto Screen::operator<<<Base>(Base output) -> Screen & {
base=static_cast<int>(output);
return *this;
}
template <>
auto Screen::operator<<<int>(int op) -> Screen & {
uintptr_t output=op;
const char* chars="0123456789ABCDEF";
char buf[33];
buf[32]='\0';
char* ptr=buf+31;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Screen::operator<<<long int>(long int op) -> Screen & {
uint64_t output=op;
const char* chars="0123456789ABCDEF";
char buf[65];
buf[64]='\0';
char* ptr=buf+63;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Screen::operator<<<char>(char output) -> Screen & {
putChar(output);
return *this;
}
template <>
auto Screen::operator<<<char*>(char* output) -> Screen & {
puts(output);
return *this;
}
}

View file

@ -18,47 +18,47 @@
#define DRV 6
#define CMD 7
namespace MTGosHAL {
BlockDevice::BlockDevice(): numDevices(0), ata0(0x1F0,0), ata1(0x170,1), ata2(0x1E8,2), ata3(0x168,3) {
BlockDevice::BlockDevice(): numDevices(0), ata0(0x1F0,0), ata1(0x170,1), ata2(0x1E8,2), ata3(0x168,3) {
if(getDriveCnt()==0) {
//err<<"Not a single device was found!\n";
//err<<"Not a single device was found!\n";
}
}
auto BlockDevice::getDriveCnt() -> int32_t {return ata0.getDriveCnt()+ata1.getDriveCnt()+ata2.getDriveCnt()+ata3.getDriveCnt();}
auto BlockDevice::getDriveNumByName(const char * name) -> int32_t {
}
auto BlockDevice::getDriveCnt() -> int32_t {return ata0.getDriveCnt()+ata1.getDriveCnt()+ata2.getDriveCnt()+ata3.getDriveCnt();}
auto BlockDevice::getDriveNumByName(const char * name) -> int32_t {
int32_t tmp;
if((tmp=ata0.getDriveNumByName(name))!=-1)
return tmp;
return tmp;
else if((tmp=ata1.getDriveNumByName(name))!=-1)
return tmp+ata0.getDriveCnt();
return tmp+ata0.getDriveCnt();
else if((tmp=ata2.getDriveNumByName(name))!=-1)
return tmp+ata0.getDriveCnt()+ata1.getDriveCnt();
return tmp+ata0.getDriveCnt()+ata1.getDriveCnt();
else if((tmp=ata3.getDriveNumByName(name))!=-1)
return tmp+ata0.getDriveCnt()+ata1.getDriveCnt()+ata2.getDriveCnt();
return tmp+ata0.getDriveCnt()+ata1.getDriveCnt()+ata2.getDriveCnt();
else return -1;
}
BlockDevice::~BlockDevice() {};
auto BlockDevice::readSector(int32_t drv, uint64_t sectorNum, uint8_t *buf) -> void {
}
BlockDevice::~BlockDevice() {};
auto BlockDevice::readSector(int32_t drv, uint64_t sectorNum, uint8_t *buf) -> void {
ata0.readSector(drv, sectorNum, buf);
ata1.readSector(drv, sectorNum, buf);
ata2.readSector(drv, sectorNum, buf);
ata3.readSector(drv, sectorNum, buf);
}
auto BlockDevice::readSector(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
}
auto BlockDevice::readSector(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
ata0.readSector(drv, sectorNum, num, buf);
ata1.readSector(drv, sectorNum, num, buf);
ata2.readSector(drv, sectorNum, num, buf);
ata3.readSector(drv, sectorNum, num, buf);
}
auto BlockDevice::writeSector(int32_t drv, uint64_t sectorNum, uint8_t *buf) -> void {
}
auto BlockDevice::writeSector(int32_t drv, uint64_t sectorNum, uint8_t *buf) -> void {
ata0.writeSector(drv, sectorNum, buf);
ata1.writeSector(drv, sectorNum, buf);
ata2.writeSector(drv, sectorNum, buf);
ata3.writeSector(drv, sectorNum, buf);
}
auto BlockDevice::writeSector(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
}
auto BlockDevice::writeSector(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
ata0.writeSector(drv, sectorNum, num, buf);
ata1.writeSector(drv, sectorNum, num, buf);
ata2.writeSector(drv, sectorNum, num, buf);
ata3.writeSector(drv, sectorNum, num, buf);
}
}
}

View file

@ -19,22 +19,22 @@
#define CMD 7
#define ALTCMD 0x206
namespace MTGosHAL {
IDE::IDE(uint16_t baseport, uint8_t num): baseport(baseport), num(num), existent(0), numDevices(0) {
IDE::IDE(uint16_t baseport, uint8_t num): baseport(baseport), num(num), existent(0), numDevices(0) {
if(inb(baseport+CMD)!=0xFF) { //Does the ATA controller return floating bus?
// Checking existence of the master
outb(baseport+DRV, 0xE0);
outb(baseport+LBAlo,0x55);
if(inb(baseport+LBAlo)==0x55) {
existent|=1;
numDevices++;
}
// Checking existence of the slave
outb(baseport+DRV, 0xF0);
outb(baseport+LBAlo,0x55);
if(inb(baseport+LBAlo)==0x55) {
existent|=2;
numDevices++;
}
// Checking existence of the master
outb(baseport+DRV, 0xE0);
outb(baseport+LBAlo,0x55);
if(inb(baseport+LBAlo)==0x55) {
existent|=1;
numDevices++;
}
// Checking existence of the slave
outb(baseport+DRV, 0xF0);
outb(baseport+LBAlo,0x55);
if(inb(baseport+LBAlo)==0x55) {
existent|=2;
numDevices++;
}
} else {
//err << "ATA device could not be found!\n";
}
@ -43,31 +43,31 @@ namespace MTGosHAL {
inb(baseport+CMD);
inb(baseport+CMD);
outb(baseport+ALTCMD,0x00);
}
auto IDE::getDriveCnt() -> int32_t {return numDevices;}
auto IDE::getDriveNumByName(const char* name) -> int32_t {
}
auto IDE::getDriveCnt() -> int32_t {return numDevices;}
auto IDE::getDriveNumByName(const char* name) -> int32_t {
if(strlen(name)!=5)
return -1; //Format is ATA[0-3][sm] (regex)
return -1; //Format is ATA[0-3][sm] (regex)
if((name[0]!=name[2])||(name[2]!='A'))
return -1;
return -1;
if(name[1]!='T')
return -1;
return -1;
int32_t drivenum=name[3]-0x30;
if(drivenum!=num)
return -1;
return -1;
if((name[4]!='s')&&(name[4]!='m'))
return -1;
return -1;
drivenum<<=1;
drivenum+=(name[4]=='s')?1:0;
if(!(existent&(1<<drivenum)))
return -1;
return -1;
return drivenum;
}
auto IDE::readSector(int32_t drive, uint64_t sectorNum, uint8_t *buf) -> void {
}
auto IDE::readSector(int32_t drive, uint64_t sectorNum, uint8_t *buf) -> void {
if(drive<(num*2)||drive>(num*2+1))
return;
return;
if(!(existent&(1<<(drive-num*2))))
return;
return;
while(inb(baseport+ALTCMD)&ATAPIO_BSY);
outb(baseport+DRV, 0x40 | (drive&1)<<4);
outb(baseport+SECTOR_CNT, 0);
@ -85,12 +85,12 @@ namespace MTGosHAL {
while(inb(baseport+CMD)&0x80);
uint16_t *bufw=(uint16_t *)buf;
asm volatile ("rep insw" : : "D"((int)bufw),"d"(baseport),"c"(256));
}
auto IDE::readSector(int32_t drive, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
}
auto IDE::readSector(int32_t drive, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
if(drive<(this->num*2)||drive>(this->num*2+1))
return;
return;
if(!(existent&(1<<(drive-this->num*2))))
return;
return;
if(num==0)
return;
if(num>65536)
@ -114,12 +114,12 @@ namespace MTGosHAL {
while(inb(baseport+CMD)&0x80);
uint16_t *bufw=(uint16_t *)buf;
asm volatile ("rep insw" : : "D"((int)bufw),"d"(baseport),"c"(256*num));
}
auto IDE::writeSector(int32_t drive, uint64_t sectorNum, uint8_t *buf) -> void {
}
auto IDE::writeSector(int32_t drive, uint64_t sectorNum, uint8_t *buf) -> void {
if(drive<(this->num*2)||drive>(this->num*2+1))
return;
return;
if(!(existent&(1<<(drive-this->num*2))))
return;
return;
while(inb(baseport+ALTCMD)&ATAPIO_BSY);
outb(baseport+SECTOR_CNT, (uint8_t)(0));
outb(baseport+LBAlo, (uint8_t)(sectorNum>>24));
@ -138,11 +138,11 @@ namespace MTGosHAL {
asm volatile("outsw; aad" : : "S"((int)buf),"d"(baseport),"a"(8787)); //The AAD is for creating a short delay between writes, as the compiler might unroll this loop.
}
}
auto IDE::writeSector(int32_t drive, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
auto IDE::writeSector(int32_t drive, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
if(drive<(this->num*2)||drive>(this->num*2+1))
return;
return;
if(!(existent&(1<<(drive-this->num*2))))
return;
return;
if(num==0)
return;
if(num>65536)

View file

@ -11,18 +11,18 @@ auto schedule(struct cpu_state* cpu) -> struct cpu_state* {
}
Multitasking::Multitasking(): curr_task(nullptr), first_task(nullptr)
{
for(int i=0;i<32;i++) {
if(i==2)
continue;
tss[i]=0;
}
tss[2]=0x10;
for(int i=0;i<32;i++) {
if(i==2)
continue;
tss[i]=0;
}
tss[2]=0x10;
//task_states[0] = initTask(stack_a, user_stack_a, task_a);
//task_states[1] = initTask(stack_b, user_stack_b, task_b);
if(!idt.request(0x20,MTGosHAL::schedule)) {
err << "Could not start multitasking\nFatal error; Kernel halted!\n";
while(true)
asm volatile("cli; hlt");
asm volatile("cli; hlt");
}
}
auto Multitasking::initTask(void(* entry)()) -> struct cpu_state*
@ -59,24 +59,24 @@ auto Multitasking::initTask(void(* entry)()) -> struct cpu_state*
//Create new task class
Task* task = new Task(state);
if(first_task)
first_task->addTask(task);
first_task->addTask(task);
else {
first_task=task;
first_task=task;
}
return state;
}
auto Multitasking::schedule(struct cpu_state* cpu) -> struct cpu_state*
{
Task* next=nullptr;
if(curr_task) {
next=curr_task->pause(cpu);
}
if (!next) {
next=first_task;
}
curr_task=next;
struct cpu_state* cpu_state=next->unpause();
MTGosHAL::tasks.tss[1] = (uint32_t) (cpu_state + 1);
return cpu_state;
Task* next=nullptr;
if(curr_task) {
next=curr_task->pause(cpu);
}
if (!next) {
next=first_task;
}
curr_task=next;
struct cpu_state* cpu_state=next->unpause();
MTGosHAL::tasks.tss[1] = (uint32_t) (cpu_state + 1);
return cpu_state;
}
} // namespace MTGosHAL

View file

@ -2,20 +2,20 @@
#include <gdt.hpp>
#include <serial.hpp>
namespace MTGosHAL {
GDT::GDT() {
gdt[0]=gdt[1]=gdt[2]=gdt[3]=gdt[4]=gdt[5]=gdt[6]=0x0ull;
}
auto GDT::setEntry(int i, unsigned int base, unsigned int limit, int flags) -> void {
gdt[i] = limit & 0xffffLL;
gdt[i] |= (base & 0xffffffLL) << 16;
gdt[i] |= (flags & 0xffLL) << 40;
gdt[i] |= ((limit >> 16) & 0xfLL) << 48;
gdt[i] |= ((flags >> 8 )& 0xffLL) << 52;
gdt[i] |= ((base >> 24) & 0xffLL) << 56;
}
auto GDT::apply() -> void {
debug << "We are now trying to set our GDT. If the CPU triplefaults, something went wrong in MTGosHAL::GDT::apply() or loadGDT().\n";
fin={(uint16_t)7*8-1, (void*)gdt};
loadGDT((void*)(&fin));
};
GDT::GDT() {
gdt[0]=gdt[1]=gdt[2]=gdt[3]=gdt[4]=gdt[5]=gdt[6]=0x0ull;
}
auto GDT::setEntry(int i, unsigned int base, unsigned int limit, int flags) -> void {
gdt[i] = limit & 0xffffLL;
gdt[i] |= (base & 0xffffffLL) << 16;
gdt[i] |= (flags & 0xffLL) << 40;
gdt[i] |= ((limit >> 16) & 0xfLL) << 48;
gdt[i] |= ((flags >> 8 )& 0xffLL) << 52;
gdt[i] |= ((base >> 24) & 0xffLL) << 56;
}
auto GDT::apply() -> void {
debug << "We are now trying to set our GDT. If the CPU triplefaults, something went wrong in MTGosHAL::GDT::apply() or loadGDT().\n";
fin={(uint16_t)7*8-1, (void*)gdt};
loadGDT((void*)(&fin));
};
}

View file

@ -7,85 +7,85 @@
auto syscall(uint32_t syscall_num, void* handle, void* args) -> void*;
extern void** progs;
namespace MTGosHAL {
IDT::IDT() {
//Init PIC
outb(0x20, 0x11); //Init Master-PIC
outb(0x21, 0x20); //Interrupt number for IRQ0
outb(0x21, 0x04); //IRQ is the Slave
outb(0x21, 0x01); //ICW 4
outb(0xA0, 0x11); //Init Master-PIC
outb(0xA1, 0x28); //Interrupt number for IRQ8
outb(0xA1, 0x02); //IRQ is the Slave
outb(0xA1, 0x01); //ICW 4
//Activate IRQ's
outb(0x21, 0x00);
outb(0xA1, 0x00);
}
auto IDT::setEntry(int i, void* offset, uint16_t seg, uint8_t flags) -> void {
idt[i]=(uint16_t)((uint32_t)offset);
idt[i]|=(uint64_t)(((uint32_t)offset)>>16)<<48;
idt[i]|=((uint64_t)seg)<<16;
idt[i]|=((uint64_t)flags)<<40;
}
auto IDT::apply() -> void {
debug << "Now trying to load the IDT.\n";
idtptr.limit=(uint16_t)(256*8-1);
idtptr.pointer=(uint64_t*)&idt;
loadIDT((void*)&idtptr);
}
auto IDT::handle(struct cpu_state* cpu) -> struct cpu_state* {
IDT::IDT() {
//Init PIC
outb(0x20, 0x11); //Init Master-PIC
outb(0x21, 0x20); //Interrupt number for IRQ0
outb(0x21, 0x04); //IRQ is the Slave
outb(0x21, 0x01); //ICW 4
outb(0xA0, 0x11); //Init Master-PIC
outb(0xA1, 0x28); //Interrupt number for IRQ8
outb(0xA1, 0x02); //IRQ is the Slave
outb(0xA1, 0x01); //ICW 4
//Activate IRQ's
outb(0x21, 0x00);
outb(0xA1, 0x00);
}
auto IDT::setEntry(int i, void* offset, uint16_t seg, uint8_t flags) -> void {
idt[i]=(uint16_t)((uint32_t)offset);
idt[i]|=(uint64_t)(((uint32_t)offset)>>16)<<48;
idt[i]|=((uint64_t)seg)<<16;
idt[i]|=((uint64_t)flags)<<40;
}
auto IDT::apply() -> void {
debug << "Now trying to load the IDT.\n";
idtptr.limit=(uint16_t)(256*8-1);
idtptr.pointer=(uint64_t*)&idt;
loadIDT((void*)&idtptr);
}
auto IDT::handle(struct cpu_state* cpu) -> struct cpu_state* {
struct cpu_state* new_cpu=cpu;
debug << "Interrupt 0x" << Base::HEXADECIMAL << (int) cpu->intr << " was raised.\n";
if(cpu->intr<=0x1F) {
err << "Exception 0x" << Base::HEXADECIMAL << (int) cpu->intr << "! Kernel halted!\n";
err << "EAX = 0x" << (int)cpu->eax << " - EBX = 0x" << (int)cpu->ebx << "\n";
err << "ECX = 0x" << (int)cpu->ecx << " - EDX = 0x" << (int)cpu->edx << "\n";
err << "ESI = 0x" << (int)cpu->esi << " - EDI = 0x" << (int)cpu->edi << "\n";
err << "SS:ESP = 0x" << (int)cpu->ss << ":0x" << (int)cpu->esp << " - SS:EBP = 0x" << (int)cpu->ss << ":0x" << (int)cpu->ebp << "\n";
err << "CS:EIP = 0x" << (int)cpu->cs << ":0x" << (int)cpu->eip << " - INTR:ERR = 0x" << (int)cpu->intr << ":0x" << (int)cpu->error << "\n";
err << "------ END OF REGISTER DUMP ------ ------ START OF PROGRAM LOADPOINTS ------\n";
for(int i=0;i<1024;i++) {
if(!progs[i])
break;
err << "0x" << (int)((uint32_t)progs[i]) << "; ";
}
err << "\n";
uint16_t counter = 1193180 / 220; //Make an annoying beep
outb(0x43, 0xB6);
outb(0x42, (uint8_t)counter);
outb(0x42, (uint8_t)(counter>>8));
outb(0x61, inb(0x61) | 3);
while(1) {
asm volatile("cli; hlt");
}
} else if(cpu->intr >= 0x20 && cpu->intr <= 0x2F) {
if(cpu->intr >= 0x28) {
outb(0xA0, 0x20);
}
outb(0x20, 0x20);
debug << "The IRQ " << Base::DECIMAL << (int) cpu->intr-0x20 << " was handled.\n";
if(cpu->intr==0x20) {
debug.debug();
}
}
for(int i=0;i<16;i++) {
if(ivt[cpu->intr][i])
new_cpu=ivt[cpu->intr][i](new_cpu);
}
if(cpu->intr>=48)
new_cpu->eax=(uint32_t)(::syscall(cpu->eax, (void*)(cpu->ebx), (void*)(cpu->esp)));
return new_cpu;
}
auto IDT::request(uint8_t intr, struct cpu_state* (*handler)(struct cpu_state*)) -> bool {
for(int i=0;i<16;i++) {
if(ivt[intr][i])
continue;
ivt[intr][i]=handler;
return true;
}
return false;
}
debug << "Interrupt 0x" << Base::HEXADECIMAL << (int) cpu->intr << " was raised.\n";
if(cpu->intr<=0x1F) {
err << "Exception 0x" << Base::HEXADECIMAL << (int) cpu->intr << "! Kernel halted!\n";
err << "EAX = 0x" << (int)cpu->eax << " - EBX = 0x" << (int)cpu->ebx << "\n";
err << "ECX = 0x" << (int)cpu->ecx << " - EDX = 0x" << (int)cpu->edx << "\n";
err << "ESI = 0x" << (int)cpu->esi << " - EDI = 0x" << (int)cpu->edi << "\n";
err << "SS:ESP = 0x" << (int)cpu->ss << ":0x" << (int)cpu->esp << " - SS:EBP = 0x" << (int)cpu->ss << ":0x" << (int)cpu->ebp << "\n";
err << "CS:EIP = 0x" << (int)cpu->cs << ":0x" << (int)cpu->eip << " - INTR:ERR = 0x" << (int)cpu->intr << ":0x" << (int)cpu->error << "\n";
err << "------ END OF REGISTER DUMP ------ ------ START OF PROGRAM LOADPOINTS ------\n";
for(int i=0;i<1024;i++) {
if(!progs[i])
break;
err << "0x" << (int)((uint32_t)progs[i]) << "; ";
}
err << "\n";
uint16_t counter = 1193180 / 220; //Make an annoying beep
outb(0x43, 0xB6);
outb(0x42, (uint8_t)counter);
outb(0x42, (uint8_t)(counter>>8));
outb(0x61, inb(0x61) | 3);
while(1) {
asm volatile("cli; hlt");
}
} else if(cpu->intr >= 0x20 && cpu->intr <= 0x2F) {
if(cpu->intr >= 0x28) {
outb(0xA0, 0x20);
}
outb(0x20, 0x20);
debug << "The IRQ " << Base::DECIMAL << (int) cpu->intr-0x20 << " was handled.\n";
if(cpu->intr==0x20) {
debug.debug();
}
}
for(int i=0;i<16;i++) {
if(ivt[cpu->intr][i])
new_cpu=ivt[cpu->intr][i](new_cpu);
}
if(cpu->intr>=48)
new_cpu->eax=(uint32_t)(::syscall(cpu->eax, (void*)(cpu->ebx), (void*)(cpu->esp)));
return new_cpu;
}
auto IDT::request(uint8_t intr, struct cpu_state* (*handler)(struct cpu_state*)) -> bool {
for(int i=0;i<16;i++) {
if(ivt[intr][i])
continue;
ivt[intr][i]=handler;
return true;
}
return false;
}
}
extern "C" void* handleINT(void* cpu) {
return (void*)MTGosHAL::idt.handle((MTGosHAL::cpu_state*)cpu);
return (void*)MTGosHAL::idt.handle((MTGosHAL::cpu_state*)cpu);
}

View file

@ -25,12 +25,12 @@ namespace MTGosHAL {
BlockDevice disk;
void main(int eax, struct multiboot_info* ebx) {
//Init debug output
new (&debug) Serial();
debug << "Hello debugger! This is MTGos v00r01\nThese logs are probably very long, so please redirect the output to a file.\n";
new (&debug) Serial();
debug << "Hello debugger! This is MTGos v00r01\nThese logs are probably very long, so please redirect the output to a file.\n";
debug << "Init GDT\n";
new (&gdt) GDT();
gdt.setEntry(0, 0, 0, 0);
debug << "Init GDT\n";
new (&gdt) GDT();
gdt.setEntry(0, 0, 0, 0);
gdt.setEntry(1, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT);
gdt.setEntry(2, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT);
gdt.setEntry(3, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
@ -39,51 +39,51 @@ namespace MTGosHAL {
gdt.setEntry(6, 0, 0xfffff, GDT_FLAG_RING3 | GDT_FLAG_TSS | GDT_FLAG_PRESENT);
gdt.apply();
debug << "Init IDT\n";
new (&idt) IDT();
for(int i=0;i<256;i++) {
debug << "Init IDT\n";
new (&idt) IDT();
for(int i=0;i<256;i++) {
idt.setEntry(i, (void *)((uint32_t)&intr_stub_0+i*16), SEG_KERNEL, IDT_INTERRUPT_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED);
}
idt.setEntry(48, (void *)((uint32_t)&intr_stub_0+768), SEG_KERNEL, IDT_TRAP_GATE | IDT_SEG_32_BIT | IDT_RING_3 | IDT_USED);
idt.setEntry(8, (void *)((uint32_t)&intr_stub_0+128), SEG_DBL_FAULT, IDT_TASK_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED);
idt.apply();
asm volatile("ltr %%ax" : : "a"(5<<3));
debug << "Init MM\n";
new (&mm) PMM(ebx);
asm volatile("ltr %%ax" : : "a"(5<<3));
debug << "Init MM\n";
new (&mm) PMM(ebx);
debug << "Init Screen output\n";
new (&out) Screen(ebx);
new (&err) Screen(ebx);
debug << "Init Screen output\n";
new (&out) Screen(ebx);
new (&err) Screen(ebx);
out << BG_color::BLACK << FG_color::WHITE << "Loading MTGos...\n";
err << BG_color::BLACK << FG_color::RED;
debug << "Init Keyboard\n";
new (&in) Keyboard();
debug << "Init Keyboard\n";
new (&in) Keyboard();
debug << "Init Multitasking\n";
new (&tasks) Multitasking();
debug << "Init Disk\n";
new (&disk) BlockDevice();
debug << "Init Disk\n";
new (&disk) BlockDevice();
debug << "Kernel initialized\n";
debug << "Kernel initialized\n";
if(eax!=0x2BADB002)
err << "System wasn't loaded by a Multiboot-conformant launcher!\n";
multiboot_mod_list *mods = (multiboot_mod_list*) ebx->mods_addr;
multiboot_mod_list *mods = (multiboot_mod_list*) ebx->mods_addr;
progs=(void**)mm.alloc(4096);
for(int i=0;i<1024;i++) {
progs[i]=nullptr;
}
for(int i=0;i<1024;i++) {
progs[i]=nullptr;
}
for(uint32_t i=0;i<(ebx->mods_count<1023?ebx->mods_count:1023);i++) { //Basically until MIN(ebx->mods_count, 1023), as we only support loading up to 1023 programs directly.
progs[i]=(void*)(mods[i].mod_start);
debug << "Found module!\n";
}
::main(progs, debug, mm, out, err, in, tasks, disk);
uint8_t buf[512];
disk.readSector(disk.getDriveNumByName("ATA0m"),0,buf);
out << (char*)buf;
out << "こんにちは、ユニコード。\nЗдравствуй, Юникод.\nΓεια σου, Γιούνικοντ.\n안녕하세요, 유니코드.\n"_s;
//sti();
uint8_t buf[512];
disk.readSector(disk.getDriveNumByName("ATA0m"),0,buf);
out << (char*)buf;
out << "こんにちは、ユニコード。\nЗдравствуй, Юникод.\nΓεια σου, Γιούνικοντ.\n안녕하세요, 유니코드.\n"_s;
sti();
for(;;);
}
}

View file

@ -5,124 +5,124 @@
#include <keymap_DE.hpp>
namespace MTGosHAL {
auto handleIRQ(struct cpu_state* cpu) -> struct cpu_state* {
return in.handleIRQ1(cpu);
}
auto Keyboard::getChar() -> char {
char chr=buf[0];
for(int i=0;i<15;i++) {
buf[i]=buf[i+1];
}
buf[15]='\0';
if(len)
len--;
return chr;
}
auto Keyboard::sendCommand(uint8_t command) -> void {
while((inb(0x64) & 0x2));
outb(0x60, command);
}
auto Keyboard::handleIRQ1(struct cpu_state* cpu) -> struct cpu_state* {
uint8_t keycode=0,scancode=inb(0x60);
if(scancode==0xFA) {
response=false;
return cpu;
} else if(response && scancode == 0xFE) {
sendCommand(0xED);
outb(0x60, (scrolllock) + (numlock<<1) + (capslock<<2));
return cpu;
}
debug << "Keyboard interrupt received.\nGot: 0x" << Base::HEXADECIMAL << (int)scancode;
bool break_code=false;
static bool e0_code=false;
static int e1_code=0;
static uint16_t e1_prev=0;
uint8_t tableID=0;
if((scancode & 0x80 ) && (e1_code || (scancode != 0xE1)) && (e0_code || (scancode != 0xE0))) {
break_code = true;
scancode &= ~0x80;
}
if(e0_code) {
if((scancode==0x2A) || (scancode = 0x36)) {
e0_code = false;
return cpu;
}
keycode=keyboardKeycodes[1][scancode];
e0_code=false;
} else if (e1_code == 2) {
e1_prev |= ((uint16_t) scancode << 8);
//TODO. translate it, although I might not even use this code
return cpu;
} else if (e1_code) {
e1_prev = scancode;
e1_code++;
return cpu;
} else if (scancode == 0xE0) {
e0_code = true;
return cpu;
} else if (scancode == 0xE1) {
e1_code = true;
return cpu;
} else {
keycode=keyboardKeycodes[0][scancode];
}
//Now put it into the keystate array
if(break_code)
keydowns[keycode]=false;
else
keydowns[keycode]=true;
//0x2A 0x36 = Shift
if(keydowns[0x2A] || keydowns[0x36])
tableID^=1;
//0x1D = Ctrl
if(keydowns[0x1D])
tableID^=2;
//0x38 = Alt
if(keydowns[0x38])
tableID^=4;
auto handleIRQ(struct cpu_state* cpu) -> struct cpu_state* {
return in.handleIRQ1(cpu);
}
auto Keyboard::getChar() -> char {
char chr=buf[0];
for(int i=0;i<15;i++) {
buf[i]=buf[i+1];
}
buf[15]='\0';
if(len)
len--;
return chr;
}
auto Keyboard::sendCommand(uint8_t command) -> void {
while((inb(0x64) & 0x2));
outb(0x60, command);
}
auto Keyboard::handleIRQ1(struct cpu_state* cpu) -> struct cpu_state* {
uint8_t keycode=0,scancode=inb(0x60);
if(scancode==0xFA) {
response=false;
return cpu;
} else if(response && scancode == 0xFE) {
sendCommand(0xED);
outb(0x60, (scrolllock) + (numlock<<1) + (capslock<<2));
return cpu;
}
debug << "Keyboard interrupt received.\nGot: 0x" << Base::HEXADECIMAL << (int)scancode;
bool break_code=false;
static bool e0_code=false;
static int e1_code=0;
static uint16_t e1_prev=0;
uint8_t tableID=0;
if((scancode & 0x80 ) && (e1_code || (scancode != 0xE1)) && (e0_code || (scancode != 0xE0))) {
break_code = true;
scancode &= ~0x80;
}
if(e0_code) {
if((scancode==0x2A) || (scancode = 0x36)) {
e0_code = false;
return cpu;
}
keycode=keyboardKeycodes[1][scancode];
e0_code=false;
} else if (e1_code == 2) {
e1_prev |= ((uint16_t) scancode << 8);
//TODO. translate it, although I might not even use this code
return cpu;
} else if (e1_code) {
e1_prev = scancode;
e1_code++;
return cpu;
} else if (scancode == 0xE0) {
e0_code = true;
return cpu;
} else if (scancode == 0xE1) {
e1_code = true;
return cpu;
} else {
keycode=keyboardKeycodes[0][scancode];
}
//Now put it into the keystate array
if(break_code)
keydowns[keycode]=false;
else
keydowns[keycode]=true;
//0x2A 0x36 = Shift
if(keydowns[0x2A] || keydowns[0x36])
tableID^=1;
//0x1D = Ctrl
if(keydowns[0x1D])
tableID^=2;
//0x38 = Alt
if(keydowns[0x38])
tableID^=4;
//0x45 = Numlock
if(keycode==0x45)
numlock=!numlock;
//0x3A = CAPS
if(keycode==0x3A)
capslock=!capslock;
//0x46 = Scrolllock
if(keycode==0x46)
scrolllock=!scrolllock;
//0x45 = Numlock
if(keycode==0x45)
numlock=!numlock;
//0x3A = CAPS
if(keycode==0x3A)
capslock=!capslock;
//0x46 = Scrolllock
if(keycode==0x46)
scrolllock=!scrolllock;
if(capslock)
tableID^=1;
//Correct the LEDs
sendCommand(0xED);
outb(0x60, (scrolllock) + (numlock<<1) + (capslock<<2));
response=true;
//Convert it into a char
if(!break_code)
out << keymap[tableID][keycode];
debug << " -> 0x" << (int)keycode << ".\n";
return cpu;
}
Keyboard::Keyboard(): numlock(true), capslock(false), scrolllock(false), response(false) {
if(!idt.request(0x21, (struct cpu_state*(*)(struct cpu_state*))&handleIRQ)) {
debug << "Could not get an handler for IRQ1 (Keyboard)\n";
return;
}
//Clear keyboard buffer
while(inb(0x64) & 0x1) {
inb(0x60);
}
sendCommand(0xF4); //Activate keyboard
//Check for self-test being passed
sendCommand(0x20);
uint8_t ccb=inb(0x60);
if((ccb&4)) {
ccb &= ~1;
} else {
debug << "Keyboard didn't pass self-test!\nDeactivating IRQ1.\n";
ccb |= 1;
}
sendCommand(0x60);
outb(0x64, ccb);
}
if(capslock)
tableID^=1;
//Correct the LEDs
sendCommand(0xED);
outb(0x60, (scrolllock) + (numlock<<1) + (capslock<<2));
response=true;
//Convert it into a char
if(!break_code)
out << keymap[tableID][keycode];
debug << " -> 0x" << (int)keycode << ".\n";
return cpu;
}
Keyboard::Keyboard(): numlock(true), capslock(false), scrolllock(false), response(false) {
if(!idt.request(0x21, (struct cpu_state*(*)(struct cpu_state*))&handleIRQ)) {
debug << "Could not get an handler for IRQ1 (Keyboard)\n";
return;
}
//Clear keyboard buffer
while(inb(0x64) & 0x1) {
inb(0x60);
}
sendCommand(0xF4); //Activate keyboard
//Check for self-test being passed
sendCommand(0x20);
uint8_t ccb=inb(0x60);
if((ccb&4)) {
ccb &= ~1;
} else {
debug << "Keyboard didn't pass self-test!\nDeactivating IRQ1.\n";
ccb |= 1;
}
sendCommand(0x60);
outb(0x64, ccb);
}
}

View file

@ -3,52 +3,52 @@
#include <serial.hpp>
#include <textDISP.hpp>
namespace MTGosHAL {
auto Output::puts(const char* s) -> void {
int i=0;
while(s[i]!='\0')
putChar(s[i++]);
}
template <>
auto Output::operator<<<Base>(Base output) -> Output & {
base=static_cast<int>(output);
return *this;
}
template <>
auto Output::operator<<<int>(int op) -> Output & {
uintptr_t output=op;
const char* chars="0123456789ABCDEF";
char buf[33];
buf[32]='\0';
char* ptr=buf+31;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Output::operator<<<long int>(long int op) -> Output & {
uint64_t output=op;
const char* chars="0123456789ABCDEF";
char buf[65];
buf[64]='\0';
char* ptr=buf+63;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Output::operator<<<char>(char output) -> Output & {
putChar(output);
return *this;
}
template <>
auto Output::operator<<<char*>(char* output) -> Output & {
puts(output);
return *this;
}
auto Output::puts(const char* s) -> void {
int i=0;
while(s[i]!='\0')
putChar(s[i++]);
}
template <>
auto Output::operator<<<Base>(Base output) -> Output & {
base=static_cast<int>(output);
return *this;
}
template <>
auto Output::operator<<<int>(int op) -> Output & {
uintptr_t output=op;
const char* chars="0123456789ABCDEF";
char buf[33];
buf[32]='\0';
char* ptr=buf+31;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Output::operator<<<long int>(long int op) -> Output & {
uint64_t output=op;
const char* chars="0123456789ABCDEF";
char buf[65];
buf[64]='\0';
char* ptr=buf+63;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Output::operator<<<char>(char output) -> Output & {
putChar(output);
return *this;
}
template <>
auto Output::operator<<<char*>(char* output) -> Output & {
puts(output);
return *this;
}
}

View file

@ -1,78 +1,78 @@
#include <base.hpp>
#include <serial.hpp>
namespace MTGosHAL {
auto Serial::isTransmitEmpty() -> int {
return inb(port+SERIAL_LSR)&0x20;
}
auto Serial::putChar(char chr) -> void {
// if(!works)
return;
int tries=65535;
while(!isTransmitEmpty()) {
waittimes++;
tries--;
if(!tries){
works=false;
return;
}
}
outb(port, chr);
transmits++;
}
auto Serial::serial_received() -> int {
return inb(port+SERIAL_LSR)&1;
}
auto Serial::getChar() -> char {
//We try 500 times to get a character
int tries=500;
while(!serial_received()) {
tries--;
waittimes++;
if(!tries) {
return '\0';
}
}
transmits++;
char chr = inb(port);
if(chr!='\r')
*this << chr;
else
*this << '\n';
return chr;
}
Serial::Serial(): works(true) {
uint32_t baud=115200;
port=*((uint16_t*)0x0400);
union {
uint8_t b[2];
uint16_t w;
} divisor;
divisor.w = 115200/baud;
//Turn off interrupts
outb(port+SERIAL_IER, 0x00);
//Set DLAB-bit
outb(port+SERIAL_LCR, 0x80);
//Set baud divisor
outb(port, divisor.b[0]);
outb(port+1, divisor.b[1]);
//Set bit count, parity and reset DLAB
outb(port+SERIAL_LCR, 3);
//Finish init
outb(port+SERIAL_FCR, 0xC7);
outb(port+SERIAL_MCR, 0x0B);
}
auto Serial::debug() -> void {
if(getChar()) {
*this << "The interactive debug shell was started.\n> ";
out << "The debug shell was started.\n";
char buf[256];
*this >> buf;
out << buf << "\nDebug shell closed.\n";
*this << "Unknown command. TODO\n";
}
uint64_t wt = waittimes;
uint64_t tm = transmits;
*this << "Transmit stats: " << (int32_t)wt << " times waited; " << (int32_t)tm << " bytes transferred.\n";
waittimes=transmits=0;
}
auto Serial::isTransmitEmpty() -> int {
return inb(port+SERIAL_LSR)&0x20;
}
auto Serial::putChar(char chr) -> void {
if(!works)
return;
int tries=65535;
while(!isTransmitEmpty()) {
waittimes++;
tries--;
if(!tries){
works=false;
return;
}
}
outb(port, chr);
transmits++;
}
auto Serial::serial_received() -> int {
return inb(port+SERIAL_LSR)&1;
}
auto Serial::getChar() -> char {
//We try 500 times to get a character
int tries=500;
while(!serial_received()) {
tries--;
waittimes++;
if(!tries) {
return '\0';
}
}
transmits++;
char chr = inb(port);
if(chr!='\r')
*this << chr;
else
*this << '\n';
return chr;
}
Serial::Serial(): works(true) {
uint32_t baud=115200;
port=*((uint16_t*)0x0400);
union {
uint8_t b[2];
uint16_t w;
} divisor;
divisor.w = 115200/baud;
//Turn off interrupts
outb(port+SERIAL_IER, 0x00);
//Set DLAB-bit
outb(port+SERIAL_LCR, 0x80);
//Set baud divisor
outb(port, divisor.b[0]);
outb(port+1, divisor.b[1]);
//Set bit count, parity and reset DLAB
outb(port+SERIAL_LCR, 3);
//Finish init
outb(port+SERIAL_FCR, 0xC7);
outb(port+SERIAL_MCR, 0x0B);
}
auto Serial::debug() -> void {
if(getChar()) {
*this << "The interactive debug shell was started.\n> ";
out << "The debug shell was started.\n";
char buf[256];
*this >> buf;
out << buf << "\nDebug shell closed.\n";
*this << "Unknown command. TODO\n";
}
uint64_t wt = waittimes;
uint64_t tm = transmits;
*this << "Transmit stats: " << (int32_t)wt << " times waited; " << (int32_t)tm << " bytes transferred.\n";
waittimes=transmits=0;
}
}

View file

@ -7,185 +7,185 @@
#include <string.h>
int x=0, y=0;
namespace MTGosHAL {
auto Screen::putChar(char c) -> void {
putChar((unsigned short)c);
}
auto Screen::putChar(unsigned short c) -> void {
switch(c) {
case '\n':
x=0; y++;
break;
case '\r':
x=0;
auto Screen::putChar(char c) -> void {
putChar((unsigned short)c);
}
auto Screen::putChar(unsigned short c) -> void {
switch(c) {
case '\n':
x=0; y++;
break;
case '\r':
x=0;
break;
case '\b':
x--;
if(x<0) x=0;
putChar(' ');
x--;
if(x<0) x=0;
break;
case '\0':
break;
default:
for(int lx=0;lx<16;lx++) {
for(int ly=0;ly<16;ly++) {
if(font[(int)(c)][ly]&(1<<(16-lx))) {
lfb[(x*16+lx)+(y*16+ly)*1024]=static_cast<uint32_t>(fg);
} else {
lfb[(x*16+lx)+(y*16+ly)*1024]=static_cast<uint32_t>(bg);
}
}
}
x++;
if(x==SCREEN_WIDTH) {
x=0; y++;
}
break;
}
if(y>SCREEN_HEIGHT)
scroll();
}
auto Screen::clrscr() -> void {
for(int p=0;p<1024*786;p++) {
lfb[p]=static_cast<uint32_t>(bg);
}
x=y=0;
}
auto Screen::scroll() -> void {
for(int ly=0;ly<786-16;ly++) {
for(int lx=0;lx<1024;lx++) {
lfb[lx+ly*1024]=lfb[lx+(ly+16)*1024];
}
}
for(int ly=786-16;ly<786;ly++) {
for(int lx=0;lx<1024;lx++) {
lfb[lx+ly*1024]=static_cast<uint32_t>(bg);
}
}
y--;
}
template <>
auto Screen::operator<<<FG_color>(FG_color fg) -> Screen &{
this->fg=fg;
return *this;
}
template <>
auto Screen::operator<<<BG_color>(BG_color bg) -> Screen &{
this->bg=bg;
return *this;
}
auto Screen::setColor(FG_color fg) -> Screen &{
this->fg=fg;
return *this;
}
auto Screen::setColor(BG_color bg) -> Screen &{
this->bg=bg;
return *this;
}
auto Screen::setColor(FG_color fg, BG_color bg) -> Screen &{
return (*this).setColor(fg).setColor(bg);
}
break;
case '\b':
x--;
if(x<0) x=0;
putChar(' ');
x--;
if(x<0) x=0;
break;
case '\0':
break;
default:
for(int lx=0;lx<16;lx++) {
for(int ly=0;ly<16;ly++) {
if(font[(int)(c)][ly]&(1<<(16-lx))) {
lfb[(x*16+lx)+(y*16+ly)*1024]=static_cast<uint32_t>(fg);
} else {
lfb[(x*16+lx)+(y*16+ly)*1024]=static_cast<uint32_t>(bg);
}
}
}
x++;
if(x==SCREEN_WIDTH) {
x=0; y++;
}
break;
}
if(y>SCREEN_HEIGHT)
scroll();
}
auto Screen::clrscr() -> void {
for(int p=0;p<1024*786;p++) {
lfb[p]=static_cast<uint32_t>(bg);
}
x=y=0;
}
auto Screen::scroll() -> void {
for(int ly=0;ly<786-16;ly++) {
for(int lx=0;lx<1024;lx++) {
lfb[lx+ly*1024]=lfb[lx+(ly+16)*1024];
}
}
for(int ly=786-16;ly<786;ly++) {
for(int lx=0;lx<1024;lx++) {
lfb[lx+ly*1024]=static_cast<uint32_t>(bg);
}
}
y--;
}
template <>
auto Screen::operator<<<FG_color>(FG_color fg) -> Screen &{
this->fg=fg;
return *this;
}
template <>
auto Screen::operator<<<BG_color>(BG_color bg) -> Screen &{
this->bg=bg;
return *this;
}
auto Screen::setColor(FG_color fg) -> Screen &{
this->fg=fg;
return *this;
}
auto Screen::setColor(BG_color bg) -> Screen &{
this->bg=bg;
return *this;
}
auto Screen::setColor(FG_color fg, BG_color bg) -> Screen &{
return (*this).setColor(fg).setColor(bg);
}
auto Screen::init(struct multiboot_info* mb_info) -> void {
lfb=(uint32_t*)((uintptr_t)mb_info->framebuffer_addr);
//Load font
multiboot_mod_list *mods = (multiboot_mod_list*) mb_info->mods_addr;
for(int i=0;i<65536;i++)
for(int j=0;j<16;j++)
font[i][j]=0;
for(uint32_t i=0;i<mb_info->mods_count;i++) {
fontfile* font=(fontfile*)(mods[i].mod_start);
if((font->magic[0]!='F')||(font->magic[1]!='O')||(font->magic[2]!='N')||(font->magic[3]!='T')) //Is it a font file?
continue;
charmap* map=(charmap*)((char*)font+font->charmap_off);
charwidth* width=(charwidth*)((char*)font+font->charwidth_off);
CHR8* chr_begin=(CHR8*)((char*)font+font->chr_off);
uint32_t hwcount=0;
for(uint32_t i=0;i<font->no_char;i++) {
uint16_t char_num=map[i].charnumber;
bool wide_char=width[i].width==0x10;
if(wide_char) {
CHR16* chr=(CHR16*)((char*)(&chr_begin[hwcount]));
for(int j=0;j<16;j++) {
uint16_t tmp=chr->rows[j]&0xFF;
tmp <<= 8;
tmp += chr->rows[j]>>8;
::font[i][j]=tmp;
}
hwcount+=2;
} else {
for(int j=0;j<16;j++)
::font[i][j]=(uint16_t)(((uint16_t)chr_begin[hwcount].rows[j])<<8);
hwcount++;
}
}
}
//clrscr();
//Render '\001' character
for(int tx=0;tx<16;tx++) {
for(int ty=0;ty<16;ty++) {
for(int x=0;x<8;x++) {
for(int y=0;y<8;y++) {
if(font[tx+ty*16][y]&(1<<x))
lfb[(x+tx*8)+(y+ty*8)*1024]=0xFFFFFF;
}
}
}
}
}
auto Screen::puts(const char* s) -> void {
int i=0;
while(s[i]!='\0')
putChar(s[i++]);
}
template <>
auto Screen::operator<<<Base>(Base output) -> Screen & {
base=static_cast<int>(output);
return *this;
}
template <>
auto Screen::operator<<<int>(int op) -> Screen & {
uintptr_t output=op;
const char* chars="0123456789ABCDEF";
char buf[33];
buf[32]='\0';
char* ptr=buf+31;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Screen::operator<<<long int>(long int op) -> Screen & {
uint64_t output=op;
const char* chars="0123456789ABCDEF";
char buf[65];
buf[64]='\0';
char* ptr=buf+63;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Screen::operator<<<char>(char output) -> Screen & {
putChar(output);
return *this;
}
template <>
auto Screen::operator<<<char*>(char* output) -> Screen & {
puts(output);
return *this;
}
auto Screen::puts(String& output) -> void {
for(size_t i=0;i<output.size();i++) {
putChar((uint16_t)output[i]);
}
}
auto Screen::init(struct multiboot_info* mb_info) -> void {
lfb=(uint32_t*)((uintptr_t)mb_info->framebuffer_addr);
//Load font
multiboot_mod_list *mods = (multiboot_mod_list*) mb_info->mods_addr;
for(int i=0;i<65536;i++)
for(int j=0;j<16;j++)
font[i][j]=0;
for(uint32_t i=0;i<mb_info->mods_count;i++) {
fontfile* font=(fontfile*)(mods[i].mod_start);
if((font->magic[0]!='F')||(font->magic[1]!='O')||(font->magic[2]!='N')||(font->magic[3]!='T')) //Is it a font file?
continue;
charmap* map=(charmap*)((char*)font+font->charmap_off);
charwidth* width=(charwidth*)((char*)font+font->charwidth_off);
CHR8* chr_begin=(CHR8*)((char*)font+font->chr_off);
uint32_t hwcount=0;
for(uint32_t i=0;i<font->no_char;i++) {
uint16_t char_num=map[i].charnumber;
bool wide_char=width[i].width==0x10;
if(wide_char) {
CHR16* chr=(CHR16*)((char*)(&chr_begin[hwcount]));
for(int j=0;j<16;j++) {
uint16_t tmp=chr->rows[j]&0xFF;
tmp <<= 8;
tmp += chr->rows[j]>>8;
::font[i][j]=tmp;
}
hwcount+=2;
} else {
for(int j=0;j<16;j++)
::font[i][j]=(uint16_t)(((uint16_t)chr_begin[hwcount].rows[j])<<8);
hwcount++;
}
}
}
//clrscr();
//Render '\001' character
for(int tx=0;tx<16;tx++) {
for(int ty=0;ty<16;ty++) {
for(int x=0;x<8;x++) {
for(int y=0;y<8;y++) {
if(font[tx+ty*16][y]&(1<<x))
lfb[(x+tx*8)+(y+ty*8)*1024]=0xFFFFFF;
}
}
}
}
}
auto Screen::puts(const char* s) -> void {
int i=0;
while(s[i]!='\0')
putChar(s[i++]);
}
template <>
auto Screen::operator<<<Base>(Base output) -> Screen & {
base=static_cast<int>(output);
return *this;
}
template <>
auto Screen::operator<<<int>(int op) -> Screen & {
uintptr_t output=op;
const char* chars="0123456789ABCDEF";
char buf[33];
buf[32]='\0';
char* ptr=buf+31;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Screen::operator<<<long int>(long int op) -> Screen & {
uint64_t output=op;
const char* chars="0123456789ABCDEF";
char buf[65];
buf[64]='\0';
char* ptr=buf+63;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Screen::operator<<<char>(char output) -> Screen & {
putChar(output);
return *this;
}
template <>
auto Screen::operator<<<char*>(char* output) -> Screen & {
puts(output);
return *this;
}
auto Screen::puts(String& output) -> void {
for(size_t i=0;i<output.size();i++) {
putChar((uint16_t)output[i]);
}
}
}

View file

@ -8,46 +8,46 @@
extern "C" const int kernel_start;
extern "C" const int kernel_end; //those are voids actually
void *operator new(size_t size) {
return MTGosHAL::mm.alloc(size);
return MTGosHAL::mm.alloc(size);
}
void *operator new[](size_t size) {
return MTGosHAL::mm.alloc(size);
return MTGosHAL::mm.alloc(size);
}
void operator delete(void* p) {
MTGosHAL::mm.free(p);
MTGosHAL::mm.free(p);
}
void operator delete[](void* p) {
MTGosHAL::mm.free(p);
MTGosHAL::mm.free(p);
}
void operator delete(void* p, size_t size) {
MTGosHAL::mm.free(p);
MTGosHAL::mm.free(p);
}
void operator delete[](void* p, size_t size) {
MTGosHAL::mm.free(p);
MTGosHAL::mm.free(p);
}
namespace MTGosHAL {
auto PMM::alloc(size_t length) -> void * {
auto PMM::alloc(size_t length) -> void * {
if(!head) {
//Alloc space for head
if(length+sizeof(malloc_t)<=PAGESIZE) { //Small optimization. The routine for allocating more than one continuous page is terribly slow.
void *tmp;
*this >> tmp;
head=(malloc_t*)tmp;
} else
head=(malloc_t*)(*this)(UNSHIFT((length+sizeof(malloc_t)))+1);
if(!head) //The alloc() didn't work! We're out of RAM!
return nullptr;
head->len=length;
head->next=head->last=nullptr;
malloc_t* tmp=head;
tmp++;
return (void*)tmp;
//Alloc space for head
if(length+sizeof(malloc_t)<=PAGESIZE) { //Small optimization. The routine for allocating more than one continuous page is terribly slow.
void *tmp;
*this >> tmp;
head=(malloc_t*)tmp;
} else
head=(malloc_t*)(*this)(UNSHIFT((length+sizeof(malloc_t)))+1);
if(!head) //The alloc() didn't work! We're out of RAM!
return nullptr;
head->len=length;
head->next=head->last=nullptr;
malloc_t* tmp=head;
tmp++;
return (void*)tmp;
}
malloc_t* curr=head;
malloc_t* last=nullptr;
do {
uintptr_t loc=(uintptr_t)curr+sizeof(malloc_t)+curr->len;
if((loc+length+sizeof(malloc_t))<((loc&(~FLAGS))+PAGESIZE) &&
uintptr_t loc=(uintptr_t)curr+sizeof(malloc_t)+curr->len;
if((loc+length+sizeof(malloc_t))<((loc&(~FLAGS))+PAGESIZE) &&
((!curr->next) || (loc+length+sizeof(malloc_t))<((uintptr_t)(curr->next)))) {
malloc_t *allocd=(malloc_t *)loc;
allocd->len=length;
@ -55,23 +55,23 @@ namespace MTGosHAL {
allocd->next=curr->next; //Set double linked list
curr->next=allocd;
if(allocd->next)
allocd->next->last=allocd;
allocd->next->last=allocd;
malloc_t *tmp=allocd;
tmp++;
return (void*)tmp;
}
last=curr;
curr=curr->next;
}
last=curr;
curr=curr->next;
} while(curr);
malloc_t *allocd=nullptr;
if(length+sizeof(malloc_t)<=PAGESIZE) { //Small optimization. The routine for allocating more than one continuous page is terribly slow.
void *tmp;
*this >> tmp;
allocd=(malloc_t*)tmp;
void *tmp;
*this >> tmp;
allocd=(malloc_t*)tmp;
} else
allocd=(malloc_t*)(*this)(UNSHIFT(length+sizeof(malloc_t))+1);
allocd=(malloc_t*)(*this)(UNSHIFT(length+sizeof(malloc_t))+1);
if(!allocd) //The alloc() didn't work! We're out of RAM!
return nullptr;
return nullptr;
last->next=allocd;
allocd->len=length;
allocd->last=last;
@ -82,24 +82,24 @@ namespace MTGosHAL {
}
auto PMM::free(void* ptr) -> bool {
if(!ptr)
return false;
return false;
malloc_t* curr=head;
malloc_t* chk=(malloc_t*)ptr;
chk--;
do {
if(curr==chk) {
uintptr_t start=((uintptr_t)chk)&(~FLAGS);
uintptr_t end=start+PAGESIZE;
if((((uintptr_t)(curr->last)<start)||((uintptr_t)(curr->last)>=end))&&(((uintptr_t)(curr->next)>=end)||((uintptr_t)(curr->next)<start))) {
*this << (void*)start;
if(curr==chk) {
uintptr_t start=((uintptr_t)chk)&(~FLAGS);
uintptr_t end=start+PAGESIZE;
if((((uintptr_t)(curr->last)<start)||((uintptr_t)(curr->last)>=end))&&(((uintptr_t)(curr->next)>=end)||((uintptr_t)(curr->next)<start))) {
*this << (void*)start;
}
if(curr->last)
curr->last->next=curr->next;
curr->last->next=curr->next;
else {
head=curr->next;
head=curr->next;
}
if(curr->next)
curr->next->last=curr->last;
curr->next->last=curr->last;
return true;
}
curr=curr->next;
@ -108,20 +108,20 @@ namespace MTGosHAL {
}
PMM::PMM(): head(nullptr), pmm2() {}
auto PMM::init(struct multiboot_info* mb_info) -> void {
pmm2.init(mb_info);
pmm2.init(mb_info);
}
auto PMM::markUsed(const void * addr, uint32_t length) -> bool {
return pmm2.markUsed(addr, length);
return pmm2.markUsed(addr, length);
}
auto PMM::operator >> (void * &addr) -> PMM & {
pmm2>>addr;
return *this;
pmm2>>addr;
return *this;
} //alloc
auto PMM::operator << (const void * addr) -> PMM & {
pmm2<<addr;
return *this;
pmm2<<addr;
return *this;
} //free
auto PMM::operator()(int pages) -> void*{
return pmm2(pages);
return pmm2(pages);
} //alloc_multipage
}

View file

@ -19,80 +19,80 @@ PMM2::PMM2(): pmm3() {
}
auto PMM2::markUsed(const void * addr, uint32_t length) -> bool {
uint32_t add=(uint32_t)addr;
uint32_t pagetid = SPLIT1_UNSHIFT(add);
if(length > 256*1024*1024) //Maximum allocation limit is 256MB
return false;
if(!pageTable[pagetid]) {
void* temp;
pmm3 >> temp;
pageTable[pagetid]=(uint16_t*)temp;
for(int i=0;i<2048;i++)
pageTable[pagetid][i]=0;
markUsed(pageTable[pagetid],1024); //Not a mistake
}
//Check if used
for(uint32_t curr_addr=add+length;curr_addr>=add;curr_addr-=0x1000) {
if(pageTable[SPLIT1_UNSHIFT(curr_addr)][SPLIT2_UNSHIFT(curr_addr)])
return false;
}
//Mark as used
uint16_t counter=1;
for(uint32_t curr_addr=add+length;curr_addr>=add;curr_addr-=0x1000) {
pageTable[SPLIT1_UNSHIFT(curr_addr)][SPLIT2_UNSHIFT(curr_addr)]=counter++;
pmm3.markUsed((void*)curr_addr);
}
return true;
uint32_t add=(uint32_t)addr;
uint32_t pagetid = SPLIT1_UNSHIFT(add);
if(length > 256*1024*1024) //Maximum allocation limit is 256MB
return false;
if(!pageTable[pagetid]) {
void* temp;
pmm3 >> temp;
pageTable[pagetid]=(uint16_t*)temp;
for(int i=0;i<2048;i++)
pageTable[pagetid][i]=0;
markUsed(pageTable[pagetid],1024); //Not a mistake
}
//Check if used
for(uint32_t curr_addr=add+length;curr_addr>=add;curr_addr-=0x1000) {
if(pageTable[SPLIT1_UNSHIFT(curr_addr)][SPLIT2_UNSHIFT(curr_addr)])
return false;
}
//Mark as used
uint16_t counter=1;
for(uint32_t curr_addr=add+length;curr_addr>=add;curr_addr-=0x1000) {
pageTable[SPLIT1_UNSHIFT(curr_addr)][SPLIT2_UNSHIFT(curr_addr)]=counter++;
pmm3.markUsed((void*)curr_addr);
}
return true;
}
auto PMM2::operator >> (void * &addr) -> PMM2 & {
pmm3 >> addr;
markUsed(addr,4096);
return *this;
pmm3 >> addr;
markUsed(addr,4096);
return *this;
}
auto PMM2::operator << (const void *addr) -> PMM2 & {
uint32_t add=(uint32_t)addr;
if(!pageTable[SPLIT1_UNSHIFT(add)])
return *this; //Prevent nullptr derefs
for(int i=0;i<pageTable[SPLIT1_UNSHIFT(add)][SPLIT2_UNSHIFT(add)];i++) {
pageTable[SPLIT1_UNSHIFT(add+i*4096)][SPLIT2_UNSHIFT(add+i*4096)]=0;
pmm3 << (void*)(add+i*4096);
}
return *this;
uint32_t add=(uint32_t)addr;
if(!pageTable[SPLIT1_UNSHIFT(add)])
return *this; //Prevent nullptr derefs
for(int i=0;i<pageTable[SPLIT1_UNSHIFT(add)][SPLIT2_UNSHIFT(add)];i++) {
pageTable[SPLIT1_UNSHIFT(add+i*4096)][SPLIT2_UNSHIFT(add+i*4096)]=0;
pmm3 << (void*)(add+i*4096);
}
return *this;
}
auto PMM2::operator()(int pages) -> void* {
//I want to get this working so:
//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
// NEVER USE A BRUTE-FORCE ALGO TO ALLOC PAGES!
//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
for(uint32_t i=0;i<(uint32_t)(-(pages*4096));i+=4096) {
if(markUsed((void*)i,pages*4096))
return (void*)i;
}
return nullptr;
//I want to get this working so:
//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
// NEVER USE A BRUTE-FORCE ALGO TO ALLOC PAGES!
//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
for(uint32_t i=0;i<(uint32_t)(-(pages*4096));i+=4096) {
if(markUsed((void*)i,pages*4096))
return (void*)i;
}
return nullptr;
}
auto PMM2::init(struct multiboot_info* mb_info) -> void {
pmm3.init(mb_info);
void *temp;
pmm3 >> temp;
pageTable=(uint16_t**)temp;
for(int i=0;i<4096;i++)
pageTable[i]=nullptr;
markUsed(pageTable,4096);
markUsed((void*)nullptr,4096);
struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*) mb_info->mmap_addr;
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((unsigned int) mb_info->mmap_addr + mb_info->mmap_length);
while(mmap < mmap_end) {
if(mmap->type != 1) {
markUsed((void*)mmap->addr,mmap->len);
pmm3.init(mb_info);
void *temp;
pmm3 >> temp;
pageTable=(uint16_t**)temp;
for(int i=0;i<4096;i++)
pageTable[i]=nullptr;
markUsed(pageTable,4096);
markUsed((void*)nullptr,4096);
struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*) mb_info->mmap_addr;
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((unsigned int) mb_info->mmap_addr + mb_info->mmap_length);
while(mmap < mmap_end) {
if(mmap->type != 1) {
markUsed((void*)mmap->addr,mmap->len);
}
mmap++;
}
markUsed(&kernel_start,((uint32_t)&kernel_end)-((uint32_t)&kernel_start)); //Protect kernel)
multiboot_mod_list *mods = (multiboot_mod_list*) mb_info->mods_addr;
for(uint32_t i=0;i<mb_info->mods_count;i++) {
markUsed((void*)((uint32_t)(&mods[i])&(~0xFFF)),4096); //Mark all of the module table as used
markUsed((void*)mods[i].mod_start,mods[i].mod_end-mods[i].mod_start);
}
mmap++;
}
markUsed(&kernel_start,((uint32_t)&kernel_end)-((uint32_t)&kernel_start)); //Protect kernel)
multiboot_mod_list *mods = (multiboot_mod_list*) mb_info->mods_addr;
for(uint32_t i=0;i<mb_info->mods_count;i++) {
markUsed((void*)((uint32_t)(&mods[i])&(~0xFFF)),4096); //Mark all of the module table as used
markUsed((void*)mods[i].mod_start,mods[i].mod_end-mods[i].mod_start);
}
}
}

View file

@ -7,65 +7,65 @@ extern "C" const int kernel_end; //those are voids actually
namespace MTGosHAL {
PMM3::PMM3() {}
auto PMM3::init(struct multiboot_info * mb_info) -> void {
for(int i=0;i<0x8000;i++)
bitmap[i]=0;
struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*) mb_info->mmap_addr;
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((unsigned int) mb_info->mmap_addr + mb_info->mmap_length);
while (mmap < mmap_end) {
if (mmap->type == 1) {
// Memory is free
uintptr_t addr = mmap->addr;
uintptr_t end_addr = addr + mmap->len;
while (addr < end_addr) {
*this << (void*) addr;
addr += 0x1000;
}
}
mmap++;
}
unsigned int addr = (unsigned int) &kernel_start;
while(addr < (unsigned int) &kernel_end) {
markUsed((void*)addr);
addr+=0x1000;
}
markUsed((void*)0);
multiboot_mod_list *mods = (multiboot_mod_list*) mb_info->mods_addr;
for(uint32_t i=0;i<mb_info->mods_count;i++) {
markUsed((void*)((uint32_t)(&mods[i])&(~0xFFF))); //Mark all of the module table as used
for(uint32_t start=(uint32_t)(mods[i].mod_start)&(~0xFFF);start<(uint32_t)(mods[i].mod_end);start+=0x1000) {
markUsed((void*)start); //Protect all multiboot modules
}
}
for(int i=0;i<0x8000;i++)
bitmap[i]=0;
struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*) mb_info->mmap_addr;
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((unsigned int) mb_info->mmap_addr + mb_info->mmap_length);
while (mmap < mmap_end) {
if (mmap->type == 1) {
// Memory is free
uintptr_t addr = mmap->addr;
uintptr_t end_addr = addr + mmap->len;
while (addr < end_addr) {
*this << (void*) addr;
addr += 0x1000;
}
}
mmap++;
}
unsigned int addr = (unsigned int) &kernel_start;
while(addr < (unsigned int) &kernel_end) {
markUsed((void*)addr);
addr+=0x1000;
}
markUsed((void*)0);
multiboot_mod_list *mods = (multiboot_mod_list*) mb_info->mods_addr;
for(uint32_t i=0;i<mb_info->mods_count;i++) {
markUsed((void*)((uint32_t)(&mods[i])&(~0xFFF))); //Mark all of the module table as used
for(uint32_t start=(uint32_t)(mods[i].mod_start)&(~0xFFF);start<(uint32_t)(mods[i].mod_end);start+=0x1000) {
markUsed((void*)start); //Protect all multiboot modules
}
}
}
auto PMM3::markUsed(const void * addr) -> void {
unsigned int address=(unsigned int)addr;
address>>=12;
int index=address>>5;
int bit=1<<(address&0x1F);
bitmap[index]&=~bit;
unsigned int address=(unsigned int)addr;
address>>=12;
int index=address>>5;
int bit=1<<(address&0x1F);
bitmap[index]&=~bit;
}
auto PMM3::operator >> (void * &addr) -> PMM3 & {
for(int i=0;i<0x8000;i++) {
if(!bitmap[i])
continue;
for(int j=0;j<32;j++) {
if(bitmap[i]&(1<<j)) {
//We found a free page!
bitmap[i]&=~(1<<j);
addr=(void*)(((i<<5)+j)<<12);
return *this;
}
}
}
addr=nullptr;
return *this;
for(int i=0;i<0x8000;i++) {
if(!bitmap[i])
continue;
for(int j=0;j<32;j++) {
if(bitmap[i]&(1<<j)) {
//We found a free page!
bitmap[i]&=~(1<<j);
addr=(void*)(((i<<5)+j)<<12);
return *this;
}
}
}
addr=nullptr;
return *this;
}
auto PMM3::operator << (const void * addr) -> PMM3 & {
unsigned int address=(unsigned int)addr;
address>>=12;
int index=address>>5;
int bit=1<<(address&0x1F);
bitmap[index]|=bit;
return *this;
unsigned int address=(unsigned int)addr;
address>>=12;
int index=address>>5;
int bit=1<<(address&0x1F);
bitmap[index]|=bit;
return *this;
}
}

View file

@ -5,21 +5,21 @@ namespace MTGosHAL {
VMM3::VMM3(): pmm() {
}
auto VMM3::init(struct multiboot_info* mb_info) -> void {
pmm.init(mb_info);
void* tmp;
pmm >> tmp;
pd=(uint32_t**)tmp;
uint32_t ent=0x87;
for(int i=0;i<1024;i++) {
pd[i]=(uint32_t*)ent;
ent+=0x1000*1024;
}
enterPaging(pd);
pmm.init(mb_info);
void* tmp;
pmm >> tmp;
pd=(uint32_t**)tmp;
uint32_t ent=0x87;
for(int i=0;i<1024;i++) {
pd[i]=(uint32_t*)ent;
ent+=0x1000*1024;
}
enterPaging(pd);
}
auto VMM3::alloc(uint32_t length) -> void* {
return pmm.alloc(length);
return pmm.alloc(length);
}
auto VMM3::free(void* ptr) -> bool {
return pmm.free(ptr);
return pmm.free(ptr);
}
}

View file

@ -1,5 +1,5 @@
#include <blockdev.hpp>
namespace MTGosHAL {
BlockDevice::BlockDevice() {}
BlockDevice::~BlockDevice() {}
BlockDevice::BlockDevice() {}
BlockDevice::~BlockDevice() {}
}

View file

@ -11,12 +11,12 @@ auto schedule(struct cpu_state* cpu) -> struct cpu_state* {
}
Multitasking::Multitasking(): curr_task(nullptr), first_task(nullptr)
{
for(int i=0;i<32;i++) {
if(i==2)
continue;
tss[i]=0;
}
tss[2]=0x10;
for(int i=0;i<32;i++) {
if(i==2)
continue;
tss[i]=0;
}
tss[2]=0x10;
//task_states[0] = initTask(stack_a, user_stack_a, task_a);
//task_states[1] = initTask(stack_b, user_stack_b, task_b);
if(!idt.request(0x20,MTGosHAL::schedule)) {
@ -67,24 +67,24 @@ auto Multitasking::initTask(void(* entry)()) -> struct cpu_state*
//Create new task class
Task* task = new Task(state);
if(first_task)
first_task->addTask(task);
first_task->addTask(task);
else {
first_task=task;
first_task=task;
}
return state;
}
auto Multitasking::schedule(struct cpu_state* cpu) -> struct cpu_state*
{
Task* next=nullptr;
if(curr_task) {
next=curr_task->pause(cpu);
}
if (!next) {
next=first_task;
}
curr_task=next;
struct cpu_state* cpu_state=next->unpause();
MTGosHAL::tasks.tss[1] = (uint32_t) (uint64_t)(cpu_state + 1);
return cpu_state;
Task* next=nullptr;
if(curr_task) {
next=curr_task->pause(cpu);
}
if (!next) {
next=first_task;
}
curr_task=next;
struct cpu_state* cpu_state=next->unpause();
MTGosHAL::tasks.tss[1] = (uint32_t) (uint64_t)(cpu_state + 1);
return cpu_state;
}
} // namespace MTGosHAL

View file

@ -2,20 +2,20 @@
#include <gdt.hpp>
#include <serial.hpp>
namespace MTGosHAL {
GDT::GDT() {
gdt[0]=gdt[1]=gdt[2]=gdt[3]=gdt[4]=gdt[5]=gdt[6]=0x0ull;
}
auto GDT::setEntry(int i, unsigned int base, unsigned int limit, int flags) -> void {
gdt[i] = limit & 0xffffLL;
gdt[i] |= (base & 0xffffffLL) << 16;
gdt[i] |= (flags & 0xffLL) << 40;
gdt[i] |= ((limit >> 16) & 0xfLL) << 48;
gdt[i] |= ((flags >> 8 )& 0xffLL) << 52;
gdt[i] |= ((base >> 24) & 0xffLL) << 56;
}
auto GDT::apply() -> void {
debug << "We are now trying to set our GDT. If the CPU triplefaults, something went wrong in MTGosHAL::GDT::apply() or loadGDT().\n";
fin={(uint16_t)7*8-1, (void*)gdt};
loadGDT((void*)(&fin));
};
GDT::GDT() {
gdt[0]=gdt[1]=gdt[2]=gdt[3]=gdt[4]=gdt[5]=gdt[6]=0x0ull;
}
auto GDT::setEntry(int i, unsigned int base, unsigned int limit, int flags) -> void {
gdt[i] = limit & 0xffffLL;
gdt[i] |= (base & 0xffffffLL) << 16;
gdt[i] |= (flags & 0xffLL) << 40;
gdt[i] |= ((limit >> 16) & 0xfLL) << 48;
gdt[i] |= ((flags >> 8 )& 0xffLL) << 52;
gdt[i] |= ((base >> 24) & 0xffLL) << 56;
}
auto GDT::apply() -> void {
debug << "We are now trying to set our GDT. If the CPU triplefaults, something went wrong in MTGosHAL::GDT::apply() or loadGDT().\n";
fin={(uint16_t)7*8-1, (void*)gdt};
loadGDT((void*)(&fin));
};
}

View file

@ -8,119 +8,119 @@ bool epicfail=false;
auto syscall(uint32_t syscall_num, void* handle, void* args) -> void*;
extern void** progs;
namespace MTGosHAL {
auto startup() -> void;
IDT::IDT() {
//Init PIC
outb(0x20, 0x11); //Init Master-PIC
outb(0x21, 0x20); //Interrupt number for IRQ0
outb(0x21, 0x04); //IRQ is the Slave
outb(0x21, 0x01); //ICW 4
outb(0xA0, 0x11); //Init Master-PIC
outb(0xA1, 0x28); //Interrupt number for IRQ8
outb(0xA1, 0x02); //IRQ is the Slave
outb(0xA1, 0x01); //ICW 4
//Activate IRQ's
outb(0x21, 0x00);
outb(0xA1, 0x00);
}
auto IDT::setEntry(int i, void* offset, uint16_t seg, uint8_t flags) -> void {
idt[i]=(uint16_t)((uint64_t)offset);
idt[i]|=(unsigned __int128)(((uint64_t)offset)>>16)<<48;
idt[i]|=((unsigned __int128)seg)<<16;
idt[i]|=((unsigned __int128)flags)<<40;
}
auto IDT::apply() -> void {
debug << "Now trying to load the IDT.\n";
idtptr.limit=(uint16_t)(256*8-1);
idtptr.pointer=(unsigned __int128*)&idt;
loadIDT((void*)&idtptr);
}
auto IDT::handle(struct cpu_state* cpu) -> struct cpu_state* {
struct cpu_state* new_cpu=cpu;
debug << "Interrupt 0x" << Base::HEXADECIMAL << (int) cpu->intr << " was raised.\n";
if(cpu->intr<=0x1F) {
if(epicfail) {
err << "While trying to output the stack another exception happened\n";
while(1) {
asm volatile("cli; hlt");
}
}
epicfail=true;
err << "Exception 0x" << Base::HEXADECIMAL << (int) cpu->intr << "! Kernel halted!\n";
err << "RAX = 0x" << (int)cpu->rax << " - RBX = 0x" << (int)cpu->rbx << "\n";
err << "RCX = 0x" << (int)cpu->rcx << " - RDX = 0x" << (int)cpu->rdx << "\n";
err << "RSI = 0x" << (int)cpu->rsi << " - RDI = 0x" << (int)cpu->rdi << "\n";
err << "SS:RSP = 0x" << (int)cpu->ss << ":0x" << (int)cpu->rsp << " - SS:RBP = 0x" << (int)cpu->ss << ":0x" << (int)cpu->rbp << "\n";
err << "CS:RIP = 0x" << (int)cpu->cs << ":0x" << (int)cpu->rip << " - INTR:ERR = 0x" << (int)cpu->intr << ":0x" << (int)cpu->error << "\n";
err << "------ END OF REGISTER DUMP ------ ------ START OF PROGRAM LOADPOINTS ------\n";
for(int i=0;i<1024;i++) {
if(!progs[i])
break;
err << "0x" << (int)((uint64_t)progs[i]) << "; ";
}
err << "\n";
uint16_t counter = 1193180 / 220; //Make an annoying beep
outb(0x43, 0xB6);
outb(0x42, (uint8_t)counter);
outb(0x42, (uint8_t)(counter>>8));
//outb(0x61, inb(0x61) | 3);
err << "A detailled traceback is being output over the serial connector.\n";
debug << "Outputting 32 stacks...\n";
uint64_t *rsp=(uint64_t*)cpu->rsp;
uint64_t *rbp=(uint64_t*)cpu->rbp;
uint64_t *rip=(uint64_t*)cpu->rip;
for(int i=0;i<32;i++) {
if(!(rsp||rbp||rip))
break;
if((int64_t)(rbp-rsp)<1)
break;
debug << Base::HEXADECIMAL << "Execution at 0x" << (int64_t) rip << ":\n";
debug << "Number of local variables: 0x" << (int64_t)(rbp-rsp)-1 << "\n";
for(uintptr_t i=0;i<(uintptr_t)(rbp-rsp)-1;i++) {
debug << "0x"<< (int64_t)(i*8) << ": 0x" << (int64_t)rsp[i] << "\n";
}
rip=(uint64_t*)rbp[1];
rsp=rbp;
rbp=(uint64_t*)rbp[0];
}
while(1) {
asm volatile("cli; hlt");
}
} else if(cpu->intr >= 0x20 && cpu->intr <= 0x2F) {
if(cpu->intr >= 0x28) {
outb(0xA0, 0x20);
}
outb(0x20, 0x20);
debug << "The IRQ " << Base::DECIMAL << (int) cpu->intr-0x20 << " was handled.\n";
if(cpu->intr==0x20) {
debug.debug();
}
auto startup() -> void;
IDT::IDT() {
//Init PIC
outb(0x20, 0x11); //Init Master-PIC
outb(0x21, 0x20); //Interrupt number for IRQ0
outb(0x21, 0x04); //IRQ is the Slave
outb(0x21, 0x01); //ICW 4
outb(0xA0, 0x11); //Init Master-PIC
outb(0xA1, 0x28); //Interrupt number for IRQ8
outb(0xA1, 0x02); //IRQ is the Slave
outb(0xA1, 0x01); //ICW 4
//Activate IRQ's
outb(0x21, 0x00);
outb(0xA1, 0x00);
}
auto IDT::setEntry(int i, void* offset, uint16_t seg, uint8_t flags) -> void {
idt[i]=(uint16_t)((uint64_t)offset);
idt[i]|=(unsigned __int128)(((uint64_t)offset)>>16)<<48;
idt[i]|=((unsigned __int128)seg)<<16;
idt[i]|=((unsigned __int128)flags)<<40;
}
for(int i=0;i<16;i++) {
if(ivt[cpu->intr][i])
new_cpu=ivt[cpu->intr][i](new_cpu);
auto IDT::apply() -> void {
debug << "Now trying to load the IDT.\n";
idtptr.limit=(uint16_t)(256*8-1);
idtptr.pointer=(unsigned __int128*)&idt;
loadIDT((void*)&idtptr);
}
if(cpu->intr==48)
new_cpu->rax=(uint64_t)(::syscall(cpu->rax, (void*)(cpu->rbx), (void*)(cpu->rsp)));
if(cpu->intr==49) {
startup();
for(int i=0;i<16;i++) {
if(ivt[0x20][i])
new_cpu=ivt[0x20][i](new_cpu);
}
}
return new_cpu;
}
auto IDT::request(uint8_t intr, struct cpu_state* (*handler)(struct cpu_state*)) -> bool {
for(int i=0;i<16;i++) {
if(ivt[intr][i])
continue;
ivt[intr][i]=handler;
return true;
auto IDT::handle(struct cpu_state* cpu) -> struct cpu_state* {
struct cpu_state* new_cpu=cpu;
debug << "Interrupt 0x" << Base::HEXADECIMAL << (int) cpu->intr << " was raised.\n";
if(cpu->intr<=0x1F) {
if(epicfail) {
err << "While trying to output the stack another exception happened\n";
while(1) {
asm volatile("cli; hlt");
}
}
epicfail=true;
err << "Exception 0x" << Base::HEXADECIMAL << (int) cpu->intr << "! Kernel halted!\n";
err << "RAX = 0x" << (int)cpu->rax << " - RBX = 0x" << (int)cpu->rbx << "\n";
err << "RCX = 0x" << (int)cpu->rcx << " - RDX = 0x" << (int)cpu->rdx << "\n";
err << "RSI = 0x" << (int)cpu->rsi << " - RDI = 0x" << (int)cpu->rdi << "\n";
err << "SS:RSP = 0x" << (int)cpu->ss << ":0x" << (int)cpu->rsp << " - SS:RBP = 0x" << (int)cpu->ss << ":0x" << (int)cpu->rbp << "\n";
err << "CS:RIP = 0x" << (int)cpu->cs << ":0x" << (int)cpu->rip << " - INTR:ERR = 0x" << (int)cpu->intr << ":0x" << (int)cpu->error << "\n";
err << "------ END OF REGISTER DUMP ------ ------ START OF PROGRAM LOADPOINTS ------\n";
for(int i=0;i<1024;i++) {
if(!progs[i])
break;
err << "0x" << (int)((uint64_t)progs[i]) << "; ";
}
err << "\n";
uint16_t counter = 1193180 / 220; //Make an annoying beep
outb(0x43, 0xB6);
outb(0x42, (uint8_t)counter);
outb(0x42, (uint8_t)(counter>>8));
//outb(0x61, inb(0x61) | 3);
err << "A detailled traceback is being output over the serial connector.\n";
debug << "Outputting 32 stacks...\n";
uint64_t *rsp=(uint64_t*)cpu->rsp;
uint64_t *rbp=(uint64_t*)cpu->rbp;
uint64_t *rip=(uint64_t*)cpu->rip;
for(int i=0;i<32;i++) {
if(!(rsp||rbp||rip))
break;
if((int64_t)(rbp-rsp)<1)
break;
debug << Base::HEXADECIMAL << "Execution at 0x" << (int64_t) rip << ":\n";
debug << "Number of local variables: 0x" << (int64_t)(rbp-rsp)-1 << "\n";
for(uintptr_t i=0;i<(uintptr_t)(rbp-rsp)-1;i++) {
debug << "0x"<< (int64_t)(i*8) << ": 0x" << (int64_t)rsp[i] << "\n";
}
rip=(uint64_t*)rbp[1];
rsp=rbp;
rbp=(uint64_t*)rbp[0];
}
while(1) {
asm volatile("cli; hlt");
}
} else if(cpu->intr >= 0x20 && cpu->intr <= 0x2F) {
if(cpu->intr >= 0x28) {
outb(0xA0, 0x20);
}
outb(0x20, 0x20);
debug << "The IRQ " << Base::DECIMAL << (int) cpu->intr-0x20 << " was handled.\n";
if(cpu->intr==0x20) {
debug.debug();
}
}
for(int i=0;i<16;i++) {
if(ivt[cpu->intr][i])
new_cpu=ivt[cpu->intr][i](new_cpu);
}
if(cpu->intr==48)
new_cpu->rax=(uint64_t)(::syscall(cpu->rax, (void*)(cpu->rbx), (void*)(cpu->rsp)));
if(cpu->intr==49) {
startup();
for(int i=0;i<16;i++) {
if(ivt[0x20][i])
new_cpu=ivt[0x20][i](new_cpu);
}
}
return new_cpu;
}
return false;
}
}
extern "C" void* handleINT(void* cpu) {
return (void*)MTGosHAL::idt.handle((MTGosHAL::cpu_state*)cpu);
}
auto IDT::request(uint8_t intr, struct cpu_state* (*handler)(struct cpu_state*)) -> bool {
for(int i=0;i<16;i++) {
if(ivt[intr][i])
continue;
ivt[intr][i]=handler;
return true;
}
return false;
}
}
extern "C" void* handleINT(void* cpu) {
return (void*)MTGosHAL::idt.handle((MTGosHAL::cpu_state*)cpu);
}

View file

@ -11,77 +11,75 @@
#include <pmm.hpp>
extern "C" void intr_stub_0(void);
void main(void ** programs, MTGosHAL::Serial debug, MTGosHAL::PMM mm, MTGosHAL::Screen out,
MTGosHAL::Screen err, MTGosHAL::Keyboard in, MTGosHAL::Multitasking tasks, MTGosHAL::BlockDevice disk);
MTGosHAL::Screen err, MTGosHAL::Keyboard in, MTGosHAL::Multitasking tasks, MTGosHAL::BlockDevice disk);
void** progs;
namespace MTGosHAL {
Serial debug;
GDT gdt;
IDT idt;
PMM mm;
Screen out;
Screen err;
Keyboard in;
Multitasking tasks;
BlockDevice disk;
struct multiboot_info* ebx;
void main(long eax, struct multiboot_info* mb, uint64_t**** pt) {
ebx=mb;
new (&debug) Serial();
debug << "Hello debugger! This is MTGos v00r01\nThese logs are probably very long, so please redirect the output to a file.\n";
Serial debug;
GDT gdt;
IDT idt;
PMM mm;
Screen out;
Screen err;
Keyboard in;
Multitasking tasks;
BlockDevice disk;
struct multiboot_info* ebx;
void main(long eax, struct multiboot_info* mb, uint64_t**** pt) {
ebx=mb;
new (&debug) Serial();
debug << "Hello debugger! This is MTGos v00r01\nThese logs are probably very long, so please redirect the output to a file.\n";
debug << "Init Screen output\n";
new (&out) Screen(ebx);
new (&err) Screen(ebx);
out << BG_color::BLACK << FG_color::WHITE << "Loading MTGos...\n";
err << BG_color::BLACK << FG_color::RED;
debug << "Init GDT\n";
new (&gdt) GDT();
gdt.setEntry(0, 0, 0, 0);
gdt.setEntry(1, 0, 0, GDT_FLAG_PRESENT | GDT_FLAG_64_BIT | GDT_FLAG_4K_GRAN | GDT_FLAG_RING0 | GDT_FLAG_SEGMENT | GDT_FLAG_CODESEG);
gdt.setEntry(2, 0, 0, GDT_FLAG_PRESENT | GDT_FLAG_32_BIT | GDT_FLAG_4K_GRAN | GDT_FLAG_RING0 | GDT_FLAG_SEGMENT | GDT_FLAG_DATASEG);
gdt.setEntry(3, 0, 0, GDT_FLAG_PRESENT | GDT_FLAG_64_BIT | GDT_FLAG_4K_GRAN | GDT_FLAG_RING3 | GDT_FLAG_SEGMENT | GDT_FLAG_CODESEG);
gdt.setEntry(4, 0, 0, GDT_FLAG_PRESENT | GDT_FLAG_32_BIT | GDT_FLAG_4K_GRAN | GDT_FLAG_RING3 | GDT_FLAG_SEGMENT | GDT_FLAG_DATASEG);
gdt.setEntry(5, (uint64_t)tasks.tss, sizeof(tasks.tss), GDT_FLAG_RING0 | GDT_FLAG_TSS | GDT_FLAG_PRESENT);
gdt.setEntry(6, 0, 0, GDT_FLAG_RING3 | GDT_FLAG_TSS | GDT_FLAG_PRESENT);
gdt.apply();
debug << "Init Screen output\n";
new (&out) Screen(ebx);
new (&err) Screen(ebx);
out << BG_color::BLACK << FG_color::WHITE << "Loading MTGos...\n";
err << BG_color::BLACK << FG_color::RED;
debug << "Init GDT\n";
new (&gdt) GDT();
gdt.setEntry(0, 0, 0, 0);
gdt.setEntry(1, 0, 0, GDT_FLAG_PRESENT | GDT_FLAG_64_BIT | GDT_FLAG_4K_GRAN | GDT_FLAG_RING0 | GDT_FLAG_SEGMENT | GDT_FLAG_CODESEG);
gdt.setEntry(2, 0, 0, GDT_FLAG_PRESENT | GDT_FLAG_32_BIT | GDT_FLAG_4K_GRAN | GDT_FLAG_RING0 | GDT_FLAG_SEGMENT | GDT_FLAG_DATASEG);
gdt.setEntry(3, 0, 0, GDT_FLAG_PRESENT | GDT_FLAG_64_BIT | GDT_FLAG_4K_GRAN | GDT_FLAG_RING3 | GDT_FLAG_SEGMENT | GDT_FLAG_CODESEG);
gdt.setEntry(4, 0, 0, GDT_FLAG_PRESENT | GDT_FLAG_32_BIT | GDT_FLAG_4K_GRAN | GDT_FLAG_RING3 | GDT_FLAG_SEGMENT | GDT_FLAG_DATASEG);
gdt.setEntry(5, (uint64_t)tasks.tss, sizeof(tasks.tss), GDT_FLAG_RING0 | GDT_FLAG_TSS | GDT_FLAG_PRESENT);
gdt.setEntry(6, 0, 0, GDT_FLAG_RING3 | GDT_FLAG_TSS | GDT_FLAG_PRESENT);
gdt.apply();
debug << "Init IDT\n";
new (&idt) IDT();
for(int i=0;i<256;i++) {
idt.setEntry(i, (void *)((uint64_t)&intr_stub_0+i*32), SEG_KERNEL, IDT_INTERRUPT_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED);
}
idt.setEntry(48, (void *)((uint64_t)&intr_stub_0+768*2), SEG_KERNEL, IDT_TRAP_GATE | IDT_SEG_32_BIT | IDT_RING_3 | IDT_USED);
idt.setEntry(8, (void *)((uint64_t)&intr_stub_0+128*2), SEG_DBL_FAULT, IDT_TASK_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED);
idt.apply();
asm volatile("int $49"); // Finish loading GDT
debug << "Init IDT\n";
new (&idt) IDT();
for(int i=0;i<256;i++) {
idt.setEntry(i, (void *)((uint64_t)&intr_stub_0+i*32), SEG_KERNEL, IDT_INTERRUPT_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED);
}
idt.setEntry(48, (void *)((uint64_t)&intr_stub_0+768*2), SEG_KERNEL, IDT_TRAP_GATE | IDT_SEG_32_BIT | IDT_RING_3 | IDT_USED);
idt.setEntry(8, (void *)((uint64_t)&intr_stub_0+128*2), SEG_DBL_FAULT, IDT_TASK_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED);
idt.apply();
asm volatile("int $49"); // Finish loading GDT
}
auto startup() -> void {
//asm volatile("ltr %%ax" : : "a"(5<<3));
//asm volatile("ltr %%ax" : : "a"(5<<3));
out << "Init MM\n";
new (&mm) PMM(ebx);
out << "Init MM\n";
new (&mm) PMM(ebx);
out << "Init Keyboard\n";
new (&in) Keyboard();
out << "Init Keyboard\n";
new (&in) Keyboard();
out << "Init Multitasking\n";
new (&tasks) Multitasking();
out << "Init Multitasking\n";
new (&tasks) Multitasking();
out << "Init blockdev\n";
new (&disk) BlockDevice();
out << "Kernel initialized\n";
multiboot_mod_list *mods = (multiboot_mod_list*) (uint64_t)(ebx->mods_addr);
progs=(void**)mm.alloc(8192);
for(int i=0;i<1024;i++) {
progs[i]=nullptr;
}
for(uint32_t i=0;i<(ebx->mods_count<1023?ebx->mods_count:1023);i++) { //Basically until MIN(ebx->mods_count, 1023), as we only support loading up to 1023 programs directly.
progs[i]=(void*)((uint64_t)mods[i].mod_start);
out << "Found module!\n";
}
::main(progs, debug, mm, out, err, in, tasks, disk);
out << "Init blockdev\n";
new (&disk) BlockDevice();
out << "Kernel initialized\n";
multiboot_mod_list *mods = (multiboot_mod_list*) (uint64_t)(ebx->mods_addr);
progs=(void**)mm.alloc(8192);
for(int i=0;i<1024;i++) {
progs[i]=nullptr;
}
for(uint32_t i=0;i<(ebx->mods_count<1023?ebx->mods_count:1023);i++) { //Basically until MIN(ebx->mods_count, 1023), as we only support loading up to 1023 programs directly.
progs[i]=(void*)((uint64_t)mods[i].mod_start);
out << "Found module!\n";
}
::main(progs, debug, mm, out, err, in, tasks, disk);
}
}
@ -90,10 +88,10 @@ typedef void (*destructor)();
extern "C" destructor start_dtors;
extern "C" destructor end_dtors;
extern "C" void init(int eax, struct multiboot_info* ebx, uint64_t**** ecx) {
MTGosHAL::main(eax, ebx,ecx);
for(destructor* i = &start_dtors; i != &end_dtors; i++)
(*i)();
MTGosHAL::main(eax, ebx,ecx);
for(destructor* i = &start_dtors; i != &end_dtors; i++)
(*i)();
}
extern "C" void __cxa_pure_virtual() {
MTGosHAL::debug << "A pure virtual function just got called.\n";
MTGosHAL::debug << "A pure virtual function just got called.\n";
}

View file

@ -5,124 +5,124 @@
#include <keymap_DE.hpp>
namespace MTGosHAL {
auto handleIRQ(struct cpu_state* cpu) -> struct cpu_state* {
return in.handleIRQ1(cpu);
}
auto Keyboard::getChar() -> char {
char chr=buf[0];
for(int i=0;i<15;i++) {
buf[i]=buf[i+1];
}
buf[15]='\0';
if(len)
len--;
return chr;
}
auto Keyboard::sendCommand(uint8_t command) -> void {
while((inb(0x64) & 0x2));
outb(0x60, command);
}
auto Keyboard::handleIRQ1(struct cpu_state* cpu) -> struct cpu_state* {
uint8_t keycode=0,scancode=inb(0x60);
if(scancode==0xFA) {
response=false;
return cpu;
} else if(response && scancode == 0xFE) {
sendCommand(0xED);
outb(0x60, (scrolllock) + (numlock<<1) + (capslock<<2));
return cpu;
}
debug << "Keyboard interrupt received.\nGot: 0x" << Base::HEXADECIMAL << (int)scancode;
bool break_code=false;
static bool e0_code=false;
static int e1_code=0;
static uint16_t e1_prev=0;
uint8_t tableID=0;
if((scancode & 0x80 ) && (e1_code || (scancode != 0xE1)) && (e0_code || (scancode != 0xE0))) {
break_code = true;
scancode &= ~0x80;
}
if(e0_code) {
if((scancode==0x2A) || (scancode = 0x36)) {
e0_code = false;
return cpu;
}
keycode=keyboardKeycodes[1][scancode];
e0_code=false;
} else if (e1_code == 2) {
e1_prev |= ((uint16_t) scancode << 8);
//TODO. translate it, although I might not even use this code
return cpu;
} else if (e1_code) {
e1_prev = scancode;
e1_code++;
return cpu;
} else if (scancode == 0xE0) {
e0_code = true;
return cpu;
} else if (scancode == 0xE1) {
e1_code = true;
return cpu;
} else {
keycode=keyboardKeycodes[0][scancode];
}
//Now put it into the keystate array
if(break_code)
keydowns[keycode]=false;
else
keydowns[keycode]=true;
//0x2A 0x36 = Shift
if(keydowns[0x2A] || keydowns[0x36])
tableID^=1;
//0x1D = Ctrl
if(keydowns[0x1D])
tableID^=2;
//0x38 = Alt
if(keydowns[0x38])
tableID^=4;
auto handleIRQ(struct cpu_state* cpu) -> struct cpu_state* {
return in.handleIRQ1(cpu);
}
auto Keyboard::getChar() -> char {
char chr=buf[0];
for(int i=0;i<15;i++) {
buf[i]=buf[i+1];
}
buf[15]='\0';
if(len)
len--;
return chr;
}
auto Keyboard::sendCommand(uint8_t command) -> void {
while((inb(0x64) & 0x2));
outb(0x60, command);
}
auto Keyboard::handleIRQ1(struct cpu_state* cpu) -> struct cpu_state* {
uint8_t keycode=0,scancode=inb(0x60);
if(scancode==0xFA) {
response=false;
return cpu;
} else if(response && scancode == 0xFE) {
sendCommand(0xED);
outb(0x60, (scrolllock) + (numlock<<1) + (capslock<<2));
return cpu;
}
debug << "Keyboard interrupt received.\nGot: 0x" << Base::HEXADECIMAL << (int)scancode;
bool break_code=false;
static bool e0_code=false;
static int e1_code=0;
static uint16_t e1_prev=0;
uint8_t tableID=0;
if((scancode & 0x80 ) && (e1_code || (scancode != 0xE1)) && (e0_code || (scancode != 0xE0))) {
break_code = true;
scancode &= ~0x80;
}
if(e0_code) {
if((scancode==0x2A) || (scancode = 0x36)) {
e0_code = false;
return cpu;
}
keycode=keyboardKeycodes[1][scancode];
e0_code=false;
} else if (e1_code == 2) {
e1_prev |= ((uint16_t) scancode << 8);
//TODO. translate it, although I might not even use this code
return cpu;
} else if (e1_code) {
e1_prev = scancode;
e1_code++;
return cpu;
} else if (scancode == 0xE0) {
e0_code = true;
return cpu;
} else if (scancode == 0xE1) {
e1_code = true;
return cpu;
} else {
keycode=keyboardKeycodes[0][scancode];
}
//Now put it into the keystate array
if(break_code)
keydowns[keycode]=false;
else
keydowns[keycode]=true;
//0x2A 0x36 = Shift
if(keydowns[0x2A] || keydowns[0x36])
tableID^=1;
//0x1D = Ctrl
if(keydowns[0x1D])
tableID^=2;
//0x38 = Alt
if(keydowns[0x38])
tableID^=4;
//0x45 = Numlock
if(keycode==0x45)
numlock=!numlock;
//0x3A = CAPS
if(keycode==0x3A)
capslock=!capslock;
//0x46 = Scrolllock
if(keycode==0x46)
scrolllock=!scrolllock;
//0x45 = Numlock
if(keycode==0x45)
numlock=!numlock;
//0x3A = CAPS
if(keycode==0x3A)
capslock=!capslock;
//0x46 = Scrolllock
if(keycode==0x46)
scrolllock=!scrolllock;
if(capslock)
tableID^=1;
//Correct the LEDs
sendCommand(0xED);
outb(0x60, (scrolllock) + (numlock<<1) + (capslock<<2));
response=true;
//Convert it into a char
if(!break_code)
out << keymap[tableID][keycode];
debug << " -> 0x" << (int)keycode << ".\n";
return cpu;
}
Keyboard::Keyboard(): numlock(true), capslock(false), scrolllock(false), response(false) {
if(!idt.request(0x21, (struct cpu_state*(*)(struct cpu_state*))&handleIRQ)) {
debug << "Could not get an handler for IRQ1 (Keyboard)\n";
return;
}
//Clear keyboard buffer
while(inb(0x64) & 0x1) {
inb(0x60);
}
sendCommand(0xF4); //Activate keyboard
//Check for self-test being passed
sendCommand(0x20);
uint8_t ccb=inb(0x60);
if((ccb&4)) {
ccb &= ~1;
} else {
debug << "Keyboard didn't pass self-test!\nDeactivating IRQ1.\n";
ccb |= 1;
}
sendCommand(0x60);
outb(0x64, ccb);
}
if(capslock)
tableID^=1;
//Correct the LEDs
sendCommand(0xED);
outb(0x60, (scrolllock) + (numlock<<1) + (capslock<<2));
response=true;
//Convert it into a char
if(!break_code)
out << keymap[tableID][keycode];
debug << " -> 0x" << (int)keycode << ".\n";
return cpu;
}
Keyboard::Keyboard(): numlock(true), capslock(false), scrolllock(false), response(false) {
if(!idt.request(0x21, (struct cpu_state*(*)(struct cpu_state*))&handleIRQ)) {
debug << "Could not get an handler for IRQ1 (Keyboard)\n";
return;
}
//Clear keyboard buffer
while(inb(0x64) & 0x1) {
inb(0x60);
}
sendCommand(0xF4); //Activate keyboard
//Check for self-test being passed
sendCommand(0x20);
uint8_t ccb=inb(0x60);
if((ccb&4)) {
ccb &= ~1;
} else {
debug << "Keyboard didn't pass self-test!\nDeactivating IRQ1.\n";
ccb |= 1;
}
sendCommand(0x60);
outb(0x64, ccb);
}
}

View file

@ -3,52 +3,52 @@
#include <serial.hpp>
#include <textDISP.hpp>
namespace MTGosHAL {
auto Output::puts(const char* s) -> void {
int i=0;
while(s[i]!='\0')
putChar(s[i++]);
}
template <>
auto Output::operator<<<Base>(Base output) -> Output & {
base=static_cast<int>(output);
return *this;
}
template <>
auto Output::operator<<<int>(int op) -> Output & {
uintptr_t output=op;
const char* chars="0123456789ABCDEF";
char buf[33];
buf[32]='\0';
char* ptr=buf+31;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Output::operator<<<long int>(long int op) -> Output & {
uint64_t output=op;
const char* chars="0123456789ABCDEF";
char buf[65];
buf[64]='\0';
char* ptr=buf+63;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Output::operator<<<char>(char output) -> Output & {
putChar(output);
return *this;
}
template <>
auto Output::operator<<<char*>(char* output) -> Output & {
puts(output);
return *this;
}
auto Output::puts(const char* s) -> void {
int i=0;
while(s[i]!='\0')
putChar(s[i++]);
}
template <>
auto Output::operator<<<Base>(Base output) -> Output & {
base=static_cast<int>(output);
return *this;
}
template <>
auto Output::operator<<<int>(int op) -> Output & {
uintptr_t output=op;
const char* chars="0123456789ABCDEF";
char buf[33];
buf[32]='\0';
char* ptr=buf+31;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Output::operator<<<long int>(long int op) -> Output & {
uint64_t output=op;
const char* chars="0123456789ABCDEF";
char buf[65];
buf[64]='\0';
char* ptr=buf+63;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Output::operator<<<char>(char output) -> Output & {
putChar(output);
return *this;
}
template <>
auto Output::operator<<<char*>(char* output) -> Output & {
puts(output);
return *this;
}
}

View file

@ -1,78 +1,78 @@
#include <base.hpp>
#include <serial.hpp>
namespace MTGosHAL {
auto Serial::isTransmitEmpty() -> int {
return inb(port+SERIAL_LSR)&0x20;
}
auto Serial::putChar(char chr) -> void {
if(!works)
return;
int tries=65535;
while(!isTransmitEmpty()) {
waittimes++;
tries--;
if(!tries){
works=false;
return;
}
}
outb(port, chr);
transmits++;
}
auto Serial::serial_received() -> int {
return inb(port+SERIAL_LSR)&1;
}
auto Serial::getChar() -> char {
//We try 500 times to get a character
int tries=500;
while(!serial_received()) {
tries--;
waittimes++;
if(!tries) {
return '\0';
}
}
transmits++;
char chr = inb(port);
if(chr!='\r')
*this << chr;
else
*this << '\n';
return chr;
}
Serial::Serial(): works(true) {
uint32_t baud=115200;
port=*((uint16_t*)0x0400);
union {
uint8_t b[2];
uint16_t w;
} divisor;
divisor.w = 115200/baud;
//Turn off interrupts
outb(port+SERIAL_IER, 0x00);
//Set DLAB-bit
outb(port+SERIAL_LCR, 0x80);
//Set baud divisor
outb(port, divisor.b[0]);
outb(port+1, divisor.b[1]);
//Set bit count, parity and reset DLAB
outb(port+SERIAL_LCR, 3);
//Finish init
outb(port+SERIAL_FCR, 0xC7);
outb(port+SERIAL_MCR, 0x0B);
}
auto Serial::debug() -> void {
if(getChar()) {
*this << "The interactive debug shell was started.\n> ";
out << "The debug shell was started.\n";
char buf[256];
*this >> buf;
out << buf << "\nDebug shell closed.\n";
*this << "Unknown command. TODO\n";
}
uint64_t wt = waittimes;
uint64_t tm = transmits;
*this << "Transmit stats: " << (int32_t)wt << " times waited; " << (int32_t)tm << " bytes transferred.\n";
waittimes=transmits=0;
}
auto Serial::isTransmitEmpty() -> int {
return inb(port+SERIAL_LSR)&0x20;
}
auto Serial::putChar(char chr) -> void {
if(!works)
return;
int tries=65535;
while(!isTransmitEmpty()) {
waittimes++;
tries--;
if(!tries){
works=false;
return;
}
}
outb(port, chr);
transmits++;
}
auto Serial::serial_received() -> int {
return inb(port+SERIAL_LSR)&1;
}
auto Serial::getChar() -> char {
//We try 500 times to get a character
int tries=500;
while(!serial_received()) {
tries--;
waittimes++;
if(!tries) {
return '\0';
}
}
transmits++;
char chr = inb(port);
if(chr!='\r')
*this << chr;
else
*this << '\n';
return chr;
}
Serial::Serial(): works(true) {
uint32_t baud=115200;
port=*((uint16_t*)0x0400);
union {
uint8_t b[2];
uint16_t w;
} divisor;
divisor.w = 115200/baud;
//Turn off interrupts
outb(port+SERIAL_IER, 0x00);
//Set DLAB-bit
outb(port+SERIAL_LCR, 0x80);
//Set baud divisor
outb(port, divisor.b[0]);
outb(port+1, divisor.b[1]);
//Set bit count, parity and reset DLAB
outb(port+SERIAL_LCR, 3);
//Finish init
outb(port+SERIAL_FCR, 0xC7);
outb(port+SERIAL_MCR, 0x0B);
}
auto Serial::debug() -> void {
if(getChar()) {
*this << "The interactive debug shell was started.\n> ";
out << "The debug shell was started.\n";
char buf[256];
*this >> buf;
out << buf << "\nDebug shell closed.\n";
*this << "Unknown command. TODO\n";
}
uint64_t wt = waittimes;
uint64_t tm = transmits;
*this << "Transmit stats: " << (int32_t)wt << " times waited; " << (int32_t)tm << " bytes transferred.\n";
waittimes=transmits=0;
}
}

View file

@ -7,145 +7,145 @@
#include <string.h>
int x=0, y=0;
namespace MTGosHAL {
auto Screen::putChar(char c) -> void {
switch(c) {
case '\n':
x=0; y++;
break;
case '\r':
x=0;
auto Screen::putChar(char c) -> void {
switch(c) {
case '\n':
x=0; y++;
break;
case '\r':
x=0;
break;
case '\b':
x--;
if(x<0) x=0;
putChar(' ');
x--;
if(x<0) x=0;
break;
case '\0':
break;
default:
for(int lx=0;lx<8;lx++) {
for(int ly=0;ly<8;ly++) {
if(font[(int)((uint8_t)c)][ly]&(1<<lx)) {
lfb[(x*8+lx)+(y*8+ly)*1024]=0xFFFFFF;//static_cast<uint32_t>(fg);
} else {
lfb[(x*8+lx)+(y*8+ly)*1024]=0x000000;//static_cast<uint32_t>(bg);
}
}
}
x++;
if(x==SCREEN_WIDTH) {
x=0; y++;
}
break;
}
if(y>SCREEN_HEIGHT)
scroll();
}
auto Screen::clrscr() -> void {
for(int p=0;p<1024*786;p++) {
lfb[p]=0x000000;//static_cast<uint32_t>(bg);
}
x=y=0;
}
auto Screen::scroll() -> void {
for(int ly=0;ly<786-8;ly++) {
for(int lx=0;lx<1024;lx++) {
lfb[lx+ly*1024]=lfb[lx+(ly+8)*1024];
}
}
for(int ly=786-8;ly<786;ly++) {
for(int lx=0;lx<1024;lx++) {
lfb[lx+ly*1024]=0x000000;//static_cast<uint32_t>(bg);
}
}
y--;
}
template <>
auto Screen::operator<<<FG_color>(FG_color fg) -> Screen &{
this->fg=fg;
return *this;
}
template <>
auto Screen::operator<<<BG_color>(BG_color bg) -> Screen &{
this->bg=bg;
return *this;
}
auto Screen::setColor(FG_color fg) -> Screen &{
this->fg=fg;
return *this;
}
auto Screen::setColor(BG_color bg) -> Screen &{
this->bg=bg;
return *this;
}
auto Screen::setColor(FG_color fg, BG_color bg) -> Screen &{
return (*this).setColor(fg).setColor(bg);
}
break;
case '\b':
x--;
if(x<0) x=0;
putChar(' ');
x--;
if(x<0) x=0;
break;
case '\0':
break;
default:
for(int lx=0;lx<8;lx++) {
for(int ly=0;ly<8;ly++) {
if(font[(int)((uint8_t)c)][ly]&(1<<lx)) {
lfb[(x*8+lx)+(y*8+ly)*1024]=0xFFFFFF;//static_cast<uint32_t>(fg);
} else {
lfb[(x*8+lx)+(y*8+ly)*1024]=0x000000;//static_cast<uint32_t>(bg);
}
}
}
x++;
if(x==SCREEN_WIDTH) {
x=0; y++;
}
break;
}
if(y>SCREEN_HEIGHT)
scroll();
}
auto Screen::clrscr() -> void {
for(int p=0;p<1024*786;p++) {
lfb[p]=0x000000;//static_cast<uint32_t>(bg);
}
x=y=0;
}
auto Screen::scroll() -> void {
for(int ly=0;ly<786-8;ly++) {
for(int lx=0;lx<1024;lx++) {
lfb[lx+ly*1024]=lfb[lx+(ly+8)*1024];
}
}
for(int ly=786-8;ly<786;ly++) {
for(int lx=0;lx<1024;lx++) {
lfb[lx+ly*1024]=0x000000;//static_cast<uint32_t>(bg);
}
}
y--;
}
template <>
auto Screen::operator<<<FG_color>(FG_color fg) -> Screen &{
this->fg=fg;
return *this;
}
template <>
auto Screen::operator<<<BG_color>(BG_color bg) -> Screen &{
this->bg=bg;
return *this;
}
auto Screen::setColor(FG_color fg) -> Screen &{
this->fg=fg;
return *this;
}
auto Screen::setColor(BG_color bg) -> Screen &{
this->bg=bg;
return *this;
}
auto Screen::setColor(FG_color fg, BG_color bg) -> Screen &{
return (*this).setColor(fg).setColor(bg);
}
auto Screen::init(struct multiboot_info* mb_info) -> void {
lfb=(uint32_t*)((uintptr_t)mb_info->framebuffer_addr);
//clrscr();
//Render '\001' character
for(int tx=0;tx<16;tx++) {
for(int ty=0;ty<16;ty++) {
for(int x=0;x<8;x++) {
for(int y=0;y<8;y++) {
if(font[tx+ty*16][y]&(1<<x))
lfb[(x+tx*8)+(y+ty*8)*1024]=0xFFFFFF;
}
}
}
}
}
auto Screen::puts(const char* s) -> void {
int i=0;
while(s[i]!='\0')
putChar(s[i++]);
}
template <>
auto Screen::operator<<<Base>(Base output) -> Screen & {
base=static_cast<int>(output);
return *this;
}
template <>
auto Screen::operator<<<int>(int op) -> Screen & {
uintptr_t output=op;
const char* chars="0123456789ABCDEF";
char buf[33];
buf[32]='\0';
char* ptr=buf+31;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Screen::operator<<<long int>(long int op) -> Screen & {
uint64_t output=op;
const char* chars="0123456789ABCDEF";
char buf[65];
buf[64]='\0';
char* ptr=buf+63;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Screen::operator<<<char>(char output) -> Screen & {
putChar(output);
return *this;
}
template <>
auto Screen::operator<<<char*>(char* output) -> Screen & {
puts(output);
return *this;
}
auto Screen::init(struct multiboot_info* mb_info) -> void {
lfb=(uint32_t*)((uintptr_t)mb_info->framebuffer_addr);
//clrscr();
//Render '\001' character
for(int tx=0;tx<16;tx++) {
for(int ty=0;ty<16;ty++) {
for(int x=0;x<8;x++) {
for(int y=0;y<8;y++) {
if(font[tx+ty*16][y]&(1<<x))
lfb[(x+tx*8)+(y+ty*8)*1024]=0xFFFFFF;
}
}
}
}
}
auto Screen::puts(const char* s) -> void {
int i=0;
while(s[i]!='\0')
putChar(s[i++]);
}
template <>
auto Screen::operator<<<Base>(Base output) -> Screen & {
base=static_cast<int>(output);
return *this;
}
template <>
auto Screen::operator<<<int>(int op) -> Screen & {
uintptr_t output=op;
const char* chars="0123456789ABCDEF";
char buf[33];
buf[32]='\0';
char* ptr=buf+31;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Screen::operator<<<long int>(long int op) -> Screen & {
uint64_t output=op;
const char* chars="0123456789ABCDEF";
char buf[65];
buf[64]='\0';
char* ptr=buf+63;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Screen::operator<<<char>(char output) -> Screen & {
putChar(output);
return *this;
}
template <>
auto Screen::operator<<<char*>(char* output) -> Screen & {
puts(output);
return *this;
}
}

View file

@ -7,70 +7,70 @@ extern "C" const int kernel_end; //those are voids actually
#define SHIFT(a) ((a)<<20)
#define FLAGS 0x7ffff
void *operator new(size_t size) {
return MTGosHAL::mm.alloc(size);
return MTGosHAL::mm.alloc(size);
}
void *operator new[](size_t size) {
return MTGosHAL::mm.alloc(size);
return MTGosHAL::mm.alloc(size);
}
void operator delete(void* p) {
MTGosHAL::mm.free(p);
MTGosHAL::mm.free(p);
}
void operator delete[](void* p) {
MTGosHAL::mm.free(p);
MTGosHAL::mm.free(p);
}
void operator delete(void* p, size_t size) {
MTGosHAL::mm.free(p);
MTGosHAL::mm.free(p);
}
void operator delete[](void* p, size_t size) {
MTGosHAL::mm.free(p);
MTGosHAL::mm.free(p);
}
namespace MTGosHAL {
auto PMM::alloc(size_t length) -> void * {
auto PMM::alloc(size_t length) -> void * {
if(!head) {
//Alloc space for head
if(length+sizeof(malloc_t)<=PAGESIZE) { //Small optimization. The routine for allocating more than one continuous page is terribly slow.
void *tmp;
*this >> tmp;
head=(malloc_t*)tmp;
} else
head=(malloc_t*)(*this)(UNSHIFT((length+sizeof(malloc_t)))+1);
if(!head) //The alloc() didn't work! We're out of RAM!
return nullptr;
head->len=length;
head->next=head->last=nullptr;
malloc_t* tmp=head;
tmp++;
return (void*)tmp;
//Alloc space for head
if(length+sizeof(malloc_t)<=PAGESIZE) { //Small optimization. The routine for allocating more than one continuous page is terribly slow.
void *tmp;
*this >> tmp;
head=(malloc_t*)tmp;
} else
head=(malloc_t*)(*this)(UNSHIFT((length+sizeof(malloc_t)))+1);
if(!head) //The alloc() didn't work! We're out of RAM!
return nullptr;
head->len=length;
head->next=head->last=nullptr;
malloc_t* tmp=head;
tmp++;
return (void*)tmp;
}
malloc_t* curr=head;
malloc_t* last=nullptr;
do {
uintptr_t loc=(uintptr_t)curr+sizeof(malloc_t)+curr->len;
if((loc+length+sizeof(malloc_t))<((loc&(~FLAGS))+PAGESIZE) &&
((!curr->next) || (loc+length+sizeof(malloc_t))<((uintptr_t)(curr->next)))) {
malloc_t *allocd=(malloc_t *)loc;
allocd->len=length;
allocd->last=curr;
allocd->next=curr->next; //Set double linked list
curr->next=allocd;
if(allocd->next)
allocd->next->last=allocd;
malloc_t *tmp=allocd;
tmp++;
return (void*)tmp;
}
last=curr;
curr=curr->next;
uintptr_t loc=(uintptr_t)curr+sizeof(malloc_t)+curr->len;
if((loc+length+sizeof(malloc_t))<((loc&(~FLAGS))+PAGESIZE) &&
((!curr->next) || (loc+length+sizeof(malloc_t))<((uintptr_t)(curr->next)))) {
malloc_t *allocd=(malloc_t *)loc;
allocd->len=length;
allocd->last=curr;
allocd->next=curr->next; //Set double linked list
curr->next=allocd;
if(allocd->next)
allocd->next->last=allocd;
malloc_t *tmp=allocd;
tmp++;
return (void*)tmp;
}
last=curr;
curr=curr->next;
} while(curr);
malloc_t *allocd=nullptr;
if(length+sizeof(malloc_t)<=PAGESIZE) { //Small optimization. The routine for allocating more than one continuous page is terribly slow.
void *tmp;
*this >> tmp;
allocd=(malloc_t*)tmp;
void *tmp;
*this >> tmp;
allocd=(malloc_t*)tmp;
} else
allocd=(malloc_t*)(*this)(UNSHIFT(length+sizeof(malloc_t))+1);
allocd=(malloc_t*)(*this)(UNSHIFT(length+sizeof(malloc_t))+1);
if(!allocd) //The alloc() didn't work! We're out of RAM!
return nullptr;
return nullptr;
last->next=allocd;
allocd->len=length;
allocd->last=last;
@ -81,46 +81,46 @@ namespace MTGosHAL {
}
auto PMM::free(void* ptr) -> bool {
if(!ptr)
return false;
return false;
malloc_t* curr=head;
malloc_t* chk=(malloc_t*)ptr;
chk--;
do {
if(curr==chk) {
uintptr_t start=((uintptr_t)chk)&(~FLAGS);
uintptr_t end=start+PAGESIZE;
if((((uintptr_t)(curr->last)<start)||((uintptr_t)(curr->last)>=end))&&(((uintptr_t)(curr->next)>=end)||((uintptr_t)(curr->next)<start))) {
*this << (void*)start;
if(curr==chk) {
uintptr_t start=((uintptr_t)chk)&(~FLAGS);
uintptr_t end=start+PAGESIZE;
if((((uintptr_t)(curr->last)<start)||((uintptr_t)(curr->last)>=end))&&(((uintptr_t)(curr->next)>=end)||((uintptr_t)(curr->next)<start))) {
*this << (void*)start;
}
if(curr->last)
curr->last->next=curr->next;
else {
head=curr->next;
}
if(curr->next)
curr->next->last=curr->last;
return true;
}
if(curr->last)
curr->last->next=curr->next;
else {
head=curr->next;
}
if(curr->next)
curr->next->last=curr->last;
return true;
}
curr=curr->next;
curr=curr->next;
} while(curr);
return false;
}
PMM::PMM(): head(nullptr), pmm2() {}
auto PMM::init(struct multiboot_info* mb_info) -> void {
pmm2.init(mb_info);
pmm2.init(mb_info);
}
auto PMM::markUsed(const void * addr, uint64_t length) -> bool {
return pmm2.markUsed(addr, length);
return pmm2.markUsed(addr, length);
}
auto PMM::operator >> (void * &addr) -> PMM & {
pmm2>>addr;
return *this;
pmm2>>addr;
return *this;
} //alloc
auto PMM::operator << (const void * addr) -> PMM & {
pmm2<<addr;
return *this;
pmm2<<addr;
return *this;
} //free
auto PMM::operator()(int pages) -> void*{
return pmm2(pages);
return pmm2(pages);
} //alloc_multipage
}

View file

@ -16,70 +16,70 @@ namespace MTGosHAL {
PMM2::PMM2(): pmm3() {
}
auto PMM2::markUsed(const void * addr, uint32_t length) -> bool {
if(length<0x200000)
length=0x200000;
uintptr_t add=(uintptr_t)addr;
uint64_t pagetid = SPLIT1_UNSHIFT(add);
if(length<0x200000)
length=0x200000;
uintptr_t add=(uintptr_t)addr;
uint64_t pagetid = SPLIT1_UNSHIFT(add);
//Check if used
for(uintptr_t curr_addr=add+length;curr_addr>add;curr_addr-=0x200000) {
if(pageTable[SPLIT1_UNSHIFT(curr_addr)])
return false;
}
//Mark as used
uint64_t counter=1;
for(uintptr_t curr_addr=add+length;curr_addr>add;curr_addr-=0x200000) {
pageTable[SPLIT1_UNSHIFT(curr_addr)]=counter++;
pmm3.markUsed((void*)curr_addr);
}
return true;
//Check if used
for(uintptr_t curr_addr=add+length;curr_addr>add;curr_addr-=0x200000) {
if(pageTable[SPLIT1_UNSHIFT(curr_addr)])
return false;
}
//Mark as used
uint64_t counter=1;
for(uintptr_t curr_addr=add+length;curr_addr>add;curr_addr-=0x200000) {
pageTable[SPLIT1_UNSHIFT(curr_addr)]=counter++;
pmm3.markUsed((void*)curr_addr);
}
return true;
}
auto PMM2::operator >> (void * &addr) -> PMM2 & {
pmm3 >> addr;
markUsed(addr,0x200000);
return *this;
pmm3 >> addr;
markUsed(addr,0x200000);
return *this;
}
auto PMM2::operator << (const void *addr) -> PMM2 & {
uint64_t add=(uint64_t)addr;
for(uint64_t i=0;i<pageTable[SPLIT1_UNSHIFT(add)];i++) {
pageTable[SPLIT1_UNSHIFT(add+i*0x200000)]=0;
pmm3 << (void*)(add+i*0x200000);
}
return *this;
uint64_t add=(uint64_t)addr;
for(uint64_t i=0;i<pageTable[SPLIT1_UNSHIFT(add)];i++) {
pageTable[SPLIT1_UNSHIFT(add+i*0x200000)]=0;
pmm3 << (void*)(add+i*0x200000);
}
return *this;
}
auto PMM2::operator()(int pages) -> void* {
//I want to get this working so:
//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
// NEVER USE A BRUTE-FORCE ALGO TO ALLOC PAGES!
//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
for(uint64_t i=0;i<(uint64_t)(-(pages*0x200000));i+=0x200000) {
if(markUsed((void*)i,pages*0x200000))
return (void*)i;
}
return nullptr;
//I want to get this working so:
//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
// NEVER USE A BRUTE-FORCE ALGO TO ALLOC PAGES!
//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
for(uint64_t i=0;i<(uint64_t)(-(pages*0x200000));i+=0x200000) {
if(markUsed((void*)i,pages*0x200000))
return (void*)i;
}
return nullptr;
}
auto PMM2::init(struct multiboot_info* mb_info) -> void {
pmm3.init(mb_info);
void *temp;
pmm3 >> temp;
pageTable=(uint64_t*)temp;
for(int i=0;i<0x80000;i++)
pageTable[i]=0;
markUsed(pageTable,0x200000);
markUsed((void*)nullptr,0x200000);
struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*) (uintptr_t)(mb_info->mmap_addr);
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((uintptr_t) mb_info->mmap_addr + mb_info->mmap_length);
while(mmap < mmap_end) {
if(mmap->type != 1) {
markUsed((void*)mmap->addr,mmap->len);
pmm3.init(mb_info);
void *temp;
pmm3 >> temp;
pageTable=(uint64_t*)temp;
for(int i=0;i<0x80000;i++)
pageTable[i]=0;
markUsed(pageTable,0x200000);
markUsed((void*)nullptr,0x200000);
struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*) (uintptr_t)(mb_info->mmap_addr);
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((uintptr_t) mb_info->mmap_addr + mb_info->mmap_length);
while(mmap < mmap_end) {
if(mmap->type != 1) {
markUsed((void*)mmap->addr,mmap->len);
}
mmap++;
}
markUsed(&kernel_start,((uintptr_t)&kernel_end)-((uintptr_t)&kernel_start)); //Protect kernel)
multiboot_mod_list *mods = (multiboot_mod_list*) (uintptr_t)(mb_info->mods_addr);
for(uint32_t i=0;i<mb_info->mods_count;i++) {
markUsed((void*)((uintptr_t)(&mods[i])&(~0xFFF)),4096); //Mark all of the module table as used
markUsed((void*)(uintptr_t)(mods[i].mod_start),mods[i].mod_end-mods[i].mod_start);
}
mmap++;
}
markUsed(&kernel_start,((uintptr_t)&kernel_end)-((uintptr_t)&kernel_start)); //Protect kernel)
multiboot_mod_list *mods = (multiboot_mod_list*) (uintptr_t)(mb_info->mods_addr);
for(uint32_t i=0;i<mb_info->mods_count;i++) {
markUsed((void*)((uintptr_t)(&mods[i])&(~0xFFF)),4096); //Mark all of the module table as used
markUsed((void*)(uintptr_t)(mods[i].mod_start),mods[i].mod_end-mods[i].mod_start);
}
}
}

View file

@ -7,65 +7,65 @@ extern "C" const int kernel_end; //those are voids actually
namespace MTGosHAL {
PMM3::PMM3() {}
auto PMM3::init(struct multiboot_info * mb_info) -> void {
for(int i=0;i<0x8000;i++)
bitmap[i]=0;
struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*) (uintptr_t)(mb_info->mmap_addr);
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((uintptr_t) mb_info->mmap_addr + mb_info->mmap_length);
while (mmap < mmap_end) {
if (mmap->type == 1) {
// Memory is free
uintptr_t addr = mmap->addr;
uintptr_t end_addr = addr + mmap->len;
while (addr < end_addr) {
*this << (void*) addr;
addr += 0x200000;
}
}
mmap++;
}
uintptr_t addr = (uintptr_t) &kernel_start;
while(addr < (uintptr_t) &kernel_end) {
markUsed((void*)addr);
addr+=0x200000;
}
markUsed((void*)0);
multiboot_mod_list *mods = (multiboot_mod_list*) (uintptr_t)(mb_info->mods_addr);
for(uint32_t i=0;i<mb_info->mods_count;i++) {
markUsed((void*)((uint64_t)(&mods[i])&(~0x1FFFFF))); //Mark all of the module table as used
for(uint64_t start=(uint64_t)(mods[i].mod_start)&(~0x1FFFFF);start<(uint32_t)(mods[i].mod_end);start+=0x200000) {
markUsed((void*)start); //Protect all multiboot modules
}
}
for(int i=0;i<0x8000;i++)
bitmap[i]=0;
struct multiboot_mmap_entry* mmap = (struct multiboot_mmap_entry*) (uintptr_t)(mb_info->mmap_addr);
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((uintptr_t) mb_info->mmap_addr + mb_info->mmap_length);
while (mmap < mmap_end) {
if (mmap->type == 1) {
// Memory is free
uintptr_t addr = mmap->addr;
uintptr_t end_addr = addr + mmap->len;
while (addr < end_addr) {
*this << (void*) addr;
addr += 0x200000;
}
}
mmap++;
}
uintptr_t addr = (uintptr_t) &kernel_start;
while(addr < (uintptr_t) &kernel_end) {
markUsed((void*)addr);
addr+=0x200000;
}
markUsed((void*)0);
multiboot_mod_list *mods = (multiboot_mod_list*) (uintptr_t)(mb_info->mods_addr);
for(uint32_t i=0;i<mb_info->mods_count;i++) {
markUsed((void*)((uint64_t)(&mods[i])&(~0x1FFFFF))); //Mark all of the module table as used
for(uint64_t start=(uint64_t)(mods[i].mod_start)&(~0x1FFFFF);start<(uint32_t)(mods[i].mod_end);start+=0x200000) {
markUsed((void*)start); //Protect all multiboot modules
}
}
}
auto PMM3::markUsed(const void * addr) -> void {
uintptr_t address=(uintptr_t)addr;
address>>=21;
int index=address>>5;
int bit=1<<(address&0x1F);
bitmap[index]&=~bit;
uintptr_t address=(uintptr_t)addr;
address>>=21;
int index=address>>5;
int bit=1<<(address&0x1F);
bitmap[index]&=~bit;
}
auto PMM3::operator >> (void * &addr) -> PMM3 & {
for(uintptr_t i=0;i<0x8000;i++) {
if(!bitmap[i])
continue;
for(uintptr_t j=0;j<32;j++) {
if(bitmap[i]&(1<<j)) {
//We found a free page!
bitmap[i]&=~(1<<j);
addr=(void*)(((i<<5)+j)<<21);
return *this;
}
}
}
addr=nullptr;
return *this;
for(uintptr_t i=0;i<0x8000;i++) {
if(!bitmap[i])
continue;
for(uintptr_t j=0;j<32;j++) {
if(bitmap[i]&(1<<j)) {
//We found a free page!
bitmap[i]&=~(1<<j);
addr=(void*)(((i<<5)+j)<<21);
return *this;
}
}
}
addr=nullptr;
return *this;
}
auto PMM3::operator << (const void * addr) -> PMM3 & {
uintptr_t address=(uintptr_t)addr;
address>>=21;
int index=address>>5;
int bit=1<<(address&0x1F);
bitmap[index]|=bit;
return *this;
uintptr_t address=(uintptr_t)addr;
address>>=21;
int index=address>>5;
int bit=1<<(address&0x1F);
bitmap[index]|=bit;
return *this;
}
}

View file

@ -2,23 +2,22 @@
#include <textDISP.hpp>
#include <Multitasking.hpp>
namespace MTGosHAL {
Task::Task(struct cpu_state* cpu): cpu_state(cpu), next(nullptr) {};
//This is run every time this task is chosen by the scheduler
auto Task::unpause() -> struct cpu_state* {
return cpu_state;
}
//This is run every time the timer ticks and a task is running
auto Task::pause(struct cpu_state* cpu) -> Task * {
cpu_state=cpu;
return next;
}
auto Task::addTask(Task* task) -> void {
if(next)
return next->addTask(task);
next=task;
}
auto Task::hasNext() -> bool {
return next!=nullptr;
}
Task::Task(struct cpu_state* cpu): cpu_state(cpu), next(nullptr) {};
//This is run every time this task is chosen by the scheduler
auto Task::unpause() -> struct cpu_state* {
return cpu_state;
}
//This is run every time the timer ticks and a task is running
auto Task::pause(struct cpu_state* cpu) -> Task * {
cpu_state=cpu;
return next;
}
auto Task::addTask(Task* task) -> void {
if(next)
return next->addTask(task);
next=task;
}
auto Task::hasNext() -> bool {
return next!=nullptr;
}
}

View file

@ -4,32 +4,32 @@
#include <output.hpp>
using namespace MTGosHAL;
auto load(Elf32_Ehdr* file) -> void* {
if((file->e_ident[0]!=ELFMAG0)||
(file->e_ident[1]!=ELFMAG1)||
(file->e_ident[2]!=ELFMAG2)||
(file->e_ident[3]!=ELFMAG3) ) {
return nullptr;
debug << "File is not a valid ELF file!\n";
}
Elf32_Phdr *phdr = (Elf32_Phdr*)((uintptr_t)(file->e_phoff)+(uintptr_t)file);
debug << "entry=";
debug << Base::HEXADECIMAL;
debug << (int)file->e_entry;
for(int i=0;i<file->e_phnum;i++) {
uint32_t start=phdr[i].p_vaddr;
debug << "start=";
debug << Base::HEXADECIMAL;
debug << (int)start;
uint32_t end=start+phdr[i].p_memsz;
debug << "end=";
debug << Base::HEXADECIMAL;
debug << (int)end;
if((start <= file->e_entry) && (file->e_entry < end)) {
debug << "start=";
debug << Base::HEXADECIMAL;
debug << (int)(file->e_entry-start+phdr[i].p_offset+(uintptr_t)file);
return (void*) (file->e_entry-start+phdr[i].p_offset+(uintptr_t)file); //Calculate _start address
if((file->e_ident[0]!=ELFMAG0)||
(file->e_ident[1]!=ELFMAG1)||
(file->e_ident[2]!=ELFMAG2)||
(file->e_ident[3]!=ELFMAG3) ) {
return nullptr;
debug << "File is not a valid ELF file!\n";
}
Elf32_Phdr *phdr = (Elf32_Phdr*)((uintptr_t)(file->e_phoff)+(uintptr_t)file);
debug << "entry=";
debug << Base::HEXADECIMAL;
debug << (int)file->e_entry;
for(int i=0;i<file->e_phnum;i++) {
uint32_t start=phdr[i].p_vaddr;
debug << "start=";
debug << Base::HEXADECIMAL;
debug << (int)start;
uint32_t end=start+phdr[i].p_memsz;
debug << "end=";
debug << Base::HEXADECIMAL;
debug << (int)end;
if((start <= file->e_entry) && (file->e_entry < end)) {
debug << "start=";
debug << Base::HEXADECIMAL;
debug << (int)(file->e_entry-start+phdr[i].p_offset+(uintptr_t)file);
return (void*) (file->e_entry-start+phdr[i].p_offset+(uintptr_t)file); //Calculate _start address
}
}
}
return nullptr;
}

View file

@ -13,33 +13,33 @@ void operator delete (void *, void *) { }
void operator delete[] (void *, void *) { }
using namespace MTGosHAL;
void pid_null() {
for(;;);
for(;;);
}
void task_a() {
while(true)
out << "a";
while(true)
out << "a";
}
void task_b() {
while(true)
out << "b";
while(true)
out << "b";
}
void task_c() {
while(true)
out << "c";
while(true)
out << "c";
}
void task_d() {
while(true)
out << "d";
while(true)
out << "d";
}
void main(void ** files, MTGosHAL::Serial &debug, MTGosHAL::PMM &mm, MTGosHAL::Screen &out,
MTGosHAL::Screen &err, MTGosHAL::Keyboard &in, MTGosHAL::Multitasking &tasks, MTGosHAL::BlockDevice &disk) {
out << "Initializing Kernel!\n";
Elf32_Ehdr** programs=(Elf32_Ehdr**)files;
tasks.initTask(&pid_null);
for(int i=0;programs[i];i++) {
void(*start)()=(void(*)())load(programs[i]);
if(!start)
continue;
tasks.initTask(start);
}
MTGosHAL::Screen &err, MTGosHAL::Keyboard &in, MTGosHAL::Multitasking &tasks, MTGosHAL::BlockDevice &disk) {
out << "Initializing Kernel!\n";
Elf32_Ehdr** programs=(Elf32_Ehdr**)files;
tasks.initTask(&pid_null);
for(int i=0;programs[i];i++) {
void(*start)()=(void(*)())load(programs[i]);
if(!start)
continue;
tasks.initTask(start);
}
}

View file

@ -3,39 +3,39 @@
#pragma GCC push_options
#pragma GCC optimize ("O0")
void memmove(void* dst, void* src, uint32_t size) {
uint8_t* from=(uint8_t*)src;
uint8_t* to=(uint8_t*)dst;
if((src<dst)&&((src+size)>dst)) {
for(int i=size-1;i>=0;i--)
to[i]=from[i]; //This would get optimized by gcc to memmove(dst, src, size); if optimizations are enabled.
} else if(src != dst) {
for(int i=0;i<size;i++)
to[i]=from[i]; //This would get optimized by gcc to memmove(dst, src, size); if optimizations are enabled.
}
uint8_t* from=(uint8_t*)src;
uint8_t* to=(uint8_t*)dst;
if((src<dst)&&((src+size)>dst)) {
for(int i=size-1;i>=0;i--)
to[i]=from[i]; //This would get optimized by gcc to memmove(dst, src, size); if optimizations are enabled.
} else if(src != dst) {
for(int i=0;i<size;i++)
to[i]=from[i]; //This would get optimized by gcc to memmove(dst, src, size); if optimizations are enabled.
}
}
void memcpy(void* dest, void* src, uint32_t size) {
memmove(dest, src, size);
memmove(dest, src, size);
}
uint32_t strlen(const char* str) {
uint32_t i=0;
char* str2=(char*)((uintptr_t)str);
while(*str2) {
i++;
str2++;
}
return i;
uint32_t i=0;
char* str2=(char*)((uintptr_t)str);
while(*str2) {
i++;
str2++;
}
return i;
}
int strcmp(const char* str1, const char* str2) {
uint32_t len1=strlen(str1);
uint32_t len2=strlen(str2);
if(len1>len2)
return 1;
else if (len1<len2)
return -1;
for(int i=0;i<len1;i++) {
if(str1[i]!=str2[i])
return str1[i]-str2[i];
}
return 0;
uint32_t len1=strlen(str1);
uint32_t len2=strlen(str2);
if(len1>len2)
return 1;
else if (len1<len2)
return -1;
for(int i=0;i<len1;i++) {
if(str1[i]!=str2[i])
return str1[i]-str2[i];
}
return 0;
}
#pragma GCC pop_options

View file

@ -2,70 +2,70 @@
#include <syscall.hpp>
#include <base.hpp>
#include <textDISP.hpp>
#include <string.hpp>
ScreenOut::ScreenOut(bool err): err(err) {
}
auto ScreenOut::operator<<(char *text) -> ScreenOut & {
if(!text)
if(!text)
return *this;
if(err)
MTGosHAL::err << String(text);
else
MTGosHAL::out << String(text);
return *this;
if(err)
MTGosHAL::err << text;
else
MTGosHAL::out << text;
return *this;
}
auto ScreenOut::clrscr() -> ScreenOut & {
if(err)
MTGosHAL::err.clrscr();
else
MTGosHAL::out.clrscr();
return *this;
if(err)
MTGosHAL::err.clrscr();
else
MTGosHAL::out.clrscr();
return *this;
}
auto ScreenOut::setColor(BGColor bg, FGColor fg) -> ScreenOut & {
if(err)
MTGosHAL::err << static_cast<MTGosHAL::BG_color>(bg) << static_cast<MTGosHAL::FG_color>(fg) ;
else
MTGosHAL::out << static_cast<MTGosHAL::BG_color>(bg) << static_cast<MTGosHAL::FG_color>(fg) ;
return *this;
if(err)
MTGosHAL::err << static_cast<MTGosHAL::BG_color>(bg) << static_cast<MTGosHAL::FG_color>(fg) ;
else
MTGosHAL::out << static_cast<MTGosHAL::BG_color>(bg) << static_cast<MTGosHAL::FG_color>(fg) ;
return *this;
}
ScreenOut::~ScreenOut() {}
auto syscall(uint32_t syscall_num, void* handle, void* args) -> void* {
uint16_t objnum=(uint16_t)(syscall_num>>16);
uint16_t funcnum=(uint16_t)syscall_num;
switch(objnum) {
case 0: {
ScreenOut *obj = (ScreenOut*)handle;
switch(funcnum) {
case 0:
return (void*)(new ScreenOut(((bool *)args)[0]));
case 0: {
ScreenOut *obj = (ScreenOut*)handle;
switch(funcnum) {
case 0:
return (void*)(new ScreenOut(((bool *)args)[0]));
break;
case 1:
*obj << ((char**)args)[0];
return handle;
break;
case 2:
obj->clrscr();
return handle;
break;
case 3: {
BGColor bg=static_cast<BGColor>(((uint32_t *)args)[0]);
FGColor fg=static_cast<FGColor>(((uint32_t *)args)[1]);
obj->setColor(bg,fg);
return handle;
break;
}
case 0xFFFF:
delete obj;
return nullptr;
break;
default:
break;
}
break;
}
default:
break;
case 1:
*obj << ((char**)args)[0];
return handle;
break;
case 2:
obj->clrscr();
return handle;
break;
case 3: {
BGColor bg=static_cast<BGColor>(((uint32_t *)args)[0]);
FGColor fg=static_cast<FGColor>(((uint32_t *)args)[1]);
obj->setColor(bg,fg);
return handle;
break;
}
case 0xFFFF:
delete obj;
return nullptr;
break;
default:
break;
}
break;
}
default:
break;
}
return nullptr;
}

View file

@ -1,45 +1,45 @@
.global screenout_init
// void * screenout_init(int err);
screenout_init:
stmdb sp!, {r0} //r0 is err
mov r0, #0
svc #0 //Only one svc
sub sp, #4
bx lr
stmdb sp!, {r0} //r0 is err
mov r0, #0
svc #0 //Only one svc
sub sp, #4
bx lr
.global screenout_out
// void * screenout_out(void* handle, char *str);
screenout_out:
stmdb sp!, {r1} // R1 is str
mov r1, r0 //R0 is handle
mov r0, #1
svc #0
add sp, #4
bx lr
stmdb sp!, {r1} // R1 is str
mov r1, r0 //R0 is handle
mov r0, #1
svc #0
add sp, #4
bx lr
.global screenout_clear
// void * screenout_clear(void* handle);
screenout_clear:
mov r1, r0
mov r0, #2
svc #0
bx lr
mov r1, r0
mov r0, #2
svc #0
bx lr
.global screenout_setcolor
// void * screenout_setcolor(void* handle, uint32_t BG, uint32_t FG)
screenout_setcolor:
stmdb sp!, {r1, r2}
mov r1, r0
mov r0, #3
svc #0
add sp, #8
bx lr
stmdb sp!, {r1, r2}
mov r1, r0
mov r0, #3
svc #0
add sp, #8
bx lr
.global screenout_destroy
// void * screenout_destroy(void * handle)
screenout_destroy:
mov r1, r0
mov r0, #0x10000
sub r0, #1
svc #0
bx lr
mov r1, r0
mov r0, #0x10000
sub r0, #1
svc #0
bx lr

View file

@ -7,38 +7,38 @@ void * screenout_setcolor(void* handle, uint32_t BG, uint32_t FG);
void * screenout_destroy(void * handle);
}
ScreenOut::ScreenOut(bool err) {
handle=screenout_init(err);
handle=screenout_init(err);
}
auto ScreenOut::operator<<(const char * str) -> ScreenOut & {
screenout_out(handle, str);
return *this;
screenout_out(handle, str);
return *this;
}
auto ScreenOut::operator<<(int output) -> ScreenOut & {
int base=10;
const char* chars="0123456789ABCDEF";
char buf[33];
buf[32]='\0';
char* ptr=buf+31;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
*this << ptr+1;
return *this;
int base=10;
const char* chars="0123456789ABCDEF";
char buf[33];
buf[32]='\0';
char* ptr=buf+31;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
*this << ptr+1;
return *this;
}
auto ScreenOut::clrscr() -> ScreenOut & {
screenout_clear(handle);
return *this;
screenout_clear(handle);
return *this;
}
auto ScreenOut::setColor(BGColor bg, FGColor fg) -> ScreenOut & {
screenout_setcolor(handle, static_cast<uint32_t>(bg), static_cast<uint32_t>(fg));
return *this;
screenout_setcolor(handle, static_cast<uint32_t>(bg), static_cast<uint32_t>(fg));
return *this;
}
ScreenOut::~ScreenOut() {
handle=screenout_destroy(handle);
handle=screenout_destroy(handle);
}
void main();
extern "C" void _start() {
main();
for(;;);
main();
for(;;);
}

View file

@ -1,26 +1,26 @@
#include <mtgos.hpp>
static unsigned short* videomem = (unsigned short*) 0xb8000;
void temp() {
int i;
int i;
for (i = 0; i < 3; i++) {
*videomem++ = (0x07 << 8) | ('0' + i);
}
}
void main()
{
char arr[4]="123";
ScreenOut out=ScreenOut(false);
int i;
out.setColor(BGColor::BLUE, FGColor::YELLOW);
for(;;) {
long double a;
long double b=a;
out << a;
a+=0.5;
if(a!=b+0.5)
out << " ";
else
out << "=";
out << a;
}
char arr[4]="123";
ScreenOut out=ScreenOut(false);
int i;
out.setColor(BGColor::BLUE, FGColor::YELLOW);
for(;;) {
long double a;
long double b=a;
out << a;
a+=0.5;
if(a!=b+0.5)
out << " ";
else
out << "=";
out << a;
}
}

View file

@ -1,62 +1,62 @@
.global screenout_init
// void * screenout_init(int err);
screenout_init:
mov 0x4(%esp), %eax
push %eax
xor %eax, %eax
int $0x30
pop %ecx
ret
mov 0x4(%esp), %eax
push %eax
xor %eax, %eax
int $0x30
pop %ecx
ret
.global screenout_out
// void * screenout_out(void* handle, char *str);
screenout_out:
push %ebx
mov 0xC(%esp), %eax
mov 0x8(%esp), %ebx
push %eax
xor %eax, %eax
inc %eax
int $0x30
pop %ebx
pop %ebx
ret
push %ebx
mov 0xC(%esp), %eax
mov 0x8(%esp), %ebx
push %eax
xor %eax, %eax
inc %eax
int $0x30
pop %ebx
pop %ebx
ret
.global screenout_clear
// void * screenout_clear(void* handle);
screenout_clear:
push %ebx
mov 0x8(%esp), %ebx
xor %eax, %eax
inc %eax
inc %eax
int $0x30
pop %ebx
ret
push %ebx
mov 0x8(%esp), %ebx
xor %eax, %eax
inc %eax
inc %eax
int $0x30
pop %ebx
ret
.global screenout_setcolor
// void * screenout_setcolor(void* handle, uint32_t BG, uint32_t FG)
screenout_setcolor:
push %ebx
mov 0x8(%esp), %ebx
mov 0xC(%esp), %eax
mov 0x10(%esp), %ecx
push %ecx
push %eax
mov $3, %eax
int $0x30
pop %ebx
pop %ebx
pop %ebx
ret
push %ebx
mov 0x8(%esp), %ebx
mov 0xC(%esp), %eax
mov 0x10(%esp), %ecx
push %ecx
push %eax
mov $3, %eax
int $0x30
pop %ebx
pop %ebx
pop %ebx
ret
.global screenout_destroy
// void * screenout_destroy(void * handle)
screenout_destroy:
push %ebx
mov 0x8(%esp), %ebx
xor %eax, %eax
dec %ax
int $0x30
pop %ebx
ret
push %ebx
mov 0x8(%esp), %ebx
xor %eax, %eax
dec %ax
int $0x30
pop %ebx
ret