aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2013-12-18 18:52:13 -0500
committerH. Peter Anvin <hpa@linux.intel.com>2013-12-18 19:07:53 -0500
commit7306006f103567fcf595d23dd741da0b8642f4c5 (patch)
tree779b11f355093d7982d01d8ba383eb74f0bf25ad
parentd8af4ce490e92adfa123ae79899332bd829903e7 (diff)
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
-rw-r--r--arch/x86/realmode/init.c26
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)
29void __init setup_real_mode(void) 29void __init setup_real_mode(void)
30{ 30{
31 u16 real_mode_seg; 31 u16 real_mode_seg;
32 u32 *rel; 32 const u32 *rel;
33 u32 count; 33 u32 count;
34 u32 *ptr;
35 u16 *seg;
36 int i;
37 unsigned char *base; 34 unsigned char *base;
35 unsigned long phys_base;
38 struct trampoline_header *trampoline_header; 36 struct trampoline_header *trampoline_header;
39 size_t size = PAGE_ALIGN(real_mode_blob_end - real_mode_blob); 37 size_t size = PAGE_ALIGN(real_mode_blob_end - real_mode_blob);
40#ifdef CONFIG_X86_64 38#ifdef CONFIG_X86_64
@@ -46,23 +44,23 @@ void __init setup_real_mode(void)
46 44
47 memcpy(base, real_mode_blob, size); 45 memcpy(base, real_mode_blob, size);
48 46
49 real_mode_seg = __pa(base) >> 4; 47 phys_base = __pa(base);
48 real_mode_seg = phys_base >> 4;
49
50 rel = (u32 *) real_mode_relocs; 50 rel = (u32 *) real_mode_relocs;
51 51
52 /* 16-bit segment relocations. */ 52 /* 16-bit segment relocations. */
53 count = rel[0]; 53 count = *rel++;
54 rel = &rel[1]; 54 while (count--) {
55 for (i = 0; i < count; i++) { 55 u16 *seg = (u16 *) (base + *rel++);
56 seg = (u16 *) (base + rel[i]);
57 *seg = real_mode_seg; 56 *seg = real_mode_seg;
58 } 57 }
59 58
60 /* 32-bit linear relocations. */ 59 /* 32-bit linear relocations. */
61 count = rel[i]; 60 count = *rel++;
62 rel = &rel[i + 1]; 61 while (count--) {
63 for (i = 0; i < count; i++) { 62 u32 *ptr = (u32 *) (base + *rel++);
64 ptr = (u32 *) (base + rel[i]); 63 *ptr += phys_base;
65 *ptr += __pa(base);
66 } 64 }
67 65
68 /* Must be perfomed *after* relocation. */ 66 /* Must be perfomed *after* relocation. */