Subversion Repositories shark

Rev

Rev 83 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
42 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
/*      As the name says... All the hardware-dependent instructions
23
        there is a 1->1 corrispondence with ASM instructions    */
24
 
25
#ifndef __LL_I386_HW_INSTR_H__
26
#define __LL_I386_HW_INSTR_H__
27
 
28
#include <ll/i386/defs.h>
29
 
30
#define INLINE_OP __inline__ static
31
 
32
#include <ll/i386/hw-data.h>
33
 
34
/* Low Level I/O funcs are in a separate file (by Luca) */
35
#include <ll/i386/hw-io.h>
36
 
83 pj 37
BEGIN_DEF
38
 
42 pj 39
INLINE_OP WORD get_CS(void)
40
{WORD r; __asm__ __volatile__ ("movw %%cs,%0" : "=q" (r)); return(r);}
41
 
42
INLINE_OP WORD get_DS(void)
43
{WORD r; __asm__ __volatile__ ("movw %%ds,%0" : "=q" (r)); return(r);}
44
INLINE_OP WORD get_FS(void)
45
{WORD r; __asm__ __volatile__ ("movw %%fs,%0" : "=q" (r)); return(r);}
46
 
47
/*INLINE_OP DWORD get_SP(void)
48
{DWORD r; __asm__ __volatile__ ("movw %%esp,%0" : "=q" (r)); return(r);}*/
49
INLINE_OP DWORD get_SP(void)
50
{
51
    DWORD rv;
52
    __asm__ __volatile__ ("movl %%esp, %0"
53
          : "=a" (rv));
54
    return(rv);
55
}
56
 
57
INLINE_OP DWORD get_BP(void)
58
{
59
    DWORD rv;
60
    __asm__ __volatile__ ("movl %%ebp, %0"
61
          : "=a" (rv));
62
    return(rv);
63
}
64
 
65
INLINE_OP WORD get_TR(void)
66
{WORD r; __asm__ __volatile__ ("strw %0" : "=q" (r)); return(r); }
67
 
68
INLINE_OP void set_TR(WORD n)
69
{__asm__ __volatile__("ltr %%ax": /* no output */ :"a" (n)); }
70
 
71
INLINE_OP void set_LDTR(WORD addr)
72
{ __asm__ __volatile__("lldt %%ax": /* no output */ :"a" (addr)); }
73
 
74
 
75
/* Clear Task Switched Flag! Used for FPU preemtion */
76
INLINE_OP void clts(void)
77
{__asm__ __volatile__ ("clts"); }
78
 
79
/* Halt the processor! */
80
INLINE_OP void hlt(void)
81
{__asm__ __volatile__ ("hlt"); }
82
 
83
/* These functions are used to mask/unmask interrupts           */
84
INLINE_OP void sti(void) {__asm__ __volatile__ ("sti"); }
85
INLINE_OP void cli(void) {__asm__ __volatile__ ("cli"); }
86
 
87
INLINE_OP SYS_FLAGS ll_fsave(void)
88
{
89
    SYS_FLAGS result;
90
 
91
    __asm__ __volatile__ ("pushfl");
92
    __asm__ __volatile__ ("cli");
93
    __asm__ __volatile__ ("popl %eax");
94
    __asm__ __volatile__ ("movl %%eax,%0"
95
        : "=r" (result)
96
        :
97
        : "eax" );
98
    return(result);
99
}
100
 
101
INLINE_OP void ll_frestore(SYS_FLAGS f)
102
{
103
    __asm__ __volatile__ ("mov %0,%%eax"
104
        :
105
        : "r" (f)
106
        : "eax");
107
    __asm__ __volatile__ ("pushl %eax");
108
    __asm__ __volatile__ ("popfl");
109
}
110
 
111
/*
112
    FPU context switch management functions!
113
    FPU management exported at kernel layer to allow the use
114
    of floating point in kernel primitives; this turns to be
115
    useful for bandwidth reservation or guarantee!
116
*/
117
 
118
/* FPU lazy state save handling.. */
119
INLINE_OP void save_fpu(TSS *t)
120
{
121
    __asm__ __volatile__("fnsave %0\n\tfwait":"=m" (t->ctx_FPU));
122
}
123
 
124
INLINE_OP void restore_fpu(TSS *t)
125
{
126
#if 1
380 giacomo 127
    __asm__ __volatile__("frstor %0": :"p" (t->ctx_FPU));
42 pj 128
#else
380 giacomo 129
    __asm__ __volatile__("frstor %0\n\tfwait": :"p" (t->ctx_FPU));
42 pj 130
#endif
131
/*    __asm__ __volatile__("frstor _LL_FPU_savearea"); */
132
}
133
 
134
INLINE_OP void smartsave_fpu(TSS *t)
135
{
136
    if (t->control & FPU_USED) save_fpu(t);
137
}
138
 
139
INLINE_OP void reset_fpu(void) { __asm__ __volatile__ ("fninit"); }
140
 
141
#if 0
142
/* OK, now everything is clear... We test the NE bit to see if the
143
 * CPU is using the internal mechanism for reporting FPU errors or not...
144
 */
145
INLINE_OP int check_fpu(void)
146
{
147
    int result;
148
 
149
    __asm__ __volatile__ ("movl %cr0,%eax");
150
    __asm__ __volatile__ ("movl %eax,%edi");
151
    __asm__ __volatile__ ("andl $0x0FFFFFFEF,%eax");
152
    __asm__ __volatile__ ("movl %eax,%cr0");
153
    __asm__ __volatile__ ("movl %cr0,%eax");
154
    __asm__ __volatile__ ("xchgl %edi,%eax");
155
    __asm__ __volatile__ ("movl %eax,%cr0");
156
#if 0
157
    __asm__ __volatile__ ("xorl %eax,%eax");
158
    __asm__ __volatile__ ("movb %bl,%al");
159
#else
160
    __asm__ __volatile__ ("movl %edi,%eax");
161
    __asm__ __volatile__ ("andl $0x10,%eax");
162
#endif
163
    __asm__ __volatile__ ("shrb $4,%al");
164
    __asm__ __volatile__ ("movl %%eax,%0"
165
        : "=r" (result)
166
        :
167
        : "eax" );
168
    return(result);
169
}
170
#endif
171
 
172
INLINE_OP void init_fpu(void)
173
{
174
    __asm__ __volatile__ ("movl %cr0,%eax");
175
    __asm__ __volatile__ ("orl  $34,%eax");
176
    __asm__ __volatile__ ("movl %eax,%cr0");
177
    __asm__ __volatile__ ("fninit");
178
}
179
 
180
 
181
extern BYTE LL_FPU_savearea[];
182
 
183
extern __inline__ void LL_FPU_save(void)
184
{
185
    #ifdef __LINUX__
186
        __asm__ __volatile__ ("fsave LL_FPU_savearea");
187
    #else
188
        __asm__ __volatile__ ("fsave _LL_FPU_savearea");
189
    #endif
190
}
191
 
192
extern __inline__ void LL_FPU_restore(void)
193
{
194
    #ifdef __LINUX__
195
        __asm__ __volatile__ ("frstor LL_FPU_savearea");
196
    #else
197
        __asm__ __volatile__ ("frstor _LL_FPU_savearea");
198
    #endif
199
}
200
 
201
 
202
 
203
 
204
 
205
INLINE_OP void lmempokeb(LIN_ADDR a, BYTE v)
206
{
207
        *((BYTE *)a) = v;
208
}
209
INLINE_OP void lmempokew(LIN_ADDR a, WORD v)
210
{
211
        *((WORD *)a) = v;
212
}
213
INLINE_OP void lmempoked(LIN_ADDR a, DWORD v)
214
{
215
        *((DWORD *)a) = v;
216
}
217
 
218
INLINE_OP BYTE lmempeekb(LIN_ADDR a)
219
{
220
        return *((BYTE *)a);
221
}
222
INLINE_OP WORD lmempeekw(LIN_ADDR a)
223
{
224
        return *((WORD *)a);
225
}
226
INLINE_OP DWORD lmempeekd(LIN_ADDR a)
227
{
228
        return *((DWORD *)a);
229
}
230
 
231
 
232
 
233
END_DEF
234
 
235
#endif