Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/* Project:     OSLib
2
 * Description: The OS Construction Kit
3
 * Date:                1.6.2000
4
 * Idea by:             Luca Abeni & Gerardo Lamastra
5
 *
6
 * OSLib is an SO project aimed at developing a common, easy-to-use
7
 * low-level infrastructure for developing OS kernels and Embedded
8
 * Applications; it partially derives from the HARTIK project but it
9
 * currently is independently developed.
10
 *
11
 * OSLib is distributed under GPL License, and some of its code has
12
 * been derived from the Linux kernel source; also some important
13
 * ideas come from studying the DJGPP go32 extender.
14
 *
15
 * We acknowledge the Linux Community, Free Software Foundation,
16
 * D.J. Delorie and all the other developers who believe in the
17
 * freedom of software and ideas.
18
 *
19
 * For legalese, check out the included GPL license.
20
 */
21
 
22
/* These function provide access to hardware structutes GDT/IDT */
23
 
24
#include <ll/i386/cons.h>
25
#include <ll/i386/mem.h>
26
#include <ll/math.h>
27
 
28
FILE(X - SysTab);
29
 
30
extern GATE IDT[256];
31
 
32
/* We usually need to set-up an interrupt handler; to do this we have */
33
/* to fill a GATE structure & copy it into the Interrupt Descriptor   */
34
/* Table or IDT; its phisical address is given by IDT_base            */
35
 
36
void IDT_place(BYTE num, void (*handler) (void))
37
{
38
    DWORD offset = (DWORD) (handler);
39
    IDT[num].sel = X_FLATCODE_SEL;
40
    /* Set DPL = 3, to allow execution of the gate from any ring */
41
    IDT[num].access = INT_GATE386 | 0x60;
42
    IDT[num].dword_cnt = 0;
43
    IDT[num].offset_lo = offset & 0xFFFF;
44
    offset >>= 16;
45
    IDT[num].offset_hi = offset & 0xFFFF;
46
}
47
 
48
/* Ok; the GDT is managed in the same way as the IDT                */
49
/* When a descriptor is cleared using it will cause a SEGMENT FAULT */
50
/* to refer such descriptor                                         */
51
 
52
void GDT_place(WORD sel, DWORD base, DWORD lim, BYTE acc, BYTE gran)
53
{
54
    union gdt_entry x;
55
    /* This is declared in [wc32/gnu]\x0.[asm/s] */
56
    extern LIN_ADDR GDT_base;
57
/*    DWORD offset = appl2linear(&x); */
58
    x.d.base_lo = (base & 0x0000FFFF);
59
    x.d.base_med = ((base & 0x00FF0000) >> 16);
60
    x.d.base_hi = ((base & 0xFF000000) >> 24);
61
    x.d.access = acc;
62
    x.d.lim_lo = (lim & 0xFFFF);
63
    x.d.gran = (gran | ((lim >> 16) & 0x0F) | 0x40);
64
    memcpy(GDT_base + (sel & ~3), &x, sizeof(union gdt_entry));
65
}
66
 
67
/* This function is used to read & format the descriptor data */
68
/* Anyway is better to use the hw 386 instruction to modify   */
69
/* a descriptor rather than reading,modifying & updating with */
70
/* this high level functions!                                 */
71
 
72
DWORD GDT_read(WORD sel, DWORD * lim, BYTE * acc, BYTE * gran)
73
{
74
    union gdt_entry x;
75
    /* This is declared in [wc32/gnu]\x0.[asm/s] */
76
    extern LIN_ADDR GDT_base;
77
    /*DWORD offset = appl2linear(&x); */
78
    DWORD base;
79
    memcpy(&x, GDT_base + sel, sizeof(union gdt_entry));
80
    base = x.d.base_hi;
81
    base <<= 8;
82
    base |= x.d.base_med;
83
    base <<= 16;
84
    base |= x.d.base_lo;
85
    if (lim != NULL) {
86
        *lim = (x.d.gran & 0x0F);
87
        *lim <<= 16;
88
        *lim |= x.d.lim_lo;
89
    }
90
    if (acc != NULL)
91
        *acc = x.d.access;
92
    if (gran != NULL)
93
        *gran = x.d.gran & 0xF0;
94
    return (base);
95
}