source: trunk/hal/i386/cpu-asm.h @ 7

Last change on this file since 7 was 1, checked in by alain, 8 years ago

First import

File size: 6.7 KB
Line 
1/*
2 * cpu-asm.h - implementation of CPU related Hardware Abstraction Layer
3 *
4 * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless
5 * Copyright (c) 2011,2012 UPMC Sorbonne Universites
6 *
7 * This file is part of ALMOS-kernel.
8 *
9 * ALMOS-kernel is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2.0 of the License.
12 *
13 * ALMOS-kernel is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with ALMOS-kernel; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#ifndef  _CPU_ASM_H_
24#define  _CPU_ASM_H_
25
26
27#ifndef _HAL_CPU_H_
28#error this file connot be included directly, use cpu.h instead
29#endif
30
31#include <config.h>
32#include <cpu-internal.h>
33
34/* CPU IRQ macros */
35#undef  CPU_HW_IRQ_NR
36#define CPU_HW_IRQ_NR  1
37
38#undef  CPU_IRQ_NR
39#define CPU_IRQ_NR  CPU_HW_IRQ_NR
40
41/* SR USR/SYS mask */
42#undef  CPU_USR_MODE
43#define CPU_USR_MODE  0x01
44
45#undef  CPU_SYS_MODE
46#define CPU_SYS_MODE  0x00
47
48/* Porcessor Context*/
49struct cpu_context_s
50{
51        /* Current CPU Context */
52        reg_t ebx,esp,ebp,edi,esi;
53        reg_t eip,cr3;
54        reg_t loadable;
55        reg_t tss_ptr;
56        reg_t thread_ptr;
57        reg_t kstack_ptr;
58
59        /* Initialization Info */
60        reg_t stack_ptr;
61        reg_t cpu_id;
62        reg_t mode;
63        reg_t entry_func;
64        reg_t exit_func;
65        reg_t arg1;
66        reg_t arg2;
67}__attribute__ ((packed));
68
69extern void __cpu_context_init(struct cpu_context_s* ctx, struct cpu_context_attr_s *attr);
70
71static inline void cpu_context_init(struct cpu_context_s* ctx, struct cpu_context_attr_s *attr)
72{
73        __cpu_context_init(ctx,attr);
74}
75
76inline void cpu_context_destroy(struct cpu_context_s *ctx)
77{
78}
79
80
81extern void *memcpy(void *, void*, unsigned long);
82static void cpu_context_dup(struct cpu_context_s *dest,
83                            struct cpu_context_s *src)
84{
85        memcpy(dest, src, (unsigned long)sizeof(*src));
86}
87
88
89/* Return processor id */
90static inline uint_t cpu_get_id(void)
91{
92        register unsigned int proc_id = 0;
93
94        //  asm volatile ("mfc0    %0,  $0" : "=r" (proc_id));
95 
96        return proc_id;
97}
98
99/* Return current execution cycle number */
100static inline uint_t cpu_time_stamp(void)
101{
102        register uint32_t lo;
103        register uint32_t hi;
104
105        __asm__ volatile 
106                ("rdtsc" : "=a" (lo), "=d" (hi));
107
108        return lo;
109}
110
111/* Return pointer to current thread */
112inline struct thread_s* cpu_current_thread (void)
113{
114        register struct cpu_tss_s *tss;
115 
116        tss = cpu_get_tss(cpu_get_id());
117        return (struct thread_s*)tss->esp_r1;
118}
119
120/* Set current thread pointer */
121static inline void cpu_set_current_thread (struct thread_s *thread)
122{ 
123        //asm volatile ("mtc0    %0,  $4,  2" : : "r" (thread));
124}
125
126static inline bool_t cpu_isBad_addr(void *addr)
127{
128        return false;
129}
130
131static inline void cpu_fpu_enable(void)
132{
133}
134
135static inline void cpu_fpu_disable(void)
136{
137}
138
139static inline uint_t cpu_get_stack(void)
140{
141        return 0;
142}
143
144static inline uint_t cpu_set_stack(void* val)
145{
146        return 0;
147}
148
149/* Disable all IRQs and save old IF state */
150static inline void cpu_disable_all_irq (uint_t *old)
151{
152        register unsigned int eflags;
153
154        __asm__ volatile
155                ("pushfl               \n"
156                 "popl        %0       \n"
157                 "cli                  \n"
158                 : "=r" (eflags));
159
160        if(old) *old = (eflags & 0x200) ? 1 : 0;
161}
162
163/* Enable all IRQs and save old IF state */
164static inline void cpu_enable_all_irq (uint_t *old)
165{
166        register unsigned int eflags;
167
168        __asm__ volatile
169                ("pushfl               \n"
170                 "popl        %0       \n"
171                 "sti                  \n"
172                 : "=r" (eflags));
173
174        if(old) *old = (eflags & 0x200) ? 1 : 0;
175}
176
177/* Disable a specific IRQ number and save old IF state */
178static inline void cpu_disable_single_irq (uint_t irq_num, uint_t *old)
179{
180        cpu_disable_all_irq(old);
181}
182
183/* Enable a specific IRQ number and save old IF state */
184static inline void cpu_enable_single_irq(uint_t irq_num, uint_t *old)
185{
186        cpu_enable_all_irq(old);
187}
188
189/* Restore old IF state, saved by precedents functions */
190static inline void cpu_restore_irq(uint_t old)
191{
192        register unsigned int isIF;
193
194        isIF = (old == 1) ? 1 : 0;
195
196        __asm__ volatile
197                ("bt          $0,        %0             \n"
198                 "jc          1f                        \n"
199                 "cli                                   \n"
200                 "jmp         2f                        \n"
201                 "1:                                    \n"
202                 "sti                                   \n"
203                 "2:                                    \n"
204                 : : "r" (isIF));
205}
206
207static inline void cpu_spinlock_init(void *lock, uint_t val)
208{
209        *((uint_t*)lock) = val;
210}
211
212static inline void cpu_spinlock_destroy(void *lock)
213{
214        *((uint_t*)lock) = 0;       /* ToDo: Put dead value instead */
215}
216
217/* Try to take a spinlock */
218static inline bool_t cpu_spinlock_trylock (void *lock)
219{ 
220        register int8_t state;
221   
222        __asm__ volatile
223                ("lock bts    $1,        (%1)      \n"
224                 "setc        %0                   \n"
225                 : "=r" (state) : "r" (lock));
226
227        return state;
228}
229
230/** Lock a spinlock  */
231extern uint_t rand();
232//extern int __kperror (const char *fmt, ...);
233static inline void cpu_spinlock_lock(void *lock)
234{
235#if CONFIG_CPU_BACKOFF_SPINLOCK
236        volatile uint_t i;
237        register uint_t backoff;
238
239        backoff = cpu_get_id();//rand() % 5;
240#endif
241        while((cpu_spinlock_trylock(lock)))
242        {
243#if CONFIG_CPU_BACKOFF_SPINLOCK
244                i = 1 << backoff;
245                backoff ++;
246                for(; i > 0; i--);
247#endif
248        }
249}
250
251
252/* Unlock a spinlock */
253static inline void cpu_spinlock_unlock (void *lock)
254{ 
255        __asm__ volatile
256                ("lock btr    $1,        (%0)      \n"
257                 : : "r" (lock));
258}
259
260static inline sint_t cpu_atomic_add(void *ptr, sint_t val)
261{
262        register  sint_t current;
263
264        __asm__ volatile
265                ("movl       %1,     %%ecx        \n"
266                 "movl       %2,     %%eax        \n"
267                 "lock xaddl %%eax,  (%%ecx)      \n"
268                 "movl       %%eax,  %0           \n" 
269                 : "=r" (current) : "r" (ptr), "r" (val) : "%ecx", "%eax");
270
271        return current;
272}
273
274static inline sint_t cpu_atomic_inc(void *ptr)
275{
276        return cpu_atomic_add(ptr, 1);
277}
278
279static inline sint_t cpu_atomic_dec(void *ptr)
280{
281        return cpu_atomic_add(ptr, -1);
282}
283
284static inline sint_t cpu_atomic_set(void *ptr, sint_t new_val)
285{
286        register sint_t old_val = 0;
287
288        __asm__ volatile
289                ("movl        %1,        %%ecx        \n"
290                 "movl        %2,        %%eax        \n"
291                 "lock xchg   %%eax,      (%%ecx)      \n"
292                 "movl        %%eax,      %0          \n"       
293                 : "=r" (old_val) : "r" (ptr), "r" (new_val) : "%ecx", "%eax");
294       
295        return old_val;
296}
297
298static inline sint_t cpu_atomic_get(void *ptr)
299{
300        return *((sint_t*)ptr);
301}
302
303/* Cache operations */
304static inline void cpu_invalid_dcache_line(void *ptr)
305{
306#if 0
307        __asm__ volatile
308                ("cache    %0,     (%1)             \n"
309                 : : "i" (0x11) , "r" (ptr));
310#endif
311}
312
313
314#endif  /* _CPU_ASM_H_ */
Note: See TracBrowser for help on using the repository browser.