summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGraeme Russ <graeme.russ@gmail.com>2011-11-08 02:33:21 +0000
committerGraeme Russ <graeme.russ@gmail.com>2011-11-29 21:10:01 +1100
commit303418cc97c0922cdbbc328e6d9111bd9a84d1c7 (patch)
treee7642dad72be366ffa78e076fa91481f577f1767
parenta76fc70ee190416e0c161efebdb955a5fac904d3 (diff)
downloadu-boot-imx-303418cc97c0922cdbbc328e6d9111bd9a84d1c7.zip
u-boot-imx-303418cc97c0922cdbbc328e6d9111bd9a84d1c7.tar.gz
u-boot-imx-303418cc97c0922cdbbc328e6d9111bd9a84d1c7.tar.bz2
x86: Ensure IDT and GDT remain 16-byte aligned post relocation
Some CPUs have strict alignment requirements for these tables Signed-off-by: Graeme Russ <graeme.russ@gmail.com>
-rw-r--r--arch/x86/cpu/interrupts.c2
-rw-r--r--arch/x86/lib/board.c17
2 files changed, 13 insertions, 6 deletions
diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c
index e007511..e0958eb 100644
--- a/arch/x86/cpu/interrupts.c
+++ b/arch/x86/cpu/interrupts.c
@@ -174,7 +174,7 @@ struct desc_ptr {
unsigned short segment;
} __packed;
-struct idt_entry idt[256];
+struct idt_entry idt[256] __attribute__((aligned(16)));
struct desc_ptr idt_ptr;
diff --git a/arch/x86/lib/board.c b/arch/x86/lib/board.c
index b445179..244a021 100644
--- a/arch/x86/lib/board.c
+++ b/arch/x86/lib/board.c
@@ -161,19 +161,26 @@ gd_t *gd;
static int calculate_relocation_address(void)
{
- void *text_start = &__text_start;
- void *bss_end = &__bss_end;
- void *dest_addr;
+ ulong text_start = (ulong)&__text_start;
+ ulong bss_end = (ulong)&__bss_end;
+ ulong dest_addr;
ulong rel_offset;
/* Calculate destination RAM Address and relocation offset */
- dest_addr = (void *)gd->ram_size;
+ dest_addr = gd->ram_size;
dest_addr -= CONFIG_SYS_STACK_SIZE;
dest_addr -= (bss_end - text_start);
+
+ /*
+ * Round destination address down to 16-byte boundary to keep
+ * IDT and GDT 16-byte aligned
+ */
+ dest_addr &= ~15;
+
rel_offset = dest_addr - text_start;
gd->start_addr_sp = gd->ram_size;
- gd->relocaddr = (ulong)dest_addr;
+ gd->relocaddr = dest_addr;
gd->reloc_off = rel_offset;
return 0;