summaryrefslogtreecommitdiffstats
path: root/arch/x86/include
diff options
context:
space:
mode:
authorGraeme Russ <graeme.russ@gmail.com>2011-12-31 22:58:15 +1100
committerGraeme Russ <graeme.russ@gmail.com>2012-01-04 22:17:24 +1100
commit9e6c572ff03cda84c88663b23c7157d8b1f275ac (patch)
treea2c42fef142e1d179d47b20c35d3c331a279359a /arch/x86/include
parent240ab5aa2161df500e8950c2a4f392e84324f78a (diff)
downloadblackbird-obmc-uboot-9e6c572ff03cda84c88663b23c7157d8b1f275ac.tar.gz
blackbird-obmc-uboot-9e6c572ff03cda84c88663b23c7157d8b1f275ac.zip
x86: Use fs for global data
Use the base address of the 'F' segment as a pointer to the global data structure. By adding the linear address (i.e. the 'D' segment address) as the first word of the global data structure, the address of the global data relative to the 'D' segment can be found simply, for example, by: fs movl 0, %eax This makes the gd 'pointer' writable prior to relocation (by reloading the Global Desctriptor Table) which brings x86 into line with all other arches NOTE: Writing to the gd 'pointer' is expensive (but we only do it twice) but using it to access global data members (read and write) is still fairly cheap -- Changes for v2: - Rebased against changes made to patch #3 - Removed extra indent - Tweaked commit message
Diffstat (limited to 'arch/x86/include')
-rw-r--r--arch/x86/include/asm/global_data.h21
-rw-r--r--arch/x86/include/asm/processor.h1
-rw-r--r--arch/x86/include/asm/u-boot-x86.h2
3 files changed, 17 insertions, 7 deletions
diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h
index 05a2139d00..908a02c900 100644
--- a/arch/x86/include/asm/global_data.h
+++ b/arch/x86/include/asm/global_data.h
@@ -36,6 +36,8 @@
#ifndef __ASSEMBLY__
typedef struct global_data {
+ /* NOTE: gd_addr MUST be first member of struct global_data! */
+ unsigned long gd_addr; /* Location of Global Data */
bd_t *bd;
unsigned long flags;
unsigned long baudrate;
@@ -51,13 +53,24 @@ typedef struct global_data {
unsigned long bus_clk;
unsigned long relocaddr; /* Start address of U-Boot in RAM */
unsigned long start_addr_sp; /* start_addr_stackpointer */
+ unsigned long gdt_addr; /* Location of GDT */
+ unsigned long new_gd_addr; /* New location of Global Data */
phys_size_t ram_size; /* RAM size */
unsigned long reset_status; /* reset status register at boot */
void **jt; /* jump table */
char env_buf[32]; /* buffer for getenv() before reloc. */
} gd_t;
-extern gd_t *gd;
+static inline gd_t *get_fs_gd_ptr(void)
+{
+ gd_t *gd_ptr;
+
+ asm volatile("fs movl 0, %0\n" : "=r" (gd_ptr));
+
+ return gd_ptr;
+}
+
+#define gd get_fs_gd_ptr()
#endif
@@ -73,12 +86,6 @@ extern gd_t *gd;
#define GD_FLG_DISABLE_CONSOLE 0x00040 /* Disable console (in & out) */
#define GD_FLG_ENV_READY 0x00080 /* Environment imported into hash table */
-#if 0
#define DECLARE_GLOBAL_DATA_PTR
-#else
-#define XTRN_DECLARE_GLOBAL_DATA_PTR extern
-#define DECLARE_GLOBAL_DATA_PTR XTRN_DECLARE_GLOBAL_DATA_PTR \
-gd_t *gd
-#endif
#endif /* __ASM_GBL_DATA_H */
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index aa8188e51a..6eb518063b 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -33,6 +33,7 @@ enum {
X86_GDT_ENTRY_UNUSED,
X86_GDT_ENTRY_32BIT_CS,
X86_GDT_ENTRY_32BIT_DS,
+ X86_GDT_ENTRY_32BIT_FS,
X86_GDT_ENTRY_16BIT_CS,
X86_GDT_ENTRY_16BIT_DS,
X86_GDT_NUM_ENTRIES
diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h
index c3d2277834..5540d51769 100644
--- a/arch/x86/include/asm/u-boot-x86.h
+++ b/arch/x86/include/asm/u-boot-x86.h
@@ -37,6 +37,8 @@ int x86_cpu_init_r(void);
int cpu_init_r(void);
int x86_cpu_init_f(void);
int cpu_init_f(void);
+void init_gd(gd_t *id, u64 *gdt_addr);
+void setup_gdt(gd_t *id, u64 *gdt_addr);
/* cpu/.../timer.c */
void timer_isr(void *);
OpenPOWER on IntegriCloud