Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


created a test directory to hold test guest OSes
[palacios.git] / test / geekos_test_vm / src / geekos / segment.c
diff --git a/test/geekos_test_vm/src/geekos/segment.c b/test/geekos_test_vm/src/geekos/segment.c
new file mode 100644 (file)
index 0000000..4e83db0
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * General data structures and routines for segmentation
+ * Copyright (c) 2001, 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".
+ */
+
+/*
+ * Source: _Protected Mode Software Architecture_ by Tom Shanley,
+ * ISBN 020155447X.
+ */
+
+#include <geekos/kassert.h>
+#include <geekos/string.h>
+#include <geekos/tss.h>
+#include <geekos/segment.h>
+
+static __inline__ void Set_Size_And_Base_Pages(
+    struct Segment_Descriptor* desc,
+    ulong_t baseAddr,
+    ulong_t numPages
+)
+{
+    /*
+     * There are 20 bits in the size fields of a segment descriptor.
+     * The maximum possible value is thus 0xFFFFF, which in terms of
+     * pages is one page less than 4GB.  So, I conclude that the
+     * number of pages in the segment is one greater than the
+     * value specified in the descriptor.
+     */
+    KASSERT(numPages > 0);
+    numPages -= 1;
+
+    desc->sizeLow     = numPages & 0xFFFF;
+    desc->sizeHigh    = (numPages >> 16) & 0x0F;
+    desc->baseLow     = baseAddr & 0xFFFFFF;
+    desc->baseHigh    = (baseAddr >> 24) & 0xFF;
+    desc->granularity = 1;  /* size in pages */
+}
+
+static __inline__ void Set_Size_And_Base_Bytes(
+    struct Segment_Descriptor* desc,
+    ulong_t baseAddr,
+    ulong_t numBytes
+)
+{
+    desc->sizeLow     = numBytes & 0xFFFF;
+    desc->sizeHigh    = (numBytes >> 16) & 0x0F;
+    desc->baseLow     = baseAddr & 0xFFFFFF;
+    desc->baseHigh    = (baseAddr >> 24) & 0xFF;
+    desc->granularity = 0;  /* size in bytes */
+}
+
+/*
+ * Initialize an unused segment descriptor.
+ */
+void Init_Null_Segment_Descriptor(struct Segment_Descriptor* desc)
+{
+    memset(desc, '\0', sizeof(*desc));
+}
+
+/*
+ * Initialize a code segment descriptor.
+ */
+void Init_Code_Segment_Descriptor(
+    struct Segment_Descriptor* desc,
+    ulong_t baseAddr,
+    ulong_t numPages,
+    int privilegeLevel
+)
+{
+    KASSERT(privilegeLevel >= 0 && privilegeLevel <= 3);
+
+    Set_Size_And_Base_Pages(desc, baseAddr, numPages);
+    desc->type     = 0x0A;   /* 1010b: code, !conforming, readable, !accessed */
+    desc->system   = 1;
+    desc->dpl      = privilegeLevel;
+    desc->present  = 1;
+    desc->reserved = 0;
+    desc->dbBit    = 1;  /* 32 bit code segment */
+}
+
+/*
+ * Initialize a data segment descriptor.
+ */
+void Init_Data_Segment_Descriptor(
+    struct Segment_Descriptor* desc,
+    ulong_t baseAddr,
+    ulong_t numPages,
+    int privilegeLevel
+)
+{
+    KASSERT(privilegeLevel >= 0 && privilegeLevel <= 3);
+
+    Set_Size_And_Base_Pages(desc, baseAddr, numPages);
+    desc->type     = 0x02;  /* 0010b: data, expand-up, writable, !accessed */
+    desc->system   = 1;
+    desc->dpl      = privilegeLevel;
+    desc->present  = 1;
+    desc->reserved = 0;
+    desc->dbBit    = 1;  /* 32 bit operands */
+}
+
+/*
+ * Initialize a TSS descriptor.
+ */
+void Init_TSS_Descriptor(struct Segment_Descriptor* desc, struct TSS* theTSS)
+{
+    Set_Size_And_Base_Bytes(desc, (ulong_t) theTSS, sizeof(struct TSS));
+    desc->type     = 0x09;  /* 1001b: 32 bit, !busy */
+    desc->system   = 0;
+    desc->dpl      = 0;
+    desc->present  = 1;
+    desc->reserved = 0;
+    desc->dbBit    = 0;  /* must be 0 in TSS */
+}
+
+/*
+ * Initialize an LDT (Local Descriptor Table) descriptor.
+ */
+void Init_LDT_Descriptor(
+    struct Segment_Descriptor* desc,
+    struct Segment_Descriptor theLDT[],
+    int numEntries
+)
+{
+    Set_Size_And_Base_Bytes(
+       desc, (ulong_t) theLDT, sizeof(struct Segment_Descriptor) * numEntries);
+
+    desc->type     = 0x02;  /* 0010b */
+    desc->system   = 0;
+    desc->dpl      = 0;
+    desc->present  = 1;
+    desc->reserved = 0;
+    desc->dbBit    = 0;
+}