aboutsummaryrefslogtreecommitdiff
path: root/arch/ia64
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2005-09-16 11:43:10 -0600
committerTony Luck <tony.luck@intel.com>2005-09-19 15:55:48 -0700
commit44c451208da397438e7062393aeb3a19ddb76a60 (patch)
treeb6478dc02cab1a189e25c7b9ea0586ccf4c9f8e9 /arch/ia64
parent044a500e46742d39d22f1781cfb64ba93b463e39 (diff)
[IA64] ia64: add ar.k0 usage note
Update comment about how ar.k0 is used. Make the initialization the same as in start_secondary() (no functional change, just make it look more similar). Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64')
-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 1f5c26dbe70..e256b114bf4 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -244,28 +244,31 @@ find_initrd (void)
static void __init
io_port_init (void)
{
- extern unsigned long ia64_iobase;
unsigned long phys_iobase;
/*
- * Set `iobase' to the appropriate address in region 6 (uncached access range).
+ * Set `iobase' based on the EFI memory map or, failing that, the
+ * value firmware left in ar.k0.
*
- * The EFI memory map is the "preferred" location to get the I/O port space base,
- * rather the relying on AR.KR0. This should become more clear in future SAL
- * specs. We'll fall back to getting it out of AR.KR0 if no appropriate entry is
- * found in the memory map.
+ * Note that in ia32 mode, IN/OUT instructions use ar.k0 to compute
+ * the port's virtual address, so ia32_load_state() loads it with a
+ * user virtual address. But in ia64 mode, glibc uses the
+ * *physical* address in ar.k0 to mmap the appropriate area from
+ * /dev/mem, and the inX()/outX() interfaces use MMIO. In both
+ * cases, user-mode can only use the legacy 0-64K I/O port space.
+ *
+ * ar.k0 is not involved in kernel I/O port accesses, which can use
+ * any of the I/O port spaces and are done via MMIO using the
+ * virtual mmio_base from the appropriate io_space[].
*/
phys_iobase = efi_get_iobase();
- if (phys_iobase)
- /* set AR.KR0 since this is all we use it for anyway */
- ia64_set_kr(IA64_KR_IO_BASE, phys_iobase);
- else {
+ if (!phys_iobase) {
phys_iobase = ia64_get_kr(IA64_KR_IO_BASE);
- printk(KERN_INFO "No I/O port range found in EFI memory map, falling back "
- "to AR.KR0\n");
- printk(KERN_INFO "I/O port base = 0x%lx\n", phys_iobase);
+ printk(KERN_INFO "No I/O port range found in EFI memory map, "
+ "falling back to AR.KR0 (0x%lx)\n", phys_iobase);
}
ia64_iobase = (unsigned long) ioremap(phys_iobase, 0);
+ ia64_set_kr(IA64_KR_IO_BASE, __pa(ia64_iobase));
/* setup legacy IO port space */
io_space[0].mmio_base = ia64_iobase;