ia64/xen-unstable

view extras/mini-os/include/ia64/os.h @ 16731:03c2236e0089

minios: Add noreturn attribute to do_exit

Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jan 17 14:39:45 2008 +0000 (2008-01-17)
parents d1853a39e063
children 945820bfedb6
line source
1 /*
2 * Copyright (C) 2007 - Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
3 *
4 ****************************************************************************
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
25 #if !defined(__OS_H__)
26 #define __OS_H__
28 #if !defined(__ASSEMBLY__)
30 #include "types.h"
31 #include "endian.h"
32 #include "ia64_cpu.h"
33 #include "atomic.h"
34 #include "efi.h"
35 #include "sal.h"
36 #include "pal.h"
37 #include "hypervisor.h"
40 typedef uint64_t paddr_t; /* Physical address. */
41 typedef uint64_t caddr_t; /* rr7/kernel memory address. */
43 #include "page.h"
44 #include "mm.h"
47 void do_exit(void) __attribute__((noreturn));
48 void arch_init(start_info_t *si); /* in common.c */
49 void arch_print_info(void); /* in common.c */
52 /* Size of xen_ia64_boot_param.command_line */
53 #define COMMAND_LINE_SIZE 512
55 extern struct xen_ia64_boot_param* ia64_boot_paramP;
56 extern struct xen_ia64_boot_param ia64BootParamG;
57 extern char boot_cmd_line[];
58 extern efi_system_table_t* efiSysTableP;
59 extern int bootverbose;
61 extern void ia64_probe_sapics(void);
65 /* Contains the needed stuff from efi. */
66 struct efi
67 {
69 efi_system_table_t* efiSysTableP;
70 efi_set_virtual_address_map_t setVirtAddrMapF;
71 efi_get_time_t getTimeF;
72 efi_reset_system_t resetSystemF;
74 };
76 struct machine_fw
77 {
78 struct efi efi;
80 uint64_t ia64_port_base; /* physical address */
81 uint64_t ia64_pal_base; /* virtual rr7 address */
83 sal_system_table_t* ia64_sal_tableP;
84 sal_entry_t* ia64_sal_entryP; /* SAL_PROC entrypoint */
86 uint64_t ia64_efi_acpi_table; /* physical address */
87 uint64_t ia64_efi_acpi20_table; /* physical address */
89 uint64_t mach_mem_start; /* phys start addr of machine memory */
90 uint64_t mach_mem_size; /* size of machine memory */
92 uint64_t kernstart; /* virt address of kern text start */
93 uint64_t kernend;
94 uint64_t kernpstart; /* phys address of kern text start */
95 uint64_t kernpend;
96 };
98 extern struct machine_fw machineFwG;
100 #define ia64_sal_entry machineFwG.ia64_sal_entryP
102 #define smp_processor_id() 0
104 static inline uint64_t
105 xchg8(uint64_t* ptr, uint64_t x) \
106 {
107 uint64_t oldVal;
108 asm volatile ("xchg8 %0=[%1],%2" : "=r" (oldVal)
109 : "r" (ptr), "r" (x) : "memory");
110 return oldVal;
111 }
112 #define xchg xchg8
114 // Counts the number of 1-bits in x.
115 #if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
116 # define get_popcnt(x) __builtin_popcountl(x)
117 #else
118 # define get_popcnt(x) \
119 ({ \
120 uint64_t num; \
121 asm ("popcnt %0=%1" : "=r" (num) : "r" (x)); \
122 num; \
123 })
124 #endif
126 /**
127 * __ffs - find first bit in word.
128 * @x: The word to search
129 *
130 * Undefined if no bit exists, so code should check against 0 first.
131 */
132 static inline unsigned long
133 __ffs (unsigned long x)
134 {
135 unsigned long result;
137 result = get_popcnt((x-1) & ~x);
138 return result;
139 }
142 static inline void
143 synch_clear_bit(int num, volatile void *addr)
144 {
145 clear_bit(num, addr);
146 }
148 static inline void
149 synch_set_bit(int num, volatile void *addr)
150 {
151 set_bit(num, addr);
152 }
154 static inline int
155 synch_test_bit(int nr, const volatile void *addr)
156 {
157 return test_bit(nr, addr);
158 }
160 static inline int
161 synch_test_and_set_bit(int num, volatile void * addr)
162 {
163 return test_and_set_bit(num, addr);
164 }
167 #define synch_cmpxchg(ptr, old, new) \
168 ((__typeof__(*(ptr)))__synch_cmpxchg((ptr),\
169 (unsigned long)(old), \
170 (unsigned long)(new), \
171 sizeof(*(ptr))))
173 static inline unsigned long
174 __synch_cmpxchg(volatile void *ptr, uint64_t old, uint64_t new, int size)
175 {
176 switch (size)
177 {
178 case 1:
179 return ia64_cmpxchg_acq_8(ptr, old, new);
180 case 2:
181 return ia64_cmpxchg_acq_16(ptr, old, new);
182 case 4:
183 return ia64_cmpxchg_acq_32(ptr, old, new);
184 case 8:
185 return ia64_cmpxchg_acq_64(ptr, old, new);
186 }
187 return ia64_cmpxchg_acq_64(ptr, old, new);
188 }
190 /*
191 * Force a proper event-channel callback from Xen after clearing the
192 * callback mask. We do this in a very simple manner, by making a call
193 * down into Xen. The pending flag will be checked by Xen on return.
194 */
195 static inline void
196 force_evtchn_callback(void)
197 {
198 (void)HYPERVISOR_xen_version(0, NULL);
199 }
201 extern shared_info_t *HYPERVISOR_shared_info;
203 static inline int
204 HYPERVISOR_shutdown(unsigned int reason)
205 {
206 struct sched_shutdown sched_shutdown = {
207 .reason = reason
208 };
210 int rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
212 if (rc == -ENOSYS)
213 rc = HYPERVISOR_sched_op_compat(SCHEDOP_shutdown, reason);
215 return rc;
216 }
219 /*
220 * This code is from the originally os.h and should be put in a
221 * common header file!
222 */
224 /*
225 * The use of 'barrier' in the following reflects their use as local-lock
226 * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
227 * critical operations are executed. All critical operations must complete
228 * /before/ reentrancy is permitted (e.g., __sti()). Alpha architecture also
229 * includes these barriers, for example.
230 */
232 #define __cli() \
233 do { \
234 vcpu_info_t *_vcpu; \
235 _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
236 _vcpu->evtchn_upcall_mask = SWAP(1); \
237 barrier(); \
238 } while (0)
240 #define __sti() \
241 do { \
242 vcpu_info_t *_vcpu; \
243 barrier(); \
244 _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
245 _vcpu->evtchn_upcall_mask = 0; \
246 barrier(); /* unmask then check (avoid races) */ \
247 if (unlikely(SWAP(_vcpu->evtchn_upcall_pending))) \
248 force_evtchn_callback(); \
249 } while (0)
251 #define __save_flags(x) \
252 do { \
253 vcpu_info_t *_vcpu; \
254 _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
255 (x) = SWAP(_vcpu->evtchn_upcall_mask); \
256 } while (0)
258 #define __restore_flags(x) \
259 do { \
260 vcpu_info_t *_vcpu; \
261 barrier(); \
262 _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
263 if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \
264 barrier(); /* unmask then check (avoid races) */ \
265 if ( unlikely(SWAP(_vcpu->evtchn_upcall_pending)) ) \
266 force_evtchn_callback(); \
267 }\
268 } while (0)
270 #define safe_halt() ((void)0)
272 #define __save_and_cli(x) \
273 do { \
274 vcpu_info_t *_vcpu; \
275 _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
276 (x) = SWAP(_vcpu->evtchn_upcall_mask); \
277 _vcpu->evtchn_upcall_mask = SWAP(1); \
278 barrier(); \
279 } while (0)
281 #define local_irq_save(x) __save_and_cli(x)
282 #define local_irq_restore(x) __restore_flags(x)
283 #define local_save_flags(x) __save_flags(x)
284 #define local_irq_disable() __cli()
285 #define local_irq_enable() __sti()
287 #define irqs_disabled() \
288 SWAP(HYPERVISOR_shared_info->vcpu_info[smp_processor_id()].evtchn_upcall_mask)
290 /* This is a barrier for the compiler only, NOT the processor! */
291 #define barrier() __asm__ __volatile__("": : :"memory")
293 #define mb() ia64_mf()
294 #define rmb() mb()
295 #define wmb() mb()
298 #define BUG() \
299 { printk("mini-os BUG at %s:%d!\n", __FILE__, __LINE__); do_exit(); }
301 #define PRINT_BV(_fmt, _params...) \
302 if (bootverbose) \
303 printk(_fmt , ## _params)
305 #endif /* !defined(__ASSEMBLY__) */
307 #if defined(__ASSEMBLY__)
309 #define UL_CONST(x) x
310 #define UL_TYPE(x) x
312 #else /* defined(__ASSEMBLY__) */
314 #define UL_CONST(x) x##UL
315 #define UL_TYPE(x) ((uint64_t)x)
317 #endif /* defined(__ASSEMBLY__) */
319 #endif /* !defined(__OS_H__) */