aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2006-12-06 20:14:02 -0500
committerAndi Kleen <andi@basil.nowhere.org>2006-12-06 20:14:02 -0500
commit9ca36101a8d74704d78f10910f89d62de96f9dc8 (patch)
tree358086c902c021f9316968062dc1b1165cf5f897
parenteb5b7b9d86f46b45ba1f986302fdf7df84fb8297 (diff)
[PATCH] i386: Basic definitions for i386-pda
This patch has the basic definitions of struct i386_pda, and the segment selector in the GDT. asm-i386/pda.h is more or less a direct copy of asm-x86_64/pda.h. The most interesting difference is the use of _proxy_pda, which is used to give gcc a model for the actual memory operations on the real pda structure. No actual reference is ever made to _proxy_pda, so it is never defined. Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com> Signed-off-by: Andi Kleen <ak@suse.de> Cc: Chuck Ebbert <76306.1226@compuserve.com> Cc: Zachary Amsden <zach@vmware.com> Cc: Jan Beulich <jbeulich@novell.com> Cc: Andi Kleen <ak@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org>
-rw-r--r--arch/i386/kernel/head.S2
-rw-r--r--include/asm-i386/pda.h95
-rw-r--r--include/asm-i386/segment.h5
3 files changed, 100 insertions, 2 deletions
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index b1f1df11fcc6..4a83384c5a61 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -585,7 +585,7 @@ ENTRY(cpu_gdt_table)
585 .quad 0x004092000000ffff /* 0xc8 APM DS data */ 585 .quad 0x004092000000ffff /* 0xc8 APM DS data */
586 586
587 .quad 0x00c0920000000000 /* 0xd0 - ESPFIX SS */ 587 .quad 0x00c0920000000000 /* 0xd0 - ESPFIX SS */
588 .quad 0x0000000000000000 /* 0xd8 - unused */ 588 .quad 0x0000000000000000 /* 0xd8 - PDA */
589 .quad 0x0000000000000000 /* 0xe0 - unused */ 589 .quad 0x0000000000000000 /* 0xe0 - unused */
590 .quad 0x0000000000000000 /* 0xe8 - unused */ 590 .quad 0x0000000000000000 /* 0xe8 - unused */
591 .quad 0x0000000000000000 /* 0xf0 - unused */ 591 .quad 0x0000000000000000 /* 0xf0 - unused */
diff --git a/include/asm-i386/pda.h b/include/asm-i386/pda.h
new file mode 100644
index 000000000000..4c39ccb1305c
--- /dev/null
+++ b/include/asm-i386/pda.h
@@ -0,0 +1,95 @@
1/*
2 Per-processor Data Areas
3 Jeremy Fitzhardinge <jeremy@goop.org> 2006
4 Based on asm-x86_64/pda.h by Andi Kleen.
5 */
6#ifndef _I386_PDA_H
7#define _I386_PDA_H
8
9#include <linux/stddef.h>
10
11struct i386_pda
12{
13 struct i386_pda *_pda; /* pointer to self */
14};
15
16extern struct i386_pda *_cpu_pda[];
17
18#define cpu_pda(i) (_cpu_pda[i])
19
20#define pda_offset(field) offsetof(struct i386_pda, field)
21
22extern void __bad_pda_field(void);
23
24/* This variable is never instantiated. It is only used as a stand-in
25 for the real per-cpu PDA memory, so that gcc can understand what
26 memory operations the inline asms() below are performing. This
27 eliminates the need to make the asms volatile or have memory
28 clobbers, so gcc can readily analyse them. */
29extern struct i386_pda _proxy_pda;
30
31#define pda_to_op(op,field,val) \
32 do { \
33 typedef typeof(_proxy_pda.field) T__; \
34 if (0) { T__ tmp__; tmp__ = (val); } \
35 switch (sizeof(_proxy_pda.field)) { \
36 case 1: \
37 asm(op "b %1,%%gs:%c2" \
38 : "+m" (_proxy_pda.field) \
39 :"ri" ((T__)val), \
40 "i"(pda_offset(field))); \
41 break; \
42 case 2: \
43 asm(op "w %1,%%gs:%c2" \
44 : "+m" (_proxy_pda.field) \
45 :"ri" ((T__)val), \
46 "i"(pda_offset(field))); \
47 break; \
48 case 4: \
49 asm(op "l %1,%%gs:%c2" \
50 : "+m" (_proxy_pda.field) \
51 :"ri" ((T__)val), \
52 "i"(pda_offset(field))); \
53 break; \
54 default: __bad_pda_field(); \
55 } \
56 } while (0)
57
58#define pda_from_op(op,field) \
59 ({ \
60 typeof(_proxy_pda.field) ret__; \
61 switch (sizeof(_proxy_pda.field)) { \
62 case 1: \
63 asm(op "b %%gs:%c1,%0" \
64 : "=r" (ret__) \
65 : "i" (pda_offset(field)), \
66 "m" (_proxy_pda.field)); \
67 break; \
68 case 2: \
69 asm(op "w %%gs:%c1,%0" \
70 : "=r" (ret__) \
71 : "i" (pda_offset(field)), \
72 "m" (_proxy_pda.field)); \
73 break; \
74 case 4: \
75 asm(op "l %%gs:%c1,%0" \
76 : "=r" (ret__) \
77 : "i" (pda_offset(field)), \
78 "m" (_proxy_pda.field)); \
79 break; \
80 default: __bad_pda_field(); \
81 } \
82 ret__; })
83
84/* Return a pointer to a pda field */
85#define pda_addr(field) \
86 ((typeof(_proxy_pda.field) *)((unsigned char *)read_pda(_pda) + \
87 pda_offset(field)))
88
89#define read_pda(field) pda_from_op("mov",field)
90#define write_pda(field,val) pda_to_op("mov",field,val)
91#define add_pda(field,val) pda_to_op("add",field,val)
92#define sub_pda(field,val) pda_to_op("sub",field,val)
93#define or_pda(field,val) pda_to_op("or",field,val)
94
95#endif /* _I386_PDA_H */
diff --git a/include/asm-i386/segment.h b/include/asm-i386/segment.h
index b7ab59685ba7..5bdda79b6b53 100644
--- a/include/asm-i386/segment.h
+++ b/include/asm-i386/segment.h
@@ -39,7 +39,7 @@
39 * 25 - APM BIOS support 39 * 25 - APM BIOS support
40 * 40 *
41 * 26 - ESPFIX small SS 41 * 26 - ESPFIX small SS
42 * 27 - unused 42 * 27 - PDA [ per-cpu private data area ]
43 * 28 - unused 43 * 28 - unused
44 * 29 - unused 44 * 29 - unused
45 * 30 - unused 45 * 30 - unused
@@ -74,6 +74,9 @@
74#define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14) 74#define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
75#define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8) 75#define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
76 76
77#define GDT_ENTRY_PDA (GDT_ENTRY_KERNEL_BASE + 15)
78#define __KERNEL_PDA (GDT_ENTRY_PDA * 8)
79
77#define GDT_ENTRY_DOUBLEFAULT_TSS 31 80#define GDT_ENTRY_DOUBLEFAULT_TSS 31
78 81
79/* 82/*