ia64/xen-unstable

changeset 6458:3ca4ca7a9cc2

Final changes for linux 2.6.13 rebasing and some directory reorgs
author djm@kirby.fc.hp.com
date Thu Sep 01 12:46:28 2005 -0600 (2005-09-01)
parents d34925e4144b
children 888877bc3d79 b55363593dfc
files xen/arch/ia64/Makefile xen/arch/ia64/linux/README.origin xen/arch/ia64/linux/bitop.c xen/arch/ia64/linux/clear_page.S xen/arch/ia64/linux/copy_page_mck.S xen/arch/ia64/linux/flush.S xen/arch/ia64/linux/idiv32.S xen/arch/ia64/linux/idiv64.S xen/arch/ia64/linux/memcpy_mck.S xen/arch/ia64/linux/memset.S xen/arch/ia64/linux/strlen.S xen/arch/ia64/vmx/mm.c xen/arch/ia64/vmx/mmio.c xen/arch/ia64/vmx/pal_emul.c xen/arch/ia64/vmx/vlsapic.c xen/arch/ia64/vmx/vmmu.c xen/arch/ia64/vmx/vmx_entry.S xen/arch/ia64/vmx/vmx_hypercall.c xen/arch/ia64/vmx/vmx_init.c xen/arch/ia64/vmx/vmx_interrupt.c xen/arch/ia64/vmx/vmx_irq_ia64.c xen/arch/ia64/vmx/vmx_ivt.S xen/arch/ia64/vmx/vmx_minstate.h xen/arch/ia64/vmx/vmx_phy_mode.c xen/arch/ia64/vmx/vmx_process.c xen/arch/ia64/vmx/vmx_support.c xen/arch/ia64/vmx/vmx_utility.c xen/arch/ia64/vmx/vmx_vcpu.c xen/arch/ia64/vmx/vmx_virt.c xen/arch/ia64/vmx/vmx_vsa.S xen/arch/ia64/vmx/vtlb.c xen/arch/ia64/xen/acpi.c xen/arch/ia64/xen/dom0_ops.c xen/arch/ia64/xen/dom_fw.c xen/arch/ia64/xen/domain.c xen/arch/ia64/xen/grant_table.c xen/arch/ia64/xen/hpsimserial.c xen/arch/ia64/xen/hypercall.c xen/arch/ia64/xen/hyperprivop.S xen/arch/ia64/xen/idle0_task.c xen/arch/ia64/xen/irq.c xen/arch/ia64/xen/ivt.S xen/arch/ia64/xen/mm_init.c xen/arch/ia64/xen/pcdp.c xen/arch/ia64/xen/privop.c xen/arch/ia64/xen/process.c xen/arch/ia64/xen/regionreg.c xen/arch/ia64/xen/sn_console.c xen/arch/ia64/xen/vcpu.c xen/arch/ia64/xen/vhpt.c xen/arch/ia64/xen/xen.lds.S xen/arch/ia64/xen/xenasm.S xen/arch/ia64/xen/xenirq.c xen/arch/ia64/xen/xenmem.c xen/arch/ia64/xen/xenmisc.c xen/arch/ia64/xen/xensetup.c xen/arch/ia64/xen/xentime.c xen/include/asm-ia64/config.h xen/include/asm-ia64/linux-xen/asm/pgtable.h xen/include/asm-ia64/linux/asm-generic/bug.h xen/include/asm-ia64/linux/asm-generic/errno.h xen/include/asm-ia64/linux/asm-generic/iomap.h xen/include/asm-ia64/linux/asm-generic/pci.h xen/include/asm-ia64/linux/asm-generic/pgtable-nopud.h xen/include/asm-ia64/linux/asm-generic/pgtable.h xen/include/asm-ia64/linux/asm-generic/sections.h xen/include/asm-ia64/linux/asm-generic/topology.h xen/include/asm-ia64/linux/asm-generic/unaligned.h xen/include/asm-ia64/linux/asm-generic/vmlinux.lds.h xen/include/asm-ia64/linux/asm/acpi.h xen/include/asm-ia64/linux/asm/bitops.h xen/include/asm-ia64/linux/asm/break.h xen/include/asm-ia64/linux/asm/bug.h xen/include/asm-ia64/linux/asm/cacheflush.h xen/include/asm-ia64/linux/asm/numnodes.h xen/include/asm-ia64/linux/asm/param.h xen/include/asm-ia64/linux/asm/pci.h xen/include/asm-ia64/linux/asm/percpu.h xen/include/asm-ia64/linux/asm/sections.h xen/include/asm-ia64/linux/asm/signal.h xen/include/asm-ia64/linux/asm/smp.h xen/include/asm-ia64/linux/asm/thread_info.h xen/include/asm-ia64/linux/asm/topology.h xen/include/asm-ia64/linux/asm/unaligned.h xen/include/asm-ia64/linux/asm/unistd.h xen/include/asm-ia64/linux/bitmap.h xen/include/asm-ia64/linux/bitops.h xen/include/asm-ia64/linux/dma-mapping.h xen/include/asm-ia64/linux/efi.h xen/include/asm-ia64/linux/err.h xen/include/asm-ia64/linux/gfp.h xen/include/asm-ia64/linux/mmzone.h xen/include/asm-ia64/linux/numa.h xen/include/asm-ia64/linux/page-flags.h xen/include/asm-ia64/linux/slab.h xen/include/asm-ia64/linux/threads.h xen/include/asm-ia64/linux/time.h xen/include/asm-ia64/linux/timex.h xen/include/asm-ia64/linux/topology.h xen/include/asm-ia64/linux/wait.h xen/include/asm-ia64/mm.h xen/include/asm-ia64/time.h
line diff
     1.1 --- a/xen/arch/ia64/Makefile	Thu Sep 01 11:09:27 2005 -0600
     1.2 +++ b/xen/arch/ia64/Makefile	Thu Sep 01 12:46:28 2005 -0600
     1.3 @@ -1,9 +1,6 @@
     1.4  include $(BASEDIR)/Rules.mk
     1.5  
     1.6 -VPATH = linux linux-xen linux/lib
     1.7 -#VPATH = linux-xen linux/lib
     1.8 -
     1.9 -# libs-y	+= arch/ia64/lib/lib.a
    1.10 +VPATH = xen vmx linux linux-xen
    1.11  
    1.12  OBJS = xensetup.o setup.o time.o irq.o ia64_ksyms.o process.o smp.o \
    1.13  	xenmisc.o acpi.o hypercall.o \
    1.14 @@ -15,8 +12,6 @@ OBJS = xensetup.o setup.o time.o irq.o i
    1.15  	irq_ia64.o irq_lsapic.o vhpt.o xenasm.o hyperprivop.o dom_fw.o \
    1.16  	grant_table.o sn_console.o
    1.17  
    1.18 -#OBJS += idiv64.o idiv32.o			\
    1.19 -
    1.20  # TMP holder to contain *.0 moved out of CONFIG_VTI
    1.21  OBJS += vmx_init.o
    1.22  
    1.23 @@ -27,7 +22,7 @@ OBJS += vmx_virt.o vmx_vcpu.o vmx_proces
    1.24  	pal_emul.o vmx_irq_ia64.o
    1.25  endif
    1.26  
    1.27 -# files from xen/arch/ia64/linux/lib (linux/arch/ia64/lib)
    1.28 +# lib files from xen/arch/ia64/linux/ (linux/arch/ia64/lib)
    1.29  OBJS +=	bitop.o clear_page.o flush.o copy_page_mck.o			\
    1.30  	memset.o strlen.o memcpy_mck.o 					\
    1.31  	__divsi3.o __udivsi3.o __modsi3.o __umodsi3.o			\
    1.32 @@ -86,9 +81,9 @@ asm-xsi-offsets.s: asm-xsi-offsets.c
    1.33  	 touch $@
    1.34  
    1.35  # I'm sure a Makefile wizard would know a better way to do this
    1.36 -xen.lds.s: xen.lds.S
    1.37 +xen.lds.s: xen/xen.lds.S
    1.38  	$(CC) -E $(CPPFLAGS) -P -DXEN -D__ASSEMBLY__ \
    1.39 -		-o xen.lds.s xen.lds.S
    1.40 +		-o xen.lds.s xen/xen.lds.S
    1.41  
    1.42  # variants of divide/modulo
    1.43  # see files in xen/arch/ia64/linux/lib (linux/arch/ia64/lib)
    1.44 @@ -111,7 +106,7 @@ xen.lds.s: xen.lds.S
    1.45  
    1.46  
    1.47  clean:
    1.48 -	rm -f *.o *~ core  xen.lds.s $(BASEDIR)/include/asm-ia64/.offsets.h.stamp asm-offsets.s
    1.49 +	rm -f *.o *~ core  xen.lds.s $(BASEDIR)/include/asm-ia64/.offsets.h.stamp asm-offsets.s map.out
    1.50  	rm -f asm-xsi-offsets.s $(BASEDIR)/include/asm-ia64/asm-xsi-offsets.h
    1.51  	rm -f linux/lib/*.o
    1.52  
     2.1 --- a/xen/arch/ia64/acpi.c	Thu Sep 01 11:09:27 2005 -0600
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,678 +0,0 @@
     2.4 -/*
     2.5 - *  acpi.c - Architecture-Specific Low-Level ACPI Support
     2.6 - *
     2.7 - *  Copyright (C) 1999 VA Linux Systems
     2.8 - *  Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
     2.9 - *  Copyright (C) 2000, 2002-2003 Hewlett-Packard Co.
    2.10 - *	David Mosberger-Tang <davidm@hpl.hp.com>
    2.11 - *  Copyright (C) 2000 Intel Corp.
    2.12 - *  Copyright (C) 2000,2001 J.I. Lee <jung-ik.lee@intel.com>
    2.13 - *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
    2.14 - *  Copyright (C) 2001 Jenna Hall <jenna.s.hall@intel.com>
    2.15 - *  Copyright (C) 2001 Takayoshi Kochi <t-kochi@bq.jp.nec.com>
    2.16 - *  Copyright (C) 2002 Erich Focht <efocht@ess.nec.de>
    2.17 - *
    2.18 - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    2.19 - *
    2.20 - *  This program is free software; you can redistribute it and/or modify
    2.21 - *  it under the terms of the GNU General Public License as published by
    2.22 - *  the Free Software Foundation; either version 2 of the License, or
    2.23 - *  (at your option) any later version.
    2.24 - *
    2.25 - *  This program is distributed in the hope that it will be useful,
    2.26 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.27 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2.28 - *  GNU General Public License for more details.
    2.29 - *
    2.30 - *  You should have received a copy of the GNU General Public License
    2.31 - *  along with this program; if not, write to the Free Software
    2.32 - *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    2.33 - *
    2.34 - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    2.35 - */
    2.36 -
    2.37 -#include <linux/config.h>
    2.38 -#include <linux/module.h>
    2.39 -#include <linux/init.h>
    2.40 -#include <linux/kernel.h>
    2.41 -#include <linux/sched.h>
    2.42 -#include <linux/smp.h>
    2.43 -#include <linux/string.h>
    2.44 -#include <linux/types.h>
    2.45 -#include <linux/irq.h>
    2.46 -#include <linux/acpi.h>
    2.47 -#include <linux/efi.h>
    2.48 -#include <linux/mmzone.h>
    2.49 -#include <asm/io.h>
    2.50 -//#include <asm/iosapic.h>
    2.51 -#include <asm/machvec.h>
    2.52 -#include <asm/page.h>
    2.53 -#include <asm/system.h>
    2.54 -#include <asm/numa.h>
    2.55 -#include <asm/sal.h>
    2.56 -//#include <asm/cyclone.h>
    2.57 -
    2.58 -#define BAD_MADT_ENTRY(entry, end) (                                        \
    2.59 -		(!entry) || (unsigned long)entry + sizeof(*entry) > end ||  \
    2.60 -		((acpi_table_entry_header *)entry)->length != sizeof(*entry))
    2.61 -
    2.62 -#define PREFIX			"ACPI: "
    2.63 -
    2.64 -void (*pm_idle) (void);
    2.65 -EXPORT_SYMBOL(pm_idle);
    2.66 -void (*pm_power_off) (void);
    2.67 -
    2.68 -unsigned char acpi_kbd_controller_present = 1;
    2.69 -unsigned char acpi_legacy_devices;
    2.70 -
    2.71 -const char *
    2.72 -acpi_get_sysname (void)
    2.73 -{
    2.74 -/* #ifdef CONFIG_IA64_GENERIC */
    2.75 -	unsigned long rsdp_phys;
    2.76 -	struct acpi20_table_rsdp *rsdp;
    2.77 -	struct acpi_table_xsdt *xsdt;
    2.78 -	struct acpi_table_header *hdr;
    2.79 -
    2.80 -	rsdp_phys = acpi_find_rsdp();
    2.81 -	if (!rsdp_phys) {
    2.82 -		printk(KERN_ERR "ACPI 2.0 RSDP not found, default to \"dig\"\n");
    2.83 -		return "dig";
    2.84 -	}
    2.85 -
    2.86 -	rsdp = (struct acpi20_table_rsdp *) __va(rsdp_phys);
    2.87 -	if (strncmp(rsdp->signature, RSDP_SIG, sizeof(RSDP_SIG) - 1)) {
    2.88 -		printk(KERN_ERR "ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n");
    2.89 -		return "dig";
    2.90 -	}
    2.91 -
    2.92 -	xsdt = (struct acpi_table_xsdt *) __va(rsdp->xsdt_address);
    2.93 -	hdr = &xsdt->header;
    2.94 -	if (strncmp(hdr->signature, XSDT_SIG, sizeof(XSDT_SIG) - 1)) {
    2.95 -		printk(KERN_ERR "ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n");
    2.96 -		return "dig";
    2.97 -	}
    2.98 -
    2.99 -	if (!strcmp(hdr->oem_id, "HP")) {
   2.100 -		return "hpzx1";
   2.101 -	}
   2.102 -	else if (!strcmp(hdr->oem_id, "SGI")) {
   2.103 -		return "sn2";
   2.104 -	}
   2.105 -
   2.106 -	return "dig";
   2.107 -/*
   2.108 -#else
   2.109 -# if defined (CONFIG_IA64_HP_SIM)
   2.110 -	return "hpsim";
   2.111 -# elif defined (CONFIG_IA64_HP_ZX1)
   2.112 -	return "hpzx1";
   2.113 -# elif defined (CONFIG_IA64_SGI_SN2)
   2.114 -	return "sn2";
   2.115 -# elif defined (CONFIG_IA64_DIG)
   2.116 -	return "dig";
   2.117 -# else
   2.118 -#	error Unknown platform.  Fix acpi.c.
   2.119 -# endif
   2.120 -#endif
   2.121 -*/
   2.122 -}
   2.123 -
   2.124 -#ifdef CONFIG_ACPI_BOOT
   2.125 -
   2.126 -#define ACPI_MAX_PLATFORM_INTERRUPTS	256
   2.127 -
   2.128 -#if 0
   2.129 -/* Array to record platform interrupt vectors for generic interrupt routing. */
   2.130 -int platform_intr_list[ACPI_MAX_PLATFORM_INTERRUPTS] = {
   2.131 -	[0 ... ACPI_MAX_PLATFORM_INTERRUPTS - 1] = -1
   2.132 -};
   2.133 -
   2.134 -enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC;
   2.135 -
   2.136 -/*
   2.137 - * Interrupt routing API for device drivers.  Provides interrupt vector for
   2.138 - * a generic platform event.  Currently only CPEI is implemented.
   2.139 - */
   2.140 -int
   2.141 -acpi_request_vector (u32 int_type)
   2.142 -{
   2.143 -	int vector = -1;
   2.144 -
   2.145 -	if (int_type < ACPI_MAX_PLATFORM_INTERRUPTS) {
   2.146 -		/* corrected platform error interrupt */
   2.147 -		vector = platform_intr_list[int_type];
   2.148 -	} else
   2.149 -		printk(KERN_ERR "acpi_request_vector(): invalid interrupt type\n");
   2.150 -	return vector;
   2.151 -}
   2.152 -#endif
   2.153 -char *
   2.154 -__acpi_map_table (unsigned long phys_addr, unsigned long size)
   2.155 -{
   2.156 -	return __va(phys_addr);
   2.157 -}
   2.158 -
   2.159 -/* --------------------------------------------------------------------------
   2.160 -                            Boot-time Table Parsing
   2.161 -   -------------------------------------------------------------------------- */
   2.162 -
   2.163 -static int			total_cpus __initdata;
   2.164 -static int			available_cpus __initdata;
   2.165 -struct acpi_table_madt *	acpi_madt __initdata;
   2.166 -static u8			has_8259;
   2.167 -
   2.168 -#if 0
   2.169 -static int __init
   2.170 -acpi_parse_lapic_addr_ovr (
   2.171 -	acpi_table_entry_header *header, const unsigned long end)
   2.172 -{
   2.173 -	struct acpi_table_lapic_addr_ovr *lapic;
   2.174 -
   2.175 -	lapic = (struct acpi_table_lapic_addr_ovr *) header;
   2.176 -
   2.177 -	if (BAD_MADT_ENTRY(lapic, end))
   2.178 -		return -EINVAL;
   2.179 -
   2.180 -	acpi_table_print_madt_entry(header);
   2.181 -
   2.182 -	if (lapic->address) {
   2.183 -		iounmap((void *) ipi_base_addr);
   2.184 -		ipi_base_addr = (unsigned long) ioremap(lapic->address, 0);
   2.185 -	}
   2.186 -	return 0;
   2.187 -}
   2.188 -
   2.189 -
   2.190 -static int __init
   2.191 -acpi_parse_lsapic (acpi_table_entry_header *header, const unsigned long end)
   2.192 -{
   2.193 -	struct acpi_table_lsapic *lsapic;
   2.194 -
   2.195 -	lsapic = (struct acpi_table_lsapic *) header;
   2.196 -
   2.197 -	if (BAD_MADT_ENTRY(lsapic, end))
   2.198 -		return -EINVAL;
   2.199 -
   2.200 -	acpi_table_print_madt_entry(header);
   2.201 -
   2.202 -	printk(KERN_INFO "CPU %d (0x%04x)", total_cpus, (lsapic->id << 8) | lsapic->eid);
   2.203 -
   2.204 -	if (!lsapic->flags.enabled)
   2.205 -		printk(" disabled");
   2.206 -	else {
   2.207 -		printk(" enabled");
   2.208 -#ifdef CONFIG_SMP
   2.209 -		smp_boot_data.cpu_phys_id[available_cpus] = (lsapic->id << 8) | lsapic->eid;
   2.210 -		if (hard_smp_processor_id()
   2.211 -		    == (unsigned int) smp_boot_data.cpu_phys_id[available_cpus])
   2.212 -			printk(" (BSP)");
   2.213 -#endif
   2.214 -		++available_cpus;
   2.215 -	}
   2.216 -
   2.217 -	printk("\n");
   2.218 -
   2.219 -	total_cpus++;
   2.220 -	return 0;
   2.221 -}
   2.222 -
   2.223 -
   2.224 -static int __init
   2.225 -acpi_parse_lapic_nmi (acpi_table_entry_header *header, const unsigned long end)
   2.226 -{
   2.227 -	struct acpi_table_lapic_nmi *lacpi_nmi;
   2.228 -
   2.229 -	lacpi_nmi = (struct acpi_table_lapic_nmi*) header;
   2.230 -
   2.231 -	if (BAD_MADT_ENTRY(lacpi_nmi, end))
   2.232 -		return -EINVAL;
   2.233 -
   2.234 -	acpi_table_print_madt_entry(header);
   2.235 -
   2.236 -	/* TBD: Support lapic_nmi entries */
   2.237 -	return 0;
   2.238 -}
   2.239 -
   2.240 -
   2.241 -static int __init
   2.242 -acpi_parse_iosapic (acpi_table_entry_header *header, const unsigned long end)
   2.243 -{
   2.244 -	struct acpi_table_iosapic *iosapic;
   2.245 -
   2.246 -	iosapic = (struct acpi_table_iosapic *) header;
   2.247 -
   2.248 -	if (BAD_MADT_ENTRY(iosapic, end))
   2.249 -		return -EINVAL;
   2.250 -
   2.251 -	acpi_table_print_madt_entry(header);
   2.252 -
   2.253 -	iosapic_init(iosapic->address, iosapic->global_irq_base);
   2.254 -
   2.255 -	return 0;
   2.256 -}
   2.257 -
   2.258 -
   2.259 -static int __init
   2.260 -acpi_parse_plat_int_src (
   2.261 -	acpi_table_entry_header *header, const unsigned long end)
   2.262 -{
   2.263 -	struct acpi_table_plat_int_src *plintsrc;
   2.264 -	int vector;
   2.265 -
   2.266 -	plintsrc = (struct acpi_table_plat_int_src *) header;
   2.267 -
   2.268 -	if (BAD_MADT_ENTRY(plintsrc, end))
   2.269 -		return -EINVAL;
   2.270 -
   2.271 -	acpi_table_print_madt_entry(header);
   2.272 -
   2.273 -	/*
   2.274 -	 * Get vector assignment for this interrupt, set attributes,
   2.275 -	 * and program the IOSAPIC routing table.
   2.276 -	 */
   2.277 -	vector = iosapic_register_platform_intr(plintsrc->type,
   2.278 -						plintsrc->global_irq,
   2.279 -						plintsrc->iosapic_vector,
   2.280 -						plintsrc->eid,
   2.281 -						plintsrc->id,
   2.282 -						(plintsrc->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
   2.283 -						(plintsrc->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
   2.284 -
   2.285 -	platform_intr_list[plintsrc->type] = vector;
   2.286 -	return 0;
   2.287 -}
   2.288 -
   2.289 -
   2.290 -static int __init
   2.291 -acpi_parse_int_src_ovr (
   2.292 -	acpi_table_entry_header *header, const unsigned long end)
   2.293 -{
   2.294 -	struct acpi_table_int_src_ovr *p;
   2.295 -
   2.296 -	p = (struct acpi_table_int_src_ovr *) header;
   2.297 -
   2.298 -	if (BAD_MADT_ENTRY(p, end))
   2.299 -		return -EINVAL;
   2.300 -
   2.301 -	acpi_table_print_madt_entry(header);
   2.302 -
   2.303 -	iosapic_override_isa_irq(p->bus_irq, p->global_irq,
   2.304 -				 (p->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
   2.305 -				 (p->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
   2.306 -	return 0;
   2.307 -}
   2.308 -
   2.309 -
   2.310 -static int __init
   2.311 -acpi_parse_nmi_src (acpi_table_entry_header *header, const unsigned long end)
   2.312 -{
   2.313 -	struct acpi_table_nmi_src *nmi_src;
   2.314 -
   2.315 -	nmi_src = (struct acpi_table_nmi_src*) header;
   2.316 -
   2.317 -	if (BAD_MADT_ENTRY(nmi_src, end))
   2.318 -		return -EINVAL;
   2.319 -
   2.320 -	acpi_table_print_madt_entry(header);
   2.321 -
   2.322 -	/* TBD: Support nimsrc entries */
   2.323 -	return 0;
   2.324 -}
   2.325 -/* Hook from generic ACPI tables.c */
   2.326 -void __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
   2.327 -{
   2.328 -	if (!strncmp(oem_id, "IBM", 3) &&
   2.329 -	    (!strncmp(oem_table_id, "SERMOW", 6))){
   2.330 -
   2.331 -		/* Unfortunatly ITC_DRIFT is not yet part of the
   2.332 -		 * official SAL spec, so the ITC_DRIFT bit is not
   2.333 -		 * set by the BIOS on this hardware.
   2.334 -		 */
   2.335 -		sal_platform_features |= IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT;
   2.336 -
   2.337 -		/*Start cyclone clock*/
   2.338 -		cyclone_setup(0);
   2.339 -	}
   2.340 -}
   2.341 -
   2.342 -static int __init
   2.343 -acpi_parse_madt (unsigned long phys_addr, unsigned long size)
   2.344 -{
   2.345 -	if (!phys_addr || !size)
   2.346 -		return -EINVAL;
   2.347 -
   2.348 -	acpi_madt = (struct acpi_table_madt *) __va(phys_addr);
   2.349 -
   2.350 -	/* remember the value for reference after free_initmem() */
   2.351 -#ifdef CONFIG_ITANIUM
   2.352 -	has_8259 = 1; /* Firmware on old Itanium systems is broken */
   2.353 -#else
   2.354 -	has_8259 = acpi_madt->flags.pcat_compat;
   2.355 -#endif
   2.356 -	iosapic_system_init(has_8259);
   2.357 -
   2.358 -	/* Get base address of IPI Message Block */
   2.359 -
   2.360 -	if (acpi_madt->lapic_address)
   2.361 -		ipi_base_addr = (unsigned long) ioremap(acpi_madt->lapic_address, 0);
   2.362 -
   2.363 -	printk(KERN_INFO PREFIX "Local APIC address 0x%lx\n", ipi_base_addr);
   2.364 -
   2.365 -	acpi_madt_oem_check(acpi_madt->header.oem_id,
   2.366 -		acpi_madt->header.oem_table_id);
   2.367 -
   2.368 -	return 0;
   2.369 -}
   2.370 -#endif
   2.371 -
   2.372 -#ifdef CONFIG_ACPI_NUMA
   2.373 -
   2.374 -#undef SLIT_DEBUG
   2.375 -
   2.376 -#define PXM_FLAG_LEN ((MAX_PXM_DOMAINS + 1)/32)
   2.377 -
   2.378 -static int __initdata srat_num_cpus;			/* number of cpus */
   2.379 -static u32 __initdata pxm_flag[PXM_FLAG_LEN];
   2.380 -#define pxm_bit_set(bit)	(set_bit(bit,(void *)pxm_flag))
   2.381 -#define pxm_bit_test(bit)	(test_bit(bit,(void *)pxm_flag))
   2.382 -/* maps to convert between proximity domain and logical node ID */
   2.383 -int __initdata pxm_to_nid_map[MAX_PXM_DOMAINS];
   2.384 -int __initdata nid_to_pxm_map[MAX_NUMNODES];
   2.385 -static struct acpi_table_slit __initdata *slit_table;
   2.386 -
   2.387 -/*
   2.388 - * ACPI 2.0 SLIT (System Locality Information Table)
   2.389 - * http://devresource.hp.com/devresource/Docs/TechPapers/IA64/slit.pdf
   2.390 - */
   2.391 -void __init
   2.392 -acpi_numa_slit_init (struct acpi_table_slit *slit)
   2.393 -{
   2.394 -	u32 len;
   2.395 -
   2.396 -	len = sizeof(struct acpi_table_header) + 8
   2.397 -		+ slit->localities * slit->localities;
   2.398 -	if (slit->header.length != len) {
   2.399 -		printk(KERN_ERR "ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n",
   2.400 -		       len, slit->header.length);
   2.401 -		memset(numa_slit, 10, sizeof(numa_slit));
   2.402 -		return;
   2.403 -	}
   2.404 -	slit_table = slit;
   2.405 -}
   2.406 -
   2.407 -void __init
   2.408 -acpi_numa_processor_affinity_init (struct acpi_table_processor_affinity *pa)
   2.409 -{
   2.410 -	/* record this node in proximity bitmap */
   2.411 -	pxm_bit_set(pa->proximity_domain);
   2.412 -
   2.413 -	node_cpuid[srat_num_cpus].phys_id = (pa->apic_id << 8) | (pa->lsapic_eid);
   2.414 -	/* nid should be overridden as logical node id later */
   2.415 -	node_cpuid[srat_num_cpus].nid = pa->proximity_domain;
   2.416 -	srat_num_cpus++;
   2.417 -}
   2.418 -
   2.419 -void __init
   2.420 -acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma)
   2.421 -{
   2.422 -	unsigned long paddr, size;
   2.423 -	u8 pxm;
   2.424 -	struct node_memblk_s *p, *q, *pend;
   2.425 -
   2.426 -	pxm = ma->proximity_domain;
   2.427 -
   2.428 -	/* fill node memory chunk structure */
   2.429 -	paddr = ma->base_addr_hi;
   2.430 -	paddr = (paddr << 32) | ma->base_addr_lo;
   2.431 -	size = ma->length_hi;
   2.432 -	size = (size << 32) | ma->length_lo;
   2.433 -
   2.434 -	/* Ignore disabled entries */
   2.435 -	if (!ma->flags.enabled)
   2.436 -		return;
   2.437 -
   2.438 -	/* record this node in proximity bitmap */
   2.439 -	pxm_bit_set(pxm);
   2.440 -
   2.441 -	/* Insertion sort based on base address */
   2.442 -	pend = &node_memblk[num_node_memblks];
   2.443 -	for (p = &node_memblk[0]; p < pend; p++) {
   2.444 -		if (paddr < p->start_paddr)
   2.445 -			break;
   2.446 -	}
   2.447 -	if (p < pend) {
   2.448 -		for (q = pend - 1; q >= p; q--)
   2.449 -			*(q + 1) = *q;
   2.450 -	}
   2.451 -	p->start_paddr = paddr;
   2.452 -	p->size = size;
   2.453 -	p->nid = pxm;
   2.454 -	num_node_memblks++;
   2.455 -}
   2.456 -
   2.457 -void __init
   2.458 -acpi_numa_arch_fixup (void)
   2.459 -{
   2.460 -	int i, j, node_from, node_to;
   2.461 -
   2.462 -	/* If there's no SRAT, fix the phys_id */
   2.463 -	if (srat_num_cpus == 0) {
   2.464 -		node_cpuid[0].phys_id = hard_smp_processor_id();
   2.465 -		return;
   2.466 -	}
   2.467 -
   2.468 -	/* calculate total number of nodes in system from PXM bitmap */
   2.469 -	numnodes = 0;		/* init total nodes in system */
   2.470 -
   2.471 -	memset(pxm_to_nid_map, -1, sizeof(pxm_to_nid_map));
   2.472 -	memset(nid_to_pxm_map, -1, sizeof(nid_to_pxm_map));
   2.473 -	for (i = 0; i < MAX_PXM_DOMAINS; i++) {
   2.474 -		if (pxm_bit_test(i)) {
   2.475 -			pxm_to_nid_map[i] = numnodes;
   2.476 -			node_set_online(numnodes);
   2.477 -			nid_to_pxm_map[numnodes++] = i;
   2.478 -		}
   2.479 -	}
   2.480 -
   2.481 -	/* set logical node id in memory chunk structure */
   2.482 -	for (i = 0; i < num_node_memblks; i++)
   2.483 -		node_memblk[i].nid = pxm_to_nid_map[node_memblk[i].nid];
   2.484 -
   2.485 -	/* assign memory bank numbers for each chunk on each node */
   2.486 -	for (i = 0; i < numnodes; i++) {
   2.487 -		int bank;
   2.488 -
   2.489 -		bank = 0;
   2.490 -		for (j = 0; j < num_node_memblks; j++)
   2.491 -			if (node_memblk[j].nid == i)
   2.492 -				node_memblk[j].bank = bank++;
   2.493 -	}
   2.494 -
   2.495 -	/* set logical node id in cpu structure */
   2.496 -	for (i = 0; i < srat_num_cpus; i++)
   2.497 -		node_cpuid[i].nid = pxm_to_nid_map[node_cpuid[i].nid];
   2.498 -
   2.499 -	printk(KERN_INFO "Number of logical nodes in system = %d\n", numnodes);
   2.500 -	printk(KERN_INFO "Number of memory chunks in system = %d\n", num_node_memblks);
   2.501 -
   2.502 -	if (!slit_table) return;
   2.503 -	memset(numa_slit, -1, sizeof(numa_slit));
   2.504 -	for (i=0; i<slit_table->localities; i++) {
   2.505 -		if (!pxm_bit_test(i))
   2.506 -			continue;
   2.507 -		node_from = pxm_to_nid_map[i];
   2.508 -		for (j=0; j<slit_table->localities; j++) {
   2.509 -			if (!pxm_bit_test(j))
   2.510 -				continue;
   2.511 -			node_to = pxm_to_nid_map[j];
   2.512 -			node_distance(node_from, node_to) =
   2.513 -				slit_table->entry[i*slit_table->localities + j];
   2.514 -		}
   2.515 -	}
   2.516 -
   2.517 -#ifdef SLIT_DEBUG
   2.518 -	printk("ACPI 2.0 SLIT locality table:\n");
   2.519 -	for (i = 0; i < numnodes; i++) {
   2.520 -		for (j = 0; j < numnodes; j++)
   2.521 -			printk("%03d ", node_distance(i,j));
   2.522 -		printk("\n");
   2.523 -	}
   2.524 -#endif
   2.525 -}
   2.526 -#endif /* CONFIG_ACPI_NUMA */
   2.527 -
   2.528 -#if 0
   2.529 -unsigned int
   2.530 -acpi_register_gsi (u32 gsi, int polarity, int trigger)
   2.531 -{
   2.532 -	return acpi_register_irq(gsi, polarity, trigger);
   2.533 -}
   2.534 -EXPORT_SYMBOL(acpi_register_gsi);
   2.535 -static int __init
   2.536 -acpi_parse_fadt (unsigned long phys_addr, unsigned long size)
   2.537 -{
   2.538 -	struct acpi_table_header *fadt_header;
   2.539 -	struct fadt_descriptor_rev2 *fadt;
   2.540 -
   2.541 -	if (!phys_addr || !size)
   2.542 -		return -EINVAL;
   2.543 -
   2.544 -	fadt_header = (struct acpi_table_header *) __va(phys_addr);
   2.545 -	if (fadt_header->revision != 3)
   2.546 -		return -ENODEV;		/* Only deal with ACPI 2.0 FADT */
   2.547 -
   2.548 -	fadt = (struct fadt_descriptor_rev2 *) fadt_header;
   2.549 -
   2.550 -	if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER))
   2.551 -		acpi_kbd_controller_present = 0;
   2.552 -
   2.553 -	if (fadt->iapc_boot_arch & BAF_LEGACY_DEVICES)
   2.554 -		acpi_legacy_devices = 1;
   2.555 -
   2.556 -	acpi_register_gsi(fadt->sci_int, ACPI_ACTIVE_LOW, ACPI_LEVEL_SENSITIVE);
   2.557 -	return 0;
   2.558 -}
   2.559 -#endif
   2.560 -
   2.561 -unsigned long __init
   2.562 -acpi_find_rsdp (void)
   2.563 -{
   2.564 -	unsigned long rsdp_phys = 0;
   2.565 -
   2.566 -	if (efi.acpi20)
   2.567 -		rsdp_phys = __pa(efi.acpi20);
   2.568 -	else if (efi.acpi)
   2.569 -		printk(KERN_WARNING PREFIX "v1.0/r0.71 tables no longer supported\n");
   2.570 -	return rsdp_phys;
   2.571 -}
   2.572 -
   2.573 -#if 0
   2.574 -int __init
   2.575 -acpi_boot_init (void)
   2.576 -{
   2.577 -
   2.578 -	/*
   2.579 -	 * MADT
   2.580 -	 * ----
   2.581 -	 * Parse the Multiple APIC Description Table (MADT), if exists.
   2.582 -	 * Note that this table provides platform SMP configuration
   2.583 -	 * information -- the successor to MPS tables.
   2.584 -	 */
   2.585 -
   2.586 -	if (acpi_table_parse(ACPI_APIC, acpi_parse_madt) < 1) {
   2.587 -		printk(KERN_ERR PREFIX "Can't find MADT\n");
   2.588 -		goto skip_madt;
   2.589 -	}
   2.590 -
   2.591 -	/* Local APIC */
   2.592 -
   2.593 -	if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0) < 0)
   2.594 -		printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
   2.595 -
   2.596 -	if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_parse_lsapic, NR_CPUS) < 1)
   2.597 -		printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n");
   2.598 -
   2.599 -	if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0) < 0)
   2.600 -		printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
   2.601 -
   2.602 -	/* I/O APIC */
   2.603 -
   2.604 -	if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC, acpi_parse_iosapic, NR_IOSAPICS) < 1)
   2.605 -		printk(KERN_ERR PREFIX "Error parsing MADT - no IOSAPIC entries\n");
   2.606 -
   2.607 -	/* System-Level Interrupt Routing */
   2.608 -
   2.609 -	if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC, acpi_parse_plat_int_src, ACPI_MAX_PLATFORM_INTERRUPTS) < 0)
   2.610 -		printk(KERN_ERR PREFIX "Error parsing platform interrupt source entry\n");
   2.611 -
   2.612 -	if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, 0) < 0)
   2.613 -		printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
   2.614 -
   2.615 -	if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, 0) < 0)
   2.616 -		printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
   2.617 -  skip_madt:
   2.618 -
   2.619 -	/*
   2.620 -	 * FADT says whether a legacy keyboard controller is present.
   2.621 -	 * The FADT also contains an SCI_INT line, by which the system
   2.622 -	 * gets interrupts such as power and sleep buttons.  If it's not
   2.623 -	 * on a Legacy interrupt, it needs to be setup.
   2.624 -	 */
   2.625 -	if (acpi_table_parse(ACPI_FADT, acpi_parse_fadt) < 1)
   2.626 -		printk(KERN_ERR PREFIX "Can't find FADT\n");
   2.627 -
   2.628 -#ifdef CONFIG_SMP
   2.629 -	if (available_cpus == 0) {
   2.630 -		printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n");
   2.631 -		printk(KERN_INFO "CPU 0 (0x%04x)", hard_smp_processor_id());
   2.632 -		smp_boot_data.cpu_phys_id[available_cpus] = hard_smp_processor_id();
   2.633 -		available_cpus = 1; /* We've got at least one of these, no? */
   2.634 -	}
   2.635 -	smp_boot_data.cpu_count = available_cpus;
   2.636 -
   2.637 -	smp_build_cpu_map();
   2.638 -# ifdef CONFIG_ACPI_NUMA
   2.639 -	if (srat_num_cpus == 0) {
   2.640 -		int cpu, i = 1;
   2.641 -		for (cpu = 0; cpu < smp_boot_data.cpu_count; cpu++)
   2.642 -			if (smp_boot_data.cpu_phys_id[cpu] != hard_smp_processor_id())
   2.643 -				node_cpuid[i++].phys_id = smp_boot_data.cpu_phys_id[cpu];
   2.644 -	}
   2.645 -	build_cpu_to_node_map();
   2.646 -# endif
   2.647 -#endif
   2.648 -	/* Make boot-up look pretty */
   2.649 -	printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
   2.650 -	return 0;
   2.651 -}
   2.652 -int
   2.653 -acpi_gsi_to_irq (u32 gsi, unsigned int *irq)
   2.654 -{
   2.655 -	int vector;
   2.656 -
   2.657 -	if (has_8259 && gsi < 16)
   2.658 -		*irq = isa_irq_to_vector(gsi);
   2.659 -	else {
   2.660 -		vector = gsi_to_vector(gsi);
   2.661 -		if (vector == -1)
   2.662 -			return -1;
   2.663 -
   2.664 -		*irq = vector;
   2.665 -	}
   2.666 -	return 0;
   2.667 -}
   2.668 -
   2.669 -int
   2.670 -acpi_register_irq (u32 gsi, u32 polarity, u32 trigger)
   2.671 -{
   2.672 -	if (has_8259 && gsi < 16)
   2.673 -		return isa_irq_to_vector(gsi);
   2.674 -
   2.675 -	return iosapic_register_intr(gsi,
   2.676 -			(polarity == ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
   2.677 -			(trigger == ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
   2.678 -}
   2.679 -EXPORT_SYMBOL(acpi_register_irq);
   2.680 -#endif
   2.681 -#endif /* CONFIG_ACPI_BOOT */
     3.1 --- a/xen/arch/ia64/dom0_ops.c	Thu Sep 01 11:09:27 2005 -0600
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,237 +0,0 @@
     3.4 -/******************************************************************************
     3.5 - * Arch-specific dom0_ops.c
     3.6 - * 
     3.7 - * Process command requests from domain-0 guest OS.
     3.8 - * 
     3.9 - * Copyright (c) 2002, K A Fraser
    3.10 - */
    3.11 -
    3.12 -#include <xen/config.h>
    3.13 -#include <xen/types.h>
    3.14 -#include <xen/lib.h>
    3.15 -#include <xen/mm.h>
    3.16 -#include <public/dom0_ops.h>
    3.17 -#include <xen/sched.h>
    3.18 -#include <xen/event.h>
    3.19 -#include <asm/pdb.h>
    3.20 -#include <xen/trace.h>
    3.21 -#include <xen/console.h>
    3.22 -#include <public/sched_ctl.h>
    3.23 -
    3.24 -long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op)
    3.25 -{
    3.26 -    long ret = 0;
    3.27 -
    3.28 -    if ( !IS_PRIV(current->domain) )
    3.29 -        return -EPERM;
    3.30 -
    3.31 -    switch ( op->cmd )
    3.32 -    {
    3.33 -    case DOM0_GETPAGEFRAMEINFO:
    3.34 -    {
    3.35 -        struct pfn_info *page;
    3.36 -        unsigned long pfn = op->u.getpageframeinfo.pfn;
    3.37 -        domid_t dom = op->u.getpageframeinfo.domain;
    3.38 -        struct domain *d;
    3.39 -
    3.40 -        ret = -EINVAL;
    3.41 -
    3.42 -        if ( unlikely(pfn >= max_page) || 
    3.43 -             unlikely((d = find_domain_by_id(dom)) == NULL) )
    3.44 -            break;
    3.45 -
    3.46 -        page = &frame_table[pfn];
    3.47 -
    3.48 -        if ( likely(get_page(page, d)) )
    3.49 -        {
    3.50 -            ret = 0;
    3.51 -
    3.52 -            op->u.getpageframeinfo.type = NOTAB;
    3.53 -
    3.54 -            if ( (page->u.inuse.type_info & PGT_count_mask) != 0 )
    3.55 -            {
    3.56 -                switch ( page->u.inuse.type_info & PGT_type_mask )
    3.57 -                {
    3.58 -		default:
    3.59 -		    panic("No such page type\n");
    3.60 -                    break;
    3.61 -                }
    3.62 -            }
    3.63 -            
    3.64 -            put_page(page);
    3.65 -        }
    3.66 -
    3.67 -        put_domain(d);
    3.68 -
    3.69 -        copy_to_user(u_dom0_op, op, sizeof(*op));
    3.70 -    }
    3.71 -    break;
    3.72 -
    3.73 -    case DOM0_GETPAGEFRAMEINFO2:
    3.74 -    {
    3.75 -#define GPF2_BATCH 128
    3.76 -        int n,j;
    3.77 -        int num = op->u.getpageframeinfo2.num;
    3.78 -        domid_t dom = op->u.getpageframeinfo2.domain;
    3.79 -        unsigned long *s_ptr = (unsigned long*) op->u.getpageframeinfo2.array;
    3.80 -        struct domain *d;
    3.81 -        unsigned long *l_arr;
    3.82 -        ret = -ESRCH;
    3.83 -
    3.84 -        if ( unlikely((d = find_domain_by_id(dom)) == NULL) )
    3.85 -            break;
    3.86 -
    3.87 -        if ( unlikely(num > 1024) )
    3.88 -        {
    3.89 -            ret = -E2BIG;
    3.90 -            break;
    3.91 -        }
    3.92 -
    3.93 -        l_arr = (unsigned long *)alloc_xenheap_page();
    3.94 - 
    3.95 -        ret = 0;
    3.96 -        for( n = 0; n < num; )
    3.97 -        {
    3.98 -            int k = ((num-n)>GPF2_BATCH)?GPF2_BATCH:(num-n);
    3.99 -
   3.100 -            if ( copy_from_user(l_arr, &s_ptr[n], k*sizeof(unsigned long)) )
   3.101 -            {
   3.102 -                ret = -EINVAL;
   3.103 -                break;
   3.104 -            }
   3.105 -     
   3.106 -            for( j = 0; j < k; j++ )
   3.107 -            {      
   3.108 -                struct pfn_info *page;
   3.109 -                unsigned long mfn = l_arr[j];
   3.110 -
   3.111 -                if ( unlikely(mfn >= max_page) )
   3.112 -                    goto e2_err;
   3.113 -
   3.114 -                page = &frame_table[mfn];
   3.115 -  
   3.116 -                if ( likely(get_page(page, d)) )
   3.117 -                {
   3.118 -                    unsigned long type = 0;
   3.119 -
   3.120 -                    switch( page->u.inuse.type_info & PGT_type_mask )
   3.121 -                    {
   3.122 -		    default:
   3.123 -			panic("No such page type\n");
   3.124 -			break;
   3.125 -                    }
   3.126 -
   3.127 -                    if ( page->u.inuse.type_info & PGT_pinned )
   3.128 -                        type |= LPINTAB;
   3.129 -                    l_arr[j] |= type;
   3.130 -                    put_page(page);
   3.131 -                }
   3.132 -                else
   3.133 -                {
   3.134 -                e2_err:
   3.135 -                    l_arr[j] |= XTAB;
   3.136 -                }
   3.137 -
   3.138 -            }
   3.139 -
   3.140 -            if ( copy_to_user(&s_ptr[n], l_arr, k*sizeof(unsigned long)) )
   3.141 -            {
   3.142 -                ret = -EINVAL;
   3.143 -                break;
   3.144 -            }
   3.145 -
   3.146 -            n += j;
   3.147 -        }
   3.148 -
   3.149 -        free_xenheap_page((unsigned long)l_arr);
   3.150 -
   3.151 -        put_domain(d);
   3.152 -    }
   3.153 -    break;
   3.154 -#ifndef CONFIG_VTI
   3.155 -    /*
   3.156 -     * NOTE: DOM0_GETMEMLIST has somewhat different semantics on IA64 -
   3.157 -     * it actually allocates and maps pages.
   3.158 -     */
   3.159 -    case DOM0_GETMEMLIST:
   3.160 -    {
   3.161 -        unsigned long i;
   3.162 -        struct domain *d = find_domain_by_id(op->u.getmemlist.domain);
   3.163 -        unsigned long start_page = op->u.getmemlist.max_pfns >> 32;
   3.164 -        unsigned long nr_pages = op->u.getmemlist.max_pfns & 0xffffffff;
   3.165 -        unsigned long pfn;
   3.166 -        unsigned long *buffer = op->u.getmemlist.buffer;
   3.167 -        struct page *page;
   3.168 -
   3.169 -        ret = -EINVAL;
   3.170 -        if ( d != NULL )
   3.171 -        {
   3.172 -            ret = 0;
   3.173 -
   3.174 -            for ( i = start_page; i < (start_page + nr_pages); i++ )
   3.175 -            {
   3.176 -                page = map_new_domain_page(d, i << PAGE_SHIFT);
   3.177 -                if ( page == NULL )
   3.178 -                {
   3.179 -                    ret = -ENOMEM;
   3.180 -                    break;
   3.181 -                }
   3.182 -                pfn = page_to_pfn(page);
   3.183 -                if ( put_user(pfn, buffer) )
   3.184 -                {
   3.185 -                    ret = -EFAULT;
   3.186 -                    break;
   3.187 -                }
   3.188 -                buffer++;
   3.189 -            }
   3.190 -
   3.191 -            op->u.getmemlist.num_pfns = i - start_page;
   3.192 -            copy_to_user(u_dom0_op, op, sizeof(*op));
   3.193 -            
   3.194 -            put_domain(d);
   3.195 -        }
   3.196 -    }
   3.197 -    break;
   3.198 -#else
   3.199 -    case DOM0_GETMEMLIST:
   3.200 -    {
   3.201 -	int i;
   3.202 -	struct domain *d = find_domain_by_id(op->u.getmemlist.domain);
   3.203 -	unsigned long max_pfns = op->u.getmemlist.max_pfns;
   3.204 -	unsigned long pfn;
   3.205 -	unsigned long *buffer = op->u.getmemlist.buffer;
   3.206 -	struct list_head *list_ent;
   3.207 -
   3.208 -	ret = -EINVAL;
   3.209 -	if (!d) {
   3.210 -	    ret = 0;
   3.211 -
   3.212 -	    spin_lock(&d->page_alloc_lock);
   3.213 -	    list_ent = d->page_list.next;
   3.214 -	    for (i = 0; (i < max_pfns) && (list_ent != &d->page_list); i++) {
   3.215 -		pfn = list_entry(list_ent, struct pfn_info, list) -
   3.216 -		    frame_table;
   3.217 -		if (put_user(pfn, buffer)) {
   3.218 -		    ret = -EFAULT;
   3.219 -		    break;
   3.220 -		}
   3.221 -		buffer++;
   3.222 -		list_ent = frame_table[pfn].list.next;
   3.223 -	    }
   3.224 -	    spin_unlock(&d->page_alloc_lock);
   3.225 -
   3.226 -	    op->u.getmemlist.num_pfns = i;
   3.227 -	    copy_to_user(u_dom0_op, op, sizeof(*op));
   3.228 -
   3.229 -	    put_domain(d);
   3.230 -	}
   3.231 -    }
   3.232 -    break;
   3.233 -#endif // CONFIG_VTI
   3.234 -    default:
   3.235 -        ret = -ENOSYS;
   3.236 -
   3.237 -    }
   3.238 -
   3.239 -    return ret;
   3.240 -}
     4.1 --- a/xen/arch/ia64/dom_fw.c	Thu Sep 01 11:09:27 2005 -0600
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,688 +0,0 @@
     4.4 -/*
     4.5 - *  Xen domain firmware emulation support
     4.6 - *  Copyright (C) 2004 Hewlett-Packard Co.
     4.7 - *       Dan Magenheimer (dan.magenheimer@hp.com)
     4.8 - *
     4.9 - */
    4.10 -
    4.11 -#include <xen/config.h>
    4.12 -#include <asm/system.h>
    4.13 -#include <asm/pgalloc.h>
    4.14 -
    4.15 -#include <linux/efi.h>
    4.16 -#include <asm/io.h>
    4.17 -#include <asm/pal.h>
    4.18 -#include <asm/sal.h>
    4.19 -#include <xen/acpi.h>
    4.20 -
    4.21 -#include <asm/dom_fw.h>
    4.22 -
    4.23 -struct ia64_boot_param *dom_fw_init(struct domain *, char *,int,char *,int);
    4.24 -extern unsigned long domain_mpa_to_imva(struct domain *,unsigned long mpaddr);
    4.25 -extern struct domain *dom0;
    4.26 -extern unsigned long dom0_start;
    4.27 -
    4.28 -extern unsigned long running_on_sim;
    4.29 -
    4.30 -
    4.31 -unsigned long dom_fw_base_mpa = -1;
    4.32 -unsigned long imva_fw_base = -1;
    4.33 -
    4.34 -// return domain (meta)physical address for a given imva
    4.35 -// this function is a call-back from dom_fw_init
    4.36 -unsigned long dom_pa(unsigned long imva)
    4.37 -{
    4.38 -	if (dom_fw_base_mpa == -1 || imva_fw_base == -1) {
    4.39 -		printf("dom_pa: uninitialized! (spinning...)\n");
    4.40 -		while(1);
    4.41 -	}
    4.42 -	if (imva - imva_fw_base > PAGE_SIZE) {
    4.43 -		printf("dom_pa: bad offset! imva=%p, imva_fw_base=%p (spinning...)\n",imva,imva_fw_base);
    4.44 -		while(1);
    4.45 -	}
    4.46 -	return dom_fw_base_mpa + (imva - imva_fw_base);
    4.47 -}
    4.48 -
    4.49 -// builds a hypercall bundle at domain physical address
    4.50 -void dom_efi_hypercall_patch(struct domain *d, unsigned long paddr, unsigned long hypercall)
    4.51 -{
    4.52 -	unsigned long imva;
    4.53 -
    4.54 -	if (d == dom0) paddr += dom0_start;
    4.55 -	imva = domain_mpa_to_imva(d,paddr);
    4.56 -	build_hypercall_bundle(imva,d->arch.breakimm,hypercall,1);
    4.57 -}
    4.58 -
    4.59 -
    4.60 -// builds a hypercall bundle at domain physical address
    4.61 -void dom_fw_hypercall_patch(struct domain *d, unsigned long paddr, unsigned long hypercall,unsigned long ret)
    4.62 -{
    4.63 -	unsigned long imva;
    4.64 -
    4.65 -	if (d == dom0) paddr += dom0_start;
    4.66 -	imva = domain_mpa_to_imva(d,paddr);
    4.67 -	build_hypercall_bundle(imva,d->arch.breakimm,hypercall,ret);
    4.68 -}
    4.69 -
    4.70 -
    4.71 -// FIXME: This is really a hack: Forcing the boot parameter block
    4.72 -// at domain mpaddr 0 page, then grabbing only the low bits of the
    4.73 -// Xen imva, which is the offset into the page
    4.74 -unsigned long dom_fw_setup(struct domain *d, char *args, int arglen)
    4.75 -{
    4.76 -	struct ia64_boot_param *bp;
    4.77 -
    4.78 -	dom_fw_base_mpa = 0;
    4.79 -	if (d == dom0) dom_fw_base_mpa += dom0_start;
    4.80 -	imva_fw_base = domain_mpa_to_imva(d,dom_fw_base_mpa);
    4.81 -	bp = dom_fw_init(d,args,arglen,imva_fw_base,PAGE_SIZE);
    4.82 -	return dom_pa((unsigned long)bp);
    4.83 -}
    4.84 -
    4.85 -
    4.86 -/* the following heavily leveraged from linux/arch/ia64/hp/sim/fw-emu.c */
    4.87 -
    4.88 -#define MB	(1024*1024UL)
    4.89 -
    4.90 -#define NUM_EFI_SYS_TABLES 6
    4.91 -#define PASS_THRU_IOPORT_SPACE
    4.92 -#ifdef PASS_THRU_IOPORT_SPACE
    4.93 -# define NUM_MEM_DESCS	4
    4.94 -#else
    4.95 -# define NUM_MEM_DESCS	3
    4.96 -#endif
    4.97 -
    4.98 -
    4.99 -#define SECS_PER_HOUR   (60 * 60)
   4.100 -#define SECS_PER_DAY    (SECS_PER_HOUR * 24)
   4.101 -
   4.102 -/* Compute the `struct tm' representation of *T,
   4.103 -   offset OFFSET seconds east of UTC,
   4.104 -   and store year, yday, mon, mday, wday, hour, min, sec into *TP.
   4.105 -   Return nonzero if successful.  */
   4.106 -int
   4.107 -offtime (unsigned long t, efi_time_t *tp)
   4.108 -{
   4.109 -	const unsigned short int __mon_yday[2][13] =
   4.110 -	{
   4.111 -		/* Normal years.  */
   4.112 -		{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
   4.113 -		/* Leap years.  */
   4.114 -		{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
   4.115 -	};
   4.116 -	long int days, rem, y;
   4.117 -	const unsigned short int *ip;
   4.118 -
   4.119 -	days = t / SECS_PER_DAY;
   4.120 -	rem = t % SECS_PER_DAY;
   4.121 -	while (rem < 0) {
   4.122 -		rem += SECS_PER_DAY;
   4.123 -		--days;
   4.124 -	}
   4.125 -	while (rem >= SECS_PER_DAY) {
   4.126 -		rem -= SECS_PER_DAY;
   4.127 -		++days;
   4.128 -	}
   4.129 -	tp->hour = rem / SECS_PER_HOUR;
   4.130 -	rem %= SECS_PER_HOUR;
   4.131 -	tp->minute = rem / 60;
   4.132 -	tp->second = rem % 60;
   4.133 -	/* January 1, 1970 was a Thursday.  */
   4.134 -	y = 1970;
   4.135 -
   4.136 -#	define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
   4.137 -#	define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
   4.138 -#	define __isleap(year) \
   4.139 -	  ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
   4.140 -
   4.141 -	while (days < 0 || days >= (__isleap (y) ? 366 : 365)) {
   4.142 -		/* Guess a corrected year, assuming 365 days per year.  */
   4.143 -		long int yg = y + days / 365 - (days % 365 < 0);
   4.144 -
   4.145 -		/* Adjust DAYS and Y to match the guessed year.  */
   4.146 -		days -= ((yg - y) * 365 + LEAPS_THRU_END_OF (yg - 1)
   4.147 -			 - LEAPS_THRU_END_OF (y - 1));
   4.148 -		y = yg;
   4.149 -	}
   4.150 -	tp->year = y;
   4.151 -	ip = __mon_yday[__isleap(y)];
   4.152 -	for (y = 11; days < (long int) ip[y]; --y)
   4.153 -		continue;
   4.154 -	days -= ip[y];
   4.155 -	tp->month = y + 1;
   4.156 -	tp->day = days + 1;
   4.157 -	return 1;
   4.158 -}
   4.159 -
   4.160 -extern struct ia64_pal_retval pal_emulator_static (unsigned long);
   4.161 -
   4.162 -/* Macro to emulate SAL call using legacy IN and OUT calls to CF8, CFC etc.. */
   4.163 -
   4.164 -#define BUILD_CMD(addr)		((0x80000000 | (addr)) & ~3)
   4.165 -
   4.166 -#define REG_OFFSET(addr)	(0x00000000000000FF & (addr))
   4.167 -#define DEVICE_FUNCTION(addr)	(0x000000000000FF00 & (addr))
   4.168 -#define BUS_NUMBER(addr)	(0x0000000000FF0000 & (addr))
   4.169 -
   4.170 -#ifndef XEN
   4.171 -static efi_status_t
   4.172 -fw_efi_get_time (efi_time_t *tm, efi_time_cap_t *tc)
   4.173 -{
   4.174 -#if defined(CONFIG_IA64_HP_SIM) || defined(CONFIG_IA64_GENERIC)
   4.175 -	struct {
   4.176 -		int tv_sec;	/* must be 32bits to work */
   4.177 -		int tv_usec;
   4.178 -	} tv32bits;
   4.179 -
   4.180 -	ssc((unsigned long) &tv32bits, 0, 0, 0, SSC_GET_TOD);
   4.181 -
   4.182 -	memset(tm, 0, sizeof(*tm));
   4.183 -	offtime(tv32bits.tv_sec, tm);
   4.184 -
   4.185 -	if (tc)
   4.186 -		memset(tc, 0, sizeof(*tc));
   4.187 -#else
   4.188 -#	error Not implemented yet...
   4.189 -#endif
   4.190 -	return EFI_SUCCESS;
   4.191 -}
   4.192 -
   4.193 -static void
   4.194 -efi_reset_system (int reset_type, efi_status_t status, unsigned long data_size, efi_char16_t *data)
   4.195 -{
   4.196 -#if defined(CONFIG_IA64_HP_SIM) || defined(CONFIG_IA64_GENERIC)
   4.197 -	ssc(status, 0, 0, 0, SSC_EXIT);
   4.198 -#else
   4.199 -#	error Not implemented yet...
   4.200 -#endif
   4.201 -}
   4.202 -
   4.203 -static efi_status_t
   4.204 -efi_unimplemented (void)
   4.205 -{
   4.206 -	return EFI_UNSUPPORTED;
   4.207 -}
   4.208 -#endif /* !XEN */
   4.209 -
   4.210 -struct sal_ret_values
   4.211 -sal_emulator (long index, unsigned long in1, unsigned long in2,
   4.212 -	      unsigned long in3, unsigned long in4, unsigned long in5,
   4.213 -	      unsigned long in6, unsigned long in7)
   4.214 -{
   4.215 -	long r9  = 0;
   4.216 -	long r10 = 0;
   4.217 -	long r11 = 0;
   4.218 -	long status;
   4.219 -
   4.220 -	/*
   4.221 -	 * Don't do a "switch" here since that gives us code that
   4.222 -	 * isn't self-relocatable.
   4.223 -	 */
   4.224 -	status = 0;
   4.225 -	if (index == SAL_FREQ_BASE) {
   4.226 -		if (!running_on_sim)
   4.227 -			status = ia64_sal_freq_base(in1,&r9,&r10);
   4.228 -		else switch (in1) {
   4.229 -		      case SAL_FREQ_BASE_PLATFORM:
   4.230 -			r9 = 200000000;
   4.231 -			break;
   4.232 -
   4.233 -		      case SAL_FREQ_BASE_INTERVAL_TIMER:
   4.234 -			r9 = 700000000;
   4.235 -			break;
   4.236 -
   4.237 -		      case SAL_FREQ_BASE_REALTIME_CLOCK:
   4.238 -			r9 = 1;
   4.239 -			break;
   4.240 -
   4.241 -		      default:
   4.242 -			status = -1;
   4.243 -			break;
   4.244 -		}
   4.245 -	} else if (index == SAL_PCI_CONFIG_READ) {
   4.246 -		if (current->domain == dom0) {
   4.247 -			u64 value;
   4.248 -			// note that args 2&3 are swapped!!
   4.249 -			status = ia64_sal_pci_config_read(in1,in3,in2,&value);
   4.250 -			r9 = value;
   4.251 -		}
   4.252 -		else printf("NON-PRIV DOMAIN CALLED SAL_PCI_CONFIG_READ\n");
   4.253 -	} else if (index == SAL_PCI_CONFIG_WRITE) {
   4.254 -		if (current->domain == dom0) {
   4.255 -			if (((in1 & ~0xffffffffUL) && (in4 == 0)) ||
   4.256 -			    (in4 > 1) ||
   4.257 -			    (in2 > 8) || (in2 & (in2-1)))
   4.258 -			    	printf("*** SAL_PCI_CONF_WRITE?!?(adr=%p,typ=%p,sz=%p,val=%p)\n",in1,in4,in2,in3);
   4.259 -			// note that args are in a different order!!
   4.260 -			status = ia64_sal_pci_config_write(in1,in4,in2,in3);
   4.261 -		}
   4.262 -		else printf("NON-PRIV DOMAIN CALLED SAL_PCI_CONFIG_WRITE\n");
   4.263 -	} else if (index == SAL_SET_VECTORS) {
   4.264 -		printf("*** CALLED SAL_SET_VECTORS.  IGNORED...\n");
   4.265 -	} else if (index == SAL_GET_STATE_INFO) {
   4.266 -		printf("*** CALLED SAL_GET_STATE_INFO.  IGNORED...\n");
   4.267 -	} else if (index == SAL_GET_STATE_INFO_SIZE) {
   4.268 -		printf("*** CALLED SAL_GET_STATE_INFO_SIZE.  IGNORED...\n");
   4.269 -	} else if (index == SAL_CLEAR_STATE_INFO) {
   4.270 -		printf("*** CALLED SAL_CLEAR_STATE_INFO.  IGNORED...\n");
   4.271 -	} else if (index == SAL_MC_RENDEZ) {
   4.272 -		printf("*** CALLED SAL_MC_RENDEZ.  IGNORED...\n");
   4.273 -	} else if (index == SAL_MC_SET_PARAMS) {
   4.274 -		printf("*** CALLED SAL_MC_SET_PARAMS.  IGNORED...\n");
   4.275 -	} else if (index == SAL_CACHE_FLUSH) {
   4.276 -		printf("*** CALLED SAL_CACHE_FLUSH.  IGNORED...\n");
   4.277 -	} else if (index == SAL_CACHE_INIT) {
   4.278 -		printf("*** CALLED SAL_CACHE_INIT.  IGNORED...\n");
   4.279 -	} else if (index == SAL_UPDATE_PAL) {
   4.280 -		printf("*** CALLED SAL_UPDATE_PAL.  IGNORED...\n");
   4.281 -	} else {
   4.282 -		printf("*** CALLED SAL_ WITH UNKNOWN INDEX.  IGNORED...\n");
   4.283 -		status = -1;
   4.284 -	}
   4.285 -	return ((struct sal_ret_values) {status, r9, r10, r11});
   4.286 -}
   4.287 -
   4.288 -struct ia64_pal_retval
   4.289 -xen_pal_emulator(unsigned long index, unsigned long in1,
   4.290 -	unsigned long in2, unsigned long in3)
   4.291 -{
   4.292 -	long r9  = 0;
   4.293 -	long r10 = 0;
   4.294 -	long r11 = 0;
   4.295 -	long status = -1;
   4.296 -
   4.297 -#define USE_PAL_EMULATOR
   4.298 -#ifdef USE_PAL_EMULATOR
   4.299 -	return pal_emulator_static(index);
   4.300 -#endif
   4.301 -	if (running_on_sim) return pal_emulator_static(index);
   4.302 -	if (index >= PAL_COPY_PAL) {
   4.303 -		printk("xen_pal_emulator: UNIMPLEMENTED PAL CALL %d!!!!\n",
   4.304 -				index);
   4.305 -	}
   4.306 -	else switch (index) {
   4.307 -	    case PAL_MEM_ATTRIB:
   4.308 -		status = ia64_pal_mem_attrib(&r9);
   4.309 -		break;
   4.310 -	    case PAL_FREQ_BASE:
   4.311 -		status = ia64_pal_freq_base(&r9);
   4.312 -		break;
   4.313 -	    case PAL_PROC_GET_FEATURES:
   4.314 -		status = ia64_pal_proc_get_features(&r9,&r10,&r11);
   4.315 -		break;
   4.316 -	    case PAL_BUS_GET_FEATURES:
   4.317 -		status = ia64_pal_bus_get_features(&r9,&r10,&r11);
   4.318 -		break;
   4.319 -	    case PAL_FREQ_RATIOS:
   4.320 -		status = ia64_pal_freq_ratios(&r9,&r10,&r11);
   4.321 -		break;
   4.322 -	    case PAL_PTCE_INFO:
   4.323 -		{
   4.324 -			// return hard-coded xen-specific values because ptc.e
   4.325 -			// is emulated on xen to always flush everything
   4.326 -			// these values result in only one ptc.e instruction
   4.327 -			status = 0; r9 = 0; r10 = (1L << 32) | 1L; r11 = 0;
   4.328 -		}
   4.329 -		break;
   4.330 -	    case PAL_VERSION:
   4.331 -		status = ia64_pal_version(&r9,&r10);
   4.332 -		break;
   4.333 -	    case PAL_VM_PAGE_SIZE:
   4.334 -		status = ia64_pal_vm_page_size(&r9,&r10);
   4.335 -		break;
   4.336 -	    case PAL_DEBUG_INFO:
   4.337 -		status = ia64_pal_debug_info(&r9,&r10);
   4.338 -		break;
   4.339 -	    case PAL_CACHE_SUMMARY:
   4.340 -		status = ia64_pal_cache_summary(&r9,&r10);
   4.341 -		break;
   4.342 -	    case PAL_VM_SUMMARY:
   4.343 -		// FIXME: what should xen return for these, figure out later
   4.344 -		// For now, linux does the right thing if pal call fails
   4.345 -		// In particular, rid_size must be set properly!
   4.346 -		//status = ia64_pal_vm_summary(&r9,&r10);
   4.347 -		break;
   4.348 -	    case PAL_RSE_INFO:
   4.349 -		status = ia64_pal_rse_info(&r9,&r10);
   4.350 -		break;
   4.351 -	    case PAL_VM_INFO:
   4.352 -		status = ia64_pal_vm_info(in1,in2,&r9,&r10);
   4.353 -		break;
   4.354 -	    case PAL_REGISTER_INFO:
   4.355 -		status = ia64_pal_register_info(in1,&r9,&r10);
   4.356 -		break;
   4.357 -	    case PAL_CACHE_FLUSH:
   4.358 -		/* FIXME */
   4.359 -		printk("PAL_CACHE_FLUSH NOT IMPLEMENTED!\n");
   4.360 -		BUG();
   4.361 -		break;
   4.362 -	    case PAL_PERF_MON_INFO:
   4.363 -		{
   4.364 -			unsigned long pm_buffer[16];
   4.365 -			int i;
   4.366 -			status = ia64_pal_perf_mon_info(pm_buffer,&r9);
   4.367 -			if (status != 0) {
   4.368 -				while(1)
   4.369 -				printk("PAL_PERF_MON_INFO fails ret=%d\n",status);
   4.370 -				break;
   4.371 -			}
   4.372 -			if (copy_to_user((void __user *)in1,pm_buffer,128)) {
   4.373 -				while(1)
   4.374 -				printk("xen_pal_emulator: PAL_PERF_MON_INFO "
   4.375 -					"can't copy to user!!!!\n");
   4.376 -				status = -1;
   4.377 -				break;
   4.378 -			}
   4.379 -		}
   4.380 -		break;
   4.381 -	    case PAL_CACHE_INFO:
   4.382 -		{
   4.383 -			pal_cache_config_info_t ci;
   4.384 -			status = ia64_pal_cache_config_info(in1,in2,&ci);
   4.385 -			if (status != 0) break;
   4.386 -			r9 = ci.pcci_info_1.pcci1_data;
   4.387 -			r10 = ci.pcci_info_2.pcci2_data;
   4.388 -		}
   4.389 -		break;
   4.390 -	    case PAL_VM_TR_READ:	/* FIXME: vcpu_get_tr?? */
   4.391 -		printk("PAL_VM_TR_READ NOT IMPLEMENTED, IGNORED!\n");
   4.392 -		break;
   4.393 -	    case PAL_HALT_INFO:		/* inappropriate info for guest? */
   4.394 -		printk("PAL_HALT_INFO NOT IMPLEMENTED, IGNORED!\n");
   4.395 -		break;
   4.396 -	    default:
   4.397 -		printk("xen_pal_emulator: UNIMPLEMENTED PAL CALL %d!!!!\n",
   4.398 -				index);
   4.399 -		break;
   4.400 -	}
   4.401 -	return ((struct ia64_pal_retval) {status, r9, r10, r11});
   4.402 -}
   4.403 -
   4.404 -#define NFUNCPTRS 20
   4.405 -
   4.406 -void print_md(efi_memory_desc_t *md)
   4.407 -{
   4.408 -#if 1
   4.409 -	printk("domain mem: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n",
   4.410 -		md->type, md->attribute, md->phys_addr,
   4.411 -		md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
   4.412 -		md->num_pages >> (20 - EFI_PAGE_SHIFT));
   4.413 -#endif
   4.414 -}
   4.415 -
   4.416 -#define LSAPIC_NUM 16	// TEMP
   4.417 -static u32 lsapic_flag=1;
   4.418 -
   4.419 -/* Provide only one LP to guest */
   4.420 -static int 
   4.421 -acpi_update_lsapic (acpi_table_entry_header *header)
   4.422 -{
   4.423 -	struct acpi_table_lsapic *lsapic;
   4.424 -
   4.425 -	lsapic = (struct acpi_table_lsapic *) header;
   4.426 -	if (!lsapic)
   4.427 -		return -EINVAL;
   4.428 -
   4.429 -	if (lsapic->flags.enabled && lsapic_flag) {
   4.430 -		printk("enable lsapic entry: 0x%lx\n", (u64)lsapic);
   4.431 -		lsapic_flag = 0; /* disable all the following processros */
   4.432 -	} else if (lsapic->flags.enabled) {
   4.433 -		printk("DISABLE lsapic entry: 0x%lx\n", (u64)lsapic);
   4.434 -		lsapic->flags.enabled = 0;
   4.435 -	} else
   4.436 -		printk("lsapic entry is already disabled: 0x%lx\n", (u64)lsapic);
   4.437 -
   4.438 -	return 0;
   4.439 -}
   4.440 -
   4.441 -static int
   4.442 -acpi_update_madt_checksum (unsigned long phys_addr, unsigned long size)
   4.443 -{
   4.444 -	u8 checksum=0;
   4.445 -    	u8* ptr;
   4.446 -	int len;
   4.447 -	struct acpi_table_madt* acpi_madt;
   4.448 -
   4.449 -	if (!phys_addr || !size)
   4.450 -		return -EINVAL;
   4.451 -
   4.452 -	acpi_madt = (struct acpi_table_madt *) __va(phys_addr);
   4.453 -	acpi_madt->header.checksum=0;
   4.454 -
   4.455 -    	/* re-calculate MADT checksum */
   4.456 -	ptr = (u8*)acpi_madt;
   4.457 -    	len = acpi_madt->header.length;
   4.458 -	while (len>0){
   4.459 -		checksum = (u8)( checksum + (*ptr++) );
   4.460 -		len--;
   4.461 -	}
   4.462 -    	acpi_madt->header.checksum = 0x0 - checksum;	
   4.463 -	
   4.464 -	return 0;
   4.465 -}
   4.466 -
   4.467 -/* base is physical address of acpi table */
   4.468 -void touch_acpi_table(void)
   4.469 -{
   4.470 -	u64 count = 0;
   4.471 -	count = acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_update_lsapic, NR_CPUS);
   4.472 -	if ( count < 1)
   4.473 -		printk("Error parsing MADT - no LAPIC entires\n");
   4.474 -	printk("Total %d lsapic entry\n", count);
   4.475 -	acpi_table_parse(ACPI_APIC, acpi_update_madt_checksum);
   4.476 -
   4.477 -	return;
   4.478 -}
   4.479 -
   4.480 -
   4.481 -struct ia64_boot_param *
   4.482 -dom_fw_init (struct domain *d, char *args, int arglen, char *fw_mem, int fw_mem_size)
   4.483 -{
   4.484 -	efi_system_table_t *efi_systab;
   4.485 -	efi_runtime_services_t *efi_runtime;
   4.486 -	efi_config_table_t *efi_tables;
   4.487 -	struct ia64_sal_systab *sal_systab;
   4.488 -	efi_memory_desc_t *efi_memmap, *md;
   4.489 -	unsigned long *pal_desc, *sal_desc;
   4.490 -	struct ia64_sal_desc_entry_point *sal_ed;
   4.491 -	struct ia64_boot_param *bp;
   4.492 -	unsigned long *pfn;
   4.493 -	unsigned char checksum = 0;
   4.494 -	char *cp, *cmd_line, *fw_vendor;
   4.495 -	int i = 0;
   4.496 -	unsigned long maxmem = d->max_pages * PAGE_SIZE;
   4.497 -	unsigned long start_mpaddr = ((d==dom0)?dom0_start:0);
   4.498 -
   4.499 -#	define MAKE_MD(typ, attr, start, end, abs) 	\	
   4.500 -	do {						\
   4.501 -		md = efi_memmap + i++;			\
   4.502 -		md->type = typ;				\
   4.503 -		md->pad = 0;				\
   4.504 -		md->phys_addr = abs ? start : start_mpaddr + start;	\
   4.505 -		md->virt_addr = 0;			\
   4.506 -		md->num_pages = (end - start) >> 12;	\
   4.507 -		md->attribute = attr;			\
   4.508 -		print_md(md);				\
   4.509 -	} while (0)
   4.510 -
   4.511 -/* FIXME: should check size but for now we have a whole MB to play with.
   4.512 -   And if stealing code from fw-emu.c, watch out for new fw_vendor on the end!
   4.513 -	if (fw_mem_size < sizeof(fw_mem_proto)) {
   4.514 -		printf("sys_fw_init: insufficient space for fw_mem\n");
   4.515 -		return 0;
   4.516 -	}
   4.517 -*/
   4.518 -	memset(fw_mem, 0, fw_mem_size);
   4.519 -
   4.520 -#ifdef XEN
   4.521 -#else
   4.522 -	pal_desc = (unsigned long *) &pal_emulator_static;
   4.523 -	sal_desc = (unsigned long *) &sal_emulator;
   4.524 -#endif
   4.525 -
   4.526 -	cp = fw_mem;
   4.527 -	efi_systab  = (void *) cp; cp += sizeof(*efi_systab);
   4.528 -	efi_runtime = (void *) cp; cp += sizeof(*efi_runtime);
   4.529 -	efi_tables  = (void *) cp; cp += NUM_EFI_SYS_TABLES * sizeof(*efi_tables);
   4.530 -	sal_systab  = (void *) cp; cp += sizeof(*sal_systab);
   4.531 -	sal_ed      = (void *) cp; cp += sizeof(*sal_ed);
   4.532 -	efi_memmap  = (void *) cp; cp += NUM_MEM_DESCS*sizeof(*efi_memmap);
   4.533 -	bp	    = (void *) cp; cp += sizeof(*bp);
   4.534 -	pfn        = (void *) cp; cp += NFUNCPTRS * 2 * sizeof(pfn);
   4.535 -	cmd_line    = (void *) cp;
   4.536 -
   4.537 -	if (args) {
   4.538 -		if (arglen >= 1024)
   4.539 -			arglen = 1023;
   4.540 -		memcpy(cmd_line, args, arglen);
   4.541 -	} else {
   4.542 -		arglen = 0;
   4.543 -	}
   4.544 -	cmd_line[arglen] = '\0';
   4.545 -
   4.546 -	memset(efi_systab, 0, sizeof(efi_systab));
   4.547 -	efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
   4.548 -	efi_systab->hdr.revision  = EFI_SYSTEM_TABLE_REVISION;
   4.549 -	efi_systab->hdr.headersize = sizeof(efi_systab->hdr);
   4.550 -	cp = fw_vendor = &cmd_line[arglen] + (2-(arglen&1)); // round to 16-bit boundary
   4.551 -#define FW_VENDOR "X\0e\0n\0/\0i\0a\0\066\0\064\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
   4.552 -	cp += sizeof(FW_VENDOR) + (8-((unsigned long)cp & 7)); // round to 64-bit boundary
   4.553 -
   4.554 -	memcpy(fw_vendor,FW_VENDOR,sizeof(FW_VENDOR));
   4.555 -	efi_systab->fw_vendor = dom_pa(fw_vendor);
   4.556 -	
   4.557 -	efi_systab->fw_revision = 1;
   4.558 -	efi_systab->runtime = (void *) dom_pa(efi_runtime);
   4.559 -	efi_systab->nr_tables = NUM_EFI_SYS_TABLES;
   4.560 -	efi_systab->tables = dom_pa(efi_tables);
   4.561 -
   4.562 -	efi_runtime->hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE;
   4.563 -	efi_runtime->hdr.revision = EFI_RUNTIME_SERVICES_REVISION;
   4.564 -	efi_runtime->hdr.headersize = sizeof(efi_runtime->hdr);
   4.565 -#define EFI_HYPERCALL_PATCH(tgt,call) do { \
   4.566 -    dom_efi_hypercall_patch(d,FW_HYPERCALL_##call##_PADDR,FW_HYPERCALL_##call); \
   4.567 -    tgt = dom_pa(pfn); \
   4.568 -    *pfn++ = FW_HYPERCALL_##call##_PADDR + ((d==dom0)?dom0_start:0); \
   4.569 -    *pfn++ = 0; \
   4.570 -    } while (0)
   4.571 -
   4.572 -	EFI_HYPERCALL_PATCH(efi_runtime->get_time,EFI_GET_TIME);
   4.573 -	EFI_HYPERCALL_PATCH(efi_runtime->set_time,EFI_SET_TIME);
   4.574 -	EFI_HYPERCALL_PATCH(efi_runtime->get_wakeup_time,EFI_GET_WAKEUP_TIME);
   4.575 -	EFI_HYPERCALL_PATCH(efi_runtime->set_wakeup_time,EFI_SET_WAKEUP_TIME);
   4.576 -	EFI_HYPERCALL_PATCH(efi_runtime->set_virtual_address_map,EFI_SET_VIRTUAL_ADDRESS_MAP);
   4.577 -	EFI_HYPERCALL_PATCH(efi_runtime->get_variable,EFI_GET_VARIABLE);
   4.578 -	EFI_HYPERCALL_PATCH(efi_runtime->get_next_variable,EFI_GET_NEXT_VARIABLE);
   4.579 -	EFI_HYPERCALL_PATCH(efi_runtime->set_variable,EFI_SET_VARIABLE);
   4.580 -	EFI_HYPERCALL_PATCH(efi_runtime->get_next_high_mono_count,EFI_GET_NEXT_HIGH_MONO_COUNT);
   4.581 -	EFI_HYPERCALL_PATCH(efi_runtime->reset_system,EFI_RESET_SYSTEM);
   4.582 -
   4.583 -	efi_tables[0].guid = SAL_SYSTEM_TABLE_GUID;
   4.584 -	efi_tables[0].table = dom_pa(sal_systab);
   4.585 -	for (i = 1; i < NUM_EFI_SYS_TABLES; i++) {
   4.586 -		efi_tables[i].guid = NULL_GUID;
   4.587 -		efi_tables[i].table = 0;
   4.588 -	}
   4.589 -	if (d == dom0) {
   4.590 -		printf("Domain0 EFI passthrough:");
   4.591 -		i = 1;
   4.592 -		if (efi.mps) {
   4.593 -			efi_tables[i].guid = MPS_TABLE_GUID;
   4.594 -			efi_tables[i].table = __pa(efi.mps);
   4.595 -			printf(" MPS=%0xlx",efi_tables[i].table);
   4.596 -			i++;
   4.597 -		}
   4.598 -
   4.599 -		touch_acpi_table();
   4.600 -
   4.601 -		if (efi.acpi20) {
   4.602 -			efi_tables[i].guid = ACPI_20_TABLE_GUID;
   4.603 -			efi_tables[i].table = __pa(efi.acpi20);
   4.604 -			printf(" ACPI 2.0=%0xlx",efi_tables[i].table);
   4.605 -			i++;
   4.606 -		}
   4.607 -		if (efi.acpi) {
   4.608 -			efi_tables[i].guid = ACPI_TABLE_GUID;
   4.609 -			efi_tables[i].table = __pa(efi.acpi);
   4.610 -			printf(" ACPI=%0xlx",efi_tables[i].table);
   4.611 -			i++;
   4.612 -		}
   4.613 -		if (efi.smbios) {
   4.614 -			efi_tables[i].guid = SMBIOS_TABLE_GUID;
   4.615 -			efi_tables[i].table = __pa(efi.smbios);
   4.616 -			printf(" SMBIOS=%0xlx",efi_tables[i].table);
   4.617 -			i++;
   4.618 -		}
   4.619 -		if (efi.hcdp) {
   4.620 -			efi_tables[i].guid = HCDP_TABLE_GUID;
   4.621 -			efi_tables[i].table = __pa(efi.hcdp);
   4.622 -			printf(" HCDP=%0xlx",efi_tables[i].table);
   4.623 -			i++;
   4.624 -		}
   4.625 -		printf("\n");
   4.626 -	}
   4.627 -
   4.628 -	/* fill in the SAL system table: */
   4.629 -	memcpy(sal_systab->signature, "SST_", 4);
   4.630 -	sal_systab->size = sizeof(*sal_systab);
   4.631 -	sal_systab->sal_rev_minor = 1;
   4.632 -	sal_systab->sal_rev_major = 0;
   4.633 -	sal_systab->entry_count = 1;
   4.634 -
   4.635 -	strcpy(sal_systab->oem_id, "Xen/ia64");
   4.636 -	strcpy(sal_systab->product_id, "Xen/ia64");
   4.637 -
   4.638 -	/* fill in an entry point: */
   4.639 -	sal_ed->type = SAL_DESC_ENTRY_POINT;
   4.640 -#define FW_HYPERCALL_PATCH(tgt,call,ret) do { \
   4.641 -    dom_fw_hypercall_patch(d,FW_HYPERCALL_##call##_PADDR,FW_HYPERCALL_##call,ret); \
   4.642 -    tgt = FW_HYPERCALL_##call##_PADDR + ((d==dom0)?dom0_start:0); \
   4.643 -    } while (0)
   4.644 -	FW_HYPERCALL_PATCH(sal_ed->pal_proc,PAL_CALL,0);
   4.645 -	FW_HYPERCALL_PATCH(sal_ed->sal_proc,SAL_CALL,1);
   4.646 -	sal_ed->gp = 0;  // will be ignored
   4.647 -
   4.648 -	for (cp = (char *) sal_systab; cp < (char *) efi_memmap; ++cp)
   4.649 -		checksum += *cp;
   4.650 -
   4.651 -	sal_systab->checksum = -checksum;
   4.652 -
   4.653 -	/* simulate 1MB free memory at physical address zero */
   4.654 -	i = 0;
   4.655 -	MAKE_MD(EFI_BOOT_SERVICES_DATA,EFI_MEMORY_WB,0*MB,1*MB, 0);
   4.656 -	/* hypercall patches live here, masquerade as reserved PAL memory */
   4.657 -	MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB,HYPERCALL_START,HYPERCALL_END, 0);
   4.658 -	MAKE_MD(EFI_CONVENTIONAL_MEMORY,EFI_MEMORY_WB,HYPERCALL_END,maxmem, 0);
   4.659 -#ifdef PASS_THRU_IOPORT_SPACE
   4.660 -	if (d == dom0 && !running_on_sim) {
   4.661 -		/* pass through the I/O port space */
   4.662 -		efi_memory_desc_t *efi_get_io_md(void);
   4.663 -		efi_memory_desc_t *ia64_efi_io_md = efi_get_io_md();
   4.664 -		u32 type;
   4.665 -		u64 iostart, ioend, ioattr;
   4.666 -		
   4.667 -		type = ia64_efi_io_md->type;
   4.668 -		iostart = ia64_efi_io_md->phys_addr;
   4.669 -		ioend = ia64_efi_io_md->phys_addr +
   4.670 -			(ia64_efi_io_md->num_pages << 12);
   4.671 -		ioattr = ia64_efi_io_md->attribute;
   4.672 -		MAKE_MD(type,ioattr,iostart,ioend, 1);
   4.673 -	}
   4.674 -	else
   4.675 -		MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0);
   4.676 -#endif
   4.677 -
   4.678 -	bp->efi_systab = dom_pa(fw_mem);
   4.679 -	bp->efi_memmap = dom_pa(efi_memmap);
   4.680 -	bp->efi_memmap_size = NUM_MEM_DESCS*sizeof(efi_memory_desc_t);
   4.681 -	bp->efi_memdesc_size = sizeof(efi_memory_desc_t);
   4.682 -	bp->efi_memdesc_version = 1;
   4.683 -	bp->command_line = dom_pa(cmd_line);
   4.684 -	bp->console_info.num_cols = 80;
   4.685 -	bp->console_info.num_rows = 25;
   4.686 -	bp->console_info.orig_x = 0;
   4.687 -	bp->console_info.orig_y = 24;
   4.688 -	bp->fpswa = 0;
   4.689 -
   4.690 -	return bp;
   4.691 -}
     5.1 --- a/xen/arch/ia64/domain.c	Thu Sep 01 11:09:27 2005 -0600
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,1103 +0,0 @@
     5.4 -/*
     5.5 - *  Copyright (C) 1995  Linus Torvalds
     5.6 - *
     5.7 - *  Pentium III FXSR, SSE support
     5.8 - *	Gareth Hughes <gareth@valinux.com>, May 2000
     5.9 - *
    5.10 - *  Copyright (C) 2005 Intel Co
    5.11 - *	Kun Tian (Kevin Tian) <kevin.tian@intel.com>
    5.12 - *
    5.13 - * 05/04/29 Kun Tian (Kevin Tian) <kevin.tian@intel.com> Add CONFIG_VTI domain support
    5.14 - */
    5.15 -
    5.16 -#include <xen/config.h>
    5.17 -#include <xen/lib.h>
    5.18 -#include <xen/errno.h>
    5.19 -#include <xen/sched.h>
    5.20 -#include <xen/smp.h>
    5.21 -#include <xen/delay.h>
    5.22 -#include <xen/softirq.h>
    5.23 -#include <xen/mm.h>
    5.24 -#include <asm/ptrace.h>
    5.25 -#include <asm/system.h>
    5.26 -#include <asm/io.h>
    5.27 -#include <asm/processor.h>
    5.28 -#include <asm/desc.h>
    5.29 -//#include <asm/mpspec.h>
    5.30 -#include <xen/irq.h>
    5.31 -#include <xen/event.h>
    5.32 -//#include <xen/shadow.h>
    5.33 -#include <xen/console.h>
    5.34 -
    5.35 -#include <xen/elf.h>
    5.36 -//#include <asm/page.h>
    5.37 -#include <asm/pgalloc.h>
    5.38 -#include <asm/dma.h>	/* for MAX_DMA_ADDRESS */
    5.39 -
    5.40 -#include <asm/asm-offsets.h>  /* for IA64_THREAD_INFO_SIZE */
    5.41 -
    5.42 -#include <asm/vcpu.h>   /* for function declarations */
    5.43 -#include <public/arch-ia64.h>
    5.44 -#include <asm/vmx.h>
    5.45 -#include <asm/vmx_vcpu.h>
    5.46 -#include <asm/vmx_vpd.h>
    5.47 -#include <asm/pal.h>
    5.48 -#include <public/io/ioreq.h>
    5.49 -
    5.50 -#define CONFIG_DOMAIN0_CONTIGUOUS
    5.51 -unsigned long dom0_start = -1L;
    5.52 -unsigned long dom0_size = 512*1024*1024; //FIXME: Should be configurable
    5.53 -//FIXME: alignment should be 256MB, lest Linux use a 256MB page size
    5.54 -unsigned long dom0_align = 256*1024*1024;
    5.55 -#ifdef DOMU_BUILD_STAGING
    5.56 -unsigned long domU_staging_size = 32*1024*1024; //FIXME: Should be configurable
    5.57 -unsigned long domU_staging_start;
    5.58 -unsigned long domU_staging_align = 64*1024;
    5.59 -unsigned long *domU_staging_area;
    5.60 -#endif
    5.61 -
    5.62 -// initialized by arch/ia64/setup.c:find_initrd()
    5.63 -unsigned long initrd_start = 0, initrd_end = 0;
    5.64 -
    5.65 -#define IS_XEN_ADDRESS(d,a) ((a >= d->xen_vastart) && (a <= d->xen_vaend))
    5.66 -
    5.67 -//extern int loadelfimage(char *);
    5.68 -extern int readelfimage_base_and_size(char *, unsigned long,
    5.69 -	              unsigned long *, unsigned long *, unsigned long *);
    5.70 -
    5.71 -unsigned long map_domain_page0(struct domain *);
    5.72 -extern unsigned long dom_fw_setup(struct domain *, char *, int);
    5.73 -
    5.74 -/* this belongs in include/asm, but there doesn't seem to be a suitable place */
    5.75 -void free_perdomain_pt(struct domain *d)
    5.76 -{
    5.77 -	printf("free_perdomain_pt: not implemented\n");
    5.78 -	//free_page((unsigned long)d->mm.perdomain_pt);
    5.79 -}
    5.80 -
    5.81 -int hlt_counter;
    5.82 -
    5.83 -void disable_hlt(void)
    5.84 -{
    5.85 -	hlt_counter++;
    5.86 -}
    5.87 -
    5.88 -void enable_hlt(void)
    5.89 -{
    5.90 -	hlt_counter--;
    5.91 -}
    5.92 -
    5.93 -static void default_idle(void)
    5.94 -{
    5.95 -	if ( hlt_counter == 0 )
    5.96 -	{
    5.97 -	local_irq_disable();
    5.98 -	    if ( !softirq_pending(smp_processor_id()) )
    5.99 -	        safe_halt();
   5.100 -	    //else
   5.101 -		local_irq_enable();
   5.102 -	}
   5.103 -}
   5.104 -
   5.105 -void continue_cpu_idle_loop(void)
   5.106 -{
   5.107 -	int cpu = smp_processor_id();
   5.108 -	for ( ; ; )
   5.109 -	{
   5.110 -#ifdef IA64
   5.111 -//        __IRQ_STAT(cpu, idle_timestamp) = jiffies
   5.112 -#else
   5.113 -	    irq_stat[cpu].idle_timestamp = jiffies;
   5.114 -#endif
   5.115 -	    while ( !softirq_pending(cpu) )
   5.116 -	        default_idle();
   5.117 -	    raise_softirq(SCHEDULE_SOFTIRQ);
   5.118 -	    do_softirq();
   5.119 -	}
   5.120 -}
   5.121 -
   5.122 -void startup_cpu_idle_loop(void)
   5.123 -{
   5.124 -	/* Just some sanity to ensure that the scheduler is set up okay. */
   5.125 -	ASSERT(current->domain == IDLE_DOMAIN_ID);
   5.126 -	raise_softirq(SCHEDULE_SOFTIRQ);
   5.127 -	do_softirq();
   5.128 -
   5.129 -	/*
   5.130 -	 * Declares CPU setup done to the boot processor.
   5.131 -	 * Therefore memory barrier to ensure state is visible.
   5.132 -	 */
   5.133 -	smp_mb();
   5.134 -#if 0
   5.135 -//do we have to ensure the idle task has a shared page so that, for example,
   5.136 -//region registers can be loaded from it.  Apparently not...
   5.137 -	idle0_task.shared_info = (void *)alloc_xenheap_page();
   5.138 -	memset(idle0_task.shared_info, 0, PAGE_SIZE);
   5.139 -	/* pin mapping */
   5.140 -	// FIXME: Does this belong here?  Or do only at domain switch time?
   5.141 -	{
   5.142 -		/* WARNING: following must be inlined to avoid nested fault */
   5.143 -		unsigned long psr = ia64_clear_ic();
   5.144 -		ia64_itr(0x2, IA64_TR_SHARED_INFO, SHAREDINFO_ADDR,
   5.145 -		 pte_val(pfn_pte(ia64_tpa(idle0_task.shared_info) >> PAGE_SHIFT, PAGE_KERNEL)),
   5.146 -		 PAGE_SHIFT);
   5.147 -		ia64_set_psr(psr);
   5.148 -		ia64_srlz_i();
   5.149 -	}
   5.150 -#endif
   5.151 -
   5.152 -	continue_cpu_idle_loop();
   5.153 -}
   5.154 -
   5.155 -struct vcpu *arch_alloc_vcpu_struct(void)
   5.156 -{
   5.157 -	/* Per-vp stack is used here. So we need keep vcpu
   5.158 -	 * same page as per-vp stack */
   5.159 -	return alloc_xenheap_pages(KERNEL_STACK_SIZE_ORDER);
   5.160 -}
   5.161 -
   5.162 -void arch_free_vcpu_struct(struct vcpu *v)
   5.163 -{
   5.164 -	free_xenheap_pages(v, KERNEL_STACK_SIZE_ORDER);
   5.165 -}
   5.166 -
   5.167 -static void init_switch_stack(struct vcpu *v)
   5.168 -{
   5.169 -	struct pt_regs *regs = (struct pt_regs *) ((unsigned long) v + IA64_STK_OFFSET) - 1;
   5.170 -	struct switch_stack *sw = (struct switch_stack *) regs - 1;
   5.171 -	extern void ia64_ret_from_clone;
   5.172 -
   5.173 -	memset(sw, 0, sizeof(struct switch_stack) + sizeof(struct pt_regs));
   5.174 -	sw->ar_bspstore = (unsigned long)v + IA64_RBS_OFFSET;
   5.175 -	sw->b0 = (unsigned long) &ia64_ret_from_clone;
   5.176 -	sw->ar_fpsr = FPSR_DEFAULT;
   5.177 -	v->arch._thread.ksp = (unsigned long) sw - 16;
   5.178 -	// stay on kernel stack because may get interrupts!
   5.179 -	// ia64_ret_from_clone (which b0 gets in new_thread) switches
   5.180 -	// to user stack
   5.181 -	v->arch._thread.on_ustack = 0;
   5.182 -	memset(v->arch._thread.fph,0,sizeof(struct ia64_fpreg)*96);
   5.183 -}
   5.184 -
   5.185 -void arch_do_createdomain(struct vcpu *v)
   5.186 -{
   5.187 -	struct domain *d = v->domain;
   5.188 -	struct thread_info *ti = alloc_thread_info(v);
   5.189 -
   5.190 -	/* Clear thread_info to clear some important fields, like preempt_count */
   5.191 -	memset(ti, 0, sizeof(struct thread_info));
   5.192 -	init_switch_stack(v);
   5.193 -
   5.194 -	d->shared_info = (void *)alloc_xenheap_page();
   5.195 -	if (!d->shared_info) {
   5.196 -   		printk("ERROR/HALTING: CAN'T ALLOC PAGE\n");
   5.197 -   		while (1);
   5.198 -	}
   5.199 -	memset(d->shared_info, 0, PAGE_SIZE);
   5.200 -	d->shared_info->vcpu_data[0].arch.privregs = 
   5.201 -			alloc_xenheap_pages(get_order(sizeof(mapped_regs_t)));
   5.202 -	printf("arch_vcpu_info=%p\n", d->shared_info->vcpu_data[0].arch.privregs);
   5.203 -	memset(d->shared_info->vcpu_data[0].arch.privregs, 0, PAGE_SIZE);
   5.204 -	v->vcpu_info = &(d->shared_info->vcpu_data[0]);
   5.205 -
   5.206 -	d->max_pages = (128UL*1024*1024)/PAGE_SIZE; // 128MB default // FIXME
   5.207 -
   5.208 -#ifdef CONFIG_VTI
   5.209 -	/* Per-domain vTLB and vhpt implementation. Now vmx domain will stick
   5.210 -	 * to this solution. Maybe it can be deferred until we know created
   5.211 -	 * one as vmx domain */
   5.212 -	v->arch.vtlb = init_domain_tlb(v);
   5.213 -#endif
   5.214 -
   5.215 -	/* We may also need emulation rid for region4, though it's unlikely
   5.216 -	 * to see guest issue uncacheable access in metaphysical mode. But
   5.217 -	 * keep such info here may be more sane.
   5.218 -	 */
   5.219 -	if (((d->arch.metaphysical_rr0 = allocate_metaphysical_rr()) == -1UL)
   5.220 -	 || ((d->arch.metaphysical_rr4 = allocate_metaphysical_rr()) == -1UL))
   5.221 -		BUG();
   5.222 -	VCPU(v, metaphysical_mode) = 1;
   5.223 -	v->arch.metaphysical_rr0 = d->arch.metaphysical_rr0;
   5.224 -	v->arch.metaphysical_rr4 = d->arch.metaphysical_rr4;
   5.225 -	v->arch.metaphysical_saved_rr0 = d->arch.metaphysical_rr0;
   5.226 -	v->arch.metaphysical_saved_rr4 = d->arch.metaphysical_rr4;
   5.227 -#define DOMAIN_RID_BITS_DEFAULT 18
   5.228 -	if (!allocate_rid_range(d,DOMAIN_RID_BITS_DEFAULT)) // FIXME
   5.229 -		BUG();
   5.230 -	v->arch.starting_rid = d->arch.starting_rid;
   5.231 -	v->arch.ending_rid = d->arch.ending_rid;
   5.232 -	// the following will eventually need to be negotiated dynamically
   5.233 -	d->xen_vastart = XEN_START_ADDR;
   5.234 -	d->xen_vaend = XEN_END_ADDR;
   5.235 -	d->shared_info_va = SHAREDINFO_ADDR;
   5.236 -	d->arch.breakimm = 0x1000;
   5.237 -	v->arch.breakimm = d->arch.breakimm;
   5.238 -
   5.239 -	d->arch.mm = xmalloc(struct mm_struct);
   5.240 -	if (unlikely(!d->arch.mm)) {
   5.241 -		printk("Can't allocate mm_struct for domain %d\n",d->domain_id);
   5.242 -		return -ENOMEM;
   5.243 -	}
   5.244 -	memset(d->arch.mm, 0, sizeof(*d->arch.mm));
   5.245 -	d->arch.mm->pgd = pgd_alloc(d->arch.mm);
   5.246 -	if (unlikely(!d->arch.mm->pgd)) {
   5.247 -		printk("Can't allocate pgd for domain %d\n",d->domain_id);
   5.248 -		return -ENOMEM;
   5.249 -	}
   5.250 -}
   5.251 -
   5.252 -void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c)
   5.253 -{
   5.254 -	struct pt_regs *regs = (struct pt_regs *) ((unsigned long) v + IA64_STK_OFFSET) - 1;
   5.255 -
   5.256 -	printf("arch_getdomaininfo_ctxt\n");
   5.257 -	c->regs = *regs;
   5.258 -	c->vcpu.evtchn_vector = v->vcpu_info->arch.evtchn_vector;
   5.259 -#if 0
   5.260 -	if (c->vcpu.privregs && copy_to_user(c->vcpu.privregs,
   5.261 -			v->vcpu_info->arch.privregs, sizeof(mapped_regs_t))) {
   5.262 -		printk("Bad ctxt address: 0x%lx\n", c->vcpu.privregs);
   5.263 -		return -EFAULT;
   5.264 -	}
   5.265 -#endif
   5.266 -
   5.267 -	c->shared = v->domain->shared_info->arch;
   5.268 -}
   5.269 -
   5.270 -int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c)
   5.271 -{
   5.272 -	struct pt_regs *regs = (struct pt_regs *) ((unsigned long) v + IA64_STK_OFFSET) - 1;
   5.273 -	struct domain *d = v->domain;
   5.274 -	int i, rc, ret;
   5.275 -	unsigned long progress = 0;
   5.276 -
   5.277 -	printf("arch_set_info_guest\n");
   5.278 -	if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
   5.279 -            return 0;
   5.280 -
   5.281 -	if (c->flags & VGCF_VMX_GUEST) {
   5.282 -	    if (!vmx_enabled) {
   5.283 -		printk("No VMX hardware feature for vmx domain.\n");
   5.284 -		return -EINVAL;
   5.285 -	    }
   5.286 -
   5.287 -	    vmx_setup_platform(v, c);
   5.288 -	}
   5.289 -
   5.290 -	*regs = c->regs;
   5.291 -	new_thread(v, regs->cr_iip, 0, 0);
   5.292 -
   5.293 - 	v->vcpu_info->arch.evtchn_vector = c->vcpu.evtchn_vector;
   5.294 -	if ( c->vcpu.privregs && copy_from_user(v->vcpu_info->arch.privregs,
   5.295 -			   c->vcpu.privregs, sizeof(mapped_regs_t))) {
   5.296 -	    printk("Bad ctxt address in arch_set_info_guest: 0x%lx\n", c->vcpu.privregs);
   5.297 -	    return -EFAULT;
   5.298 -	}
   5.299 -
   5.300 -	v->arch.domain_itm_last = -1L;
   5.301 -	d->shared_info->arch = c->shared;
   5.302 -
   5.303 -	/* Don't redo final setup */
   5.304 -	set_bit(_VCPUF_initialised, &v->vcpu_flags);
   5.305 -	return 0;
   5.306 -}
   5.307 -
   5.308 -void arch_do_boot_vcpu(struct vcpu *v)
   5.309 -{
   5.310 -	struct domain *d = v->domain;
   5.311 -	printf("arch_do_boot_vcpu: not implemented\n");
   5.312 -
   5.313 -	d->shared_info->vcpu_data[v->vcpu_id].arch.privregs = 
   5.314 -			alloc_xenheap_pages(get_order(sizeof(mapped_regs_t)));
   5.315 -	printf("arch_vcpu_info=%p\n", d->shared_info->vcpu_data[v->vcpu_id].arch.privregs);
   5.316 -	memset(d->shared_info->vcpu_data[v->vcpu_id].arch.privregs, 0, PAGE_SIZE);
   5.317 -	return;
   5.318 -}
   5.319 -
   5.320 -void domain_relinquish_resources(struct domain *d)
   5.321 -{
   5.322 -	/* FIXME */
   5.323 -	printf("domain_relinquish_resources: not implemented\n");
   5.324 -}
   5.325 -
   5.326 -// heavily leveraged from linux/arch/ia64/kernel/process.c:copy_thread()
   5.327 -// and linux/arch/ia64/kernel/process.c:kernel_thread()
   5.328 -void new_thread(struct vcpu *v,
   5.329 -                unsigned long start_pc,
   5.330 -                unsigned long start_stack,
   5.331 -                unsigned long start_info)
   5.332 -{
   5.333 -	struct domain *d = v->domain;
   5.334 -	struct pt_regs *regs;
   5.335 -	struct ia64_boot_param *bp;
   5.336 -	extern char saved_command_line[];
   5.337 -
   5.338 -
   5.339 -#ifdef CONFIG_DOMAIN0_CONTIGUOUS
   5.340 -	if (d == dom0) start_pc += dom0_start;
   5.341 -#endif
   5.342 -
   5.343 -	regs = (struct pt_regs *) ((unsigned long) v + IA64_STK_OFFSET) - 1;
   5.344 -	if (VMX_DOMAIN(v)) {
   5.345 -		/* dt/rt/it:1;i/ic:1, si:1, vm/bn:1, ac:1 */
   5.346 -		regs->cr_ipsr = 0x501008826008; /* Need to be expanded as macro */
   5.347 -	} else {
   5.348 -		regs->cr_ipsr = ia64_getreg(_IA64_REG_PSR)
   5.349 -			| IA64_PSR_BITS_TO_SET | IA64_PSR_BN
   5.350 -			& ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_RI | IA64_PSR_IS);
   5.351 -		regs->cr_ipsr |= 2UL << IA64_PSR_CPL0_BIT; // domain runs at PL2
   5.352 -	}
   5.353 -	regs->cr_iip = start_pc;
   5.354 -	regs->cr_ifs = 1UL << 63; /* or clear? */
   5.355 -	regs->ar_fpsr = FPSR_DEFAULT;
   5.356 -
   5.357 -	if (VMX_DOMAIN(v)) {
   5.358 -#ifdef CONFIG_VTI
   5.359 -		vmx_init_all_rr(v);
   5.360 -		if (d == dom0)
   5.361 -		    VMX_VPD(v,vgr[12]) = dom_fw_setup(d,saved_command_line,256L);
   5.362 -		/* Virtual processor context setup */
   5.363 -		VMX_VPD(v, vpsr) = IA64_PSR_BN;
   5.364 -		VPD_CR(v, dcr) = 0;
   5.365 -#endif
   5.366 -	} else {
   5.367 -		init_all_rr(v);
   5.368 -		if (d == dom0) 
   5.369 -		    regs->r28 = dom_fw_setup(d,saved_command_line,256L);
   5.370 -		else {
   5.371 -		    regs->ar_rsc |= (2 << 2); /* force PL2/3 */
   5.372 -		    regs->r28 = dom_fw_setup(d,"nomca nosmp xencons=tty0 console=tty0 root=/dev/hda1",256L);  //FIXME
   5.373 -		}
   5.374 -		VCPU(v, banknum) = 1;
   5.375 -		VCPU(v, metaphysical_mode) = 1;
   5.376 -		d->shared_info->arch.flags = (d == dom0) ? (SIF_INITDOMAIN|SIF_PRIVILEGED|SIF_BLK_BE_DOMAIN|SIF_NET_BE_DOMAIN|SIF_USB_BE_DOMAIN) : 0;
   5.377 -	}
   5.378 -}
   5.379 -
   5.380 -static struct page * map_new_domain0_page(unsigned long mpaddr)
   5.381 -{
   5.382 -	if (mpaddr < dom0_start || mpaddr >= dom0_start + dom0_size) {
   5.383 -		printk("map_new_domain0_page: bad domain0 mpaddr %p!\n",mpaddr);
   5.384 -printk("map_new_domain0_page: start=%p,end=%p!\n",dom0_start,dom0_start+dom0_size);
   5.385 -		while(1);
   5.386 -	}
   5.387 -	return pfn_to_page((mpaddr >> PAGE_SHIFT));
   5.388 -}
   5.389 -
   5.390 -/* allocate new page for domain and map it to the specified metaphysical addr */
   5.391 -struct page * map_new_domain_page(struct domain *d, unsigned long mpaddr)
   5.392 -{
   5.393 -	struct mm_struct *mm = d->arch.mm;
   5.394 -	struct page *p = (struct page *)0;
   5.395 -	pgd_t *pgd;
   5.396 -	pud_t *pud;
   5.397 -	pmd_t *pmd;
   5.398 -	pte_t *pte;
   5.399 -extern unsigned long vhpt_paddr, vhpt_pend;
   5.400 -
   5.401 -	if (!mm->pgd) {
   5.402 -		printk("map_new_domain_page: domain pgd must exist!\n");
   5.403 -		return(p);
   5.404 -	}
   5.405 -	pgd = pgd_offset(mm,mpaddr);
   5.406 -	if (pgd_none(*pgd))
   5.407 -		pgd_populate(mm, pgd, pud_alloc_one(mm,mpaddr));
   5.408 -
   5.409 -	pud = pud_offset(pgd, mpaddr);
   5.410 -	if (pud_none(*pud))
   5.411 -		pud_populate(mm, pud, pmd_alloc_one(mm,mpaddr));
   5.412 -
   5.413 -	pmd = pmd_offset(pud, mpaddr);
   5.414 -	if (pmd_none(*pmd))
   5.415 -		pmd_populate_kernel(mm, pmd, pte_alloc_one_kernel(mm,mpaddr));
   5.416 -//		pmd_populate(mm, pmd, pte_alloc_one(mm,mpaddr));
   5.417 -
   5.418 -	pte = pte_offset_map(pmd, mpaddr);
   5.419 -	if (pte_none(*pte)) {
   5.420 -#ifdef CONFIG_DOMAIN0_CONTIGUOUS
   5.421 -		if (d == dom0) p = map_new_domain0_page(mpaddr);
   5.422 -		else
   5.423 -#endif
   5.424 -		{
   5.425 -			p = alloc_domheap_page(d);
   5.426 -			// zero out pages for security reasons
   5.427 -			memset(__va(page_to_phys(p)),0,PAGE_SIZE);
   5.428 -		}
   5.429 -		if (unlikely(!p)) {
   5.430 -printf("map_new_domain_page: Can't alloc!!!! Aaaargh!\n");
   5.431 -			return(p);
   5.432 -		}
   5.433 -if (unlikely(page_to_phys(p) > vhpt_paddr && page_to_phys(p) < vhpt_pend)) {
   5.434 -  printf("map_new_domain_page: reassigned vhpt page %p!!\n",page_to_phys(p));
   5.435 -}
   5.436 -		set_pte(pte, pfn_pte(page_to_phys(p) >> PAGE_SHIFT,
   5.437 -			__pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)));
   5.438 -	}
   5.439 -	else printk("map_new_domain_page: mpaddr %lx already mapped!\n",mpaddr);
   5.440 -	return p;
   5.441 -}
   5.442 -
   5.443 -/* map a physical address to the specified metaphysical addr */
   5.444 -void map_domain_page(struct domain *d, unsigned long mpaddr, unsigned long physaddr)
   5.445 -{
   5.446 -	struct mm_struct *mm = d->arch.mm;
   5.447 -	pgd_t *pgd;
   5.448 -	pud_t *pud;
   5.449 -	pmd_t *pmd;
   5.450 -	pte_t *pte;
   5.451 -
   5.452 -	if (!mm->pgd) {
   5.453 -		printk("map_domain_page: domain pgd must exist!\n");
   5.454 -		return;
   5.455 -	}
   5.456 -	pgd = pgd_offset(mm,mpaddr);
   5.457 -	if (pgd_none(*pgd))
   5.458 -		pgd_populate(mm, pgd, pud_alloc_one(mm,mpaddr));
   5.459 -
   5.460 -	pud = pud_offset(pgd, mpaddr);
   5.461 -	if (pud_none(*pud))
   5.462 -		pud_populate(mm, pud, pmd_alloc_one(mm,mpaddr));
   5.463 -
   5.464 -	pmd = pmd_offset(pud, mpaddr);
   5.465 -	if (pmd_none(*pmd))
   5.466 -		pmd_populate_kernel(mm, pmd, pte_alloc_one_kernel(mm,mpaddr));
   5.467 -//		pmd_populate(mm, pmd, pte_alloc_one(mm,mpaddr));
   5.468 -
   5.469 -	pte = pte_offset_map(pmd, mpaddr);
   5.470 -	if (pte_none(*pte)) {
   5.471 -		set_pte(pte, pfn_pte(physaddr >> PAGE_SHIFT,
   5.472 -			__pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)));
   5.473 -	}
   5.474 -	else printk("map_domain_page: mpaddr %lx already mapped!\n",mpaddr);
   5.475 -}
   5.476 -
   5.477 -void mpafoo(unsigned long mpaddr)
   5.478 -{
   5.479 -	extern unsigned long privop_trace;
   5.480 -	if (mpaddr == 0x3800)
   5.481 -		privop_trace = 1;
   5.482 -}
   5.483 -
   5.484 -unsigned long lookup_domain_mpa(struct domain *d, unsigned long mpaddr)
   5.485 -{
   5.486 -	struct mm_struct *mm = d->arch.mm;
   5.487 -	pgd_t *pgd = pgd_offset(mm, mpaddr);
   5.488 -	pud_t *pud;
   5.489 -	pmd_t *pmd;
   5.490 -	pte_t *pte;
   5.491 -
   5.492 -#ifdef CONFIG_DOMAIN0_CONTIGUOUS
   5.493 -	if (d == dom0) {
   5.494 -		if (mpaddr < dom0_start || mpaddr >= dom0_start + dom0_size) {
   5.495 -			//printk("lookup_domain_mpa: bad dom0 mpaddr %p!\n",mpaddr);
   5.496 -//printk("lookup_domain_mpa: start=%p,end=%p!\n",dom0_start,dom0_start+dom0_size);
   5.497 -			mpafoo(mpaddr);
   5.498 -		}
   5.499 -		pte_t pteval = pfn_pte(mpaddr >> PAGE_SHIFT,
   5.500 -			__pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX));
   5.501 -		pte = &pteval;
   5.502 -		return *(unsigned long *)pte;
   5.503 -	}
   5.504 -#endif
   5.505 -tryagain:
   5.506 -	if (pgd_present(*pgd)) {
   5.507 -		pud = pud_offset(pgd,mpaddr);
   5.508 -		if (pud_present(*pud)) {
   5.509 -			pmd = pmd_offset(pud,mpaddr);
   5.510 -			if (pmd_present(*pmd)) {
   5.511 -				pte = pte_offset_map(pmd,mpaddr);
   5.512 -				if (pte_present(*pte)) {
   5.513 -//printk("lookup_domain_page: found mapping for %lx, pte=%lx\n",mpaddr,pte_val(*pte));
   5.514 -					return *(unsigned long *)pte;
   5.515 -				}
   5.516 -			}
   5.517 -		}
   5.518 -	}
   5.519 -	/* if lookup fails and mpaddr is "legal", "create" the page */
   5.520 -	if ((mpaddr >> PAGE_SHIFT) < d->max_pages) {
   5.521 -		if (map_new_domain_page(d,mpaddr)) goto tryagain;
   5.522 -	}
   5.523 -	printk("lookup_domain_mpa: bad mpa %p (> %p\n",
   5.524 -		mpaddr,d->max_pages<<PAGE_SHIFT);
   5.525 -	mpafoo(mpaddr);
   5.526 -	return 0;
   5.527 -}
   5.528 -
   5.529 -// FIXME: ONLY USE FOR DOMAIN PAGE_SIZE == PAGE_SIZE
   5.530 -#ifndef CONFIG_VTI
   5.531 -unsigned long domain_mpa_to_imva(struct domain *d, unsigned long mpaddr)
   5.532 -{
   5.533 -	unsigned long pte = lookup_domain_mpa(d,mpaddr);
   5.534 -	unsigned long imva;
   5.535 -
   5.536 -	pte &= _PAGE_PPN_MASK;
   5.537 -	imva = __va(pte);
   5.538 -	imva |= mpaddr & ~PAGE_MASK;
   5.539 -	return(imva);
   5.540 -}
   5.541 -#else // CONFIG_VTI
   5.542 -unsigned long domain_mpa_to_imva(struct domain *d, unsigned long mpaddr)
   5.543 -{
   5.544 -    unsigned long imva = __gpa_to_mpa(d, mpaddr);
   5.545 -
   5.546 -    return __va(imva);
   5.547 -}
   5.548 -#endif // CONFIG_VTI
   5.549 -
   5.550 -// remove following line if not privifying in memory
   5.551 -//#define HAVE_PRIVIFY_MEMORY
   5.552 -#ifndef HAVE_PRIVIFY_MEMORY
   5.553 -#define	privify_memory(x,y) do {} while(0)
   5.554 -#endif
   5.555 -
   5.556 -// see arch/x86/xxx/domain_build.c
   5.557 -int elf_sanity_check(Elf_Ehdr *ehdr)
   5.558 -{
   5.559 -	return (IS_ELF(*ehdr));
   5.560 -}
   5.561 -
   5.562 -static void copy_memory(void *dst, void *src, int size)
   5.563 -{
   5.564 -	int remain;
   5.565 -
   5.566 -	if (IS_XEN_ADDRESS(dom0,src)) {
   5.567 -		memcpy(dst,src,size);
   5.568 -	}
   5.569 -	else {
   5.570 -		printf("About to call __copy_from_user(%p,%p,%d)\n",
   5.571 -			dst,src,size);
   5.572 -		while (remain = __copy_from_user(dst,src,size)) {
   5.573 -			printf("incomplete user copy, %d remain of %d\n",
   5.574 -				remain,size);
   5.575 -			dst += size - remain; src += size - remain;
   5.576 -			size -= remain;
   5.577 -		}
   5.578 -	}
   5.579 -}
   5.580 -
   5.581 -void loaddomainelfimage(struct domain *d, unsigned long image_start)
   5.582 -{
   5.583 -	char *elfbase = image_start;
   5.584 -	//Elf_Ehdr *ehdr = (Elf_Ehdr *)image_start;
   5.585 -	Elf_Ehdr ehdr;
   5.586 -	Elf_Phdr phdr;
   5.587 -	int h, filesz, memsz, paddr;
   5.588 -	unsigned long elfaddr, dom_mpaddr, dom_imva;
   5.589 -	struct page *p;
   5.590 -	unsigned long pteval;
   5.591 -  
   5.592 -	copy_memory(&ehdr,image_start,sizeof(Elf_Ehdr));
   5.593 -	for ( h = 0; h < ehdr.e_phnum; h++ ) {
   5.594 -		copy_memory(&phdr,elfbase + ehdr.e_phoff + (h*ehdr.e_phentsize),
   5.595 -		sizeof(Elf_Phdr));
   5.596 -	    //if ( !is_loadable_phdr(phdr) )
   5.597 -	    if ((phdr.p_type != PT_LOAD)) {
   5.598 -	        continue;
   5.599 -	}
   5.600 -	filesz = phdr.p_filesz; memsz = phdr.p_memsz;
   5.601 -	elfaddr = elfbase + phdr.p_offset;
   5.602 -	dom_mpaddr = phdr.p_paddr;
   5.603 -//printf("p_offset: %x, size=%x\n",elfaddr,filesz);
   5.604 -#ifdef CONFIG_DOMAIN0_CONTIGUOUS
   5.605 -	if (d == dom0) {
   5.606 -		if (dom_mpaddr+memsz>dom0_size || dom_mpaddr+filesz>dom0_size) {
   5.607 -			printf("Domain0 doesn't fit in allocated space!\n");
   5.608 -			while(1);
   5.609 -		}
   5.610 -		dom_imva = __va(dom_mpaddr + dom0_start);
   5.611 -		copy_memory(dom_imva,elfaddr,filesz);
   5.612 -		if (memsz > filesz) memset(dom_imva+filesz,0,memsz-filesz);
   5.613 -//FIXME: This test for code seems to find a lot more than objdump -x does
   5.614 -		if (phdr.p_flags & PF_X) privify_memory(dom_imva,filesz);
   5.615 -	}
   5.616 -	else
   5.617 -#endif
   5.618 -	while (memsz > 0) {
   5.619 -#ifdef DOMU_AUTO_RESTART
   5.620 -		pteval = lookup_domain_mpa(d,dom_mpaddr);
   5.621 -		if (pteval) dom_imva = __va(pteval & _PFN_MASK);
   5.622 -		else { printf("loaddomainelfimage: BAD!\n"); while(1); }
   5.623 -#else
   5.624 -		p = map_new_domain_page(d,dom_mpaddr);
   5.625 -		if (unlikely(!p)) BUG();
   5.626 -		dom_imva = __va(page_to_phys(p));
   5.627 -#endif
   5.628 -		if (filesz > 0) {
   5.629 -			if (filesz >= PAGE_SIZE)
   5.630 -				copy_memory(dom_imva,elfaddr,PAGE_SIZE);
   5.631 -			else { // copy partial page, zero the rest of page
   5.632 -				copy_memory(dom_imva,elfaddr,filesz);
   5.633 -				memset(dom_imva+filesz,0,PAGE_SIZE-filesz);
   5.634 -			}
   5.635 -//FIXME: This test for code seems to find a lot more than objdump -x does
   5.636 -			if (phdr.p_flags & PF_X)
   5.637 -				privify_memory(dom_imva,PAGE_SIZE);
   5.638 -		}
   5.639 -		else if (memsz > 0) // always zero out entire page
   5.640 -			memset(dom_imva,0,PAGE_SIZE);
   5.641 -		memsz -= PAGE_SIZE; filesz -= PAGE_SIZE;
   5.642 -		elfaddr += PAGE_SIZE; dom_mpaddr += PAGE_SIZE;
   5.643 -	}
   5.644 -	}
   5.645 -}
   5.646 -
   5.647 -int
   5.648 -parsedomainelfimage(char *elfbase, unsigned long elfsize, unsigned long *entry)
   5.649 -{
   5.650 -	Elf_Ehdr ehdr;
   5.651 -
   5.652 -	copy_memory(&ehdr,elfbase,sizeof(Elf_Ehdr));
   5.653 -
   5.654 -	if ( !elf_sanity_check(&ehdr) ) {
   5.655 -	    printk("ELF sanity check failed.\n");
   5.656 -	    return -EINVAL;
   5.657 -	}
   5.658 -
   5.659 -	if ( (ehdr.e_phoff + (ehdr.e_phnum * ehdr.e_phentsize)) > elfsize )
   5.660 -	{
   5.661 -	    printk("ELF program headers extend beyond end of image.\n");
   5.662 -	    return -EINVAL;
   5.663 -	}
   5.664 -
   5.665 -	if ( (ehdr.e_shoff + (ehdr.e_shnum * ehdr.e_shentsize)) > elfsize )
   5.666 -	{
   5.667 -	    printk("ELF section headers extend beyond end of image.\n");
   5.668 -	    return -EINVAL;
   5.669 -	}
   5.670 -
   5.671 -#if 0
   5.672 -	/* Find the section-header strings table. */
   5.673 -	if ( ehdr.e_shstrndx == SHN_UNDEF )
   5.674 -	{
   5.675 -	    printk("ELF image has no section-header strings table (shstrtab).\n");
   5.676 -	    return -EINVAL;
   5.677 -	}
   5.678 -#endif
   5.679 -
   5.680 -	*entry = ehdr.e_entry;
   5.681 -printf("parsedomainelfimage: entry point = %p\n",*entry);
   5.682 -
   5.683 -	return 0;
   5.684 -}
   5.685 -
   5.686 -
   5.687 -void alloc_dom0(void)
   5.688 -{
   5.689 -#ifdef CONFIG_DOMAIN0_CONTIGUOUS
   5.690 -	if (platform_is_hp_ski()) {
   5.691 -	dom0_size = 128*1024*1024; //FIXME: Should be configurable
   5.692 -	}
   5.693 -	printf("alloc_dom0: starting (initializing %d MB...)\n",dom0_size/(1024*1024));
   5.694 - 
   5.695 -     /* FIXME: The first trunk (say 256M) should always be assigned to
   5.696 -      * Dom0, since Dom0's physical == machine address for DMA purpose.
   5.697 -      * Some old version linux, like 2.4, assumes physical memory existing
   5.698 -      * in 2nd 64M space.
   5.699 -      */
   5.700 -     dom0_start = alloc_boot_pages(
   5.701 -         dom0_size >> PAGE_SHIFT, dom0_align >> PAGE_SHIFT);
   5.702 -     dom0_start <<= PAGE_SHIFT;
   5.703 -	if (!dom0_start) {
   5.704 -	printf("construct_dom0: can't allocate contiguous memory size=%p\n",
   5.705 -		dom0_size);
   5.706 -	while(1);
   5.707 -	}
   5.708 -	printf("alloc_dom0: dom0_start=%p\n",dom0_start);
   5.709 -#else
   5.710 -	dom0_start = 0;
   5.711 -#endif
   5.712 -
   5.713 -}
   5.714 -
   5.715 -#ifdef DOMU_BUILD_STAGING
   5.716 -void alloc_domU_staging(void)
   5.717 -{
   5.718 -	domU_staging_size = 32*1024*1024; //FIXME: Should be configurable
   5.719 -	printf("alloc_domU_staging: starting (initializing %d MB...)\n",domU_staging_size/(1024*1024));
   5.720 -	domU_staging_start = alloc_boot_pages(
   5.721 -            domU_staging_size >> PAGE_SHIFT, domU_staging_align >> PAGE_SHIFT);
   5.722 -        domU_staging_start <<= PAGE_SHIFT;
   5.723 -	if (!domU_staging_size) {
   5.724 -		printf("alloc_domU_staging: can't allocate, spinning...\n");
   5.725 -		while(1);
   5.726 -	}
   5.727 -	else domU_staging_area = (unsigned long *)__va(domU_staging_start);
   5.728 -	printf("alloc_domU_staging: domU_staging_area=%p\n",domU_staging_area);
   5.729 -
   5.730 -}
   5.731 -
   5.732 -unsigned long
   5.733 -domU_staging_read_8(unsigned long at)
   5.734 -{
   5.735 -	// no way to return errors so just do it
   5.736 -	return domU_staging_area[at>>3];
   5.737 -	
   5.738 -}
   5.739 -
   5.740 -unsigned long
   5.741 -domU_staging_write_32(unsigned long at, unsigned long a, unsigned long b,
   5.742 -	unsigned long c, unsigned long d)
   5.743 -{
   5.744 -	if (at + 32 > domU_staging_size) return -1;
   5.745 -	if (at & 0x1f) return -1;
   5.746 -	at >>= 3;
   5.747 -	domU_staging_area[at++] = a;
   5.748 -	domU_staging_area[at++] = b;
   5.749 -	domU_staging_area[at++] = c;
   5.750 -	domU_staging_area[at] = d;
   5.751 -	return 0;
   5.752 -	
   5.753 -}
   5.754 -#endif
   5.755 -
   5.756 -/*
   5.757 - * Domain 0 has direct access to all devices absolutely. However
   5.758 - * the major point of this stub here, is to allow alloc_dom_mem
   5.759 - * handled with order > 0 request. Dom0 requires that bit set to
   5.760 - * allocate memory for other domains.
   5.761 - */
   5.762 -void physdev_init_dom0(struct domain *d)
   5.763 -{
   5.764 -	set_bit(_DOMF_physdev_access, &d->domain_flags);
   5.765 -}
   5.766 -
   5.767 -extern unsigned long running_on_sim;
   5.768 -unsigned int vmx_dom0 = 0;
   5.769 -int construct_dom0(struct domain *d, 
   5.770 -	               unsigned long image_start, unsigned long image_len, 
   5.771 -	               unsigned long initrd_start, unsigned long initrd_len,
   5.772 -	               char *cmdline)
   5.773 -{
   5.774 -	char *dst;
   5.775 -	int i, rc;
   5.776 -	unsigned long pfn, mfn;
   5.777 -	unsigned long nr_pt_pages;
   5.778 -	unsigned long count;
   5.779 -	unsigned long alloc_start, alloc_end;
   5.780 -	struct pfn_info *page = NULL;
   5.781 -	start_info_t *si;
   5.782 -	struct vcpu *v = d->vcpu[0];
   5.783 -
   5.784 -	struct domain_setup_info dsi;
   5.785 -	unsigned long p_start;
   5.786 -	unsigned long pkern_start;
   5.787 -	unsigned long pkern_entry;
   5.788 -	unsigned long pkern_end;
   5.789 -	unsigned long ret, progress = 0;
   5.790 -
   5.791 -//printf("construct_dom0: starting\n");
   5.792 -	/* Sanity! */
   5.793 -#ifndef CLONE_DOMAIN0
   5.794 -	if ( d != dom0 ) 
   5.795 -	    BUG();
   5.796 -	if ( test_bit(_DOMF_constructed, &d->domain_flags) ) 
   5.797 -	    BUG();
   5.798 -#endif
   5.799 -
   5.800 -	memset(&dsi, 0, sizeof(struct domain_setup_info));
   5.801 -
   5.802 -	printk("*** LOADING DOMAIN 0 ***\n");
   5.803 -
   5.804 -	alloc_start = dom0_start;
   5.805 -	alloc_end = dom0_start + dom0_size;
   5.806 -	d->tot_pages = d->max_pages = dom0_size/PAGE_SIZE;
   5.807 -	image_start = __va(ia64_boot_param->initrd_start);
   5.808 -	image_len = ia64_boot_param->initrd_size;
   5.809 -//printk("image_start=%lx, image_len=%lx\n",image_start,image_len);
   5.810 -//printk("First word of image: %lx\n",*(unsigned long *)image_start);
   5.811 -
   5.812 -//printf("construct_dom0: about to call parseelfimage\n");
   5.813 -	dsi.image_addr = (unsigned long)image_start;
   5.814 -	dsi.image_len  = image_len;
   5.815 -	rc = parseelfimage(&dsi);
   5.816 -	if ( rc != 0 )
   5.817 -	    return rc;
   5.818 -
   5.819 -#ifdef CONFIG_VTI
   5.820 -	/* Temp workaround */
   5.821 -	if (running_on_sim)
   5.822 -	    dsi.xen_section_string = (char *)1;
   5.823 -
   5.824 -	/* Check whether dom0 is vti domain */
   5.825 -	if ((!vmx_enabled) && !dsi.xen_section_string) {
   5.826 -	    printk("Lack of hardware support for unmodified vmx dom0\n");
   5.827 -	    panic("");
   5.828 -	}
   5.829 -
   5.830 -	if (vmx_enabled && !dsi.xen_section_string) {
   5.831 -	    printk("Dom0 is vmx domain!\n");
   5.832 -	    vmx_dom0 = 1;
   5.833 -	}
   5.834 -#endif
   5.835 -
   5.836 -	p_start = dsi.v_start;
   5.837 -	pkern_start = dsi.v_kernstart;
   5.838 -	pkern_end = dsi.v_kernend;
   5.839 -	pkern_entry = dsi.v_kernentry;
   5.840 -
   5.841 -//printk("p_start=%lx, pkern_start=%lx, pkern_end=%lx, pkern_entry=%lx\n",p_start,pkern_start,pkern_end,pkern_entry);
   5.842 -
   5.843 -	if ( (p_start & (PAGE_SIZE-1)) != 0 )
   5.844 -	{
   5.845 -	    printk("Initial guest OS must load to a page boundary.\n");
   5.846 -	    return -EINVAL;
   5.847 -	}
   5.848 -
   5.849 -	printk("METAPHYSICAL MEMORY ARRANGEMENT:\n"
   5.850 -	       " Kernel image:  %lx->%lx\n"
   5.851 -	       " Entry address: %lx\n"
   5.852 -	       " Init. ramdisk:   (NOT IMPLEMENTED YET)\n",
   5.853 -	       pkern_start, pkern_end, pkern_entry);
   5.854 -
   5.855 -	if ( (pkern_end - pkern_start) > (d->max_pages * PAGE_SIZE) )
   5.856 -	{
   5.857 -	    printk("Initial guest OS requires too much space\n"
   5.858 -	           "(%luMB is greater than %luMB limit)\n",
   5.859 -	           (pkern_end-pkern_start)>>20, (d->max_pages<<PAGE_SHIFT)>>20);
   5.860 -	    return -ENOMEM;
   5.861 -	}
   5.862 -
   5.863 -	// if high 3 bits of pkern start are non-zero, error
   5.864 -
   5.865 -	// if pkern end is after end of metaphysical memory, error
   5.866 -	//  (we should be able to deal with this... later)
   5.867 -
   5.868 -
   5.869 -	//
   5.870 -
   5.871 -#if 0
   5.872 -	strcpy(d->name,"Domain0");
   5.873 -#endif
   5.874 -
   5.875 -	/* Mask all upcalls... */
   5.876 -	for ( i = 0; i < MAX_VIRT_CPUS; i++ )
   5.877 -	    d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
   5.878 -
   5.879 -#ifdef CONFIG_VTI
   5.880 -	/* Construct a frame-allocation list for the initial domain, since these
   5.881 -	 * pages are allocated by boot allocator and pfns are not set properly
   5.882 -	 */
   5.883 -	for ( mfn = (alloc_start>>PAGE_SHIFT); 
   5.884 -	      mfn < (alloc_end>>PAGE_SHIFT); 
   5.885 -	      mfn++ )
   5.886 -	{
   5.887 -            page = &frame_table[mfn];
   5.888 -            page_set_owner(page, d);
   5.889 -            page->u.inuse.type_info = 0;
   5.890 -            page->count_info        = PGC_allocated | 1;
   5.891 -            list_add_tail(&page->list, &d->page_list);
   5.892 -
   5.893 -	    /* Construct 1:1 mapping */
   5.894 -	    machine_to_phys_mapping[mfn] = mfn;
   5.895 -	}
   5.896 -
   5.897 -	/* Dom0's pfn is equal to mfn, so there's no need to allocate pmt
   5.898 -	 * for dom0
   5.899 -	 */
   5.900 -	d->arch.pmt = NULL;
   5.901 -#endif
   5.902 -
   5.903 -	/* Copy the OS image. */
   5.904 -	loaddomainelfimage(d,image_start);
   5.905 -
   5.906 -	/* Copy the initial ramdisk. */
   5.907 -	//if ( initrd_len != 0 )
   5.908 -	//    memcpy((void *)vinitrd_start, initrd_start, initrd_len);
   5.909 -
   5.910 -	/* Sync d/i cache conservatively */
   5.911 -	ret = ia64_pal_cache_flush(4, 0, &progress, NULL);
   5.912 -	if (ret != PAL_STATUS_SUCCESS)
   5.913 -	    panic("PAL CACHE FLUSH failed for dom0.\n");
   5.914 -	printk("Sync i/d cache for dom0 image SUCC\n");
   5.915 -
   5.916 -#if 0
   5.917 -	/* Set up start info area. */
   5.918 -	//si = (start_info_t *)vstartinfo_start;
   5.919 -	memset(si, 0, PAGE_SIZE);
   5.920 -	si->nr_pages     = d->tot_pages;
   5.921 -	si->shared_info  = virt_to_phys(d->shared_info);
   5.922 -	si->flags        = SIF_PRIVILEGED | SIF_INITDOMAIN;
   5.923 -	//si->pt_base      = vpt_start;
   5.924 -	//si->nr_pt_frames = nr_pt_pages;
   5.925 -	//si->mfn_list     = vphysmap_start;
   5.926 -
   5.927 -	if ( initrd_len != 0 )
   5.928 -	{
   5.929 -	    //si->mod_start = vinitrd_start;
   5.930 -	    si->mod_len   = initrd_len;
   5.931 -	    printk("Initrd len 0x%lx, start at 0x%08lx\n",
   5.932 -	           si->mod_len, si->mod_start);
   5.933 -	}
   5.934 -
   5.935 -	dst = si->cmd_line;
   5.936 -	if ( cmdline != NULL )
   5.937 -	{
   5.938 -	    for ( i = 0; i < 255; i++ )
   5.939 -	    {
   5.940 -	        if ( cmdline[i] == '\0' )
   5.941 -	            break;
   5.942 -	        *dst++ = cmdline[i];
   5.943 -	    }
   5.944 -	}
   5.945 -	*dst = '\0';
   5.946 -
   5.947 -	zap_low_mappings(); /* Do the same for the idle page tables. */
   5.948 -#endif
   5.949 -	
   5.950 -	/* Give up the VGA console if DOM0 is configured to grab it. */
   5.951 -	if (cmdline != NULL)
   5.952 -	    console_endboot(strstr(cmdline, "tty0") != NULL);
   5.953 -
   5.954 -	/* VMX specific construction for Dom0, if hardware supports VMX
   5.955 -	 * and Dom0 is unmodified image
   5.956 -	 */
   5.957 -	printk("Dom0: 0x%lx, domain: 0x%lx\n", (u64)dom0, (u64)d);
   5.958 -	if (vmx_dom0)
   5.959 -	    vmx_final_setup_domain(dom0);
   5.960 -
   5.961 -	set_bit(_DOMF_constructed, &d->domain_flags);
   5.962 -
   5.963 -	new_thread(v, pkern_entry, 0, 0);
   5.964 -	physdev_init_dom0(d);
   5.965 -
   5.966 -	// FIXME: Hack for keyboard input
   5.967 -#ifdef CLONE_DOMAIN0
   5.968 -if (d == dom0)
   5.969 -#endif
   5.970 -	serial_input_init();
   5.971 -	if (d == dom0) {
   5.972 -		VCPU(v, delivery_mask[0]) = -1L;
   5.973 -		VCPU(v, delivery_mask[1]) = -1L;
   5.974 -		VCPU(v, delivery_mask[2]) = -1L;
   5.975 -		VCPU(v, delivery_mask[3]) = -1L;
   5.976 -	}
   5.977 -	else __set_bit(0x30, VCPU(v, delivery_mask));
   5.978 -
   5.979 -	return 0;
   5.980 -}
   5.981 -
   5.982 -// FIXME: When dom0 can construct domains, this goes away (or is rewritten)
   5.983 -int construct_domU(struct domain *d,
   5.984 -		   unsigned long image_start, unsigned long image_len,
   5.985 -	           unsigned long initrd_start, unsigned long initrd_len,
   5.986 -	           char *cmdline)
   5.987 -{
   5.988 -	int i, rc;
   5.989 -	struct vcpu *v = d->vcpu[0];
   5.990 -	unsigned long pkern_entry;
   5.991 -
   5.992 -#ifndef DOMU_AUTO_RESTART
   5.993 -	if ( test_bit(_DOMF_constructed, &d->domain_flags) ) BUG();
   5.994 -#endif
   5.995 -
   5.996 -	printk("*** LOADING DOMAIN %d ***\n",d->domain_id);
   5.997 -
   5.998 -	d->max_pages = dom0_size/PAGE_SIZE;	// FIXME: use dom0 size
   5.999 -	// FIXME: use domain0 command line
  5.1000 -	rc = parsedomainelfimage(image_start, image_len, &pkern_entry);
  5.1001 -	printk("parsedomainelfimage returns %d\n",rc);
  5.1002 -	if ( rc != 0 ) return rc;
  5.1003 -
  5.1004 -	/* Mask all upcalls... */
  5.1005 -	for ( i = 0; i < MAX_VIRT_CPUS; i++ )
  5.1006 -		d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
  5.1007 -
  5.1008 -	/* Copy the OS image. */
  5.1009 -	printk("calling loaddomainelfimage(%p,%p)\n",d,image_start);
  5.1010 -	loaddomainelfimage(d,image_start);
  5.1011 -	printk("loaddomainelfimage returns\n");
  5.1012 -
  5.1013 -	set_bit(_DOMF_constructed, &d->domain_flags);
  5.1014 -
  5.1015 -	printk("calling new_thread, entry=%p\n",pkern_entry);
  5.1016 -#ifdef DOMU_AUTO_RESTART
  5.1017 -	v->domain->arch.image_start = image_start;
  5.1018 -	v->domain->arch.image_len = image_len;
  5.1019 -	v->domain->arch.entry = pkern_entry;
  5.1020 -#endif
  5.1021 -	new_thread(v, pkern_entry, 0, 0);
  5.1022 -	printk("new_thread returns\n");
  5.1023 -	__set_bit(0x30, VCPU(v, delivery_mask));
  5.1024 -
  5.1025 -	return 0;
  5.1026 -}
  5.1027 -
  5.1028 -#ifdef DOMU_AUTO_RESTART
  5.1029 -void reconstruct_domU(struct vcpu *v)
  5.1030 -{
  5.1031 -	/* re-copy the OS image to reset data values to original */
  5.1032 -	printk("reconstruct_domU: restarting domain %d...\n",
  5.1033 -		v->domain->domain_id);
  5.1034 -	loaddomainelfimage(v->domain,v->domain->arch.image_start);
  5.1035 -	new_thread(v, v->domain->arch.entry, 0, 0);
  5.1036 -}
  5.1037 -#endif
  5.1038 -
  5.1039 -// FIXME: When dom0 can construct domains, this goes away (or is rewritten)
  5.1040 -int launch_domainU(unsigned long size)
  5.1041 -{
  5.1042 -#ifdef CLONE_DOMAIN0
  5.1043 -	static int next = CLONE_DOMAIN0+1;
  5.1044 -#else
  5.1045 -	static int next = 1;
  5.1046 -#endif	
  5.1047 -
  5.1048 -	struct domain *d = do_createdomain(next,0);
  5.1049 -	if (!d) {
  5.1050 -		printf("launch_domainU: couldn't create\n");
  5.1051 -		return 1;
  5.1052 -	}
  5.1053 -	else next++;
  5.1054 -	if (construct_domU(d, (unsigned long)domU_staging_area, size,0,0,0)) {
  5.1055 -		printf("launch_domainU: couldn't construct(id=%d,%lx,%lx)\n",
  5.1056 -			d->domain_id,domU_staging_area,size);
  5.1057 -		return 2;
  5.1058 -	}
  5.1059 -	domain_unpause_by_systemcontroller(d);
  5.1060 -}
  5.1061 -
  5.1062 -void machine_restart(char * __unused)
  5.1063 -{
  5.1064 -	if (platform_is_hp_ski()) dummy();
  5.1065 -	printf("machine_restart called: spinning....\n");
  5.1066 -	while(1);
  5.1067 -}
  5.1068 -
  5.1069 -void machine_halt(void)
  5.1070 -{
  5.1071 -	if (platform_is_hp_ski()) dummy();
  5.1072 -	printf("machine_halt called: spinning....\n");
  5.1073 -	while(1);
  5.1074 -}
  5.1075 -
  5.1076 -void dummy_called(char *function)
  5.1077 -{
  5.1078 -	if (platform_is_hp_ski()) asm("break 0;;");
  5.1079 -	printf("dummy called in %s: spinning....\n", function);
  5.1080 -	while(1);
  5.1081 -}
  5.1082 -
  5.1083 -
  5.1084 -#if 0
  5.1085 -void switch_to(struct vcpu *prev, struct vcpu *next)
  5.1086 -{
  5.1087 - 	struct vcpu *last;
  5.1088 -
  5.1089 -	__switch_to(prev,next,last);
  5.1090 -	//set_current(next);
  5.1091 -}
  5.1092 -#endif
  5.1093 -
  5.1094 -void domain_pend_keyboard_interrupt(int irq)
  5.1095 -{
  5.1096 -	vcpu_pend_interrupt(dom0->vcpu[0],irq);
  5.1097 -}
  5.1098 -
  5.1099 -void vcpu_migrate_cpu(struct vcpu *v, int newcpu)
  5.1100 -{
  5.1101 -	if ( v->processor == newcpu )
  5.1102 -		return;
  5.1103 -
  5.1104 -	set_bit(_VCPUF_cpu_migrated, &v->vcpu_flags);
  5.1105 -	v->processor = newcpu;
  5.1106 -}
     6.1 --- a/xen/arch/ia64/grant_table.c	Thu Sep 01 11:09:27 2005 -0600
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,1288 +0,0 @@
     6.4 -#ifndef CONFIG_VTI
     6.5 -// temporarily in arch/ia64 until can merge into common/grant_table.c
     6.6 -/******************************************************************************
     6.7 - * common/grant_table.c
     6.8 - * 
     6.9 - * Mechanism for granting foreign access to page frames, and receiving
    6.10 - * page-ownership transfers.
    6.11 - * 
    6.12 - * Copyright (c) 2005 Christopher Clark
    6.13 - * Copyright (c) 2004 K A Fraser
    6.14 - * 
    6.15 - * This program is free software; you can redistribute it and/or modify
    6.16 - * it under the terms of the GNU General Public License as published by
    6.17 - * the Free Software Foundation; either version 2 of the License, or
    6.18 - * (at your option) any later version.
    6.19 - * 
    6.20 - * This program is distributed in the hope that it will be useful,
    6.21 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.22 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.23 - * GNU General Public License for more details.
    6.24 - * 
    6.25 - * You should have received a copy of the GNU General Public License
    6.26 - * along with this program; if not, write to the Free Software
    6.27 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    6.28 - */
    6.29 -
    6.30 -#define GRANT_DEBUG 0
    6.31 -#define GRANT_DEBUG_VERBOSE 0
    6.32 -
    6.33 -#include <xen/config.h>
    6.34 -#include <xen/lib.h>
    6.35 -#include <xen/sched.h>
    6.36 -#include <xen/shadow.h>
    6.37 -#include <xen/mm.h>
    6.38 -#ifdef __ia64__
    6.39 -#define __addr_ok(a) 1	// FIXME-ia64: a variant of access_ok??
    6.40 -// FIXME-ia64: need to implement real cmpxchg_user on ia64
    6.41 -//#define cmpxchg_user(_p,_o,_n) ((*_p == _o) ? ((*_p = _n), 0) : ((_o = *_p), 0))
    6.42 -// FIXME-ia64: these belong in an asm/grant_table.h... PAGE_SIZE different
    6.43 -#undef ORDER_GRANT_FRAMES
    6.44 -//#undef NUM_GRANT_FRAMES
    6.45 -#define ORDER_GRANT_FRAMES 0
    6.46 -//#define NUM_GRANT_FRAMES  (1U << ORDER_GRANT_FRAMES)
    6.47 -#endif
    6.48 -
    6.49 -#define PIN_FAIL(_lbl, _rc, _f, _a...)   \
    6.50 -    do {                           \
    6.51 -        DPRINTK( _f, ## _a );      \
    6.52 -        rc = (_rc);                \
    6.53 -        goto _lbl;                 \
    6.54 -    } while ( 0 )
    6.55 -
    6.56 -static inline int
    6.57 -get_maptrack_handle(
    6.58 -    grant_table_t *t)
    6.59 -{
    6.60 -    unsigned int h;
    6.61 -    if ( unlikely((h = t->maptrack_head) == t->maptrack_limit) )
    6.62 -        return -1;
    6.63 -    t->maptrack_head = t->maptrack[h].ref_and_flags >> MAPTRACK_REF_SHIFT;
    6.64 -    t->map_count++;
    6.65 -    return h;
    6.66 -}
    6.67 -
    6.68 -static inline void
    6.69 -put_maptrack_handle(
    6.70 -    grant_table_t *t, int handle)
    6.71 -{
    6.72 -    t->maptrack[handle].ref_and_flags = t->maptrack_head << MAPTRACK_REF_SHIFT;
    6.73 -    t->maptrack_head = handle;
    6.74 -    t->map_count--;
    6.75 -}
    6.76 -
    6.77 -static int
    6.78 -__gnttab_activate_grant_ref(
    6.79 -    struct domain          *mapping_d,          /* IN */
    6.80 -    struct vcpu     *mapping_ed,
    6.81 -    struct domain          *granting_d,
    6.82 -    grant_ref_t             ref,
    6.83 -    u16                     dev_hst_ro_flags,
    6.84 -    unsigned long           host_virt_addr,
    6.85 -    unsigned long          *pframe )            /* OUT */
    6.86 -{
    6.87 -    domid_t               sdom;
    6.88 -    u16                   sflags;
    6.89 -    active_grant_entry_t *act;
    6.90 -    grant_entry_t        *sha;
    6.91 -    s16                   rc = 1;
    6.92 -    unsigned long         frame = 0;
    6.93 -    int                   retries = 0;
    6.94 -
    6.95 -    /*
    6.96 -     * Objectives of this function:
    6.97 -     * . Make the record ( granting_d, ref ) active, if not already.
    6.98 -     * . Update shared grant entry of owner, indicating frame is mapped.
    6.99 -     * . Increment the owner act->pin reference counts.
   6.100 -     * . get_page on shared frame if new mapping.
   6.101 -     * . get_page_type if this is first RW mapping of frame.
   6.102 -     * . Add PTE to virtual address space of mapping_d, if necessary.
   6.103 -     * Returns:
   6.104 -     * .  -ve: error
   6.105 -     * .    1: ok
   6.106 -     * .    0: ok and TLB invalidate of host_virt_addr needed.
   6.107 -     *
   6.108 -     * On success, *pframe contains mfn.
   6.109 -     */
   6.110 -
   6.111 -    /*
   6.112 -     * We bound the number of times we retry CMPXCHG on memory locations that
   6.113 -     * we share with a guest OS. The reason is that the guest can modify that
   6.114 -     * location at a higher rate than we can read-modify-CMPXCHG, so the guest
   6.115 -     * could cause us to livelock. There are a few cases where it is valid for
   6.116 -     * the guest to race our updates (e.g., to change the GTF_readonly flag),
   6.117 -     * so we allow a few retries before failing.
   6.118 -     */
   6.119 -
   6.120 -    act = &granting_d->grant_table->active[ref];
   6.121 -    sha = &granting_d->grant_table->shared[ref];
   6.122 -
   6.123 -    spin_lock(&granting_d->grant_table->lock);
   6.124 -
   6.125 -    if ( act->pin == 0 )
   6.126 -    {
   6.127 -        /* CASE 1: Activating a previously inactive entry. */
   6.128 -
   6.129 -        sflags = sha->flags;
   6.130 -        sdom   = sha->domid;
   6.131 -
   6.132 -        for ( ; ; )
   6.133 -        {
   6.134 -            u32 scombo, prev_scombo, new_scombo;
   6.135 -
   6.136 -            if ( unlikely((sflags & GTF_type_mask) != GTF_permit_access) ||
   6.137 -                 unlikely(sdom != mapping_d->domain_id) )
   6.138 -                PIN_FAIL(unlock_out, GNTST_general_error,
   6.139 -                         "Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
   6.140 -                        sflags, sdom, mapping_d->domain_id);
   6.141 -
   6.142 -            /* Merge two 16-bit values into a 32-bit combined update. */
   6.143 -            /* NB. Endianness! */
   6.144 -            prev_scombo = scombo = ((u32)sdom << 16) | (u32)sflags;
   6.145 -
   6.146 -            new_scombo = scombo | GTF_reading;
   6.147 -            if ( !(dev_hst_ro_flags & GNTMAP_readonly) )
   6.148 -            {
   6.149 -                new_scombo |= GTF_writing;
   6.150 -                if ( unlikely(sflags & GTF_readonly) )
   6.151 -                    PIN_FAIL(unlock_out, GNTST_general_error,
   6.152 -                             "Attempt to write-pin a r/o grant entry.\n");
   6.153 -            }
   6.154 -
   6.155 -            /* NB. prev_scombo is updated in place to seen value. */
   6.156 -            if ( unlikely(cmpxchg_user((u32 *)&sha->flags,
   6.157 -                                       prev_scombo,
   6.158 -                                       new_scombo)) )
   6.159 -                PIN_FAIL(unlock_out, GNTST_general_error,
   6.160 -                         "Fault while modifying shared flags and domid.\n");
   6.161 -
   6.162 -            /* Did the combined update work (did we see what we expected?). */
   6.163 -            if ( likely(prev_scombo == scombo) )
   6.164 -                break;
   6.165 -
   6.166 -            if ( retries++ == 4 )
   6.167 -                PIN_FAIL(unlock_out, GNTST_general_error,
   6.168 -                         "Shared grant entry is unstable.\n");
   6.169 -
   6.170 -            /* Didn't see what we expected. Split out the seen flags & dom. */
   6.171 -            /* NB. Endianness! */
   6.172 -            sflags = (u16)prev_scombo;
   6.173 -            sdom   = (u16)(prev_scombo >> 16);
   6.174 -        }
   6.175 -
   6.176 -        /* rmb(); */ /* not on x86 */
   6.177 -
   6.178 -        frame = __gpfn_to_mfn_foreign(granting_d, sha->frame);
   6.179 -
   6.180 -#ifdef __ia64__
   6.181 -// FIXME-ia64: any error checking need to be done here?
   6.182 -#else
   6.183 -        if ( unlikely(!pfn_valid(frame)) ||
   6.184 -             unlikely(!((dev_hst_ro_flags & GNTMAP_readonly) ?
   6.185 -                        get_page(&frame_table[frame], granting_d) :
   6.186 -                        get_page_and_type(&frame_table[frame], granting_d,
   6.187 -                                          PGT_writable_page))) )
   6.188 -        {
   6.189 -            clear_bit(_GTF_writing, &sha->flags);
   6.190 -            clear_bit(_GTF_reading, &sha->flags);
   6.191 -            PIN_FAIL(unlock_out, GNTST_general_error,
   6.192 -                     "Could not pin the granted frame (%lx)!\n", frame);
   6.193 -        }
   6.194 -#endif
   6.195 -
   6.196 -        if ( dev_hst_ro_flags & GNTMAP_device_map )
   6.197 -            act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
   6.198 -                GNTPIN_devr_inc : GNTPIN_devw_inc;
   6.199 -        if ( dev_hst_ro_flags & GNTMAP_host_map )
   6.200 -            act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
   6.201 -                GNTPIN_hstr_inc : GNTPIN_hstw_inc;
   6.202 -        act->domid = sdom;
   6.203 -        act->frame = frame;
   6.204 -    }
   6.205 -    else 
   6.206 -    {
   6.207 -        /* CASE 2: Active modications to an already active entry. */
   6.208 -
   6.209 -        /*
   6.210 -         * A cheesy check for possible pin-count overflow.
   6.211 -         * A more accurate check cannot be done with a single comparison.
   6.212 -         */
   6.213 -        if ( (act->pin & 0x80808080U) != 0 )
   6.214 -            PIN_FAIL(unlock_out, ENOSPC,
   6.215 -                     "Risk of counter overflow %08x\n", act->pin);
   6.216 -
   6.217 -        frame = act->frame;
   6.218 -
   6.219 -        if ( !(dev_hst_ro_flags & GNTMAP_readonly) && 
   6.220 -             !((sflags = sha->flags) & GTF_writing) )
   6.221 -        {
   6.222 -            for ( ; ; )
   6.223 -            {
   6.224 -                u16 prev_sflags;
   6.225 -                
   6.226 -                if ( unlikely(sflags & GTF_readonly) )
   6.227 -                    PIN_FAIL(unlock_out, GNTST_general_error,
   6.228 -                             "Attempt to write-pin a r/o grant entry.\n");
   6.229 -
   6.230 -                prev_sflags = sflags;
   6.231 -
   6.232 -                /* NB. prev_sflags is updated in place to seen value. */
   6.233 -                if ( unlikely(cmpxchg_user(&sha->flags, prev_sflags, 
   6.234 -                                           prev_sflags | GTF_writing)) )
   6.235 -                    PIN_FAIL(unlock_out, GNTST_general_error,
   6.236 -                         "Fault while modifying shared flags.\n");
   6.237 -
   6.238 -                if ( likely(prev_sflags == sflags) )
   6.239 -                    break;
   6.240 -
   6.241 -                if ( retries++ == 4 )
   6.242 -                    PIN_FAIL(unlock_out, GNTST_general_error,
   6.243 -                             "Shared grant entry is unstable.\n");
   6.244 -
   6.245 -                sflags = prev_sflags;
   6.246 -            }
   6.247 -
   6.248 -#ifdef __ia64__
   6.249 -// FIXME-ia64: any error checking need to be done here?
   6.250 -#else
   6.251 -            if ( unlikely(!get_page_type(&frame_table[frame],
   6.252 -                                         PGT_writable_page)) )
   6.253 -            {
   6.254 -                clear_bit(_GTF_writing, &sha->flags);
   6.255 -                PIN_FAIL(unlock_out, GNTST_general_error,
   6.256 -                         "Attempt to write-pin a unwritable page.\n");
   6.257 -            }
   6.258 -#endif
   6.259 -        }
   6.260 -
   6.261 -        if ( dev_hst_ro_flags & GNTMAP_device_map )
   6.262 -            act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ? 
   6.263 -                GNTPIN_devr_inc : GNTPIN_devw_inc;
   6.264 -
   6.265 -        if ( dev_hst_ro_flags & GNTMAP_host_map )
   6.266 -            act->pin += (dev_hst_ro_flags & GNTMAP_readonly) ?
   6.267 -                GNTPIN_hstr_inc : GNTPIN_hstw_inc;
   6.268 -    }
   6.269 -
   6.270 -    /*
   6.271 -     * At this point:
   6.272 -     * act->pin updated to reflect mapping.
   6.273 -     * sha->flags updated to indicate to granting domain mapping done.
   6.274 -     * frame contains the mfn.
   6.275 -     */
   6.276 -
   6.277 -    spin_unlock(&granting_d->grant_table->lock);
   6.278 -
   6.279 -#ifdef __ia64__
   6.280 -// FIXME-ia64: any error checking need to be done here?
   6.281 -#else
   6.282 -    if ( (host_virt_addr != 0) && (dev_hst_ro_flags & GNTMAP_host_map) )
   6.283 -    {
   6.284 -        /* Write update into the pagetable. */
   6.285 -        l1_pgentry_t pte;
   6.286 -        pte = l1e_from_pfn(frame, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);
   6.287 -        if ( !(dev_hst_ro_flags & GNTMAP_readonly) )
   6.288 -            l1e_add_flags(pte,_PAGE_RW);
   6.289 -        rc = update_grant_va_mapping( host_virt_addr, pte, 
   6.290 -                       mapping_d, mapping_ed );
   6.291 -
   6.292 -        /*
   6.293 -         * IMPORTANT: (rc == 0) => must flush / invalidate entry in TLB.
   6.294 -         * This is done in the outer gnttab_map_grant_ref.
   6.295 -         */
   6.296 -
   6.297 -        if ( rc < 0 )
   6.298 -        {
   6.299 -            /* Failure: undo and abort. */
   6.300 -
   6.301 -            spin_lock(&granting_d->grant_table->lock);
   6.302 -
   6.303 -            if ( dev_hst_ro_flags & GNTMAP_readonly )
   6.304 -            {
   6.305 -                act->pin -= GNTPIN_hstr_inc;
   6.306 -            }
   6.307 -            else
   6.308 -            {
   6.309 -                act->pin -= GNTPIN_hstw_inc;
   6.310 -                if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 )
   6.311 -                {
   6.312 -                    clear_bit(_GTF_writing, &sha->flags);
   6.313 -                    put_page_type(&frame_table[frame]);
   6.314 -                }
   6.315 -            }
   6.316 -
   6.317 -            if ( act->pin == 0 )
   6.318 -            {
   6.319 -                clear_bit(_GTF_reading, &sha->flags);
   6.320 -                put_page(&frame_table[frame]);
   6.321 -            }
   6.322 -
   6.323 -            spin_unlock(&granting_d->grant_table->lock);
   6.324 -        }
   6.325 -
   6.326 -    }
   6.327 -#endif
   6.328 -
   6.329 -    *pframe = frame;
   6.330 -    return rc;
   6.331 -
   6.332 - unlock_out:
   6.333 -    spin_unlock(&granting_d->grant_table->lock);
   6.334 -    return rc;
   6.335 -}
   6.336 -
   6.337 -/*
   6.338 - * Returns 0 if TLB flush / invalidate required by caller.
   6.339 - * va will indicate the address to be invalidated.
   6.340 - */
   6.341 -static int
   6.342 -__gnttab_map_grant_ref(
   6.343 -    gnttab_map_grant_ref_t *uop,
   6.344 -    unsigned long *va)
   6.345 -{
   6.346 -    domid_t               dom;
   6.347 -    grant_ref_t           ref;
   6.348 -    struct domain        *ld, *rd;
   6.349 -    struct vcpu   *led;
   6.350 -    u16                   dev_hst_ro_flags;
   6.351 -    int                   handle;
   6.352 -    unsigned long         frame = 0, host_virt_addr;
   6.353 -    int                   rc;
   6.354 -
   6.355 -    led = current;
   6.356 -    ld = led->domain;
   6.357 -
   6.358 -    /* Bitwise-OR avoids short-circuiting which screws control flow. */
   6.359 -    if ( unlikely(__get_user(dom, &uop->dom) |
   6.360 -                  __get_user(ref, &uop->ref) |
   6.361 -                  __get_user(host_virt_addr, &uop->host_addr) |
   6.362 -                  __get_user(dev_hst_ro_flags, &uop->flags)) )
   6.363 -    {
   6.364 -        DPRINTK("Fault while reading gnttab_map_grant_ref_t.\n");
   6.365 -        return -EFAULT; /* don't set status */
   6.366 -    }
   6.367 -
   6.368 -
   6.369 -    if ( ((host_virt_addr != 0) || (dev_hst_ro_flags & GNTMAP_host_map)) &&
   6.370 -         unlikely(!__addr_ok(host_virt_addr)))
   6.371 -    {
   6.372 -        DPRINTK("Bad virtual address (%lx) or flags (%x).\n",
   6.373 -                host_virt_addr, dev_hst_ro_flags);
   6.374 -        (void)__put_user(GNTST_bad_virt_addr, &uop->handle);
   6.375 -        return GNTST_bad_gntref;
   6.376 -    }
   6.377 -
   6.378 -    if ( unlikely(ref >= NR_GRANT_ENTRIES) ||
   6.379 -         unlikely((dev_hst_ro_flags &
   6.380 -                   (GNTMAP_device_map|GNTMAP_host_map)) == 0) )
   6.381 -    {
   6.382 -        DPRINTK("Bad ref (%d) or flags (%x).\n", ref, dev_hst_ro_flags);
   6.383 -        (void)__put_user(GNTST_bad_gntref, &uop->handle);
   6.384 -        return GNTST_bad_gntref;
   6.385 -    }
   6.386 -
   6.387 -    if ( unlikely((rd = find_domain_by_id(dom)) == NULL) ||
   6.388 -         unlikely(ld == rd) )
   6.389 -    {
   6.390 -        if ( rd != NULL )
   6.391 -            put_domain(rd);
   6.392 -        DPRINTK("Could not find domain %d\n", dom);
   6.393 -        (void)__put_user(GNTST_bad_domain, &uop->handle);
   6.394 -        return GNTST_bad_domain;
   6.395 -    }
   6.396 -
   6.397 -    /* Get a maptrack handle. */
   6.398 -    if ( unlikely((handle = get_maptrack_handle(ld->grant_table)) == -1) )
   6.399 -    {
   6.400 -        int              i;
   6.401 -        grant_mapping_t *new_mt;
   6.402 -        grant_table_t   *lgt      = ld->grant_table;
   6.403 -
   6.404 -        /* Grow the maptrack table. */
   6.405 -        new_mt = alloc_xenheap_pages(lgt->maptrack_order + 1);
   6.406 -        if ( new_mt == NULL )
   6.407 -        {
   6.408 -            put_domain(rd);
   6.409 -            DPRINTK("No more map handles available\n");
   6.410 -            (void)__put_user(GNTST_no_device_space, &uop->handle);
   6.411 -            return GNTST_no_device_space;
   6.412 -        }
   6.413 -
   6.414 -        memcpy(new_mt, lgt->maptrack, PAGE_SIZE << lgt->maptrack_order);
   6.415 -        for ( i = lgt->maptrack_limit; i < (lgt->maptrack_limit << 1); i++ )
   6.416 -            new_mt[i].ref_and_flags = (i+1) << MAPTRACK_REF_SHIFT;
   6.417 -
   6.418 -        free_xenheap_pages(lgt->maptrack, lgt->maptrack_order);
   6.419 -        lgt->maptrack          = new_mt;
   6.420 -        lgt->maptrack_order   += 1;
   6.421 -        lgt->maptrack_limit  <<= 1;
   6.422 -
   6.423 -        printk("Doubled maptrack size\n");
   6.424 -        handle = get_maptrack_handle(ld->grant_table);
   6.425 -    }
   6.426 -
   6.427 -#if GRANT_DEBUG_VERBOSE
   6.428 -    DPRINTK("Mapping grant ref (%hu) for domain (%hu) with flags (%x)\n",
   6.429 -            ref, dom, dev_hst_ro_flags);
   6.430 -#endif
   6.431 -
   6.432 -    if ( 0 <= ( rc = __gnttab_activate_grant_ref( ld, led, rd, ref,
   6.433 -                                                  dev_hst_ro_flags,
   6.434 -                                                  host_virt_addr, &frame)))
   6.435 -    {
   6.436 -        /*
   6.437 -         * Only make the maptrack live _after_ writing the pte, in case we 
   6.438 -         * overwrite the same frame number, causing a maptrack walk to find it
   6.439 -         */
   6.440 -        ld->grant_table->maptrack[handle].domid = dom;
   6.441 -
   6.442 -        ld->grant_table->maptrack[handle].ref_and_flags
   6.443 -            = (ref << MAPTRACK_REF_SHIFT) |
   6.444 -              (dev_hst_ro_flags & MAPTRACK_GNTMAP_MASK);
   6.445 -
   6.446 -        (void)__put_user(frame, &uop->dev_bus_addr);
   6.447 -
   6.448 -        if ( dev_hst_ro_flags & GNTMAP_host_map )
   6.449 -            *va = host_virt_addr;
   6.450 -
   6.451 -        (void)__put_user(handle, &uop->handle);
   6.452 -    }
   6.453 -    else
   6.454 -    {
   6.455 -        (void)__put_user(rc, &uop->handle);
   6.456 -        put_maptrack_handle(ld->grant_table, handle);
   6.457 -    }
   6.458 -
   6.459 -    put_domain(rd);
   6.460 -    return rc;
   6.461 -}
   6.462 -
   6.463 -static long
   6.464 -gnttab_map_grant_ref(
   6.465 -    gnttab_map_grant_ref_t *uop, unsigned int count)
   6.466 -{
   6.467 -    int i, flush = 0;
   6.468 -    unsigned long va = 0;
   6.469 -
   6.470 -    for ( i = 0; i < count; i++ )
   6.471 -        if ( __gnttab_map_grant_ref(&uop[i], &va) == 0 )
   6.472 -            flush++;
   6.473 -
   6.474 -#ifdef __ia64__
   6.475 -// FIXME-ia64: probably need to do something here to avoid stale mappings?
   6.476 -#else
   6.477 -    if ( flush == 1 )
   6.478 -        flush_tlb_one_mask(current->domain->cpumask, va);
   6.479 -    else if ( flush != 0 ) 
   6.480 -        flush_tlb_mask(current->domain->cpumask);
   6.481 -#endif
   6.482 -
   6.483 -    return 0;
   6.484 -}
   6.485 -
   6.486 -static int
   6.487 -__gnttab_unmap_grant_ref(
   6.488 -    gnttab_unmap_grant_ref_t *uop,
   6.489 -    unsigned long *va)
   6.490 -{
   6.491 -    domid_t        dom;
   6.492 -    grant_ref_t    ref;
   6.493 -    u16            handle;
   6.494 -    struct domain *ld, *rd;
   6.495 -
   6.496 -    active_grant_entry_t *act;
   6.497 -    grant_entry_t *sha;
   6.498 -    grant_mapping_t *map;
   6.499 -    u16            flags;
   6.500 -    s16            rc = 1;
   6.501 -    unsigned long  frame, virt;
   6.502 -
   6.503 -    ld = current->domain;
   6.504 -
   6.505 -    /* Bitwise-OR avoids short-circuiting which screws control flow. */
   6.506 -    if ( unlikely(__get_user(virt, &uop->host_addr) |
   6.507 -                  __get_user(frame, &uop->dev_bus_addr) |
   6.508 -                  __get_user(handle, &uop->handle)) )
   6.509 -    {
   6.510 -        DPRINTK("Fault while reading gnttab_unmap_grant_ref_t.\n");
   6.511 -        return -EFAULT; /* don't set status */
   6.512 -    }
   6.513 -
   6.514 -    map = &ld->grant_table->maptrack[handle];
   6.515 -
   6.516 -    if ( unlikely(handle >= ld->grant_table->maptrack_limit) ||
   6.517 -         unlikely(!(map->ref_and_flags & MAPTRACK_GNTMAP_MASK)) )
   6.518 -    {
   6.519 -        DPRINTK("Bad handle (%d).\n", handle);
   6.520 -        (void)__put_user(GNTST_bad_handle, &uop->status);
   6.521 -        return GNTST_bad_handle;
   6.522 -    }
   6.523 -
   6.524 -    dom   = map->domid;
   6.525 -    ref   = map->ref_and_flags >> MAPTRACK_REF_SHIFT;
   6.526 -    flags = map->ref_and_flags & MAPTRACK_GNTMAP_MASK;
   6.527 -
   6.528 -    if ( unlikely((rd = find_domain_by_id(dom)) == NULL) ||
   6.529 -         unlikely(ld == rd) )
   6.530 -    {
   6.531 -        if ( rd != NULL )
   6.532 -            put_domain(rd);
   6.533 -        DPRINTK("Could not find domain %d\n", dom);
   6.534 -        (void)__put_user(GNTST_bad_domain, &uop->status);
   6.535 -        return GNTST_bad_domain;
   6.536 -    }
   6.537 -
   6.538 -#if GRANT_DEBUG_VERBOSE
   6.539 -    DPRINTK("Unmapping grant ref (%hu) for domain (%hu) with handle (%hu)\n",
   6.540 -            ref, dom, handle);
   6.541 -#endif
   6.542 -
   6.543 -    act = &rd->grant_table->active[ref];
   6.544 -    sha = &rd->grant_table->shared[ref];
   6.545 -
   6.546 -    spin_lock(&rd->grant_table->lock);
   6.547 -
   6.548 -    if ( frame == 0 )
   6.549 -    {
   6.550 -        frame = act->frame;
   6.551 -    }
   6.552 -    else
   6.553 -    {
   6.554 -        if ( unlikely(frame != act->frame) )
   6.555 -            PIN_FAIL(unmap_out, GNTST_general_error,
   6.556 -                     "Bad frame number doesn't match gntref.\n");
   6.557 -        if ( flags & GNTMAP_device_map )
   6.558 -            act->pin -= (flags & GNTMAP_readonly) ? GNTPIN_devr_inc
   6.559 -                                                  : GNTPIN_devw_inc;
   6.560 -
   6.561 -        map->ref_and_flags &= ~GNTMAP_device_map;
   6.562 -        (void)__put_user(0, &uop->dev_bus_addr);
   6.563 -
   6.564 -        /* Frame is now unmapped for device access. */
   6.565 -    }
   6.566 -
   6.567 -    if ( (virt != 0) &&
   6.568 -         (flags & GNTMAP_host_map) &&
   6.569 -         ((act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask)) > 0))
   6.570 -    {
   6.571 -#ifdef __ia64__
   6.572 -// FIXME-ia64: any error checking need to be done here?
   6.573 -#else
   6.574 -        l1_pgentry_t   *pl1e;
   6.575 -        unsigned long   _ol1e;
   6.576 -
   6.577 -        pl1e = &linear_pg_table[l1_linear_offset(virt)];
   6.578 -
   6.579 -        if ( unlikely(__get_user(_ol1e, (unsigned long *)pl1e) != 0) )
   6.580 -        {
   6.581 -            DPRINTK("Could not find PTE entry for address %lx\n", virt);
   6.582 -            rc = -EINVAL;
   6.583 -            goto unmap_out;
   6.584 -        }
   6.585 -
   6.586 -        /*
   6.587 -         * Check that the virtual address supplied is actually mapped to 
   6.588 -         * act->frame.
   6.589 -         */
   6.590 -        if ( unlikely((_ol1e >> PAGE_SHIFT) != frame ))
   6.591 -        {
   6.592 -            DPRINTK("PTE entry %lx for address %lx doesn't match frame %lx\n",
   6.593 -                    _ol1e, virt, frame);
   6.594 -            rc = -EINVAL;
   6.595 -            goto unmap_out;
   6.596 -        }
   6.597 -
   6.598 -        /* Delete pagetable entry. */
   6.599 -        if ( unlikely(__put_user(0, (unsigned long *)pl1e)))
   6.600 -        {
   6.601 -            DPRINTK("Cannot delete PTE entry at %p for virtual address %lx\n",
   6.602 -                    pl1e, virt);
   6.603 -            rc = -EINVAL;
   6.604 -            goto unmap_out;
   6.605 -        }
   6.606 -#endif
   6.607 -
   6.608 -        map->ref_and_flags &= ~GNTMAP_host_map;
   6.609 -
   6.610 -        act->pin -= (flags & GNTMAP_readonly) ? GNTPIN_hstr_inc
   6.611 -                                              : GNTPIN_hstw_inc;
   6.612 -
   6.613 -        rc = 0;
   6.614 -        *va = virt;
   6.615 -    }
   6.616 -
   6.617 -    if ( (map->ref_and_flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0)
   6.618 -    {
   6.619 -        map->ref_and_flags = 0;
   6.620 -        put_maptrack_handle(ld->grant_table, handle);
   6.621 -    }
   6.622 -
   6.623 -#ifdef __ia64__
   6.624 -// FIXME-ia64: any error checking need to be done here?  I think not and then
   6.625 -//  this can probably be macro-ized into nothingness
   6.626 -#else
   6.627 -    /* If just unmapped a writable mapping, mark as dirtied */
   6.628 -    if ( unlikely(shadow_mode_log_dirty(rd)) &&
   6.629 -        !( flags & GNTMAP_readonly ) )
   6.630 -         mark_dirty(rd, frame);
   6.631 -#endif
   6.632 -
   6.633 -    /* If the last writable mapping has been removed, put_page_type */
   6.634 -    if ( ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask) ) == 0) &&
   6.635 -         ( !( flags & GNTMAP_readonly ) ) )
   6.636 -    {
   6.637 -        clear_bit(_GTF_writing, &sha->flags);
   6.638 -        put_page_type(&frame_table[frame]);
   6.639 -    }
   6.640 -
   6.641 -    if ( act->pin == 0 )
   6.642 -    {
   6.643 -        clear_bit(_GTF_reading, &sha->flags);
   6.644 -        put_page(&frame_table[frame]);
   6.645 -    }
   6.646 -
   6.647 - unmap_out:
   6.648 -    (void)__put_user(rc, &uop->status);
   6.649 -    spin_unlock(&rd->grant_table->lock);
   6.650 -    put_domain(rd);
   6.651 -    return rc;
   6.652 -}
   6.653 -
   6.654 -static long
   6.655 -gnttab_unmap_grant_ref(
   6.656 -    gnttab_unmap_grant_ref_t *uop, unsigned int count)
   6.657 -{
   6.658 -    int i, flush = 0;
   6.659 -    unsigned long va = 0;
   6.660 -
   6.661 -    for ( i = 0; i < count; i++ )
   6.662 -        if ( __gnttab_unmap_grant_ref(&uop[i], &va) == 0 )
   6.663 -            flush++;
   6.664 -
   6.665 -#ifdef __ia64__
   6.666 -// FIXME-ia64: probably need to do something here to avoid stale mappings?
   6.667 -#else
   6.668 -    if ( flush == 1 )
   6.669 -        flush_tlb_one_mask(current->domain->cpumask, va);
   6.670 -    else if ( flush != 0 ) 
   6.671 -        flush_tlb_mask(current->domain->cpumask);
   6.672 -#endif
   6.673 -
   6.674 -    return 0;
   6.675 -}
   6.676 -
   6.677 -static long 
   6.678 -gnttab_setup_table(
   6.679 -    gnttab_setup_table_t *uop, unsigned int count)
   6.680 -{
   6.681 -    gnttab_setup_table_t  op;
   6.682 -    struct domain        *d;
   6.683 -    int                   i;
   6.684 -    unsigned long addr;
   6.685 -
   6.686 -    if ( count != 1 )
   6.687 -        return -EINVAL;
   6.688 -
   6.689 -    if ( unlikely(copy_from_user(&op, uop, sizeof(op)) != 0) )
   6.690 -    {
   6.691 -        DPRINTK("Fault while reading gnttab_setup_table_t.\n");
   6.692 -        return -EFAULT;
   6.693 -    }
   6.694 -
   6.695 -    if ( unlikely(op.nr_frames > NR_GRANT_FRAMES) )
   6.696 -    {
   6.697 -        DPRINTK("Xen only supports up to %d grant-table frames per domain.\n",
   6.698 -                NR_GRANT_FRAMES);
   6.699 -        (void)put_user(GNTST_general_error, &uop->status);
   6.700 -        return 0;
   6.701 -    }
   6.702 -
   6.703 -    if ( op.dom == DOMID_SELF )
   6.704 -    {
   6.705 -        op.dom = current->domain->domain_id;
   6.706 -    }
   6.707 -    else if ( unlikely(!IS_PRIV(current->domain)) )
   6.708 -    {
   6.709 -        (void)put_user(GNTST_permission_denied, &uop->status);
   6.710 -        return 0;
   6.711 -    }
   6.712 -
   6.713 -    if ( unlikely((d = find_domain_by_id(op.dom)) == NULL) )
   6.714 -    {
   6.715 -        DPRINTK("Bad domid %d.\n", op.dom);
   6.716 -        (void)put_user(GNTST_bad_domain, &uop->status);
   6.717 -        return 0;
   6.718 -    }
   6.719 -
   6.720 -    if ( op.nr_frames <= NR_GRANT_FRAMES )
   6.721 -    {
   6.722 -        ASSERT(d->grant_table != NULL);
   6.723 -        (void)put_user(GNTST_okay, &uop->status);
   6.724 -#ifdef __ia64__
   6.725 -	if (d == dom0) {
   6.726 -            for ( i = 0; i < op.nr_frames; i++ )
   6.727 -                (void)put_user(
   6.728 -                    (virt_to_phys(d->grant_table->shared) >> PAGE_SHIFT) + i,
   6.729 -                    &uop->frame_list[i]);
   6.730 -	} else {
   6.731 -            /* IA64 hack - need to map it somewhere */
   6.732 -            addr = (1UL << 40);
   6.733 -            map_domain_page(d, addr, virt_to_phys(d->grant_table->shared));
   6.734 -            (void)put_user(addr >> PAGE_SHIFT, &uop->frame_list[0]);
   6.735 -        }
   6.736 -#else
   6.737 -        for ( i = 0; i < op.nr_frames; i++ )
   6.738 -            (void)put_user(
   6.739 -                (virt_to_phys(d->grant_table->shared) >> PAGE_SHIFT) + i,
   6.740 -                &uop->frame_list[i]);
   6.741 -#endif
   6.742 -    }
   6.743 -
   6.744 -    put_domain(d);
   6.745 -    return 0;
   6.746 -}
   6.747 -
   6.748 -#if GRANT_DEBUG
   6.749 -static int
   6.750 -gnttab_dump_table(gnttab_dump_table_t *uop)
   6.751 -{
   6.752 -    grant_table_t        *gt;
   6.753 -    gnttab_dump_table_t   op;
   6.754 -    struct domain        *d;
   6.755 -    u32                   shared_mfn;
   6.756 -    active_grant_entry_t *act;
   6.757 -    grant_entry_t         sha_copy;
   6.758 -    grant_mapping_t      *maptrack;
   6.759 -    int                   i;
   6.760 -
   6.761 -
   6.762 -    if ( unlikely(copy_from_user(&op, uop, sizeof(op)) != 0) )
   6.763 -    {
   6.764 -        DPRINTK("Fault while reading gnttab_dump_table_t.\n");
   6.765 -        return -EFAULT;
   6.766 -    }
   6.767 -
   6.768 -    if ( op.dom == DOMID_SELF )
   6.769 -    {
   6.770 -        op.dom = current->domain->domain_id;
   6.771 -    }
   6.772 -
   6.773 -    if ( unlikely((d = find_domain_by_id(op.dom)) == NULL) )
   6.774 -    {
   6.775 -        DPRINTK("Bad domid %d.\n", op.dom);
   6.776 -        (void)put_user(GNTST_bad_domain, &uop->status);
   6.777 -        return 0;
   6.778 -    }
   6.779 -
   6.780 -    ASSERT(d->grant_table != NULL);
   6.781 -    gt = d->grant_table;
   6.782 -    (void)put_user(GNTST_okay, &uop->status);
   6.783 -
   6.784 -    shared_mfn = virt_to_phys(d->grant_table->shared);
   6.785 -
   6.786 -    DPRINTK("Grant table for dom (%hu) MFN (%x)\n",
   6.787 -            op.dom, shared_mfn);
   6.788 -
   6.789 -    ASSERT(d->grant_table->active != NULL);
   6.790 -    ASSERT(d->grant_table->shared != NULL);
   6.791 -    ASSERT(d->grant_table->maptrack != NULL);
   6.792 -
   6.793 -    for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
   6.794 -    {
   6.795 -        sha_copy =  gt->shared[i];
   6.796 -
   6.797 -        if ( sha_copy.flags )
   6.798 -        {
   6.799 -            DPRINTK("Grant: dom (%hu) SHARED (%d) flags:(%hx) "
   6.800 -                    "dom:(%hu) frame:(%lx)\n",
   6.801 -                    op.dom, i, sha_copy.flags, sha_copy.domid, sha_copy.frame);
   6.802 -        }
   6.803 -    }
   6.804 -
   6.805 -    spin_lock(&gt->lock);
   6.806 -
   6.807 -    for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
   6.808 -    {
   6.809 -        act = &gt->active[i];
   6.810 -
   6.811 -        if ( act->pin )
   6.812 -        {
   6.813 -            DPRINTK("Grant: dom (%hu) ACTIVE (%d) pin:(%x) "
   6.814 -                    "dom:(%hu) frame:(%lx)\n",
   6.815 -                    op.dom, i, act->pin, act->domid, act->frame);
   6.816 -        }
   6.817 -    }
   6.818 -
   6.819 -    for ( i = 0; i < gt->maptrack_limit; i++ )
   6.820 -    {
   6.821 -        maptrack = &gt->maptrack[i];
   6.822 -
   6.823 -        if ( maptrack->ref_and_flags & MAPTRACK_GNTMAP_MASK )
   6.824 -        {
   6.825 -            DPRINTK("Grant: dom (%hu) MAP (%d) ref:(%hu) flags:(%x) "
   6.826 -                    "dom:(%hu)\n",
   6.827 -                    op.dom, i,
   6.828 -                    maptrack->ref_and_flags >> MAPTRACK_REF_SHIFT,
   6.829 -                    maptrack->ref_and_flags & MAPTRACK_GNTMAP_MASK,
   6.830 -                    maptrack->domid);
   6.831 -        }
   6.832 -    }
   6.833 -
   6.834 -    spin_unlock(&gt->lock);
   6.835 -
   6.836 -    put_domain(d);
   6.837 -    return 0;
   6.838 -}
   6.839 -#endif
   6.840 -
   6.841 -long 
   6.842 -do_grant_table_op(
   6.843 -    unsigned int cmd, void *uop, unsigned int count)
   6.844 -{
   6.845 -    long rc;
   6.846 -
   6.847 -    if ( count > 512 )
   6.848 -        return -EINVAL;
   6.849 -
   6.850 -    LOCK_BIGLOCK(current->domain);
   6.851 -
   6.852 -    rc = -EFAULT;
   6.853 -    switch ( cmd )
   6.854 -    {
   6.855 -    case GNTTABOP_map_grant_ref:
   6.856 -        if ( unlikely(!array_access_ok(
   6.857 -            uop, count, sizeof(gnttab_map_grant_ref_t))) )
   6.858 -            goto out;
   6.859 -        rc = gnttab_map_grant_ref((gnttab_map_grant_ref_t *)uop, count);
   6.860 -        break;
   6.861 -    case GNTTABOP_unmap_grant_ref:
   6.862 -        if ( unlikely(!array_access_ok(
   6.863 -            uop, count, sizeof(gnttab_unmap_grant_ref_t))) )
   6.864 -            goto out;
   6.865 -        rc = gnttab_unmap_grant_ref((gnttab_unmap_grant_ref_t *)uop, count);
   6.866 -        break;
   6.867 -    case GNTTABOP_setup_table:
   6.868 -        rc = gnttab_setup_table((gnttab_setup_table_t *)uop, count);
   6.869 -        break;
   6.870 -#if GRANT_DEBUG
   6.871 -    case GNTTABOP_dump_table:
   6.872 -        rc = gnttab_dump_table((gnttab_dump_table_t *)uop);
   6.873 -        break;
   6.874 -#endif
   6.875 -    default:
   6.876 -        rc = -ENOSYS;
   6.877 -        break;
   6.878 -    }
   6.879 -
   6.880 -out:
   6.881 -    UNLOCK_BIGLOCK(current->domain);
   6.882 -
   6.883 -    return rc;
   6.884 -}
   6.885 -
   6.886 -int
   6.887 -gnttab_check_unmap(
   6.888 -    struct domain *rd, struct domain *ld, unsigned long frame, int readonly)
   6.889 -{
   6.890 -    /* Called when put_page is invoked on a page belonging to a foreign domain.
   6.891 -     * Instead of decrementing the frame table ref count, locate the grant
   6.892 -     * table entry, if any, and if found, decrement that count.
   6.893 -     * Called a _lot_ at domain creation because pages mapped by priv domains
   6.894 -     * also traverse this.
   6.895 -     */
   6.896 -
   6.897 -    /* Note: If the same frame is mapped multiple times, and then one of
   6.898 -     *       the ptes is overwritten, which maptrack handle gets invalidated?
   6.899 -     * Advice: Don't do it. Explicitly unmap.
   6.900 -     */
   6.901 -
   6.902 -    unsigned int handle, ref, refcount;
   6.903 -    grant_table_t        *lgt, *rgt;
   6.904 -    active_grant_entry_t *act;
   6.905 -    grant_mapping_t      *map;
   6.906 -    int found = 0;
   6.907 -
   6.908 -    lgt = ld->grant_table;
   6.909 -
   6.910 -#if GRANT_DEBUG_VERBOSE
   6.911 -    if ( ld->domain_id != 0 )
   6.912 -    {
   6.913 -        DPRINTK("Foreign unref rd(%d) ld(%d) frm(%x) flgs(%x).\n",
   6.914 -                rd->domain_id, ld->domain_id, frame, readonly);
   6.915 -    }
   6.916 -#endif
   6.917 -
   6.918 -    /* Fast exit if we're not mapping anything using grant tables */
   6.919 -    if ( lgt->map_count == 0 )
   6.920 -        return 0;
   6.921 -
   6.922 -    if ( get_domain(rd) == 0 )
   6.923 -    {
   6.924 -        DPRINTK("gnttab_check_unmap: couldn't get_domain rd(%d)\n",
   6.925 -                rd->domain_id);
   6.926 -        return 0;
   6.927 -    }
   6.928 -
   6.929 -    rgt = rd->grant_table;
   6.930 -
   6.931 -    for ( handle = 0; handle < lgt->maptrack_limit; handle++ )
   6.932 -    {
   6.933 -        map = &lgt->maptrack[handle];
   6.934 -
   6.935 -        if ( ( map->ref_and_flags & MAPTRACK_GNTMAP_MASK ) &&
   6.936 -             ( readonly ? 1 : (!(map->ref_and_flags & GNTMAP_readonly))))
   6.937 -        {
   6.938 -            ref = (map->ref_and_flags >> MAPTRACK_REF_SHIFT);
   6.939 -            act = &rgt->active[ref];
   6.940 -
   6.941 -            spin_lock(&rgt->lock);
   6.942 -
   6.943 -            if ( act->frame != frame )
   6.944 -            {
   6.945 -                spin_unlock(&rgt->lock);
   6.946 -                continue;
   6.947 -            }
   6.948 -
   6.949 -            refcount = act->pin & ( readonly ? GNTPIN_hstr_mask
   6.950 -                                             : GNTPIN_hstw_mask );
   6.951 -            if ( refcount == 0 )
   6.952 -            {
   6.953 -                spin_unlock(&rgt->lock);
   6.954 -                continue;
   6.955 -            }
   6.956 -
   6.957 -            /* gotcha */
   6.958 -            DPRINTK("Grant unref rd(%d) ld(%d) frm(%lx) flgs(%x).\n",
   6.959 -                    rd->domain_id, ld->domain_id, frame, readonly);
   6.960 -
   6.961 -            if ( readonly )
   6.962 -                act->pin -= GNTPIN_hstr_inc;
   6.963 -            else
   6.964 -            {
   6.965 -                act->pin -= GNTPIN_hstw_inc;
   6.966 -
   6.967 -                /* any more granted writable mappings? */
   6.968 -                if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 )
   6.969 -                {
   6.970 -                    clear_bit(_GTF_writing, &rgt->shared[ref].flags);
   6.971 -                    put_page_type(&frame_table[frame]);
   6.972 -                }
   6.973 -            }
   6.974 -
   6.975 -            if ( act->pin == 0 )
   6.976 -            {
   6.977 -                clear_bit(_GTF_reading, &rgt->shared[ref].flags);
   6.978 -                put_page(&frame_table[frame]);
   6.979 -            }
   6.980 -            spin_unlock(&rgt->lock);
   6.981 -
   6.982 -            clear_bit(GNTMAP_host_map, &map->ref_and_flags);
   6.983 -
   6.984 -            if ( !(map->ref_and_flags & GNTMAP_device_map) )
   6.985 -                put_maptrack_handle(lgt, handle);
   6.986 -
   6.987 -            found = 1;
   6.988 -            break;
   6.989 -        }
   6.990 -    }
   6.991 -    put_domain(rd);
   6.992 -
   6.993 -    return found;
   6.994 -}
   6.995 -
   6.996 -int 
   6.997 -gnttab_prepare_for_transfer(
   6.998 -    struct domain *rd, struct domain *ld, grant_ref_t ref)
   6.999 -{
  6.1000 -    grant_table_t *rgt;
  6.1001 -    grant_entry_t *sha;
  6.1002 -    domid_t        sdom;
  6.1003 -    u16            sflags;
  6.1004 -    u32            scombo, prev_scombo;
  6.1005 -    int            retries = 0;
  6.1006 -    unsigned long  target_pfn;
  6.1007 -
  6.1008 -    DPRINTK("gnttab_prepare_for_transfer rd(%hu) ld(%hu) ref(%hu).\n",
  6.1009 -            rd->domain_id, ld->domain_id, ref);
  6.1010 -
  6.1011 -    if ( unlikely((rgt = rd->grant_table) == NULL) ||
  6.1012 -         unlikely(ref >= NR_GRANT_ENTRIES) )
  6.1013 -    {
  6.1014 -        DPRINTK("Dom %d has no g.t., or ref is bad (%d).\n",
  6.1015 -                rd->domain_id, ref);
  6.1016 -        return 0;
  6.1017 -    }
  6.1018 -
  6.1019 -    spin_lock(&rgt->lock);
  6.1020 -
  6.1021 -    sha = &rgt->shared[ref];
  6.1022 -    
  6.1023 -    sflags = sha->flags;
  6.1024 -    sdom   = sha->domid;
  6.1025 -
  6.1026 -    for ( ; ; )
  6.1027 -    {
  6.1028 -        target_pfn = sha->frame;
  6.1029 -
  6.1030 -        if ( unlikely(target_pfn >= max_page ) )
  6.1031 -        {
  6.1032 -            DPRINTK("Bad pfn (%lx)\n", target_pfn);
  6.1033 -            goto fail;
  6.1034 -        }
  6.1035 -
  6.1036 -        if ( unlikely(sflags != GTF_accept_transfer) ||
  6.1037 -             unlikely(sdom != ld->domain_id) )
  6.1038 -        {
  6.1039 -            DPRINTK("Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
  6.1040 -                    sflags, sdom, ld->domain_id);
  6.1041 -            goto fail;
  6.1042 -        }
  6.1043 -
  6.1044 -        /* Merge two 16-bit values into a 32-bit combined update. */
  6.1045 -        /* NB. Endianness! */
  6.1046 -        prev_scombo = scombo = ((u32)sdom << 16) | (u32)sflags;
  6.1047 -
  6.1048 -        /* NB. prev_scombo is updated in place to seen value. */
  6.1049 -        if ( unlikely(cmpxchg_user((u32 *)&sha->flags, prev_scombo, 
  6.1050 -                                   prev_scombo | GTF_transfer_committed)) )
  6.1051 -        {
  6.1052 -            DPRINTK("Fault while modifying shared flags and domid.\n");
  6.1053 -            goto fail;
  6.1054 -        }
  6.1055 -
  6.1056 -        /* Did the combined update work (did we see what we expected?). */
  6.1057 -        if ( likely(prev_scombo == scombo) )
  6.1058 -            break;
  6.1059 -
  6.1060 -        if ( retries++ == 4 )
  6.1061 -        {
  6.1062 -            DPRINTK("Shared grant entry is unstable.\n");
  6.1063 -            goto fail;
  6.1064 -        }
  6.1065 -
  6.1066 -        /* Didn't see what we expected. Split out the seen flags & dom. */
  6.1067 -        /* NB. Endianness! */
  6.1068 -        sflags = (u16)prev_scombo;
  6.1069 -        sdom   = (u16)(prev_scombo >> 16);
  6.1070 -    }
  6.1071 -
  6.1072 -    spin_unlock(&rgt->lock);
  6.1073 -    return 1;
  6.1074 -
  6.1075 - fail:
  6.1076 -    spin_unlock(&rgt->lock);
  6.1077 -    return 0;
  6.1078 -}
  6.1079 -
  6.1080 -void 
  6.1081 -gnttab_notify_transfer(
  6.1082 -    struct domain *rd, struct domain *ld, grant_ref_t ref, unsigned long frame)
  6.1083 -{
  6.1084 -    grant_entry_t  *sha;
  6.1085 -    unsigned long   pfn;
  6.1086 -
  6.1087 -    DPRINTK("gnttab_notify_transfer rd(%hu) ld(%hu) ref(%hu).\n",
  6.1088 -            rd->domain_id, ld->domain_id, ref);
  6.1089 -
  6.1090 -    sha = &rd->grant_table->shared[ref];
  6.1091 -
  6.1092 -    spin_lock(&rd->grant_table->lock);
  6.1093 -
  6.1094 -#ifdef __ia64__
  6.1095 -// FIXME-ia64: any error checking need to be done here?
  6.1096 -#else
  6.1097 -    pfn = sha->frame;
  6.1098 -
  6.1099 -    if ( unlikely(pfn >= max_page ) )
  6.1100 -        DPRINTK("Bad pfn (%lx)\n", pfn);
  6.1101 -    else
  6.1102 -    {
  6.1103 -        machine_to_phys_mapping[frame] = pfn;
  6.1104 -
  6.1105 -        if ( unlikely(shadow_mode_log_dirty(ld)))
  6.1106 -             mark_dirty(ld, frame);
  6.1107 -
  6.1108 -        if (shadow_mode_translate(ld))
  6.1109 -            __phys_to_machine_mapping[pfn] = frame;
  6.1110 -    }
  6.1111 -#endif
  6.1112 -    sha->frame = __mfn_to_gpfn(rd, frame);
  6.1113 -    sha->domid = rd->domain_id;
  6.1114 -    wmb();
  6.1115 -    sha->flags = ( GTF_accept_transfer | GTF_transfer_completed );
  6.1116 -
  6.1117 -    spin_unlock(&rd->grant_table->lock);
  6.1118 -
  6.1119 -    return;
  6.1120 -}
  6.1121 -
  6.1122 -int 
  6.1123 -grant_table_create(
  6.1124 -    struct domain *d)
  6.1125 -{
  6.1126 -    grant_table_t *t;
  6.1127 -    int            i;
  6.1128 -
  6.1129 -    if ( (t = xmalloc(grant_table_t)) == NULL )
  6.1130 -        goto no_mem;
  6.1131 -
  6.1132 -    /* Simple stuff. */
  6.1133 -    memset(t, 0, sizeof(*t));
  6.1134 -    spin_lock_init(&t->lock);
  6.1135 -
  6.1136 -    /* Active grant table. */
  6.1137 -    if ( (t->active = xmalloc_array(active_grant_entry_t, NR_GRANT_ENTRIES))
  6.1138 -         == NULL )
  6.1139 -        goto no_mem;
  6.1140 -    memset(t->active, 0, sizeof(active_grant_entry_t) * NR_GRANT_ENTRIES);
  6.1141 -
  6.1142 -    /* Tracking of mapped foreign frames table */
  6.1143 -    if ( (t->maptrack = alloc_xenheap_page()) == NULL )
  6.1144 -        goto no_mem;
  6.1145 -    t->maptrack_order = 0;
  6.1146 -    t->maptrack_limit = PAGE_SIZE / sizeof(grant_mapping_t);
  6.1147 -    memset(t->maptrack, 0, PAGE_SIZE);
  6.1148 -    for ( i = 0; i < t->maptrack_limit; i++ )
  6.1149 -        t->maptrack[i].ref_and_flags = (i+1) << MAPTRACK_REF_SHIFT;
  6.1150 -
  6.1151 -    /* Shared grant table. */
  6.1152 -    t->shared = alloc_xenheap_pages(ORDER_GRANT_FRAMES);
  6.1153 -    if ( t->shared == NULL )
  6.1154 -        goto no_mem;
  6.1155 -    memset(t->shared, 0, NR_GRANT_FRAMES * PAGE_SIZE);
  6.1156 -
  6.1157 -#ifdef __ia64__
  6.1158 -// I don't think there's anything to do here on ia64?...
  6.1159 -#else
  6.1160 -    for ( i = 0; i < NR_GRANT_FRAMES; i++ )
  6.1161 -    {
  6.1162 -        SHARE_PFN_WITH_DOMAIN(
  6.1163 -            virt_to_page((char *)(t->shared)+(i*PAGE_SIZE)), d);
  6.1164 -        machine_to_phys_mapping[(virt_to_phys(t->shared) >> PAGE_SHIFT) + i] =
  6.1165 -            INVALID_M2P_ENTRY;
  6.1166 -    }
  6.1167 -#endif
  6.1168 -
  6.1169 -    /* Okay, install the structure. */
  6.1170 -    wmb(); /* avoid races with lock-free access to d->grant_table */
  6.1171 -    d->grant_table = t;
  6.1172 -    return 0;
  6.1173 -
  6.1174 - no_mem:
  6.1175 -    if ( t != NULL )
  6.1176 -    {
  6.1177 -        xfree(t->active);
  6.1178 -        if ( t->maptrack != NULL )
  6.1179 -            free_xenheap_page(t->maptrack);
  6.1180 -        xfree(t);
  6.1181 -    }
  6.1182 -    return -ENOMEM;
  6.1183 -}
  6.1184 -
  6.1185 -void
  6.1186 -gnttab_release_dev_mappings(grant_table_t *gt)
  6.1187 -{
  6.1188 -    grant_mapping_t        *map;
  6.1189 -    domid_t                 dom;
  6.1190 -    grant_ref_t             ref;
  6.1191 -    u16                     handle;
  6.1192 -    struct domain          *ld, *rd;
  6.1193 -    unsigned long           frame;
  6.1194 -    active_grant_entry_t   *act;
  6.1195 -    grant_entry_t          *sha;
  6.1196 -
  6.1197 -    ld = current->domain;
  6.1198 -
  6.1199 -    for ( handle = 0; handle < gt->maptrack_limit; handle++ )
  6.1200 -    {
  6.1201 -        map = &gt->maptrack[handle];
  6.1202 -
  6.1203 -        if ( map->ref_and_flags & GNTMAP_device_map )
  6.1204 -        {
  6.1205 -            dom = map->domid;
  6.1206 -            ref = map->ref_and_flags >> MAPTRACK_REF_SHIFT;
  6.1207 -
  6.1208 -            DPRINTK("Grant release (%hu) ref:(%hu) flags:(%x) dom:(%hu)\n",
  6.1209 -                    handle, ref,
  6.1210 -                    map->ref_and_flags & MAPTRACK_GNTMAP_MASK, dom);
  6.1211 -
  6.1212 -            if ( unlikely((rd = find_domain_by_id(dom)) == NULL) ||
  6.1213 -                 unlikely(ld == rd) )
  6.1214 -            {
  6.1215 -                if ( rd != NULL )
  6.1216 -                    put_domain(rd);
  6.1217 -
  6.1218 -                printk(KERN_WARNING "Grant release: No dom%d\n", dom);
  6.1219 -                continue;
  6.1220 -            }
  6.1221 -
  6.1222 -            act = &rd->grant_table->active[ref];
  6.1223 -            sha = &rd->grant_table->shared[ref];
  6.1224 -
  6.1225 -            spin_lock(&rd->grant_table->lock);
  6.1226 -
  6.1227 -            if ( act->pin & (GNTPIN_devw_mask | GNTPIN_devr_mask) )
  6.1228 -            {
  6.1229 -                frame = act->frame;
  6.1230 -
  6.1231 -                if ( ( (act->pin & GNTPIN_hstw_mask) == 0 ) &&
  6.1232 -                     ( (act->pin & GNTPIN_devw_mask) >  0 ) )
  6.1233 -                {
  6.1234 -                    clear_bit(_GTF_writing, &sha->flags);
  6.1235 -                    put_page_type(&frame_table[frame]);
  6.1236 -                }
  6.1237 -
  6.1238 -                act->pin &= ~(GNTPIN_devw_mask | GNTPIN_devr_mask);
  6.1239 -
  6.1240 -                if ( act->pin == 0 )
  6.1241 -                {
  6.1242 -                    clear_bit(_GTF_reading, &sha->flags);
  6.1243 -                    map->ref_and_flags = 0;
  6.1244 -                    put_page(&frame_table[frame]);
  6.1245 -                }
  6.1246 -                else
  6.1247 -                    map->ref_and_flags &= ~GNTMAP_device_map;
  6.1248 -            }
  6.1249 -
  6.1250 -            spin_unlock(&rd->grant_table->lock);
  6.1251 -
  6.1252 -            put_domain(rd);
  6.1253 -        }
  6.1254 -    }
  6.1255 -}
  6.1256 -
  6.1257 -
  6.1258 -void
  6.1259 -grant_table_destroy(
  6.1260 -    struct domain *d)
  6.1261 -{
  6.1262 -    grant_table_t *t;
  6.1263 -
  6.1264 -    if ( (t = d->grant_table) != NULL )
  6.1265 -    {
  6.1266 -        /* Free memory relating to this grant table. */
  6.1267 -        d->grant_table = NULL;
  6.1268 -        free_xenheap_pages(t->shared, ORDER_GRANT_FRAMES);
  6.1269 -        free_xenheap_page(t->maptrack);
  6.1270 -        xfree(t->active);
  6.1271 -        xfree(t);
  6.1272 -    }
  6.1273 -}
  6.1274 -
  6.1275 -void
  6.1276 -grant_table_init(
  6.1277 -    void)
  6.1278 -{
  6.1279 -    /* Nothing. */
  6.1280 -}
  6.1281 -#endif
  6.1282 -
  6.1283 -/*
  6.1284 - * Local variables:
  6.1285 - * mode: C
  6.1286 - * c-set-style: "BSD"
  6.1287 - * c-basic-offset: 4
  6.1288 - * tab-width: 4
  6.1289 - * indent-tabs-mode: nil
  6.1290 - * End:
  6.1291 - */
     7.1 --- a/xen/arch/ia64/hpsimserial.c	Thu Sep 01 11:09:27 2005 -0600
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,23 +0,0 @@
     7.4 -/*
     7.5 - * HP Ski simulator serial I/O
     7.6 - *
     7.7 - * Copyright (C) 2004 Hewlett-Packard Co
     7.8 - *	Dan Magenheimer <dan.magenheimer@hp.com>
     7.9 - */
    7.10 -
    7.11 -#include <linux/config.h>
    7.12 -#include <xen/sched.h>
    7.13 -#include <xen/serial.h>
    7.14 -#include "hpsim_ssc.h"
    7.15 -
    7.16 -static void hp_ski_putc(struct serial_port *port, char c)
    7.17 -{
    7.18 -	ia64_ssc(c,0,0,0,SSC_PUTCHAR);
    7.19 -}
    7.20 -
    7.21 -static struct uart_driver hp_ski = { .putc = hp_ski_putc };
    7.22 -
    7.23 -void hpsim_serial_init(void)
    7.24 -{
    7.25 -	serial_register_uart(0, &hp_ski, 0);
    7.26 -}
     8.1 --- a/xen/arch/ia64/hypercall.c	Thu Sep 01 11:09:27 2005 -0600
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,182 +0,0 @@
     8.4 -/*
     8.5 - * Hypercall implementations
     8.6 - * 
     8.7 - * Copyright (C) 2005 Hewlett-Packard Co.
     8.8 - *	Dan Magenheimer (dan.magenheimer@hp.com)
     8.9 - *
    8.10 - */
    8.11 -
    8.12 -#include <xen/config.h>
    8.13 -#include <xen/sched.h>
    8.14 -
    8.15 -#include <linux/efi.h>	/* FOR EFI_UNIMPLEMENTED */
    8.16 -#include <asm/sal.h>	/* FOR struct ia64_sal_retval */
    8.17 -
    8.18 -#include <asm/vcpu.h>
    8.19 -#include <asm/dom_fw.h>
    8.20 -
    8.21 -extern unsigned long translate_domain_mpaddr(unsigned long);
    8.22 -extern struct ia64_pal_retval xen_pal_emulator(UINT64,UINT64,UINT64,UINT64);
    8.23 -extern struct ia64_sal_retval sal_emulator(UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64);
    8.24 -
    8.25 -unsigned long idle_when_pending = 0;
    8.26 -unsigned long pal_halt_light_count = 0;
    8.27 -
    8.28 -int
    8.29 -ia64_hypercall (struct pt_regs *regs)
    8.30 -{
    8.31 -	struct vcpu *v = (struct domain *) current;
    8.32 -	struct ia64_sal_retval x;
    8.33 -	struct ia64_pal_retval y;
    8.34 -	unsigned long *tv, *tc;
    8.35 -	int pi;
    8.36 -
    8.37 -	switch (regs->r2) {
    8.38 -	    case FW_HYPERCALL_PAL_CALL:
    8.39 -		//printf("*** PAL hypercall: index=%d\n",regs->r28);
    8.40 -		//FIXME: This should call a C routine
    8.41 -#if 0
    8.42 -		// This is very conservative, but avoids a possible
    8.43 -		// (and deadly) freeze in paravirtualized domains due
    8.44 -		// to a yet-to-be-found bug where pending_interruption
    8.45 -		// is zero when it shouldn't be. Since PAL is called
    8.46 -		// in the idle loop, this should resolve it
    8.47 -		VCPU(v,pending_interruption) = 1;
    8.48 -#endif
    8.49 -		if (regs->r28 == PAL_HALT_LIGHT) {
    8.50 -#define SPURIOUS_VECTOR 15
    8.51 -			pi = vcpu_check_pending_interrupts(v);
    8.52 -			if (pi != SPURIOUS_VECTOR) {
    8.53 -				if (!VCPU(v,pending_interruption))
    8.54 -					idle_when_pending++;
    8.55 -				vcpu_pend_unspecified_interrupt(v);
    8.56 -//printf("idle w/int#%d pending!\n",pi);
    8.57 -//this shouldn't happen, but it apparently does quite a bit!  so don't
    8.58 -//allow it to happen... i.e. if a domain has an interrupt pending and
    8.59 -//it tries to halt itself because it thinks it is idle, just return here
    8.60 -//as deliver_pending_interrupt is called on the way out and will deliver it
    8.61 -			}
    8.62 -			else {
    8.63 -				pal_halt_light_count++;
    8.64 -				do_sched_op(SCHEDOP_yield);
    8.65 -			}
    8.66 -			//break;
    8.67 -		}
    8.68 -		else if (regs->r28 >= PAL_COPY_PAL) {	/* FIXME */
    8.69 -			printf("stacked PAL hypercalls not supported\n");
    8.70 -			regs->r8 = -1;
    8.71 -			break;
    8.72 -		}
    8.73 -		else y = xen_pal_emulator(regs->r28,regs->r29,
    8.74 -						regs->r30,regs->r31);
    8.75 -		regs->r8 = y.status; regs->r9 = y.v0;
    8.76 -		regs->r10 = y.v1; regs->r11 = y.v2;
    8.77 -		break;
    8.78 -	    case FW_HYPERCALL_SAL_CALL:
    8.79 -		x = sal_emulator(vcpu_get_gr(v,32),vcpu_get_gr(v,33),
    8.80 -			vcpu_get_gr(v,34),vcpu_get_gr(v,35),
    8.81 -			vcpu_get_gr(v,36),vcpu_get_gr(v,37),
    8.82 -			vcpu_get_gr(v,38),vcpu_get_gr(v,39));
    8.83 -		regs->r8 = x.status; regs->r9 = x.v0;
    8.84 -		regs->r10 = x.v1; regs->r11 = x.v2;
    8.85 -		break;
    8.86 -	    case FW_HYPERCALL_EFI_RESET_SYSTEM:
    8.87 -		printf("efi.reset_system called ");
    8.88 -		if (current->domain == dom0) {
    8.89 -			printf("(by dom0)\n ");
    8.90 -			(*efi.reset_system)(EFI_RESET_WARM,0,0,NULL);
    8.91 -		}
    8.92 -#ifdef DOMU_AUTO_RESTART
    8.93 -		else {
    8.94 -			reconstruct_domU(current);
    8.95 -			return 0;  // don't increment ip!
    8.96 -		}
    8.97 -#else	
    8.98 -		printf("(not supported for non-0 domain)\n");
    8.99 -		regs->r8 = EFI_UNSUPPORTED;
   8.100 -#endif
   8.101 -		break;
   8.102 -	    case FW_HYPERCALL_EFI_GET_TIME:
   8.103 -		tv = vcpu_get_gr(v,32);
   8.104 -		tc = vcpu_get_gr(v,33);
   8.105 -		//printf("efi_get_time(%p,%p) called...",tv,tc);
   8.106 -		tv = __va(translate_domain_mpaddr(tv));
   8.107 -		if (tc) tc = __va(translate_domain_mpaddr(tc));
   8.108 -		regs->r8 = (*efi.get_time)(tv,tc);
   8.109 -		//printf("and returns %lx\n",regs->r8);
   8.110 -		break;
   8.111 -	    case FW_HYPERCALL_EFI_SET_TIME:
   8.112 -	    case FW_HYPERCALL_EFI_GET_WAKEUP_TIME:
   8.113 -	    case FW_HYPERCALL_EFI_SET_WAKEUP_TIME:
   8.114 -		// FIXME: need fixes in efi.h from 2.6.9
   8.115 -	    case FW_HYPERCALL_EFI_SET_VIRTUAL_ADDRESS_MAP:
   8.116 -		// FIXME: WARNING!! IF THIS EVER GETS IMPLEMENTED
   8.117 -		// SOME OF THE OTHER EFI EMULATIONS WILL CHANGE AS 
   8.118 -		// POINTER ARGUMENTS WILL BE VIRTUAL!!
   8.119 -	    case FW_HYPERCALL_EFI_GET_VARIABLE:
   8.120 -		// FIXME: need fixes in efi.h from 2.6.9
   8.121 -	    case FW_HYPERCALL_EFI_GET_NEXT_VARIABLE:
   8.122 -	    case FW_HYPERCALL_EFI_SET_VARIABLE:
   8.123 -	    case FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT:
   8.124 -		// FIXME: need fixes in efi.h from 2.6.9
   8.125 -		regs->r8 = EFI_UNSUPPORTED;
   8.126 -		break;
   8.127 -	    case 0xffff: // test dummy hypercall
   8.128 -		regs->r8 = dump_privop_counts_to_user(
   8.129 -			vcpu_get_gr(v,32),
   8.130 -			vcpu_get_gr(v,33));
   8.131 -		break;
   8.132 -	    case 0xfffe: // test dummy hypercall
   8.133 -		regs->r8 = zero_privop_counts_to_user(
   8.134 -			vcpu_get_gr(v,32),
   8.135 -			vcpu_get_gr(v,33));
   8.136 -		break;
   8.137 -	    case 0xfffd: // test dummy hypercall
   8.138 -		regs->r8 = launch_domainU(
   8.139 -			vcpu_get_gr(v,32));
   8.140 -		break;
   8.141 -	    case 0xfffc: // test dummy hypercall
   8.142 -		regs->r8 = domU_staging_write_32(
   8.143 -			vcpu_get_gr(v,32),
   8.144 -			vcpu_get_gr(v,33),
   8.145 -			vcpu_get_gr(v,34),
   8.146 -			vcpu_get_gr(v,35),
   8.147 -			vcpu_get_gr(v,36));
   8.148 -		break;
   8.149 -	    case 0xfffb: // test dummy hypercall
   8.150 -		regs->r8 = domU_staging_read_8(vcpu_get_gr(v,32));
   8.151 -		break;
   8.152 -
   8.153 -	    case __HYPERVISOR_dom0_op:
   8.154 -		regs->r8 = do_dom0_op(regs->r14);
   8.155 -		break;
   8.156 -
   8.157 -	    case __HYPERVISOR_dom_mem_op:
   8.158 -#ifdef CONFIG_VTI
   8.159 -		regs->r8 = do_dom_mem_op(regs->r14, regs->r15, regs->r16, regs->r17, regs->r18); 
   8.160 -#else
   8.161 -		/* we don't handle reservations; just return success */
   8.162 -		regs->r8 = regs->r16;
   8.163 -#endif
   8.164 -		break;
   8.165 -
   8.166 -	    case __HYPERVISOR_event_channel_op:
   8.167 -		regs->r8 = do_event_channel_op(regs->r14);
   8.168 -		break;
   8.169 -
   8.170 -#ifndef CONFIG_VTI
   8.171 -	    case __HYPERVISOR_grant_table_op:
   8.172 -		regs->r8 = do_grant_table_op(regs->r14, regs->r15, regs->r16);
   8.173 -		break;
   8.174 -#endif
   8.175 -
   8.176 -	    case __HYPERVISOR_console_io:
   8.177 -		regs->r8 = do_console_io(regs->r14, regs->r15, regs->r16);
   8.178 -		break;
   8.179 -
   8.180 -	    default:
   8.181 -		printf("unknown hypercall %x\n", regs->r2);
   8.182 -		regs->r8 = (unsigned long)-1;
   8.183 -	}
   8.184 -	return 1;
   8.185 -}
     9.1 --- a/xen/arch/ia64/hyperprivop.S	Thu Sep 01 11:09:27 2005 -0600
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,1592 +0,0 @@
     9.4 -/*
     9.5 - * arch/ia64/kernel/hyperprivop.S
     9.6 - *
     9.7 - * Copyright (C) 2005 Hewlett-Packard Co
     9.8 - *	Dan Magenheimer <dan.magenheimer@hp.com>
     9.9 - */
    9.10 -
    9.11 -#include <linux/config.h>
    9.12 -
    9.13 -#include <asm/asmmacro.h>
    9.14 -#include <asm/kregs.h>
    9.15 -#include <asm/offsets.h>
    9.16 -#include <asm/processor.h>
    9.17 -#include <asm/system.h>
    9.18 -#include <public/arch-ia64.h>
    9.19 -
    9.20 -#if 1	 // change to 0 to turn off all fast paths
    9.21 -#define FAST_HYPERPRIVOPS
    9.22 -#define FAST_HYPERPRIVOP_CNT
    9.23 -#define FAST_REFLECT_CNT
    9.24 -//#define FAST_TICK
    9.25 -#define FAST_BREAK
    9.26 -#define FAST_ACCESS_REFLECT
    9.27 -#define FAST_RFI
    9.28 -#define FAST_SSM_I
    9.29 -#define FAST_PTC_GA
    9.30 -#undef RFI_TO_INTERRUPT // not working yet
    9.31 -#endif
    9.32 -
    9.33 -#ifdef CONFIG_SMP
    9.34 -#warning "FIXME: ptc.ga instruction requires spinlock for SMP"
    9.35 -#undef FAST_PTC_GA
    9.36 -#endif
    9.37 -
    9.38 -// FIXME: turn off for now... but NaTs may crash Xen so re-enable soon!
    9.39 -//#define HANDLE_AR_UNAT
    9.40 -
    9.41 -// FIXME: This is defined in include/asm-ia64/hw_irq.h but this
    9.42 -// doesn't appear to be include'able from assembly?
    9.43 -#define IA64_TIMER_VECTOR 0xef
    9.44 -
    9.45 -// Should be included from common header file (also in process.c)
    9.46 -//  NO PSR_CLR IS DIFFERENT! (CPL)
    9.47 -#define IA64_PSR_CPL1	(__IA64_UL(1) << IA64_PSR_CPL1_BIT)
    9.48 -#define IA64_PSR_CPL0	(__IA64_UL(1) << IA64_PSR_CPL0_BIT)
    9.49 -// note IA64_PSR_PK removed from following, why is this necessary?
    9.50 -#define	DELIVER_PSR_SET	(IA64_PSR_IC | IA64_PSR_I | \
    9.51 -			IA64_PSR_DT | IA64_PSR_RT | IA64_PSR_CPL1 | \
    9.52 -			IA64_PSR_IT | IA64_PSR_BN)
    9.53 -
    9.54 -#define	DELIVER_PSR_CLR	(IA64_PSR_AC | IA64_PSR_DFL | IA64_PSR_DFH | \
    9.55 -			IA64_PSR_SP | IA64_PSR_DI | IA64_PSR_SI |	\
    9.56 -			IA64_PSR_DB | IA64_PSR_LP | IA64_PSR_TB | \
    9.57 -			IA64_PSR_MC | IA64_PSR_IS | \
    9.58 -			IA64_PSR_ID | IA64_PSR_DA | IA64_PSR_DD | \
    9.59 -			IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | IA64_PSR_IA)
    9.60 -
    9.61 -// Note: not hand-scheduled for now
    9.62 -//  Registers at entry
    9.63 -//	r16 == cr.isr
    9.64 -//	r17 == cr.iim
    9.65 -//	r18 == XSI_PSR_IC_OFS
    9.66 -//	r19 == vpsr.ic (low 32 bits) | vpsr.i (high 32 bits)
    9.67 -//	r31 == pr
    9.68 -GLOBAL_ENTRY(fast_hyperprivop)
    9.69 -#ifndef FAST_HYPERPRIVOPS // see beginning of file
    9.70 -	br.sptk.many dispatch_break_fault ;;
    9.71 -#endif
    9.72 -	// HYPERPRIVOP_SSM_I?
    9.73 -	// assumes domain interrupts pending, so just do it
    9.74 -	cmp.eq p7,p6=XEN_HYPER_SSM_I,r17
    9.75 -(p7)	br.sptk.many hyper_ssm_i;;
    9.76 -
    9.77 -	// FIXME. This algorithm gives up (goes to the slow path) if there
    9.78 -	// are ANY interrupts pending, even if they are currently
    9.79 -	// undeliverable.  This should be improved later...
    9.80 -	adds r20=XSI_PEND_OFS-XSI_PSR_IC_OFS,r18 ;;
    9.81 -	ld4 r20=[r20] ;;
    9.82 -	cmp.eq p7,p0=r0,r20
    9.83 -(p7)	br.cond.sptk.many 1f
    9.84 -	movl r20=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;
    9.85 -	ld8 r20=[r20];;
    9.86 -	adds r21=IA64_VCPU_IRR0_OFFSET,r20;
    9.87 -	adds r22=IA64_VCPU_IRR0_OFFSET+8,r20;;
    9.88 -	ld8 r23=[r21],16; ld8 r24=[r22],16;;
    9.89 -	ld8 r21=[r21]; ld8 r22=[r22];;
    9.90 -	or r23=r23,r24; or r21=r21,r22;;
    9.91 -	or r20=r23,r21;;
    9.92 -1:	// when we get to here r20=~=interrupts pending
    9.93 -
    9.94 -	// HYPERPRIVOP_RFI?
    9.95 -	cmp.eq p7,p6=XEN_HYPER_RFI,r17
    9.96 -(p7)	br.sptk.many hyper_rfi;;
    9.97 -
    9.98 -	// HYPERPRIVOP_GET_IVR?
    9.99 -	cmp.eq p7,p6=XEN_HYPER_GET_IVR,r17
   9.100 -(p7)	br.sptk.many hyper_get_ivr;;
   9.101 -
   9.102 -	cmp.ne p7,p0=r20,r0
   9.103 -(p7)	br.spnt.many dispatch_break_fault ;;
   9.104 -
   9.105 -	// HYPERPRIVOP_COVER?
   9.106 -	cmp.eq p7,p6=XEN_HYPER_COVER,r17
   9.107 -(p7)	br.sptk.many hyper_cover;;
   9.108 -
   9.109 -	// HYPERPRIVOP_SSM_DT?
   9.110 -	cmp.eq p7,p6=XEN_HYPER_SSM_DT,r17
   9.111 -(p7)	br.sptk.many hyper_ssm_dt;;
   9.112 -
   9.113 -	// HYPERPRIVOP_RSM_DT?
   9.114 -	cmp.eq p7,p6=XEN_HYPER_RSM_DT,r17
   9.115 -(p7)	br.sptk.many hyper_rsm_dt;;
   9.116 -
   9.117 -	// HYPERPRIVOP_GET_TPR?
   9.118 -	cmp.eq p7,p6=XEN_HYPER_GET_TPR,r17
   9.119 -(p7)	br.sptk.many hyper_get_tpr;;
   9.120 -
   9.121 -	// HYPERPRIVOP_SET_TPR?
   9.122 -	cmp.eq p7,p6=XEN_HYPER_SET_TPR,r17
   9.123 -(p7)	br.sptk.many hyper_set_tpr;;
   9.124 -
   9.125 -	// HYPERPRIVOP_EOI?
   9.126 -	cmp.eq p7,p6=XEN_HYPER_EOI,r17
   9.127 -(p7)	br.sptk.many hyper_eoi;;
   9.128 -
   9.129 -	// HYPERPRIVOP_SET_ITM?
   9.130 -	cmp.eq p7,p6=XEN_HYPER_SET_ITM,r17
   9.131 -(p7)	br.sptk.many hyper_set_itm;;
   9.132 -
   9.133 -	// HYPERPRIVOP_SET_RR?
   9.134 -	cmp.eq p7,p6=XEN_HYPER_SET_RR,r17
   9.135 -(p7)	br.sptk.many hyper_set_rr;;
   9.136 -
   9.137 -	// HYPERPRIVOP_GET_RR?
   9.138 -	cmp.eq p7,p6=XEN_HYPER_GET_RR,r17
   9.139 -(p7)	br.sptk.many hyper_get_rr;;
   9.140 -
   9.141 -	// HYPERPRIVOP_PTC_GA?
   9.142 -	cmp.eq p7,p6=XEN_HYPER_PTC_GA,r17
   9.143 -(p7)	br.sptk.many hyper_ptc_ga;;
   9.144 -
   9.145 -	// HYPERPRIVOP_ITC_D?
   9.146 -	cmp.eq p7,p6=XEN_HYPER_ITC_D,r17
   9.147 -(p7)	br.sptk.many hyper_itc_d;;
   9.148 -
   9.149 -	// HYPERPRIVOP_ITC_I?
   9.150 -	cmp.eq p7,p6=XEN_HYPER_ITC_I,r17
   9.151 -(p7)	br.sptk.many hyper_itc_i;;
   9.152 -
   9.153 -	// HYPERPRIVOP_THASH?
   9.154 -	cmp.eq p7,p6=XEN_HYPER_THASH,r17
   9.155 -(p7)	br.sptk.many hyper_thash;;
   9.156 -
   9.157 -	// if not one of the above, give up for now and do it the slow way
   9.158 -	br.sptk.many dispatch_break_fault ;;
   9.159 -
   9.160 -
   9.161 -// give up for now if: ipsr.be==1, ipsr.pp==1
   9.162 -// from reflect_interruption, don't need to:
   9.163 -//  - printf first extint (debug only)
   9.164 -//  - check for interrupt collection enabled (routine will force on)
   9.165 -//  - set ifa (not valid for extint)
   9.166 -//  - set iha (not valid for extint)
   9.167 -//  - set itir (not valid for extint)
   9.168 -// DO need to
   9.169 -//  - increment the HYPER_SSM_I fast_hyperprivop counter
   9.170 -//  - set shared_mem iip to instruction after HYPER_SSM_I
   9.171 -//  - set cr.iip to guest iva+0x3000
   9.172 -//  - set shared_mem ipsr to [vcpu_get_ipsr_int_state]
   9.173 -//     be = pp = bn = 0; dt = it = rt = 1; cpl = 3 or 0;
   9.174 -//     i = shared_mem interrupt_delivery_enabled
   9.175 -//     ic = shared_mem interrupt_collection_enabled
   9.176 -//     ri = instruction after HYPER_SSM_I
   9.177 -//     all other bits unchanged from real cr.ipsr
   9.178 -//  - set cr.ipsr (DELIVER_PSR_SET/CLEAR, don't forget cpl!)
   9.179 -//  - set shared_mem isr: isr.ei to instr following HYPER_SSM_I
   9.180 -//	and isr.ri to cr.isr.ri (all other bits zero)
   9.181 -//  - cover and set shared_mem precover_ifs to cr.ifs
   9.182 -//		^^^ MISSED THIS FOR fast_break??
   9.183 -//  - set shared_mem ifs and incomplete_regframe to 0
   9.184 -//  - set shared_mem interrupt_delivery_enabled to 0
   9.185 -//  - set shared_mem interrupt_collection_enabled to 0
   9.186 -//  - set r31 to SHAREDINFO_ADDR
   9.187 -//  - virtual bank switch 0
   9.188 -// maybe implement later
   9.189 -//  - verify that there really IS a deliverable interrupt pending
   9.190 -//  - set shared_mem iva
   9.191 -// needs to be done but not implemented (in reflect_interruption)
   9.192 -//  - set shared_mem iipa
   9.193 -// don't know for sure
   9.194 -//  - set shared_mem unat
   9.195 -//	r16 == cr.isr
   9.196 -//	r17 == cr.iim
   9.197 -//	r18 == XSI_PSR_IC
   9.198 -//	r19 == vpsr.ic (low 32 bits) | vpsr.i (high 32 bits)
   9.199 -//	r31 == pr
   9.200 -ENTRY(hyper_ssm_i)
   9.201 -#ifndef FAST_SSM_I
   9.202 -	br.spnt.few dispatch_break_fault ;;
   9.203 -#endif
   9.204 -	// give up for now if: ipsr.be==1, ipsr.pp==1
   9.205 -	mov r30=cr.ipsr;;
   9.206 -	mov r29=cr.iip;;
   9.207 -	extr.u r21=r30,IA64_PSR_BE_BIT,1 ;;
   9.208 -	cmp.ne p7,p0=r21,r0
   9.209 -(p7)	br.sptk.many dispatch_break_fault ;;
   9.210 -	extr.u r21=r30,IA64_PSR_PP_BIT,1 ;;
   9.211 -	cmp.ne p7,p0=r21,r0
   9.212 -(p7)	br.sptk.many dispatch_break_fault ;;
   9.213 -#ifdef FAST_HYPERPRIVOP_CNT
   9.214 -	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_SSM_I);;
   9.215 -	ld8 r21=[r20];;
   9.216 -	adds r21=1,r21;;
   9.217 -	st8 [r20]=r21;;
   9.218 -#endif
   9.219 -	// set shared_mem iip to instruction after HYPER_SSM_I
   9.220 -	extr.u r20=r30,41,2 ;;
   9.221 -	cmp.eq p6,p7=2,r20 ;;
   9.222 -(p6)	mov r20=0
   9.223 -(p6)	adds r29=16,r29
   9.224 -(p7)	adds r20=1,r20 ;;
   9.225 -	dep r30=r20,r30,41,2;;	// adjust cr.ipsr.ri but don't save yet
   9.226 -	adds r21=XSI_IIP_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.227 -	st8 [r21]=r29 ;;
   9.228 -	// set shared_mem isr
   9.229 -	extr.u r16=r16,38,1;;	// grab cr.isr.ir bit
   9.230 -	dep r16=r16,r0,38,1 ;;	// insert into cr.isr (rest of bits zero)
   9.231 -	dep r16=r20,r16,41,2 ;; // deposit cr.isr.ri
   9.232 -	adds r21=XSI_ISR_OFS-XSI_PSR_IC_OFS,r18 ;; 
   9.233 -	st8 [r21]=r16 ;;
   9.234 -	// set cr.ipsr
   9.235 -	mov r29=r30 ;;
   9.236 -	movl r28=DELIVER_PSR_SET;;
   9.237 -	movl r27=~DELIVER_PSR_CLR;;
   9.238 -	or r29=r29,r28;;
   9.239 -	and r29=r29,r27;;
   9.240 -	mov cr.ipsr=r29;;
   9.241 -	// set shared_mem ipsr (from ipsr in r30 with ipsr.ri already set)
   9.242 -	extr.u r29=r30,IA64_PSR_CPL0_BIT,2;;
   9.243 -	cmp.eq p6,p7=3,r29;;
   9.244 -(p6)	dep r30=-1,r30,IA64_PSR_CPL0_BIT,2
   9.245 -(p7)	dep r30=0,r30,IA64_PSR_CPL0_BIT,2
   9.246 -	;;
   9.247 -	// FOR SSM_I ONLY, also turn on psr.i and psr.ic
   9.248 -	movl r28=(IA64_PSR_DT|IA64_PSR_IT|IA64_PSR_RT|IA64_PSR_I|IA64_PSR_IC);;
   9.249 -	movl r27=~(IA64_PSR_BE|IA64_PSR_PP|IA64_PSR_BN);;
   9.250 -	or r30=r30,r28;;
   9.251 -	and r30=r30,r27;;
   9.252 -	adds r21=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.253 -	st8 [r21]=r30 ;;
   9.254 -	// set shared_mem interrupt_delivery_enabled to 0
   9.255 -	// set shared_mem interrupt_collection_enabled to 0
   9.256 -	st8 [r18]=r0;;
   9.257 -	// cover and set shared_mem precover_ifs to cr.ifs
   9.258 -	// set shared_mem ifs and incomplete_regframe to 0
   9.259 -	cover ;;
   9.260 -	mov r20=cr.ifs;;
   9.261 -	adds r21=XSI_INCOMPL_REG_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.262 -	st4 [r21]=r0 ;;
   9.263 -	adds r21=XSI_IFS_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.264 -	st8 [r21]=r0 ;;
   9.265 -	adds r21=XSI_PRECOVER_IFS_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.266 -	st8 [r21]=r20 ;;
   9.267 -	// leave cr.ifs alone for later rfi
   9.268 -	// set iip to go to domain IVA break instruction vector
   9.269 -	movl r22=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;
   9.270 -	ld8 r22=[r22];;
   9.271 -	adds r22=IA64_VCPU_IVA_OFFSET,r22;;
   9.272 -	ld8 r23=[r22];;
   9.273 -	movl r24=0x3000;;
   9.274 -	add r24=r24,r23;;
   9.275 -	mov cr.iip=r24;;
   9.276 -	// OK, now all set to go except for switch to virtual bank0
   9.277 -	mov r30=r2; mov r29=r3;;
   9.278 -	adds r2=XSI_BANK1_OFS-XSI_PSR_IC_OFS,r18;
   9.279 -	adds r3=(XSI_BANK1_OFS+8)-XSI_PSR_IC_OFS,r18;;
   9.280 -	bsw.1;;
   9.281 -	// FIXME?: ar.unat is not really handled correctly,
   9.282 -	// but may not matter if the OS is NaT-clean
   9.283 -	.mem.offset 0,0; st8.spill [r2]=r16,16;
   9.284 -	.mem.offset 8,0; st8.spill [r3]=r17,16 ;;
   9.285 -	.mem.offset 0,0; st8.spill [r2]=r18,16;
   9.286 -	.mem.offset 8,0; st8.spill [r3]=r19,16 ;;
   9.287 -	.mem.offset 0,0; st8.spill [r2]=r20,16;
   9.288 -	.mem.offset 8,0; st8.spill [r3]=r21,16 ;;
   9.289 -	.mem.offset 0,0; st8.spill [r2]=r22,16;
   9.290 -	.mem.offset 8,0; st8.spill [r3]=r23,16 ;;
   9.291 -	.mem.offset 0,0; st8.spill [r2]=r24,16;
   9.292 -	.mem.offset 8,0; st8.spill [r3]=r25,16 ;;
   9.293 -	.mem.offset 0,0; st8.spill [r2]=r26,16;
   9.294 -	.mem.offset 8,0; st8.spill [r3]=r27,16 ;;
   9.295 -	.mem.offset 0,0; st8.spill [r2]=r28,16;
   9.296 -	.mem.offset 8,0; st8.spill [r3]=r29,16 ;;
   9.297 -	.mem.offset 0,0; st8.spill [r2]=r30,16;
   9.298 -	.mem.offset 8,0; st8.spill [r3]=r31,16 ;;
   9.299 -	movl r31=XSI_IPSR;;
   9.300 -	bsw.0 ;;
   9.301 -	mov r2=r30; mov r3=r29;;
   9.302 -	adds r20=XSI_BANKNUM_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.303 -	st4 [r20]=r0 ;;
   9.304 -	mov pr=r31,-1 ;;
   9.305 -	rfi
   9.306 -	;;
   9.307 -
   9.308 -// reflect domain clock interrupt
   9.309 -//	r31 == pr
   9.310 -//	r30 == cr.ivr
   9.311 -//	r29 == rp
   9.312 -GLOBAL_ENTRY(fast_tick_reflect)
   9.313 -#ifndef FAST_TICK // see beginning of file
   9.314 -	br.cond.sptk.many rp;;
   9.315 -#endif
   9.316 -	mov r28=IA64_TIMER_VECTOR;;
   9.317 -	cmp.ne p6,p0=r28,r30
   9.318 -(p6)	br.cond.spnt.few rp;;
   9.319 -	movl r20=THIS_CPU(cpu_info)+IA64_CPUINFO_ITM_NEXT_OFFSET;;
   9.320 -	ld8 r26=[r20];;
   9.321 -	mov r27=ar.itc;;
   9.322 -	adds r27=200,r27;;	// safety margin
   9.323 -	cmp.ltu p6,p0=r26,r27
   9.324 -(p6)	br.cond.spnt.few rp;;
   9.325 -	mov r17=cr.ipsr;;
   9.326 -	// slow path if: ipsr.be==1, ipsr.pp==1
   9.327 -	extr.u r21=r17,IA64_PSR_BE_BIT,1 ;;
   9.328 -	cmp.ne p6,p0=r21,r0
   9.329 -(p6)	br.cond.spnt.few rp;;
   9.330 -	extr.u r21=r17,IA64_PSR_PP_BIT,1 ;;
   9.331 -	cmp.ne p6,p0=r21,r0
   9.332 -(p6)	br.cond.spnt.few rp;;
   9.333 -	// definitely have a domain tick
   9.334 -	mov cr.eoi=r0;;
   9.335 -	mov rp=r29;;
   9.336 -	mov cr.itm=r26;;	// ensure next tick
   9.337 -#ifdef FAST_REFLECT_CNT
   9.338 -	movl r20=fast_reflect_count+((0x3000>>8)*8);;
   9.339 -	ld8 r21=[r20];;
   9.340 -	adds r21=1,r21;;
   9.341 -	st8 [r20]=r21;;
   9.342 -#endif
   9.343 -	// vcpu_pend_timer(current)
   9.344 -	movl r18=XSI_PSR_IC;;
   9.345 -	adds r20=XSI_ITV_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.346 -	ld8 r20=[r20];;
   9.347 -	cmp.eq p6,p0=r20,r0	// if cr.itv==0 done
   9.348 -(p6)	br.cond.spnt.few fast_tick_reflect_done;;
   9.349 -	tbit.nz p6,p0=r20,16;;	// check itv.m (discard) bit
   9.350 -(p6)	br.cond.spnt.few fast_tick_reflect_done;;
   9.351 -	extr.u r27=r20,0,6	// r27 has low 6 bits of itv.vector
   9.352 -	extr.u r26=r20,6,2;;	// r26 has irr index of itv.vector
   9.353 -	movl r19=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;
   9.354 -	ld8 r19=[r19];;
   9.355 -	adds r22=IA64_VCPU_DOMAIN_ITM_LAST_OFFSET,r19
   9.356 -	adds r23=IA64_VCPU_DOMAIN_ITM_OFFSET,r19;;
   9.357 -	ld8 r24=[r22];;
   9.358 -	ld8 r23=[r23];;
   9.359 -	cmp.eq p6,p0=r23,r24	// skip if this tick already delivered
   9.360 -(p6)	br.cond.spnt.few fast_tick_reflect_done;;
   9.361 -	// set irr bit
   9.362 -	adds r21=IA64_VCPU_IRR0_OFFSET,r19;
   9.363 -	shl r26=r26,3;;
   9.364 -	add r21=r21,r26;;
   9.365 -	mov r25=1;;
   9.366 -	shl r22=r25,r27;;
   9.367 -	ld8 r23=[r21];;
   9.368 -	or r22=r22,r23;;
   9.369 -	st8 [r21]=r22;;
   9.370 -	// set PSCB(pending_interruption)!
   9.371 -	adds r20=XSI_PEND_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.372 -	st4 [r20]=r25;;
   9.373 -	
   9.374 -	// if interrupted at pl0, we're done
   9.375 -	extr.u r16=r17,IA64_PSR_CPL0_BIT,2;;
   9.376 -	cmp.eq p6,p0=r16,r0;;
   9.377 -(p6)	br.cond.spnt.few fast_tick_reflect_done;;
   9.378 -	// if guest vpsr.i is off, we're done
   9.379 -	adds r21=XSI_PSR_I_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.380 -	ld4 r21=[r21];;
   9.381 -	cmp.eq p6,p0=r21,r0
   9.382 -(p6)	br.cond.spnt.few fast_tick_reflect_done;;
   9.383 -
   9.384 -	// OK, we have a clock tick to deliver to the active domain!
   9.385 -	// so deliver to iva+0x3000
   9.386 -	//	r17 == cr.ipsr
   9.387 -	//	r18 == XSI_PSR_IC
   9.388 -	//	r19 == IA64_KR(CURRENT)
   9.389 -	//	r31 == pr
   9.390 -	mov r16=cr.isr;;
   9.391 -	mov r29=cr.iip;;
   9.392 -	adds r21=XSI_IIP_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.393 -	st8 [r21]=r29 ;;
   9.394 -	// set shared_mem isr
   9.395 -	extr.u r16=r16,38,1;;	// grab cr.isr.ir bit
   9.396 -	dep r16=r16,r0,38,1 ;;	// insert into cr.isr (rest of bits zero)
   9.397 -	extr.u r20=r17,41,2 ;;	// get ipsr.ri
   9.398 -	dep r16=r20,r16,41,2 ;; // deposit cr.isr.ei
   9.399 -	adds r21=XSI_ISR_OFS-XSI_PSR_IC_OFS,r18 ;; 
   9.400 -	st8 [r21]=r16 ;;
   9.401 -	// set cr.ipsr (make sure cpl==2!)
   9.402 -	mov r29=r17 ;;
   9.403 -	movl r28=DELIVER_PSR_SET;;
   9.404 -	movl r27=~(DELIVER_PSR_CLR|IA64_PSR_CPL0);;
   9.405 -	or r29=r29,r28;;
   9.406 -	and r29=r29,r27;;
   9.407 -	mov cr.ipsr=r29;;
   9.408 -	// set shared_mem ipsr (from ipsr in r17 with ipsr.ri already set)
   9.409 -	extr.u r29=r17,IA64_PSR_CPL0_BIT,2;;
   9.410 -	cmp.eq p6,p7=3,r29;;
   9.411 -(p6)	dep r17=-1,r17,IA64_PSR_CPL0_BIT,2
   9.412 -(p7)	dep r17=0,r17,IA64_PSR_CPL0_BIT,2
   9.413 -	;;
   9.414 -	movl r28=(IA64_PSR_DT|IA64_PSR_IT|IA64_PSR_RT);;
   9.415 -	movl r27=~(IA64_PSR_BE|IA64_PSR_PP|IA64_PSR_BN|IA64_PSR_I|IA64_PSR_IC);;
   9.416 -	dep r21=-1,r21,IA64_PSR_CPL1_BIT,1 ;;
   9.417 -	or r17=r17,r28;;
   9.418 -	and r17=r17,r27;;
   9.419 -	ld4 r16=[r18],4;;
   9.420 -	cmp.ne p6,p0=r16,r0;;
   9.421 -(p6)	dep r17=-1,r17,IA64_PSR_IC_BIT,1 ;;
   9.422 -	ld4 r16=[r18],-4;;
   9.423 -	cmp.ne p6,p0=r16,r0;;
   9.424 -(p6)	dep r17=-1,r17,IA64_PSR_I_BIT,1 ;;
   9.425 -	adds r21=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.426 -	st8 [r21]=r17 ;;
   9.427 -	// set shared_mem interrupt_delivery_enabled to 0
   9.428 -	// set shared_mem interrupt_collection_enabled to 0
   9.429 -	st8 [r18]=r0;;
   9.430 -	// cover and set shared_mem precover_ifs to cr.ifs
   9.431 -	// set shared_mem ifs and incomplete_regframe to 0
   9.432 -	cover ;;
   9.433 -	mov r20=cr.ifs;;
   9.434 -	adds r21=XSI_INCOMPL_REG_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.435 -	st4 [r21]=r0 ;;
   9.436 -	adds r21=XSI_IFS_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.437 -	st8 [r21]=r0 ;;
   9.438 -	adds r21=XSI_PRECOVER_IFS_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.439 -	st8 [r21]=r20 ;;
   9.440 -	// leave cr.ifs alone for later rfi
   9.441 -	// set iip to go to domain IVA break instruction vector
   9.442 -	adds r22=IA64_VCPU_IVA_OFFSET,r19;;
   9.443 -	ld8 r23=[r22];;
   9.444 -	movl r24=0x3000;;
   9.445 -	add r24=r24,r23;;
   9.446 -	mov cr.iip=r24;;
   9.447 -	// OK, now all set to go except for switch to virtual bank0
   9.448 -	mov r30=r2; mov r29=r3;;
   9.449 -#ifdef HANDLE_AR_UNAT
   9.450 -	mov r28=ar.unat;
   9.451 -#endif
   9.452 -	adds r2=XSI_BANK1_OFS-XSI_PSR_IC_OFS,r18;
   9.453 -	adds r3=(XSI_BANK1_OFS+8)-XSI_PSR_IC_OFS,r18;;
   9.454 -	bsw.1;;
   9.455 -	.mem.offset 0,0; st8.spill [r2]=r16,16;
   9.456 -	.mem.offset 8,0; st8.spill [r3]=r17,16 ;;
   9.457 -	.mem.offset 0,0; st8.spill [r2]=r18,16;
   9.458 -	.mem.offset 8,0; st8.spill [r3]=r19,16 ;;
   9.459 -	.mem.offset 0,0; st8.spill [r2]=r20,16;
   9.460 -	.mem.offset 8,0; st8.spill [r3]=r21,16 ;;
   9.461 -	.mem.offset 0,0; st8.spill [r2]=r22,16;
   9.462 -	.mem.offset 8,0; st8.spill [r3]=r23,16 ;;
   9.463 -	.mem.offset 0,0; st8.spill [r2]=r24,16;
   9.464 -	.mem.offset 8,0; st8.spill [r3]=r25,16 ;;
   9.465 -	.mem.offset 0,0; st8.spill [r2]=r26,16;
   9.466 -	.mem.offset 8,0; st8.spill [r3]=r27,16 ;;
   9.467 -	.mem.offset 0,0; st8.spill [r2]=r28,16;
   9.468 -	.mem.offset 8,0; st8.spill [r3]=r29,16 ;;
   9.469 -	.mem.offset 0,0; st8.spill [r2]=r30,16;
   9.470 -	.mem.offset 8,0; st8.spill [r3]=r31,16 ;;
   9.471 -#ifdef HANDLE_AR_UNAT
   9.472 -	// bank0 regs have no NaT bit, so ensure they are NaT clean
   9.473 -	mov r16=r0; mov r17=r0; mov r18=r0; mov r19=r0;
   9.474 -	mov r20=r0; mov r21=r0; mov r22=r0; mov r23=r0;
   9.475 -	mov r24=r0; mov r25=r0; mov r26=r0; mov r27=r0;
   9.476 -	mov r28=r0; mov r29=r0; mov r30=r0; movl r31=XSI_IPSR;;
   9.477 -#endif
   9.478 -	bsw.0 ;;
   9.479 -	mov r2=r30; mov r3=r29;;
   9.480 -#ifdef HANDLE_AR_UNAT
   9.481 -	mov ar.unat=r28;
   9.482 -#endif
   9.483 -	adds r20=XSI_BANKNUM_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.484 -	st4 [r20]=r0 ;;
   9.485 -fast_tick_reflect_done:
   9.486 -	mov pr=r31,-1 ;;
   9.487 -	rfi
   9.488 -END(fast_tick_reflect)
   9.489 -
   9.490 -// reflect domain breaks directly to domain
   9.491 -//	r16 == cr.isr
   9.492 -//	r17 == cr.iim
   9.493 -//	r18 == XSI_PSR_IC
   9.494 -//	r19 == vpsr.ic (low 32 bits) | vpsr.i (high 32 bits)
   9.495 -//	r31 == pr
   9.496 -GLOBAL_ENTRY(fast_break_reflect)
   9.497 -#ifndef FAST_BREAK // see beginning of file
   9.498 -	br.sptk.many dispatch_break_fault ;;
   9.499 -#endif
   9.500 -	mov r30=cr.ipsr;;
   9.501 -	mov r29=cr.iip;;
   9.502 -	extr.u r21=r30,IA64_PSR_BE_BIT,1 ;;
   9.503 -	cmp.ne p7,p0=r21,r0 ;;
   9.504 -(p7)	br.spnt.few dispatch_break_fault ;;
   9.505 -	extr.u r21=r30,IA64_PSR_PP_BIT,1 ;;
   9.506 -	cmp.ne p7,p0=r21,r0 ;;
   9.507 -(p7)	br.spnt.few dispatch_break_fault ;;
   9.508 -#if 1 /* special handling in case running on simulator */
   9.509 -	movl r20=first_break;;
   9.510 -	ld4 r23=[r20];;
   9.511 -	movl r21=0x80001;
   9.512 -	movl r22=0x80002;;
   9.513 -	cmp.ne p7,p0=r23,r0;;
   9.514 -(p7)	br.spnt.few dispatch_break_fault ;;
   9.515 -	cmp.eq p7,p0=r21,r17;
   9.516 -(p7)	br.spnt.few dispatch_break_fault ;;
   9.517 -	cmp.eq p7,p0=r22,r17;
   9.518 -(p7)	br.spnt.few dispatch_break_fault ;;
   9.519 -#endif
   9.520 -	movl r20=0x2c00;
   9.521 -	// save iim in shared_info
   9.522 -	adds r21=XSI_IIM_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.523 -	st8 [r21]=r17;;
   9.524 -	// fall through
   9.525 -
   9.526 -
   9.527 -// reflect to domain ivt+r20
   9.528 -// sets up isr,iip,ipsr,ifs (FIXME: do iipa too)
   9.529 -//	r16 == cr.isr
   9.530 -//	r18 == XSI_PSR_IC
   9.531 -//	r20 == offset into ivt
   9.532 -//	r29 == iip
   9.533 -//	r30 == ipsr
   9.534 -//	r31 == pr
   9.535 -ENTRY(fast_reflect)
   9.536 -#ifdef FAST_REFLECT_CNT
   9.537 -	movl r22=fast_reflect_count;
   9.538 -	shr r23=r20,5;;
   9.539 -	add r22=r22,r23;;
   9.540 -	ld8 r21=[r22];;
   9.541 -	adds r21=1,r21;;
   9.542 -	st8 [r22]=r21;;
   9.543 -#endif
   9.544 -	// save iip in shared_info (DON'T POINT TO NEXT INSTRUCTION!)
   9.545 -	adds r21=XSI_IIP_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.546 -	st8 [r21]=r29;;
   9.547 -	// set shared_mem isr
   9.548 -	adds r21=XSI_ISR_OFS-XSI_PSR_IC_OFS,r18 ;; 
   9.549 -	st8 [r21]=r16 ;;
   9.550 -	// set cr.ipsr
   9.551 -	mov r29=r30 ;;
   9.552 -	movl r28=DELIVER_PSR_SET;;
   9.553 -	movl r27=~(DELIVER_PSR_CLR|IA64_PSR_CPL0);;
   9.554 -	or r29=r29,r28;;
   9.555 -	and r29=r29,r27;;
   9.556 -	mov cr.ipsr=r29;;
   9.557 -	// set shared_mem ipsr (from ipsr in r30 with ipsr.ri already set)
   9.558 -	extr.u r29=r30,IA64_PSR_CPL0_BIT,2;;
   9.559 -	cmp.eq p6,p7=3,r29;;
   9.560 -(p6)	dep r30=-1,r30,IA64_PSR_CPL0_BIT,2
   9.561 -(p7)	dep r30=0,r30,IA64_PSR_CPL0_BIT,2
   9.562 -	;;
   9.563 -	movl r28=(IA64_PSR_DT|IA64_PSR_IT|IA64_PSR_RT);;
   9.564 -	movl r27=~(IA64_PSR_BE|IA64_PSR_PP|IA64_PSR_BN);;
   9.565 -	or r30=r30,r28;;
   9.566 -	and r30=r30,r27;;
   9.567 -	// also set shared_mem ipsr.i and ipsr.ic appropriately
   9.568 -	ld8 r24=[r18];;
   9.569 -	extr.u r22=r24,32,32
   9.570 -	cmp4.eq p6,p7=r24,r0;;
   9.571 -(p6)	dep r30=0,r30,IA64_PSR_IC_BIT,1
   9.572 -(p7)	dep r30=-1,r30,IA64_PSR_IC_BIT,1 ;;
   9.573 -	cmp4.eq p6,p7=r22,r0;;
   9.574 -(p6)	dep r30=0,r30,IA64_PSR_I_BIT,1
   9.575 -(p7)	dep r30=-1,r30,IA64_PSR_I_BIT,1 ;;
   9.576 -	adds r21=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.577 -	st8 [r21]=r30 ;;
   9.578 -	// set shared_mem interrupt_delivery_enabled to 0
   9.579 -	// set shared_mem interrupt_collection_enabled to 0
   9.580 -	st8 [r18]=r0;;
   9.581 -	// cover and set shared_mem precover_ifs to cr.ifs
   9.582 -	// set shared_mem ifs and incomplete_regframe to 0
   9.583 -	cover ;;
   9.584 -	mov r24=cr.ifs;;
   9.585 -	adds r21=XSI_INCOMPL_REG_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.586 -	st4 [r21]=r0 ;;
   9.587 -	adds r21=XSI_IFS_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.588 -	st8 [r21]=r0 ;;
   9.589 -	adds r21=XSI_PRECOVER_IFS_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.590 -	st8 [r21]=r24 ;;
   9.591 -	// vpsr.i = vpsr.ic = 0 on delivery of interruption
   9.592 -	st8 [r18]=r0;;
   9.593 -	// FIXME: need to save iipa and isr to be arch-compliant
   9.594 -	// set iip to go to domain IVA break instruction vector
   9.595 -	movl r22=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;
   9.596 -	ld8 r22=[r22];;
   9.597 -	adds r22=IA64_VCPU_IVA_OFFSET,r22;;
   9.598 -	ld8 r23=[r22];;
   9.599 -	add r20=r20,r23;;
   9.600 -	mov cr.iip=r20;;
   9.601 -	// OK, now all set to go except for switch to virtual bank0
   9.602 -	mov r30=r2; mov r29=r3;;
   9.603 -#ifdef HANDLE_AR_UNAT
   9.604 -	mov r28=ar.unat;
   9.605 -#endif
   9.606 -	adds r2=XSI_BANK1_OFS-XSI_PSR_IC_OFS,r18;
   9.607 -	adds r3=(XSI_BANK1_OFS+8)-XSI_PSR_IC_OFS,r18;;
   9.608 -	bsw.1;;
   9.609 -	.mem.offset 0,0; st8.spill [r2]=r16,16;
   9.610 -	.mem.offset 8,0; st8.spill [r3]=r17,16 ;;
   9.611 -	.mem.offset 0,0; st8.spill [r2]=r18,16;
   9.612 -	.mem.offset 8,0; st8.spill [r3]=r19,16 ;;
   9.613 -	.mem.offset 0,0; st8.spill [r2]=r20,16;
   9.614 -	.mem.offset 8,0; st8.spill [r3]=r21,16 ;;
   9.615 -	.mem.offset 0,0; st8.spill [r2]=r22,16;
   9.616 -	.mem.offset 8,0; st8.spill [r3]=r23,16 ;;
   9.617 -	.mem.offset 0,0; st8.spill [r2]=r24,16;
   9.618 -	.mem.offset 8,0; st8.spill [r3]=r25,16 ;;
   9.619 -	.mem.offset 0,0; st8.spill [r2]=r26,16;
   9.620 -	.mem.offset 8,0; st8.spill [r3]=r27,16 ;;
   9.621 -	.mem.offset 0,0; st8.spill [r2]=r28,16;
   9.622 -	.mem.offset 8,0; st8.spill [r3]=r29,16 ;;
   9.623 -	.mem.offset 0,0; st8.spill [r2]=r30,16;
   9.624 -	.mem.offset 8,0; st8.spill [r3]=r31,16 ;;
   9.625 -#ifdef HANDLE_AR_UNAT
   9.626 -	// bank0 regs have no NaT bit, so ensure they are NaT clean
   9.627 -	mov r16=r0; mov r17=r0; mov r18=r0; mov r19=r0;
   9.628 -	mov r20=r0; mov r21=r0; mov r22=r0; mov r23=r0;
   9.629 -	mov r24=r0; mov r25=r0; mov r26=r0; mov r27=r0;
   9.630 -	mov r28=r0; mov r29=r0; mov r30=r0; movl r31=XSI_IPSR;;
   9.631 -#endif
   9.632 -	movl r31=XSI_IPSR;;
   9.633 -	bsw.0 ;;
   9.634 -	mov r2=r30; mov r3=r29;;
   9.635 -#ifdef HANDLE_AR_UNAT
   9.636 -	mov ar.unat=r28;
   9.637 -#endif
   9.638 -	adds r20=XSI_BANKNUM_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.639 -	st4 [r20]=r0 ;;
   9.640 -	mov pr=r31,-1 ;;
   9.641 -	rfi
   9.642 -	;;
   9.643 -
   9.644 -// reflect access faults (0x2400,0x2800,0x5300) directly to domain
   9.645 -//	r16 == isr
   9.646 -//	r17 == ifa
   9.647 -//	r19 == reflect number (only pass-thru to dispatch_reflection)
   9.648 -//	r20 == offset into ivt
   9.649 -//	r31 == pr
   9.650 -GLOBAL_ENTRY(fast_access_reflect)
   9.651 -#ifndef FAST_ACCESS_REFLECT // see beginning of file
   9.652 -	br.spnt.few dispatch_reflection ;;
   9.653 -#endif
   9.654 -	mov r30=cr.ipsr;;
   9.655 -	mov r29=cr.iip;;
   9.656 -	extr.u r21=r30,IA64_PSR_BE_BIT,1 ;;
   9.657 -	cmp.ne p7,p0=r21,r0
   9.658 -(p7)	br.spnt.few dispatch_reflection ;;
   9.659 -	extr.u r21=r30,IA64_PSR_PP_BIT,1 ;;
   9.660 -	cmp.ne p7,p0=r21,r0
   9.661 -(p7)	br.spnt.few dispatch_reflection ;;
   9.662 -	extr.u r21=r30,IA64_PSR_CPL0_BIT,2 ;;
   9.663 -	cmp.eq p7,p0=r21,r0
   9.664 -(p7)	br.spnt.few dispatch_reflection ;;
   9.665 -	movl r18=XSI_PSR_IC;;
   9.666 -	ld8 r21=[r18];;
   9.667 -	cmp.eq p7,p0=r0,r21
   9.668 -(p7)	br.spnt.few dispatch_reflection ;;
   9.669 -	// set shared_mem ifa, FIXME: should we validate it?
   9.670 -	mov r17=cr.ifa;;
   9.671 -	adds r21=XSI_IFA_OFS-XSI_PSR_IC_OFS,r18 ;; 
   9.672 -	st8 [r21]=r17 ;;
   9.673 -	// get rr[ifa] and save to itir in shared memory (extra bits ignored)
   9.674 -	shr.u r22=r17,61
   9.675 -	adds r23=XSI_ITIR_OFS-XSI_PSR_IC_OFS,r18 
   9.676 -	adds r21=XSI_RR0_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.677 -	shladd r22=r22,3,r21;;
   9.678 -	ld8 r22=[r22];;
   9.679 -	st8 [r23]=r22;;
   9.680 -	br.cond.sptk.many fast_reflect;;
   9.681 -
   9.682 -
   9.683 -// ensure that, if giving up, registers at entry to fast_hyperprivop unchanged
   9.684 -ENTRY(hyper_rfi)
   9.685 -#ifndef FAST_RFI
   9.686 -	br.spnt.few dispatch_break_fault ;;
   9.687 -#endif
   9.688 -	// if no interrupts pending, proceed
   9.689 -	mov r30=r0
   9.690 -	cmp.eq p7,p0=r20,r0
   9.691 -(p7)	br.sptk.many 1f
   9.692 -	;;
   9.693 -	adds r20=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.694 -	ld8 r21=[r20];;		// r21 = vcr.ipsr
   9.695 -	extr.u r22=r21,IA64_PSR_I_BIT,1 ;;
   9.696 -	mov r30=r22	
   9.697 -	// r30 determines whether we might deliver an immediate extint
   9.698 -1:
   9.699 -	adds r20=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.700 -	ld8 r21=[r20];;		// r21 = vcr.ipsr
   9.701 -	extr.u r22=r21,IA64_PSR_BE_BIT,1 ;;
   9.702 -	// if turning on psr.be, give up for now and do it the slow way
   9.703 -	cmp.ne p7,p0=r22,r0
   9.704 -(p7)	br.spnt.few dispatch_break_fault ;;
   9.705 -	// if (!(vpsr.dt && vpsr.rt && vpsr.it)), do it the slow way
   9.706 -	movl r20=(IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_IT);;
   9.707 -	and r22=r20,r21
   9.708 -	;;
   9.709 -	cmp.ne p7,p0=r22,r20
   9.710 -(p7)	br.spnt.few dispatch_break_fault ;;
   9.711 -	// if was in metaphys mode, do it the slow way (FIXME later?)
   9.712 -	adds r20=XSI_METAPHYS_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.713 -	ld4 r20=[r20];;
   9.714 -	cmp.ne p7,p0=r20,r0
   9.715 -(p7)	br.spnt.few dispatch_break_fault ;;
   9.716 -	// if domain hasn't already done virtual bank switch
   9.717 -	//  do it the slow way (FIXME later?)
   9.718 -#if 0
   9.719 -	adds r20=XSI_BANKNUM_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.720 -	ld4 r20=[r20];;
   9.721 -	cmp.eq p7,p0=r20,r0
   9.722 -(p7)	br.spnt.few dispatch_break_fault ;;
   9.723 -#endif
   9.724 -	// validate vcr.iip, if in Xen range, do it the slow way
   9.725 -	adds r20=XSI_IIP_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.726 -	ld8 r22=[r20];;
   9.727 -	movl r23=XEN_VIRT_SPACE_LOW
   9.728 -	movl r24=XEN_VIRT_SPACE_HIGH ;;
   9.729 -	cmp.ltu p0,p7=r22,r23 ;;	// if !(iip<low) &&
   9.730 -(p7)	cmp.geu p0,p7=r22,r24 ;;	//    !(iip>=high)
   9.731 -(p7)	br.spnt.few dispatch_break_fault ;;
   9.732 -#ifndef RFI_TO_INTERRUPT // see beginning of file
   9.733 -	cmp.ne p6,p0=r30,r0
   9.734 -(p6)	br.cond.spnt.few dispatch_break_fault ;;
   9.735 -#endif
   9.736 -
   9.737 -1:	// OK now, let's do an rfi.
   9.738 -#ifdef FAST_HYPERPRIVOP_CNT
   9.739 -	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_RFI);;
   9.740 -	ld8 r23=[r20];;
   9.741 -	adds r23=1,r23;;
   9.742 -	st8 [r20]=r23;;
   9.743 -#endif
   9.744 -#ifdef RFI_TO_INTERRUPT
   9.745 -	// maybe do an immediate interrupt delivery?
   9.746 -	cmp.ne p6,p0=r30,r0
   9.747 -(p6)	br.cond.spnt.few rfi_check_extint;;
   9.748 -#endif
   9.749 -
   9.750 -just_do_rfi:
   9.751 -	// r18=&vpsr.i|vpsr.ic, r21==vpsr, r22=vcr.iip
   9.752 -	mov cr.iip=r22;;
   9.753 -	adds r20=XSI_INCOMPL_REG_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.754 -	st4 [r20]=r0 ;;
   9.755 -	adds r20=XSI_IFS_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.756 -	ld8 r20=[r20];;
   9.757 -	dep r20=0,r20,38,25;; // ensure ifs has no reserved bits set
   9.758 -	mov cr.ifs=r20 ;;
   9.759 -	// ipsr.cpl == (vcr.ipsr.cpl == 0) 2 : 3;
   9.760 -	dep r21=-1,r21,IA64_PSR_CPL1_BIT,1 ;;
   9.761 -	// vpsr.i = vcr.ipsr.i; vpsr.ic = vcr.ipsr.ic
   9.762 -	mov r19=r0 ;;
   9.763 -	extr.u r23=r21,IA64_PSR_I_BIT,1 ;;
   9.764 -	cmp.ne p7,p6=r23,r0 ;;
   9.765 -	// not done yet
   9.766 -(p7)	dep r19=-1,r19,32,1
   9.767 -	extr.u r23=r21,IA64_PSR_IC_BIT,1 ;;
   9.768 -	cmp.ne p7,p6=r23,r0 ;;
   9.769 -(p7)	dep r19=-1,r19,0,1 ;;
   9.770 -	st8 [r18]=r19 ;;
   9.771 -	// force on psr.ic, i, dt, rt, it, bn
   9.772 -	movl r20=(IA64_PSR_I|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_IT|IA64_PSR_BN)
   9.773 -	;;
   9.774 -	or r21=r21,r20
   9.775 -	;;
   9.776 -	mov cr.ipsr=r21
   9.777 -	adds r20=XSI_BANKNUM_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.778 -	ld4 r21=[r20];;
   9.779 -	cmp.ne p7,p0=r21,r0	// domain already did "bank 1 switch?"
   9.780 -(p7)	br.cond.spnt.few 1f;
   9.781 -	// OK, now all set to go except for switch to virtual bank1
   9.782 -	mov r22=1;; st4 [r20]=r22;
   9.783 -	mov r30=r2; mov r29=r3;;
   9.784 -	adds r2=XSI_BANK1_OFS-XSI_PSR_IC_OFS,r18;
   9.785 -	adds r3=(XSI_BANK1_OFS+8)-XSI_PSR_IC_OFS,r18;;
   9.786 -	bsw.1;;
   9.787 -	// FIXME?: ar.unat is not really handled correctly,
   9.788 -	// but may not matter if the OS is NaT-clean
   9.789 -	.mem.offset 0,0; ld8.fill r16=[r2],16 ;
   9.790 -	.mem.offset 8,0; ld8.fill r17=[r3],16 ;;
   9.791 -	.mem.offset 0,0; ld8.fill r18=[r2],16 ;
   9.792 -	.mem.offset 0,0; ld8.fill r19=[r3],16 ;;
   9.793 -	.mem.offset 8,0; ld8.fill r20=[r2],16 ;
   9.794 -	.mem.offset 8,0; ld8.fill r21=[r3],16 ;;
   9.795 -	.mem.offset 8,0; ld8.fill r22=[r2],16 ;
   9.796 -	.mem.offset 8,0; ld8.fill r23=[r3],16 ;;
   9.797 -	.mem.offset 8,0; ld8.fill r24=[r2],16 ;
   9.798 -	.mem.offset 8,0; ld8.fill r25=[r3],16 ;;
   9.799 -	.mem.offset 8,0; ld8.fill r26=[r2],16 ;
   9.800 -	.mem.offset 8,0; ld8.fill r27=[r3],16 ;;
   9.801 -	.mem.offset 8,0; ld8.fill r28=[r2],16 ;
   9.802 -	.mem.offset 8,0; ld8.fill r29=[r3],16 ;;
   9.803 -	.mem.offset 8,0; ld8.fill r30=[r2],16 ;
   9.804 -	.mem.offset 8,0; ld8.fill r31=[r3],16 ;;
   9.805 -	bsw.0 ;;
   9.806 -	mov r2=r30; mov r3=r29;;
   9.807 -1:	mov pr=r31,-1
   9.808 -	;;
   9.809 -	rfi
   9.810 -	;;
   9.811 -
   9.812 -#ifdef RFI_TO_INTERRUPT
   9.813 -GLOBAL_ENTRY(rfi_check_extint)
   9.814 -	//br.sptk.many dispatch_break_fault ;;
   9.815 -
   9.816 -	// r18=&vpsr.i|vpsr.ic, r21==vpsr, r22=vcr.iip
   9.817 -	// make sure none of these get trashed in case going to just_do_rfi
   9.818 -	movl r30=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;
   9.819 -	ld8 r30=[r30];;
   9.820 -	adds r24=IA64_VCPU_INSVC3_OFFSET,r30;;
   9.821 -	mov r25=192
   9.822 -	adds r16=IA64_VCPU_IRR3_OFFSET,r30;;
   9.823 -	ld8 r23=[r16];;
   9.824 -	cmp.eq p6,p0=r23,r0;;
   9.825 -(p6)	adds r16=-8,r16;;
   9.826 -(p6)	adds r24=-8,r24;;
   9.827 -(p6)	adds r25=-64,r25;;
   9.828 -(p6)	ld8 r23=[r16];;
   9.829 -(p6)	cmp.eq p6,p0=r23,r0;;
   9.830 -(p6)	adds r16=-8,r16;;
   9.831 -(p6)	adds r24=-8,r24;;
   9.832 -(p6)	adds r25=-64,r25;;
   9.833 -(p6)	ld8 r23=[r16];;
   9.834 -(p6)	cmp.eq p6,p0=r23,r0;;
   9.835 -(p6)	adds r16=-8,r16;;
   9.836 -(p6)	adds r24=-8,r24;;
   9.837 -(p6)	adds r25=-64,r25;;
   9.838 -(p6)	ld8 r23=[r16];;
   9.839 -(p6)	cmp.eq p6,p0=r23,r0;;
   9.840 -	cmp.eq p6,p0=r23,r0
   9.841 -(p6)	br.cond.spnt.few just_do_rfi;	// this is actually an error
   9.842 -	// r16 points to non-zero element of irr, r23 has value
   9.843 -	// r24 points to corr element of insvc, r25 has elt*64
   9.844 -	ld8 r26=[r24];;
   9.845 -	cmp.geu p6,p0=r26,r23
   9.846 -(p6)	br.cond.spnt.many just_do_rfi;
   9.847 -
   9.848 -	// not masked by insvc, get vector number
   9.849 -	shr.u r26=r23,1;;
   9.850 -	or r26=r23,r26;;
   9.851 -	shr.u r27=r26,2;;
   9.852 -	or r26=r26,r27;;
   9.853 -	shr.u r27=r26,4;;
   9.854 -	or r26=r26,r27;;
   9.855 -	shr.u r27=r26,8;;
   9.856 -	or r26=r26,r27;;
   9.857 -	shr.u r27=r26,16;;
   9.858 -	or r26=r26,r27;;
   9.859 -	shr.u r27=r26,32;;
   9.860 -	or r26=r26,r27;;
   9.861 -	andcm r26=0xffffffffffffffff,r26;;
   9.862 -	popcnt r26=r26;;
   9.863 -	sub r26=63,r26;;
   9.864 -	// r26 now contains the bit index (mod 64)
   9.865 -	mov r27=1;;
   9.866 -	shl r27=r27,r26;;
   9.867 -	// r27 now contains the (within the proper word) bit mask 
   9.868 -	add r26=r25,r26
   9.869 -	// r26 now contains the vector [0..255]
   9.870 -	adds r20=XSI_TPR_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.871 -	ld8 r20=[r20] ;;
   9.872 -	extr.u r28=r20,16,1
   9.873 -	extr.u r29=r20,4,4 ;;
   9.874 -	cmp.ne p6,p0=r28,r0	// if tpr.mmi is set, just rfi
   9.875 -(p6)	br.cond.spnt.few just_do_rfi;;
   9.876 -	shl r29=r29,4;;
   9.877 -	adds r29=15,r29;;
   9.878 -	cmp.ge p6,p0=r29,r26	// if tpr masks interrupt, just rfi
   9.879 -(p6)	br.cond.spnt.few just_do_rfi;;
   9.880 -
   9.881 -// this doesn't work yet (dies early after getting to user mode)
   9.882 -// but happens relatively infrequently, so fix it later.
   9.883 -// NOTE that these will be counted incorrectly for now (for privcnt output)
   9.884 -GLOBAL_ENTRY(rfi_with_interrupt)
   9.885 -#if 1
   9.886 -	br.sptk.many dispatch_break_fault ;;
   9.887 -#endif
   9.888 -
   9.889 -	// OK, have an unmasked vector, so deliver extint to vcr.iva+0x3000
   9.890 -	//	r18 == XSI_PSR_IC
   9.891 -	//	r21 == vipsr (ipsr in shared_mem)
   9.892 -	//	r30 == IA64_KR(CURRENT)
   9.893 -	//	r31 == pr
   9.894 -	mov r17=cr.ipsr;;
   9.895 -	mov r16=cr.isr;;
   9.896 -	// set shared_mem isr
   9.897 -	extr.u r16=r16,38,1;;	// grab cr.isr.ir bit
   9.898 -	dep r16=r16,r0,38,1 ;;	// insert into cr.isr (rest of bits zero)
   9.899 -	extr.u r20=r21,41,2 ;;	// get v(!)psr.ri
   9.900 -	dep r16=r20,r16,41,2 ;; // deposit cr.isr.ei
   9.901 -	adds r22=XSI_ISR_OFS-XSI_PSR_IC_OFS,r18 ;; 
   9.902 -	st8 [r22]=r16 ;;
   9.903 -	// set cr.ipsr (make sure cpl==2!)
   9.904 -	mov r29=r17 ;;
   9.905 -	movl r28=DELIVER_PSR_SET;;
   9.906 -	movl r27=~(DELIVER_PSR_CLR|IA64_PSR_CPL0);;
   9.907 -	or r29=r29,r28;;
   9.908 -	and r29=r29,r27;;
   9.909 -	mov cr.ipsr=r29;;
   9.910 -	// v.ipsr and v.iip are already set (and v.iip validated) as rfi target
   9.911 -	// set shared_mem interrupt_delivery_enabled to 0
   9.912 -	// set shared_mem interrupt_collection_enabled to 0
   9.913 -	st8 [r18]=r0;;
   9.914 -	// cover and set shared_mem precover_ifs to cr.ifs
   9.915 -	// set shared_mem ifs and incomplete_regframe to 0
   9.916 -#if 0
   9.917 -	cover ;;
   9.918 -	mov r20=cr.ifs;;
   9.919 -	adds r22=XSI_INCOMPL_REG_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.920 -	st4 [r22]=r0 ;;
   9.921 -	adds r22=XSI_IFS_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.922 -	st8 [r22]=r0 ;;
   9.923 -	adds r22=XSI_PRECOVER_IFS_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.924 -	st8 [r22]=r20 ;;
   9.925 -	// leave cr.ifs alone for later rfi
   9.926 -#else
   9.927 -	adds r22=XSI_INCOMPL_REG_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.928 -	st4 [r22]=r0 ;;
   9.929 -	adds r22=XSI_IFS_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.930 -	ld8 r20=[r22];;
   9.931 -	st8 [r22]=r0 ;;
   9.932 -	adds r22=XSI_PRECOVER_IFS_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.933 -	st8 [r22]=r20 ;;
   9.934 -#endif
   9.935 -	// set iip to go to domain IVA break instruction vector
   9.936 -	adds r22=IA64_VCPU_IVA_OFFSET,r30;;
   9.937 -	ld8 r23=[r22];;
   9.938 -	movl r24=0x3000;;
   9.939 -	add r24=r24,r23;;
   9.940 -	mov cr.iip=r24;;
   9.941 -#if 0
   9.942 -	// OK, now all set to go except for switch to virtual bank0
   9.943 -	mov r30=r2; mov r29=r3;;
   9.944 -	adds r2=XSI_BANK1_OFS-XSI_PSR_IC_OFS,r18;
   9.945 -	adds r3=(XSI_BANK1_OFS+8)-XSI_PSR_IC_OFS,r18;;
   9.946 -	bsw.1;;
   9.947 -	// FIXME: need to handle ar.unat!
   9.948 -	.mem.offset 0,0; st8.spill [r2]=r16,16;
   9.949 -	.mem.offset 8,0; st8.spill [r3]=r17,16 ;;
   9.950 -	.mem.offset 0,0; st8.spill [r2]=r18,16;
   9.951 -	.mem.offset 8,0; st8.spill [r3]=r19,16 ;;
   9.952 -	.mem.offset 0,0; st8.spill [r2]=r20,16;
   9.953 -	.mem.offset 8,0; st8.spill [r3]=r21,16 ;;
   9.954 -	.mem.offset 0,0; st8.spill [r2]=r22,16;
   9.955 -	.mem.offset 8,0; st8.spill [r3]=r23,16 ;;
   9.956 -	.mem.offset 0,0; st8.spill [r2]=r24,16;
   9.957 -	.mem.offset 8,0; st8.spill [r3]=r25,16 ;;
   9.958 -	.mem.offset 0,0; st8.spill [r2]=r26,16;
   9.959 -	.mem.offset 8,0; st8.spill [r3]=r27,16 ;;
   9.960 -	.mem.offset 0,0; st8.spill [r2]=r28,16;
   9.961 -	.mem.offset 8,0; st8.spill [r3]=r29,16 ;;
   9.962 -	.mem.offset 0,0; st8.spill [r2]=r30,16;
   9.963 -	.mem.offset 8,0; st8.spill [r3]=r31,16 ;;
   9.964 -	movl r31=XSI_IPSR;;
   9.965 -	bsw.0 ;;
   9.966 -	mov r2=r30; mov r3=r29;;
   9.967 -#else
   9.968 -	bsw.1;;
   9.969 -	movl r31=XSI_IPSR;;
   9.970 -	bsw.0 ;;
   9.971 -#endif
   9.972 -	adds r20=XSI_BANKNUM_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.973 -	st4 [r20]=r0 ;;
   9.974 -	mov pr=r31,-1 ;;
   9.975 -	rfi
   9.976 -#endif // RFI_TO_INTERRUPT
   9.977 -
   9.978 -ENTRY(hyper_cover)
   9.979 -#ifdef FAST_HYPERPRIVOP_CNT
   9.980 -	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_COVER);;
   9.981 -	ld8 r21=[r20];;
   9.982 -	adds r21=1,r21;;
   9.983 -	st8 [r20]=r21;;
   9.984 -#endif
   9.985 -	mov r24=cr.ipsr
   9.986 -	mov r25=cr.iip;;
   9.987 -	// skip test for vpsr.ic.. it's a prerequisite for hyperprivops
   9.988 -	cover ;;
   9.989 -	adds r20=XSI_INCOMPL_REG_OFS-XSI_PSR_IC_OFS,r18 ;;
   9.990 -	mov r30=cr.ifs;;
   9.991 -	adds r22=XSI_IFS_OFS-XSI_PSR_IC_OFS,r18
   9.992 -	ld4 r21=[r20] ;;
   9.993 -	cmp.eq p6,p7=r21,r0 ;;
   9.994 -(p6)	st8 [r22]=r30;;
   9.995 -(p7)	st4 [r20]=r0;;
   9.996 -	mov cr.ifs=r0;;
   9.997 -	// adjust return address to skip over break instruction
   9.998 -	extr.u r26=r24,41,2 ;;
   9.999 -	cmp.eq p6,p7=2,r26 ;;
  9.1000 -(p6)	mov r26=0
  9.1001 -(p6)	adds r25=16,r25
  9.1002 -(p7)	adds r26=1,r26
  9.1003 -	;;
  9.1004 -	dep r24=r26,r24,41,2
  9.1005 -	;;
  9.1006 -	mov cr.ipsr=r24
  9.1007 -	mov cr.iip=r25
  9.1008 -	mov pr=r31,-1 ;;
  9.1009 -	rfi
  9.1010 -	;;
  9.1011 -
  9.1012 -// return from metaphysical mode (meta=1) to virtual mode (meta=0)
  9.1013 -ENTRY(hyper_ssm_dt)
  9.1014 -#ifdef FAST_HYPERPRIVOP_CNT
  9.1015 -	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_SSM_DT);;
  9.1016 -	ld8 r21=[r20];;
  9.1017 -	adds r21=1,r21;;
  9.1018 -	st8 [r20]=r21;;
  9.1019 -#endif
  9.1020 -	mov r24=cr.ipsr
  9.1021 -	mov r25=cr.iip;;
  9.1022 -	adds r20=XSI_METAPHYS_OFS-XSI_PSR_IC_OFS,r18 ;;
  9.1023 -	ld4 r21=[r20];;
  9.1024 -	cmp.eq p7,p0=r21,r0	// meta==0?
  9.1025 -(p7)	br.spnt.many	1f ;;	// already in virtual mode
  9.1026 -	movl r22=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;
  9.1027 -	ld8 r22=[r22];;
  9.1028 -	adds r22=IA64_VCPU_META_SAVED_RR0_OFFSET,r22;;
  9.1029 -	ld4 r23=[r22];;
  9.1030 -	mov rr[r0]=r23;;
  9.1031 -	srlz.i;;
  9.1032 -	st4 [r20]=r0 ;;
  9.1033 -	// adjust return address to skip over break instruction
  9.1034 -1:	extr.u r26=r24,41,2 ;;
  9.1035 -	cmp.eq p6,p7=2,r26 ;;
  9.1036 -(p6)	mov r26=0
  9.1037 -(p6)	adds r25=16,r25
  9.1038 -(p7)	adds r26=1,r26
  9.1039 -	;;
  9.1040 -	dep r24=r26,r24,41,2
  9.1041 -	;;
  9.1042 -	mov cr.ipsr=r24
  9.1043 -	mov cr.iip=r25
  9.1044 -	mov pr=r31,-1 ;;
  9.1045 -	rfi
  9.1046 -	;;
  9.1047 -
  9.1048 -// go to metaphysical mode (meta=1) from virtual mode (meta=0)
  9.1049 -ENTRY(hyper_rsm_dt)
  9.1050 -#ifdef FAST_HYPERPRIVOP_CNT
  9.1051 -	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_RSM_DT);;
  9.1052 -	ld8 r21=[r20];;
  9.1053 -	adds r21=1,r21;;
  9.1054 -	st8 [r20]=r21;;
  9.1055 -#endif
  9.1056 -	mov r24=cr.ipsr
  9.1057 -	mov r25=cr.iip;;
  9.1058 -	adds r20=XSI_METAPHYS_OFS-XSI_PSR_IC_OFS,r18 ;;
  9.1059 -	ld4 r21=[r20];;
  9.1060 -	cmp.ne p7,p0=r21,r0	// meta==0?
  9.1061 -(p7)	br.spnt.many	1f ;;	// already in metaphysical mode
  9.1062 -	movl r22=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;
  9.1063 -	ld8 r22=[r22];;
  9.1064 -	adds r22=IA64_VCPU_META_RR0_OFFSET,r22;;
  9.1065 -	ld4 r23=[r22];;
  9.1066 -	mov rr[r0]=r23;;
  9.1067 -	srlz.i;;
  9.1068 -	adds r21=1,r0 ;;
  9.1069 -	st4 [r20]=r21 ;;
  9.1070 -	// adjust return address to skip over break instruction
  9.1071 -1:	extr.u r26=r24,41,2 ;;
  9.1072 -	cmp.eq p6,p7=2,r26 ;;
  9.1073 -(p6)	mov r26=0
  9.1074 -(p6)	adds r25=16,r25
  9.1075 -(p7)	adds r26=1,r26
  9.1076 -	;;
  9.1077 -	dep r24=r26,r24,41,2
  9.1078 -	;;
  9.1079 -	mov cr.ipsr=r24
  9.1080 -	mov cr.iip=r25
  9.1081 -	mov pr=r31,-1 ;;
  9.1082 -	rfi
  9.1083 -	;;
  9.1084 -
  9.1085 -ENTRY(hyper_get_tpr)
  9.1086 -#ifdef FAST_HYPERPRIVOP_CNT
  9.1087 -	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_GET_TPR);;
  9.1088 -	ld8 r21=[r20];;
  9.1089 -	adds r21=1,r21;;
  9.1090 -	st8 [r20]=r21;;
  9.1091 -#endif
  9.1092 -	mov r24=cr.ipsr
  9.1093 -	mov r25=cr.iip;;
  9.1094 -	adds r20=XSI_TPR_OFS-XSI_PSR_IC_OFS,r18 ;;
  9.1095 -	ld8 r8=[r20];;
  9.1096 -	extr.u r26=r24,41,2 ;;
  9.1097 -	cmp.eq p6,p7=2,r26 ;;
  9.1098 -(p6)	mov r26=0
  9.1099 -(p6)	adds r25=16,r25
  9.1100 -(p7)	adds r26=1,r26
  9.1101 -	;;
  9.1102 -	dep r24=r26,r24,41,2
  9.1103 -	;;
  9.1104 -	mov cr.ipsr=r24
  9.1105 -	mov cr.iip=r25
  9.1106 -	mov pr=r31,-1 ;;
  9.1107 -	rfi
  9.1108 -	;;
  9.1109 -END(hyper_get_tpr)
  9.1110 -
  9.1111 -// if we get to here, there are no interrupts pending so we
  9.1112 -// can change virtual tpr to any value without fear of provoking
  9.1113 -// (or accidentally missing) delivering an interrupt
  9.1114 -ENTRY(hyper_set_tpr)
  9.1115 -#ifdef FAST_HYPERPRIVOP_CNT
  9.1116 -	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_SET_TPR);;
  9.1117 -	ld8 r21=[r20];;
  9.1118 -	adds r21=1,r21;;
  9.1119 -	st8 [r20]=r21;;
  9.1120 -#endif
  9.1121 -	mov r24=cr.ipsr
  9.1122 -	mov r25=cr.iip;;
  9.1123 -	movl r27=0xff00;;
  9.1124 -	adds r20=XSI_TPR_OFS-XSI_PSR_IC_OFS,r18 ;;
  9.1125 -	andcm r8=r8,r27;;
  9.1126 -	st8 [r20]=r8;;
  9.1127 -	extr.u r26=r24,41,2 ;;
  9.1128 -	cmp.eq p6,p7=2,r26 ;;
  9.1129 -(p6)	mov r26=0
  9.1130 -(p6)	adds r25=16,r25
  9.1131 -(p7)	adds r26=1,r26
  9.1132 -	;;
  9.1133 -	dep r24=r26,r24,41,2
  9.1134 -	;;
  9.1135 -	mov cr.ipsr=r24
  9.1136 -	mov cr.iip=r25
  9.1137 -	mov pr=r31,-1 ;;
  9.1138 -	rfi
  9.1139 -	;;
  9.1140 -END(hyper_set_tpr)
  9.1141 -
  9.1142 -ENTRY(hyper_get_ivr)
  9.1143 -#ifdef FAST_HYPERPRIVOP_CNT
  9.1144 -	movl r22=fast_hyperpriv_cnt+(8*XEN_HYPER_GET_IVR);;
  9.1145 -	ld8 r21=[r22];;
  9.1146 -	adds r21=1,r21;;
  9.1147 -	st8 [r22]=r21;;
  9.1148 -#endif
  9.1149 -	mov r8=15;;
  9.1150 -	// when we get to here r20=~=interrupts pending
  9.1151 -	cmp.eq p7,p0=r20,r0;;
  9.1152 -(p7)	adds r20=XSI_PEND_OFS-XSI_PSR_IC_OFS,r18 ;;
  9.1153 -(p7)	st4 [r20]=r0;;
  9.1154 -(p7)	br.spnt.many 1f ;;
  9.1155 -	movl r30=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;
  9.1156 -	ld8 r30=[r30];;
  9.1157 -	adds r24=IA64_VCPU_INSVC3_OFFSET,r30;;
  9.1158 -	mov r25=192
  9.1159 -	adds r22=IA64_VCPU_IRR3_OFFSET,r30;;
  9.1160 -	ld8 r23=[r22];;
  9.1161 -	cmp.eq p6,p0=r23,r0;;
  9.1162 -(p6)	adds r22=-8,r22;;
  9.1163 -(p6)	adds r24=-8,r24;;
  9.1164 -(p6)	adds r25=-64,r25;;
  9.1165 -(p6)	ld8 r23=[r22];;
  9.1166 -(p6)	cmp.eq p6,p0=r23,r0;;
  9.1167 -(p6)	adds r22=-8,r22;;
  9.1168 -(p6)	adds r24=-8,r24;;
  9.1169 -(p6)	adds r25=-64,r25;;
  9.1170 -(p6)	ld8 r23=[r22];;
  9.1171 -(p6)	cmp.eq p6,p0=r23,r0;;
  9.1172 -(p6)	adds r22=-8,r22;;
  9.1173 -(p6)	adds r24=-8,r24;;
  9.1174 -(p6)	adds r25=-64,r25;;
  9.1175 -(p6)	ld8 r23=[r22];;
  9.1176 -(p6)	cmp.eq p6,p0=r23,r0;;
  9.1177 -	cmp.eq p6,p0=r23,r0
  9.1178 -(p6)	br.cond.spnt.few 1f;	// this is actually an error
  9.1179 -	// r22 points to non-zero element of irr, r23 has value
  9.1180 -	// r24 points to corr element of insvc, r25 has elt*64
  9.1181 -	ld8 r26=[r24];;
  9.1182 -	cmp.geu p6,p0=r26,r23
  9.1183 -(p6)	br.cond.spnt.many 1f;
  9.1184 -	// not masked by insvc, get vector number
  9.1185 -	shr.u r26=r23,1;;
  9.1186 -	or r26=r23,r26;;
  9.1187 -	shr.u r27=r26,2;;
  9.1188 -	or r26=r26,r27;;
  9.1189 -	shr.u r27=r26,4;;
  9.1190 -	or r26=r26,r27;;
  9.1191 -	shr.u r27=r26,8;;
  9.1192 -	or r26=r26,r27;;
  9.1193 -	shr.u r27=r26,16;;
  9.1194 -	or r26=r26,r27;;
  9.1195 -	shr.u r27=r26,32;;
  9.1196 -	or r26=r26,r27;;
  9.1197 -	andcm r26=0xffffffffffffffff,r26;;
  9.1198 -	popcnt r26=r26;;
  9.1199 -	sub r26=63,r26;;
  9.1200 -	// r26 now contains the bit index (mod 64)
  9.1201 -	mov r27=1;;
  9.1202 -	shl r27=r27,r26;;
  9.1203 -	// r27 now contains the (within the proper word) bit mask 
  9.1204 -	add r26=r25,r26
  9.1205 -	// r26 now contains the vector [0..255]
  9.1206 -	adds r20=XSI_TPR_OFS-XSI_PSR_IC_OFS,r18 ;;
  9.1207 -	ld8 r20=[r20] ;;
  9.1208 -	extr.u r28=r20,16,1
  9.1209 -	extr.u r29=r20,4,4 ;;
  9.1210 -	cmp.ne p6,p0=r28,r0	// if tpr.mmi is set, return SPURIOUS
  9.1211 -(p6)	br.cond.spnt.few 1f;
  9.1212 -	shl r29=r29,4;;
  9.1213 -	adds r29=15,r29;;
  9.1214 -	cmp.ge p6,p0=r29,r26
  9.1215 -(p6)	br.cond.spnt.few 1f;
  9.1216 -	// OK, have an unmasked vector to process/return
  9.1217 -	ld8 r25=[r24];;
  9.1218 -	or r25=r25,r27;;
  9.1219 -	st8 [r24]=r25;;
  9.1220 -	ld8 r25=[r22];;
  9.1221 -	andcm r25=r25,r27;;
  9.1222 -	st8 [r22]=r25;;
  9.1223 -	mov r8=r26;;
  9.1224 -	// if its a clock tick, remember itm to avoid delivering it twice
  9.1225 -	adds r20=XSI_ITV_OFS-XSI_PSR_IC_OFS,r18 ;;
  9.1226 -	ld8 r20=[r20];;
  9.1227 -	extr.u r20=r20,0,8;;
  9.1228 -	cmp.eq p6,p0=r20,r8
  9.1229 -	adds r22=IA64_VCPU_DOMAIN_ITM_LAST_OFFSET,r30
  9.1230 -	adds r23=IA64_VCPU_DOMAIN_ITM_OFFSET,r30;;
  9.1231 -	ld8 r23=[r23];;
  9.1232 -(p6)	st8 [r22]=r23;;
  9.1233 -	// all done
  9.1234 -1:	mov r24=cr.ipsr
  9.1235 -	mov r25=cr.iip;;
  9.1236 -	extr.u r26=r24,41,2 ;;
  9.1237 -	cmp.eq p6,p7=2,r26 ;;
  9.1238 -(p6)	mov r26=0
  9.1239 -(p6)	adds r25=16,r25
  9.1240 -(p7)	adds r26=1,r26
  9.1241 -	;;
  9.1242 -	dep r24=r26,r24,41,2
  9.1243 -	;;
  9.1244 -	mov cr.ipsr=r24
  9.1245 -	mov cr.iip=r25
  9.1246 -	mov pr=r31,-1 ;;
  9.1247 -	rfi
  9.1248 -	;;
  9.1249 -END(hyper_get_ivr)
  9.1250 -
  9.1251 -ENTRY(hyper_eoi)
  9.1252 -	// when we get to here r20=~=interrupts pending
  9.1253 -	cmp.ne p7,p0=r20,r0
  9.1254 -(p7)	br.spnt.many dispatch_break_fault ;;
  9.1255 -#ifdef FAST_HYPERPRIVOP_CNT
  9.1256 -	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_EOI);;
  9.1257 -	ld8 r21=[r20];;
  9.1258 -	adds r21=1,r21;;
  9.1259 -	st8 [r20]=r21;;
  9.1260 -#endif
  9.1261 -	movl r22=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;
  9.1262 -	ld8 r22=[r22];;
  9.1263 -	adds r22=IA64_VCPU_INSVC3_OFFSET,r22;;
  9.1264 -	ld8 r23=[r22];;
  9.1265 -	cmp.eq p6,p0=r23,r0;;
  9.1266 -(p6)	adds r22=-8,r22;;
  9.1267 -(p6)	ld8 r23=[r22];;
  9.1268 -(p6)	cmp.eq p6,p0=r23,r0;;
  9.1269 -(p6)	adds r22=-8,r22;;
  9.1270 -(p6)	ld8 r23=[r22];;
  9.1271 -(p6)	cmp.eq p6,p0=r23,r0;;
  9.1272 -(p6)	adds r22=-8,r22;;
  9.1273 -(p6)	ld8 r23=[r22];;
  9.1274 -(p6)	cmp.eq p6,p0=r23,r0;;
  9.1275 -	cmp.eq p6,p0=r23,r0
  9.1276 -(p6)	br.cond.spnt.few 1f;	// this is actually an error
  9.1277 -	// r22 points to non-zero element of insvc, r23 has value
  9.1278 -	shr.u r24=r23,1;;
  9.1279 -	or r24=r23,r24;;
  9.1280 -	shr.u r25=r24,2;;
  9.1281 -	or r24=r24,r25;;
  9.1282 -	shr.u r25=r24,4;;
  9.1283 -	or r24=r24,r25;;
  9.1284 -	shr.u r25=r24,8;;
  9.1285 -	or r24=r24,r25;;
  9.1286 -	shr.u r25=r24,16;;
  9.1287 -	or r24=r24,r25;;
  9.1288 -	shr.u r25=r24,32;;
  9.1289 -	or r24=r24,r25;;
  9.1290 -	andcm r24=0xffffffffffffffff,r24;;
  9.1291 -	popcnt r24=r24;;
  9.1292 -	sub r24=63,r24;;
  9.1293 -	// r24 now contains the bit index
  9.1294 -	mov r25=1;;
  9.1295 -	shl r25=r25,r24;;
  9.1296 -	andcm r23=r23,r25;;
  9.1297 -	st8 [r22]=r23;;
  9.1298 -1:	mov r24=cr.ipsr
  9.1299 -	mov r25=cr.iip;;
  9.1300 -	extr.u r26=r24,41,2 ;;
  9.1301 -	cmp.eq p6,p7=2,r26 ;;
  9.1302 -(p6)	mov r26=0
  9.1303 -(p6)	adds r25=16,r25
  9.1304 -(p7)	adds r26=1,r26
  9.1305 -	;;
  9.1306 -	dep r24=r26,r24,41,2
  9.1307 -	;;
  9.1308 -	mov cr.ipsr=r24
  9.1309 -	mov cr.iip=r25
  9.1310 -	mov pr=r31,-1 ;;
  9.1311 -	rfi
  9.1312 -	;;
  9.1313 -END(hyper_eoi)
  9.1314 -
  9.1315 -ENTRY(hyper_set_itm)
  9.1316 -	// when we get to here r20=~=interrupts pending
  9.1317 -	cmp.ne p7,p0=r20,r0
  9.1318 -(p7)	br.spnt.many dispatch_break_fault ;;
  9.1319 -#ifdef FAST_HYPERPRIVOP_CNT
  9.1320 -	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_SET_ITM);;
  9.1321 -	ld8 r21=[r20];;
  9.1322 -	adds r21=1,r21;;
  9.1323 -	st8 [r20]=r21;;
  9.1324 -#endif
  9.1325 -	movl r20=THIS_CPU(cpu_info)+IA64_CPUINFO_ITM_NEXT_OFFSET;;
  9.1326 -	ld8 r21=[r20];;
  9.1327 -	movl r20=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;
  9.1328 -	ld8 r20=[r20];;
  9.1329 -	adds r20=IA64_VCPU_DOMAIN_ITM_OFFSET,r20;;
  9.1330 -	st8 [r20]=r8;;
  9.1331 -	cmp.geu p6,p0=r21,r8;;
  9.1332 -(p6)	mov r21=r8;;
  9.1333 -	// now "safe set" cr.itm=r21
  9.1334 -	mov r23=100;;
  9.1335 -2:	mov cr.itm=r21;;
  9.1336 -	srlz.d;;
  9.1337 -	mov r22=ar.itc ;;
  9.1338 -	cmp.leu p6,p0=r21,r22;;
  9.1339 -	add r21=r21,r23;;
  9.1340 -	shl r23=r23,1;;
  9.1341 -(p6)	br.cond.spnt.few 2b;;
  9.1342 -1:	mov r24=cr.ipsr
  9.1343 -	mov r25=cr.iip;;
  9.1344 -	extr.u r26=r24,41,2 ;;
  9.1345 -	cmp.eq p6,p7=2,r26 ;;
  9.1346 -(p6)	mov r26=0
  9.1347 -(p6)	adds r25=16,r25
  9.1348 -(p7)	adds r26=1,r26
  9.1349 -	;;
  9.1350 -	dep r24=r26,r24,41,2
  9.1351 -	;;
  9.1352 -	mov cr.ipsr=r24
  9.1353 -	mov cr.iip=r25
  9.1354 -	mov pr=r31,-1 ;;
  9.1355 -	rfi
  9.1356 -	;;
  9.1357 -END(hyper_set_itm)
  9.1358 -
  9.1359 -ENTRY(hyper_get_rr)
  9.1360 -#ifdef FAST_HYPERPRIVOP_CNT
  9.1361 -	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_GET_RR);;
  9.1362 -	ld8 r21=[r20];;
  9.1363 -	adds r21=1,r21;;
  9.1364 -	st8 [r20]=r21;;
  9.1365 -#endif
  9.1366 -	extr.u r25=r8,61,3;;
  9.1367 -	adds r20=XSI_RR0_OFS-XSI_PSR_IC_OFS,r18 ;;
  9.1368 -	shl r25=r25,3;;
  9.1369 -	add r20=r20,r25;;
  9.1370 -	ld8 r8=[r20];;
  9.1371 -1:	mov r24=cr.ipsr
  9.1372 -	mov r25=cr.iip;;
  9.1373 -	extr.u r26=r24,41,2 ;;
  9.1374 -	cmp.eq p6,p7=2,r26 ;;
  9.1375 -(p6)	mov r26=0
  9.1376 -(p6)	adds r25=16,r25
  9.1377 -(p7)	adds r26=1,r26
  9.1378 -	;;
  9.1379 -	dep r24=r26,r24,41,2
  9.1380 -	;;
  9.1381 -	mov cr.ipsr=r24
  9.1382 -	mov cr.iip=r25
  9.1383 -	mov pr=r31,-1 ;;
  9.1384 -	rfi
  9.1385 -	;;
  9.1386 -END(hyper_get_rr)
  9.1387 -
  9.1388 -ENTRY(hyper_set_rr)
  9.1389 -	extr.u r25=r8,61,3;;
  9.1390 -	cmp.leu p7,p0=7,r25	// punt on setting rr7
  9.1391 -(p7)	br.spnt.many dispatch_break_fault ;;
  9.1392 -#ifdef FAST_HYPERPRIVOP_CNT
  9.1393 -	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_SET_RR);;
  9.1394 -	ld8 r21=[r20];;
  9.1395 -	adds r21=1,r21;;
  9.1396 -	st8 [r20]=r21;;
  9.1397 -#endif
  9.1398 -	extr.u r26=r9,8,24	// r26 = r9.rid
  9.1399 -	movl r20=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;
  9.1400 -	ld8 r20=[r20];;
  9.1401 -	adds r21=IA64_VCPU_STARTING_RID_OFFSET,r20;;
  9.1402 -	ld4 r22=[r21];;
  9.1403 -	adds r21=IA64_VCPU_ENDING_RID_OFFSET,r20;;
  9.1404 -	ld4 r23=[r21];;
  9.1405 -	adds r24=IA64_VCPU_META_SAVED_RR0_OFFSET,r20;;
  9.1406 -	add r22=r26,r22;;
  9.1407 -	cmp.geu p6,p0=r22,r23	// if r9.rid + starting_rid >= ending_rid
  9.1408 -(p6)	br.cond.spnt.few 1f;	// this is an error, but just ignore/return
  9.1409 -	// r21=starting_rid
  9.1410 -	adds r20=XSI_RR0_OFS-XSI_PSR_IC_OFS,r18 ;;
  9.1411 -	shl r25=r25,3;;
  9.1412 -	add r20=r20,r25;;
  9.1413 -	st8 [r20]=r9;;		// store away exactly what was passed
  9.1414 -	// but adjust value actually placed in rr[r8]
  9.1415 -	// r22 contains adjusted rid, "mangle" it (see regionreg.c)
  9.1416 -	// and set ps to PAGE_SHIFT and ve to 1
  9.1417 -	extr.u r27=r22,0,8
  9.1418 -	extr.u r28=r22,8,8
  9.1419 -	extr.u r29=r22,16,8;;
  9.1420 -	dep.z r23=PAGE_SHIFT,2,6;;
  9.1421 -	dep r23=-1,r23,0,1;;	// mangling is swapping bytes 1 & 3
  9.1422 -	dep r23=r27,r23,24,8;;
  9.1423 -	dep r23=r28,r23,16,8;;
  9.1424 -	dep r23=r29,r23,8,8
  9.1425 -	cmp.eq p6,p0=r25,r0;;	// if rr0, save for metaphysical
  9.1426 -(p6)	st4 [r24]=r23
  9.1427 -	mov rr[r8]=r23;;
  9.1428 -	// done, mosey on back
  9.1429 -1:	mov r24=cr.ipsr
  9.1430 -	mov r25=cr.iip;;
  9.1431 -	extr.u r26=r24,41,2 ;;
  9.1432 -	cmp.eq p6,p7=2,r26 ;;
  9.1433 -(p6)	mov r26=0
  9.1434 -(p6)	adds r25=16,r25
  9.1435 -(p7)	adds r26=1,r26
  9.1436 -	;;
  9.1437 -	dep r24=r26,r24,41,2
  9.1438 -	;;
  9.1439 -	mov cr.ipsr=r24
  9.1440 -	mov cr.iip=r25
  9.1441 -	mov pr=r31,-1 ;;
  9.1442 -	rfi
  9.1443 -	;;
  9.1444 -END(hyper_set_rr)
  9.1445 -
  9.1446 -// this routine was derived from optimized assembly output from
  9.1447 -// vcpu_thash so it is dense and difficult to read but it works
  9.1448 -// On entry:
  9.1449 -//	r18 == XSI_PSR_IC
  9.1450 -//	r31 == pr
  9.1451 -GLOBAL_ENTRY(hyper_thash)
  9.1452 -#ifdef FAST_HYPERPRIVOP_CNT
  9.1453 -	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_THASH);;
  9.1454 -	ld8 r21=[r20];;
  9.1455 -	adds r21=1,r21;;
  9.1456 -	st8 [r20]=r21;;
  9.1457 -#endif
  9.1458 -	shr.u r20 = r8, 61
  9.1459 -	addl r25 = 1, r0
  9.1460 -	movl r17 = 0xe000000000000000
  9.1461 -	;;
  9.1462 -	and r21 = r17, r8		// VHPT_Addr1
  9.1463 -	;;
  9.1464 -	shladd r28 = r20, 3, r18
  9.1465 -	adds r19 = XSI_PTA_OFS-XSI_PSR_IC_OFS, r18
  9.1466 -	;;
  9.1467 -	adds r27 = XSI_RR0_OFS-XSI_PSR_IC_OFS, r28
  9.1468 -	addl r28 = 32767, r0
  9.1469 -	ld8 r24 = [r19]			// pta
  9.1470 -	;;
  9.1471 -	ld8 r23 = [r27]			// rrs[vadr>>61]
  9.1472 -	extr.u r26 = r24, 2, 6
  9.1473 -	;;
  9.1474 -	extr.u r22 = r23, 2, 6
  9.1475 -	shl r30 = r25, r26
  9.1476 -	;;
  9.1477 -	shr.u r19 = r8, r22
  9.1478 -	shr.u r29 = r24, 15
  9.1479 -	;;
  9.1480 -	adds r17 = -1, r30
  9.1481 -	;;
  9.1482 -	shladd r27 = r19, 3, r0
  9.1483 -	extr.u r26 = r17, 15, 46
  9.1484 -	;;
  9.1485 -	andcm r24 = r29, r26
  9.1486 -	and r19 = r28, r27
  9.1487 -	shr.u r25 = r27, 15
  9.1488 -	;;
  9.1489 -	and r23 = r26, r25
  9.1490 -	;;
  9.1491 -	or r22 = r24, r23
  9.1492 -	;;
  9.1493 -	dep.z r20 = r22, 15, 46
  9.1494 -	;;
  9.1495 -	or r16 = r20, r21
  9.1496 -	;;
  9.1497 -	or r8 = r19, r16
  9.1498 -	// done, update iip/ipsr to next instruction
  9.1499 -	mov r24=cr.ipsr
  9.1500 -	mov r25=cr.iip;;
  9.1501 -	extr.u r26=r24,41,2 ;;
  9.1502 -	cmp.eq p6,p7=2,r26 ;;
  9.1503 -(p6)	mov r26=0
  9.1504 -(p6)	adds r25=16,r25
  9.1505 -(p7)	adds r26=1,r26
  9.1506 -	;;
  9.1507 -	dep r24=r26,r24,41,2
  9.1508 -	;;
  9.1509 -	mov cr.ipsr=r24
  9.1510 -	mov cr.iip=r25
  9.1511 -	mov pr=r31,-1 ;;
  9.1512 -	rfi
  9.1513 -	;;
  9.1514 -END(hyper_thash)
  9.1515 -
  9.1516 -ENTRY(hyper_ptc_ga)
  9.1517 -#ifndef FAST_PTC_GA
  9.1518 -	br.spnt.few dispatch_break_fault ;;
  9.1519 -#endif
  9.1520 -	// FIXME: validate not flushing Xen addresses
  9.1521 -#ifdef FAST_HYPERPRIVOP_CNT
  9.1522 -	movl r20=fast_hyperpriv_cnt+(8*XEN_HYPER_PTC_GA);;
  9.1523 -	ld8 r21=[r20];;
  9.1524 -	adds r21=1,r21;;
  9.1525 -	st8 [r20]=r21;;
  9.1526 -#endif
  9.1527 -	mov r28=r8
  9.1528 -	extr.u r19=r9,2,6		// addr_range=1<<((r9&0xfc)>>2)
  9.1529 -	mov r20=1
  9.1530 -	shr.u r24=r8,61
  9.1531 -	addl r27=56,r0			// PAGE_SHIFT<<2 (for ptc.ga)
  9.1532 -	movl r26=0x8000000000000000	// INVALID_TI_TAG
  9.1533 -	mov r30=ar.lc
  9.1534 -	;;
  9.1535 -	shl r19=r20,r19
  9.1536 -	cmp.eq p7,p0=7,r24
  9.1537 -(p7)	br.spnt.many dispatch_break_fault ;;	// slow way for rr7
  9.1538 -	;;
  9.1539 -	cmp.le p7,p0=r19,r0		// skip flush if size<=0
  9.1540 -(p7)	br.cond.dpnt 2f ;;
  9.1541 -	extr.u r24=r19,0,PAGE_SHIFT
  9.1542 -	shr.u r23=r19,PAGE_SHIFT ;;	// repeat loop for n pages
  9.1543 -	cmp.ne p7,p0=r24,r0 ;;
  9.1544 -(p7)	adds r23=1,r23 ;;		// n_pages<size<n_pages+1? extra iter
  9.1545 -	mov ar.lc=r23
  9.1546 -	movl r29=PAGE_SIZE;;
  9.1547 -1:
  9.1548 -	thash r25=r28 ;;
  9.1549 -	adds r25=16,r25 ;;
  9.1550 -	ld8 r24=[r25] ;;
  9.1551 -	// FIXME: should check if tag matches, not just blow it away
  9.1552 -	or r24=r26,r24 ;;		// vhpt_entry->ti_tag = 1
  9.1553 -	st8 [r25]=r24
  9.1554 -	ptc.ga r28,r27 ;;
  9.1555 -	srlz.i ;;
  9.1556 -	add r28=r29,r28
  9.1557 -	br.cloop.sptk.few 1b
  9.1558 -	;;
  9.1559 -2:
  9.1560 -	mov ar.lc=r30 ;;
  9.1561 -	mov r29=cr.ipsr
  9.1562 -	mov r30=cr.iip;;
  9.1563 -	movl r27=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;
  9.1564 -	ld8 r27=[r27];;
  9.1565 -	adds r25=IA64_VCPU_DTLB_OFFSET,r27
  9.1566 -	adds r26=IA64_VCPU_ITLB_OFFSET,r27;;
  9.1567 -	ld8 r24=[r25]
  9.1568 -	ld8 r27=[r26] ;;
  9.1569 -	and r24=-2,r24
  9.1570 -	and r27=-2,r27 ;;
  9.1571 -	st8 [r25]=r24			// set 1-entry i/dtlb as not present
  9.1572 -	st8 [r26]=r27 ;;
  9.1573 -	// increment to point to next instruction
  9.1574 -	extr.u r26=r29,41,2 ;;
  9.1575 -	cmp.eq p6,p7=2,r26 ;;
  9.1576 -(p6)	mov r26=0
  9.1577 -(p6)	adds r30=16,r30
  9.1578 -(p7)	adds r26=1,r26
  9.1579 -	;;
  9.1580 -	dep r29=r26,r29,41,2
  9.1581 -	;;
  9.1582 -	mov cr.ipsr=r29
  9.1583 -	mov cr.iip=r30
  9.1584 -	mov pr=r31,-1 ;;
  9.1585 -	rfi
  9.1586 -	;;
  9.1587 -END(hyper_ptc_ga)
  9.1588 -
  9.1589 -ENTRY(hyper_itc_d)
  9.1590 -	br.spnt.many dispatch_break_fault ;;
  9.1591 -END(hyper_itc_d)
  9.1592 -
  9.1593 -ENTRY(hyper_itc_i)
  9.1594 -	br.spnt.many dispatch_break_fault ;;
  9.1595 -END(hyper_itc_i)
    10.1 --- a/xen/arch/ia64/idle0_task.c	Thu Sep 01 11:09:27 2005 -0600
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,58 +0,0 @@
    10.4 -#include <xen/config.h>
    10.5 -#include <xen/sched.h>
    10.6 -#include <asm/desc.h>
    10.7 -
    10.8 -#define INIT_MM(name) \
    10.9 -{			 					\
   10.10 -	.pgd		= swapper_pg_dir, 			\
   10.11 -	.mm_users	= ATOMIC_INIT(2), 			\
   10.12 -	.mm_count	= ATOMIC_INIT(1), 			\
   10.13 -	.page_table_lock =  SPIN_LOCK_UNLOCKED, 		\
   10.14 -	.mmlist		= LIST_HEAD_INIT(name.mmlist),		\
   10.15 -}
   10.16 -
   10.17 -#define IDLE0_EXEC_DOMAIN(_ed,_d)    \
   10.18 -{                                    \
   10.19 -    processor:   0,                  \
   10.20 -    mm:          0,                  \
   10.21 -    thread:      INIT_THREAD,        \
   10.22 -    domain:      (_d)                \
   10.23 -}
   10.24 -
   10.25 -#define IDLE0_DOMAIN(_t)             \
   10.26 -{                                    \
   10.27 -    domain_id:   IDLE_DOMAIN_ID,     \
   10.28 -    domain_flags:DOMF_idle_domain,   \
   10.29 -    refcnt:      ATOMIC_INIT(1)      \
   10.30 -}
   10.31 -
   10.32 -struct mm_struct init_mm = INIT_MM(init_mm);
   10.33 -EXPORT_SYMBOL(init_mm);
   10.34 -
   10.35 -struct domain idle0_domain = IDLE0_DOMAIN(idle0_domain);
   10.36 -#if 0
   10.37 -struct vcpu idle0_vcpu = IDLE0_EXEC_DOMAIN(idle0_vcpu,
   10.38 -                                                         &idle0_domain);
   10.39 -#endif
   10.40 -
   10.41 -
   10.42 -/*
   10.43 - * Initial task structure.
   10.44 - *
   10.45 - * We need to make sure that this is properly aligned due to the way process stacks are
   10.46 - * handled. This is done by having a special ".data.init_task" section...
   10.47 - */
   10.48 -union {
   10.49 -	struct {
   10.50 -		struct domain task;
   10.51 -	} s;
   10.52 -	unsigned long stack[KERNEL_STACK_SIZE/sizeof (unsigned long)];
   10.53 -} init_task_mem asm ("init_task") __attribute__((section(".data.init_task")));
   10.54 -// = {{
   10.55 -	;
   10.56 -//.task =		IDLE0_EXEC_DOMAIN(init_task_mem.s.task,&idle0_domain),
   10.57 -//};
   10.58 -//};
   10.59 -
   10.60 -EXPORT_SYMBOL(init_task);
   10.61 -
    11.1 --- a/xen/arch/ia64/irq.c	Thu Sep 01 11:09:27 2005 -0600
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,1503 +0,0 @@
    11.4 -/*
    11.5 - *	linux/arch/ia64/kernel/irq.c
    11.6 - *
    11.7 - *	Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
    11.8 - *
    11.9 - * This file contains the code used by various IRQ handling routines:
   11.10 - * asking for different IRQ's should be done through these routines
   11.11 - * instead of just grabbing them. Thus setups with different IRQ numbers
   11.12 - * shouldn't result in any weird surprises, and installing new handlers
   11.13 - * should be easier.
   11.14 - *
   11.15 - * Copyright (C) Ashok Raj<ashok.raj@intel.com>, Intel Corporation 2004
   11.16 - *
   11.17 - * 4/14/2004: Added code to handle cpu migration and do safe irq
   11.18 - *			migration without lossing interrupts for iosapic
   11.19 - *			architecture.
   11.20 - */
   11.21 -
   11.22 -/*
   11.23 - * (mostly architecture independent, will move to kernel/irq.c in 2.5.)
   11.24 - *
   11.25 - * IRQs are in fact implemented a bit like signal handlers for the kernel.
   11.26 - * Naturally it's not a 1:1 relation, but there are similarities.
   11.27 - */
   11.28 -
   11.29 -#include <linux/config.h>
   11.30 -#include <linux/errno.h>
   11.31 -#include <linux/module.h>
   11.32 -#ifndef XEN
   11.33 -#include <linux/signal.h>
   11.34 -#endif
   11.35 -#include <linux/sched.h>
   11.36 -#include <linux/ioport.h>
   11.37 -#include <linux/interrupt.h>
   11.38 -#include <linux/timex.h>
   11.39 -#include <linux/slab.h>
   11.40 -#ifndef XEN
   11.41 -#include <linux/random.h>
   11.42 -#include <linux/cpu.h>
   11.43 -#endif
   11.44 -#include <linux/ctype.h>
   11.45 -#ifndef XEN
   11.46 -#include <linux/smp_lock.h>
   11.47 -#endif
   11.48 -#include <linux/init.h>
   11.49 -#ifndef XEN
   11.50 -#include <linux/kernel_stat.h>
   11.51 -#endif
   11.52 -#include <linux/irq.h>
   11.53 -#ifndef XEN
   11.54 -#include <linux/proc_fs.h>
   11.55 -#endif
   11.56 -#include <linux/seq_file.h>
   11.57 -#ifndef XEN
   11.58 -#include <linux/kallsyms.h>
   11.59 -#include <linux/notifier.h>
   11.60 -#endif
   11.61 -
   11.62 -#include <asm/atomic.h>
   11.63 -#ifndef XEN
   11.64 -#include <asm/cpu.h>
   11.65 -#endif
   11.66 -#include <asm/io.h>
   11.67 -#include <asm/smp.h>
   11.68 -#include <asm/system.h>
   11.69 -#include <asm/bitops.h>
   11.70 -#include <asm/uaccess.h>
   11.71 -#include <asm/pgalloc.h>
   11.72 -#ifndef XEN
   11.73 -#include <asm/tlbflush.h>
   11.74 -#endif
   11.75 -#include <asm/delay.h>
   11.76 -#include <asm/irq.h>
   11.77 -
   11.78 -#ifdef XEN
   11.79 -#include <xen/event.h>
   11.80 -#define _irq_desc irq_desc
   11.81 -#define irq_descp(irq) &irq_desc[irq]
   11.82 -#define apicid_to_phys_cpu_present(x)	1
   11.83 -#endif
   11.84 -
   11.85 -
   11.86 -/*
   11.87 - * Linux has a controller-independent x86 interrupt architecture.
   11.88 - * every controller has a 'controller-template', that is used
   11.89 - * by the main code to do the right thing. Each driver-visible
   11.90 - * interrupt source is transparently wired to the appropriate
   11.91 - * controller. Thus drivers need not be aware of the
   11.92 - * interrupt-controller.
   11.93 - *
   11.94 - * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
   11.95 - * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
   11.96 - * (IO-APICs assumed to be messaging to Pentium local-APICs)
   11.97 - *
   11.98 - * the code is designed to be easily extended with new/different
   11.99 - * interrupt controllers, without having to do assembly magic.
  11.100 - */
  11.101 -
  11.102 -/*
  11.103 - * Controller mappings for all interrupt sources:
  11.104 - */
  11.105 -irq_desc_t _irq_desc[NR_IRQS] __cacheline_aligned = {
  11.106 -	[0 ... NR_IRQS-1] = {
  11.107 -		.status = IRQ_DISABLED,
  11.108 -		.handler = &no_irq_type,
  11.109 -		.lock = SPIN_LOCK_UNLOCKED
  11.110 -	}
  11.111 -};
  11.112 -
  11.113 -/*
  11.114 - * This is updated when the user sets irq affinity via /proc
  11.115 - */
  11.116 -cpumask_t    __cacheline_aligned pending_irq_cpumask[NR_IRQS];
  11.117 -
  11.118 -#ifdef CONFIG_IA64_GENERIC
  11.119 -irq_desc_t * __ia64_irq_desc (unsigned int irq)
  11.120 -{
  11.121 -	return _irq_desc + irq;
  11.122 -}
  11.123 -
  11.124 -ia64_vector __ia64_irq_to_vector (unsigned int irq)
  11.125 -{
  11.126 -	return (ia64_vector) irq;
  11.127 -}
  11.128 -
  11.129 -unsigned int __ia64_local_vector_to_irq (ia64_vector vec)
  11.130 -{
  11.131 -	return (unsigned int) vec;
  11.132 -}
  11.133 -#endif
  11.134 -
  11.135 -static void register_irq_proc (unsigned int irq);
  11.136 -
  11.137 -/*
  11.138 - * Special irq handlers.
  11.139 - */
  11.140 -
  11.141 -#ifdef XEN
  11.142 -void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
  11.143 -#else
  11.144 -irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs)
  11.145 -{ return IRQ_NONE; }
  11.146 -#endif
  11.147 -
  11.148 -/*
  11.149 - * Generic no controller code
  11.150 - */
  11.151 -
  11.152 -static void enable_none(unsigned int irq) { }
  11.153 -static unsigned int startup_none(unsigned int irq) { return 0; }
  11.154 -static void disable_none(unsigned int irq) { }
  11.155 -static void ack_none(unsigned int irq)
  11.156 -{
  11.157 -/*
  11.158 - * 'what should we do if we get a hw irq event on an illegal vector'.
  11.159 - * each architecture has to answer this themselves, it doesn't deserve
  11.160 - * a generic callback i think.
  11.161 - */
  11.162 -#ifdef CONFIG_X86
  11.163 -	printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq);
  11.164 -#ifdef CONFIG_X86_LOCAL_APIC
  11.165 -	/*
  11.166 -	 * Currently unexpected vectors happen only on SMP and APIC.
  11.167 -	 * We _must_ ack these because every local APIC has only N
  11.168 -	 * irq slots per priority level, and a 'hanging, unacked' IRQ
  11.169 -	 * holds up an irq slot - in excessive cases (when multiple
  11.170 -	 * unexpected vectors occur) that might lock up the APIC
  11.171 -	 * completely.
  11.172 -	 */
  11.173 -	ack_APIC_irq();
  11.174 -#endif
  11.175 -#endif
  11.176 -#ifdef CONFIG_IA64
  11.177 -	printk(KERN_ERR "Unexpected irq vector 0x%x on CPU %u!\n", irq, smp_processor_id());
  11.178 -#endif
  11.179 -}
  11.180 -
  11.181 -/* startup is the same as "enable", shutdown is same as "disable" */
  11.182 -#define shutdown_none	disable_none
  11.183 -#define end_none	enable_none
  11.184 -
  11.185 -struct hw_interrupt_type no_irq_type = {
  11.186 -	"none",
  11.187 -	startup_none,
  11.188 -	shutdown_none,
  11.189 -	enable_none,
  11.190 -	disable_none,
  11.191 -	ack_none,
  11.192 -	end_none
  11.193 -};
  11.194 -
  11.195 -atomic_t irq_err_count;
  11.196 -#ifdef CONFIG_X86_IO_APIC
  11.197 -#ifdef APIC_MISMATCH_DEBUG
  11.198 -atomic_t irq_mis_count;
  11.199 -#endif
  11.200 -#endif
  11.201 -
  11.202 -/*
  11.203 - * Generic, controller-independent functions:
  11.204 - */
  11.205 -
  11.206 -#ifndef XEN
  11.207 -int show_interrupts(struct seq_file *p, void *v)
  11.208 -{
  11.209 -	int j, i = *(loff_t *) v;
  11.210 -	struct irqaction * action;
  11.211 -	irq_desc_t *idesc;
  11.212 -	unsigned long flags;
  11.213 -
  11.214 -	if (i == 0) {
  11.215 -		seq_puts(p, "           ");
  11.216 -		for (j=0; j<NR_CPUS; j++)
  11.217 -			if (cpu_online(j))
  11.218 -				seq_printf(p, "CPU%d       ",j);
  11.219 -		seq_putc(p, '\n');
  11.220 -	}
  11.221 -
  11.222 -	if (i < NR_IRQS) {
  11.223 -		idesc = irq_descp(i);
  11.224 -		spin_lock_irqsave(&idesc->lock, flags);
  11.225 -		action = idesc->action;
  11.226 -		if (!action)
  11.227 -			goto skip;
  11.228 -		seq_printf(p, "%3d: ",i);
  11.229 -#ifndef CONFIG_SMP
  11.230 -		seq_printf(p, "%10u ", kstat_irqs(i));
  11.231 -#else
  11.232 -		for (j = 0; j < NR_CPUS; j++)
  11.233 -			if (cpu_online(j))
  11.234 -				seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
  11.235 -#endif
  11.236 -		seq_printf(p, " %14s", idesc->handler->typename);
  11.237 -		seq_printf(p, "  %s", action->name);
  11.238 -
  11.239 -		for (action=action->next; action; action = action->next)
  11.240 -			seq_printf(p, ", %s", action->name);
  11.241 -
  11.242 -		seq_putc(p, '\n');
  11.243 -skip:
  11.244 -		spin_unlock_irqrestore(&idesc->lock, flags);
  11.245 -	} else if (i == NR_IRQS) {
  11.246 -		seq_puts(p, "NMI: ");
  11.247 -		for (j = 0; j < NR_CPUS; j++)
  11.248 -			if (cpu_online(j))
  11.249 -				seq_printf(p, "%10u ", nmi_count(j));
  11.250 -		seq_putc(p, '\n');
  11.251 -#ifdef CONFIG_X86_LOCAL_APIC
  11.252 -		seq_puts(p, "LOC: ");
  11.253 -		for (j = 0; j < NR_CPUS; j++)
  11.254 -			if (cpu_online(j))
  11.255 -				seq_printf(p, "%10u ", irq_stat[j].apic_timer_irqs);
  11.256 -		seq_putc(p, '\n');
  11.257 -#endif
  11.258 -		seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
  11.259 -#ifdef CONFIG_X86_IO_APIC
  11.260 -#ifdef APIC_MISMATCH_DEBUG
  11.261 -		seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
  11.262 -#endif
  11.263 -#endif
  11.264 -	}
  11.265 -	return 0;
  11.266 -}
  11.267 -#endif
  11.268 -
  11.269 -#ifdef CONFIG_SMP
  11.270 -inline void synchronize_irq(unsigned int irq)
  11.271 -{
  11.272 -#ifndef XEN
  11.273 -	struct irq_desc *desc = irq_desc + irq;
  11.274 -
  11.275 -	while (desc->status & IRQ_INPROGRESS)
  11.276 -		cpu_relax();
  11.277 -#endif
  11.278 -}
  11.279 -EXPORT_SYMBOL(synchronize_irq);
  11.280 -#endif
  11.281 -
  11.282 -/*
  11.283 - * This should really return information about whether
  11.284 - * we should do bottom half handling etc. Right now we
  11.285 - * end up _always_ checking the bottom half, which is a
  11.286 - * waste of time and is not what some drivers would
  11.287 - * prefer.
  11.288 - */
  11.289 -int handle_IRQ_event(unsigned int irq,
  11.290 -		struct pt_regs *regs, struct irqaction *action)
  11.291 -{
  11.292 -	int status = 1;	/* Force the "do bottom halves" bit */
  11.293 -	int retval = 0;
  11.294 -
  11.295 -#ifndef XEN
  11.296 -	if (!(action->flags & SA_INTERRUPT))
  11.297 -#endif
  11.298 -		local_irq_enable();
  11.299 -
  11.300 -#ifdef XEN
  11.301 -		action->handler(irq, action->dev_id, regs);
  11.302 -#else
  11.303 -	do {
  11.304 -		status |= action->flags;
  11.305 -		retval |= action->handler(irq, action->dev_id, regs);
  11.306 -		action = action->next;
  11.307 -	} while (action);
  11.308 -	if (status & SA_SAMPLE_RANDOM)
  11.309 -		add_interrupt_randomness(irq);
  11.310 -#endif
  11.311 -	local_irq_disable();
  11.312 -	return retval;
  11.313 -}
  11.314 -
  11.315 -#ifndef XEN
  11.316 -static void __report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret)
  11.317 -{
  11.318 -	struct irqaction *action;
  11.319 -
  11.320 -	if (action_ret != IRQ_HANDLED && action_ret != IRQ_NONE) {
  11.321 -		printk(KERN_ERR "irq event %d: bogus return value %x\n",
  11.322 -				irq, action_ret);
  11.323 -	} else {
  11.324 -		printk(KERN_ERR "irq %d: nobody cared!\n", irq);
  11.325 -	}
  11.326 -	dump_stack();
  11.327 -	printk(KERN_ERR "handlers:\n");
  11.328 -	action = desc->action;
  11.329 -	do {
  11.330 -		printk(KERN_ERR "[<%p>]", action->handler);
  11.331 -		print_symbol(" (%s)",
  11.332 -			(unsigned long)action->handler);
  11.333 -		printk("\n");
  11.334 -		action = action->next;
  11.335 -	} while (action);
  11.336 -}
  11.337 -
  11.338 -static void report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret)
  11.339 -{
  11.340 -	static int count = 100;
  11.341 -
  11.342 -	if (count) {
  11.343 -		count--;
  11.344 -		__report_bad_irq(irq, desc, action_ret);
  11.345 -	}
  11.346 -}
  11.347 -#endif
  11.348 -
  11.349 -static int noirqdebug;
  11.350 -
  11.351 -static int __init noirqdebug_setup(char *str)
  11.352 -{
  11.353 -	noirqdebug = 1;
  11.354 -	printk("IRQ lockup detection disabled\n");
  11.355 -	return 1;
  11.356 -}
  11.357 -
  11.358 -__setup("noirqdebug", noirqdebug_setup);
  11.359 -
  11.360 -/*
  11.361 - * If 99,900 of the previous 100,000 interrupts have not been handled then
  11.362 - * assume that the IRQ is stuck in some manner.  Drop a diagnostic and try to
  11.363 - * turn the IRQ off.
  11.364 - *
  11.365 - * (The other 100-of-100,000 interrupts may have been a correctly-functioning
  11.366 - *  device sharing an IRQ with the failing one)
  11.367 - *
  11.368 - * Called under desc->lock
  11.369 - */
  11.370 -#ifndef XEN
  11.371 -static void note_interrupt(int irq, irq_desc_t *desc, irqreturn_t action_ret)
  11.372 -{
  11.373 -	if (action_ret != IRQ_HANDLED) {
  11.374 -		desc->irqs_unhandled++;
  11.375 -		if (action_ret != IRQ_NONE)
  11.376 -			report_bad_irq(irq, desc, action_ret);
  11.377 -	}
  11.378 -
  11.379 -	desc->irq_count++;
  11.380 -	if (desc->irq_count < 100000)
  11.381 -		return;
  11.382 -
  11.383 -	desc->irq_count = 0;
  11.384 -	if (desc->irqs_unhandled > 99900) {
  11.385 -		/*
  11.386 -		 * The interrupt is stuck
  11.387 -		 */
  11.388 -		__report_bad_irq(irq, desc, action_ret);
  11.389 -		/*
  11.390 -		 * Now kill the IRQ
  11.391 -		 */
  11.392 -		printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
  11.393 -		desc->status |= IRQ_DISABLED;
  11.394 -		desc->handler->disable(irq);
  11.395 -	}
  11.396 -	desc->irqs_unhandled = 0;
  11.397 -}
  11.398 -#endif
  11.399 -
  11.400 -/*
  11.401 - * Generic enable/disable code: this just calls
  11.402 - * down into the PIC-specific version for the actual
  11.403 - * hardware disable after having gotten the irq
  11.404 - * controller lock.
  11.405 - */
  11.406 -
  11.407 -/**
  11.408 - *	disable_irq_nosync - disable an irq without waiting
  11.409 - *	@irq: Interrupt to disable
  11.410 - *
  11.411 - *	Disable the selected interrupt line.  Disables and Enables are
  11.412 - *	nested.
  11.413 - *	Unlike disable_irq(), this function does not ensure existing
  11.414 - *	instances of the IRQ handler have completed before returning.
  11.415 - *
  11.416 - *	This function may be called from IRQ context.
  11.417 - */
  11.418 -
  11.419 -inline void disable_irq_nosync(unsigned int irq)
  11.420 -{
  11.421 -	irq_desc_t *desc = irq_descp(irq);
  11.422 -	unsigned long flags;
  11.423 -
  11.424 -	spin_lock_irqsave(&desc->lock, flags);
  11.425 -	if (!desc->depth++) {
  11.426 -		desc->status |= IRQ_DISABLED;
  11.427 -		desc->handler->disable(irq);
  11.428 -	}
  11.429 -	spin_unlock_irqrestore(&desc->lock, flags);
  11.430 -}
  11.431 -EXPORT_SYMBOL(disable_irq_nosync);
  11.432 -
  11.433 -/**
  11.434 - *	disable_irq - disable an irq and wait for completion
  11.435 - *	@irq: Interrupt to disable
  11.436 - *
  11.437 - *	Disable the selected interrupt line.  Enables and Disables are
  11.438 - *	nested.
  11.439 - *	This function waits for any pending IRQ handlers for this interrupt
  11.440 - *	to complete before returning. If you use this function while
  11.441 - *	holding a resource the IRQ handler may need you will deadlock.
  11.442 - *
  11.443 - *	This function may be called - with care - from IRQ context.
  11.444 - */
  11.445 -
  11.446 -void disable_irq(unsigned int irq)
  11.447 -{
  11.448 -	irq_desc_t *desc = irq_descp(irq);
  11.449 -
  11.450 -	disable_irq_nosync(irq);
  11.451 -	if (desc->action)
  11.452 -		synchronize_irq(irq);
  11.453 -}
  11.454 -EXPORT_SYMBOL(disable_irq);
  11.455 -
  11.456 -/**
  11.457 - *	enable_irq - enable handling of an irq
  11.458 - *	@irq: Interrupt to enable
  11.459 - *
  11.460 - *	Undoes the effect of one call to disable_irq().  If this
  11.461 - *	matches the last disable, processing of interrupts on this
  11.462 - *	IRQ line is re-enabled.
  11.463 - *
  11.464 - *	This function may be called from IRQ context.
  11.465 - */
  11.466 -
  11.467 -void enable_irq(unsigned int irq)
  11.468 -{
  11.469 -	irq_desc_t *desc = irq_descp(irq);
  11.470 -	unsigned long flags;
  11.471 -
  11.472 -	spin_lock_irqsave(&desc->lock, flags);
  11.473 -	switch (desc->depth) {
  11.474 -	case 1: {
  11.475 -		unsigned int status = desc->status & ~IRQ_DISABLED;
  11.476 -		desc->status = status;
  11.477 -#ifndef XEN
  11.478 -		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
  11.479 -			desc->status = status | IRQ_REPLAY;
  11.480 -			hw_resend_irq(desc->handler,irq);
  11.481 -		}
  11.482 -#endif
  11.483 -		desc->handler->enable(irq);
  11.484 -		/* fall-through */
  11.485 -	}
  11.486 -	default:
  11.487 -		desc->depth--;
  11.488 -		break;
  11.489 -	case 0:
  11.490 -		printk(KERN_ERR "enable_irq(%u) unbalanced from %p\n",
  11.491 -		       irq, (void *) __builtin_return_address(0));
  11.492 -	}
  11.493 -	spin_unlock_irqrestore(&desc->lock, flags);
  11.494 -}
  11.495 -EXPORT_SYMBOL(enable_irq);
  11.496 -
  11.497 -/*
  11.498 - * do_IRQ handles all normal device IRQ's (the special
  11.499 - * SMP cross-CPU interrupts have their own specific
  11.500 - * handlers).
  11.501 - */
  11.502 -fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs)
  11.503 -{
  11.504 -	irq_desc_t *desc = irq_desc + irq;
  11.505 -	struct irqaction * action;
  11.506 -	unsigned int status;
  11.507 -
  11.508 -#ifndef XEN
  11.509 -	kstat_this_cpu.irqs[irq]++;
  11.510 -#endif
  11.511 -	if (desc->status & IRQ_PER_CPU) {
  11.512 -		irqreturn_t action_ret;
  11.513 -
  11.514 -		/*
  11.515 -		 * No locking required for CPU-local interrupts:
  11.516 -		 */
  11.517 -		desc->handler->ack(irq);
  11.518 -		action_ret = handle_IRQ_event(irq, regs, desc->action);
  11.519 -#ifndef XEN
  11.520 -		if (!noirqdebug)
  11.521 -			note_interrupt(irq, desc, action_ret);
  11.522 -#endif
  11.523 -		desc->handler->end(irq);
  11.524 -		return 1;
  11.525 -	}
  11.526 -
  11.527 -	spin_lock(&desc->lock);
  11.528 -	desc->handler->ack(irq);
  11.529 -	/*
  11.530 -	 * REPLAY is when Linux resends an IRQ that was dropped earlier
  11.531 -	 * WAITING is used by probe to mark irqs that are being tested
  11.532 -	 */
  11.533 -#ifdef XEN
  11.534 -	status = desc->status & ~IRQ_REPLAY;
  11.535 -#else
  11.536 -	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
  11.537 -#endif
  11.538 -	status |= IRQ_PENDING; /* we _want_ to handle it */
  11.539 -
  11.540 -	/*
  11.541 -	 * If the IRQ is disabled for whatever reason, we cannot
  11.542 -	 * use the action we have.
  11.543 -	 */
  11.544 -	action = NULL;
  11.545 -	if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
  11.546 -		action = desc->action;
  11.547 -		status &= ~IRQ_PENDING; /* we commit to handling */
  11.548 -		status |= IRQ_INPROGRESS; /* we are handling it */
  11.549 -	}
  11.550 -	desc->status = status;
  11.551 -
  11.552 -	/*
  11.553 -	 * If there is no IRQ handler or it was disabled, exit early.
  11.554 -	 * Since we set PENDING, if another processor is handling
  11.555 -	 * a different instance of this same irq, the other processor
  11.556 -	 * will take care of it.
  11.557 -	 */
  11.558 -	if (unlikely(!action))
  11.559 -		goto out;
  11.560 -
  11.561 -	/*
  11.562 -	 * Edge triggered interrupts need to remember
  11.563 -	 * pending events.
  11.564 -	 * This applies to any hw interrupts that allow a second
  11.565 -	 * instance of the same irq to arrive while we are in do_IRQ
  11.566 -	 * or in the handler. But the code here only handles the _second_
  11.567 -	 * instance of the irq, not the third or fourth. So it is mostly
  11.568 -	 * useful for irq hardware that does not mask cleanly in an
  11.569 -	 * SMP environment.
  11.570 -	 */
  11.571 -	for (;;) {
  11.572 -		irqreturn_t action_ret;
  11.573 -
  11.574 -		spin_unlock(&desc->lock);
  11.575 -
  11.576 -		action_ret = handle_IRQ_event(irq, regs, action);
  11.577 -
  11.578 -		spin_lock(&desc->lock);
  11.579 -#ifndef XEN
  11.580 -		if (!noirqdebug)
  11.581 -			note_interrupt(irq, desc, action_ret);
  11.582 -#endif
  11.583 -		if (likely(!(desc->status & IRQ_PENDING)))
  11.584 -			break;
  11.585 -		desc->status &= ~IRQ_PENDING;
  11.586 -	}
  11.587 -	desc->status &= ~IRQ_INPROGRESS;
  11.588 -
  11.589 -out:
  11.590 -	/*
  11.591 -	 * The ->end() handler has to deal with interrupts which got
  11.592 -	 * disabled while the handler was running.
  11.593 -	 */
  11.594 -	desc->handler->end(irq);
  11.595 -	spin_unlock(&desc->lock);
  11.596 -
  11.597 -	return 1;
  11.598 -}
  11.599 -
  11.600 -/**
  11.601 - *	request_irq - allocate an interrupt line
  11.602 - *	@irq: Interrupt line to allocate
  11.603 - *	@handler: Function to be called when the IRQ occurs
  11.604 - *	@irqflags: Interrupt type flags
  11.605 - *	@devname: An ascii name for the claiming device
  11.606 - *	@dev_id: A cookie passed back to the handler function
  11.607 - *
  11.608 - *	This call allocates interrupt resources and enables the
  11.609 - *	interrupt line and IRQ handling. From the point this
  11.610 - *	call is made your handler function may be invoked. Since
  11.611 - *	your handler function must clear any interrupt the board 
  11.612 - *	raises, you must take care both to initialise your hardware
  11.613 - *	and to set up the interrupt handler in the right order.
  11.614 - *
  11.615 - *	Dev_id must be globally unique. Normally the address of the
  11.616 - *	device data structure is used as the cookie. Since the handler
  11.617 - *	receives this value it makes sense to use it.
  11.618 - *
  11.619 - *	If your interrupt is shared you must pass a non NULL dev_id
  11.620 - *	as this is required when freeing the interrupt.
  11.621 - *
  11.622 - *	Flags:
  11.623 - *
  11.624 - *	SA_SHIRQ		Interrupt is shared
  11.625 - *
  11.626 - *	SA_INTERRUPT		Disable local interrupts while processing
  11.627 - *
  11.628 - *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
  11.629 - *
  11.630 - */
  11.631 -
  11.632 -int request_irq(unsigned int irq,
  11.633 -		irqreturn_t (*handler)(int, void *, struct pt_regs *),
  11.634 -		unsigned long irqflags,
  11.635 -		const char * devname,
  11.636 -		void *dev_id)
  11.637 -{
  11.638 -	int retval;
  11.639 -	struct irqaction * action;
  11.640 -
  11.641 -#if 1
  11.642 -	/*
  11.643 -	 * Sanity-check: shared interrupts should REALLY pass in
  11.644 -	 * a real dev-ID, otherwise we'll have trouble later trying
  11.645 -	 * to figure out which interrupt is which (messes up the
  11.646 -	 * interrupt freeing logic etc).
  11.647 -	 */
  11.648 -	if (irqflags & SA_SHIRQ) {
  11.649 -		if (!dev_id)
  11.650 -			printk(KERN_ERR "Bad boy: %s called us without a dev_id!\n", devname);
  11.651 -	}
  11.652 -#endif
  11.653 -
  11.654 -	if (irq >= NR_IRQS)
  11.655 -		return -EINVAL;
  11.656 -	if (!handler)
  11.657 -		return -EINVAL;
  11.658 -
  11.659 -	action = xmalloc(struct irqaction);
  11.660 -	if (!action)
  11.661 -		return -ENOMEM;
  11.662 -
  11.663 -	action->handler = handler;
  11.664 -#ifndef XEN
  11.665 -	action->flags = irqflags;
  11.666 -	action->mask = 0;
  11.667 -#endif
  11.668 -	action->name = devname;
  11.669 -#ifndef XEN
  11.670 -	action->next = NULL;
  11.671 -#endif
  11.672 -	action->dev_id = dev_id;
  11.673 -
  11.674 -	retval = setup_irq(irq, action);
  11.675 -	if (retval)
  11.676 -		xfree(action);
  11.677 -	return retval;
  11.678 -}
  11.679 -
  11.680 -EXPORT_SYMBOL(request_irq);
  11.681 -
  11.682 -/**
  11.683 - *	free_irq - free an interrupt
  11.684 - *	@irq: Interrupt line to free
  11.685 - *	@dev_id: Device identity to free
  11.686 - *
  11.687 - *	Remove an interrupt handler. The handler is removed and if the
  11.688 - *	interrupt line is no longer in use by any driver it is disabled.
  11.689 - *	On a shared IRQ the caller must ensure the interrupt is disabled
  11.690 - *	on the card it drives before calling this function. The function
  11.691 - *	does not return until any executing interrupts for this IRQ
  11.692 - *	have completed.
  11.693 - *
  11.694 - *	This function must not be called from interrupt context.
  11.695 - */
  11.696 -
  11.697 -#ifdef XEN
  11.698 -void free_irq(unsigned int irq)
  11.699 -#else
  11.700 -void free_irq(unsigned int irq, void *dev_id)
  11.701 -#endif
  11.702 -{
  11.703 -	irq_desc_t *desc;
  11.704 -	struct irqaction **p;
  11.705 -	unsigned long flags;
  11.706 -
  11.707 -	if (irq >= NR_IRQS)
  11.708 -		return;
  11.709 -
  11.710 -	desc = irq_descp(irq);
  11.711 -	spin_lock_irqsave(&desc->lock,flags);
  11.712 -#ifdef XEN
  11.713 -	if (desc->action) {
  11.714 -		struct irqaction * action = desc->action;
  11.715 -		desc->action = NULL;
  11.716 -#else
  11.717 -	p = &desc->action;
  11.718 -	for (;;) {
  11.719 -		struct irqaction * action = *p;
  11.720 -		if (action) {
  11.721 -			struct irqaction **pp = p;
  11.722 -			p = &action->next;
  11.723 -			if (action->dev_id != dev_id)
  11.724 -				continue;
  11.725 -
  11.726 -			/* Found it - now remove it from the list of entries */
  11.727 -			*pp = action->next;
  11.728 -			if (!desc->action) {
  11.729 -#endif
  11.730 -				desc->status |= IRQ_DISABLED;
  11.731 -				desc->handler->shutdown(irq);
  11.732 -#ifndef XEN
  11.733 -			}
  11.734 -#endif
  11.735 -			spin_unlock_irqrestore(&desc->lock,flags);
  11.736 -
  11.737 -			/* Wait to make sure it's not being used on another CPU */
  11.738 -			synchronize_irq(irq);
  11.739 -			xfree(action);
  11.740 -			return;
  11.741 -		}
  11.742 -		printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
  11.743 -		spin_unlock_irqrestore(&desc->lock,flags);
  11.744 -#ifndef XEN
  11.745 -		return;
  11.746 -	}
  11.747 -#endif
  11.748 -}
  11.749 -
  11.750 -EXPORT_SYMBOL(free_irq);
  11.751 -
  11.752 -/*
  11.753 - * IRQ autodetection code..
  11.754 - *
  11.755 - * This depends on the fact that any interrupt that
  11.756 - * comes in on to an unassigned handler will get stuck
  11.757 - * with "IRQ_WAITING" cleared and the interrupt
  11.758 - * disabled.
  11.759 - */
  11.760 -
  11.761 -static DECLARE_MUTEX(probe_sem);
  11.762 -
  11.763 -/**
  11.764 - *	probe_irq_on	- begin an interrupt autodetect
  11.765 - *
  11.766 - *	Commence probing for an interrupt. The interrupts are scanned
  11.767 - *	and a mask of potential interrupt lines is returned.
  11.768 - *
  11.769 - */
  11.770 -
  11.771 -#ifndef XEN
  11.772 -unsigned long probe_irq_on(void)
  11.773 -{
  11.774 -	unsigned int i;
  11.775 -	irq_desc_t *desc;
  11.776 -	unsigned long val;
  11.777 -	unsigned long delay;
  11.778 -
  11.779 -	down(&probe_sem);
  11.780 -	/*
  11.781 -	 * something may have generated an irq long ago and we want to
  11.782 -	 * flush such a longstanding irq before considering it as spurious.
  11.783 -	 */
  11.784 -	for (i = NR_IRQS-1; i > 0; i--)  {
  11.785 -		desc = irq_descp(i);
  11.786 -
  11.787 -		spin_lock_irq(&desc->lock);
  11.788 -		if (!desc->action)
  11.789 -			desc->handler->startup(i);
  11.790 -		spin_unlock_irq(&desc->lock);
  11.791 -	}
  11.792 -
  11.793 -	/* Wait for longstanding interrupts to trigger. */
  11.794 -	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
  11.795 -		/* about 20ms delay */ barrier();
  11.796 -
  11.797 -	/*
  11.798 -	 * enable any unassigned irqs
  11.799 -	 * (we must startup again here because if a longstanding irq
  11.800 -	 * happened in the previous stage, it may have masked itself)
  11.801 -	 */
  11.802 -	for (i = NR_IRQS-1; i > 0; i--) {
  11.803 -		desc = irq_descp(i);
  11.804 -
  11.805 -		spin_lock_irq(&desc->lock);
  11.806 -		if (!desc->action) {
  11.807 -			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
  11.808 -			if (desc->handler->startup(i))
  11.809 -				desc->status |= IRQ_PENDING;
  11.810 -		}
  11.811 -		spin_unlock_irq(&desc->lock);
  11.812 -	}
  11.813 -
  11.814 -	/*
  11.815 -	 * Wait for spurious interrupts to trigger
  11.816 -	 */
  11.817 -	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
  11.818 -		/* about 100ms delay */ barrier();
  11.819 -
  11.820 -	/*
  11.821 -	 * Now filter out any obviously spurious interrupts
  11.822 -	 */
  11.823 -	val = 0;
  11.824 -	for (i = 0; i < NR_IRQS; i++) {
  11.825 -		irq_desc_t *desc = irq_descp(i);
  11.826 -		unsigned int status;
  11.827 -
  11.828 -		spin_lock_irq(&desc->lock);
  11.829 -		status = desc->status;
  11.830 -
  11.831 -		if (status & IRQ_AUTODETECT) {
  11.832 -			/* It triggered already - consider it spurious. */
  11.833 -			if (!(status & IRQ_WAITING)) {
  11.834 -				desc->status = status & ~IRQ_AUTODETECT;
  11.835 -				desc->handler->shutdown(i);
  11.836 -			} else
  11.837 -				if (i < 32)
  11.838 -					val |= 1 << i;
  11.839 -		}
  11.840 -		spin_unlock_irq(&desc->lock);
  11.841 -	}
  11.842 -
  11.843 -	return val;
  11.844 -}
  11.845 -
  11.846 -EXPORT_SYMBOL(probe_irq_on);
  11.847 -
  11.848 -/**
  11.849 - *	probe_irq_mask - scan a bitmap of interrupt lines
  11.850 - *	@val:	mask of interrupts to consider
  11.851 - *
  11.852 - *	Scan the ISA bus interrupt lines and return a bitmap of
  11.853 - *	active interrupts. The interrupt probe logic state is then
  11.854 - *	returned to its previous value.
  11.855 - *
  11.856 - *	Note: we need to scan all the irq's even though we will
  11.857 - *	only return ISA irq numbers - just so that we reset them
  11.858 - *	all to a known state.
  11.859 - */
  11.860 -unsigned int probe_irq_mask(unsigned long val)
  11.861 -{
  11.862 -	int i;
  11.863 -	unsigned int mask;
  11.864 -
  11.865 -	mask = 0;
  11.866 -	for (i = 0; i < 16; i++) {
  11.867 -		irq_desc_t *desc = irq_descp(i);
  11.868 -		unsigned int status;
  11.869 -
  11.870 -		spin_lock_irq(&desc->lock);
  11.871 -		status = desc->status;
  11.872 -
  11.873 -		if (status & IRQ_AUTODETECT) {
  11.874 -			if (!(status & IRQ_WAITING))
  11.875 -				mask |= 1 << i;
  11.876 -
  11.877 -			desc->status = status & ~IRQ_AUTODETECT;
  11.878 -			desc->handler->shutdown(i);
  11.879 -		}
  11.880 -		spin_unlock_irq(&desc->lock);
  11.881 -	}
  11.882 -	up(&probe_sem);
  11.883 -
  11.884 -	return mask & val;
  11.885 -}
  11.886 -EXPORT_SYMBOL(probe_irq_mask);
  11.887 -
  11.888 -/**
  11.889 - *	probe_irq_off	- end an interrupt autodetect
  11.890 - *	@val: mask of potential interrupts (unused)
  11.891 - *
  11.892 - *	Scans the unused interrupt lines and returns the line which
  11.893 - *	appears to have triggered the interrupt. If no interrupt was
  11.894 - *	found then zero is returned. If more than one interrupt is
  11.895 - *	found then minus the first candidate is returned to indicate
  11.896 - *	their is doubt.
  11.897 - *
  11.898 - *	The interrupt probe logic state is returned to its previous
  11.899 - *	value.
  11.900 - *
  11.901 - *	BUGS: When used in a module (which arguably shouldn't happen)
  11.902 - *	nothing prevents two IRQ probe callers from overlapping. The
  11.903 - *	results of this are non-optimal.
  11.904 - */
  11.905 -
  11.906 -int probe_irq_off(unsigned long val)
  11.907 -{
  11.908 -	int i, irq_found, nr_irqs;
  11.909 -
  11.910 -	nr_irqs = 0;
  11.911 -	irq_found = 0;
  11.912 -	for (i = 0; i < NR_IRQS; i++) {
  11.913 -		irq_desc_t *desc = irq_descp(i);
  11.914 -		unsigned int status;
  11.915 -
  11.916 -		spin_lock_irq(&desc->lock);
  11.917 -		status = desc->status;
  11.918 -
  11.919 -		if (status & IRQ_AUTODETECT) {
  11.920 -			if (!(status & IRQ_WAITING)) {
  11.921 -				if (!nr_irqs)
  11.922 -					irq_found = i;
  11.923 -				nr_irqs++;
  11.924 -			}
  11.925 -			desc->status = status & ~IRQ_AUTODETECT;
  11.926 -			desc->handler->shutdown(i);
  11.927 -		}
  11.928 -		spin_unlock_irq(&desc->lock);
  11.929 -	}
  11.930 -	up(&probe_sem);
  11.931 -
  11.932 -	if (nr_irqs > 1)
  11.933 -		irq_found = -irq_found;
  11.934 -	return irq_found;
  11.935 -}
  11.936 -
  11.937 -EXPORT_SYMBOL(probe_irq_off);
  11.938 -#endif
  11.939 -
  11.940 -int setup_irq(unsigned int irq, struct irqaction * new)
  11.941 -{
  11.942 -	int shared = 0;
  11.943 -	unsigned long flags;
  11.944 -	struct irqaction *old, **p;
  11.945 -	irq_desc_t *desc = irq_descp(irq);
  11.946 -
  11.947 -#ifndef XEN
  11.948 -	if (desc->handler == &no_irq_type)
  11.949 -		return -ENOSYS;
  11.950 -	/*
  11.951 -	 * Some drivers like serial.c use request_irq() heavily,
  11.952 -	 * so we have to be careful not to interfere with a
  11.953 -	 * running system.
  11.954 -	 */
  11.955 -	if (new->flags & SA_SAMPLE_RANDOM) {
  11.956 -		/*
  11.957 -		 * This function might sleep, we want to call it first,
  11.958 -		 * outside of the atomic block.
  11.959 -		 * Yes, this might clear the entropy pool if the wrong
  11.960 -		 * driver is attempted to be loaded, without actually
  11.961 -		 * installing a new handler, but is this really a problem,
  11.962 -		 * only the sysadmin is able to do this.
  11.963 -		 */
  11.964 -		rand_initialize_irq(irq);
  11.965 -	}
  11.966 -
  11.967 -	if (new->flags & SA_PERCPU_IRQ) {
  11.968 -		desc->status |= IRQ_PER_CPU;
  11.969 -		desc->handler = &irq_type_ia64_lsapic;
  11.970 -	}
  11.971 -#endif
  11.972 -
  11.973 -	/*
  11.974 -	 * The following block of code has to be executed atomically
  11.975 -	 */
  11.976 -	spin_lock_irqsave(&desc->lock,flags);
  11.977 -	p = &desc->action;
  11.978 -	if ((old = *p) != NULL) {
  11.979 -#ifdef XEN
  11.980 -		if (1) {
  11.981 -		/* Can't share interrupts unless both agree to */
  11.982 -#else
  11.983 -		if (!(old->flags & new->flags & SA_SHIRQ)) {
  11.984 -#endif
  11.985 -			spin_unlock_irqrestore(&desc->lock,flags);
  11.986 -			return -EBUSY;
  11.987 -		}
  11.988 -
  11.989 -#ifndef XEN
  11.990 -		/* add new interrupt at end of irq queue */
  11.991 -		do {
  11.992 -			p = &old->next;
  11.993 -			old = *p;
  11.994 -		} while (old);
  11.995 -		shared = 1;
  11.996 -#endif
  11.997 -	}
  11.998 -
  11.999 -	*p = new;
 11.1000 -
 11.1001 -#ifndef XEN
 11.1002 -	if (!shared) {
 11.1003 -#else
 11.1004 -	{
 11.1005 -#endif
 11.1006 -		desc->depth = 0;
 11.1007 -#ifdef XEN
 11.1008 -		desc->status &= ~(IRQ_DISABLED | IRQ_INPROGRESS);
 11.1009 -#else
 11.1010 -		desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
 11.1011 -#endif
 11.1012 -		desc->handler->startup(irq);
 11.1013 -	}
 11.1014 -	spin_unlock_irqrestore(&desc->lock,flags);
 11.1015 -
 11.1016 -#ifndef XEN
 11.1017 -	register_irq_proc(irq);
 11.1018 -#endif
 11.1019 -	return 0;
 11.1020 -}
 11.1021 -
 11.1022 -#ifndef XEN
 11.1023 -
 11.1024 -static struct proc_dir_entry * root_irq_dir;
 11.1025 -static struct proc_dir_entry * irq_dir [NR_IRQS];
 11.1026 -
 11.1027 -#ifdef CONFIG_SMP
 11.1028 -
 11.1029 -static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
 11.1030 -
 11.1031 -static cpumask_t irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
 11.1032 -
 11.1033 -static char irq_redir [NR_IRQS]; // = { [0 ... NR_IRQS-1] = 1 };
 11.1034 -
 11.1035 -void set_irq_affinity_info (unsigned int irq, int hwid, int redir)
 11.1036 -{
 11.1037 -	cpumask_t mask = CPU_MASK_NONE;
 11.1038 -
 11.1039 -	cpu_set(cpu_logical_id(hwid), mask);
 11.1040 -
 11.1041 -	if (irq < NR_IRQS) {
 11.1042 -		irq_affinity[irq] = mask;
 11.1043 -		irq_redir[irq] = (char) (redir & 0xff);
 11.1044 -	}
 11.1045 -}
 11.1046 -
 11.1047 -static int irq_affinity_read_proc (char *page, char **start, off_t off,
 11.1048 -			int count, int *eof, void *data)
 11.1049 -{
 11.1050 -	int len = sprintf(page, "%s", irq_redir[(long)data] ? "r " : "");
 11.1051 -
 11.1052 -	len += cpumask_scnprintf(page+len, count, irq_affinity[(long)data]);
 11.1053 -	if (count - len < 2)
 11.1054 -		return -EINVAL;
 11.1055 -	len += sprintf(page + len, "\n");
 11.1056 -	return len;
 11.1057 -}
 11.1058 -
 11.1059 -static int irq_affinity_write_proc (struct file *file, const char *buffer,
 11.1060 -				    unsigned long count, void *data)
 11.1061 -{
 11.1062 -	unsigned int irq = (unsigned long) data;
 11.1063 -	int full_count = count, err;
 11.1064 -	cpumask_t new_value, tmp;
 11.1065 -#	define R_PREFIX_LEN 16
 11.1066 -	char rbuf[R_PREFIX_LEN];
 11.1067 -	int rlen;
 11.1068 -	int prelen;
 11.1069 -	irq_desc_t *desc = irq_descp(irq);
 11.1070 -	unsigned long flags;
 11.1071 -
 11.1072 -	if (!desc->handler->set_affinity)
 11.1073 -		return -EIO;
 11.1074 -
 11.1075 -	/*
 11.1076 -	 * If string being written starts with a prefix of 'r' or 'R'
 11.1077 -	 * and some limited number of spaces, set IA64_IRQ_REDIRECTED.
 11.1078 -	 * If more than (R_PREFIX_LEN - 2) spaces are passed, they won't
 11.1079 -	 * all be trimmed as part of prelen, the untrimmed spaces will
 11.1080 -	 * cause the hex parsing to fail, and this write() syscall will
 11.1081 -	 * fail with EINVAL.
 11.1082 -	 */
 11.1083 -
 11.1084 -	if (!count)
 11.1085 -		return -EINVAL;
 11.1086 -	rlen = min(sizeof(rbuf)-1, count);
 11.1087 -	if (copy_from_user(rbuf, buffer, rlen))
 11.1088 -		return -EFAULT;
 11.1089 -	rbuf[rlen] = 0;
 11.1090 -	prelen = 0;
 11.1091 -	if (tolower(*rbuf) == 'r') {
 11.1092 -		prelen = strspn(rbuf, "Rr ");
 11.1093 -		irq |= IA64_IRQ_REDIRECTED;
 11.1094 -	}
 11.1095 -
 11.1096 -	err = cpumask_parse(buffer+prelen, count-prelen, new_value);
 11.1097 -	if (err)
 11.1098 -		return err;
 11.1099 -
 11.1100 -	/*
 11.1101 -	 * Do not allow disabling IRQs completely - it's a too easy
 11.1102 -	 * way to make the system unusable accidentally :-) At least
 11.1103 -	 * one online CPU still has to be targeted.
 11.1104 -	 */
 11.1105 -	cpus_and(tmp, new_value, cpu_online_map);
 11.1106 -	if (cpus_empty(tmp))
 11.1107 -		return -EINVAL;
 11.1108 -
 11.1109 -	spin_lock_irqsave(&desc->lock, flags);
 11.1110 -	pending_irq_cpumask[irq] = new_value;
 11.1111 -	spin_unlock_irqrestore(&desc->lock, flags);
 11.1112 -
 11.1113 -	return full_count;
 11.1114 -}
 11.1115 -
 11.1116 -void move_irq(int irq)
 11.1117 -{
 11.1118 -	/* note - we hold desc->lock */
 11.1119 -	cpumask_t tmp;
 11.1120 -	irq_desc_t *desc = irq_descp(irq);
 11.1121 -
 11.1122 -	if (!cpus_empty(pending_irq_cpumask[irq])) {
 11.1123 -		cpus_and(tmp, pending_irq_cpumask[irq], cpu_online_map);
 11.1124 -		if (unlikely(!cpus_empty(tmp))) {
 11.1125 -			desc->handler->set_affinity(irq, pending_irq_cpumask[irq]);
 11.1126 -		}
 11.1127 -		cpus_clear(pending_irq_cpumask[irq]);
 11.1128 -	}
 11.1129 -}
 11.1130 -
 11.1131 -
 11.1132 -#endif /* CONFIG_SMP */
 11.1133 -#endif
 11.1134 -
 11.1135 -#ifdef CONFIG_HOTPLUG_CPU
 11.1136 -unsigned int vectors_in_migration[NR_IRQS];
 11.1137 -
 11.1138 -/*
 11.1139 - * Since cpu_online_map is already updated, we just need to check for
 11.1140 - * affinity that has zeros
 11.1141 - */
 11.1142 -static void migrate_irqs(void)
 11.1143 -{
 11.1144 -	cpumask_t	mask;
 11.1145 -	irq_desc_t *desc;
 11.1146 -	int 		irq, new_cpu;
 11.1147 -
 11.1148 -	for (irq=0; irq < NR_IRQS; irq++) {
 11.1149 -		desc = irq_descp(irq);
 11.1150 -
 11.1151 -		/*
 11.1152 -		 * No handling for now.
 11.1153 -		 * TBD: Implement a disable function so we can now
 11.1154 -		 * tell CPU not to respond to these local intr sources.
 11.1155 -		 * such as ITV,CPEI,MCA etc.
 11.1156 -		 */
 11.1157 -		if (desc->status == IRQ_PER_CPU)
 11.1158 -			continue;
 11.1159 -
 11.1160 -		cpus_and(mask, irq_affinity[irq], cpu_online_map);
 11.1161 -		if (any_online_cpu(mask) == NR_CPUS) {
 11.1162 -			/*
 11.1163 -			 * Save it for phase 2 processing
 11.1164 -			 */
 11.1165 -			vectors_in_migration[irq] = irq;
 11.1166 -
 11.1167 -			new_cpu = any_online_cpu(cpu_online_map);
 11.1168 -			mask = cpumask_of_cpu(new_cpu);
 11.1169 -
 11.1170 -			/*
 11.1171 -			 * Al three are essential, currently WARN_ON.. maybe panic?
 11.1172 -			 */
 11.1173 -			if (desc->handler && desc->handler->disable &&
 11.1174 -				desc->handler->enable && desc->handler->set_affinity) {
 11.1175 -				desc->handler->disable(irq);
 11.1176 -				desc->handler->set_affinity(irq, mask);
 11.1177 -				desc->handler->enable(irq);
 11.1178 -			} else {
 11.1179 -				WARN_ON((!(desc->handler) || !(desc->handler->disable) ||
 11.1180 -						!(desc->handler->enable) ||
 11.1181 -						!(desc->handler->set_affinity)));
 11.1182 -			}
 11.1183 -		}
 11.1184 -	}
 11.1185 -}
 11.1186 -
 11.1187 -void fixup_irqs(void)
 11.1188 -{
 11.1189 -	unsigned int irq;
 11.1190 -	extern void ia64_process_pending_intr(void);
 11.1191 -
 11.1192 -	ia64_set_itv(1<<16);
 11.1193 -	/*
 11.1194 -	 * Phase 1: Locate irq's bound to this cpu and
 11.1195 -	 * relocate them for cpu removal.
 11.1196 -	 */
 11.1197 -	migrate_irqs();
 11.1198 -
 11.1199 -	/*
 11.1200 -	 * Phase 2: Perform interrupt processing for all entries reported in
 11.1201 -	 * local APIC.
 11.1202 -	 */
 11.1203 -	ia64_process_pending_intr();
 11.1204 -
 11.1205 -	/*
 11.1206 -	 * Phase 3: Now handle any interrupts not captured in local APIC.
 11.1207 -	 * This is to account for cases that device interrupted during the time the
 11.1208 -	 * rte was being disabled and re-programmed.
 11.1209 -	 */
 11.1210 -	for (irq=0; irq < NR_IRQS; irq++) {
 11.1211 -		if (vectors_in_migration[irq]) {
 11.1212 -			vectors_in_migration[irq]=0;
 11.1213 -			do_IRQ(irq, NULL);
 11.1214 -		}
 11.1215 -	}
 11.1216 -
 11.1217 -	/*
 11.1218 -	 * Now let processor die. We do irq disable and max_xtp() to
 11.1219 -	 * ensure there is no more interrupts routed to this processor.
 11.1220 -	 * But the local timer interrupt can have 1 pending which we
 11.1221 -	 * take care in timer_interrupt().
 11.1222 -	 */
 11.1223 -	max_xtp();
 11.1224 -	local_irq_disable();
 11.1225 -}
 11.1226 -#endif
 11.1227 -
 11.1228 -#ifndef XEN
 11.1229 -static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
 11.1230 -			int count, int *eof, void *data)
 11.1231 -{
 11.1232 -	int len = cpumask_scnprintf(page, count, *(cpumask_t *)data);
 11.1233 -	if (count - len < 2)
 11.1234 -		return -EINVAL;
 11.1235 -	len += sprintf(page + len, "\n");
 11.1236 -	return len;
 11.1237 -}
 11.1238 -
 11.1239 -static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
 11.1240 -					unsigned long count, void *data)
 11.1241 -{
 11.1242 -	cpumask_t *mask = (cpumask_t *)data;
 11.1243 -	unsigned long full_count = count, err;
 11.1244 -	cpumask_t new_value;
 11.1245 -
 11.1246 -	err = cpumask_parse(buffer, count, new_value);
 11.1247 -	if (err)
 11.1248 -		return err;
 11.1249 -
 11.1250 -	*mask = new_value;
 11.1251 -	return full_count;
 11.1252 -}
 11.1253 -
 11.1254 -#define MAX_NAMELEN 10
 11.1255 -
 11.1256 -static void register_irq_proc (unsigned int irq)
 11.1257 -{
 11.1258 -	char name [MAX_NAMELEN];
 11.1259 -
 11.1260 -	if (!root_irq_dir || (irq_descp(irq)->handler == &no_irq_type) || irq_dir[irq])
 11.1261 -		return;
 11.1262 -
 11.1263 -	memset(name, 0, MAX_NAMELEN);
 11.1264 -	sprintf(name, "%d", irq);
 11.1265 -
 11.1266 -	/* create /proc/irq/1234 */
 11.1267 -	irq_dir[irq] = proc_mkdir(name, root_irq_dir);
 11.1268 -
 11.1269 -#ifdef CONFIG_SMP
 11.1270 -	{
 11.1271 -		struct proc_dir_entry *entry;
 11.1272 -
 11.1273 -		/* create /proc/irq/1234/smp_affinity */
 11.1274 -		entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
 11.1275 -
 11.1276 -		if (entry) {
 11.1277 -			entry->nlink = 1;
 11.1278 -			entry->data = (void *)(long)irq;
 11.1279 -			entry->read_proc = irq_affinity_read_proc;
 11.1280 -			entry->write_proc = irq_affinity_write_proc;
 11.1281 -		}
 11.1282 -
 11.1283 -		smp_affinity_entry[irq] = entry;
 11.1284 -	}
 11.1285 -#endif
 11.1286 -}
 11.1287 -
 11.1288 -cpumask_t prof_cpu_mask = CPU_MASK_ALL;
 11.1289 -
 11.1290 -void init_irq_proc (void)
 11.1291 -{
 11.1292 -	struct proc_dir_entry *entry;
 11.1293 -	int i;
 11.1294 -
 11.1295 -	/* create /proc/irq */
 11.1296 -	root_irq_dir = proc_mkdir("irq", 0);
 11.1297 -
 11.1298 -	/* create /proc/irq/prof_cpu_mask */
 11.1299 -	entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
 11.1300 -
 11.1301 -	if (!entry)
 11.1302 -		return;
 11.1303 -
 11.1304 -	entry->nlink = 1;
 11.1305 -	entry->data = (void *)&prof_cpu_mask;
 11.1306 -	entry->read_proc = prof_cpu_mask_read_proc;
 11.1307 -	entry->write_proc = prof_cpu_mask_write_proc;
 11.1308 -
 11.1309 -	/*
 11.1310 -	 * Create entries for all existing IRQs.
 11.1311 -	 */
 11.1312 -	for (i = 0; i < NR_IRQS; i++) {
 11.1313 -		if (irq_descp(i)->handler == &no_irq_type)
 11.1314 -			continue;
 11.1315 -		register_irq_proc(i);
 11.1316 -	}
 11.1317 -}
 11.1318 -#endif
 11.1319 -
 11.1320 -
 11.1321 -#ifdef XEN
 11.1322 -/*
 11.1323 - * HANDLING OF GUEST-BOUND PHYSICAL IRQS
 11.1324 - */
 11.1325 -
 11.1326 -#define IRQ_MAX_GUESTS 7
 11.1327 -typedef struct {
 11.1328 -    u8 nr_guests;
 11.1329 -    u8 in_flight;
 11.1330 -    u8 shareable;
 11.1331 -    struct domain *guest[IRQ_MAX_GUESTS];
 11.1332 -} irq_guest_action_t;
 11.1333 -
 11.1334 -static void __do_IRQ_guest(int irq)
 11.1335 -{
 11.1336 -    irq_desc_t         *desc = &irq_desc[irq];
 11.1337 -    irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
 11.1338 -    struct domain      *d;
 11.1339 -    int                 i;
 11.1340 -
 11.1341 -    for ( i = 0; i < action->nr_guests; i++ )
 11.1342 -    {
 11.1343 -        d = action->guest[i];
 11.1344 -        if ( !test_and_set_bit(irq, &d->pirq_mask) )
 11.1345 -            action->in_flight++;
 11.1346 -        send_guest_pirq(d, irq);
 11.1347 -    }
 11.1348 -}
 11.1349 -
 11.1350 -int pirq_guest_unmask(struct domain *d)
 11.1351 -{
 11.1352 -    irq_desc_t    *desc;
 11.1353 -    int            i, j, pirq;
 11.1354 -    u32            m;
 11.1355 -    shared_info_t *s = d->shared_info;
 11.1356 -
 11.1357 -    for ( i = 0; i < ARRAY_SIZE(d->pirq_mask); i++ )
 11.1358 -    {
 11.1359 -        m = d->pirq_mask[i];
 11.1360 -        while ( (j = ffs(m)) != 0 )
 11.1361 -        {
 11.1362 -            m &= ~(1 << --j);
 11.1363 -            pirq = (i << 5) + j;
 11.1364 -            desc = &irq_desc[pirq];
 11.1365 -            spin_lock_irq(&desc->lock);
 11.1366 -            if ( !test_bit(d->pirq_to_evtchn[pirq], &s->evtchn_mask[0]) &&
 11.1367 -                 test_and_clear_bit(pirq, &d->pirq_mask) &&
 11.1368 -                 (--((irq_guest_action_t *)desc->action)->in_flight == 0) )
 11.1369 -                desc->handler->end(pirq);
 11.1370 -            spin_unlock_irq(&desc->lock);
 11.1371 -        }
 11.1372 -    }
 11.1373 -
 11.1374 -    return 0;
 11.1375 -}
 11.1376 -
 11.1377 -int pirq_guest_bind(struct vcpu *d, int irq, int will_share)
 11.1378 -{
 11.1379 -    irq_desc_t         *desc = &irq_desc[irq];
 11.1380 -    irq_guest_action_t *action;
 11.1381 -    unsigned long       flags;
 11.1382 -    int                 rc = 0;
 11.1383 -
 11.1384 -    if ( !IS_CAPABLE_PHYSDEV(d->domain) )
 11.1385 -        return -EPERM;
 11.1386 -
 11.1387 -    spin_lock_irqsave(&desc->lock, flags);
 11.1388 -
 11.1389 -    action = (irq_guest_action_t *)desc->action;
 11.1390 -
 11.1391 -    if ( !(desc->status & IRQ_GUEST) )
 11.1392 -    {
 11.1393 -        if ( desc->action != NULL )
 11.1394 -        {
 11.1395 -            DPRINTK("Cannot bind IRQ %d to guest. In use by '%s'.\n",
 11.1396 -                    irq, desc->action->name);
 11.1397 -            rc = -EBUSY;
 11.1398 -            goto out;
 11.1399 -        }
 11.1400 -
 11.1401 -        action = xmalloc(irq_guest_action_t);
 11.1402 -        if ( (desc->action = (struct irqaction *)action) == NULL )
 11.1403 -        {
 11.1404 -            DPRINTK("Cannot bind IRQ %d to guest. Out of memory.\n", irq);
 11.1405 -            rc = -ENOMEM;
 11.1406 -            goto out;
 11.1407 -        }
 11.1408 -
 11.1409 -        action->nr_guests = 0;
 11.1410 -        action->in_flight = 0;
 11.1411 -        action->shareable = will_share;
 11.1412 -        
 11.1413 -        desc->depth = 0;
 11.1414 -        desc->status |= IRQ_GUEST;
 11.1415 -        desc->status &= ~IRQ_DISABLED;
 11.1416 -        desc->handler->startup(irq);
 11.1417 -
 11.1418 -        /* Attempt to bind the interrupt target to the correct CPU. */
 11.1419 -#if 0 /* FIXME CONFIG_SMP ??? */
 11.1420 -        if ( desc->handler->set_affinity != NULL )
 11.1421 -            desc->handler->set_affinity(
 11.1422 -                irq, apicid_to_phys_cpu_present(d->processor));
 11.1423 -#endif
 11.1424 -    }
 11.1425 -    else if ( !will_share || !action->shareable )
 11.1426 -    {
 11.1427 -        DPRINTK("Cannot bind IRQ %d to guest. Will not share with others.\n",
 11.1428 -                irq);
 11.1429 -        rc = -EBUSY;
 11.1430 -        goto out;
 11.1431 -    }
 11.1432 -
 11.1433 -    if ( action->nr_guests == IRQ_MAX_GUESTS )
 11.1434 -    {
 11.1435 -        DPRINTK("Cannot bind IRQ %d to guest. Already at max share.\n", irq);
 11.1436 -        rc = -EBUSY;
 11.1437 -        goto out;
 11.1438 -    }
 11.1439 -
 11.1440 -    action->guest[action->nr_guests++] = d;
 11.1441 -
 11.1442 - out:
 11.1443 -    spin_unlock_irqrestore(&desc->lock, flags);
 11.1444 -    return rc;
 11.1445 -}
 11.1446 -
 11.1447 -int pirq_guest_unbind(struct domain *d, int irq)
 11.1448 -{
 11.1449 -    irq_desc_t         *desc = &irq_desc[irq];
 11.1450 -    irq_guest_action_t *action;
 11.1451 -    unsigned long       flags;
 11.1452 -    int                 i;
 11.1453 -
 11.1454 -    spin_lock_irqsave(&desc->lock, flags);
 11.1455 -
 11.1456 -    action = (irq_guest_action_t *)desc->action;
 11.1457 -
 11.1458 -    if ( test_and_clear_bit(irq, &d->pirq_mask) &&
 11.1459 -         (--action->in_flight == 0) )
 11.1460 -        desc->handler->end(irq);
 11.1461 -
 11.1462 -    if ( action->nr_guests == 1 )
 11.1463 -    {
 11.1464 -        desc->action = NULL;
 11.1465 -        xfree(action);
 11.1466 -        desc->depth   = 1;
 11.1467 -        desc->status |= IRQ_DISABLED;
 11.1468 -        desc->status &= ~IRQ_GUEST;
 11.1469 -        desc->handler->shutdown(irq);
 11.1470 -    }
 11.1471 -    else
 11.1472 -    {
 11.1473 -        i = 0;
 11.1474 -        while ( action->guest[i] != d )
 11.1475 -            i++;
 11.1476 -        memmove(&action->guest[i], &action->guest[i+1], IRQ_MAX_GUESTS-i-1);
 11.1477 -        action->nr_guests--;
 11.1478 -    }
 11.1479 -
 11.1480 -    spin_unlock_irqrestore(&desc->lock, flags);    
 11.1481 -    return 0;
 11.1482 -}
 11.1483 -
 11.1484 -#endif
 11.1485 -
 11.1486 -#ifdef XEN
 11.1487 -#ifdef IA64
 11.1488 -// this is a temporary hack until real console input is implemented
 11.1489 -irqreturn_t guest_forward_keyboard_input(int irq, void *nada, struct pt_regs *regs)
 11.1490 -{
 11.1491 -	domain_pend_keyboard_interrupt(irq);
 11.1492 -}
 11.1493 -
 11.1494 -void serial_input_init(void)
 11.1495 -{
 11.1496 -	int retval;
 11.1497 -	int irq = 0x30;	// FIXME
 11.1498 -
 11.1499 -	retval = request_irq(irq,guest_forward_keyboard_input,SA_INTERRUPT,"siminput",NULL);
 11.1500 -	if (retval) {
 11.1501 -		printk("serial_input_init: broken request_irq call\n");
 11.1502 -		while(1);
 11.1503 -	}
 11.1504 -}
 11.1505 -#endif
 11.1506 -#endif
    12.1 --- a/xen/arch/ia64/ivt.S	Thu Sep 01 11:09:27 2005 -0600
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,1975 +0,0 @@
    12.4 -
    12.5 -#ifdef XEN
    12.6 -//#define CONFIG_DISABLE_VHPT	// FIXME: change when VHPT is enabled??
    12.7 -// these are all hacked out for now as the entire IVT
    12.8 -// will eventually be replaced... just want to use it
    12.9 -// for startup code to handle TLB misses
   12.10 -//#define ia64_leave_kernel 0
   12.11 -//#define ia64_ret_from_syscall 0
   12.12 -//#define ia64_handle_irq 0
   12.13 -//#define ia64_fault 0
   12.14 -#define ia64_illegal_op_fault 0
   12.15 -#define ia64_prepare_handle_unaligned 0
   12.16 -#define ia64_bad_break 0
   12.17 -#define ia64_trace_syscall 0
   12.18 -#define sys_call_table 0
   12.19 -#define sys_ni_syscall 0
   12.20 -#include <asm/vhpt.h>
   12.21 -#endif
   12.22 -/*
   12.23 - * arch/ia64/kernel/ivt.S
   12.24 - *
   12.25 - * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
   12.26 - *	Stephane Eranian <eranian@hpl.hp.com>
   12.27 - *	David Mosberger <davidm@hpl.hp.com>
   12.28 - * Copyright (C) 2000, 2002-2003 Intel Co
   12.29 - *	Asit Mallick <asit.k.mallick@intel.com>
   12.30 - *      Suresh Siddha <suresh.b.siddha@intel.com>
   12.31 - *      Kenneth Chen <kenneth.w.chen@intel.com>
   12.32 - *      Fenghua Yu <fenghua.yu@intel.com>
   12.33 - *
   12.34 - * 00/08/23 Asit Mallick <asit.k.mallick@intel.com> TLB handling for SMP
   12.35 - * 00/12/20 David Mosberger-Tang <davidm@hpl.hp.com> DTLB/ITLB handler now uses virtual PT.
   12.36 - */
   12.37 -/*
   12.38 - * This file defines the interruption vector table used by the CPU.
   12.39 - * It does not include one entry per possible cause of interruption.
   12.40 - *
   12.41 - * The first 20 entries of the table contain 64 bundles each while the
   12.42 - * remaining 48 entries contain only 16 bundles each.
   12.43 - *
   12.44 - * The 64 bundles are used to allow inlining the whole handler for critical
   12.45 - * interruptions like TLB misses.
   12.46 - *
   12.47 - *  For each entry, the comment is as follows:
   12.48 - *
   12.49 - *		// 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
   12.50 - *  entry offset ----/     /         /                  /          /
   12.51 - *  entry number ---------/         /                  /          /
   12.52 - *  size of the entry -------------/                  /          /
   12.53 - *  vector name -------------------------------------/          /
   12.54 - *  interruptions triggering this vector ----------------------/
   12.55 - *
   12.56 - * The table is 32KB in size and must be aligned on 32KB boundary.
   12.57 - * (The CPU ignores the 15 lower bits of the address)
   12.58 - *
   12.59 - * Table is based upon EAS2.6 (Oct 1999)
   12.60 - */
   12.61 -
   12.62 -#include <linux/config.h>
   12.63 -
   12.64 -#include <asm/asmmacro.h>
   12.65 -#include <asm/break.h>
   12.66 -#include <asm/ia32.h>
   12.67 -#include <asm/kregs.h>
   12.68 -#include <asm/offsets.h>
   12.69 -#include <asm/pgtable.h>
   12.70 -#include <asm/processor.h>
   12.71 -#include <asm/ptrace.h>
   12.72 -#include <asm/system.h>
   12.73 -#include <asm/thread_info.h>
   12.74 -#include <asm/unistd.h>
   12.75 -#include <asm/errno.h>
   12.76 -
   12.77 -#if 1
   12.78 -# define PSR_DEFAULT_BITS	psr.ac
   12.79 -#else
   12.80 -# define PSR_DEFAULT_BITS	0
   12.81 -#endif
   12.82 -
   12.83 -#if 0
   12.84 -  /*
   12.85 -   * This lets you track the last eight faults that occurred on the CPU.  Make sure ar.k2 isn't
   12.86 -   * needed for something else before enabling this...
   12.87 -   */
   12.88 -# define DBG_FAULT(i)	mov r16=ar.k2;;	shl r16=r16,8;;	add r16=(i),r16;;mov ar.k2=r16
   12.89 -#else
   12.90 -# define DBG_FAULT(i)
   12.91 -#endif
   12.92 -
   12.93 -#define MINSTATE_VIRT	/* needed by minstate.h */
   12.94 -#include "minstate.h"
   12.95 -
   12.96 -#define FAULT(n)									\
   12.97 -	mov r31=pr;									\
   12.98 -	mov r19=n;;			/* prepare to save predicates */		\
   12.99 -	br.sptk.many dispatch_to_fault_handler
  12.100 -
  12.101 -#ifdef XEN
  12.102 -#define REFLECT(n)									\
  12.103 -	mov r31=pr;									\
  12.104 -	mov r19=n;;			/* prepare to save predicates */		\
  12.105 -	br.sptk.many dispatch_reflection
  12.106 -#endif
  12.107 -
  12.108 -	.section .text.ivt,"ax"
  12.109 -
  12.110 -	.align 32768	// align on 32KB boundary
  12.111 -	.global ia64_ivt
  12.112 -ia64_ivt:
  12.113 -/////////////////////////////////////////////////////////////////////////////////////////
  12.114 -// 0x0000 Entry 0 (size 64 bundles) VHPT Translation (8,20,47)
  12.115 -ENTRY(vhpt_miss)
  12.116 -	DBG_FAULT(0)
  12.117 -	/*
  12.118 -	 * The VHPT vector is invoked when the TLB entry for the virtual page table
  12.119 -	 * is missing.  This happens only as a result of a previous
  12.120 -	 * (the "original") TLB miss, which may either be caused by an instruction
  12.121 -	 * fetch or a data access (or non-access).
  12.122 -	 *
  12.123 -	 * What we do here is normal TLB miss handing for the _original_ miss, followed
  12.124 -	 * by inserting the TLB entry for the virtual page table page that the VHPT
  12.125 -	 * walker was attempting to access.  The latter gets inserted as long
  12.126 -	 * as both L1 and L2 have valid mappings for the faulting address.
  12.127 -	 * The TLB entry for the original miss gets inserted only if
  12.128 -	 * the L3 entry indicates that the page is present.
  12.129 -	 *
  12.130 -	 * do_page_fault gets invoked in the following cases:
  12.131 -	 *	- the faulting virtual address uses unimplemented address bits
  12.132 -	 *	- the faulting virtual address has no L1, L2, or L3 mapping
  12.133 -	 */
  12.134 -	mov r16=cr.ifa				// get address that caused the TLB miss
  12.135 -#ifdef CONFIG_HUGETLB_PAGE
  12.136 -	movl r18=PAGE_SHIFT
  12.137 -	mov r25=cr.itir
  12.138 -#endif
  12.139 -	;;
  12.140 -	rsm psr.dt				// use physical addressing for data
  12.141 -	mov r31=pr				// save the predicate registers
  12.142 -#ifdef XEN
  12.143 -	movl r19=THIS_CPU(cpu_kr)+IA64_KR_PT_BASE_OFFSET;;
  12.144 -#else
  12.145 -	mov r19=IA64_KR(PT_BASE)		// get page table base address
  12.146 -#endif
  12.147 -	shl r21=r16,3				// shift bit 60 into sign bit
  12.148 -	shr.u r17=r16,61			// get the region number into r17
  12.149 -	;;
  12.150 -	shr r22=r21,3
  12.151 -#ifdef CONFIG_HUGETLB_PAGE
  12.152 -	extr.u r26=r25,2,6
  12.153 -	;;
  12.154 -	cmp.ne p8,p0=r18,r26
  12.155 -	sub r27=r26,r18
  12.156 -	;;
  12.157 -(p8)	dep r25=r18,r25,2,6
  12.158 -(p8)	shr r22=r22,r27
  12.159 -#endif
  12.160 -	;;
  12.161 -	cmp.eq p6,p7=5,r17			// is IFA pointing into to region 5?
  12.162 -	shr.u r18=r22,PGDIR_SHIFT		// get bits 33-63 of the faulting address
  12.163 -	;;
  12.164 -(p7)	dep r17=r17,r19,(PAGE_SHIFT-3),3	// put region number bits in place
  12.165 -
  12.166 -	srlz.d
  12.167 -	LOAD_PHYSICAL(p6, r19, swapper_pg_dir)	// region 5 is rooted at swapper_pg_dir
  12.168 -
  12.169 -	.pred.rel "mutex", p6, p7
  12.170 -(p6)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
  12.171 -(p7)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
  12.172 -	;;
  12.173 -(p6)	dep r17=r18,r19,3,(PAGE_SHIFT-3)	// r17=PTA + IFA(33,42)*8
  12.174 -(p7)	dep r17=r18,r17,3,(PAGE_SHIFT-6)	// r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8)
  12.175 -	cmp.eq p7,p6=0,r21			// unused address bits all zeroes?
  12.176 -	shr.u r18=r22,PMD_SHIFT			// shift L2 index into position
  12.177 -	;;
  12.178 -	ld8 r17=[r17]				// fetch the L1 entry (may be 0)
  12.179 -	;;
  12.180 -(p7)	cmp.eq p6,p7=r17,r0			// was L1 entry NULL?
  12.181 -	dep r17=r18,r17,3,(PAGE_SHIFT-3)	// compute address of L2 page table entry
  12.182 -	;;
  12.183 -(p7)	ld8 r20=[r17]				// fetch the L2 entry (may be 0)
  12.184 -	shr.u r19=r22,PAGE_SHIFT		// shift L3 index into position
  12.185 -	;;
  12.186 -(p7)	cmp.eq.or.andcm p6,p7=r20,r0		// was L2 entry NULL?
  12.187 -	dep r21=r19,r20,3,(PAGE_SHIFT-3)	// compute address of L3 page table entry
  12.188 -	;;
  12.189 -(p7)	ld8 r18=[r21]				// read the L3 PTE
  12.190 -	mov r19=cr.isr				// cr.isr bit 0 tells us if this is an insn miss
  12.191 -	;;
  12.192 -(p7)	tbit.z p6,p7=r18,_PAGE_P_BIT		// page present bit cleared?
  12.193 -	mov r22=cr.iha				// get the VHPT address that caused the TLB miss
  12.194 -	;;					// avoid RAW on p7
  12.195 -(p7)	tbit.nz.unc p10,p11=r19,32		// is it an instruction TLB miss?
  12.196 -	dep r23=0,r20,0,PAGE_SHIFT		// clear low bits to get page address
  12.197 -	;;
  12.198 -(p10)	itc.i r18				// insert the instruction TLB entry
  12.199 -(p11)	itc.d r18				// insert the data TLB entry
  12.200 -(p6)	br.cond.spnt.many page_fault		// handle bad address/page not present (page fault)
  12.201 -	mov cr.ifa=r22
  12.202 -
  12.203 -#ifdef CONFIG_HUGETLB_PAGE
  12.204 -(p8)	mov cr.itir=r25				// change to default page-size for VHPT
  12.205 -#endif
  12.206 -
  12.207 -	/*
  12.208 -	 * Now compute and insert the TLB entry for the virtual page table.  We never
  12.209 -	 * execute in a page table page so there is no need to set the exception deferral
  12.210 -	 * bit.
  12.211 -	 */
  12.212 -	adds r24=__DIRTY_BITS_NO_ED|_PAGE_PL_0|_PAGE_AR_RW,r23
  12.213 -	;;
  12.214 -(p7)	itc.d r24
  12.215 -	;;
  12.216 -#ifdef CONFIG_SMP
  12.217 -	/*
  12.218 -	 * Tell the assemblers dependency-violation checker that the above "itc" instructions
  12.219 -	 * cannot possibly affect the following loads:
  12.220 -	 */
  12.221 -	dv_serialize_data
  12.222 -
  12.223 -	/*
  12.224 -	 * Re-check L2 and L3 pagetable.  If they changed, we may have received a ptc.g
  12.225 -	 * between reading the pagetable and the "itc".  If so, flush the entry we
  12.226 -	 * inserted and retry.
  12.227 -	 */
  12.228 -	ld8 r25=[r21]				// read L3 PTE again
  12.229 -	ld8 r26=[r17]				// read L2 entry again
  12.230 -	;;
  12.231 -	cmp.ne p6,p7=r26,r20			// did L2 entry change
  12.232 -	mov r27=PAGE_SHIFT<<2
  12.233 -	;;
  12.234 -(p6)	ptc.l r22,r27				// purge PTE page translation
  12.235 -(p7)	cmp.ne.or.andcm p6,p7=r25,r18		// did L3 PTE change
  12.236 -	;;
  12.237 -(p6)	ptc.l r16,r27				// purge translation
  12.238 -#endif
  12.239 -
  12.240 -	mov pr=r31,-1				// restore predicate registers
  12.241 -	rfi
  12.242 -END(vhpt_miss)
  12.243 -
  12.244 -	.org ia64_ivt+0x400
  12.245 -/////////////////////////////////////////////////////////////////////////////////////////
  12.246 -// 0x0400 Entry 1 (size 64 bundles) ITLB (21)
  12.247 -ENTRY(itlb_miss)
  12.248 -	DBG_FAULT(1)
  12.249 -#ifdef XEN
  12.250 -	VHPT_CCHAIN_LOOKUP(itlb_miss,i)
  12.251 -#ifdef VHPT_GLOBAL
  12.252 -	br.cond.sptk page_fault
  12.253 -	;;
  12.254 -#endif
  12.255 -#endif
  12.256 -	/*
  12.257 -	 * The ITLB handler accesses the L3 PTE via the virtually mapped linear
  12.258 -	 * page table.  If a nested TLB miss occurs, we switch into physical
  12.259 -	 * mode, walk the page table, and then re-execute the L3 PTE read
  12.260 -	 * and go on normally after that.
  12.261 -	 */
  12.262 -	mov r16=cr.ifa				// get virtual address
  12.263 -	mov r29=b0				// save b0
  12.264 -	mov r31=pr				// save predicates
  12.265 -.itlb_fault:
  12.266 -	mov r17=cr.iha				// get virtual address of L3 PTE
  12.267 -	movl r30=1f				// load nested fault continuation point
  12.268 -	;;
  12.269 -1:	ld8 r18=[r17]				// read L3 PTE
  12.270 -	;;
  12.271 -	mov b0=r29
  12.272 -	tbit.z p6,p0=r18,_PAGE_P_BIT		// page present bit cleared?
  12.273 -(p6)	br.cond.spnt page_fault
  12.274 -	;;
  12.275 -	itc.i r18
  12.276 -	;;
  12.277 -#ifdef CONFIG_SMP
  12.278 -	/*
  12.279 -	 * Tell the assemblers dependency-violation checker that the above "itc" instructions
  12.280 -	 * cannot possibly affect the following loads:
  12.281 -	 */
  12.282 -	dv_serialize_data
  12.283 -
  12.284 -	ld8 r19=[r17]				// read L3 PTE again and see if same
  12.285 -	mov r20=PAGE_SHIFT<<2			// setup page size for purge
  12.286 -	;;
  12.287 -	cmp.ne p7,p0=r18,r19
  12.288 -	;;
  12.289 -(p7)	ptc.l r16,r20
  12.290 -#endif
  12.291 -	mov pr=r31,-1
  12.292 -	rfi
  12.293 -END(itlb_miss)
  12.294 -
  12.295 -	.org ia64_ivt+0x0800
  12.296 -/////////////////////////////////////////////////////////////////////////////////////////
  12.297 -// 0x0800 Entry 2 (size 64 bundles) DTLB (9,48)
  12.298 -ENTRY(dtlb_miss)
  12.299 -	DBG_FAULT(2)
  12.300 -#ifdef XEN
  12.301 -	VHPT_CCHAIN_LOOKUP(dtlb_miss,d)
  12.302 -#ifdef VHPT_GLOBAL
  12.303 -	br.cond.sptk page_fault
  12.304 -	;;
  12.305 -#endif
  12.306 -#endif
  12.307 -	/*
  12.308 -	 * The DTLB handler accesses the L3 PTE via the virtually mapped linear
  12.309 -	 * page table.  If a nested TLB miss occurs, we switch into physical
  12.310 -	 * mode, walk the page table, and then re-execute the L3 PTE read
  12.311 -	 * and go on normally after that.
  12.312 -	 */
  12.313 -	mov r16=cr.ifa				// get virtual address
  12.314 -	mov r29=b0				// save b0
  12.315 -	mov r31=pr				// save predicates
  12.316 -dtlb_fault:
  12.317 -	mov r17=cr.iha				// get virtual address of L3 PTE
  12.318 -	movl r30=1f				// load nested fault continuation point
  12.319 -	;;
  12.320 -1:	ld8 r18=[r17]				// read L3 PTE
  12.321 -	;;
  12.322 -	mov b0=r29
  12.323 -	tbit.z p6,p0=r18,_PAGE_P_BIT		// page present bit cleared?
  12.324 -(p6)	br.cond.spnt page_fault
  12.325 -	;;
  12.326 -	itc.d r18
  12.327 -	;;
  12.328 -#ifdef CONFIG_SMP
  12.329 -	/*
  12.330 -	 * Tell the assemblers dependency-violation checker that the above "itc" instructions
  12.331 -	 * cannot possibly affect the following loads:
  12.332 -	 */
  12.333 -	dv_serialize_data
  12.334 -
  12.335 -	ld8 r19=[r17]				// read L3 PTE again and see if same
  12.336 -	mov r20=PAGE_SHIFT<<2			// setup page size for purge
  12.337 -	;;
  12.338 -	cmp.ne p7,p0=r18,r19
  12.339 -	;;
  12.340 -(p7)	ptc.l r16,r20
  12.341 -#endif
  12.342 -	mov pr=r31,-1
  12.343 -	rfi
  12.344 -END(dtlb_miss)
  12.345 -
  12.346 -	.org ia64_ivt+0x0c00
  12.347 -/////////////////////////////////////////////////////////////////////////////////////////
  12.348 -// 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19)
  12.349 -ENTRY(alt_itlb_miss)
  12.350 -	DBG_FAULT(3)
  12.351 -#ifdef XEN
  12.352 -//#ifdef VHPT_GLOBAL
  12.353 -//	VHPT_CCHAIN_LOOKUP(alt_itlb_miss,i)
  12.354 -//	br.cond.sptk page_fault
  12.355 -//	;;
  12.356 -//#endif
  12.357 -#endif
  12.358 -#ifdef XEN
  12.359 -	mov r31=pr
  12.360 -	mov r16=cr.ifa		// get address that caused the TLB miss
  12.361 -	;;
  12.362 -late_alt_itlb_miss:
  12.363 -	movl r17=PAGE_KERNEL
  12.364 -	mov r21=cr.ipsr
  12.365 -	movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
  12.366 -	;;
  12.367 -#else
  12.368 -	mov r16=cr.ifa		// get address that caused the TLB miss
  12.369 -	movl r17=PAGE_KERNEL
  12.370 -	mov r21=cr.ipsr
  12.371 -	movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
  12.372 -	mov r31=pr
  12.373 -	;;
  12.374 -#endif
  12.375 -#ifdef CONFIG_DISABLE_VHPT
  12.376 -	shr.u r22=r16,61			// get the region number into r21
  12.377 -	;;
  12.378 -	cmp.gt p8,p0=6,r22			// user mode
  12.379 -	;;
  12.380 -(p8)	thash r17=r16
  12.381 -	;;
  12.382 -(p8)	mov cr.iha=r17
  12.383 -(p8)	mov r29=b0				// save b0
  12.384 -(p8)	br.cond.dptk .itlb_fault
  12.385 -#endif
  12.386 -	extr.u r23=r21,IA64_PSR_CPL0_BIT,2	// extract psr.cpl
  12.387 -	and r19=r19,r16		// clear ed, reserved bits, and PTE control bits
  12.388 -#ifdef XEN
  12.389 -	shr.u r18=r16,55	// move address bit 59 to bit 4
  12.390 -	;;
  12.391 -	and r18=0x10,r18	// bit 4=address-bit(59)
  12.392 -#else
  12.393 -	shr.u r18=r16,57	// move address bit 61 to bit 4
  12.394 -	;;
  12.395 -	andcm r18=0x10,r18	// bit 4=~address-bit(61)
  12.396 -#endif
  12.397 -	cmp.ne p8,p0=r0,r23	// psr.cpl != 0?
  12.398 -	or r19=r17,r19		// insert PTE control bits into r19
  12.399 -	;;
  12.400 -	or r19=r19,r18		// set bit 4 (uncached) if the access was to region 6
  12.401 -(p8)	br.cond.spnt page_fault
  12.402 -	;;
  12.403 -	itc.i r19		// insert the TLB entry
  12.404 -	mov pr=r31,-1
  12.405 -	rfi
  12.406 -END(alt_itlb_miss)
  12.407 -
  12.408 -	.org ia64_ivt+0x1000
  12.409 -/////////////////////////////////////////////////////////////////////////////////////////
  12.410 -// 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46)
  12.411 -ENTRY(alt_dtlb_miss)
  12.412 -	DBG_FAULT(4)
  12.413 -#ifdef XEN
  12.414 -//#ifdef VHPT_GLOBAL
  12.415 -//	VHPT_CCHAIN_LOOKUP(alt_dtlb_miss,d)
  12.416 -//	br.cond.sptk page_fault
  12.417 -//	;;
  12.418 -//#endif
  12.419 -#endif
  12.420 -#ifdef XEN
  12.421 -	mov r31=pr
  12.422 -	mov r16=cr.ifa		// get address that caused the TLB miss
  12.423 -	;;
  12.424 -late_alt_dtlb_miss:
  12.425 -	movl r17=PAGE_KERNEL
  12.426 -	mov r20=cr.isr
  12.427 -	movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
  12.428 -	mov r21=cr.ipsr
  12.429 -	;;
  12.430 -#else
  12.431 -#endif
  12.432 -#ifdef CONFIG_DISABLE_VHPT
  12.433 -	shr.u r22=r16,61			// get the region number into r21
  12.434 -	;;
  12.435 -	cmp.gt p8,p0=6,r22			// access to region 0-5
  12.436 -	;;
  12.437 -(p8)	thash r17=r16
  12.438 -	;;
  12.439 -(p8)	mov cr.iha=r17
  12.440 -(p8)	mov r29=b0				// save b0
  12.441 -(p8)	br.cond.dptk dtlb_fault
  12.442 -#endif
  12.443 -	extr.u r23=r21,IA64_PSR_CPL0_BIT,2	// extract psr.cpl
  12.444 -	and r22=IA64_ISR_CODE_MASK,r20		// get the isr.code field
  12.445 -	tbit.nz p6,p7=r20,IA64_ISR_SP_BIT	// is speculation bit on?
  12.446 -#ifdef XEN
  12.447 -	shr.u r18=r16,55			// move address bit 59 to bit 4
  12.448 -	and r19=r19,r16				// clear ed, reserved bits, and PTE control bits
  12.449 -	tbit.nz p9,p0=r20,IA64_ISR_NA_BIT	// is non-access bit on?
  12.450 -	;;
  12.451 -	and r18=0x10,r18	// bit 4=address-bit(59)
  12.452 -#else
  12.453 -	shr.u r18=r16,57			// move address bit 61 to bit 4
  12.454 -	and r19=r19,r16				// clear ed, reserved bits, and PTE control bits
  12.455 -	tbit.nz p9,p0=r20,IA64_ISR_NA_BIT	// is non-access bit on?
  12.456 -	;;
  12.457 -	andcm r18=0x10,r18	// bit 4=~address-bit(61)
  12.458 -#endif
  12.459 -	cmp.ne p8,p0=r0,r23
  12.460 -(p9)	cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22	// check isr.code field
  12.461 -(p8)	br.cond.spnt page_fault
  12.462 -#ifdef XEN
  12.463 -	;;
  12.464 -	// Test for Xen address, if not handle via page_fault
  12.465 -	// note that 0xf000 (cached) and 0xe800 (uncached) addresses
  12.466 -	// should be OK.
  12.467 -	extr.u r22=r16,59,5;;
  12.468 -	cmp.eq p8,p0=0x1e,r22
  12.469 -(p8)	br.cond.spnt 1f;;
  12.470 -	cmp.ne p8,p0=0x1d,r22
  12.471 -(p8)	br.cond.sptk page_fault ;;
  12.472 -1:
  12.473 -#endif
  12.474 -
  12.475 -	dep r21=-1,r21,IA64_PSR_ED_BIT,1
  12.476 -	or r19=r19,r17		// insert PTE control bits into r19
  12.477 -	;;
  12.478 -	or r19=r19,r18		// set bit 4 (uncached) if the access was to region 6
  12.479 -(p6)	mov cr.ipsr=r21
  12.480 -	;;
  12.481 -(p7)	itc.d r19		// insert the TLB entry
  12.482 -	mov pr=r31,-1
  12.483 -	rfi
  12.484 -END(alt_dtlb_miss)
  12.485 -
  12.486 -	.org ia64_ivt+0x1400
  12.487 -/////////////////////////////////////////////////////////////////////////////////////////
  12.488 -// 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45)
  12.489 -ENTRY(nested_dtlb_miss)
  12.490 -	/*
  12.491 -	 * In the absence of kernel bugs, we get here when the virtually mapped linear
  12.492 -	 * page table is accessed non-speculatively (e.g., in the Dirty-bit, Instruction
  12.493 -	 * Access-bit, or Data Access-bit faults).  If the DTLB entry for the virtual page
  12.494 -	 * table is missing, a nested TLB miss fault is triggered and control is
  12.495 -	 * transferred to this point.  When this happens, we lookup the pte for the
  12.496 -	 * faulting address by walking the page table in physical mode and return to the
  12.497 -	 * continuation point passed in register r30 (or call page_fault if the address is
  12.498 -	 * not mapped).
  12.499 -	 *
  12.500 -	 * Input:	r16:	faulting address
  12.501 -	 *		r29:	saved b0
  12.502 -	 *		r30:	continuation address
  12.503 -	 *		r31:	saved pr
  12.504 -	 *
  12.505 -	 * Output:	r17:	physical address of L3 PTE of faulting address
  12.506 -	 *		r29:	saved b0
  12.507 -	 *		r30:	continuation address
  12.508 -	 *		r31:	saved pr
  12.509 -	 *
  12.510 -	 * Clobbered:	b0, r18, r19, r21, psr.dt (cleared)
  12.511 -	 */
  12.512 -	rsm psr.dt				// switch to using physical data addressing
  12.513 -#ifdef XEN
  12.514 -	movl r19=THIS_CPU(cpu_kr)+IA64_KR_PT_BASE_OFFSET;;
  12.515 -#else
  12.516 -	mov r19=IA64_KR(PT_BASE)		// get the page table base address
  12.517 -#endif
  12.518 -	shl r21=r16,3				// shift bit 60 into sign bit
  12.519 -	;;
  12.520 -	shr.u r17=r16,61			// get the region number into r17
  12.521 -	;;
  12.522 -	cmp.eq p6,p7=5,r17			// is faulting address in region 5?
  12.523 -	shr.u r18=r16,PGDIR_SHIFT		// get bits 33-63 of faulting address
  12.524 -	;;
  12.525 -(p7)	dep r17=r17,r19,(PAGE_SHIFT-3),3	// put region number bits in place
  12.526 -
  12.527 -	srlz.d
  12.528 -	LOAD_PHYSICAL(p6, r19, swapper_pg_dir)	// region 5 is rooted at swapper_pg_dir
  12.529 -
  12.530 -	.pred.rel "mutex", p6, p7
  12.531 -(p6)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
  12.532 -(p7)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
  12.533 -	;;
  12.534 -(p6)	dep r17=r18,r19,3,(PAGE_SHIFT-3)	// r17=PTA + IFA(33,42)*8
  12.535 -(p7)	dep r17=r18,r17,3,(PAGE_SHIFT-6)	// r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8)
  12.536 -	cmp.eq p7,p6=0,r21			// unused address bits all zeroes?
  12.537 -	shr.u r18=r16,PMD_SHIFT			// shift L2 index into position
  12.538 -	;;
  12.539 -	ld8 r17=[r17]				// fetch the L1 entry (may be 0)
  12.540 -	;;
  12.541 -(p7)	cmp.eq p6,p7=r17,r0			// was L1 entry NULL?
  12.542 -	dep r17=r18,r17,3,(PAGE_SHIFT-3)	// compute address of L2 page table entry
  12.543 -	;;
  12.544 -(p7)	ld8 r17=[r17]				// fetch the L2 entry (may be 0)
  12.545 -	shr.u r19=r16,PAGE_SHIFT		// shift L3 index into position
  12.546 -	;;
  12.547 -(p7)	cmp.eq.or.andcm p6,p7=r17,r0		// was L2 entry NULL?
  12.548 -	dep r17=r19,r17,3,(PAGE_SHIFT-3)	// compute address of L3 page table entry
  12.549 -(p6)	br.cond.spnt page_fault
  12.550 -	mov b0=r30
  12.551 -	br.sptk.many b0				// return to continuation point
  12.552 -END(nested_dtlb_miss)
  12.553 -
  12.554 -	.org ia64_ivt+0x1800
  12.555 -/////////////////////////////////////////////////////////////////////////////////////////
  12.556 -// 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24)
  12.557 -ENTRY(ikey_miss)
  12.558 -#ifdef XEN
  12.559 -	REFLECT(6)
  12.560 -#endif
  12.561 -	DBG_FAULT(6)
  12.562 -	FAULT(6)
  12.563 -END(ikey_miss)
  12.564 -
  12.565 -	//-----------------------------------------------------------------------------------
  12.566 -	// call do_page_fault (predicates are in r31, psr.dt may be off, r16 is faulting address)
  12.567 -ENTRY(page_fault)
  12.568 -	ssm psr.dt
  12.569 -	;;
  12.570 -	srlz.i
  12.571 -	;;
  12.572 -	SAVE_MIN_WITH_COVER
  12.573 -#ifdef XEN
  12.574 -	alloc r15=ar.pfs,0,0,4,0
  12.575 -	mov out0=cr.ifa
  12.576 -	mov out1=cr.isr
  12.577 -	mov out3=cr.itir
  12.578 -#else
  12.579 -	alloc r15=ar.pfs,0,0,3,0
  12.580 -	mov out0=cr.ifa
  12.581 -	mov out1=cr.isr
  12.582 -#endif
  12.583 -	adds r3=8,r2				// set up second base pointer
  12.584 -	;;
  12.585 -	ssm psr.ic | PSR_DEFAULT_BITS
  12.586 -	;;
  12.587 -	srlz.i					// guarantee that interruption collectin is on
  12.588 -	;;
  12.589 -(p15)	ssm psr.i				// restore psr.i
  12.590 -	movl r14=ia64_leave_kernel
  12.591 -	;;
  12.592 -	SAVE_REST
  12.593 -	mov rp=r14
  12.594 -	;;
  12.595 -	adds out2=16,r12			// out2 = pointer to pt_regs
  12.596 -	br.call.sptk.many b6=ia64_do_page_fault	// ignore return address
  12.597 -END(page_fault)
  12.598 -
  12.599 -	.org ia64_ivt+0x1c00
  12.600 -/////////////////////////////////////////////////////////////////////////////////////////
  12.601 -// 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
  12.602 -ENTRY(dkey_miss)
  12.603 -#ifdef XEN
  12.604 -	REFLECT(7)
  12.605 -#endif
  12.606 -	DBG_FAULT(7)
  12.607 -	FAULT(7)
  12.608 -END(dkey_miss)
  12.609 -
  12.610 -	.org ia64_ivt+0x2000
  12.611 -/////////////////////////////////////////////////////////////////////////////////////////
  12.612 -// 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54)
  12.613 -ENTRY(dirty_bit)
  12.614 -#ifdef XEN
  12.615 -	REFLECT(8)
  12.616 -#endif
  12.617 -	DBG_FAULT(8)
  12.618 -	/*
  12.619 -	 * What we do here is to simply turn on the dirty bit in the PTE.  We need to
  12.620 -	 * update both the page-table and the TLB entry.  To efficiently access the PTE,
  12.621 -	 * we address it through the virtual page table.  Most likely, the TLB entry for
  12.622 -	 * the relevant virtual page table page is still present in the TLB so we can
  12.623 -	 * normally do this without additional TLB misses.  In case the necessary virtual
  12.624 -	 * page table TLB entry isn't present, we take a nested TLB miss hit where we look
  12.625 -	 * up the physical address of the L3 PTE and then continue at label 1 below.
  12.626 -	 */
  12.627 -	mov r16=cr.ifa				// get the address that caused the fault
  12.628 -	movl r30=1f				// load continuation point in case of nested fault
  12.629 -	;;
  12.630 -	thash r17=r16				// compute virtual address of L3 PTE
  12.631 -	mov r29=b0				// save b0 in case of nested fault
  12.632 -	mov r31=pr				// save pr
  12.633 -#ifdef CONFIG_SMP
  12.634 -	mov r28=ar.ccv				// save ar.ccv
  12.635 -	;;
  12.636 -1:	ld8 r18=[r17]
  12.637 -	;;					// avoid RAW on r18
  12.638 -	mov ar.ccv=r18				// set compare value for cmpxchg
  12.639 -	or r25=_PAGE_D|_PAGE_A,r18		// set the dirty and accessed bits
  12.640 -	;;
  12.641 -	cmpxchg8.acq r26=[r17],r25,ar.ccv
  12.642 -	mov r24=PAGE_SHIFT<<2
  12.643 -	;;
  12.644 -	cmp.eq p6,p7=r26,r18
  12.645 -	;;
  12.646 -(p6)	itc.d r25				// install updated PTE
  12.647 -	;;
  12.648 -	/*
  12.649 -	 * Tell the assemblers dependency-violation checker that the above "itc" instructions
  12.650 -	 * cannot possibly affect the following loads:
  12.651 -	 */
  12.652 -	dv_serialize_data
  12.653 -
  12.654 -	ld8 r18=[r17]				// read PTE again
  12.655 -	;;
  12.656 -	cmp.eq p6,p7=r18,r25			// is it same as the newly installed
  12.657 -	;;
  12.658 -(p7)	ptc.l r16,r24
  12.659 -	mov b0=r29				// restore b0
  12.660 -	mov ar.ccv=r28
  12.661 -#else
  12.662 -	;;
  12.663 -1:	ld8 r18=[r17]
  12.664 -	;;					// avoid RAW on r18
  12.665 -	or r18=_PAGE_D|_PAGE_A,r18		// set the dirty and accessed bits
  12.666 -	mov b0=r29				// restore b0
  12.667 -	;;
  12.668 -	st8 [r17]=r18				// store back updated PTE
  12.669 -	itc.d r18				// install updated PTE
  12.670 -#endif
  12.671 -	mov pr=r31,-1				// restore pr
  12.672 -	rfi
  12.673 -END(dirty_bit)
  12.674 -
  12.675 -	.org ia64_ivt+0x2400
  12.676 -/////////////////////////////////////////////////////////////////////////////////////////
  12.677 -// 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27)
  12.678 -ENTRY(iaccess_bit)
  12.679 -#ifdef XEN
  12.680 -	mov r31=pr;
  12.681 -	mov r16=cr.isr
  12.682 -	mov r17=cr.ifa
  12.683 -	mov r19=9
  12.684 -	movl r20=0x2400
  12.685 -	br.sptk.many fast_access_reflect;;
  12.686 -#endif
  12.687 -	DBG_FAULT(9)
  12.688 -	// Like Entry 8, except for instruction access
  12.689 -	mov r16=cr.ifa				// get the address that caused the fault
  12.690 -	movl r30=1f				// load continuation point in case of nested fault
  12.691 -	mov r31=pr				// save predicates
  12.692 -#ifdef CONFIG_ITANIUM
  12.693 -	/*
  12.694 -	 * Erratum 10 (IFA may contain incorrect address) has "NoFix" status.
  12.695 -	 */
  12.696 -	mov r17=cr.ipsr
  12.697 -	;;
  12.698 -	mov r18=cr.iip
  12.699 -	tbit.z p6,p0=r17,IA64_PSR_IS_BIT	// IA64 instruction set?
  12.700 -	;;
  12.701 -(p6)	mov r16=r18				// if so, use cr.iip instead of cr.ifa
  12.702 -#endif /* CONFIG_ITANIUM */
  12.703 -	;;
  12.704 -	thash r17=r16				// compute virtual address of L3 PTE
  12.705 -	mov r29=b0				// save b0 in case of nested fault)
  12.706 -#ifdef CONFIG_SMP
  12.707 -	mov r28=ar.ccv				// save ar.ccv
  12.708 -	;;
  12.709 -1:	ld8 r18=[r17]
  12.710 -	;;
  12.711 -	mov ar.ccv=r18				// set compare value for cmpxchg
  12.712 -	or r25=_PAGE_A,r18			// set the accessed bit
  12.713 -	;;
  12.714 -	cmpxchg8.acq r26=[r17],r25,ar.ccv
  12.715 -	mov r24=PAGE_SHIFT<<2
  12.716 -	;;
  12.717 -	cmp.eq p6,p7=r26,r18
  12.718 -	;;
  12.719 -(p6)	itc.i r25				// install updated PTE
  12.720 -	;;
  12.721 -	/*
  12.722 -	 * Tell the assemblers dependency-violation checker that the above "itc" instructions
  12.723 -	 * cannot possibly affect the following loads:
  12.724 -	 */
  12.725 -	dv_serialize_data
  12.726 -
  12.727 -	ld8 r18=[r17]				// read PTE again
  12.728 -	;;
  12.729 -	cmp.eq p6,p7=r18,r25			// is it same as the newly installed
  12.730 -	;;
  12.731 -(p7)	ptc.l r16,r24
  12.732 -	mov b0=r29				// restore b0
  12.733 -	mov ar.ccv=r28
  12.734 -#else /* !CONFIG_SMP */
  12.735 -	;;
  12.736 -1:	ld8 r18=[r17]
  12.737 -	;;
  12.738 -	or r18=_PAGE_A,r18			// set the accessed bit
  12.739 -	mov b0=r29				// restore b0
  12.740 -	;;
  12.741 -	st8 [r17]=r18				// store back updated PTE
  12.742 -	itc.i r18				// install updated PTE
  12.743 -#endif /* !CONFIG_SMP */
  12.744 -	mov pr=r31,-1
  12.745 -	rfi
  12.746 -END(iaccess_bit)
  12.747 -
  12.748 -	.org ia64_ivt+0x2800
  12.749 -/////////////////////////////////////////////////////////////////////////////////////////
  12.750 -// 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55)
  12.751 -ENTRY(daccess_bit)
  12.752 -#ifdef XEN
  12.753 -	mov r31=pr;
  12.754 -	mov r16=cr.isr
  12.755 -	mov r17=cr.ifa
  12.756 -	mov r19=10
  12.757 -	movl r20=0x2800
  12.758 -	br.sptk.many fast_access_reflect;;
  12.759 -#endif
  12.760 -	DBG_FAULT(10)
  12.761 -	// Like Entry 8, except for data access
  12.762 -	mov r16=cr.ifa				// get the address that caused the fault
  12.763 -	movl r30=1f				// load continuation point in case of nested fault
  12.764 -	;;
  12.765 -	thash r17=r16				// compute virtual address of L3 PTE
  12.766 -	mov r31=pr
  12.767 -	mov r29=b0				// save b0 in case of nested fault)
  12.768 -#ifdef CONFIG_SMP
  12.769 -	mov r28=ar.ccv				// save ar.ccv
  12.770 -	;;
  12.771 -1:	ld8 r18=[r17]
  12.772 -	;;					// avoid RAW on r18
  12.773 -	mov ar.ccv=r18				// set compare value for cmpxchg
  12.774 -	or r25=_PAGE_A,r18			// set the dirty bit
  12.775 -	;;
  12.776 -	cmpxchg8.acq r26=[r17],r25,ar.ccv
  12.777 -	mov r24=PAGE_SHIFT<<2
  12.778 -	;;
  12.779 -	cmp.eq p6,p7=r26,r18
  12.780 -	;;
  12.781 -(p6)	itc.d r25				// install updated PTE
  12.782 -	/*
  12.783 -	 * Tell the assemblers dependency-violation checker that the above "itc" instructions
  12.784 -	 * cannot possibly affect the following loads:
  12.785 -	 */
  12.786 -	dv_serialize_data
  12.787 -	;;
  12.788 -	ld8 r18=[r17]				// read PTE again
  12.789 -	;;
  12.790 -	cmp.eq p6,p7=r18,r25			// is it same as the newly installed
  12.791 -	;;
  12.792 -(p7)	ptc.l r16,r24
  12.793 -	mov ar.ccv=r28
  12.794 -#else
  12.795 -	;;
  12.796 -1:	ld8 r18=[r17]
  12.797 -	;;					// avoid RAW on r18
  12.798 -	or r18=_PAGE_A,r18			// set the accessed bit
  12.799 -	;;
  12.800 -	st8 [r17]=r18				// store back updated PTE
  12.801 -	itc.d r18				// install updated PTE
  12.802 -#endif
  12.803 -	mov b0=r29				// restore b0
  12.804 -	mov pr=r31,-1
  12.805 -	rfi
  12.806 -END(daccess_bit)
  12.807 -
  12.808 -	.org ia64_ivt+0x2c00
  12.809 -/////////////////////////////////////////////////////////////////////////////////////////
  12.810 -// 0x2c00 Entry 11 (size 64 bundles) Break instruction (33)
  12.811 -ENTRY(break_fault)
  12.812 -	/*
  12.813 -	 * The streamlined system call entry/exit paths only save/restore the initial part
  12.814 -	 * of pt_regs.  This implies that the callers of system-calls must adhere to the
  12.815 -	 * normal procedure calling conventions.
  12.816 -	 *
  12.817 -	 *   Registers to be saved & restored:
  12.818 -	 *	CR registers: cr.ipsr, cr.iip, cr.ifs
  12.819 -	 *	AR registers: ar.unat, ar.pfs, ar.rsc, ar.rnat, ar.bspstore, ar.fpsr
  12.820 -	 * 	others: pr, b0, b6, loadrs, r1, r11, r12, r13, r15
  12.821 -	 *   Registers to be restored only:
  12.822 -	 * 	r8-r11: output value from the system call.
  12.823 -	 *
  12.824 -	 * During system call exit, scratch registers (including r15) are modified/cleared
  12.825 -	 * to prevent leaking bits from kernel to user level.
  12.826 -	 */
  12.827 -	DBG_FAULT(11)
  12.828 -#ifdef XEN
  12.829 -	mov r16=cr.isr
  12.830 -	mov r17=cr.iim
  12.831 -	mov r31=pr
  12.832 -	;;
  12.833 -	movl r18=XSI_PSR_IC
  12.834 -	;;
  12.835 -	ld8 r19=[r18]
  12.836 -	;;
  12.837 -	cmp.eq p7,p0=r0,r17			// is this a psuedo-cover?
  12.838 -(p7)	br.spnt.many dispatch_privop_fault
  12.839 -	;;
  12.840 -	// if vpsr.ic is off, we have a hyperprivop
  12.841 -	// A hyperprivop is hand-coded assembly with psr.ic off
  12.842 -	// which means no calls, no use of r1-r15 and no memory accesses
  12.843 -	// except to pinned addresses!
  12.844 -	cmp4.eq p7,p0=r0,r19
  12.845 -(p7)	br.sptk.many fast_hyperprivop
  12.846 -	;;
  12.847 -	movl r22=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;
  12.848 -	ld8 r22 = [r22]
  12.849 -	;;
  12.850 -	adds r22=IA64_VCPU_BREAKIMM_OFFSET,r22;;
  12.851 -	ld4 r23=[r22];;
  12.852 -	cmp4.eq p6,p7=r23,r17			// Xen-reserved breakimm?
  12.853 -(p6)	br.spnt.many dispatch_break_fault
  12.854 -	;;
  12.855 -	br.sptk.many fast_break_reflect
  12.856 -	;;
  12.857 -#endif
  12.858 -	movl r16=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;
  12.859 -	ld8 r16=[r16]
  12.860 -	mov r17=cr.iim
  12.861 -	mov r18=__IA64_BREAK_SYSCALL
  12.862 -	mov r21=ar.fpsr
  12.863 -	mov r29=cr.ipsr
  12.864 -	mov r19=b6
  12.865 -	mov r25=ar.unat
  12.866 -	mov r27=ar.rsc
  12.867 -	mov r26=ar.pfs
  12.868 -	mov r28=cr.iip
  12.869 -#ifndef XEN
  12.870 -	mov r31=pr				// prepare to save predicates
  12.871 -#endif
  12.872 -	mov r20=r1
  12.873 -	;;
  12.874 -	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16
  12.875 -	cmp.eq p0,p7=r18,r17			// is this a system call? (p7 <- false, if so)
  12.876 -(p7)	br.cond.spnt non_syscall
  12.877 -	;;
  12.878 -	ld1 r17=[r16]				// load current->thread.on_ustack flag
  12.879 -	st1 [r16]=r0				// clear current->thread.on_ustack flag
  12.880 -	add r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16	// set r1 for MINSTATE_START_SAVE_MIN_VIRT
  12.881 -	;;
  12.882 -	invala
  12.883 -
  12.884 -	/* adjust return address so we skip over the break instruction: */
  12.885 -
  12.886 -	extr.u r8=r29,41,2			// extract ei field from cr.ipsr
  12.887 -	;;
  12.888 -	cmp.eq p6,p7=2,r8			// isr.ei==2?
  12.889 -	mov r2=r1				// setup r2 for ia64_syscall_setup
  12.890 -	;;
  12.891 -(p6)	mov r8=0				// clear ei to 0
  12.892 -(p6)	adds r28=16,r28				// switch cr.iip to next bundle cr.ipsr.ei wrapped
  12.893 -(p7)	adds r8=1,r8				// increment ei to next slot
  12.894 -	;;
  12.895 -	cmp.eq pKStk,pUStk=r0,r17		// are we in kernel mode already?
  12.896 -	dep r29=r8,r29,41,2			// insert new ei into cr.ipsr
  12.897 -	;;
  12.898 -
  12.899 -	// switch from user to kernel RBS:
  12.900 -	MINSTATE_START_SAVE_MIN_VIRT
  12.901 -	br.call.sptk.many b7=ia64_syscall_setup
  12.902 -	;;
  12.903 -	MINSTATE_END_SAVE_MIN_VIRT		// switch to bank 1
  12.904 -	ssm psr.ic | PSR_DEFAULT_BITS
  12.905 -	;;
  12.906 -	srlz.i					// guarantee that interruption collection is on
  12.907 -	mov r3=NR_syscalls - 1
  12.908 -	;;
  12.909 -(p15)	ssm psr.i				// restore psr.i
  12.910 -	// p10==true means out registers are more than 8 or r15's Nat is true
  12.911 -(p10)	br.cond.spnt.many ia64_ret_from_syscall
  12.912 -	;;
  12.913 -	movl r16=sys_call_table
  12.914 -
  12.915 -	adds r15=-1024,r15			// r15 contains the syscall number---subtract 1024
  12.916 -	movl r2=ia64_ret_from_syscall
  12.917 -	;;
  12.918 -	shladd r20=r15,3,r16			// r20 = sys_call_table + 8*(syscall-1024)
  12.919 -	cmp.leu p6,p7=r15,r3			// (syscall > 0 && syscall < 1024 + NR_syscalls) ?
  12.920 -	mov rp=r2				// set the real return addr
  12.921 -	;;
  12.922 -(p6)	ld8 r20=[r20]				// load address of syscall entry point
  12.923 -(p7)	movl r20=sys_ni_syscall
  12.924 -
  12.925 -	add r2=TI_FLAGS+IA64_TASK_SIZE,r13
  12.926 -	;;
  12.927 -	ld4 r2=[r2]				// r2 = current_thread_info()->flags
  12.928 -	;;
  12.929 -	and r2=_TIF_SYSCALL_TRACEAUDIT,r2	// mask trace or audit
  12.930 -	;;
  12.931 -	cmp.eq p8,p0=r2,r0
  12.932 -	mov b6=r20
  12.933 -	;;
  12.934 -(p8)	br.call.sptk.many b6=b6			// ignore this return addr
  12.935 -	br.cond.sptk ia64_trace_syscall
  12.936 -	// NOT REACHED
  12.937 -END(break_fault)
  12.938 -
  12.939 -	.org ia64_ivt+0x3000
  12.940 -/////////////////////////////////////////////////////////////////////////////////////////
  12.941 -// 0x3000 Entry 12 (size 64 bundles) External Interrupt (4)
  12.942 -ENTRY(interrupt)
  12.943 -	DBG_FAULT(12)
  12.944 -	mov r31=pr		// prepare to save predicates
  12.945 -	;;
  12.946 -#ifdef XEN
  12.947 -	mov r30=cr.ivr		// pass cr.ivr as first arg
  12.948 -	// FIXME: this is a hack... use cpuinfo.ksoftirqd because its
  12.949 -	// not used anywhere else and we need a place to stash ivr and
  12.950 -	// there's no registers available unused by SAVE_MIN/REST
  12.951 -	movl r29=THIS_CPU(cpu_info)+IA64_CPUINFO_KSOFTIRQD_OFFSET;;
  12.952 -	st8 [r29]=r30;;
  12.953 -	movl r28=slow_interrupt;;
  12.954 -	mov r29=rp;;
  12.955 -	mov rp=r28;;
  12.956 -	br.cond.sptk.many fast_tick_reflect
  12.957 -	;;
  12.958 -slow_interrupt:
  12.959 -	mov rp=r29;;
  12.960 -#endif
  12.961 -	SAVE_MIN_WITH_COVER	// uses r31; defines r2 and r3
  12.962 -	ssm psr.ic | PSR_DEFAULT_BITS
  12.963 -	;;
  12.964 -	adds r3=8,r2		// set up second base pointer for SAVE_REST
  12.965 -	srlz.i			// ensure everybody knows psr.ic is back on
  12.966 -	;;
  12.967 -	SAVE_REST
  12.968 -	;;
  12.969 -	alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
  12.970 -#ifdef XEN
  12.971 -	movl out0=THIS_CPU(cpu_info)+IA64_CPUINFO_KSOFTIRQD_OFFSET;;
  12.972 -	ld8 out0=[out0];;
  12.973 -#else
  12.974 -	mov out0=cr.ivr		// pass cr.ivr as first arg
  12.975 -#endif
  12.976 -	add out1=16,sp		// pass pointer to pt_regs as second arg
  12.977 -	;;
  12.978 -	srlz.d			// make sure we see the effect of cr.ivr
  12.979 -	movl r14=ia64_leave_kernel
  12.980 -	;;
  12.981 -	mov rp=r14
  12.982 -	br.call.sptk.many b6=ia64_handle_irq
  12.983 -END(interrupt)
  12.984 -
  12.985 -	.org ia64_ivt+0x3400
  12.986 -/////////////////////////////////////////////////////////////////////////////////////////
  12.987 -// 0x3400 Entry 13 (size 64 bundles) Reserved
  12.988 -	DBG_FAULT(13)
  12.989 -	FAULT(13)
  12.990 -
  12.991 -#ifdef XEN
  12.992 -	// There is no particular reason for this code to be here, other than that
  12.993 -	// there happens to be space here that would go unused otherwise.  If this
  12.994 -	// fault ever gets "unreserved", simply moved the following code to a more
  12.995 -	// suitable spot...
  12.996 -
  12.997 -GLOBAL_ENTRY(dispatch_break_fault)
  12.998 -	SAVE_MIN_WITH_COVER
  12.999 -	;;
 12.1000 -dispatch_break_fault_post_save:
 12.1001 -	alloc r14=ar.pfs,0,0,4,0 // now it's safe (must be first in insn group!)
 12.1002 -	mov out0=cr.ifa
 12.1003 -	adds out1=16,sp
 12.1004 -	mov out2=cr.isr		// FIXME: pity to make this slow access twice
 12.1005 -	mov out3=cr.iim		// FIXME: pity to make this slow access twice
 12.1006 -
 12.1007 -	ssm psr.ic | PSR_DEFAULT_BITS
 12.1008 -	;;
 12.1009 -	srlz.i					// guarantee that interruption collection is on
 12.1010 -	;;
 12.1011 -(p15)	ssm psr.i				// restore psr.i
 12.1012 -	adds r3=8,r2				// set up second base pointer
 12.1013 -	;;
 12.1014 -	SAVE_REST
 12.1015 -	movl r14=ia64_leave_kernel
 12.1016 -	;;
 12.1017 -	mov rp=r14
 12.1018 -	br.sptk.many ia64_prepare_handle_break
 12.1019 -END(dispatch_break_fault)
 12.1020 -#endif
 12.1021 -
 12.1022 -	.org ia64_ivt+0x3800
 12.1023 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1024 -// 0x3800 Entry 14 (size 64 bundles) Reserved
 12.1025 -	DBG_FAULT(14)
 12.1026 -	FAULT(14)
 12.1027 -
 12.1028 -	/*
 12.1029 -	 * There is no particular reason for this code to be here, other than that
 12.1030 -	 * there happens to be space here that would go unused otherwise.  If this
 12.1031 -	 * fault ever gets "unreserved", simply moved the following code to a more
 12.1032 -	 * suitable spot...
 12.1033 -	 *
 12.1034 -	 * ia64_syscall_setup() is a separate subroutine so that it can
 12.1035 -	 *	allocate stacked registers so it can safely demine any
 12.1036 -	 *	potential NaT values from the input registers.
 12.1037 -	 *
 12.1038 -	 * On entry:
 12.1039 -	 *	- executing on bank 0 or bank 1 register set (doesn't matter)
 12.1040 -	 *	-  r1: stack pointer
 12.1041 -	 *	-  r2: current task pointer
 12.1042 -	 *	-  r3: preserved
 12.1043 -	 *	- r11: original contents (saved ar.pfs to be saved)
 12.1044 -	 *	- r12: original contents (sp to be saved)
 12.1045 -	 *	- r13: original contents (tp to be saved)
 12.1046 -	 *	- r15: original contents (syscall # to be saved)
 12.1047 -	 *	- r18: saved bsp (after switching to kernel stack)
 12.1048 -	 *	- r19: saved b6
 12.1049 -	 *	- r20: saved r1 (gp)
 12.1050 -	 *	- r21: saved ar.fpsr
 12.1051 -	 *	- r22: kernel's register backing store base (krbs_base)
 12.1052 -	 *	- r23: saved ar.bspstore
 12.1053 -	 *	- r24: saved ar.rnat
 12.1054 -	 *	- r25: saved ar.unat
 12.1055 -	 *	- r26: saved ar.pfs
 12.1056 -	 *	- r27: saved ar.rsc
 12.1057 -	 *	- r28: saved cr.iip
 12.1058 -	 *	- r29: saved cr.ipsr
 12.1059 -	 *	- r31: saved pr
 12.1060 -	 *	-  b0: original contents (to be saved)
 12.1061 -	 * On exit:
 12.1062 -	 *	- executing on bank 1 registers
 12.1063 -	 *	- psr.ic enabled, interrupts restored
 12.1064 -	 *	-  p10: TRUE if syscall is invoked with more than 8 out
 12.1065 -	 *		registers or r15's Nat is true
 12.1066 -	 *	-  r1: kernel's gp
 12.1067 -	 *	-  r3: preserved (same as on entry)
 12.1068 -	 *	-  r8: -EINVAL if p10 is true
 12.1069 -	 *	- r12: points to kernel stack
 12.1070 -	 *	- r13: points to current task
 12.1071 -	 *	- p15: TRUE if interrupts need to be re-enabled
 12.1072 -	 *	- ar.fpsr: set to kernel settings
 12.1073 -	 */
 12.1074 -GLOBAL_ENTRY(ia64_syscall_setup)
 12.1075 -#ifndef XEN
 12.1076 -#if PT(B6) != 0
 12.1077 -# error This code assumes that b6 is the first field in pt_regs.
 12.1078 -#endif
 12.1079 -#endif
 12.1080 -	st8 [r1]=r19				// save b6
 12.1081 -	add r16=PT(CR_IPSR),r1			// initialize first base pointer
 12.1082 -	add r17=PT(R11),r1			// initialize second base pointer
 12.1083 -	;;
 12.1084 -	alloc r19=ar.pfs,8,0,0,0		// ensure in0-in7 are writable
 12.1085 -	st8 [r16]=r29,PT(AR_PFS)-PT(CR_IPSR)	// save cr.ipsr
 12.1086 -	tnat.nz p8,p0=in0
 12.1087 -
 12.1088 -	st8.spill [r17]=r11,PT(CR_IIP)-PT(R11)	// save r11
 12.1089 -	tnat.nz p9,p0=in1
 12.1090 -(pKStk)	mov r18=r0				// make sure r18 isn't NaT
 12.1091 -	;;
 12.1092 -
 12.1093 -	st8 [r16]=r26,PT(CR_IFS)-PT(AR_PFS)	// save ar.pfs
 12.1094 -	st8 [r17]=r28,PT(AR_UNAT)-PT(CR_IIP)	// save cr.iip
 12.1095 -	mov r28=b0				// save b0 (2 cyc)
 12.1096 -	;;
 12.1097 -
 12.1098 -	st8 [r17]=r25,PT(AR_RSC)-PT(AR_UNAT)	// save ar.unat
 12.1099 -	dep r19=0,r19,38,26			// clear all bits but 0..37 [I0]
 12.1100 -(p8)	mov in0=-1
 12.1101 -	;;
 12.1102 -
 12.1103 -	st8 [r16]=r19,PT(AR_RNAT)-PT(CR_IFS)	// store ar.pfs.pfm in cr.ifs
 12.1104 -	extr.u r11=r19,7,7	// I0		// get sol of ar.pfs
 12.1105 -	and r8=0x7f,r19		// A		// get sof of ar.pfs
 12.1106 -
 12.1107 -	st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc
 12.1108 -	tbit.nz p15,p0=r29,IA64_PSR_I_BIT // I0
 12.1109 -(p9)	mov in1=-1
 12.1110 -	;;
 12.1111 -
 12.1112 -(pUStk) sub r18=r18,r22				// r18=RSE.ndirty*8
 12.1113 -	tnat.nz p10,p0=in2
 12.1114 -	add r11=8,r11
 12.1115 -	;;
 12.1116 -(pKStk) adds r16=PT(PR)-PT(AR_RNAT),r16		// skip over ar_rnat field
 12.1117 -(pKStk) adds r17=PT(B0)-PT(AR_BSPSTORE),r17	// skip over ar_bspstore field
 12.1118 -	tnat.nz p11,p0=in3
 12.1119 -	;;
 12.1120 -(p10)	mov in2=-1
 12.1121 -	tnat.nz p12,p0=in4				// [I0]
 12.1122 -(p11)	mov in3=-1
 12.1123 -	;;
 12.1124 -(pUStk) st8 [r16]=r24,PT(PR)-PT(AR_RNAT)	// save ar.rnat
 12.1125 -(pUStk) st8 [r17]=r23,PT(B0)-PT(AR_BSPSTORE)	// save ar.bspstore
 12.1126 -	shl r18=r18,16				// compute ar.rsc to be used for "loadrs"
 12.1127 -	;;
 12.1128 -	st8 [r16]=r31,PT(LOADRS)-PT(PR)		// save predicates
 12.1129 -	st8 [r17]=r28,PT(R1)-PT(B0)		// save b0
 12.1130 -	tnat.nz p13,p0=in5				// [I0]
 12.1131 -	;;
 12.1132 -	st8 [r16]=r18,PT(R12)-PT(LOADRS)	// save ar.rsc value for "loadrs"
 12.1133 -	st8.spill [r17]=r20,PT(R13)-PT(R1)	// save original r1
 12.1134 -(p12)	mov in4=-1
 12.1135 -	;;
 12.1136 -
 12.1137 -.mem.offset 0,0; st8.spill [r16]=r12,PT(AR_FPSR)-PT(R12)	// save r12
 12.1138 -.mem.offset 8,0; st8.spill [r17]=r13,PT(R15)-PT(R13)		// save r13
 12.1139 -(p13)	mov in5=-1
 12.1140 -	;;
 12.1141 -	st8 [r16]=r21,PT(R8)-PT(AR_FPSR)	// save ar.fpsr
 12.1142 -	tnat.nz p14,p0=in6
 12.1143 -	cmp.lt p10,p9=r11,r8	// frame size can't be more than local+8
 12.1144 -	;;
 12.1145 -	stf8 [r16]=f1		// ensure pt_regs.r8 != 0 (see handle_syscall_error)
 12.1146 -(p9)	tnat.nz p10,p0=r15
 12.1147 -	adds r12=-16,r1		// switch to kernel memory stack (with 16 bytes of scratch)
 12.1148 -
 12.1149 -	st8.spill [r17]=r15			// save r15
 12.1150 -	tnat.nz p8,p0=in7
 12.1151 -	nop.i 0
 12.1152 -
 12.1153 -	mov r13=r2				// establish `current'
 12.1154 -	movl r1=__gp				// establish kernel global pointer
 12.1155 -	;;
 12.1156 -(p14)	mov in6=-1
 12.1157 -(p8)	mov in7=-1
 12.1158 -	nop.i 0
 12.1159 -
 12.1160 -	cmp.eq pSys,pNonSys=r0,r0		// set pSys=1, pNonSys=0
 12.1161 -	movl r17=FPSR_DEFAULT
 12.1162 -	;;
 12.1163 -	mov.m ar.fpsr=r17			// set ar.fpsr to kernel default value
 12.1164 -(p10)	mov r8=-EINVAL
 12.1165 -	br.ret.sptk.many b7
 12.1166 -END(ia64_syscall_setup)
 12.1167 -
 12.1168 -	.org ia64_ivt+0x3c00
 12.1169 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1170 -// 0x3c00 Entry 15 (size 64 bundles) Reserved
 12.1171 -	DBG_FAULT(15)
 12.1172 -	FAULT(15)
 12.1173 -
 12.1174 -	/*
 12.1175 -	 * Squatting in this space ...
 12.1176 -	 *
 12.1177 -	 * This special case dispatcher for illegal operation faults allows preserved
 12.1178 -	 * registers to be modified through a callback function (asm only) that is handed
 12.1179 -	 * back from the fault handler in r8. Up to three arguments can be passed to the
 12.1180 -	 * callback function by returning an aggregate with the callback as its first
 12.1181 -	 * element, followed by the arguments.
 12.1182 -	 */
 12.1183 -ENTRY(dispatch_illegal_op_fault)
 12.1184 -	SAVE_MIN_WITH_COVER
 12.1185 -	ssm psr.ic | PSR_DEFAULT_BITS
 12.1186 -	;;
 12.1187 -	srlz.i		// guarantee that interruption collection is on
 12.1188 -	;;
 12.1189 -(p15)	ssm psr.i	// restore psr.i
 12.1190 -	adds r3=8,r2	// set up second base pointer for SAVE_REST
 12.1191 -	;;
 12.1192 -	alloc r14=ar.pfs,0,0,1,0	// must be first in insn group
 12.1193 -	mov out0=ar.ec
 12.1194 -	;;
 12.1195 -	SAVE_REST
 12.1196 -	;;
 12.1197 -	br.call.sptk.many rp=ia64_illegal_op_fault
 12.1198 -.ret0:	;;
 12.1199 -	alloc r14=ar.pfs,0,0,3,0	// must be first in insn group
 12.1200 -	mov out0=r9
 12.1201 -	mov out1=r10
 12.1202 -	mov out2=r11
 12.1203 -	movl r15=ia64_leave_kernel
 12.1204 -	;;
 12.1205 -	mov rp=r15
 12.1206 -	mov b6=r8
 12.1207 -	;;
 12.1208 -	cmp.ne p6,p0=0,r8
 12.1209 -(p6)	br.call.dpnt.many b6=b6		// call returns to ia64_leave_kernel
 12.1210 -	br.sptk.many ia64_leave_kernel
 12.1211 -END(dispatch_illegal_op_fault)
 12.1212 -
 12.1213 -	.org ia64_ivt+0x4000
 12.1214 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1215 -// 0x4000 Entry 16 (size 64 bundles) Reserved
 12.1216 -	DBG_FAULT(16)
 12.1217 -	FAULT(16)
 12.1218 -
 12.1219 -#ifdef XEN
 12.1220 -	// There is no particular reason for this code to be here, other than that
 12.1221 -	// there happens to be space here that would go unused otherwise.  If this
 12.1222 -	// fault ever gets "unreserved", simply moved the following code to a more
 12.1223 -	// suitable spot...
 12.1224 -
 12.1225 -ENTRY(dispatch_privop_fault)
 12.1226 -	SAVE_MIN_WITH_COVER
 12.1227 -	;;
 12.1228 -	alloc r14=ar.pfs,0,0,4,0		// now it's safe (must be first in insn group!)
 12.1229 -	mov out0=cr.ifa
 12.1230 -	adds out1=16,sp
 12.1231 -	mov out2=cr.isr		// FIXME: pity to make this slow access twice
 12.1232 -	mov out3=cr.itir
 12.1233 -
 12.1234 -	ssm psr.ic | PSR_DEFAULT_BITS
 12.1235 -	;;
 12.1236 -	srlz.i					// guarantee that interruption collection is on
 12.1237 -	;;
 12.1238 -(p15)	ssm psr.i				// restore psr.i
 12.1239 -	adds r3=8,r2				// set up second base pointer
 12.1240 -	;;
 12.1241 -	SAVE_REST
 12.1242 -	movl r14=ia64_leave_kernel
 12.1243 -	;;
 12.1244 -	mov rp=r14
 12.1245 -	br.sptk.many ia64_prepare_handle_privop
 12.1246 -END(dispatch_privop_fault)
 12.1247 -#endif
 12.1248 -
 12.1249 -
 12.1250 -	.org ia64_ivt+0x4400
 12.1251 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1252 -// 0x4400 Entry 17 (size 64 bundles) Reserved
 12.1253 -	DBG_FAULT(17)
 12.1254 -	FAULT(17)
 12.1255 -
 12.1256 -ENTRY(non_syscall)
 12.1257 -	SAVE_MIN_WITH_COVER
 12.1258 -
 12.1259 -	// There is no particular reason for this code to be here, other than that
 12.1260 -	// there happens to be space here that would go unused otherwise.  If this
 12.1261 -	// fault ever gets "unreserved", simply moved the following code to a more
 12.1262 -	// suitable spot...
 12.1263 -
 12.1264 -	alloc r14=ar.pfs,0,0,2,0
 12.1265 -	mov out0=cr.iim
 12.1266 -	add out1=16,sp
 12.1267 -	adds r3=8,r2			// set up second base pointer for SAVE_REST
 12.1268 -
 12.1269 -	ssm psr.ic | PSR_DEFAULT_BITS
 12.1270 -	;;
 12.1271 -	srlz.i				// guarantee that interruption collection is on
 12.1272 -	;;
 12.1273 -(p15)	ssm psr.i			// restore psr.i
 12.1274 -	movl r15=ia64_leave_kernel
 12.1275 -	;;
 12.1276 -	SAVE_REST
 12.1277 -	mov rp=r15
 12.1278 -	;;
 12.1279 -	br.call.sptk.many b6=ia64_bad_break	// avoid WAW on CFM and ignore return addr
 12.1280 -END(non_syscall)
 12.1281 -
 12.1282 -	.org ia64_ivt+0x4800
 12.1283 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1284 -// 0x4800 Entry 18 (size 64 bundles) Reserved
 12.1285 -	DBG_FAULT(18)
 12.1286 -	FAULT(18)
 12.1287 -
 12.1288 -	/*
 12.1289 -	 * There is no particular reason for this code to be here, other than that
 12.1290 -	 * there happens to be space here that would go unused otherwise.  If this
 12.1291 -	 * fault ever gets "unreserved", simply moved the following code to a more
 12.1292 -	 * suitable spot...
 12.1293 -	 */
 12.1294 -
 12.1295 -ENTRY(dispatch_unaligned_handler)
 12.1296 -	SAVE_MIN_WITH_COVER
 12.1297 -	;;
 12.1298 -	alloc r14=ar.pfs,0,0,2,0		// now it's safe (must be first in insn group!)
 12.1299 -	mov out0=cr.ifa
 12.1300 -	adds out1=16,sp
 12.1301 -
 12.1302 -	ssm psr.ic | PSR_DEFAULT_BITS
 12.1303 -	;;
 12.1304 -	srlz.i					// guarantee that interruption collection is on
 12.1305 -	;;
 12.1306 -(p15)	ssm psr.i				// restore psr.i
 12.1307 -	adds r3=8,r2				// set up second base pointer
 12.1308 -	;;
 12.1309 -	SAVE_REST
 12.1310 -	movl r14=ia64_leave_kernel
 12.1311 -	;;
 12.1312 -	mov rp=r14
 12.1313 -	br.sptk.many ia64_prepare_handle_unaligned
 12.1314 -END(dispatch_unaligned_handler)
 12.1315 -
 12.1316 -	.org ia64_ivt+0x4c00
 12.1317 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1318 -// 0x4c00 Entry 19 (size 64 bundles) Reserved
 12.1319 -	DBG_FAULT(19)
 12.1320 -	FAULT(19)
 12.1321 -
 12.1322 -	/*
 12.1323 -	 * There is no particular reason for this code to be here, other than that
 12.1324 -	 * there happens to be space here that would go unused otherwise.  If this
 12.1325 -	 * fault ever gets "unreserved", simply moved the following code to a more
 12.1326 -	 * suitable spot...
 12.1327 -	 */
 12.1328 -
 12.1329 -ENTRY(dispatch_to_fault_handler)
 12.1330 -	/*
 12.1331 -	 * Input:
 12.1332 -	 *	psr.ic:	off
 12.1333 -	 *	r19:	fault vector number (e.g., 24 for General Exception)
 12.1334 -	 *	r31:	contains saved predicates (pr)
 12.1335 -	 */
 12.1336 -	SAVE_MIN_WITH_COVER_R19
 12.1337 -	alloc r14=ar.pfs,0,0,5,0
 12.1338 -	mov out0=r15
 12.1339 -	mov out1=cr.isr
 12.1340 -	mov out2=cr.ifa
 12.1341 -	mov out3=cr.iim
 12.1342 -	mov out4=cr.itir
 12.1343 -	;;
 12.1344 -	ssm psr.ic | PSR_DEFAULT_BITS
 12.1345 -	;;
 12.1346 -	srlz.i					// guarantee that interruption collection is on
 12.1347 -	;;
 12.1348 -(p15)	ssm psr.i				// restore psr.i
 12.1349 -	adds r3=8,r2				// set up second base pointer for SAVE_REST
 12.1350 -	;;
 12.1351 -	SAVE_REST
 12.1352 -	movl r14=ia64_leave_kernel
 12.1353 -	;;
 12.1354 -	mov rp=r14
 12.1355 -	br.call.sptk.many b6=ia64_fault
 12.1356 -END(dispatch_to_fault_handler)
 12.1357 -
 12.1358 -//
 12.1359 -// --- End of long entries, Beginning of short entries
 12.1360 -//
 12.1361 -
 12.1362 -	.org ia64_ivt+0x5000
 12.1363 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1364 -// 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49)
 12.1365 -ENTRY(page_not_present)
 12.1366 -#ifdef XEN
 12.1367 -	REFLECT(20)
 12.1368 -#endif
 12.1369 -	DBG_FAULT(20)
 12.1370 -	mov r16=cr.ifa
 12.1371 -	rsm psr.dt
 12.1372 -	/*
 12.1373 -	 * The Linux page fault handler doesn't expect non-present pages to be in
 12.1374 -	 * the TLB.  Flush the existing entry now, so we meet that expectation.
 12.1375 -	 */
 12.1376 -	mov r17=PAGE_SHIFT<<2
 12.1377 -	;;
 12.1378 -	ptc.l r16,r17
 12.1379 -	;;
 12.1380 -	mov r31=pr
 12.1381 -	srlz.d
 12.1382 -	br.sptk.many page_fault
 12.1383 -END(page_not_present)
 12.1384 -
 12.1385 -	.org ia64_ivt+0x5100
 12.1386 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1387 -// 0x5100 Entry 21 (size 16 bundles) Key Permission (13,25,52)
 12.1388 -ENTRY(key_permission)
 12.1389 -#ifdef XEN
 12.1390 -	REFLECT(21)
 12.1391 -#endif
 12.1392 -	DBG_FAULT(21)
 12.1393 -	mov r16=cr.ifa
 12.1394 -	rsm psr.dt
 12.1395 -	mov r31=pr
 12.1396 -	;;
 12.1397 -	srlz.d
 12.1398 -	br.sptk.many page_fault
 12.1399 -END(key_permission)
 12.1400 -
 12.1401 -	.org ia64_ivt+0x5200
 12.1402 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1403 -// 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26)
 12.1404 -ENTRY(iaccess_rights)
 12.1405 -#ifdef XEN
 12.1406 -	REFLECT(22)
 12.1407 -#endif
 12.1408 -	DBG_FAULT(22)
 12.1409 -	mov r16=cr.ifa
 12.1410 -	rsm psr.dt
 12.1411 -	mov r31=pr
 12.1412 -	;;
 12.1413 -	srlz.d
 12.1414 -	br.sptk.many page_fault
 12.1415 -END(iaccess_rights)
 12.1416 -
 12.1417 -	.org ia64_ivt+0x5300
 12.1418 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1419 -// 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53)
 12.1420 -ENTRY(daccess_rights)
 12.1421 -#ifdef XEN
 12.1422 -	mov r31=pr;
 12.1423 -	mov r16=cr.isr
 12.1424 -	mov r17=cr.ifa
 12.1425 -	mov r19=23
 12.1426 -	movl r20=0x5300
 12.1427 -	br.sptk.many fast_access_reflect;;
 12.1428 -#endif
 12.1429 -	DBG_FAULT(23)
 12.1430 -	mov r16=cr.ifa
 12.1431 -	rsm psr.dt
 12.1432 -	mov r31=pr
 12.1433 -	;;
 12.1434 -	srlz.d
 12.1435 -	br.sptk.many page_fault
 12.1436 -END(daccess_rights)
 12.1437 -
 12.1438 -	.org ia64_ivt+0x5400
 12.1439 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1440 -// 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39)
 12.1441 -ENTRY(general_exception)
 12.1442 -	DBG_FAULT(24)
 12.1443 -	mov r16=cr.isr
 12.1444 -	mov r31=pr
 12.1445 -	;;
 12.1446 -#ifdef XEN
 12.1447 -	cmp4.ge p6,p0=0x20,r16
 12.1448 -(p6)	br.sptk.many dispatch_privop_fault
 12.1449 -#else
 12.1450 -	cmp4.eq p6,p0=0,r16
 12.1451 -(p6)	br.sptk.many dispatch_illegal_op_fault
 12.1452 -#endif
 12.1453 -	;;
 12.1454 -	mov r19=24		// fault number
 12.1455 -	br.sptk.many dispatch_to_fault_handler
 12.1456 -END(general_exception)
 12.1457 -
 12.1458 -	.org ia64_ivt+0x5500
 12.1459 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1460 -// 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35)
 12.1461 -ENTRY(disabled_fp_reg)
 12.1462 -#ifdef XEN
 12.1463 -	REFLECT(25)
 12.1464 -#endif
 12.1465 -	DBG_FAULT(25)
 12.1466 -	rsm psr.dfh		// ensure we can access fph
 12.1467 -	;;
 12.1468 -	srlz.d
 12.1469 -	mov r31=pr
 12.1470 -	mov r19=25
 12.1471 -	br.sptk.many dispatch_to_fault_handler
 12.1472 -END(disabled_fp_reg)
 12.1473 -
 12.1474 -	.org ia64_ivt+0x5600
 12.1475 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1476 -// 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50)
 12.1477 -ENTRY(nat_consumption)
 12.1478 -#ifdef XEN
 12.1479 -	REFLECT(26)
 12.1480 -#endif
 12.1481 -	DBG_FAULT(26)
 12.1482 -	FAULT(26)
 12.1483 -END(nat_consumption)
 12.1484 -
 12.1485 -	.org ia64_ivt+0x5700
 12.1486 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1487 -// 0x5700 Entry 27 (size 16 bundles) Speculation (40)
 12.1488 -ENTRY(speculation_vector)
 12.1489 -#ifdef XEN
 12.1490 -	// this probably need not reflect...
 12.1491 -	REFLECT(27)
 12.1492 -#endif
 12.1493 -	DBG_FAULT(27)
 12.1494 -	/*
 12.1495 -	 * A [f]chk.[as] instruction needs to take the branch to the recovery code but
 12.1496 -	 * this part of the architecture is not implemented in hardware on some CPUs, such
 12.1497 -	 * as Itanium.  Thus, in general we need to emulate the behavior.  IIM contains
 12.1498 -	 * the relative target (not yet sign extended).  So after sign extending it we
 12.1499 -	 * simply add it to IIP.  We also need to reset the EI field of the IPSR to zero,
 12.1500 -	 * i.e., the slot to restart into.
 12.1501 -	 *
 12.1502 -	 * cr.imm contains zero_ext(imm21)
 12.1503 -	 */
 12.1504 -	mov r18=cr.iim
 12.1505 -	;;
 12.1506 -	mov r17=cr.iip
 12.1507 -	shl r18=r18,43			// put sign bit in position (43=64-21)
 12.1508 -	;;
 12.1509 -
 12.1510 -	mov r16=cr.ipsr
 12.1511 -	shr r18=r18,39			// sign extend (39=43-4)
 12.1512 -	;;
 12.1513 -
 12.1514 -	add r17=r17,r18			// now add the offset
 12.1515 -	;;
 12.1516 -	mov cr.iip=r17
 12.1517 -	dep r16=0,r16,41,2		// clear EI
 12.1518 -	;;
 12.1519 -
 12.1520 -	mov cr.ipsr=r16
 12.1521 -	;;
 12.1522 -
 12.1523 -	rfi				// and go back
 12.1524 -END(speculation_vector)
 12.1525 -
 12.1526 -	.org ia64_ivt+0x5800
 12.1527 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1528 -// 0x5800 Entry 28 (size 16 bundles) Reserved
 12.1529 -	DBG_FAULT(28)
 12.1530 -	FAULT(28)
 12.1531 -
 12.1532 -	.org ia64_ivt+0x5900
 12.1533 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1534 -// 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56)
 12.1535 -ENTRY(debug_vector)
 12.1536 -#ifdef XEN
 12.1537 -	REFLECT(29)
 12.1538 -#endif
 12.1539 -	DBG_FAULT(29)
 12.1540 -	FAULT(29)
 12.1541 -END(debug_vector)
 12.1542 -
 12.1543 -	.org ia64_ivt+0x5a00
 12.1544 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1545 -// 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57)
 12.1546 -ENTRY(unaligned_access)
 12.1547 -#ifdef XEN
 12.1548 -	REFLECT(30)
 12.1549 -#endif
 12.1550 -	DBG_FAULT(30)
 12.1551 -	mov r16=cr.ipsr
 12.1552 -	mov r31=pr		// prepare to save predicates
 12.1553 -	;;
 12.1554 -	br.sptk.many dispatch_unaligned_handler
 12.1555 -END(unaligned_access)
 12.1556 -
 12.1557 -	.org ia64_ivt+0x5b00
 12.1558 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1559 -// 0x5b00 Entry 31 (size 16 bundles) Unsupported Data Reference (57)
 12.1560 -ENTRY(unsupported_data_reference)
 12.1561 -#ifdef XEN
 12.1562 -	REFLECT(31)
 12.1563 -#endif
 12.1564 -	DBG_FAULT(31)
 12.1565 -	FAULT(31)
 12.1566 -END(unsupported_data_reference)
 12.1567 -
 12.1568 -	.org ia64_ivt+0x5c00
 12.1569 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1570 -// 0x5c00 Entry 32 (size 16 bundles) Floating-Point Fault (64)
 12.1571 -ENTRY(floating_point_fault)
 12.1572 -#ifdef XEN
 12.1573 -	REFLECT(32)
 12.1574 -#endif
 12.1575 -	DBG_FAULT(32)
 12.1576 -	FAULT(32)
 12.1577 -END(floating_point_fault)
 12.1578 -
 12.1579 -	.org ia64_ivt+0x5d00
 12.1580 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1581 -// 0x5d00 Entry 33 (size 16 bundles) Floating Point Trap (66)
 12.1582 -ENTRY(floating_point_trap)
 12.1583 -#ifdef XEN
 12.1584 -	REFLECT(33)
 12.1585 -#endif
 12.1586 -	DBG_FAULT(33)
 12.1587 -	FAULT(33)
 12.1588 -END(floating_point_trap)
 12.1589 -
 12.1590 -	.org ia64_ivt+0x5e00
 12.1591 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1592 -// 0x5e00 Entry 34 (size 16 bundles) Lower Privilege Transfer Trap (66)
 12.1593 -ENTRY(lower_privilege_trap)
 12.1594 -#ifdef XEN
 12.1595 -	REFLECT(34)
 12.1596 -#endif
 12.1597 -	DBG_FAULT(34)
 12.1598 -	FAULT(34)
 12.1599 -END(lower_privilege_trap)
 12.1600 -
 12.1601 -	.org ia64_ivt+0x5f00
 12.1602 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1603 -// 0x5f00 Entry 35 (size 16 bundles) Taken Branch Trap (68)
 12.1604 -ENTRY(taken_branch_trap)
 12.1605 -#ifdef XEN
 12.1606 -	REFLECT(35)
 12.1607 -#endif
 12.1608 -	DBG_FAULT(35)
 12.1609 -	FAULT(35)
 12.1610 -END(taken_branch_trap)
 12.1611 -
 12.1612 -	.org ia64_ivt+0x6000
 12.1613 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1614 -// 0x6000 Entry 36 (size 16 bundles) Single Step Trap (69)
 12.1615 -ENTRY(single_step_trap)
 12.1616 -#ifdef XEN
 12.1617 -	REFLECT(36)
 12.1618 -#endif
 12.1619 -	DBG_FAULT(36)
 12.1620 -	FAULT(36)
 12.1621 -END(single_step_trap)
 12.1622 -
 12.1623 -	.org ia64_ivt+0x6100
 12.1624 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1625 -// 0x6100 Entry 37 (size 16 bundles) Reserved
 12.1626 -	DBG_FAULT(37)
 12.1627 -	FAULT(37)
 12.1628 -
 12.1629 -	.org ia64_ivt+0x6200
 12.1630 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1631 -// 0x6200 Entry 38 (size 16 bundles) Reserved
 12.1632 -	DBG_FAULT(38)
 12.1633 -	FAULT(38)
 12.1634 -
 12.1635 -	.org ia64_ivt+0x6300
 12.1636 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1637 -// 0x6300 Entry 39 (size 16 bundles) Reserved
 12.1638 -	DBG_FAULT(39)
 12.1639 -	FAULT(39)
 12.1640 -
 12.1641 -	.org ia64_ivt+0x6400
 12.1642 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1643 -// 0x6400 Entry 40 (size 16 bundles) Reserved
 12.1644 -	DBG_FAULT(40)
 12.1645 -	FAULT(40)
 12.1646 -
 12.1647 -	.org ia64_ivt+0x6500
 12.1648 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1649 -// 0x6500 Entry 41 (size 16 bundles) Reserved
 12.1650 -	DBG_FAULT(41)
 12.1651 -	FAULT(41)
 12.1652 -
 12.1653 -	.org ia64_ivt+0x6600
 12.1654 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1655 -// 0x6600 Entry 42 (size 16 bundles) Reserved
 12.1656 -	DBG_FAULT(42)
 12.1657 -	FAULT(42)
 12.1658 -
 12.1659 -	.org ia64_ivt+0x6700
 12.1660 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1661 -// 0x6700 Entry 43 (size 16 bundles) Reserved
 12.1662 -	DBG_FAULT(43)
 12.1663 -	FAULT(43)
 12.1664 -
 12.1665 -	.org ia64_ivt+0x6800
 12.1666 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1667 -// 0x6800 Entry 44 (size 16 bundles) Reserved
 12.1668 -	DBG_FAULT(44)
 12.1669 -	FAULT(44)
 12.1670 -
 12.1671 -	.org ia64_ivt+0x6900
 12.1672 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1673 -// 0x6900 Entry 45 (size 16 bundles) IA-32 Exeception (17,18,29,41,42,43,44,58,60,61,62,72,73,75,76,77)
 12.1674 -ENTRY(ia32_exception)
 12.1675 -#ifdef XEN
 12.1676 -	REFLECT(45)
 12.1677 -#endif
 12.1678 -	DBG_FAULT(45)
 12.1679 -	FAULT(45)
 12.1680 -END(ia32_exception)
 12.1681 -
 12.1682 -	.org ia64_ivt+0x6a00
 12.1683 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1684 -// 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept  (30,31,59,70,71)
 12.1685 -ENTRY(ia32_intercept)
 12.1686 -#ifdef XEN
 12.1687 -	REFLECT(46)
 12.1688 -#endif
 12.1689 -	DBG_FAULT(46)
 12.1690 -#ifdef	CONFIG_IA32_SUPPORT
 12.1691 -	mov r31=pr
 12.1692 -	mov r16=cr.isr
 12.1693 -	;;
 12.1694 -	extr.u r17=r16,16,8	// get ISR.code
 12.1695 -	mov r18=ar.eflag
 12.1696 -	mov r19=cr.iim		// old eflag value
 12.1697 -	;;
 12.1698 -	cmp.ne p6,p0=2,r17
 12.1699 -(p6)	br.cond.spnt 1f		// not a system flag fault
 12.1700 -	xor r16=r18,r19
 12.1701 -	;;
 12.1702 -	extr.u r17=r16,18,1	// get the eflags.ac bit
 12.1703 -	;;
 12.1704 -	cmp.eq p6,p0=0,r17
 12.1705 -(p6)	br.cond.spnt 1f		// eflags.ac bit didn't change
 12.1706 -	;;
 12.1707 -	mov pr=r31,-1		// restore predicate registers
 12.1708 -	rfi
 12.1709 -
 12.1710 -1:
 12.1711 -#endif	// CONFIG_IA32_SUPPORT
 12.1712 -	FAULT(46)
 12.1713 -END(ia32_intercept)
 12.1714 -
 12.1715 -	.org ia64_ivt+0x6b00
 12.1716 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1717 -// 0x6b00 Entry 47 (size 16 bundles) IA-32 Interrupt  (74)
 12.1718 -ENTRY(ia32_interrupt)
 12.1719 -#ifdef XEN
 12.1720 -	REFLECT(47)
 12.1721 -#endif
 12.1722 -	DBG_FAULT(47)
 12.1723 -#ifdef CONFIG_IA32_SUPPORT
 12.1724 -	mov r31=pr
 12.1725 -	br.sptk.many dispatch_to_ia32_handler
 12.1726 -#else
 12.1727 -	FAULT(47)
 12.1728 -#endif
 12.1729 -END(ia32_interrupt)
 12.1730 -
 12.1731 -	.org ia64_ivt+0x6c00
 12.1732 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1733 -// 0x6c00 Entry 48 (size 16 bundles) Reserved
 12.1734 -	DBG_FAULT(48)
 12.1735 -	FAULT(48)
 12.1736 -
 12.1737 -	.org ia64_ivt+0x6d00
 12.1738 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1739 -// 0x6d00 Entry 49 (size 16 bundles) Reserved
 12.1740 -	DBG_FAULT(49)
 12.1741 -	FAULT(49)
 12.1742 -
 12.1743 -	.org ia64_ivt+0x6e00
 12.1744 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1745 -// 0x6e00 Entry 50 (size 16 bundles) Reserved
 12.1746 -	DBG_FAULT(50)
 12.1747 -	FAULT(50)
 12.1748 -
 12.1749 -	.org ia64_ivt+0x6f00
 12.1750 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1751 -// 0x6f00 Entry 51 (size 16 bundles) Reserved
 12.1752 -	DBG_FAULT(51)
 12.1753 -	FAULT(51)
 12.1754 -
 12.1755 -	.org ia64_ivt+0x7000
 12.1756 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1757 -// 0x7000 Entry 52 (size 16 bundles) Reserved
 12.1758 -	DBG_FAULT(52)
 12.1759 -	FAULT(52)
 12.1760 -
 12.1761 -	.org ia64_ivt+0x7100
 12.1762 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1763 -// 0x7100 Entry 53 (size 16 bundles) Reserved
 12.1764 -	DBG_FAULT(53)
 12.1765 -	FAULT(53)
 12.1766 -
 12.1767 -	.org ia64_ivt+0x7200
 12.1768 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1769 -// 0x7200 Entry 54 (size 16 bundles) Reserved
 12.1770 -	DBG_FAULT(54)
 12.1771 -	FAULT(54)
 12.1772 -
 12.1773 -	.org ia64_ivt+0x7300
 12.1774 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1775 -// 0x7300 Entry 55 (size 16 bundles) Reserved
 12.1776 -	DBG_FAULT(55)
 12.1777 -	FAULT(55)
 12.1778 -
 12.1779 -	.org ia64_ivt+0x7400
 12.1780 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1781 -// 0x7400 Entry 56 (size 16 bundles) Reserved
 12.1782 -	DBG_FAULT(56)
 12.1783 -	FAULT(56)
 12.1784 -
 12.1785 -	.org ia64_ivt+0x7500
 12.1786 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1787 -// 0x7500 Entry 57 (size 16 bundles) Reserved
 12.1788 -	DBG_FAULT(57)
 12.1789 -	FAULT(57)
 12.1790 -
 12.1791 -	.org ia64_ivt+0x7600
 12.1792 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1793 -// 0x7600 Entry 58 (size 16 bundles) Reserved
 12.1794 -	DBG_FAULT(58)
 12.1795 -	FAULT(58)
 12.1796 -
 12.1797 -	.org ia64_ivt+0x7700
 12.1798 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1799 -// 0x7700 Entry 59 (size 16 bundles) Reserved
 12.1800 -	DBG_FAULT(59)
 12.1801 -	FAULT(59)
 12.1802 -
 12.1803 -	.org ia64_ivt+0x7800
 12.1804 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1805 -// 0x7800 Entry 60 (size 16 bundles) Reserved
 12.1806 -	DBG_FAULT(60)
 12.1807 -	FAULT(60)
 12.1808 -
 12.1809 -	.org ia64_ivt+0x7900
 12.1810 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1811 -// 0x7900 Entry 61 (size 16 bundles) Reserved
 12.1812 -	DBG_FAULT(61)
 12.1813 -	FAULT(61)
 12.1814 -
 12.1815 -	.org ia64_ivt+0x7a00
 12.1816 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1817 -// 0x7a00 Entry 62 (size 16 bundles) Reserved
 12.1818 -	DBG_FAULT(62)
 12.1819 -	FAULT(62)
 12.1820 -
 12.1821 -	.org ia64_ivt+0x7b00
 12.1822 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1823 -// 0x7b00 Entry 63 (size 16 bundles) Reserved
 12.1824 -	DBG_FAULT(63)
 12.1825 -	FAULT(63)
 12.1826 -
 12.1827 -	.org ia64_ivt+0x7c00
 12.1828 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1829 -// 0x7c00 Entry 64 (size 16 bundles) Reserved
 12.1830 -	DBG_FAULT(64)
 12.1831 -	FAULT(64)
 12.1832 -
 12.1833 -	.org ia64_ivt+0x7d00
 12.1834 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1835 -// 0x7d00 Entry 65 (size 16 bundles) Reserved
 12.1836 -	DBG_FAULT(65)
 12.1837 -	FAULT(65)
 12.1838 -
 12.1839 -	.org ia64_ivt+0x7e00
 12.1840 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1841 -// 0x7e00 Entry 66 (size 16 bundles) Reserved
 12.1842 -	DBG_FAULT(66)
 12.1843 -	FAULT(66)
 12.1844 -
 12.1845 -	.org ia64_ivt+0x7f00
 12.1846 -/////////////////////////////////////////////////////////////////////////////////////////
 12.1847 -// 0x7f00 Entry 67 (size 16 bundles) Reserved
 12.1848 -	DBG_FAULT(67)
 12.1849 -	FAULT(67)
 12.1850 -
 12.1851 -#ifdef XEN
 12.1852 -	.org ia64_ivt+0x8000
 12.1853 -GLOBAL_ENTRY(dispatch_reflection)
 12.1854 -	/*
 12.1855 -	 * Input:
 12.1856 -	 *	psr.ic:	off
 12.1857 -	 *	r19:	intr type (offset into ivt, see ia64_int.h)
 12.1858 -	 *	r31:	contains saved predicates (pr)
 12.1859 -	 */
 12.1860 -	SAVE_MIN_WITH_COVER_R19
 12.1861 -	alloc r14=ar.pfs,0,0,5,0
 12.1862 -	mov out4=r15
 12.1863 -	mov out0=cr.ifa
 12.1864 -	adds out1=16,sp
 12.1865 -	mov out2=cr.isr
 12.1866 -	mov out3=cr.iim
 12.1867 -//	mov out3=cr.itir
 12.1868 -
 12.1869 -	ssm psr.ic | PSR_DEFAULT_BITS
 12.1870 -	;;
 12.1871 -	srlz.i					// guarantee that interruption collection is on
 12.1872 -	;;
 12.1873 -(p15)	ssm psr.i				// restore psr.i
 12.1874 -	adds r3=8,r2				// set up second base pointer
 12.1875 -	;;
 12.1876 -	SAVE_REST
 12.1877 -	movl r14=ia64_leave_kernel
 12.1878 -	;;
 12.1879 -	mov rp=r14
 12.1880 -	br.sptk.many ia64_prepare_handle_reflection
 12.1881 -END(dispatch_reflection)
 12.1882 -
 12.1883 -#define SAVE_MIN_COVER_DONE	DO_SAVE_MIN(,mov r30=cr.ifs,)
 12.1884 -
 12.1885 -// same as dispatch_break_fault except cover has already been done
 12.1886 -GLOBAL_ENTRY(dispatch_slow_hyperprivop)
 12.1887 -	SAVE_MIN_COVER_DONE
 12.1888 -	;;
 12.1889 -	br.sptk.many dispatch_break_fault_post_save
 12.1890 -END(dispatch_slow_hyperprivop)
 12.1891 -#endif
 12.1892 -
 12.1893 -#ifdef CONFIG_IA32_SUPPORT
 12.1894 -
 12.1895 -	/*
 12.1896 -	 * There is no particular reason for this code to be here, other than that
 12.1897 -	 * there happens to be space here that would go unused otherwise.  If this
 12.1898 -	 * fault ever gets "unreserved", simply moved the following code to a more
 12.1899 -	 * suitable spot...
 12.1900 -	 */
 12.1901 -
 12.1902 -	// IA32 interrupt entry point
 12.1903 -
 12.1904 -ENTRY(dispatch_to_ia32_handler)
 12.1905 -	SAVE_MIN
 12.1906 -	;;
 12.1907 -	mov r14=cr.isr
 12.1908 -	ssm psr.ic | PSR_DEFAULT_BITS
 12.1909 -	;;
 12.1910 -	srlz.i					// guarantee that interruption collection is on
 12.1911 -	;;
 12.1912 -(p15)	ssm psr.i
 12.1913 -	adds r3=8,r2		// Base pointer for SAVE_REST
 12.1914 -	;;
 12.1915 -	SAVE_REST
 12.1916 -	;;
 12.1917 -	mov r15=0x80
 12.1918 -	shr r14=r14,16		// Get interrupt number
 12.1919 -	;;
 12.1920 -	cmp.ne p6,p0=r14,r15
 12.1921 -(p6)	br.call.dpnt.many b6=non_ia32_syscall
 12.1922 -
 12.1923 -	adds r14=IA64_PT_REGS_R8_OFFSET + 16,sp	// 16 byte hole per SW conventions
 12.1924 -	adds r15=IA64_PT_REGS_R1_OFFSET + 16,sp
 12.1925 -	;;
 12.1926 -	cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0
 12.1927 -	ld8 r8=[r14]		// get r8
 12.1928 -	;;
 12.1929 -	st8 [r15]=r8		// save original EAX in r1 (IA32 procs don't use the GP)
 12.1930 -	;;
 12.1931 -	alloc r15=ar.pfs,0,0,6,0	// must first in an insn group
 12.1932 -	;;
 12.1933 -	ld4 r8=[r14],8		// r8 == eax (syscall number)
 12.1934 -	mov r15=IA32_NR_syscalls
 12.1935 -	;;
 12.1936 -	cmp.ltu.unc p6,p7=r8,r15
 12.1937 -	ld4 out1=[r14],8	// r9 == ecx
 12.1938 -	;;
 12.1939 -	ld4 out2=[r14],8	// r10 == edx
 12.1940 -	;;
 12.1941 -	ld4 out0=[r14]		// r11 == ebx
 12.1942 -	adds r14=(IA64_PT_REGS_R13_OFFSET) + 16,sp
 12.1943 -	;;
 12.1944 -	ld4 out5=[r14],PT(R14)-PT(R13)	// r13 == ebp
 12.1945 -	;;
 12.1946 -	ld4 out3=[r14],PT(R15)-PT(R14)	// r14 == esi
 12.1947 -	adds r2=TI_FLAGS+IA64_TASK_SIZE,r13
 12.1948 -	;;
 12.1949 -	ld4 out4=[r14]		// r15 == edi
 12.1950 -	movl r16=ia32_syscall_table
 12.1951 -	;;
 12.1952 -(p6)	shladd r16=r8,3,r16	// force ni_syscall if not valid syscall number
 12.1953 -	ld4 r2=[r2]		// r2 = current_thread_info()->flags
 12.1954 -	;;
 12.1955 -	ld8 r16=[r16]
 12.1956 -	and r2=_TIF_SYSCALL_TRACEAUDIT,r2	// mask trace or audit
 12.1957 -	;;
 12.1958 -	mov b6=r16
 12.1959 -	movl r15=ia32_ret_from_syscall
 12.1960 -	cmp.eq p8,p0=r2,r0
 12.1961 -	;;
 12.1962 -	mov rp=r15
 12.1963 -(p8)	br.call.sptk.many b6=b6
 12.1964 -	br.cond.sptk ia32_trace_syscall
 12.1965 -
 12.1966 -non_ia32_syscall:
 12.1967 -	alloc r15=ar.pfs,0,0,2,0
 12.1968 -	mov out0=r14				// interrupt #
 12.1969 -	add out1=16,sp				// pointer to pt_regs
 12.1970 -	;;			// avoid WAW on CFM
 12.1971 -	br.call.sptk.many rp=ia32_bad_interrupt
 12.1972 -.ret1:	movl r15=ia64_leave_kernel
 12.1973 -	;;
 12.1974 -	mov rp=r15
 12.1975 -	br.ret.sptk.many rp
 12.1976 -END(dispatch_to_ia32_handler)
 12.1977 -
 12.1978 -#endif /* CONFIG_IA32_SUPPORT */
    13.1 --- a/xen/arch/ia64/linux/README.origin	Thu Sep 01 11:09:27 2005 -0600
    13.2 +++ b/xen/arch/ia64/linux/README.origin	Thu Sep 01 12:46:28 2005 -0600
    13.3 @@ -13,12 +13,13 @@ linuxextable.c		-> linux/kernel/extable.
    13.4  machvec.c		-> linux/arch/ia64/kernel/machvec.c
    13.5  patch.c			-> linux/arch/ia64/kernel/patch.c
    13.6  pcdp.h			-> drivers/firmware/pcdp.h
    13.7 -lib/bitop.c		-> linux/arch/ia64/lib/bitop.c
    13.8 -lib/clear_page.S	-> linux/arch/ia64/lib/clear_page.S
    13.9 -lib/copy_page_mck.S	-> linux/arch/ia64/lib/copy_page_mck.S
   13.10 -lib/flush.S		-> linux/arch/ia64/lib/flush.S
   13.11 -lib/idiv32.S		-> linux/arch/ia64/lib/idiv32.S
   13.12 -lib/idiv64.S		-> linux/arch/ia64/lib/idiv64.S
   13.13 -lib/memcpy_mck.S	-> linux/arch/ia64/lib/memcpy_mck.S
   13.14 -lib/memset.S		-> linux/arch/ia64/lib/memset.S
   13.15 -lib/strlen.S		-> linux/arch/ia64/lib/strlen.S
   13.16 +
   13.17 +bitop.c			-> linux/arch/ia64/lib/bitop.c
   13.18 +clear_page.S		-> linux/arch/ia64/lib/clear_page.S
   13.19 +copy_page_mck.S		-> linux/arch/ia64/lib/copy_page_mck.S
   13.20 +flush.S			-> linux/arch/ia64/lib/flush.S
   13.21 +idiv32.S		-> linux/arch/ia64/lib/idiv32.S
   13.22 +idiv64.S		-> linux/arch/ia64/lib/idiv64.S
   13.23 +memcpy_mck.S		-> linux/arch/ia64/lib/memcpy_mck.S
   13.24 +memset.S		-> linux/arch/ia64/lib/memset.S
   13.25 +strlen.S		-> linux/arch/ia64/lib/strlen.S
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/xen/arch/ia64/linux/bitop.c	Thu Sep 01 12:46:28 2005 -0600
    14.3 @@ -0,0 +1,88 @@
    14.4 +#include <linux/compiler.h>
    14.5 +#include <linux/types.h>
    14.6 +#include <asm/intrinsics.h>
    14.7 +#include <linux/module.h>
    14.8 +#include <linux/bitops.h>
    14.9 +
   14.10 +/*
   14.11 + * Find next zero bit in a bitmap reasonably efficiently..
   14.12 + */
   14.13 +
   14.14 +int __find_next_zero_bit (const void *addr, unsigned long size, unsigned long offset)
   14.15 +{
   14.16 +	unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
   14.17 +	unsigned long result = offset & ~63UL;
   14.18 +	unsigned long tmp;
   14.19 +
   14.20 +	if (offset >= size)
   14.21 +		return size;
   14.22 +	size -= result;
   14.23 +	offset &= 63UL;
   14.24 +	if (offset) {
   14.25 +		tmp = *(p++);
   14.26 +		tmp |= ~0UL >> (64-offset);
   14.27 +		if (size < 64)
   14.28 +			goto found_first;
   14.29 +		if (~tmp)
   14.30 +			goto found_middle;
   14.31 +		size -= 64;
   14.32 +		result += 64;
   14.33 +	}
   14.34 +	while (size & ~63UL) {
   14.35 +		if (~(tmp = *(p++)))
   14.36 +			goto found_middle;
   14.37 +		result += 64;
   14.38 +		size -= 64;
   14.39 +	}
   14.40 +	if (!size)
   14.41 +		return result;
   14.42 +	tmp = *p;
   14.43 +found_first:
   14.44 +	tmp |= ~0UL << size;
   14.45 +	if (tmp == ~0UL)		/* any bits zero? */
   14.46 +		return result + size;	/* nope */
   14.47 +found_middle:
   14.48 +	return result + ffz(tmp);
   14.49 +}
   14.50 +EXPORT_SYMBOL(__find_next_zero_bit);
   14.51 +
   14.52 +/*
   14.53 + * Find next bit in a bitmap reasonably efficiently..
   14.54 + */
   14.55 +int __find_next_bit(const void *addr, unsigned long size, unsigned long offset)
   14.56 +{
   14.57 +	unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
   14.58 +	unsigned long result = offset & ~63UL;
   14.59 +	unsigned long tmp;
   14.60 +
   14.61 +	if (offset >= size)
   14.62 +		return size;
   14.63 +	size -= result;
   14.64 +	offset &= 63UL;
   14.65 +	if (offset) {
   14.66 +		tmp = *(p++);
   14.67 +		tmp &= ~0UL << offset;
   14.68 +		if (size < 64)
   14.69 +			goto found_first;
   14.70 +		if (tmp)
   14.71 +			goto found_middle;
   14.72 +		size -= 64;
   14.73 +		result += 64;
   14.74 +	}
   14.75 +	while (size & ~63UL) {
   14.76 +		if ((tmp = *(p++)))
   14.77 +			goto found_middle;
   14.78 +		result += 64;
   14.79 +		size -= 64;
   14.80 +	}
   14.81 +	if (!size)
   14.82 +		return result;
   14.83 +	tmp = *p;
   14.84 +  found_first:
   14.85 +	tmp &= ~0UL >> (64-size);
   14.86 +	if (tmp == 0UL)		/* Are any bits set? */
   14.87 +		return result + size; /* Nope. */
   14.88 +  found_middle:
   14.89 +	return result + __ffs(tmp);
   14.90 +}
   14.91 +EXPORT_SYMBOL(__find_next_bit);
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/xen/arch/ia64/linux/clear_page.S	Thu Sep 01 12:46:28 2005 -0600
    15.3 @@ -0,0 +1,77 @@
    15.4 +/*
    15.5 + * Copyright (C) 1999-2002 Hewlett-Packard Co
    15.6 + *	Stephane Eranian <eranian@hpl.hp.com>
    15.7 + *	David Mosberger-Tang <davidm@hpl.hp.com>
    15.8 + * Copyright (C) 2002 Ken Chen <kenneth.w.chen@intel.com>
    15.9 + *
   15.10 + * 1/06/01 davidm	Tuned for Itanium.
   15.11 + * 2/12/02 kchen	Tuned for both Itanium and McKinley
   15.12 + * 3/08/02 davidm	Some more tweaking
   15.13 + */
   15.14 +#include <linux/config.h>
   15.15 +
   15.16 +#include <asm/asmmacro.h>
   15.17 +#include <asm/page.h>
   15.18 +
   15.19 +#ifdef CONFIG_ITANIUM
   15.20 +# define L3_LINE_SIZE	64	// Itanium L3 line size
   15.21 +# define PREFETCH_LINES	9	// magic number
   15.22 +#else
   15.23 +# define L3_LINE_SIZE	128	// McKinley L3 line size
   15.24 +# define PREFETCH_LINES	12	// magic number
   15.25 +#endif
   15.26 +
   15.27 +#define saved_lc	r2
   15.28 +#define dst_fetch	r3
   15.29 +#define dst1		r8
   15.30 +#define dst2		r9
   15.31 +#define dst3		r10
   15.32 +#define dst4		r11
   15.33 +
   15.34 +#define dst_last	r31
   15.35 +
   15.36 +GLOBAL_ENTRY(clear_page)
   15.37 +	.prologue
   15.38 +	.regstk 1,0,0,0
   15.39 +	mov r16 = PAGE_SIZE/L3_LINE_SIZE-1	// main loop count, -1=repeat/until
   15.40 +	.save ar.lc, saved_lc
   15.41 +	mov saved_lc = ar.lc
   15.42 +
   15.43 +	.body
   15.44 +	mov ar.lc = (PREFETCH_LINES - 1)
   15.45 +	mov dst_fetch = in0
   15.46 +	adds dst1 = 16, in0
   15.47 +	adds dst2 = 32, in0
   15.48 +	;;
   15.49 +.fetch:	stf.spill.nta [dst_fetch] = f0, L3_LINE_SIZE
   15.50 +	adds dst3 = 48, in0		// executing this multiple times is harmless
   15.51 +	br.cloop.sptk.few .fetch
   15.52 +	;;
   15.53 +	addl dst_last = (PAGE_SIZE - PREFETCH_LINES*L3_LINE_SIZE), dst_fetch
   15.54 +	mov ar.lc = r16			// one L3 line per iteration
   15.55 +	adds dst4 = 64, in0
   15.56 +	;;
   15.57 +#ifdef CONFIG_ITANIUM
   15.58 +	// Optimized for Itanium
   15.59 +1:	stf.spill.nta [dst1] = f0, 64
   15.60 +	stf.spill.nta [dst2] = f0, 64
   15.61 +	cmp.lt p8,p0=dst_fetch, dst_last
   15.62 +	;;
   15.63 +#else
   15.64 +	// Optimized for McKinley
   15.65 +1:	stf.spill.nta [dst1] = f0, 64
   15.66 +	stf.spill.nta [dst2] = f0, 64
   15.67 +	stf.spill.nta [dst3] = f0, 64
   15.68 +	stf.spill.nta [dst4] = f0, 128
   15.69 +	cmp.lt p8,p0=dst_fetch, dst_last
   15.70 +	;;
   15.71 +	stf.spill.nta [dst1] = f0, 64
   15.72 +	stf.spill.nta [dst2] = f0, 64
   15.73 +#endif
   15.74 +	stf.spill.nta [dst3] = f0, 64
   15.75 +(p8)	stf.spill.nta [dst_fetch] = f0, L3_LINE_SIZE
   15.76 +	br.cloop.sptk.few 1b
   15.77 +	;;
   15.78 +	mov ar.lc = saved_lc		// restore lc
   15.79 +	br.ret.sptk.many rp
   15.80 +END(clear_page)
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/xen/arch/ia64/linux/copy_page_mck.S	Thu Sep 01 12:46:28 2005 -0600
    16.3 @@ -0,0 +1,185 @@
    16.4 +/*
    16.5 + * McKinley-optimized version of copy_page().
    16.6 + *
    16.7 + * Copyright (C) 2002 Hewlett-Packard Co
    16.8 + *	David Mosberger <davidm@hpl.hp.com>
    16.9 + *
   16.10 + * Inputs:
   16.11 + *	in0:	address of target page
   16.12 + *	in1:	address of source page
   16.13 + * Output:
   16.14 + *	no return value
   16.15 + *
   16.16 + * General idea:
   16.17 + *	- use regular loads and stores to prefetch data to avoid consuming M-slot just for
   16.18 + *	  lfetches => good for in-cache performance
   16.19 + *	- avoid l2 bank-conflicts by not storing into the same 16-byte bank within a single
   16.20 + *	  cycle
   16.21 + *
   16.22 + * Principle of operation:
   16.23 + *	First, note that L1 has a line-size of 64 bytes and L2 a line-size of 128 bytes.
   16.24 + *	To avoid secondary misses in L2, we prefetch both source and destination with a line-size
   16.25 + *	of 128 bytes.  When both of these lines are in the L2 and the first half of the
   16.26 + *	source line is in L1, we start copying the remaining words.  The second half of the
   16.27 + *	source line is prefetched in an earlier iteration, so that by the time we start
   16.28 + *	accessing it, it's also present in the L1.
   16.29 + *
   16.30 + *	We use a software-pipelined loop to control the overall operation.  The pipeline
   16.31 + *	has 2*PREFETCH_DIST+K stages.  The first PREFETCH_DIST stages are used for prefetching
   16.32 + *	source cache-lines.  The second PREFETCH_DIST stages are used for prefetching destination
   16.33 + *	cache-lines, the last K stages are used to copy the cache-line words not copied by
   16.34 + *	the prefetches.  The four relevant points in the pipelined are called A, B, C, D:
   16.35 + *	p[A] is TRUE if a source-line should be prefetched, p[B] is TRUE if a destination-line
   16.36 + *	should be prefetched, p[C] is TRUE if the second half of an L2 line should be brought
   16.37 + *	into L1D and p[D] is TRUE if a cacheline needs to be copied.
   16.38 + *
   16.39 + *	This all sounds very complicated, but thanks to the modulo-scheduled loop support,
   16.40 + *	the resulting code is very regular and quite easy to follow (once you get the idea).
   16.41 + *
   16.42 + *	As a secondary optimization, the first 2*PREFETCH_DIST iterations are implemented
   16.43 + *	as the separate .prefetch_loop.  Logically, this loop performs exactly like the
   16.44 + *	main-loop (.line_copy), but has all known-to-be-predicated-off instructions removed,
   16.45 + *	so that each loop iteration is faster (again, good for cached case).
   16.46 + *
   16.47 + *	When reading the code, it helps to keep the following picture in mind:
   16.48 + *
   16.49 + *	       word 0 word 1
   16.50 + *            +------+------+---
   16.51 + *	      |	v[x] | 	t1  | ^
   16.52 + *	      |	t2   |	t3  | |
   16.53 + *	      |	t4   |	t5  | |
   16.54 + *	      |	t6   |	t7  | | 128 bytes
   16.55 + *     	      |	n[y] | 	t9  | |	(L2 cache line)
   16.56 + *	      |	t10  | 	t11 | |
   16.57 + *	      |	t12  | 	t13 | |
   16.58 + *	      |	t14  | 	t15 | v
   16.59 + *	      +------+------+---
   16.60 + *
   16.61 + *	Here, v[x] is copied by the (memory) prefetch.  n[y] is loaded at p[C]
   16.62 + *	to fetch the second-half of the L2 cache line into L1, and the tX words are copied in
   16.63 + *	an order that avoids bank conflicts.
   16.64 + */
   16.65 +#include <asm/asmmacro.h>
   16.66 +#include <asm/page.h>
   16.67 +
   16.68 +#define PREFETCH_DIST	8		// McKinley sustains 16 outstanding L2 misses (8 ld, 8 st)
   16.69 +
   16.70 +#define src0		r2
   16.71 +#define src1		r3
   16.72 +#define dst0		r9
   16.73 +#define dst1		r10
   16.74 +#define src_pre_mem	r11
   16.75 +#define dst_pre_mem	r14
   16.76 +#define src_pre_l2	r15
   16.77 +#define dst_pre_l2	r16
   16.78 +#define t1		r17
   16.79 +#define t2		r18
   16.80 +#define t3		r19
   16.81 +#define t4		r20
   16.82 +#define t5		t1	// alias!
   16.83 +#define t6		t2	// alias!
   16.84 +#define t7		t3	// alias!
   16.85 +#define t9		t5	// alias!
   16.86 +#define t10		t4	// alias!
   16.87 +#define t11		t7	// alias!
   16.88 +#define t12		t6	// alias!
   16.89 +#define t14		t10	// alias!
   16.90 +#define t13		r21
   16.91 +#define t15		r22
   16.92 +
   16.93 +#define saved_lc	r23
   16.94 +#define saved_pr	r24
   16.95 +
   16.96 +#define	A	0
   16.97 +#define B	(PREFETCH_DIST)
   16.98 +#define C	(B + PREFETCH_DIST)
   16.99 +#define D	(C + 3)
  16.100 +#define N	(D + 1)
  16.101 +#define Nrot	((N + 7) & ~7)
  16.102 +
  16.103 +GLOBAL_ENTRY(copy_page)
  16.104 +	.prologue
  16.105 +	alloc r8 = ar.pfs, 2, Nrot-2, 0, Nrot
  16.106 +
  16.107 +	.rotr v[2*PREFETCH_DIST], n[D-C+1]
  16.108 +	.rotp p[N]
  16.109 +
  16.110 +	.save ar.lc, saved_lc
  16.111 +	mov saved_lc = ar.lc
  16.112 +	.save pr, saved_pr
  16.113 +	mov saved_pr = pr
  16.114 +	.body
  16.115 +
  16.116 +	mov src_pre_mem = in1
  16.117 +	mov pr.rot = 0x10000
  16.118 +	mov ar.ec = 1				// special unrolled loop
  16.119 +
  16.120 +	mov dst_pre_mem = in0
  16.121 +	mov ar.lc = 2*PREFETCH_DIST - 1
  16.122 +
  16.123 +	add src_pre_l2 = 8*8, in1
  16.124 +	add dst_pre_l2 = 8*8, in0
  16.125 +	add src0 = 8, in1			// first t1 src
  16.126 +	add src1 = 3*8, in1			// first t3 src
  16.127 +	add dst0 = 8, in0			// first t1 dst
  16.128 +	add dst1 = 3*8, in0			// first t3 dst
  16.129 +	mov t1 = (PAGE_SIZE/128) - (2*PREFETCH_DIST) - 1
  16.130 +	nop.m 0
  16.131 +	nop.i 0
  16.132 +	;;
  16.133 +	// same as .line_copy loop, but with all predicated-off instructions removed:
  16.134 +.prefetch_loop:
  16.135 +(p[A])	ld8 v[A] = [src_pre_mem], 128		// M0
  16.136 +(p[B])	st8 [dst_pre_mem] = v[B], 128		// M2
  16.137 +	br.ctop.sptk .prefetch_loop
  16.138 +	;;
  16.139 +	cmp.eq p16, p0 = r0, r0			// reset p16 to 1 (br.ctop cleared it to zero)
  16.140 +	mov ar.lc = t1				// with 64KB pages, t1 is too big to fit in 8 bits!
  16.141 +	mov ar.ec = N				// # of stages in pipeline
  16.142 +	;;
  16.143 +.line_copy:
  16.144 +(p[D])	ld8 t2 = [src0], 3*8			// M0
  16.145 +(p[D])	ld8 t4 = [src1], 3*8			// M1
  16.146 +(p[B])	st8 [dst_pre_mem] = v[B], 128		// M2 prefetch dst from memory
  16.147 +(p[D])	st8 [dst_pre_l2] = n[D-C], 128		// M3 prefetch dst from L2
  16.148 +	;;
  16.149 +(p[A])	ld8 v[A] = [src_pre_mem], 128		// M0 prefetch src from memory
  16.150 +(p[C])	ld8 n[0] = [src_pre_l2], 128		// M1 prefetch src from L2
  16.151 +(p[D])	st8 [dst0] =  t1, 8			// M2
  16.152 +(p[D])	st8 [dst1] =  t3, 8			// M3
  16.153 +	;;
  16.154 +(p[D])	ld8  t5 = [src0], 8
  16.155 +(p[D])	ld8  t7 = [src1], 3*8
  16.156 +(p[D])	st8 [dst0] =  t2, 3*8
  16.157 +(p[D])	st8 [dst1] =  t4, 3*8
  16.158 +	;;
  16.159 +(p[D])	ld8  t6 = [src0], 3*8
  16.160 +(p[D])	ld8 t10 = [src1], 8
  16.161 +(p[D])	st8 [dst0] =  t5, 8
  16.162 +(p[D])	st8 [dst1] =  t7, 3*8
  16.163 +	;;
  16.164 +(p[D])	ld8  t9 = [src0], 3*8
  16.165 +(p[D])	ld8 t11 = [src1], 3*8
  16.166 +(p[D])	st8 [dst0] =  t6, 3*8
  16.167 +(p[D])	st8 [dst1] = t10, 8
  16.168 +	;;
  16.169 +(p[D])	ld8 t12 = [src0], 8
  16.170 +(p[D])	ld8 t14 = [src1], 8
  16.171 +(p[D])	st8 [dst0] =  t9, 3*8
  16.172 +(p[D])	st8 [dst1] = t11, 3*8
  16.173 +	;;
  16.174 +(p[D])	ld8 t13 = [src0], 4*8
  16.175 +(p[D])	ld8 t15 = [src1], 4*8
  16.176 +(p[D])	st8 [dst0] = t12, 8
  16.177 +(p[D])	st8 [dst1] = t14, 8
  16.178 +	;;
  16.179 +(p[D-1])ld8  t1 = [src0], 8
  16.180 +(p[D-1])ld8  t3 = [src1], 8
  16.181 +(p[D])	st8 [dst0] = t13, 4*8
  16.182 +(p[D])	st8 [dst1] = t15, 4*8
  16.183 +	br.ctop.sptk .line_copy
  16.184 +	;;
  16.185 +	mov ar.lc = saved_lc
  16.186 +	mov pr = saved_pr, -1
  16.187 +	br.ret.sptk.many rp
  16.188 +END(copy_page)
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/xen/arch/ia64/linux/flush.S	Thu Sep 01 12:46:28 2005 -0600
    17.3 @@ -0,0 +1,61 @@
    17.4 +/*
    17.5 + * Cache flushing routines.
    17.6 + *
    17.7 + * Copyright (C) 1999-2001, 2005 Hewlett-Packard Co
    17.8 + *	David Mosberger-Tang <davidm@hpl.hp.com>
    17.9 + *
   17.10 + * 05/28/05 Zoltan Menyhart	Dynamic stride size
   17.11 + */
   17.12 +
   17.13 +#include <asm/asmmacro.h>
   17.14 +
   17.15 +
   17.16 +	/*
   17.17 +	 * flush_icache_range(start,end)
   17.18 +	 *
   17.19 +	 *	Make i-cache(s) coherent with d-caches.
   17.20 +	 *
   17.21 +	 *	Must deal with range from start to end-1 but nothing else (need to
   17.22 +	 *	be careful not to touch addresses that may be unmapped).
   17.23 +	 *
   17.24 +	 *	Note: "in0" and "in1" are preserved for debugging purposes.
   17.25 +	 */
   17.26 +GLOBAL_ENTRY(flush_icache_range)
   17.27 +
   17.28 +	.prologue
   17.29 +	alloc	r2=ar.pfs,2,0,0,0
   17.30 +	movl	r3=ia64_i_cache_stride_shift
   17.31 + 	mov	r21=1
   17.32 +	;;
   17.33 +	ld8	r20=[r3]		// r20: stride shift
   17.34 +	sub	r22=in1,r0,1		// last byte address
   17.35 +	;;
   17.36 +	shr.u	r23=in0,r20		// start / (stride size)
   17.37 +	shr.u	r22=r22,r20		// (last byte address) / (stride size)
   17.38 +	shl	r21=r21,r20		// r21: stride size of the i-cache(s)
   17.39 +	;;
   17.40 +	sub	r8=r22,r23		// number of strides - 1
   17.41 +	shl	r24=r23,r20		// r24: addresses for "fc.i" =
   17.42 +					//	"start" rounded down to stride boundary
   17.43 +	.save	ar.lc,r3
   17.44 +	mov	r3=ar.lc		// save ar.lc
   17.45 +	;;
   17.46 +
   17.47 +	.body
   17.48 +	mov	ar.lc=r8
   17.49 +	;;
   17.50 +	/*
   17.51 +	 * 32 byte aligned loop, even number of (actually 2) bundles
   17.52 +	 */
   17.53 +.Loop:	fc.i	r24			// issuable on M0 only
   17.54 +	add	r24=r21,r24		// we flush "stride size" bytes per iteration
   17.55 +	nop.i	0
   17.56 +	br.cloop.sptk.few .Loop
   17.57 +	;;
   17.58 +	sync.i
   17.59 +	;;
   17.60 +	srlz.i
   17.61 +	;;
   17.62 +	mov	ar.lc=r3		// restore ar.lc
   17.63 +	br.ret.sptk.many rp
   17.64 +END(flush_icache_range)
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/xen/arch/ia64/linux/idiv32.S	Thu Sep 01 12:46:28 2005 -0600
    18.3 @@ -0,0 +1,83 @@
    18.4 +/*
    18.5 + * Copyright (C) 2000 Hewlett-Packard Co
    18.6 + * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
    18.7 + *
    18.8 + * 32-bit integer division.
    18.9 + *
   18.10 + * This code is based on the application note entitled "Divide, Square Root
   18.11 + * and Remainder Algorithms for the IA-64 Architecture".  This document
   18.12 + * is available as Intel document number 248725-002 or via the web at
   18.13 + * http://developer.intel.com/software/opensource/numerics/
   18.14 + *
   18.15 + * For more details on the theory behind these algorithms, see "IA-64
   18.16 + * and Elementary Functions" by Peter Markstein; HP Professional Books
   18.17 + * (http://www.hp.com/go/retailbooks/)
   18.18 + */
   18.19 +
   18.20 +#include <asm/asmmacro.h>
   18.21 +
   18.22 +#ifdef MODULO
   18.23 +# define OP	mod
   18.24 +#else
   18.25 +# define OP	div
   18.26 +#endif
   18.27 +
   18.28 +#ifdef UNSIGNED
   18.29 +# define SGN	u
   18.30 +# define EXTEND	zxt4
   18.31 +# define INT_TO_FP(a,b)	fcvt.xuf.s1 a=b
   18.32 +# define FP_TO_INT(a,b)	fcvt.fxu.trunc.s1 a=b
   18.33 +#else
   18.34 +# define SGN
   18.35 +# define EXTEND	sxt4
   18.36 +# define INT_TO_FP(a,b)	fcvt.xf a=b
   18.37 +# define FP_TO_INT(a,b)	fcvt.fx.trunc.s1 a=b
   18.38 +#endif
   18.39 +
   18.40 +#define PASTE1(a,b)	a##b
   18.41 +#define PASTE(a,b)	PASTE1(a,b)