From 303418cc97c0922cdbbc328e6d9111bd9a84d1c7 Mon Sep 17 00:00:00 2001 From: Graeme Russ Date: Tue, 8 Nov 2011 02:33:21 +0000 Subject: 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 --- arch/x86/cpu/interrupts.c | 2 +- arch/x86/lib/board.c | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c index e0075110f..e0958eb67 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 b4451795c..244a02163 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; -- cgit v1.2.3