Still some issues, but it seems to not crash anymore
[tpg/acess2.git] / Kernel / arch / x86 / include / arch.h
1 /*
2  * Acess2
3  * - x86 Architecture
4  * arch/i386/include/arch.h
5  */
6 #ifndef _ARCH_H_
7 #define _ARCH_H_
8
9 // - Base Defintions
10 #define KERNEL_BASE     0xC0000000
11 #define BITS    32
12
13 // Allow nested spinlocks?
14 #define STACKED_LOCKS   1
15 #define LOCK_DISABLE_INTS       0
16
17 // - Processor/Machine Specific Features
18 #if ARCH != i386 && ARCH != i486 && ARCH != i586
19 # error "Unknown architecture '" #ARCH "'"
20 #endif
21
22 #if USE_MP
23 # define        MAX_CPUS        8
24 #else
25 # define        MAX_CPUS        1
26 #endif
27
28 #if USE_PAE
29 # define        PHYS_BITS       48
30 #else
31 # define        PHYS_BITS       32
32 #endif
33
34 #define __ASM__ __asm__ __volatile__
35
36 // === Spinlocks ===
37 /**
38  * \brief Short Spinlock structure
39  */
40 struct sShortSpinlock {
41         volatile int    Lock;   //!< Lock value
42         #if LOCK_DISABLE_INTS
43          int    IF;     //!< Interrupt state on call to SHORTLOCK
44         #endif
45         #if STACKED_LOCKS
46          int    Depth;
47         #endif
48 };
49 /**
50  * \brief Determine if a short spinlock is locked
51  * \param Lock  Lock pointer
52  */
53 static inline int IS_LOCKED(struct sShortSpinlock *Lock) {
54         return !!Lock->Lock;
55 }
56
57 /**
58  * \brief Check if the current CPU has the lock
59  * \param Lock  Lock pointer
60  */
61 static inline int CPU_HAS_LOCK(struct sShortSpinlock *Lock) {
62         extern int      GetCPUNum(void);
63         return Lock->Lock == GetCPUNum() + 1;
64 }
65
66 /**
67  * \brief Acquire a Short Spinlock
68  * \param Lock  Lock pointer
69  * 
70  * This type of mutex should only be used for very short sections of code,
71  * or in places where a Mutex_* would be overkill, such as appending
72  * an element to linked list (usually two assignement lines in C)
73  * 
74  * \note This type of lock halts interrupts, so ensure that no timing
75  * functions are called while it is held. As a matter of fact, spend as
76  * little time as possible with this lock held
77  */
78 static inline void SHORTLOCK(struct sShortSpinlock *Lock) {
79          int    v = 1;
80         #if LOCK_DISABLE_INTS
81          int    IF;
82         #endif
83         #if STACKED_LOCKS
84         extern int      GetCPUNum(void);
85          int    cpu = GetCPUNum() + 1;
86         #endif
87         
88         #if LOCK_DISABLE_INTS
89         // Save interrupt state and clear interrupts
90         __ASM__ ("pushf;\n\tpop %%eax\n\tcli" : "=a"(IF));
91         IF &= 0x200;    // AND out all but the interrupt flag
92         #endif
93         
94         #if STACKED_LOCKS
95         if( Lock->Lock == cpu ) {
96                 Lock->Depth ++;
97                 return ;
98         }
99         #endif
100         
101         // Wait for another CPU to release
102         while(v) {
103                 #if STACKED_LOCKS
104                 // CMPXCHG:
105                 //  If r/m32 == EAX, set ZF and set r/m32 = r32
106                 //  Else, clear ZF and set EAX = r/m32
107                 __ASM__("lock cmpxchgl %2, (%3)"
108                         : "=a"(v)
109                         : "a"(0), "r"(cpu), "r"(&Lock->Lock)
110                         );
111                 #else
112                 __ASM__("xchgl %%eax, (%%edi)":"=a"(v):"a"(1),"D"(&Lock->Lock));
113                 #endif
114         }
115         
116         #if LOCK_DISABLE_INTS
117         Lock->IF = IF;
118         #endif
119 }
120 /**
121  * \brief Release a short lock
122  * \param Lock  Lock pointer
123  */
124 static inline void SHORTREL(struct sShortSpinlock *Lock) {
125         #if STACKED_LOCKS
126         if( Lock->Depth ) {
127                 Lock->Depth --;
128                 return ;
129         }
130         #endif
131         
132         #if LOCK_DISABLE_INTS
133         // Lock->IF can change anytime once Lock->Lock is zeroed
134         if(Lock->IF) {
135                 Lock->Lock = 0;
136                 __ASM__ ("sti");
137         }
138         else {
139                 Lock->Lock = 0;
140         }
141         #else
142         Lock->Lock = 0;
143         #endif
144 }
145
146 // === MACROS ===
147 /**
148  * \brief Halt the CPU
149  */
150 #define HALT()  __asm__ __volatile__ ("hlt")
151 /**
152  * \brief Fire a magic breakpoint (bochs)
153  */
154 #define MAGIC_BREAK()   __asm__ __volatile__ ("xchg %bx, %bx")
155
156 // === TYPES ===
157 typedef unsigned int    Uint;   // Unsigned machine native integer
158 typedef unsigned char   Uint8;
159 typedef unsigned short  Uint16;
160 typedef unsigned long   Uint32;
161 typedef unsigned long long      Uint64;
162 typedef signed int              Sint;   // Signed Machine Native integer
163 typedef signed char             Sint8;
164 typedef signed short    Sint16;
165 typedef signed long             Sint32;
166 typedef signed long long        Sint64;
167 typedef Uint    size_t;
168
169 typedef Uint64  tPAddr;
170 typedef Uint32  tVAddr;
171
172 typedef struct {
173     Uint        gs, fs, es, ds;
174     Uint        edi, esi, ebp, kesp;
175         Uint    ebx, edx, ecx, eax;
176     Uint        int_num, err_code;
177     Uint        eip, cs;
178         Uint    eflags, esp, ss;
179 } tRegs;
180
181 typedef struct {
182         Uint    Resvd1[4];      // GS, FS, ES, DS
183         Uint    Arg4, Arg5;     // EDI, ESI
184         Uint    Arg6;   // EBP
185         Uint    Resvd2[1];      // Kernel ESP
186         union {
187                 Uint    Arg1;
188                 Uint    Error;
189         };      // EBX
190         union {
191                 Uint    Arg3;
192                 Uint    RetHi;  // High 32 bits of ret
193         };      // EDX
194         Uint    Arg2;   // ECX
195         union {
196                 Uint    Num;
197                 Uint    Return;
198         };      // EAX
199         Uint    Resvd3[5];      // Int, Err, Eip, CS, ...
200         Uint    StackPointer;   // ESP
201         Uint    Resvd4[1];      // SS
202 } tSyscallRegs;
203
204 typedef struct {
205         #if USE_PAE
206         Uint    PDPT[4];
207         #else
208         Uint    CR3;
209         #endif
210 } tMemoryState;
211
212 typedef struct {
213         Uint    EIP, ESP, EBP;
214 } tTaskState;
215
216 #endif  // !defined(_ARCH_H_)

UCC git Repository :: git.ucc.asn.au