aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/efi.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/kernel/efi.c')
-rw-r--r--arch/ia64/kernel/efi.c502
1 files changed, 272 insertions, 230 deletions
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 242d79341120..919070a9aed7 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * Extensible Firmware Interface 2 * Extensible Firmware Interface
3 * 3 *
4 * Based on Extensible Firmware Interface Specification version 0.9 April 30, 1999 4 * Based on Extensible Firmware Interface Specification version 0.9
5 * April 30, 1999
5 * 6 *
6 * Copyright (C) 1999 VA Linux Systems 7 * Copyright (C) 1999 VA Linux Systems
7 * Copyright (C) 1999 Walt Drummond <drummond@valinux.com> 8 * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
@@ -48,145 +49,157 @@ static unsigned long mem_limit = ~0UL, max_addr = ~0UL, min_addr = 0UL;
48 49
49#define efi_call_virt(f, args...) (*(f))(args) 50#define efi_call_virt(f, args...) (*(f))(args)
50 51
51#define STUB_GET_TIME(prefix, adjust_arg) \ 52#define STUB_GET_TIME(prefix, adjust_arg) \
52static efi_status_t \ 53static efi_status_t \
53prefix##_get_time (efi_time_t *tm, efi_time_cap_t *tc) \ 54prefix##_get_time (efi_time_t *tm, efi_time_cap_t *tc) \
54{ \ 55{ \
55 struct ia64_fpreg fr[6]; \ 56 struct ia64_fpreg fr[6]; \
56 efi_time_cap_t *atc = NULL; \ 57 efi_time_cap_t *atc = NULL; \
57 efi_status_t ret; \ 58 efi_status_t ret; \
58 \ 59 \
59 if (tc) \ 60 if (tc) \
60 atc = adjust_arg(tc); \ 61 atc = adjust_arg(tc); \
61 ia64_save_scratch_fpregs(fr); \ 62 ia64_save_scratch_fpregs(fr); \
62 ret = efi_call_##prefix((efi_get_time_t *) __va(runtime->get_time), adjust_arg(tm), atc); \ 63 ret = efi_call_##prefix((efi_get_time_t *) __va(runtime->get_time), \
63 ia64_load_scratch_fpregs(fr); \ 64 adjust_arg(tm), atc); \
64 return ret; \ 65 ia64_load_scratch_fpregs(fr); \
66 return ret; \
65} 67}
66 68
67#define STUB_SET_TIME(prefix, adjust_arg) \ 69#define STUB_SET_TIME(prefix, adjust_arg) \
68static efi_status_t \ 70static efi_status_t \
69prefix##_set_time (efi_time_t *tm) \ 71prefix##_set_time (efi_time_t *tm) \
70{ \ 72{ \
71 struct ia64_fpreg fr[6]; \ 73 struct ia64_fpreg fr[6]; \
72 efi_status_t ret; \ 74 efi_status_t ret; \
73 \ 75 \
74 ia64_save_scratch_fpregs(fr); \ 76 ia64_save_scratch_fpregs(fr); \
75 ret = efi_call_##prefix((efi_set_time_t *) __va(runtime->set_time), adjust_arg(tm)); \ 77 ret = efi_call_##prefix((efi_set_time_t *) __va(runtime->set_time), \
76 ia64_load_scratch_fpregs(fr); \ 78 adjust_arg(tm)); \
77 return ret; \ 79 ia64_load_scratch_fpregs(fr); \
80 return ret; \
78} 81}
79 82
80#define STUB_GET_WAKEUP_TIME(prefix, adjust_arg) \ 83#define STUB_GET_WAKEUP_TIME(prefix, adjust_arg) \
81static efi_status_t \ 84static efi_status_t \
82prefix##_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, efi_time_t *tm) \ 85prefix##_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, \
83{ \ 86 efi_time_t *tm) \
84 struct ia64_fpreg fr[6]; \ 87{ \
85 efi_status_t ret; \ 88 struct ia64_fpreg fr[6]; \
86 \ 89 efi_status_t ret; \
87 ia64_save_scratch_fpregs(fr); \ 90 \
88 ret = efi_call_##prefix((efi_get_wakeup_time_t *) __va(runtime->get_wakeup_time), \ 91 ia64_save_scratch_fpregs(fr); \
89 adjust_arg(enabled), adjust_arg(pending), adjust_arg(tm)); \ 92 ret = efi_call_##prefix( \
90 ia64_load_scratch_fpregs(fr); \ 93 (efi_get_wakeup_time_t *) __va(runtime->get_wakeup_time), \
91 return ret; \ 94 adjust_arg(enabled), adjust_arg(pending), adjust_arg(tm)); \
95 ia64_load_scratch_fpregs(fr); \
96 return ret; \
92} 97}
93 98
94#define STUB_SET_WAKEUP_TIME(prefix, adjust_arg) \ 99#define STUB_SET_WAKEUP_TIME(prefix, adjust_arg) \
95static efi_status_t \ 100static efi_status_t \
96prefix##_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm) \ 101prefix##_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm) \
97{ \ 102{ \
98 struct ia64_fpreg fr[6]; \ 103 struct ia64_fpreg fr[6]; \
99 efi_time_t *atm = NULL; \ 104 efi_time_t *atm = NULL; \
100 efi_status_t ret; \ 105 efi_status_t ret; \
101 \ 106 \
102 if (tm) \ 107 if (tm) \
103 atm = adjust_arg(tm); \ 108 atm = adjust_arg(tm); \
104 ia64_save_scratch_fpregs(fr); \ 109 ia64_save_scratch_fpregs(fr); \
105 ret = efi_call_##prefix((efi_set_wakeup_time_t *) __va(runtime->set_wakeup_time), \ 110 ret = efi_call_##prefix( \
106 enabled, atm); \ 111 (efi_set_wakeup_time_t *) __va(runtime->set_wakeup_time), \
107 ia64_load_scratch_fpregs(fr); \ 112 enabled, atm); \
108 return ret; \ 113 ia64_load_scratch_fpregs(fr); \
114 return ret; \
109} 115}
110 116
111#define STUB_GET_VARIABLE(prefix, adjust_arg) \ 117#define STUB_GET_VARIABLE(prefix, adjust_arg) \
112static efi_status_t \ 118static efi_status_t \
113prefix##_get_variable (efi_char16_t *name, efi_guid_t *vendor, u32 *attr, \ 119prefix##_get_variable (efi_char16_t *name, efi_guid_t *vendor, u32 *attr, \
114 unsigned long *data_size, void *data) \ 120 unsigned long *data_size, void *data) \
115{ \ 121{ \
116 struct ia64_fpreg fr[6]; \ 122 struct ia64_fpreg fr[6]; \
117 u32 *aattr = NULL; \ 123 u32 *aattr = NULL; \
118 efi_status_t ret; \ 124 efi_status_t ret; \
119 \ 125 \
120 if (attr) \ 126 if (attr) \
121 aattr = adjust_arg(attr); \ 127 aattr = adjust_arg(attr); \
122 ia64_save_scratch_fpregs(fr); \ 128 ia64_save_scratch_fpregs(fr); \
123 ret = efi_call_##prefix((efi_get_variable_t *) __va(runtime->get_variable), \ 129 ret = efi_call_##prefix( \
124 adjust_arg(name), adjust_arg(vendor), aattr, \ 130 (efi_get_variable_t *) __va(runtime->get_variable), \
125 adjust_arg(data_size), adjust_arg(data)); \ 131 adjust_arg(name), adjust_arg(vendor), aattr, \
126 ia64_load_scratch_fpregs(fr); \ 132 adjust_arg(data_size), adjust_arg(data)); \
127 return ret; \ 133 ia64_load_scratch_fpregs(fr); \
134 return ret; \
128} 135}
129 136
130#define STUB_GET_NEXT_VARIABLE(prefix, adjust_arg) \ 137#define STUB_GET_NEXT_VARIABLE(prefix, adjust_arg) \
131static efi_status_t \ 138static efi_status_t \
132prefix##_get_next_variable (unsigned long *name_size, efi_char16_t *name, efi_guid_t *vendor) \ 139prefix##_get_next_variable (unsigned long *name_size, efi_char16_t *name, \
133{ \ 140 efi_guid_t *vendor) \
134 struct ia64_fpreg fr[6]; \ 141{ \
135 efi_status_t ret; \ 142 struct ia64_fpreg fr[6]; \
136 \ 143 efi_status_t ret; \
137 ia64_save_scratch_fpregs(fr); \ 144 \
138 ret = efi_call_##prefix((efi_get_next_variable_t *) __va(runtime->get_next_variable), \ 145 ia64_save_scratch_fpregs(fr); \
139 adjust_arg(name_size), adjust_arg(name), adjust_arg(vendor)); \ 146 ret = efi_call_##prefix( \
140 ia64_load_scratch_fpregs(fr); \ 147 (efi_get_next_variable_t *) __va(runtime->get_next_variable), \
141 return ret; \ 148 adjust_arg(name_size), adjust_arg(name), adjust_arg(vendor)); \
149 ia64_load_scratch_fpregs(fr); \
150 return ret; \
142} 151}
143 152
144#define STUB_SET_VARIABLE(prefix, adjust_arg) \ 153#define STUB_SET_VARIABLE(prefix, adjust_arg) \
145static efi_status_t \ 154static efi_status_t \
146prefix##_set_variable (efi_char16_t *name, efi_guid_t *vendor, unsigned long attr, \ 155prefix##_set_variable (efi_char16_t *name, efi_guid_t *vendor, \
147 unsigned long data_size, void *data) \ 156 unsigned long attr, unsigned long data_size, \
148{ \ 157 void *data) \
149 struct ia64_fpreg fr[6]; \ 158{ \
150 efi_status_t ret; \ 159 struct ia64_fpreg fr[6]; \
151 \ 160 efi_status_t ret; \
152 ia64_save_scratch_fpregs(fr); \ 161 \
153 ret = efi_call_##prefix((efi_set_variable_t *) __va(runtime->set_variable), \ 162 ia64_save_scratch_fpregs(fr); \
154 adjust_arg(name), adjust_arg(vendor), attr, data_size, \ 163 ret = efi_call_##prefix( \
155 adjust_arg(data)); \ 164 (efi_set_variable_t *) __va(runtime->set_variable), \
156 ia64_load_scratch_fpregs(fr); \ 165 adjust_arg(name), adjust_arg(vendor), attr, data_size, \
157 return ret; \ 166 adjust_arg(data)); \
167 ia64_load_scratch_fpregs(fr); \
168 return ret; \
158} 169}
159 170
160#define STUB_GET_NEXT_HIGH_MONO_COUNT(prefix, adjust_arg) \ 171#define STUB_GET_NEXT_HIGH_MONO_COUNT(prefix, adjust_arg) \
161static efi_status_t \ 172static efi_status_t \
162prefix##_get_next_high_mono_count (u32 *count) \ 173prefix##_get_next_high_mono_count (u32 *count) \
163{ \ 174{ \
164 struct ia64_fpreg fr[6]; \ 175 struct ia64_fpreg fr[6]; \
165 efi_status_t ret; \ 176 efi_status_t ret; \
166 \ 177 \
167 ia64_save_scratch_fpregs(fr); \ 178 ia64_save_scratch_fpregs(fr); \
168 ret = efi_call_##prefix((efi_get_next_high_mono_count_t *) \ 179 ret = efi_call_##prefix((efi_get_next_high_mono_count_t *) \
169 __va(runtime->get_next_high_mono_count), adjust_arg(count)); \ 180 __va(runtime->get_next_high_mono_count), \
170 ia64_load_scratch_fpregs(fr); \ 181 adjust_arg(count)); \
171 return ret; \ 182 ia64_load_scratch_fpregs(fr); \
183 return ret; \
172} 184}
173 185
174#define STUB_RESET_SYSTEM(prefix, adjust_arg) \ 186#define STUB_RESET_SYSTEM(prefix, adjust_arg) \
175static void \ 187static void \
176prefix##_reset_system (int reset_type, efi_status_t status, \ 188prefix##_reset_system (int reset_type, efi_status_t status, \
177 unsigned long data_size, efi_char16_t *data) \ 189 unsigned long data_size, efi_char16_t *data) \
178{ \ 190{ \
179 struct ia64_fpreg fr[6]; \ 191 struct ia64_fpreg fr[6]; \
180 efi_char16_t *adata = NULL; \ 192 efi_char16_t *adata = NULL; \
181 \ 193 \
182 if (data) \ 194 if (data) \
183 adata = adjust_arg(data); \ 195 adata = adjust_arg(data); \
184 \ 196 \
185 ia64_save_scratch_fpregs(fr); \ 197 ia64_save_scratch_fpregs(fr); \
186 efi_call_##prefix((efi_reset_system_t *) __va(runtime->reset_system), \ 198 efi_call_##prefix( \
187 reset_type, status, data_size, adata); \ 199 (efi_reset_system_t *) __va(runtime->reset_system), \
188 /* should not return, but just in case... */ \ 200 reset_type, status, data_size, adata); \
189 ia64_load_scratch_fpregs(fr); \ 201 /* should not return, but just in case... */ \
202 ia64_load_scratch_fpregs(fr); \
190} 203}
191 204
192#define phys_ptr(arg) ((__typeof__(arg)) ia64_tpa(arg)) 205#define phys_ptr(arg) ((__typeof__(arg)) ia64_tpa(arg))
@@ -223,7 +236,8 @@ efi_gettimeofday (struct timespec *ts)
223 return; 236 return;
224 } 237 }
225 238
226 ts->tv_sec = mktime(tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second); 239 ts->tv_sec = mktime(tm.year, tm.month, tm.day,
240 tm.hour, tm.minute, tm.second);
227 ts->tv_nsec = tm.nanosecond; 241 ts->tv_nsec = tm.nanosecond;
228} 242}
229 243
@@ -297,8 +311,8 @@ walk (efi_freemem_callback_t callback, void *arg, u64 attr)
297} 311}
298 312
299/* 313/*
300 * Walks the EFI memory map and calls CALLBACK once for each EFI memory descriptor that 314 * Walk the EFI memory map and call CALLBACK once for each EFI memory
301 * has memory that is available for OS use. 315 * descriptor that has memory that is available for OS use.
302 */ 316 */
303void 317void
304efi_memmap_walk (efi_freemem_callback_t callback, void *arg) 318efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
@@ -307,8 +321,8 @@ efi_memmap_walk (efi_freemem_callback_t callback, void *arg)
307} 321}
308 322
309/* 323/*
310 * Walks the EFI memory map and calls CALLBACK once for each EFI memory descriptor that 324 * Walk the EFI memory map and call CALLBACK once for each EFI memory
311 * has memory that is available for uncached allocator. 325 * descriptor that has memory that is available for uncached allocator.
312 */ 326 */
313void 327void
314efi_memmap_walk_uc (efi_freemem_callback_t callback, void *arg) 328efi_memmap_walk_uc (efi_freemem_callback_t callback, void *arg)
@@ -317,11 +331,10 @@ efi_memmap_walk_uc (efi_freemem_callback_t callback, void *arg)
317} 331}
318 332
319/* 333/*
320 * Look for the PAL_CODE region reported by EFI and maps it using an 334 * Look for the PAL_CODE region reported by EFI and map it using an
321 * ITR to enable safe PAL calls in virtual mode. See IA-64 Processor 335 * ITR to enable safe PAL calls in virtual mode. See IA-64 Processor
322 * Abstraction Layer chapter 11 in ADAG 336 * Abstraction Layer chapter 11 in ADAG
323 */ 337 */
324
325void * 338void *
326efi_get_pal_addr (void) 339efi_get_pal_addr (void)
327{ 340{
@@ -341,45 +354,47 @@ efi_get_pal_addr (void)
341 continue; 354 continue;
342 355
343 if (++pal_code_count > 1) { 356 if (++pal_code_count > 1) {
344 printk(KERN_ERR "Too many EFI Pal Code memory ranges, dropped @ %lx\n", 357 printk(KERN_ERR "Too many EFI Pal Code memory ranges, "
345 md->phys_addr); 358 "dropped @ %lx\n", md->phys_addr);
346 continue; 359 continue;
347 } 360 }
348 /* 361 /*
349 * The only ITLB entry in region 7 that is used is the one installed by 362 * The only ITLB entry in region 7 that is used is the one
350 * __start(). That entry covers a 64MB range. 363 * installed by __start(). That entry covers a 64MB range.
351 */ 364 */
352 mask = ~((1 << KERNEL_TR_PAGE_SHIFT) - 1); 365 mask = ~((1 << KERNEL_TR_PAGE_SHIFT) - 1);
353 vaddr = PAGE_OFFSET + md->phys_addr; 366 vaddr = PAGE_OFFSET + md->phys_addr;
354 367
355 /* 368 /*
356 * We must check that the PAL mapping won't overlap with the kernel 369 * We must check that the PAL mapping won't overlap with the
357 * mapping. 370 * kernel mapping.
358 * 371 *
359 * PAL code is guaranteed to be aligned on a power of 2 between 4k and 372 * PAL code is guaranteed to be aligned on a power of 2 between
360 * 256KB and that only one ITR is needed to map it. This implies that the 373 * 4k and 256KB and that only one ITR is needed to map it. This
361 * PAL code is always aligned on its size, i.e., the closest matching page 374 * implies that the PAL code is always aligned on its size,
362 * size supported by the TLB. Therefore PAL code is guaranteed never to 375 * i.e., the closest matching page size supported by the TLB.
363 * cross a 64MB unless it is bigger than 64MB (very unlikely!). So for 376 * Therefore PAL code is guaranteed never to cross a 64MB unless
364 * now the following test is enough to determine whether or not we need a 377 * it is bigger than 64MB (very unlikely!). So for now the
365 * dedicated ITR for the PAL code. 378 * following test is enough to determine whether or not we need
379 * a dedicated ITR for the PAL code.
366 */ 380 */
367 if ((vaddr & mask) == (KERNEL_START & mask)) { 381 if ((vaddr & mask) == (KERNEL_START & mask)) {
368 printk(KERN_INFO "%s: no need to install ITR for PAL code\n", 382 printk(KERN_INFO "%s: no need to install ITR for "
369 __FUNCTION__); 383 "PAL code\n", __FUNCTION__);
370 continue; 384 continue;
371 } 385 }
372 386
373 if (efi_md_size(md) > IA64_GRANULE_SIZE) 387 if (efi_md_size(md) > IA64_GRANULE_SIZE)
374 panic("Woah! PAL code size bigger than a granule!"); 388 panic("Whoa! PAL code size bigger than a granule!");
375 389
376#if EFI_DEBUG 390#if EFI_DEBUG
377 mask = ~((1 << IA64_GRANULE_SHIFT) - 1); 391 mask = ~((1 << IA64_GRANULE_SHIFT) - 1);
378 392
379 printk(KERN_INFO "CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n", 393 printk(KERN_INFO "CPU %d: mapping PAL code "
380 smp_processor_id(), md->phys_addr, 394 "[0x%lx-0x%lx) into [0x%lx-0x%lx)\n",
381 md->phys_addr + efi_md_size(md), 395 smp_processor_id(), md->phys_addr,
382 vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE); 396 md->phys_addr + efi_md_size(md),
397 vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE);
383#endif 398#endif
384 return __va(md->phys_addr); 399 return __va(md->phys_addr);
385 } 400 }
@@ -401,11 +416,11 @@ efi_map_pal_code (void)
401 * Cannot write to CRx with PSR.ic=1 416 * Cannot write to CRx with PSR.ic=1
402 */ 417 */
403 psr = ia64_clear_ic(); 418 psr = ia64_clear_ic();
404 ia64_itr(0x1, IA64_TR_PALCODE, GRANULEROUNDDOWN((unsigned long) pal_vaddr), 419 ia64_itr(0x1, IA64_TR_PALCODE,
420 GRANULEROUNDDOWN((unsigned long) pal_vaddr),
405 pte_val(pfn_pte(__pa(pal_vaddr) >> PAGE_SHIFT, PAGE_KERNEL)), 421 pte_val(pfn_pte(__pa(pal_vaddr) >> PAGE_SHIFT, PAGE_KERNEL)),
406 IA64_GRANULE_SHIFT); 422 IA64_GRANULE_SHIFT);
407 ia64_set_psr(psr); /* restore psr */ 423 ia64_set_psr(psr); /* restore psr */
408 ia64_srlz_i();
409} 424}
410 425
411void __init 426void __init
@@ -418,7 +433,10 @@ efi_init (void)
418 char *cp, vendor[100] = "unknown"; 433 char *cp, vendor[100] = "unknown";
419 int i; 434 int i;
420 435
421 /* it's too early to be able to use the standard kernel command line support... */ 436 /*
437 * It's too early to be able to use the standard kernel command line
438 * support...
439 */
422 for (cp = boot_command_line; *cp; ) { 440 for (cp = boot_command_line; *cp; ) {
423 if (memcmp(cp, "mem=", 4) == 0) { 441 if (memcmp(cp, "mem=", 4) == 0) {
424 mem_limit = memparse(cp + 4, &cp); 442 mem_limit = memparse(cp + 4, &cp);
@@ -434,9 +452,11 @@ efi_init (void)
434 } 452 }
435 } 453 }
436 if (min_addr != 0UL) 454 if (min_addr != 0UL)
437 printk(KERN_INFO "Ignoring memory below %luMB\n", min_addr >> 20); 455 printk(KERN_INFO "Ignoring memory below %luMB\n",
456 min_addr >> 20);
438 if (max_addr != ~0UL) 457 if (max_addr != ~0UL)
439 printk(KERN_INFO "Ignoring memory above %luMB\n", max_addr >> 20); 458 printk(KERN_INFO "Ignoring memory above %luMB\n",
459 max_addr >> 20);
440 460
441 efi.systab = __va(ia64_boot_param->efi_systab); 461 efi.systab = __va(ia64_boot_param->efi_systab);
442 462
@@ -444,9 +464,9 @@ efi_init (void)
444 * Verify the EFI Table 464 * Verify the EFI Table
445 */ 465 */
446 if (efi.systab == NULL) 466 if (efi.systab == NULL)
447 panic("Woah! Can't find EFI system table.\n"); 467 panic("Whoa! Can't find EFI system table.\n");
448 if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) 468 if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
449 panic("Woah! EFI system table signature incorrect\n"); 469 panic("Whoa! EFI system table signature incorrect\n");
450 if ((efi.systab->hdr.revision >> 16) == 0) 470 if ((efi.systab->hdr.revision >> 16) == 0)
451 printk(KERN_WARNING "Warning: EFI system table version " 471 printk(KERN_WARNING "Warning: EFI system table version "
452 "%d.%02d, expected 1.00 or greater\n", 472 "%d.%02d, expected 1.00 or greater\n",
@@ -464,7 +484,8 @@ efi_init (void)
464 } 484 }
465 485
466 printk(KERN_INFO "EFI v%u.%.02u by %s:", 486 printk(KERN_INFO "EFI v%u.%.02u by %s:",
467 efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff, vendor); 487 efi.systab->hdr.revision >> 16,
488 efi.systab->hdr.revision & 0xffff, vendor);
468 489
469 efi.mps = EFI_INVALID_TABLE_ADDR; 490 efi.mps = EFI_INVALID_TABLE_ADDR;
470 efi.acpi = EFI_INVALID_TABLE_ADDR; 491 efi.acpi = EFI_INVALID_TABLE_ADDR;
@@ -519,9 +540,12 @@ efi_init (void)
519 efi_memory_desc_t *md; 540 efi_memory_desc_t *md;
520 void *p; 541 void *p;
521 542
522 for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) { 543 for (i = 0, p = efi_map_start; p < efi_map_end;
544 ++i, p += efi_desc_size)
545 {
523 md = p; 546 md = p;
524 printk("mem%02u: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n", 547 printk("mem%02u: type=%u, attr=0x%lx, "
548 "range=[0x%016lx-0x%016lx) (%luMB)\n",
525 i, md->type, md->attribute, md->phys_addr, 549 i, md->type, md->attribute, md->phys_addr,
526 md->phys_addr + efi_md_size(md), 550 md->phys_addr + efi_md_size(md),
527 md->num_pages >> (20 - EFI_PAGE_SHIFT)); 551 md->num_pages >> (20 - EFI_PAGE_SHIFT));
@@ -549,8 +573,8 @@ efi_enter_virtual_mode (void)
549 md = p; 573 md = p;
550 if (md->attribute & EFI_MEMORY_RUNTIME) { 574 if (md->attribute & EFI_MEMORY_RUNTIME) {
551 /* 575 /*
552 * Some descriptors have multiple bits set, so the order of 576 * Some descriptors have multiple bits set, so the
553 * the tests is relevant. 577 * order of the tests is relevant.
554 */ 578 */
555 if (md->attribute & EFI_MEMORY_WB) { 579 if (md->attribute & EFI_MEMORY_WB) {
556 md->virt_addr = (u64) __va(md->phys_addr); 580 md->virt_addr = (u64) __va(md->phys_addr);
@@ -558,21 +582,26 @@ efi_enter_virtual_mode (void)
558 md->virt_addr = (u64) ioremap(md->phys_addr, 0); 582 md->virt_addr = (u64) ioremap(md->phys_addr, 0);
559 } else if (md->attribute & EFI_MEMORY_WC) { 583 } else if (md->attribute & EFI_MEMORY_WC) {
560#if 0 584#if 0
561 md->virt_addr = ia64_remap(md->phys_addr, (_PAGE_A | _PAGE_P 585 md->virt_addr = ia64_remap(md->phys_addr,
562 | _PAGE_D 586 (_PAGE_A |
563 | _PAGE_MA_WC 587 _PAGE_P |
564 | _PAGE_PL_0 588 _PAGE_D |
565 | _PAGE_AR_RW)); 589 _PAGE_MA_WC |
590 _PAGE_PL_0 |
591 _PAGE_AR_RW));
566#else 592#else
567 printk(KERN_INFO "EFI_MEMORY_WC mapping\n"); 593 printk(KERN_INFO "EFI_MEMORY_WC mapping\n");
568 md->virt_addr = (u64) ioremap(md->phys_addr, 0); 594 md->virt_addr = (u64) ioremap(md->phys_addr, 0);
569#endif 595#endif
570 } else if (md->attribute & EFI_MEMORY_WT) { 596 } else if (md->attribute & EFI_MEMORY_WT) {
571#if 0 597#if 0
572 md->virt_addr = ia64_remap(md->phys_addr, (_PAGE_A | _PAGE_P 598 md->virt_addr = ia64_remap(md->phys_addr,
573 | _PAGE_D | _PAGE_MA_WT 599 (_PAGE_A |
574 | _PAGE_PL_0 600 _PAGE_P |
575 | _PAGE_AR_RW)); 601 _PAGE_D |
602 _PAGE_MA_WT |
603 _PAGE_PL_0 |
604 _PAGE_AR_RW));
576#else 605#else
577 printk(KERN_INFO "EFI_MEMORY_WT mapping\n"); 606 printk(KERN_INFO "EFI_MEMORY_WT mapping\n");
578 md->virt_addr = (u64) ioremap(md->phys_addr, 0); 607 md->virt_addr = (u64) ioremap(md->phys_addr, 0);
@@ -583,16 +612,18 @@ efi_enter_virtual_mode (void)
583 612
584 status = efi_call_phys(__va(runtime->set_virtual_address_map), 613 status = efi_call_phys(__va(runtime->set_virtual_address_map),
585 ia64_boot_param->efi_memmap_size, 614 ia64_boot_param->efi_memmap_size,
586 efi_desc_size, ia64_boot_param->efi_memdesc_version, 615 efi_desc_size,
616 ia64_boot_param->efi_memdesc_version,
587 ia64_boot_param->efi_memmap); 617 ia64_boot_param->efi_memmap);
588 if (status != EFI_SUCCESS) { 618 if (status != EFI_SUCCESS) {
589 printk(KERN_WARNING "warning: unable to switch EFI into virtual mode " 619 printk(KERN_WARNING "warning: unable to switch EFI into "
590 "(status=%lu)\n", status); 620 "virtual mode (status=%lu)\n", status);
591 return; 621 return;
592 } 622 }
593 623
594 /* 624 /*
595 * Now that EFI is in virtual mode, we call the EFI functions more efficiently: 625 * Now that EFI is in virtual mode, we call the EFI functions more
626 * efficiently:
596 */ 627 */
597 efi.get_time = virt_get_time; 628 efi.get_time = virt_get_time;
598 efi.set_time = virt_set_time; 629 efi.set_time = virt_set_time;
@@ -606,8 +637,8 @@ efi_enter_virtual_mode (void)
606} 637}
607 638
608/* 639/*
609 * Walk the EFI memory map looking for the I/O port range. There can only be one entry of 640 * Walk the EFI memory map looking for the I/O port range. There can only be
610 * this type, other I/O port ranges should be described via ACPI. 641 * one entry of this type, other I/O port ranges should be described via ACPI.
611 */ 642 */
612u64 643u64
613efi_get_iobase (void) 644efi_get_iobase (void)
@@ -678,7 +709,6 @@ efi_memmap_intersects (unsigned long phys_addr, unsigned long size)
678 709
679 for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { 710 for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
680 md = p; 711 md = p;
681
682 if (md->phys_addr < end && efi_md_end(md) > phys_addr) 712 if (md->phys_addr < end && efi_md_end(md) > phys_addr)
683 return 1; 713 return 1;
684 } 714 }
@@ -731,7 +761,7 @@ efi_mem_attribute (unsigned long phys_addr, unsigned long size)
731 if (!md || (md->attribute & ~EFI_MEMORY_RUNTIME) != attr) 761 if (!md || (md->attribute & ~EFI_MEMORY_RUNTIME) != attr)
732 return 0; 762 return 0;
733 } while (md); 763 } while (md);
734 return 0; 764 return 0; /* never reached */
735} 765}
736 766
737u64 767u64
@@ -767,7 +797,7 @@ kern_mem_attribute (unsigned long phys_addr, unsigned long size)
767 if (!md || md->attribute != attr) 797 if (!md || md->attribute != attr)
768 return 0; 798 return 0;
769 } while (md); 799 } while (md);
770 return 0; 800 return 0; /* never reached */
771} 801}
772EXPORT_SYMBOL(kern_mem_attribute); 802EXPORT_SYMBOL(kern_mem_attribute);
773 803
@@ -883,7 +913,7 @@ efi_uart_console_only(void)
883 return 1; 913 return 1;
884 uart = 0; 914 uart = 0;
885 } 915 }
886 hdr = (struct efi_generic_dev_path *) ((u8 *) hdr + hdr->length); 916 hdr = (struct efi_generic_dev_path *)((u8 *) hdr + hdr->length);
887 } 917 }
888 printk(KERN_ERR "Malformed %s value\n", name); 918 printk(KERN_ERR "Malformed %s value\n", name);
889 return 0; 919 return 0;
@@ -921,10 +951,12 @@ find_memmap_space (void)
921 if (!efi_wb(md)) { 951 if (!efi_wb(md)) {
922 continue; 952 continue;
923 } 953 }
924 if (pmd == NULL || !efi_wb(pmd) || efi_md_end(pmd) != md->phys_addr) { 954 if (pmd == NULL || !efi_wb(pmd) ||
955 efi_md_end(pmd) != md->phys_addr) {
925 contig_low = GRANULEROUNDUP(md->phys_addr); 956 contig_low = GRANULEROUNDUP(md->phys_addr);
926 contig_high = efi_md_end(md); 957 contig_high = efi_md_end(md);
927 for (q = p + efi_desc_size; q < efi_map_end; q += efi_desc_size) { 958 for (q = p + efi_desc_size; q < efi_map_end;
959 q += efi_desc_size) {
928 check_md = q; 960 check_md = q;
929 if (!efi_wb(check_md)) 961 if (!efi_wb(check_md))
930 break; 962 break;
@@ -988,8 +1020,9 @@ efi_memmap_init(unsigned long *s, unsigned long *e)
988 for (p = efi_map_start; p < efi_map_end; pmd = md, p += efi_desc_size) { 1020 for (p = efi_map_start; p < efi_map_end; pmd = md, p += efi_desc_size) {
989 md = p; 1021 md = p;
990 if (!efi_wb(md)) { 1022 if (!efi_wb(md)) {
991 if (efi_uc(md) && (md->type == EFI_CONVENTIONAL_MEMORY || 1023 if (efi_uc(md) &&
992 md->type == EFI_BOOT_SERVICES_DATA)) { 1024 (md->type == EFI_CONVENTIONAL_MEMORY ||
1025 md->type == EFI_BOOT_SERVICES_DATA)) {
993 k->attribute = EFI_MEMORY_UC; 1026 k->attribute = EFI_MEMORY_UC;
994 k->start = md->phys_addr; 1027 k->start = md->phys_addr;
995 k->num_pages = md->num_pages; 1028 k->num_pages = md->num_pages;
@@ -997,10 +1030,12 @@ efi_memmap_init(unsigned long *s, unsigned long *e)
997 } 1030 }
998 continue; 1031 continue;
999 } 1032 }
1000 if (pmd == NULL || !efi_wb(pmd) || efi_md_end(pmd) != md->phys_addr) { 1033 if (pmd == NULL || !efi_wb(pmd) ||
1034 efi_md_end(pmd) != md->phys_addr) {
1001 contig_low = GRANULEROUNDUP(md->phys_addr); 1035 contig_low = GRANULEROUNDUP(md->phys_addr);
1002 contig_high = efi_md_end(md); 1036 contig_high = efi_md_end(md);
1003 for (q = p + efi_desc_size; q < efi_map_end; q += efi_desc_size) { 1037 for (q = p + efi_desc_size; q < efi_map_end;
1038 q += efi_desc_size) {
1004 check_md = q; 1039 check_md = q;
1005 if (!efi_wb(check_md)) 1040 if (!efi_wb(check_md))
1006 break; 1041 break;
@@ -1025,13 +1060,17 @@ efi_memmap_init(unsigned long *s, unsigned long *e)
1025 if (md->phys_addr < contig_low) { 1060 if (md->phys_addr < contig_low) {
1026 lim = min(efi_md_end(md), contig_low); 1061 lim = min(efi_md_end(md), contig_low);
1027 if (efi_uc(md)) { 1062 if (efi_uc(md)) {
1028 if (k > kern_memmap && (k-1)->attribute == EFI_MEMORY_UC && 1063 if (k > kern_memmap &&
1064 (k-1)->attribute == EFI_MEMORY_UC &&
1029 kmd_end(k-1) == md->phys_addr) { 1065 kmd_end(k-1) == md->phys_addr) {
1030 (k-1)->num_pages += (lim - md->phys_addr) >> EFI_PAGE_SHIFT; 1066 (k-1)->num_pages +=
1067 (lim - md->phys_addr)
1068 >> EFI_PAGE_SHIFT;
1031 } else { 1069 } else {
1032 k->attribute = EFI_MEMORY_UC; 1070 k->attribute = EFI_MEMORY_UC;
1033 k->start = md->phys_addr; 1071 k->start = md->phys_addr;
1034 k->num_pages = (lim - md->phys_addr) >> EFI_PAGE_SHIFT; 1072 k->num_pages = (lim - md->phys_addr)
1073 >> EFI_PAGE_SHIFT;
1035 k++; 1074 k++;
1036 } 1075 }
1037 } 1076 }
@@ -1049,7 +1088,8 @@ efi_memmap_init(unsigned long *s, unsigned long *e)
1049 } else { 1088 } else {
1050 k->attribute = EFI_MEMORY_UC; 1089 k->attribute = EFI_MEMORY_UC;
1051 k->start = lim; 1090 k->start = lim;
1052 k->num_pages = (efi_md_end(md) - lim) >> EFI_PAGE_SHIFT; 1091 k->num_pages = (efi_md_end(md) - lim)
1092 >> EFI_PAGE_SHIFT;
1053 k++; 1093 k++;
1054 } 1094 }
1055 } 1095 }
@@ -1151,8 +1191,10 @@ efi_initialize_iomem_resources(struct resource *code_resource,
1151 break; 1191 break;
1152 } 1192 }
1153 1193
1154 if ((res = kzalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) { 1194 if ((res = kzalloc(sizeof(struct resource),
1155 printk(KERN_ERR "failed to alocate resource for iomem\n"); 1195 GFP_KERNEL)) == NULL) {
1196 printk(KERN_ERR
1197 "failed to allocate resource for iomem\n");
1156 return; 1198 return;
1157 } 1199 }
1158 1200
@@ -1187,44 +1229,44 @@ efi_initialize_iomem_resources(struct resource *code_resource,
1187 rsvd_regions are sorted 1229 rsvd_regions are sorted
1188 */ 1230 */
1189unsigned long __init 1231unsigned long __init
1190kdump_find_rsvd_region (unsigned long size, 1232kdump_find_rsvd_region (unsigned long size, struct rsvd_region *r, int n)
1191 struct rsvd_region *r, int n)
1192{ 1233{
1193 int i; 1234 int i;
1194 u64 start, end; 1235 u64 start, end;
1195 u64 alignment = 1UL << _PAGE_SIZE_64M; 1236 u64 alignment = 1UL << _PAGE_SIZE_64M;
1196 void *efi_map_start, *efi_map_end, *p; 1237 void *efi_map_start, *efi_map_end, *p;
1197 efi_memory_desc_t *md; 1238 efi_memory_desc_t *md;
1198 u64 efi_desc_size; 1239 u64 efi_desc_size;
1199 1240
1200 efi_map_start = __va(ia64_boot_param->efi_memmap); 1241 efi_map_start = __va(ia64_boot_param->efi_memmap);
1201 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; 1242 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
1202 efi_desc_size = ia64_boot_param->efi_memdesc_size; 1243 efi_desc_size = ia64_boot_param->efi_memdesc_size;
1203 1244
1204 for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { 1245 for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
1205 md = p; 1246 md = p;
1206 if (!efi_wb(md)) 1247 if (!efi_wb(md))
1207 continue; 1248 continue;
1208 start = ALIGN(md->phys_addr, alignment); 1249 start = ALIGN(md->phys_addr, alignment);
1209 end = efi_md_end(md); 1250 end = efi_md_end(md);
1210 for (i = 0; i < n; i++) { 1251 for (i = 0; i < n; i++) {
1211 if (__pa(r[i].start) >= start && __pa(r[i].end) < end) { 1252 if (__pa(r[i].start) >= start && __pa(r[i].end) < end) {
1212 if (__pa(r[i].start) > start + size) 1253 if (__pa(r[i].start) > start + size)
1213 return start; 1254 return start;
1214 start = ALIGN(__pa(r[i].end), alignment); 1255 start = ALIGN(__pa(r[i].end), alignment);
1215 if (i < n-1 && __pa(r[i+1].start) < start + size) 1256 if (i < n-1 &&
1216 continue; 1257 __pa(r[i+1].start) < start + size)
1217 else 1258 continue;
1218 break; 1259 else
1260 break;
1261 }
1219 } 1262 }
1220 } 1263 if (end > start + size)
1221 if (end > start + size) 1264 return start;
1222 return start; 1265 }
1223 } 1266
1224 1267 printk(KERN_WARNING
1225 printk(KERN_WARNING "Cannot reserve 0x%lx byte of memory for crashdump\n", 1268 "Cannot reserve 0x%lx byte of memory for crashdump\n", size);
1226 size); 1269 return ~0UL;
1227 return ~0UL;
1228} 1270}
1229#endif 1271#endif
1230 1272