aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/kernel/setup.c')
-rw-r--r--arch/ia64/kernel/setup.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 1f5c26dbe705..e256b114bf4e 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -244,28 +244,31 @@ find_initrd (void)
244static void __init 244static void __init
245io_port_init (void) 245io_port_init (void)
246{ 246{
247 extern unsigned long ia64_iobase;
248 unsigned long phys_iobase; 247 unsigned long phys_iobase;
249 248
250 /* 249 /*
251 * Set `iobase' to the appropriate address in region 6 (uncached access range). 250 * Set `iobase' based on the EFI memory map or, failing that, the
251 * value firmware left in ar.k0.
252 * 252 *
253 * The EFI memory map is the "preferred" location to get the I/O port space base, 253 * Note that in ia32 mode, IN/OUT instructions use ar.k0 to compute
254 * rather the relying on AR.KR0. This should become more clear in future SAL 254 * the port's virtual address, so ia32_load_state() loads it with a
255 * specs. We'll fall back to getting it out of AR.KR0 if no appropriate entry is 255 * user virtual address. But in ia64 mode, glibc uses the
256 * found in the memory map. 256 * *physical* address in ar.k0 to mmap the appropriate area from
257 * /dev/mem, and the inX()/outX() interfaces use MMIO. In both
258 * cases, user-mode can only use the legacy 0-64K I/O port space.
259 *
260 * ar.k0 is not involved in kernel I/O port accesses, which can use
261 * any of the I/O port spaces and are done via MMIO using the
262 * virtual mmio_base from the appropriate io_space[].
257 */ 263 */
258 phys_iobase = efi_get_iobase(); 264 phys_iobase = efi_get_iobase();
259 if (phys_iobase) 265 if (!phys_iobase) {
260 /* set AR.KR0 since this is all we use it for anyway */
261 ia64_set_kr(IA64_KR_IO_BASE, phys_iobase);
262 else {
263 phys_iobase = ia64_get_kr(IA64_KR_IO_BASE); 266 phys_iobase = ia64_get_kr(IA64_KR_IO_BASE);
264 printk(KERN_INFO "No I/O port range found in EFI memory map, falling back " 267 printk(KERN_INFO "No I/O port range found in EFI memory map, "
265 "to AR.KR0\n"); 268 "falling back to AR.KR0 (0x%lx)\n", phys_iobase);
266 printk(KERN_INFO "I/O port base = 0x%lx\n", phys_iobase);
267 } 269 }
268 ia64_iobase = (unsigned long) ioremap(phys_iobase, 0); 270 ia64_iobase = (unsigned long) ioremap(phys_iobase, 0);
271 ia64_set_kr(IA64_KR_IO_BASE, __pa(ia64_iobase));
269 272
270 /* setup legacy IO port space */ 273 /* setup legacy IO port space */
271 io_space[0].mmio_base = ia64_iobase; 274 io_space[0].mmio_base = ia64_iobase;