diff options
| author | Graeme Russ <graeme.russ@gmail.com> | 2011-11-08 02:33:21 +0000 | 
|---|---|---|
| committer | Graeme Russ <graeme.russ@gmail.com> | 2011-11-29 21:10:01 +1100 | 
| commit | 303418cc97c0922cdbbc328e6d9111bd9a84d1c7 (patch) | |
| tree | e7642dad72be366ffa78e076fa91481f577f1767 | |
| parent | a76fc70ee190416e0c161efebdb955a5fac904d3 (diff) | |
| download | olio-uboot-2014.01-303418cc97c0922cdbbc328e6d9111bd9a84d1c7.tar.xz olio-uboot-2014.01-303418cc97c0922cdbbc328e6d9111bd9a84d1c7.zip | |
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.c | 2 | ||||
| -rw-r--r-- | 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; |