2010-09-10 22:18:55 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2010 Stefan Lankes, Chair for Operating Systems,
|
|
|
|
* RWTH Aachen University
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*
|
|
|
|
* This file is part of MetalSVM.
|
|
|
|
*/
|
|
|
|
|
2011-04-03 19:41:46 +02:00
|
|
|
/**
|
|
|
|
* @file arch/x86/include/asm/gdt.h
|
|
|
|
* @brief Definitions and functions related to segmentation
|
|
|
|
* @author Stefan Lankes
|
|
|
|
*
|
|
|
|
* This file defines the interface for segmentation as like structures to describe segments.\n
|
|
|
|
* There are also some other gdt-private functions in the gdt.c file defined.
|
|
|
|
*/
|
|
|
|
|
2010-09-10 22:18:55 +00:00
|
|
|
#ifndef __ARCH_GDT_H__
|
|
|
|
#define __ARCH_GDT_H__
|
|
|
|
|
|
|
|
#include <metalsvm/stddef.h>
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2011-04-03 19:41:46 +02:00
|
|
|
/// This segment is a data segment
|
2012-06-10 08:05:24 +02:00
|
|
|
#define GDT_FLAG_DATASEG 0x02
|
2011-04-03 19:41:46 +02:00
|
|
|
/// This segment is a code segment
|
2012-06-10 08:05:24 +02:00
|
|
|
#define GDT_FLAG_CODESEG 0x0a
|
|
|
|
#define GDT_FLAG_TSS 0x09
|
2010-09-10 22:18:55 +00:00
|
|
|
#define GDT_FLAG_TSS_BUSY 0x02
|
|
|
|
|
2012-06-10 08:05:24 +02:00
|
|
|
#define GDT_FLAG_SEGMENT 0x10
|
2011-04-03 19:41:46 +02:00
|
|
|
/// Privilege level: Ring 0
|
2012-06-10 08:05:24 +02:00
|
|
|
#define GDT_FLAG_RING0 0x00
|
2011-04-03 19:41:46 +02:00
|
|
|
/// Privilege level: Ring 1
|
2012-06-10 08:05:24 +02:00
|
|
|
#define GDT_FLAG_RING1 0x20
|
2011-04-03 19:41:46 +02:00
|
|
|
/// Privilege level: Ring 2
|
2012-06-10 08:05:24 +02:00
|
|
|
#define GDT_FLAG_RING2 0x40
|
2011-04-03 19:41:46 +02:00
|
|
|
/// Privilege level: Ring 3
|
2012-06-10 08:05:24 +02:00
|
|
|
#define GDT_FLAG_RING3 0x60
|
2011-04-03 19:41:46 +02:00
|
|
|
/// Segment is present
|
2012-06-10 08:05:24 +02:00
|
|
|
#define GDT_FLAG_PRESENT 0x80
|
2011-04-03 19:41:46 +02:00
|
|
|
/**
|
|
|
|
* @brief Granularity of segment limit
|
|
|
|
* - set: segment limit unit is 4 KB (page size)
|
|
|
|
* - not set: unit is bytes
|
|
|
|
*/
|
2012-06-10 08:05:24 +02:00
|
|
|
#define GDT_FLAG_4K_GRAN 0x80
|
2011-04-03 19:41:46 +02:00
|
|
|
/**
|
|
|
|
* @brief Default operand size
|
|
|
|
* - set: 32 bit
|
|
|
|
* - not set: 16 bit
|
|
|
|
*/
|
2012-06-10 08:05:24 +02:00
|
|
|
#define GDT_FLAG_16_BIT 0x00
|
|
|
|
#define GDT_FLAG_32_BIT 0x40
|
|
|
|
#define GDT_FLAG_64_BIT 0x20
|
2010-09-10 22:18:55 +00:00
|
|
|
|
2011-04-03 19:41:46 +02:00
|
|
|
/** @brief Defines a GDT entry
|
|
|
|
*
|
|
|
|
* A global descriptor table entry consists of:
|
|
|
|
* - 32 bit base address (chunkwise embedded into this structure)
|
|
|
|
* - 20 bit limit
|
|
|
|
*/
|
2010-09-10 22:18:55 +00:00
|
|
|
typedef struct {
|
2011-04-03 19:41:46 +02:00
|
|
|
/// Lower 16 bits of limit range
|
2012-06-10 08:05:24 +02:00
|
|
|
uint16_t limit_low;
|
2011-04-03 19:41:46 +02:00
|
|
|
/// Lower 16 bits of base address
|
2012-06-10 08:05:24 +02:00
|
|
|
uint16_t base_low;
|
2011-04-03 19:41:46 +02:00
|
|
|
/// middle 8 bits of base address
|
2012-06-10 08:05:24 +02:00
|
|
|
uint8_t base_middle;
|
2011-04-03 19:41:46 +02:00
|
|
|
/// Access bits
|
2012-06-10 08:05:24 +02:00
|
|
|
uint8_t access;
|
2011-04-03 19:41:46 +02:00
|
|
|
/// Granularity bits
|
2012-06-10 08:05:24 +02:00
|
|
|
uint8_t granularity;
|
2011-04-03 19:41:46 +02:00
|
|
|
/// Higher 8 bits of base address
|
2012-06-10 08:05:24 +02:00
|
|
|
uint8_t base_high;
|
2010-09-10 22:18:55 +00:00
|
|
|
} __attribute__ ((packed)) gdt_entry_t;
|
|
|
|
|
2011-04-03 19:41:46 +02:00
|
|
|
/** @brief defines the GDT pointer structure
|
|
|
|
*
|
|
|
|
* This structure tells the address and size of the table.
|
|
|
|
*/
|
2010-09-10 22:18:55 +00:00
|
|
|
typedef struct {
|
2011-04-03 19:41:46 +02:00
|
|
|
/// Size of the table in bytes (not the number of entries!)
|
2012-06-10 08:05:24 +02:00
|
|
|
uint16_t limit;
|
2011-04-03 19:41:46 +02:00
|
|
|
/// Address of the table
|
2012-06-10 08:05:24 +02:00
|
|
|
size_t base;
|
2010-09-10 22:18:55 +00:00
|
|
|
} __attribute__ ((packed)) gdt_ptr_t;
|
|
|
|
|
2011-04-03 19:41:46 +02:00
|
|
|
/// Defines the maximum number of GDT entries
|
2012-06-11 16:16:35 +02:00
|
|
|
#ifdef CONFIG_X86_32
|
|
|
|
#define GDT_ENTRIES (5+MAX_TASKS)
|
|
|
|
#else
|
|
|
|
// a TSS descriptor is twice larger than a code/data descriptor
|
|
|
|
#define GDT_ENTRIES (5+MAX_TASKS*2)
|
|
|
|
#endif
|
2010-09-10 22:18:55 +00:00
|
|
|
#if GDT_ENTRIES > 8192
|
|
|
|
#error Too many GDT entries!
|
|
|
|
#endif
|
|
|
|
|
2011-04-03 19:41:46 +02:00
|
|
|
/** @brief Installs the global descriptor table
|
|
|
|
*
|
|
|
|
* The installation involves the following steps:
|
|
|
|
* - set up the special GDT pointer
|
|
|
|
* - set up the entries in our GDT
|
|
|
|
* - finally call gdt_flush() in our assembler file
|
|
|
|
* in order to tell the processor where the new GDT is
|
|
|
|
* - update the new segment registers
|
|
|
|
*/
|
2010-09-10 22:18:55 +00:00
|
|
|
void gdt_install(void);
|
|
|
|
|
2012-06-13 09:36:28 +02:00
|
|
|
/** @brief Configures and returns a GDT descriptor with chosen attributes
|
|
|
|
*
|
|
|
|
* Just feed this function with address, limit and the flags
|
|
|
|
* you have seen in idt.h
|
|
|
|
*
|
|
|
|
* @return a preconfigured gdt descriptor
|
|
|
|
*/
|
|
|
|
void configure_gdt_entry(gdt_entry_t *dest_entry, unsigned long base, unsigned long limit,
|
|
|
|
unsigned char access, unsigned char gran);
|
|
|
|
|
2010-09-10 22:18:55 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|