+++ /dev/null
-/*
- * Initialize kernel GDT.
- * Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
- * $Revision: 1.1 $
- *
- * This is free software. You are permitted to use,
- * redistribute, and modify it as specified in the file "COPYING".
- */
-
-#include <geekos/kassert.h>
-#include <geekos/segment.h>
-#include <geekos/int.h>
-#include <geekos/tss.h>
-#include <geekos/gdt.h>
-#include <libc/string.h>
-
-
-/*
- * This is defined in lowlevel.asm.
- */
-extern void Load_GDTR(ushort_t* limitAndBase);
-
-/* ----------------------------------------------------------------------
- * Data
- * ---------------------------------------------------------------------- */
-
-/*
- * Number of entries in the kernel GDT.
- */
-#define NUM_GDT_ENTRIES 16
-
-/*
- * This is the kernel's global descriptor table.
- */
-struct Segment_Descriptor *s_GDT=(struct Segment_Descriptor *)GDT_LOCATION;
-
-/*
- * Number of allocated GDT entries.
- */
-static int s_numAllocated = 0;
-
-
-
-
-
-void DumpGDT()
-{
- int i;
- Print("GDT Contents:\n");
-
- for (i=0;i<NUM_GDT_ENTRIES;i++) {
- if (s_GDT[i].present) {
- Print("%d: base=%u, limit=%u, sizeLow=%u, baseLow=%u, type=%u, system=%u, dpl=%u, preent=%u, sizeHigh=%u, avail=%u, reserved=%u, dbBit=%u, granularity=%u, baseHigh=%u\n",
- i,
- (s_GDT[i].baseHigh<<24) + s_GDT[i].baseLow,
- (s_GDT[i].sizeHigh<<16) + s_GDT[i].sizeLow,
- s_GDT[i].sizeLow,
- s_GDT[i].baseLow,
- s_GDT[i].type,
- s_GDT[i].system,
- s_GDT[i].dpl,
- s_GDT[i].present,
- s_GDT[i].sizeHigh,
- s_GDT[i].avail,
- s_GDT[i].reserved,
- s_GDT[i].dbBit,
- s_GDT[i].granularity,
- s_GDT[i].baseHigh );
- } else {
- Print("%d: Not Present\n",i);
- }
- }
-}
-
-
-/* ----------------------------------------------------------------------
- * Functions
- * ---------------------------------------------------------------------- */
-
-/*
- * Allocate an descriptor from the GDT.
- * Returns null if there are none left.
- */
-struct Segment_Descriptor* Allocate_Segment_Descriptor(void)
-{
- struct Segment_Descriptor* result = 0;
- int i;
- bool iflag;
-
- iflag = Begin_Int_Atomic();
-
- /* Note; entry 0 is unused (thus never allocated) */
- for (i = 1; i < NUM_GDT_ENTRIES; ++i) {
- struct Segment_Descriptor *desc = &s_GDT[ i ];
- if (desc->avail) {
- ++s_numAllocated;
- desc->avail = 0;
- result = desc;
- break;
- }
- }
-
- End_Int_Atomic(iflag);
-
- return result;
-}
-
-/*
- * Free a segment descriptor.
- */
-void Free_Segment_Descriptor(struct Segment_Descriptor* desc)
-{
- bool iflag = Begin_Int_Atomic();
-
- KASSERT(!desc->avail);
-
- Init_Null_Segment_Descriptor(desc);
- desc->avail = 1;
- --s_numAllocated;
-
- End_Int_Atomic(iflag);
-}
-
-/*
- * Get the index (int the GDT) of given segment descriptor.
- */
-int Get_Descriptor_Index(struct Segment_Descriptor* desc)
-{
- return (int) (desc - s_GDT);
-}
-
-/*
- * Initialize the kernel's GDT.
- */
-void Init_GDT(void)
-{
- ushort_t limitAndBase[3];
- ulong_t gdtBaseAddr = (ulong_t) s_GDT;
- struct Segment_Descriptor* desc;
- int i;
-
- Print("GDT Placed at %x, %d entries\n",GDT_LOCATION,NUM_GDT_ENTRIES);
-
- KASSERT(sizeof(struct Segment_Descriptor) == 8);
-
- /* Clear out entries. */
- for (i = 0; i < NUM_GDT_ENTRIES; ++i) {
- desc = &s_GDT[ i ];
- Init_Null_Segment_Descriptor(desc);
- desc->avail = 1;
- }
-
- /* Kernel code segment. */
- desc = Allocate_Segment_Descriptor();
- Init_Code_Segment_Descriptor(
- desc,
- 0, /* base address */
- 0x100000, /* num pages (== 2^20) */
- 0 /* privilege level (0 == kernel) */
- );
- KASSERT(Get_Descriptor_Index(desc) == (KERNEL_CS >> 3));
-
- /* Kernel data segment. */
- desc = Allocate_Segment_Descriptor();
- Init_Data_Segment_Descriptor(
- desc,
- 0, /* base address */
- 0x100000, /* num pages (== 2^20) */
- 0 /* privilege level (0 == kernel) */
- );
- KASSERT(Get_Descriptor_Index(desc) == (KERNEL_DS >> 3));
-
- /* Activate the kernel GDT. */
- limitAndBase[0] = sizeof(struct Segment_Descriptor) * NUM_GDT_ENTRIES;
- limitAndBase[1] = gdtBaseAddr & 0xffff;
- limitAndBase[2] = gdtBaseAddr >> 16;
- Load_GDTR(limitAndBase);
-}