Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9ca36101 authored by Jeremy Fitzhardinge's avatar Jeremy Fitzhardinge Committed by Andi Kleen
Browse files

[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: default avatarJeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: default avatarAndi 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: default avatarAndrew Morton <akpm@osdl.org>
parent eb5b7b9d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -585,7 +585,7 @@ ENTRY(cpu_gdt_table)
	.quad 0x004092000000ffff	/* 0xc8 APM DS    data */

	.quad 0x00c0920000000000	/* 0xd0 - ESPFIX SS */
	.quad 0x0000000000000000	/* 0xd8 - unused */
	.quad 0x0000000000000000	/* 0xd8 - PDA */
	.quad 0x0000000000000000	/* 0xe0 - unused */
	.quad 0x0000000000000000	/* 0xe8 - unused */
	.quad 0x0000000000000000	/* 0xf0 - unused */

include/asm-i386/pda.h

0 → 100644
+95 −0
Original line number Diff line number Diff line
/*
   Per-processor Data Areas
   Jeremy Fitzhardinge <jeremy@goop.org> 2006
   Based on asm-x86_64/pda.h by Andi Kleen.
 */
#ifndef _I386_PDA_H
#define _I386_PDA_H

#include <linux/stddef.h>

struct i386_pda
{
	struct i386_pda *_pda;		/* pointer to self */
};

extern struct i386_pda *_cpu_pda[];

#define cpu_pda(i)	(_cpu_pda[i])

#define pda_offset(field) offsetof(struct i386_pda, field)

extern void __bad_pda_field(void);

/* This variable is never instantiated.  It is only used as a stand-in
   for the real per-cpu PDA memory, so that gcc can understand what
   memory operations the inline asms() below are performing.  This
   eliminates the need to make the asms volatile or have memory
   clobbers, so gcc can readily analyse them. */
extern struct i386_pda _proxy_pda;

#define pda_to_op(op,field,val)						\
	do {								\
		typedef typeof(_proxy_pda.field) T__;			\
		if (0) { T__ tmp__; tmp__ = (val); }			\
		switch (sizeof(_proxy_pda.field)) {			\
		case 1:							\
			asm(op "b %1,%%gs:%c2"				\
			    : "+m" (_proxy_pda.field)			\
			    :"ri" ((T__)val),				\
			     "i"(pda_offset(field)));			\
			break;						\
		case 2:							\
			asm(op "w %1,%%gs:%c2"				\
			    : "+m" (_proxy_pda.field)			\
			    :"ri" ((T__)val),				\
			     "i"(pda_offset(field)));			\
			break;						\
		case 4:							\
			asm(op "l %1,%%gs:%c2"				\
			    : "+m" (_proxy_pda.field)			\
			    :"ri" ((T__)val),				\
			     "i"(pda_offset(field)));			\
			break;						\
		default: __bad_pda_field();				\
		}							\
	} while (0)

#define pda_from_op(op,field)						\
	({								\
		typeof(_proxy_pda.field) ret__;				\
		switch (sizeof(_proxy_pda.field)) {			\
		case 1:							\
			asm(op "b %%gs:%c1,%0"				\
			    : "=r" (ret__)				\
			    : "i" (pda_offset(field)),			\
			      "m" (_proxy_pda.field));			\
			break;						\
		case 2:							\
			asm(op "w %%gs:%c1,%0"				\
			    : "=r" (ret__)				\
			    : "i" (pda_offset(field)),			\
			      "m" (_proxy_pda.field));			\
			break;						\
		case 4:							\
			asm(op "l %%gs:%c1,%0"				\
			    : "=r" (ret__)				\
			    : "i" (pda_offset(field)),			\
			      "m" (_proxy_pda.field));			\
			break;						\
		default: __bad_pda_field();				\
		}							\
		ret__; })

/* Return a pointer to a pda field */
#define pda_addr(field)							\
	((typeof(_proxy_pda.field) *)((unsigned char *)read_pda(_pda) + \
				      pda_offset(field)))

#define read_pda(field) pda_from_op("mov",field)
#define write_pda(field,val) pda_to_op("mov",field,val)
#define add_pda(field,val) pda_to_op("add",field,val)
#define sub_pda(field,val) pda_to_op("sub",field,val)
#define or_pda(field,val) pda_to_op("or",field,val)

#endif	/* _I386_PDA_H */
+4 −1
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@
 *  25 - APM BIOS support 
 *
 *  26 - ESPFIX small SS
 *  27 - unused
 *  27 - PDA				[ per-cpu private data area ]
 *  28 - unused
 *  29 - unused
 *  30 - unused
@@ -74,6 +74,9 @@
#define GDT_ENTRY_ESPFIX_SS		(GDT_ENTRY_KERNEL_BASE + 14)
#define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)

#define GDT_ENTRY_PDA			(GDT_ENTRY_KERNEL_BASE + 15)
#define __KERNEL_PDA (GDT_ENTRY_PDA * 8)

#define GDT_ENTRY_DOUBLEFAULT_TSS	31

/*