//----------------------------------------------------------------------------//
// OS on Kaleid //
// //
// Desc: GDT related functions //
// //
// //
// Copyright © 2018-2021 The OS/K Team //
// //
// This file is part of OS/K. //
// //
// OS/K is free software: you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation, either version 3 of the License, or //
// any later version. //
// //
// OS/K is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY//without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with OS/K. If not, see . //
//----------------------------------------------------------------------------//
#include
#include
#include
GdtPtr_t gdtPtr;
GdtEntry_t gdt[7] __attribute__((__aligned__(KPAGESIZE)));
TssDescriptor_t tssDesc __attribute__((__aligned__(KPAGESIZE)));
Tss_t tss __attribute__((__aligned__(KPAGESIZE)));
void MmInitGdt(void)
{
ushort tssOffset = (ushort)((ulong)(&gdt[5]) - (ulong)(&gdt[0]));
gdtPtr.base = (ulong)&gdt[0];
gdtPtr.limit = sizeof(gdt) - 1;
memzero((void *)&gdt[0], sizeof(gdt));
memzero((void *)&tssDesc, sizeof(tssDesc));
memzero((void *)&tss, sizeof(tss));
// Kernel codeseg
gdt[1].lowLimit = 0x0;
gdt[1].access = 0x9A;
gdt[1].flags = 0x20;
// Kernel dataseg
gdt[2].lowLimit = 0x0;
gdt[2].access = 0x92;
gdt[2].flags = 0x00;
// User dataseg
gdt[3].lowLimit = 0x0;
gdt[3].access = 0xF2;
gdt[3].flags = 0x20;
// User codeseg
gdt[4].lowLimit = 0x0;
gdt[4].access = 0xFA;
gdt[4].flags = 0x20;
tssDesc.access = 0x89;
tssDesc.flags = 0x40;
tssDesc.lowBase = (ulong)&tss & 0xFFFF;
tssDesc.middleBase = ((ulong)&tss >> 16) & 0xFF;
tssDesc.highBase = ((ulong)&tss >> 24) & 0xFF;
tssDesc.veryHighBase = ((ulong)&tss >> 32) & 0xFFFFFFFF;
tssDesc.lowLimit = sizeof(tss);
tss.ist1 = (ulong)memalign(4*MB, 4*KB) + 4*MB; // ISR RESCUE STACK
tss.ist2 = (ulong)memalign(4*MB, 4*KB) + 4*MB; // ISR STACK
tss.ist3 = (ulong)memalign(4*MB, 4*KB) + 4*MB; // ISR STACK
tss.rsp0 = (ulong)memalign(4*MB, 4*KB) + 4*MB; // Another Stack
tss.iomap_base = sizeof(tss);
memmove(&gdt[5], &tssDesc, sizeof(TssDescriptor_t));
DebugLog("GDT & TSS initialized\n");
DebugLog("Null descriptor : %#p\n", &gdt[0]);
DebugLog("Kernel code descriptor : %#p\n", &gdt[1]);
DebugLog("Kernel data descriptor : %#p\n", &gdt[2]);
DebugLog("User data descriptor : %#p\n", &gdt[3]);
DebugLog("User code descriptor : %#p\n", &gdt[4]);
DebugLog("tss : %#p\n", &gdt[5]);
DebugLog("ist1 : %#p\n", tss.ist1);
DebugLog("ist2 : %#p\n", tss.ist2);
DebugLog("ist3 : %#p\n", tss.ist3);
DebugLog("rsp0 : %#p\n", tss.ist1);
MmLoadGdt(&gdtPtr, tssOffset);
}