IBNOS
gdt.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014, Michael Müller
3  * Copyright (c) 2014, Sebastian Lackner
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
19  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  */
27 
28 #ifndef _H_GDT_
29 #define _H_GDT_
30 
31 #ifdef __KERNEL__
32 
33  #include <stdint.h>
34 
35  #include <hardware/context.h>
36  #include <process/thread.h>
37 
45  #define GDT_CPL_MASK 3
46  #define GDT_CPL_RING0 0
47  #define GDT_CPL_RING3 3
55  #define INT_TYPE_TASK32 0x5
56  #define INT_TYPE_INT16 0x6
57  #define INT_TYPE_TRAP16 0x7
58  #define INT_TYPE_INT32 0xE
59  #define INT_TYPE_TRAP32 0xF
65  #define KERNELSTACK_SIZE PAGE_SIZE
66 
72  #define GDT_MAX_SIZE 0x10000
73 
74  #define GDT_MAX_PAGES ((GDT_MAX_SIZE + PAGE_MASK) >> PAGE_BITS)
75 
76  #define GDT_MAX_COUNT (GDT_MAX_SIZE / sizeof(struct GDTEntry))
77 
84  #define IDT_MAX_SIZE PAGE_SIZE
85 
86  #define IDT_MAX_COUNT 256
87 
92  /* fixed addresses in virtual address space */
93  #define USERMODE_KERNELSTACK_ADDRESS 0xFF800000
94  #define USERMODE_GDT_ADDRESS 0xFF801000
95  #define USERMODE_IDT_ADDRESS 0xFF811000
96  #define USERMODE_INTJMP_ADDRESS 0xFF812000
97  #define USERMODE_TASK_ADDRESS 0xFF813000
98 
99  #define USERMODE_KERNELSTACK_LIMIT (USERMODE_KERNELSTACK_ADDRESS + KERNELSTACK_SIZE)
100 
101  /* dispatcher ring0 functions */
102  #define USERMODE_INTJMP_ENABLE_FPU (USERMODE_INTJMP_ADDRESS + 2048)
103 
104  /* memory locations filled by GDT functions */
105  extern void *kernelStack;
106 
107  extern void *intJmpTable_kernel;
108  extern void *intJmpTable_user;
109 
110  extern struct GDTEntry *codeRing0;
111  extern struct GDTEntry *dataRing0;
112  extern struct GDTEntry *codeRing3;
113  extern struct GDTEntry *dataRing3;
114 
115  extern struct GDTEntry *kernelTask;
116  extern struct GDTEntry *usermodeTask;
122  struct GDTTable
123  {
124  uint16_t limit;
125  uint32_t address;
126  } __attribute__((packed));
128  struct GDTEntry
129  {
130  uint16_t limit1;
131  uint16_t address1;
132  uint8_t address2;
133  union {
134  uint8_t access;
135  struct {
136  uint8_t accessed : 1;
137  uint8_t readWrite : 1;
138  uint8_t dc : 1;
139  uint8_t execute : 1;
140  uint8_t isSystem : 1;
141  uint8_t privlevel : 2;
142  uint8_t present : 1;
143  } accessBits;
144  };
145  uint8_t limit2 : 4;
146  uint8_t user : 1;
147  uint8_t reserved : 1;
148  uint8_t is32bit : 1;
149  uint8_t granularity : 1;
150  uint8_t address3;
151  } __attribute__((packed));
152 
153  struct IDTTable
154  {
155  uint16_t limit;
156  uint32_t address;
157  } __attribute__((packed));
158 
159  struct IDTEntry
160  {
161  uint16_t addressLow;
162  union{
163  uint16_t csSelector;
164  uint16_t taskSelector;
165  };
166  uint8_t zero;
167  union{
168  uint8_t typeAttr;
169  struct {
170  uint8_t type : 4;
171  uint8_t storageSegment : 1;
172  uint8_t dpl : 2;
173  uint8_t present : 1;
174  } typeBits;
175  };
176  uint16_t addressHigh;
177  } __attribute__((packed));
178 
179  void gdtInit();
180  struct GDTEntry* gdtGetFreeEntry();
181  uint32_t gdtGetEntryOffset(struct GDTEntry* entry, uint32_t ring);
182  void gdtEntrySetAddress(struct GDTEntry* entry, uint32_t address);
183  void gdtEntrySetLimit(struct GDTEntry* entry, uint64_t limit);
184  void gdtReleaseEntry(struct GDTEntry* entry);
185 
186  uint32_t tssRunUsermodeThread(struct thread *t);
187  void __attribute__((cdecl)) tssKernelIdle();
188 
192 #endif
193 
194 #endif /* _H_GDT_ */
uint8_t address2
Definition: gdt.h:119
uint8_t dc
Definition: gdt.h:138
void gdtEntrySetAddress(struct GDTEntry *entry, uint32_t address)
Helper function to set the address inside a GDTEntry.
Definition: gdt.c:557
uint8_t execute
Definition: gdt.h:139
uint8_t typeAttr
Definition: gdt.h:168
struct GDTEntry * gdtGetFreeEntry()
Get a free entry in the GDT.
Definition: gdt.c:503
uint8_t isSystem
Definition: gdt.h:140
void gdtReleaseEntry(struct GDTEntry *entry)
Mark a GDTEntry as free.
Definition: gdt.c:612
uint32_t address
Definition: gdt.h:156
uint8_t address3
Definition: gdt.h:150
uint8_t storageSegment
Definition: gdt.h:171
uint8_t reserved
Definition: gdt.h:147
void * intJmpTable_user
Definition: gdt.c:54
uint8_t present
Definition: gdt.h:142
uint16_t addressLow
Definition: gdt.h:161
uint16_t addressHigh
Definition: gdt.h:176
Definition: thread.h:47
Definition: gdt.h:122
uint16_t taskSelector
Definition: gdt.h:164
struct GDTEntry * codeRing3
Definition: gdt.c:65
Definition: gdt.h:153
struct @2::@4 accessBits
struct GDTEntry * dataRing0
Definition: gdt.c:64
void * kernelStack
Definition: gdt.c:42
uint8_t is32bit
Definition: gdt.h:148
uint32_t gdtGetEntryOffset(struct GDTEntry *entry, uint32_t ring)
Determines the offset of a GDT entry.
Definition: gdt.c:537
uint32_t tssRunUsermodeThread(struct thread *t)
Run a thread.
Definition: gdt.c:628
uint8_t privlevel
Definition: gdt.h:141
struct @12::@14 typeBits
Definition: gdt.h:128
uint8_t access
Definition: gdt.h:121
struct GDTEntry * dataRing3
Definition: gdt.c:66
uint8_t zero
Definition: gdt.h:166
uint16_t limit1
Definition: gdt.h:130
uint8_t type
Definition: gdt.h:170
uint32_t address
Definition: gdt.h:125
uint16_t address1
Definition: gdt.h:131
uint8_t limit2
Definition: gdt.h:145
uint8_t accessed
Definition: gdt.h:123
uint8_t user
Definition: gdt.h:146
void * intJmpTable_kernel
Definition: gdt.c:53
struct GDTEntry * usermodeTask
Definition: gdt.c:70
void gdtEntrySetLimit(struct GDTEntry *entry, uint64_t length)
Helper function to set the length inside a GDTEntry.
Definition: gdt.c:582
uint8_t present
Definition: gdt.h:173
uint16_t limit
Definition: gdt.h:124
uint8_t readWrite
Definition: gdt.h:124
struct GDTEntry * kernelTask
Definition: gdt.c:69
uint8_t granularity
Definition: gdt.h:149
uint16_t limit
Definition: gdt.h:155
uint8_t dpl
Definition: gdt.h:172
struct GDTEntry * codeRing0
Definition: gdt.c:63
void gdtInit()
Initializes the GDT, task registers, and sets up everything required for multiprocessing.
Definition: gdt.c:432
Definition: gdt.h:159
struct GDTTable __attribute__((packed))
uint16_t csSelector
Definition: gdt.h:163