diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2013-12-18 15:52:13 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2013-12-18 16:07:53 -0800 |
commit | 7306006f103567fcf595d23dd741da0b8642f4c5 (patch) | |
tree | 779b11f355093d7982d01d8ba383eb74f0bf25ad /arch/x86/realmode | |
parent | d8af4ce490e92adfa123ae79899332bd829903e7 (diff) | |
download | lwn-7306006f103567fcf595d23dd741da0b8642f4c5.tar.gz lwn-7306006f103567fcf595d23dd741da0b8642f4c5.zip |
x86, realmode: Pointer walk cleanups, pull out invariant use of __pa()
The pointer arithmetic in this function was really bizarre, where in
fact all we really wanted was a simple pointer array walk. Use the
much more idiomatic construction for that (*ptr++).
Factor an invariant use of __pa() out of the relocation loop. At
least on 64 bits it seems gcc isn't capable of doing that
automatically.
Change the scope of a couple of variables to make it extra obvious
that they are extremely local temp variables.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Link: http://lkml.kernel.org/n/tip-rd908t9c8kvcojdabtmm94mb@git.kernel.org
Diffstat (limited to 'arch/x86/realmode')
-rw-r--r-- | arch/x86/realmode/init.c | 26 |
1 files changed, 12 insertions, 14 deletions
diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c index a44f457e70a1..bad628a620c4 100644 --- a/arch/x86/realmode/init.c +++ b/arch/x86/realmode/init.c @@ -29,12 +29,10 @@ void __init reserve_real_mode(void) void __init setup_real_mode(void) { u16 real_mode_seg; - u32 *rel; + const u32 *rel; u32 count; - u32 *ptr; - u16 *seg; - int i; unsigned char *base; + unsigned long phys_base; struct trampoline_header *trampoline_header; size_t size = PAGE_ALIGN(real_mode_blob_end - real_mode_blob); #ifdef CONFIG_X86_64 @@ -46,23 +44,23 @@ void __init setup_real_mode(void) memcpy(base, real_mode_blob, size); - real_mode_seg = __pa(base) >> 4; + phys_base = __pa(base); + real_mode_seg = phys_base >> 4; + rel = (u32 *) real_mode_relocs; /* 16-bit segment relocations. */ - count = rel[0]; - rel = &rel[1]; - for (i = 0; i < count; i++) { - seg = (u16 *) (base + rel[i]); + count = *rel++; + while (count--) { + u16 *seg = (u16 *) (base + *rel++); *seg = real_mode_seg; } /* 32-bit linear relocations. */ - count = rel[i]; - rel = &rel[i + 1]; - for (i = 0; i < count; i++) { - ptr = (u32 *) (base + rel[i]); - *ptr += __pa(base); + count = *rel++; + while (count--) { + u32 *ptr = (u32 *) (base + *rel++); + *ptr += phys_base; } /* Must be perfomed *after* relocation. */ |