Warning, cross-references for /kernel/include/arch/i386-percpu.h need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #ifndef __I386_PERPCU_H__
0019 #define __I386_PERCPU_H__
0020
0021 #include "util/stringify.h"
0022
0023 #define PER_CPU_SEG fs
0024 #define PER_CPU_DBG dr3
0025 #define PER_CPU_SEG_STR __stringify(PER_CPU_SEG)
0026 #define PER_CPU_DBG_STR __stringify(PER_CPU_DBG)
0027
0028 #ifndef __ASSEMBLER__
0029 #include "types.h"
0030
0031
0032
0033
0034
0035 #define DEF_PER_CPU(type,var) PER_CPU_ATTR type var
0036
0037
0038 #define INIT_PER_CPU(var) \
0039 void __##var##_ctor_func (void); \
0040 PER_CPU_CTOR_ATTR void (*__##var##_ctor_ptr) (void) = \
0041 __##var##_ctor_func; \
0042 void __##var##_ctor_func (void)
0043
0044
0045 #define percpu_read(var) percpu_op_src ("mov", var, "m" (var))
0046 #define percpu_read64(var) \
0047 ({ \
0048 u32 _percpu_lo, _percpu_hi; \
0049 u64 _percpu_ret; \
0050 asm ("movl "__percpu_arg (1)", %0" \
0051 : "=r" (_percpu_lo) \
0052 : "m" (var)); \
0053 asm ("movl "__percpu_arg (1)", %0" \
0054 : "=r" (_percpu_hi) \
0055 : "m" (((u32 *) &var)[1])); \
0056 _percpu_ret = (((u64) _percpu_hi) << 32); \
0057 _percpu_ret |= (u64) _percpu_lo; \
0058 _percpu_ret; \
0059 })
0060 #define percpu_write(var, val) percpu_op_dest ("mov", var, val)
0061 #define percpu_write64(var, val) do { \
0062 asm ("movl %2, "__percpu_arg (0)"\n" \
0063 "movl %3, "__percpu_arg (1) \
0064 : "+m" (var), "+m" (((u32 *) &var)[1]) \
0065 : "re" ((u32) val), \
0066 "re" ((u32) (val >> 32))); \
0067 } while (0)
0068
0069
0070 extern void percpu_per_cpu_init (void);
0071
0072
0073 extern u8 *percpu_virt[];
0074 #define percpu_pointer(cpu, var) ((void *) (&percpu_virt[cpu][(uint) &var]))
0075
0076
0077
0078 #define PER_CPU_ATTR __attribute__((section(".percpu")))
0079 #define PER_CPU_CTOR_ATTR __attribute__((section(".percpu.ctor")))
0080
0081 #define __percpu_arg(x) "%%"PER_CPU_SEG_STR":%"#x
0082 #define percpu_op_dest(op, var, val) \
0083 do { \
0084 switch (sizeof (typeof (var))) { \
0085 case 1: \
0086 asm (op "b %1, "__percpu_arg (0) \
0087 : "+m" (var) : "qi" (val)); \
0088 break; \
0089 case 2: \
0090 asm (op "w %1, "__percpu_arg (0) \
0091 : "+m" (var) : "ri" (val)); \
0092 break; \
0093 case 4: \
0094 asm (op "l %1, "__percpu_arg (0) \
0095 : "+m" (var) : "ri" (val)); \
0096 break; \
0097 default: panic ("percpu_op_dest: bad size"); \
0098 } \
0099 } while (0)
0100
0101 #define percpu_op_src(op, var, constraint) \
0102 ({ \
0103 typeof(var) _percpu_ret; \
0104 switch (sizeof (typeof (var))) { \
0105 case 1: \
0106 asm (op "b "__percpu_arg (1)", %0" \
0107 : "=q" (_percpu_ret) : constraint); \
0108 break; \
0109 case 2: \
0110 asm (op "w "__percpu_arg (1)", %0" \
0111 : "=r" (_percpu_ret) : constraint); \
0112 break; \
0113 case 4: \
0114 asm (op "l "__percpu_arg (1)", %0" \
0115 : "=r" (_percpu_ret) : constraint); \
0116 break; \
0117 default: panic ("percpu_op_src: bad size"); \
0118 } \
0119 _percpu_ret; \
0120 })
0121
0122 #endif
0123
0124 #endif
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135