Fiddling with threading bugs (both Qemu and Bochs hate atm)
[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 // - Processor/Machine Specific Features
14 #if ARCH != i386 && ARCH != i486 && ARCH != i586
15 # error "Unknown architecture '" #ARCH "'"
16 #endif
17
18 #if USE_MP
19 # define        MAX_CPUS        8
20 #else
21 # define        MAX_CPUS        1
22 #endif
23
24 #if USE_PAE
25 # define        PHYS_BITS       48
26 #else
27 # define        PHYS_BITS       32
28 #endif
29
30 #define __ASM__ __asm__ __volatile__
31
32 // === Spinlocks ===
33 /**
34  * \brief Short Spinlock structure
35  */
36 struct sShortSpinlock {
37         volatile int    Lock;   //!< Lock value
38          int    IF;     //!< Interrupt state on call to SHORTLOCK
39 };
40 /**
41  * \brief Determine if a short spinlock is locked
42  * \param Lock  Lock pointer
43  */
44 static inline int IS_LOCKED(struct sShortSpinlock *Lock) {
45         return !!Lock->Lock;
46 }
47 /**
48  * \brief Acquire a Short Spinlock
49  * \param Lock  Lock pointer
50  * 
51  * This type of mutex should only be used for very short sections of code,
52  * or in places where a Mutex_* would be overkill, such as appending
53  * an element to linked list (usually two assignement lines in C)
54  * 
55  * \note This type of lock halts interrupts, so ensure that no timing
56  * functions are called while it is held.
57  */
58 static inline void SHORTLOCK(struct sShortSpinlock *Lock) {
59          int    v = 1;
60          int    IF;
61         // int  cpu = GetCPUNum() + 1;
62         
63         // Save interrupt state and clear interrupts
64         __ASM__ ("pushf;\n\tpop %%eax\n\tcli" : "=a"(IF));
65         IF &= 0x200;    // AND out all but the interrupt flag
66         
67         // Wait for another CPU to release
68         while(v)
69                 __ASM__("xchgl %%eax, (%%edi)":"=a"(v):"a"(1),"D"(&Lock->Lock));
70         
71         Lock->IF = IF;
72 }
73 /**
74  * \brief Release a short lock
75  * \param Lock  Lock pointer
76  */
77 static inline void SHORTREL(struct sShortSpinlock *Lock) {
78         // Lock->IF can change anytime once Lock->Lock is zeroed
79         if(Lock->IF) {
80                 Lock->Lock = 0;
81                 __ASM__ ("sti");
82         }
83         else {
84                 Lock->Lock = 0;
85         }
86 }
87
88 // === MACROS ===
89 /**
90  * \brief Halt the CPU
91  */
92 #define HALT()  __asm__ __volatile__ ("hlt")
93 /**
94  * \brief Fire a magic breakpoint (bochs)
95  */
96 #define MAGIC_BREAK()   __asm__ __volatile__ ("xchg %bx, %bx")
97
98 // === TYPES ===
99 typedef unsigned int    Uint;   // Unsigned machine native integer
100 typedef unsigned char   Uint8;
101 typedef unsigned short  Uint16;
102 typedef unsigned long   Uint32;
103 typedef unsigned long long      Uint64;
104 typedef signed int              Sint;   // Signed Machine Native integer
105 typedef signed char             Sint8;
106 typedef signed short    Sint16;
107 typedef signed long             Sint32;
108 typedef signed long long        Sint64;
109 typedef Uint    size_t;
110
111 typedef Uint64  tPAddr;
112 typedef Uint32  tVAddr;
113
114 typedef struct {
115     Uint        gs, fs, es, ds;
116     Uint        edi, esi, ebp, kesp;
117         Uint    ebx, edx, ecx, eax;
118     Uint        int_num, err_code;
119     Uint        eip, cs;
120         Uint    eflags, esp, ss;
121 } tRegs;
122
123 typedef struct {
124         Uint    Resvd1[4];      // GS, FS, ES, DS
125         Uint    Arg4, Arg5;     // EDI, ESI
126         Uint    Arg6;   // EBP
127         Uint    Resvd2[1];      // Kernel ESP
128         union {
129                 Uint    Arg1;
130                 Uint    Error;
131         };      // EBX
132         union {
133                 Uint    Arg3;
134                 Uint    RetHi;  // High 32 bits of ret
135         };      // EDX
136         Uint    Arg2;   // ECX
137         union {
138                 Uint    Num;
139                 Uint    Return;
140         };      // EAX
141         Uint    Resvd3[5];      // Int, Err, Eip, CS, ...
142         Uint    StackPointer;   // ESP
143         Uint    Resvd4[1];      // SS
144 } tSyscallRegs;
145
146 typedef struct {
147         #if USE_PAE
148         Uint    PDPT[4];
149         #else
150         Uint    CR3;
151         #endif
152 } tMemoryState;
153
154 typedef struct {
155         Uint    EIP, ESP, EBP;
156 } tTaskState;
157
158 #endif  // !defined(_ARCH_H_)

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