Unborking some threading code
[tpg/acess2.git] / Kernel / arch / x86_64 / include / arch.h
1 /*
2  * Acess2 x86-64 Architecure Module
3  * - By John Hodge (thePowersGang)
4  */
5 #ifndef _ARCH_H_
6 #define _ARCH_H_
7
8 //#include <stdint.h>
9 //#define KERNEL_BASE   0xFFFF8000##00000000
10 #define KERNEL_BASE     0xFFFFFFFF##80000000
11 #define BITS    64
12
13 //#define INT_MAX       0x7FFFFFFF
14 //#define UINT_MAX      0xFFFFFFFF
15
16 // === Core Types ===
17 typedef signed char     Sint8;
18 typedef unsigned char   Uint8;
19 typedef signed short    Sint16;
20 typedef unsigned short  Uint16;
21 typedef signed int      Sint32;
22 typedef unsigned int    Uint32;
23 #if __WORDSIZE == 64
24 typedef signed long int Sint64;
25 typedef unsigned long int       Uint64;
26 #else
27 typedef signed long long int    Sint64;
28 typedef unsigned long long int  Uint64;
29 #endif
30
31 typedef Sint64  Sint;
32 typedef Uint64  Uint;
33 typedef Uint64  tPAddr;
34 typedef Uint64  tVAddr;
35
36 typedef Uint64  size_t;
37
38 #define __ASM__ __asm__ __volatile__
39
40 // === MACROS ===
41 /**
42  * \brief Halt the CPU
43  */
44 #define HALT()  __asm__ __volatile__ ("hlt")
45 /**
46  * \brief Fire a magic breakpoint (bochs)
47  */
48 #define MAGIC_BREAK()   __asm__ __volatile__ ("xchg %bx, %bx")
49
50 // Systemcall Registers
51 // TODO: Fix this structure
52 typedef struct sSyscallRegs
53 {
54         union {
55                 Uint    Num;
56                 Uint    Return;
57         };      // RAX
58         Uint    Arg4;   // RCX
59         Uint    Arg3;   // RDX
60         Uint    Error;  // RBX
61         Uint    Resvd1[2];      // Kernel RSP, RBP
62         Uint    Arg2;   // RSI
63         Uint    Arg1;   // RDI
64         Uint    Arg5;   // R8
65         Uint    Arg6;   // R9
66         Uint    Resvd2[6];      // R10 - R15
67         Uint    Resvd3[5];      // IntNum, ErrCode, RIP, CS, RFLAGS
68         
69         Uint    Resvd4[5];      // Int, Err, rip, CS, ...
70         Uint    StackPointer;   // RSP
71         Uint    Resvd5[1];      // SS   
72 }       tSyscallRegs;
73
74 /**
75  * \brief Short Spinlock structure
76  */
77 struct sShortSpinlock {
78         volatile int    Lock;   //!< Lock value
79          int    IF;     //!< Interrupt state on call to SHORTLOCK
80 };
81 /**
82  * \brief Determine if a short spinlock is locked
83  * \param Lock  Lock pointer
84  */
85 static inline int IS_LOCKED(struct sShortSpinlock *Lock) {
86         return !!Lock->Lock;
87 }
88 /**
89  * \brief Acquire a Short Spinlock
90  * \param Lock  Lock pointer
91  * 
92  * This type of mutex should only be used for very short sections of code,
93  * or in places where a Mutex_* would be overkill, such as appending
94  * an element to linked list (usually two assignement lines in C)
95  * 
96  * \note This type of lock halts interrupts, so ensure that no timing
97  * functions are called while it is held.
98  */
99 static inline void SHORTLOCK(struct sShortSpinlock *Lock) {
100          int    v = 1;
101         
102         // Save interrupt state
103         __ASM__ ("pushf;\n\tpop %%rax" : "=a"(Lock->IF));
104         Lock->IF &= 0x200;
105         
106         // Stop interrupts
107         __ASM__ ("cli");
108         
109         // Wait for another CPU to release
110         while(v)
111                 __ASM__("xchgl %%eax, (%%rdi)":"=a"(v):"a"(1),"D"(&Lock->Lock));
112 }
113 /**
114  * \brief Release a short lock
115  * \param Lock  Lock pointer
116  */
117 static inline void SHORTREL(struct sShortSpinlock *Lock) {
118         Lock->Lock = 0;
119         #if 0   // Which is faster?, meh the test is simpler
120         __ASM__ ("pushf;\n\tor %0, (%%rsp);\n\tpopf" : : "a"(Lock->IF));
121         #else
122         if(Lock->IF)    __ASM__ ("sti");
123         #endif
124 }
125
126 #endif
127

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